📄 innd.c
字号:
** We ran out of space or other I/O error, throttle ourselves.*/voidThrottleIOError(when) char *when;{ char buff[SMBUF]; STRING p; int oerrno; if (Mode == OMrunning) { oerrno = errno; if (Reservation) { DISPOSE(Reservation); Reservation = NULL; } (void)sprintf(buff, "%s writing %s file -- throttling", strerror(oerrno), when); if ((p = CCblock(OMthrottled, buff)) != NULL) syslog(L_ERROR, "%s cant throttle %s", LogName, p); syslog(L_FATAL, "%s throttle %s", LogName, buff); errno = oerrno; }}/*** Close down all parts of the system (e.g., before calling exit or exec).*/voidJustCleanup(){ SITEflushall(FALSE); /* PROCclose(FALSE); */ CCclose(); LCclose(); NCclose(); RCclose(); ICDclose(); HISclose(); ARTclose(); (void)sleep(1); /* PROCclose(TRUE); */ if (unlink(PID) < 0 && errno != ENOENT) syslog(L_ERROR, "%s cant unlink %s %m", LogName, PID);}/*** The name is self-explanatory.*/NORETURNCleanupAndExit(x, why) int x; char *why;{ JustCleanup(); syslog(L_NOTICE, "%s shutdown %s", LogName, why); exit(x);}#if NOFILE_LIMIT > 0/*** Set the limit on the number of open files we can have. I don't** like having to do this.*/STATIC voidSetDescriptorLimit(i) int i;{ struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { syslog(L_ERROR, "%s cant getrlimit(NOFILE) %m", LogName); return; } rl.rlim_cur = i; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { syslog(L_ERROR, "%s cant setrlimit(NOFILE) %d %m", LogName, i); return; }}#endif /* NOFILE_LIMIT > 0 *//*** Signal handler to catch SIGTERM and queue a clean shutdown.*/STATIC SIGHANDLERCatchTerminate(s) int s;{ GotTerminate = TRUE; (void)signal(s, CatchTerminate);}/*** Print a usage message and exit.*/STATIC NORETURNUsage(){ (void)fprintf(stderr, "Usage error.\n"); exit(1);}intmain(ac, av) int ac; char *av[];{ static char WHEN[] = "PID file"; int i; int port; int logflags; char buff[SMBUF]; char *master; STRING path; STRING p; FILE *F; BOOL ShouldFork; BOOL ShouldRenumber; BOOL ShouldSyntaxCheck; long pid;#if defined(_DEBUG_MALLOC_INC) union malloptarg m;#endif /* defined(_DEBUG_MALLOC_INC) */ /* Set up the pathname, first thing. */ path = av[0]; if (path == NULL || *path == '\0') path = "innd"; else if ((p = strrchr(path, '/')) != NULL) path = p + 1; ONALLLOCFAIL(AllocationFailure); Version = INNVersion(); /* Handle malloc debugging. */#if defined(_DEBUG_MALLOC_INC) m.i = M_HANDLE_ABORT; dbmallopt(MALLOC_WARN, &m); dbmallopt(MALLOC_FATAL, &m); m.i = 3; dbmallopt(MALLOC_FILLAREA, &m); m.i = 0; dbmallopt(MALLOC_CKCHAIN, &m); dbmallopt(MALLOC_CKDATA, &m);#endif /* defined(_DEBUG_MALLOC_INC) */ /* Set defaults. */ TimeOut.tv_sec = DEFAULT_TIMEOUT; ShouldFork = TRUE; ShouldRenumber = FALSE; ShouldSyntaxCheck = FALSE; logflags = L_OPENLOG_FLAGS | LOG_NOWAIT; port = -1; master = NULL;#if defined(DONT_ALLOW_READERS) NNRPFollows = TRUE;#endif /* defined(DONT_ALLOW_READERS) */#if defined(DO_FAST_RESOLV) /* We only use FQDN's in the hosts.nntp file. */ _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);#endif /* defined(DO_FAST_RESOLV) */ /* Parse JCL. */ CCcopyargv(av); while ((i = getopt(ac, av, "ac:dfi:l:m:o:n:p:rsS:t:ux")) != EOF) switch (i) { default: Usage(); /* NOTREACHED */ case 'a': AnyIncoming = TRUE; break; case 'c': Cutoff = atoi(optarg) * 24 * 60 * 60; break; case 'd': Debug = TRUE;#if defined(LOG_PERROR) logflags = LOG_PERROR | (logflags & ~LOG_CONS);#endif /* defined(LOG_PERROR) */ break; case 'f': ShouldFork = FALSE; break; case 'i': MaxIncoming = atoi(optarg); break; case 'l': LargestArticle = atol(optarg); break; case 'm': if (ModeReason) DISPOSE(ModeReason); switch (*optarg) { default: Usage(); /* NOTREACHED */ case 'g': Mode = OMrunning; break; case 'p': Mode = OMpaused; break; case 't': Mode = OMthrottled; break; } if (Mode != OMrunning) { (void)sprintf(buff, "%sed from command line", Mode == OMpaused ? "Paus" : "Throttl"); ModeReason = COPY(buff); } break; case 'n': switch (*optarg) { default: Usage(); /* NOTREACHED */ case 'n': NNRPFollows = TRUE; break; case 'y': NNRPFollows = FALSE; break; } break; case 'o': MaxOutgoing = atoi(optarg); break; case 'p': /* Silently ignore multiple -p flags, in case ctlinnd xexec * called inndstart. */ if (port == -1) { port = atoi(optarg); AmRoot = FALSE; } break; case 'r': ShouldRenumber = TRUE; break; case 's': ShouldSyntaxCheck = TRUE; break; case 'S': master = optarg; break; case 't': TimeOut.tv_sec = atol(optarg); break; case 'u': BufferedLogs = FALSE; break; case 'x': AlwaysCrosspost = TRUE; break; } ac -= optind; if (ac != 0) Usage(); if (ModeReason && NNRPFollows) NNRPReason = COPY(ModeReason); openlog(path, logflags, LOG_INN_SERVER); if (ShouldSyntaxCheck) { if ((p = CCcheckfile((char **)NULL)) == NULL) exit(0); (void)fprintf(stderr, "%s\n", p + 2); } /* Go to where the data is. */ if (chdir(SPOOL) < 0) { syslog(L_FATAL, "%s cant chdir %s %m", LogName, SPOOL); exit(1); } /* Get the Path entry. */ if ((path = GetConfigValue(_CONF_PATHHOST)) == NULL) { syslog(L_FATAL, "%s cant GetConfigValue %s %m", LogName, _CONF_PATHHOST); exit(1); } Path.Used = strlen(path) + 1; Path.Data = NEW(char, Path.Used + 1); (void)sprintf(Path.Data, "%s!", path); /* Get the Xref prefix. */ Xref.Size = SMBUF; Xref.Data = NEW(char, Xref.Size); (void)sprintf(Xref.Data, "Xref: %s", path); Xref.Used = strlen(Xref.Data); Xrefbase = Xref.Used;#if !defined(__CENTERLINE__) /* Set standard input to /dev/null. */ if ((i = open("/dev/null", O_RDWR)) < 0) { syslog(L_FATAL, "%s cant open /dev/null %m", LogName); exit(1); } if (dup2(i, 0) != 0) syslog(L_NOTICE, "%s cant dup2 %d to 0 %m", LogName, i); (void)close(i);#endif /* !defined(__CENTERLINE__) */ /* Set up our permissions. */ (void)umask(NEWSUMASK); if (!GetNewsOwnerships()) { syslog(L_FATAL, "%s internal cant stat control directory %m", LogName); exit(1); } if (port != -1 && setgid(NewsGID) < 0) syslog(L_ERROR, "%s cant setgid running as %d not %d %m", LogName, (int)getgid(), (int)NewsGID); if (Debug) { Log = stdout; Errlog = stderr; (void)signal(SIGINT, CatchTerminate); } else { if (ShouldFork) { /* Become a server. */ i = fork(); if (i < 0) { syslog(L_FATAL, "%s cant fork %m", LogName); exit(1); } if (i > 0) _exit(0);#if defined(TIOCNOTTY) /* Disassociate from terminal. */ if ((i = open("/dev/tty", O_RDWR)) >= 0) { if (ioctl(i, TIOCNOTTY, (char *)NULL) < 0) syslog(L_ERROR, "%s cant ioctl(TIOCNOTTY) %m", LogName); if (close(i) < 0) syslog(L_ERROR, "%s cant close /dev/tty %m", LogName); }#endif /* defined(TIOCNOTTY) */#if defined(DO_HAVE_SETSID) (void)setsid();#endif /* defined(DO_HAVE_SETSID) */ } /* Open the Log. */ (void)fclose(stdout); if ((Log = fopen(LOG, "a")) == NULL) { syslog(L_FATAL, "%s cant fopen %s %m", LogName, LOG); exit(1); } if (AmRoot) xchown(LOG); if (BufferedLogs && (LogBuffer = NEW(char, LogBufferSize)) != NULL) SETBUFFER(Log, LogBuffer, LogBufferSize); /* Open the Errlog. */ (void)fclose(stderr); if ((Errlog = fopen(ERRLOG, "a")) == NULL) { syslog(L_FATAL, "%s cant fopen %s %m", LogName, ERRLOG); exit(1); } if (AmRoot) xchown(ERRLOG); if (BufferedLogs && (ErrlogBuffer = NEW(char, LogBufferSize)) != NULL) SETBUFFER(Errlog, ErrlogBuffer, LogBufferSize); } /* Set number of open channels. */#if NOFILE_LIMIT > 0 if (AmRoot) SetDescriptorLimit(NOFILE_LIMIT);#endif /* NOFILE_LIMIT > 0 */ /* Get number of open channels. */ if ((i = getfdcount()) < 0) { syslog(L_FATAL, "%s cant getfdcount %m", LogName); exit(1); } syslog(L_NOTICE, "%s descriptors %d", LogName, i); if (MaxOutgoing == 0) { /* getfdcount() - (stdio + dbz + cc + lc + rc + art + fudge) */ MaxOutgoing = i - ( 3 + 3 + 2 + 1 + 1 + 1 + 2 ); syslog(L_NOTICE, "%s outgoing %d", LogName, MaxOutgoing); } /* See if another instance is alive. */ if ((F = fopen(PID, "r")) != NULL) { if (fgets(buff, sizeof buff, F) != NULL && ((pid = atoi(buff)) > 0) && (kill((PID_T)pid, 0) > 0 || errno != ESRCH)) { (void)syslog(L_FATAL, "%s already_running pid %d", LogName, pid); exit(1); } (void)fclose(F); } /* Set up the various parts of the system. Channel feeds start * processes so call PROCsetup before ICDsetup. NNTP needs to know * if it's a slave, so call RCsetup before NCsetup. */ (void)signal(SIGTERM, CatchTerminate);#if defined(SIGDANGER) (void)signal(SIGDANGER, CatchTerminate);#endif /* defined(SIGDANGER) */ CHANsetup(i); PROCsetup(i * 2); HISsetup(); CCsetup(); LCsetup(); RCsetup(port, master); NCsetup(i); ARTsetup(); ICDsetup(TRUE);#if defined(_DEBUG_MALLOC_INC) m.i = 1; dbmallopt(MALLOC_CKCHAIN, &m); dbmallopt(MALLOC_CKDATA, &m);#endif /* defined(_DEBUG_MALLOC_INC) */ /* Record our PID. */ pid = getpid(); if ((F = fopen(PID, "w")) == NULL) { IOError(WHEN); syslog(L_ERROR, "%s cant fopen %s %m", LogName, PID); } else { if (fprintf(F, "%ld\n", (long)pid) == EOF || ferror(F)) { IOError(WHEN); syslog(L_ERROR, "%s cant fprintf %s %m", LogName, PID); } if (fclose(F) == EOF) { IOError(WHEN); syslog(L_ERROR, "%s cant fclose %s %m", LogName, PID); } if (chmod(PID, 0664) < 0) { IOError(WHEN); syslog(L_ERROR, "%s cant chmod %s %m", LogName, PID); } } /* And away we go... */ if (ShouldRenumber) { syslog(L_NOTICE, "%s renumbering", LogName); ICDrenumberactive(); } syslog(L_NOTICE, "%s starting", LogName); CHANreadloop(); CleanupAndExit(1, "CHANreadloop returned"); /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -