/* Walk a folder and call a user defined command for each messages. Grab the output and use that to classify the message. */ #include #include #include #include #include #include #include #include #include #include "tlmpmail.h" #include "tlmpmail.m" #if 0 static int forkexecvp (const char *command, const char *argv[]) { int ret = -1; pid_t pid = fork(); if (pid == 0){ execvp (command,(char**)argv); }else if (pid == (pid_t)-1){ tlmp_error (MSG_U(E_CANTEXEC,"Can't fork (%s)\n"),strerror(errno)); }else{ int status; wait(&status); ret = WIFEXITED(status); } return ret; } #endif /* Grab all the IP address found in a mail header. IPs are presented between []. */ static int pickipaddrs (const char *head, SSTRINGS &ips) { int ret = 0; while (*head != '\0'){ head = strchr(head,'['); if (head == NULL) break; head++; if (isdigit(*head)){ const char *start = head; while (*head != ']' && *head != '\0') head++; if (head > start){ SSTRING *s = new SSTRING; s->setfrom (start,head-start); ips.add (s); ret++; } } } return ret; } int folderwalk (int argc, char *argv[]) { glocal const char *command = NULL; glocal bool verbose = false; static const char *tbdic[]={"tlmpwork","tlmpsql",NULL}; int ret = (argc,argv,tbdic); setproginfo ("folderwalk",TLMPWORK_VERSION,TLMPWORK_RELEASE ,MSG_U(T_FOLDERWALK ,"Walk a folder and execute a user defined command\n" "for each message to help classification.\n" "\n" "A folder may specify a virtual folder using the same\n" "syntax supported by the GUI. For example:\n" "\n" "\tINBOX:filter1:filter2\n" "\n" "specified a virtual folder showing the INBOX filtered\n" "twice.\n" ) ); setdbconfname ("tlmpmail"); setarg ('c',"command",MSG_U(I_COMMAND,"Command to execute for each message"),glocal.command,true); setarg ('v',"verbose",MSG_U(I_VERBOSE,"Verbose mode"),glocal.verbose,false); int ret = -1; if (argc < 1){ usage(); }else{ query_setdefaultdb ("localhost","usermail"); for (int i=0; iincrusage(); MAIL_MESSAGES msgs; int revision=-1; f->loadindex (msgs,revision); for (int i=0; iloadmsg(*m,full)!=-1){ if (glocal.verbose){ printf ("%4d: %s\n",i+1,m->subject.get()); } SSTRINGS ips; pickipaddrs (full.header.get(),ips); #if 0 SSTRINGS args; args.add (glocal.command); args.add ("--subject"); args.add (m->subject); args.add ("--from"); args.add (m->from.getfirstaddr()); args.add ("--replyto"); args.add (m->reply.getfirstaddr()); for (int j=0; jget()); } const char *tb[args.getnb()+1]; for (int j=0; jget(); } tb[args.getnb()] = NULL; forkexecvp (glocal.command,tb); #else SSTRING args; args.appendf ("--from %s",m->from.getfirstaddr()); args.appendf (" --replyto \"%s\"",m->reply.getfirstaddr()); for (int j=0; jget()); } glocal MAIL_MESSAGE *m = m; (glocal.command,args.get(),true); bool ok = false; SSTRINGS words; str_splitline (line,' ',words); if (words.getnb()==3){ const char *cmd = words.getitem(0)->get(); const char *arg1 = words.getitem(1)->get(); const char *arg2 = words.getitem(2)->get(); if (strcmp(cmd,"setvar")==0){ glocal.m->flags.set_str (arg1,arg2); glocal.m->setmodified(); ok = true; } } if (!ok){ tlmp_error (MSG_U(E_WALKERR,"Command %s produced this line: %s\n") ,glocal.command,line); } return 0; return 0; #endif } } // if (glocal.delet && !glocal.test) fl_in->update (true); f->decrusage(); folders_free (); } } } return ret; return ret; }