Annotation of researchv10no/lbin/mailx/names.c, revision 1.1.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.