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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1985 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) 1985 Regents of the University of California.\n\
        !            21:  All rights reserved.\n";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #ifndef lint
        !            25: static char sccsid[] = "@(#)timed.c    2.14 (Berkeley) 6/18/88";
        !            26: #endif /* not lint */
        !            27: 
        !            28: #include "globals.h"
        !            29: #define TSPTYPES
        !            30: #include <protocols/timed.h>
        !            31: #include <net/if.h>
        !            32: #include <sys/file.h>
        !            33: #include <sys/ioctl.h>
        !            34: #include <setjmp.h>
        !            35: 
        !            36: int id;
        !            37: int trace;
        !            38: int sock, sock_raw = -1;
        !            39: int status = 0;
        !            40: int backoff;
        !            41: int slvcount;                          /* no. of slaves controlled by master */
        !            42: int machup;
        !            43: u_short sequence;                      /* sequence number */
        !            44: long delay1;
        !            45: long delay2;
        !            46: long random();
        !            47: char hostname[MAXHOSTNAMELEN];
        !            48: struct host hp[NHOSTS];
        !            49: char tracefile[] = "/usr/adm/timed.log";
        !            50: FILE *fd;
        !            51: jmp_buf jmpenv;
        !            52: struct netinfo *nettab = NULL;
        !            53: int nslavenets;                /* Number of networks were I could be a slave */
        !            54: int nmasternets;       /* Number of networks were I could be a master */
        !            55: int nignorednets;      /* Number of ignored networks */
        !            56: int nnets;             /* Number of networks I am connected to */
        !            57: struct netinfo *slavenet;
        !            58: struct netinfo *firstslavenet();
        !            59: int Mflag;
        !            60: int justquit = 0;
        !            61: 
        !            62: struct nets {
        !            63:        char *name;
        !            64:        long net;
        !            65:        struct nets *next;
        !            66: } *nets = (struct nets *)0;
        !            67: 
        !            68: /*
        !            69:  * The timedaemons synchronize the clocks of hosts in a local area network.
        !            70:  * One daemon runs as master, all the others as slaves. The master
        !            71:  * performs the task of computing clock differences and sends correction
        !            72:  * values to the slaves. 
        !            73:  * Slaves start an election to choose a new master when the latter disappears 
        !            74:  * because of a machine crash, network partition, or when killed.
        !            75:  * A resolution protocol is used to kill all but one of the masters
        !            76:  * that happen to exist in segments of a partitioned network when the 
        !            77:  * network partition is fixed.
        !            78:  *
        !            79:  * Authors: Riccardo Gusella & Stefano Zatti
        !            80:  */
        !            81: 
        !            82: main(argc, argv)
        !            83: int argc;
        !            84: char **argv;
        !            85: {
        !            86:        int on;
        !            87:        int ret;
        !            88:        long seed;
        !            89:        int nflag, iflag;
        !            90:        struct timeval time;
        !            91:        struct servent *srvp;
        !            92:        long casual();
        !            93:        char *date();
        !            94:        int n;
        !            95:        int flag;
        !            96:        char buf[BUFSIZ];
        !            97:        struct ifconf ifc;
        !            98:        struct ifreq ifreq, *ifr;
        !            99:        register struct netinfo *ntp;
        !           100:        struct netinfo *ntip;
        !           101:        struct netinfo *savefromnet;
        !           102:        struct sockaddr_in server;
        !           103:        u_short port;
        !           104:        uid_t getuid();
        !           105: 
        !           106: #ifdef lint
        !           107:        ntip = NULL;
        !           108: #endif
        !           109: 
        !           110:        Mflag = 0;
        !           111:        on = 1;
        !           112:        backoff = 1;
        !           113:        trace = OFF;
        !           114:        nflag = OFF;
        !           115:        iflag = OFF;
        !           116:        openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON);
        !           117: 
        !           118:        if (getuid() != 0) {
        !           119:                fprintf(stderr, "Timed: not superuser\n");
        !           120:                exit(1);
        !           121:        }
        !           122: 
        !           123:        while (--argc > 0 && **++argv == '-') {
        !           124:                (*argv)++;
        !           125:                do {
        !           126:                        switch (**argv) {
        !           127: 
        !           128:                        case 'M':
        !           129:                                Mflag = 1; 
        !           130:                                break;
        !           131:                        case 't':
        !           132:                                trace = ON; 
        !           133:                                break;
        !           134:                        case 'n':
        !           135:                                argc--, argv++;
        !           136:                                if (iflag) {
        !           137:                                        fprintf(stderr,
        !           138:                                    "timed: -i and -n make no sense together\n");
        !           139:                                } else {
        !           140:                                        nflag = ON;
        !           141:                                        addnetname(*argv);
        !           142:                                }
        !           143:                                while (*(++(*argv)+1)) ;
        !           144:                                break;
        !           145:                        case 'i':
        !           146:                                argc--, argv++;
        !           147:                                if (nflag) {
        !           148:                                        fprintf(stderr,
        !           149:                                    "timed: -i and -n make no sense together\n");
        !           150:                                } else {
        !           151:                                        iflag = ON;
        !           152:                                        addnetname(*argv);
        !           153:                                }
        !           154:                                while (*(++(*argv)+1)) ;
        !           155:                                break;
        !           156:                        default:
        !           157:                                fprintf(stderr, "timed: -%c: unknown option\n", 
        !           158:                                                        **argv);
        !           159:                                break;
        !           160:                        }
        !           161:                } while (*++(*argv));
        !           162:        }
        !           163: 
        !           164: #ifndef DEBUG
        !           165:        if (fork())
        !           166:                exit(0);
        !           167:        { int s;
        !           168:          for (s = getdtablesize(); s >= 0; --s)
        !           169:                (void) close(s);
        !           170:          (void) open("/dev/null", 0);
        !           171:          (void) dup2(0, 1);
        !           172:          (void) dup2(0, 2);
        !           173:          s = open("/dev/tty", 2);
        !           174:          if (s >= 0) {
        !           175:                (void) ioctl(s, TIOCNOTTY, (char *)0);
        !           176:                (void) close(s);
        !           177:          }
        !           178:        }
        !           179: #endif
        !           180: 
        !           181:        if (trace == ON) {
        !           182:                fd = fopen(tracefile, "w");
        !           183:                setlinebuf(fd);
        !           184:                fprintf(fd, "Tracing started on: %s\n\n", 
        !           185:                                        date());
        !           186:        }
        !           187: 
        !           188:        srvp = getservbyname("timed", "udp");
        !           189:        if (srvp == 0) {
        !           190:                syslog(LOG_CRIT, "unknown service 'timed/udp'");
        !           191:                exit(1);
        !           192:        }
        !           193:        port = srvp->s_port;
        !           194:        server.sin_port = srvp->s_port;
        !           195:        server.sin_family = AF_INET;
        !           196:        sock = socket(AF_INET, SOCK_DGRAM, 0);
        !           197:        if (sock < 0) {
        !           198:                syslog(LOG_ERR, "socket: %m");
        !           199:                exit(1);
        !           200:        }
        !           201:        if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, 
        !           202:                                                        sizeof(on)) < 0) {
        !           203:                syslog(LOG_ERR, "setsockopt: %m");
        !           204:                exit(1);
        !           205:        }
        !           206:        if (bind(sock, &server, sizeof(server))) {
        !           207:                if (errno == EADDRINUSE)
        !           208:                        syslog(LOG_ERR, "server already running");
        !           209:                else
        !           210:                        syslog(LOG_ERR, "bind: %m");
        !           211:                exit(1);
        !           212:        }
        !           213: 
        !           214:        /* choose a unique seed for random number generation */
        !           215:        (void)gettimeofday(&time, (struct timezone *)0);
        !           216:        seed = time.tv_sec + time.tv_usec;
        !           217:        srandom(seed);
        !           218: 
        !           219:        sequence = random();     /* initial seq number */
        !           220: 
        !           221:        /* rounds kernel variable time to multiple of 5 ms. */
        !           222:        time.tv_sec = 0;
        !           223:        time.tv_usec = -((time.tv_usec/1000) % 5) * 1000;
        !           224:        (void)adjtime(&time, (struct timeval *)0);
        !           225: 
        !           226:        id = getpid();
        !           227: 
        !           228:        if (gethostname(hostname, sizeof(hostname) - 1) < 0) {
        !           229:                syslog(LOG_ERR, "gethostname: %m");
        !           230:                exit(1);
        !           231:        }
        !           232:        hp[0].name = hostname;
        !           233: 
        !           234:        if (nflag || iflag) {
        !           235:                struct netent *getnetent();
        !           236:                struct netent *n;
        !           237:                struct nets *np;
        !           238:                for ( np = nets ; np ; np = np->next) {
        !           239:                        n = getnetbyname(np->name);
        !           240:                        if (n == NULL) {
        !           241:                                syslog(LOG_ERR, "getnetbyname: unknown net %s",
        !           242:                                        np->name);
        !           243:                                exit(1);
        !           244:                        }
        !           245:                        np->net = n->n_net;
        !           246:                }
        !           247:        }
        !           248:        ifc.ifc_len = sizeof(buf);
        !           249:        ifc.ifc_buf = buf;
        !           250:        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
        !           251:                syslog(LOG_ERR, "get interface configuration: %m");
        !           252:                exit(1);
        !           253:        }
        !           254:        n = ifc.ifc_len/sizeof(struct ifreq);
        !           255:        ntp = NULL;
        !           256:        for (ifr = ifc.ifc_req; n > 0; n--, ifr++) {
        !           257:                if (ifr->ifr_addr.sa_family != AF_INET)
        !           258:                        continue;
        !           259:                ifreq = *ifr;
        !           260:                if (ntp == NULL)
        !           261:                        ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
        !           262:                ntp->my_addr = 
        !           263:                        ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
        !           264:                if (ioctl(sock, SIOCGIFFLAGS, 
        !           265:                                        (char *)&ifreq) < 0) {
        !           266:                        syslog(LOG_ERR, "get interface flags: %m");
        !           267:                        continue;
        !           268:                }
        !           269:                if ((ifreq.ifr_flags & IFF_UP) == 0 ||
        !           270:                        ((ifreq.ifr_flags & IFF_BROADCAST) == 0 &&
        !           271:                        (ifreq.ifr_flags & IFF_POINTOPOINT) == 0)) {
        !           272:                        continue;
        !           273:                }
        !           274:                if (ifreq.ifr_flags & IFF_BROADCAST)
        !           275:                        flag = 1;
        !           276:                else
        !           277:                        flag = 0;
        !           278:                if (ioctl(sock, SIOCGIFNETMASK, 
        !           279:                                        (char *)&ifreq) < 0) {
        !           280:                        syslog(LOG_ERR, "get netmask: %m");
        !           281:                        continue;
        !           282:                }
        !           283:                ntp->mask = ((struct sockaddr_in *)
        !           284:                        &ifreq.ifr_addr)->sin_addr.s_addr;
        !           285:                if (flag) {
        !           286:                        if (ioctl(sock, SIOCGIFBRDADDR, 
        !           287:                                                (char *)&ifreq) < 0) {
        !           288:                                syslog(LOG_ERR, "get broadaddr: %m");
        !           289:                                continue;
        !           290:                        }
        !           291:                        ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
        !           292:                } else {
        !           293:                        if (ioctl(sock, SIOCGIFDSTADDR, 
        !           294:                                                (char *)&ifreq) < 0) {
        !           295:                                syslog(LOG_ERR, "get destaddr: %m");
        !           296:                                continue;
        !           297:                        }
        !           298:                        ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_dstaddr;
        !           299:                }
        !           300:                ntp->dest_addr.sin_port = port;
        !           301:                if (nflag || iflag) {
        !           302:                        u_long addr, mask;
        !           303:                        struct nets *n;
        !           304: 
        !           305:                        addr = ntohl(ntp->dest_addr.sin_addr.s_addr);
        !           306:                        mask = ntohl(ntp->mask);
        !           307:                        while ((mask & 1) == 0) {
        !           308:                                addr >>= 1;
        !           309:                                mask >>= 1;
        !           310:                        }
        !           311:                        for (n = nets ; n ; n = n->next)
        !           312:                                if (addr == n->net)
        !           313:                                        break;
        !           314:                        if (nflag && !n || iflag && n)
        !           315:                                continue;
        !           316:                }
        !           317:                ntp->net = ntp->mask & ntp->dest_addr.sin_addr.s_addr;
        !           318:                ntp->next = NULL;
        !           319:                if (nettab == NULL) {
        !           320:                        nettab = ntp;
        !           321:                } else {
        !           322:                        ntip->next = ntp;
        !           323:                }
        !           324:                ntip = ntp;
        !           325:                ntp = NULL;
        !           326:        }
        !           327:        if (ntp)
        !           328:                (void) free((char *)ntp);
        !           329:        if (nettab == NULL) {
        !           330:                syslog(LOG_ERR, "No network usable");
        !           331:                exit(1);
        !           332:        }
        !           333: 
        !           334:        for (ntp = nettab; ntp != NULL; ntp = ntp->next)
        !           335:                lookformaster(ntp);
        !           336:        setstatus();
        !           337:        /*
        !           338:         * Take care of some basic initialization.
        !           339:         */
        !           340:        /* us. delay to be used in response to broadcast */
        !           341:        delay1 = casual((long)10000, 200000);   
        !           342: 
        !           343:        /* election timer delay in secs. */
        !           344:        delay2 = casual((long)MINTOUT, (long)MAXTOUT);
        !           345: 
        !           346:        if (Mflag) {
        !           347:                /*
        !           348:                 * number (increased by 1) of slaves controlled by master: 
        !           349:                 * used in master.c, candidate.c, networkdelta.c, and 
        !           350:                 * correct.c 
        !           351:                 */
        !           352:                slvcount = 1;
        !           353:                ret = setjmp(jmpenv);
        !           354: 
        !           355:                switch (ret) {
        !           356: 
        !           357:                case 0: 
        !           358:                        makeslave(firstslavenet());
        !           359:                        setstatus();
        !           360:                        break;
        !           361:                case 1: 
        !           362:                        /* Just lost our master */
        !           363:                        setstatus();
        !           364:                        slavenet->status = election(slavenet);
        !           365:                        checkignorednets();
        !           366:                        setstatus();
        !           367:                        if (slavenet->status == MASTER)
        !           368:                                makeslave(firstslavenet());
        !           369:                        else
        !           370:                                makeslave(slavenet);
        !           371:                        setstatus();
        !           372:                        break;
        !           373:                case 2:
        !           374:                        /* Just been told to quit */
        !           375:                        fromnet->status = SLAVE;
        !           376:                        setstatus();
        !           377:                        savefromnet = fromnet;
        !           378:                        rmnetmachs(fromnet);
        !           379:                        checkignorednets();
        !           380:                        if (slavenet)
        !           381:                                makeslave(slavenet);
        !           382:                        else
        !           383:                                makeslave(savefromnet);
        !           384:                        setstatus();
        !           385:                        justquit = 1;
        !           386:                        break;
        !           387:                        
        !           388:                default:
        !           389:                        /* this should not happen */
        !           390:                        syslog(LOG_ERR, "Attempt to enter invalid state");
        !           391:                        break;
        !           392:                }
        !           393:                        
        !           394:                if (status & MASTER) {
        !           395:                        /* open raw socket used to measure time differences */
        !           396:                        if (sock_raw == -1) {
        !           397:                            sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 
        !           398:                            if (sock_raw < 0)  {
        !           399:                                    syslog(LOG_ERR, "opening raw socket: %m");
        !           400:                                    exit (1);
        !           401:                            }
        !           402:                        }
        !           403:                } else {
        !           404:                        /* sock_raw is not being used now */
        !           405:                        if (sock_raw != -1) {
        !           406:                            (void)close(sock_raw);
        !           407:                            sock_raw = -1;
        !           408:                        }
        !           409:                }
        !           410: 
        !           411:                if (status == MASTER) 
        !           412:                        master();
        !           413:                else 
        !           414:                        slave();
        !           415:        } else {
        !           416:                /* if Mflag is not set timedaemon is forced to act as a slave */
        !           417:                status = SLAVE;
        !           418:                if (setjmp(jmpenv)) {
        !           419:                        setstatus();
        !           420:                        checkignorednets();
        !           421:                }
        !           422:                makeslave(firstslavenet());
        !           423:                for (ntp = nettab; ntp != NULL; ntp = ntp->next)
        !           424:                        if (ntp->status == MASTER)
        !           425:                                ntp->status = IGNORE;
        !           426:                setstatus();
        !           427:                slave();
        !           428:        }
        !           429: }
        !           430: 
        !           431: /*
        !           432:  * Try to become master over ignored nets..
        !           433:  */
        !           434: checkignorednets()
        !           435: {
        !           436:        register struct netinfo *ntp;
        !           437:        for (ntp = nettab; ntp != NULL; ntp = ntp->next)
        !           438:                if (ntp->status == IGNORE)
        !           439:                        lookformaster(ntp);
        !           440: }
        !           441: 
        !           442: lookformaster(ntp)
        !           443:        register struct netinfo *ntp;
        !           444: {
        !           445:        struct tsp resp, conflict, *answer, *readmsg(), *acksend();
        !           446:        struct timeval time;
        !           447:        char mastername[MAXHOSTNAMELEN];
        !           448:        struct sockaddr_in masteraddr;
        !           449: 
        !           450:        ntp->status = SLAVE;
        !           451:        /* look for master */
        !           452:        resp.tsp_type = TSP_MASTERREQ;
        !           453:        (void)strcpy(resp.tsp_name, hostname);
        !           454:        answer = acksend(&resp, &ntp->dest_addr, (char *)ANYADDR, 
        !           455:            TSP_MASTERACK, ntp);
        !           456:        if (answer == NULL) {
        !           457:                /*
        !           458:                 * Various conditions can cause conflict: race between
        !           459:                 * two just started timedaemons when no master is
        !           460:                 * present, or timedaemon started during an election.
        !           461:                 * Conservative approach is taken: give up and became a
        !           462:                 * slave postponing election of a master until first
        !           463:                 * timer expires.
        !           464:                 */
        !           465:                time.tv_sec = time.tv_usec = 0;
        !           466:                answer = readmsg(TSP_MASTERREQ, (char *)ANYADDR,
        !           467:                    &time, ntp);
        !           468:                if (answer != NULL) {
        !           469:                        ntp->status = SLAVE;
        !           470:                        return;
        !           471:                }
        !           472: 
        !           473:                time.tv_sec = time.tv_usec = 0;
        !           474:                answer = readmsg(TSP_MASTERUP, (char *)ANYADDR,
        !           475:                    &time, ntp);
        !           476:                if (answer != NULL) {
        !           477:                        ntp->status = SLAVE;
        !           478:                        return;
        !           479:                }
        !           480: 
        !           481:                time.tv_sec = time.tv_usec = 0;
        !           482:                answer = readmsg(TSP_ELECTION, (char *)ANYADDR,
        !           483:                    &time, ntp);
        !           484:                if (answer != NULL) {
        !           485:                        ntp->status = SLAVE;
        !           486:                        return;
        !           487:                }
        !           488:                ntp->status = MASTER;
        !           489:        } else {
        !           490:                (void)strcpy(mastername, answer->tsp_name);
        !           491:                masteraddr = from;
        !           492: 
        !           493:                /*
        !           494:                 * If network has been partitioned, there might be other
        !           495:                 * masters; tell the one we have just acknowledged that 
        !           496:                 * it has to gain control over the others. 
        !           497:                 */
        !           498:                time.tv_sec = 0;
        !           499:                time.tv_usec = 300000;
        !           500:                answer = readmsg(TSP_MASTERACK, (char *)ANYADDR, &time,
        !           501:                    ntp);
        !           502:                /*
        !           503:                 * checking also not to send CONFLICT to ack'ed master
        !           504:                 * due to duplicated MASTERACKs
        !           505:                 */
        !           506:                if (answer != NULL && 
        !           507:                    strcmp(answer->tsp_name, mastername) != 0) {
        !           508:                        conflict.tsp_type = TSP_CONFLICT;
        !           509:                        (void)strcpy(conflict.tsp_name, hostname);
        !           510:                        if (acksend(&conflict, &masteraddr, mastername,
        !           511:                            TSP_ACK, (struct netinfo *)NULL) == NULL) {
        !           512:                                syslog(LOG_ERR, 
        !           513:                                    "error on sending TSP_CONFLICT");
        !           514:                                exit(1);
        !           515:                        }
        !           516:                }
        !           517:        }
        !           518: }
        !           519: /*
        !           520:  * based on the current network configuration, set the status, and count
        !           521:  * networks;
        !           522:  */
        !           523: setstatus()
        !           524: {
        !           525:        register struct netinfo *ntp;
        !           526: 
        !           527:        status = 0;
        !           528:        nmasternets = nslavenets = nnets = nignorednets = 0;
        !           529:        if (trace)
        !           530:                fprintf(fd, "Net status:\n");
        !           531:        for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
        !           532:                switch ((int)ntp->status) {
        !           533:                  case MASTER:
        !           534:                        nmasternets++;
        !           535:                        break;
        !           536:                  case SLAVE:
        !           537:                        nslavenets++;
        !           538:                        break;
        !           539:                  case IGNORE:
        !           540:                        nignorednets++;
        !           541:                        break;
        !           542:                }
        !           543:                if (trace) {
        !           544:                        fprintf(fd, "\t%-16s", inet_ntoa(ntp->net));
        !           545:                        switch ((int)ntp->status) {
        !           546:                          case MASTER:
        !           547:                                fprintf(fd, "MASTER\n");
        !           548:                                break;
        !           549:                          case SLAVE:
        !           550:                                fprintf(fd, "SLAVE\n");
        !           551:                                break;
        !           552:                          case IGNORE:
        !           553:                                fprintf(fd, "IGNORE\n");
        !           554:                                break;
        !           555:                          default:
        !           556:                                fprintf(fd, "invalid state %d\n",(int)ntp->status);
        !           557:                                break;
        !           558:                        }
        !           559:                }
        !           560:                nnets++;
        !           561:                status |= ntp->status;
        !           562:        }
        !           563:        status &= ~IGNORE;
        !           564:        if (trace)
        !           565:                fprintf(fd,
        !           566:                      "\tnets = %d, masters = %d, slaves = %d, ignored = %d\n",
        !           567:                      nnets, nmasternets, nslavenets, nignorednets);
        !           568: }
        !           569: 
        !           570: makeslave(net)
        !           571:        struct netinfo *net;
        !           572: {
        !           573:        register struct netinfo *ntp;
        !           574: 
        !           575:        for (ntp = nettab; ntp != NULL; ntp = ntp->next)
        !           576:                if (ntp->status == SLAVE && ntp != net)
        !           577:                        ntp->status = IGNORE;
        !           578:        slavenet = net;
        !           579: }
        !           580:        
        !           581: struct netinfo *
        !           582: firstslavenet()
        !           583: {
        !           584:        register struct netinfo *ntp;
        !           585: 
        !           586:        for (ntp = nettab; ntp != NULL; ntp = ntp->next)
        !           587:                if (ntp->status == SLAVE)
        !           588:                        return (ntp);
        !           589:        return ((struct netinfo *)0);
        !           590: }
        !           591: 
        !           592: /*
        !           593:  * `casual' returns a random number in the range [inf, sup]
        !           594:  */
        !           595: 
        !           596: long
        !           597: casual(inf, sup)
        !           598: long inf;
        !           599: long sup;
        !           600: {
        !           601:        float value;
        !           602: 
        !           603:        value = (float)(random() & 0x7fffffff) / 0x7fffffff;
        !           604:        return(inf + (sup - inf) * value);
        !           605: }
        !           606: 
        !           607: char *
        !           608: date()
        !           609: {
        !           610:        char    *ctime();
        !           611:        struct  timeval tv;
        !           612: 
        !           613:        (void)gettimeofday(&tv, (struct timezone *)0);
        !           614:        return (ctime(&tv.tv_sec));
        !           615: }
        !           616: 
        !           617: addnetname(name)
        !           618:        char *name;
        !           619: {
        !           620:        register struct nets **netlist = &nets;
        !           621: 
        !           622:        while (*netlist)
        !           623:                netlist = &((*netlist)->next);
        !           624:        *netlist = (struct nets *)malloc(sizeof **netlist);
        !           625:        if (*netlist == (struct nets *)0) {
        !           626:                syslog(LOG_ERR, "malloc failed");
        !           627:                exit(1);
        !           628:        }
        !           629:        bzero((char *)*netlist, sizeof(**netlist));
        !           630:        (*netlist)->name = name;
        !           631: }

unix.superglobalmegacorp.com

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