📄 main.c
字号:
FullName = newstr(optarg); break; case 'h': /* hop count */ CurEnv->e_hopcount = strtol(optarg, &ep, 10); if (*ep) { usrerr("Bad hop count (%s)", optarg); ExitStat = EX_USAGE; break; } break; case 'n': /* don't alias */ NoAlias = TRUE; break; case 'o': /* set option */ setoption(*optarg, optarg + 1, FALSE, TRUE, CurEnv); break; case 'p': /* set protocol */ p = strchr(optarg, ':'); if (p != NULL) *p++ = '\0'; if (*optarg != '\0') define('r', newstr(optarg), CurEnv); if (p != NULL && *p != '\0') define('s', newstr(p), CurEnv); break; case 'q': /* run queue files at intervals */# ifdef QUEUE (void) unsetenv("HOSTALIASES"); FullName = NULL; queuemode = TRUE; switch (optarg[0]) { case 'I': QueueLimitId = newstr(&optarg[1]); break; case 'R': QueueLimitRecipient = newstr(&optarg[1]); break; case 'S': QueueLimitSender = newstr(&optarg[1]); break; default: QueueIntvl = convtime(optarg, 'm'); break; }# else /* QUEUE */ usrerr("I don't know about queues"); ExitStat = EX_USAGE;# endif /* QUEUE */ break; case 't': /* read recipients from message */ GrabTo = TRUE; break; case 'X': /* traffic log file */ setuid(RealUid); TrafficLogFile = fopen(optarg, "a"); if (TrafficLogFile == NULL) { syserr("cannot open %s", optarg); break; }#ifdef HASSETVBUF setvbuf(TrafficLogFile, NULL, _IOLBF, 0);#else setlinebuf(TrafficLogFile);#endif break; /* compatibility flags */ case 'c': /* connect to non-local mailers */ case 'i': /* don't let dot stop me */ case 'm': /* send to me too */ case 'T': /* set timeout interval */ case 'v': /* give blow-by-blow description */ setoption(j, "T", FALSE, TRUE, CurEnv); break; case 'e': /* error message disposition */# if defined(ultrix) case 'M': /* define macro */# endif setoption(j, optarg, FALSE, TRUE, CurEnv); break; case 's': /* save From lines in headers */ setoption('f', "T", FALSE, TRUE, CurEnv); break;# ifdef DBM case 'I': /* initialize alias DBM file */ OpMode = MD_INITALIAS; break;# endif /* DBM */# if defined(__osf__) || defined(_AIX3) case 'x': /* random flag that OSF/1 & AIX mailx passes */ break;# endif# if defined(NeXT) case 'O': /* random flag that NeXT Mail.app passes */ break;# endif default: ExitStat = EX_USAGE; finis(); break; } } av += optind; /* ** Do basic initialization. ** Read system control file. ** Extract special fields for local use. */#ifdef XDEBUG checkfd012("before readcf");#endif readcf(getcfname(), safecf, CurEnv); if (tTd(0, 1)) { printf("SYSTEM IDENTITY (after readcf):"); printf("\n\t (short domain name) $w = "); xputs(macvalue('w', CurEnv)); printf("\n\t(canonical domain name) $j = "); xputs(macvalue('j', CurEnv)); printf("\n\t (subdomain name) $m = "); xputs(macvalue('m', CurEnv)); printf("\n\t (node name) $k = "); xputs(macvalue('k', CurEnv)); printf("\n"); } /* ** Process authorization warnings from command line. */ if (warn_C_flag) auth_warning(CurEnv, "Processed by %s with -C %s", RealUserName, ConfFile);/* if (warn_f_flag != '\0') auth_warning(CurEnv, "%s set sender to %s using -%c", RealUserName, from, warn_f_flag);*/ if (Warn_Q_option) auth_warning(CurEnv, "Processed from queue %s", QueueDir); /* Enforce use of local time (null string overrides this) */ if (TimeZoneSpec == NULL) unsetenv("TZ"); else if (TimeZoneSpec[0] != '\0') { char **evp = UserEnviron; char tzbuf[100]; strcpy(tzbuf, "TZ="); strcpy(&tzbuf[3], TimeZoneSpec); while (*evp != NULL && strncmp(*evp, "TZ=", 3) != 0) evp++; if (*evp == NULL) { *evp++ = newstr(tzbuf); *evp = NULL; } else *evp++ = newstr(tzbuf); } if (ConfigLevel > MAXCONFIGLEVEL) { syserr("Warning: .cf version level (%d) exceeds program functionality (%d)", ConfigLevel, MAXCONFIGLEVEL); } if (MeToo) BlankEnvelope.e_flags |= EF_METOO;# ifdef QUEUE if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags)) { struct stat stbuf; /* check to see if we own the queue directory */ if (stat(QueueDir, &stbuf) < 0) syserr("main: cannot stat %s", QueueDir); if (stbuf.st_uid != RealUid) { /* nope, really a botch */ usrerr("You do not have permission to process the queue"); exit (EX_NOPERM); } }# endif /* QUEUE */ switch (OpMode) { case MD_INITALIAS: Verbose = TRUE; break; case MD_DAEMON: /* remove things that don't make sense in daemon mode */ FullName = NULL; break; } /* do heuristic mode adjustment */ if (Verbose) { /* turn off noconnect option */ setoption('c', "F", TRUE, FALSE, CurEnv); /* turn on interactive delivery */ setoption('d', "", TRUE, FALSE, CurEnv); } if (ConfigLevel < 3) { UseErrorsTo = TRUE; } /* our name for SMTP codes */ expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv); MyHostName = jbuf; /* make certain that this name is part of the $=w class */ setclass('w', MyHostName); /* the indices of built-in mailers */ st = stab("local", ST_MAILER, ST_FIND); if (st == NULL) syserr("No local mailer defined"); else LocalMailer = st->s_mailer; st = stab("prog", ST_MAILER, ST_FIND); if (st == NULL) syserr("No prog mailer defined"); else ProgMailer = st->s_mailer; st = stab("*file*", ST_MAILER, ST_FIND); if (st == NULL) syserr("No *file* mailer defined"); else FileMailer = st->s_mailer; st = stab("*include*", ST_MAILER, ST_FIND); if (st == NULL) syserr("No *include* mailer defined"); else InclMailer = st->s_mailer; /* operate in queue directory */ if (OpMode != MD_TEST && chdir(QueueDir) < 0) { syserr("cannot chdir(%s)", QueueDir); ExitStat = EX_SOFTWARE; } /* if we've had errors so far, exit now */ if (ExitStat != EX_OK && OpMode != MD_TEST) { setuid(RealUid); exit(ExitStat); }#ifdef XDEBUG checkfd012("before main() initmaps");#endif /* ** Do operation-mode-dependent initialization. */ switch (OpMode) { case MD_PRINT: /* print the queue */#ifdef QUEUE dropenvelope(CurEnv); printqueue(); setuid(RealUid); exit(EX_OK);#else /* QUEUE */ usrerr("No queue to print"); finis();#endif /* QUEUE */ case MD_INITALIAS: /* initialize alias database */ initmaps(TRUE, CurEnv); setuid(RealUid); exit(EX_OK); case MD_DAEMON: /* don't open alias database -- done in srvrsmtp */ break; default: /* open the alias database */ initmaps(FALSE, CurEnv); break; } if (tTd(0, 15)) { /* print configuration table (or at least part of it) */ printrules(); for (i = 0; i < MAXMAILERS; i++) { register struct mailer *m = Mailer[i]; int j; if (m == NULL) continue; printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld F=", i, m->m_name, m->m_mailer, m->m_se_rwset, m->m_sh_rwset, m->m_re_rwset, m->m_rh_rwset, m->m_maxsize); for (j = '\0'; j <= '\177'; j++) if (bitnset(j, m->m_flags)) (void) putchar(j); printf(" E="); xputs(m->m_eol); if (m->m_argv != NULL) { char **a = m->m_argv; printf(" A="); while (*a != NULL) { if (a != m->m_argv) printf(" "); xputs(*a++); } } printf("\n"); } } /* ** Switch to the main envelope. */ CurEnv = newenvelope(&MainEnvelope, CurEnv); MainEnvelope.e_flags = BlankEnvelope.e_flags; /* ** If test mode, read addresses from stdin and process. */ if (OpMode == MD_TEST) { char buf[MAXLINE]; if (isatty(fileno(stdin))) Verbose = TRUE; if (Verbose) { printf("ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)\n"); printf("Enter <ruleset> <address>\n"); } for (;;) { register char **pvp; char *q; auto char *delimptr; extern bool invalidaddr(); extern char *crackaddr(); if (Verbose) printf("> "); (void) fflush(stdout); if (fgets(buf, sizeof buf, stdin) == NULL) finis(); if (!Verbose) printf("> %s", buf); switch (buf[0]) { case '#': continue;#ifdef MAYBENEXTRELEASE case 'C': /* try crackaddr */ q = crackaddr(&buf[1]); xputs(q); printf("\n"); continue;#endif } for (p = buf; isascii(*p) && isspace(*p); p++) continue; q = p; while (*p != '\0' && !(isascii(*p) && isspace(*p))) p++; if (*p == '\0') { printf("No address!\n"); continue; } *p = '\0'; if (invalidaddr(p + 1, NULL)) continue; do { char pvpbuf[PSBUFSIZE]; pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf, &delimptr); if (pvp == NULL) continue; p = q; while (*p != '\0') { int stat; stat = rewrite(pvp, atoi(p), 0, CurEnv); if (stat != EX_OK) printf("== Ruleset %s status %d\n", p, stat); while (*p != '\0' && *p++ != ',') continue; } } while (*(p = delimptr) != '\0'); } }# ifdef QUEUE /* ** If collecting stuff from the queue, go start doing that. */ if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0) { runqueue(FALSE); finis(); }# endif /* QUEUE */ /* ** If a daemon, wait for a request. ** getrequests will always return in a child. ** If we should also be processing the queue, start ** doing it in background. ** We check for any errors that might have happened ** during startup. */ if (OpMode == MD_DAEMON || QueueIntvl != 0) { char dtype[200]; if (!tTd(0, 1)) { /* put us in background */ i = fork(); if (i < 0) syserr("daemon: cannot fork"); if (i != 0) exit(0); /* disconnect from our controlling tty */ disconnect(2, CurEnv); } dtype[0] = '\0'; if (OpMode == MD_DAEMON) strcat(dtype, "+SMTP"); if (QueueIntvl != 0) { strcat(dtype, "+queueing@"); strcat(dtype, pintvl(QueueIntvl, TRUE)); } if (tTd(0, 1)) strcat(dtype, "+debugging");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -