Annotation of researchv8dc/cmd/asd/inspkg.c, revision 1.1.1.1

1.1       root        1: #include "asd.h"
                      2: 
                      3: #define CHUNK 64
                      4: 
                      5: /* type codes for installation subroutine */
                      6: #define BACKUP 0
                      7: #define INSTALL 1
                      8: 
                      9: static int retcode;
                     10: 
                     11: void readtemp();
                     12: 
                     13: /*
                     14:  *     The following declarations and functions manipulate
                     15:  *     a list of directory names.  This list is used to decide
                     16:  *     which files should be backed up and which have already been.
                     17:  */
                     18: 
                     19: struct list {
                     20:        char *name;
                     21:        struct list *next;
                     22: };
                     23: 
                     24: static struct list *dirs;
                     25: 
                     26: /* is the name given a subdirectory of the name on the list? */
                     27: static int
                     28: subsumed (name)
                     29:        register char *name;
                     30: {
                     31:        register struct list *item;
                     32:        register char *p, *q;
                     33: 
                     34:        for (item = dirs; item; item = item->next) {
                     35:                p = item->name;
                     36:                q = name;
                     37:                while (*p && *p == *q)
                     38:                        p++, q++;
                     39:                if (*p == '\0' && (*q == '/' || *q == '\0'))
                     40:                        return 1;
                     41:        }
                     42: 
                     43:        return 0;
                     44: }
                     45: 
                     46: /* add the name given to the list */
                     47: static void
                     48: addlist (name)
                     49:        register char *name;
                     50: {
                     51:        register struct list *l;
                     52: 
                     53:        l = new (struct list);
                     54:        l->next = dirs;
                     55:        l->name = copy (name);
                     56:        dirs = l;
                     57: }
                     58: 
                     59: /* clear the entire list */
                     60: static void
                     61: clearlist()
                     62: {
                     63:        register struct list *l;
                     64: 
                     65:        while (l = dirs) {
                     66:                dirs = l->next;
                     67:                free (l->name);
                     68:                free ((char *) l);
                     69:        }
                     70: }
                     71: 
                     72: /*
                     73:  *     install the given file
                     74:  */
                     75: process (file, fname)
                     76:        FILE *file;
                     77:        char *fname;
                     78: {
                     79:        register int c, rc = 0;
                     80: 
                     81:        if (vflag)
                     82:                fprintf (stderr, "%s:\n", fname);
                     83: 
                     84:        while ((c = getc (file)) != EOF) {
                     85:                ungetc (c, file);
                     86:                rc += doarch (file);
                     87:        }
                     88: 
                     89:        return rc;
                     90: }
                     91: 
                     92: main (argc, argv)
                     93:        int argc;
                     94:        char **argv;
                     95: {
                     96:        umask (0);
                     97:        return getargs (argc, argv, "nvbD:", process);
                     98: }
                     99: 
                    100: static char tfname[TMPNAML];
                    101: void delete();
                    102: 
                    103: /* process a single archive in a concatenation */
                    104: doarch (file)
                    105:        register FILE *file;
                    106: {
                    107:        register FILE *tf;
                    108:        Sig_typ sigsav;
                    109:        register long size;
                    110:        register int c;
                    111:        char armag[SARMAG];
                    112: 
                    113:        /* Make sure the file is an archive */
                    114:        if (fread (armag, sizeof (*armag), SARMAG, file) != SARMAG) {
                    115:                fprintf (stderr, "inspkg: unexpected EOF\n");
                    116:                exit (1);
                    117:        }
                    118:        if (strncmp (armag, ARMAG, SARMAG) != 0) {
                    119:                fprintf (stderr, "inspkg: input not a package\n");
                    120:                exit (1);
                    121:        }
                    122: 
                    123:        /* establish a temporary file */
                    124:        (void) tmpname (tfname);
                    125:        tf = fopen (tfname, "w");
                    126:        sigsav = signal (SIGINT, SIG_IGN);
                    127:        if (sigsav != SIG_IGN)
                    128:                signal (SIGINT, delete);
                    129:        chmod (tfname, 0600);
                    130: 
                    131:        /* copy the installation instructions to the temp file */
                    132:        size = read_header (instr, file);
                    133:        while (--size >= 0) {
                    134:                c = getc (file);
                    135:                if (c == EOF) {
                    136:                        fprintf (stderr, "inspkg: premature EOF\n");
                    137:                        exit (1);
                    138:                }
                    139:                putc (c, tf);
                    140:        }
                    141:        fclose (tf);
                    142: 
                    143:        next_header (file);
                    144: 
                    145:        /* create the optional backup package */
                    146:        if (bflag) {
                    147:                pkgstart();
                    148:                readtemp (BACKUP, file);
                    149:                pkgend();
                    150:                clearlist();
                    151:        }
                    152: 
                    153:        /* do the actual work */
                    154:        readtemp (INSTALL, file);
                    155: 
                    156:        /* delete the temporary file */
                    157:        nchk (unlink (tfname));
                    158:        signal (SIGINT, sigsav);
                    159: 
                    160:        return 0;
                    161: }
                    162: 
                    163: /*
                    164:  *     Make a pass through the temp file.
                    165:  */
                    166: static void
                    167: readtemp (code, file)
                    168:        register int code;
                    169:        register FILE *file;
                    170: {
                    171:        register FILE *tf;
                    172:        register int c;
                    173: 
                    174:        /* we're done writing the temp file, time to read it */
                    175:        tf = fopen (tfname, "r");
                    176:        schk ((char *) tf);
                    177: 
                    178:        /*
                    179:         *      The main loop -- one iteration per line
                    180:         *      We are careful in use and reuse of storage here;
                    181:         *      if you change this code make sure you understand
                    182:         *      the times at which getfield and transname
                    183:         *      recycle storage or strange things will happen.
                    184:         */
                    185:        while ((c = getc (tf)) != EOF) {
                    186:                char *param, *path, *path2;
                    187:                register FILE *outfd;
                    188:                int uid, gid, mode, dmajor, dminor, dev;
                    189:                register long size;
                    190:                char component[MAXCOMP+1];
                    191: 
                    192:                switch (c) {
                    193: 
                    194:                /* special files */
                    195:                case 'b':
                    196:                case 'c':
                    197:                        /* read the parameters */
                    198:                        param = getfield (tf);
                    199:                        mode = cvlong (param, strlen (param), 8) |
                    200:                            (c == 'c'? S_IFCHR: S_IFBLK);
                    201:                        param = getfield (tf);
                    202:                        dmajor = cvlong (param, strlen (param), 10);
                    203:                        param = getfield (tf);
                    204:                        dminor = cvlong (param, strlen (param), 10);
                    205:                        dev = makedev (dmajor, dminor);
                    206:                        uid = numuid (getfield (tf));
                    207:                        gid = numgid (getfield (tf));
                    208:                        path = transname (getfield (tf));
                    209:                        geteol (tf);
                    210: 
                    211:                        switch (code) {
                    212: 
                    213:                        case BACKUP:
                    214:                                if (!subsumed (path)) {
                    215:                                        pkgfile (path);
                    216:                                        addlist (path);
                    217:                                }
                    218:                                break;
                    219: 
                    220:                        case INSTALL:
                    221:                                if (vflag) {
                    222:                                        fprintf (stderr, "special file ");
                    223:                                        putpath (stderr, path);
                    224:                                        fprintf (stderr, "\n");
                    225:                                }
                    226: 
                    227:                                if (!nflag) {
                    228:                                        if (mknod (path, mode, dev) >= 0)
                    229:                                                chown (path, uid, gid);
                    230:                                        else
                    231:                                                perror (path);
                    232:                                }
                    233:                                break;
                    234:                        }
                    235:                        break;
                    236: 
                    237:                /* directory */
                    238:                case 'd':
                    239:                        /* read the parameters */
                    240:                        param = getfield (tf);
                    241:                        mode = cvlong (param, strlen (param), 8);
                    242:                        uid = numuid (getfield (tf));
                    243:                        gid = numgid (getfield (tf));
                    244:                        path = transname (getfield (tf));
                    245:                        geteol (tf);
                    246: 
                    247:                        switch (code) {
                    248: 
                    249:                        case BACKUP:
                    250:                                if (!subsumed (path)) {
                    251:                                        pkgfile (path);
                    252:                                        addlist (path);
                    253:                                }
                    254:                                break;
                    255: 
                    256:                        case INSTALL:
                    257:                                /* make the directory */
                    258:                                if (vflag) {
                    259:                                        fprintf (stderr, "directory ");
                    260:                                        putpath (stderr, path);
                    261:                                        putc ('\n', stderr);
                    262:                                }
                    263:                                if (!nflag) {
                    264:                                        rmall (path);
                    265:                                        mkdir (path);
                    266:                                        chmod (path, mode);
                    267:                                        chown (path, uid, gid);
                    268:                                        chmod (path, mode);
                    269:                                }
                    270:                                break;
                    271:                        }
                    272: 
                    273:                        break;
                    274: 
                    275:                /* file */
                    276:                case 'f':
                    277:                        /* read parameters */
                    278:                        param = getfield (tf);
                    279:                        if (strlen (param) > MAXCOMP) {
                    280:                                fprintf (stderr,
                    281:                                    "inspkg: impossibly long component name\n");
                    282:                                delete();
                    283:                                exit (1);
                    284:                        }
                    285:                        strcpy (component, param);
                    286:                        uid = numuid (getfield (tf));
                    287:                        gid = numgid (getfield (tf));
                    288:                        path = transname (getfield (tf));
                    289:                        geteol (tf);
                    290: 
                    291:                        switch (code) {
                    292: 
                    293:                        case BACKUP:
                    294:                                if (!subsumed (path))
                    295:                                        pkgfile (path);
                    296:                                break;
                    297: 
                    298:                        case INSTALL:
                    299:                                /* read the corresponding archive header */
                    300:                                size = read_header (component, file);
                    301: 
                    302:                                if (vflag) {
                    303:                                        fprintf (stderr, "file ");
                    304:                                        putpath (stderr, path);
                    305:                                        putc ('\n', stderr);
                    306:                                }
                    307: 
                    308:                                /* create and open the file */
                    309:                                if (!nflag) {
                    310:                                        rmall (path);
                    311:                                        umask (077);
                    312:                                        outfd = fopen (path, "w");
                    313:                                        umask (0);
                    314:                                        if (outfd == NULL) {
                    315:                                                fprintf (stderr,
                    316:                                                    "inspkg: cannot create ");
                    317:                                                putpath (stderr, path);
                    318:                                                putc ('\n', stderr);
                    319:                                        }
                    320:                                }
                    321:                                if (nflag || outfd == NULL) {
                    322:                                        outfd = fopen ("/dev/null", "w");
                    323:                                        schk ((char *) outfd);
                    324:                                }
                    325: 
                    326:                                /* copy the file, advance input */
                    327:                                while (--size >= 0)
                    328:                                        putc (getc (file), outfd);
                    329:                                next_header (file);
                    330: 
                    331:                                /* check successful completion, close output */
                    332:                                fflush (outfd);
                    333:                                if (feof (file) || ferror (file) ||
                    334:                                    ferror (outfd)) {
                    335:                                        fprintf (stderr, "inspkg: can't write ");
                    336:                                        putpath (stderr, path);
                    337:                                        putc ('\n', stderr);
                    338:                                }
                    339:                                fclose (outfd);
                    340:                                
                    341:                                /*
                    342:                                 *      Update output modification times
                    343:                                 *      and change mode and owner.
                    344:                                 *      This is done here to cater to systems
                    345:                                 *      that allow people to give files away.
                    346:                                 *      The chmod is done twice because
                    347:                                 *      systems that let you give files away
                    348:                                 *      won't let you change the mode after
                    349:                                 *      you've done so, and some other systems
                    350:                                 *      turn off the setuid bit as a side
                    351:                                 *      effect of chown, so the second chmod
                    352:                                 *      will restore that bit.
                    353:                                 */
                    354:                                if (!nflag) {
                    355:                                        time_t timep[2];
                    356:                                        timep[0] = timep[1] = hdr.date;
                    357:                                        utime (path, timep);
                    358:                                        chmod (path, hdr.mode & 07777);
                    359:                                        chown (path, uid, gid);
                    360:                                        chmod (path, hdr.mode & 07777);
                    361:                                }
                    362: 
                    363:                                break;
                    364:                        }
                    365:                        break;
                    366: 
                    367:                /* link */
                    368:                case 'l':
                    369:                        /* read parameters */
                    370:                        path = copy (transname (getfield (tf)));
                    371:                        path2 = transname (getfield (tf));
                    372:                        geteol (tf);
                    373: 
                    374:                        switch (code) {
                    375: 
                    376:                        case BACKUP:
                    377:                                if (!subsumed (path2))
                    378:                                        pkgfile (path2);
                    379:                                break;
                    380: 
                    381:                        case INSTALL:
                    382:                                /* log it if requested */
                    383:                                if (vflag) {
                    384:                                        fprintf (stderr, "link ");
                    385:                                        putpath (stderr, path);
                    386:                                        fprintf (stderr, " to ");
                    387:                                        putpath (stderr, path2);
                    388:                                        putc ('\n', stderr);
                    389:                                }
                    390: 
                    391:                                /* make the link */
                    392:                                if (!nflag) {
                    393:                                        struct stat sb, sb2;
                    394: 
                    395:                                        /* are we about to link x to x? */
                    396:                                        if (stat (path, &sb) < 0
                    397:                                            || stat (path2, &sb2) < 0
                    398:                                            || sb.st_dev != sb2.st_dev
                    399:                                            || sb.st_ino != sb2.st_ino) {
                    400:                                                rmall (path2);
                    401:                                                if (link (path, path2) < 0)
                    402:                                                        perror (path2);
                    403:                                        }
                    404:                                }
                    405: 
                    406:                                free (path);
                    407:                                break;
                    408:                        }
                    409:                        break;
                    410:                
                    411:                /* remove */
                    412:                case 'r':
                    413:                        /* get parameters */
                    414:                        path = transname (getfield (tf));
                    415:                        geteol (tf);
                    416: 
                    417:                        switch (code) {
                    418: 
                    419:                        case BACKUP:
                    420:                                if (!subsumed (path))
                    421:                                        pkgfile (path);
                    422:                                break;
                    423: 
                    424:                        case INSTALL:
                    425:                                if (vflag) {
                    426:                                        fprintf (stderr, "remove file ");
                    427:                                        putpath (stderr, path);
                    428:                                        putc ('\n', stderr);
                    429:                                }
                    430:                                if (!nflag)
                    431:                                        rmall (path);
                    432:                                break;
                    433:                        }
                    434: 
                    435:                        break;
                    436: 
                    437:                default:
                    438:                        fprintf (stderr, "inspkg: invalid package\n");
                    439:                        delete();
                    440:                        exit (1);
                    441:                }
                    442:        }
                    443:        fclose (tf);
                    444: 
                    445: }
                    446: 
                    447: static void
                    448: delete()
                    449: {
                    450:        unlink (tfname);
                    451:        exit (3);
                    452: }

unix.superglobalmegacorp.com

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