1: #ifndef lint
   2: static char *sccsid = "@(#)serve.c	1.29	(Berkeley) 2/6/88";
   3: #endif
   4: 
   5: /*
   6:  * Main server routine
   7:  */
   8: 
   9: #include "common.h"
  10: #include <signal.h>
  11: #ifdef USG
  12: #include <sys/times.h>
  13: #else
  14: #include <sys/time.h>
  15: #endif
  16: 
  17: #ifdef LOG
  18: # ifndef USG
  19: #  include <sys/resource.h>
  20: # endif not USG
  21: #endif
  22: 
  23: extern  int ahbs(), group(), help(), ihave();
  24: extern  int list(), newgroups(), newnews(), nextlast(), post();
  25: extern  int slave(), stat(), xhdr();
  26: 
  27: static struct cmdent {
  28:     char    *cmd_name;
  29:     int (*cmd_fctn)();
  30: } cmdtbl[] = {
  31:     "article",  ahbs,
  32:     "body",     ahbs,
  33:     "group",    group,
  34:     "head",     ahbs,
  35:     "help",     help,
  36:     "ihave",    ihave,
  37:     "last",     nextlast,
  38:     "list",     list,
  39:     "newgroups",    newgroups,
  40:     "newnews",  newnews,
  41:     "next",     nextlast,
  42:     "post",     post,
  43:     "slave",    slave,
  44:     "stat",     ahbs,
  45: #ifdef XHDR
  46:     "xhdr",     xhdr,
  47: #endif XHDR
  48: };
  49: #define NUMCMDS (sizeof(cmdtbl) / sizeof(struct cmdent))
  50: 
  51: 
  52: /*
  53:  * serve -- given a connection on stdin/stdout, serve
  54:  *	a client, executing commands until the client
  55:  *	says goodbye.
  56:  *
  57:  *	Parameters:	None.
  58:  *
  59:  *	Returns:	Exits.
  60:  *
  61:  *	Side effects:	Talks to client, does a lot of
  62:  *			stuff.
  63:  */
  64: 
  65: serve()
  66: {
  67:     char        line[NNTP_STRLEN];
  68:     char        host[MAXHOSTNAMELEN];
  69:     char        gdbuf[MAXBUFLEN];
  70:     char        **argp;
  71:     char        *timeptr, *cp;
  72:     int     argnum, i;
  73:     double      Tstart, Tfinish;
  74:     double      user, sys;
  75: #ifdef USG
  76:     time_t      start, finish;
  77: #else not USG
  78:     struct timeval  start, finish;
  79: #endif not USG
  80:     extern char *ctime();
  81: #ifdef POSTER
  82:     struct passwd   *pp;
  83: #endif
  84: #ifdef LOG
  85: # ifdef USG
  86:     struct tms  cpu;
  87: # else not USG
  88:     struct rusage   me, kids;
  89: # endif not USG
  90: # ifdef TIMEOUT
  91:     void        timeout();
  92: # endif
  93: 
  94:     grps_acsd = arts_acsd = 0;
  95: #endif
  96: 
  97:     /* Not all systems pass fd's 1 and 2 from inetd */
  98: 
  99:     (void) close(1);
 100:     (void) close(2);
 101:     (void) dup(0);
 102:     (void) dup(0);
 103: 
 104:     /* If we're ALONE, then we've already opened syslog */
 105: 
 106: #ifndef ALONE
 107: # ifdef SYSLOG
 108: #  ifdef BSD_42
 109:     openlog("nntpd", LOG_PID);
 110: #  else
 111:     openlog("nntpd", LOG_PID, SYSLOG);
 112: #  endif
 113: # endif
 114: #endif
 115: 
 116: #ifdef ALONE
 117: #ifndef USG
 118:     (void) signal(SIGCHLD, SIG_IGN);
 119: #endif not USG
 120: #endif
 121: 
 122:     /* Ignore SIGPIPE, since we'll see closed connections with read */
 123: 
 124:     (void) signal(SIGPIPE, SIG_IGN);
 125: 
 126:     /* Get permissions and see if we can talk to this client */
 127: 
 128:     host_access(&canread, &canpost, &canxfer, gdbuf);
 129: 
 130:     if (gethostname(host, sizeof(host)) < 0)
 131:         (void) strcpy(host, "Amnesiac");
 132: 
 133:     if (!canread && !canxfer) {
 134:         printf("%d %s NNTP server can't talk to you.  Goodbye.\r\n",
 135:             ERR_ACCESS, host);
 136:         (void) fflush(stdout);
 137: #ifdef LOG
 138:         syslog(LOG_INFO, "%s refused connection", hostname);
 139: #endif
 140:         exit(1);
 141:     }
 142: 
 143:     /* If we can talk, proceed with initialization */
 144: 
 145:     ngpermcount = get_nglist(&ngpermlist, gdbuf);
 146: 
 147: #ifdef POSTER
 148:     pp = getpwnam(POSTER);
 149:     if (pp != NULL) {
 150:         uid_poster = pp->pw_uid;
 151:         gid_poster = pp->pw_gid;
 152:     } else
 153: #endif
 154:         uid_poster = gid_poster = 0;
 155: 
 156: #ifndef FASTFORK
 157:     num_groups = 0;
 158:     num_groups = read_groups(); /* Read in the active file */
 159: #else
 160:     signal(SIGALRM, SIG_IGN);   /* Children don't deal with */
 161:                     /* these things */
 162: #endif
 163: 
 164:     art_fp = NULL;
 165:     argp = (char **) NULL;      /* for first time */
 166: 
 167: #ifdef USG
 168:     (void) time(&start);
 169:     Tstart = (double) start;
 170:     timeptr = ctime(&start);
 171: #else not USG
 172:     (void) gettimeofday(&start, (struct timezone *)NULL);
 173:     Tstart = (double) start.tv_sec - ((double)start.tv_usec)/1000000.0;
 174:     timeptr = ctime(&start.tv_sec);
 175: #endif not USG
 176:     if ((cp = index(timeptr, '\n')) != NULL)
 177:         *cp = '\0';
 178:     else
 179:         timeptr = "Unknown date";
 180: 
 181:     printf("%d %s NNTP server version %s ready at %s (%s).\r\n",
 182:         canpost ? OK_CANPOST : OK_NOPOST,
 183:         host, nntp_version,
 184:         timeptr,
 185:         canpost ? "posting ok" : "no posting");
 186:     (void) fflush(stdout);
 187: 
 188:     /*
 189: 	 * Now get commands one at a time and execute the
 190: 	 * appropriate routine to deal with them.
 191: 	 */
 192: 
 193: #ifdef TIMEOUT
 194:     (void) signal(SIGALRM, timeout);
 195:     (void) alarm(TIMEOUT);
 196: #endif TIMEOUT
 197: 
 198:     while (fgets(line, sizeof(line), stdin) != NULL) {
 199: #ifdef TIMEOUT
 200:         (void) alarm(0);
 201: #endif TIMEOUT
 202: 
 203:         cp = index(line, '\r');     /* Zap CR-LF */
 204:         if (cp != NULL)
 205:             *cp = '\0';
 206:         else {
 207:             cp = index(line, '\n');
 208:             if (cp != NULL)
 209:                 *cp = '\0';
 210:         }
 211: 
 212:         if ((argnum = parsit(line, &argp)) == 0)
 213:             continue;       /* Null command */
 214:         else {
 215:             for (i = 0; i < NUMCMDS; ++i)
 216:                 if (!strcasecmp(cmdtbl[i].cmd_name, argp[0]))
 217:                     break;
 218:             if (i < NUMCMDS)
 219:                 (*cmdtbl[i].cmd_fctn)(argnum, argp);
 220:             else {
 221:                 if (!strcasecmp(argp[0], "quit"))
 222:                     break;
 223: #ifdef LOG
 224:                 syslog(LOG_INFO, "%s unrecognized %s",
 225:                     hostname,
 226:                     line);
 227: #endif
 228:                 printf("%d Command unrecognized.\r\n",
 229:                     ERR_COMMAND);
 230:                 (void) fflush(stdout);
 231:             }
 232:         }
 233: #ifdef TIMEOUT
 234:         (void) alarm(TIMEOUT);
 235: #endif TIMEOUT
 236:     }
 237: 
 238:     printf("%d %s closing connection.  Goodbye.\r\n", OK_GOODBYE, host);
 239:     (void) fflush(stdout);
 240: 
 241: 
 242: #ifdef LOG
 243:     if (ferror(stdout))
 244:         syslog(LOG_ERR, "%s disconnect: %m", hostname);
 245: 
 246: #ifdef USG
 247:     (void) time(&finish);
 248:     Tfinish = (double) finish;
 249: 
 250: #ifndef HZ
 251: #define HZ  60.0    /* typical system clock ticks - param.h */
 252: #endif not HZ
 253: 
 254:     (void) times(&cpu);
 255:     user = (double)(cpu.tms_utime + cpu.tms_cutime) / HZ;
 256:     sys  = (double)(cpu.tms_stime + cpu.tms_cstime) / HZ;
 257: #else not USG
 258:     (void) gettimeofday(&finish, (struct timezone *)NULL);
 259:     Tfinish = (double) finish.tv_sec - ((double)finish.tv_usec)/1000000.0;
 260: 
 261:     (void) getrusage(RUSAGE_SELF, &me);
 262:     (void) getrusage(RUSAGE_CHILDREN, &kids);
 263: 
 264:     user = (double) me.ru_utime.tv_sec + me.ru_utime.tv_usec/1000000.0 +
 265:         kids.ru_utime.tv_sec + kids.ru_utime.tv_usec/1000000.0;
 266:     sys = (double) me.ru_stime.tv_sec + me.ru_stime.tv_usec/1000000.0 +
 267:         kids.ru_stime.tv_sec + kids.ru_stime.tv_usec/1000000.0;
 268: #endif not USG
 269:     if (grps_acsd)
 270:         syslog(LOG_INFO, "%s exit %d articles %d groups",
 271:             hostname, arts_acsd, grps_acsd);
 272:     if (nn_told)
 273:         syslog(LOG_INFO, "%s newnews_stats told %d took %d",
 274:             hostname, nn_told, nn_took);
 275:     if (ih_accepted || ih_rejected || ih_failed)
 276:         syslog(LOG_INFO,
 277:             "%s ihave_stats accepted %d rejected %d failed %d",
 278:             hostname,
 279:             ih_accepted,
 280:             ih_rejected,
 281:             ih_failed);
 282:     (void) sprintf(line, "user %.1f system %.1f elapsed %.1f",
 283:         user, sys, Tfinish - Tstart);
 284:     syslog(LOG_INFO, "%s times %s", hostname, line);
 285: #endif LOG
 286: 
 287: #ifdef PROFILE
 288:     profile();
 289: #endif
 290: 
 291:     exit(0);
 292: }
 293: 
 294: 
 295: #ifdef TIMEOUT
 296: /*
 297:  * No activity for TIMEOUT seconds, so print an error message
 298:  * and close the connection.
 299:  */
 300: 
 301: void
 302: timeout()
 303: {
 304:     printf("%d Timeout after %d seconds, closing connection.\r\n",
 305:         ERR_FAULT, TIMEOUT);
 306:     (void) fflush(stdout);
 307: 
 308: #ifdef LOG
 309:     syslog(LOG_ERR, "%s timeout", hostname);
 310: #endif LOG
 311: 
 312:     exit(1);
 313: }
 314: #endif TIMEOUT

Defined functions

serve defined in line 65; used 2 times
timeout defined in line 301; used 2 times

Defined variables

cmdtbl defined in line 30; used 3 times
sccsid defined in line 2; never used

Defined struct's

cmdent defined in line 27; never used

Defined macros

HZ defined in line 251; used 3 times
NUMCMDS defined in line 49; used 2 times
Last modified: 1988-02-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4401
Valid CSS Valid XHTML 1.0 Strict