summaryrefslogtreecommitdiff
path: root/src/qmail-qmaint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-qmaint.c')
-rw-r--r--src/qmail-qmaint.c110
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();