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: }