Annotation of researchv10no/cmd/odist/src.tar, revision 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.