📄 nnrpd.c
字号:
continue; PERMcanread = strchr(fields[1], 'R') != NULL; PERMcanpost = strchr(fields[1], 'P') != NULL; (void)strcpy(PERMuser, fields[2]); (void)strcpy(PERMpass, fields[3]); (void)strcpy(accesslist, fields[4]); found = TRUE; } (void)fclose(F); return found;}/*** Determine access rights of the client.*/STATIC voidStartConnection(accesslist) char *accesslist;{ struct sockaddr_in sin; int length; char buff[SMBUF]; char *ClientAddr; /* Get the peer's name. */ length = sizeof sin; ClientAddr = NULL; if (getpeername(STDIN, (struct sockaddr *)&sin, &length) < 0) { if (!isatty(STDIN)) { syslog(L_ERROR, "%s cant getpeername %m", "?"); Printf("%d I can't get your name. Goodbye.\r\n", NNTP_ACCESS_VAL); ExitWithStats(1); } (void)strcpy(ClientHost, "stdin"); } else { if (sin.sin_family != AF_INET) { syslog(L_ERROR, "%s bad_address_family %ld", "?", (long)sin.sin_family); Printf("%d Bad address family. Goodbye.\r\n", NNTP_ACCESS_VAL); ExitWithStats(1); } /* Get client's name. */#if defined(DO_NNRP_GETHOSTBYADDR) if (!Address2Name(&sin.sin_addr, ClientHost, sizeof ClientHost)) { (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr)); syslog(L_ERROR, "? cant gethostbyaddr %s %m", ClientHost); } else { ClientAddr = buff; (void)strcpy(buff, inet_ntoa(sin.sin_addr)); }#else (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));#endif /* defined(DO_NNRP_GETHOSTBYADDR) */ } syslog(L_NOTICE, "%s connect", ClientHost); if (!PERMinfile(ClientHost, ClientAddr, (char *)NULL, (char *)NULL, accesslist)) { syslog(L_NOTICE, "%s no_access", ClientHost); Printf("%d You are not in my access file. Goodbye.\r\n", NNTP_ACCESS_VAL); ExitWithStats(1); }}#if !defined(VAR_NONE)#if defined(VAR_VARARGS)#if defined(lint)#define START_VARARG(fmt, vp, type) va_start(vp); fmt = NULL#else#define START_VARARG(fmt, vp, type) va_start(vp); fmt = va_arg(vp, type)#endif /* defined(lint) */#endif /* defined(VAR_VARARGS) */#if defined(VAR_STDARGS)#define START_VARARG(fmt, vp, type) va_start(vp, fmt)#endif /* defined(VAR_STDARGS) *//*** Send a reply, possibly with debugging output.*//*VARARGS*/void#if defined(VAR_VARARGS)Reply(va_alist) va_dcl#endif /* defined(VAR_VARARGS) */#if defined(VAR_STDARGS)Reply(char *fmt, ...)#endif /* defined(VAR_STDARGS) */{ register int oerrno; register char *p; va_list vp; char buff[2048];#if defined(VAR_VARARGS) register char *fmt;#endif /* defined(VAR_VARARGS) */ START_VARARG(fmt, vp, char*); (void)vprintf(fmt, vp); va_end(vp); if (Tracing) { oerrno = errno; START_VARARG(fmt, vp, char*); /* Copy output, but strip trailing CR-LF. */ (void)vsprintf(buff, fmt, vp); p = buff + strlen(buff) - 1; while (p >= buff && (*p == '\n' || *p == '\r')) *p-- = '\0'; syslog(LOG_DEBUG, "%s > %s", ClientHost, buff); va_end(vp); errno = oerrno; }}#endif /* !defined(VAR_NONE) *//*** Got a signal; toggle tracing.*/STATIC SIGHANDLERToggleTrace(s) int s;{ ChangeTrace = TRUE; (void)signal(s, ToggleTrace);}/*** Print a usage message and exit.*/STATIC voidUsage(){ (void)fprintf(stderr, "Usage error.\n"); exit(1);}/* ARGSUSED0 */intmain(argc, argv) int argc; char *argv[];{#if NNRP_LOADLIMIT > 0 int load;#endif /* NNRP_LOADLIMIT > 0 */ CMDENT *cp; char buff[NNTP_STRLEN]; char **av; int ac; READTYPE r; TIMEINFO Now; register int i; char *Reject; char accesslist[BIG_BUFFER];#if !defined(HPUX) /* Save start and extent of argv for TITLEset. */ TITLEstart = argv[0]; TITLEend = argv[argc - 1] + strlen(argv[argc - 1]) - 1;#endif /* !defined(HPUX) */ /* Parse arguments. Must COPY() optarg if used because the * TITLEset() routine would clobber it! */ Reject = NULL; while ((i = getopt(argc, argv, "S:r:s:t")) != EOF) switch (i) { default: Usage(); /* NOTREACHED */ case 'S': /* We're a slave to NNTP master */ RemoteMaster = COPY(optarg); break; case 's': /* Unused title string */ break; case 't': /* Tracing */ Tracing = TRUE; break; case 'r': /* Reject connection message */ Reject = COPY(optarg); break; } argc -= optind; if (argc) Usage(); /* Setup. */ openlog("nnrpd", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG); if (GetTimeInfo(&Now) < 0) { syslog(L_FATAL, "cant gettimeinfo %m"); exit(1); } STATstart = TIMEINFOasDOUBLE(Now); if ((MyHostName = GetConfigValue(_CONF_PATHHOST)) == NULL) { syslog(L_FATAL, "cant getconfigvalue %m"); ExitWithStats(1); } MyHostName = COPY(MyHostName);#if NNRP_LOADLIMIT > 0 if ((load = GetLoadAverage()) > NNRP_LOADLIMIT) { syslog(L_NOTICE, "load %d > %d", load, NNRP_LOADLIMIT); Reply("%d load at %d, try later\r\n", NNTP_GOODBYE_VAL, load); ExitWithStats(1); }#endif /* NNRP_LOADLIMIT > 0 */ /* Ignore SIGPIPE, since we'll see closed connections with read. */ (void)signal(SIGPIPE, SIG_IGN); /* Arrange to toggle tracing. */ (void)signal(SIGHUP, ToggleTrace); /* Get permissions and see if we can talk to this client */ StartConnection(accesslist); if (!PERMcanread && !PERMcanpost) { syslog(L_NOTICE, "%s no_permission", ClientHost); Printf("%d You have no permission to talk. Goodbye.\r\n", NNTP_ACCESS_VAL); ExitWithStats(1); } /* Proceed with initialization. */ PERMneedauth = PERMuser[0] != '\0' && PERMpass != '\0'; PERMspecified = NGgetlist(&PERMlist, accesslist); TITLEset("connect"); /* Were we told to reject connections? */ if (Reject) { syslog(L_NOTICE, "%s rejected %s", ClientHost, Reject); Reply("%s %s\r\n", NNTP_GOODBYE, Reject); ExitWithStats(0); } ARTreadschema(); if (!GetGroupList()) { /* This shouldn't really happen. */ syslog(L_NOTICE, "%s cant getgrouplist %m", ClientHost); Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL); ExitWithStats(1); } Reply("%d %s InterNetNews NNRP server %s ready (%s).\r\n", PERMcanpost ? NNTP_POSTOK_VAL : NNTP_NOPOSTOK_VAL, MyHostName, INNVersion(), PERMcanpost ? "posting ok" : "no posting"); /* Main dispatch loop. */ for (av = NULL; ; ) { (void)fflush(stdout); if (ChangeTrace) { Tracing = Tracing ? FALSE : TRUE; syslog(L_TRACE, "trace %sabled", Tracing ? "en" : "dis"); ChangeTrace = FALSE; } switch (r = READline(buff, (int)sizeof buff, CLIENT_TIMEOUT)) { default: syslog(L_ERROR, "%s internal %d in main", ClientHost, r); /* FALLTHROUGH */ case RTtimeout: syslog(L_NOTICE, "%s timeout", ClientHost); Printf("%d Timeout after %d seconds, closing connection.\r\n", NNTP_TEMPERR_VAL, CLIENT_TIMEOUT); ExitWithStats(1); break; case RTlong: Reply("%d Line too long\r\n", NNTP_BAD_COMMAND_VAL); continue; case RTok: /* Do some input processing, check for blank line. */ if (buff[0] == '\0') continue; if (Tracing) syslog(L_TRACE, "%s < %s", ClientHost, buff); ac = Argify(buff, &av); if (ac == 0) continue; break; case RTeof: /* Handled below. */ break; } /* Client gone? */ if (r == RTeof || caseEQ(av[0], "quit")) break; /* Find command. */ for (cp = CMDtable; cp->Name; cp++) if (caseEQ(cp->Name, av[0])) break; if (cp->Name == NULL) { if ((int)strlen(buff) > 40) syslog(L_NOTICE, "%s unrecognized %.40s...", ClientHost, buff); else syslog(L_NOTICE, "%s unrecognized %s", ClientHost, buff); Reply("%d What?\r\n", NNTP_BAD_COMMAND_VAL); continue; } /* Check usage. */ if ((cp->Minac != CMDany && ac < cp->Minac) || (cp->Maxac != CMDany && ac > cp->Maxac)) { Reply("%d %s\r\n", NNTP_SYNTAX_VAL, cp->Help ? cp->Help : "Usage error"); continue; } /* Check permissions and dispatch. */ if (cp->Needauth && PERMneedauth) { Reply("%d Authentication required for command\r\n", NNTP_AUTH_NEEDED_VAL); continue; } TITLEset(av[0]); (*cp->Function)(ac, av); } Reply("%s\r\n", NNTP_GOODBYE_ACK); ExitWithStats(0); /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -