?? nnrpd.c
字號:
/* $Revision: 1.18 $**** NNTP server for readers (NNRP) for InterNetNews.** This server doesn't do any real load-limiting, except for what has** proven empirically necesary (i.e., look at GRPscandir).*/#define MAINLINE#include <signal.h>#include "nnrpd.h"#include <sys/time.h>#include <netdb.h>#if defined(HPUX)#include <sys/pstat.h>#endif /* defined(HPUX) */#define CMDany -1typedef struct _CMDENT { STRING Name; FUNCPTR Function; BOOL Needauth; int Minac; int Maxac; STRING Help;} CMDENT;char NOACCESS[] = NNTP_ACCESS;char ACTIVE[] = _PATH_ACTIVE;char ACTIVETIMES[] = _PATH_ACTIVETIMES;char HISTORY[] = _PATH_HISTORY;char NEWSGROUPS[] = _PATH_NEWSGROUPS; /* Default permission -- change with adb. */BOOL PERMdefault = FALSE;STATIC double STATstart;STATIC double STATfinish;#if !defined(HPUX)STATIC char *TITLEstart;STATIC char *TITLEend;#endif /* !defined(HPUX) */STATIC SIGVAR ChangeTrace;extern FUNCTYPE CMDauthinfo();extern FUNCTYPE CMDdate();extern FUNCTYPE CMDfetch();extern FUNCTYPE CMDgroup();STATIC FUNCTYPE CMDhelp();extern FUNCTYPE CMDlist();extern FUNCTYPE CMDmode();extern FUNCTYPE CMDnewgroups();extern FUNCTYPE CMDnewnews();extern FUNCTYPE CMDnextlast();extern FUNCTYPE CMDpost();extern FUNCTYPE CMDxgtitle();extern FUNCTYPE CMDxhdr();extern FUNCTYPE CMDxover();extern FUNCTYPE CMDxpat();extern FUNCTYPE CMDxpath();extern FUNCTYPE CMD_unimp();#if defined(DO_DO_XTHREAD)extern FUNCTYPE CMDxthread();#endif /* defined(DO_DO_XTHREAD) */STATIC char CMDfetchhelp[] = "[MessageID|Number]";STATIC CMDENT CMDtable[] = { { "authinfo", CMDauthinfo, FALSE, 3, 3, "user Name|pass Password" }, { "article", CMDfetch, FALSE, 1, 2, CMDfetchhelp }, { "body", CMDfetch, FALSE, 1, 2, CMDfetchhelp }, { "date", CMDdate, FALSE, 1, 1, NULL }, { "group", CMDgroup, FALSE, 2, 2, "newsgroup" }, { "head", CMDfetch, FALSE, 1, 2, CMDfetchhelp }, { "help", CMDhelp, FALSE, 1, CMDany, NULL }, { "ihave", CMD_unimp, TRUE, 1, 2, NULL }, { "last", CMDnextlast, FALSE, 1, 1, NULL }, { "list", CMDlist, FALSE, 1, 2, "[active|newsgroups|distributions|schema]" }, { "listgroup", CMDgroup, FALSE, 1, 2, "newsgroup" }, { "mode", CMDmode, FALSE, 2, 2, "reader" }, { "newgroups", CMDnewgroups, FALSE, 3, 5, "yymmdd hhmmss [\"GMT\"] [<distributions>]" }, { "newnews", CMDnewnews, FALSE, 4, 6, "newsgroups yymmdd hhmmss [\"GMT\"] [<distributions>]" }, { "next", CMDnextlast, FALSE, 1, 1, NULL }, { "post", CMDpost, TRUE, 1, 1, NULL }, { "slave", CMD_unimp, FALSE, 1, 1, NULL }, { "stat", CMDfetch, FALSE, 1, 2, CMDfetchhelp }, { "xgtitle", CMDxgtitle, FALSE, 1, 2, "[group_pattern]" }, { "xhdr", CMDxhdr, FALSE, 2, 3, "header [range|MessageID]" }, { "xover", CMDxover, FALSE, 1, 2, "[range]" }, { "xpat", CMDxpat, FALSE, 4, CMDany, "header range|MessageID pat [morepat...]" }, { "xpath", CMDxpath, FALSE, 2, 2, "xpath MessageID" },#if defined(DO_DO_XTHREAD) { "xthread", CMDxthread, FALSE, 1, 2, "[dbinit|thread]" },#endif /* defined(DO_DO_XTHREAD) */ { NULL }};/*** Log a summary status message and exit.*/NORETURNExitWithStats(x) int x;{ TIMEINFO Now; double usertime; double systime; (void)fflush(stdout); (void)GetTimeInfo(&Now); STATfinish = TIMEINFOasDOUBLE(Now); if (GetResourceUsage(&usertime, &systime) < 0) { usertime = 0; systime = 0; } GRPreport(); syslog(L_NOTICE, "%s exit articles %ld groups %ld", ClientHost, ARTcount, GRPcount); if (POSTreceived || POSTrejected) syslog(L_NOTICE, "%s posts received %ld rejected %ld", ClientHost, POSTreceived, POSTrejected); syslog(L_NOTICE, "%s times user %.3f system %.3f elapsed %.3f", ClientHost, usertime, systime, STATfinish - STATstart); exit(x);}/*** The "help" command.*//* ARGSUSED0 */STATIC FUNCTYPECMDhelp(ac, av) int ac; char *av[];{ CMDENT *cp; Reply("%s\r\n", NNTP_HELP_FOLLOWS); for (cp = CMDtable; cp->Name; cp++) if (cp->Help == NULL) Printf(" %s\r\n", cp->Name); else Printf(" %s %s\r\n", cp->Name, cp->Help); Printf("Report problems to <%s@%s>\r\n", NEWSMASTER, GetConfigValue(_CONF_FROMHOST)); Reply(".\r\n");}/*** Unimplemented catch-all.*//* ARGSUSED0 */FUNCTYPECMD_unimp(ac, av) int ac; char *av[];{ if (caseEQ(av[0], "ihave")) Reply("%d Transfer permission denied\r\n", NNTP_AUTH_NEEDED_VAL); else if (caseEQ(av[0], "slave")) /* Somebody sends us this? I don't believe it! */ Reply("%d Unsupported\r\n", NNTP_SLAVEOK_VAL); else Reply("%d %s not implemented; try help\r\n", NNTP_BAD_COMMAND_VAL, av[0]);}/*** Overwrite the original argv so that ps will show what's going on.*/STATIC voidTITLEset(what) char *what;{#if !defined(HPUX) register char *p; register int i; char buff[BUFSIZ]; /* Make ps think we're swapped out so we get "(nnrpd)" in the output. */ p = TITLEstart; *p++ = '-'; (void)sprintf(buff, "%s %s", ClientHost, what); i = strlen(buff); if (i > TITLEend - p - 2) { i = TITLEend - p - 2; buff[i] = '\0'; } (void)strcpy(p, buff); for (p += i; p < TITLEend; ) *p++ = ' ';#else char buff[BUFSIZ]; (void)sprintf(buff, "(nnrpd) %s %s", ClientHost, what); (void)pstat(PSTAT_SETCMD, buff, 0, 0, 0);#endif /* defined(HPUX) */}#if defined(DO_NNRP_GETHOSTBYADDR)/*** Convert an IP address to a hostname. Don't trust the reverse lookup,** since anyone can fake .in-addr.arpa entries.*/STATIC BOOLAddress2Name(ap, hostname, i) register INADDR *ap; register char *hostname; register int i;{ register char *p; register struct hostent *hp;#if defined(h_addr) register char **pp;#endif /* Get the official hostname, store it away. */ if ((hp = gethostbyaddr((char *)ap, sizeof *ap, AF_INET)) == NULL) return FALSE; (void)strncpy(hostname, hp->h_name, i); hostname[i - 1] = '\0'; /* Get addresses for this host. */ if ((hp = gethostbyname(hostname)) == NULL) return FALSE; /* Make sure one of those addresses is the address we got. */#if defined(h_addr) /* We have many addresses */ for (pp = hp->h_addr_list; *pp; pp++) if (memcmp((POINTER)&ap->s_addr, (POINTER)*pp, (SIZE_T)hp->h_length) == 0) break; if (*pp == NULL) return FALSE;#else /* We have one address. */ if (memcmp((POINTER)&ap->s_addr, (POINTER)hp->h_addr, (SIZE_T)hp->h_length) != 0) return FALSE;#endif /* Only needed for misconfigured YP/NIS systems. */ if (strchr(hostname, '.') == NULL && (p = GetConfigValue(_CONF_DOMAIN)) != NULL) { (void)strcat(hostname, "."); (void)strcat(hostname, p); } /* Make all lowercase, for wildmat. */ for (p = hostname; *p; p++) if (CTYPE(isupper, *p)) *p = tolower(*p); return TRUE;}#endif /* defined(DO_NNRP_GETHOSTBYADDR) */BOOLPERMinfile(hp, ip, user, pass, accesslist) char *hp; char *ip; char *user; char *pass; char *accesslist;{ static char ACCESS[] = _PATH_NNRPACCESS; register FILE *F; register char *p; register BOOL found; register int i; char buff[BIG_BUFFER]; char *fields[5]; if ((F = fopen(ACCESS, "r")) == NULL) { syslog(L_ERROR, "%s cant fopen %s %m", ClientHost, ACCESS); return FALSE; } PERMcanread = FALSE; PERMcanpost = FALSE; found = FALSE; accesslist[0] = '\0'; while (fgets(buff, sizeof buff, F) != NULL) { if ((p = strchr(buff, '\n')) != NULL) *p = '\0'; if ((p = strchr(buff, COMMENT_CHAR)) != NULL) *p = '\0'; if (buff[0] == '\0') continue; /* Split "host:permissions:user:pass:groups" into fields. */ for (fields[0] = buff, i = 0, p = buff; *p; p++) if (*p == ':') { *p = '\0'; fields[++i] = p + 1; } if (i != 4) /* Malformed line. */ continue; if (hp) /* Got an address; try to match either the IP address or as * a text hostname. */ if (!(ip && wildmat(ip, fields[0])) && !wildmat(hp, fields[0])) continue; /* Matching for a specific user or just the host? */ if (user && (!EQ(user, fields[2]) || !EQ(pass, fields[3])))
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -