diff options
Diffstat (limited to 'src/qmail-qmaint.c')
-rw-r--r-- | src/qmail-qmaint.c | 110 |
1 files changed, 95 insertions, 15 deletions
diff --git a/src/qmail-qmaint.c b/src/qmail-qmaint.c index e83ab6f..02304e7 100644 --- a/src/qmail-qmaint.c +++ b/src/qmail-qmaint.c @@ -22,6 +22,8 @@ #include "auto_qmail.h" #include "auto_split.h" #include "auto_uids.h" +#include "datetime.h" +#include "date822fmt.h" #define WHO "qmail-qmaint" @@ -32,7 +34,9 @@ stralloc temp_filename = {0}; /*temporary used for checking individuals*/ stralloc old_name = {0}; /*used in rename*/ stralloc new_name = {0}; /*used in rename*/ stralloc mess_dir = {0}; /*used for renaming in mess dir*/ +stralloc dkim_dir = {0}; /*used for cleaning up dkim dir*/ stralloc query = {0}; /*used in interactive query function*/ +stralloc birth_date = {0}; /*used to display dkim messages*/ char strnum[FMT_ULONG]; int flag_interactive = 0; @@ -78,6 +82,18 @@ void die_nomem() logmsg(WHO,110,ERROR,"Out of memory."); } +void err_unlink(unsigned long id) +{ + char foo[FMT_ULONG]; + foo[fmt_ulong(foo,id)] = 0; + logmsg(WHO,100,ERROR,B("trouble with unlinking #",foo)); +} + +void err_chdir() +{ + logmsg(WHO,110,FATAL,"unable to chdir"); +} + /*returns 1==yes, 0==no*/ int confirm() @@ -321,6 +337,72 @@ int rename_mess(char *dir, char *part, char *new_part, char *old_filename, char return 0; } +unsigned int datefmt(char *s,datetime_sec when) +{ + unsigned int i; + unsigned int len; + struct datetime dt; + datetime_tai(&dt,when); + len = 0; + i = fmt_str(s," Date: "); len += i; if (s) s += i; + i = date822fmt(s,&dt); len += i; if (s) s += i; + return len; +} + +int date_make(datetime_sec when) +{ + if (!stralloc_ready(&birth_date,datefmt(FMT_LEN,when))) return 0; + birth_date.len = datefmt(birth_date.s,when); + return 1; +} + +int cleanup_dkim() +{ + DIR *dir; + direntry *d; + struct stat st; + int deleted = 0; + unsigned long id; + + if (chdir(auto_qmail) == -1) err_chdir(); + if (chdir("queue") == -1) err_chdir(); + if (chdir("dkim") == -1) return 0; + + if (!stralloc_copy(&dkim_dir,&queue_dir)) die_nomem(); + if (!stralloc_cats(&dkim_dir,"dkim/")) die_nomem(); + + for (int i = 0; i < split_num; i++) { + strnum[fmt_uint(strnum,i)] = 0; + if (!stralloc_copy(&temp_dirname,&dkim_dir)) die_nomem(); + if (!stralloc_cats(&temp_dirname,strnum)) die_nomem(); + if (!stralloc_append(&temp_dirname,"/")) die_nomem(); + + dir = opendir(temp_dirname.s); + if (!dir) continue; + + while ((d = readdir(dir))) { + if (d->d_name[0] == '.') continue; + /*check for dkim remnant */ + if (!stralloc_copy(&temp_filename,&temp_dirname)) die_nomem(); + if (!stralloc_cats(&temp_filename,d->d_name)) die_nomem(); + if (!stralloc_0(&temp_filename)) die_nomem(); + + if (stat(temp_filename.s,&st) == -1) continue; + date_make(st.st_mtime); + // message + logmsg(WHO,0,INFO,B("Deleting DKIM remnant message: ",temp_filename.s,birth_date.s)); + // delete + if (unlink(temp_filename.s) == -1) { + logmsg(WHO,111,ERROR,B("Can't remove file: ",temp_filename.s)); + } + // counter + ++deleted; + } + } + + return deleted; +} + int fix_part(char *part) { DIR *dir; @@ -359,6 +441,7 @@ int fix_part(char *part) /*rename*/ inode[fmt_ulong(inode,st.st_ino)] = 0; new_part[fmt_ulong(new_part,correct_part_num)] = 0; + if (rename_mess("dkim/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; } if (rename_mess("mess/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; } if (rename_mess("info/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; } if (rename_mess("local/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; } @@ -497,18 +580,6 @@ void warn_unlink(unsigned long id) logmsg(WHO,99,WARN,B("no such file to unlink #",foo)); } -void err_unlink(unsigned long id) -{ - char foo[FMT_ULONG]; - foo[fmt_ulong(foo,id)] = 0; - logmsg(WHO,100,ERROR,B("trouble with unlinking #",foo)); -} - -void err_chdir() -{ - logmsg(WHO,110,FATAL,"unable to chdir"); -} - int delete_msg(unsigned long id) { struct stat st; @@ -553,16 +624,21 @@ int main(int argc, char **argv) { char *mess = 0; unsigned long id = 0; + unsigned int n; + if (argc > 1) { if (!str_diff(argv[1],"-i")) { flag_interactive = 1; } else if (!str_diff(argv[1],"-d")) { - if (!argv[2]) logmsg(WHO,111,USAGE,"qmail-qmaint [-i] || [-d messid]"); + if (!argv[2]) logmsg(WHO,111,USAGE,"qmail-qmaint [-i] || [-d messid] || [-D]"); mess = argv[2]; flag_delete = 1; scan_ulong(mess,&id); - } + } else if (!str_diff(argv[1],"-D")) { + flag_delete = 2; + } else + logmsg(WHO,111,USAGE,"qmail-qmaint [-i] || [-d messid] || [-D]"); } if (!stralloc_copys(&queue_dir,auto_qmail)) die_nomem(); @@ -582,9 +658,13 @@ int main(int argc, char **argv) if (check_dirs()) die_check(); - if (flag_delete) { + if (flag_delete == 1) { if (!delete_msg(id)) logmsg(WHO,0,INFO,B("file ",mess," from queue deleted.")); + } else if (flag_delete == 2) { + n = cleanup_dkim(); + strnum[fmt_uint(strnum,n)] = 0; + logmsg(WHO,0,INFO,B(strnum," DKIM staging files from queue deleted.")); } else if (fix_names()) die_check(); |