# include <pwd.h>
# include "dlvrmail.h"
-static char SccsId[] = "@(#)alias.c 1.3 %G%";
+static char SccsId[] = "@(#)alias.c 1.4 %G%";
/*
** ALIAS -- Compute aliases.
**
-** Scans the file /usr/lib/mailaliases for a set of aliases.
+** Scans the file ALIASFILE for a set of aliases.
** If found, it arranges to deliver to them by inserting the
-** new names onto the SendQ queue.
+** new names onto the SendQ queue. Uses libdbm database if -DDBM.
**
** Parameters:
** none
** where 'alias' expands to all of
** 'name[i]'. Continuations begin with
** space or tab.
+** ALIASFILE.pag, ALIASFILE.dir: libdbm version
+** of alias file. Keys are aliases, datums
+** (data?) are name1,name2, ...
**
** Notes:
** If NoAlias (the "-n" flag) is set, no aliasing is
# define ALIASFILE "/usr/lib/mailaliases"
# define MAXRCRSN 10
+#ifdef DBM
+typedef struct {char *dptr; int dsize;} datum;
+datum lhs, rhs;
+datum fetch();
+#endif DBM
alias()
{
# endif
/* open alias file if not already open */
+#ifndef DBM
# ifdef DEBUG
if (Debug && (af = fopen("mailaliases", "r")) != NULL)
printf(" [using local alias file]\n");
errno = 0;
return;
}
+#else DBM
+ dbminit(ALIASFILE);
+#endif DBM
+#ifndef DBM
/*
** Scan alias file.
** If we find any user that any line matches any user, we
** continuation lines.
*/
- didalias = TRUE;
- while (didalias)
+ do
{
didalias = FALSE;
gotmatch = FALSE;
{
if (gotmatch)
{
-# ifdef DEBUG
- if (Debug)
- printf(" ... also aliased to %s", line);
-# endif
sendto(line, 1);
}
continue;
}
if (q != NULL)
{
+#else DBM
+ /*
+ ** Scan SendQ
+ ** We pass through the queue several times. Didalias tells
+ ** us if we took some alias on this pass through the queue;
+ ** when it goes false at the top of the loop we don't have
+ ** to scan any more.
+ */
+
+ do
+ {
+ didalias = FALSE;
+ /* Scan SendQ for that canonical form. */
+ for (q = &SendQ; (q = nxtinq(q)) != NULL; )
+ {
+ lhs.dptr = q -> q_paddr;
+ lhs.dsize = strlen(lhs.dptr)+1;
+ rhs = fetch(lhs);
+ p = rhs.dptr;
+ if (p != NULL)
+ {
+#endif
/*
** Match on Alias.
** Deliver to the target list.
sendto(p, 1);
}
}
- }
+ } while (didalias);
+#ifndef DBM
fclose(af);
+#endif
}
\f/*
** FORWARD -- Try to forward mail
# include <log.h>
# endif LOG
-static char SccsId[] = "@(#)deliver.c 1.5 %G%";
+static char SccsId[] = "@(#)deliver.c 1.6 %G%";
/*
** DELIVER -- Deliver a message to a particular address.
syserr("pipe");
return (-1);
}
+# ifdef VFORK
+ pid = vfork();
+# else
pid = fork();
+# endif
if (pid < 0)
{
syserr("Cannot fork");
# ifdef LOG
initlog(NULL, 0, LOG_CLOSE);
# endif LOG
+# ifndef VFORK
+ /*
+ * We have to be careful with vfork - we can't mung up the
+ * memory but we don't want the mailer to inherit any extra
+ * open files. Chances are the mailer won't
+ * care about an extra file, but then again you never know.
+ * Actually, we would like to close(fileno(pwf)), but it's
+ * declared static so we can't. But if we fclose(pwf), which
+ * is what endpwent does, it closes it in the parent too and
+ * the next getpwnam will be slower. If you have a weird mailer
+ * that chokes on the extra file you should do the endpwent().
+ */
endpwent();
+# endif
execv(m->m_mailer, pvp);
/* syserr fails because log is closed */
/* syserr("Cannot exec %s", m->m_mailer); */