23 messages in net.sourceforge.lists.courier-users[courier-users] Re: Does courier / ma...
FromSent OnAttachments
Mitch (WebCob)Jan 13, 2004 9:50 am 
Mitch (WebCob)Jan 13, 2004 9:56 am 
Mitch (WebCob)Jan 13, 2004 10:34 am 
Courier UserJan 13, 2004 10:55 am 
Mitch (WebCob)Jan 13, 2004 11:47 am 
RolandJan 13, 2004 12:15 pm 
RolandJan 13, 2004 12:20 pm 
Mitch (WebCob)Jan 13, 2004 12:37 pm 
Courier UserJan 13, 2004 12:45 pm 
Sam VarshavchikJan 13, 2004 4:33 pm 
RolandJan 13, 2004 4:51 pm 
Gordon MessmerJan 13, 2004 5:17 pm 
Courier UserJan 13, 2004 5:46 pm 
Mitch (WebCob)Jan 13, 2004 9:05 pm 
Mitch (WebCob)Jan 13, 2004 9:06 pm 
Sam VarshavchikJan 14, 2004 4:11 am 
Jon NelsonJan 14, 2004 5:45 am 
Courier UserJan 14, 2004 7:11 am 
Courier UserJan 14, 2004 7:20 am.patch
RolandJan 15, 2004 2:12 am 
Courier UserJan 15, 2004 2:55 am 
Mitch (WebCob)Jan 15, 2004 9:03 am 
Courier UserJan 15, 2004 11:55 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:[courier-users] Re: Does courier / maildrop unset SENDER if it's empty?Actions...
From:Courier User (cour@asfast.net)
Date:Jan 14, 2004 7:20:40 am
List:net.sourceforge.lists.courier-users
Attachments:

Jon Nelson <jnel@jamponi.net> writes:

I don't think I could have voiced it better myself. Mitch is absolutely right here when he says that empty ("") is *not* the same as non-existant. It may not make perfect sense for SENDER, but for other variables it may -- indeed, the mere presence (regardless of content) of the variable is enough for some programs.

Please, Sam, reconsider this code that seems to me to:

a) /not/ operate on the principle of least surprise (thanks, "Courier User"). b) /not/ follow common convention c) unintuitive d) it breaks a bunch of software

Adding the 'unset' directive would allow those people that rely on the current (broken, IMO) behavior to continue "unsetting" variables.

Attached is a patch to maildrop (in the 0.44.2.20031219 release of Courier) which implements the following features:

1. VAR=""

No longer unsets the variable, but simply sets it to an empty string, as does every other variable-setting language that I know of.

2. unset VAR

A new directive that completely removes the variable.

I've done a small amount of testing, and it seems OK, but please do your own testing, as well.

*** maildrop/lexer.C.save Wed Jan 14 09:31:21 2004 --- maildrop/lexer.C Wed Jan 14 09:32:29 2004 *************** *** 384,389 **** --- 384,391 ---- t.Type(Token::importtoken); else if (pattern == "-") // Hack t.Type(Token::minus); + else if (pattern == "unset") + t.Type(Token::unset); else t.Type(Token::qstring); return; *** maildrop/recipenode.C.save Wed Jan 14 09:27:59 2004 --- maildrop/recipenode.C Wed Jan 14 09:49:54 2004 *************** *** 1066,1071 **** --- 1066,1089 ---- b.append( (unsigned long)t ); } break; + case unset: + if (!firstChild) + throw "Internal error in unset statement."; + firstChild->Evaluate(r, b); + { + Buffer s; + + if (VerboseLevel() > 3) + { + s="unset "; + s += b; + s += '\0'; + r.errmsg(*this, s); + } + + UnsetVar(b); + } + break; } }

*** maildrop/recipenode.h.save Wed Jan 14 09:27:46 2004 --- maildrop/recipenode.h Wed Jan 14 09:48:48 2004 *************** *** 116,122 **** gdbmfetch, gdbmstore, timetoken, ! importtoken } nodeType;

RecipeNode(RecipeNodeType); --- 116,123 ---- gdbmfetch, gdbmstore, timetoken, ! importtoken, ! unset } nodeType;

RecipeNode(RecipeNodeType); *** maildrop/recipeparse.C.save Wed Jan 14 09:28:08 2004 --- maildrop/recipeparse.C Wed Jan 14 09:46:47 2004 *************** *** 235,240 **** --- 235,248 ---- throw "Syntax error."; lex->token(cur_tok); return (n); + case Token::unset: + lex->token(cur_tok); + n=alloc(RecipeNode::unset); + n->AppendSibling( ParseExpr()); + if (cur_tok.Type() != Token::semicolon) + throw "Syntax error."; + lex->token(cur_tok); + return (n); default: break; } *** maildrop/token.C.save Wed Jan 14 09:32:48 2004 --- maildrop/token.C Wed Jan 14 09:35:07 2004 *************** *** 67,73 **** "gdbmfetch", "gdbmstore", "time", ! "import" } ;

static Buffer namebuf; --- 67,74 ---- "gdbmfetch", "gdbmstore", "time", ! "import", ! "unset" } ;

static Buffer namebuf; *** maildrop/token.h.save Wed Jan 14 09:32:53 2004 --- maildrop/token.h Wed Jan 14 09:46:33 2004 *************** *** 84,89 **** --- 84,90 ---- gdbmstore, timetoken, importtoken, + unset, }; private: tokentype type; *** maildrop/varlist.C.save Wed Jan 14 09:15:22 2004 --- maildrop/varlist.C Wed Jan 14 09:22:41 2004 *************** *** 16,21 **** --- 16,52 ----

static Variable *varlist[101];

+ void UnsetVar(const Buffer &var) + { + int varlen=var.Length(); + unsigned n=0; + int i; + const char *p=var; + for (i=varlen; i; --i) + n = (n << 1) ^ (unsigned char)*p++; + + if (var.Length() == 7 && + strncmp( (const char *)var, "VERBOSE", 7) == 0) + { + maildrop.verbose_level=0; + } + + n %= sizeof(varlist)/sizeof(varlist[0]); + + Variable **v; + + for (v= &varlist[n]; *v; v= &(*v)->next) + if ( (*v)->name == var ) + { + Variable *vv= (*v); + + (*v)= vv->next; + delete vv; + break; + } + return; + } + void SetVar(const Buffer &var, const Buffer &value) { int varlen=var.Length(); *************** *** 34,55 **** }

n %= sizeof(varlist)/sizeof(varlist[0]); - - if (value.Length() == 0) // Delete variable - { - Variable **v; - - for (v= &varlist[n]; *v; v= &(*v)->next) - if ( (*v)->name == var ) - { - Variable *vv= (*v); - - (*v)= vv->next; - delete vv; - break; - } - return; - }

Variable *v;

--- 65,70 ---- *** maildrop/varlist.h.save Wed Jan 14 09:23:42 2004 --- maildrop/varlist.h Wed Jan 14 09:24:05 2004 *************** *** 9,14 **** --- 9,15 ----

class Buffer;

+ void UnsetVar(const Buffer &); void SetVar(const Buffer &, const Buffer &); const Buffer *GetVar(const Buffer &); const char *GetVarStr(const Buffer &);