X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsieve.c;h=cc3ad14a2d9920092b2b87223f722d5c73069973;hb=e4a89c47c2a7d9a9268f36728b4b4f1b028b17b1;hp=4301d1ab7d6520e6dab7b6b085af619c3bd2b37e;hpb=059ec3d9952740285fb1ebf47961b8aca2eb1b4a;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/sieve.c b/src/src/sieve.c index 4301d1ab7..cc3ad14a2 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/sieve.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */ +/* $Cambridge: exim/src/src/sieve.c,v 1.9 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Michael Haardt 2003,2004 */ +/* Copyright (c) Michael Haardt 2003-2005 */ /* See the file NOTICE for conditions of use and distribution. */ /* This code was contributed by Michael Haardt. */ @@ -32,8 +32,7 @@ /* The code is currently broken. */ #undef SUBADDRESS -/* Define this for development of the vacation Sieve extension. */ -/* The code is not yet finished. */ +/* Define this for the vacation Sieve extension. */ #define VACATION /* Must be >= 1 */ @@ -62,6 +61,8 @@ struct Sieve int vacation_ran; #endif uschar *vacation_directory; + const uschar *subaddress; + const uschar *useraddress; int require_copy; int require_iascii_numeric; }; @@ -631,7 +632,7 @@ static int compare(struct Sieve *filter, const struct String *needle, const stru { int r=0; -if ((filter_test != NULL && debug_selector != 0) || +if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) { debug_printf("String comparison (match "); @@ -728,7 +729,7 @@ switch (mt) break; } } -if ((filter_test != NULL && debug_selector != 0) || +if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) debug_printf(" Result %s\n",r?"true":"false"); return r; @@ -852,7 +853,7 @@ for (new_addr=*generated; new_addr; new_addr=new_addr->next) { if (Ustrcmp(new_addr->address,addr)==0 && (file ? testflag(new_addr, af_pfr|af_file) : 1)) { - if ((filter_test != NULL && debug_selector != 0) || (debug_selector & D_filter) != 0) + if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) { debug_printf("Repeated %s `%s' ignored.\n",file ? "fileinto" : "redirect", addr); } @@ -860,7 +861,7 @@ for (new_addr=*generated; new_addr; new_addr=new_addr->next) } } -if ((filter_test != NULL && debug_selector != 0) || (debug_selector & D_filter) != 0) +if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) { debug_printf("%s `%s'\n",file ? "fileinto" : "redirect", addr); } @@ -1712,10 +1713,8 @@ if (parse_identifier(filter,CUS "address")) case ADDRPART_LOCALPART: part=extracted_addr; part[domain-1]='\0'; break; case ADDRPART_DOMAIN: part=extracted_addr+domain; break; #ifdef SUBADDRESS - case ADDRPART_DETAIL: - part=NULL; + case ADDRPART_DETAIL: part=NULL; break; #endif - break; } *end_addr = saveend; @@ -2020,9 +2019,7 @@ else if (parse_identifier(filter,CUS "envelope")) case ADDRPART_LOCALPART: envelopeExpr=CUS "${local_part:$sender_address}"; break; case ADDRPART_DOMAIN: envelopeExpr=CUS "${domain:$sender_address}"; break; #ifdef SUBADDRESS - case ADDRPART_DETAIL: - envelopeExpr=CUS 0; - break; + case ADDRPART_DETAIL: envelopeExpr=CUS 0; break; #endif } } @@ -2032,8 +2029,8 @@ else if (parse_identifier(filter,CUS "envelope")) { case ADDRPART_ALL: envelopeExpr=CUS "$local_part_prefix$local_part$local_part_suffix@$domain"; break; #ifdef SUBADDRESS - case ADDRPART_USER: envelopeExpr=CUS "$local_part_prefix$local_part"; break; - case ADDRPART_DETAIL: envelopeExpr=CUS "$local_part_suffix"; break; + case ADDRPART_USER: envelopeExpr=filter->useraddress; break; + case ADDRPART_DETAIL: envelopeExpr=filter->subaddress; break; #endif case ADDRPART_LOCALPART: envelopeExpr=CUS "$local_part_prefix$local_part$local_part_suffix"; break; case ADDRPART_DOMAIN: envelopeExpr=CUS "$domain"; break; @@ -2102,7 +2099,7 @@ if (*filter->pc=='{') } else { - filter->errmsg=CUS "missing closing brace"; + filter->errmsg=CUS "expecting command or closing brace"; return -1; } } @@ -2374,7 +2371,7 @@ while (*filter->pc) int m; unsigned long days; - struct String *addresses=(struct String*)0; + struct String *addresses; struct String subject; int reason_is_mime; string_item *aliases; @@ -2395,6 +2392,7 @@ while (*filter->pc) filter->vacation_ran=1; } days=VACATION_MIN_DAYS>7 ? VACATION_MIN_DAYS : 7; + addresses=(struct String*)0; subject.character=(uschar*)0; subject.length=-1; aliases=NULL; @@ -2459,6 +2457,7 @@ while (*filter->pc) uschar *buffer; int buffer_capacity; struct String key; + struct String *a; md5 base; uschar digest[16]; uschar hexdigest[33]; @@ -2467,11 +2466,12 @@ while (*filter->pc) if (filter_personal(aliases,TRUE)) { + if (filter_test == FTEST_NONE) + { + /* ensure oncelog directory exists; failure will be detected later */ - /* ensure oncelog directory exists; failure will be detected later */ - - (void)directory_make(NULL, filter->vacation_directory, 0700, FALSE); - + (void)directory_make(NULL, filter->vacation_directory, 0700, FALSE); + } /* build oncelog filename */ key.character=(uschar*)0; @@ -2480,89 +2480,110 @@ while (*filter->pc) if (subject.length!=-1) key.character=string_cat(key.character,&capacity,&key.length,subject.character,subject.length); key.character=string_cat(key.character,&capacity,&key.length,reason_is_mime?US"1":US"0",1); key.character=string_cat(key.character,&capacity,&key.length,reason.character,reason.length); + if (addresses!=(struct String*)0) for (a=addresses; a->length!=-1; ++a) + { + key.character=string_cat(key.character,&capacity,&key.length,US":",1); + key.character=string_cat(key.character,&capacity,&key.length,a->character,a->length); + } md5_start(&base); md5_end(&base, key.character, key.length, digest); for (i = 0; i < 16; i++) sprintf(CS (hexdigest+2*i), "%02X", digest[i]); - capacity=Ustrlen(filter->vacation_directory); - start=capacity; - once=string_cat(filter->vacation_directory,&capacity,&start,US"/",1); - once=string_cat(once,&capacity,&start,hexdigest,33); - - /* process subject */ - - if (subject.length==-1) - { - expand_header(&subject,&str_subject); - while (subject.length>=4 && Ustrncmp(subject.character,"Re: ",4)==0) + if (filter_test != FTEST_NONE) { - subject.character+=4; - subject.length-=4; + debug_printf("Sieve: mail was personal, vacation file basename: %s\n", hexdigest); } - capacity=6; - start=6; - subject.character=string_cat(US"Auto: ",&capacity,&start,subject.character,subject.length); - subject.length=start; - } - - /* add address to list of generated addresses */ - - addr = deliver_make_addr(string_sprintf(">%.256s", sender_address), FALSE); - setflag(addr, af_pfr); - setflag(addr, af_ignore_error); - addr->next = *generated; - *generated = addr; - addr->reply = store_get(sizeof(reply_item)); - memset(addr->reply,0,sizeof(reply_item)); /* XXX */ - addr->reply->to = string_copy(sender_address); - /* Allocation is larger than neccessary, but enough even for split MIME words */ - buffer_capacity=16+4*subject.length; - buffer=store_get(buffer_capacity); - addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity); - addr->reply->oncelog=once; - addr->reply->once_repeat=days*86400; - - /* build body and MIME headers */ - - if (reason_is_mime) + else { - uschar *mime_body,*reason_end; + capacity=Ustrlen(filter->vacation_directory); + start=capacity; + once=string_cat(filter->vacation_directory,&capacity,&start,US"/",1); + once=string_cat(once,&capacity,&start,hexdigest,33); + once[start] = '\0'; + + /* process subject */ + + if (subject.length==-1) + { + expand_header(&subject,&str_subject); + while (subject.length>=4 && Ustrncmp(subject.character,"Re: ",4)==0) + { + subject.character+=4; + subject.length-=4; + } + capacity=6; + start=6; + subject.character=string_cat(US"Auto: ",&capacity,&start,subject.character,subject.length); + subject.length=start; + } + + /* add address to list of generated addresses */ + + addr = deliver_make_addr(string_sprintf(">%.256s", sender_address), FALSE); + setflag(addr, af_pfr); + setflag(addr, af_ignore_error); + addr->next = *generated; + *generated = addr; + addr->reply = store_get(sizeof(reply_item)); + memset(addr->reply,0,sizeof(reply_item)); /* XXX */ + addr->reply->to = string_copy(sender_address); + addr->reply->from = expand_string(US"$local_part@$domain"); + /* Allocation is larger than neccessary, but enough even for split MIME words */ + buffer_capacity=16+4*subject.length; + buffer=store_get(buffer_capacity); + addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity); + addr->reply->oncelog=once; + addr->reply->once_repeat=days*86400; + + /* build body and MIME headers */ + + if (reason_is_mime) + { + uschar *mime_body,*reason_end; #ifdef RFC_EOL - static const uschar nlnl[]="\r\n\r\n"; + static const uschar nlnl[]="\r\n\r\n"; #else - static const uschar nlnl[]="\n\n"; + static const uschar nlnl[]="\n\n"; #endif - for - ( - mime_body=reason.character,reason_end=reason.character+reason.length; - mime_body<(reason_end-sizeof(nlnl)-1) && memcmp(mime_body,nlnl,sizeof(nlnl)-1); - ++mime_body - ); - capacity = 0; - start = 0; - addr->reply->headers = string_cat(NULL,&capacity,&start,reason.character,mime_body-reason.character); - capacity = 0; - start = 0; - if (mime_bodyreply->text = string_cat(NULL,&capacity,&start,mime_body,reason_end-mime_body); + for + ( + mime_body=reason.character,reason_end=reason.character+reason.length; + mime_body<(reason_end-sizeof(nlnl)-1) && memcmp(mime_body,nlnl,sizeof(nlnl)-1); + ++mime_body + ); + capacity = 0; + start = 0; + addr->reply->headers = string_cat(NULL,&capacity,&start,reason.character,mime_body-reason.character); + addr->reply->headers[start] = '\0'; + capacity = 0; + start = 0; + if (mime_body+(sizeof(nlnl)-1)reply->text = string_cat(NULL,&capacity,&start,mime_body,reason_end-mime_body); + addr->reply->text[start] = '\0'; + } + else + { + struct String qp; + + capacity = 0; + start = reason.length; + addr->reply->headers = US"MIME-Version: 1.0\n" + "Content-Type: text/plain;\n" + "\tcharset=\"utf-8\"\n" + "Content-Transfer-Encoding: quoted-printable"; + addr->reply->text = quoted_printable_encode(&reason,&qp)->character; + } } - else + } + else if (filter_test != FTEST_NONE) { - struct String qp; - - capacity = 0; - start = reason.length; - addr->reply->headers = US"MIME-Version: 1.0\n" - "Content-Type: text/plain;\n" - "\tcharset=\"utf-8\"\n" - "Content-Transfer-Encoding: quoted-printable"; - addr->reply->text = quoted_printable_encode(&reason,&qp)->character; + debug_printf("Sieve: mail was not personal, vacation would ignore it\n"); } - } } } + else break; #endif - else break; } return 1; } @@ -2602,7 +2623,7 @@ filter->require_iascii_numeric=0; if (parse_white(filter)==-1) return -1; -if (exec && filter->vacation_directory != NULL) /* 2nd test added by PH */ +if (exec && filter->vacation_directory != NULL && filter_test == FTEST_NONE) { DIR *oncelogdir; struct dirent *oncelog; @@ -2661,7 +2682,7 @@ while (parse_identifier(filter,CUS "require")) #ifdef VACATION else if (eq_asciicase(check,&str_vacation,0)) { - if (filter->vacation_directory == NULL) + if (filter_test == FTEST_NONE && filter->vacation_directory == NULL) { filter->errmsg=CUS "vacation disabled"; return -1; @@ -2701,6 +2722,8 @@ Arguments: options controls whether various special things are allowed, and requests special actions (not currently used) sieve_vacation_directory where to store vacation "once" files + useraddress string expression for :user part of address + subaddress string expression for :subaddress part of address generated where to hang newly-generated addresses error where to pass back an error text @@ -2714,7 +2737,7 @@ Returns: FF_DELIVERED success, a significant action was taken int sieve_interpret(uschar *filter, int options, uschar *vacation_directory, - address_item **generated, uschar **error) + uschar *useraddress, uschar *subaddress, address_item **generated, uschar **error) { struct Sieve sieve; int r; @@ -2740,6 +2763,9 @@ else } } +sieve.useraddress = useraddress == NULL ? CUS "$local_part_prefix$local_part$local_part_suffix" : useraddress; +sieve.subaddress = subaddress; + #ifdef COMPILE_SYNTAX_CHECKER if (parse_start(&sieve,0,generated)==1) #else @@ -2771,7 +2797,7 @@ else } #ifndef COMPILE_SYNTAX_CHECKER -if (filter_test != NULL) printf("%s\n", (const char*) msg); +if (filter_test != FTEST_NONE) printf("%s\n", (const char*) msg); else debug_printf("%s\n", msg); #endif