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

unix.superglobalmegacorp.com

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