|
|
1.1 ! root 1: static char *sccsid = "@(#)find.c 4.5 (Berkeley) 3/31/82"; ! 2: /* find COMPILE: cc -o find -s -O -i find.c -lS */ ! 3: #include <stdio.h> ! 4: #include <sys/types.h> ! 5: #include <sys/stat.h> ! 6: #include <errno.h> ! 7: #define A_DAY 86400L /* a day full of seconds */ ! 8: #define EQ(x, y) (strcmp(x, y)==0) ! 9: #define MINUSINF (int)~((unsigned)-1>>1) ! 10: ! 11: int Randlast; ! 12: char Pathname[200]; ! 13: ! 14: struct anode { ! 15: int (*F)(); ! 16: struct anode *L, *R; ! 17: } Node[100]; ! 18: int Nn; /* number of nodes */ ! 19: char *Fname; ! 20: long Now; ! 21: int Argc, ! 22: Ai, ! 23: Pi; ! 24: char **Argv; ! 25: /* cpio stuff */ ! 26: int Cpio; ! 27: short *Buf, *Dbuf, *Wp; ! 28: int Bufsize = 5120; ! 29: int Wct = 2560; ! 30: ! 31: long Newer; ! 32: ! 33: struct stat Statb; ! 34: int Status; ! 35: int Statusqueried; ! 36: ! 37: struct anode *exp(), ! 38: *e1(), ! 39: *e2(), ! 40: *e3(), ! 41: *mk(); ! 42: char *nxtarg(); ! 43: char Home[128]; ! 44: long Blocks; ! 45: char *strrchr(); ! 46: char *sbrk(); ! 47: main(argc, argv) char *argv[]; ! 48: { ! 49: int or(), and(), errchk(); ! 50: struct anode *exlist, *errchklist; ! 51: int paths; ! 52: register char *cp, *sp = 0; ! 53: FILE *pwd, *popen(); ! 54: ! 55: time(&Now); ! 56: pwd = popen("pwd", "r"); ! 57: fgets(Home, 128, pwd); ! 58: pclose(pwd); ! 59: Home[strlen(Home) - 1] = '\0'; ! 60: Argc = argc; Argv = argv; ! 61: if(argc<3) { ! 62: usage: fprintf(stderr, "Usage: find path-list predicate-list\n"); ! 63: exit(1); ! 64: } ! 65: for(Ai = paths = 1; Ai < (argc-1); ++Ai, ++paths) ! 66: if(*Argv[Ai] == '-' || EQ(Argv[Ai], "(") || EQ(Argv[Ai], "!")) ! 67: break; ! 68: if(paths == 1) /* no path-list */ ! 69: goto usage; ! 70: if(!(exlist = exp())) { /* parse and compile the arguments */ ! 71: fprintf(stderr, "find: parsing error\n"); ! 72: exit(1); ! 73: } ! 74: errchklist = mk(errchk, (struct anode*)0, (struct anode*)0); ! 75: exlist = mk(or, mk(and, exlist, errchklist), errchklist); ! 76: if(Ai<argc) { ! 77: fprintf(stderr, "find: missing conjunction\n"); ! 78: exit(1); ! 79: } ! 80: for(Pi = 1; Pi < paths; ++Pi) { ! 81: sp = 0; ! 82: chdir(Home); ! 83: strcpy(Pathname, Argv[Pi]); ! 84: if(cp = strrchr(Pathname, '/')) { ! 85: sp = cp + 1; ! 86: *cp = '\0'; ! 87: if(chdir(*Pathname? Pathname: "/") == -1) { ! 88: fprintf(stderr, "find: bad starting directory\n"); ! 89: exit(2); ! 90: } ! 91: *cp = '/'; ! 92: } ! 93: Fname = sp? sp: Pathname; ! 94: descend(Pathname, Fname, exlist); /* to find files that match */ ! 95: } ! 96: if(Cpio) { ! 97: strcpy(Pathname, "TRAILER!!!"); ! 98: Statb.st_size = 0; ! 99: cpio(); ! 100: printf("%D blocks\n", Blocks*10); ! 101: } ! 102: exit(0); ! 103: } ! 104: ! 105: /* compile time functions: priority is exp()<e1()<e2()<e3() */ ! 106: ! 107: struct anode *exp() { /* parse ALTERNATION (-o) */ ! 108: int or(); ! 109: register struct anode * p1; ! 110: ! 111: p1 = e1() /* get left operand */ ; ! 112: if(EQ(nxtarg(), "-o")) { ! 113: Randlast--; ! 114: return(mk(or, p1, exp())); ! 115: } ! 116: else if(Ai <= Argc) --Ai; ! 117: return(p1); ! 118: } ! 119: struct anode *e1() { /* parse CONCATENATION (formerly -a) */ ! 120: int and(); ! 121: register struct anode * p1; ! 122: register char *a; ! 123: ! 124: p1 = e2(); ! 125: a = nxtarg(); ! 126: if(EQ(a, "-a")) { ! 127: And: ! 128: Randlast--; ! 129: return(mk(and, p1, e1())); ! 130: } else if(EQ(a, "(") || EQ(a, "!") || (*a=='-' && !EQ(a, "-o"))) { ! 131: --Ai; ! 132: goto And; ! 133: } else if(Ai <= Argc) --Ai; ! 134: return(p1); ! 135: } ! 136: struct anode *e2() { /* parse NOT (!) */ ! 137: int not(); ! 138: ! 139: if(Randlast) { ! 140: fprintf(stderr, "find: operand follows operand\n"); ! 141: exit(1); ! 142: } ! 143: Randlast++; ! 144: if(EQ(nxtarg(), "!")) ! 145: return(mk(not, e3(), (struct anode *)0)); ! 146: else if(Ai <= Argc) --Ai; ! 147: return(e3()); ! 148: } ! 149: struct anode *e3() { /* parse parens and predicates */ ! 150: int exeq(), ok(), glob(), ctime(), mtime(), atime(), user(), ! 151: group(), size(), perm(), links(), print(), ! 152: type(), ino(), cpio(), newer(), status(), errchk(); ! 153: struct anode *p1; ! 154: int i; ! 155: register char *a, *b, s; ! 156: ! 157: a = nxtarg(); ! 158: if(EQ(a, "(")) { ! 159: Randlast--; ! 160: p1 = exp(); ! 161: a = nxtarg(); ! 162: if(!EQ(a, ")")) goto err; ! 163: return(p1); ! 164: } ! 165: else if(EQ(a, "-print")) { ! 166: return(mk(print, (struct anode *)0, (struct anode *)0)); ! 167: } ! 168: b = nxtarg(); ! 169: s = *b; ! 170: if(s=='+') b++; ! 171: if(EQ(a, "-name")) ! 172: return(mk(glob, (struct anode *)b, (struct anode *)0)); ! 173: else if(EQ(a, "-ctime")) ! 174: return(mk(ctime, (struct anode *)atoi(b), (struct anode *)s)); ! 175: else if(EQ(a, "-mtime")) ! 176: return(mk(mtime, (struct anode *)atoi(b), (struct anode *)s)); ! 177: else if(EQ(a, "-atime")) ! 178: return(mk(atime, (struct anode *)atoi(b), (struct anode *)s)); ! 179: else if(EQ(a, "-user")) { ! 180: if((i=getunum("/etc/passwd", b)) == -1) { ! 181: if(amatch(b, "[0-9]*")) ! 182: return mk(user, (struct anode *)atoi(b), (struct anode *)s); ! 183: fprintf(stderr, "find: cannot find -user name\n"); ! 184: exit(1); ! 185: } ! 186: return(mk(user, (struct anode *)i, (struct anode *)s)); ! 187: } ! 188: else if(EQ(a, "-inum")) ! 189: return(mk(ino, (struct anode *)atoi(b), (struct anode *)s)); ! 190: else if(EQ(a, "-group")) { ! 191: if((i=getunum("/etc/group", b)) == -1) { ! 192: if(amatch(b, "[0-9]*")) ! 193: return mk(group, (struct anode *)atoi(b), (struct anode *)s); ! 194: fprintf(stderr, "find: cannot find -group name\n"); ! 195: exit(1); ! 196: } ! 197: return(mk(group, (struct anode *)i, (struct anode *)s)); ! 198: } else if(EQ(a, "-size")) ! 199: return(mk(size, (struct anode *)atoi(b), (struct anode *)s)); ! 200: else if(EQ(a, "-links")) ! 201: return(mk(links, (struct anode *)atoi(b), (struct anode *)s)); ! 202: else if(EQ(a, "-status")) ! 203: return(mk(status, (struct anode *)atoi(b), (struct anode *)s)); ! 204: else if(EQ(a, "-perm")) { ! 205: for(i=0; *b ; ++b) { ! 206: if(*b=='-') continue; ! 207: i <<= 3; ! 208: i = i + (*b - '0'); ! 209: } ! 210: return(mk(perm, (struct anode *)i, (struct anode *)s)); ! 211: } ! 212: else if(EQ(a, "-type")) { ! 213: i = s=='d' ? S_IFDIR : ! 214: s=='b' ? S_IFBLK : ! 215: s=='c' ? S_IFCHR : ! 216: s=='L' ? S_IFLNK : ! 217: s=='f' ? 0100000 : ! 218: 0; ! 219: return(mk(type, (struct anode *)i, (struct anode *)0)); ! 220: } ! 221: else if (EQ(a, "-exec")) { ! 222: i = Ai - 1; ! 223: while(!EQ(nxtarg(), ";")); ! 224: return(mk(exeq, (struct anode *)i, (struct anode *)0)); ! 225: } ! 226: else if (EQ(a, "-ok")) { ! 227: i = Ai - 1; ! 228: while(!EQ(nxtarg(), ";")); ! 229: return(mk(ok, (struct anode *)i, (struct anode *)0)); ! 230: } ! 231: else if(EQ(a, "-cpio")) { ! 232: if((Cpio = creat(b, 0666)) < 0) { ! 233: fprintf(stderr, "find: cannot create < %s >\n", s); ! 234: exit(1); ! 235: } ! 236: Buf = (short *)sbrk(512); ! 237: Wp = Dbuf = (short *)sbrk(5120); ! 238: return(mk(cpio, (struct anode *)0, (struct anode *)0)); ! 239: } ! 240: else if(EQ(a, "-newer")) { ! 241: if(stat(b, &Statb) < 0) { ! 242: fprintf(stderr, "find: cannot access < %s >\n", b); ! 243: exit(1); ! 244: } ! 245: Newer = Statb.st_mtime; ! 246: return mk(newer, (struct anode *)0, (struct anode *)0); ! 247: } ! 248: err: fprintf(stderr, "find: bad option < %s >\n", a); ! 249: exit(1); ! 250: } ! 251: struct anode *mk(f, l, r) ! 252: int (*f)(); ! 253: struct anode *l, *r; ! 254: { ! 255: Node[Nn].F = f; ! 256: Node[Nn].L = l; ! 257: Node[Nn].R = r; ! 258: return(&(Node[Nn++])); ! 259: } ! 260: ! 261: char *nxtarg() { /* get next arg from command line */ ! 262: static strikes = 0; ! 263: ! 264: if(strikes==3) { ! 265: fprintf(stderr, "find: incomplete statement\n"); ! 266: exit(1); ! 267: } ! 268: if(Ai>=Argc) { ! 269: strikes++; ! 270: Ai = Argc + 1; ! 271: return(""); ! 272: } ! 273: return(Argv[Ai++]); ! 274: } ! 275: ! 276: /* execution time functions */ ! 277: and(p) ! 278: register struct anode *p; ! 279: { ! 280: return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R))?1:0); ! 281: } ! 282: or(p) ! 283: register struct anode *p; ! 284: { ! 285: return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R))?1:0); ! 286: } ! 287: not(p) ! 288: register struct anode *p; ! 289: { ! 290: return( !((*p->L->F)(p->L))); ! 291: } ! 292: glob(p) ! 293: register struct { int f; char *pat; } *p; ! 294: { ! 295: return(amatch(Fname, p->pat)); ! 296: } ! 297: print() ! 298: { ! 299: puts(Pathname); ! 300: return(1); ! 301: } ! 302: mtime(p) ! 303: register struct { int f, t, s; } *p; ! 304: { ! 305: if(Status != 0) return 0; ! 306: return(scomp((int)((Now - Statb.st_mtime) / A_DAY), p->t, p->s)); ! 307: } ! 308: ctime(p) ! 309: register struct { int f, t, s; } *p; ! 310: { ! 311: if(Status != 0) return 0; ! 312: return(scomp((int)((Now - Statb.st_ctime) / A_DAY), p->t, p->s)); ! 313: } ! 314: atime(p) ! 315: register struct { int f, t, s; } *p; ! 316: { ! 317: if(Status != 0) return 0; ! 318: return(scomp((int)((Now - Statb.st_atime) / A_DAY), p->t, p->s)); ! 319: } ! 320: user(p) ! 321: register struct { int f, u, s; } *p; ! 322: { ! 323: if(Status != 0) return 0; ! 324: return(scomp(Statb.st_uid, p->u, p->s)); ! 325: } ! 326: ino(p) ! 327: register struct { int f, u, s; } *p; ! 328: { ! 329: if(Status != 0) return 0; ! 330: return(scomp((int)Statb.st_ino, p->u, p->s)); ! 331: } ! 332: group(p) ! 333: register struct { int f, u; } *p; ! 334: { ! 335: if(Status != 0) return 0; ! 336: return(p->u == Statb.st_gid); ! 337: } ! 338: links(p) ! 339: register struct { int f, link, s; } *p; ! 340: { ! 341: if(Status != 0) return 0; ! 342: return(scomp(Statb.st_nlink, p->link, p->s)); ! 343: } ! 344: size(p) ! 345: register struct { int f, sz, s; } *p; ! 346: { ! 347: if(Status != 0) return 0; ! 348: return(scomp((int)((Statb.st_size+511)>>9), p->sz, p->s)); ! 349: } ! 350: perm(p) ! 351: register struct { int f, per, s; } *p; ! 352: { ! 353: register i; ! 354: if(Status != 0) return 0; ! 355: i = (p->s=='-') ? p->per : 07777; /* '-' means only arg bits */ ! 356: return((Statb.st_mode & i & 07777) == p->per); ! 357: } ! 358: type(p) ! 359: register struct { int f, per, s; } *p; ! 360: { ! 361: if(Status != 0) return 0; ! 362: return((Statb.st_mode&S_IFMT)==p->per); ! 363: } ! 364: exeq(p) ! 365: register struct { int f, com; } *p; ! 366: { ! 367: fflush(stdout); /* to flush possible `-print' */ ! 368: return(doex(p->com)); ! 369: } ! 370: ok(p) ! 371: struct { int f, com; } *p; ! 372: { ! 373: char c; int yes; ! 374: yes = 0; ! 375: fflush(stdout); /* to flush possible `-print' */ ! 376: fprintf(stderr, "< %s ... %s > ? ", Argv[p->com], Pathname); ! 377: fflush(stderr); ! 378: if((c=getchar())=='y') yes = 1; ! 379: while(c!='\n') c = getchar(); ! 380: if(yes) return(doex(p->com)); ! 381: return(0); ! 382: } ! 383: ! 384: #define MKSHORT(v, lv) {U.l=1L;if(U.c[0]) U.l=lv, v[0]=U.s[1], v[1]=U.s[0]; else U.l=lv, v[0]=U.s[0], v[1]=U.s[1];} ! 385: union { long l; short s[2]; char c[4]; } U; ! 386: long mklong(v) ! 387: short v[]; ! 388: { ! 389: U.l = 1; ! 390: if(U.c[0] /* VAX */) ! 391: U.s[0] = v[1], U.s[1] = v[0]; ! 392: else ! 393: U.s[0] = v[0], U.s[1] = v[1]; ! 394: return U.l; ! 395: } ! 396: cpio() ! 397: { ! 398: #define MAGIC 070707 ! 399: struct header { ! 400: short h_magic, ! 401: h_dev, ! 402: h_ino, ! 403: h_mode, ! 404: h_uid, ! 405: h_gid, ! 406: h_nlink, ! 407: h_rdev; ! 408: short h_mtime[2]; ! 409: short h_namesize; ! 410: short h_filesize[2]; ! 411: char h_name[256]; ! 412: } hdr; ! 413: register ifile, ct; ! 414: static long fsz; ! 415: register i; ! 416: ! 417: hdr.h_magic = MAGIC; ! 418: strcpy(hdr.h_name, !strncmp(Pathname, "./", 2)? Pathname+2: Pathname); ! 419: hdr.h_namesize = strlen(hdr.h_name) + 1; ! 420: hdr.h_uid = Statb.st_uid; ! 421: hdr.h_gid = Statb.st_gid; ! 422: hdr.h_dev = Statb.st_dev; ! 423: hdr.h_ino = Statb.st_ino; ! 424: hdr.h_mode = Statb.st_mode; ! 425: MKSHORT(hdr.h_mtime, Statb.st_mtime); ! 426: hdr.h_nlink = Statb.st_nlink; ! 427: fsz = hdr.h_mode & S_IFREG? Statb.st_size: 0L; ! 428: MKSHORT(hdr.h_filesize, fsz); ! 429: hdr.h_rdev = Statb.st_rdev; ! 430: if(EQ(hdr.h_name, "TRAILER!!!")) { ! 431: bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize); ! 432: for(i = 0; i < 10; ++i) ! 433: bwrite(Buf, 512); ! 434: return; ! 435: } ! 436: if(!mklong(hdr.h_filesize)) ! 437: return; ! 438: if((ifile = open(Fname, 0)) < 0) { ! 439: cerror: ! 440: fprintf(stderr, "find: cannot copy < %s >\n", hdr.h_name); ! 441: return; ! 442: } ! 443: bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize); ! 444: for(fsz = mklong(hdr.h_filesize); fsz > 0; fsz -= 512) { ! 445: ct = fsz>512? 512: fsz; ! 446: if(read(ifile, (char *)Buf, ct) < 0) ! 447: goto cerror; ! 448: bwrite(Buf, ct); ! 449: } ! 450: close(ifile); ! 451: return; ! 452: } ! 453: newer() ! 454: { ! 455: if(Status != 0) return 0; ! 456: return Statb.st_mtime > Newer; ! 457: } ! 458: status(p) ! 459: register struct { int f, st, s; } *p; ! 460: { ! 461: Statusqueried = 1; ! 462: return scomp(Status, p->st, p->s); ! 463: } ! 464: errchk() ! 465: { ! 466: if(Status && !Statusqueried) { ! 467: fflush(stdout); ! 468: fprintf(stderr, "find: "); ! 469: perror(Pathname); ! 470: } ! 471: return 1; ! 472: } ! 473: ! 474: /* support functions */ ! 475: scomp(a, b, s) /* funny signed compare */ ! 476: register a, b; ! 477: register char s; ! 478: { ! 479: if(s == '+') ! 480: return(a > b); ! 481: if(s == '-') ! 482: return(a < (b * -1)); ! 483: return(a == b); ! 484: } ! 485: ! 486: doex(com) ! 487: { ! 488: register np; ! 489: register char *na; ! 490: static char *nargv[50]; ! 491: static ccode; ! 492: ! 493: ccode = np = 0; ! 494: while (na=Argv[com++]) { ! 495: if(strcmp(na, ";")==0) break; ! 496: if(strcmp(na, "{}")==0) nargv[np++] = Pathname; ! 497: else nargv[np++] = na; ! 498: } ! 499: nargv[np] = 0; ! 500: if (np==0) return(9); ! 501: if(fork()) /*parent*/ { ! 502: #include <signal.h> ! 503: int (*old)() = signal(SIGINT, SIG_IGN); ! 504: int (*oldq)() = signal(SIGQUIT, SIG_IGN); ! 505: wait(&ccode); ! 506: signal(SIGINT, old); ! 507: signal(SIGQUIT, oldq); ! 508: } else { /*child*/ ! 509: chdir(Home); ! 510: execvp(nargv[0], nargv, np); ! 511: exit(1); ! 512: } ! 513: return(ccode ? 0:1); ! 514: } ! 515: ! 516: getunum(f, s) char *f, *s; { /* find user/group name and return number */ ! 517: register i; ! 518: register char *sp; ! 519: register c; ! 520: char str[20]; ! 521: FILE *pin; ! 522: ! 523: i = -1; ! 524: pin = fopen(f, "r"); ! 525: c = '\n'; /* prime with a CR */ ! 526: do { ! 527: if(c=='\n') { ! 528: sp = str; ! 529: while((c = *sp++ = getc(pin)) != ':') ! 530: if(c == EOF) goto RET; ! 531: *--sp = '\0'; ! 532: if(EQ(str, s)) { ! 533: while((c=getc(pin)) != ':') ! 534: if(c == EOF) goto RET; ! 535: sp = str; ! 536: while((*sp = getc(pin)) != ':') sp++; ! 537: *sp = '\0'; ! 538: i = atoi(str); ! 539: goto RET; ! 540: } ! 541: } ! 542: } while((c = getc(pin)) != EOF); ! 543: RET: ! 544: fclose(pin); ! 545: return(i); ! 546: } ! 547: ! 548: #include <ndir.h> ! 549: ! 550: ! 551: descend(name, fname, exlist) ! 552: struct anode *exlist; ! 553: char *name, *fname; ! 554: { ! 555: DIR *dir = 0; ! 556: register struct direct *dp; ! 557: register char *c1, *c2; ! 558: int i; ! 559: int rv = 0; ! 560: char *endofname; ! 561: ! 562: errno = 0; ! 563: if (lstat(fname, &Statb) == -1) { ! 564: fprintf(stderr, "find: bad status < %s >\n", name); ! 565: return 0; ! 566: } ! 567: Status = errno; ! 568: Statusqueried = 0; ! 569: (*exlist->F)(exlist); ! 570: if((Statb.st_mode&S_IFMT)!=S_IFDIR) ! 571: return(1); ! 572: for(c1 = name; *c1; ++c1); ! 573: if(*(c1-1) == '/') ! 574: --c1; ! 575: endofname = c1; ! 576: ! 577: if(chdir(fname) == -1) ! 578: return(0); ! 579: if ((dir = opendir(".")) == 0) { ! 580: fprintf(stderr, "find: cannot open < %s >\n", name); ! 581: rv = 0; ! 582: goto ret; ! 583: } ! 584: for (dp = readdir(dir); dp; dp = readdir(dir)) { ! 585: if ((dp->d_name[0]=='.' && dp->d_name[1]=='\0') || ! 586: (dp->d_name[0]=='.' && dp->d_name[1]=='.' && dp->d_name[2]=='\0')) ! 587: continue; ! 588: c1 = endofname; ! 589: *c1++ = '/'; ! 590: strcpy(c1, dp->d_name); ! 591: Fname = endofname+1; ! 592: if(!descend(name, Fname, exlist)) { ! 593: *endofname = '\0'; ! 594: chdir(Home); ! 595: if(chdir(Pathname) == -1) { ! 596: fprintf(stderr, "find: bad directory tree\n"); ! 597: exit(1); ! 598: } ! 599: } ! 600: } ! 601: rv = 1; ! 602: closedir(dir); ! 603: ret: ! 604: if(chdir("..") == -1) { ! 605: *endofname = '\0'; ! 606: fprintf(stderr, "find: bad directory <%s>\n", name); ! 607: rv = 1; ! 608: } ! 609: return(rv); ! 610: } ! 611: ! 612: amatch(s, p) ! 613: register char *s, *p; ! 614: { ! 615: register cc; ! 616: int scc, k; ! 617: int c, lc; ! 618: ! 619: scc = *s; ! 620: lc = 077777; ! 621: switch (c = *p) { ! 622: ! 623: case '[': ! 624: k = 0; ! 625: while (cc = *++p) { ! 626: switch (cc) { ! 627: ! 628: case ']': ! 629: if (k) ! 630: return(amatch(++s, ++p)); ! 631: else ! 632: return(0); ! 633: ! 634: case '-': ! 635: k |= lc <= scc & scc <= (cc=p[1]); ! 636: } ! 637: if (scc==(lc=cc)) k++; ! 638: } ! 639: return(0); ! 640: ! 641: case '?': ! 642: caseq: ! 643: if(scc) return(amatch(++s, ++p)); ! 644: return(0); ! 645: case '*': ! 646: return(umatch(s, ++p)); ! 647: case 0: ! 648: return(!scc); ! 649: } ! 650: if (c==scc) goto caseq; ! 651: return(0); ! 652: } ! 653: ! 654: umatch(s, p) ! 655: register char *s, *p; ! 656: { ! 657: if(*p==0) return(1); ! 658: while(*s) ! 659: if (amatch(s++, p)) return(1); ! 660: return(0); ! 661: } ! 662: ! 663: bwrite(rp, c) ! 664: register short *rp; ! 665: register c; ! 666: { ! 667: register short *wp = Wp; ! 668: ! 669: c = (c+1) >> 1; ! 670: while(c--) { ! 671: if(!Wct) { ! 672: again: ! 673: if(write(Cpio, (char *)Dbuf, Bufsize)<0) { ! 674: Cpio = chgreel(1, Cpio); ! 675: goto again; ! 676: } ! 677: Wct = Bufsize >> 1; ! 678: wp = Dbuf; ! 679: ++Blocks; ! 680: } ! 681: *wp++ = *rp++; ! 682: --Wct; ! 683: } ! 684: Wp = wp; ! 685: } ! 686: chgreel(x, fl) ! 687: { ! 688: register f; ! 689: char str[22]; ! 690: FILE *devtty; ! 691: struct stat statb; ! 692: extern errno; ! 693: ! 694: fprintf(stderr, "find: errno: %d, ", errno); ! 695: fprintf(stderr, "find: can't %s\n", x? "write output": "read input"); ! 696: fstat(fl, &statb); ! 697: if((statb.st_mode&S_IFMT) != S_IFCHR) ! 698: exit(1); ! 699: again: ! 700: fprintf(stderr, "If you want to go on, type device/file name %s\n", ! 701: "when ready"); ! 702: devtty = fopen("/dev/tty", "r"); ! 703: fgets(str, 20, devtty); ! 704: str[strlen(str) - 1] = '\0'; ! 705: if(!*str) ! 706: exit(1); ! 707: close(fl); ! 708: if((f = open(str, x? 1: 0)) < 0) { ! 709: fprintf(stderr, "That didn't work"); ! 710: fclose(devtty); ! 711: goto again; ! 712: } ! 713: return f; ! 714: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.