Annotation of 43BSDTahoe/etc/syslogd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983, 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that the above copyright notice and this paragraph are
        !             7:  * duplicated in all such forms and that any documentation,
        !             8:  * advertising materials, and other materials related to such
        !             9:  * distribution and use acknowledge that the software was developed
        !            10:  * by the University of California, Berkeley.  The name of the
        !            11:  * University may not be used to endorse or promote products derived
        !            12:  * from this software without specific prior written permission.
        !            13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            16:  */
        !            17: 
        !            18: #ifndef lint
        !            19: char copyright[] =
        !            20: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
        !            21:  All rights reserved.\n";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #ifndef lint
        !            25: static char sccsid[] = "@(#)syslogd.c  5.24 (Berkeley) 6/18/88";
        !            26: #endif /* not lint */
        !            27: 
        !            28: /*
        !            29:  *  syslogd -- log system messages
        !            30:  *
        !            31:  * This program implements a system log. It takes a series of lines.
        !            32:  * Each line may have a priority, signified as "<n>" as
        !            33:  * the first characters of the line.  If this is
        !            34:  * not present, a default priority is used.
        !            35:  *
        !            36:  * To kill syslogd, send a signal 15 (terminate).  A signal 1 (hup) will
        !            37:  * cause it to reread its configuration file.
        !            38:  *
        !            39:  * Defined Constants:
        !            40:  *
        !            41:  * MAXLINE -- the maximimum line length that can be handled.
        !            42:  * DEFUPRI -- the default priority for user messages
        !            43:  * DEFSPRI -- the default priority for kernel messages
        !            44:  *
        !            45:  * Author: Eric Allman
        !            46:  * extensive changes by Ralph Campbell
        !            47:  * more extensive changes by Eric Allman (again)
        !            48:  */
        !            49: 
        !            50: #define        MAXLINE         1024            /* maximum line length */
        !            51: #define        MAXSVLINE       120             /* maximum saved line length */
        !            52: #define DEFUPRI                (LOG_USER|LOG_NOTICE)
        !            53: #define DEFSPRI                (LOG_KERN|LOG_CRIT)
        !            54: #define TIMERINTVL     30              /* interval for checking flush, mark */
        !            55: 
        !            56: #include <stdio.h>
        !            57: #include <utmp.h>
        !            58: #include <ctype.h>
        !            59: #include <strings.h>
        !            60: #include <setjmp.h>
        !            61: 
        !            62: #include <sys/syslog.h>
        !            63: #include <sys/param.h>
        !            64: #include <sys/errno.h>
        !            65: #include <sys/ioctl.h>
        !            66: #include <sys/stat.h>
        !            67: #include <sys/wait.h>
        !            68: #include <sys/socket.h>
        !            69: #include <sys/file.h>
        !            70: #include <sys/msgbuf.h>
        !            71: #include <sys/uio.h>
        !            72: #include <sys/un.h>
        !            73: #include <sys/time.h>
        !            74: #include <sys/resource.h>
        !            75: #include <sys/signal.h>
        !            76: 
        !            77: #include <netinet/in.h>
        !            78: #include <netdb.h>
        !            79: 
        !            80: #define        CTTY    "/dev/console"
        !            81: char   *LogName = "/dev/log";
        !            82: char   *ConfFile = "/etc/syslog.conf";
        !            83: char   *PidFile = "/etc/syslog.pid";
        !            84: char   ctty[] = CTTY;
        !            85: 
        !            86: #define FDMASK(fd)     (1 << (fd))
        !            87: 
        !            88: #define        dprintf         if (Debug) printf
        !            89: 
        !            90: #define UNAMESZ                8       /* length of a login name */
        !            91: #define MAXUNAMES      20      /* maximum number of user names */
        !            92: #define MAXFNAME       200     /* max file pathname length */
        !            93: 
        !            94: #define NOPRI          0x10    /* the "no priority" priority */
        !            95: #define        LOG_MARK        LOG_MAKEPRI(LOG_NFACILITIES, 0) /* mark "facility" */
        !            96: 
        !            97: /*
        !            98:  * Flags to logmsg().
        !            99:  */
        !           100: 
        !           101: #define IGN_CONS       0x001   /* don't print on console */
        !           102: #define SYNC_FILE      0x002   /* do fsync on file after printing */
        !           103: #define ADDDATE                0x004   /* add a date to the message */
        !           104: #define MARK           0x008   /* this message is a mark */
        !           105: 
        !           106: /*
        !           107:  * This structure represents the files that will have log
        !           108:  * copies printed.
        !           109:  */
        !           110: 
        !           111: struct filed {
        !           112:        struct  filed *f_next;          /* next in linked list */
        !           113:        short   f_type;                 /* entry type, see below */
        !           114:        short   f_file;                 /* file descriptor */
        !           115:        time_t  f_time;                 /* time this was last written */
        !           116:        u_char  f_pmask[LOG_NFACILITIES+1];     /* priority mask */
        !           117:        union {
        !           118:                char    f_uname[MAXUNAMES][UNAMESZ+1];
        !           119:                struct {
        !           120:                        char    f_hname[MAXHOSTNAMELEN+1];
        !           121:                        struct sockaddr_in      f_addr;
        !           122:                } f_forw;               /* forwarding address */
        !           123:                char    f_fname[MAXFNAME];
        !           124:        } f_un;
        !           125:        char    f_prevline[MAXSVLINE];          /* last message logged */
        !           126:        char    f_lasttime[16];                 /* time of last occurrence */
        !           127:        char    f_prevhost[MAXHOSTNAMELEN+1];   /* host from which recd. */
        !           128:        int     f_prevpri;                      /* pri of f_prevline */
        !           129:        int     f_prevlen;                      /* length of f_prevline */
        !           130:        int     f_prevcount;                    /* repetition cnt of prevline */
        !           131:        int     f_repeatcount;                  /* number of "repeated" msgs */
        !           132: };
        !           133: 
        !           134: /*
        !           135:  * Intervals at which we flush out "message repeated" messages,
        !           136:  * in seconds after previous message is logged.  After each flush,
        !           137:  * we move to the next interval until we reach the largest.
        !           138:  */
        !           139: int    repeatinterval[] = { 30, 120, 600 };    /* # of secs before flush */
        !           140: #define        MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
        !           141: #define        REPEATTIME(f)   ((f)->f_time + repeatinterval[(f)->f_repeatcount])
        !           142: #define        BACKOFF(f)      { if (++(f)->f_repeatcount > MAXREPEAT) \
        !           143:                                 (f)->f_repeatcount = MAXREPEAT; \
        !           144:                        }
        !           145: 
        !           146: /* values for f_type */
        !           147: #define F_UNUSED       0               /* unused entry */
        !           148: #define F_FILE         1               /* regular file */
        !           149: #define F_TTY          2               /* terminal */
        !           150: #define F_CONSOLE      3               /* console terminal */
        !           151: #define F_FORW         4               /* remote machine */
        !           152: #define F_USERS                5               /* list of users */
        !           153: #define F_WALL         6               /* everyone logged on */
        !           154: 
        !           155: char   *TypeNames[7] = {
        !           156:        "UNUSED",       "FILE",         "TTY",          "CONSOLE",
        !           157:        "FORW",         "USERS",        "WALL"
        !           158: };
        !           159: 
        !           160: struct filed *Files;
        !           161: struct filed consfile;
        !           162: 
        !           163: int    Debug;                  /* debug flag */
        !           164: char   LocalHostName[MAXHOSTNAMELEN+1];        /* our hostname */
        !           165: char   *LocalDomain;           /* our local domain name */
        !           166: int    InetInuse = 0;          /* non-zero if INET sockets are being used */
        !           167: int    finet;                  /* Internet datagram socket */
        !           168: int    LogPort;                /* port number for INET connections */
        !           169: int    Initialized = 0;        /* set when we have initialized ourselves */
        !           170: int    MarkInterval = 20 * 60; /* interval between marks in seconds */
        !           171: int    MarkSeq = 0;            /* mark sequence number */
        !           172: 
        !           173: extern int errno, sys_nerr;
        !           174: extern char *sys_errlist[];
        !           175: extern char *ctime(), *index(), *calloc();
        !           176: 
        !           177: main(argc, argv)
        !           178:        int argc;
        !           179:        char **argv;
        !           180: {
        !           181:        register int i;
        !           182:        register char *p;
        !           183:        int funix, inetm, fklog, klogm, len;
        !           184:        struct sockaddr_un sunx, fromunix;
        !           185:        struct sockaddr_in sin, frominet;
        !           186:        FILE *fp;
        !           187:        char line[MSG_BSIZE + 1];
        !           188:        extern int die(), domark(), reapchild();
        !           189: 
        !           190:        while (--argc > 0) {
        !           191:                p = *++argv;
        !           192:                if (p[0] != '-')
        !           193:                        usage();
        !           194:                switch (p[1]) {
        !           195:                case 'f':               /* configuration file */
        !           196:                        if (p[2] != '\0')
        !           197:                                ConfFile = &p[2];
        !           198:                        break;
        !           199: 
        !           200:                case 'd':               /* debug */
        !           201:                        Debug++;
        !           202:                        break;
        !           203: 
        !           204:                case 'p':               /* path */
        !           205:                        if (p[2] != '\0')
        !           206:                                LogName = &p[2];
        !           207:                        break;
        !           208: 
        !           209:                case 'm':               /* mark interval */
        !           210:                        if (p[2] != '\0')
        !           211:                                MarkInterval = atoi(&p[2]) * 60;
        !           212:                        break;
        !           213: 
        !           214:                default:
        !           215:                        usage();
        !           216:                }
        !           217:        }
        !           218: 
        !           219:        if (!Debug) {
        !           220:                if (fork())
        !           221:                        exit(0);
        !           222:                for (i = 0; i < 10; i++)
        !           223:                        (void) close(i);
        !           224:                (void) open("/", 0);
        !           225:                (void) dup2(0, 1);
        !           226:                (void) dup2(0, 2);
        !           227:                untty();
        !           228:        } else
        !           229:                setlinebuf(stdout);
        !           230: 
        !           231:        consfile.f_type = F_CONSOLE;
        !           232:        (void) strcpy(consfile.f_un.f_fname, ctty);
        !           233:        (void) gethostname(LocalHostName, sizeof LocalHostName);
        !           234:        if (p = index(LocalHostName, '.')) {
        !           235:                *p++ = '\0';
        !           236:                LocalDomain = p;
        !           237:        }
        !           238:        else
        !           239:                LocalDomain = "";
        !           240:        (void) signal(SIGTERM, die);
        !           241:        (void) signal(SIGINT, Debug ? die : SIG_IGN);
        !           242:        (void) signal(SIGQUIT, Debug ? die : SIG_IGN);
        !           243:        (void) signal(SIGCHLD, reapchild);
        !           244:        (void) signal(SIGALRM, domark);
        !           245:        (void) alarm(TIMERINTVL);
        !           246:        (void) unlink(LogName);
        !           247: 
        !           248:        sunx.sun_family = AF_UNIX;
        !           249:        (void) strncpy(sunx.sun_path, LogName, sizeof sunx.sun_path);
        !           250:        funix = socket(AF_UNIX, SOCK_DGRAM, 0);
        !           251:        if (funix < 0 || bind(funix, (struct sockaddr *) &sunx,
        !           252:            sizeof(sunx.sun_family)+strlen(sunx.sun_path)) < 0 ||
        !           253:            chmod(LogName, 0666) < 0) {
        !           254:                (void) sprintf(line, "cannot create %s", LogName);
        !           255:                logerror(line);
        !           256:                dprintf("cannot create %s (%d)\n", LogName, errno);
        !           257:                die(0);
        !           258:        }
        !           259:        finet = socket(AF_INET, SOCK_DGRAM, 0);
        !           260:        if (finet >= 0) {
        !           261:                struct servent *sp;
        !           262: 
        !           263:                sp = getservbyname("syslog", "udp");
        !           264:                if (sp == NULL) {
        !           265:                        errno = 0;
        !           266:                        logerror("syslog/udp: unknown service");
        !           267:                        die(0);
        !           268:                }
        !           269:                sin.sin_family = AF_INET;
        !           270:                sin.sin_port = LogPort = sp->s_port;
        !           271:                if (bind(finet, &sin, sizeof(sin)) < 0) {
        !           272:                        logerror("bind");
        !           273:                        if (!Debug)
        !           274:                                die(0);
        !           275:                } else {
        !           276:                        inetm = FDMASK(finet);
        !           277:                        InetInuse = 1;
        !           278:                }
        !           279:        }
        !           280:        if ((fklog = open("/dev/klog", O_RDONLY)) >= 0)
        !           281:                klogm = FDMASK(fklog);
        !           282:        else {
        !           283:                dprintf("can't open /dev/klog (%d)\n", errno);
        !           284:                klogm = 0;
        !           285:        }
        !           286: 
        !           287:        /* tuck my process id away */
        !           288:        fp = fopen(PidFile, "w");
        !           289:        if (fp != NULL) {
        !           290:                fprintf(fp, "%d\n", getpid());
        !           291:                (void) fclose(fp);
        !           292:        }
        !           293: 
        !           294:        dprintf("off & running....\n");
        !           295: 
        !           296:        init();
        !           297:        (void) signal(SIGHUP, init);
        !           298: 
        !           299:        for (;;) {
        !           300:                int nfds, readfds = FDMASK(funix) | inetm | klogm;
        !           301: 
        !           302:                errno = 0;
        !           303:                dprintf("readfds = %#x\n", readfds);
        !           304:                nfds = select(20, (fd_set *) &readfds, (fd_set *) NULL,
        !           305:                                  (fd_set *) NULL, (struct timeval *) NULL);
        !           306:                if (nfds == 0)
        !           307:                        continue;
        !           308:                if (nfds < 0) {
        !           309:                        if (errno != EINTR)
        !           310:                                logerror("select");
        !           311:                        continue;
        !           312:                }
        !           313:                dprintf("got a message (%d, %#x)\n", nfds, readfds);
        !           314:                if (readfds & klogm) {
        !           315:                        i = read(fklog, line, sizeof(line) - 1);
        !           316:                        if (i > 0) {
        !           317:                                line[i] = '\0';
        !           318:                                printsys(line);
        !           319:                        } else if (i < 0 && errno != EINTR) {
        !           320:                                logerror("klog");
        !           321:                                fklog = -1;
        !           322:                                klogm = 0;
        !           323:                        }
        !           324:                }
        !           325:                if (readfds & FDMASK(funix)) {
        !           326:                        len = sizeof fromunix;
        !           327:                        i = recvfrom(funix, line, MAXLINE, 0,
        !           328:                                     (struct sockaddr *) &fromunix, &len);
        !           329:                        if (i > 0) {
        !           330:                                line[i] = '\0';
        !           331:                                printline(LocalHostName, line);
        !           332:                        } else if (i < 0 && errno != EINTR)
        !           333:                                logerror("recvfrom unix");
        !           334:                }
        !           335:                if (readfds & inetm) {
        !           336:                        len = sizeof frominet;
        !           337:                        i = recvfrom(finet, line, MAXLINE, 0, &frominet, &len);
        !           338:                        if (i > 0) {
        !           339:                                extern char *cvthname();
        !           340: 
        !           341:                                line[i] = '\0';
        !           342:                                printline(cvthname(&frominet), line);
        !           343:                        } else if (i < 0 && errno != EINTR)
        !           344:                                logerror("recvfrom inet");
        !           345:                } 
        !           346:        }
        !           347: }
        !           348: 
        !           349: usage()
        !           350: {
        !           351:        fprintf(stderr, "usage: syslogd [-d] [-mmarkinterval] [-ppath] [-fconffile]\n");
        !           352:        exit(1);
        !           353: }
        !           354: 
        !           355: untty()
        !           356: {
        !           357:        int i;
        !           358: 
        !           359:        if (!Debug) {
        !           360:                i = open("/dev/tty", O_RDWR);
        !           361:                if (i >= 0) {
        !           362:                        (void) ioctl(i, (int) TIOCNOTTY, (char *)0);
        !           363:                        (void) close(i);
        !           364:                }
        !           365:        }
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * Take a raw input line, decode the message, and print the message
        !           370:  * on the appropriate log files.
        !           371:  */
        !           372: 
        !           373: printline(hname, msg)
        !           374:        char *hname;
        !           375:        char *msg;
        !           376: {
        !           377:        register char *p, *q;
        !           378:        register int c;
        !           379:        char line[MAXLINE + 1];
        !           380:        int pri;
        !           381: 
        !           382:        /* test for special codes */
        !           383:        pri = DEFUPRI;
        !           384:        p = msg;
        !           385:        if (*p == '<') {
        !           386:                pri = 0;
        !           387:                while (isdigit(*++p))
        !           388:                        pri = 10 * pri + (*p - '0');
        !           389:                if (*p == '>')
        !           390:                        ++p;
        !           391:        }
        !           392:        if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
        !           393:                pri = DEFUPRI;
        !           394: 
        !           395:        /* don't allow users to log kernel messages */
        !           396:        if (LOG_FAC(pri) == LOG_KERN)
        !           397:                pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
        !           398: 
        !           399:        q = line;
        !           400: 
        !           401:        while ((c = *p++ & 0177) != '\0' && c != '\n' &&
        !           402:            q < &line[sizeof(line) - 1]) {
        !           403:                if (iscntrl(c)) {
        !           404:                        *q++ = '^';
        !           405:                        *q++ = c ^ 0100;
        !           406:                } else
        !           407:                        *q++ = c;
        !           408:        }
        !           409:        *q = '\0';
        !           410: 
        !           411:        logmsg(pri, line, hname, 0);
        !           412: }
        !           413: 
        !           414: /*
        !           415:  * Take a raw input line from /dev/klog, split and format similar to syslog().
        !           416:  */
        !           417: 
        !           418: printsys(msg)
        !           419:        char *msg;
        !           420: {
        !           421:        register char *p, *q;
        !           422:        register int c;
        !           423:        char line[MAXLINE + 1];
        !           424:        int pri, flags;
        !           425:        char *lp;
        !           426: 
        !           427:        (void) sprintf(line, "vmunix: ");
        !           428:        lp = line + strlen(line);
        !           429:        for (p = msg; *p != '\0'; ) {
        !           430:                flags = SYNC_FILE | ADDDATE;    /* fsync file after write */
        !           431:                pri = DEFSPRI;
        !           432:                if (*p == '<') {
        !           433:                        pri = 0;
        !           434:                        while (isdigit(*++p))
        !           435:                                pri = 10 * pri + (*p - '0');
        !           436:                        if (*p == '>')
        !           437:                                ++p;
        !           438:                } else {
        !           439:                        /* kernel printf's come out on console */
        !           440:                        flags |= IGN_CONS;
        !           441:                }
        !           442:                if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
        !           443:                        pri = DEFSPRI;
        !           444:                q = lp;
        !           445:                while (*p != '\0' && (c = *p++) != '\n' &&
        !           446:                    q < &line[MAXLINE])
        !           447:                        *q++ = c;
        !           448:                *q = '\0';
        !           449:                logmsg(pri, line, LocalHostName, flags);
        !           450:        }
        !           451: }
        !           452: 
        !           453: time_t now;
        !           454: 
        !           455: /*
        !           456:  * Log a message to the appropriate log files, users, etc. based on
        !           457:  * the priority.
        !           458:  */
        !           459: 
        !           460: logmsg(pri, msg, from, flags)
        !           461:        int pri;
        !           462:        char *msg, *from;
        !           463:        int flags;
        !           464: {
        !           465:        register struct filed *f;
        !           466:        int fac, prilev;
        !           467:        int omask, msglen;
        !           468:        char *timestamp;
        !           469: 
        !           470:        dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", pri, flags, from, msg);
        !           471: 
        !           472:        omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
        !           473: 
        !           474:        /*
        !           475:         * Check to see if msg looks non-standard.
        !           476:         */
        !           477:        msglen = strlen(msg);
        !           478:        if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
        !           479:            msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')
        !           480:                flags |= ADDDATE;
        !           481: 
        !           482:        (void) time(&now);
        !           483:        if (flags & ADDDATE)
        !           484:                timestamp = ctime(&now) + 4;
        !           485:        else {
        !           486:                timestamp = msg;
        !           487:                msg += 16;
        !           488:                msglen -= 16;
        !           489:        }
        !           490: 
        !           491:        /* extract facility and priority level */
        !           492:        if (flags & MARK)
        !           493:                fac = LOG_NFACILITIES;
        !           494:        else
        !           495:                fac = LOG_FAC(pri);
        !           496:        prilev = LOG_PRI(pri);
        !           497: 
        !           498:        /* log the message to the particular outputs */
        !           499:        if (!Initialized) {
        !           500:                f = &consfile;
        !           501:                f->f_file = open(ctty, O_WRONLY);
        !           502: 
        !           503:                if (f->f_file >= 0) {
        !           504:                        untty();
        !           505:                        fprintlog(f, flags, (char *)NULL);
        !           506:                        (void) close(f->f_file);
        !           507:                }
        !           508:                (void) sigsetmask(omask);
        !           509:                return;
        !           510:        }
        !           511:        for (f = Files; f; f = f->f_next) {
        !           512:                /* skip messages that are incorrect priority */
        !           513:                if (f->f_pmask[fac] < prilev || f->f_pmask[fac] == NOPRI)
        !           514:                        continue;
        !           515: 
        !           516:                if (f->f_type == F_CONSOLE && (flags & IGN_CONS))
        !           517:                        continue;
        !           518: 
        !           519:                /* don't output marks to recently written files */
        !           520:                if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2)
        !           521:                        continue;
        !           522: 
        !           523:                /*
        !           524:                 * suppress duplicate lines to this file
        !           525:                 */
        !           526:                if ((flags & MARK) == 0 && msglen == f->f_prevlen &&
        !           527:                    !strcmp(msg, f->f_prevline) &&
        !           528:                    !strcmp(from, f->f_prevhost)) {
        !           529:                        (void) strncpy(f->f_lasttime, timestamp, 15);
        !           530:                        f->f_prevcount++;
        !           531:                        dprintf("msg repeated %d times, %d sec of %d\n",
        !           532:                            f->f_prevcount, now - f->f_time,
        !           533:                            repeatinterval[f->f_repeatcount]);
        !           534:                        /*
        !           535:                         * If domark would have logged this by now,
        !           536:                         * flush it now (so we don't hold isolated messages),
        !           537:                         * but back off so we'll flush less often
        !           538:                         * in the future.
        !           539:                         */
        !           540:                        if (now > REPEATTIME(f)) {
        !           541:                                fprintlog(f, flags, (char *)NULL);
        !           542:                                BACKOFF(f);
        !           543:                        }
        !           544:                } else {
        !           545:                        /* new line, save it */
        !           546:                        if (f->f_prevcount)
        !           547:                                fprintlog(f, 0, (char *)NULL);
        !           548:                        f->f_repeatcount = 0;
        !           549:                        (void) strncpy(f->f_lasttime, timestamp, 15);
        !           550:                        (void) strncpy(f->f_prevhost, from,
        !           551:                                        sizeof(f->f_prevhost));
        !           552:                        if (msglen < MAXSVLINE) {
        !           553:                                f->f_prevlen = msglen;
        !           554:                                f->f_prevpri = pri;
        !           555:                                (void) strcpy(f->f_prevline, msg);
        !           556:                                fprintlog(f, flags, (char *)NULL);
        !           557:                        } else {
        !           558:                                f->f_prevline[0] = 0;
        !           559:                                f->f_prevlen = 0;
        !           560:                                fprintlog(f, flags, msg);
        !           561:                        }
        !           562:                }
        !           563:        }
        !           564:        (void) sigsetmask(omask);
        !           565: }
        !           566: 
        !           567: fprintlog(f, flags, msg)
        !           568:        register struct filed *f;
        !           569:        int flags;
        !           570:        char *msg;
        !           571: {
        !           572:        struct iovec iov[6];
        !           573:        register struct iovec *v = iov;
        !           574:        register int l;
        !           575:        char line[MAXLINE + 1];
        !           576:        char repbuf[80];
        !           577: 
        !           578:        v->iov_base = f->f_lasttime;
        !           579:        v->iov_len = 15;
        !           580:        v++;
        !           581:        v->iov_base = " ";
        !           582:        v->iov_len = 1;
        !           583:        v++;
        !           584:        v->iov_base = f->f_prevhost;
        !           585:        v->iov_len = strlen(v->iov_base);
        !           586:        v++;
        !           587:        v->iov_base = " ";
        !           588:        v->iov_len = 1;
        !           589:        v++;
        !           590:        if (msg) {
        !           591:                v->iov_base = msg;
        !           592:                v->iov_len = strlen(msg);
        !           593:        } else if (f->f_prevcount > 1) {
        !           594:                (void) sprintf(repbuf, "last message repeated %d times",
        !           595:                    f->f_prevcount);
        !           596:                v->iov_base = repbuf;
        !           597:                v->iov_len = strlen(repbuf);
        !           598:        } else {
        !           599:                v->iov_base = f->f_prevline;
        !           600:                v->iov_len = f->f_prevlen;
        !           601:        }
        !           602:        v++;
        !           603: 
        !           604:        dprintf("Logging to %s", TypeNames[f->f_type]);
        !           605:        f->f_time = now;
        !           606: 
        !           607:        switch (f->f_type) {
        !           608:        case F_UNUSED:
        !           609:                dprintf("\n");
        !           610:                break;
        !           611: 
        !           612:        case F_FORW:
        !           613:                dprintf(" %s\n", f->f_un.f_forw.f_hname);
        !           614:                (void) sprintf(line, "<%d>%.15s %s", f->f_prevpri,
        !           615:                        iov[0].iov_base, iov[4].iov_base);
        !           616:                l = strlen(line);
        !           617:                if (l > MAXLINE)
        !           618:                        l = MAXLINE;
        !           619:                if (sendto(finet, line, l, 0, &f->f_un.f_forw.f_addr,
        !           620:                    sizeof f->f_un.f_forw.f_addr) != l) {
        !           621:                        int e = errno;
        !           622:                        (void) close(f->f_file);
        !           623:                        f->f_type = F_UNUSED;
        !           624:                        errno = e;
        !           625:                        logerror("sendto");
        !           626:                }
        !           627:                break;
        !           628: 
        !           629:        case F_CONSOLE:
        !           630:                if (flags & IGN_CONS) {
        !           631:                        dprintf(" (ignored)\n");
        !           632:                        break;
        !           633:                }
        !           634:                /* FALLTHROUGH */
        !           635: 
        !           636:        case F_TTY:
        !           637:        case F_FILE:
        !           638:                dprintf(" %s\n", f->f_un.f_fname);
        !           639:                if (f->f_type != F_FILE) {
        !           640:                        v->iov_base = "\r\n";
        !           641:                        v->iov_len = 2;
        !           642:                } else {
        !           643:                        v->iov_base = "\n";
        !           644:                        v->iov_len = 1;
        !           645:                }
        !           646:        again:
        !           647:                if (writev(f->f_file, iov, 6) < 0) {
        !           648:                        int e = errno;
        !           649:                        (void) close(f->f_file);
        !           650:                        /*
        !           651:                         * Check for EBADF on TTY's due to vhangup() XXX
        !           652:                         */
        !           653:                        if (e == EBADF && f->f_type != F_FILE) {
        !           654:                                f->f_file = open(f->f_un.f_fname, O_WRONLY|O_APPEND);
        !           655:                                if (f->f_file < 0) {
        !           656:                                        f->f_type = F_UNUSED;
        !           657:                                        logerror(f->f_un.f_fname);
        !           658:                                } else {
        !           659:                                        untty();
        !           660:                                        goto again;
        !           661:                                }
        !           662:                        } else {
        !           663:                                f->f_type = F_UNUSED;
        !           664:                                errno = e;
        !           665:                                logerror(f->f_un.f_fname);
        !           666:                        }
        !           667:                } else if (flags & SYNC_FILE)
        !           668:                        (void) fsync(f->f_file);
        !           669:                break;
        !           670: 
        !           671:        case F_USERS:
        !           672:        case F_WALL:
        !           673:                dprintf("\n");
        !           674:                v->iov_base = "\r\n";
        !           675:                v->iov_len = 2;
        !           676:                wallmsg(f, iov);
        !           677:                break;
        !           678:        }
        !           679:        f->f_prevcount = 0;
        !           680: }
        !           681: 
        !           682: jmp_buf ttybuf;
        !           683: 
        !           684: endtty()
        !           685: {
        !           686:        longjmp(ttybuf, 1);
        !           687: }
        !           688: 
        !           689: /*
        !           690:  *  WALLMSG -- Write a message to the world at large
        !           691:  *
        !           692:  *     Write the specified message to either the entire
        !           693:  *     world, or a list of approved users.
        !           694:  */
        !           695: 
        !           696: wallmsg(f, iov)
        !           697:        register struct filed *f;
        !           698:        struct iovec *iov;
        !           699: {
        !           700:        register char *p;
        !           701:        register int i;
        !           702:        int ttyf, len;
        !           703:        FILE *uf;
        !           704:        static int reenter = 0;
        !           705:        struct utmp ut;
        !           706:        char greetings[200];
        !           707: 
        !           708:        if (reenter++)
        !           709:                return;
        !           710: 
        !           711:        /* open the user login file */
        !           712:        if ((uf = fopen("/etc/utmp", "r")) == NULL) {
        !           713:                logerror("/etc/utmp");
        !           714:                reenter = 0;
        !           715:                return;
        !           716:        }
        !           717: 
        !           718:        /*
        !           719:         * Might as well fork instead of using nonblocking I/O
        !           720:         * and doing notty().
        !           721:         */
        !           722:        if (fork() == 0) {
        !           723:                (void) signal(SIGTERM, SIG_DFL);
        !           724:                (void) alarm(0);
        !           725:                (void) signal(SIGALRM, endtty);
        !           726:                (void) signal(SIGTTOU, SIG_IGN);
        !           727:                (void) sigsetmask(0);
        !           728:                (void) sprintf(greetings,
        !           729:                    "\r\n\7Message from syslogd@%s at %.24s ...\r\n",
        !           730:                        iov[2].iov_base, ctime(&now));
        !           731:                len = strlen(greetings);
        !           732: 
        !           733:                /* scan the user login file */
        !           734:                while (fread((char *) &ut, sizeof ut, 1, uf) == 1) {
        !           735:                        /* is this slot used? */
        !           736:                        if (ut.ut_name[0] == '\0')
        !           737:                                continue;
        !           738: 
        !           739:                        /* should we send the message to this user? */
        !           740:                        if (f->f_type == F_USERS) {
        !           741:                                for (i = 0; i < MAXUNAMES; i++) {
        !           742:                                        if (!f->f_un.f_uname[i][0]) {
        !           743:                                                i = MAXUNAMES;
        !           744:                                                break;
        !           745:                                        }
        !           746:                                        if (strncmp(f->f_un.f_uname[i],
        !           747:                                            ut.ut_name, UNAMESZ) == 0)
        !           748:                                                break;
        !           749:                                }
        !           750:                                if (i >= MAXUNAMES)
        !           751:                                        continue;
        !           752:                        }
        !           753: 
        !           754:                        /* compute the device name */
        !           755:                        p = "/dev/12345678";
        !           756:                        strncpy(&p[5], ut.ut_line, UNAMESZ);
        !           757: 
        !           758:                        if (f->f_type == F_WALL) {
        !           759:                                iov[0].iov_base = greetings;
        !           760:                                iov[0].iov_len = len;
        !           761:                                iov[1].iov_len = 0;
        !           762:                        }
        !           763:                        if (setjmp(ttybuf) == 0) {
        !           764:                                (void) alarm(15);
        !           765:                                /* open the terminal */
        !           766:                                ttyf = open(p, O_WRONLY);
        !           767:                                if (ttyf >= 0) {
        !           768:                                        struct stat statb;
        !           769: 
        !           770:                                        if (fstat(ttyf, &statb) == 0 &&
        !           771:                                            (statb.st_mode & S_IWRITE))
        !           772:                                                (void) writev(ttyf, iov, 6);
        !           773:                                        close(ttyf);
        !           774:                                        ttyf = -1;
        !           775:                                }
        !           776:                        }
        !           777:                        (void) alarm(0);
        !           778:                }
        !           779:                exit(0);
        !           780:        }
        !           781:        /* close the user login file */
        !           782:        (void) fclose(uf);
        !           783:        reenter = 0;
        !           784: }
        !           785: 
        !           786: reapchild()
        !           787: {
        !           788:        union wait status;
        !           789: 
        !           790:        while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
        !           791:                ;
        !           792: }
        !           793: 
        !           794: /*
        !           795:  * Return a printable representation of a host address.
        !           796:  */
        !           797: char *
        !           798: cvthname(f)
        !           799:        struct sockaddr_in *f;
        !           800: {
        !           801:        struct hostent *hp;
        !           802:        register char *p;
        !           803:        extern char *inet_ntoa();
        !           804: 
        !           805:        dprintf("cvthname(%s)\n", inet_ntoa(f->sin_addr));
        !           806: 
        !           807:        if (f->sin_family != AF_INET) {
        !           808:                dprintf("Malformed from address\n");
        !           809:                return ("???");
        !           810:        }
        !           811:        hp = gethostbyaddr(&f->sin_addr, sizeof(struct in_addr), f->sin_family);
        !           812:        if (hp == 0) {
        !           813:                dprintf("Host name for your address (%s) unknown\n",
        !           814:                        inet_ntoa(f->sin_addr));
        !           815:                return (inet_ntoa(f->sin_addr));
        !           816:        }
        !           817:        if ((p = index(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
        !           818:                *p = '\0';
        !           819:        return (hp->h_name);
        !           820: }
        !           821: 
        !           822: domark()
        !           823: {
        !           824:        register struct filed *f;
        !           825: 
        !           826:        now = time(0);
        !           827:        MarkSeq += TIMERINTVL;
        !           828:        if (MarkSeq >= MarkInterval) {
        !           829:                logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK);
        !           830:                MarkSeq = 0;
        !           831:        }
        !           832: 
        !           833:        for (f = Files; f; f = f->f_next) {
        !           834:                if (f->f_prevcount && now >= REPEATTIME(f)) {
        !           835:                        dprintf("flush %s: repeated %d times, %d sec.\n",
        !           836:                            TypeNames[f->f_type], f->f_prevcount,
        !           837:                            repeatinterval[f->f_repeatcount]);
        !           838:                        fprintlog(f, 0, (char *)NULL);
        !           839:                        BACKOFF(f);
        !           840:                }
        !           841:        }
        !           842:        (void) alarm(TIMERINTVL);
        !           843: }
        !           844: 
        !           845: /*
        !           846:  * Print syslogd errors some place.
        !           847:  */
        !           848: logerror(type)
        !           849:        char *type;
        !           850: {
        !           851:        char buf[100];
        !           852: 
        !           853:        if (errno == 0)
        !           854:                (void) sprintf(buf, "syslogd: %s", type);
        !           855:        else if ((unsigned) errno > sys_nerr)
        !           856:                (void) sprintf(buf, "syslogd: %s: error %d", type, errno);
        !           857:        else
        !           858:                (void) sprintf(buf, "syslogd: %s: %s", type, sys_errlist[errno]);
        !           859:        errno = 0;
        !           860:        dprintf("%s\n", buf);
        !           861:        logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE);
        !           862: }
        !           863: 
        !           864: die(sig)
        !           865: {
        !           866:        register struct filed *f;
        !           867:        char buf[100];
        !           868: 
        !           869:        for (f = Files; f != NULL; f = f->f_next) {
        !           870:                /* flush any pending output */
        !           871:                if (f->f_prevcount)
        !           872:                        fprintlog(f, 0, (char *)NULL);
        !           873:        }
        !           874:        if (sig) {
        !           875:                dprintf("syslogd: exiting on signal %d\n", sig);
        !           876:                (void) sprintf(buf, "exiting on signal %d", sig);
        !           877:                errno = 0;
        !           878:                logerror(buf);
        !           879:        }
        !           880:        (void) unlink(LogName);
        !           881:        exit(0);
        !           882: }
        !           883: 
        !           884: /*
        !           885:  *  INIT -- Initialize syslogd from configuration table
        !           886:  */
        !           887: 
        !           888: init()
        !           889: {
        !           890:        register int i;
        !           891:        register FILE *cf;
        !           892:        register struct filed *f, *next, **nextp;
        !           893:        register char *p;
        !           894:        char cline[BUFSIZ];
        !           895: 
        !           896:        dprintf("init\n");
        !           897: 
        !           898:        /*
        !           899:         *  Close all open log files.
        !           900:         */
        !           901:        Initialized = 0;
        !           902:        for (f = Files; f != NULL; f = next) {
        !           903:                /* flush any pending output */
        !           904:                if (f->f_prevcount)
        !           905:                        fprintlog(f, 0, (char *)NULL);
        !           906: 
        !           907:                switch (f->f_type) {
        !           908:                  case F_FILE:
        !           909:                  case F_TTY:
        !           910:                  case F_CONSOLE:
        !           911:                        (void) close(f->f_file);
        !           912:                        break;
        !           913:                }
        !           914:                next = f->f_next;
        !           915:                free((char *) f);
        !           916:        }
        !           917:        Files = NULL;
        !           918:        nextp = &Files;
        !           919: 
        !           920:        /* open the configuration file */
        !           921:        if ((cf = fopen(ConfFile, "r")) == NULL) {
        !           922:                dprintf("cannot open %s\n", ConfFile);
        !           923:                *nextp = (struct filed *)calloc(1, sizeof(*f));
        !           924:                cfline("*.ERR\t/dev/console", *nextp);
        !           925:                (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f));
        !           926:                cfline("*.PANIC\t*", (*nextp)->f_next);
        !           927:                Initialized = 1;
        !           928:                return;
        !           929:        }
        !           930: 
        !           931:        /*
        !           932:         *  Foreach line in the conf table, open that file.
        !           933:         */
        !           934:        f = NULL;
        !           935:        while (fgets(cline, sizeof cline, cf) != NULL) {
        !           936:                /*
        !           937:                 * check for end-of-section, comments, strip off trailing
        !           938:                 * spaces and newline character.
        !           939:                 */
        !           940:                for (p = cline; isspace(*p); ++p);
        !           941:                if (*p == NULL || *p == '#')
        !           942:                        continue;
        !           943:                for (p = index(cline, '\0'); isspace(*--p););
        !           944:                *++p = '\0';
        !           945:                f = (struct filed *)calloc(1, sizeof(*f));
        !           946:                *nextp = f;
        !           947:                nextp = &f->f_next;
        !           948:                cfline(cline, f);
        !           949:        }
        !           950: 
        !           951:        /* close the configuration file */
        !           952:        (void) fclose(cf);
        !           953: 
        !           954:        Initialized = 1;
        !           955: 
        !           956:        if (Debug) {
        !           957:                for (f = Files; f; f = f->f_next) {
        !           958:                        for (i = 0; i <= LOG_NFACILITIES; i++)
        !           959:                                if (f->f_pmask[i] == NOPRI)
        !           960:                                        printf("X ");
        !           961:                                else
        !           962:                                        printf("%d ", f->f_pmask[i]);
        !           963:                        printf("%s: ", TypeNames[f->f_type]);
        !           964:                        switch (f->f_type) {
        !           965:                        case F_FILE:
        !           966:                        case F_TTY:
        !           967:                        case F_CONSOLE:
        !           968:                                printf("%s", f->f_un.f_fname);
        !           969:                                break;
        !           970: 
        !           971:                        case F_FORW:
        !           972:                                printf("%s", f->f_un.f_forw.f_hname);
        !           973:                                break;
        !           974: 
        !           975:                        case F_USERS:
        !           976:                                for (i = 0; i < MAXUNAMES && *f->f_un.f_uname[i]; i++)
        !           977:                                        printf("%s, ", f->f_un.f_uname[i]);
        !           978:                                break;
        !           979:                        }
        !           980:                        printf("\n");
        !           981:                }
        !           982:        }
        !           983: 
        !           984:        logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE);
        !           985:        dprintf("syslogd: restarted\n");
        !           986: }
        !           987: 
        !           988: /*
        !           989:  * Crack a configuration file line
        !           990:  */
        !           991: 
        !           992: struct code {
        !           993:        char    *c_name;
        !           994:        int     c_val;
        !           995: };
        !           996: 
        !           997: struct code    PriNames[] = {
        !           998:        "panic",        LOG_EMERG,
        !           999:        "emerg",        LOG_EMERG,
        !          1000:        "alert",        LOG_ALERT,
        !          1001:        "crit",         LOG_CRIT,
        !          1002:        "err",          LOG_ERR,
        !          1003:        "error",        LOG_ERR,
        !          1004:        "warn",         LOG_WARNING,
        !          1005:        "warning",      LOG_WARNING,
        !          1006:        "notice",       LOG_NOTICE,
        !          1007:        "info",         LOG_INFO,
        !          1008:        "debug",        LOG_DEBUG,
        !          1009:        "none",         NOPRI,
        !          1010:        NULL,           -1
        !          1011: };
        !          1012: 
        !          1013: struct code    FacNames[] = {
        !          1014:        "kern",         LOG_KERN,
        !          1015:        "user",         LOG_USER,
        !          1016:        "mail",         LOG_MAIL,
        !          1017:        "daemon",       LOG_DAEMON,
        !          1018:        "auth",         LOG_AUTH,
        !          1019:        "security",     LOG_AUTH,
        !          1020:        "mark",         LOG_MARK,
        !          1021:        "syslog",       LOG_SYSLOG,
        !          1022:        "lpr",          LOG_LPR,
        !          1023:        "news",         LOG_NEWS,
        !          1024:        "uucp",         LOG_UUCP,
        !          1025:        "local0",       LOG_LOCAL0,
        !          1026:        "local1",       LOG_LOCAL1,
        !          1027:        "local2",       LOG_LOCAL2,
        !          1028:        "local3",       LOG_LOCAL3,
        !          1029:        "local4",       LOG_LOCAL4,
        !          1030:        "local5",       LOG_LOCAL5,
        !          1031:        "local6",       LOG_LOCAL6,
        !          1032:        "local7",       LOG_LOCAL7,
        !          1033:        NULL,           -1
        !          1034: };
        !          1035: 
        !          1036: cfline(line, f)
        !          1037:        char *line;
        !          1038:        register struct filed *f;
        !          1039: {
        !          1040:        register char *p;
        !          1041:        register char *q;
        !          1042:        register int i;
        !          1043:        char *bp;
        !          1044:        int pri;
        !          1045:        struct hostent *hp;
        !          1046:        char buf[MAXLINE];
        !          1047: 
        !          1048:        dprintf("cfline(%s)\n", line);
        !          1049: 
        !          1050:        errno = 0;      /* keep sys_errlist stuff out of logerror messages */
        !          1051: 
        !          1052:        /* clear out file entry */
        !          1053:        bzero((char *) f, sizeof *f);
        !          1054:        for (i = 0; i <= LOG_NFACILITIES; i++)
        !          1055:                f->f_pmask[i] = NOPRI;
        !          1056: 
        !          1057:        /* scan through the list of selectors */
        !          1058:        for (p = line; *p && *p != '\t';) {
        !          1059: 
        !          1060:                /* find the end of this facility name list */
        !          1061:                for (q = p; *q && *q != '\t' && *q++ != '.'; )
        !          1062:                        continue;
        !          1063: 
        !          1064:                /* collect priority name */
        !          1065:                for (bp = buf; *q && !index("\t,;", *q); )
        !          1066:                        *bp++ = *q++;
        !          1067:                *bp = '\0';
        !          1068: 
        !          1069:                /* skip cruft */
        !          1070:                while (index(", ;", *q))
        !          1071:                        q++;
        !          1072: 
        !          1073:                /* decode priority name */
        !          1074:                pri = decode(buf, PriNames);
        !          1075:                if (pri < 0) {
        !          1076:                        char xbuf[200];
        !          1077: 
        !          1078:                        (void) sprintf(xbuf, "unknown priority name \"%s\"", buf);
        !          1079:                        logerror(xbuf);
        !          1080:                        return;
        !          1081:                }
        !          1082: 
        !          1083:                /* scan facilities */
        !          1084:                while (*p && !index("\t.;", *p)) {
        !          1085:                        int i;
        !          1086: 
        !          1087:                        for (bp = buf; *p && !index("\t,;.", *p); )
        !          1088:                                *bp++ = *p++;
        !          1089:                        *bp = '\0';
        !          1090:                        if (*buf == '*')
        !          1091:                                for (i = 0; i < LOG_NFACILITIES; i++)
        !          1092:                                        f->f_pmask[i] = pri;
        !          1093:                        else {
        !          1094:                                i = decode(buf, FacNames);
        !          1095:                                if (i < 0) {
        !          1096:                                        char xbuf[200];
        !          1097: 
        !          1098:                                        (void) sprintf(xbuf, "unknown facility name \"%s\"", buf);
        !          1099:                                        logerror(xbuf);
        !          1100:                                        return;
        !          1101:                                }
        !          1102:                                f->f_pmask[i >> 3] = pri;
        !          1103:                        }
        !          1104:                        while (*p == ',' || *p == ' ')
        !          1105:                                p++;
        !          1106:                }
        !          1107: 
        !          1108:                p = q;
        !          1109:        }
        !          1110: 
        !          1111:        /* skip to action part */
        !          1112:        while (*p == '\t')
        !          1113:                p++;
        !          1114: 
        !          1115:        switch (*p)
        !          1116:        {
        !          1117:        case '@':
        !          1118:                if (!InetInuse)
        !          1119:                        break;
        !          1120:                (void) strcpy(f->f_un.f_forw.f_hname, ++p);
        !          1121:                hp = gethostbyname(p);
        !          1122:                if (hp == NULL) {
        !          1123:                        char buf[100];
        !          1124: 
        !          1125:                        (void) sprintf(buf, "unknown host %s", p);
        !          1126:                        errno = 0;
        !          1127:                        logerror(buf);
        !          1128:                        break;
        !          1129:                }
        !          1130:                bzero((char *) &f->f_un.f_forw.f_addr,
        !          1131:                         sizeof f->f_un.f_forw.f_addr);
        !          1132:                f->f_un.f_forw.f_addr.sin_family = AF_INET;
        !          1133:                f->f_un.f_forw.f_addr.sin_port = LogPort;
        !          1134:                bcopy(hp->h_addr, (char *) &f->f_un.f_forw.f_addr.sin_addr, hp->h_length);
        !          1135:                f->f_type = F_FORW;
        !          1136:                break;
        !          1137: 
        !          1138:        case '/':
        !          1139:                (void) strcpy(f->f_un.f_fname, p);
        !          1140:                if ((f->f_file = open(p, O_WRONLY|O_APPEND)) < 0) {
        !          1141:                        f->f_file = F_UNUSED;
        !          1142:                        logerror(p);
        !          1143:                        break;
        !          1144:                }
        !          1145:                if (isatty(f->f_file)) {
        !          1146:                        f->f_type = F_TTY;
        !          1147:                        untty();
        !          1148:                }
        !          1149:                else
        !          1150:                        f->f_type = F_FILE;
        !          1151:                if (strcmp(p, ctty) == 0)
        !          1152:                        f->f_type = F_CONSOLE;
        !          1153:                break;
        !          1154: 
        !          1155:        case '*':
        !          1156:                f->f_type = F_WALL;
        !          1157:                break;
        !          1158: 
        !          1159:        default:
        !          1160:                for (i = 0; i < MAXUNAMES && *p; i++) {
        !          1161:                        for (q = p; *q && *q != ','; )
        !          1162:                                q++;
        !          1163:                        (void) strncpy(f->f_un.f_uname[i], p, UNAMESZ);
        !          1164:                        if ((q - p) > UNAMESZ)
        !          1165:                                f->f_un.f_uname[i][UNAMESZ] = '\0';
        !          1166:                        else
        !          1167:                                f->f_un.f_uname[i][q - p] = '\0';
        !          1168:                        while (*q == ',' || *q == ' ')
        !          1169:                                q++;
        !          1170:                        p = q;
        !          1171:                }
        !          1172:                f->f_type = F_USERS;
        !          1173:                break;
        !          1174:        }
        !          1175: }
        !          1176: 
        !          1177: 
        !          1178: /*
        !          1179:  *  Decode a symbolic name to a numeric value
        !          1180:  */
        !          1181: 
        !          1182: decode(name, codetab)
        !          1183:        char *name;
        !          1184:        struct code *codetab;
        !          1185: {
        !          1186:        register struct code *c;
        !          1187:        register char *p;
        !          1188:        char buf[40];
        !          1189: 
        !          1190:        if (isdigit(*name))
        !          1191:                return (atoi(name));
        !          1192: 
        !          1193:        (void) strcpy(buf, name);
        !          1194:        for (p = buf; *p; p++)
        !          1195:                if (isupper(*p))
        !          1196:                        *p = tolower(*p);
        !          1197:        for (c = codetab; c->c_name; c++)
        !          1198:                if (!strcmp(buf, c->c_name))
        !          1199:                        return (c->c_val);
        !          1200: 
        !          1201:        return (-1);
        !          1202: }

unix.superglobalmegacorp.com

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