From: Tom C. <tom...@us...> - 2004-11-27 17:18:20
|
Update of /cvsroot/qmailadmin/qmailadmin In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12690 Modified Files: Tag: stable-1_2 ChangeLog template.c user.c user.h Log Message: Vacation now delivers first, then sends response. Wrote new code to parse .qmail file, works with new vacation .qmail format and allows for future flexibility. Index: user.c =================================================================== RCS file: /cvsroot/qmailadmin/qmailadmin/user.c,v retrieving revision 1.11.2.5 retrieving revision 1.11.2.6 diff -u -d -r1.11.2.5 -r1.11.2.6 --- user.c 20 Nov 2004 01:10:41 -0000 1.11.2.5 +++ user.c 27 Nov 2004 17:18:06 -0000 1.11.2.6 @@ -933,14 +933,16 @@ /* open the .qmail file */ snprintf(NewBuf,sizeof(NewBuf),"%s/.qmail", vpw->pw_dir); fs = fopen(NewBuf,"w+"); - fprintf(fs, "| %s/autorespond 86400 3 %s/vacation/message %s/vacation\n", - AUTORESPOND_PATH, vpw->pw_dir, vpw->pw_dir ); /* save a copy for the user (if checking for spam, it will keep a copy)*/ if(spam_check==1) fprintf(fs, "%s\n", SPAM_COMMAND); else fprintf(fs,"%s/" MAILDIR "/\n", vpw->pw_dir); + + fprintf(fs, "| %s/autorespond 86400 3 %s/vacation/message %s/vacation\n", + AUTORESPOND_PATH, vpw->pw_dir, vpw->pw_dir ); + fclose(fs); /* set up the message file */ @@ -989,3 +991,180 @@ call_hooks(HOOK_MODUSER, ActionUser, Domain, Password1, Gecos); moduser(); } + +/* display ##i0 - ##i9 macros */ +void parse_users_dotqmail (char newchar) +{ + static struct vqpasswd *vpw = NULL; + static FILE *fs1=NULL; /* for the .qmail file */ + static FILE *fs2=NULL; /* for the vacation message file */ + int i; + char fn[500]; + char linebuf[256]; + int inheader; + + static unsigned int dotqmail_flags = 0; +#define DOTQMAIL_STANDARD (1<<0) +#define DOTQMAIL_FORWARD (1<<1) +#define DOTQMAIL_SAVECOPY (1<<3) +#define DOTQMAIL_VACATION (1<<4) +#define DOTQMAIL_BLACKHOLE (1<<8) +#define DOTQMAIL_SPAMCHECK (1<<9) +#define DOTQMAIL_OTHERPGM (1<<14) + + + if (vpw == NULL) vpw = vauth_getpw(ActionUser, Domain); + if (vpw == NULL) return; + + if (fs1 == NULL) { + + snprintf (fn, sizeof(fn), "%s/.qmail", vpw->pw_dir); + fs1 = fopen (fn, "r"); + if (fs1 == NULL) { + /* no .qmail file, standard delivery */ + dotqmail_flags = DOTQMAIL_STANDARD; + } else { + while (fgets (linebuf, sizeof(linebuf), fs1) != NULL) { + i = strlen (linebuf); + /* strip trailing newline if any */ + if (i && linebuf[i-1] == '\n') linebuf[i-1] = '\0'; + + switch (*linebuf) { + case '\0': /* blank line, ignore */ + break; + + case '/': /* maildir delivery */ + /* see if it's the user's maildir */ + if (1) + dotqmail_flags |= DOTQMAIL_SAVECOPY; + break; + + case '|': /* program delivery */ + /* in older versions of QmailAdmin, we used "|/bin/true delete" + * for blackhole accounts. Since the path to true may vary, + * just check for the end of the string + */ + if (strstr (linebuf, "/true delete") != NULL) + dotqmail_flags |= DOTQMAIL_BLACKHOLE; + + else if (strstr (linebuf, "/autorespond ") != NULL) { + dotqmail_flags |= DOTQMAIL_VACATION; + snprintf (fn, sizeof(fn), "%s/vacation/message", vpw->pw_dir); + fs2 = fopen (fn, "r"); + } + + else if (strstr (linebuf, SPAM_COMMAND) != NULL ) + dotqmail_flags |= DOTQMAIL_SPAMCHECK; + + else /* unrecognized program delivery, set a flag so we don't blackhole */ + dotqmail_flags |= DOTQMAIL_OTHERPGM; + + break; + + case '#': /* comment */ + /* ignore unless it's our 'blackhole' comment */ + if (strcmp (linebuf, "# delete") == 0) + dotqmail_flags |= DOTQMAIL_BLACKHOLE; + break; + + default: /* email address delivery */ + dotqmail_flags |= DOTQMAIL_FORWARD; + + } + } + + /* if other flags were set, in addition to blackhole, clear blackhole flag */ + if (dotqmail_flags & ~DOTQMAIL_BLACKHOLE) + dotqmail_flags &= ~DOTQMAIL_BLACKHOLE; + + /* if no flags were set (.qmail file without delivery), it's a blackhole */ + if (dotqmail_flags == 0) + dotqmail_flags = DOTQMAIL_BLACKHOLE; + + /* if unrecognized programs were all that was set, consider it standard */ + if (dotqmail_flags == DOTQMAIL_OTHERPGM) + dotqmail_flags = DOTQMAIL_STANDARD; + + /* clear OTHERPGM flag, as it tells us nothing at this point */ + dotqmail_flags &= ~DOTQMAIL_OTHERPGM; + + /* if forward and save-a-copy are set, it will actually set the spam flag? */ + if ((dotqmail_flags & DOTQMAIL_FORWARD) && (dotqmail_flags & DOTQMAIL_SPAMCHECK)) + dotqmail_flags |= DOTQMAIL_SAVECOPY; + + /* if vacation is set, it will set save a copy as well, so we clear it */ + if (dotqmail_flags & DOTQMAIL_VACATION) + dotqmail_flags &= ~DOTQMAIL_SAVECOPY; + } + + /* if only spam detection was set, it's standard delivery */ + /* default to standard delivery */ + if (! (dotqmail_flags & ~DOTQMAIL_SPAMCHECK)) + dotqmail_flags |= DOTQMAIL_STANDARD; + } + + switch (newchar) { + case '0': /* standard delivery checkbox */ + case '1': /* forward delivery checkbox */ + case '3': /* save-a-copy checkbox */ + case '4': /* vacation checkbox */ + case '8': /* blackhole checkbox */ + case '9': /* spam check checkbox */ + if (dotqmail_flags & (1 << (newchar - '0'))) printf ("checked "); + break; + + case '2': /* forwarding addresses */ + if (fs1 != NULL) { + rewind (fs1); + i = 0; + while (fgets (linebuf, sizeof(linebuf), fs1) != NULL) { + switch (*linebuf) { + case '\0': /* blank line */ + case '/': /* maildir delivery */ + case '|': /* program delivery */ + case '#': /* comment */ + /* ignore */ + break; + + default: /* email address delivery */ + /* print address, skipping over '&' if necessary and removing newline */ + if (i++) printf (", "); + printh ("%H", strtok(&linebuf[(*linebuf == '&' ? 1 : 0)], "\n")); + } + } + } + break; + + case '5': /* vacation subject */ + if (fs2 != NULL) { + rewind (fs2); + + /* scan headers for Subject */ + while (fgets (linebuf, sizeof(linebuf), fs2) != NULL) { + if (*linebuf == '\n') break; + if (strncasecmp (linebuf, "Subject: ", 9) == 0) + printh ("%H", &linebuf[9]); + } + } + break; + + case '6': /* vacation message */ + if (fs2 != NULL) { + rewind (fs2); + + /* read from file, skipping headers (look for first blank line) */ + inheader = 1; + while (fgets (linebuf, sizeof(linebuf), fs2) != NULL) { + if (!inheader) printh ("%H", linebuf); + if (*linebuf == '\n') inheader = 0; + } + } + break; + + case '7': /* gecos (real name) */ + printh ("%H", vpw->pw_gecos); + break; + } + +} + Index: template.c =================================================================== RCS file: /cvsroot/qmailadmin/qmailadmin/template.c,v retrieving revision 1.7.2.6 retrieving revision 1.7.2.7 diff -u -d -r1.7.2.6 -r1.7.2.7 --- template.c 20 Nov 2004 06:24:51 -0000 1.7.2.6 +++ template.c 27 Nov 2004 17:18:06 -0000 1.7.2.7 @@ -49,7 +49,6 @@ #include "util.h" static char dchar[4]; -void check_user_forward_vacation(char newchar); void check_mailbox_flags(char newchar); void transmit_block(FILE *fs); void ignore_to_end_tag(FILE *fs); @@ -278,7 +277,7 @@ /* check for user forward and forward/store vacation */ case 'i': - check_user_forward_vacation(fgetc(fs)); + parse_users_dotqmail( fgetc(fs) ); break; /* show mailbox flag status */ @@ -722,147 +721,6 @@ return; } -void check_user_forward_vacation(char newchar) -{ - static struct vqpasswd *vpw = NULL; - static FILE *fs1=NULL; /* for the .qmail file */ - static FILE *fs2=NULL; /* for the vacation message file */ - int i; - - if (vpw==NULL) vpw = vauth_getpw(ActionUser, Domain); - if (fs1== NULL) { - snprintf(NTmpBuf, sizeof(NTmpBuf), "%s/.qmail", vpw->pw_dir); - fs1 = fopen(NTmpBuf,"r"); - } - - if ( newchar=='7') { - printh ("%H", vpw->pw_gecos); - return; - } - - if (fs1 == NULL) { - if (newchar=='0'){ - printf("checked "); - } - return; - } - - /* start at the begingin if second time thru */ - rewind(fs1); - - if (fgets(NTmpBuf,sizeof(NTmpBuf),fs1)!=NULL) { - - /* if it is a forward to a program */ - if (strstr(NTmpBuf, "autorespond")!=NULL ) { - if (newchar=='4') { - printf("checked "); - } else if (newchar=='5') { - if (fs2 == NULL) { - snprintf(NTmpBuf, sizeof(NTmpBuf), "%s/vacation/message", vpw->pw_dir); - fs2 = fopen(NTmpBuf,"r"); - } - if (fs2 != NULL) { - rewind(fs2); - /* - * it's a hack, the second line always has - * the subject - */ - fgets(NTmpBuf,sizeof(NTmpBuf),fs2); - fgets(NTmpBuf,sizeof(NTmpBuf),fs2); - printh("%H", &NTmpBuf[9]); - } - } else if (newchar=='6') { - if (fs2 == NULL) { - snprintf(NTmpBuf, sizeof(NTmpBuf), "%s/vacation/message", vpw->pw_dir); - fs2 = fopen(NTmpBuf,"r"); - } - if (fs2 != NULL) { - rewind(fs2); - for(i = 0; i < 3 && fgets(NTmpBuf,sizeof(NTmpBuf),fs2) != NULL; ++i); - while (fgets(NTmpBuf,sizeof(NTmpBuf),fs2) != NULL) { - printf("%s", NTmpBuf); - } - } - } - - i = 0; - do { - if (newchar == '3' && (NTmpBuf[0] == '/' || - strstr(NTmpBuf, SPAM_COMMAND)!=NULL) ) { - printf("checked "); - return; - } - if ( newchar == '2' ) { - if (NTmpBuf[0]=='/') continue; - if (NTmpBuf[0]=='|') continue; - if ( i>0 ) printf(", "); - if (NTmpBuf[0]=='&') { - printh("%H", strtok(&NTmpBuf[1], "\n")); - } else { - printh("%H", NTmpBuf[0]); - } - ++i; - } - /* Jeff Hedlund (jef...@ma...) 28 May 2003 */ - /* i9: "checked" if spam filtering on */ - if ( newchar == '9' && strstr(NTmpBuf, SPAM_COMMAND)!=NULL ) { - printf("checked "); - return; - } - } while(fgets(NTmpBuf,sizeof(NTmpBuf),fs1) != NULL ); - - - return; - } else { - - /* James Raftery <ja...@no...>, 21 May 2003 */ - /* i8: "checked" if blackhole */ - if (strstr(NTmpBuf, " delete\n") != NULL) { - if (newchar == '8') { - printf("checked "); - } - return; - } - - if (newchar == '1' || newchar == '0') { - if(strstr(NTmpBuf, SPAM_COMMAND)!=NULL) { - if(newchar == '0') printf("checked "); - } else { - if(newchar == '1') printf("checked "); - } - return; - } - - i = 0; - do { - if (newchar == '3' && (NTmpBuf[0] == '/' || - strstr(NTmpBuf, SPAM_COMMAND)!=NULL)) { - printf("checked "); - return; - } - - if (newchar == '9' && strstr(NTmpBuf, SPAM_COMMAND)!=NULL ) { - printf("checked "); - return; - } - - if (newchar == '2') { - if (NTmpBuf[0]=='/') continue; - if (strstr(NTmpBuf, SPAM_COMMAND)!=NULL) continue; - if (i > 0) printf(", "); - if (NTmpBuf[0] == '&') { - printh("%H", strtok(&NTmpBuf[1], "\n")); - } else { - printh("%H", NTmpBuf); - } - ++i; - } - } while (fgets(NTmpBuf,sizeof(NTmpBuf),fs1) != NULL); - } - } - return; -} - void transmit_block(FILE *fs) { /* tests to see if text between ##tX and ##tt should be transmitted */ /* where X is a letter corresponding to one of the below values */ Index: user.h =================================================================== RCS file: /cvsroot/qmailadmin/qmailadmin/Attic/user.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -d -r1.1.2.1 -r1.1.2.2 --- user.h 20 Nov 2004 01:10:41 -0000 1.1.2.1 +++ user.h 27 Nov 2004 17:18:06 -0000 1.1.2.2 @@ -15,6 +15,7 @@ void moduser(); void modusergo(); void modusernow(); +void parse_users_dotqmail (char newchar); void setremotecatchall(); void setremotecatchallnow(); void show_users(char *Username, char *Domain, time_t Mytime); Index: ChangeLog =================================================================== RCS file: /cvsroot/qmailadmin/qmailadmin/ChangeLog,v retrieving revision 1.15.2.35 retrieving revision 1.15.2.36 diff -u -d -r1.15.2.35 -r1.15.2.36 --- ChangeLog 22 Nov 2004 16:04:10 -0000 1.15.2.35 +++ ChangeLog 27 Nov 2004 17:18:06 -0000 1.15.2.36 @@ -7,6 +7,10 @@ - Remove unnecessary name attributes in SUBMIT buttons. [869292] - When adding a mailing list, automatically subscribe the list owner and make them a moderator/remote admin. [892489] + - user.c: deliver mail to Maildir before sending vacation message + in order to prevent autorespond from losing messages. + - Move .qmail parsing code from template.c to user.c. Rewrite + for more flexibility and to allow new format for vacation. - configure.in: Compile with all warnings on. - Add header files: alias.h auth.h autorespond.h cgi.h command.h dotqmail.h forward.h limits.h mailinglist.h show.h template.h |