📄 cc.c
字号:
*/STATIC STRINGCCreject(av) char *av[];{ if (RejectReason) return "1 Already rejecting"; RejectReason = COPY(av[0]); return NULL;}/*** Re-read all in-core data.*/STATIC STRINGCCreload(av) char *av[];{ static char BADSCHEMA[] = "1 Can't read schema"; STRING p; p = av[0]; if (*p == '\0' || EQ(p, "all")) { SITEflushall(FALSE); HISclose(); RCreadlist(); HISsetup(); ICDwrite(); ICDsetup(TRUE); if (!ARTreadschema()) return BADSCHEMA; p = "all"; } else if (EQ(p, "active") || EQ(p, "newsfeeds")) { SITEflushall(FALSE); ICDwrite(); ICDsetup(TRUE); } else if (EQ(p, "history")) { HISclose(); HISsetup(); } else if (EQ(p, "hosts.nntp")) RCreadlist(); else if (EQ(p, "overview.fmt")) { if (!ARTreadschema()) return BADSCHEMA; } else return "1 Unknown reload type"; syslog(L_NOTICE, "%s reload %s %s", LogName, p, av[1]); return NULL;}/*** Renumber the active file.*/STATIC STRINGCCrenumber(av) char *av[];{ char *p; NEWSGROUP *ngp; if (Mode != OMrunning) return CCnotrunning; if (ICDneedsetup) return "1 Must first reload newsfeeds"; p = av[0]; if (*p) { if ((ngp = NGfind(p)) == NULL) return CCnogroup; if (!NGrenumber(ngp)) return "1 Failed (see syslog)"; } else ICDrenumberactive(); return NULL;}/*** Reserve a lock.*/STATIC STRINGCCreserve(av) char *av[];{ char *p; if (Mode != OMrunning) return CCnotrunning; p = av[0]; if (*p) { /* Trying to make a reservation. */ if (Reservation) return "1 Already reserved"; Reservation = COPY(p); } else { /* Trying to remove a reservation. */ if (Reservation == NULL) return "1 Not reserved"; DISPOSE(Reservation); Reservation = NULL; } return NULL;}/*** Remove a newsgroup.*/STATIC STRINGCCrmgroup(av) char *av[];{ NEWSGROUP *ngp; if ((ngp = NGfind(av[0])) == NULL) return CCnogroup; /* Update the in-core data. */ if (!ICDrmgroup(ngp)) return "1 Failed"; syslog(L_NOTICE, "%s rmgroup %s", LogName, av[0]); return NULL;}/*** Send a command line to an exploder.*/STATIC STRINGCCsend(av) char *av[];{ SITE *sp; if ((sp = SITEfind(av[0])) == NULL) return CCnosite; if (sp->Type != FTexploder) return CCwrongtype; SITEwrite(sp, av[1]); return NULL;}/*** Shut down the system.*/STATIC STRINGCCshutdown(av) char *av[];{ syslog(L_NOTICE, "%s shutdown %s", LogName, av[0]); CleanupAndExit(0, av[0]); /* NOTREACHED */}/*** Send a signal to a site's feed.*/STATIC STRINGCCsignal(av) char *av[];{ register SITE *sp; register char *p; int s; int oerrno; /* Parse the signal. */ p = av[0]; if (*p == '-') p++; if (caseEQ(p, "HUP")) s = SIGHUP; else if (caseEQ(p, "INT")) s = SIGINT; else if (caseEQ(p, "TERM")) s = SIGTERM; else if ((s = atoi(p)) <= 0) return "1 Invalid signal"; /* Parse the site. */ p = av[1]; if ((sp = SITEfind(p)) == NULL) return CCnosite; if (sp->Type != FTchannel && sp->Type != FTexploder) return CCwrongtype; if (sp->Spooling || sp->Process < 0) return "1 Site has no process"; /* Do it. */ if (kill(sp->pid, s) < 0) { oerrno = errno; syslog(L_ERROR, "%s cant kill %d %d site %s, %m", sp->Process, s, p); (void)sprintf(CCreply.Data, "1 Can't signal process %d, %s", sp->Process, strerror(oerrno)); return CCreply.Data; } return NULL;}/*** Enter throttled mode.*/STATIC STRINGCCthrottle(av) char *av[];{ char *p; p = av[0]; switch (Mode) { case OMpaused: if (*p && !EQ(p, ModeReason)) return "1 Already paused"; /* FALLTHROUGH */ case OMrunning: return CCblock(OMthrottled, p); case OMthrottled: return "1 Already throttled"; } return "1 unknown mode";}/*** Add or remove tracing.*/STATIC STRINGCCtrace(av) char *av[];{ char *p; BOOL Flag; STRING word; CHANNEL *cp; /* Parse the flag. */ p = av[1]; switch (p[0]) { default: return "1 Bad trace flag"; case 'y': case 'Y': Flag = TRUE; word = "on"; break; case 'n': case 'N': Flag = FALSE; word = "off"; break; } /* Parse what's being traced. */ p = av[0]; switch (*p) { default: return "1 Bad trace item"; case 'i': case 'I': Tracing = Flag; syslog(L_NOTICE, "%s trace innd %s", LogName, word); break; case 'n': case 'N': NNRPTracing = Flag; syslog(L_NOTICE, "%s trace nnrpd %s", LogName, word); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((cp = CHANfromdescriptor(atoi(p))) == NULL) return CCnochannel; CHANtracing(cp, Flag); break; } return NULL;}/*** Split up the text into fields and stuff them in argv. Return the** number of elements or -1 on error.*/STATIC intCCargsplit(p, end, argv, size) register char *p; register char *end; register char **argv; register int size;{ char **save; for (save = argv, *argv++ = p, size--; p < end; p++) if (*p == SC_SEP) { if (--size <= 0) return -1; *p = '\0'; *argv++ = p + 1; } *argv = NULL; return argv - save;}/*** Read function. Read and process the message.*/STATIC FUNCTYPECCreader(cp) CHANNEL *cp;{ static char TOOLONG[] = "0 Reply too long for server to send"; register CCDISPATCH *dp; register STRING p; register char *q;#if defined(DO_HAVE_UNIX_DOMAIN) struct sockaddr_un client;#else int written;#endif /* defined(DO_HAVE_UNIX_DOMAIN) */ int i; char buff[BUFSIZ + 2]; char copy[BUFSIZ + 2]; char *argv[SC_MAXFIELDS + 2]; int argc; int len; if (cp != CCchan) { syslog(L_ERROR, "%s internal CCreader wrong channel 0x%x not 0x%x", LogName, cp, CCchan); return; } /* Get the message. */ i = RECVorREAD(CCchan->fd, buff, sizeof buff - 1); if (i < 0) { syslog(L_ERROR, "%s cant recv CCreader %m", LogName); return; } if (i == 0) { syslog(L_ERROR, "%s cant recv CCreader empty", LogName); return; } buff[i] = '\0'; /* Copy to a printable buffer, and log. */ (void)strcpy(copy, buff); for (p = NULL, q = copy; *q; q++) if (*q == SC_SEP) { *q = ':'; if (p == NULL) p = q + 1; } syslog(L_CC_CMD, "%s", p ? p : copy); /* Split up the fields, get the command letter. */ if ((argc = CCargsplit(buff, &buff[i], argv, SIZEOF(argv))) < 2 || argc == SIZEOF(argv)) { syslog(L_ERROR, "%s bad_fields CCreader", LogName); return; } p = argv[1]; i = *p; /* Dispatch to the command function. */ for (argc -= 2, dp = CCcommands; dp < ENDOF(CCcommands); dp++) if (i == dp->Name) { if (argc != dp->argc) p = "1 Wrong number of parameters"; else p = (*dp->Function)(&argv[2]); break; } if (dp == ENDOF(CCcommands)) { syslog(L_NOTICE, "%s bad_message %c", LogName, i); p = "1 Bad command"; } else if (p == NULL) p = "0 Ok"; /* Build the reply address and send the reply. */ len = strlen(p);#if defined(DO_HAVE_UNIX_DOMAIN) (void)memset((POINTER)&client, 0, sizeof client); client.sun_family = AF_UNIX; (void)strcpy(client.sun_path, argv[0]); if (sendto(CCwriter, p, len, 0, (struct sockaddr *)&client, AF_UNIX_SOCKSIZE(client)) < 0) { i = errno; syslog(i == ENOENT ? L_NOTICE : L_ERROR, "%s cant sendto CCreader bytes %d %m", LogName, len); if (i == EMSGSIZE) (void)sendto(CCwriter, TOOLONG, STRLEN(TOOLONG), 0, (struct sockaddr *)&client, AF_UNIX_SOCKSIZE(client)); }#else if ((i = open(argv[0], O_WRONLY)) < 0) syslog(L_ERROR, "%s cant open %s %m", LogName, argv[0]); else { if ((written = write(i, p, len)) != len) if (written < 0) syslog(L_ERROR, "%s cant write %s %m", LogName, argv[0]); else syslog(L_ERROR, "%s cant write %s", LogName, argv[0]); if (close(i) < 0) syslog(L_ERROR, "%s cant close %s %m", LogName, argv[0]); }#endif /* defined(DO_HAVE_UNIX_DOMAIN) */}/*** Called when a write-in-progress is done on the channel. Shouldn't happen.*/STATIC FUNCTYPECCwritedone(){ syslog(L_ERROR, "%s internal CCwritedone", LogName);}/*** Create the channel.*/voidCCsetup(){ int i;#if defined(DO_HAVE_UNIX_DOMAIN) struct sockaddr_un server;#endif /* defined(DO_HAVE_UNIX_DOMAIN) */ /* Remove old detritus. */ if (unlink(CCpath) < 0 && errno != ENOENT) { syslog(L_FATAL, "%s cant unlink %s %m", LogName, CCpath); exit(1); }#if defined(DO_HAVE_UNIX_DOMAIN) /* Create a socket and name it. */ if ((i = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { syslog(L_FATAL, "%s cant socket %s %m", LogName, CCpath); exit(1); } (void)memset((POINTER)&server, 0, sizeof server); server.sun_family = AF_UNIX; (void)strcpy(server.sun_path, CCpath); if (bind(i, (struct sockaddr *)&server, AF_UNIX_SOCKSIZE(server)) < 0) { syslog(L_FATAL, "%s cant bind %s %m", LogName, CCpath); exit(1); } /* Create an unbound socket to reply on. */ if ((CCwriter = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { syslog(L_FATAL, "%s cant socket unbound %m", LogName); exit(1); }#else /* Create a named pipe and open it. */ if (mkfifo(CCpath, 0666) < 0) { syslog(L_FATAL, "%s cant mkfifo %s %m", LogName, CCpath); exit(1); } if ((i = open(CCpath, O_RDWR)) < 0) { syslog(L_FATAL, "%s cant open %s %m", LogName, CCpath); exit(1); }#endif /* defined(DO_HAVE_UNIX_DOMAIN) */ CCchan = CHANcreate(i, CTcontrol, CSwaiting, CCreader, CCwritedone); syslog(L_NOTICE, "%s ccsetup %s", LogName, CHANname(CCchan)); RCHANadd(CCchan); CCreply.Size = SMBUF; CCreply.Data = NEW(char, CCreply.Size);}/*** Cleanly shut down the channel.*/voidCCclose(){ CHANclose(CCchan, CHANname(CCchan)); CCchan = NULL; if (unlink(CCpath) < 0) syslog(L_ERROR, "%s cant unlink %s %m", LogName, CCpath);#if defined(DO_HAVE_UNIX_DOMAIN) if (close(CCwriter) < 0) syslog(L_ERROR, "%s cant close unbound %m", LogName);#endif /* defined(DO_HAVE_UNIX_DOMAIN) */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -