📄 alias.c
字号:
dbmclose(); sleep(30);# ifdef NDBM dbminit(aliasfile);# endif NDBM } } else atcnt = 1; /* ** 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. */ modtime = stb.st_mtime; (void) strcpy(buf, aliasfile); (void) strcat(buf, ".pag"); stb.st_ino = 0; if (!init && (stat(buf, &stb) < 0 || stb.st_mtime < modtime || atcnt < 0)) { errno = 0; if (AutoRebuild && stb.st_ino != 0 && ((stb.st_mode & 0777) == 0666 || stb.st_uid == geteuid())) { init = TRUE; automatic = TRUE; message(Arpa_Info, "rebuilding alias database");#ifdef LOG if (LogLevel >= 7) syslog(LOG_INFO, "rebuilding alias database");#endif LOG } else {#ifdef LOG if (LogLevel >= 7) syslog(LOG_INFO, "alias database out of date");#endif LOG message(Arpa_Info, "Warning: alias database out of date"); } } /* ** If necessary, load the DBM file. ** If running without DBM, load the symbol table. */ if (init) {#ifdef LOG if (LogLevel >= 6) { extern char *username(); syslog(LOG_NOTICE, "alias database %srebuilt by %s", automatic ? "auto" : "", username()); }#endif LOG readaliases(aliasfile, TRUE, modtime); }# else DBM readaliases(aliasfile, init, modtime);# endif DBM}/*** 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.*/staticreadaliases(aliasfile, init, modtime) char *aliasfile; bool init; time_t modtime;{ register char *p; char *rhs; bool skipping; int naliases, bytes, longest; FILE *af; void (*oldsigint)(); ADDRESS al, bl; register STAB *s; char line[BUFSIZ]; if ((af = fopen(aliasfile, "r")) == NULL) {# ifdef DEBUG if (tTd(27, 1)) printf("Can't open %s\n", aliasfile);# endif errno = 0; NoAlias++; return; }# ifdef DBM /* see if someone else is rebuilding the alias file already */ if (flock(fileno(af), LOCK_EX | LOCK_NB) < 0 && errno == EWOULDBLOCK) { /* yes, they are -- wait until done and then return */ message(Arpa_Info, "Alias file is already being rebuilt"); if (OpMode != MD_INITALIAS) { /* wait for other rebuild to complete */ (void) flock(fileno(af), LOCK_EX); } (void) fclose(af); errno = 0; return; }# endif DBM /* ** If initializing, create the new DBM files, then reopen them ** in case they did not previously exist. */ if (init) { oldsigint = signal(SIGINT, SIG_IGN); (void) strcpy(line, aliasfile); (void) strcat(line, ".dir"); if (close(creat(line, DBMMODE)) < 0) { syserr("cannot make %s", line); (void) signal(SIGINT, oldsigint); return; } (void) strcpy(line, aliasfile); (void) strcat(line, ".pag"); if (close(creat(line, DBMMODE)) < 0) { syserr("cannot make %s", line); (void) signal(SIGINT, oldsigint); return; } if (dbminit(aliasfile)<0) { syserr("cannot open database %s",aliasfile); (void) signal(SIGINT, oldsigint); return; } } /* ** Read and interpret lines */ FileName = aliasfile; LineNumber = 0; naliases = bytes = longest = 0; skipping = FALSE; while (fgets(line, sizeof (line), af) != NULL) { int lhssize, rhssize; LineNumber++; p = index(line, '\n'); if (p != NULL) *p = '\0'; switch (line[0]) { case '#': case '\0': skipping = FALSE; continue; case ' ': case '\t': if (!skipping) syserr("Non-continuation line starts with space"); skipping = TRUE; continue; } skipping = FALSE; /* ** Process the LHS ** Find the final colon, and parse the address. ** It should resolve to a local name -- this will ** be checked later (we want to optionally do ** parsing of the RHS first to maximize error ** detection). */ for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) continue; if (*p++ != ':') { syserr("missing colon"); continue; } if (parseaddr(line, &al, 0, ':') == NULL) { syserr("illegal alias name"); continue; } loweraddr(&al); /* ** Process the RHS. ** 'al' is the internal form of the LHS address. ** 'p' points to the text of the RHS. */ rhs = p; for (;;) { register char c; if (init && CheckAliases) { /* do parsing & compression of addresses */ while (*p != '\0') { extern char *DelimChar; while (isspace(*p) || *p == ',') p++; if (*p == '\0') break; if (parseaddr(p, &bl, -1, ',') == NULL) usrerr("%s... bad address", p); p = DelimChar; } } else { p = &p[strlen(p)]; if (p[-1] == '\n') *--p = '\0'; } /* see if there should be a continuation line */ c = fgetc(af); if (!feof(af)) (void) ungetc(c, af); if (c != ' ' && c != '\t') break; /* read continuation line */ if (fgets(p, sizeof line - (p - line), af) == NULL) break; LineNumber++; } if (al.q_mailer != LocalMailer) { syserr("cannot alias non-local names"); continue; } /* ** Insert alias into symbol table or DBM file */ lhssize = strlen(al.q_user) + 1; rhssize = strlen(rhs) + 1;# ifdef DBM if (init) { DATUM key, content; key.dsize = lhssize; key.dptr = al.q_user; content.dsize = rhssize; content.dptr = rhs; store(key, content); free(al.q_user); al.q_user = NULL; } else# endif DBM { s = stab(al.q_user, ST_ALIAS, ST_ENTER); s->s_alias = newstr(rhs); } /* statistics */ naliases++; bytes += lhssize + rhssize; if (rhssize > longest) longest = rhssize; }# ifdef DBM if (init) { /* add the distinquished alias "@" */ DATUM key, value; char last_modified[16]; /* * Add the special NIS entries. We can do this * without harm even if this host is not itself a NIS * server. */ key.dptr = "YP_LAST_MODIFIED"; key.dsize = strlen(key.dptr); sprintf(last_modified,"%10.10d",modtime); value.dptr = last_modified; value.dsize = strlen(value.dptr); store(key, value); key.dptr = "YP_MASTER_NAME"; key.dsize = strlen(key.dptr); value.dptr = macvalue('w',CurEnv); value.dsize = strlen(value.dptr); store(key, value); key.dsize = 2; key.dptr = "@"; store(key, key); /* restore the old signal */ (void) signal(SIGINT, oldsigint); }# endif DBM /* closing the alias file drops the lock */ (void) fclose(af); CurEnv->e_to = NULL; FileName = NULL; message(Arpa_Info, "%d aliases, longest %d bytes, %d bytes total", naliases, longest, bytes);# ifdef LOG if (LogLevel >= 8) syslog(LOG_INFO, "%d aliases, longest %d bytes, %d bytes total", naliases, longest, bytes);# endif LOG}/*** FORWARD -- Try to forward mail**** This is similar but not identical to aliasing.**** Parameters:** user -- the name of the user who's mail we would like** to forward to. It must have been verified --** i.e., the q_home field must have been filled** in.** sendq -- a pointer to the head of the send queue to** put this user's aliases in.**** Returns:** none.**** Side Effects:** New names are added to send queues.*/forward(user, sendq) ADDRESS *user; ADDRESS **sendq;{ char buf[60]; extern bool safefile();# ifdef DEBUG if (tTd(27, 1)) printf("forward(%s)\n", user->q_paddr);# endif DEBUG if (user->q_mailer != LocalMailer || bitset(QBADADDR, user->q_flags)) return;# ifdef DEBUG if (user->q_home == NULL) syserr("forward: no home");# endif DEBUG /* good address -- look for .forward file in home */ define('z', user->q_home, CurEnv); expand("\001z/.forward", buf, &buf[sizeof buf - 1], CurEnv); if (!safefile(buf, user->q_uid, S_IREAD)) return; /* we do have an address to forward to -- do it */ include(buf, "forwarding", user, sendq);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -