Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F120825130
cyr_expire.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
cyr_expire.c
View Options
/* cyr_expire.c -- Program to expire deliver.db entries and messages
*
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any other legal
* details, please contact
* Office of Technology Transfer
* Carnegie Mellon University
* 5000 Forbes Avenue
* Pittsburgh, PA 15213-3890
* (412) 268-4387, fax: (412) 268-7395
* tech-transfer@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: cyr_expire.c,v 1.6 2004/02/27 17:44:49 ken3 Exp $
*/
#include
<config.h>
#ifdef HAVE_UNISTD_H
#include
<unistd.h>
#endif
#include
<stdlib.h>
#include
<stdio.h>
#include
<string.h>
#include
<ctype.h>
#include
<fcntl.h>
#include
<sys/stat.h>
#include
<syslog.h>
#include
<com_err.h>
#include
<errno.h>
#include
<signal.h>
#include
"annotate.h"
#include
"cyrusdb.h"
#include
"duplicate.h"
#include
"exitcodes.h"
#include
"global.h"
#include
"hash.h"
#include
"libcyr_cfg.h"
#include
"mboxlist.h"
#include
"util.h"
#include
"xmalloc.h"
/* global state */
const
int
config_need_data
=
0
;
void
usage
(
void
)
{
fprintf
(
stderr
,
"cyr_expire [-C <altconfig>] -E <days> [-v]
\n
"
);
exit
(
-1
);
}
/*
* mboxlist_findall() callback function to build a hash table of mailboxes
* which need to have messages expired.
*/
int
build_table
(
char
*
name
,
int
matchlen
,
int
maycreate
__attribute__
((
unused
)),
void
*
rock
)
{
struct
hash_table
*
expire_table
=
(
struct
hash_table
*
)
rock
;
char
buf
[
MAX_MAILBOX_NAME
+
1
]
=
""
,
*
p
;
struct
annotation_data
attrib
;
int
r
,
domainlen
=
0
;
if
(
config_virtdomains
&&
(
p
=
strchr
(
name
,
'!'
)))
domainlen
=
p
-
name
+
1
;
strncpy
(
buf
,
name
,
matchlen
);
buf
[
matchlen
]
=
'\0'
;
/* since mailboxes inherit /vendor/cmu/cyrus-imapd/expire,
we need to iterate all the way up to "" (server entry) */
while
(
1
)
{
r
=
annotatemore_lookup
(
buf
,
"/vendor/cmu/cyrus-imapd/expire"
,
""
,
&
attrib
);
if
(
r
||
/* error */
attrib
.
value
||
/* found an entry */
!
buf
[
0
]
||
/* done recursing */
!
strcmp
(
buf
+
domainlen
,
"user"
))
{
/* server entry doesn't apply
to personal mailboxes */
break
;
}
p
=
strrchr
(
buf
,
'.'
);
/* find parent mailbox */
if
(
p
&&
(
p
-
buf
>
domainlen
))
/* don't split subdomain */
*
p
=
'\0'
;
else
if
(
!
buf
[
domainlen
])
/* server entry */
buf
[
0
]
=
'\0'
;
else
/* domain entry */
buf
[
domainlen
]
=
'\0'
;
}
if
(
!
r
&&
attrib
.
value
)
{
/* add mailbox to table */
unsigned
long
days
=
strtoul
(
attrib
.
value
,
NULL
,
10
);
time_t
*
expmark
=
(
time_t
*
)
xmalloc
(
sizeof
(
time_t
));
*
expmark
=
days
?
time
(
0
)
-
(
days
*
60
*
60
*
24
)
:
0
/* never */
;
hash_insert
(
name
,
(
void
*
)
expmark
,
expire_table
);
}
return
r
;
}
struct
expire_rock
{
time_t
expmark
;
unsigned
long
mailboxes
;
unsigned
long
messages
;
unsigned
long
deleted
;
int
verbose
;
};
/*
* mailbox_expunge() callback to expunge expired articles.
*/
static
int
expunge_cb
(
struct
mailbox
*
mailbox
__attribute__
((
unused
)),
void
*
rock
,
char
*
index
)
{
struct
expire_rock
*
erock
=
(
struct
expire_rock
*
)
rock
;
bit32
senttime
=
ntohl
(
*
((
bit32
*
)(
index
+
OFFSET_SENTDATE
)));
erock
->
messages
++
;
if
(
senttime
<
erock
->
expmark
)
{
erock
->
deleted
++
;
return
1
;
}
return
0
;
}
static
void
do_expire
(
char
*
mboxname
,
void
*
data
,
void
*
rock
)
{
struct
expire_rock
*
erock
=
(
struct
expire_rock
*
)
rock
;
time_t
*
expmark
=
(
time_t
*
)
data
;
struct
mailbox
mailbox
;
int
r
;
if
(
erock
->
verbose
)
{
fprintf
(
stderr
,
"expiring messages in %s older than %ld days
\n
"
,
mboxname
,
(
time
(
0
)
-
*
expmark
)
/
(
60
*
60
*
24
));
}
erock
->
mailboxes
++
;
erock
->
expmark
=
*
expmark
;
/* Open/lock header */
r
=
mailbox_open_header
(
mboxname
,
0
,
&
mailbox
);
if
(
!
r
&&
mailbox
.
header_fd
!=
-1
)
{
(
void
)
mailbox_lock_header
(
&
mailbox
);
mailbox
.
header_lock_count
=
1
;
}
if
(
!
r
)
r
=
chdir
(
mailbox
.
path
);
/* Attempt to open/lock index */
if
(
!
r
)
r
=
mailbox_open_index
(
&
mailbox
);
if
(
!
r
)
{
(
void
)
mailbox_lock_index
(
&
mailbox
);
mailbox
.
index_lock_count
=
1
;
}
if
(
!
r
)
mailbox_expunge
(
&
mailbox
,
1
,
expunge_cb
,
erock
);
mailbox_close
(
&
mailbox
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
extern
char
*
optarg
;
int
opt
,
r
=
0
,
days
=
0
;
char
*
alt_config
=
NULL
;
char
buf
[
100
];
struct
hash_table
expire_table
;
struct
expire_rock
erock
;
if
(
geteuid
()
==
0
)
fatal
(
"must run as the Cyrus user"
,
EC_USAGE
);
/* zero the expire_rock */
memset
(
&
erock
,
0
,
sizeof
(
erock
));
while
((
opt
=
getopt
(
argc
,
argv
,
"C:E:v"
))
!=
EOF
)
{
switch
(
opt
)
{
case
'C'
:
/* alt config file */
alt_config
=
optarg
;
break
;
case
'E'
:
if
(
days
)
usage
();
days
=
atoi
(
optarg
);
break
;
case
'v'
:
erock
.
verbose
++
;
break
;
default
:
usage
();
break
;
}
}
if
(
!
days
)
usage
();
cyrus_init
(
alt_config
,
"cyr_expire"
,
0
);
annotatemore_init
(
0
,
NULL
,
NULL
);
annotatemore_open
(
NULL
);
mboxlist_init
(
0
);
mboxlist_open
(
NULL
);
/* open the quota db, we'll need it for expunge */
quotadb_init
(
0
);
quotadb_open
(
NULL
);
if
(
duplicate_init
(
NULL
,
0
)
!=
0
)
{
fprintf
(
stderr
,
"cyr_expire: unable to init duplicate delivery database
\n
"
);
exit
(
1
);
}
/* xxx better way to determine a size for this table? */
construct_hash_table
(
&
expire_table
,
10000
,
1
);
strlcpy
(
buf
,
"*"
,
sizeof
(
buf
));
mboxlist_findall
(
NULL
,
buf
,
1
,
0
,
0
,
&
build_table
,
&
expire_table
);
r
=
duplicate_prune
(
days
,
&
expire_table
);
if
(
!
r
)
{
hash_enumerate
(
&
expire_table
,
do_expire
,
&
erock
);
syslog
(
LOG_NOTICE
,
"expunged %lu out of %lu messages from %lu mailboxes"
,
erock
.
deleted
,
erock
.
messages
,
erock
.
mailboxes
);
if
(
erock
.
verbose
)
{
fprintf
(
stderr
,
"
\n
expunged %lu out of %lu messages from %lu mailboxes
\n
"
,
erock
.
deleted
,
erock
.
messages
,
erock
.
mailboxes
);
}
}
free_hash_table
(
&
expire_table
,
free
);
quotadb_close
();
quotadb_done
();
mboxlist_close
();
mboxlist_done
();
annotatemore_close
();
annotatemore_done
();
duplicate_done
();
cyrus_done
();
exit
(
r
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Apr 24, 10:33 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18890576
Default Alt Text
cyr_expire.c (7 KB)
Attached To
Mode
R111 cyrus-imapd
Attached
Detach File
Event Timeline