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