Annotation of 43BSDReno/usr.bin/mail/cmd3.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)cmd3.c     5.24 (Berkeley) 6/25/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #include "rcv.h"
        !            25: 
        !            26: /*
        !            27:  * Mail -- a mail program
        !            28:  *
        !            29:  * Still more user commands.
        !            30:  */
        !            31: 
        !            32: /*
        !            33:  * Process a shell escape by saving signals, ignoring signals,
        !            34:  * and forking a sh -c
        !            35:  */
        !            36: shell(str)
        !            37:        char *str;
        !            38: {
        !            39:        sig_t sigint = signal(SIGINT, SIG_IGN);
        !            40:        char *shell;
        !            41:        char cmd[BUFSIZ];
        !            42: 
        !            43:        (void) strcpy(cmd, str);
        !            44:        if (bangexp(cmd) < 0)
        !            45:                return 1;
        !            46:        if ((shell = value("SHELL")) == NOSTR)
        !            47:                shell = _PATH_CSHELL;
        !            48:        (void) run_command(shell, 0, -1, -1, "-c", cmd, NOSTR);
        !            49:        (void) signal(SIGINT, sigint);
        !            50:        printf("!\n");
        !            51:        return 0;
        !            52: }
        !            53: 
        !            54: /*
        !            55:  * Fork an interactive shell.
        !            56:  */
        !            57: /*ARGSUSED*/
        !            58: dosh(str)
        !            59:        char *str;
        !            60: {
        !            61:        sig_t sigint = signal(SIGINT, SIG_IGN);
        !            62:        char *shell;
        !            63: 
        !            64:        if ((shell = value("SHELL")) == NOSTR)
        !            65:                shell = _PATH_CSHELL;
        !            66:        (void) run_command(shell, 0, -1, -1, NOSTR);
        !            67:        (void) signal(SIGINT, sigint);
        !            68:        putchar('\n');
        !            69:        return 0;
        !            70: }
        !            71: 
        !            72: /*
        !            73:  * Expand the shell escape by expanding unescaped !'s into the
        !            74:  * last issued command where possible.
        !            75:  */
        !            76: 
        !            77: char   lastbang[128];
        !            78: 
        !            79: bangexp(str)
        !            80:        char *str;
        !            81: {
        !            82:        char bangbuf[BUFSIZ];
        !            83:        register char *cp, *cp2;
        !            84:        register int n;
        !            85:        int changed = 0;
        !            86: 
        !            87:        cp = str;
        !            88:        cp2 = bangbuf;
        !            89:        n = BUFSIZ;
        !            90:        while (*cp) {
        !            91:                if (*cp == '!') {
        !            92:                        if (n < strlen(lastbang)) {
        !            93: overf:
        !            94:                                printf("Command buffer overflow\n");
        !            95:                                return(-1);
        !            96:                        }
        !            97:                        changed++;
        !            98:                        strcpy(cp2, lastbang);
        !            99:                        cp2 += strlen(lastbang);
        !           100:                        n -= strlen(lastbang);
        !           101:                        cp++;
        !           102:                        continue;
        !           103:                }
        !           104:                if (*cp == '\\' && cp[1] == '!') {
        !           105:                        if (--n <= 1)
        !           106:                                goto overf;
        !           107:                        *cp2++ = '!';
        !           108:                        cp += 2;
        !           109:                        changed++;
        !           110:                }
        !           111:                if (--n <= 1)
        !           112:                        goto overf;
        !           113:                *cp2++ = *cp++;
        !           114:        }
        !           115:        *cp2 = 0;
        !           116:        if (changed) {
        !           117:                printf("!%s\n", bangbuf);
        !           118:                fflush(stdout);
        !           119:        }
        !           120:        strcpy(str, bangbuf);
        !           121:        strncpy(lastbang, bangbuf, 128);
        !           122:        lastbang[127] = 0;
        !           123:        return(0);
        !           124: }
        !           125: 
        !           126: /*
        !           127:  * Print out a nice help message from some file or another.
        !           128:  */
        !           129: 
        !           130: help()
        !           131: {
        !           132:        register c;
        !           133:        register FILE *f;
        !           134: 
        !           135:        if ((f = Fopen(_PATH_HELP, "r")) == NULL) {
        !           136:                perror(_PATH_HELP);
        !           137:                return(1);
        !           138:        }
        !           139:        while ((c = getc(f)) != EOF)
        !           140:                putchar(c);
        !           141:        Fclose(f);
        !           142:        return(0);
        !           143: }
        !           144: 
        !           145: /*
        !           146:  * Change user's working directory.
        !           147:  */
        !           148: schdir(arglist)
        !           149:        char **arglist;
        !           150: {
        !           151:        char *cp;
        !           152: 
        !           153:        if (*arglist == NOSTR)
        !           154:                cp = homedir;
        !           155:        else
        !           156:                if ((cp = expand(*arglist)) == NOSTR)
        !           157:                        return(1);
        !           158:        if (chdir(cp) < 0) {
        !           159:                perror(cp);
        !           160:                return(1);
        !           161:        }
        !           162:        return 0;
        !           163: }
        !           164: 
        !           165: respond(msgvec)
        !           166:        int *msgvec;
        !           167: {
        !           168:        if (value("Replyall") == NOSTR)
        !           169:                return (_respond(msgvec));
        !           170:        else
        !           171:                return (_Respond(msgvec));
        !           172: }
        !           173: 
        !           174: /*
        !           175:  * Reply to a list of messages.  Extract each name from the
        !           176:  * message header and send them off to mail1()
        !           177:  */
        !           178: _respond(msgvec)
        !           179:        int *msgvec;
        !           180: {
        !           181:        struct message *mp;
        !           182:        char *cp, *rcv, *replyto;
        !           183:        char **ap;
        !           184:        struct name *np;
        !           185:        struct header head;
        !           186: 
        !           187:        if (msgvec[1] != 0) {
        !           188:                printf("Sorry, can't reply to multiple messages at once\n");
        !           189:                return(1);
        !           190:        }
        !           191:        mp = &message[msgvec[0] - 1];
        !           192:        touch(mp);
        !           193:        dot = mp;
        !           194:        if ((rcv = skin(hfield("from", mp))) == NOSTR)
        !           195:                rcv = skin(nameof(mp, 1));
        !           196:        if ((replyto = skin(hfield("reply-to", mp))) != NOSTR)
        !           197:                np = extract(replyto, GTO);
        !           198:        else if ((cp = skin(hfield("to", mp))) != NOSTR)
        !           199:                np = extract(cp, GTO);
        !           200:        else
        !           201:                np = NIL;
        !           202:        np = elide(np);
        !           203:        /*
        !           204:         * Delete my name from the reply list,
        !           205:         * and with it, all my alternate names.
        !           206:         */
        !           207:        np = delname(np, myname);
        !           208:        if (altnames)
        !           209:                for (ap = altnames; *ap; ap++)
        !           210:                        np = delname(np, *ap);
        !           211:        if (np != NIL && replyto == NOSTR)
        !           212:                np = cat(np, extract(rcv, GTO));
        !           213:        else if (np == NIL) {
        !           214:                if (replyto != NOSTR)
        !           215:                        printf("Empty reply-to field -- replying to author\n");
        !           216:                np = extract(rcv, GTO);
        !           217:        }
        !           218:        head.h_to = np;
        !           219:        if ((head.h_subject = hfield("subject", mp)) == NOSTR)
        !           220:                head.h_subject = hfield("subj", mp);
        !           221:        head.h_subject = reedit(head.h_subject);
        !           222:        if (replyto == NOSTR && (cp = skin(hfield("cc", mp))) != NOSTR) {
        !           223:                np = elide(extract(cp, GCC));
        !           224:                np = delname(np, myname);
        !           225:                if (altnames != 0)
        !           226:                        for (ap = altnames; *ap; ap++)
        !           227:                                np = delname(np, *ap);
        !           228:                head.h_cc = np;
        !           229:        } else
        !           230:                head.h_cc = NIL;
        !           231:        head.h_bcc = NIL;
        !           232:        head.h_smopts = NIL;
        !           233:        mail1(&head, 1);
        !           234:        return(0);
        !           235: }
        !           236: 
        !           237: /*
        !           238:  * Modify the subject we are replying to to begin with Re: if
        !           239:  * it does not already.
        !           240:  */
        !           241: char *
        !           242: reedit(subj)
        !           243:        register char *subj;
        !           244: {
        !           245:        char *newsubj;
        !           246: 
        !           247:        if (subj == NOSTR)
        !           248:                return NOSTR;
        !           249:        if ((subj[0] == 'r' || subj[0] == 'R') &&
        !           250:            (subj[1] == 'e' || subj[1] == 'E') &&
        !           251:            subj[2] == ':')
        !           252:                return subj;
        !           253:        newsubj = salloc(strlen(subj) + 5);
        !           254:        strcpy(newsubj, "Re: ");
        !           255:        strcpy(newsubj + 4, subj);
        !           256:        return newsubj;
        !           257: }
        !           258: 
        !           259: /*
        !           260:  * Preserve the named messages, so that they will be sent
        !           261:  * back to the system mailbox.
        !           262:  */
        !           263: 
        !           264: preserve(msgvec)
        !           265:        int *msgvec;
        !           266: {
        !           267:        register struct message *mp;
        !           268:        register int *ip, mesg;
        !           269: 
        !           270:        if (edit) {
        !           271:                printf("Cannot \"preserve\" in edit mode\n");
        !           272:                return(1);
        !           273:        }
        !           274:        for (ip = msgvec; *ip != NULL; ip++) {
        !           275:                mesg = *ip;
        !           276:                mp = &message[mesg-1];
        !           277:                mp->m_flag |= MPRESERVE;
        !           278:                mp->m_flag &= ~MBOX;
        !           279:                dot = mp;
        !           280:        }
        !           281:        return(0);
        !           282: }
        !           283: 
        !           284: /*
        !           285:  * Mark all given messages as unread.
        !           286:  */
        !           287: unread(msgvec)
        !           288:        int     msgvec[];
        !           289: {
        !           290:        register int *ip;
        !           291: 
        !           292:        for (ip = msgvec; *ip != NULL; ip++) {
        !           293:                dot = &message[*ip-1];
        !           294:                dot->m_flag &= ~(MREAD|MTOUCH);
        !           295:                dot->m_flag |= MSTATUS;
        !           296:        }
        !           297:        return(0);
        !           298: }
        !           299: 
        !           300: /*
        !           301:  * Print the size of each message.
        !           302:  */
        !           303: 
        !           304: messize(msgvec)
        !           305:        int *msgvec;
        !           306: {
        !           307:        register struct message *mp;
        !           308:        register int *ip, mesg;
        !           309: 
        !           310:        for (ip = msgvec; *ip != NULL; ip++) {
        !           311:                mesg = *ip;
        !           312:                mp = &message[mesg-1];
        !           313:                printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size);
        !           314:        }
        !           315:        return(0);
        !           316: }
        !           317: 
        !           318: /*
        !           319:  * Quit quickly.  If we are sourcing, just pop the input level
        !           320:  * by returning an error.
        !           321:  */
        !           322: 
        !           323: rexit(e)
        !           324: {
        !           325:        if (sourcing)
        !           326:                return(1);
        !           327:        exit(e);
        !           328:        /*NOTREACHED*/
        !           329: }
        !           330: 
        !           331: /*
        !           332:  * Set or display a variable value.  Syntax is similar to that
        !           333:  * of csh.
        !           334:  */
        !           335: 
        !           336: set(arglist)
        !           337:        char **arglist;
        !           338: {
        !           339:        register struct var *vp;
        !           340:        register char *cp, *cp2;
        !           341:        char varbuf[BUFSIZ], **ap, **p;
        !           342:        int errs, h, s;
        !           343: 
        !           344:        if (*arglist == NOSTR) {
        !           345:                for (h = 0, s = 1; h < HSHSIZE; h++)
        !           346:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
        !           347:                                s++;
        !           348:                ap = (char **) salloc(s * sizeof *ap);
        !           349:                for (h = 0, p = ap; h < HSHSIZE; h++)
        !           350:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
        !           351:                                *p++ = vp->v_name;
        !           352:                *p = NOSTR;
        !           353:                sort(ap);
        !           354:                for (p = ap; *p != NOSTR; p++)
        !           355:                        printf("%s\t%s\n", *p, value(*p));
        !           356:                return(0);
        !           357:        }
        !           358:        errs = 0;
        !           359:        for (ap = arglist; *ap != NOSTR; ap++) {
        !           360:                cp = *ap;
        !           361:                cp2 = varbuf;
        !           362:                while (*cp != '=' && *cp != '\0')
        !           363:                        *cp2++ = *cp++;
        !           364:                *cp2 = '\0';
        !           365:                if (*cp == '\0')
        !           366:                        cp = "";
        !           367:                else
        !           368:                        cp++;
        !           369:                if (equal(varbuf, "")) {
        !           370:                        printf("Non-null variable name required\n");
        !           371:                        errs++;
        !           372:                        continue;
        !           373:                }
        !           374:                assign(varbuf, cp);
        !           375:        }
        !           376:        return(errs);
        !           377: }
        !           378: 
        !           379: /*
        !           380:  * Unset a bunch of variable values.
        !           381:  */
        !           382: 
        !           383: unset(arglist)
        !           384:        char **arglist;
        !           385: {
        !           386:        register struct var *vp, *vp2;
        !           387:        int errs, h;
        !           388:        char **ap;
        !           389: 
        !           390:        errs = 0;
        !           391:        for (ap = arglist; *ap != NOSTR; ap++) {
        !           392:                if ((vp2 = lookup(*ap)) == NOVAR) {
        !           393:                        if (!sourcing) {
        !           394:                                printf("\"%s\": undefined variable\n", *ap);
        !           395:                                errs++;
        !           396:                        }
        !           397:                        continue;
        !           398:                }
        !           399:                h = hash(*ap);
        !           400:                if (vp2 == variables[h]) {
        !           401:                        variables[h] = variables[h]->v_link;
        !           402:                        vfree(vp2->v_name);
        !           403:                        vfree(vp2->v_value);
        !           404:                        cfree((char *)vp2);
        !           405:                        continue;
        !           406:                }
        !           407:                for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
        !           408:                        ;
        !           409:                vp->v_link = vp2->v_link;
        !           410:                vfree(vp2->v_name);
        !           411:                vfree(vp2->v_value);
        !           412:                cfree((char *) vp2);
        !           413:        }
        !           414:        return(errs);
        !           415: }
        !           416: 
        !           417: /*
        !           418:  * Put add users to a group.
        !           419:  */
        !           420: 
        !           421: group(argv)
        !           422:        char **argv;
        !           423: {
        !           424:        register struct grouphead *gh;
        !           425:        register struct group *gp;
        !           426:        register int h;
        !           427:        int s;
        !           428:        char **ap, *gname, **p;
        !           429: 
        !           430:        if (*argv == NOSTR) {
        !           431:                for (h = 0, s = 1; h < HSHSIZE; h++)
        !           432:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
        !           433:                                s++;
        !           434:                ap = (char **) salloc(s * sizeof *ap);
        !           435:                for (h = 0, p = ap; h < HSHSIZE; h++)
        !           436:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
        !           437:                                *p++ = gh->g_name;
        !           438:                *p = NOSTR;
        !           439:                sort(ap);
        !           440:                for (p = ap; *p != NOSTR; p++)
        !           441:                        printgroup(*p);
        !           442:                return(0);
        !           443:        }
        !           444:        if (argv[1] == NOSTR) {
        !           445:                printgroup(*argv);
        !           446:                return(0);
        !           447:        }
        !           448:        gname = *argv;
        !           449:        h = hash(gname);
        !           450:        if ((gh = findgroup(gname)) == NOGRP) {
        !           451:                gh = (struct grouphead *) calloc(sizeof *gh, 1);
        !           452:                gh->g_name = vcopy(gname);
        !           453:                gh->g_list = NOGE;
        !           454:                gh->g_link = groups[h];
        !           455:                groups[h] = gh;
        !           456:        }
        !           457: 
        !           458:        /*
        !           459:         * Insert names from the command list into the group.
        !           460:         * Who cares if there are duplicates?  They get tossed
        !           461:         * later anyway.
        !           462:         */
        !           463: 
        !           464:        for (ap = argv+1; *ap != NOSTR; ap++) {
        !           465:                gp = (struct group *) calloc(sizeof *gp, 1);
        !           466:                gp->ge_name = vcopy(*ap);
        !           467:                gp->ge_link = gh->g_list;
        !           468:                gh->g_list = gp;
        !           469:        }
        !           470:        return(0);
        !           471: }
        !           472: 
        !           473: /*
        !           474:  * Sort the passed string vecotor into ascending dictionary
        !           475:  * order.
        !           476:  */
        !           477: 
        !           478: sort(list)
        !           479:        char **list;
        !           480: {
        !           481:        register char **ap;
        !           482:        int diction();
        !           483: 
        !           484:        for (ap = list; *ap != NOSTR; ap++)
        !           485:                ;
        !           486:        if (ap-list < 2)
        !           487:                return;
        !           488:        qsort((char *)list, ap-list, sizeof *list, diction);
        !           489: }
        !           490: 
        !           491: /*
        !           492:  * Do a dictionary order comparison of the arguments from
        !           493:  * qsort.
        !           494:  */
        !           495: 
        !           496: diction(a, b)
        !           497:        register char **a, **b;
        !           498: {
        !           499:        return(strcmp(*a, *b));
        !           500: }
        !           501: 
        !           502: /*
        !           503:  * The do nothing command for comments.
        !           504:  */
        !           505: 
        !           506: /*ARGSUSED*/
        !           507: null(e)
        !           508: {
        !           509:        return 0;
        !           510: }
        !           511: 
        !           512: /*
        !           513:  * Change to another file.  With no argument, print information about
        !           514:  * the current file.
        !           515:  */
        !           516: file(argv)
        !           517:        register char **argv;
        !           518: {
        !           519: 
        !           520:        if (argv[0] == NOSTR) {
        !           521:                newfileinfo();
        !           522:                return 0;
        !           523:        }
        !           524:        if (setfile(*argv) < 0)
        !           525:                return 1;
        !           526:        announce();
        !           527:        return 0;
        !           528: }
        !           529: 
        !           530: /*
        !           531:  * Expand file names like echo
        !           532:  */
        !           533: echo(argv)
        !           534:        char **argv;
        !           535: {
        !           536:        register char **ap;
        !           537:        register char *cp;
        !           538: 
        !           539:        for (ap = argv; *ap != NOSTR; ap++) {
        !           540:                cp = *ap;
        !           541:                if ((cp = expand(cp)) != NOSTR) {
        !           542:                        if (ap != argv)
        !           543:                                putchar(' ');
        !           544:                        printf("%s", cp);
        !           545:                }
        !           546:        }
        !           547:        putchar('\n');
        !           548:        return 0;
        !           549: }
        !           550: 
        !           551: Respond(msgvec)
        !           552:        int *msgvec;
        !           553: {
        !           554:        if (value("Replyall") == NOSTR)
        !           555:                return (_Respond(msgvec));
        !           556:        else
        !           557:                return (_respond(msgvec));
        !           558: }
        !           559: 
        !           560: /*
        !           561:  * Reply to a series of messages by simply mailing to the senders
        !           562:  * and not messing around with the To: and Cc: lists as in normal
        !           563:  * reply.
        !           564:  */
        !           565: _Respond(msgvec)
        !           566:        int msgvec[];
        !           567: {
        !           568:        struct header head;
        !           569:        struct message *mp;
        !           570:        register int *ap;
        !           571:        register char *cp;
        !           572: 
        !           573:        head.h_to = NIL;
        !           574:        for (ap = msgvec; *ap != 0; ap++) {
        !           575:                mp = &message[*ap - 1];
        !           576:                touch(mp);
        !           577:                dot = mp;
        !           578:                if ((cp = skin(hfield("from", mp))) == NOSTR)
        !           579:                        cp = skin(nameof(mp, 2));
        !           580:                head.h_to = cat(head.h_to, extract(cp, GTO));
        !           581:        }
        !           582:        if (head.h_to == NIL)
        !           583:                return 0;
        !           584:        mp = &message[msgvec[0] - 1];
        !           585:        if ((head.h_subject = hfield("subject", mp)) == NOSTR)
        !           586:                head.h_subject = hfield("subj", mp);
        !           587:        head.h_subject = reedit(head.h_subject);
        !           588:        head.h_cc = NIL;
        !           589:        head.h_bcc = NIL;
        !           590:        head.h_smopts = NIL;
        !           591:        mail1(&head, 1);
        !           592:        return 0;
        !           593: }
        !           594: 
        !           595: /*
        !           596:  * Conditional commands.  These allow one to parameterize one's
        !           597:  * .mailrc and do some things if sending, others if receiving.
        !           598:  */
        !           599: 
        !           600: ifcmd(argv)
        !           601:        char **argv;
        !           602: {
        !           603:        register char *cp;
        !           604: 
        !           605:        if (cond != CANY) {
        !           606:                printf("Illegal nested \"if\"\n");
        !           607:                return(1);
        !           608:        }
        !           609:        cond = CANY;
        !           610:        cp = argv[0];
        !           611:        switch (*cp) {
        !           612:        case 'r': case 'R':
        !           613:                cond = CRCV;
        !           614:                break;
        !           615: 
        !           616:        case 's': case 'S':
        !           617:                cond = CSEND;
        !           618:                break;
        !           619: 
        !           620:        default:
        !           621:                printf("Unrecognized if-keyword: \"%s\"\n", cp);
        !           622:                return(1);
        !           623:        }
        !           624:        return(0);
        !           625: }
        !           626: 
        !           627: /*
        !           628:  * Implement 'else'.  This is pretty simple -- we just
        !           629:  * flip over the conditional flag.
        !           630:  */
        !           631: 
        !           632: elsecmd()
        !           633: {
        !           634: 
        !           635:        switch (cond) {
        !           636:        case CANY:
        !           637:                printf("\"Else\" without matching \"if\"\n");
        !           638:                return(1);
        !           639: 
        !           640:        case CSEND:
        !           641:                cond = CRCV;
        !           642:                break;
        !           643: 
        !           644:        case CRCV:
        !           645:                cond = CSEND;
        !           646:                break;
        !           647: 
        !           648:        default:
        !           649:                printf("Mail's idea of conditions is screwed up\n");
        !           650:                cond = CANY;
        !           651:                break;
        !           652:        }
        !           653:        return(0);
        !           654: }
        !           655: 
        !           656: /*
        !           657:  * End of if statement.  Just set cond back to anything.
        !           658:  */
        !           659: 
        !           660: endifcmd()
        !           661: {
        !           662: 
        !           663:        if (cond == CANY) {
        !           664:                printf("\"Endif\" without matching \"if\"\n");
        !           665:                return(1);
        !           666:        }
        !           667:        cond = CANY;
        !           668:        return(0);
        !           669: }
        !           670: 
        !           671: /*
        !           672:  * Set the list of alternate names.
        !           673:  */
        !           674: alternates(namelist)
        !           675:        char **namelist;
        !           676: {
        !           677:        register int c;
        !           678:        register char **ap, **ap2, *cp;
        !           679: 
        !           680:        c = argcount(namelist) + 1;
        !           681:        if (c == 1) {
        !           682:                if (altnames == 0)
        !           683:                        return(0);
        !           684:                for (ap = altnames; *ap; ap++)
        !           685:                        printf("%s ", *ap);
        !           686:                printf("\n");
        !           687:                return(0);
        !           688:        }
        !           689:        if (altnames != 0)
        !           690:                cfree((char *) altnames);
        !           691:        altnames = (char **) calloc((unsigned) c, sizeof (char *));
        !           692:        for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
        !           693:                cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char));
        !           694:                strcpy(cp, *ap);
        !           695:                *ap2 = cp;
        !           696:        }
        !           697:        *ap2 = 0;
        !           698:        return(0);
        !           699: }

unix.superglobalmegacorp.com

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