|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.