Annotation of researchv10no/cmd/odist/pax/ship/shipop.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Glenn Fowler
                      3:  * AT&T Bell Laboratories
                      4:  *
                      5:  * ship support -- a single file for easy bootstrap
                      6:  *
                      7:  * shipop newer [ reference [ file ... ] ]
                      8:  *
                      9:  *     true if reference file is newer than file ...
                     10:  *     false if any of the files do not exist
                     11:  *
                     12:  * shipop seal [ file ... ]
                     13:  *
                     14:  *     generate 32 bit multiplicative congruential PRG checksum for files
                     15:  *
                     16:  * shipop state reference [ file ... | <files ]
                     17:  *
                     18:  *     generate mam state file
                     19:  *
                     20:  * shipop time [ file ]
                     21:  *
                     22:  *     generate seconds-since-epoch time in hex for today [ file ]
                     23:  *
                     24:  * shipop xap [ file ... ]
                     25:  *
                     26:  *     restore pax self-delta files extracted by non-pax cpio
                     27:  */
                     28: 
                     29: #if !lint
                     30: static char id[] = "\n@(#)shipop (AT&T Bell Laboratories) 02/11/91\0\n";
                     31: #endif
                     32: 
                     33: #include <stdio.h>
                     34: #include <sys/types.h>
                     35: #include <sys/stat.h>
                     36: 
                     37: #define elements(x)    (sizeof(x)/sizeof(x[0]))
                     38: 
                     39: struct optab
                     40: {
                     41:        char*   name;
                     42:        int     (*func)();
                     43: };
                     44: 
                     45: static char*   cmd = "shipop";
                     46: 
                     47: static int     shipnewer();
                     48: static int     shipseal();
                     49: static int     shipstate();
                     50: static int     shiptime();
                     51: static int     shipxap();
                     52: 
                     53: static struct optab ops[] =
                     54: {
                     55:        "newer",        shipnewer,
                     56:        "seal",         shipseal,
                     57:        "state",        shipstate,
                     58:        "time",         shiptime,
                     59:        "xap",          shipxap,
                     60: };
                     61: 
                     62: static char*   op;
                     63: 
                     64: static int     status;
                     65: 
                     66: static void    error();
                     67: 
                     68: main(argc, argv)
                     69: int    argc;
                     70: char** argv;
                     71: {
                     72:        register char*  s;
                     73:        register int    i;
                     74: 
                     75:        if (!(s = *++argv))
                     76:                exit(0);
                     77:        for (i = 0; i < elements(ops); i++)
                     78:                if (!strcmp(s, ops[i].name))
                     79:                {
                     80:                        op = ops[i].name;
                     81:                        exit((*ops[i].func)(argv + 1));
                     82:                }
                     83:        fprintf(stderr, "Usage: %s %s", cmd, ops[0].name);
                     84:        for (i = 1; i < elements(ops); i++)
                     85:                fprintf(stderr, " | %s", ops[i].name);
                     86:        fprintf(stderr, " [ file ... ]\n");
                     87:        exit(2);
                     88: }
                     89: 
                     90: static void
                     91: error(level, file, msg)
                     92: char*  file;
                     93: char*  msg;
                     94: {
                     95:        fprintf(stderr, "%s: %s", cmd, op);
                     96:        if (level == 1) fprintf(stderr, ": warning");
                     97:        if (file) fprintf(stderr, ": %s", file);
                     98:        if (msg) fprintf(stderr, ": %s", msg);
                     99:        fprintf(stderr, "\n");
                    100:        if (level > status)
                    101:        {
                    102:                if (level > 2) exit(level - 2);
                    103:                status = level;
                    104:        }
                    105: }
                    106: 
                    107: /*
                    108:  * shipop newer [ reference [ file ... ] ]
                    109:  */
                    110: 
                    111: static int
                    112: shipnewer(argv)
                    113: register char**        argv;
                    114: {
                    115:        unsigned long   ref;
                    116:        struct stat     st;
                    117: 
                    118:        if (!*argv || stat(*argv, &st)) return(1);
                    119:        ref = (unsigned long)st.st_mtime;
                    120:        while (*++argv)
                    121:                if (stat(*argv, &st) || ref < (unsigned long)st.st_mtime) return(1);
                    122:        return(0);
                    123: }
                    124: 
                    125: /*
                    126:  * shipop seal [ file ... ]
                    127:  */
                    128: 
                    129: #define HASHPART(h,c)  (h = (h) * 987654321L + 123456879L + (c))
                    130: 
                    131: static char            buf[4096];
                    132: 
                    133: static unsigned long   sealfile();
                    134: 
                    135: static int
                    136: shipseal(argv)
                    137: register char**        argv;
                    138: {
                    139:        register char*  f;
                    140:        register int    fd;
                    141:        unsigned long   s;
                    142: 
                    143:        s = 0;
                    144:        if (!*argv) s = sealfile("/dev/stdin", 0, s);
                    145:        else while (f = *argv++)
                    146:        {
                    147:                if (*f == '-' && !*(f + 1)) s = sealfile("/dev/stdin", 0, s);
                    148:                else if ((fd = open(f, 0)) < 0) error(2, f, "cannot read");
                    149:                else
                    150:                {
                    151:                        s = sealfile(f, fd, s);
                    152:                        (void)close(fd);
                    153:                }
                    154:        }
                    155:        printf("%08x\n", s);
                    156:        return(status);
                    157: }
                    158: 
                    159: static unsigned long
                    160: sealfile(file, fd, s)
                    161: char*          file;
                    162: int            fd;
                    163: unsigned long  s;
                    164: {
                    165:        register unsigned char* b;
                    166:        register unsigned char* e;
                    167:        register int            n;
                    168: 
                    169:        HASHPART(s, 0);
                    170:        while ((n = read(fd, buf, sizeof(buf))) > 0)
                    171:        {
                    172:                b = (unsigned char*)buf;
                    173:                e = b + n;
                    174:                while (b < e) HASHPART(s, *b++);
                    175:        }
                    176:        if (n < 0) error(2, file, "read error");
                    177:        return(s);
                    178: }
                    179: 
                    180: /*
                    181:  * shipop state reference [ file ... | <file-list ]
                    182:  */
                    183: 
                    184: static int
                    185: shipstate(argv)
                    186: register char**        argv;
                    187: {
                    188:        register char*  s;
                    189:        register int    c;
                    190:        long            ref;
                    191:        struct stat     st;
                    192: 
                    193:        if (!(s = *argv++) || stat(s, &st)) error(3, (char*)0, "reference file omitted");
                    194:        ref = (long)st.st_mtime;
                    195:        if (s = *argv++) do
                    196:        {
                    197:                if (!stat(s, &st))
                    198:                        printf("%s %ld\n", s, (long)st.st_mtime - ref);
                    199:        } while (s = *argv++);
                    200:        else do
                    201:        {
                    202:                s = buf;
                    203:                while ((c = getchar()) != EOF && c != ' ' && c != '\n')
                    204:                        if (s < buf + sizeof(buf) - 1) *s++ = c;
                    205:                if (s > buf)
                    206:                {
                    207:                        *s = 0;
                    208:                        if (!stat(buf, &st))
                    209:                                printf("%s %ld\n", buf, (long)st.st_mtime - ref);
                    210:                }
                    211:        } while (c != EOF);
                    212:        return(status);
                    213: }
                    214: 
                    215: /*
                    216:  * shipop time [ file ]
                    217:  */
                    218: 
                    219: static int
                    220: shiptime(argv)
                    221: register char**        argv;
                    222: {
                    223:        struct stat     st;
                    224:        time_t          date;
                    225: 
                    226:        extern time_t   time();
                    227: 
                    228:        if (*argv && !stat(*argv, &st)) date = st.st_mtime;
                    229:        else time(&date);
                    230:        printf("%08x\n", (long)date);
                    231:        return(status);
                    232: }
                    233: 
                    234: /*
                    235:  * shipop xap [ file ... ]
                    236:  */
                    237: 
                    238: #define XAPHEADER      1024
                    239: 
                    240: #define round(x)       (((x)+(XAPHEADER*8)-1)&~((XAPHEADER*8)-1))
                    241: 
                    242: static void    xapfile();
                    243: static int     isdelta();
                    244: 
                    245: extern char*   malloc();
                    246: 
                    247: /* ----- enough of sfio and delta/update to do update() ----- */
                    248: #define reg    register
                    249: #define NIL(t) ((t)0)
                    250: 
                    251: typedef struct
                    252: {
                    253:        unsigned char*  buf;
                    254:        unsigned char*  nxt;
                    255:        unsigned char*  end;
                    256:        long            siz;
                    257: } Sfile_t;
                    258: 
                    259: #define sfgetc(f)      ((f)->nxt<(f)->end?*(f)->nxt++:(-1))
                    260: #define sfgetu(f)      ((_Sfi = sfgetc(f)) < 0 ? -1 : \
                    261:                                ((_Sfi&SF_MORE) ? _sfgetu(f) : (unsigned long)_Sfi))
                    262: #define sfread(f,b,n)  (((f)->nxt+=(n))<=(f)->end?(n):(-1))
                    263: #define sfseek(f,o,w)  ((f)->nxt=(f)->buf+(o),(o))
                    264: #define sfsync(f)
                    265: 
                    266: #define SFUVALUE(v)    ((v)&(SF_MORE-1))
                    267: #define SF_UBITS       7
                    268: #define SF_MORE                (1<<SF_UBITS)
                    269: 
                    270: static long    _Sfi;
                    271: 
                    272: static unsigned long
                    273: _sfgetu(f)
                    274: Sfile_t*       f;
                    275: {
                    276:        register int            c;
                    277:        register unsigned long  v;
                    278: 
                    279:        v = SFUVALUE(_Sfi);
                    280:        do
                    281:        {
                    282:                if ((c = sfgetc(f)) < 0) return(-1);
                    283:                v = (v << SF_UBITS) | SFUVALUE(c);
                    284:        } while (c & SF_MORE);
                    285:        return(v);
                    286: }
                    287: 
                    288: static int
                    289: sfmove(fr, fw, n)
                    290: Sfile_t*       fr;
                    291: Sfile_t*       fw;
                    292: register int   n;
                    293: {
                    294:        register char*  r;
                    295:        register char*  w;
                    296:        register char*  e;
                    297: 
                    298:        r = (char*)fr->nxt;
                    299:        w = (char*)fw->nxt;
                    300:        e = w + n;
                    301:        while (w < e) *w++ = *r++;
                    302:        fr->nxt = (unsigned char*)r;
                    303:        fw->nxt = (unsigned char*)w;
                    304:        return(n);
                    305: }
                    306: 
                    307: #define CODE_BIT       8
                    308: #define DELTA_ADD      (0)
                    309: #define DELTA_MOVE     (1<<(CODE_BIT-1))
                    310: #define M_MIN          4
                    311: #define C_BITS         (3)
                    312: #define C_SIZE         ((1<<C_BITS)-3)
                    313: #define A_SIZE         (1 << CODE_BIT)
                    314: #define C_ADDRS                (C_SIZE)
                    315: #define C_CADDR                (C_SIZE+1)
                    316: #define C_RADDR                (C_SIZE+2)
                    317: #define C_SIZEOF(addr,indx)    (indx == C_ADDRS ? 1 : sfulen(addr))
                    318: #define C_INIT(c,cache,addrs) \
                    319:        { cache[c=0] = 128; while((c += 1) < C_SIZE) cache[c] = (c+1)*128; \
                    320:          addrs[c=0] = 256; while((c += 1) < A_SIZE) addrs[c] = c+256; \
                    321:        }
                    322: #define C_SET(real,indx,cache,c,addrs) \
                    323:        { if((c += 1) >= C_SIZE) c = 0; cache[c] = real; \
                    324:          if(indx != C_ADDRS) addrs[real&(A_SIZE-1)] = real; \
                    325:        }
                    326: #define C_REAL(real,addr,indx,caddr,cache,addrs) \
                    327:        { real = indx == C_RADDR ? addr : \
                    328:                 indx == C_ADDRS ? addrs[addr] : \
                    329:                 indx == C_CADDR ? caddr-addr : addr+cache[indx]; \
                    330:        }
                    331: #define A_BITS         (CODE_BIT-3)
                    332: #define A_HERE(i)      ((i) & ((1<<A_BITS)-2))
                    333: #define A_LOCAL                ((1<<A_BITS)-1)
                    334: #define A_read(f,i,s)  ((s) = A_HERE(i) ? ((i)&A_LOCAL)-1 : sfgetu(f)+A_LOCAL )
                    335: 
                    336: #define M_BITS         (CODE_BIT-(C_BITS+1))
                    337: #define M_LOCAL                ((1<<M_BITS) + M_MIN-1)
                    338: #define M_HERE(i)      ((i) & ((1<<M_BITS)-1))
                    339: #define M_sread(f,i,s) ((s) = ((s) = M_HERE(i)) ? \
                    340:                                (s)+(M_MIN-1) : sfgetu(f)+M_LOCAL )
                    341: #define M_cread(i,c)   ((c) = ((i)>>M_BITS) & ((1<<C_BITS)-1) )
                    342: #define M_aread(f,c,a) ((a) = (c) == C_ADDRS ? sfgetc(f) : sfgetu(f) )
                    343: #define M_READ(f,i,a,c,s) \
                    344:                ((M_cread(i,c)<0 || M_aread(f,c,a)<0 || M_sread(f,i,s)<0) ? -1 : 0)
                    345: 
                    346: #define T_MBITS                (CODE_BIT - (A_BITS+1))
                    347: #define T_ABITS                (CODE_BIT - (T_MBITS+C_BITS+1))
                    348: #define T_TINY(i)      ((i) & (((1<<T_MBITS)-1) << (C_BITS+T_ABITS)) )
                    349: #define T_MREAD(f,i,a,c,s) \
                    350:                (((c) = ((i)>>T_ABITS) & ((1<<C_BITS)-1)), \
                    351:                 ((s) = (((i)>>(C_BITS+T_ABITS))&((1<<T_MBITS)-1)) + M_MIN-1), \
                    352:                 M_aread(f,c,a) )
                    353: #define T_AREAD(i,s)   ((s) = ((i) & ((1<<T_ABITS)-1)) + 1)
                    354: #define A_READ(f,i,s)  (T_TINY(i) ? T_AREAD(i,s) : A_read(f,i,s))
                    355: 
                    356: /* now the untouched libdelta/update.c */
                    357: 
                    358: /*
                    359: **     Reconstruct a target file from a source file and a delta file.
                    360: **     The delta file contain block move instructions computed by delta().
                    361: **
                    362: **     Written by Kiem-Phong Vo, 03/27/90
                    363: */
                    364: 
                    365: static long supdate(fsrc,fdel,wtar,rtar,sbase,tbase)
                    366: Sfile_t                *fsrc;  /* source file */
                    367: Sfile_t                *fdel;  /* delta instruction file */
                    368: Sfile_t                *wtar;  /* target file for writing */
                    369: Sfile_t                *rtar;  /* target file for reading */
                    370: reg long       *sbase, *tbase; /* current bases */
                    371: {
                    372:        reg int         inst;
                    373:        reg int         c;
                    374:        reg long        caddr;
                    375:        long            cache[C_SIZE], addrs[A_SIZE];
                    376:        long            n_src, n_tar;
                    377: #ifdef DEBUG
                    378:        int             n_inst = 0;
                    379: #endif
                    380:        if((n_src = sfgetu(fdel)) < 0 || (n_tar = sfgetu(fdel)) < 0)
                    381:                return -1;
                    382: 
                    383:        C_INIT(c,cache,addrs);
                    384:        caddr = n_src;
                    385:        while((inst = sfgetc(fdel)) >= 0)
                    386:        {
                    387:                reg long        addr, real, size;
                    388:                reg int         indx;
                    389: #ifdef DEBUG
                    390:                n_inst++;
                    391: #endif
                    392:                if(inst == 0)
                    393:                {
                    394:                        if(sbase)
                    395:                                *sbase += n_src;
                    396:                        if(tbase)
                    397:                                *tbase += n_tar;
                    398:                        return caddr == (n_tar+n_src) ? n_tar : -1L;
                    399:                }
                    400: 
                    401:                if((inst&DELTA_MOVE) == 0)
                    402:                {       /* do add */
                    403:                        if(A_READ(fdel,inst,size) < 0)
                    404:                                return -1L;
                    405:                        if(sfmove(fdel,wtar,size) < 0)
                    406:                                return -1L;
                    407:                        caddr += size;
                    408: 
                    409:                        if(T_TINY(inst))
                    410:                        {       /* read the merged move instruction */
                    411:                                if(T_MREAD(fdel,inst,addr,indx,size) < 0)
                    412:                                        return -1;
                    413:                                goto do_move;
                    414:                        }
                    415:                }
                    416:                else
                    417:                {       /* move instruction */
                    418:                        if(M_READ(fdel,inst,addr,indx,size) < 0)
                    419:                                return -1;
                    420:                do_move:
                    421:                        C_REAL(real,addr,indx,caddr,cache,addrs);
                    422:                        C_SET(real,indx,cache,c,addrs);
                    423:                        if(real >= n_src || !sbase)
                    424:                        {       /* self-move */
                    425:                                sfsync(wtar);
                    426:                                real = (real-n_src) + *tbase;
                    427:                                if(sfseek(rtar,real,0) < 0)
                    428:                                        return -1L;
                    429:                                if(sfmove(rtar,wtar,size) < 0)
                    430:                                        return -1L;
                    431:                        }
                    432:                        else
                    433:                        {       /* source-move */
                    434:                                if(sbase)
                    435:                                        real += *sbase;
                    436:                                if(sfseek(fsrc,real,0) < 0)
                    437:                                        return -1L;
                    438:                                if(sfmove(fsrc,wtar,size) < 0)
                    439:                                        return -1L;
                    440:                        }
                    441:                        caddr += size;
                    442:                }
                    443:        }
                    444: 
                    445:        /* should never get here */
                    446:        return -1L;
                    447: }
                    448: 
                    449: long update(fsrc,fdel,wtar,rtar)
                    450: Sfile_t        *fsrc;  /* source stream */
                    451: Sfile_t        *fdel;  /* delta stream */
                    452: Sfile_t        *wtar;  /* write stream for target file */
                    453: Sfile_t        *rtar;  /* read stream for target file */
                    454: {
                    455:        reg long        nsrc, ntar, header, t, tar;
                    456:        char            magic[4];
                    457:        long            sbase, tbase;
                    458:        extern long     supdate();
                    459: 
                    460:        if(sfread(fdel,magic,4) != 4 || sfgetc(fdel) < 0)
                    461:                return -1L;
                    462: 
                    463:        if((nsrc = sfgetu(fdel)) < 0 || (ntar = sfgetu(fdel)) < 0 ||
                    464:           (header = sfgetu(fdel)) < 0)
                    465:                return -1L;
                    466: 
                    467: /* ----- cheat here to setup wtar and rtar ----- */
                    468:        if (wtar->siz < ntar)
                    469:        {
                    470:                if (wtar->buf) free(wtar->buf);
                    471:                wtar->siz = round(ntar);
                    472:                if (!(wtar->buf = (unsigned char*)malloc(wtar->siz)))
                    473:                        error(3, (char*)0, "out of space");
                    474:                rtar->siz = wtar->siz;
                    475:        }
                    476:        rtar->nxt = rtar->buf = wtar->nxt = wtar->buf;
                    477: /* ----- */
                    478:        for(tbase = sbase = tar = 0; ;)
                    479:        {       /* process all windows */
                    480:                if(header > 0)
                    481:                        t = supdate(fsrc,fdel,wtar,rtar,NIL(long*),&tbase);
                    482:                else    t = supdate(fsrc,fdel,wtar,rtar,&sbase,&tbase);
                    483:                if(t >= 0)
                    484:                {
                    485:                        if((tar += t) == ntar)
                    486:                                break;
                    487:                        else if(tar < ntar)
                    488:                                continue;
                    489:                }
                    490: 
                    491:                /* error happened */
                    492:                ntar = -1L;
                    493:                break;
                    494:        }
                    495: 
                    496:        return ntar;
                    497: }
                    498: /* ----- */
                    499: 
                    500: static int
                    501: shipxap(argv)
                    502: char** argv;
                    503: {
                    504:        char*   file;
                    505: 
                    506:        umask(0);
                    507:        while (file = *argv++) xapfile(file);
                    508:        return(status);
                    509: }
                    510: 
                    511: static void
                    512: xapfile(file)
                    513: char*  file;
                    514: {
                    515:        int             fd;
                    516:        long            n;
                    517:        int             m;
                    518:        struct stat     st;
                    519: 
                    520:        static Sfile_t  fdel;
                    521:        static Sfile_t  rtar;
                    522:        static Sfile_t  wtar;
                    523: 
                    524:        if ((fd = open(file, 0)) < 0)
                    525:        {
                    526:                error(2, file, "cannot read");
                    527:                return;
                    528:        }
                    529:        if (fstat(fd, &st))
                    530:        {
                    531:                error(2, file, "cannot stat");
                    532:                close(fd);
                    533:                return;
                    534:        }
                    535:        n = st.st_size;
                    536:        if (n > fdel.siz)
                    537:        {
                    538:                if (fdel.buf) free(fdel.buf);
                    539:                fdel.siz = round(n);
                    540:                if (!(fdel.buf = (unsigned char*)malloc(fdel.siz)))
                    541:                        error(3, file, "out of space");
                    542:        }
                    543:        m = n > XAPHEADER ? XAPHEADER : n;
                    544:        if (read(fd, fdel.buf, m) != m)
                    545:        {
                    546:                error(2, file, "cannot read header");
                    547:                close(fd);
                    548:                return;
                    549:        }
                    550:        fdel.nxt = fdel.buf;
                    551:        fdel.end = fdel.buf + m;
                    552:        if (!isdelta(&fdel))
                    553:        {
                    554:                close(fd);
                    555:                return;
                    556:        }
                    557:        if ((n -= m) > 0)
                    558:        {
                    559:                if (read(fd, fdel.buf + m, n) != n)
                    560:                {
                    561:                        error(2, file, "cannot read");
                    562:                        close(fd);
                    563:                        return;
                    564:                }
                    565:                fdel.end += n;
                    566:        }
                    567:        close(fd);
                    568:        if ((n = update((Sfile_t*)0, &fdel, &wtar, &rtar)) < 0)
                    569:        {
                    570:                error(2, file, "cannot update");
                    571:                return;
                    572:        }
                    573:        if ((fd = creat(file, st.st_mode&0777)) < 0)
                    574:        {
                    575:                if (chmod(file, st.st_mode | 0200) || (fd = creat(file, st.st_mode&0777)) < 0)
                    576:                {
                    577:                        error(2, file, "cannot open for writing");
                    578:                        return;
                    579:                }
                    580:                chmod(file, st.st_mode);
                    581:        }
                    582:        if (write(fd, wtar.buf, n) != n)
                    583:                error(2, file, "cannot write");
                    584:        close(fd);
                    585: }
                    586: 
                    587: static int
                    588: isdelta(f)
                    589: register Sfile_t*      f;
                    590: {
                    591:        register int    b;
                    592:        register int    c;
                    593: 
                    594:        if (sfgetc(f) != 'c' || sfgetc(f) != 'A') return(0);
                    595:        b = 0;
                    596:        for (;;)
                    597:        {
                    598:                if ((c = sfgetc(f)) < 0) return(0);
                    599:                if (c) b = 0;
                    600:                else
                    601:                {
                    602:                        if (b) return(1);
                    603:                        b = 1;
                    604:                }
                    605:        }
                    606: }

unix.superglobalmegacorp.com

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