+ if (Verbose)
+ message(Arpa_Info, "aliased to %s", p);
+ a->q_flags |= QDONTSEND;
+ AliasLevel++;
+ sendto(p, 1);
+ AliasLevel--;
+}
+\f/*
+** INITALIASES -- initialize for aliasing
+**
+** Very different depending on whether we are running DBM or not.
+**
+** Parameters:
+** aliasfile -- location of aliases.
+** init -- if set and if DBM, initialize the DBM files.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** initializes aliases:
+** if DBM: opens the database.
+** if ~DBM: reads the aliases into the symbol table.
+*/
+
+# define DBMMODE 0666
+
+initaliases(aliasfile, init)
+ char *aliasfile;
+ bool init;
+{
+ char buf[MAXNAME];
+ struct stat stb;
+ time_t modtime;
+
+ /*
+ ** See if the DBM version of the file is out of date with
+ ** the text version. If so, go into 'init' mode automatically.
+ ** This only happens if our effective userid owns the DBM
+ ** version or if the mode of the database is 666 -- this
+ ** is an attempt to avoid protection problems. Note the
+ ** unpalatable hack to see if the stat succeeded.
+ */
+
+ if (stat(aliasfile, &stb) < 0)
+ return;
+# ifdef DBM
+ modtime = stb.st_mtime;
+ (void) strcpy(buf, aliasfile);
+ (void) strcat(buf, ".pag");
+ stb.st_ino = 0;
+ if ((stat(buf, &stb) < 0 || stb.st_mtime < modtime) && !init)
+ {
+ if (stb.st_ino != 0 &&
+ ((stb.st_mode & 0666) == 0666 || stb.st_uid == geteuid()))
+ {
+ init = TRUE;
+ if (Verbose)
+ message(Arpa_Info, "rebuilding alias database");
+ }
+ else
+ {
+ message(Arpa_Info, "Warning: alias database out of date");
+ }
+ }
+# endif DBM
+
+ /*
+ ** If initializing, create the new files.
+ ** We should lock the alias file here to prevent other
+ ** instantiations of sendmail from reading an incomplete
+ ** file -- or worse yet, doing a concurrent initialize.
+ */
+
+# ifdef DBM
+ if (init)
+ {
+ (void) strcpy(buf, aliasfile);
+ (void) strcat(buf, ".dir");
+ if (close(creat(buf, DBMMODE)) < 0)
+ {
+ syserr("cannot make %s", buf);
+ return;
+ }
+ (void) strcpy(buf, aliasfile);
+ (void) strcat(buf, ".pag");
+ if (close(creat(buf, DBMMODE)) < 0)
+ {
+ syserr("cannot make %s", buf);
+ return;
+ }
+ }
+
+ /*
+ ** Open and, if necessary, load the DBM file.
+ ** If running without DBM, load the symbol table.
+ */
+
+ dbminit(aliasfile);
+ if (init)
+ readaliases(aliasfile, TRUE);
+# else DBM
+ readaliases(aliasfile, init);
+# endif DBM
+}
+\f/*
+** READALIASES -- read and process the alias file.
+**
+** This routine implements the part of initaliases that occurs
+** when we are not going to use the DBM stuff.
+**
+** Parameters:
+** aliasfile -- the pathname of the alias file master.
+** init -- if set, initialize the DBM stuff.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Reads aliasfile into the symbol table.
+** Optionally, builds the .dir & .pag files.
+*/
+
+static
+readaliases(aliasfile, init)
+ char *aliasfile;
+ bool init;
+{
+ char line[BUFSIZ];
+ register char *p;
+ char *p2;
+ char *rhs;
+ bool skipping;
+ ADDRESS al, bl;
+ FILE *af;
+ int lineno;
+ register STAB *s;
+ int naliases, bytes, longest;
+
+ if ((af = fopen(aliasfile, "r")) == NULL)