Annotation of 43BSDTahoe/new/nntp/server/serve.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.