Annotation of 43BSDReno/contrib/isode-beta/others/quipu/tools/dsaconfig/dsaconfig.c, revision 1.1

1.1     ! root        1: /* dsaconfig.c - build a database directory for a Level-1 DSA */
        !             2: 
        !             3: #ifndef        lint
        !             4: static char *rcsid = "$Header: /f/osi/others/quipu/tools/dsaconfig/RCS/dsaconfig.c,v 7.4 90/07/27 08:44:58 mrose Exp $";
        !             5: #endif
        !             6: 
        !             7: /* 
        !             8:  * $Header: /f/osi/others/quipu/tools/dsaconfig/RCS/dsaconfig.c,v 7.4 90/07/27 08:44:58 mrose Exp $
        !             9:  *
        !            10:  *
        !            11:  * $Log:       dsaconfig.c,v $
        !            12:  * Revision 7.4  90/07/27  08:44:58  mrose
        !            13:  * update
        !            14:  * 
        !            15:  * Revision 7.3  90/03/22  08:38:31  mrose
        !            16:  * touch-up
        !            17:  * 
        !            18:  * Revision 7.2  90/01/11  18:36:09  mrose
        !            19:  * real-sync
        !            20:  * 
        !            21:  * Revision 7.1  89/12/06  17:30:24  mrose
        !            22:  * update
        !            23:  * 
        !            24:  * Revision 7.0  89/11/23  22:02:38  mrose
        !            25:  * Release 6.0
        !            26:  * 
        !            27:  */
        !            28: 
        !            29: /*
        !            30:  *                               NOTICE
        !            31:  *
        !            32:  *    Acquisition, use, and distribution of this module and related
        !            33:  *    materials are subject to the restrictions of a license agreement.
        !            34:  *    Consult the Preface in the User's Manual for the full terms of
        !            35:  *    this agreement.
        !            36:  *
        !            37:  */
        !            38: 
        !            39: 
        !            40: #include <ctype.h>
        !            41: #include <errno.h>
        !            42: #include <grp.h>
        !            43: #include <pwd.h>
        !            44: #include <stdio.h>
        !            45: #include <varargs.h>
        !            46: #include "general.h"
        !            47: #include "manifest.h"
        !            48: #include "internet.h"
        !            49: #include "psap.h"
        !            50: #include "tailor.h"
        !            51: 
        !            52: 
        !            53: #ifdef SYS5
        !            54: struct group *getgrnam ();
        !            55: struct passwd *getpwnam (), *getpwuid ();
        !            56: #endif
        !            57: 
        !            58: /*    DATA */
        !            59: 
        !            60: static int debug =0;
        !            61: 
        !            62: static int uid = 0;
        !            63: static int gid = 0;
        !            64: 
        !            65: static char *myname = "dsaconfig";
        !            66: 
        !            67: static char *wildlife = NULL;
        !            68: static char sedfil[BUFSIZ];
        !            69: 
        !            70: 
        !            71: void   adios (), advise ();
        !            72: char   *version ();
        !            73: 
        !            74: 
        !            75: extern int errno;
        !            76: 
        !            77: extern char  *quipuversion;
        !            78: 
        !            79: /*    MAIN */
        !            80: 
        !            81: /* ARGSUSED */
        !            82: 
        !            83: main (argc, argv, envp)
        !            84: int    argc;
        !            85: char  **argv,
        !            86:       **envp;
        !            87: {
        !            88:     char    buffer[BUFSIZ];
        !            89: 
        !            90:     arginit (argv);
        !            91:     if (access (wildlife, 0x00) != NOTOK)
        !            92:        adios (NULLCP, "%s already exists, choose a different name", wildlife);
        !            93: 
        !            94:     read_config ();
        !            95:     generate_sed ();
        !            96: 
        !            97:     build_root ();
        !            98:     build_TLC ();
        !            99:     build_organization ();
        !           100:     build_unit ();
        !           101: 
        !           102:     build_tailor ();
        !           103:     build_startup ();
        !           104:     build_nightly ();
        !           105: 
        !           106:     build_dsap ();
        !           107:     build_fred ();
        !           108: 
        !           109: #ifndef        SYS5
        !           110:     (void) sprintf (buffer, "find %s -exec /etc/chown %d {} \\;",
        !           111:                    wildlife, uid);
        !           112: #else
        !           113:     (void) sprintf (buffer, "find %s -exec chown %d {} \\;", wildlife, uid);
        !           114: #endif
        !           115:     if (debug)
        !           116:        fprintf (stderr, "%s\n", buffer);
        !           117:     (void) system (buffer);
        !           118: 
        !           119:     (void) sprintf (buffer, "find %s -exec chgrp %d {} \\;",
        !           120:                    wildlife, gid);
        !           121:     if (debug)
        !           122:        fprintf (stderr, "%s\n", buffer);
        !           123:     (void) system (buffer);
        !           124: 
        !           125:     (void) unlink (sedfil);
        !           126: 
        !           127:     exit (0);
        !           128: }
        !           129: 
        !           130: /*    CONFIG */
        !           131: 
        !           132: struct country {
        !           133:     char   *c_code;
        !           134:     int            c_number;
        !           135:     char   *c_name;
        !           136: 
        !           137:     char   *c_root;
        !           138:     char   *c_master;
        !           139:     char   *c_other;
        !           140:     
        !           141:     char   *c_phone;
        !           142: 
        !           143:     int            c_flags;
        !           144: #define        C_SHORT 0x01
        !           145: };
        !           146: 
        !           147: struct country *read_country ();
        !           148: 
        !           149: /*  */
        !           150: 
        !           151: struct pair {
        !           152:     char   *p_name;
        !           153:     char   *p_value;
        !           154: 
        !           155:     int            p_flags;
        !           156: #define        P_NULL  0x00
        !           157: #define        P_OPT   0x01
        !           158: #define        P_MBOX  0x02
        !           159: #define        P_XXX   0x04
        !           160: #define        P_ZAP   0x08
        !           161: #define        P_POST  0x10
        !           162: };
        !           163: 
        !           164: static struct pair pairs[] = {
        !           165:     "dsa", NULL,                       /* Spectacled Bear */
        !           166:        P_NULL,
        !           167: 
        !           168:     "country", NULL,                   /* US */
        !           169:         P_OPT,
        !           170:     "organization", NULL,              /* NYSERNet, Inc. */
        !           171:        P_NULL,
        !           172:     "domain", NULL,                    /* nyser.net */
        !           173:         P_NULL,
        !           174:     "unit", NULL,                      /* Research and Development */
        !           175:        P_NULL,
        !           176:     "street", NULL,                    /* 165 Jordan Road */
        !           177:        P_OPT,
        !           178:     "pob", NULL,                       /* 1234 */
        !           179:        P_OPT,
        !           180:     "town", NULL,                      /* Troy */
        !           181:        P_NULL,
        !           182:     "state", NULL,                     /* New York */
        !           183:        P_NULL,
        !           184:     "zipcode", NULL,                   /* 12180 */
        !           185:        P_NULL,
        !           186:     "locality", NULL,                  /* Troy, New York */
        !           187:         P_OPT,
        !           188:     "postaladdress", NULL,             /* org $ address */
        !           189:        P_OPT | P_POST,
        !           190: 
        !           191:     "telephone", NULL,                 /* +1 518-283-8860 */
        !           192:        P_NULL,
        !           193:     "fax", NULL,                       /* +1 518-283-8904 */
        !           194:        P_OPT,
        !           195: 
        !           196:     "description", NULL,               /* not-for-profit ... */
        !           197:        P_NULL,
        !           198: 
        !           199:     "ipaddr", NULL,                    /* 127.0.0.1 */
        !           200:         P_OPT,
        !           201:     "port", NULL,                      /* 17003 */
        !           202:         P_OPT,
        !           203: 
        !           204:     "firstname", NULL,                 /* Marshall */
        !           205:        P_NULL,
        !           206:     "lastname", NULL,                  /* Rose */
        !           207:        P_NULL,
        !           208:     "middleinitial", NULL,             /* T */
        !           209:        P_OPT,
        !           210:     "middlename", NULL,                        /* Txxx */
        !           211:        P_OPT,
        !           212:     "mailbox", NULL,                   /* [email protected] */
        !           213:        P_MBOX,
        !           214:     "title", NULL,                     /* Senior Scientist */
        !           215:        P_NULL,
        !           216:     "userid", NULL,                    /* mrose */
        !           217:        P_OPT,
        !           218:     "groupid", NULL,                   /* whitepages */
        !           219:        P_OPT,
        !           220:     "password", NULL,                  /* secret */
        !           221:        P_NULL,
        !           222:     "extension", NULL,                 /* +1 518-283-8860 */
        !           223:        P_OPT,
        !           224: 
        !           225:     "wildlife", NULL,                  /* spectacled-bear */
        !           226:        P_XXX,
        !           227:     "bindir", NULL,                    /* /usr/local/bin/ */
        !           228:         P_XXX,
        !           229:     "sbindir", NULL,                   /* /usr/etc/ */
        !           230:         P_XXX,
        !           231:     "etcdir", NULL,                    /* /usr/etc/ */
        !           232:         P_XXX,
        !           233:     "quipuversion", NULL,              /* from -lquipu */
        !           234:         P_XXX,
        !           235:     "rootDSA", NULL,                   /* root upstream */
        !           236:         P_XXX,
        !           237:     "countryDSA", NULL,                        /* country upstream */
        !           238:         P_XXX,
        !           239:     "otherDSA", NULL,                  /* hack... */
        !           240:        P_XXX,
        !           241:     "rootDSAaddress", NULL,            /* PSAP of root upstream */
        !           242:         P_XXX,
        !           243:     "countryDSAaddress", NULL,         /* PSAP of country upstream */
        !           244:         P_XXX,
        !           245:     "otherDSAaddress", NULL,           /* PSAP of hack... */
        !           246:        P_XXX,
        !           247: 
        !           248:     NULL
        !           249: };
        !           250: 
        !           251: struct pair *n2p ();
        !           252: 
        !           253: /*  */
        !           254: 
        !           255: static read_config () {
        !           256:     int            lineno;
        !           257:     register char *cp,
        !           258:                  *dp;
        !           259:     char    buffer[BUFSIZ],
        !           260:            file[BUFSIZ],
        !           261:            line[BUFSIZ],
        !           262:           *vec[NVEC + 1];
        !           263:     FILE   *fp;
        !           264:     register struct country *c;
        !           265:     register struct pair *p,
        !           266:                         *q;
        !           267:     register struct hostent *hp;
        !           268:     struct sockaddr_in in_socket;
        !           269:     register struct sockaddr_in *isock = &in_socket;
        !           270: 
        !           271:     (void) sprintf (file, "%s.dsa", wildlife);
        !           272:     if ((fp = fopen (file, "r")) == NULL)
        !           273:        adios (file, "unable to read");
        !           274: 
        !           275:     for (lineno = 1; fgets (buffer, sizeof buffer, fp); lineno++) {
        !           276:        if (*buffer == '#')
        !           277:            continue;
        !           278:        if (cp = index (buffer, '\n'))
        !           279:            *cp = NULL;
        !           280:        (void) strcpy (line, buffer);
        !           281: 
        !           282:        bzero ((char *) vec, sizeof vec);
        !           283:        switch (str2vec (buffer, vec)) {
        !           284:            case 0:
        !           285:                continue;
        !           286: 
        !           287:            case 1:
        !           288:                for (p = pairs; p -> p_name; p++)
        !           289:                    if (strcmp (p -> p_name, vec[0]) == 0)
        !           290:                        break;
        !           291:                if (!p -> p_name || (p -> p_flags & P_XXX))
        !           292:                    adios (NULLCP, "unknown variable \"%s\"", vec[0]);
        !           293:                continue;
        !           294: 
        !           295:            case 2:
        !           296:                break;
        !           297: 
        !           298:            default:
        !           299:                adios (NULLCP, "syntax error on line %d:\n%s", lineno, line);
        !           300:                /* NOTREACHED */
        !           301:        }
        !           302: 
        !           303:        for (p = pairs; p -> p_name; p++)
        !           304:            if (strcmp (p -> p_name, vec[0]) == 0)
        !           305:                break;
        !           306:        if (!p -> p_name || (p -> p_flags & P_XXX))
        !           307:            adios (NULLCP, "unknown variable \"%s\"", vec[0]);
        !           308:        if (p -> p_value)
        !           309:            adios (NULLCP, "multiple values for \"%s\" starting at line %d",
        !           310:                   p -> p_name, lineno);
        !           311: 
        !           312:        if (p -> p_flags & P_MBOX) {
        !           313:            for (cp = vec[1]; *cp; cp++)
        !           314:                if (!isascii (*cp) || *cp == '$' || *cp == '&') {
        !           315: illegal: ;
        !           316:                    adios (NULLCP,
        !           317:                           "illegal character %c (0%o) in value for \"%s\"",
        !           318:                           *cp, *cp & 0xff, p -> p_name);
        !           319:                }
        !           320:        }
        !           321:        else
        !           322:            for (cp = vec[1]; *cp; cp++) {
        !           323:                if (isalpha (*cp) || isdigit (*cp))
        !           324:                    continue;
        !           325:                switch (*cp) {
        !           326:                    case 047: /* ' */
        !           327:                    case '(':
        !           328:                    case ')':
        !           329:                    case '+':
        !           330:                    case ',':
        !           331:                    case '-':
        !           332:                    case '.':
        !           333:                    case '/':
        !           334:                    case ':':
        !           335:                    case '?':
        !           336:                    case ' ':
        !           337:                        continue;
        !           338: 
        !           339:                    default:
        !           340:                        if ((p -> p_flags & P_POST) && *cp == '$')
        !           341:                            continue;
        !           342:                        goto illegal;
        !           343:                }
        !           344:            }
        !           345: 
        !           346:        p -> p_value = strdup (vec[1]);
        !           347:     }
        !           348: 
        !           349:     if (ferror (fp) && !feof (fp))
        !           350:        adios (file, "error reading");
        !           351:     (void) fclose (fp);
        !           352: 
        !           353:     for (p = pairs; p -> p_name; p++)
        !           354:        if (!p -> p_value && !(p -> p_flags & (P_OPT | P_XXX)))
        !           355:            adios (NULLCP, "missing value for \"%s\"", p -> p_name);
        !           356: 
        !           357:     if (n2p ("country", 0) == NULL)
        !           358:        n2p ("country", 1) -> p_value = strdup ("US");
        !           359: 
        !           360:     if ((c = read_country (cp = n2p ("country", 1) -> p_value)) == NULL)
        !           361:        adios (NULLCP, "unknown country code \"%s\"", cp);
        !           362:     n2p ("rootDSA", 1) -> p_value =
        !           363:                            strdup (c -> c_root ? c -> c_root : c -> c_master);
        !           364:     if (c -> c_root)
        !           365:        read_psap (c -> c_root, &(n2p ("rootDSAaddress", 1) -> p_value));
        !           366:     n2p ("countryDSA", 1) -> p_value = strdup (c -> c_master);
        !           367:     read_psap (c -> c_master, &(n2p ("countryDSAaddress", 1) -> p_value));
        !           368:     if (c -> c_other) {
        !           369:        n2p ("otherDSA", 1) -> p_value = strdup (c -> c_other);
        !           370:        read_psap (c -> c_other, &(n2p ("otherDSAaddress", 1) -> p_value));
        !           371:     }
        !           372: 
        !           373:     if (n2p ("postaladdress", 0) == NULL
        !           374:            && n2p ("street", 0) == NULL
        !           375:            && n2p ("pob", 0) == NULL)
        !           376:        adios (NULLCP, "must specify either \"street\" or \"pob\"");
        !           377: 
        !           378:     if ((p = n2p ("locality", 1)) -> p_value == NULL) {
        !           379:        (void) sprintf (buffer, "%s, %s", n2p ("town", 1) -> p_value,
        !           380:                        n2p ("state", 1) -> p_value);
        !           381: 
        !           382:        p -> p_value = strdup (buffer);
        !           383: 
        !           384:        if (debug)
        !           385:            printf ("setting locality to \"%s\"\n", p -> p_value);
        !           386:     }
        !           387:     
        !           388:     if (*(p = n2p ("telephone", 1)) -> p_value != '+') {
        !           389:        (void) sprintf (buffer, "+%s %s", c -> c_phone, p -> p_value);
        !           390:        free (p -> p_value);
        !           391:        p -> p_value = strdup (buffer);
        !           392: 
        !           393:        if (debug)
        !           394:            printf ("setting telephone number to \"%s\"\n", p -> p_value);
        !           395:     }
        !           396: 
        !           397:     if ((p = n2p ("fax", 0)) && *p -> p_value != '+') {
        !           398:        (void) sprintf (buffer, "+%s %s", c -> c_phone, p -> p_value);
        !           399:        free (p -> p_value);
        !           400:        p -> p_value = strdup (buffer);
        !           401: 
        !           402:        if (debug)
        !           403:            printf ("setting fax number to \"%s\"\n", p -> p_value);
        !           404:     }
        !           405: 
        !           406:     if ((p = n2p ("ipaddr", 1)) -> p_value == NULL) {
        !           407:        if ((hp = gethostbyname (cp = getlocalhost ())) == NULL)
        !           408:            adios (NULLCP, "%s: unknown host", cp);
        !           409:     }
        !           410:     else {
        !           411:        if ((hp = gethostbystring (p -> p_value)) == NULL)
        !           412:            adios (NULLCP, "%s: unknown host", p -> p_value);
        !           413:     }
        !           414:     bzero ((char *) isock, sizeof *isock);
        !           415:     isock -> sin_family = hp -> h_addrtype;
        !           416:     inaddr_copy (hp, isock);
        !           417:     p -> p_value = strdup (inet_ntoa (isock -> sin_addr));
        !           418:     if (debug)
        !           419:        printf ("setting IP address of DSA to \"%s\"\n", p -> p_value);
        !           420: 
        !           421:     if ((p = n2p ("port", 1)) -> p_value == NULL) {
        !           422:        p -> p_value = strdup ("17003");
        !           423: 
        !           424:        if (debug)
        !           425:            printf ("setting TCP port of DSA to \"%s\"\n", p -> p_value);
        !           426:     }
        !           427: 
        !           428:     if ((p = n2p ("middlename", 1)) -> p_value
        !           429:            && (q = n2p ("middleinitial", 1)) -> p_value == NULL) {
        !           430:        (void) sprintf (buffer, "%c", *p -> p_value);
        !           431:        p -> p_value = strdup (buffer);
        !           432: 
        !           433:        if (debug)
        !           434:            printf ("setting MiddleInitial to \"%s\"\n", p -> p_value);
        !           435:     }
        !           436: 
        !           437:     uid = getuid (), gid = getgid ();
        !           438:     if ((p = n2p ("userid", 1)) -> p_value) {
        !           439:        register struct passwd *pw = getpwnam (p -> p_value);
        !           440: 
        !           441:        if (pw == NULL)
        !           442:            adios (NULLCP, "unknown user name \"%s\"", p -> p_value);
        !           443:        uid = pw -> pw_uid, gid = pw -> pw_gid;
        !           444:     }
        !           445:     else {
        !           446:        register struct passwd *pw = getpwuid (uid);
        !           447: 
        !           448:        if (pw == NULL)
        !           449:            adios (NULLCP, "unknown user name \"%s\"", p -> p_value);
        !           450:        p -> p_value = strdup (pw -> pw_name);
        !           451: 
        !           452:        if (debug)
        !           453:            printf ("setting userid to \"%s\"\n", p -> p_value);
        !           454:     }
        !           455: 
        !           456:     if (p = n2p ("groupid", 0)) {
        !           457:        register struct group *gr = getgrnam (p -> p_value);
        !           458: 
        !           459:        if (gr == NULL)
        !           460:            adios (NULLCP, "unknown group name \"%s\"", p -> p_value);
        !           461:        gid = gr -> gr_gid;
        !           462:     }
        !           463: 
        !           464:     p = n2p ("extension", 1), q = n2p ("telephone", 1);
        !           465:     if (cp = p -> p_value) {
        !           466:        if (*cp == 'X' || *cp == 'x') {
        !           467:            (void) sprintf (buffer, "%s x%s", q -> p_value, p -> p_value);
        !           468:            free (p -> p_value);
        !           469:            p -> p_value = strdup (buffer);
        !           470: 
        !           471:            if (debug)
        !           472:                printf ("setting user's telephone number to \"%s\"\n",
        !           473:                        p -> p_value);
        !           474:        }
        !           475:     }
        !           476:     else {
        !           477:        p -> p_value = strdup (q -> p_value);
        !           478: 
        !           479:        if (debug)
        !           480:            printf ("setting user telephone number to \"%s\"\n", p -> p_value);
        !           481:     }
        !           482: 
        !           483:     n2p ("wildlife", 1) -> p_value = strdup (wildlife);
        !           484:     n2p ("bindir", 1) -> p_value = strdup (isodebinpath);
        !           485:     n2p ("sbindir", 1) -> p_value = strdup (isodesbinpath);
        !           486:     n2p ("etcdir", 1) -> p_value = strdup (isodetcpath);
        !           487:     n2p ("quipuversion", 1) -> p_value = strdup (quipuversion);
        !           488: 
        !           489:     if (dp = (p = n2p ("postaladdress", 1)) -> p_value) {
        !           490:        int     i;
        !           491: 
        !           492:        for (i = 1; cp = index (dp, '$'); dp = cp + 1, i++) {
        !           493:            *cp = NULL;
        !           494:            if (strlen (dp) > 30)
        !           495:                goto too_long;
        !           496:            *cp = '$';
        !           497:        }
        !           498:        if (strlen (dp) > 30) {
        !           499: too_long: ;
        !           500:            adios (NULLCP,
        !           501:                   "item %d is too long (30 characters maximum): \"%s\"", i,
        !           502:                   dp);
        !           503:        }
        !           504:        if (i > 6)
        !           505:            adios (NULLCP, "too many items (%d) in postalAddress, 6 maximum",
        !           506:                   i);
        !           507:     }
        !           508:     else {
        !           509:        int     i;
        !           510: 
        !           511:        cp = buffer;
        !           512: 
        !           513:        (void) sprintf (cp, "%s $ ", n2p ("organization", 1) -> p_value);
        !           514:        if ((i = strlen (cp)) > 30 + 3) {
        !           515:            advise (NULLCP,
        !           516:                    "your organization name is longer than 30 characters!");
        !           517: postal_problem: ;
        !           518:            adios (NULLCP,
        !           519:           "You must explicitly define the postalAddress attribute in the\n\
        !           520:            configuration file for your Level-1 DSA.\n\
        !           521: \n\
        !           522:            The format is:\n\
        !           523: \n\
        !           524:                postaladdress \"item1 $ item2 $ ... $ itemN\"\n\
        !           525: \n\
        !           526:            where each item is <= 30 characters in length and there are no\n\
        !           527:            more than six items.  Refer to the Administrator's Guide for more\n\
        !           528:            information.\n\
        !           529: ");
        !           530:        }
        !           531:        cp += i;
        !           532: 
        !           533:        if (q = n2p ("pob", 0)) {
        !           534:            (void) sprintf (cp, "POB %s $ ", q -> p_value);
        !           535:            if ((i = strlen (cp)) > 30 + 3) {
        !           536:                advise (NULLCP, "your POB is longer than 26 characters!");
        !           537:                goto postal_problem;
        !           538:            }
        !           539:            cp += i;
        !           540:        }
        !           541:        else
        !           542:            if (q = n2p ("street", 0)) {
        !           543:                (void) sprintf (cp, "%s $ ", q -> p_value);
        !           544:                if ((i = strlen (cp)) > 30 + 3) {
        !           545:                    advise (NULLCP,
        !           546:                        "your street address is longer than 30 characters!");
        !           547:                    goto postal_problem;
        !           548:                }
        !           549:                cp += i;
        !           550: 
        !           551:                q -> p_flags |= P_ZAP;
        !           552:            }
        !           553: 
        !           554:        (void) sprintf (cp, "%s, %s %s $ ",
        !           555:                        n2p ("town", 1) -> p_value,
        !           556:                        n2p ("state", 1) -> p_value,
        !           557:                        n2p ("zipcode", 1) -> p_value);
        !           558:        if ((i = strlen (cp)) > 30 + 3) {
        !           559:            advise (NULLCP,
        !           560:                    "your town/state/zipcode is longer than 30 characters!");
        !           561:            goto postal_problem;
        !           562:        }
        !           563:        cp += i;
        !           564: 
        !           565:        if ((c -> c_flags & C_SHORT) || (i = strlen (dp = c -> c_name)) > 30)
        !           566:            i = strlen (dp = c -> c_code);
        !           567:        (void) strcpy (cp, dp);
        !           568:        cp += i;
        !           569: 
        !           570:        p -> p_value = strdup (buffer);
        !           571:     }
        !           572: }
        !           573: 
        !           574: /*  */
        !           575: 
        !           576: static struct country *read_country (code)
        !           577: char   *code;
        !           578: {
        !           579:     int            vecp;
        !           580:     register char *cp,
        !           581:                  *dp;
        !           582:     char    d,
        !           583:           *ep,
        !           584:            buffer[BUFSIZ + 1],
        !           585:            file[BUFSIZ],
        !           586:           *vec[NVEC + NSLACK + 1];
        !           587:     FILE   *fp;
        !           588:     static struct country cs;
        !           589:     register struct country *c = NULL;
        !           590: 
        !           591:     (void) strcpy (file, "iso3166");
        !           592:     if ((fp = fopen (file, "r")) == NULL)
        !           593:        adios (file, "unable to open");
        !           594: 
        !           595:     ep = (dp = buffer) + sizeof buffer;
        !           596:     while (fgets (dp, ep - dp, fp)) {
        !           597:        if (*buffer == '#')
        !           598:            continue;
        !           599:        if (cp = index (buffer, '\n')) {
        !           600:            *cp = NULL;
        !           601:            if ((d = getc (fp)) != EOF)
        !           602:                (void) ungetc (d, fp);
        !           603:            switch (d) {
        !           604:                case '#':
        !           605:                case '\n':
        !           606:                case EOF:
        !           607:                    break;
        !           608: 
        !           609:                default:
        !           610:                    *cp++ = ' ';
        !           611:                    if ((dp = cp) + 1 >= ep) {
        !           612:                        *ep = NULL;
        !           613:                        adios (NULLCP,
        !           614:                               "virtual line too long in %s: \"%s\"",
        !           615:                               file, cp);
        !           616:                    }
        !           617:                    continue;
        !           618:            }
        !           619:        }
        !           620: 
        !           621:        dp = buffer;
        !           622:        switch (vecp = str2vec (buffer, vec)) {
        !           623:            case 7:             /* standard entry */
        !           624:            case 8:
        !           625:                if (strcmp (vec[0], code))
        !           626:                    continue;
        !           627:                c = &cs;
        !           628:                bzero ((char *) c, sizeof *c);
        !           629:                c -> c_code = strdup (vec[0]);
        !           630:                if (sscanf (vec[1], "%d", &c -> c_number) != 1)
        !           631:                    adios (NULLCP,
        !           632:                           "malformed ISO3166 number for country %s in %s",
        !           633:                           code, file);
        !           634:                c -> c_number = atoi (vec[1]);
        !           635:                c -> c_name = strdup (vec[2]);
        !           636:                if (strcmp (vec[3], "NULL"))
        !           637:                    c -> c_root = strdup (vec[3]);
        !           638:                if (strcmp (vec[4], "NULL"))
        !           639:                    c -> c_master = strdup (vec[4]);
        !           640:                else
        !           641:                    adios (NULLCP, "no masterDSA known for country %s in %s",
        !           642:                           code,file);
        !           643:                if (strcmp (vec[5], "NULL"))
        !           644:                    c -> c_other = strdup (vec[5]);
        !           645:                c -> c_phone = strdup (vec[6]);
        !           646:                if (vecp == 8) {
        !           647:                    char   *bp;
        !           648: 
        !           649:                    if (strncmp (cp = vec[7], "0x", 2) == 0)
        !           650:                        cp += 2, bp = "%x";
        !           651:                    else
        !           652:                        if (*cp == '0')
        !           653:                            cp += 1, bp = "%o";
        !           654:                        else
        !           655:                            bp = "%d";
        !           656:                    if (sscanf (cp, bp, &c -> c_flags) != 1)
        !           657:                        adios (NULLCP,
        !           658:                              "malformed entry for country %s in %s",
        !           659:                               code, file);
        !           660:                }
        !           661:                break;
        !           662: 
        !           663:            default:
        !           664:                continue;
        !           665:        }
        !           666:        break;
        !           667:     }
        !           668: 
        !           669:     (void) fclose (fp);
        !           670: 
        !           671:     return c;
        !           672: }
        !           673: 
        !           674: /*  */
        !           675: 
        !           676: static read_psap (dsa, addr)
        !           677: char   *dsa,
        !           678:      **addr;
        !           679: {
        !           680:     int            i;
        !           681:     register char *cp,
        !           682:                  *dp;
        !           683:     char    buffer[BUFSIZ],
        !           684:            stuff[BUFSIZ];
        !           685:     FILE   *fp;
        !           686: 
        !           687:     if ((fp = fopen (cp = isodefile ("dsaptailor", 0), "r")) == NULL)
        !           688:        adios (cp, "unable to open");
        !           689: 
        !           690:     while (fgets (buffer, sizeof buffer, fp)) {
        !           691:        if (lexnequ (buffer, "dsa_address", sizeof "dsa_address" - 1)
        !           692:                || (cp = index (buffer, '"')) == NULL
        !           693:                || lexnequ (++cp, dsa + 3, i = strlen (dsa + 3))
        !           694:                || *(cp += i ) != '"')
        !           695:            continue;
        !           696:        for (cp++; isspace (*cp); cp++)
        !           697:            continue;
        !           698:        if (*cp == NULL) {
        !           699: malformed: ;
        !           700:            adios (NULLCP, "malformed entry in dsaptailor for DSA %s", dsa);
        !           701:        }
        !           702:        for (dp = stuff; *cp; *dp++ = *cp++) {
        !           703:            switch (*cp) {
        !           704:                case '\n':
        !           705:                    break;
        !           706: 
        !           707:                case '\'':
        !           708:                    *dp++ = '\\';
        !           709:                    /* and fall... */
        !           710:                case '\\':
        !           711:                    *dp++ = '\\';
        !           712:                    continue;
        !           713: 
        !           714:                default:
        !           715:                    continue;
        !           716:            }
        !           717:            break;
        !           718:        }
        !           719:        *dp = NULL;
        !           720:        if (*cp != '\n')
        !           721:            goto malformed;
        !           722:        *addr = strdup (stuff);
        !           723:        goto hit;
        !           724:     }
        !           725:     adios (NULLCP, "unable to find presentationAddress for DSA %s", dsa);
        !           726: 
        !           727: hit: ;
        !           728:     (void) fclose (fp);
        !           729: }
        !           730: 
        !           731: /*  */
        !           732: 
        !           733: generate_sed () {
        !           734:     FILE   *fp;
        !           735:     register struct pair *p;
        !           736: 
        !           737:     (void) sprintf (sedfil, "/tmp/%sXXXXXX", myname);
        !           738:     (void) unlink (mktemp (sedfil));
        !           739: 
        !           740:     if ((fp = fopen (sedfil, "w")) == NULL)
        !           741:        adios (sedfil, "unable to create");
        !           742: 
        !           743:     for (p = pairs; p -> p_name; p++)
        !           744:        if (!(p -> p_flags & P_MBOX) && p -> p_value)
        !           745:            fprintf (fp, "s!@(%s)!%s!\n", p -> p_name, p -> p_value);
        !           746: 
        !           747:     if (ferror (fp))
        !           748:        adios (sedfil, "error writing");
        !           749:     (void) fclose (fp);
        !           750: }
        !           751: 
        !           752: /*  */
        !           753: 
        !           754: static struct pair *n2p (name, any)
        !           755: char   *name;
        !           756: int    any;
        !           757: {
        !           758:     register struct pair *p;
        !           759: 
        !           760:     for (p = pairs; p -> p_name; p++)
        !           761:        if (strcmp (p -> p_name, name) == 0)
        !           762:            return (any || (p -> p_value && !(p -> p_flags & P_ZAP)) ? p
        !           763:                                                                      : NULL);
        !           764: 
        !           765:     adios (NULLCP, "internal error -- unable to find \"%s\"", name);
        !           766:     /* NOTREACHED */
        !           767: }
        !           768: 
        !           769: /*  */
        !           770: 
        !           771: static munge (fp, entries)
        !           772: FILE   *fp;
        !           773: char   *entries[];
        !           774: {
        !           775:     register char   c,
        !           776:                   *bp,
        !           777:                   *cp,
        !           778:                   *dp,
        !           779:                  **pp;
        !           780:     char    buffer[BUFSIZ];
        !           781:     register struct pair *p;
        !           782: 
        !           783: 
        !           784:     for (pp = entries; cp = *pp; pp++) {
        !           785:        bp = buffer;
        !           786: 
        !           787:        while (c = *cp++) {
        !           788:            if (c != '@' || *cp != '(') {
        !           789:                *bp++ = c;
        !           790:                continue;
        !           791:            }
        !           792:            if ((dp = index (++cp, ')')) == NULL)
        !           793:                adios (NULLCP, "internal error -- you lose big");
        !           794:            *dp = NULL;
        !           795: 
        !           796:            if ((p = n2p (cp, 0)) == NULL) {
        !           797:                bp = buffer;
        !           798:                goto no_match;
        !           799:            }
        !           800:            (void) strcpy (bp, p -> p_value);
        !           801:            bp += strlen (bp);
        !           802: 
        !           803:            cp = ++dp;
        !           804:        }
        !           805: 
        !           806:        *bp = NULL;
        !           807:        fprintf (fp, "%s\n", buffer);
        !           808: no_match: ;
        !           809:     }
        !           810: }
        !           811: 
        !           812: /*    EDB */
        !           813: 
        !           814: static build_root () {
        !           815:     if (debug)
        !           816:        fprintf (stderr, "mkdir %s\n", wildlife);
        !           817:     if (mkdir (wildlife, 0700) == NOTOK)
        !           818:        adios (wildlife, "unable to create directory");
        !           819: 
        !           820:     make_file ("root.edb", "EDB", 0600, 0);
        !           821: }
        !           822: 
        !           823: /*  */
        !           824: 
        !           825: static char *c_TLC[] = {
        !           826:     "o=@(organization)",
        !           827:     "masterDSA= c=@(country)@cn=@(dsa)#",
        !           828:     "acl= others # read # entry",
        !           829:     "acl= group # c=@(country)@o=@(organization)@cn=Manager # write # entry",
        !           830:     "acl= others # read # default",
        !           831:     "acl= group # c=@(country)@o=@(organization)@cn=Manager # write # default",
        !           832:     "acl= others # compare # attributes # accessControlList$userPassword",
        !           833:     "acl= group # c=@(country)@o=@(organization)@cn=Manager # write # attributes # accessControlList$userPassword",
        !           834:     "o= @(organization)",
        !           835:     "streetAddress= @(street)",
        !           836:     "postOfficeBox= @(pob)",
        !           837:     "physicalDeliveryOfficeName= @(town)",
        !           838:     "stateOrProvinceName= @(state)",
        !           839:     "postalCode= @(zipcode)",
        !           840:     "postalAddress= @(postaladdress)",
        !           841:     "telephoneNumber= @(telephone)",
        !           842:     "facsimileTelephoneNumber= @(fax)",
        !           843:     "localityName= @(locality)",
        !           844:     "description= @(description)",
        !           845:     "associatedDomain= @(domain)",
        !           846:     "treeStructure= quipuNonLeafObject & organizationalUnit",
        !           847:     "treeStructure= quipuDSA & alias & organizationalRole",
        !           848:     "treeStructure= domainRelatedObject",
        !           849:     "objectClass= top & quipuObject & quipuNonLeafObject",
        !           850:     "objectClass= domainRelatedObject",
        !           851:     "objectClass= organization",
        !           852:     "",
        !           853: 
        !           854:     "cn=@(dsa)",
        !           855:     "acl= others # read # entry",
        !           856:     "acl= group # c=@(country)@o=@(organization)@cn=Manager # write # entry",
        !           857:     "acl= others # read # default",
        !           858:     "acl= group # c=@(country)@o=@(organization)@cn=Manager # write # default",
        !           859:     "acl= others # compare # attributes # accessControlList$userPassword",
        !           860:     "acl= group # c=@(country)@o=@(organization)@cn=Manager # write # attributes # accessControlList$userPassword",
        !           861:     "cn= @(dsa)",
        !           862:     "eDBinfo= # @(rootDSA) #",
        !           863:     "eDBinfo= c=@(country) # @(countryDSA) #",
        !           864:     "eDBinfo= c=@(country)@o=@(organization) # # @(countryDSA)",
        !           865:     "eDBinfo= c=@(country)@o=@(organization) # # @(rootDSA)",
        !           866:     "eDBinfo= c=@(country)@o=@(organization) # # @(otherDSA)",
        !           867:     "presentationAddress= '0101'H/Internet=@(ipaddr)+@(port)",
        !           868:     "manager= c=@(country)@o=@(organization)@cn=Manager#",
        !           869:     "manager= c=@(country)@cn=Manager#",
        !           870:     "userPassword= @(wildlife)",
        !           871:     "quipuVersion= @(quipuversion)",
        !           872:     "localityName= @(locality)",
        !           873:     "description= The Endangered @(dsa)",
        !           874:     "description= Master DSA for @(organization) in the @(country)",
        !           875:     "objectClass= top & quipuObject",
        !           876:     "objectClass= applicationEntity & dSA & quipuDSA",
        !           877:     "supportedApplicationContext= x500DSP & x500DAP & quipuDSP",
        !           878:     "",
        !           879: 
        !           880:     NULL
        !           881: };
        !           882: 
        !           883: 
        !           884: static build_TLC () {
        !           885:     char    buffer[BUFSIZ];
        !           886: 
        !           887:     (void) sprintf (buffer, "%s/c=%s", wildlife,
        !           888:                    n2p ("country", 1) -> p_value);
        !           889:     make_edb (buffer, "SLAVE", "0000000000Z", c_TLC);
        !           890: }
        !           891: 
        !           892: /*  */
        !           893: 
        !           894: static char *o_I[] = {
        !           895:     "cn=Manager",
        !           896:     "acl=",
        !           897:     "cn= Manager",
        !           898:     "aliasedObjectName= c=@(country)@o=@(organization)@ou=@(unit)@cn=@(firstname) @(lastname)#",
        !           899:     "objectClass= top & quipuObject",
        !           900:     "objectClass= alias",
        !           901:     "",
        !           902: 
        !           903:     "cn=Postmaster",
        !           904:     "acl=",
        !           905:     "cn= Postmaster",
        !           906:     "aliasedObjectName= c=@(country)@o=@(organization)@ou=@(unit)@cn=@(firstname) @(lastname)#",
        !           907:     "objectClass= top & quipuObject",
        !           908:     "objectClass= alias",
        !           909:     "",
        !           910: 
        !           911:     "ou=@(unit)",
        !           912:     "masterDSA= c=@(country)@cn=@(dsa)#",
        !           913:     "acl= others # read # entry",
        !           914:     "acl= others # read # default",
        !           915:     "acl= others # compare # attributes # accessControlList$userPassword",
        !           916:     "ou= @(unit)",
        !           917:     "treeStructure= quipuNonLeafObject & organizationalUnit",
        !           918:     "treeStructure= alias & pilotPerson & organizationalRole",
        !           919:     "objectClass= top & quipuObject & quipuNonLeafObject",
        !           920:     "objectClass= organizationalUnit",
        !           921:     "",
        !           922: 
        !           923:     NULL
        !           924: };
        !           925:        
        !           926: 
        !           927: static build_organization () {
        !           928:     char    buffer[BUFSIZ];
        !           929: 
        !           930:     (void) sprintf (buffer, "%s/c=%s/o=%s", wildlife,
        !           931:                   n2p ("country", 1) -> p_value,
        !           932:                   n2p ("organization", 1) -> p_value);
        !           933:     make_edb (buffer, "MASTER", version (), o_I);
        !           934: }
        !           935: 
        !           936: /*  */
        !           937: 
        !           938: static char *u_J[] = {
        !           939:     "cn=@(firstname) @(lastname)",
        !           940:     "acl= self # write # entry",
        !           941:     "acl= others # read # entry",
        !           942:     "acl= self # write # default",
        !           943:     "acl= others # read # default",
        !           944:     "acl= self # write # attributes # accessControlList$userPassword",
        !           945:     "acl= others # compare # attributes # accessControlList$userPassword",
        !           946:     "rfc822Mailbox= @(mailbox)",
        !           947:     "otherMailbox = internet $ @(mailbox)",
        !           948:     "title= @(title)",
        !           949:     "userid= @(userid)",
        !           950:     "userPassword= @(password)",
        !           951:     "telephoneNumber= @(extension)",
        !           952:     "surname= @(lastname)",
        !           953:     "cn= @(firstname) @(lastname)",
        !           954:     "cn= @(firstname) @(middleinitial). @(lastname)",
        !           955:     "cn= @(firstname) @(middlename) @(lastname)",
        !           956:     "objectClass= top & quipuObject",
        !           957:     "objectClass= person & thornPerson & pilotPerson",
        !           958:     "",
        !           959: 
        !           960:     NULL
        !           961: };
        !           962: 
        !           963: 
        !           964: static build_unit () {
        !           965:     char    buffer[BUFSIZ];
        !           966: 
        !           967:     (void) sprintf (buffer, "%s/c=%s/o=%s/ou=%s", wildlife,
        !           968:                   n2p ("country", 1) -> p_value,
        !           969:                   n2p ("organization", 1) -> p_value,
        !           970:                   n2p ("unit", 1) -> p_value);
        !           971:     make_edb (buffer, "MASTER", version (), u_J);
        !           972: }
        !           973: 
        !           974: /*  */
        !           975: 
        !           976: static make_edb (dir, type, date, entries)
        !           977: char   *dir,
        !           978:        *type,
        !           979:        *date;
        !           980: char   *entries[];
        !           981: {
        !           982:     char    edb[BUFSIZ];
        !           983:     FILE   *fp;
        !           984: 
        !           985:     if (debug)
        !           986:        fprintf (stderr, "mkdir %s\n", dir);
        !           987:     if (mkdir (dir, 0700) == NOTOK)
        !           988:        adios (dir, "unable to create directory");
        !           989: 
        !           990:     (void) sprintf (edb, "%s/EDB", dir);
        !           991:     if (debug)
        !           992:        fprintf (stderr, "create %s\n", edb);
        !           993:     if ((fp = fopen (edb, "w")) == NULL)
        !           994:        adios (edb, "unable to create");
        !           995: 
        !           996:     fprintf (fp, "%s\n%s\n", type, date);
        !           997:     munge (fp, entries);
        !           998:     
        !           999:     if (ferror (fp))
        !          1000:        adios (edb, "error writing");
        !          1001:     (void) fclose (fp);
        !          1002: 
        !          1003:     (void) chmod (edb, 0600);
        !          1004: }
        !          1005: 
        !          1006: /*  */
        !          1007: 
        !          1008: static char *version () {
        !          1009:     long    clock;
        !          1010:     struct UTCtime ut;
        !          1011:     static char buffer[BUFSIZ];
        !          1012: 
        !          1013:     (void) time (&clock);
        !          1014:     tm2ut (gmtime (&clock), &ut);
        !          1015:     (void) strcpy (buffer, gent2str (&ut));
        !          1016: 
        !          1017:     return buffer;
        !          1018: }
        !          1019: 
        !          1020: /*    FILES */
        !          1021: 
        !          1022: static build_tailor () { make_file ("quiputailor", "quiputailor", 0644, 1); }
        !          1023: 
        !          1024: static build_startup () { make_file ("startup.sh", "startup.sh", 0755, 1); }
        !          1025: 
        !          1026: static build_nightly () { make_file ("nightly.sh", "nightly.sh", 0755, 1); }
        !          1027: 
        !          1028: /*  */
        !          1029: 
        !          1030: static make_file (infile, outfile, mode, dosed)
        !          1031: char   *infile,
        !          1032:        *outfile;
        !          1033: int    mode,
        !          1034:        dosed;
        !          1035: {
        !          1036:     char    buffer[BUFSIZ];
        !          1037: 
        !          1038:     if (dosed)
        !          1039:        (void) sprintf (buffer, "sed -f %s < templates/%s > %s/%s",
        !          1040:                        sedfil, infile, wildlife, outfile);
        !          1041:     else
        !          1042:        (void) sprintf (buffer, "cp templates/%s %s/%s", infile, wildlife,
        !          1043:                        outfile);
        !          1044: 
        !          1045:     if (debug)
        !          1046:        fprintf (stderr, "%s\n", buffer);
        !          1047:     if (system (buffer) != 0)
        !          1048:        adios (NULLCP, "%s of %s failed", dosed ? "sed" : "cp", infile);
        !          1049: 
        !          1050:     (void) sprintf (buffer, "%s/%s", wildlife, outfile);
        !          1051:     (void) chmod (buffer, mode);
        !          1052: }
        !          1053: 
        !          1054: /*    SED */
        !          1055: 
        !          1056: static build_dsap () { fudge_file ("dsaptailor"); }
        !          1057: 
        !          1058: static build_fred () { fudge_file ("fredrc"); fudge_file ("ufnrc"); }
        !          1059: 
        !          1060: /*  */
        !          1061: 
        !          1062: static fudge_file (name)
        !          1063: char   *name;
        !          1064: {
        !          1065:     char   buffer[BUFSIZ],
        !          1066:           file[BUFSIZ],
        !          1067:           oldfil[BUFSIZ],
        !          1068:           tmpfil[BUFSIZ];
        !          1069: 
        !          1070:     (void) strcpy (file, isodefile (name, 0));
        !          1071:     
        !          1072:     (void) sprintf (buffer, "%sXXXXXX", myname);
        !          1073:     (void) strcpy (tmpfil, isodefile (buffer, 0));
        !          1074:     (void) unlink (mktemp (tmpfil));
        !          1075: 
        !          1076:     (void) sprintf (buffer, "sed -f %s < %s > %s", sedfil, file, tmpfil);
        !          1077:     if (debug)
        !          1078:        fprintf (stderr, "%s\n", buffer);
        !          1079:     if (system (buffer) != 0) {
        !          1080:        (void) unlink (tmpfil);
        !          1081:        adios (NULLCP, "sed failed");
        !          1082:     }
        !          1083: 
        !          1084:     (void) sprintf (oldfil, "%s.old", file);
        !          1085:     if (access (oldfil, 0x00) == NOTOK)
        !          1086:        (void) rename (file, oldfil);
        !          1087:     if (rename (tmpfil, file) == NOTOK)
        !          1088:        adios (file, "unable to rename %s to", tmpfil);
        !          1089: }
        !          1090: 
        !          1091: /*    ARGINIT */
        !          1092: 
        !          1093: static arginit (vec)
        !          1094: char  **vec;
        !          1095: {
        !          1096:     register char  *ap;
        !          1097: 
        !          1098:     if (myname = rindex (*vec, '/'))
        !          1099:        myname++;
        !          1100:     if (myname == NULL || *myname == NULL)
        !          1101:        myname = *vec;
        !          1102: 
        !          1103:     isodetailor (myname, 1);
        !          1104: 
        !          1105:     for (vec++; ap = *vec; vec++) {
        !          1106:        if (*ap == '-') {
        !          1107:            while (*++ap)
        !          1108:                switch (*ap) {
        !          1109:                    case 'd':
        !          1110:                        debug++;
        !          1111:                        break;
        !          1112: 
        !          1113:                    default:
        !          1114:                        adios (NULLCP, "unknown switch -%c", *ap);
        !          1115:                }
        !          1116:            continue;
        !          1117:        }
        !          1118: 
        !          1119:        if (wildlife) {
        !          1120: usage: ;
        !          1121:            adios (NULLCP, "usage: %s config-file", myname);
        !          1122:        }
        !          1123:        wildlife = ap;
        !          1124:     }
        !          1125: 
        !          1126:     if (!wildlife)
        !          1127:        goto usage;
        !          1128: }
        !          1129: 
        !          1130: /*    ERRORS */
        !          1131: 
        !          1132: #ifndef        lint
        !          1133: void   _advise ();
        !          1134: 
        !          1135: 
        !          1136: static void  adios (va_alist)
        !          1137: va_dcl
        !          1138: {
        !          1139:     va_list ap;
        !          1140: 
        !          1141:     va_start (ap);
        !          1142: 
        !          1143:     _advise (ap);
        !          1144: 
        !          1145:     va_end (ap);
        !          1146: 
        !          1147:     _exit (1);
        !          1148: }
        !          1149: #else
        !          1150: /* VARARGS */
        !          1151: 
        !          1152: static void  adios (what, fmt)
        !          1153: char   *what,
        !          1154:        *fmt;
        !          1155: {
        !          1156:     adios (what, fmt);
        !          1157: }
        !          1158: #endif
        !          1159: 
        !          1160: 
        !          1161: #ifndef        lint
        !          1162: static void  advise (va_alist)
        !          1163: va_dcl
        !          1164: {
        !          1165:     va_list ap;
        !          1166: 
        !          1167:     va_start (ap);
        !          1168: 
        !          1169:     _advise (ap);
        !          1170: 
        !          1171:     va_end (ap);
        !          1172: }
        !          1173: 
        !          1174: 
        !          1175: static void  _advise (ap)
        !          1176: va_list        ap;
        !          1177: {
        !          1178:     char    buffer[BUFSIZ];
        !          1179: 
        !          1180:     asprintf (buffer, ap);
        !          1181: 
        !          1182:     (void) fflush (stdout);
        !          1183: 
        !          1184:     fprintf (stderr, "%s: ", myname);
        !          1185:     (void) fputs (buffer, stderr);
        !          1186:     (void) fputc ('\n', stderr);
        !          1187: 
        !          1188:     (void) fflush (stderr);
        !          1189: }
        !          1190: #else
        !          1191: /* VARARGS */
        !          1192: 
        !          1193: static void  advise (what, fmt)
        !          1194: char   *what,
        !          1195:        *fmt;
        !          1196: {
        !          1197:     advise (what, fmt);
        !          1198: }
        !          1199: #endif
        !          1200: 
        !          1201: /*    MISCELLANY */
        !          1202: 
        !          1203: #ifndef        lint
        !          1204: static char *strdup (s)
        !          1205: char   *s;
        !          1206: {
        !          1207:     char    *p;
        !          1208: 
        !          1209:     if ((p = malloc((unsigned) (strlen (s) + 1))) == NULL)
        !          1210:        adios (NULLCP, "out of memory");
        !          1211: 
        !          1212:     (void) strcpy (p, s);
        !          1213: 
        !          1214:     return p;
        !          1215: }
        !          1216: #endif

unix.superglobalmegacorp.com

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