Annotation of researchv10no/cmd/odist/src.tar, revision 1.1.1.1

1.1       root        1: TODO   644   3513      4         417  5032703557   4565 finish new setuid scheme
                      2: write document
                      3: add security configuration file support
                      4: (idea: receive reads this file, which looks like:
                      5: local-user remote-system       remote-user     remote-file     actions...)
                      6: set up two-pass install/remove scheme
                      7: make a backup package before installation
                      8:   ������ape/   755   3513      4           0  5032703607   4567 ape/Future/   755   3513      4           0  5031447510   6036 ape/Future/conf.c   644   3513      4        4652  5016334717   7232 #include <ctype.h>
                      9: #include <regexp.h>    /* FIXME: use Posix interface. */
                     10: #include <stdio.h>
                     11: #include <stdlib.h>
                     12: #include <string.h>
                     13: #include "conf.h"
                     14: #include "dist.h"
                     15: 
                     16: static char *
                     17: gettok(char *tok, char *src)
                     18: {
                     19:        while (!isspace(*src)) {
                     20:                if (!*src)
                     21:                        break;
                     22:                *tok++ = *src++;
                     23:        }
                     24:        while (isspace(*src))
                     25:                ++src;
                     26:        return src;
                     27: }
                     28: 
                     29: /* return the next line of the config file matching the given args.
                     30:    and argument can be NULL and will be assumed to match.  the return
                     31:    value is in a static data area.  */
                     32: struct conf *
                     33: confread(FILE *fp, char *host, char *user, char *file)
                     34: {
                     35:        static char confline[MAXLINE];
                     36:        static char confhost[MAXLINE], confuser[MAXLINE], conffile[MAXLINE];
                     37:        char *next;
                     38:        static struct conf conf = { confhost, confuser, conffile };
                     39:        int len, flag;
                     40:        regexp *re;
                     41:        regsubexp match[1];
                     42: 
                     43:        for (;;) {
                     44:                if (!fgets(confline, MAXLINE, fp))
                     45:                        return NULL;
                     46:                if (confline[0] == '#')
                     47:                        continue;
                     48:                len = strlen(confline);
                     49:                if (confline[len - 1] != '\n') {
                     50:                        if (feof(fp))
                     51:                                eprintf("readconf: incomplete last line!");
                     52:                        else
                     53:                                eprintf("readconf: line too long or embedded NUL!");
                     54:                        exit(1);
                     55:                }
                     56:                next = gettok(confhost, confline);
                     57:                next = gettok(confuser, next);
                     58:                conf.cmds = gettok(conffile, next);
                     59:                if (host) {
                     60:                        re = regcomp(confhost);
                     61:                        flag = regexec(re, host, match, 1);
                     62:                        free(re);
                     63:                        if (!flag || match[0].ep - match[0].sp != strlen(host))
                     64:                                continue;
                     65:                }
                     66:                if (user) {
                     67:                        re = regcomp(confuser);
                     68:                        flag = regexec(re, user, match, 1);
                     69:                        free(re);
                     70:                        if (!flag || match[0].ep - match[0].sp != strlen(user))
                     71:                                continue;
                     72:                }
                     73:                if (file) {
                     74:                        re = regcomp(conffile);
                     75:                        flag = regexec(re, file, match, 1);
                     76:                        free(re);
                     77:                        if (!flag || match[0].ep - match[0].sp != strlen(file))
                     78:                                continue;
                     79:                }
                     80:                return &conf;
                     81:        }
                     82: }
                     83: 
                     84: /* call functions associated with the commands in the given string
                     85:    return the total of the return values */
                     86: int
                     87: confexec(char *cmdstr, struct confcmds cmdtab[])
                     88: {
                     89:        char cmd[MAXLINE], arg[MAXLINE];
                     90:        int i, np, ret;
                     91: 
                     92:        ret = 0;
                     93:        while (*cmdstr) {
                     94:                for (i = 0; isalnum(*cmdstr); ++cmdstr)
                     95:                        cmd[i++] = *cmdstr;
                     96:                cmd[i] = 0;
                     97:                if (*cmdstr == '(')
                     98:                        for (i = 0, np = 1, ++cmdstr; *cmdstr && np; ++cmdstr) {
                     99:                                if (*cmdstr == '(')
                    100:                                        ++np;
                    101:                                if (*cmdstr == ')' && !--np)
                    102:                                        continue;
                    103:                                arg[i++] = *cmdstr;
                    104:                        }
                    105:                for (i = 0; cmdtab[i].name; ++i)
                    106:                        if (!strcmp(cmd, cmdtab[i].name)) {
                    107:                                ret += (*cmdtab[i].func)(arg);
                    108:                                break;
                    109:                        }
                    110:                while (*cmdstr && !isalnum(*cmdstr))
                    111:                        ++cmdstr;
                    112:        }
                    113:        return ret;
                    114: }
                    115: t i, np, ret;
                    116: 
                    117:        ret = 0;
                    118:        while (*cmdstr) {
                    119:                for (i = 0; isalnum(*cmdstr); ++cmdstr)
                    120: ape/Future/conf.h   644   3513      4         676  5016334663   7221 /* structure corresponding to line of the config file */
                    121: struct conf {
                    122:        char *host;     /* regexp */
                    123:        char *user;     /* regexp */
                    124:        char *file;     /* regexp */
                    125:        char *cmds;     /* cmd+cmd+cmd... */
                    126: };
                    127: 
                    128: extern struct conf *confread(FILE *fp, char *host, char *user, char *file);
                    129: 
                    130: /* configuration command name and associated function to call */
                    131: struct confcmds {
                    132:        char *name;
                    133:        int (*func)(char *);
                    134: };
                    135: 
                    136: extern int confexec(char *cmdstr, struct confcmds *cmdtab);
                    137: = 0;
                    138:        while (*cmdstr) {
                    139:                for (i = 0; isalnum(*cmdstr); ++cmdstr)
                    140: ape/dist.sh   644   3513      4        4306  5032703266   6157 #! /bin/sh -
                    141: 
                    142: umask 022
                    143: 
                    144: LDIR=%LDIR%
                    145: SDIR=%SDIR%
                    146: QPREFIX=Q.
                    147: 
                    148: PATH=$LDIR:/bin:/usr/bin:/usr/ucb:/usr/bsd
                    149: export PATH
                    150: 
                    151: DEST=$LDIR/destinations
                    152: 
                    153: showq=0
                    154: recv=0
                    155: notify=0
                    156: systems=
                    157: usage='usage: dist [-q|-r] [system|-[Ff] file] [-n] [files...]'
                    158: 
                    159: while [ $# -gt 0 ]
                    160: do
                    161:        case "$1" in
                    162:        -q)
                    163:                showq=1
                    164:                ;;
                    165:        -r)
                    166:                recv=1
                    167:                ;;
                    168:        -n)
                    169:                notify=1
                    170:                ;;
                    171:        -[Ff])
                    172:                if [ $# -lt 2 ]
                    173:                then
                    174:                        echo "$usage" 1>&2
                    175:                        exit 1
                    176:                fi
                    177:                if [ x$1 = x-f -a -r "$2" ]
                    178:                then
                    179:                        systems=`cat "$2" 2>/dev/null`
                    180:                elif [ -r $DEST/"$2" ]
                    181:                then
                    182:                        systems=`cat $DEST/"$2" 2>/dev/null`
                    183:                else
                    184:                        echo "dist: can't open '$2'" 1>&2
                    185:                        exit 1
                    186:                fi
                    187:                shift
                    188:                ;;
                    189:        *)
                    190:                if [ "x$systems" != x ]
                    191:                then
                    192:                        break
                    193:                fi
                    194:                systems="$1"
                    195:                ;;
                    196:        esac
                    197:        shift
                    198: done
                    199: 
                    200: if [ $recv = 1 ]
                    201: then
                    202:        if [ x"$systems" = x ]
                    203:        then
                    204:                echo dist: no systems specified 1>&2
                    205:                exit 1
                    206:        else
                    207:                for sys in $systems
                    208:                do
                    209:                        echo $sys:
                    210:                        connect $sys transmit io receive || exit 1
                    211:                done
                    212:                exit 0
                    213:        fi
                    214: fi
                    215: 
                    216: if [ $showq = 1 ]
                    217: then
                    218:        if [ x"$systems" = x ]
                    219:        then
                    220:                showq
                    221:                exit 0
                    222:        else
                    223:                for sys in $systems
                    224:                do
                    225:                        echo $sys:
                    226:                        connect $sys showq i /bin/cat
                    227:                done
                    228:                exit 0
                    229:        fi
                    230: fi
                    231: 
                    232: if [ $# = 0 ]
                    233: then
                    234:        echo "$usage" 1>&2
                    235:        exit 1
                    236: fi
                    237: 
                    238: # construct spool directory
                    239: for d in `echo $$ | awk '{for (i = 0; i < 1000; ++i) printf "%3d%d\n", i, $1}'`
                    240: do
                    241:        if [ ! -f $SDIR/$QPREFIX$d ]
                    242:        then
                    243:                dir=$QPREFIX$d
                    244:                mkdir $SDIR/$dir && break
                    245:                echo "dist: can't make spool directory" 1>&2
                    246:                exit 1
                    247:        fi
                    248: done
                    249: 
                    250: data=$SDIR/$dir/data
                    251: ctl=$SDIR/$dir/tempctl
                    252: files=$SDIR/$dir/files
                    253: 
                    254: # use canonical system names.
                    255: canon $systems | awk '{for (i = 1; i <= NF; ++i) printf "%d %s\n", ++n, $i}' > $ctl
                    256: 
                    257: mkpkg "$@" > $data
                    258: 
                    259: pwd=`pwd`
                    260: for f in "$@"
                    261: do
                    262:        case "$f" in
                    263:        -*)     # flag to mkpkg
                    264:                ;;
                    265:        /*)
                    266:                echo "$f"
                    267:                ;;
                    268:        *)
                    269:                echo "$pwd/$f"
                    270:                ;;
                    271:        esac
                    272: done | sort > $files
                    273: 
                    274: # rename the ctl file to its real name; at this point the package
                    275: # is now available for shipment.
                    276: mv $ctl $SDIR/$dir/ctl
                    277: 
                    278: # supersede old jobs containing the same files
                    279: cd $SDIR
                    280: for d in $QPREFIX*
                    281: do
                    282:        test $d = $dir && continue
                    283:        test -w $d || continue
                    284:        if [ `comm -23 $d/files $dir/files | wc -c` = 0 ]
                    285:        then
                    286:                sort +1 $d/ctl $dir/ctl | uniq -d -2 |
                    287:                while read num sys
                    288:                do
                    289:                        echo superseded by $dir > $d/$num.done
                    290:                done
                    291:        fi
                    292: done
                    293: 
                    294: # clean up any jobs we completely superseded.
                    295: cleanq
                    296: 
                    297: done | sort > $files
                    298: 
                    299: # rename the ctl file to its real name; at this point the package
                    300: # is now available for shipment.
                    301: mv $ctl $SDIR/$dir/ctl
                    302: 
                    303: # supersede old jobs containing the same files
                    304: cd $SDIR
                    305: for d in $QPREFIX*
                    306: do
                    307:        test $d = $dir && continue
                    308:        test -w $d || continue
                    309:        if [ `comm -23 $d/files $dir/files | ape/mkfile   644   3513      4        2060  5031455043   6041 <../mkconf.$SYS
                    310: <../mkrules.$SYS
                    311: 
                    312: CFLAGS=-g
                    313: BPROG=dist
                    314: LPROG=receive transmit showq cleanq genmail nightly
                    315: LSUID=transmit cleanq
                    316: 
                    317: LIBOBJ=chat.$O chkperm.$O crc.$O eprintf.$O path.$O scanq.$O tryperm.$O
                    318: 
                    319: %.$O: %.c
                    320:        $CC -DLDIR='"'$LDIR'"' -DSDIR='"'$SDIR'"' -c $stem.c
                    321: 
                    322: %: %.$SH
                    323:        sed -e s@%LDIR%@$LDIR@ -e s@%SDIR%@$SDIR@ $stem.$SH > $target || rm -f $target
                    324:        chmod +x $target
                    325: 
                    326: compile:V: $BPROG $LPROG
                    327: 
                    328: install:V: compile
                    329:        test -d $LDIR || mkdir $LDIR
                    330:        test -d $SDIR || mkdir $SDIR && chmod 777 $SDIR
                    331:        cp $BPROG $BDIR
                    332:        cp $LPROG $LDIR
                    333:        (cd $LDIR; chown root $LSUID; chmod 4755 $LSUID)
                    334: 
                    335: receive: receive.$O lib.a ../$SYS/lib.a
                    336:        $CC -o receive receive.$O lib.a ../$SYS/lib.a $CCLIB
                    337: 
                    338: transmit: transmit.$O lib.a ../$SYS/lib.a
                    339:        $CC -o transmit transmit.$O lib.a ../$SYS/lib.a $CCLIB
                    340: 
                    341: showq: showq.$O lib.a ../$SYS/lib.a
                    342:        $CC -o showq showq.$O lib.a ../$SYS/lib.a $CCLIB
                    343: 
                    344: cleanq: cleanq.$O lib.a ../$SYS/lib.a
                    345:        $CC -o cleanq cleanq.$O lib.a ../$SYS/lib.a $CCLIB
                    346: 
                    347: lib.a: ${LIBOBJ:%=lib.a(%)}
                    348:        $RL lib.a
                    349: 
                    350: lib.a(%): %
                    351:        ar r lib.a $stem
                    352: 
                    353: clean:V:
                    354:        rm -f $BPROG $LPROG *.[$OS] lib.a
                    355: UID; chmod 4755 $LSUID)
                    356: 
                    357: receive: receive.$O lib.a ../$SYS/lib.a
                    358:        $CC -o receive receive.$O lib.a ../$SYS/lib.a $CCLIB
                    359: 
                    360: transmit: transmit.$O lib.a ../$SYS/lib.a
                    361:        $CC -o transmit transmit.$O lib.a ../$SYS/lib.a $CCLIB
                    362: 
                    363: showq: showq.$O lib.a ../$SYS/lib.a
                    364:        $CC -o showq showq.$O lib.a ../$SYS/lib.a $CCLIB
                    365: 
                    366: cleanq: cleanq.$O lib.a ../$SYS/lib.a
                    367:        $CC -o cleanq cleanq.$O lib.a ../$SYS/lib.a $CCLIB
                    368: 
                    369: lib.a: ${LIBOBJ:%=lib.a(%)}
                    370:        $RL lib.a
                    371: 
                    372: lib.a(%): %
                    373:        ar r lib.a $stape/scanq.c   644   3513      4        3466  5032142073   6130 #include <dirent.h>
                    374: #include <limits.h>
                    375: #include <stdio.h>
                    376: #include <stdlib.h>
                    377: #include <string.h>
                    378: #include <unistd.h>
                    379: #include "dist.h"
                    380: 
                    381: static char *
                    382: copy(char *s)
                    383: {
                    384:        char *r;
                    385: 
                    386:        r = malloc(strlen(s) + 1);
                    387:        if (r)
                    388:                strcpy(r, s);
                    389:        return r;
                    390: }
                    391: 
                    392: static void
                    393: removeq(char *name)
                    394: {
                    395:        DIR *dp;
                    396:        struct dirent *d;
                    397:        char file[2 * MAXNAME + 1];
                    398: 
                    399:        name = copy(name);      /* readdir bug?!? */
                    400:        if (fork() == 0) {
                    401:                setuid(getuid());
                    402:                execl(LDIR "/genmail", "genmail", "-f", name, (char *) 0);
                    403:                exit(0);
                    404:        } else
                    405:                wait(0);
                    406:        if (!(dp = opendir(name)))
                    407:                return;
                    408:        while (d = readdir(dp)) {
                    409:                if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
                    410:                        continue;
                    411:                sprintf(file, "%s/%.*s", name, MAXNAME, d->d_name);
                    412:                remove(file);
                    413:        }
                    414:        closedir(dp);
                    415:        rmdir(name);
                    416:        free(name);
                    417: }
                    418: 
                    419: void
                    420: scanq(char *remsys, void (*func)(char *, int, char *))
                    421: {
                    422:        DIR *dp;
                    423:        struct dirent *d;
                    424:        FILE *fp;
                    425:        char sys[MAXLINE], cansys[MAXLINE], file[MAXNAME];
                    426:        int num, zapq;
                    427: 
                    428:        if (remsys)
                    429:                canon(remsys, cansys);
                    430: 
                    431:        if (chdir(SDIR) < 0) {
                    432:                eprintf("can't chdir %s", SDIR);
                    433:                exit(1);
                    434:        }
                    435: 
                    436:        if (!(dp = opendir("."))) {
                    437:                eprintf("can't read spool directory!");
                    438:                exit(1);
                    439:        }
                    440: 
                    441:        while (d = readdir(dp))
                    442:                if (strncmp(d->d_name, QPREFIX, strlen(QPREFIX)) == 0) {
                    443:                        zapq = 1;
                    444:                        if (chdir(d->d_name) < 0) {
                    445:                                eprintf("can't chdir %s/%s", SDIR, d->d_name);
                    446:                                continue;
                    447:                        }
                    448:                        if (fp = fopen(CTL, "r")) {
                    449:                                while (fscanf(fp, "%d%s", &num, sys) == 2) {
                    450:                                        sprintf(file, "%d.%s", num, DONE);
                    451:                                        if (access(file, F_OK) == 0)
                    452:                                                continue;
                    453:                                        if (remsys && strcmp(sys, cansys) != 0) {
                    454:                                                zapq = 0;
                    455:                                                continue;
                    456:                                        }
                    457:                                        if (func)
                    458:                                                (*func)(d->d_name, num, sys);
                    459:                                        if (access(file, F_OK) != 0)
                    460:                                                zapq = 0;
                    461:                                }
                    462:                                fclose(fp);
                    463:                        } else
                    464:                                eprintf("can't read %s/%s", d->d_name, CTL);
                    465:                        chdir("..");
                    466:                        if (zapq)
                    467:                                removeq(d->d_name);
                    468:                }
                    469: 
                    470:        closedir(dp);
                    471: }
                    472:                if (fp = fopen(CTL, "r")) {
                    473:                                while (fscanf(fp, "%d%s", &num, sys) == 2) {
                    474:                                        sprintf(file, "%d.%s", num, DONE);
                    475:                                        if (access(file, F_OK) == 0)
                    476:                                                continue;
                    477:                                        if (remsys && strcmp(sys, caape/eprintf.c   644   3513      4        1030  5020312715   6452 #include <stdarg.h>
                    478: #include <stdio.h>
                    479: #include <time.h>
                    480: #include <unistd.h>
                    481: #include "dist.h"
                    482: 
                    483: char *prog;
                    484: 
                    485: void
                    486: eprintf(char *fmt, ...)
                    487: {
                    488:        time_t now;
                    489:        char mesg[MAXLINE];
                    490:        va_list ap;
                    491:        static int fd = -1;
                    492: 
                    493:        time(&now);
                    494:        sprintf(mesg, "%s[%d %.24s]: ", prog, getpid(), ctime(&now));
                    495:        va_start(ap, fmt);
                    496:        vsprintf(mesg + strlen(mesg), fmt, ap);
                    497:        strcat(mesg, "\n");
                    498:        write(2, mesg, strlen(mesg));
                    499:        if (fd < 0)
                    500:                fd = open(SDIR "/log", 1);
                    501:        lseek(fd, 0L, 2);       /* we really want O_APPEND mode, but... */
                    502:        write(fd, mesg, strlen(mesg));
                    503: }
                    504: lude <stdio.h>
                    505: #include <time.h>
                    506: #include <unistd.h>
                    507: #include "dist.h"
                    508: 
                    509: char *prog;
                    510: 
                    511: void
                    512: eprintf(char *fmt, ...)
                    513: {
                    514:        time_t now;
                    515:        char mesg[MAXLINE];
                    516:        va_list ap;
                    517:        static int fd = -1;
                    518: 
                    519:        time(&now);
                    520:        sprintf(mesg, "%s[%d %.24s]: ", prog, getpid(), ctime(&now));
                    521:        va_start(ap, fmt);
                    522:        vsprintf(mesg + strlen(mesg), fmt, ap);
                    523:        strcat(mesg, "\n");
                    524:        write(2, mesg, strlen(mesg));
                    525:        if (fd < 0)
                    526:                fd = open(SDIR "/log", 1);
                    527:        lseek(fd, 0L, 2);       /* we really want O_APPEND mode, but... */
                    528:        write(fd,ape/receive.c   644   3513      4        3406  5032661703   6445 #include <stddef.h>
                    529: #include <stdio.h>
                    530: #include <sys/types.h>
                    531: #include <sys/stat.h>
                    532: #include <fcntl.h>
                    533: #include <unistd.h>
                    534: #include "dist.h"
                    535: 
                    536: void
                    537: recvjob(void)
                    538: {
                    539:        char data[MAXNAME], errs[MAXNAME], mesg[MAXLINE];
                    540:        int dfd, efd, attempt, status;
                    541: 
                    542:        if (!getline(mesg))
                    543:                exit(0);
                    544: 
                    545:        if (sscanf(mesg, "begin job %s", data) != 1) {
                    546:                eprintf("job header munged: mesg = %s", mesg);
                    547:                exit(1);
                    548:        }
                    549: 
                    550:        sprintf(data, "data.%d", getpid());
                    551:        remove(data);
                    552:        dfd = creat(data, 0600); /* ape deficiency */
                    553:        close(dfd);
                    554:        dfd = open(data, O_RDWR);
                    555:        if (dfd < 0) {
                    556:                eprintf("can't create data file %s", data);
                    557:                exit(1);
                    558:        }
                    559: 
                    560:        if (!recvfile(dfd)) {
                    561:                remove(data);
                    562:                eprintf("recvfile failed");
                    563:                exit(1);
                    564:        }
                    565: 
                    566:        /* see if file system permissions will likely allow inspkg to succeed */
                    567:        lseek(dfd, 0L, 0);
                    568:        attempt = tryperm(dfd);
                    569:        sprintf(mesg, "client attempt=%d\n", attempt);
                    570:        write(1, mesg, strlen(mesg));
                    571: 
                    572:        if (attempt) {
                    573:                sprintf(errs, "errs.%d", getpid());
                    574:                efd = creat(errs, 0600);        /* more ape bogosity */
                    575:                close(efd);
                    576:                efd = open(errs, O_RDWR);
                    577:                if (efd < 0) {
                    578:                        eprintf("can't create errs file %s", errs);
                    579:                        exit(1);
                    580:                }
                    581: 
                    582:                if (fork()) {
                    583:                        status = 0xFF; /* evilly catch wait failures */
                    584:                        wait(&status);
                    585:                        if (status & 0xFF) {
                    586:                                sprintf(mesg, "inspkg: exit %d\n", status & 0xFF);
                    587:                                write(efd, mesg, strlen(mesg));
                    588:                        }
                    589:                } else {
                    590:                        lseek(dfd, 0L, 0);
                    591:                        dup2(dfd, 0);
                    592:                        dup2(efd, 1);
                    593:                        dup2(efd, 2);
                    594:                        close(dfd);
                    595:                        close(efd);
                    596:                        execl(LDIR "/inspkg", "inspkg", 0);
                    597:                        eprintf("can't exec inspkg");
                    598:                        exit(1);
                    599:                }
                    600: 
                    601:                lseek(efd, 0L, 0);
                    602:                if (!sendfile(efd)) {
                    603:                        remove(data);
                    604:                        remove(errs);
                    605:                        eprintf("can't send error log");
                    606:                        exit(1);
                    607:                }
                    608:        }
                    609: 
                    610:        close(dfd);
                    611:        remove(data);
                    612:        close(efd);
                    613:        remove(errs);
                    614: }
                    615: 
                    616: int
                    617: main(int argc, char *argv[])
                    618: {
                    619:        prog = argv[0];
                    620:        for (;;)
                    621:                recvjob();
                    622: }
                    623:        write(efd, mesg, strlen(mesg));
                    624:                        }
                    625:                } else {
                    626:                        lseek(dfd, 0L, 0);
                    627:                        dup2(dfd, 0);
                    628:                        dup2(efd, 1);
                    629:                        dup2(efd, 2);
                    630:                        close(dfd);
                    631:                        close(efd);
                    632:                        execl(LDIR "/inspkg", "inspkg", 0);
                    633:                        eprintf("can't exec inspkg");
                    634:                        exit(1);
                    635:                }
                    636: 
                    637:                lseek(eape/tryperm.c   644   3513      4        6311  5027736536   6536 #include <ctype.h>
                    638: #include <stddef.h>
                    639: #include <stdlib.h>
                    640: #include <stdio.h>
                    641: #include <string.h>
                    642: #include <sys/types.h>
                    643: #include <sys/stat.h>
                    644: #include <fcntl.h>
                    645: #include <unistd.h>
                    646: #include "../pkg/ar.h"
                    647: #include "dist.h"
                    648: 
                    649: /* determine if we can create the given pathname.  not a generally useful
                    650:    function since it destroys the pathname in the process... */
                    651: static int
                    652: cancreate(char *path, int recurse)
                    653: {
                    654:        char *slash;
                    655: 
                    656:        for (;;) {
                    657:                slash = strrchr(path, '/');
                    658:                if (! slash)
                    659:                        return 0;       /* supposed to be absolute */
                    660:                *slash = '\0';
                    661:                if (!*path)
                    662:                        break;
                    663:                if (access(path, W_OK) == 0)
                    664:                        return 1;
                    665:                if (!recurse)           /* for remove we check only one directory */
                    666:                        return 0;
                    667:                if (access(path, F_OK) == 0)
                    668:                        return 0;
                    669:        }
                    670:        return access("/", W_OK) == 0;
                    671: }
                    672:                
                    673: /*
                    674:  * try the instructions of the package on the given fd against the
                    675:  * permissions currently in the file system.  return 1 if we think we
                    676:  * ought to go ahead and try inspkg.
                    677:  */
                    678: int
                    679: tryperm(int fd)
                    680: {
                    681:        char armag[SARMAG];
                    682:        struct ar_hdr arhdr;
                    683:        long size;
                    684:        char temp[L_tmpnam];
                    685:        int tfd;
                    686:        FILE *tfp;
                    687:        int cmd, c, nf, retval;
                    688:        char *path;
                    689: 
                    690:        /* return 1 so inspkg will be called and barf for us */
                    691:        if (read(fd, armag, sizeof armag) != SARMAG || strncmp(armag, ARMAG, SARMAG))
                    692:                return 1;
                    693:        if (read(fd, (char *) &arhdr, sizeof arhdr) != sizeof arhdr)
                    694:                return 1;
                    695:        size = strtol(arhdr.ar_size, 0, 10);
                    696:        tmpnam(temp);
                    697:        close(creat(temp, 0600));       /* ape deficiency */
                    698:        tfd = open(temp, O_RDWR);
                    699:        if (tfd < 0) {
                    700:                eprintf("can't create temp file %s for tryperm", temp);
                    701:                remove(temp);           /* just in case something's *real* weird */
                    702:                exit(1);
                    703:        }
                    704:        if (fdcopy(tfd, fd, size, 0) != size) {
                    705:                close(tfd);
                    706:                remove(temp);
                    707:                eprintf("can't extract Instructions in tryperm");
                    708:                return 1;               /* inspkg will (presumably) barf for us */
                    709:        }
                    710:        lseek(tfd, 0L, 0);
                    711:        tfp = fdopen(tfd, "r");
                    712: 
                    713:        /* now that we have the instructions file, do the real meat.  */
                    714:        retval = 1;
                    715:        while ((cmd = getc(tfp)) != EOF) {
                    716:                switch (cmd) {
                    717:                case 'b':       /* b <mode> <dmaj> <dmin> <uid> <gid> <path> */
                    718:                case 'c':       /* c <mode> <dmaj> <dmin> <uid> <gid> <path> */
                    719:                        nf = 6;
                    720:                        break;
                    721:                case 'd':       /* d <mode> <uid> <gid> <path> */
                    722:                case 'f':       /* f <component> <uid> <gid> <path> */
                    723:                        nf = 4;
                    724:                        break;
                    725:                case 'l':       /* l <path1> <path2> */
                    726:                case 's':       /* s <path1> <path2> */
                    727:                        nf = 2;
                    728:                        break;
                    729:                case 'r':       /* r <path> */
                    730:                case 'x':       /* x <command> */
                    731:                case 'X':       /* X <path> */
                    732:                        nf = 1;
                    733:                        break;
                    734:                default:
                    735:                        goto reterr;
                    736:                }
                    737: 
                    738:                /* get the last field of the line */
                    739:                while (nf--) {
                    740:                        while ((c = getc(tfp)) != EOF)
                    741:                                if (!isspace(c))
                    742:                                        break;
                    743:                        if (c == EOF)
                    744:                                goto reterr;
                    745:                        ungetc(c, tfp);
                    746:                        path = getpath(tfp);
                    747:                }
                    748: 
                    749:                /* eat the newline */
                    750:                if (getc(tfp) != '\n')
                    751:                        goto reterr;
                    752: 
                    753:                switch (cmd) {
                    754:                case 'X':
                    755:                case 'x':
                    756:                        break;
                    757: 
                    758:                case 'r':
                    759:                        if (access(path, F_OK) != 0)
                    760:                                break;
                    761:                        if (cancreate(path, 0))
                    762:                                break;
                    763:                        retval = 0;
                    764:                        goto out;
                    765: 
                    766:                default:
                    767:                        if (cancreate(path, 1))
                    768:                                break;
                    769:                        retval = 0;
                    770:                        goto out;
                    771:                }
                    772:        }
                    773: 
                    774:  out:
                    775:        fclose(tfp);
                    776:        remove(temp);
                    777:        return retval;
                    778: 
                    779:  reterr:
                    780:        /* there was some kind of bug in the format of the package.  return 1
                    781:           and later on inspkg will generate an appropriate error message to
                    782:           be returned to the remote system */
                    783:        fclose(tfp);    
                    784:        remove(temp);
                    785:        return 1;
                    786: }
                    787: ase 'x':
                    788:                        break;
                    789: 
                    790:                case 'r':
                    791:                        if (access(path, F_OK) != 0)
                    792:                                break;
                    793:                        if (cancreate(path, 0))
                    794:                                break;
                    795:                        retval = 0;
                    796:                        goto out;
                    797: 
                    798:                default:
                    799:                        if (cancreate(path, 1))
                    800:                                break;
                    801:                        retval = 0;
                    802:                        goto out;
                    803:                }
                    804:        }
                    805: 
                    806:  out:
                    807:        fclose(tfp);
                    808:        remove(temp);
                    809:        return retval;
                    810: 
                    811:  reterr:
                    812:        /* there was some kindape/dist.h   644   3513      4        1530  5030707254   5767 #define QPREFIX "Q."
                    813: #define CTL "ctl"
                    814: #define DATA "data"
                    815: #define BUSY "busy"
                    816: #define DONE "done"
                    817: #define FILES "files"
                    818: 
                    819: #define MAXLINE 256
                    820: #define MAXNAME 20
                    821: 
                    822: /* system dependent */
                    823: extern void canon(char *sys, char cansys[]);
                    824: extern int lcreat(char *name, int mode);
                    825: 
                    826: /* chat.c */
                    827: extern int getline(char line[]);
                    828: extern long fdcopy(int dfd, int sfd, long size, unsigned long *crc);
                    829: extern int recvfile(int fd);
                    830: extern int sendfile(int fd);
                    831: 
                    832: /* chkperm.c */
                    833: extern int chkperm(int fd);
                    834: 
                    835: /* crc.c */
                    836: extern void crcinit(int *aux);
                    837: extern unsigned long crcincr(unsigned char *, size_t, unsigned long, int *);
                    838: 
                    839: /* eprintf.c */
                    840: extern char *prog;
                    841: extern void eprintf(char *fmt, ...);
                    842: 
                    843: /* path.c */
                    844: extern char *getpath(FILE *);
                    845: 
                    846: /* scanq.c */
                    847: extern void scanq(char *remsys, void (*func)(char *, int, char *));
                    848: 
                    849: /* tryperm.c */
                    850: extern int tryperm(int fd);
                    851: , int sfd, long size, unsigned long *crc);
                    852: extern int recvfile(int fd);
                    853: extern int sendfile(int fd);
                    854: 
                    855: /* chkperm.c */
                    856: extern int chkperm(int fd);
                    857: 
                    858: /* crc.c */
                    859: extern voape/chat.c   644   3513      4        3611  5027732160   5740 #include <stddef.h>
                    860: #include <stdio.h>
                    861: #include <unistd.h>
                    862: #include "dist.h"
                    863: 
                    864: #define MIN(A, B) ((A) < (B) ? (A) : (B))
                    865: 
                    866: int
                    867: getline(char line[])
                    868: {
                    869:        int i;
                    870: 
                    871:        i = 0;
                    872:        do
                    873:                if (read(0, line + i, 1) != 1)
                    874:                        return 0;
                    875:        while (line[i++] != '\n' && i < MAXLINE - 1);
                    876:        if (line[i - 1] != '\n')
                    877:                return 0;
                    878:        line[i] = 0;
                    879:        return 1;
                    880: }
                    881: 
                    882: long
                    883: fdcopy(int dst, int src, long size, unsigned long *crc)
                    884: {
                    885:        char buf[4096];
                    886:        long cc, total;
                    887:        int aux;
                    888: 
                    889:        total = 0;
                    890:        if (crc) {
                    891:                crcinit(&aux);
                    892:                *crc = 0;
                    893:        }
                    894:        while (total < size) {
                    895:                if ((cc = read(src, buf, MIN(sizeof buf, size - total))) <= 0)
                    896:                        break;
                    897:                if (crc)
                    898:                        *crc = crcincr((unsigned char *) buf, cc, *crc, &aux);
                    899:                if (write(dst, buf, cc) != cc)
                    900:                        break;
                    901:                total += cc;
                    902:        }
                    903:        return total;
                    904: }
                    905: 
                    906: int
                    907: sendfile(int fd)
                    908: {
                    909:        long len;
                    910:        char mesg[MAXLINE];
                    911:        unsigned long crc;
                    912: 
                    913:        /* size header */
                    914:        len = lseek(fd, 0L, 2);
                    915:        lseek(fd, 0L, 0);
                    916:        sprintf(mesg, "file length=%ld\n", len);
                    917:        write(1, mesg, strlen(mesg));
                    918: 
                    919:        /* body */
                    920:        if (fdcopy(1, fd, len, &crc) != len) {
                    921:                eprintf("sendfile fdcopy failure");
                    922:                return 0;
                    923:        }
                    924: 
                    925:        /* crc footer */
                    926:        sprintf(mesg, "file crc=%lu\n", crc);
                    927:        write(1, mesg, strlen(mesg));
                    928: 
                    929:        /* acknowledge */
                    930:        if (!getline(mesg) || strcmp(mesg, "ok\n") != 0) {
                    931:                eprintf("sendfile acknowledgement failure");
                    932:                return 0;
                    933:        }
                    934: 
                    935:        return 1;
                    936: }
                    937: 
                    938: int
                    939: recvfile(int fd)
                    940: {
                    941:        long len;
                    942:        char mesg[MAXLINE];
                    943:        unsigned long crc, trycrc;
                    944: 
                    945:        /* size header */
                    946:        if (!getline(mesg) || sscanf(mesg, "file length=%ld\n", &len) != 1) {
                    947:                eprintf("recvfile header munged");
                    948:                return 0;
                    949:        }
                    950: 
                    951:        /* body */
                    952:        if (fdcopy(fd, 0, len, &crc) != len) {
                    953:                eprintf("recvfile fdcopy failure");
                    954:                return 0;
                    955:        }
                    956: 
                    957:        /* crc footer */
                    958:        if (!getline(mesg) || sscanf(mesg, "file crc=%lu\n", &trycrc) != 1) {
                    959:                eprintf("recvfile footer munged");
                    960:                return 0;
                    961:        }
                    962:        if (crc != trycrc) {
                    963:                eprintf("recvfile crc failure");
                    964:                return 0;
                    965:        }
                    966: 
                    967:        /* acknowledge */
                    968:        sprintf(mesg, "ok\n");
                    969:        write(1, mesg, strlen(mesg));
                    970:        return 1;
                    971: }
                    972:  || sscanf(mesg, "file length=%ld\n", &len) != 1) {
                    973:                eprintf("recvfile header munged");
                    974:                return 0;
                    975:        }
                    976: 
                    977:        /* body */
                    978:        iape/chkperm.c   644   3513      4         135  5030710456   6426 #include <stddef.h>
                    979: #include <stdio.h>
                    980: #include "dist.h"
                    981: 
                    982: int
                    983: chkperm(int fd)
                    984: {
                    985:        return 1;
                    986: }
                    987: /* crc footer */
                    988:        if (!getline(mesg) || sscanf(mesg, "file crc=%lu\n", &trycrc) != 1) {
                    989:                eprintf("recvfile footer munged");
                    990:                return 0;
                    991:        }
                    992:        if (crc != trycrc) {
                    993:                eprintf("recvfile crc failure");
                    994:                return 0;
                    995:        }
                    996: 
                    997:        /* acknowledge */
                    998:        sprintf(mesg, "ok\n");
                    999:        write(1, mesg, strlen(mesg));
                   1000:        return 1;
                   1001: }
                   1002:  || sscanf(mesg, "file length=%ld\n", &len) != 1) {
                   1003:                eprintf("recvfile header munged");
                   1004:                return 0;
                   1005:        }
                   1006: 
                   1007:        /* body */
                   1008:        iape/transmit.c   644   3513      4        2347  5025030057   6661 #include <stdio.h>
                   1009: #include <sys/types.h>
                   1010: #include <sys/stat.h>
                   1011: #include <fcntl.h>
                   1012: #include <unistd.h>
                   1013: #include "dist.h"
                   1014: 
                   1015: static void
                   1016: sendjob(char *job, int num, char *sys)
                   1017: {
                   1018:        char busy[MAXNAME], done[MAXNAME], mesg[MAXLINE];
                   1019:        int fd, attempt;
                   1020: 
                   1021:        sprintf(busy, "%d.%s", num, BUSY);
                   1022:        sprintf(done, "%d.%s", num, DONE);
                   1023: 
                   1024:        fd = lcreat(busy, 0600);
                   1025:        if (fd < 0)
                   1026:                return;
                   1027:        dup2(fd, 2);
                   1028:        close(fd);
                   1029: 
                   1030:        /* avoid race condition */
                   1031:        if (access(done, F_OK) == 0)
                   1032:                goto out;
                   1033: 
                   1034:        fd = open(DATA, O_RDONLY);
                   1035:        if (fd < 0)
                   1036:                goto out;
                   1037: 
                   1038:        if (!chkperm(fd)) {
                   1039:                close(fd);
                   1040:                goto out;
                   1041:        }
                   1042: 
                   1043:        sprintf(mesg, "begin job %s\n", job);
                   1044:        write(1, mesg, strlen(mesg));
                   1045: 
                   1046:        if (!sendfile(fd))
                   1047:                goto err;
                   1048: 
                   1049:        if (!getline(mesg) || sscanf(mesg, "client attempt=%d\n", &attempt) != 1)
                   1050:                goto err;
                   1051:        if (!attempt)
                   1052:                goto out;
                   1053: 
                   1054:        if (!recvfile(2))
                   1055:                goto err;
                   1056: 
                   1057:        rename(busy, done);
                   1058: 
                   1059:        fd = open("/dev/null", O_WRONLY);
                   1060:        dup2(fd, 2);
                   1061:        close(fd);
                   1062:        return;
                   1063: 
                   1064:  out:
                   1065:        /* continue with the next job */
                   1066:        remove(busy);
                   1067:        return;
                   1068: 
                   1069:  err:
                   1070:        /* failure that's too hard to resynchronize */
                   1071:        eprintf("sendjob really barfed");
                   1072:        remove(busy);
                   1073:        exit(1);
                   1074: }
                   1075: 
                   1076: int
                   1077: main(int argc, char *argv[])
                   1078: {
                   1079:        prog = argv[0];
                   1080:        if (argc < 2) {
                   1081:                eprintf("usage: transmit system");
                   1082:                return 1;
                   1083:        }
                   1084:        scanq(argv[1], sendjob);
                   1085:        return 0;
                   1086: }
                   1087: = 1)
                   1088:                goto err;
                   1089:        if (!attempt)
                   1090:                goto out;
                   1091: 
                   1092:        if (!recvfile(2))
                   1093:                goto err;
                   1094: 
                   1095:        rename(busy, done);
                   1096: 
                   1097:        fd = open("/dev/null", O_WRONLY);
                   1098:        dup2(fd, 2);
                   1099:        close(fd);
                   1100:        return;
                   1101: 
                   1102:  out:
                   1103:        /* continue with the next job */
                   1104:        remove(busy);
                   1105:        return;
                   1106: 
                   1107:  err:
                   1108:        /* failure that's too hard to resynchroape/showq.c   644   3513      4         352  5030710545   6136 #include <stddef.h>
                   1109: #include <stdio.h>
                   1110: #include "dist.h"
                   1111: 
                   1112: static void
                   1113: showq(char *job, int num, char *sys)
                   1114: {
                   1115:        printf("%s: %d %s\n", job, num, sys);
                   1116: }
                   1117: 
                   1118: int
                   1119: main(int argc, char *argv[])
                   1120: {
                   1121:        prog = argv[0];
                   1122:        scanq(0, showq);
                   1123:        return 0;
                   1124: }
                   1125: )
                   1126:                goto err;
                   1127:        if (!attempt)
                   1128:                goto out;
                   1129: 
                   1130:        if (!recvfile(2))
                   1131:                goto err;
                   1132: 
                   1133:        rename(busy, done);
                   1134: 
                   1135:        fd = open("/dev/null", O_WRONLY);
                   1136:        dup2(fd, 2);
                   1137:        close(fd);
                   1138:        return;
                   1139: 
                   1140:  out:
                   1141:        /* continue with the next job */
                   1142:        remove(busy);
                   1143:        return;
                   1144: 
                   1145:  err:
                   1146:        /* failure that's too hard to resynchroape/TODO   644   3513      4         330  5023514043   5312 Pervasive error checking:
                   1147: 
                   1148: * dist.sh
                   1149:        check exit code of mkpkg and other programs; don't
                   1150:        make a valid queue entry unless everything went perfectly.
                   1151: * scanq.c transmit.c:
                   1152:        inspect for places that need error checking
                   1153: wq);
                   1154:        return 0;
                   1155: }
                   1156: )
                   1157:                goto err;
                   1158:        if (!attempt)
                   1159:                goto out;
                   1160: 
                   1161:        if (!recvfile(2))
                   1162:                goto err;
                   1163: 
                   1164:        rename(busy, done);
                   1165: 
                   1166:        fd = open("/dev/null", O_WRONLY);
                   1167:        dup2(fd, 2);
                   1168:        close(fd);
                   1169:        return;
                   1170: 
                   1171:  out:
                   1172:        /* continue with the next job */
                   1173:        remove(busy);
                   1174:        return;
                   1175: 
                   1176:  err:
                   1177:        /* failure that's too hard to resynchroape/path.c   644   3513      4        4341  5027737356   5772 /* brutally hacked from ../pkg/path.c */
                   1178: 
                   1179: #include <ctype.h>
                   1180: #include <stdio.h>
                   1181: #include <stdlib.h>
                   1182: #include "dist.h"
                   1183: 
                   1184: #define CHUNK 64
                   1185: 
                   1186: static char *r;
                   1187: static unsigned size;
                   1188: 
                   1189: static char *
                   1190: ralloc(char *ptr, size_t size)
                   1191: {
                   1192:        char *result;
                   1193: 
                   1194:        if (!ptr)
                   1195:                result = malloc(size);
                   1196:        else
                   1197:                result = realloc(ptr, size);
                   1198:        if (!result) {
                   1199:                eprintf("out of memory in getpath");
                   1200:                exit(1);
                   1201:        }
                   1202:        return result;
                   1203: }
                   1204: 
                   1205: char *
                   1206: getpath (FILE *file)
                   1207: {
                   1208:        register int c;
                   1209:        register int len = 0;
                   1210: 
                   1211:        c = getc (file);
                   1212: 
                   1213:        while (!isspace(c) && c != EOF) {
                   1214:                register int i = 0, n = 0;
                   1215: 
                   1216:                /* determine the next input character */
                   1217:                if (c == '\\') {
                   1218:                        c = getc (file);
                   1219:                        switch (c) {
                   1220: 
                   1221:                        case '\\':
                   1222:                                break;
                   1223:                        
                   1224:                        case 'n':
                   1225:                                c = '\n';
                   1226:                                break;
                   1227: 
                   1228:                        case 'r':
                   1229:                                c = '\r';
                   1230:                                break;
                   1231: 
                   1232:                        case 't':
                   1233:                                c = '\t';
                   1234:                                break;
                   1235: 
                   1236:                        case 'b':
                   1237:                                c = '\b';
                   1238:                                break;
                   1239:                        
                   1240:                        case 'f':
                   1241:                                c = '\f';
                   1242:                                break;
                   1243:                        
                   1244:                        case 'v':
                   1245:                                c = '\v';
                   1246:                                break;
                   1247:                        
                   1248:                        case ' ':
                   1249:                             /* c = ' '; */
                   1250:                                break;
                   1251: 
                   1252:                        default:
                   1253:                                while (c >= '0' && c <= '7' && i < 3) {
                   1254:                                        n = (n << 3) + c - '0';
                   1255:                                        i++;
                   1256:                                        c = getc (file);
                   1257:                                }
                   1258:                                ungetc (c, file);
                   1259:                                c = n;
                   1260:                                break;
                   1261:                        }
                   1262:                }
                   1263: 
                   1264:                /* ensure there's room in the buffer */
                   1265:                if (len >= size)
                   1266:                        r = ralloc (r, size += CHUNK);
                   1267: 
                   1268:                /* put the character in the buffer */
                   1269:                r[len++] = c;
                   1270: 
                   1271:                /* read the next character */
                   1272:                c = getc (file);
                   1273:        }
                   1274: 
                   1275:        /* unless we hit eof, we read one character too far. */
                   1276:        if (c != EOF)
                   1277:                ungetc (c, file);
                   1278:        
                   1279:        /* put a final null into the buffer */
                   1280:        if (len >= size)
                   1281:                r = ralloc (r, size += CHUNK);
                   1282:        r[len] = '\0';
                   1283: 
                   1284:        return r;
                   1285: }
                   1286: 
                   1287: void
                   1288: putpath (FILE *file, char *path)
                   1289: {
                   1290:        register char *p = path;
                   1291:        register int c;
                   1292:        
                   1293:        while ((c = *p++) != NULL) {
                   1294:                switch (c) {
                   1295: 
                   1296:                case '\n':
                   1297:                        fprintf (file, "\\n");
                   1298:                        break;
                   1299: 
                   1300:                case '\r':
                   1301:                        fprintf (file, "\\r");
                   1302:                        break;
                   1303: 
                   1304:                case '\b':
                   1305:                        fprintf (file, "\\b");
                   1306:                        break;
                   1307: 
                   1308:                case '\t':
                   1309:                        fprintf (file, "\\t");
                   1310:                        break;
                   1311: 
                   1312:                case '\f':
                   1313:                        fprintf (file, "\\f");
                   1314:                        break;
                   1315:                
                   1316:                case '\v':
                   1317:                        fprintf (file, "\\v");
                   1318:                        break;
                   1319:                
                   1320:                case '\\':
                   1321:                        fprintf (file, "\\\\");
                   1322:                        break;
                   1323:                
                   1324:                case ' ':
                   1325:                        fprintf (file, "\\ ");
                   1326:                        break;
                   1327:                
                   1328:                default:
                   1329:                        if (iscntrl (c))
                   1330:                                fprintf (file,
                   1331:                                    *p >= '0' && *p <= '7'? "\\%.3o": "\\%o",
                   1332:                                    c);
                   1333:                        else
                   1334:                                putc (c, file);
                   1335:                        break;
                   1336:                }
                   1337:        }
                   1338: }
                   1339: e '\r':
                   1340:                        fprintf (file, "\\r");
                   1341:                        break;
                   1342: 
                   1343:                case '\b':
                   1344:                        fprintf (file, "\\b");
                   1345:                        break;
                   1346: 
                   1347:                case '\t':
                   1348:                        fprintf (file, "\\t");
                   1349:                        break;
                   1350: 
                   1351:                case '\f':
                   1352:                        fprintf (file, "\\f");
                   1353:                        break;
                   1354:                
                   1355:                case '\v':
                   1356:                        fprintf (file, "\\v");
                   1357:                        break;
                   1358:                
                   1359:                case '\\':
                   1360:                        fprintf (file, "\\\\")ape/crc.c   644   3513      4        7124  5030710503   5562 #include <stddef.h>
                   1361: #include <stdio.h>
                   1362: #include "dist.h"
                   1363: 
                   1364: /* CRC table for cksum from IEEE 1003.2 draft 11. */
                   1365: const unsigned long crctab[] = {
                   1366:        0x7FFFFFFF, 0x77073096, 0xEE0E612C, 0x990951BA,
                   1367:        0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
                   1368:        0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
                   1369:        0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
                   1370:        0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
                   1371:        0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
                   1372:        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
                   1373:        0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
                   1374:        0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
                   1375:        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
                   1376:        0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
                   1377:        0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
                   1378:        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
                   1379:        0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
                   1380:        0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
                   1381:        0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
                   1382:        0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
                   1383:        0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
                   1384:        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
                   1385:        0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
                   1386:        0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
                   1387:        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
                   1388:        0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
                   1389:        0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
                   1390:        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
                   1391:        0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
                   1392:        0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
                   1393:        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
                   1394:        0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
                   1395:        0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
                   1396:        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
                   1397:        0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
                   1398:        0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
                   1399:        0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
                   1400:        0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
                   1401:        0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
                   1402:        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
                   1403:        0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
                   1404:        0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
                   1405:        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
                   1406:        0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
                   1407:        0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
                   1408:        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
                   1409:        0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
                   1410:        0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
                   1411:        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
                   1412:        0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
                   1413:        0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
                   1414:        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
                   1415:        0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
                   1416:        0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
                   1417:        0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
                   1418:        0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
                   1419:        0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
                   1420:        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
                   1421:        0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
                   1422:        0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
                   1423:        0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
                   1424:        0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
                   1425:        0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
                   1426:        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
                   1427:        0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
                   1428:        0xB3667A2E, 0xC4619AB8, 0x5D681B02, 0x2A6F2B94,
                   1429:        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
                   1430: };
                   1431: 
                   1432: void
                   1433: crcinit(int *aux)
                   1434: {
                   1435:        *aux = 0;
                   1436: }
                   1437: 
                   1438: /* incrementally compute crc for part of a block */
                   1439: unsigned long
                   1440: crcincr(unsigned char *addr, size_t size, unsigned long crc, int *aux)
                   1441: {
                   1442:        int i;
                   1443: 
                   1444:        while (size--) {
                   1445:                i = (crc >> 24) ^ *addr++;
                   1446:                if (i == 0) {
                   1447:                        i = (*aux)++;
                   1448:                        if (*aux >= sizeof crctab / sizeof crctab[0])
                   1449:                                *aux = 0;
                   1450:                }
                   1451:                crc = (crc << 8) ^ crctab[i];
                   1452:        }
                   1453:        return crc;
                   1454: }
                   1455: , 0x54DE5729, 0x23D967BF,
                   1456:        0xB3667A2E, 0xC4619AB8, 0x5D681B02, 0x2A6F2B94,
                   1457:        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
                   1458: };
                   1459: 
                   1460: void
                   1461: crcinit(int *aux)
                   1462: {
                   1463:        *aux = 0;
                   1464: }
                   1465: 
                   1466: /* incrementally compute crc for part of a block */
                   1467: unsigned long
                   1468: crcincr(unsigned char *addr, size_t size, unsigned long crc, int *aux)
                   1469: {
                   1470:        int i;
                   1471: 
                   1472:        while (size--) {
                   1473:                i = (crc >> 24) ^ *addr++;
                   1474:                if (i == 0) {
                   1475:                        i = (*aux)++;
                   1476:                        if (*aux >= sizeof crctab / siape/genmail.sh   644   3513      4        1605  5031142116   6615 #! /bin/sh -
                   1477: # send mail to a user for the given job
                   1478: # option -f: say this is the final report
                   1479: exec 2>> %SDIR%/log
                   1480: 
                   1481: PATH=%LDIR%:/bin:/usr/bin:/usr/ucb:/usr/bsd
                   1482: cd %SDIR%
                   1483: 
                   1484: if [ "x$1" = x-f ]
                   1485: then
                   1486:        shift
                   1487:        final=1
                   1488: else
                   1489:        final=0
                   1490: fi
                   1491: 
                   1492: if [ $# != 1 ]
                   1493: then
                   1494:        exit 1
                   1495: fi
                   1496: 
                   1497: user=`ls -ld $1 | awk '{print $3}'`
                   1498: host=`hostname`
                   1499: 
                   1500: trap 'rm -f /tmp/genmail.$$' 0 1 2 3
                   1501: rm -f /tmp/genmail.$$
                   1502: 
                   1503: if [ $final = 0 ]
                   1504: then
                   1505:        echo current status report of dist job $host!$1
                   1506: else
                   1507:        echo final status report of dist job $host!$1
                   1508: fi > /tmp/genmail.$$
                   1509: 
                   1510: while read num sys
                   1511: do
                   1512:        if [ -f $1/$num.mail ]
                   1513:        then
                   1514:                :
                   1515:        else
                   1516:                if [ -s $1/$num.done ]
                   1517:                then
                   1518:                        echo $sys completed with errors:
                   1519:                        sed 's/^/       /' $1/$num.done
                   1520:                        touch $1/$num.mail
                   1521:                elif [ -f $1/$num.done ]
                   1522:                then
                   1523:                        echo $sys completed successfully.
                   1524:                        touch $1/$num.mail
                   1525:                else
                   1526:                        echo $sys not completed.
                   1527:                fi
                   1528:        fi
                   1529: done < $1/ctl >> /tmp/genmail.$$
                   1530: 
                   1531: mail $user < /tmp/genmail.$$
                   1532:  ]
                   1533: then
                   1534:        echo current status report of dist job $host!$1
                   1535: else
                   1536:        echo final status report of dist job $host!$1
                   1537: fi > /tmp/genmape/nightly.sh   644   3513      4         173  5021521457   6646 #! /bin/sh -
                   1538: # nightly shell script to send mail for unfinished jobs
                   1539: cd %SDIR%
                   1540: for job in Q.*
                   1541: do
                   1542:        %LDIR%/genmail $job
                   1543: done
                   1544: d with errors:
                   1545:                        sed 's/^/       /' $1/$num.done
                   1546:                        touch $1/$num.mail
                   1547:                elif [ -f $1/$num.done ]
                   1548:                then
                   1549:                        echo $sys completed successfully.
                   1550:                        touch $1/$num.mail
                   1551:                else
                   1552:                        echo $sys not completed.
                   1553:                fi
                   1554:        fi
                   1555: done < $1/ctl >> /tmp/genmail.$$
                   1556: 
                   1557: mail $user < /tmp/genmail.$$
                   1558:  ]
                   1559: then
                   1560:        echo current status report of dist job $host!$1
                   1561: else
                   1562:        echo final status report of dist job $host!$1
                   1563: fi > /tmp/genmape/cleanq.c   644   3513      4         211  5031454571   6237 #include <stddef.h>
                   1564: #include <stdio.h>
                   1565: #include "dist.h"
                   1566: 
                   1567: int
                   1568: main(int argc, char *argv[])
                   1569: {
                   1570:        prog = argv[0];
                   1571:        scanq(0, 0);
                   1572:        return 0;
                   1573: }
                   1574: 
                   1575:                        sed 's/^/       /' $1/$num.done
                   1576:                        touch $1/$num.mail
                   1577:                elif [ -f $1/$num.done ]
                   1578:                then
                   1579:                        echo $sys completed successfully.
                   1580:                        touch $1/$num.mail
                   1581:                else
                   1582:                        echo $sys not completed.
                   1583:                fi
                   1584:        fi
                   1585: done < $1/ctl >> /tmp/genmail.$$
                   1586: 
                   1587: mail $user < /tmp/genmail.$$
                   1588:  ]
                   1589: then
                   1590:        echo current status report of dist job $host!$1
                   1591: else
                   1592:        echo final status report of dist job $host!$1
                   1593: fi > /tmp/genmdoc.ms   644   3513      4        1177  5032532571   5223 .TL
                   1594: A System for Automatic Source Distribution
                   1595: .AU
                   1596: Mike Haertel
                   1597: .AI
                   1598: AT&T Bell Laboratories
                   1599: Murray Hill, NJ  07974
                   1600: .AB
                   1601: .\"
                   1602: .\" "Single Heterogeneous network seeks automatic software distribution mechanism..."
                   1603: .\"    \(em Greg Lindahl
                   1604: .\"
                   1605: With the advent of wildly heterogeneous networks, automatic software
                   1606: distribution has become a nightmare.  Binaries are useless, and source
                   1607: code often fails to recompile across ostensibly standard systems.
                   1608: Finally, security is, as always, a concern, especially when the automatic
                   1609: installation of priviliged system software is desired.  We describe
                   1610: yet another attempt to address some of these issues.
                   1611: .AE
                   1612: Single Heterogeneous network seeks automatic software distribution mechanism..."
                   1613: .\"    \(em Greg Lindahl
                   1614: .\"
                   1615: With the advent of wildly heterogeneous networks, automatic software
                   1616: distribution has become a nightmare.  Binaries are useless, and source
                   1617: code often fails to recompile across ostensibly standard systems.
                   1618: Finally, security is, as always, a concern, especially when the automatigenmkfile.sh   644   3513      4         721  5031150727   6362 #! /bin/sh
                   1619: echo "<mkconf.$1" > mkfile
                   1620: 
                   1621: cat << 'EOF' >> mkfile
                   1622: DIRS=ape pkg $SYS
                   1623: 
                   1624: %-compile:V: paths.h
                   1625:        cd $stem; mk compile
                   1626: 
                   1627: %-install:V: %-compile
                   1628:        cd $stem; mk install
                   1629: 
                   1630: %-clean:V:
                   1631:        cd $stem; mk clean
                   1632: 
                   1633: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   1634: 
                   1635: compile:V: ${DIRS:%=%-compile}
                   1636: 
                   1637: install:V: ${DIRS:%=%-install}
                   1638: 
                   1639: clean:V: ${DIRS:%=%-clean}
                   1640:        rm -f paths.h
                   1641: 
                   1642: paths.h: mkconf.$SYS
                   1643:        echo '#define LDIR "'$LDIR'"' > paths.h
                   1644:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   1645: EOF
                   1646: always, a concern, especially when the automatiman/   755   3513      4           0  5031450027   4567 man/dist.1   644   3513      4        3344  5031462000   5677 .TH DIST 1
                   1647: .SH NAME
                   1648: dist \(mi distribute files to remote systems
                   1649: .SH SYNOPSIS
                   1650: .\".BI "dist [ " system " | -[Ff] " file " ] [ -n ] " files
                   1651: .BI "dist [ " system " | -[Ff] " file " ] " files
                   1652: .PP
                   1653: .B "dist -q ["
                   1654: .I system
                   1655: .B "| -[Ff]"
                   1656: .I file
                   1657: .B "]"
                   1658: .PP
                   1659: .B "dist -r ["
                   1660: .I system
                   1661: .B "| -[Ff]"
                   1662: .I file
                   1663: .B "]"
                   1664: .SH DESCRIPTION
                   1665: .I Dist
                   1666: distributes files to other systems, where they are installed
                   1667: under the same names.
                   1668: .I Dist
                   1669: operates by packaging the files with
                   1670: .IR mkpkg (1),
                   1671: and queuing the resulting package in a spool directory to be
                   1672: picked up by the remote systems.
                   1673: .PP
                   1674: The remote systems' names are given as a single argument, containing
                   1675: the system names (in the format of
                   1676: .IR ipc (3))
                   1677: separated by white space; alternatively, the
                   1678: .B -f
                   1679: option may be used to specify a file containing a list of system names.
                   1680: The
                   1681: .B -F
                   1682: option is identical to
                   1683: .B -f
                   1684: except
                   1685: .I dist
                   1686: looks for the file in a standard directory.
                   1687: .PP
                   1688: The
                   1689: .I dist
                   1690: command has two forms of use.  In the first form,
                   1691: .I dist
                   1692: packages a group of files and queues them for transmission.
                   1693: .\"If the
                   1694: .\".B -n
                   1695: .\"option is specified, the remote systems are notified that the package
                   1696: .\"is available.
                   1697: The
                   1698: .I file
                   1699: arguments may be either file names or options for
                   1700: .IR mkpkg (1).
                   1701: .PP
                   1702: When 
                   1703: .B -q
                   1704: is given,
                   1705: .I dist
                   1706: queries the named systems and displays the contents of their transmission
                   1707: queues; if no systems are given the local queue is displayed
                   1708: by default.
                   1709: .PP
                   1710: When
                   1711: .B -r
                   1712: is given,
                   1713: .I dist
                   1714: calls the named system and installs any packages it has queued for
                   1715: the local system.
                   1716: .SH EXAMPLES
                   1717: Distribute a new binary for grep to all vaxes:
                   1718: .IP
                   1719: .B "dist -F vaxes /bin/grep"
                   1720: .SH FILES
                   1721: .B /usr/lib/dist/*
                   1722: .br
                   1723: .B /usr/lib/dist/destinations/*
                   1724: .br
                   1725: .B /usr/spool/dist/*
                   1726: .SH "SEE ALSO"
                   1727: .IR mkpkg (1),
                   1728: .IR dist (5),
                   1729: .IR dist (8)
                   1730: I dist
                   1731: queries the named systems and displays the contents of their transmission
                   1732: queues; if no systems are given the local queue is displayed
                   1733: by default.
                   1734: .PP
                   1735: When
                   1736: .B -r
                   1737: is given,
                   1738: .I dist
                   1739: calls the named system and installs any packages it has queued for
                   1740: the local system.
                   1741: .SH EXAMPLESman/dist.5   644   3513      4        3634  5017041737   5723 .TH DIST 5
                   1742: .SH NAME
                   1743: dist \(mi spool directory structure for
                   1744: .B dist
                   1745: .SH SYNOPSIS
                   1746: .ds sd /usr/spool/dist
                   1747: .B \*(sd/Q.*/
                   1748: .PP
                   1749: .B \*(sd/Q.*/ctl
                   1750: .PP
                   1751: .B \*(sd/Q.*/data
                   1752: .PP
                   1753: .B \*(sd/Q.*/files
                   1754: .PP
                   1755: .B \*(sd/Q.*/[1-9]*.busy
                   1756: .PP
                   1757: .B \*(sd/Q.*/[1-9]*.done
                   1758: .SH DESCRIPTION
                   1759: The
                   1760: .I dist
                   1761: spool directory contains distributions queued for transmission
                   1762: to remote systems, and is also used as the working directory when
                   1763: unpacking distributions received from remote systems.
                   1764: .PP
                   1765: Each job has its own subdirectory
                   1766: of the spool directory.  Several files with conventional names
                   1767: appear in this per-job directory, as well as files with
                   1768: generated names containing status information for each remote
                   1769: system in the job.
                   1770: .PP
                   1771: The files in a job's spool directory include:
                   1772: .TP
                   1773: .B ctl
                   1774: The control file contains a list of identifying numbers
                   1775: and remote system names.  The identifying number
                   1776: is used in file names containing status information for corresponding
                   1777: remote system, since network names may not be legal file names.
                   1778: The file contains a sequence of lines; each line contains
                   1779: an identifying number, a space, and the corresponding remote system name.
                   1780: .TP
                   1781: .B data
                   1782: The data file contains the output of
                   1783: .IR mkpkg (1)
                   1784: for the distribution.
                   1785: .TP
                   1786: .B files
                   1787: A list of file names specified in the command line
                   1788: that created the job.  This is mainly used as a key
                   1789: for superseding jobs:  if a new job is created that
                   1790: contains a superset of the files of some old
                   1791: job, the old job is marked as completed for all remote
                   1792: systems it has in common with the new job.
                   1793: .TP
                   1794: .B [1-9]*.busy
                   1795: An empty lock file indicating that the identified system
                   1796: is currently receiving the distribution.
                   1797: .TP
                   1798: .B [1-9]*.done
                   1799: Status file indicating that the identified system is
                   1800: finished with the distribution.  This file is empty
                   1801: if and only if the distribution was successfully installed;
                   1802: otherwise it contains any error messages from the remote
                   1803: system.
                   1804: .SH FILES
                   1805: .B \*(sd/*
                   1806: .SH "SEE ALSO"
                   1807: .IR dist (1),
                   1808: .IR dist (8)
                   1809: b is marked as completed for all remote
                   1810: systems it has in common with the new job.
                   1811: .TP
                   1812: .B [1-9]*.busman/dist.8   644   3513      4        7340  5017051644   5722 .TH DIST 8
                   1813: .ds ld /usr/lib/dist
                   1814: .SH NAME
                   1815: connect, dispatch \(mi generic network client and server
                   1816: .PP
                   1817: query, receive, notify \(mi network clients
                   1818: .PP
                   1819: answer, transmit, notified \(mi network servers
                   1820: .SH SYNOPSIS
                   1821: .B \*(ld/connect
                   1822: .I remote-system remote-cmd io local-cmd local-args
                   1823: .PP
                   1824: .B \*(ld/query
                   1825: .PP
                   1826: .B \*(ld/receive
                   1827: .I package-id
                   1828: .PP
                   1829: .B \*(ld/notify
                   1830: .I package-id
                   1831: .PP
                   1832: .B \*(ld/dispatch
                   1833: .I remote-system remote-user
                   1834: .PP
                   1835: .B \*(ld/answer
                   1836: .I remote-system remote-user
                   1837: .PP
                   1838: .B \*(ld/transmit
                   1839: .I remote-system remote-user
                   1840: .PP
                   1841: .B \*(ld/notified
                   1842: .I remote-system remote-user
                   1843: .SH DESCRIPTION
                   1844: These programs act behind the scenes on behalf of
                   1845: .IR dist (1).
                   1846: .I Connect
                   1847: and
                   1848: .I dispatch
                   1849: deal with all the details of establishing and authenticating connections
                   1850: on the network.  The remaining programs are independent of the underlying
                   1851: network.
                   1852: .PP
                   1853: .I Connect
                   1854: encapsulates all the details of making a call on the underlying network.
                   1855: Its arguments are mostly self explanatory.
                   1856: .I Remote-cmd
                   1857: must be one of
                   1858: .BR answer ", " transmit ", or " notified "."
                   1859: If
                   1860: .I io
                   1861: is
                   1862: .BR i ,
                   1863: the standard input of the local command is connected
                   1864: to the standard output of the remote command.  If
                   1865: .B i
                   1866: is not specified, the local command inherits its local
                   1867: standard input, and the remote command has its standard
                   1868: output directed to a log file.
                   1869: Similarly,
                   1870: .B o
                   1871: means the standard output of the local command is connected
                   1872: to the standard input of the remote command.  If
                   1873: .B o
                   1874: is not specified, the local command inherits its local
                   1875: standard output, and the remote command has its standard
                   1876: input attached to
                   1877: .BR /dev/null .
                   1878: Legal possibilities are
                   1879: .BR i ,
                   1880: .BR o ,
                   1881: and
                   1882: .BR io.
                   1883: .PP
                   1884: .I Dispatch
                   1885: is intended to be called by a generic network daemon
                   1886: such as
                   1887: .IR svcmgr (8).
                   1888: It talks to
                   1889: .I connect
                   1890: and takes care of establishing the appropriate standard input and
                   1891: output before calling
                   1892: .IR answer ,
                   1893: .IR transmit ,
                   1894: or
                   1895: .IR notified .
                   1896: .I Dispatch
                   1897: expects arguments giving the remote system, remote user, and remote
                   1898: address, and passes these to whatever program it calls.
                   1899: .PP
                   1900: .I Query
                   1901: is a simple program called by
                   1902: .I connect
                   1903: with its standard input attached to the remote
                   1904: .IR answer .
                   1905: .I Query
                   1906: displays a formatted version of the queue list from the remote machine.
                   1907: (It may even turn out to be the same as
                   1908: .BR /bin/cat .)
                   1909: .PP
                   1910: .I Receive
                   1911: is a more complicated program that is called by
                   1912: .I connect
                   1913: with both its input and output attached to the remote
                   1914: .IR transmit .
                   1915: .I Receive
                   1916: performs actual software installation and sends a transcript of any
                   1917: errors back to the remote system.
                   1918: .PP
                   1919: .I Notify
                   1920: is a simple program called by
                   1921: .I connect
                   1922: with its standard output attached to the remote
                   1923: .IR notified .
                   1924: .I Notify
                   1925: sends an announcement of the availability of some specific package.
                   1926: .PP
                   1927: All of the servers read a configuration file,
                   1928: .BR \*(ld/conf ,
                   1929: to determine how to handle installation on behalf
                   1930: of a given remote system and user.  The file consists of lines
                   1931: containing patterns and actions.  Empty lines or lines beginning
                   1932: with a '\c
                   1933: .BR "#" "'"
                   1934: are ignored.  The first three fields (separated by white space)
                   1935: of each line are regular
                   1936: expressions to be matched the remote system name, remote user name,
                   1937: and file name respectively.  The first line in which all three match
                   1938: will be chosen.
                   1939: The remainder of the line contains
                   1940: the associated actions.
                   1941: Each action is an alphanumeric name, optionally followed immediately
                   1942: by a parenthesized argument.
                   1943: .PP
                   1944: Someday the actions will be enumerated here, but I don't know what
                   1945: they are yet.
                   1946: .SH EXAMPLES
                   1947: A simple configuration file:
                   1948: .EX
                   1949: .ta \w'00000000'u +\w'00000000'u +\w'00000000'u +\w'00000000'u +\w'00000000'u +\w'00000000'u
                   1950: # system       user            pathname        action
                   1951: # we are willing to distribute stuff to coma and pyxis.
                   1952: (coma|pyxis)   .*              .*              accept(yes)
                   1953: \&.*           .*              .*              accept(no)
                   1954: .EE
                   1955: .SH "SEE ALSO"
                   1956: .IR dist (1),
                   1957: .IR dist (5)
                   1958: ach action is an alphanumeric name, optionally followed immediately
                   1959: by a parenthesized argument.
                   1960: .PP
                   1961: Someday the actions will be enumerated here, but I don't know what
                   1962: they are yet.
                   1963: .SH EXAMPLES
                   1964: A simple configuration file:
                   1965: .EX
                   1966: .ta \w'00000000'u +\w'00000000'u +\w'00000000'u +\w'00000000mkconf.bsd   644   3513      4         106  5031147027   6030 SYS=bsd
                   1967: BDIR=/usr/mjh/bin
                   1968: LDIR=/usr/mjh/dist
                   1969: SDIR=/usr/mjh/dist/spool
                   1970:  pkg $SYS
                   1971: 
                   1972: %-compile:V: paths.h
                   1973:        cd $stem; mk compile
                   1974: 
                   1975: %-install:V: %-compile
                   1976:        cd $stem; mk install
                   1977: 
                   1978: %-clean:V:
                   1979:        cd $stem; mk clean
                   1980: 
                   1981: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   1982: 
                   1983: compile:V: ${DIRS:%=%-compile}
                   1984: 
                   1985: install:V: ${DIRS:%=%-install}
                   1986: 
                   1987: clean:V: ${DIRS:%=%-clean}
                   1988:        rm -f paths.h
                   1989: 
                   1990: paths.h: mkconf.$SYS
                   1991:        echo '#define LDIR "'$LDIR'"' > paths.h
                   1992:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   1993: EOF
                   1994: always, a concern, especially when the automatimkconf.sysv   644   3513      4          73  5031452264   6251 SYS=sysv
                   1995: BDIR=/v/bin
                   1996: LDIR=/v/lib/dist
                   1997: SDIR=/usr/spool/dist
                   1998: dist/spool
                   1999:  pkg $SYS
                   2000: 
                   2001: %-compile:V: paths.h
                   2002:        cd $stem; mk compile
                   2003: 
                   2004: %-install:V: %-compile
                   2005:        cd $stem; mk install
                   2006: 
                   2007: %-clean:V:
                   2008:        cd $stem; mk clean
                   2009: 
                   2010: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   2011: 
                   2012: compile:V: ${DIRS:%=%-compile}
                   2013: 
                   2014: install:V: ${DIRS:%=%-install}
                   2015: 
                   2016: clean:V: ${DIRS:%=%-clean}
                   2017:        rm -f paths.h
                   2018: 
                   2019: paths.h: mkconf.$SYS
                   2020:        echo '#define LDIR "'$LDIR'"' > paths.h
                   2021:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   2022: EOF
                   2023: always, a concern, especially when the automatimkconf.v10   644   3513      4          76  5031450436   5655 SYS=v10
                   2024: BDIR=/usr/bin
                   2025: LDIR=/usr/lib/dist
                   2026: SDIR=/usr/spool/dist
                   2027: t/spool
                   2028:  pkg $SYS
                   2029: 
                   2030: %-compile:V: paths.h
                   2031:        cd $stem; mk compile
                   2032: 
                   2033: %-install:V: %-compile
                   2034:        cd $stem; mk install
                   2035: 
                   2036: %-clean:V:
                   2037:        cd $stem; mk clean
                   2038: 
                   2039: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   2040: 
                   2041: compile:V: ${DIRS:%=%-compile}
                   2042: 
                   2043: install:V: ${DIRS:%=%-install}
                   2044: 
                   2045: clean:V: ${DIRS:%=%-clean}
                   2046:        rm -f paths.h
                   2047: 
                   2048: paths.h: mkconf.$SYS
                   2049:        echo '#define LDIR "'$LDIR'"' > paths.h
                   2050:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   2051: EOF
                   2052: always, a concern, especially when the automatimkrules.bsd   644   3513      4          57  5031147365   6227 CC=cc -g
                   2053: CCLIB=
                   2054: O=o
                   2055: OS=o
                   2056: SH=sh
                   2057: AR=ar
                   2058: RL=ranlib
                   2059: usr/spool/dist
                   2060: t/spool
                   2061:  pkg $SYS
                   2062: 
                   2063: %-compile:V: paths.h
                   2064:        cd $stem; mk compile
                   2065: 
                   2066: %-install:V: %-compile
                   2067:        cd $stem; mk install
                   2068: 
                   2069: %-clean:V:
                   2070:        cd $stem; mk clean
                   2071: 
                   2072: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   2073: 
                   2074: compile:V: ${DIRS:%=%-compile}
                   2075: 
                   2076: install:V: ${DIRS:%=%-install}
                   2077: 
                   2078: clean:V: ${DIRS:%=%-clean}
                   2079:        rm -f paths.h
                   2080: 
                   2081: paths.h: mkconf.$SYS
                   2082:        echo '#define LDIR "'$LDIR'"' > paths.h
                   2083:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   2084: EOF
                   2085: always, a concern, especially when the automatimkrules.sysv   644   3513      4          64  5031457630   6460 CC=cc -g -I../sysv
                   2086: CCLIB=
                   2087: O=o
                   2088: OS=o
                   2089: SH=sh
                   2090: AR=ar
                   2091: RL=:
                   2092: pool/dist
                   2093: t/spool
                   2094:  pkg $SYS
                   2095: 
                   2096: %-compile:V: paths.h
                   2097:        cd $stem; mk compile
                   2098: 
                   2099: %-install:V: %-compile
                   2100:        cd $stem; mk install
                   2101: 
                   2102: %-clean:V:
                   2103:        cd $stem; mk clean
                   2104: 
                   2105: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   2106: 
                   2107: compile:V: ${DIRS:%=%-compile}
                   2108: 
                   2109: install:V: ${DIRS:%=%-install}
                   2110: 
                   2111: clean:V: ${DIRS:%=%-clean}
                   2112:        rm -f paths.h
                   2113: 
                   2114: paths.h: mkconf.$SYS
                   2115:        echo '#define LDIR "'$LDIR'"' > paths.h
                   2116:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   2117: EOF
                   2118: always, a concern, especially when the automatimkrules.v10   644   3513      4         166  5032136552   6103 CC=/usr/ape/apebin/pcc -g -D_POSIX_SOURCE -D_RESEARCH_SOURCE
                   2119: CCLIB=/usr/ape/lib/libv.a
                   2120: O=o
                   2121: OS=o
                   2122: SH=sh
                   2123: AR=ar
                   2124: RL=ranlib
                   2125: mpile
                   2126: 
                   2127: %-install:V: %-compile
                   2128:        cd $stem; mk install
                   2129: 
                   2130: %-clean:V:
                   2131:        cd $stem; mk clean
                   2132: 
                   2133: ape-compile pkg-compile:Pexit 1: $SYS-compile
                   2134: 
                   2135: compile:V: ${DIRS:%=%-compile}
                   2136: 
                   2137: install:V: ${DIRS:%=%-install}
                   2138: 
                   2139: clean:V: ${DIRS:%=%-clean}
                   2140:        rm -f paths.h
                   2141: 
                   2142: paths.h: mkconf.$SYS
                   2143:        echo '#define LDIR "'$LDIR'"' > paths.h
                   2144:        echo '#define SDIR "'$SDIR'"' >> paths.h
                   2145: EOF
                   2146: always, a concern, especially when the automatinotes/   755   3513      4           0  5031450036   5144 notes/IDEAS   644   3513      4        1446  5013610625   6010 Use APE everywhere.  Keep inspkg, mkpkg, seal, and unseal essential unchanged
                   2147: from old ASD stuff.
                   2148: 
                   2149: Client distributee calls distributor rather than vice versa;
                   2150: eliminate the need for trust.
                   2151: 
                   2152: Eliminate the crypto stuff; nobody uses it.  Either that or figure out
                   2153: a good way to put it in avoiding the problem Dennis mentioned about
                   2154: delayed replies.
                   2155: 
                   2156: What about user ids and group ids?  There seem to be some hacks
                   2157: for when running setuid under Unix.  Does any of that mean anything
                   2158: real, or is it just feeping creaturism?
                   2159: 
                   2160: Take out the feature for shipping special files--there is no
                   2161: real support of special files in APE, and we want to run under
                   2162: that everywhere.  If you really want to you can ship a script
                   2163: to make special files on the remote machine anyway.  (How calvinist
                   2164: are you feeling, Andrew asks?)
                   2165:  the problem Dennis mentioned about
                   2166: delayed replies.
                   2167: 
                   2168: What about user ids and group ids?  There seem to be some hacks
                   2169: for when running setuid under Unix.  Does any of that mean anything
                   2170: real, or is it just feeping creanotes/PLAN   644   3513      4        6110  5012057047   5710 The ship system will live in two places, the library directory $L (typically
                   2171: /usr/lib/ship) and the spool directory $S (typically /usr/spool/ship).
                   2172: Operations are of two classes: client functions and server functions.
                   2173: A single machine may operate as both a client and a server.  The whole
                   2174: setup is controlled by a single configuration file, $L/conf.
                   2175: 
                   2176: The configuration file consists of a sequence of pattern lines interspersed
                   2177: with definitions pertaining to clients or servers matching the patterns.
                   2178: 
                   2179: Patterns are of the form 'key: match (match ...) (key: match ...)'; the whole
                   2180: pattern may be prefixed by an exclamation point to negate it.  Definitions
                   2181: are of the form var=value, in shell syntax, and appear one to a line prefixed
                   2182: by a tab character.
                   2183: 
                   2184: Each match is a restricted globbing expression, of the form understood by the shell.
                   2185: 
                   2186: Client and server programs scan the configuration file in order, choosing
                   2187: only the first configuration that applies to a given situation.
                   2188: 
                   2189: Lines beginning with a # are comments.
                   2190: 
                   2191: For example, the following excerpt might occur in the configuration file of
                   2192: a sources repository machine.
                   2193: 
                   2194:        # We accept connections from client1, client2, and client3.
                   2195:        client: client1 client2 client3
                   2196:                accept=yes
                   2197:        client: *
                   2198:                accept=no
                   2199:        # We periodically poll server1, which sends us some stuff now and then.
                   2200:        poll: server1
                   2201:                poll=hourly
                   2202:        # The user fred on server1 is a klutz.
                   2203:        server: server1 user: fred
                   2204:                accept=no
                   2205:        # We also don't accept stuff from guests.
                   2206:        server: server1 group: guest
                   2207:                accept=no
                   2208:        # This line applies if none of the rejections above do.
                   2209:        server: server1
                   2210:                accept=yes
                   2211: 
                   2212: For each configuration (server, client, poll, or other to be invented), some
                   2213: assignments may be optional and others mandatory.  For example, for client:
                   2214: and server: configurations, the 'accept=' assignment is probably mandatory.
                   2215: However, for clients the 'notify=' (do we notify them when we have a new package
                   2216: for them, or do we wait for them to call?) is optional and defaults (probably)
                   2217: to 'no'.
                   2218: 
                   2219: One uniform option understood by all configuration types is the 'transport='
                   2220: option, which specifies a program to use to place the network call.  On most
                   2221: machines this will probably be subsumed by the networking library, but some
                   2222: might require special treatment.
                   2223: 
                   2224: There should be some sort of mechanism for file inclusion.  This would allow
                   2225: system administrators to delegate administration of some aspects of the system
                   2226: to other users without actually granting write permission for the $L/conf file.
                   2227: 
                   2228: Some specific programs include:
                   2229: 
                   2230: $L/poll - a program run periodically on clients to poll appropriate servers
                   2231: $L/client - a program run on the client to accept a shipment from a particular server
                   2232: $L/server - the program run on the server that actually makes shipments
                   2233: $L/notify - a program run on the server to notify clients
                   2234: $L/notified - notify's peer on clients
                   2235: 
                   2236: The spool directory will be organized to have one subdirectory for each
                   2237: unfinished job.  Each job's subdirectory will contain a data file and
                   2238: control files for each client.  This organization makes it easy to
                   2239: atomically access and modify the status of any ongoing job.
                   2240:  program run on the client to accept a shipment from a particular server
                   2241: $L/server - the program run on the server that actually makes shipments
                   2242: $L/notify - a program run on the server to notify clients
                   2243: $L/notified - notify's peer on clients
                   2244: 
                   2245: The spool directory will be organized to have one subdirectory for each
                   2246: unfinished job.  Each job's subdirectory will contain a data file and
                   2247: control files for each client.  This organization makesnotes/PLAN2   644   3513      4        6620  5015021031   5763 The nasd (pronounced "nasty") system will live in two places, the library
                   2248: directory $L (typically /usr/lib/nasd) and the spool directory $S (typically
                   2249: /usr/spool/nasd).
                   2250: 
                   2251: Operations are of two classes: client functions, and server functions.
                   2252: A machine may act as both a client and a server.
                   2253: 
                   2254: The user interface to the system is the 'dist' command (details to be worked out,
                   2255: but mostly like ship, except the destination is taken from argument(s) rather than
                   2256: the environment).
                   2257: 
                   2258: Several programs work behind the scenes:
                   2259: 
                   2260: $L/connect - make a network connection and call $L/query, $L/receive, or $L/notify
                   2261: $L/query - query a server for pending jobs
                   2262: $L/receive - request a package from a server and optionally install it
                   2263: $L/notify - notify a client that a package is a available
                   2264: 
                   2265: $L/dispatch - dispatch incoming network connections to $L/answer, $L/send, or $L/notice
                   2266: $L/answer - the server for query
                   2267: $L/send - the server for receive
                   2268: $L/notice - the server for notify
                   2269: 
                   2270: The network programs are organized so they can work on a batch network as well
                   2271: as an interactive network.  $L/query, $L/receive expect only input from the
                   2272: network connection; $L/connect passes any initial arguments to the remote server.
                   2273: $L/notify produces only output for the network connection.
                   2274: 
                   2275: $L/dispatch, $L/answer, $L/send, and $L/notice are similarly organized.
                   2276: 
                   2277: The whole thing is driven by a configuration file $L/conf describing the
                   2278: allowed operations to be requested by remote machines.  The format of the
                   2279: file is as follows:  Lines beginning with a # are comments and are ignored.
                   2280: Other lines are of the form:
                   2281: 
                   2282:        service system user pathname action
                   2283: 
                   2284: Service is "server" or "client"; system, user, and pathname are regular
                   2285: expressions, and action is a list of actions, separated by +.  A sample
                   2286: configuration file might be:
                   2287: 
                   2288:        # service       system          user    pathname        action
                   2289: 
                   2290:        # we are willing to distribute stuff to coma and pyxis.
                   2291:        server          (coma|pyxis)    .*      .*              accept(yes)
                   2292:        server          .*              .*      .*              accept(no)
                   2293:        
                   2294:        # we don't like fred
                   2295:        client          .*              fred    .*              accept(no)
                   2296:        # we also refuse to accept stuff from root as a matter of principle
                   2297:        client          .*              root    .*              accept(no)
                   2298:        # stuff from bowell!mjh is installed in /usr/bin as root.
                   2299:        client          bowell          mjh     /usr/bin/.*     accept(yes)+user(root)
                   2300:        # we accept files in /usr/pub from anyone on alice, but we don't
                   2301:        # execute random commands for them
                   2302:        client          alice           .*      /usr/pub/.*     accept(yes)+cmds(no)
                   2303: 
                   2304: The configuration file is scanned for the first match to get actions.  If no
                   2305: match is found the request is rejected.  Some actions, such as "accept", must
                   2306: always be provided; others, such as "cmds" have defaults or are otherwise
                   2307:        # service       system          user    pathname        action
                   2308: 
                   2309:        # we are willing to distribute stuff to coma and pyxis.
                   2310:        transmit        (coma|pyxis)    .*      .*              accept(yes)
                   2311:        transmit        .*              .*      .*              accept(no)
                   2312:        
                   2313:        # we don't like fred
                   2314:        receive         .*              fred    .*              accept(no)
                   2315:        # we also refuse to accept stuff from root as a matter of principle
                   2316:        receive         .*              root    .*              accept(no)
                   2317:        # stuff from bowell!mjh is installed in /usr/bin as root.
                   2318:        receive         bowell          mjh     /usr/bin/.*     accept(yes)+user(root)
                   2319:        # we accept files in /usr/pub from anyone on alice, but we don't
                   2320:        # execute random commands for them
                   2321:        receive         alice           .*      /usr/pub/.*     accept(yes)+cmds(no)
                   2322: 
                   2323: The configuration file is scanned for the first match to get actions.  If no
                   2324: match is found the request is rejected.  Some actions, such as "accept", must
                   2325: always be provided; others, such as "cmds" have defaults or are otherwise
                   2326: unnecessary.
                   2327:  stuff from bowell!mjh is installed in /usr/bin as root.
                   2328:        receive         bowell          mjh     /usr/bin/.*     accept(yes)+user(rootnotes/PLAN2+   644   3513      4           0  5012311223   5742 notes/STRATEGY   644   3513      4        2401  5022742334   6420 The client loop:
                   2329: 
                   2330:        * for each package it receives, it checks if file system permissions
                   2331:        will permit that package to be installed.  if not, it rejects the
                   2332:        package and the server will retransmit it at a later date.
                   2333:        * it makes a backup package.
                   2334:        * it actually installs the package.  if installation fails, it installs
                   2335:        the backup package and reports errors to the server.
                   2336: 
                   2337: The server loop:
                   2338:        * for each queued package matching the remote system name, check if
                   2339:        the current user has read access to each component of the package.
                   2340:        if not, continue with the next package.
                   2341:        * transmit the package.
                   2342:        * wait for the client to check file system permissions against the package.
                   2343:        the client may decide not to try installing it.  if so, defer the package
                   2344:        until later, and continue with the next package.
                   2345:        * the client has decided to install the package.  record the error
                   2346:        transcript the client returns (if any), and mark the package as done
                   2347:        for that system.  (if it was the last outstanding system for the given
                   2348:        package, send mail to the owner of the package saying it was done.)
                   2349: 
                   2350: spool directory management:
                   2351:        * the spool directory and all files therein are owned by daemon.
                   2352:        the queue maker and the file server run setuid daemon so they can
                   2353:        make and remove queue entries respectively.
                   2354: ue with the next package.
                   2355:        * the client has decided to install the package.  record the error
                   2356:        transcript the client returns (if any), and mark the package as done
                   2357:        for that system.  (if it was the last outstanding system for the given
                   2358:        package, send mailnotes/TODO   644   3513      4         511  5020574003   5675 Figure out which regexp library to use.  POSIX mandates one.
                   2359: Perhaps I should write it.
                   2360: 
                   2361: Use alarm() on network reads and writes.
                   2362: 
                   2363: Write educated mkfiles.
                   2364: 
                   2365: Replace NAME_MAX with something that might be less
                   2366: pessimly large, considering that we have control over
                   2367: all file names in use.
                   2368: 
                   2369: Add cleanq to the man page.
                   2370: Also add canon.
                   2371: ge.  record the error
                   2372:        transcript the client returns (if any), and mark the package as done
                   2373:        for that system.  (if it was the last outstanding system for the given
                   2374:        package, send mailpkg/   755   3513      4           0  5032703620   4576 pkg/HISTORY   644   3513      4        3472  5013610562   5756 04/20/82      Initial version.
                   2375: 05/24/82       Added -b option for backup, created local versions
                   2376:                of tmpnam and ftw functions.
                   2377: 06/10/82       Handle strange characters in names.
                   2378: 08/04/82       Packaging a nonexistent file arranges to delete
                   2379:                the file during installation.
                   2380: 03/02/83       Handle character uid/gid not present on host
                   2381: 05/02/83       Added seal, unseal.
                   2382: 05/03/83       Split asd command into mkpkg, inspkg; general cleanup
                   2383: 05/12/83       In asdrcv, make separate keyfiles and permfiles.
                   2384: 05/15/83       Seal and unseal now handle lines beginning with "From"
                   2385: 08/26/83       Handle \ in file names properly
                   2386: 08/27/83       Ship is now a real command (well, a shell script...)
                   2387:                Asdrcv now looks in /etc/asd/keys and /etc/asd/perm.
                   2388: 09/10/83       It is now possible to package and install special files.
                   2389: 09/15/83       Asdrcv no longer passes -v to inspkg.
                   2390: 09/23/83       Renamed tmpnam to tmpname to avoid conflicts.
                   2391: 09/24/83       Change SIG_TYP to Sig_typ and declare it ("portability").
                   2392: 04/08/85       Change BMASK to BYTEMASK to avoid clashes with system.
                   2393: 04/10/85       Robustness changes in ship.sh
                   2394: 06/29/85       Makefile now conforms to reality again.
                   2395: 09/10/85       Handle symbolic links in package.c, inspkg.c, mkdir.c
                   2396: 09/10/85       Path.c accounts for \v
                   2397: 09/25/85       added -x and -X to mkpkg and inspkg for execution after installation
                   2398: 09/25/85       asdrcv now sends back stdout as well as stderr
                   2399: 01/29/86       ftw.c now closes directory before calling FTW_DP
                   2400: 05/29/86       numuid() and numgid() return real rather than
                   2401:                effective uid and gid on failure
                   2402: 07/04/86       adapted to UNIX PC
                   2403: 07/25/86       reworked system configuration stuff
                   2404: 09/06/86       removed duplicate free() in inspkg.c
                   2405: 09/11/86       arguments to struid() and strgid() should be unsigned
                   2406: 09/25/86       allow imbedded '.' and '-' in machine and user names
                   2407: 11/18/86       inspkg checks for error returns when closing files
                   2408: 01/20/89       more portable installation procedure
                   2409: 01/20/89       remove a special file before trying to install it
                   2410: lling FTW_DP
                   2411: 05/29/86       numuid() and numgid() return real rather than
                   2412:                effective uid and gid on failure
                   2413: 07/04/86       adapted to UNIX PC
                   2414: 07/25/86       reworked system configuration stuff
                   2415: 09/06/86       removed duplipkg/TODO   644   3513      4         276  5013610563   5342 Fix up the #include files so they aren't so redundantly included.
                   2416: 
                   2417: Make schk() and nchk() more informative.
                   2418: 
                   2419: Look into Sig_type.
                   2420: 
                   2421: Declare all the externs from "asd.h" in appropriate places.
                   2422: when closing files
                   2423: 01/20/89       more portable installation procedure
                   2424: 01/20/89       remove a special file before trying to install it
                   2425: lling FTW_DP
                   2426: 05/29/86       numuid() and numgid() return real rather than
                   2427:                effective uid and gid on failure
                   2428: 07/04/86       adapted to UNIX PC
                   2429: 07/25/86       reworked system configuration stuff
                   2430: 09/06/86       removed duplipkg/alloc.c   644   3513      4        1014  5013610563   6117 /*
                   2431:  *     storage allocator
                   2432:  *
                   2433:  *     calls malloc or realloc and aborts if unsuccessful
                   2434:  */
                   2435: 
                   2436: #include "asd.h"
                   2437: #include <stdio.h>
                   2438: #include <stdlib.h>
                   2439: #include <string.h>
                   2440: 
                   2441: void *
                   2442: alloc (size_t n)
                   2443: {
                   2444:        register void *p;
                   2445: 
                   2446:        p = malloc (n);
                   2447:        schk (p);
                   2448:        return p;
                   2449: }
                   2450: 
                   2451: void *
                   2452: ralloc (void *s, size_t n)
                   2453: {
                   2454:        register void *p;
                   2455: 
                   2456:        if (s == NULL)
                   2457:                return alloc (n);
                   2458:        
                   2459:        p = realloc (s, n);
                   2460:        schk (p);
                   2461:        return p;
                   2462: }
                   2463: 
                   2464: /* return a copy of a string */
                   2465: char *
                   2466: copy (char *s)
                   2467: {
                   2468:        register char *r;
                   2469:        r = alloc (strlen (s) + 1);
                   2470:        strcpy (r, s);
                   2471:        return r;
                   2472: }
                   2473: e allocator
                   2474:  *
                   2475:  *     calls malloc or realloc and aborts if unsuccessful
                   2476:  */
                   2477: 
                   2478: #include "asd.h"
                   2479: #include <stdio.h>
                   2480: #include <stdlib.h>
                   2481: #include <string.h>
                   2482: 
                   2483: void *
                   2484: alloc (size_t n)
                   2485: {
                   2486:        register void *p;
                   2487: 
                   2488:        p = malloc (n);
                   2489:        schk (p);
                   2490:        return p;
                   2491: }
                   2492: 
                   2493: void *
                   2494: ralloc (void *s, size_t n)
                   2495: {
                   2496:        register void *p;
                   2497: 
                   2498:        if (s == NULL)
                   2499:                return alloc (n);
                   2500:        
                   2501:        p = realloc (s, n);
                   2502:        schk (p);
                   2503:        return p;
                   2504: }
                   2505: 
                   2506: /* return a copy of a string */
                   2507: char *
                   2508: copy (char *s)
                   2509: {
                   2510:        register char *r;
                   2511:        r = alloc (strlen (s) + 1);
                   2512:        strcpy (r, s);
                   2513:        pkg/ar.h   644   3513      4         324  5013610563   5417 #define ARMAG   "!<arch>\n"
                   2514: #define        SARMAG  8
                   2515: 
                   2516: #define        ARFMAG  "`\n"
                   2517: 
                   2518: struct ar_hdr {
                   2519:        char    ar_name[16];
                   2520:        char    ar_date[12];
                   2521:        char    ar_uid[6];
                   2522:        char    ar_gid[6];
                   2523:        char    ar_mode[8];
                   2524:        char    ar_size[10];
                   2525:        char    ar_fmag[2];
                   2526: };
                   2527: = malloc (n);
                   2528:        schk (p);
                   2529:        return p;
                   2530: }
                   2531: 
                   2532: void *
                   2533: ralloc (void *s, size_t n)
                   2534: {
                   2535:        register void *p;
                   2536: 
                   2537:        if (s == NULL)
                   2538:                return alloc (n);
                   2539:        
                   2540:        p = realloc (s, n);
                   2541:        schk (p);
                   2542:        return p;
                   2543: }
                   2544: 
                   2545: /* return a copy of a string */
                   2546: char *
                   2547: copy (char *s)
                   2548: {
                   2549:        register char *r;
                   2550:        r = alloc (strlen (s) + 1);
                   2551:        strcpy (r, s);
                   2552:        pkg/args.c   644   3513      4        6462  5013610564   5776 #include "asd.h"
                   2553: #include <libv.h>
                   2554: #include <string.h>
                   2555: 
                   2556: int bflag;                     /* -b make a backup package */
                   2557: int kflag;                     /* -k crypto key (deprecated) */
                   2558: int Kflag;                     /* -K crypto key from file (deprecated) */
                   2559: int nflag;                     /* -n don't actually install files */
                   2560: int vflag;                     /* -v verbose output */
                   2561: char *xstr;                    /* -x command to execute */
                   2562: char *Xstr;                    /* -X file to execute */
                   2563: struct replist *replist;       /* -D substitutions */
                   2564: 
                   2565: int
                   2566: getargs (int argc, char **argv, char *optkey, int (*func)(FILE *, char *))
                   2567: {
                   2568:        register int c;
                   2569:        int rc = 0;
                   2570:        char *keyfile;
                   2571: 
                   2572:        while ((c = getopt (argc, argv, optkey)) != EOF) {
                   2573:                register struct replist *rl;
                   2574:                register char *p, *q;
                   2575: 
                   2576:                switch (c) {
                   2577: 
                   2578:                case 'b':
                   2579:                        bflag++;
                   2580:                        break;
                   2581: 
                   2582:                case 'k':
                   2583:                        kflag++;
                   2584:                        break;
                   2585: 
                   2586:                case 'n':
                   2587:                        nflag++;
                   2588:                        break;
                   2589:                
                   2590:                case 'v':
                   2591:                        vflag++;
                   2592:                        break;
                   2593: 
                   2594:                case 'x':
                   2595:                        if (xstr) {
                   2596:                                fprintf (stderr, "duplicate -x ignored\n");
                   2597:                                rc++;
                   2598:                        } else if (Xstr) {
                   2599:                                fprintf (stderr, "cannot have both -x and -X\n");
                   2600:                                rc++;
                   2601:                        } else
                   2602:                                xstr = optarg;
                   2603:                        break;
                   2604: 
                   2605:                case 'X':
                   2606:                        if (Xstr) {
                   2607:                                fprintf (stderr, "duplicate -X ignored\n");
                   2608:                                rc++;
                   2609:                        } else if (xstr) {
                   2610:                                fprintf (stderr, "cannot have both -x and -X\n");
                   2611:                                rc++;
                   2612:                        } else
                   2613:                                Xstr = copy (transname (optarg));
                   2614:                        break;
                   2615: 
                   2616:                case 'D':
                   2617:                        p = strchr (optarg, '=');
                   2618:                        if (p == NULL) {
                   2619:                                fprintf (stderr, "invalid option %s\n", optarg);
                   2620:                                exit (1);
                   2621:                        }
                   2622:                        rl = new (struct replist);
                   2623: 
                   2624:                        /* copy the pathname to rl->source */
                   2625:                        rl->source = alloc ((unsigned) (p - optarg + 1));
                   2626:                        p = rl->source;
                   2627:                        q = optarg;
                   2628:                        while (*q != '=')
                   2629:                                *p++ = *q++;
                   2630:                        *p = '\0';
                   2631: 
                   2632:                        /* now expand rl->source */
                   2633:                        p = rl->source;
                   2634:                        rl->source = copy (fullname (p));
                   2635:                        free (p);
                   2636: 
                   2637:                        /* expand rl->dest */
                   2638:                        rl->dest = copy (fullname (q + 1));
                   2639: 
                   2640:                        /* link rl into the chain */
                   2641:                        rl->link = replist;
                   2642:                        replist = rl;
                   2643:                        break;
                   2644: 
                   2645:                case 'K':
                   2646:                        Kflag++;
                   2647:                        keyfile = optarg;
                   2648:                        break;
                   2649: 
                   2650:                case '?':
                   2651:                default:
                   2652:                        rc++;
                   2653:                        break;
                   2654:                }
                   2655:        }
                   2656: 
                   2657:        if (rc) {
                   2658:                fprintf (stderr, "%s: bad argument\n", argv[0]);
                   2659:                exit (rc);
                   2660:        }
                   2661: 
                   2662:        if (kflag && Kflag) {
                   2663:                fprintf (stderr, "%s: cannot specify both k and K\n", argv[0]);
                   2664:                exit (1);
                   2665:        }
                   2666: 
                   2667:        /* read key from terminal if requested */
                   2668:        if (kflag) {
                   2669:                register char *p;
                   2670:                p = getpass ("Key:");
                   2671: 
                   2672:                /* a null key is treated as no key at all */
                   2673:                if (p && *p)
                   2674:                        setup (p);
                   2675:                else
                   2676:                        kflag = 0;
                   2677:        }
                   2678:        
                   2679:        /* read key from file if requested */
                   2680:        if (Kflag) {
                   2681:                char key[100];
                   2682:                register FILE *kf;
                   2683:                register char *p;
                   2684: 
                   2685:                /* try to open the file */
                   2686:                kf = fopen (keyfile, "r");
                   2687:                if (kf == NULL) {
                   2688:                        perror (keyfile);
                   2689:                        exit (1);
                   2690:                }
                   2691: 
                   2692:                /* read the first line */
                   2693:                p = fgets (key, sizeof (key), kf);
                   2694: 
                   2695:                fclose (kf);
                   2696: 
                   2697:                /* if EOF, assume no key */
                   2698:                if (p == NULL) {
                   2699:                        Kflag = 0;
                   2700:                } else {
                   2701: 
                   2702:                        /* delete the trailing newline */
                   2703:                        p = key;
                   2704:                        while (*p != '\n' && *p != '\0')
                   2705:                                p++;
                   2706:                        *p = '\0';
                   2707: 
                   2708:                        /* if the key is empty, assume no key */
                   2709:                        if (key[0] == '\0')
                   2710:                                Kflag = 0;
                   2711:                        else
                   2712:                                setup (key);
                   2713:                }
                   2714:        }
                   2715: 
                   2716:        if (func) {
                   2717:                /* process the arguments */
                   2718:                if (optind >= argc)
                   2719:                        rc = (*func) (stdin, "standard input");
                   2720:                else {
                   2721:                        register int i;
                   2722:                        for (i = optind; i < argc; i++) {
                   2723:                                register char *fn = argv[i];
                   2724:                                register FILE *f = fopen (fn, "r");
                   2725:                                if (f) {
                   2726:                                        rc += (*func) (f, argv[i]);
                   2727:                                        fclose (f);
                   2728:                                } else {
                   2729:                                        fprintf (stderr, "%s: can't open %s\n", argv[0], fn);
                   2730:                                        rc++;
                   2731:                                }
                   2732:                        }
                   2733:                }
                   2734:        }
                   2735: 
                   2736:        return rc;
                   2737: }
                   2738: ssume no key */
                   2739:                        if (key[0] == '\0')
                   2740:                                Kflag = 0;
                   2741:                        else
                   2742:                                setup (key);
                   2743:                }
                   2744:        }
                   2745: 
                   2746:        if (func) {
                   2747:                /* process the arguments */
                   2748:                if (optind >= argc)
                   2749:                        rc = (*func) (stdin, "standard input");
                   2750:                else {
                   2751:                pkg/asd.h   644   3513      4        4124  5014037413   5604 #include "ar.h"
                   2752: #include <stddef.h>
                   2753: #include <stdio.h>
                   2754: #include <stdlib.h>
                   2755: #include <sys/types.h>
                   2756: #include <sys/stat.h>
                   2757: #include <signal.h>
                   2758: #include <ctype.h>
                   2759: #include <errno.h>
                   2760: 
                   2761: #if 0
                   2762: /* system-dependent stuff */
                   2763: #ifdef unix
                   2764: #ifndef major
                   2765: #include <sys/sysmacros.h>
                   2766: #endif
                   2767: #endif
                   2768: #endif
                   2769: 
                   2770: /* longest archive component name we will generate */
                   2771: #define MAXCOMP 14
                   2772: 
                   2773: /* macro to allocate storage of a given type */
                   2774: #define new(t) ((t *) alloc (sizeof (t)))
                   2775: 
                   2776: /* some systems define SIG_TYP, others don't, so we make our own */
                   2777: #ifdef __STDC__
                   2778: typedef void (*Sig_typ)(int);
                   2779: #else
                   2780: typedef int    (*Sig_typ)();
                   2781: #endif
                   2782: 
                   2783: struct replist {
                   2784:        char *source;
                   2785:        char *dest;
                   2786:        struct replist *link;
                   2787: };
                   2788: 
                   2789: extern struct replist *replist;
                   2790: 
                   2791: /* structures to deal with archive headers */
                   2792: struct ar_hdr ar_hdr;
                   2793: struct hdr {
                   2794:        long size;
                   2795:        int mode;
                   2796:        long date;
                   2797: };
                   2798: extern struct hdr hdr;
                   2799: 
                   2800: /* alloc.c */
                   2801: extern void *alloc(size_t);
                   2802: extern void *ralloc(void *, size_t);
                   2803: extern char *copy(char *);
                   2804: 
                   2805: /* args.c */
                   2806: extern int bflag;
                   2807: extern int kflag;
                   2808: extern int Kflag;
                   2809: extern int nflag;
                   2810: extern int vflag;
                   2811: extern char *xstr;
                   2812: extern char *Xstr;
                   2813: extern int getargs(int, char **, char *, int (*)(FILE *, char *));
                   2814: 
                   2815: /* chk.c */
                   2816: extern void nchk(int);
                   2817: extern void schk(void *);
                   2818: 
                   2819: /* crypt.c */
                   2820: extern void resetN12(void);
                   2821: extern void setup(char *);
                   2822: extern void mangle(char *, char *);
                   2823: 
                   2824: /* data.c */
                   2825: extern char *hextab;
                   2826: extern char *instr;
                   2827: 
                   2828: /* fullname.c */
                   2829: extern char *fullname(char *);
                   2830: 
                   2831: /* gid.c */
                   2832: extern char *gidstr(gid_t);
                   2833: extern gid_t gidnum(char *);
                   2834: 
                   2835: /* header.c */
                   2836: extern long cvlong(char *, size_t, int);
                   2837: extern long read_header(char *, FILE *);
                   2838: extern void next_header(FILE *);
                   2839: extern char *getfield(FILE *);
                   2840: extern void geteol(FILE *);
                   2841: 
                   2842: /* mkdir.c */
                   2843: extern int mkd(char *);
                   2844: extern int rmdir(char *);
                   2845: extern int rmall(char *);
                   2846: 
                   2847: /* package.c */
                   2848: extern void pkgstart(void);
                   2849: extern void pkgfile(char *);
                   2850: extern int pkgend(void);
                   2851: 
                   2852: /* path.c */
                   2853: extern char *getpath(FILE *);
                   2854: extern void putpath(FILE *, char *);
                   2855: 
                   2856: /* pwd.c */
                   2857: extern char *pwd(void);
                   2858: 
                   2859: /* transname.c */
                   2860: extern char *transname(char *);
                   2861: 
                   2862: /* uid.c */
                   2863: extern char *uidstr(uid_t);
                   2864: extern uid_t uidnum(char *);
                   2865: id next_header(FILE *);
                   2866: extern char *getfield(FILE *);
                   2867: extern void geteol(FILE *);
                   2868: 
                   2869: /* mkdir.c */
                   2870: extern int mkd(char *);
                   2871: extern int rmdir(char *);
                   2872: extern int rmall(char *);
                   2873: 
                   2874: /* package.c */
                   2875: extern void pkgstart(void);
                   2876: extern void pkgfile(char *);
                   2877: extern int pkgend(void);
                   2878: 
                   2879: /* path.c */
                   2880: extern char *getpath(FILE *);
                   2881: extern void putpath(FILE *, char *);
                   2882: 
                   2883: /* pwd.c */
                   2884: extern char *pwd(void);
                   2885: 
                   2886: /* transname.c */
                   2887: extern char *transpkg/chk.c   644   3513      4         472  5013610565   5563 #include "asd.h"
                   2888: #include <stdio.h>
                   2889: 
                   2890: /*
                   2891:  *     little subroutines to check return codes
                   2892:  */
                   2893: 
                   2894: void
                   2895: nchk (int n)
                   2896: {
                   2897:        if (n < 0) {
                   2898:                fprintf (stderr, "unexpected error return -- help!\n");
                   2899:                exit (1);
                   2900:        }
                   2901: }
                   2902: 
                   2903: void
                   2904: schk (void *s)
                   2905: {
                   2906:        if (s == NULL) {
                   2907:                fprintf (stderr, "unexpected error return -- help!\n");
                   2908:                exit (1);
                   2909:        }
                   2910: }
                   2911:  pkgfile(char *);
                   2912: extern int pkgend(void);
                   2913: 
                   2914: /* path.c */
                   2915: extern char *getpath(FILE *);
                   2916: extern void putpath(FILE *, char *);
                   2917: 
                   2918: /* pwd.c */
                   2919: extern char *pwd(void);
                   2920: 
                   2921: /* transname.c */
                   2922: extern char *transpkg/crypt.c   644   3513      4        3604  5013610566   6200 /*
                   2923:  *     encryption service routines
                   2924:  */
                   2925: 
                   2926: #include "asd.h"
                   2927: #include <stdio.h>
                   2928: #include <stdlib.h>
                   2929: #include <string.h>
                   2930: #include <sys/types.h>
                   2931: #include <sys/wait.h>
                   2932: #include <unistd.h>
                   2933: 
                   2934: /* encryption parameters and tables */
                   2935: #define ROTORSZ 256
                   2936: #define MASK 0377
                   2937: static char    t1[ROTORSZ];
                   2938: static char    t2[ROTORSZ];
                   2939: static char    t3[ROTORSZ];
                   2940: static char    t4[ROTORSZ];
                   2941: 
                   2942: /* current rotor settings */
                   2943: static int N1, N2;
                   2944: 
                   2945: void
                   2946: resetN12(void)
                   2947: {
                   2948:        N1 = N2 = 0;
                   2949: }
                   2950: 
                   2951: void
                   2952: setup(char *pw)
                   2953: {
                   2954:        int ic, i, k, temp, pf[2];
                   2955:        unsigned random;
                   2956:        char buf[13];
                   2957:        long seed;
                   2958:        int pid;
                   2959: 
                   2960:        resetN12();
                   2961: 
                   2962:        strncpy(buf, pw, 8);
                   2963:        while (*pw)
                   2964:                *pw++ = '\0';
                   2965:        buf[8] = buf[0];
                   2966:        buf[9] = buf[1];
                   2967:        pipe(pf);
                   2968: 
                   2969:        switch (pid = fork()) {
                   2970: 
                   2971:        case -1:
                   2972:                fprintf (stderr, "seal: cannot fork\n");
                   2973:                exit (1);
                   2974: 
                   2975:        case 0:
                   2976:                close(0);
                   2977:                close(1);
                   2978:                dup(pf[0]);
                   2979:                dup(pf[1]);
                   2980:                execl("/usr/lib/makekey", "-", 0);
                   2981:                execl("/lib/makekey", "-", 0);
                   2982:                exit(1);
                   2983: 
                   2984:        default:
                   2985:                write(pf[1], buf, 10);
                   2986:                while (wait ((int *) NULL) != pid)
                   2987:                        ;
                   2988:        }
                   2989: 
                   2990:        if (read(pf[0], buf, 13) != 13) {
                   2991:                fprintf(stderr, "seal: cannot generate key\n");
                   2992:                exit(1);
                   2993:        }
                   2994:        seed = 123;
                   2995:        for (i=0; i<13; i++)
                   2996:                seed = seed*buf[i] + i;
                   2997:        for(i=0;i<ROTORSZ;i++)
                   2998:                t1[i] = i;
                   2999:        for(i=0;i<ROTORSZ;i++) {
                   3000:                seed = 5*seed + buf[i%13];
                   3001:                random = seed % 65521;
                   3002:                k = ROTORSZ-1 - i;
                   3003:                ic = (random&MASK)%(k+1);
                   3004:                random >>= 8;
                   3005:                temp = t1[k];
                   3006:                t1[k] = t1[ic];
                   3007:                t1[ic] = temp;
                   3008:                if(t3[k]!=0) continue;
                   3009:                ic = (random&MASK) % k;
                   3010:                while(t3[ic]!=0) ic = (ic+1) % k;
                   3011:                t3[k] = ic;
                   3012:                t3[ic] = k;
                   3013:        }
                   3014:        for(i=0;i<ROTORSZ;i++){
                   3015:                t2[t1[i]&MASK] = i;
                   3016:                t4[i] = (t1[i] + t3[i]) & 0377;
                   3017:        }
                   3018: }
                   3019: 
                   3020: void
                   3021: mangle (char *buf, char *limit)
                   3022: {
                   3023:        register int i;
                   3024:        register char *p;
                   3025:        register int n1 = N1, n2 = N2;
                   3026:        int n3;
                   3027: 
                   3028:        p = buf;
                   3029: 
                   3030:        while(p < limit) {
                   3031:                i = *p;
                   3032:                n3 = t4[n1];
                   3033:                i = t2[(t3[(t1[(i+n3)&MASK]+n2)&MASK]-n2)&MASK]-n3;
                   3034:                *p++ = i;
                   3035:                n1++;
                   3036:                if(n1==ROTORSZ) {
                   3037:                        n1 = 0;
                   3038:                        n2++;
                   3039:                        if(n2==ROTORSZ) n2 = 0;
                   3040:                }
                   3041:        }
                   3042:        N1 = n1;
                   3043:        N2 = n2;
                   3044: }
                   3045: dom&MASK) % k;
                   3046:                while(t3[ic]!=0) ic = (ic+1) % k;
                   3047:                t3[k] = ic;
                   3048:                t3[ic] = k;
                   3049:        }
                   3050:        for(i=0;i<ROTORSZ;i++){
                   3051:                t2[t1[i]&MASK] pkg/data.c   644   3513      4         156  5013610566   5727 /*
                   3052:  *     Initializations
                   3053:  */
                   3054: 
                   3055: #include "asd.h"
                   3056: 
                   3057: char *hextab = "0123456789abcdef";
                   3058: char *instr = "Instructions";
                   3059:  char *p;
                   3060:        register int n1 = N1, n2 = N2;
                   3061:        int n3;
                   3062: 
                   3063:        p = buf;
                   3064: 
                   3065:        while(p < limit) {
                   3066:                i = *p;
                   3067:                n3 = t4[n1];
                   3068:                i = t2[(t3[(t1[(i+n3)&MASK]+n2)&MASK]-n2)&MASK]-n3;
                   3069:                *p++ = i;
                   3070:                n1++;
                   3071:                if(n1==ROTORSZ) {
                   3072:                        n1 = 0;
                   3073:                        n2++;
                   3074:                        if(n2==ROTORSZ) n2 = 0;
                   3075:                }
                   3076:        }
                   3077:        N1 = n1;
                   3078:        N2 = n2;
                   3079: }
                   3080: dom&MASK) % k;
                   3081:                while(t3[ic]!=0) ic = (ic+1) % k;
                   3082:                t3[k] = ic;
                   3083:                t3[ic] = k;
                   3084:        }
                   3085:        for(i=0;i<ROTORSZ;i++){
                   3086:                t2[t1[i]&MASK] pkg/fullname.c   644   3513      4        1461  5013610567   6642 /*
                   3087:  *     fullname -- return the full pathname corresponding to the
                   3088:  *     abbreviated pathname given as argument.  Returned value
                   3089:  *     is in a buffer that will stay around no longer than its
                   3090:  *     argument or the next call to fullname, whichever is earlier.
                   3091:  */
                   3092: 
                   3093: #include "asd.h"
                   3094: #include <string.h>
                   3095: 
                   3096: char *
                   3097: fullname (char *s)
                   3098: {
                   3099:        register char *t;
                   3100:        static char *r;
                   3101:        static int size;
                   3102:        register unsigned n;
                   3103: 
                   3104:        /* if first char is slash, absolute path */
                   3105:        if (s[0] == '/')
                   3106:                return s;
                   3107:        
                   3108:        /* strip leading './' */
                   3109:        while (s[0] == '.' && s[1] == '/')
                   3110:                s += 2;
                   3111:        
                   3112:        t = pwd();
                   3113: 
                   3114:        /* null string or "." means current directory */
                   3115:        if (s[0] == '\0' || strcmp (s, ".") == 0)
                   3116:                return t;
                   3117:        
                   3118:        n = strlen (s) + strlen (t) + 2;
                   3119:        if (n > size) {
                   3120:                r = ralloc (r, n);
                   3121:                size = n;
                   3122:        }
                   3123: 
                   3124:        strcpy (r, t);
                   3125:        strcat (r, "/");
                   3126:        strcat (r, s);
                   3127: 
                   3128:        return r;
                   3129: }
                   3130: (char *s)
                   3131: {
                   3132:        register char *t;
                   3133:        static char *r;
                   3134:        static int size;
                   3135:        register unsigned n;
                   3136: 
                   3137:        /* if first char is slash, absolute path */
                   3138:        if (s[0] == '/')
                   3139:                return s;
                   3140:        
                   3141:        /* strip leading './' */
                   3142:        while (s[0] ==pkg/gid.c   644   3513      4        2533  5013610570   5575 #include "asd.h"
                   3143: #include <grp.h>
                   3144: #include <stdio.h>
                   3145: #include <stdlib.h>
                   3146: #include <string.h>
                   3147: #include <unistd.h>
                   3148: 
                   3149: #define CHUNK 16
                   3150: 
                   3151: static struct gtab {
                   3152:        unsigned gid;
                   3153:        char *name;
                   3154: } *gtab;
                   3155: 
                   3156: static int size, salloc;
                   3157: 
                   3158: char *
                   3159: gidstr (gid_t gid)
                   3160: {
                   3161:        register int i;
                   3162:        static char buf[12];
                   3163:        struct group *g;
                   3164: 
                   3165:        /* search the cache for the gid */
                   3166:        for (i = 0; i < size; i++)
                   3167:                if (gtab[i].gid == gid)
                   3168:                        return gtab[i].name;
                   3169: 
                   3170:        /* try to find it in the system's database */
                   3171:        if (g = getgrgid(gid)) {
                   3172:                if (size % CHUNK == 0)
                   3173:                        gtab = (struct gtab *) ralloc((char *) gtab, salloc += CHUNK);
                   3174:                gtab[size].gid = g->gr_gid;
                   3175:                gtab[size].name = copy(g->gr_name);
                   3176:                ++size;
                   3177:                return gtab[size - 1].name;
                   3178:        }
                   3179: 
                   3180:        /* failure, invent a string */
                   3181:        sprintf (buf, "#%u", gid);
                   3182:        return buf;
                   3183: }
                   3184: 
                   3185: gid_t
                   3186: gidnum (char *name)
                   3187: {
                   3188:        register int i;
                   3189:        struct group *g;
                   3190: 
                   3191:        /* if it starts with a #, use the number */
                   3192:        if (name[0] == '#')
                   3193:                return atoi (name + 1);
                   3194: 
                   3195:        /* search the cache */
                   3196:        for (i = 0; i < size; i++)
                   3197:                if (strcmp (gtab[i].name, name) == 0)
                   3198:                        return gtab[i].gid;
                   3199: 
                   3200:        /* try to find it in the system's database */
                   3201:        if (g = getgrnam(name)) {
                   3202:                if (size % CHUNK == 0)
                   3203:                        gtab = (struct gtab *) ralloc((char *) gtab, salloc += CHUNK);
                   3204:                gtab[size].gid = g->gr_gid;
                   3205:                gtab[size].name = copy(g->gr_name);
                   3206:                ++size;
                   3207:                return gtab[size - 1].gid;
                   3208:        }
                   3209: 
                   3210: 
                   3211:        /* failure, invent a value */
                   3212:        return getgid();
                   3213: }
                   3214: , use the number */
                   3215:        if (name[0] == '#')
                   3216:                return atoi (name + 1);
                   3217: 
                   3218:        /* search the cache */
                   3219:        for (i = 0; i < size; i++)
                   3220:                if (strcmp (gtab[i].name, name) == 0)
                   3221:                        repkg/header.c   644   3513      4        4144  5013610570   6262 /*
                   3222:  *     various subroutines to deal with archive headers
                   3223:  */
                   3224: 
                   3225: #include "asd.h"
                   3226: #include <ctype.h>
                   3227: #include <stdio.h>
                   3228: #include <string.h>
                   3229: 
                   3230: struct hdr hdr;
                   3231: 
                   3232: /*
                   3233:  *     convert p to a long value.  maximum input length is len,
                   3234:  *     input is to be interpreted in base b.  No negative values.
                   3235:  */
                   3236: long
                   3237: cvlong (char *p, size_t len, int base)
                   3238: {
                   3239:        register int i;
                   3240:        register long r;
                   3241: 
                   3242:        r = 0;
                   3243:        i = len;
                   3244: 
                   3245:        do {
                   3246:                register int c = *p++;
                   3247:                if (isdigit (c))
                   3248:                        r = r * base + c - '0';
                   3249:        } while (--i > 0);
                   3250: 
                   3251:        return r;
                   3252: }
                   3253: 
                   3254: long
                   3255: read_header (char *name, FILE *file)
                   3256: {
                   3257:        register int n;
                   3258:        register int i;
                   3259:        register char *p, *q;
                   3260: 
                   3261:        n = fread ((char *) &ar_hdr, sizeof (ar_hdr), 1, file);
                   3262:        if (n != 1) {
                   3263:                fprintf (stderr, "can't read %s\n", name);
                   3264:                exit (1);
                   3265:        }
                   3266: 
                   3267:        if (strncmp (ar_hdr.ar_fmag, ARFMAG, sizeof (ar_hdr.ar_fmag)) != 0) {
                   3268:                fprintf (stderr, "input phase error on %s\n", name);
                   3269:                exit (1);
                   3270:        }
                   3271: 
                   3272:        /* check the component name, allowing for trailing blanks */
                   3273:        p = name;
                   3274:        q = ar_hdr.ar_name;
                   3275:        for (i = 0; i < sizeof (ar_hdr.ar_name); i++) {
                   3276:                if (*q++ != (*p? *p++: ' ')) {
                   3277:                        fprintf (stderr, "expected %s, got %.*s\n",
                   3278:                            name, sizeof (ar_hdr.ar_name), ar_hdr.ar_name);
                   3279:                }
                   3280:        }
                   3281: 
                   3282:        /* crack the archive header and put the information in "hdr" */
                   3283:        hdr.size = cvlong (ar_hdr.ar_size, sizeof (ar_hdr.ar_size), 10);
                   3284:        hdr.mode = cvlong (ar_hdr.ar_mode, sizeof (ar_hdr.ar_mode), 8);
                   3285:        hdr.date = cvlong (ar_hdr.ar_date, sizeof (ar_hdr.ar_date), 10);
                   3286: 
                   3287:        return hdr.size;
                   3288: }
                   3289: 
                   3290: /* advance to the start of the next archive header */
                   3291: void
                   3292: next_header(FILE *f)
                   3293: {
                   3294:        if (hdr.size & 1)
                   3295:                getc(f);
                   3296: }
                   3297: 
                   3298: /* skip leading white space, return a field */
                   3299: char *
                   3300: getfield (FILE *f)
                   3301: {
                   3302:        register char c;
                   3303: 
                   3304:        /* skip leading white space */
                   3305:        do c = getc (f);
                   3306:        while (isspace (c) && c != '\n');
                   3307: 
                   3308:        /* if we hit a newline, something's wrong */
                   3309:        if (c == '\n') {
                   3310:                fprintf (stderr, "unexpected newline\n");
                   3311:                exit (1);
                   3312:        }
                   3313: 
                   3314:        /* return the nonblank, read a "pathname" and return it */
                   3315:        ungetc (c, f);
                   3316:        return getpath (f);
                   3317: }
                   3318: 
                   3319: /* insist on an end of line right here */
                   3320: void
                   3321: geteol (FILE *f)
                   3322: {
                   3323:        register int c;
                   3324: 
                   3325:        c = getc (f);
                   3326:        if (c != '\n') {
                   3327:                fprintf (stderr, "expected newline, got %c\n", c);
                   3328:                exit (1);
                   3329:        }
                   3330: }
                   3331: ister char c;
                   3332: 
                   3333:        /* skip leading white space */
                   3334:        do c = getc (f);
                   3335:        while (isspace (c) && c != '\n');
                   3336: 
                   3337:        /* if we hit a newline, something's wrong */
                   3338:        if (c == '\n') {
                   3339:                fprintf (stderr, "unexpected newline\n");
                   3340:                exit (1);
                   3341:        }
                   3342: 
                   3343:        /* return the nonblank, read a "pathname" and return it */
                   3344:        ungetc (c, f);
                   3345:        return getpath (f);
                   3346: }
                   3347: 
                   3348: /* insist on an end of line right here */
                   3349: void
                   3350: geteol (FILE *f)
                   3351: {
                   3352:        register int c;
                   3353: 
                   3354:        c pkg/inspkg.c   644   3513      4       25371  5013610572   6354 #include "asd.h"
                   3355: #include <libv.h>
                   3356: #include <string.h>
                   3357: #include <sys/types.h>
                   3358: #include <sys/wait.h>
                   3359: #include <unistd.h>
                   3360: #include <utime.h>
                   3361: 
                   3362: #define CHUNK 64
                   3363: 
                   3364: /* type codes for installation subroutine */
                   3365: #define BACKUP 0
                   3366: #define INSTALL 1
                   3367: 
                   3368: static void readtemp(int, FILE *);
                   3369: 
                   3370: /*
                   3371:  *     The following declarations and functions manipulate
                   3372:  *     a list of directory names.  This list is used to decide
                   3373:  *     which files should be backed up and which have already been.
                   3374:  */
                   3375: 
                   3376: struct list {
                   3377:        char *name;
                   3378:        struct list *next;
                   3379: };
                   3380: 
                   3381: static struct list *dirs;
                   3382: 
                   3383: /* is the name given a subdirectory of the name on the list? */
                   3384: static int
                   3385: subsumed (char *name)
                   3386: {
                   3387:        register struct list *item;
                   3388:        register char *p, *q;
                   3389: 
                   3390:        for (item = dirs; item; item = item->next) {
                   3391:                p = item->name;
                   3392:                q = name;
                   3393:                while (*p && *p == *q)
                   3394:                        p++, q++;
                   3395:                if (*p == '\0' && (*q == '/' || *q == '\0'))
                   3396:                        return 1;
                   3397:        }
                   3398: 
                   3399:        return 0;
                   3400: }
                   3401: 
                   3402: /* add the name given to the list */
                   3403: static void
                   3404: addlist (char *name)
                   3405: {
                   3406:        register struct list *l;
                   3407: 
                   3408:        l = new (struct list);
                   3409:        l->next = dirs;
                   3410:        l->name = copy (name);
                   3411:        dirs = l;
                   3412: }
                   3413: 
                   3414: /* clear the entire list */
                   3415: static void
                   3416: clearlist(void)
                   3417: {
                   3418:        register struct list *l;
                   3419: 
                   3420:        while (l = dirs) {
                   3421:                dirs = l->next;
                   3422:                free (l->name);
                   3423:                free ((char *) l);
                   3424:        }
                   3425: }
                   3426: 
                   3427: static char tfname[L_tmpnam];
                   3428: static void delete(int);
                   3429: 
                   3430: /* process a single archive in a concatenation */
                   3431: static int
                   3432: doarch (FILE *file)
                   3433: {
                   3434:        register FILE *tf;
                   3435:        Sig_typ sigsav;
                   3436:        register long size;
                   3437:        register int c;
                   3438:        char armag[SARMAG];
                   3439: 
                   3440:        /* Make sure the file is an archive */
                   3441:        if (fread (armag, sizeof (*armag), SARMAG, file) != SARMAG) {
                   3442:                fprintf (stderr, "inspkg: unexpected EOF\n");
                   3443:                exit (1);
                   3444:        }
                   3445:        if (strncmp (armag, ARMAG, SARMAG) != 0) {
                   3446:                fprintf (stderr, "inspkg: input not a package\n");
                   3447:                exit (1);
                   3448:        }
                   3449: 
                   3450:        /* establish a temporary file */
                   3451:        (void) tmpnam (tfname);
                   3452:        tf = fopen (tfname, "w");
                   3453:        sigsav = signal (SIGINT, SIG_IGN);
                   3454:        if (sigsav != SIG_IGN)
                   3455:                signal (SIGINT, delete);
                   3456:        chmod (tfname, 0600);
                   3457: 
                   3458:        /* copy the installation instructions to the temp file */
                   3459:        size = read_header (instr, file);
                   3460:        while (--size >= 0) {
                   3461:                c = getc (file);
                   3462:                if (c == EOF) {
                   3463:                        fprintf (stderr, "inspkg: premature EOF\n");
                   3464:                        exit (1);
                   3465:                }
                   3466:                if (putc (c, tf) == EOF) {
                   3467:                        perror ("inspkg: Instructions");
                   3468:                        exit (1);
                   3469:                }
                   3470:        }
                   3471:        if (fclose (tf) == EOF) {
                   3472:                perror ("inspkg: Instructions fclose");
                   3473:                exit (1);
                   3474:        }
                   3475: 
                   3476:        next_header (file);
                   3477: 
                   3478:        /* create the optional backup package */
                   3479:        if (bflag) {
                   3480:                pkgstart();
                   3481:                readtemp (BACKUP, file);
                   3482:                pkgend();
                   3483:                clearlist();
                   3484:        }
                   3485: 
                   3486:        /* do the actual work */
                   3487:        readtemp (INSTALL, file);
                   3488: 
                   3489:        /* delete the temporary file */
                   3490:        nchk (unlink (tfname));
                   3491:        signal (SIGINT, sigsav);
                   3492: 
                   3493:        return 0;
                   3494: }
                   3495: 
                   3496: /*
                   3497:  *     install the given file
                   3498:  */
                   3499: static int
                   3500: process (FILE *file, char *fname)
                   3501: {
                   3502:        register int c, rc = 0;
                   3503: 
                   3504:        if (vflag)
                   3505:                fprintf (stderr, "%s:\n", fname);
                   3506: 
                   3507:        while ((c = getc (file)) != EOF) {
                   3508:                ungetc (c, file);
                   3509:                rc += doarch (file);
                   3510:        }
                   3511: 
                   3512:        return rc;
                   3513: }
                   3514: 
                   3515: int
                   3516: main (int argc, char **argv)
                   3517: {
                   3518:        static char errbuf[BUFSIZ];
                   3519: 
                   3520:        setbuf (stderr, errbuf);
                   3521:        umask (0);
                   3522:        return getargs (argc, argv, "nvbD:", process);
                   3523: }
                   3524: 
                   3525: /*
                   3526:  *     Make a pass through the temp file.
                   3527:  */
                   3528: static void
                   3529: readtemp (int code, FILE *file)
                   3530: {
                   3531:        register FILE *tf;
                   3532:        register int c;
                   3533: 
                   3534:        /* we're done writing the temp file, time to read it */
                   3535:        tf = fopen (tfname, "r");
                   3536:        schk ((char *) tf);
                   3537: 
                   3538:        /*
                   3539:         *      The main loop -- one iteration per line
                   3540:         *      We are careful in use and reuse of storage here;
                   3541:         *      if you change this code make sure you understand
                   3542:         *      the times at which getfield and transname
                   3543:         *      recycle storage or strange things will happen.
                   3544:         */
                   3545:        while ((c = getc (tf)) != EOF) {
                   3546:                char *param, *path, *path2;
                   3547:                register FILE *outfd;
                   3548:                int uid, gid, mode, dmajor, dminor, dev;
                   3549:                register long size;
                   3550:                char component[MAXCOMP+1];
                   3551: 
                   3552:                switch (c) {
                   3553: 
                   3554: #if 0
                   3555:                /* special files */
                   3556:                case 'b':
                   3557:                case 'c':
                   3558:                        /* read the parameters */
                   3559:                        param = getfield (tf);
                   3560:                        mode = cvlong (param, strlen (param), 8) |
                   3561:                            (c == 'c'? S_IFCHR: S_IFBLK);
                   3562:                        param = getfield (tf);
                   3563:                        dmajor = cvlong (param, strlen (param), 10);
                   3564:                        param = getfield (tf);
                   3565:                        dminor = cvlong (param, strlen (param), 10);
                   3566:                        dev = makedev (dmajor, dminor);
                   3567:                        uid = uidnum (getfield (tf));
                   3568:                        gid = gidnum (getfield (tf));
                   3569:                        path = transname (getfield (tf));
                   3570:                        geteol (tf);
                   3571: 
                   3572:                        switch (code) {
                   3573: 
                   3574:                        case BACKUP:
                   3575:                                if (!subsumed (path)) {
                   3576:                                        pkgfile (path);
                   3577:                                        addlist (path);
                   3578:                                }
                   3579:                                break;
                   3580: 
                   3581:                        case INSTALL:
                   3582:                                if (vflag) {
                   3583:                                        fprintf (stderr, "special file ");
                   3584:                                        putpath (stderr, path);
                   3585:                                        fprintf (stderr, "\n");
                   3586:                                }
                   3587: 
                   3588:                                if (!nflag) {
                   3589:                                        rmall (path);
                   3590:                                        if (mknod (path, mode, dev) >= 0)
                   3591:                                                chown (path, uid, gid);
                   3592:                                        else
                   3593:                                                perror (path);
                   3594:                                }
                   3595:                                break;
                   3596:                        }
                   3597:                        break;
                   3598: #endif
                   3599: 
                   3600:                /* directory */
                   3601:                case 'd':
                   3602:                        /* read the parameters */
                   3603:                        param = getfield (tf);
                   3604:                        mode = cvlong (param, strlen (param), 8);
                   3605:                        uid = uidnum (getfield (tf));
                   3606:                        gid = gidnum (getfield (tf));
                   3607:                        path = transname (getfield (tf));
                   3608:                        geteol (tf);
                   3609: 
                   3610:                        switch (code) {
                   3611: 
                   3612:                        case BACKUP:
                   3613:                                if (!subsumed (path)) {
                   3614:                                        pkgfile (path);
                   3615:                                        addlist (path);
                   3616:                                }
                   3617:                                break;
                   3618: 
                   3619:                        case INSTALL:
                   3620:                                /* make the directory */
                   3621:                                if (vflag) {
                   3622:                                        fprintf (stderr, "directory ");
                   3623:                                        putpath (stderr, path);
                   3624:                                        putc ('\n', stderr);
                   3625:                                }
                   3626:                                if (!nflag) {
                   3627:                                        rmall (path);
                   3628:                                        mkd (path);
                   3629:                                        chmod (path, mode);
                   3630:                                        chown (path, uid, gid);
                   3631:                                        chmod (path, mode);
                   3632:                                }
                   3633:                                break;
                   3634:                        }
                   3635: 
                   3636:                        break;
                   3637: 
                   3638:                /* file */
                   3639:                case 'f':
                   3640:                        /* read parameters */
                   3641:                        param = getfield (tf);
                   3642:                        if (strlen (param) > MAXCOMP) {
                   3643:                                fprintf (stderr,
                   3644:                                    "inspkg: impossibly long component name\n");
                   3645:                                delete(0);
                   3646:                                exit (1);
                   3647:                        }
                   3648:                        strcpy (component, param);
                   3649:                        uid = uidnum (getfield (tf));
                   3650:                        gid = gidnum (getfield (tf));
                   3651:                        path = transname (getfield (tf));
                   3652:                        geteol (tf);
                   3653: 
                   3654:                        switch (code) {
                   3655: 
                   3656:                        case BACKUP:
                   3657:                                if (!subsumed (path))
                   3658:                                        pkgfile (path);
                   3659:                                break;
                   3660: 
                   3661:                        case INSTALL:
                   3662:                                /* read the corresponding archive header */
                   3663:                                size = read_header (component, file);
                   3664: 
                   3665:                                if (vflag) {
                   3666:                                        fprintf (stderr, "file ");
                   3667:                                        putpath (stderr, path);
                   3668:                                        putc ('\n', stderr);
                   3669:                                }
                   3670: 
                   3671:                                /* create and open the file */
                   3672:                                if (!nflag) {
                   3673:                                        rmall (path);
                   3674:                                        umask (077);
                   3675:                                        outfd = fopen (path, "w");
                   3676:                                        umask (0);
                   3677:                                        if (outfd == NULL) {
                   3678:                                                fprintf (stderr,
                   3679:                                                    "inspkg: cannot create ");
                   3680:                                                putpath (stderr, path);
                   3681:                                                putc ('\n', stderr);
                   3682:                                        }
                   3683:                                }
                   3684:                                if (nflag || outfd == NULL) {
                   3685:                                        outfd = fopen ("/dev/null", "w");
                   3686:                                        schk ((char *) outfd);
                   3687:                                }
                   3688: 
                   3689:                                /* copy the file, advance input */
                   3690:                                while (--size >= 0)
                   3691:                                        putc (getc (file), outfd);
                   3692:                                next_header (file);
                   3693: 
                   3694:                                /* check successful completion, close output */
                   3695:                                fflush (outfd);
                   3696:                                if (feof (file) || ferror (file) ||
                   3697:                                    ferror (outfd)) {
                   3698:                                        fprintf (stderr, "inspkg: can't write ");
                   3699:                                        putpath (stderr, path);
                   3700:                                        putc ('\n', stderr);
                   3701:                                }
                   3702:                                if (fclose (outfd) == EOF) {
                   3703:                                        fprintf (stderr, "inspkg: can't close ");
                   3704:                                        putpath (stderr, path);
                   3705:                                        fprintf (stderr, ": ");
                   3706:                                        perror ("");
                   3707:                                }
                   3708:                                
                   3709:                                /*
                   3710:                                 *      Update output modification times
                   3711:                                 *      and change mode and owner.
                   3712:                                 *      This is done here to cater to systems
                   3713:                                 *      that allow people to give files away.
                   3714:                                 *      The chmod is done twice because
                   3715:                                 *      systems that let you give files away
                   3716:                                 *      won't let you change the mode after
                   3717:                                 *      you've done so, and some other systems
                   3718:                                 *      turn off the setuid bit as a side
                   3719:                                 *      effect of chown, so the second chmod
                   3720:                                 *      will restore that bit.
                   3721:                                 */
                   3722:                                if (!nflag) {
                   3723:                                        struct utimbuf utb;
                   3724:                                        utb.actime = utb.modtime = hdr.date;
                   3725:                                        utime (path, &utb);
                   3726:                                        chmod (path, hdr.mode & 07777);
                   3727:                                        chown (path, uid, gid);
                   3728:                                        chmod (path, hdr.mode & 07777);
                   3729:                                }
                   3730: 
                   3731:                                break;
                   3732:                        }
                   3733:                        break;
                   3734: 
                   3735:                /* symbolic link */
                   3736:                case 's':
                   3737:                        /* read parameters */
                   3738:                        path = copy (transname (getfield (tf)));
                   3739:                        path2 = transname (getfield (tf));
                   3740:                        geteol (tf);
                   3741: 
                   3742:                        switch (code) {
                   3743:                        case BACKUP:
                   3744:                                if (!subsumed (path2))
                   3745:                                        pkgfile (path2);
                   3746:                                break;
                   3747: 
                   3748:                        case INSTALL:
                   3749:                                /* log it if requested */
                   3750:                                if (vflag) {
                   3751:                                        fprintf (stderr, "symlink ");
                   3752:                                        putpath (stderr, path2);
                   3753:                                        fprintf (stderr, " to ");
                   3754:                                        putpath (stderr, path);
                   3755:                                        putc ('\n', stderr);
                   3756:                                }
                   3757: #ifdef S_ISLNK
                   3758: 
                   3759:                                /* make the link */
                   3760:                                if (!nflag) {
                   3761:                                        rmall (path2);
                   3762:                                        if (symlink (path, path2) < 0)
                   3763:                                                perror (path2);
                   3764:                                }
                   3765: #else
                   3766:                                fprintf(stderr, "This system does not support symbolic links\n");
                   3767: #endif
                   3768: 
                   3769:                                break;
                   3770:                        }
                   3771:                        free (path);
                   3772:                        break;
                   3773:                
                   3774:                /* link */
                   3775:                case 'l':
                   3776:                        /* read parameters */
                   3777:                        path = copy (transname (getfield (tf)));
                   3778:                        path2 = transname (getfield (tf));
                   3779:                        geteol (tf);
                   3780: 
                   3781:                        switch (code) {
                   3782: 
                   3783:                        case BACKUP:
                   3784:                                if (!subsumed (path2))
                   3785:                                        pkgfile (path2);
                   3786:                                break;
                   3787: 
                   3788:                        case INSTALL:
                   3789:                                /* log it if requested */
                   3790:                                if (vflag) {
                   3791:                                        fprintf (stderr, "link ");
                   3792:                                        putpath (stderr, path);
                   3793:                                        fprintf (stderr, " to ");
                   3794:                                        putpath (stderr, path2);
                   3795:                                        putc ('\n', stderr);
                   3796:                                }
                   3797: 
                   3798:                                /* make the link */
                   3799:                                if (!nflag) {
                   3800:                                        struct stat sb, sb2;
                   3801: 
                   3802:                                        /* are we about to link x to x? */
                   3803:                                        if (stat (path, &sb) < 0
                   3804:                                            || stat (path2, &sb2) < 0
                   3805:                                            || sb.st_dev != sb2.st_dev
                   3806:                                            || sb.st_ino != sb2.st_ino) {
                   3807:                                                rmall (path2);
                   3808:                                                if (link (path, path2) < 0)
                   3809:                                                        perror (path2);
                   3810:                                        }
                   3811:                                }
                   3812: 
                   3813:                                break;
                   3814:                        }
                   3815:                        free (path);
                   3816:                        break;
                   3817:                
                   3818:                /* remove */
                   3819:                case 'r':
                   3820:                        /* get parameters */
                   3821:                        path = transname (getfield (tf));
                   3822:                        geteol (tf);
                   3823: 
                   3824:                        switch (code) {
                   3825: 
                   3826:                        case BACKUP:
                   3827:                                if (!subsumed (path))
                   3828:                                        pkgfile (path);
                   3829:                                break;
                   3830: 
                   3831:                        case INSTALL:
                   3832:                                if (vflag) {
                   3833:                                        fprintf (stderr, "remove file ");
                   3834:                                        putpath (stderr, path);
                   3835:                                        putc ('\n', stderr);
                   3836:                                }
                   3837:                                if (!nflag)
                   3838:                                        rmall (path);
                   3839:                                break;
                   3840:                        }
                   3841: 
                   3842:                        break;
                   3843: 
                   3844:                case 'x':
                   3845:                        xstr = getfield (tf);
                   3846:                        geteol (tf);
                   3847:                        if (code == INSTALL) {
                   3848:                                if (vflag) {
                   3849:                                        fprintf (stderr, "execute: ");
                   3850:                                        putpath (stderr, xstr);
                   3851:                                        fprintf (stderr, "\n");
                   3852:                                }
                   3853:                                if (!nflag) {
                   3854:                                        fflush (stderr);
                   3855:                                        system (xstr);
                   3856:                                }
                   3857:                        }
                   3858:                        xstr = NULL;
                   3859:                        break;
                   3860: 
                   3861:                case 'X':
                   3862:                        Xstr = transname (getfield (tf));
                   3863:                        geteol (tf);
                   3864:                        if (code == INSTALL) {
                   3865:                                if (vflag) {
                   3866:                                        fprintf (stderr, "exec file: ");
                   3867:                                        putpath (stderr, Xstr);
                   3868:                                        fprintf (stderr, "\n");
                   3869:                                }
                   3870:                                if (!nflag) {
                   3871:                                        int status, pid, w;
                   3872:                                        Sig_typ istat, qstat;
                   3873: 
                   3874:                                        fflush (stderr);
                   3875:                                        if ((pid = fork()) == 0) {
                   3876:                                                execl (Xstr, Xstr, (char *)0);
                   3877:                                                execl ("/bin/sh", "sh", Xstr, (char *) 0);
                   3878:                                                putpath (stderr, Xstr);
                   3879:                                                fprintf (stderr, ": ");
                   3880:                                                fflush (stderr);
                   3881:                                                perror ("");
                   3882:                                                _exit(127);
                   3883:                                        }
                   3884:                                        istat = signal (SIGINT, SIG_IGN);
                   3885:                                        qstat = signal (SIGQUIT, SIG_IGN);
                   3886:                                        while ((w=wait(&status)) != pid && w != -1)
                   3887:                                                ;
                   3888:                                        signal(SIGINT, istat);
                   3889:                                        signal(SIGQUIT, qstat);
                   3890:                                }
                   3891:                        }
                   3892:                        Xstr = NULL;
                   3893:                        break;
                   3894: 
                   3895:                default:
                   3896:                        fprintf (stderr, "inspkg: invalid package\n");
                   3897:                        delete(0);
                   3898:                        exit (1);
                   3899:                }
                   3900:        }
                   3901: 
                   3902:        if (ferror (tf))
                   3903:                perror ("inspkg: internal temp file");
                   3904: 
                   3905:        fclose (tf);
                   3906: 
                   3907: }
                   3908: 
                   3909: static void
                   3910: delete(int sigarg)
                   3911: {
                   3912:        unlink (tfname);
                   3913:        exit (3);
                   3914: }
                   3915:                                        perror ("");
                   3916:                                                _exit(127);
                   3917:                                        }
                   3918:                                        istat = signal (SIGINT, SIG_IGN);
                   3919:                                        qstat = signal (SIGQUIT, SIG_IGN);
                   3920:                                        while ((w=wait(&status)) != pid && w != -1)
                   3921:                                                ;
                   3922:                                        signal(SIGINT, istat);
                   3923:                                        signal(SIGQUIT, qstat);
                   3924:                                }
                   3925:                        }
                   3926:                        Xstr = NULL;
                   3927: pkg/mkcsum.c   644   3513      4         436  5013610572   6313 #include "seal.h"
                   3928: 
                   3929: unsigned long
                   3930: mkcsum (unsigned long csum, char *start, char *limit)
                   3931: {
                   3932:        register int c;
                   3933: 
                   3934:        while (start < limit) {
                   3935:                c = (unsigned char) *start++;
                   3936:                if (csum & 1)
                   3937:                        csum = (csum >> 1) | CSHIBIT;
                   3938:                else
                   3939: 
                   3940:                        csum >>= 1;
                   3941:                csum += c;
                   3942:                csum &= CSMASK;
                   3943:        }
                   3944:        return csum;
                   3945: }
                   3946:                                }
                   3947:                                        istat = signal (SIGINT, SIG_IGN);
                   3948:                                        qstat = signal (SIGQUIT, SIG_IGN);
                   3949:                                        while ((w=wait(&status)) != pid && w != -1)
                   3950:                                                ;
                   3951:                                        signal(SIGINT, istat);
                   3952:                                        signal(SIGQUIT, qstat);
                   3953:                                }
                   3954:                        }
                   3955:                        Xstr = NULL;
                   3956: pkg/mkdir.c   644   3513      4        4363  5031450263   6144 #include "asd.h"
                   3957: #include <sys/wait.h>
                   3958: #include <unistd.h>
                   3959: #include "ftw.h"
                   3960: 
                   3961: #ifndef S_ISLNK
                   3962: #ifdef S_IFLNK
                   3963: #define S_ISLNK(M) (((M)&S_IFMT) == S_IFLNK)
                   3964: #endif
                   3965: #define S_ISREG(M) (((M)&S_IFMT) == S_IFREG)
                   3966: #define S_ISDIR(M) (((M)&S_IFMT) == S_IFDIR)
                   3967: #define S_ISCHR(M) (((M)&S_IFMT) == S_IFCHR)
                   3968: #define S_ISBLK(M) (((M)&S_IFMT) == S_IFBLK)
                   3969: #endif
                   3970: 
                   3971: /*
                   3972:  *     mkd function -- tries to make a directory whose name is "d".
                   3973:  *     returns 0 if successful or if d already exists and is a
                   3974:  *     directory.  On failure, returns mkdir's return code.
                   3975:  */
                   3976: 
                   3977: int
                   3978: mkd (char *d)
                   3979: {
                   3980:        register int pid, w;
                   3981:        int status;
                   3982:        struct stat sb;
                   3983: 
                   3984:        if (stat (d, &sb) >= 0)
                   3985:                return !S_ISDIR(sb.st_mode);
                   3986: 
                   3987:        switch (pid = fork()) {
                   3988:        case 0:
                   3989:                /* we might be executed from a setuid program */
                   3990:                setgid (getegid());
                   3991:                setuid (geteuid());
                   3992:                execl ("/bin/mkdir", "mkdir", d, 0);
                   3993:                /* No break */
                   3994:        case -1:
                   3995:                return 1;
                   3996: 
                   3997:        default:
                   3998:                do w = wait (&status);
                   3999:                while (w != pid && w > 0);
                   4000:                if (w == pid)
                   4001:                        return status;
                   4002:                return w;
                   4003:        }
                   4004: }
                   4005: 
                   4006: 
                   4007: static int
                   4008: rm (char *name, struct stat *sb, int type, struct FTW *ftw)
                   4009: {
                   4010:        register int r;
                   4011: 
                   4012:        switch (type) {
                   4013: 
                   4014:        case FTW_F:
                   4015:        case FTW_SL:
                   4016:                r = unlink (name);
                   4017:                if (r < 0) {
                   4018:                        perror (name);
                   4019:                        return r;
                   4020:                }
                   4021:                break;
                   4022:        
                   4023:        case FTW_D:
                   4024:                break;
                   4025:        
                   4026:        case FTW_DNR:
                   4027:                fprintf (stderr, "cannot read directory %s\n", name);
                   4028:                exit (1);
                   4029:        
                   4030:        case FTW_NS:
                   4031:                fprintf (stderr, "cannot stat %s\n", name);
                   4032:                exit (1);
                   4033:        
                   4034:        case FTW_DP:
                   4035:                r = rmdir (name);
                   4036:                if (r != 0) {
                   4037:                        fprintf (stderr,
                   4038:                            "trouble removing directory %s\n", name);
                   4039:                        return r;
                   4040:                }
                   4041:        }
                   4042: 
                   4043:        return 0;
                   4044: }
                   4045: 
                   4046: /*
                   4047:  *     rmdir function -- tries to remove a directory whose name is "d".
                   4048:  *     returns 0 if successful.  On failure, returns rmdir's return code.
                   4049:  */
                   4050: 
                   4051: int
                   4052: rmdir (char *d)
                   4053: {
                   4054:        register int pid, w;
                   4055:        int status;
                   4056:        struct stat sb;
                   4057: 
                   4058:        if (stat (d, &sb) >= 0 && !S_ISDIR(sb.st_mode))
                   4059:                return -1;
                   4060: 
                   4061:        switch (pid = fork()) {
                   4062:        case 0:
                   4063:                /* we might be executed from a setuid program */
                   4064:                setgid (getegid());
                   4065:                setuid (geteuid());
                   4066:                execl ("/bin/rmdir", "rmdir", d, 0);
                   4067:                /* No break */
                   4068:        case -1:
                   4069:                return 1;
                   4070: 
                   4071:        default:
                   4072:                do w = wait (&status);
                   4073:                while (w != pid && w > 0);
                   4074:                if (w == pid)
                   4075:                        return status;
                   4076:                return w;
                   4077:        }
                   4078: }
                   4079: 
                   4080: /* rmall (s) recursively removes the object named s */
                   4081: int
                   4082: rmall (char *s)
                   4083: {
                   4084:        if (access(s, 0) < 0)
                   4085:                return 0;
                   4086:        return ftw (s, rm, 8);
                   4087: }
                   4088:  &sb) >= 0 && !S_ISDIR(sb.st_mode))
                   4089:                return -1;
                   4090: 
                   4091:        switch (pid = fork()) {
                   4092:        case 0:
                   4093:                /* we might be executed from a setuid program */
                   4094:                setgid (getegid());
                   4095:                setuid (geteuid());
                   4096:                execl ("/bin/rmdir", "rmdir", d, 0);
                   4097:                /* No break */
                   4098:        case -1:
                   4099:                return 1;
                   4100: 
                   4101:        default:
                   4102:        pkg/mkfile   644   3513      4        1607  5031450307   6061 <../mkconf.$SYS
                   4103: <../mkrules.$SYS
                   4104: 
                   4105: LPROG=mkpkg inspkg seal unseal
                   4106: LIB=lib-$O.a
                   4107: LIBOBJ=alloc.$O args.$O chk.$O crypt.$O data.$O ftw.$O fullname.$O \
                   4108:  gid.$O header.$O mkcsum.$O mkdir.$O package.$O path.$O pwd.$O \
                   4109:  transname.$O uid.$O
                   4110: 
                   4111: compile:V: $LPROG
                   4112: 
                   4113: install:V: compile
                   4114:        test -d $LDIR || mkdir $LDIR
                   4115:        cp $LPROG $LDIR
                   4116: 
                   4117: mkpkg: mkpkg.$O $LIB
                   4118:        $CC -o $target $prereq $CCLIB
                   4119: 
                   4120: inspkg: inspkg.$O $LIB
                   4121:        $CC -o $target $prereq $CCLIB
                   4122: 
                   4123: seal: seal.$O $LIB
                   4124:        $CC -o $target $prereq $CCLIB
                   4125: 
                   4126: unseal: unseal.$O $LIB
                   4127:        $CC -o $target $prereq $CCLIB
                   4128: 
                   4129: lib-$O.a: $LIBOBJ
                   4130:        rm -f lib-$O.a
                   4131:        ar r lib-$O.a $LIBOBJ
                   4132:        $RL lib-$O.a
                   4133: 
                   4134: # Need to check these.
                   4135: alloc.$O args.$O data.$O fullname.$O gid.$O: asd.h ar.h
                   4136: header.$O inspkg.$O mkdir.$O: asd.h ar.h
                   4137: mkpkg.$O package.$O path.$O pwd.$O seal.$O: asd.h ar.h
                   4138: transname.$O uid.$O unseal.$O: asd.h ar.h
                   4139: mkcsum.$O seal.$O unseal.$O: seal.h
                   4140: 
                   4141: clean:V:
                   4142:        rm -f *.[$OS] lib-[$OS].a $LPROG
                   4143: $LIB
                   4144:        $CC -o $target $prereq $CCLIB
                   4145: 
                   4146: seal: seal.$O $LIB
                   4147:        $CC -o $target $prereq $CCLIB
                   4148: 
                   4149: unseal: unseal.$O $LIB
                   4150:        $CC -o $tpkg/mkpkg.c   644   3513      4         453  5013610574   6126 #include "asd.h"
                   4151: #include <libv.h>
                   4152: #include <stdio.h>
                   4153: 
                   4154: int
                   4155: main (int argc, char **argv)
                   4156: {
                   4157:        register int i;
                   4158:        static char errbuf[BUFSIZ];
                   4159: 
                   4160:        setbuf (stderr, errbuf);
                   4161: 
                   4162:        getargs (argc, argv, "vx:X:D:", 0);
                   4163: 
                   4164:        pkgstart();
                   4165:        for (i = optind; i < argc; i++)
                   4166:                pkgfile (argv[i]);
                   4167: 
                   4168:        i = pkgend();
                   4169: 
                   4170:        return i;
                   4171: }
                   4172:  asd.h ar.h
                   4173: mkcsum.$O seal.$O unseal.$O: seal.h
                   4174: 
                   4175: clean:V:
                   4176:        rm -f *.[$OS] lib-[$OS].a $LPROG
                   4177: $LIB
                   4178:        $CC -o $target $prereq $CCLIB
                   4179: 
                   4180: seal: seal.$O $LIB
                   4181:        $CC -o $target $prereq $CCLIB
                   4182: 
                   4183: unseal: unseal.$O $LIB
                   4184:        $CC -o $tpkg/package.c   644   3513      4       23235  5032702500   6443 #include "asd.h"
                   4185: #include <string.h>
                   4186: #include <time.h>
                   4187: #include <unistd.h>
                   4188: #include "ftw.h"
                   4189: 
                   4190: FILE *tf;
                   4191: static Sig_typ sigsav;
                   4192: static int rc;
                   4193: static char tfname[L_tmpnam];
                   4194: static struct stat outsb;
                   4195: static struct pack *pkhead, *pktail;
                   4196: 
                   4197: /*
                   4198:  *     The following structure helps keep track of things being packaged.
                   4199:  *     iname is the internal name of the component -- in other words,
                   4200:  *     the archive element name.  ename is the (short) pathname of the
                   4201:  *     file.  The structures are chained by the "link" field.  All the
                   4202:  *     other fields are copies of things returned by "stat" and are
                   4203:  *     used mostly to make sure nothing changed while we were packaging.
                   4204:  *     head and tail point to the first and last items in the chain.
                   4205:  *     The first item is known to refer to the "Instructions" component.
                   4206:  */
                   4207: struct pack {
                   4208:        char *iname;
                   4209:        char *ename;
                   4210:        struct pack *link;
                   4211:        dev_t dev;
                   4212:        ino_t ino;
                   4213:        int uid, gid, mode;
                   4214:        time_t time;
                   4215:        off_t size;
                   4216: };
                   4217: 
                   4218: /*
                   4219:  *     Prepare to build a package.  The package will appear on stdout.
                   4220:  *     The argument is nonzero if remarks are to be read.
                   4221:  */
                   4222: 
                   4223: static void
                   4224: delete(int arg)
                   4225: {
                   4226:        unlink (tfname);
                   4227:        exit (3);
                   4228: }
                   4229: 
                   4230: void
                   4231: pkgstart(void)
                   4232: {
                   4233:        struct stat pks;
                   4234: 
                   4235:        rc = 0;
                   4236: 
                   4237:        nchk (fstat (fileno (stdout), &outsb));
                   4238: 
                   4239:        /* establish a temporary file to hold the instruction information */
                   4240:        tmpnam (tfname);
                   4241:        tf = fopen (tfname, "w");
                   4242:        sigsav = signal (SIGINT, SIG_IGN);
                   4243:        if (sigsav != SIG_IGN)
                   4244:                signal (SIGINT, delete);
                   4245:        nchk (chmod (tfname, 0644));
                   4246:        schk ((char *) tf);
                   4247: 
                   4248:        /* create the initial element in the component chain */
                   4249:        pkhead = pktail = new (struct pack);
                   4250:        pkhead->iname = copy (instr);
                   4251:        pkhead->ename = copy (tfname);
                   4252:        pkhead->time = 0;
                   4253:        pkhead->link = NULL;
                   4254:        pkhead->uid = getuid();
                   4255:        nchk (fstat (fileno(tf), &pks));
                   4256:        pkhead->gid = pks.st_gid;
                   4257:        pkhead->mode = 0100644;
                   4258: }
                   4259: 
                   4260: static int consider(char *, struct stat *, int, struct FTW *);
                   4261: 
                   4262: /*
                   4263:  *     put a file (or directory) into a package
                   4264:  */
                   4265: void
                   4266: pkgfile (char *file)
                   4267: {
                   4268:        register int x;
                   4269:        struct stat sb;
                   4270: 
                   4271:        /* if the file is truly not present, generate a remove request */
                   4272: #ifdef S_IFLNK
                   4273:        if (lstat (file, &sb) < 0 && errno == ENOENT) {
                   4274: #else
                   4275:        if (stat (file, &sb) < 0 && errno == ENOENT) {
                   4276: #endif
                   4277:                fprintf (tf, "r ");
                   4278:                putpath (tf, transname (file));
                   4279:                putc ('\n', tf);
                   4280:        } else {
                   4281:                x = ftw (file, consider, 8);
                   4282:                if (x != 0) {
                   4283:                        rc++;
                   4284:                        if (x == -1)
                   4285:                                perror (file);
                   4286:                }
                   4287:        }
                   4288: }
                   4289: 
                   4290: /*
                   4291:  *     we are done building a package.  This writes the actual file
                   4292:  *     contents, so make sure the files are still around
                   4293:  */
                   4294: int
                   4295: pkgend(void)
                   4296: {
                   4297:        register struct pack *pack;
                   4298:        struct stat s;
                   4299: 
                   4300:        /* write 'x' or 'X' execution item if requested */
                   4301:        if (xstr) {
                   4302:                fprintf (tf, "x ");
                   4303:                putpath (tf, xstr);
                   4304:                fprintf (tf, "\n");
                   4305:        }
                   4306:        if (Xstr) {
                   4307:                fprintf (tf, "X ");
                   4308:                putpath (tf, Xstr);
                   4309:                fprintf (tf, "\n");
                   4310:        }
                   4311: 
                   4312:        /* we now know how long the first component is */
                   4313:        pkhead->size = ftell (tf);
                   4314: 
                   4315:        /* we no longer need to write the temporary file */
                   4316:        fclose (tf);
                   4317: 
                   4318:        /* describe the temp file correctly so it will pass later checks */
                   4319:        if (pkhead->time == 0)
                   4320:                (void) time (&pkhead->time);
                   4321:        nchk (stat (tfname, &s));
                   4322:        pkhead->dev = s.st_dev;
                   4323:        pkhead->ino = s.st_ino;
                   4324: 
                   4325:        /*
                   4326:         * write the files out into an archive
                   4327:         */
                   4328: 
                   4329:        /* first the archive header */
                   4330:        printf (ARMAG);
                   4331: 
                   4332:        /*
                   4333:         *      run through the list, creating the archive components
                   4334:         *      and deleting the list entries.  One iteration per component.
                   4335:         *      We know there is at least one component, because the
                   4336:         *      "Instructions" component must be represented.
                   4337:         */
                   4338:        do {
                   4339:                struct ar_hdr ah;
                   4340:                char buf[30];
                   4341:                register int c;
                   4342: 
                   4343:                /* "pack" is the package component under consideration */
                   4344:                pack = pkhead;
                   4345: 
                   4346:                if (pack->iname) {      /* non-regular file entry, no data */
                   4347: 
                   4348:                        /* log it if requested */
                   4349:                        if (vflag)
                   4350:                                fprintf (stderr, "package %s\n",
                   4351:                                    strcmp (pack->iname, instr)? pack->ename: instr);
                   4352: 
                   4353:                        /* write the archive element header */
                   4354: 
                   4355: #              define ent(a,x) sprintf(buf, "%-*s", sizeof(ah.a), x); \
                   4356:                        strncpy (ah.a, buf, sizeof (ah.a))
                   4357:                        ent (ar_name, pack->iname);
                   4358:                        ent (ar_fmag, ARFMAG);
                   4359: #              undef ent
                   4360: 
                   4361: #              define ent(a,x) sprintf(buf, "%*ld", sizeof(ah.a), (long) x); \
                   4362:                        strncpy (ah.a, buf, sizeof (ah.a))
                   4363:                        ent (ar_date, pack->time);
                   4364:                        ent (ar_uid, pack->uid);
                   4365:                        ent (ar_gid, pack->gid);
                   4366:                        ent (ar_size, pack->size);
                   4367: #              undef ent
                   4368: 
                   4369: #              define ent(a,x) sprintf(buf, "%*o", sizeof(ah.a), x); \
                   4370:                        strncpy (ah.a, buf, sizeof (ah.a))
                   4371:                        ent (ar_mode, pack->mode);
                   4372: #              undef ent
                   4373: 
                   4374:                        fwrite ((char *) &ah, sizeof (ah), 1, stdout);
                   4375: 
                   4376:                        /* write the archive element itself */
                   4377:                        tf = fopen (pack->ename, "r");
                   4378:                        if (tf == NULL) {
                   4379:                                perror (pack->iname);
                   4380:                                exit (1);
                   4381:                        }
                   4382: 
                   4383:                        while ((c = getc (tf)) != EOF)
                   4384:                                putchar (c);
                   4385:                        
                   4386:                        /* if things now don't match, complain */
                   4387:                        if (fstat (fileno (tf), &s) < 0 || s.st_size != pack->size ||
                   4388:                            (s.st_mtime != pack->time && strcmp (pack->iname, instr)) ||
                   4389:                            s.st_dev != pack->dev || s.st_ino != pack->ino ||
                   4390:                            s.st_uid != pack->uid || s.st_gid != pack->gid ||
                   4391:                            (s.st_mode & 07777) != (pack->mode & 07777)) {
                   4392:                                fprintf (stderr, "phase error on %s\n",
                   4393:                                    pack->ename);
                   4394:                                rc++;
                   4395:                        }
                   4396: 
                   4397:                        fclose (tf);
                   4398: 
                   4399:                        if (pack->size & 1)
                   4400:                                putchar ('\n');
                   4401:                }
                   4402:                
                   4403:                /* delete the element, move on to the next */
                   4404:                if (pack->iname) free (pack->iname);
                   4405:                free (pack->ename);
                   4406:                pkhead = pack->link;
                   4407:                free ((char *) pack);
                   4408:        } while (pkhead);
                   4409: 
                   4410:        /* zap the tail pointer for general cleanliness */
                   4411:        pktail = NULL;
                   4412: 
                   4413:        nchk (unlink (tfname));
                   4414:        signal (SIGINT, sigsav);
                   4415: 
                   4416:        return rc;
                   4417: }
                   4418: 
                   4419: static void hdrsub(char *, struct stat *);
                   4420: static char *iname(char *);
                   4421: 
                   4422: /* internal function for package creation */
                   4423: static int
                   4424: consider (char *name, struct stat *buf, int type, struct FTW *ftw)
                   4425: {
                   4426:        register struct pack *pack;
                   4427:        register int mode;
                   4428:        char *biname;
                   4429: #ifdef S_ISLNK
                   4430:        char *slname;
                   4431: #endif
                   4432: 
                   4433:        switch (type) {
                   4434:        case FTW_D:
                   4435:                fprintf (tf, "d %-*.4o ", MAXCOMP, buf->st_mode & 07777);
                   4436:                hdrsub (name, buf);
                   4437:                fprintf (tf, "\n");
                   4438:                break;
                   4439: 
                   4440:        case FTW_SL:
                   4441:                if (ftw->level == 0) {
                   4442:                        ftw->quit = FTW_FOLLOW;
                   4443:                        return 0;
                   4444:                }
                   4445:                /* fall through */
                   4446: 
                   4447:        case FTW_F:
                   4448:                mode = buf->st_mode;
                   4449: 
                   4450:                /* Has this file already appeared?  If so, it's a link */
                   4451:                for (pack = pkhead->link; pack; pack = pack->link) {
                   4452:                        if (buf->st_dev == pack->dev &&
                   4453:                            buf->st_ino == pack->ino) {
                   4454:                                fprintf (tf, "l %s ", transname (pack->ename));
                   4455:                                fprintf (tf, "%s\n", transname (name));
                   4456:                                return 0;
                   4457:                        }
                   4458:                }
                   4459: 
                   4460:                if (S_ISREG(mode)) {
                   4461:                        /* refuse to package the standard output */
                   4462:                        if (buf->st_dev == outsb.st_dev &&
                   4463:                            buf->st_ino == outsb.st_ino) {
                   4464:                                fprintf (stderr, "skipping output file %s\n",
                   4465:                                    fullname (name));
                   4466:                                return 0;
                   4467:                        }
                   4468:                        biname = iname (name);
                   4469:                        fprintf (tf, "f ");
                   4470:                        putpath (tf, biname);
                   4471:                        fprintf (tf, " ");
                   4472:                        hdrsub (name, buf);
                   4473:                        fprintf (tf, "\n");
                   4474:                }
                   4475: #ifdef S_ISLNK
                   4476:                else if (S_ISLNK(mode)) {
                   4477:                        slname = alloc((unsigned)buf->st_size+1);
                   4478:                        slname[buf->st_size] = '\0';
                   4479:                        if (readlink(name, slname, buf->st_size) !=
                   4480:                            buf->st_size) {
                   4481:                                perror(name);
                   4482:                                return (0);
                   4483:                        }
                   4484:                        fprintf (tf, "s %s ", transname (slname));
                   4485:                        fprintf (tf, "%s\n", transname (name));
                   4486:                        biname = NULL;
                   4487:                }
                   4488: #endif
                   4489: #if 0 /* We don't handle special files any more.  */
                   4490:                else if (S_ISBLK(mode) || S_ISCHR(mode)) {
                   4491:                        fprintf (tf, "%c %#o %d %d ",
                   4492:                            mode == S_IFBLK? 'b': 'c',
                   4493:                            buf->st_mode & 07777,
                   4494:                            major (buf->st_rdev),
                   4495:                            minor (buf->st_rdev));
                   4496:                        hdrsub (name, buf);
                   4497:                        fprintf (tf, "\n");
                   4498:                        biname = NULL;
                   4499:                }
                   4500: #endif
                   4501:                else {
                   4502:                        fprintf (stderr, "%s: unrecognized file type\n",
                   4503:                                 fullname (name));
                   4504:                        break;
                   4505:                }
                   4506: 
                   4507: 
                   4508:                /* package the file */
                   4509:                pack = new (struct pack);
                   4510:                pack->ename = copy (name);
                   4511:                pack->dev = buf->st_dev;
                   4512:                pack->ino = buf->st_ino;
                   4513:                pack->uid = buf->st_uid;
                   4514:                pack->gid = buf->st_gid;
                   4515:                pack->time = buf->st_mtime;
                   4516:                if (pack->time > pkhead->time)
                   4517:                        pkhead->time = pack->time;
                   4518:                pack->size = buf->st_size;
                   4519:                pack->mode = buf->st_mode;
                   4520:                pack->link = NULL;
                   4521:                pack->iname = biname;
                   4522:                pktail->link = pack;
                   4523:                pktail = pack;
                   4524:                break;
                   4525: 
                   4526:        case FTW_DNR:
                   4527:                fprintf (stderr, "cannot read directory %s\n", name);
                   4528:                return 1;
                   4529: 
                   4530:        case FTW_NS:
                   4531:                fprintf (stderr, "cannot stat %s\n", name);
                   4532:                return 1;
                   4533: 
                   4534:        case FTW_DP:
                   4535:                break;
                   4536: 
                   4537:        default:
                   4538:                fprintf (stderr, "impossible code %d from ftw\n", type);
                   4539:                exit (1);
                   4540:        }
                   4541:        return 0;
                   4542: }
                   4543: 
                   4544: static void
                   4545: hdrsub (char *name, struct stat *buf)
                   4546: {
                   4547:        putpath (tf, uidstr (buf->st_uid));
                   4548:        putc ('\t', tf);
                   4549:        putpath (tf, gidstr (buf->st_gid));
                   4550:        putc ('\t', tf);
                   4551:        putpath (tf, transname (name));
                   4552: }
                   4553: 
                   4554: /*
                   4555:  *     generate a unique internal name for a file
                   4556:  */
                   4557: static char *
                   4558: iname (char *s)
                   4559: {
                   4560:        register char *p;
                   4561:        register char *lastcomp;
                   4562:        register struct pack *pack;
                   4563:        char trial[MAXCOMP+1];
                   4564: 
                   4565:        /* point lastcomp at the last pathname component */
                   4566:        lastcomp = s;
                   4567:        for (p = s; *p; p++) {
                   4568:                if (*p == '/')
                   4569:                        lastcomp = p + 1;
                   4570:        }
                   4571: 
                   4572:        /* if the name is acceptably short, modify it slightly */
                   4573:        if (strlen (lastcomp) <= MAXCOMP) {
                   4574: 
                   4575:                char prefix[MAXCOMP+1], suffix[MAXCOMP+1], num[30];
                   4576:                register int n;
                   4577: 
                   4578:                /* split the name, remove unprintables */
                   4579:                strcpy (prefix, lastcomp);
                   4580:                for (p = prefix; *p; p++)
                   4581:                        if (*p == ' ' || !isprint (*p))
                   4582:                                *p = '$';
                   4583:                suffix[0] = '\0';
                   4584:                p = strrchr (prefix, '.');
                   4585:                if (p != NULL) {
                   4586:                        strcpy (suffix, p);
                   4587:                        *p = '\0';
                   4588:                }
                   4589: 
                   4590:                /* generate trial names until we run out of space */
                   4591:                for (n = 0, num[0] = '\0';
                   4592:                    strlen(prefix) + strlen(suffix) + strlen(num) <= MAXCOMP;
                   4593:                    n++, sprintf (num, "%.0d", n)) {
                   4594:                        
                   4595:                        /* generate the trial name */
                   4596:                        strcpy (trial, prefix);
                   4597:                        strcat (trial, num);
                   4598:                        strcat (trial, suffix);
                   4599: 
                   4600:                        /* if the name is unique, we're done */
                   4601:                        pack = pkhead;
                   4602:                        while (pack != NULL && strcmp (pack->iname, trial) != 0)
                   4603:                                pack = pack->link;
                   4604:                        if (pack == NULL)
                   4605:                                return copy(trial);
                   4606: 
                   4607:                }
                   4608:        }
                   4609: 
                   4610:        /* punt -- generate a completely new name */
                   4611:        do {
                   4612:                static int tempno;
                   4613: 
                   4614:                tempno++;
                   4615:                sprintf (trial, "Temp%d", tempno);
                   4616:                pack = pkhead;
                   4617:                while (pack != NULL && strcmp (trial, pack->iname) != 0)
                   4618:                        pack = pack->link;
                   4619:        } while (pack != NULL);
                   4620:        return copy(trial);
                   4621: }
                   4622: at (trial, num);
                   4623:                        strcat (trial, suffix);
                   4624: 
                   4625:                        /* if the name is unique, we're done */
                   4626:                        pack = pkhead;
                   4627:                        while (pack != NULL && strcmp (pack->iname, trial) != 0)
                   4628:                                pack = pack->link;
                   4629:                        if (pack == NULL)
                   4630:                                return copy(trial);
                   4631: 
                   4632:                }
                   4633:        }
                   4634: 
                   4635:        /* punt -- generate a completely new name */
                   4636:        do {
                   4637:                static int tempno;
                   4638: 
                   4639:                tempno++;
                   4640:                sprintf (trial, "Temp%d"pkg/path.c   644   3513      4        6137  5013610576   6000 /*
                   4641:  *     getpath (file) - read a path name
                   4642:  *     putpath (file, path) - write a path name
                   4643:  *
                   4644:  *     These subroutines cater to the possibility of unprintable
                   4645:  *     characters in the path names being read or written, by
                   4646:  *     using the same sort of \ conventions commonly found in
                   4647:  *     C character constants.  The result of getpath is a pointer
                   4648:  *     to a static buffer whose contents will stay around no longer
                   4649:  *     than the next call to getpath.  When getpath is called, the
                   4650:  *     character about to be read from the input file must be the
                   4651:  *     first character of the path name.
                   4652:  *
                   4653:  *     There are a few problems, mostly relating to bugs and language
                   4654:  *     changes, to watch out for in these routines.  First of all,
                   4655:  *     we assume that \v is known by the C compiler, even though
                   4656:  *     it is not mentioned in Kernighan and Ritchie.  The reason for
                   4657:  *     this is that if we do not make this assumption, we run into
                   4658:  *     a common bug in the handling of iscntrl().  Although the
                   4659:  *     manuals all say that if c is a white-space character that is
                   4660:  *     not a blank, then iscntrl(c) is true, several versions of the
                   4661:  *     C library disagree with the documentation.  Thus we try to
                   4662:  *     list all the white-space characters explicitly.
                   4663:  */
                   4664: 
                   4665: #include "asd.h"
                   4666: #include <ctype.h>
                   4667: #include <stdio.h>
                   4668: 
                   4669: #define CHUNK 64
                   4670: 
                   4671: static char *r;
                   4672: static unsigned size;
                   4673: 
                   4674: char *
                   4675: getpath (FILE *file)
                   4676: {
                   4677:        register int c;
                   4678:        register int len = 0;
                   4679: 
                   4680:        c = getc (file);
                   4681: 
                   4682:        while (!isspace(c) && c != EOF) {
                   4683:                register int i = 0, n = 0;
                   4684: 
                   4685:                /* determine the next input character */
                   4686:                if (c == '\\') {
                   4687:                        c = getc (file);
                   4688:                        switch (c) {
                   4689: 
                   4690:                        case '\\':
                   4691:                                break;
                   4692:                        
                   4693:                        case 'n':
                   4694:                                c = '\n';
                   4695:                                break;
                   4696: 
                   4697:                        case 'r':
                   4698:                                c = '\r';
                   4699:                                break;
                   4700: 
                   4701:                        case 't':
                   4702:                                c = '\t';
                   4703:                                break;
                   4704: 
                   4705:                        case 'b':
                   4706:                                c = '\b';
                   4707:                                break;
                   4708:                        
                   4709:                        case 'f':
                   4710:                                c = '\f';
                   4711:                                break;
                   4712:                        
                   4713:                        case 'v':
                   4714:                                c = '\v';
                   4715:                                break;
                   4716:                        
                   4717:                        case ' ':
                   4718:                             /* c = ' '; */
                   4719:                                break;
                   4720: 
                   4721:                        default:
                   4722:                                while (c >= '0' && c <= '7' && i < 3) {
                   4723:                                        n = (n << 3) + c - '0';
                   4724:                                        i++;
                   4725:                                        c = getc (file);
                   4726:                                }
                   4727:                                ungetc (c, file);
                   4728:                                c = n;
                   4729:                                break;
                   4730:                        }
                   4731:                }
                   4732: 
                   4733:                /* ensure there's room in the buffer */
                   4734:                if (len >= size)
                   4735:                        r = ralloc (r, size += CHUNK);
                   4736: 
                   4737:                /* put the character in the buffer */
                   4738:                r[len++] = c;
                   4739: 
                   4740:                /* read the next character */
                   4741:                c = getc (file);
                   4742:        }
                   4743: 
                   4744:        /* unless we hit eof, we read one character too far. */
                   4745:        if (c != EOF)
                   4746:                ungetc (c, file);
                   4747:        
                   4748:        /* put a final null into the buffer */
                   4749:        if (len >= size)
                   4750:                r = ralloc (r, size += CHUNK);
                   4751:        r[len] = '\0';
                   4752: 
                   4753:        return r;
                   4754: }
                   4755: 
                   4756: void
                   4757: putpath (FILE *file, char *path)
                   4758: {
                   4759:        register char *p = path;
                   4760:        register int c;
                   4761:        
                   4762:        while ((c = *p++) != NULL) {
                   4763:                switch (c) {
                   4764: 
                   4765:                case '\n':
                   4766:                        fprintf (file, "\\n");
                   4767:                        break;
                   4768: 
                   4769:                case '\r':
                   4770:                        fprintf (file, "\\r");
                   4771:                        break;
                   4772: 
                   4773:                case '\b':
                   4774:                        fprintf (file, "\\b");
                   4775:                        break;
                   4776: 
                   4777:                case '\t':
                   4778:                        fprintf (file, "\\t");
                   4779:                        break;
                   4780: 
                   4781:                case '\f':
                   4782:                        fprintf (file, "\\f");
                   4783:                        break;
                   4784:                
                   4785:                case '\v':
                   4786:                        fprintf (file, "\\v");
                   4787:                        break;
                   4788:                
                   4789:                case '\\':
                   4790:                        fprintf (file, "\\\\");
                   4791:                        break;
                   4792:                
                   4793:                case ' ':
                   4794:                        fprintf (file, "\\ ");
                   4795:                        break;
                   4796:                
                   4797:                default:
                   4798:                        if (iscntrl (c))
                   4799:                                fprintf (file,
                   4800:                                    *p >= '0' && *p <= '7'? "\\%.3o": "\\%o",
                   4801:                                    c);
                   4802:                        else
                   4803:                                putc (c, file);
                   4804:                        break;
                   4805:                }
                   4806:        }
                   4807: }
                   4808: e '\r':
                   4809:                        fprintf (file, "\\r");
                   4810:                        break;
                   4811: 
                   4812:                case '\b':
                   4813:                        fprintf (file, "\\b");
                   4814:                        break;
                   4815: 
                   4816:                case '\t':
                   4817:                        fprintf (file, "\\t");
                   4818:                        break;
                   4819: 
                   4820:                case '\f':
                   4821:                        fprintf (file, "\\f");
                   4822:                        break;
                   4823:                
                   4824:                case '\v':
                   4825:                        fprintf (file, "\\v");
                   4826:                        break;
                   4827:                
                   4828:                case '\\':
                   4829:                        fprintf (file, "\\\\");
                   4830:                        break;
                   4831:                
                   4832:                case ' ':
                   4833:                        fprintf (file, "\\ ");
                   4834:                        break;
                   4835:                
                   4836:                default:
                   4837:                        if (iscntrl (c))
                   4838:                                fprintf (file,
                   4839:                                    *p >= pkg/pwd.c   644   3513      4        1113  5013610576   5623 /*
                   4840:  *     pwd() - return the name of the current directory.
                   4841:  *     We assume that the current directory never changes.
                   4842:  */
                   4843: 
                   4844: #include "asd.h"
                   4845: #include <libv.h>
                   4846: #include <stdio.h>
                   4847: 
                   4848: #define CHUNK 64
                   4849: 
                   4850: char *
                   4851: pwd(void)
                   4852: {
                   4853:        register FILE *f;
                   4854:        static char *r;
                   4855:        static unsigned size;
                   4856:        register int n, c;
                   4857: 
                   4858:        if (r == NULL) {
                   4859:                f = popen ("pwd", "r");
                   4860:                schk ((char *) f);
                   4861:                
                   4862:                n = 0;
                   4863:                while ((c = getc (f)) != EOF) {
                   4864:                        if (n >= size) {
                   4865:                                size += CHUNK;
                   4866:                                r = ralloc (r, size);
                   4867:                        }
                   4868:                        r[n++] = c;
                   4869:                }
                   4870: 
                   4871:                /* replace the trailing newline by a null */
                   4872:                r[n - 1] = '\0';
                   4873: 
                   4874:                pclose (f);
                   4875:        }
                   4876: 
                   4877:        return r;
                   4878: }
                   4879: he current directory never changes.
                   4880:  */
                   4881: 
                   4882: #include "asd.h"
                   4883: #include <libv.h>
                   4884: #include <stdio.h>
                   4885: 
                   4886: #define CHUNK 64
                   4887: 
                   4888: char *
                   4889: pwd(void)
                   4890: {
                   4891:        register FILE *f;
                   4892:        static char *r;
                   4893:        static unsigned size;
                   4894:        register int n, c;
                   4895: 
                   4896:        if (r == NULL) {
                   4897:                f = popen ("pwd", "r");
                   4898:                schk ((char *) f);
                   4899:                
                   4900:                n = 0;
                   4901:                while ((c = getc (f)) != EOF) {
                   4902:                        if (n >= size) {
                   4903:                                size += CHUNK;
                   4904:                                r = ralloc (r, size);
                   4905:                        }
                   4906:                        r[n++] = c;
                   4907:                }
                   4908: 
                   4909:                /* replace the trailipkg/seal.c   644   3513      4        5522  5013610577   5766 /*
                   4910:  *     seal - prepare a package for shipment
                   4911:  */
                   4912: 
                   4913: #include "asd.h"
                   4914: #include "seal.h"
                   4915: #include <ctype.h>
                   4916: #include <string.h>
                   4917: 
                   4918: static long length;
                   4919: static unsigned long checksum;
                   4920: 
                   4921: /*
                   4922:  *     convert the characters in the range (in,inend] to
                   4923:  *     storage starting at "out" -- return the number of
                   4924:  *     output characters.
                   4925:  */
                   4926: 
                   4927: static int
                   4928: hrform (char *in, char *inend, char *out)
                   4929: {
                   4930:        register char *r = out;
                   4931: 
                   4932:        /* special handling for the first character(s) */
                   4933:        if (in < inend) {
                   4934:                if (*in == '.' || *in == '!' ||
                   4935:                    (*in == 'F' && strncmp (in, "From", 4) == 0))
                   4936:                        *r++ = '\\';
                   4937: 
                   4938:                do {
                   4939:                        register int ch = (unsigned char) *in++;
                   4940: 
                   4941:                        if (isprint (ch)) {
                   4942:                                if (ch == '\\')
                   4943:                                        *r++ = '\\';
                   4944:                                *r++ = ch;
                   4945:                        } else {
                   4946:                                if (ch == ' ' || ch == '\t' || ch == '\n')
                   4947:                                        *r++ = ch;
                   4948:                                else {
                   4949:                                        *r++ = '\\';
                   4950:                                        *r++ = hextab[(ch >> 4) & 0xf];
                   4951:                                        *r++ = hextab[ch & 0xf];
                   4952:                                }
                   4953:                        }
                   4954:                } while (in < inend);
                   4955: 
                   4956:                if (r[-1] != '\n') {
                   4957:                        *r++ = '\\';
                   4958:                        *r++ = '\n';
                   4959:                }
                   4960:        }
                   4961: 
                   4962:        return r - out;
                   4963: }
                   4964: 
                   4965: static int
                   4966: mrform (char *in, char *inend, char *out)
                   4967: {
                   4968:        char *r;
                   4969:        register int len;
                   4970: 
                   4971:        len = inend - in;
                   4972:        if (len <= 0)
                   4973:                return 0;
                   4974: 
                   4975:        r = out;
                   4976: 
                   4977:        *r++ = '.';
                   4978: 
                   4979:        do {
                   4980:                register unsigned long bits;
                   4981:                register int n, outn;
                   4982:                register char *rr;
                   4983: 
                   4984:                n = len;
                   4985:                if (n > INCPW)
                   4986:                        n = INCPW;
                   4987:                len -= n;
                   4988:                outn = n + OUTCPW - INCPW;
                   4989: 
                   4990:                bits = 0;
                   4991:                do      bits = (bits << BPC) | (*in++ & BYTEMASK);
                   4992:                while (--n > 0);
                   4993: 
                   4994:                rr = r = r + outn;
                   4995:                do {
                   4996:                        *--rr = RADBASE + bits % RADIX;
                   4997:                        bits /= RADIX;
                   4998:                } while (--outn > 0);
                   4999:        } while (len > 0);
                   5000: 
                   5001:        *r++ = '\n';
                   5002: 
                   5003:        return r - out;
                   5004: }
                   5005: 
                   5006: 
                   5007: static int
                   5008: seal (FILE *f, char *fname)
                   5009: {
                   5010:        static int first = 1;
                   5011: 
                   5012:        if (first) {
                   5013:                first = 0;
                   5014:                printf ("!<seal>\n");
                   5015:        }
                   5016: 
                   5017:        do {
                   5018:                char line[MAXLINE];
                   5019:                char outline[MAXLINE*3+10];
                   5020:                register char *p, *endl;
                   5021:                register int ch;
                   5022: 
                   5023:                /* read a line, possibly short */
                   5024:                p = line;
                   5025:                endl = line + MAXLINE;
                   5026: 
                   5027:                do {
                   5028:                        ch = getc (f);
                   5029:                        if (ch == EOF)
                   5030:                                break;
                   5031:                        *p++ = ch;
                   5032:                } while (ch != '\n' && p < endl);
                   5033: 
                   5034:                endl = p;
                   5035: 
                   5036:                /*
                   5037:                 * endl now points one past the last char
                   5038:                 * in the line we have read.  If we didn't
                   5039:                 * get any characters at all, we're done.
                   5040:                 */
                   5041: 
                   5042:                if (line == endl)
                   5043:                        return ferror (f) != 0;
                   5044: 
                   5045:                length += endl - line;
                   5046: 
                   5047:                /* now convert the line to external form */
                   5048:                ch = hrform (line, endl, outline);
                   5049:                if (ch > (endl - line + INCPW - 1) / INCPW * OUTCPW + 2)
                   5050:                        ch = mrform (line, endl, outline);
                   5051:                p = outline;
                   5052: 
                   5053:                /* if encrypting, do so */
                   5054:                if (kflag || Kflag)
                   5055:                        mangle (line, endl);
                   5056: 
                   5057:                /* accumulate the (possibly encrypted) checksum */
                   5058:                checksum = mkcsum (checksum, line, endl);
                   5059: 
                   5060:                while (--ch >= 0)
                   5061:                        putchar (*p++);
                   5062:        } while (!feof (f) && !ferror (f));
                   5063: 
                   5064:        return ferror (f) != 0;
                   5065: }
                   5066: 
                   5067: int
                   5068: main (int argc, char **argv)
                   5069: {
                   5070:        int rc = 0;
                   5071:        static char stdbuf[BUFSIZ];
                   5072: 
                   5073:        setbuf (stdout, stdbuf);
                   5074: 
                   5075:        length = 0;
                   5076:        checksum = 0;
                   5077: 
                   5078:        rc = getargs (argc, argv, "kK:", seal);
                   5079: 
                   5080:        printf ("!end %ld %lu\n", length, checksum);
                   5081: 
                   5082:        return rc;
                   5083: }
                   5084:  if encrypting, do so */
                   5085:                if (kflag || Kflag)
                   5086:                        mangle (line, endl);
                   5087: 
                   5088:                /* accumulate the (possibly encrypted) checksum */
                   5089:                checksum = mkcsum (checksum, line, endl);
                   5090: 
                   5091:                whpkg/seal.h   644   3513      4         515  5013610577   5750 /*
                   5092:  *     common parameters for seal and unseal
                   5093:  */
                   5094: 
                   5095: #define        MAXLINE 100
                   5096: #define        MAXULINE 200
                   5097: #define        RADBASE (' ' + 1)
                   5098: #define        INCPW 4
                   5099: #define        OUTCPW 5
                   5100: #define        RADIX 94
                   5101: #define        BPC 8
                   5102: #define        BYTEMASK 0xff
                   5103: #define        CSMASK 0xffffffffL
                   5104: #define        CSHIBIT 0x80000000L
                   5105: 
                   5106: /* mkcsum.c */
                   5107: extern unsigned long mkcsum(unsigned long, char *, char *);
                   5108: c;
                   5109: }
                   5110:  if encrypting, do so */
                   5111:                if (kflag || Kflag)
                   5112:                        mangle (line, endl);
                   5113: 
                   5114:                /* accumulate the (possibly encrypted) checksum */
                   5115:                checksum = mkcsum (checksum, line, endl);
                   5116: 
                   5117:                whpkg/transname.c   644   3513      4        1701  5013610600   7010 /*
                   5118:  *     transname - take a pathname, expand it, and translate it
                   5119:  *     according to the replist.  The result is in a buffer
                   5120:  *     that will stay around no longer than the next call
                   5121:  *     to transname.  If no translation, transname will
                   5122:  *     just return fullname applied to its argument.
                   5123:  */
                   5124: 
                   5125: #include "asd.h"
                   5126: #include <string.h>
                   5127: 
                   5128: char *
                   5129: transname (char *s)
                   5130: {
                   5131:        register struct replist *rl;
                   5132:        static char *res;
                   5133:        static int size;
                   5134:        register int n;
                   5135: 
                   5136:        s = fullname (s);
                   5137: 
                   5138:        /* look for substitution */
                   5139:        for (rl = replist; rl; rl = rl->link) {
                   5140:                register char *p = rl->source;
                   5141:                register char *q = s;
                   5142: 
                   5143:                /* comparison loop */
                   5144:                while (*p != '\0' && *p == *q) {
                   5145:                        p++;
                   5146:                        q++;
                   5147:                }
                   5148: 
                   5149:                if (*p == '\0') {
                   5150:                        /* comparison successful */
                   5151:                        n = strlen (rl->dest) + strlen (q) + 1;
                   5152:                        if (n > size) {
                   5153:                                size = n;
                   5154:                                res = ralloc (res, (unsigned) n);
                   5155:                        }
                   5156:                        strcpy (res, rl->dest);
                   5157:                        strcat (res, q);
                   5158:                        return res;
                   5159:                }
                   5160:        }
                   5161: 
                   5162:        /* search loop failed, return expanded input */
                   5163:        return s;
                   5164: }
                   5165: 
                   5166: 
                   5167:        /* look for substitution */
                   5168:        for (rl = replist; rl; rl = rl-pkg/uid.c   644   3513      4        2535  5013610601   5610 #include "asd.h"
                   5169: #include <pwd.h>
                   5170: #include <stdio.h>
                   5171: #include <stdlib.h>
                   5172: #include <string.h>
                   5173: #include <unistd.h>
                   5174: 
                   5175: 
                   5176: #define CHUNK 16
                   5177: 
                   5178: static struct utab {
                   5179:        unsigned uid;
                   5180:        char *name;
                   5181: } *utab;
                   5182: 
                   5183: static int size, salloc;
                   5184: 
                   5185: char *
                   5186: uidstr (uid_t uid)
                   5187: {
                   5188:        register int i;
                   5189:        static char buf[12];
                   5190:        struct passwd *p;
                   5191: 
                   5192:        /* search the cache for the uid */
                   5193:        for (i = 0; i < size; i++)
                   5194:                if (utab[i].uid == uid)
                   5195:                        return utab[i].name;
                   5196: 
                   5197:        /* try to find it in the system's database */
                   5198:        if (p = getpwuid(uid)) {
                   5199:                if (size % CHUNK == 0)
                   5200:                        utab = (struct utab *) ralloc((char *) utab, salloc += CHUNK);
                   5201:                utab[size].uid = p->pw_uid;
                   5202:                utab[size].name = copy(p->pw_name);
                   5203:                ++size;
                   5204:                return utab[size - 1].name;
                   5205:        }
                   5206: 
                   5207:        /* failure, invent a string */
                   5208:        sprintf (buf, "#%u", uid);
                   5209:        return buf;
                   5210: }
                   5211: 
                   5212: uid_t
                   5213: uidnum (char *name)
                   5214: {
                   5215:        register int i;
                   5216:        struct passwd *p;
                   5217: 
                   5218:        /* if it starts with a #, use the number */
                   5219:        if (name[0] == '#')
                   5220:                return atoi (name + 1);
                   5221: 
                   5222:        /* try to find it in the system's database */
                   5223:        if (p = getpwnam(name)) {
                   5224:                if (size % CHUNK == 0)
                   5225:                        utab = (struct utab *) ralloc((char *) utab, salloc += CHUNK);
                   5226:                utab[size].uid = p->pw_uid;
                   5227:                utab[size].name = copy(p->pw_name);
                   5228:                ++size;
                   5229:                return utab[size - 1].uid;
                   5230:        }
                   5231: 
                   5232:        /* search the cache */
                   5233:        for (i = 0; i < size; i++)
                   5234:                if (strcmp (utab[i].name, name) == 0)
                   5235:                        return utab[i].uid;
                   5236: 
                   5237:        /* failure, invent a value */
                   5238:        return getuid();
                   5239: }
                   5240: #, use the number */
                   5241:        if (name[0] == '#')
                   5242:                return atoi (name + 1);
                   5243: 
                   5244:        /* try to find it in the system's database */
                   5245:        if (p = getpwnam(name)) {
                   5246:                if (size % CHUNK =pkg/unseal.c   644   3513      4       10352  5013610601   6332 /*
                   5247:  *     unseal - disclose and verify the contents of a sealed package
                   5248:  */
                   5249: 
                   5250: #include "asd.h"
                   5251: #include "seal.h"
                   5252: #include <ctype.h>
                   5253: #include <string.h>
                   5254: #include <unistd.h>
                   5255: 
                   5256: static FILE *outfd;
                   5257: static char outf[L_tmpnam];
                   5258: static char line[MAXULINE];
                   5259: 
                   5260: static unsigned long length, checksum;
                   5261: 
                   5262: static char *
                   5263: csverify (char *p, unsigned long value)
                   5264: {
                   5265:        register unsigned long n = 0;
                   5266: 
                   5267:        while (isspace (*p))
                   5268:                p++;
                   5269: 
                   5270:        if (!isdigit (*p))
                   5271:                return NULL;
                   5272: 
                   5273:        do      n = n * 10 + *p++ - '0';
                   5274:        while (isdigit (*p));
                   5275: 
                   5276:        if (!isspace (*p))
                   5277:                return NULL;
                   5278: 
                   5279:        if (n != value)
                   5280:                return NULL;
                   5281: 
                   5282:        return p;
                   5283: }
                   5284: 
                   5285: int
                   5286: docksum (char *line, unsigned long length, unsigned long checksum)
                   5287: {
                   5288:        register char *p = line + 5;
                   5289: 
                   5290:        p = csverify (p, length);
                   5291:        if (p == NULL) {
                   5292:                fprintf (stderr, "unseal: invalid length\n");
                   5293:                return 1;
                   5294:        }
                   5295:        p = csverify (p, checksum);
                   5296:        if (p == NULL) {
                   5297:                fprintf (stderr, "unseal: invalid checksum\n");
                   5298:                return 1;
                   5299:        }
                   5300:        return 0;
                   5301: }
                   5302: 
                   5303: static int
                   5304: unhex (int c)
                   5305: {
                   5306:        register char *p;
                   5307: 
                   5308:        p = hextab;
                   5309:        while (*p && *p != c)
                   5310:                p++;
                   5311:        if (*p)
                   5312:                return p - hextab;
                   5313:        return -1;
                   5314: }
                   5315: 
                   5316: static int
                   5317: hrout (char *line, char *out)
                   5318: {
                   5319:        register char *p, *q;
                   5320:        register int ch;
                   5321: 
                   5322:        p = line;
                   5323:        q = out;
                   5324: 
                   5325:        while ((ch = *p++) != '\0') {
                   5326:                if (ch != '\\') {
                   5327:                        *q++ = ch;
                   5328:                } else {
                   5329:                        ch = *p++;
                   5330:                        if (ch == '\\' || ch == '.' || ch == '!' || ch == 'F') {
                   5331:                                *q++ = ch;
                   5332:                        } else if (ch != '\n') {
                   5333:                                register int n = 0, i = 1;
                   5334: 
                   5335:                                do {
                   5336:                                        ch = unhex (ch);
                   5337:                                        if (ch < 0) {
                   5338:                                                fprintf (stderr,
                   5339:                                                        "bad hex char: %s", line);
                   5340:                                                return -1;
                   5341:                                        }
                   5342:                                        n = (n << 4) | ch;
                   5343:                                        if (i)
                   5344:                                                ch = *p++;
                   5345:                                } while (--i >= 0);
                   5346: 
                   5347:                                *q++ = n;
                   5348:                        }
                   5349:                }
                   5350:        }
                   5351: 
                   5352:        return q - out;
                   5353: }
                   5354: 
                   5355: static int
                   5356: mrout (char *line, char *out)
                   5357: {
                   5358:        register char *p = line + 1;
                   5359:        char *q = out;
                   5360: 
                   5361:        while (*p != '\n' && *p != '\0') {
                   5362:                register unsigned long bits;
                   5363:                register int n;
                   5364:                register char *rq;
                   5365: 
                   5366:                n = 0;
                   5367:                bits = 0;
                   5368:                do {
                   5369:                        register int ch = *p++;
                   5370:                        if (ch == '\n')
                   5371:                                break;
                   5372:                        if (ch < RADBASE || ch >= RADBASE + RADIX) {
                   5373:                                fprintf (stderr, "bad input char: %s", line);
                   5374:                                return -1;
                   5375:                        }
                   5376:                        bits = bits * RADIX + ch - RADBASE;
                   5377:                        n++;
                   5378:                } while (n < OUTCPW);
                   5379: 
                   5380:                n -= OUTCPW - INCPW;
                   5381:                if (n <= 0) {
                   5382:                        fprintf (stderr, "non-positive output count: %s", line);
                   5383:                        return -1;
                   5384:                }
                   5385: 
                   5386:                rq = q = q + n;
                   5387:                do {
                   5388:                        *--rq = bits;
                   5389:                        bits >>= BPC;
                   5390:                } while (--n > 0);
                   5391:        }
                   5392: 
                   5393:        return q - out;
                   5394: }
                   5395: 
                   5396: static int
                   5397: dodata (char *line)
                   5398: {
                   5399:        char out[MAXULINE * 2];
                   5400:        int r;
                   5401: 
                   5402:        r = (*(line[0] == '.'? mrout : hrout)) (line, out);
                   5403:        if (r < 0)
                   5404:                return 1;
                   5405:        fwrite (out, sizeof(*out), r, outfd);
                   5406:        length += r;
                   5407: 
                   5408:        if (kflag || Kflag)
                   5409:                mangle (out, out + r);
                   5410: 
                   5411:        checksum = mkcsum (checksum, out, out + r);
                   5412: 
                   5413:        return 0;
                   5414: }
                   5415: 
                   5416: static int
                   5417: unseal (FILE *f, char *fname)
                   5418: {
                   5419:        int intext = 0, rc = 0, nulltext = 1;
                   5420: 
                   5421:        length = checksum = 0;
                   5422:        resetN12();
                   5423: 
                   5424:        while (fgets (line, MAXULINE, f) != NULL) {
                   5425: 
                   5426:                /* check for a control line, which starts with "!" */
                   5427:                if (line[0] == '!') {
                   5428:                        if (intext) {
                   5429:                                /* only thing allowed is !end */
                   5430:                                if (strncmp (line + 1, "end ", 4) == 0) {
                   5431:                                        rc += docksum (line, length, checksum);
                   5432:                                        intext = 0;
                   5433:                                } else {
                   5434:                                        fprintf (stderr, "invalid control line %s", line);
                   5435:                                        rc++;
                   5436:                                }
                   5437:                        } else {
                   5438:                                /* look for header, else quietly ignore */
                   5439:                                if (strcmp (line + 1, "<seal>\n") == 0) {
                   5440:                                        intext++;
                   5441:                                        nulltext = 0;
                   5442:                                }
                   5443:                        }
                   5444:                /* data lines are quietly ignored if not in text */
                   5445:                } else if (intext) {
                   5446:                        rc += dodata (line);
                   5447:                }
                   5448:        }
                   5449: 
                   5450:        if (nulltext) {
                   5451:                fprintf (stderr, "unseal: no contents\n");
                   5452:                rc++;
                   5453:        }
                   5454: 
                   5455:        if (intext) {
                   5456:                fprintf (stderr, "unseal: no checksum\n");
                   5457:                rc++;
                   5458:        }
                   5459: 
                   5460:        return rc;
                   5461: }
                   5462: 
                   5463: int
                   5464: main (int argc, char **argv)
                   5465: {
                   5466:        int rc = 0;
                   5467:        int c;
                   5468:        static char stdbuf[BUFSIZ];
                   5469: 
                   5470:        setbuf (stdout, stdbuf);
                   5471: 
                   5472:        umask (077);
                   5473:        tmpnam (outf);
                   5474:        outfd = fopen (outf, "w+");
                   5475:        if (outfd == NULL) {
                   5476:                fprintf (stderr, "unseal: can't create temp file\n");
                   5477:                exit (1);
                   5478:        }
                   5479: 
                   5480:        /* don't leave dregs */
                   5481:        unlink (outf);
                   5482: 
                   5483:        rc = getargs (argc, argv, "kK:", unseal);
                   5484:        
                   5485:        /* if successful, copy the temp file to the output */
                   5486:        if (rc == 0) {
                   5487:                register FILE *in = outfd, *out = stdout;
                   5488:                register int ch;
                   5489: 
                   5490:                rewind (in);
                   5491: 
                   5492:                while ((ch = getc (in)) != EOF)
                   5493:                        putc (ch, out);
                   5494:                
                   5495:                fflush (out);
                   5496:                
                   5497:                if (ferror (in)) {
                   5498:                        fprintf (stderr, "unseal: error reading temp file\n");
                   5499:                        rc++;
                   5500:                }
                   5501: 
                   5502:                if (ferror (out)) {
                   5503:                        fprintf (stderr, "unseal: error writing stdout\n");
                   5504:                        rc++;
                   5505:                }
                   5506:        }
                   5507: 
                   5508:        return rc;
                   5509: }
                   5510: * don't leave dregs */
                   5511:        unlink (outf);
                   5512: 
                   5513:        rc = getargs (argc, argv, "kK:", unseal);
                   5514:        
                   5515:        /* if successful, copy the temp file to the output */
                   5516:        if (rc == 0) {
                   5517:                register FILE *in = outfd, *out = stdout;
                   5518:                register int ch;
                   5519: 
                   5520:                rewind (in);
                   5521: 
                   5522:                while ((ch = getc (in)) != EOF)
                   5523:                        putc pkg/libx.a   644   3513      4          44  5013644572   5732 674187646   f (ferror (in)) {
                   5524:                        fprintf (stderr, "unseal: error reading temp file\n");
                   5525:                        rc++;
                   5526:                }
                   5527: 
                   5528:                if (ferror (out)) {
                   5529:                        fprintf (stderr, "unseal: error writing stdout\n");
                   5530:                        rc++;
                   5531:                }
                   5532:        }
                   5533: 
                   5534:        return rc;
                   5535: }
                   5536: * don't leave dregs */
                   5537:        unlink (outf);
                   5538: 
                   5539:        rc = getargs (argc, argv, "kK:", unseal);
                   5540:        
                   5541:        /* if successful, copy the temp file to the output */
                   5542:        if (rc == 0) {
                   5543:                register FILE *in = outfd, *out = stdout;
                   5544:                register int ch;
                   5545: 
                   5546:                rewind (in);
                   5547: 
                   5548:                while ((ch = getc (in)) != EOF)
                   5549:                        putc pkg/INSTRUCTIONS   644   3513      4        2022  5027730714   6556 The format of the Instructions file in a package archive
                   5550: is as follows.
                   5551: 
                   5552: Each instruction is a line by itself.  Each instruction consists of a
                   5553: single character instruction code followed by a number of fields.  Fields
                   5554: do not contain spaces.
                   5555: 
                   5556: Various standard kinds of fields are:
                   5557: <command>              shell command (via putpath())
                   5558: <component>            archive component name (via putpath())
                   5559: <mode>                 octal permissions
                   5560: <dmajor>, <dminor>     major and minor decimal device numbers
                   5561: <uid>, <gid>           user and group names (via putpath())
                   5562: <path>                 path name (via putpath())
                   5563: 
                   5564: b <mode> <dmajor> <dminor> <uid> <gid> <path>
                   5565:        block device
                   5566: c <mode> <dmajor> <dminor> <uid> <gid> <path>
                   5567:        character device
                   5568: d <mode> <uid> <gid> <path>
                   5569:        directory
                   5570: f <component> <uid> <gid> <path>
                   5571:        ordinary file (rest of the information is in the archive component)
                   5572: l <path1> <path2>
                   5573:        hard link -- <path2> is the link to be created.
                   5574: s <path1> <path2>
                   5575:        symbolic link -- <path2> is the link to be created.
                   5576: r <path>
                   5577:        file to be removed
                   5578: x <command>
                   5579:        command to be executed
                   5580: X <path>
                   5581:        file to be executed
                   5582: a putpath())
                   5583: 
                   5584: b <mode> <dmajor> <dminor> <uid> <gid> <path>
                   5585:        block device
                   5586: c <mode> <dmajor> <dminor> <uid> <gid> <path>
                   5587:        character device
                   5588: d <mode> <uid> <gid> <path>
                   5589:        directory
                   5590: f <component> <uid> <gid> <path>
                   5591:        ordinary file (rest of the information is in the archive component)
                   5592: l <path1> <path2>
                   5593:        hard link -- <path2> is the link to be created.
                   5594: s <path1> <path2>
                   5595:        symbolic link -- <path2> is the link to be created.
                   5596: r <path>
                   5597:        file to be removed
                   5598: x <command>
                   5599:        command to be executed
                   5600: X <path>
                   5601:        fipkg/ftw.c   644   3513      4       24531  5031452625   5661 /*
                   5602:  *     ftw - file tree walk
                   5603:  *
                   5604:  *     int ftw (path, fn, depth)  char *path; int (*fn)(); int depth;
                   5605:  *
                   5606:  *     Given a path name, ftw starts from the file given by that path
                   5607:  *     name and visits each file and directory in the tree beneath
                   5608:  *     that file.  If a single file has multiple links within the
                   5609:  *     structure, it will be visited once for each such link.
                   5610:  *     For each object visited, fn is called with four arguments.
                   5611:  *     The fourth can often be ignored; it is a pointer, say S,
                   5612:  *     declared "struct FTW *S", discussed in more detail below.
                   5613:  *     The first contains the path name of the object, the second
                   5614:  *     contains a pointer to a stat buffer which will usually hold
                   5615:  *     appropriate information for the object and the third contains
                   5616:  *     an integer value giving additional information about the
                   5617:  *     object, as follows:
                   5618:  *
                   5619:  *             FTW_F   The object is a file for which stat was
                   5620:  *                     successful.  It does not guarantee that the
                   5621:  *                     file can actually be read.
                   5622:  *
                   5623:  *             FTW_D   The object is a directory for which stat and
                   5624:  *                     open for read were both successful.  This is
                   5625:  *                     a preorder visit -- objects in the directory
                   5626:  *                     are yet to be visited.
                   5627:  *
                   5628:  *             FTW_DNR The object is a directory for which stat
                   5629:  *                     succeeded, but which cannot be read.  Because
                   5630:  *                     the directory cannot be read, fn will not be
                   5631:  *                     called for any descendants of this directory.
                   5632:  *
                   5633:  *             FTW_DP  The object is a directory for which stat and
                   5634:  *                     open for read were both successful.  This is
                   5635:  *                     a postorder visit -- everything in the directory
                   5636:  *                     has already been visited.
                   5637:  *
                   5638:  *             FTW_NS  Lstat failed on the object.  If errno is EACCES,
                   5639:  *                     then the failure stems from lack of
                   5640:  *                     appropriate permission.  This indication will
                   5641:  *                     be given, for example, for each file in a directory
                   5642:  *                     with read but no execute permission.  Whenever
                   5643:  *                     stat fails, it is not possible to determine
                   5644:  *                     whether this object is a file or a directory.
                   5645:  *                     The stat buffer passed to fn will contain garbage.
                   5646:  *
                   5647:  *             FTW_SL  The object is a symbolic link.  Set S->quit
                   5648:  *                     (a component of the structure pointed to by
                   5649:  *                     the fourth parameter to fn) to FTW_FOLLOW to
                   5650:  *                     have the link followed and the object to which
                   5651:  *                     it points visited.
                   5652:  *
                   5653:  *             FTW_NSL Lstat succeeded, but stat failed on the object.
                   5654:  *                     This is only possible when following a symbolic
                   5655:  *                     link.
                   5656:  *
                   5657:  *     Among the components of the structure to which the fourth
                   5658:  *     parameter, S, to fn points is S->quit.  If the caller sets
                   5659:  *     S->quit to FTW_SKR, then no more files in the current directory
                   5660:  *     will be visited.  (The current directory is the one containing
                   5661:  *     the object being visited.)  If the third parameter to fn is
                   5662:  *     FTW_D and the caller sets S->quit to FTW_SKD, then this directory
                   5663:  *     (the one named in the first parameter to fn) will be skipped.
                   5664:  *
                   5665:  *     Other components pointed to by the fourth parameter S are
                   5666:  *     the current recursion level S->level (top level = 0) and
                   5667:  *     the offset S->base in the pathname of the current object
                   5668:  *     (the first parameter to fn) of the object's base name.
                   5669:  *     By expanding the definition of struct FTW given below and
                   5670:  *     including the files included below, one can arrange for
                   5671:  *     S to point to a larger structure, components of which can
                   5672:  *     be initialized (for example) on calls to fn with third
                   5673:  *     parameter FTW_D.
                   5674:  *
                   5675:  *     If fn returns nonzero, ftw stops and returns the same value
                   5676:  *     to its caller.  Ftw only initiates a nonzero return if malloc
                   5677:  *     fails; in this case ftw sets errno to ENOMEM and returns -1.
                   5678:  *
                   5679:  *     The third argument to ftw does not limit the depth to which
                   5680:  *     ftw will go.  Rather, it limits the depth to which ftw will
                   5681:  *     go before it starts recycling file descriptors.  In general,
                   5682:  *     it is necessary to use a file descriptor for each level of the
                   5683:  *     tree, but they can be recycled for deep trees by saving the position,
                   5684:  *     closing, re-opening, and seeking.  It is possible to start
                   5685:  *     recycling file descriptors by sensing when we have run out, but
                   5686:  *     in general this will not be terribly useful if fn expects to be
                   5687:  *     able to open files.  We could also figure out how many file descriptors
                   5688:  *     are available and guarantee a certain number to fn, but we would not
                   5689:  *     know how many to guarantee, and we do not want to impose the extra
                   5690:  *     overhead on a caller who knows how many are available without
                   5691:  *     having to figure it out.
                   5692:  *
                   5693:  *     It is possible for ftw to die with a memory fault in the event
                   5694:  *     of a file system so deeply nested that the stack overflows.
                   5695:  */
                   5696: 
                   5697: #include <sys/types.h>
                   5698: #include <dirent.h>
                   5699: #include <sys/stat.h>
                   5700: #include "ftw.h"
                   5701: /*
                   5702:  * Struct FTW (whose definition starts at the end of ftw.h) must
                   5703:  * must include at least the integers quit, base, and level.
                   5704:  */
                   5705: 
                   5706: #define FTW_PATHLEN0 1000
                   5707: #define FTW_PATHINC 1000
                   5708: 
                   5709: #ifndef S_ISLNK
                   5710: #define lstat stat
                   5711: #endif
                   5712: 
                   5713: #ifndef ENOMEM
                   5714: #include <errno.h>
                   5715: #endif
                   5716: 
                   5717:        extern int errno;
                   5718: 
                   5719: /*
                   5720:  *  Each generation of ftw1 (the real ftw) allocates one copy, R, of the
                   5721:  *  following structure; it passes a pointer to this structure when it
                   5722:  *  recursively invokes itself.  These structures are chained together,
                   5723:  *  so that if it becomes necessary to recycle file descriptors, then
                   5724:  *  the oldest descriptor (the one at the shallowest depth still open)
                   5725:  *  can be recycled.
                   5726:  */
                   5727: 
                   5728:        struct FTW_rec {
                   5729:                struct FTW_rec *prev;
                   5730:                long here;      /* seek to here when reopening at this level */
                   5731:                DIR *fd;        /* file descriptor at this level */
                   5732:                };
                   5733: 
                   5734: /*
                   5735:  *  One instance, T, of the following structure is allocated by ftw; a
                   5736:  *  pointer to it is passed to all generations of ftw1 (the real ftw).
                   5737:  *  T could often be a global variable, but this way the parameter fn
                   5738:  *  can invoke ftw for an independent tree walk.
                   5739:  *  Component T->path points to storage for the object path-names;
                   5740:  *  this storage may be relocated by realloc if T->path needs to be
                   5741:  *  more than T->pathlast characters long.
                   5742:  *  T->path[T->pathnext] is the next free character in the pathnames.
                   5743:  *  T->depth = parameter depth to ftw.  T->lastout is the deepest level at
                   5744:  *  which a file descriptor has been recycled.
                   5745:  */
                   5746: 
                   5747:        struct FTW_top {
                   5748:                int (*fn)();
                   5749:                char *path;
                   5750:                unsigned pathlast, pathnext;
                   5751:                int lastout;
                   5752:                int depth;
                   5753:                };
                   5754: 
                   5755: static ftw_1_();
                   5756: 
                   5757: int
                   5758: ftw (path, fn, depth)
                   5759:        char *path;
                   5760:        int (*fn)();
                   5761:        int depth;
                   5762: {
                   5763:        struct FTW_top T;
                   5764:        struct FTW_rec R;
                   5765:        struct FTW S;
                   5766:        int rc;
                   5767:        char *malloc(), *strcpy();
                   5768: 
                   5769:        T.depth = depth;
                   5770:        T.lastout = -1;
                   5771:        T.fn = fn;
                   5772:        S.quit = 0;
                   5773:        S.level = -1;
                   5774: 
                   5775:        /* initialize S.base, T.pathnext... */
                   5776:                {
                   5777:                register char c, *p, *q;
                   5778:                for (p = q = path; c = *p; p++) if (c == '/') q = p + 1;
                   5779:                S.base = q - path;
                   5780:                T.pathnext = p - path;
                   5781:                }
                   5782: 
                   5783:        T.pathlast = T.pathnext + FTW_PATHLEN0;
                   5784:        T.path = malloc(T.pathlast);
                   5785:        if (!T.path) { errno = ENOMEM; return -1; }
                   5786:        strcpy(T.path, path);
                   5787:        rc = ftw_1_(&R, &T, 0, &S);
                   5788:        free(T.path);
                   5789:        return rc;
                   5790: }
                   5791: 
                   5792: int
                   5793: static
                   5794: ftw_1_ (R, T, level, S1)
                   5795:        register struct FTW_rec *R;
                   5796:        register struct FTW_top *T;
                   5797:        int level;
                   5798:        struct FTW *S1;
                   5799: {
                   5800:        int rc, n;
                   5801:        DIR *fd;
                   5802:        struct dirent *dirp;
                   5803:        char *component, *path;
                   5804:        struct stat sb;
                   5805:        struct FTW_rec mr;
                   5806:        unsigned nextsave;
                   5807:        struct FTW S;
                   5808:        char *realloc();
                   5809:        long lseek();
                   5810: 
                   5811:        mr.prev = R;
                   5812:        path = T->path;
                   5813:        S.level = level;
                   5814:        S.quit = 0;
                   5815:        S.base = S1->base;
                   5816: 
                   5817:        /* Try to get file status.  If unsuccessful, errno will say why. */
                   5818:        if (lstat(path, &sb) < 0) {
                   5819:                rc = (*T->fn) (path, &sb, FTW_NS, &S);
                   5820:                S1->quit = S.quit;
                   5821:                return rc;
                   5822:                };
                   5823: 
                   5824:        /*
                   5825:         *      The stat succeeded, so we know the object exists.
                   5826:         *      If not a directory, call the user function and return.
                   5827:         */
                   5828: #ifdef S_ISLNK
                   5829:        if (S_ISLNK(sb.st_mode )) {
                   5830:                rc = (*T->fn) (path, &sb, FTW_SL, &S);
                   5831:                S1->quit = S.quit;
                   5832:                if (rc || S.quit == FTW_SKR) return rc;
                   5833:                if (S.quit != FTW_FOLLOW) return 0;
                   5834:                S1->quit = S.quit = 0;
                   5835:                if (stat(path, &sb) < 0) {
                   5836:                        rc = (*T->fn) (path, &sb, FTW_NSL, &S);
                   5837:                        S1->quit = S.quit;
                   5838:                        return rc;
                   5839:                        };
                   5840:                }
                   5841: #endif
                   5842:                
                   5843:        if (!S_ISDIR(sb.st_mode)) {
                   5844:                rc = (*T->fn) (path, &sb, FTW_F, &S);
                   5845:                S1->quit = S.quit;
                   5846:                return rc;
                   5847:                }
                   5848: 
                   5849:        /*
                   5850:         *      The object was a directory.
                   5851:         *
                   5852:         *      Open a file to read the directory
                   5853:         */
                   5854:        mr.fd = fd = opendir(path);
                   5855: 
                   5856:        /*
                   5857:         *      Call the user function, telling it whether
                   5858:         *      the directory can be read.  If it can't be read
                   5859:         *      call the user function or indicate an error,
                   5860:         *      depending on the reason it couldn't be read.
                   5861:         */
                   5862:        if (!fd) {
                   5863:                rc = (*T->fn) (path, &sb, FTW_DNR, &S);
                   5864:                S1->quit = S.quit;
                   5865:                return rc;
                   5866:                }
                   5867: 
                   5868:        /* We could read the directory.  Call user function. */
                   5869:        rc = (*T->fn) (path, &sb, FTW_D, &S);
                   5870:        if (rc != 0)
                   5871:                goto rtrn;
                   5872:        if (S.quit == FTW_SKD) goto rtrn;
                   5873:        if (S.quit == FTW_SKR) {S1->quit = FTW_SKR; goto rtrn;}
                   5874: 
                   5875:        /* Make sure path is big enough to hold generated pathnames. */
                   5876: 
                   5877:        n = nextsave = T->pathnext;
                   5878:        if (n + MAXNAMLEN + 1 >= T->pathlast) {
                   5879:                T->pathlast += FTW_PATHINC;
                   5880:                path = T->path = realloc(T->path, T->pathlast);
                   5881:                if (!path) {
                   5882:                        errno = ENOMEM;
                   5883:                        rc = -1;
                   5884:                        goto rtrn;
                   5885:                        }
                   5886:                }
                   5887:        
                   5888:        /* Create a prefix to which we will append component names */
                   5889: 
                   5890:        if (n > 0 && path[n-1] != '/') path[n++] = '/';
                   5891:        component = path + n;
                   5892: 
                   5893:        /*
                   5894:         *      Read the directory one component at a time.
                   5895:         *      We must ignore "." and "..", but other than that,
                   5896:         *      just create a path name and call self to check it out.
                   5897:         */
                   5898:        while (dirp = readdir(fd)) {
                   5899:                if (dirp->d_ino != 0
                   5900:                    && strcmp (dirp->d_name, ".") != 0
                   5901:                    && strcmp (dirp->d_name, "..") != 0) {
                   5902:                        int i;
                   5903:                        struct FTW_rec *pr;
                   5904: 
                   5905:                        /* Append the component name to the working path */
                   5906:                        strcpy(component, dirp->d_name);
                   5907:                        T->pathnext = n + strlen(dirp->d_name);
                   5908: 
                   5909:                        /*
                   5910:                         *      If we are about to exceed our depth,
                   5911:                         *      remember where we are and close the file.
                   5912:                         */
                   5913:                        if (level - T->lastout >= T->depth) {
                   5914:                                pr = &mr;
                   5915:                                i = T->lastout++;
                   5916:                                while (++i < level) pr = pr->prev;
                   5917:                                pr->here = telldir(pr->fd);
                   5918:                                closedir(pr->fd);
                   5919:                        }
                   5920: 
                   5921:                        /*
                   5922:                         *      Do a recursive call to process the file.
                   5923:                         */
                   5924:                        S.quit = 0;
                   5925:                        S.base = n;
                   5926:                        rc = ftw_1_(&mr, T, level+1, &S);
                   5927:                        if (rc != 0 || S.quit == FTW_SKR) {
                   5928:                                if (level > T->lastout) closedir(fd);
                   5929:                                T->pathnext = nextsave;
                   5930:                                return rc;
                   5931:                        }
                   5932: 
                   5933:                        /*
                   5934:                         *      If we closed the file, try to reopen it.
                   5935:                         */
                   5936:                        if (level <= T->lastout) {
                   5937:                                char c = path[nextsave];
                   5938:                                path[nextsave] = 0;
                   5939:                                T->lastout = level - 1;
                   5940:                                mr.fd = fd = opendir(path);
                   5941:                                if (!fd) {
                   5942:                                        rc = (*T->fn) (path, &sb, FTW_DNR, &S);
                   5943:                                        S1->quit = S.quit;
                   5944:                                        T->pathnext = nextsave;
                   5945:                                        return rc;
                   5946:                                        }
                   5947:                                path[nextsave] = c;
                   5948:                                seekdir(fd, mr.here);
                   5949:                                }
                   5950:                        }
                   5951:                }
                   5952:        T->pathnext = nextsave;
                   5953:        path[nextsave] = 0;
                   5954: 
                   5955:        /*
                   5956:         *      We got out of the subdirectory loop.  Call the user
                   5957:         *      function again at the end and clean up.
                   5958:         */
                   5959: 
                   5960:        rc = (*T->fn) (path, &sb, FTW_DP, &S);
                   5961:        S1->quit = S.quit;
                   5962: rtrn:
                   5963:        closedir(fd);
                   5964:        return rc;
                   5965: }
                   5966:                        T->lastout = level - 1;
                   5967:                                mr.fd = fd = opendir(path);
                   5968:                                if (!fd) {
                   5969:                                        rc = (*T->fn) (path, &sb, FTW_DNR, &S);
                   5970:                                        S1->quit = S.quit;
                   5971:                                        T->pathnext = nextspkg/ftw.h   644   3513      4        1462  5031452570   5643 #ifndef __FTW
                   5972: #define __FTW
                   5973: 
                   5974: /*
                   5975:  *     Codes for the third argument to the user-supplied function
                   5976:  *     which is passed as the second argument to ftw...
                   5977:  */
                   5978: 
                   5979: #define        FTW_F   0       /* file */
                   5980: #define        FTW_D   1       /* directory */
                   5981: #define        FTW_DNR 2       /* directory without read permission */
                   5982: #define        FTW_NS  3       /* unknown type, stat failed */
                   5983: #define FTW_DP 4       /* directory, postorder visit */
                   5984: #define FTW_SL 5       /* symbolic link */
                   5985: #define FTW_NSL 6      /* stat failed (errno = ENOENT) on symbolic link */
                   5986: 
                   5987: /*     Values the user-supplied function may wish to assign to
                   5988:        component quit of struct FTW...
                   5989:  */
                   5990: 
                   5991: #define FTW_SKD 1      /* skip this directory (2nd par = FTW_D) */
                   5992: #define FTW_SKR 2      /* skip rest of current directory */
                   5993: #define FTW_FOLLOW 3   /* follow symbolic link */
                   5994: 
                   5995: struct FTW { int quit, base, level;
                   5996: #ifndef FTW_more_to_come
                   5997:        };
                   5998: #endif
                   5999: 
                   6000: #endif
                   6001:  failed */
                   6002: #define FTW_DP 4       /* directory, postorder visit */
                   6003: #define FTW_SL 5       /* symbolic link */
                   6004: #define FTW_NSL 6      /* stat failed (errno = ENOENT) on symbolic link */
                   6005: 
                   6006: /*     Values the user-supplied function plan9/   755   3513      4           0  5031450043   5035 sysv/   755   3513      4           0  5031457617   5034 sysv/lcreat.c   644   3513      4         172  5031151403   6477 #include <fcntl.h>
                   6007: 
                   6008: int
                   6009: lcreat(char *name, int mode)
                   6010: {
                   6011:        return open(name, O_EXCL | O_CREAT | O_TRUNC | O_WRONLY, mode);
                   6012: }
                   6013: #define �<     �< ����9 of 05031457617ctory �<  ����9_FOL00000005034low symbolic link */
                   6014: 
                   6015: struct FTW { int quit, base, level;
                   6016: #ifndef FTW_more_to_come
                   6017:        };
                   6018: #endif
                   6019: 
                   6020: #endif
                   6021:  failed */
                   6022: #define FTW_DP 4       /* directory, postorder visit */
                   6023: #define FTW_SL 5       /* symbolink */
                   6024: ����/������D5&����/����D5��&e�#�����.$����$e�sysv/canon.c   644   3513      4         531  5031141175   6327 #include <string.h>
                   6025: 
                   6026: /* reduce tcp and dk names to their final component */
                   6027: void
                   6028: canon(char *sys, char cansys[])
                   6029: {
                   6030:        if (strncmp(sys, "dk!", 3) == 0)
                   6031:                sys += 3;
                   6032:        if (strncmp(sys, "tcp!", 4) == 0)
                   6033:                sys += 4;
                   6034:        if (strrchr(sys, '/'))
                   6035:                sys = strrchr(sys, '/') + 1;
                   6036:        strcpy(cansys, sys);
                   6037:        if (strrchr(cansys, '.'))
                   6038:                *strchr(cansys, '.') = '\0';
                   6039: }
                   6040: y, postorder visit */
                   6041: #define FTW_SL 5       /* symbolink */
                   6042: ����/������D5&����/����D5��&e�#�����.$����$e�sysv/canonmain.c   644   3513      4         176  5031141232   7173 main(int argc, char **argv)
                   6043: {
                   6044:        char cansys[256];
                   6045: 
                   6046:        while (--argc) {
                   6047:                canon(*++argv, cansys);
                   6048:                puts(cansys);
                   6049:        }
                   6050:        return 0;
                   6051: }
                   6052: p(sys, "dk!", 3) == 0)
                   6053:                sys += 3;
                   6054:        if (strncmp(sys, "tcp!", 4) == 0)
                   6055:                sys += 4;
                   6056:        if (strrchr(sys, '/'))
                   6057:                sys = strrchr(sys, '/') + 1;
                   6058:        strcpy(cansys, sys);
                   6059:        if (strrchr(cansys, '.'))
                   6060:                *strchr(cansys, '.') = '\0';
                   6061: }
                   6062: y, postorder visit */
                   6063: #define FTW_SL 5       /* symbolink */
                   6064: ����/������D5&����/����D5��&e�#�����.$����$e�sysv/connect.c   644   3513      4        3221  5031146510   6677 /* usage: connect hostname (answer|send|notice) (in|out) program [ args ... ] */
                   6065: /* TODO: should librarify the bit for opening an rsh-authenticated connection.  */
                   6066: 
                   6067: #include <sys/types.h>
                   6068: #include <sys/socket.h>
                   6069: #include <netinet/in.h>
                   6070: #include <netdb.h>
                   6071: #include <pwd.h>
                   6072: #include <stdio.h>
                   6073: #include <string.h>
                   6074: #include "../paths.h"
                   6075: 
                   6076: int
                   6077: main(int argc, char *argv[])
                   6078: {
                   6079:        int fd;
                   6080:        struct hostent *host;
                   6081:        struct servent *serv;
                   6082:        struct passwd *pw;
                   6083:        int lport;
                   6084:        struct sockaddr_in sin;
                   6085:        char byte;
                   6086: 
                   6087:        if (argc < 5)
                   6088:                exit(1);
                   6089: 
                   6090:        host = gethostbyname(argv[1]);
                   6091:        if (!host) {
                   6092:                fprintf(stderr, "connect: can't get host '%s'\n", argv[1]);
                   6093:                exit(1);
                   6094:        }
                   6095: 
                   6096:        serv = getservbyname("dist", "tcp");
                   6097:        if (!serv) {
                   6098:                fprintf(stderr, "connect: can't get 'dist' port number\n");
                   6099:                exit(1);
                   6100:        }
                   6101: 
                   6102:        pw = getpwuid(getuid());        /* we assume unique uid/name map */
                   6103:        if (!pw) {
                   6104:                fprintf(stderr, "connect: can't get user name\n");
                   6105:                exit(1);
                   6106:        }
                   6107: 
                   6108:        chdir(LDIR);
                   6109: 
                   6110:        lport = 1023;
                   6111:        fd = rresvport(&lport);
                   6112:        if (fd < 0) {
                   6113:                perror("connect: getting socket");
                   6114:                exit(1);
                   6115:        }
                   6116: 
                   6117:        sin.sin_family = host->h_addrtype;
                   6118:        memcpy(&sin.sin_addr, host->h_addr, host->h_length);
                   6119:        sin.sin_port = serv->s_port;
                   6120:        if (connect(fd, &sin, sizeof sin) < 0) {
                   6121:                perror("connect: opening connection");
                   6122:                exit(1);
                   6123:        }
                   6124: 
                   6125:        write(fd, "", 1);       /* a NUL byte */
                   6126:        write(fd, pw->pw_name, strlen(pw->pw_name) + 1);
                   6127:        write(fd, pw->pw_name, strlen(pw->pw_name) + 1);
                   6128:        if (read(fd, &byte, 1) != 1 || byte != '\0') {
                   6129:                fprintf(stderr, "connect: rsh authentication failed\n");
                   6130:                exit(1);
                   6131:        }
                   6132: 
                   6133:        write(fd, argv[2], strlen(argv[2]) + 1);
                   6134: 
                   6135:        if (strchr(argv[3], 'i'))
                   6136:                dup2(fd, 0);
                   6137:        if (strchr(argv[3], 'o'))
                   6138:                dup2(fd, 1);
                   6139:        close(fd);
                   6140:        execv(argv[4], &argv[4]);
                   6141: }
                   6142: (fd, &sin, sizeof sin) < 0) {
                   6143:                perror("connect: opening connection");
                   6144:                exit(1);
                   6145:        }
                   6146: 
                   6147:        write(fd, "", 1);       /* a NUL byte */
                   6148:        write(fd, pw->pw_name, strlen(pw->pw_name) + 1);
                   6149:        write(fd, pw->pw_name, strlen(pw->pw_name) + 1);
                   6150:        if (read(fd, &byte, 1) != 1 || byte != '\0') {
                   6151:                fprintf(stderr, "connect: rsh authentication failed\n");
                   6152:                exit(1);
                   6153:        }
                   6154: 
                   6155:        write(fd, argv[2], strsysv/dispatch.c   644   3513      4        1700  5031146670   7054 /* usage: dispatch <ipc args> */
                   6156: /* TODO: connect input to /dev/null if peer wants no output,
                   6157:    connect output to logfile if peer wants no input.  */
                   6158: 
                   6159: #include <sys/types.h>
                   6160: #include <sys/sockets.h>
                   6161: #include <netinet/in.h>
                   6162: #include <netdb.h>
                   6163: #include <string.h>
                   6164: #include "../paths.h"
                   6165: 
                   6166: int
                   6167: main(int argc, char *argv[])
                   6168: {
                   6169:        char c, d;
                   6170:        char *args[3];
                   6171:        int fd;
                   6172: 
                   6173:        if (chdir(LDIR) < 0)
                   6174:                return 1;
                   6175: 
                   6176:        /* TODO: at this point, perform rshd style authentication check,
                   6177:           set the appropriate user id, and all that.  See what kind of
                   6178:           args we can get from inetd.  */
                   6179: 
                   6180:        if (read(0, &c, 1) != 1)
                   6181:                return 1;
                   6182:        do
                   6183:                if (read(0, &d, 1) != 1)
                   6184:                        return 1;
                   6185:        while (d);
                   6186: 
                   6187:        fd = open("/dev/null", 1);
                   6188:        dup2(fd, 2);
                   6189:        if (fd > 2)
                   6190:                close(fd);
                   6191: 
                   6192:        switch (c) {
                   6193:        case 's':
                   6194:                args[0] = "showq";
                   6195:                execv("showq", args);
                   6196:                break;
                   6197:        case 't':
                   6198:                args[0] = "transmit";
                   6199:                execv("transmit", args);
                   6200:                break;
                   6201:        case 'n':
                   6202:                args[0] = "notice";
                   6203:                execv("notice", args);
                   6204:                break;
                   6205:        }
                   6206: 
                   6207:        return 1;
                   6208: }
                   6209: tion check,
                   6210:           set the appropriate user id, and all that.  See sysv/mkfile   644   3513      4        1012  5031452776   6306 <../mkconf.sysv
                   6211: 
                   6212: CC=cc
                   6213: LPROG=connect canon #dispatch
                   6214: LIBS=lib.a
                   6215: LIBOBJ=canon.o lcreat.o
                   6216: 
                   6217: %: %.sh
                   6218:        cp $stem.sh $target
                   6219:        chmod +x $target
                   6220: 
                   6221: connect: connect.o
                   6222:        $CC $CFLAGS -o connect connect.o
                   6223: 
                   6224: dispatch: dispatch.o
                   6225:        $CC $CFLAGS -o dispatch dispatch.o
                   6226: 
                   6227: canon: canonmain.o lib.a
                   6228:        $CC $CFLAGS -o canon canonmain.o lib.a
                   6229: 
                   6230: compile:V: $LPROG $LIBS
                   6231: 
                   6232: install:V:
                   6233:        test -d $LDIR || mkdir $LDIR
                   6234:        cp $LPROG $LDIR
                   6235:        chown root $LDIR/connect && chmod 4755 $LDIR/connect
                   6236: 
                   6237: lib.a: $LIBOBJ
                   6238:        ar r lib.a $LIBOBJ
                   6239: 
                   6240: clean:V:
                   6241:        rm -f $LPROG $LIBS *.o
                   6242: .sysv
                   6243: 
                   6244: CC=cc
                   6245: LPROG=connect canon #dispatch
                   6246: LIBS=lib.a
                   6247: LIBOBJ=canon.o lcreat.o
                   6248: 
                   6249: %: %.sh
                   6250:        cp $stem.sh $target
                   6251:        chmod +x $target
                   6252: 
                   6253: connect: connect.o
                   6254:        $CC $CFLAGS -o connect connect.o
                   6255: 
                   6256: dispatch: dispatch.o
                   6257:        $CC $CFLAGS -o dispatch dispatch.o
                   6258: 
                   6259: canon: canonmain.o lib.a
                   6260:        $CC $CFLAGS -o canon canonmain.o lib.a
                   6261: 
                   6262: compile:V: $LPROG $LIBS
                   6263: 
                   6264: install:V:
                   6265:        test -d $LDIR || mkdir $LDIR
                   6266:        cp $LPROG $LDIR
                   6267:        chown root $LDIR/connect && chmod 4755 $LDIR/connect
                   6268: 
                   6269: lib.a: $LIBOBJ
                   6270:        ar r lib.a $LIBOBJ
                   6271: 
                   6272: clean:V:
                   6273:        rm -f $LPROG sysv/libv.h   644   3513      4          50  5031457617   6161 extern int optind;
                   6274: extern char *optarg;
                   6275: on #dispatch
                   6276: LIBS=lib.a
                   6277: LIBOBJ=canon.o lcreat.o
                   6278: 
                   6279: %: %.sh
                   6280:        cp $stem.sh $target
                   6281:        chmod +x $target
                   6282: 
                   6283: connect: connect.o
                   6284:        $CC $CFLAGS -o connect connect.o
                   6285: 
                   6286: dispatch: dispatch.o
                   6287:        $CC $CFLAGS -o dispatch dispatch.o
                   6288: 
                   6289: canon: canonmain.o lib.a
                   6290:        $CC $CFLAGS -o canon canonmain.o lib.a
                   6291: 
                   6292: compile:V: $LPROG $LIBS
                   6293: 
                   6294: install:V:
                   6295:        test -d $LDIR || mkdir $LDIR
                   6296:        cp $LPROG $LDIR
                   6297:        chown root $LDIR/connect && chmod 4755 $LDIR/connect
                   6298: 
                   6299: lib.a: $LIBOBJ
                   6300:        ar r lib.a $LIBOBJ
                   6301: 
                   6302: clean:V:
                   6303:        rm -f $LPROG v10/   755   3513      4           0  5032703620   4423 v10/mkfile   644   3513      4         766  5030710404   5667 <../mkconf.v10
                   6304: 
                   6305: CC=lcc
                   6306: LPROG=connect dispatch canon hostname
                   6307: LIBS=lib.a
                   6308: LIBOBJ=canon.o lcreat.o
                   6309: 
                   6310: %: %.sh
                   6311:        cp $stem.sh $target
                   6312:        chmod +x $target
                   6313: 
                   6314: connect: connect.o
                   6315:        $CC $CFLAGS -o connect connect.o -lipc
                   6316: 
                   6317: dispatch: dispatch.o
                   6318:        $CC $CFLAGS -o dispatch dispatch.o -lipc
                   6319: 
                   6320: canon: canonmain.o lib.a
                   6321:        $CC $CFLAGS -o canon canonmain.o lib.a
                   6322: 
                   6323: compile:V: $LPROG $LIBS
                   6324: 
                   6325: install:V:
                   6326:        test -d $LDIR || mkdir $LDIR
                   6327:        cp $LPROG $LDIR
                   6328: 
                   6329: lib.a: $LIBOBJ
                   6330:        ar r lib.a $LIBOBJ
                   6331:        ranlib lib.a
                   6332: 
                   6333: clean:V:
                   6334:        rm -f $LPROG $LIBS *.o
                   6335: �$e�v10/connect.c   644   3513      4        1000  5030753426   6303 /* usage: connect hostname (answer|send|notice) (in|out) program [ args ... ] */
                   6336: 
                   6337: #include <ipc.h>
                   6338: #include <string.h>
                   6339: #include "../paths.h"
                   6340: 
                   6341: int
                   6342: main(int argc, char *argv[])
                   6343: {
                   6344:        int fd;
                   6345: 
                   6346:        if (argc < 5)
                   6347:                return 1;
                   6348: 
                   6349:        chdir(LDIR);
                   6350: 
                   6351:        fd = ipcopen(ipcpath(argv[1], "dk", "dist"), "heavy bsdauth");
                   6352:        if (fd < 0) {
                   6353:                perror(argv[1]);
                   6354:                return 1;
                   6355:        }
                   6356: 
                   6357:        write(fd, argv[2], strlen(argv[2]) + 1);
                   6358: 
                   6359:        if (strchr(argv[3], 'i'))
                   6360:                dup2(fd, 0);
                   6361:        if (strchr(argv[3], 'o'))
                   6362:                dup2(fd, 1);
                   6363:        close(fd);
                   6364:        execv(argv[4], &argv[4]);
                   6365: }
                   6366: v10/dispatch.c   644   3513      4        1475  5024760412   6465 /* usage: dispatch <ipc args> */
                   6367: /* TODO: connect input to /dev/null if peer wants no output,
                   6368:    connect output to logfile if peer wants no input.  */
                   6369: 
                   6370: #include <ipc.h>
                   6371: #include <string.h>
                   6372: #include "../paths.h"
                   6373: 
                   6374: int
                   6375: main(int argc, char *argv[])
                   6376: {
                   6377:        char c, d;
                   6378:        char *args[3];
                   6379:        int fd;
                   6380: 
                   6381:        if (chdir(LDIR) < 0)
                   6382:                return 1;
                   6383: 
                   6384:        (args[1] = strchr(argv[1], '=')) && ++args[1];
                   6385:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6386:        args[3] = 0;
                   6387: 
                   6388:        if (read(0, &c, 1) != 1)
                   6389:                return 1;
                   6390:        do
                   6391:                if (read(0, &d, 1) != 1)
                   6392:                        return 1;
                   6393:        while (d);
                   6394: 
                   6395:        fd = open("/dev/null", 1);
                   6396:        dup2(fd, 2);
                   6397:        if (fd > 2)
                   6398:                close(fd);
                   6399: 
                   6400:        switch (c) {
                   6401:        case 's':
                   6402:                args[0] = "showq";
                   6403:                execv("showq", args);
                   6404:                break;
                   6405:        case 't':
                   6406:                args[0] = "transmit";
                   6407:                execv("transmit", args);
                   6408:                break;
                   6409:        case 'n':
                   6410:                args[0] = "notice";
                   6411:                execv("notice", args);
                   6412:                break;
                   6413:        }
                   6414: 
                   6415:        return 1;
                   6416: }
                   6417: ;
                   6418: 
                   6419:        (args[1] = strchr(argv[1], '=')) && ++args[1];
                   6420:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6421:        args[3] = 0;
                   6422: 
                   6423:        if (read(0, &c, 1) != 1)
                   6424:                return 1;
                   6425:        do
                   6426:                if (read(0, &d, 1) != 1)
                   6427:                        return 1;v10/lcreat.c   644   3513      4         443  5020263747   6117 int
                   6428: lcreat(char *name, int mode)
                   6429: {
                   6430:        char temp[14];
                   6431:        int fd;
                   6432: 
                   6433:        sprintf(temp, "lcreat.%d", getpid());   /* only works in same file system */
                   6434:        fd = creat(temp, mode);
                   6435:        if (fd < 0)
                   6436:                return fd;
                   6437:        if (link(temp, name) < 0) {
                   6438:                close(fd);
                   6439:                unlink(temp);
                   6440:                return -1;
                   6441:        }
                   6442:        unlink(temp);
                   6443:        return fd;
                   6444: }
                   6445:                break;
                   6446:        }
                   6447: 
                   6448:        return 1;
                   6449: }
                   6450: ;
                   6451: 
                   6452:        (args[1] = strchr(argv[1], '=')) && ++args[1];
                   6453:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6454:        args[3] = 0;
                   6455: 
                   6456:        if (read(0, &c, 1) != 1)
                   6457:                return 1;
                   6458:        do
                   6459:                if (read(0, &d, 1) != 1)
                   6460:                        return 1;v10/canon.c   644   3513      4         531  5030711060   5724 #include <string.h>
                   6461: 
                   6462: /* reduce tcp and dk names to their final component */
                   6463: void
                   6464: canon(char *sys, char cansys[])
                   6465: {
                   6466:        if (strncmp(sys, "dk!", 3) == 0)
                   6467:                sys += 3;
                   6468:        if (strncmp(sys, "tcp!", 4) == 0)
                   6469:                sys += 4;
                   6470:        if (strrchr(sys, '/'))
                   6471:                sys = strrchr(sys, '/') + 1;
                   6472:        strcpy(cansys, sys);
                   6473:        if (strrchr(cansys, '.'))
                   6474:                *strchr(cansys, '.') = '\0';
                   6475: }
                   6476: ], '=')) && ++args[1];
                   6477:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6478:        args[3] = 0;
                   6479: 
                   6480:        if (read(0, &c, 1) != 1)
                   6481:                return 1;
                   6482:        do
                   6483:                if (read(0, &d, 1) != 1)
                   6484:                        return 1;v10/canonmain.c   644   3513      4         176  5030712000   6571 main(int argc, char **argv)
                   6485: {
                   6486:        char cansys[256];
                   6487: 
                   6488:        while (--argc) {
                   6489:                canon(*++argv, cansys);
                   6490:                puts(cansys);
                   6491:        }
                   6492:        return 0;
                   6493: }
                   6494: p(sys, "dk!", 3) == 0)
                   6495:                sys += 3;
                   6496:        if (strncmp(sys, "tcp!", 4) == 0)
                   6497:                sys += 4;
                   6498:        if (strrchr(sys, '/'))
                   6499:                sys = strrchr(sys, '/') + 1;
                   6500:        strcpy(cansys, sys);
                   6501:        if (strrchr(cansys, '.'))
                   6502:                *strchr(cansys, '.') = '\0';
                   6503: }
                   6504: ], '=')) && ++args[1];
                   6505:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6506:        args[3] = 0;
                   6507: 
                   6508:        if (read(0, &c, 1) != 1)
                   6509:                return 1;
                   6510:        do
                   6511:                if (read(0, &d, 1) != 1)
                   6512:                        return 1;v10/hostname.sh   644   3513      4          35  5021475777   6641 #! /bin/sh -
                   6513: cat /etc/whoami
                   6514: 
                   6515:        char cansys[256];
                   6516: 
                   6517:        while (--argc) {
                   6518:                canon(*++argv, cansys);
                   6519:                puts(cansys);
                   6520:        }
                   6521:        return 0;
                   6522: }
                   6523: p(sys, "dk!", 3) == 0)
                   6524:                sys += 3;
                   6525:        if (strncmp(sys, "tcp!", 4) == 0)
                   6526:                sys += 4;
                   6527:        if (strrchr(sys, '/'))
                   6528:                sys = strrchr(sys, '/') + 1;
                   6529:        strcpy(cansys, sys);
                   6530:        if (strrchr(cansys, '.'))
                   6531:                *strchr(cansys, '.') = '\0';
                   6532: }
                   6533: ], '=')) && ++args[1];
                   6534:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6535:        args[3] = 0;
                   6536: 
                   6537:        if (read(0, &c, 1) != 1)
                   6538:                return 1;
                   6539:        do
                   6540:                if (read(0, &d, 1) != 1)
                   6541:                        return 1;sysv/libv.h   644   3513      4          50  5031457617   6161 extern int optind;
                   6542: extern char *optarg;
                   6543: on #dispatch
                   6544: LIBS=lib.a
                   6545: LIBOBJ=canon.o lcreat.o
                   6546: 
                   6547: %: %.sh
                   6548:        cp $stem.sh $target
                   6549:        chmod +x $target
                   6550: 
                   6551: connect: connect.o
                   6552:        $CC $CFLAGS -o connect connect.o
                   6553: 
                   6554: dispatch: dispatch.o
                   6555:        $CC $CFLAGS -o dispatch dispatch.o
                   6556: 
                   6557: canon: canonmain.o lib.a
                   6558:        $CC $CFLAGS -o canon canonmain.o lib.a
                   6559: 
                   6560: compile:V: $LPROG $LIBS
                   6561: 
                   6562: install:V:
                   6563:        test -d $LDIR || mkdir $LDIR
                   6564:        cp $LPROG $LDIR
                   6565:        chown root $LDIR/connect && chmod 4755 $LDIR/connect
                   6566: 
                   6567: lib.a: $LIBOBJ
                   6568:        ar r lib.a $LIBOBJ
                   6569: 
                   6570: clean:V:
                   6571:        rm -f $LPROG v10/   755   3513      4           0  5032703620   4423 v10/mkfile   644   3513      4         766  5030710404   5667 <../mkconf.v10
                   6572: 
                   6573: CC=lcc
                   6574: LPROG=connect dispatch canon hostname
                   6575: LIBS=lib.a
                   6576: LIBOBJ=canon.o lcreat.o
                   6577: 
                   6578: %: %.sh
                   6579:        cp $stem.sh $target
                   6580:        chmod +x $target
                   6581: 
                   6582: connect: connect.o
                   6583:        $CC $CFLAGS -o connect connect.o -lipc
                   6584: 
                   6585: dispatch: dispatch.o
                   6586:        $CC $CFLAGS -o dispatch dispatch.o -lipc
                   6587: 
                   6588: canon: canonmain.o lib.a
                   6589:        $CC $CFLAGS -o canon canonmain.o lib.a
                   6590: 
                   6591: compile:V: $LPROG $LIBS
                   6592: 
                   6593: install:V:
                   6594:        test -d $LDIR || mkdir $LDIR
                   6595:        cp $LPROG $LDIR
                   6596: 
                   6597: lib.a: $LIBOBJ
                   6598:        ar r lib.a $LIBOBJ
                   6599:        ranlib lib.a
                   6600: 
                   6601: clean:V:
                   6602:        rm -f $LPROG $LIBS *.o
                   6603: �$e�v10/connect.c   644   3513      4        1000  5030753426   6303 /* usage: connect hostname (answer|send|notice) (in|out) program [ args ... ] */
                   6604: 
                   6605: #include <ipc.h>
                   6606: #include <string.h>
                   6607: #include "../paths.h"
                   6608: 
                   6609: int
                   6610: main(int argc, char *argv[])
                   6611: {
                   6612:        int fd;
                   6613: 
                   6614:        if (argc < 5)
                   6615:                return 1;
                   6616: 
                   6617:        chdir(LDIR);
                   6618: 
                   6619:        fd = ipcopen(ipcpath(argv[1], "dk", "dist"), "heavy bsdauth");
                   6620:        if (fd < 0) {
                   6621:                perror(argv[1]);
                   6622:                return 1;
                   6623:        }
                   6624: 
                   6625:        write(fd, argv[2], strlen(argv[2]) + 1);
                   6626: 
                   6627:        if (strchr(argv[3], 'i'))
                   6628:                dup2(fd, 0);
                   6629:        if (strchr(argv[3], 'o'))
                   6630:                dup2(fd, 1);
                   6631:        close(fd);
                   6632:        execv(argv[4], &argv[4]);
                   6633: }
                   6634: v10/dispatch.c   644   3513      4        1475  5024760412   6465 /* usage: dispatch <ipc args> */
                   6635: /* TODO: connect input to /dev/null if peer wants no output,
                   6636:    connect output to logfile if peer wants no input.  */
                   6637: 
                   6638: #include <ipc.h>
                   6639: #include <string.h>
                   6640: #include "../paths.h"
                   6641: 
                   6642: int
                   6643: main(int argc, char *argv[])
                   6644: {
                   6645:        char c, d;
                   6646:        char *args[3];
                   6647:        int fd;
                   6648: 
                   6649:        if (chdir(LDIR) < 0)
                   6650:                return 1;
                   6651: 
                   6652:        (args[1] = strchr(argv[1], '=')) && ++args[1];
                   6653:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6654:        args[3] = 0;
                   6655: 
                   6656:        if (read(0, &c, 1) != 1)
                   6657:                return 1;
                   6658:        do
                   6659:                if (read(0, &d, 1) != 1)
                   6660:                        return 1;
                   6661:        while (d);
                   6662: 
                   6663:        fd = open("/dev/null", 1);
                   6664:        dup2(fd, 2);
                   6665:        if (fd > 2)
                   6666:                close(fd);
                   6667: 
                   6668:        switch (c) {
                   6669:        case 's':
                   6670:                args[0] = "showq";
                   6671:                execv("showq", args);
                   6672:                break;
                   6673:        case 't':
                   6674:                args[0] = "transmit";
                   6675:                execv("transmit", args);
                   6676:                break;
                   6677:        case 'n':
                   6678:                args[0] = "notice";
                   6679:                execv("notice", args);
                   6680:                break;
                   6681:        }
                   6682: 
                   6683:        return 1;
                   6684: }
                   6685: ;
                   6686: 
                   6687:        (args[1] = strchr(argv[1], '=')) && ++args[1];
                   6688:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6689:        args[3] = 0;
                   6690: 
                   6691:        if (read(0, &c, 1) != 1)
                   6692:                return 1;
                   6693:        do
                   6694:                if (read(0, &d, 1) != 1)
                   6695:                        return 1;v10/lcreat.c   644   3513      4         443  5020263747   6117 int
                   6696: lcreat(char *name, int mode)
                   6697: {
                   6698:        char temp[14];
                   6699:        int fd;
                   6700: 
                   6701:        sprintf(temp, "lcreat.%d", getpid());   /* only works in same file system */
                   6702:        fd = creat(temp, mode);
                   6703:        if (fd < 0)
                   6704:                return fd;
                   6705:        if (link(temp, name) < 0) {
                   6706:                close(fd);
                   6707:                unlink(temp);
                   6708:                return -1;
                   6709:        }
                   6710:        unlink(temp);
                   6711:        return fd;
                   6712: }
                   6713:                break;
                   6714:        }
                   6715: 
                   6716:        return 1;
                   6717: }
                   6718: ;
                   6719: 
                   6720:        (args[1] = strchr(argv[1], '=')) && ++args[1];
                   6721:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6722:        args[3] = 0;
                   6723: 
                   6724:        if (read(0, &c, 1) != 1)
                   6725:                return 1;
                   6726:        do
                   6727:                if (read(0, &d, 1) != 1)
                   6728:                        return 1;v10/canon.c   644   3513      4         531  5030711060   5724 #include <string.h>
                   6729: 
                   6730: /* reduce tcp and dk names to their final component */
                   6731: void
                   6732: canon(char *sys, char cansys[])
                   6733: {
                   6734:        if (strncmp(sys, "dk!", 3) == 0)
                   6735:                sys += 3;
                   6736:        if (strncmp(sys, "tcp!", 4) == 0)
                   6737:                sys += 4;
                   6738:        if (strrchr(sys, '/'))
                   6739:                sys = strrchr(sys, '/') + 1;
                   6740:        strcpy(cansys, sys);
                   6741:        if (strrchr(cansys, '.'))
                   6742:                *strchr(cansys, '.') = '\0';
                   6743: }
                   6744: ], '=')) && ++args[1];
                   6745:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6746:        args[3] = 0;
                   6747: 
                   6748:        if (read(0, &c, 1) != 1)
                   6749:                return 1;
                   6750:        do
                   6751:                if (read(0, &d, 1) != 1)
                   6752:                        return 1;v10/canonmain.c   644   3513      4         176  5030712000   6571 main(int argc, char **argv)
                   6753: {
                   6754:        char cansys[256];
                   6755: 
                   6756:        while (--argc) {
                   6757:                canon(*++argv, cansys);
                   6758:                puts(cansys);
                   6759:        }
                   6760:        return 0;
                   6761: }
                   6762: p(sys, "dk!", 3) == 0)
                   6763:                sys += 3;
                   6764:        if (strncmp(sys, "tcp!", 4) == 0)
                   6765:                sys += 4;
                   6766:        if (strrchr(sys, '/'))
                   6767:                sys = strrchr(sys, '/') + 1;
                   6768:        strcpy(cansys, sys);
                   6769:        if (strrchr(cansys, '.'))
                   6770:                *strchr(cansys, '.') = '\0';
                   6771: }
                   6772: ], '=')) && ++args[1];
                   6773:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6774:        args[3] = 0;
                   6775: 
                   6776:        if (read(0, &c, 1) != 1)
                   6777:                return 1;
                   6778:        do
                   6779:                if (read(0, &d, 1) != 1)
                   6780:                        return 1;v10/hostname.sh   644   3513      4          35  5021475777   6641 #! /bin/sh -
                   6781: cat /etc/whoami
                   6782: 
                   6783:        char cansys[256];
                   6784: 
                   6785:        while (--argc) {
                   6786:                canon(*++argv, cansys);
                   6787:                puts(cansys);
                   6788:        }
                   6789:        return 0;
                   6790: }
                   6791: p(sys, "dk!", 3) == 0)
                   6792:                sys += 3;
                   6793:        if (strncmp(sys, "tcp!", 4) == 0)
                   6794:                sys += 4;
                   6795:        if (strrchr(sys, '/'))
                   6796:                sys = strrchr(sys, '/') + 1;
                   6797:        strcpy(cansys, sys);
                   6798:        if (strrchr(cansys, '.'))
                   6799:                *strchr(cansys, '.') = '\0';
                   6800: }
                   6801: ], '=')) && ++args[1];
                   6802:        (args[2] = strchr(argv[2], '=')) && ++args[2];
                   6803:        args[3] = 0;
                   6804: 
                   6805:        if (read(0, &c, 1) != 1)
                   6806:                return 1;
                   6807:        do
                   6808:                if (read(0, &d, 1) != 1)
                   6809:                        return 1;

unix.superglobalmegacorp.com

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