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