summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/vacation/vacation.c
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2001-01-21 22:17:06 +0000
committergshapiro <gshapiro@FreeBSD.org>2001-01-21 22:17:06 +0000
commit167a83e7b8733416154f871e39e86ba77eb1554d (patch)
tree4f725bdbff499cf7343d2eaeec15f8a0f0926140 /contrib/sendmail/vacation/vacation.c
parentf84ac9120cb7d9f087e5dcb863c4bf25ba2985e6 (diff)
downloadFreeBSD-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.c252
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);
OpenPOWER on IntegriCloud