Annotation of researchv10no/lbin/mailx/names.c, revision 1.1

1.1     ! root        1: #ident "@(#)names.c    1.5 'attmail mail(1) command'"
        !             2: #ident "@(#)mailx:names.c      1.10.1.2"
        !             3: /*     Copyright (c) 1984 AT&T */
        !             4: /*       All Rights Reserved   */
        !             5: 
        !             6: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
        !             7: /*     The copyright notice above does not evidence any        */
        !             8: /*     actual or intended publication of such source code.     */
        !             9: 
        !            10: #ident "@(#)mailx:names.c      1.10.1.1"
        !            11: 
        !            12: /*
        !            13:  * mailx -- a modified version of a University of California at Berkeley
        !            14:  *     mail program
        !            15:  *
        !            16:  * Handle name lists.
        !            17:  */
        !            18: 
        !            19: #include "rcv.h"
        !            20: 
        !            21: static struct name     *nalloc();
        !            22: static int             isfileaddr();
        !            23: static int             lengthof();
        !            24: static struct name     *gexpand();
        !            25: static char            *norm();
        !            26: static struct name     *put();
        !            27: 
        !            28: /*
        !            29:  * Allocate a single element of a name list,
        !            30:  * initialize its name field to the passed
        !            31:  * name and return it.
        !            32:  */
        !            33: 
        !            34: static struct name *
        !            35: nalloc(str)
        !            36:        char str[];
        !            37: {
        !            38:        register struct name *np;
        !            39: 
        !            40:        np = (struct name *) salloc(sizeof *np);
        !            41:        np->n_flink = NIL;
        !            42:        np->n_blink = NIL;
        !            43:        np->n_type = -1;
        !            44:        np->n_full = savestr(str);
        !            45:        np->n_name = skin(np->n_full);
        !            46:        return(np);
        !            47: }
        !            48: 
        !            49: /*
        !            50:  * Find the tail of a list and return it.
        !            51:  */
        !            52: 
        !            53: struct name *
        !            54: tailof(name)
        !            55:        struct name *name;
        !            56: {
        !            57:        register struct name *np;
        !            58: 
        !            59:        np = name;
        !            60:        if (np == NIL)
        !            61:                return(NIL);
        !            62:        while (np->n_flink != NIL)
        !            63:                np = np->n_flink;
        !            64:        return(np);
        !            65: }
        !            66: 
        !            67: /*
        !            68:  * Extract a list of names from a line,
        !            69:  * and make a list of names from it.
        !            70:  * Return the list or NIL if none found.
        !            71:  */
        !            72: 
        !            73: struct name *
        !            74: extract(line, arg_ntype)
        !            75:        char line[];
        !            76: {
        !            77:        short ntype = (short)arg_ntype;
        !            78:        register char *cp;
        !            79:        register struct name *top, *np, *t;
        !            80:        char nbuf[BUFSIZ], abuf[BUFSIZ];
        !            81:        int comma;
        !            82: 
        !            83:        if (line == NOSTR || strlen(line) == 0)
        !            84:                return(NIL);
        !            85:        comma = docomma(line);
        !            86:        top = NIL;
        !            87:        np = NIL;
        !            88:        cp = line;
        !            89:        while ((cp = yankword(cp, nbuf, comma)) != NOSTR) {
        !            90:                if (np != NIL && equal(nbuf, "at")) {
        !            91:                        strcpy(abuf, nbuf);
        !            92:                        if ((cp = yankword(cp, nbuf, comma)) == NOSTR) {
        !            93:                                strcpy(nbuf, abuf);
        !            94:                                goto normal;
        !            95:                        }
        !            96:                        strcpy(abuf, np->n_name);
        !            97:                        strcat(abuf, "@");
        !            98:                        strcat(abuf, nbuf);
        !            99:                        np->n_name = savestr(abuf);
        !           100:                        continue;
        !           101:                }
        !           102: normal:
        !           103:                t = nalloc(nbuf);
        !           104:                t->n_type = ntype;
        !           105:                if (top == NIL)
        !           106:                        top = t;
        !           107:                else
        !           108:                        np->n_flink = t;
        !           109:                t->n_blink = np;
        !           110:                np = t;
        !           111:        }
        !           112:        return(top);
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * Turn a list of names into a string of the same names.
        !           117:  */
        !           118: 
        !           119: char *
        !           120: detract(np, ntype)
        !           121:        register struct name *np;
        !           122: {
        !           123:        register int s;
        !           124:        register char *cp, *top;
        !           125:        register struct name *p;
        !           126: 
        !           127:        if (np == NIL)
        !           128:                return(NOSTR);
        !           129:        s = 0;
        !           130:        for (p = np; p != NIL; p = p->n_flink) {
        !           131:                if ((ntype && (p->n_type & GMASK) != ntype)
        !           132:                 || (p->n_type & GDEL))
        !           133:                        continue;
        !           134:                s += strlen(p->n_full) + 2;
        !           135:        }
        !           136:        if (s == 0)
        !           137:                return(NOSTR);
        !           138:        top = salloc((unsigned)(++s));
        !           139:        cp = top;
        !           140:        for (p = np; p != NIL; p = p->n_flink) {
        !           141:                if ((ntype && (p->n_type & GMASK) != ntype)
        !           142:                 || (p->n_type & GDEL))
        !           143:                        continue;
        !           144:                cp = copy(p->n_full, cp);
        !           145:                *cp++ = ',';
        !           146:                *cp++ = ' ';
        !           147:        }
        !           148:        *cp = 0;
        !           149:        return(top);
        !           150: }
        !           151: 
        !           152: struct name *
        !           153: outpre(to)
        !           154: struct name *to;
        !           155: {
        !           156:        register struct name *np;
        !           157: 
        !           158:        for (np = to; np; np = np->n_flink)
        !           159:                if (any(*np->n_name, "+|"))
        !           160:                        np->n_type |= GDEL;
        !           161:        return to;
        !           162: }
        !           163: 
        !           164: /*
        !           165:  * For each recipient in the passed name list with a /
        !           166:  * in the name, append the message to the end of the named file
        !           167:  * and remove him from the recipient list.
        !           168:  *
        !           169:  * Recipients whose name begins with | are piped through the given
        !           170:  * program and removed.
        !           171:  */
        !           172: 
        !           173: int
        !           174: outof(names, fo)
        !           175:        struct name *names;
        !           176:        FILE *fo;
        !           177: {
        !           178:        register int c;
        !           179:        register struct name *np;
        !           180:        long now;
        !           181:        char *date, *fname, *shell;
        !           182:        FILE *fout, *fin;
        !           183:        int ispipe, s;
        !           184:        char line[BUFSIZ];
        !           185:        int nout = 0;
        !           186: 
        !           187:        for (np = names; np != NIL; np = np->n_flink) {
        !           188:                if (!isfileaddr(np->n_name) && np->n_name[0] != '|')
        !           189:                        continue;
        !           190:                nout++;
        !           191:                ispipe = np->n_name[0] == '|';
        !           192:                if (ispipe)
        !           193:                        fname = np->n_name+1;
        !           194:                else
        !           195:                        fname = expand(np->n_name);
        !           196: 
        !           197:                /*
        !           198:                 * See if we have copied the complete message out yet.
        !           199:                 * If not, do so.
        !           200:                 */
        !           201: 
        !           202:                if (image < 0) {
        !           203:                        if ((fout = fopen(tempEdit, "a")) == NULL) {
        !           204:                                perror(tempEdit);
        !           205:                                senderr++;
        !           206:                                goto cant;
        !           207:                        }
        !           208:                        image = open(tempEdit, 2);                      /* adb */
        !           209:                        unlink(tempEdit);
        !           210:                        if (image < 0) {
        !           211:                                perror(tempEdit);
        !           212:                                senderr++;
        !           213:                                goto cant;
        !           214:                        }
        !           215:                        else {
        !           216:                                rewind(fo);
        !           217:                                time(&now);
        !           218:                                date = ctime(&now);
        !           219:                                fprintf(fout, "From %s %s", myname, date);
        !           220:                                while ((c = getc(fo)) != EOF)
        !           221:                                        putc(c, fout);
        !           222:                                rewind(fo);
        !           223:                                fflush(fout);
        !           224:                                if (ferror(fout))
        !           225:                                        perror(tempEdit);
        !           226:                                fclose(fout);
        !           227:                        }
        !           228:                }
        !           229: 
        !           230:                /*
        !           231:                 * Now either copy "image" to the desired file
        !           232:                 * or give it as the standard input to the desired
        !           233:                 * program as appropriate.
        !           234:                 */
        !           235: 
        !           236:                if (ispipe) {
        !           237:                        wait(&s);
        !           238:                        switch (fork()) {
        !           239:                        case 0:
        !           240:                                sigchild();
        !           241:                                sigset(SIGHUP, SIG_IGN);
        !           242:                                sigset(SIGINT, SIG_IGN);
        !           243:                                sigset(SIGQUIT, SIG_IGN);
        !           244:                                close(0);
        !           245:                                dup(image);
        !           246:                                close(image);
        !           247:                                lseek(0, 0L, 0);
        !           248:                                if ((shell = value("SHELL")) == NOSTR || *shell=='\0')
        !           249:                                        shell = SHELL;
        !           250:                                execlp(shell, shell, "-c", fname, (char *)0);
        !           251:                                perror(shell);
        !           252:                                exit(1);
        !           253:                                break;
        !           254: 
        !           255:                        case (pid_t)-1:
        !           256:                                perror("fork");
        !           257:                                senderr++;
        !           258:                                goto cant;
        !           259:                        }
        !           260:                }
        !           261:                else {
        !           262:                        if ((fout = fopen(fname, "a")) == NULL) {
        !           263:                                perror(fname);
        !           264:                                senderr++;
        !           265:                                goto cant;
        !           266:                        }
        !           267:                        fin = Fdopen(image, "r");
        !           268:                        if (fin == NULL) {
        !           269:                                fprintf(stderr, "Can't reopen image\n");
        !           270:                                fclose(fout);
        !           271:                                senderr++;
        !           272:                                goto cant;
        !           273:                        }
        !           274:                        rewind(fin);
        !           275:                        putc(getc(fin), fout);
        !           276:                        while (fgets(line, sizeof line, fin)) {
        !           277:                                if (!strncmp(line, "From ", 5))
        !           278:                                        putc('>', fout);
        !           279:                                fputs(line, fout);
        !           280:                        }
        !           281:                        putc('\n', fout);
        !           282:                        if (ferror(fout))
        !           283:                                senderr++, perror(fname);
        !           284:                        fclose(fout);
        !           285:                        fclose(fin);
        !           286:                }
        !           287: cant:
        !           288:                /*
        !           289:                 * In days of old we removed the entry from the
        !           290:                 * the list; now for sake of header expansion
        !           291:                 * we leave it in and mark it as deleted.
        !           292:                 */
        !           293: 
        !           294: #ifdef CRAZYWOW
        !           295:                if (np == top) {
        !           296:                        top = np->n_flink;
        !           297:                        if (top != NIL)
        !           298:                                top->n_blink = NIL;
        !           299:                        np = top;
        !           300:                        continue;
        !           301:                }
        !           302:                x = np->n_blink;
        !           303:                t = np->n_flink;
        !           304:                x->n_flink = t;
        !           305:                if (t != NIL)
        !           306:                        t->n_blink = x;
        !           307:                np = t;
        !           308: #endif
        !           309: 
        !           310:                np->n_type |= GDEL;
        !           311:        }
        !           312:        if (image >= 0) {
        !           313:                close(image);
        !           314:                image = -1;
        !           315:        }
        !           316:        return(nout);
        !           317: }
        !           318: 
        !           319: /*
        !           320:  * Determine if the passed address is a local "send to file" address.
        !           321:  * If any of the network metacharacters precedes any slashes, it can't
        !           322:  * be a filename.  We cheat with .'s to allow path names like ./...
        !           323:  */
        !           324: static int
        !           325: isfileaddr(name)
        !           326:        char *name;
        !           327: {
        !           328:        register char *cp;
        !           329: 
        !           330:        if (any('@', name))
        !           331:                return(0);
        !           332:        if (*name == '+')
        !           333:                return(1);
        !           334:        for (cp = name; *cp; cp++) {
        !           335:                if (*cp == '.')
        !           336:                        continue;
        !           337:                if (any(*cp, metanet))
        !           338:                        return(0);
        !           339:                if (*cp == '/')
        !           340:                        return(1);
        !           341:        }
        !           342:        return(0);
        !           343: }
        !           344: 
        !           345: /*
        !           346:  * Map all of the aliased users in the invoker's mailrc
        !           347:  * file and insert them into the list.
        !           348:  * Changed after all these months of service to recursively
        !           349:  * expand names (2/14/80).
        !           350:  */
        !           351: 
        !           352: struct name *
        !           353: usermap(names)
        !           354:        struct name *names;
        !           355: {
        !           356:        register struct name *new, *np, *cp;
        !           357:        struct grouphead *gh;
        !           358:        register int metoo;
        !           359: 
        !           360:        new = NIL;
        !           361:        np = names;
        !           362:        metoo = (value("metoo") != NOSTR);
        !           363:        while (np != NIL) {
        !           364:                if (np->n_name[0] == '\\') {
        !           365:                        cp = np->n_flink;
        !           366:                        new = put(new, np);
        !           367:                        np = cp;
        !           368:                        continue;
        !           369:                }
        !           370:                gh = findgroup(np->n_name);
        !           371:                cp = np->n_flink;
        !           372:                if (gh != NOGRP)
        !           373:                        new = gexpand(new, gh, metoo, np->n_type);
        !           374:                else
        !           375:                        new = put(new, np);
        !           376:                np = cp;
        !           377:        }
        !           378:        return(new);
        !           379: }
        !           380: 
        !           381: /*
        !           382:  * Recursively expand a group name.  We limit the expansion to some
        !           383:  * fixed level to keep things from going haywire.
        !           384:  * Direct recursion is not expanded for convenience.
        !           385:  */
        !           386: 
        !           387: static struct name *
        !           388: gexpand(nlist, gh, metoo, arg_ntype)
        !           389:        struct name *nlist;
        !           390:        struct grouphead *gh;
        !           391: {
        !           392:        short ntype = (short)arg_ntype;
        !           393:        struct mgroup *gp;
        !           394:        struct grouphead *ngh;
        !           395:        struct name *np;
        !           396:        static int depth;
        !           397:        char *cp;
        !           398: 
        !           399:        if (depth > MAXEXP) {
        !           400:                printf("Expanding alias to depth larger than %d\n", MAXEXP);
        !           401:                return(nlist);
        !           402:        }
        !           403:        depth++;
        !           404:        for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) {
        !           405:                cp = gp->ge_name;
        !           406:                if (*cp == '\\')
        !           407:                        goto quote;
        !           408:                if (strcmp(cp, gh->g_name) == 0)
        !           409:                        goto quote;
        !           410:                if ((ngh = findgroup(cp)) != NOGRP) {
        !           411:                        nlist = gexpand(nlist, ngh, metoo, ntype);
        !           412:                        continue;
        !           413:                }
        !           414: quote:
        !           415:                np = nalloc(cp);
        !           416:                np->n_type = ntype;
        !           417:                /*
        !           418:                 * At this point should allow to expand
        !           419:                 * to self if only person in group
        !           420:                 */
        !           421:                if (gp == gh->g_list && gp->ge_link == NOGE)
        !           422:                        goto skip;
        !           423:                if (!metoo && samebody(myname, gp->ge_name))
        !           424:                        np->n_type |= GDEL;
        !           425: skip:
        !           426:                nlist = put(nlist, np);
        !           427:        }
        !           428:        depth--;
        !           429:        return(nlist);
        !           430: }
        !           431: 
        !           432: /*
        !           433:  * Normalize a network name for comparison purposes.
        !           434:  */
        !           435: static char *
        !           436: norm(user, ubuf, nbangs)
        !           437:        register char *user, *ubuf;
        !           438: {
        !           439:        register char *cp;
        !           440: 
        !           441:        while (*user++ == '!');
        !           442:        user--;
        !           443:        if (!strchr(user, '!')) {
        !           444:                sprintf(ubuf, "%s!%s", host, user);
        !           445:                user = ubuf;
        !           446:        }
        !           447:        if (nbangs) {
        !           448:                cp = user + strlen(user);
        !           449:                while (nbangs--)
        !           450:                        while (cp > user && *--cp != '!');
        !           451:                user = (cp > user) ? ++cp : cp;
        !           452:        }
        !           453:        return user;
        !           454: }
        !           455: 
        !           456: /*
        !           457:  * Implement allnet options.
        !           458:  */
        !           459: samebody(user, addr)
        !           460:        register char *user, *addr;
        !           461: {
        !           462:        char ubuf[500], abuf[500];
        !           463:        char *allnet = value("allnet");
        !           464:        int nbangs = allnet ? !strcmp(allnet, "uucp") ? 2 : 1 : 0;
        !           465: 
        !           466:        if( strcmp(allnet, "header") == 0) {                                    /* adb */
        !           467:                /* match user string anywhere in header, case-independent */    /* adb */
        !           468:                return icsubstr(addr, user);                                    /* adb */
        !           469:        }                                                                       /* adb */
        !           470:        user = norm(user, ubuf, nbangs);
        !           471:        addr = norm(addr, abuf, nbangs);
        !           472:        return strcmp(user, addr) == 0;
        !           473: }
        !           474: 
        !           475: /*
        !           476:  * Compute the length of the passed name list and
        !           477:  * return it.
        !           478:  */
        !           479: static int
        !           480: lengthof(name)
        !           481:        struct name *name;
        !           482: {
        !           483:        register struct name *np;
        !           484:        register int c;
        !           485: 
        !           486:        for (c = 0, np = name; np != NIL; c++, np = np->n_flink)
        !           487:                ;
        !           488:        return(c);
        !           489: }
        !           490: 
        !           491: /*
        !           492:  * Concatenate the two passed name lists, return the result.
        !           493:  */
        !           494: 
        !           495: struct name *
        !           496: cat(n1, n2)
        !           497:        struct name *n1, *n2;
        !           498: {
        !           499:        register struct name *tail;
        !           500: 
        !           501:        if (n1 == NIL)
        !           502:                return(n2);
        !           503:        if (n2 == NIL)
        !           504:                return(n1);
        !           505:        tail = tailof(n1);
        !           506:        tail->n_flink = n2;
        !           507:        n2->n_blink = tail;
        !           508:        return(n1);
        !           509: }
        !           510: 
        !           511: /*
        !           512:  * Unpack the name list onto a vector of strings.
        !           513:  * Return an error if the name list won't fit.
        !           514:  */
        !           515: 
        !           516: char **
        !           517: unpack(np)
        !           518:        struct name *np;
        !           519: {
        !           520:        register char **ap, **top;
        !           521:        register struct name *n;
        !           522:        char hbuf[10];
        !           523:        int t, extra;
        !           524: #ifdef DELIVERMAIL
        !           525:        int metoo;
        !           526: #endif
        !           527: 
        !           528:        n = np;
        !           529:        if ((t = lengthof(n)) == 0)
        !           530:                panic("No names to unpack");
        !           531: 
        !           532:        /*
        !           533:         * Compute the number of extra arguments we will need.
        !           534:         * We need at least 2 extra -- one for "mail" and one for
        !           535:         * the terminating 0 pointer.
        !           536:         * Additional spots may be needed to pass along -r and -f to 
        !           537:         * the host mailer.
        !           538:         */
        !           539: 
        !           540:        extra = 2;
        !           541: 
        !           542:        if (rflag != NOSTR)
        !           543:                extra += 2;
        !           544: #ifdef DELIVERMAIL
        !           545:        extra++;
        !           546:        metoo = value("metoo") != NOSTR;
        !           547:        if (metoo)
        !           548:                extra++;
        !           549: #endif /* DELIVERMAIL */
        !           550:        if (hflag)
        !           551:                extra += 2;
        !           552:        top = (char **) salloc((t + extra) * sizeof (char *));
        !           553:        ap = top;
        !           554:        *ap++ = "mail";
        !           555:        if (rflag != NOSTR) {
        !           556:                *ap++ = "-r";
        !           557:                *ap++ = rflag;
        !           558:        }
        !           559: #ifdef DELIVERMAIL
        !           560:        *ap++ = "-i";
        !           561:        if (metoo)
        !           562:                *ap++ = "-m";
        !           563: #endif /* DELIVERMAIL */
        !           564:        if (hflag) {
        !           565:                *ap++ = "-h";
        !           566:                sprintf(hbuf, "%d", hflag);
        !           567:                *ap++ = savestr(hbuf);
        !           568:        }
        !           569:        while (n != NIL) {
        !           570:                if (n->n_type & GDEL) {
        !           571:                        n = n->n_flink;
        !           572:                        continue;
        !           573:                }
        !           574:                *ap++ = n->n_name;
        !           575:                n = n->n_flink;
        !           576:        }
        !           577:        *ap = NOSTR;
        !           578:        return(top);
        !           579: }
        !           580: 
        !           581: /*
        !           582:  * See if the user named himself as a destination
        !           583:  * for outgoing mail.  If so, set the global flag
        !           584:  * selfsent so that we avoid removing his mailbox.
        !           585:  */
        !           586: 
        !           587: void
        !           588: mechk(names)
        !           589:        struct name *names;
        !           590: {
        !           591:        register struct name *np;
        !           592: 
        !           593:        for (np = names; np != NIL; np = np->n_flink)
        !           594:                if ((np->n_type & GDEL) == 0 && samebody(np->n_name, myname)) {
        !           595:                        selfsent++;
        !           596:                        return;
        !           597:                }
        !           598: }
        !           599: 
        !           600: /*
        !           601:  * Remove all of the duplicates from the passed name list by
        !           602:  * insertion sorting them, then checking for dups.
        !           603:  * Return the head of the new list.
        !           604:  */
        !           605: 
        !           606: struct name *
        !           607: elide(names)
        !           608:        struct name *names;
        !           609: {
        !           610:        register struct name *np, *t, *new;
        !           611:        struct name *x;
        !           612: 
        !           613:        if (names == NIL)
        !           614:                return(NIL);
        !           615:        new = names;
        !           616:        np = names;
        !           617:        np = np->n_flink;
        !           618:        if (np != NIL)
        !           619:                np->n_blink = NIL;
        !           620:        new->n_flink = NIL;
        !           621:        while (np != NIL) {
        !           622:                t = new;
        !           623:                while (strcmp(t->n_name, np->n_name) < 0) {
        !           624:                        if (t->n_flink == NIL)
        !           625:                                break;
        !           626:                        t = t->n_flink;
        !           627:                }
        !           628: 
        !           629:                /*
        !           630:                 * If we ran out of t's, put the new entry after
        !           631:                 * the current value of t.
        !           632:                 */
        !           633: 
        !           634:                if (strcmp(t->n_name, np->n_name) < 0) {
        !           635:                        t->n_flink = np;
        !           636:                        np->n_blink = t;
        !           637:                        t = np;
        !           638:                        np = np->n_flink;
        !           639:                        t->n_flink = NIL;
        !           640:                        continue;
        !           641:                }
        !           642: 
        !           643:                /*
        !           644:                 * Otherwise, put the new entry in front of the
        !           645:                 * current t.  If at the front of the list,
        !           646:                 * the new guy becomes the new head of the list.
        !           647:                 */
        !           648: 
        !           649:                if (t == new) {
        !           650:                        t = np;
        !           651:                        np = np->n_flink;
        !           652:                        t->n_flink = new;
        !           653:                        new->n_blink = t;
        !           654:                        t->n_blink = NIL;
        !           655:                        new = t;
        !           656:                        continue;
        !           657:                }
        !           658: 
        !           659:                /*
        !           660:                 * The normal case -- we are inserting into the
        !           661:                 * middle of the list.
        !           662:                 */
        !           663: 
        !           664:                x = np;
        !           665:                np = np->n_flink;
        !           666:                x->n_flink = t;
        !           667:                x->n_blink = t->n_blink;
        !           668:                t->n_blink->n_flink = x;
        !           669:                t->n_blink = x;
        !           670:        }
        !           671: 
        !           672:        /*
        !           673:         * Now the list headed up by new is sorted.
        !           674:         * Go through it and remove duplicates.
        !           675:         */
        !           676: 
        !           677:        np = new;
        !           678:        while (np != NIL) {
        !           679:                t = np;
        !           680:                while (t->n_flink!=NIL &&
        !           681:                    strcmp(np->n_name, t->n_flink->n_name) == 0)
        !           682:                        t = t->n_flink;
        !           683:                if (t == np || t == NIL) {
        !           684:                        np = np->n_flink;
        !           685:                        continue;
        !           686:                }
        !           687:                
        !           688:                /*
        !           689:                 * Now t points to the last entry with the same name
        !           690:                 * as np.  Make np point beyond t.
        !           691:                 */
        !           692: 
        !           693:                np->n_flink = t->n_flink;
        !           694:                if (t->n_flink != NIL)
        !           695:                        t->n_flink->n_blink = np;
        !           696:                np = np->n_flink;
        !           697:        }
        !           698:        return(new);
        !           699: }
        !           700: 
        !           701: /*
        !           702:  * Put another node onto a list of names and return
        !           703:  * the list.
        !           704:  */
        !           705: 
        !           706: static struct name *
        !           707: put(list, node)
        !           708:        struct name *list, *node;
        !           709: {
        !           710:        node->n_flink = list;
        !           711:        node->n_blink = NIL;
        !           712:        if (list != NIL)
        !           713:                list->n_blink = node;
        !           714:        return(node);
        !           715: }
        !           716: 
        !           717: 
        !           718: /*
        !           719:  * Delete the given name from a namelist.
        !           720:  */
        !           721: struct name *
        !           722: delname(np, name)
        !           723:        register struct name *np;
        !           724:        char name[];
        !           725: {
        !           726:        register struct name *p;
        !           727: 
        !           728:        for (p = np; p != NIL; p = p->n_flink)
        !           729:                if (samebody(name, p->n_name)) {
        !           730:                        if (p->n_blink == NIL) {
        !           731:                                if (p->n_flink != NIL)
        !           732:                                        p->n_flink->n_blink = NIL;
        !           733:                                np = p->n_flink;
        !           734:                                continue;
        !           735:                        }
        !           736:                        if (p->n_flink == NIL) {
        !           737:                                if (p->n_blink != NIL)
        !           738:                                        p->n_blink->n_flink = NIL;
        !           739:                                continue;
        !           740:                        }
        !           741:                        p->n_blink->n_flink = p->n_flink;
        !           742:                        p->n_flink->n_blink = p->n_blink;
        !           743:                }
        !           744:        return(np);
        !           745: }
        !           746: 
        !           747: /*
        !           748:  * Call the given routine on each element of the name
        !           749:  * list, replacing said value if need be.
        !           750:  */
        !           751: 
        !           752: void
        !           753: mapf(np, from)
        !           754:        register struct name *np;
        !           755:        char *from;
        !           756: {
        !           757:        register struct name *p;
        !           758: 
        !           759:        if (debug) fprintf(stderr, "mapf %lx, %s\n", (long)np, from);
        !           760:        for (p = np; p != NIL; p = p->n_flink)
        !           761:                if ((p->n_type & GDEL) == 0) {
        !           762:                        p->n_name = netmap(p->n_name, from);
        !           763:                        p->n_full = splice(p->n_name, p->n_full);
        !           764:                }
        !           765:        if (debug) fprintf(stderr, "mapf %s done\n", from);
        !           766: }

unix.superglobalmegacorp.com

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