📄 alias.c
字号:
isopen = map->map_class->map_open(map, O_RDONLY); } else {#ifdef LOG if (LogLevel > 3) syslog(LOG_INFO, "alias database %s out of date", buf);#endif /* LOG */ message("Warning: alias database %s out of date", buf); } } map->map_mflags &= ~MF_ALIASWAIT; return isopen;}/*** REBUILDALIASES -- rebuild the alias database.**** Parameters:** map -- the database to rebuild.** automatic -- set if this was automatically generated.**** Returns:** none.**** Side Effects:** Reads the text version of the database, builds the** DBM or DB version.*/rebuildaliases(map, automatic) register MAP *map; bool automatic;{ FILE *af; bool nolock = FALSE; sigfunc_t oldsigint; if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) return; /* try to lock the source file */ if ((af = fopen(map->map_file, "r+")) == NULL) { if ((errno != EACCES && errno != EROFS) || automatic || (af = fopen(map->map_file, "r")) == NULL) { int saveerr = errno; if (tTd(27, 1)) printf("Can't open %s: %s\n", map->map_file, errstring(saveerr)); if (!automatic) message("newaliases: cannot open %s: %s", map->map_file, errstring(saveerr)); errno = 0; return; } nolock = TRUE; message("warning: cannot lock %s: %s", map->map_file, errstring(errno)); } /* see if someone else is rebuilding the alias file */ if (!nolock && !lockfile(fileno(af), map->map_file, NULL, LOCK_EX|LOCK_NB)) { /* yes, they are -- wait until done */ message("Alias file %s is already being rebuilt", map->map_file); if (OpMode != MD_INITALIAS) { /* wait for other rebuild to complete */ (void) lockfile(fileno(af), map->map_file, NULL, LOCK_EX); } (void) xfclose(af, "rebuildaliases1", map->map_file); errno = 0; return; } oldsigint = setsignal(SIGINT, SIG_IGN); if (map->map_class->map_open(map, O_RDWR)) {#ifdef LOG if (LogLevel > 7) { syslog(LOG_NOTICE, "alias database %s %srebuilt by %s", map->map_file, automatic ? "auto" : "", username()); }#endif /* LOG */ map->map_mflags |= MF_OPEN|MF_WRITABLE; readaliases(map, af, automatic); } else { if (tTd(27, 1)) printf("Can't create database for %s: %s\n", map->map_file, errstring(errno)); if (!automatic) syserr("Cannot create database for alias file %s", map->map_file); } /* close the file, thus releasing locks */ xfclose(af, "rebuildaliases2", map->map_file); /* add distinguished entries and close the database */ if (bitset(MF_OPEN, map->map_mflags)) map->map_class->map_close(map); /* restore the old signal */ (void) setsignal(SIGINT, oldsigint);}/*** 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:** map -- the alias database descriptor.** af -- file to read the aliases from.** automatic -- set if this was an automatic rebuild.**** Returns:** none.**** Side Effects:** Reads aliasfile into the symbol table.** Optionally, builds the .dir & .pag files.*/readaliases(map, af, automatic) register MAP *map; FILE *af; int automatic;{ register char *p; char *rhs; bool skipping; long naliases, bytes, longest; ADDRESS al, bl; char line[BUFSIZ]; /* ** Read and interpret lines */ FileName = map->map_file; LineNumber = 0; naliases = bytes = longest = 0; skipping = FALSE; while (fgets(line, sizeof (line), af) != NULL) { int lhssize, rhssize; LineNumber++; p = strchr(line, '\n'); if (p != NULL) *p = '\0'; switch (line[0]) { case '#': case '\0': skipping = FALSE; continue; case ' ': case '\t': if (!skipping) syserr("554 Non-continuation line starts with space"); skipping = TRUE; continue; } skipping = FALSE; /* ** Process the LHS ** Find the colon separator, 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("554 missing colon"); continue; } if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv) == NULL) { syserr("554 %.40s... illegal alias name", line); continue; } /* ** Process the RHS. ** 'al' is the internal form of the LHS address. ** 'p' points to the text of the RHS. */ while (isascii(*p) && isspace(*p)) p++; rhs = p; for (;;) { register char c; register char *nlp; nlp = &p[strlen(p)]; if (nlp[-1] == '\n') *--nlp = '\0'; if (CheckAliases) { /* do parsing & compression of addresses */ while (*p != '\0') { auto char *delimptr; while ((isascii(*p) && isspace(*p)) || *p == ',') p++; if (*p == '\0') break; if (parseaddr(p, &bl, RF_COPYNONE, ',', &delimptr, CurEnv) == NULL) usrerr("553 %s... bad address", p); p = delimptr; } } else { p = nlp; } /* 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++; /* check for line overflow */ if (strchr(p, '\n') == NULL) { usrerr("554 alias too long"); break; } } if (al.q_mailer != LocalMailer) { syserr("554 %s... cannot alias non-local names", al.q_paddr); continue; } /* ** Insert alias into symbol table or DBM file */ if (!bitnset(M_USR_UPPER, al.q_mailer->m_flags)) makelower(al.q_user); lhssize = strlen(al.q_user); rhssize = strlen(rhs); map->map_class->map_store(map, al.q_user, rhs); if (al.q_paddr != NULL) free(al.q_paddr); if (al.q_host != NULL) free(al.q_host); if (al.q_user != NULL) free(al.q_user); /* statistics */ naliases++; bytes += lhssize + rhssize; if (rhssize > longest) longest = rhssize; } CurEnv->e_to = NULL; FileName = NULL; if (Verbose || !automatic) message("%s: %d aliases, longest %d bytes, %d bytes total", map->map_file, naliases, longest, bytes);# ifdef LOG if (LogLevel > 7) syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total", map->map_file, 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, e) ADDRESS *user; ADDRESS **sendq; register ENVELOPE *e;{ char *pp; char *ep; if (tTd(27, 1)) printf("forward(%s)\n", user->q_paddr); if (user->q_mailer != LocalMailer || bitset(QBADADDR, user->q_flags)) return; if (user->q_home == NULL) { syserr("554 forward: no home"); user->q_home = "/nosuchdirectory"; } /* good address -- look for .forward file in home */ define('z', user->q_home, e); define('u', user->q_user, e); define('h', user->q_host, e); if (ForwardPath == NULL) ForwardPath = newstr("\201z/.forward"); for (pp = ForwardPath; pp != NULL; pp = ep) { int err; char buf[MAXPATHLEN+1]; ep = strchr(pp, ':'); if (ep != NULL) *ep = '\0'; expand(pp, buf, &buf[sizeof buf - 1], e); if (ep != NULL) *ep++ = ':'; if (tTd(27, 3)) printf("forward: trying %s\n", buf); err = include(buf, TRUE, user, sendq, e); if (err == 0) break; else if (transienterror(err)) { /* we have to suspend this message */ if (tTd(27, 2)) printf("forward: transient error on %s\n", buf);#ifdef LOG if (LogLevel > 2) syslog(LOG_ERR, "%s: forward %s: transient error: %s", e->e_id == NULL ? "NOQUEUE" : e->e_id, buf, errstring(err));#endif message("%s: %s: message queued", buf, errstring(err)); user->q_flags |= QQUEUEUP; return; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -