2 messages in net.sourceforge.lists.courier-maildrop[maildropl] maildrop xfilterz feature
FromSent OnAttachments
Dvorkin DmitryDec 10, 2007 5:23 am.patch
Devin RubiaDec 10, 2007 11:36 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[maildropl] maildrop xfilterz featureActions...
From:Dvorkin Dmitry (dvor@tvcom.ru)
Date:Dec 10, 2007 5:23:35 am
List:net.sourceforge.lists.courier-maildrop
Attachments:

Hello, everybody!

When I built my SMTP (qmail-based), I found the way of making temporary files for clamdscan processing is too strange. I don't like temporary files or any scripting language for e-mail pipe preprocessing during local delivery so I created a patch. As you know, clamdscan can read a letter from STDIN, but wan't pipe it out to STDOUT. "xfilter" waits for it... but it get's nothing. I added "xfilterz" lex to the maildrop commands specially for NO-OUT-e-mail processors. It only checks for RETURNCODE. The patch is simple.

-- Солдатов Дмитрий Ведущий специалист НИОКР ОАО "ТелеNet" Тел.: +7(4822)456784 E-mail: dvor@tvcom.ru

diff -rcs ./maildrop-2.0.4/maildrop/filter.C
./maildrop-2.0.4.dv/maildrop/filter.C *** ./maildrop-2.0.4/maildrop/filter.C 2006-09-20 05:41:58.000000000 +0400 --- ./maildrop-2.0.4.dv/maildrop/filter.C 2007-12-02 12:22:00.000000000 +0300 *************** *** 33,46 **** // ///////////////////////////////////////////////////////////////////////////

! int xfilter(const char *, int); ! ! int filter(const char *filtercmd) { try { ! int rc=xfilter(filtercmd, 0);

if (rc == 0) { Message *ptr=maildrop.savemsgptr; --- 33,55 ---- // ///////////////////////////////////////////////////////////////////////////

! // by Dv ! //int xfilter(const char *, int); ! int xfilter(const char *, int, int _noread); ! // by Dv end ! ! // by Dv ! //int filter(const char *filtercmd) ! int filter(const char *filtercmd, int _noread) ! // by Dv end { try { ! int rc=xfilter(filtercmd, 0, _noread);

+ // by Dv + // if (rc == 0 && _noread == 0) + // by Dv end if (rc == 0) { Message *ptr=maildrop.savemsgptr; *************** *** 60,66 **** } }

! int xfilter(const char *filtercmd, int ignorewerr) { FormatMbox format_mbox; char buffer[1024]; --- 69,78 ---- } }

! // by Dv ! //int xfilter(const char *filtercmd, int ignorewerr) ! int xfilter(const char *filtercmd, int ignorewerr, int _noread) ! // by Dv end { FormatMbox format_mbox; char buffer[1024]; *************** *** 171,177 **** --- 183,194 ---- } }

+ // by Dv int n=select(maxfd, &readfd, &writefd, NULL, NULL); + // int n; + // if ( _noread == 0) n=select(maxfd, &readfd, &writefd, NULL, NULL); + // if ( _noread == 1) n=select(maxfd, NULL, &writefd, NULL, NULL); + // by Dv end

if (n < 0) { *************** *** 183,188 **** --- 200,208 ---- if (pipe0.fds[1] >= 0 && FD_ISSET(pipe0.fds[1], &writefd)) { int n= ::write(pipe0.fds[1], writebufptr, writebuflen); + // by Dv + if ( _noread == 1) maildrop.savemsgptr->Init(writebufptr, writebuflen); + // by Dv end

if (n < 0) { *************** *** 206,215 **** --- 226,247 ---- } }

+ // by Dv + // if ( _noread != 1 && FD_ISSET(pipe1.fds[0], &readfd)) + // by Dv end if (FD_ISSET(pipe1.fds[0], &readfd)) { int readbuflen=::read(pipe1.fds[0], buffer, sizeof(buffer));

+ // by Dv + if ( _noread == 1 && readbuflen < 0 && errno != EINTR) { + merr << "maildrop: error reading from filter.\n"; + errflag=1; + break; } + if ( _noread == 1 && readbuflen < 0) continue; + if ( _noread == 1 && readbuflen == 0) break; + if ( _noread == 1) continue; + // by Dv end if (readbuflen < 0) { if (errno != EINTR) *************** *** 255,260 **** --- 287,295 ---- SetVar(name, val); }

+ // by Dv + if ( _noread == 1) return( 0); + // by Dv end if (wait_stat) return (-1); return (0); diff -rcs ./maildrop-2.0.4/maildrop/funcs.h ./maildrop-2.0.4.dv/maildrop/funcs.h *** ./maildrop-2.0.4/maildrop/funcs.h 1999-03-31 11:30:03.000000000 +0400 --- ./maildrop-2.0.4.dv/maildrop/funcs.h 2007-11-29 13:16:36.000000000 +0300 *************** *** 20,26 **** #define VerboseLevel() maildrop.verbose_level const char *GetDefaultMailbox(const char *); int delivery(const char *); ! int filter(const char *); void subshell(const char *); const char *TempName(); // Return temporary filename const char *TempName(const char *, unsigned=0); // ... with this prefix. --- 20,29 ---- #define VerboseLevel() maildrop.verbose_level const char *GetDefaultMailbox(const char *); int delivery(const char *); ! // by Dv ! //int filter(const char *); ! int filter(const char *, int _noread); ! // by Dv end void subshell(const char *); const char *TempName(); // Return temporary filename const char *TempName(const char *, unsigned=0); // ... with this prefix. diff -rcs ./maildrop-2.0.4/maildrop/lexer.C ./maildrop-2.0.4.dv/maildrop/lexer.C *** ./maildrop-2.0.4/maildrop/lexer.C 2004-01-15 06:12:13.000000000 +0300 --- ./maildrop-2.0.4.dv/maildrop/lexer.C 2007-11-29 11:25:40.000000000 +0300 *************** *** 41,46 **** --- 41,49 ---- case Token::tokencc: case Token::btstring: case Token::tokenxfilter: + // by Dv + case Token::tokenxfilterz: + // by Dv end case Token::dotlock: case Token::flock: case Token::logfile: *************** *** 344,349 **** --- 347,356 ---- t.Type(Token::echo); else if (pattern == "xfilter") t.Type(Token::tokenxfilter); + // by Dv + else if (pattern == "xfilterz") + t.Type(Token::tokenxfilterz); + // by Dv end else if (pattern == "dotlock") t.Type(Token::dotlock); else if (pattern == "flock") diff -rcs ./maildrop-2.0.4/maildrop/recipenode.C
./maildrop-2.0.4.dv/maildrop/recipenode.C *** ./maildrop-2.0.4/maildrop/recipenode.C 2004-06-26 19:20:14.000000000 +0400 --- ./maildrop-2.0.4.dv/maildrop/recipenode.C 2007-12-01 21:27:56.000000000
+0300 *************** *** 21,27 ****

static const char rcsid[]="$Id: recipenode.C,v 1.26 2004/04/24 19:50:18 mrsam
Exp $";

! extern int xfilter(const char *, int);

static void parse_backslash(const Buffer &, Buffer &);

--- 21,30 ----

static const char rcsid[]="$Id: recipenode.C,v 1.26 2004/04/24 19:50:18 mrsam
Exp $";

! // by Dv ! //extern int xfilter(const char *, int); ! extern int xfilter(const char *, int, int _noread); ! // by Dv end

static void parse_backslash(const Buffer &, Buffer &);

*************** *** 59,65 **** lastChild=chld; }

! void RecipeNode::Evaluate(Recipe &r, Buffer &b) { RecipeNode *c;

--- 62,71 ---- lastChild=chld; }

! // by Dv ! //void RecipeNode::Evaluate(Recipe &r, Buffer &b) ! void RecipeNode::Evaluate(Recipe &r, Buffer &b, int _noread) ! // by Dv end { RecipeNode *c;

*************** *** 70,83 **** for (c=firstChild; c; c=c->nextSibling) { b.reset(); ! c->Evaluate(r, b); } break; case assignment: if (!firstChild || !firstChild->nextSibling || firstChild->nodeType != qstring) throw "Internal error in assignment."; ! firstChild->nextSibling->Evaluate(r, b); if (VerboseLevel() > 3) { Buffer s; --- 76,95 ---- for (c=firstChild; c; c=c->nextSibling) { b.reset(); ! // by Dv ! // c->Evaluate(r, b); ! c->Evaluate(r, b, _noread); ! // by Dv end } break; case assignment: if (!firstChild || !firstChild->nextSibling || firstChild->nodeType != qstring) throw "Internal error in assignment."; ! // by Dv ! // firstChild->nextSibling->Evaluate(r, b); ! firstChild->nextSibling->Evaluate(r, b, _noread); ! // by Dv if (VerboseLevel() > 3) { Buffer s; *************** *** 97,103 **** case qstring: case sqstring: case btstring: ! EvaluateString(r, b); break; case add: case subtract: --- 109,118 ---- case qstring: case sqstring: case btstring: ! // by Dv ! // EvaluateString(r, b); ! EvaluateString(r, b, _noread); ! // by Dv end break; case add: case subtract: *************** *** 381,386 **** --- 396,402 ---- debug += '\0'; r.errmsg(*this, debug); } + firstChild->nextSibling->Evaluate(r, b); } if (VerboseLevel() > 5) *************** *** 614,623 **** if (VerboseLevel() > 0) merr << "maildrop: Filtering through xfilter " << (const char *)b << "\n"; ! if (filter(b) < 0) throw "Unable to filter message."; b = "0"; break; case exception: if (!firstChild) throw "Internal error in delivery statement."; --- 630,657 ---- if (VerboseLevel() > 0) merr << "maildrop: Filtering through xfilter " << (const char *)b << "\n"; ! // by Dv ! // if (filter(b) < 0) ! // throw "Unable to filter message."; ! if (filter(b,0) < 0) throw "Unable to filter message."; + // by Dv end + b = "0"; + break; + // by Dv + case xfilterz: + if (!firstChild) + throw "Internal error in xfilterz statement."; + firstChild->Evaluate(r,b,1); + b += '\0'; + if (VerboseLevel() > 0) + merr << "maildrop: Filtering through xfilterz " << + (const char *)b << "\n"; + if (filter(b,1) < 0) + throw "Unable to filterz message."; b = "0"; break; + // by Dv end case exception: if (!firstChild) throw "Internal error in delivery statement."; *************** *** 1188,1194 **** buf1.Length(i); }

! void RecipeNode::EvaluateString(Recipe &r, Buffer &b) { Buffer buf;

--- 1222,1231 ---- buf1.Length(i); }

! // by Dv ! //void RecipeNode::EvaluateString(Recipe &r, Buffer &b) ! void RecipeNode::EvaluateString(Recipe &r, Buffer &b, int _noread) ! // by Dv end { Buffer buf;

*************** *** 1209,1215 **** (const char *)buf << "`\n"; try { ! int rc=::xfilter(buf, 1); int l=0;

if (rc < 0) --- 1246,1255 ---- (const char *)buf << "`\n"; try { ! // by Dv ! // int rc=::xfilter(buf, 1); ! int rc=::xfilter(buf, 1, _noread); ! // by Dv end int l=0;

if (rc < 0) diff -rcs ./maildrop-2.0.4/maildrop/recipenode.h
./maildrop-2.0.4.dv/maildrop/recipenode.h *** ./maildrop-2.0.4/maildrop/recipenode.h 2004-01-15 06:12:13.000000000 +0300 --- ./maildrop-2.0.4.dv/maildrop/recipenode.h 2007-12-01 21:22:36.000000000
+0300 *************** *** 98,103 **** --- 98,106 ---- exception, echo, xfilter, + // by Dv + xfilterz, + // by Dv end dotlock, flock, logfile, *************** *** 122,131 ****

RecipeNode(RecipeNodeType); ~RecipeNode() {} ! void Evaluate(Recipe &, Buffer &); private: void AppendSibling(RecipeNode *); ! void EvaluateString(Recipe &r, Buffer &b);

void EvaluateStrRegExp(Recipe &, Buffer &, Buffer *); void EvaluateRegExp(Recipe &, Buffer &, Buffer *); --- 125,140 ----

RecipeNode(RecipeNodeType); ~RecipeNode() {} ! // by Dv ! // void Evaluate(Recipe &, Buffer &); ! void Evaluate(Recipe &, Buffer &, int _noread = 0); ! // by Dv end private: void AppendSibling(RecipeNode *); ! // by Dv ! // void EvaluateString(Recipe &r, Buffer &b); ! void EvaluateString(Recipe &r, Buffer &b, int _noread = 0); ! // by Dv end

void EvaluateStrRegExp(Recipe &, Buffer &, Buffer *); void EvaluateRegExp(Recipe &, Buffer &, Buffer *); diff -rcs ./maildrop-2.0.4/maildrop/recipeparse.C
./maildrop-2.0.4.dv/maildrop/recipeparse.C *** ./maildrop-2.0.4/maildrop/recipeparse.C 2004-01-15 06:12:13.000000000 +0300 --- ./maildrop-2.0.4.dv/maildrop/recipeparse.C 2007-12-01 21:38:59.000000000
+0300 *************** *** 168,173 **** --- 168,183 ---- throw "Syntax error."; lex->token(cur_tok); return (n); + // by Dv + case Token::tokenxfilterz: + lex->token(cur_tok); + n=alloc(RecipeNode::xfilterz); + n->AppendSibling( ParseExpr()); + if (cur_tok.Type() != Token::semicolon) + throw "Syntax error."; + lex->token(cur_tok); + return (n); + // by Dv end case Token::dotlock: lex->token(cur_tok); n=alloc(RecipeNode::dotlock); diff -rcs ./maildrop-2.0.4/maildrop/token.C ./maildrop-2.0.4.dv/maildrop/token.C *** ./maildrop-2.0.4/maildrop/token.C 2004-01-15 06:12:13.000000000 +0300 --- ./maildrop-2.0.4.dv/maildrop/token.C 2007-11-29 11:26:01.000000000 +0300 *************** *** 49,54 **** --- 49,57 ---- "exception", "echo", "xfilter", + // by Dv + "xfilterz", + // by Dv end "dotlock", "flock", "logfile", diff -rcs ./maildrop-2.0.4/maildrop/token.h ./maildrop-2.0.4.dv/maildrop/token.h *** ./maildrop-2.0.4/maildrop/token.h 2004-01-15 06:12:13.000000000 +0300 --- ./maildrop-2.0.4.dv/maildrop/token.h 2007-11-29 11:26:55.000000000 +0300 *************** *** 65,70 **** --- 65,73 ---- exception, echo, tokenxfilter, + // by Dv + tokenxfilterz, + // by Dv end dotlock, flock, logfile,