qmail-clean.c (2354B)
1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include "readwrite.h" 4 #include "sig.h" 5 #include "now.h" 6 #include "str.h" 7 #include "direntry.h" 8 #include "getln.h" 9 #include "stralloc.h" 10 #include "substdio.h" 11 #include "subfd.h" 12 #include "byte.h" 13 #include "datetime.h" 14 #include "scan.h" 15 #include "fmt.h" 16 #include "error.h" 17 #include "exit.h" 18 #include "fmtqfn.h" 19 #include "auto_qmail.h" 20 21 #define OSSIFIED 129600 /* see qmail-send.c */ 22 23 stralloc line = {0}; 24 25 void cleanuppid() 26 { 27 DIR *dir; 28 direntry *d; 29 struct stat st; 30 datetime_sec time; 31 32 time = now(); 33 dir = opendir("pid"); 34 if (!dir) return; 35 while ((d = readdir(dir))) 36 { 37 if (str_equal(d->d_name,".")) continue; 38 if (str_equal(d->d_name,"..")) continue; 39 if (!stralloc_copys(&line,"pid/")) continue; 40 if (!stralloc_cats(&line,d->d_name)) continue; 41 if (!stralloc_0(&line)) continue; 42 if (stat(line.s,&st) == -1) continue; 43 if (time < st.st_atime + OSSIFIED) continue; 44 unlink(line.s); 45 } 46 closedir(dir); 47 } 48 49 char fnbuf[FMTQFN]; 50 51 void respond(s) char *s; { if (substdio_putflush(subfdoutsmall,s,1) == -1) _exit(100); } 52 53 int main(void) 54 { 55 int i; 56 int match; 57 int cleanuploop; 58 unsigned long id; 59 60 if (chdir(auto_qmail) == -1) return 111; 61 if (chdir("queue") == -1) return 111; 62 63 sig_pipeignore(); 64 65 if (!stralloc_ready(&line,200)) return 111; 66 67 cleanuploop = 0; 68 69 for (;;) 70 { 71 if (cleanuploop) --cleanuploop; else { cleanuppid(); cleanuploop = 30; } 72 if (getln(subfdinsmall,&line,&match,'\0') == -1) break; //blocking read stdin because we do nowt else 73 if (!match) break; 74 if (line.len < 7) { respond("x"); continue; } // must be at least 7 chars 75 if (line.len > 100) { respond("x"); continue; } // must be under 101 chars 76 if (line.s[line.len - 1]) { respond("x"); continue; } /* impossible */ 77 for (i = 5;i < line.len - 1;++i) 78 if ((unsigned char) (line.s[i] - '0') > 9) 79 { respond("x"); continue; } // NaN 80 if (!scan_ulong(line.s + 5,&id)) { respond("x"); continue; } 81 if (byte_equal(line.s,5,"foop/")) 82 { 83 #define U(prefix,flag) fmtqfn(fnbuf,prefix,id,flag); \ 84 if (unlink(fnbuf) == -1) if (errno != error_noent) { respond("!"); continue; } 85 U("intd/",0) 86 U("mess/",1) 87 respond("+"); 88 } 89 else if (byte_equal(line.s,4,"todo/")) 90 { 91 U("intd/",0) 92 U("todo/",0) 93 respond("+"); 94 } 95 else 96 respond("x"); 97 } 98 return 0; 99 }