|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)serve.c 1.6 (Berkeley) 3/12/86"; ! 3: #endif ! 4: ! 5: /* ! 6: * Main server routine ! 7: */ ! 8: ! 9: #include "common.h" ! 10: ! 11: #ifdef LOG ! 12: #include <sys/time.h> ! 13: #include <sys/resource.h> ! 14: #endif ! 15: ! 16: #ifdef FASTFORK ! 17: #include <signal.h> ! 18: #endif ! 19: ! 20: struct cmdent { ! 21: char *cmd_name; ! 22: int (*cmd_fctn)(); ! 23: } cmdtbl[] = { ! 24: "article", ahbs, ! 25: "body", ahbs, ! 26: "group", group, ! 27: "head", ahbs, ! 28: "help", help, ! 29: "ihave", ihave, ! 30: "last", nextlast, ! 31: "list", list, ! 32: "newgroups", newgroups, ! 33: "newnews", newnews, ! 34: "next", nextlast, ! 35: "post", post, ! 36: "slave", slave, ! 37: "stat", ahbs, ! 38: }; ! 39: #define NUMCMDS (sizeof(cmdtbl) / sizeof(struct cmdent)) ! 40: ! 41: char *homedir = SPOOLDIR; ! 42: ! 43: char *group_array[MAX_GROUPS]; ! 44: int num_groups; ! 45: int ingroup = 0; ! 46: int art_ptr; ! 47: int num_arts, art_array[MAX_ARTICLES]; ! 48: FILE *art_fp; ! 49: int uid_poster, gid_poster; ! 50: int canpost, canread, canxfer; ! 51: extern char *version; ! 52: ! 53: #ifdef LOG ! 54: int grps_acsd, arts_acsd; ! 55: #endif ! 56: ! 57: /* ! 58: * serve -- given a connection on stdin/stdout, serve ! 59: * a client, executing commands until the client ! 60: * says goodbye. ! 61: * ! 62: * Parameters: None. ! 63: * ! 64: * Returns: Exits. ! 65: * ! 66: * Side effects: Talks to client, does a lot of ! 67: * stuff. ! 68: */ ! 69: ! 70: serve() ! 71: { ! 72: char line[MAX_STRLEN], host[MAX_STRLEN]; ! 73: char **argp; ! 74: char *timeptr, *cp; ! 75: int argnum, i; ! 76: struct passwd *pp; ! 77: long clock, time(); ! 78: char *ctime(); ! 79: ! 80: #ifdef LOG ! 81: struct rusage rusagebuf; ! 82: ! 83: grps_acsd = arts_acsd = 0; ! 84: #endif ! 85: ! 86: #ifdef BSD_42 ! 87: openlog("nntpd", LOG_PID); ! 88: #else ! 89: openlog("nntpd", LOG_PID, LOG_FACILITY); ! 90: #endif ! 91: ! 92: /* Get permissions and see if we can talk to this client */ ! 93: ! 94: host_access(&canread, &canpost, &canxfer); ! 95: ! 96: if (gethostname(host, sizeof(host)) < 0) ! 97: (void) strcpy(host, "Unknown host"); ! 98: ! 99: if (!canread && !canxfer) { ! 100: printf("%d %s NNTP server can't talk to you. Goodbye.\r\n", ! 101: ERR_ACCESS, host); ! 102: (void) fflush(stdout); ! 103: #ifdef LOG ! 104: syslog(LOG_INFO, "%s refused connection", hostname); ! 105: #endif ! 106: exit(1); ! 107: } ! 108: ! 109: /* If we can talk, proceed with initialization */ ! 110: ! 111: #ifdef POSTER ! 112: pp = getpwnam(POSTER); ! 113: if (pp != NULL) { ! 114: uid_poster = pp->pw_uid; ! 115: gid_poster = pp->pw_gid; ! 116: } else ! 117: #endif ! 118: uid_poster = gid_poster = 0; ! 119: ! 120: #ifndef FASTFORK ! 121: num_groups = 0; ! 122: num_groups = read_groups(); /* Read in the active file */ ! 123: #else ! 124: signal(SIGALRM, SIG_IGN); /* Children don't deal with */ ! 125: /* these things */ ! 126: #endif ! 127: ! 128: art_fp = NULL; ! 129: argp = (char **) NULL; /* for first time */ ! 130: ! 131: (void) time(&clock); ! 132: timeptr = ctime(&clock); ! 133: if ((cp = index(timeptr, '\n')) != NULL) ! 134: *cp = '\0'; ! 135: else ! 136: timeptr = "Unknown date"; ! 137: ! 138: printf("%d %s NNTP server version %s ready at %s (%s).\r\n", ! 139: canpost ? OK_CANPOST : OK_NOPOST, ! 140: host, version, ! 141: timeptr, ! 142: canpost ? "posting ok" : "no posting"); ! 143: (void) fflush(stdout); ! 144: ! 145: /* ! 146: * Now get commands one at a time and execute the ! 147: * appropriate routine to deal with them. ! 148: */ ! 149: ! 150: while (fgets(line, sizeof(line), stdin) != NULL) { ! 151: ! 152: cp = index(line, '\r'); /* Zap CR-LF */ ! 153: if (cp != NULL) ! 154: *cp = '\0'; ! 155: else { ! 156: cp = index(line, '\n'); ! 157: if (cp != NULL) ! 158: *cp = '\0'; ! 159: } ! 160: ! 161: if ((argnum = parsit(line, &argp)) == 0) ! 162: continue; /* Null command */ ! 163: else { ! 164: for (i = 0; i < NUMCMDS; ++i) ! 165: if (streql(cmdtbl[i].cmd_name, argp[0])) ! 166: break; ! 167: if (i < NUMCMDS) ! 168: (*cmdtbl[i].cmd_fctn)(argnum, argp); ! 169: else { ! 170: if (streql(argp[0], "quit")) ! 171: break; ! 172: printf("%d Command unrecognized.\r\n", ! 173: ERR_COMMAND); ! 174: (void) fflush(stdout); ! 175: } ! 176: } ! 177: } ! 178: ! 179: printf("%d %s closing connection. Goodbye.\r\n", OK_GOODBYE, host); ! 180: (void) fflush(stdout); ! 181: ! 182: #ifdef LOG ! 183: if (getrusage(RUSAGE_SELF, &rusagebuf) < 0) { ! 184: syslog(LOG_ERR, "getrusage RUSAGE_SELF: %m"); ! 185: syslog(LOG_INFO, "%s exit %d articles %d groups", hostname, ! 186: arts_acsd, grps_acsd); ! 187: } else { ! 188: syslog(LOG_INFO, "%s exit %d articles %d groups", ! 189: hostname, ! 190: arts_acsd, ! 191: grps_acsd); ! 192: syslog(LOG_INFO, "%s times user %d system %d elapsed %ld", ! 193: hostname, ! 194: rusagebuf.ru_utime.tv_sec, ! 195: rusagebuf.ru_stime.tv_sec, ! 196: time((long *) 0) - clock); ! 197: } ! 198: #endif ! 199: exit(0); ! 200: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.