diff options
author | gshapiro <gshapiro@FreeBSD.org> | 2001-01-21 22:17:06 +0000 |
---|---|---|
committer | gshapiro <gshapiro@FreeBSD.org> | 2001-01-21 22:17:06 +0000 |
commit | 167a83e7b8733416154f871e39e86ba77eb1554d (patch) | |
tree | 4f725bdbff499cf7343d2eaeec15f8a0f0926140 /contrib/sendmail/vacation/vacation.c | |
parent | f84ac9120cb7d9f087e5dcb863c4bf25ba2985e6 (diff) | |
download | FreeBSD-src-167a83e7b8733416154f871e39e86ba77eb1554d.zip FreeBSD-src-167a83e7b8733416154f871e39e86ba77eb1554d.tar.gz |
Import sendmail 8.11.2
Diffstat (limited to 'contrib/sendmail/vacation/vacation.c')
-rw-r--r-- | contrib/sendmail/vacation/vacation.c | 252 |
1 files changed, 171 insertions, 81 deletions
diff --git a/contrib/sendmail/vacation/vacation.c b/contrib/sendmail/vacation/vacation.c index dfc2a7d..8b85c38 100644 --- a/contrib/sendmail/vacation/vacation.c +++ b/contrib/sendmail/vacation/vacation.c @@ -21,7 +21,7 @@ static char copyright[] = #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Id: vacation.c,v 8.68.4.7 2000/09/05 21:48:45 gshapiro Exp $"; +static char id[] = "@(#)$Id: vacation.c,v 8.68.4.15 2000/11/27 22:17:27 ca Exp $"; #endif /* ! lint */ #include <ctype.h> @@ -48,6 +48,11 @@ static char id[] = "@(#)$Id: vacation.c,v 8.68.4.7 2000/09/05 21:48:45 gshapiro #define ONLY_ONCE ((time_t) 0) /* send at most one reply */ #define INTERVAL_UNDEF ((time_t) (-1)) /* no value given */ +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif /* ! TRUE */ + uid_t RealUid; gid_t RealGid; char *RealUserName; @@ -73,11 +78,6 @@ BITMAP256 DontBlameSendmail; #define SECSPERDAY (60 * 60 * 24) #define DAYSPERWEEK 7 -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif /* ! TRUE */ - #ifndef __P # ifdef __STDC__ # define __P(protos) protos @@ -111,7 +111,7 @@ static void eatmsg __P((void)); /* exit after reading input */ #define EXITIT(excode) { \ eatmsg(); \ - exit(excode); \ + return excode; \ } int main(argc, argv) @@ -138,7 +138,7 @@ main(argc, argv) extern char *optarg; extern void usage __P((void)); extern void setinterval __P((time_t)); - extern void readheaders __P((void)); + extern int readheaders __P((void)); extern bool recent __P((void)); extern void setreply __P((char *, time_t)); extern void sendmessage __P((char *, char *, bool)); @@ -348,7 +348,7 @@ main(argc, argv) static void listdb __P((void)); listdb(); - (void)Db->smdb_close(Db); + (void) Db->smdb_close(Db); exit(EX_OK); } #endif /* _FFR_LISTDB */ @@ -356,17 +356,16 @@ main(argc, argv) if (interval != INTERVAL_UNDEF) setinterval(interval); - if (iflag) + if (iflag && !exclude) { - result = Db->smdb_close(Db); - if (!exclude) - exit(EX_OK); + (void) Db->smdb_close(Db); + exit(EX_OK); } if (exclude) { xclude(stdin); - result = Db->smdb_close(Db); + (void) Db->smdb_close(Db); EXITM(EX_OK); } @@ -374,27 +373,28 @@ main(argc, argv) { msglog(LOG_NOTICE, "vacation: can't allocate memory for username.\n"); + (void) Db->smdb_close(Db); EXITM(EX_OSERR); } cur->name = name; cur->next = Names; Names = cur; - readheaders(); - if (!recent()) + result = readheaders(); + if (result == EX_OK && !recent()) { time_t now; (void) time(&now); setreply(From, now); - result = Db->smdb_close(Db); + (void) Db->smdb_close(Db); sendmessage(name, msgfilename, emptysender); } else - result = Db->smdb_close(Db); - exit(EX_OK); - /* NOTREACHED */ - return EX_OK; + (void) Db->smdb_close(Db); + if (result == EX_NOUSER) + result = EX_OK; + exit(result); } /* @@ -425,13 +425,14 @@ eatmsg() ** none. ** ** Returns: -** nothing. +** a exit code: NOUSER if no reply, OK if reply, * if error ** ** Side Effects: ** may exit(). ** */ -void + +int readheaders() { bool tome, cont; @@ -484,12 +485,12 @@ readheaders() /* ok since both strings have MAXLINE length */ if (*From == '\0') - (void)strlcpy(From, buf + 5, - sizeof From); + (void) strlcpy(From, buf + 5, + sizeof From); if ((p = strchr(buf + 5, '\n')) != NULL) *p = '\0'; if (junkmail(buf + 5)) - EXITIT(EX_OK); + EXITIT(EX_NOUSER); } break; @@ -509,7 +510,7 @@ readheaders() if (strncasecmp(p, "junk", 4) == 0 || strncasecmp(p, "bulk", 4) == 0 || strncasecmp(p, "list", 4) == 0) - EXITIT(EX_OK); + EXITIT(EX_NOUSER); break; case 'C': /* "Cc:" */ @@ -540,12 +541,13 @@ findme: } } if (!tome) - EXITIT(EX_OK); + EXITIT(EX_NOUSER); if (*From == '\0') { msglog(LOG_NOTICE, "vacation: no initial \"From \" line.\n"); EXITIT(EX_DATAERR); } + EXITIT(EX_OK); } /* @@ -600,52 +602,142 @@ nsearch(name, str) ** is this some automated/junk/bulk/list mail? ** */ + +struct ignore +{ + char *name; + size_t len; +}; + +typedef struct ignore IGNORE_T; + +#define MAX_USER_LEN 256 /* maximum length of local part (sender) */ + +/* delimiters for the local part of an address */ +#define isdelim(c) ((c) == '%' || (c) == '@' || (c) == '+') + bool junkmail(from) char *from; { - register size_t len; - register char *p; - register struct ignore *cur; - static struct ignore - { - char *name; - size_t len; - } ignore[] = + bool quot; + char *e; + size_t len; + IGNORE_T *cur; + char sender[MAX_USER_LEN]; + static IGNORE_T ignore[] = { - { "-request", 8 }, { "postmaster", 10 }, { "uucp", 4 }, { "mailer-daemon", 13 }, { "mailer", 6 }, + { NULL, 0 } + }; + + static IGNORE_T ignorepost[] = + { + { "-request", 8 }, { "-relay", 6 }, + { "-owner", 6 }, + { NULL, 0 } + }; + + static IGNORE_T ignorepre[] = + { + { "owner-", 6 }, { NULL, 0 } }; /* - * This is mildly amusing, and I'm not positive it's right; trying - * to find the "real" name of the sender, assuming that addresses - * will be some variant of: - * - * From site!site!SENDER%site.domain%site.domain@site.domain - */ - if ((p = strchr(from, '%')) == NULL && - (p = strchr(from, '@')) == NULL) + ** This is mildly amusing, and I'm not positive it's right; trying + ** to find the "real" name of the sender, assuming that addresses + ** will be some variant of: + ** + ** From site!site!SENDER%site.domain%site.domain@site.domain + */ + + quot = FALSE; + e = from; + len = 0; + while (*e != '\0' && (quot || !isdelim(*e))) { - if ((p = strrchr(from, '!')) != NULL) - ++p; - else - p = from; - for (; *p; ++p) + if (*e == '"') + { + quot = !quot; + ++e; continue; + } + if (*e == '\\') + { + if (*(++e) == '\0') + { + /* '\\' at end of string? */ + break; + } + if (len < MAX_USER_LEN) + sender[len++] = *e; + ++e; + continue; + } + if (*e == '!' && !quot) + { + len = 0; + sender[len] = '\0'; + } + else + if (len < MAX_USER_LEN) + sender[len++] = *e; + ++e; } - len = p - from; + if (len < MAX_USER_LEN) + sender[len] = '\0'; + else + sender[MAX_USER_LEN - 1] = '\0'; + + if (len <= 0) + return FALSE; +#if 0 + if (quot) + return FALSE; /* syntax error... */ +#endif /* 0 */ + + /* test prefixes */ + for (cur = ignorepre; cur->name != NULL; ++cur) + { + if (len >= cur->len && + strncasecmp(cur->name, sender, cur->len) == 0) + return TRUE; + } + + /* + ** If the name is truncated, don't test the rest. + ** We could extract the "tail" of the sender address and + ** compare it it ignorepost, however, it seems not worth + ** the effort. + ** The address surely can't match any entry in ignore[] + ** (as long as all of them are shorter than MAX_USER_LEN). + */ + + if (len > MAX_USER_LEN) + return FALSE; + + /* test full local parts */ for (cur = ignore; cur->name != NULL; ++cur) { + if (len == cur->len && + strncasecmp(cur->name, sender, cur->len) == 0) + return TRUE; + } + + /* test postfixes */ + for (cur = ignorepost; cur->name != NULL; ++cur) + { if (len >= cur->len && - strncasecmp(cur->name, p - cur->len, cur->len) == 0) + strncasecmp(cur->name, e - cur->len - 1, + cur->len) == 0) return TRUE; } + return FALSE; } @@ -675,27 +767,27 @@ recent() memset(&data, '\0', sizeof data); /* get interval time */ - key.data.data = VIT; - key.data.size = sizeof(VIT); + key.data = VIT; + key.size = sizeof(VIT); st = Db->smdb_get(Db, &key, &data, 0); if (st != SMDBE_OK) next = SECSPERDAY * DAYSPERWEEK; else - memmove(&next, data.data.data, sizeof(next)); + memmove(&next, data.data, sizeof(next)); memset(&data, '\0', sizeof data); /* get record for this address */ - key.data.data = From; - key.data.size = strlen(From); + key.data = From; + key.size = strlen(From); do { st = Db->smdb_get(Db, &key, &data, 0); if (st == SMDBE_OK) { - memmove(&then, data.data.data, sizeof(then)); + memmove(&then, data.data, sizeof(then)); if (next == ONLY_ONCE || then == ONLY_ONCE || then + next > time(NULL)) return TRUE; @@ -703,8 +795,8 @@ recent() if ((trydomain = !trydomain) && (domain = strchr(From, '@')) != NULL) { - key.data.data = domain; - key.data.size = strlen(domain); + key.data = domain; + key.size = strlen(domain); } } while (trydomain); return FALSE; @@ -732,11 +824,11 @@ setinterval(interval) memset(&key, '\0', sizeof key); memset(&data, '\0', sizeof data); - key.data.data = VIT; - key.data.size = sizeof(VIT); - data.data.data = (char*) &interval; - data.data.size = sizeof(interval); - (void)(Db->smdb_put)(Db, &key, &data, 0); + key.data = VIT; + key.size = sizeof(VIT); + data.data = (char*) &interval; + data.size = sizeof(interval); + (void) (Db->smdb_put)(Db, &key, &data, 0); } /* @@ -763,11 +855,11 @@ setreply(from, when) memset(&key, '\0', sizeof key); memset(&data, '\0', sizeof data); - key.data.data = from; - key.data.size = strlen(from); - data.data.data = (char*) &when; - data.data.size = sizeof(when); - (void)(Db->smdb_put)(Db, &key, &data, 0); + key.data = from; + key.size = strlen(from); + data.data = (char*) &when; + data.size = sizeof(when); + (void) (Db->smdb_put)(Db, &key, &data, 0); } /* @@ -932,28 +1024,26 @@ listdb() SMDB_CURSOR_GET_NEXT)) == SMDBE_OK) { /* skip magic VIT entry */ - if ((int)db_key.data.size -1 == strlen(VIT) && - strncmp((char *)db_key.data.data, VIT, - (int)db_key.data.size - 1) == 0) + if ((int)db_key.size -1 == strlen(VIT) && + strncmp((char *)db_key.data, VIT, + (int)db_key.size - 1) == 0) continue; /* skip bogus values */ - if (db_value.data.size != sizeof t) + if (db_value.size != sizeof t) { fprintf(stderr, "vacation: %.*s invalid time stamp\n", - (int) db_key.data.size, - (char *) db_key.data.data); + (int) db_key.size, (char *) db_key.data); continue; } - memcpy(&t, db_value.data.data, sizeof t); + memcpy(&t, db_value.data, sizeof t); - if (db_key.data.size > 40) - db_key.data.size = 40; + if (db_key.size > 40) + db_key.size = 40; printf("%-40.*s %-10s", - (int) db_key.data.size, (char *) db_key.data.data, - ctime(&t)); + (int) db_key.size, (char *) db_key.data, ctime(&t)); memset(&db_key, '\0', sizeof db_key); memset(&db_value, '\0', sizeof db_value); |