|
|
1.1 root 1: /* @(#)cpio.c 1.7 */
2: /* cpio COMPILE: cc -O cpio.c -s -i -o cpio
3: cpio -- copy file collections
4:
5: */
6: #include <stdio.h>
7: #include <signal.h>
8: #ifdef RT
9: #include <rt/macro.h>
10: #include <rt/types.h>
11: #include <rt/stat.h>
12: #else
13: #include <sys/types.h>
14: #include <sys/stat.h>
15: #endif
16: #define EQ(x,y) (strcmp(x,y)==0)
17: /* for VAX, Interdata, ... */
18: #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];}
19: #define MAGIC 070707 /* cpio magic number */
20: #define IN 1 /* copy in */
21: #define OUT 2 /* copy out */
22: #define PASS 3 /* direct copy */
23: #define HDRSIZE (Hdr.h_name - (char *)&Hdr) /* header size minus filename field */
24: #define LINKS 1000 /* max no. of links allowed */
25: #define CHARS 76 /* ASCII header size minus filename field */
26: #undef BUFSIZE
27: #define BUFSIZE 512 /* In u370, can't use BUFSIZ nor BSIZE */
28: #define CPIOBSZ 4096 /* file read/write */
29: #ifdef RT
30: extern long filespace;
31: #endif
32:
33: struct stat Statb, Xstatb;
34:
35: /* Cpio header format */
36: struct header {
37: short h_magic,
38: h_dev;
39: unsigned
40: short h_ino,
41: h_mode,
42: h_uid,
43: h_gid;
44: short h_nlink,
45: h_rdev,
46: h_mtime[2],
47: h_namesize,
48: h_filesize[2];
49: char h_name[256];
50: } Hdr;
51:
52: unsigned Bufsize = BUFSIZE; /* default record size */
53: short Buf[CPIOBSZ/2], *Dbuf;
54: char BBuf[CPIOBSZ], *Cbuf;
55: int Wct, Wc;
56: short *Wp;
57: char *Cp;
58:
59: #ifdef RT
60: short Actual_size[2];
61: #endif
62:
63: short Option,
64: Dir,
65: Uncond,
66: Link,
67: Rename,
68: Toc,
69: Verbose,
70: Select,
71: Mod_time,
72: Acc_time,
73: Cflag,
74: fflag,
75: #ifdef RT
76: Extent,
77: #endif
78: Swap,
79: byteswap,
80: bothswap,
81: halfswap;
82:
83: int Ifile,
84: Ofile,
85: Input = 0,
86: Output = 1;
87: long Blocks,
88: Longfile,
89: Longtime;
90:
91: char Fullname[256],
92: Name[256];
93: int Pathend;
94:
95: FILE *Rtty,
96: *Wtty;
97:
98: char *Pattern[100];
99: char Strhdr[500];
100: char *Chdr = Strhdr;
101: short Dev,
102: Uid,
103: Gid,
104: A_directory,
105: A_special,
106: #ifdef RT
107: One_extent,
108: Multi_extent,
109: #endif
110: Filetype = S_IFMT;
111:
112: extern errno;
113: char *malloc();
114: char *cd();
115: /* char *Cd_name; */
116: FILE *popen();
117:
118: union { long l; short s[2]; char c[4]; } U;
119:
120: /* for VAX, Interdata, ... */
121: long mklong(v)
122: short v[];
123: {
124: U.l = 1;
125: if(U.c[0])
126: U.s[0] = v[1], U.s[1] = v[0];
127: else
128: U.s[0] = v[0], U.s[1] = v[1];
129: return U.l;
130: }
131:
132: main(argc, argv)
133: char **argv;
134: {
135: register ct;
136: long filesz;
137: register char *fullp;
138: register i;
139: int ans;
140:
141: signal(SIGSYS, 1);
142: if(*argv[1] != '-')
143: usage();
144: Uid = getuid();
145: umask(0);
146: Gid = getgid();
147: Pattern[0] = "*";
148:
149: while(*++argv[1]) {
150: switch(*argv[1]) {
151: case 'a': /* reset access time */
152: Acc_time++;
153: break;
154: case 'B': /* change record size to 5120 bytes */
155: Bufsize = 5120;
156: break;
157: case 'i':
158: Option = IN;
159: if(argc > 2 ) { /* save patterns, if any */
160: for(i = 0; (i+2) < argc; ++i)
161: Pattern[i] = argv[i+2];
162: }
163: break;
164: case 'f': /* do not consider patterns in cmd line */
165: fflag++;
166: break;
167: case 'o':
168: if(argc != 2)
169: usage();
170: Option = OUT;
171: break;
172: case 'p':
173: if(argc != 3)
174: usage();
175: if(access(argv[2], 2) == -1) {
176: accerr:
177: fprintf(stderr,"cannot write in <%s>\n", argv[2]);
178: exit(2);
179: }
180: strcpy(Fullname, argv[2]); /* destination directory */
181: strcat(Fullname, "/");
182: stat(Fullname, &Xstatb);
183: if((Xstatb.st_mode&S_IFMT) != S_IFDIR)
184: goto accerr;
185: Option = PASS;
186: Dev = Xstatb.st_dev;
187: break;
188: case 'c': /* ASCII header */
189: Cflag++;
190: break;
191: case 'd': /* create directories when needed */
192: Dir++;
193: break;
194: case 'l': /* link files, when necessary */
195: Link++;
196: break;
197: case 'm': /* retain mod time */
198: Mod_time++;
199: break;
200: case 'r': /* rename files interactively */
201: Rename++;
202: Rtty = fopen("/dev/tty", "r");
203: Wtty = fopen("/dev/tty", "w");
204: if(Rtty==NULL || Wtty==NULL) {
205: fprintf(stderr,
206: "Cannot rename (/dev/tty missing)\n");
207: exit(2);
208: }
209: break;
210: case 'S': /* swap halfwords */
211: halfswap++;
212: Swap++;
213: break;
214: case 's': /* swap bytes */
215: byteswap++;
216: Swap++;
217: break;
218: case 'b':
219: bothswap++;
220: Swap++;
221: break;
222: case 't': /* table of contents */
223: Toc++;
224: break;
225: case 'u': /* copy unconditionally */
226: Uncond++;
227: break;
228: case 'v': /* verbose table of contents */
229: Verbose++;
230: break;
231: case '6': /* for old, sixth-edition files */
232: Filetype = 060000;
233: break;
234: #ifdef RT
235: case 'e':
236: Extent++;
237: break;
238: #endif
239: default:
240: usage();
241: }
242: }
243: if(!Option) {
244: fprintf(stderr,"Options must include o|i|p\n");
245: exit(2);
246: }
247: #ifdef RT
248: setio(-1,1); /* turn on physio */
249: #endif
250:
251: if(Option == PASS) {
252: if(Rename) {
253: fprintf(stderr,"Pass and Rename cannot be used together\n");
254: exit(2);
255: }
256: if(Bufsize == 5120) {
257: printf("`B' option is irrelevant with the '-p' option\n");
258: Bufsize = BUFSIZE;
259: }
260:
261: }else {
262: if(Cflag)
263: Cp = Cbuf = (char *)malloc(Bufsize);
264: else
265: Wp = Dbuf = (short *)malloc(Bufsize);
266: }
267: Wct = Bufsize >> 1;
268: Wc = Bufsize;
269:
270: switch(Option) {
271:
272: case OUT: /* get filename, copy header and file out */
273: while(getname()) {
274: if( mklong(Hdr.h_filesize) == 0L) {
275: if( Cflag )
276: writehdr(Chdr,CHARS+Hdr.h_namesize);
277: else
278: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
279: #ifdef RT
280: if (One_extent || Multi_extent) {
281: actsize(0);
282: if( Cflag )
283: writehdr(Chdr,CHARS+Hdr.h_namesize);
284: else
285: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
286: }
287: #endif
288: continue;
289: }
290: if((Ifile = open(Hdr.h_name, 0)) < 0) {
291: fprintf(stderr,"<%s> ?\n", Hdr.h_name);
292: continue;
293: }
294: if ( Cflag )
295: writehdr(Chdr,CHARS+Hdr.h_namesize);
296: else
297: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
298: #ifdef RT
299: if (One_extent || Multi_extent) {
300: actsize(Ifile);
301: if(Cflag)
302: writehdr(Chdr,CHARS+Hdr.h_namesize);
303: else
304: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
305: Hdr.h_filesize[0] = Actual_size[0];
306: Hdr.h_filesize[1] = Actual_size[1];
307: }
308: #endif
309: for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){
310: ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
311: if(read(Ifile, Cflag? BBuf: (char *)Buf, ct) < 0) {
312: fprintf(stderr,"Cannot read %s\n", Hdr.h_name);
313: continue;
314: }
315: Cflag? writehdr(BBuf,ct): bwrite(Buf,ct);
316: }
317: close(Ifile);
318: if(Acc_time)
319: utime(Hdr.h_name, &Statb.st_atime);
320: if(Verbose)
321: fprintf(stderr,"%s\n", Hdr.h_name);
322: }
323:
324: /* copy trailer, after all files have been copied */
325: strcpy(Hdr.h_name, "TRAILER!!!");
326: Hdr.h_magic = MAGIC;
327: MKSHORT(Hdr.h_filesize, 0L);
328: Hdr.h_namesize = strlen("TRAILER!!!") + 1;
329: if ( Cflag ) {
330: bintochar(0L);
331: writehdr(Chdr,CHARS+Hdr.h_namesize);
332: }
333: else
334: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
335: Cflag? writehdr(Cbuf, Bufsize): bwrite(Dbuf, Bufsize);
336: break;
337:
338: case IN:
339: pwd();
340: while(gethdr()) {
341: Ofile = ckname(Hdr.h_name)? openout(Hdr.h_name): 0;
342: for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){
343: ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
344: Cflag? readhdr(BBuf,ct): bread(Buf, ct);
345: if(Ofile) {
346: if(Swap)
347: Cflag? swap(BBuf,ct): swap(Buf,ct);
348: if(write(Ofile, Cflag? BBuf: (char *)Buf, ct) < 0) {
349: fprintf(stderr,"Cannot write %s\n", Hdr.h_name);
350: continue;
351: }
352: }
353: }
354: if(Ofile) {
355: close(Ofile);
356: if(chmod(Hdr.h_name, Hdr.h_mode) < 0) {
357: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno);
358: }
359: set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
360: }
361: if(!Select)
362: continue;
363: if(Verbose)
364: if(Toc)
365: pentry(Hdr.h_name);
366: else
367: puts(Hdr.h_name);
368: else if(Toc)
369: puts(Hdr.h_name);
370: }
371: break;
372:
373: case PASS: /* move files around */
374: fullp = Fullname + strlen(Fullname);
375:
376: while(getname()) {
377: if (A_directory && !Dir)
378: fprintf(stderr,"Use `-d' option to copy <%s>\n",Hdr.h_name);
379: if(!ckname(Hdr.h_name))
380: continue;
381: i = 0;
382: while(Hdr.h_name[i] == '/')
383: i++;
384: strcpy(fullp, &(Hdr.h_name[i]));
385:
386: if(Link
387: && !A_directory
388: && Dev == Statb.st_dev) {
389: /* ??? && (Uid == Statb.st_uid || !Uid)) {*/
390: if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */
391: unlink(Fullname);
392: missdir(Fullname);
393: if(link(Hdr.h_name, Fullname) < 0) {
394: fprintf(stderr,
395: "Cannot link <%s> & <%s>\n",
396: Hdr.h_name, Fullname);
397: continue;
398: }
399: }
400:
401: /* try creating (only twice) */
402: ans = 0;
403: do {
404: if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */
405: unlink(Fullname);
406: ans += 1;
407: }else {
408: ans = 0;
409: break;
410: }
411: }while(ans < 2 && missdir(Fullname) == 0);
412: if(ans == 1) {
413: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", Fullname, errno);
414: exit(0);
415: }else if(ans == 2) {
416: fprintf(stderr,"Cannot link <%s> & <%s>\n", Hdr.h_name, Fullname);
417: exit(0);
418: }
419:
420: if(chmod(Hdr.h_name, Hdr.h_mode) < 0) {
421: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno);
422: }
423: set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
424: goto ckverbose;
425: }
426: #ifdef RT
427: if (One_extent || Multi_extent)
428: actsize(0);
429: #endif
430: if(!(Ofile = openout(Fullname)))
431: continue;
432: if((Ifile = open(Hdr.h_name, 0)) < 0) {
433: fprintf(stderr,"<%s> ?\n", Hdr.h_name);
434: close(Ofile);
435: continue;
436: }
437: filesz = Statb.st_size;
438: for(; filesz > 0; filesz -= CPIOBSZ) {
439: ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
440: if(read(Ifile, Buf, ct) < 0) {
441: fprintf(stderr,"Cannot read %s\n", Hdr.h_name);
442: break;
443: }
444: if(Ofile)
445: if(write(Ofile, Buf, ct) < 0) {
446: fprintf(stderr,"Cannot write %s\n", Hdr.h_name);
447: break;
448: }
449: #ifndef u370
450: Blocks += ((ct + (BUFSIZE - 1)) / BUFSIZE);
451: #else
452: ++Blocks;
453: #endif
454: }
455: close(Ifile);
456: if(Acc_time)
457: utime(Hdr.h_name, &Statb.st_atime);
458: if(Ofile) {
459: close(Ofile);
460: if(chmod(Fullname, Hdr.h_mode) < 0) {
461: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Fullname, errno);
462: }
463: set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime));
464: ckverbose:
465: if(Verbose)
466: puts(Fullname);
467: }
468: }
469: }
470: /* print number of blocks actually copied */
471: fprintf(stderr,"%ld blocks\n", Blocks * (Bufsize>>9));
472: exit(0);
473: }
474: usage()
475: {
476: fprintf(stderr,"Usage: cpio -o[acvB] <name-list >collection\n%s\n%s\n",
477: " cpio -i[cdmrstuvfB6] [pattern ...] <collection",
478: " cpio -p[adlmruv] directory <name-list");
479: exit(2);
480: }
481:
482: getname() /* get file name, get info for header */
483: {
484: register char *namep = Name;
485: register unsigned short ftype;
486: long tlong;
487:
488: for(;;) {
489: if(gets(namep) == NULL)
490: return 0;
491: if(*namep == '.' && namep[1] == '/')
492: namep += 2;
493: strcpy(Hdr.h_name, namep);
494: if(stat(namep, &Statb) < 0) {
495: fprintf(stderr,"< %s > ?\n", Hdr.h_name);
496: continue;
497: }
498: ftype = Statb.st_mode & Filetype;
499: A_directory = (ftype == S_IFDIR);
500: A_special = (ftype == S_IFBLK)
501: || (ftype == S_IFCHR)
502: #ifdef UX3
503: || (ftype == S_IFIFO)
504: #endif
505: ;
506: #ifdef RT
507: A_special |= (ftype == S_IFREC);
508: One_extent = (ftype == S_IF1EXT);
509: Multi_extent = (ftype == S_IFEXT);
510: #endif
511: Hdr.h_magic = MAGIC;
512: Hdr.h_namesize = strlen(Hdr.h_name) + 1;
513: Hdr.h_uid = Statb.st_uid;
514: Hdr.h_gid = Statb.st_gid;
515: Hdr.h_dev = Statb.st_dev;
516: Hdr.h_ino = Statb.st_ino;
517: Hdr.h_mode = Statb.st_mode;
518: MKSHORT(Hdr.h_mtime, Statb.st_mtime);
519: Hdr.h_nlink = Statb.st_nlink;
520: tlong = (Hdr.h_mode&S_IFMT) == S_IFREG? Statb.st_size: 0L;
521: #ifdef RT
522: if (One_extent || Multi_extent) tlong = Statb.st_size;
523: #endif
524: MKSHORT(Hdr.h_filesize, tlong);
525: Hdr.h_rdev = Statb.st_rdev;
526: if( Cflag )
527: bintochar(tlong);
528: return 1;
529: }
530: }
531:
532: bintochar(t) /* ASCII header write */
533: long t;
534: {
535: sprintf(Chdr,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s",
536: MAGIC,Statb.st_dev,Statb.st_ino,Statb.st_mode,Statb.st_uid,
537: Statb.st_gid,Statb.st_nlink,Statb.st_rdev & 00000177777,
538: Statb.st_mtime,(short)strlen(Hdr.h_name)+1,t,Hdr.h_name);
539: }
540:
541: chartobin() /* ASCII header read */
542: {
543: sscanf(Chdr,"%6ho%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo",
544: &Hdr.h_magic,&Hdr.h_dev,&Hdr.h_ino,&Hdr.h_mode,&Hdr.h_uid,
545: &Hdr.h_gid,&Hdr.h_nlink,&Hdr.h_rdev,&Longtime,&Hdr.h_namesize,
546: &Longfile);
547: MKSHORT(Hdr.h_filesize, Longfile);
548: MKSHORT(Hdr.h_mtime, Longtime);
549: }
550:
551: gethdr() /* get file headers */
552: {
553: register unsigned short ftype;
554:
555: if (Cflag) {
556: readhdr(Chdr,CHARS);
557: chartobin();
558: }
559: else
560: bread(&Hdr, HDRSIZE);
561:
562: if(Hdr.h_magic != MAGIC) {
563: fprintf(stderr,"Out of phase--get help\n");
564: exit(2);
565: }
566: if(Cflag)
567: readhdr(Hdr.h_name, Hdr.h_namesize);
568: else
569: bread(Hdr.h_name, Hdr.h_namesize);
570: if(EQ(Hdr.h_name, "TRAILER!!!"))
571: return 0;
572: ftype = Hdr.h_mode & Filetype;
573: A_directory = (ftype == S_IFDIR);
574: A_special =(ftype == S_IFBLK)
575: || (ftype == S_IFCHR)
576: #ifdef UX3
577: || (ftype == S_IFIFO)
578: #endif
579: ;
580: #ifdef RT
581: A_special |= (ftype == S_IFREC);
582: One_extent = (ftype == S_IF1EXT);
583: Multi_extent = (ftype == S_IFEXT);
584: if (One_extent || Multi_extent) {
585: Actual_size[0] = Hdr.h_filesize[0];
586: Actual_size[1] = Hdr.h_filesize[1];
587: if (Cflag) {
588: readhdr(Chdr,CHARS);
589: chartobin();
590: }
591: else
592: bread(&Hdr, HDRSIZE);
593:
594: if(Hdr.h_magic != MAGIC) {
595: fprintf(stderr,"Out of phase--get RT help\n");
596: exit(2);
597: }
598: if(Cflag)
599: readhdr(Hdr.h_name, Hdr.h_namesize);
600: else
601: bread(Hdr.h_name, Hdr.h_namesize);
602: }
603: #endif
604: return 1;
605: }
606:
607: ckname(namep) /* check filenames with patterns given on cmd line */
608: register char *namep;
609: {
610: ++Select;
611: if(fflag ^ !nmatch(namep, Pattern)) {
612: Select = 0;
613: return 0;
614: }
615: if(Rename && !A_directory) { /* rename interactively */
616: fprintf(Wtty, "Rename <%s>\n", namep);
617: fflush(Wtty);
618: fgets(namep, 128, Rtty);
619: if(feof(Rtty))
620: exit(2);
621: namep[strlen(namep) - 1] = '\0';
622: if(EQ(namep, "")) {
623: printf("Skipped\n");
624: return 0;
625: }
626: }
627: return !Toc;
628: }
629:
630: openout(namep) /* open files for writing, set all necessary info */
631: register char *namep;
632: {
633: register f;
634: register char *np;
635: int ans;
636:
637: if(!strncmp(namep, "./", 2))
638: namep += 2;
639: np = namep;
640: /*
641: if(Option == IN)
642: Cd_name = namep = cd(namep);
643: */
644: if(A_directory) {
645: if(!Dir
646: || Rename
647: || EQ(namep, ".")
648: || EQ(namep, "..")) /* do not consider . or .. files */
649: return 0;
650: if(stat(namep, &Xstatb) == -1) {
651:
652: /* try creating (only twice) */
653: ans = 0;
654: do {
655: if(makdir(namep) != 0) {
656: ans += 1;
657: }else {
658: ans = 0;
659: break;
660: }
661: }while(ans < 2 && missdir(namep) == 0);
662: if(ans == 1) {
663: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
664: return(0);
665: }else if(ans == 2) {
666: fprintf(stderr,"Cannot create directory <%s> (errno:%d)\n", namep, errno);
667: return(0);
668: }
669: }
670:
671: ret:
672: if(chmod(namep, Hdr.h_mode) < 0) {
673: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", namep, errno);
674: }
675: if(Uid == 0)
676: if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) {
677: fprintf(stderr,"Cannot chown <%s> (errno:%d)\n", namep, errno);
678: }
679: set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
680: return 0;
681: }
682: if(Hdr.h_nlink > 1)
683: if(!postml(namep, np))
684: return 0;
685: if(stat(namep, &Xstatb) == 0) {
686: if(Uncond && !((!(Xstatb.st_mode & S_IWRITE) || A_special) && (Uid != 0))) {
687: if(unlink(namep) < 0) {
688: fprintf(stderr,"cannot unlink current <%s> (errno:%d)\n", namep, errno);
689: }
690: }
691: if(!Uncond && (mklong(Hdr.h_mtime) <= Xstatb.st_mtime)) {
692: /* There's a newer version of file on destination */
693: if(mklong(Hdr.h_mtime) < Xstatb.st_mtime)
694: fprintf(stderr,"current <%s> newer\n", np);
695: return 0;
696: }
697: }
698: if(Option == PASS
699: && Hdr.h_ino == Xstatb.st_ino
700: && Hdr.h_dev == Xstatb.st_dev) {
701: fprintf(stderr,"Attempt to pass file to self!\n");
702: exit(2);
703: }
704: if(A_special) {
705: #ifdef UX3
706: if((Hdr.h_mode & Filetype) == S_IFIFO)
707: Hdr.h_rdev = 0;
708: #endif
709:
710: /* try creating (only twice) */
711: ans = 0;
712: do {
713: if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) {
714: ans += 1;
715: }else {
716: ans = 0;
717: break;
718: }
719: }while(ans < 2 && missdir(np) == 0);
720: if(ans == 1) {
721: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
722: return(0);
723: }else if(ans == 2) {
724: fprintf(stderr,"Cannot mknod <%s> (errno:%d)\n", namep, errno);
725: return(0);
726: }
727:
728: goto ret;
729: }
730: #ifdef RT
731: if(One_extent || Multi_extent) {
732:
733: /* try creating (only twice) */
734: ans = 0;
735: do {
736: if((f = falloc(namep, Hdr.h_mode, longword(Hdr.h_filesize[0]))) < 0) {
737: ans += 1;
738: }else {
739: ans = 0;
740: break;
741: }
742: }while(ans < 2 && missdir(np) == 0);
743: if(ans == 1) {
744: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
745: return(0);
746: }else if(ans == 2) {
747: fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno);
748: return(0);
749: }
750:
751: if(filespace < longword(Hdr.h_filesize[0])){
752: fprintf(stderr,"Cannot create contiguous file <%s> proper size\n", namep);
753: fprintf(stderr," <%s> will be created as a regular file\n", namep);
754: if(unlink(Fullname) != 0)
755: fprintf(stderr,"<%s> not removed\n", namep);
756: Hdr.h_mode = (Hdr.h_mode & !S_IFMT) | S_IFREG;
757: One_extent = Multi_extent = 0;
758: }
759: Hdr.h_filesize[0] = Actual_size[0];
760: Hdr.h_filesize[1] = Actual_size[1];
761: }
762: if (!(One_extent || Multi_extent)) {
763: #endif
764:
765: /* try creating (only twice) */
766: ans = 0;
767: do {
768: if((f = creat(namep, Hdr.h_mode)) < 0) {
769: ans += 1;
770: }else {
771: ans = 0;
772: break;
773: }
774: }while(ans < 2 && missdir(np) == 0);
775: if(ans == 1) {
776: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
777: return(0);
778: }else if(ans == 2) {
779: fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno);
780: return(0);
781: }
782:
783: #ifdef RT
784: }
785: #endif
786: if(Uid == 0)
787: chown(namep, Hdr.h_uid, Hdr.h_gid);
788: return f;
789: }
790:
791: bread(b, c)
792: register c;
793: register short *b;
794: {
795: static nleft = 0;
796: static short *ip;
797: register int rv;
798: register short *p = ip;
799: register int in;
800:
801: c = (c+1)>>1;
802: while(c--) {
803: if(nleft == 0) {
804: in = 0;
805: while((rv=read(Input, &(((char *)Dbuf)[in]), Bufsize - in)) != Bufsize - in) {
806: if(rv <= 0) {
807: Input = chgreel(0, Input);
808: continue;
809: }
810: in += rv;
811: nleft += (rv >> 1);
812: }
813: nleft += (rv >> 1);
814: p = Dbuf;
815: ++Blocks;
816: }
817: *b++ = *p++;
818: --nleft;
819: }
820: ip = p;
821: }
822:
823: readhdr(b, c)
824: register c;
825: register char *b;
826: {
827: static nleft = 0;
828: static char *ip;
829: register int rv;
830: register char *p = ip;
831: register int in;
832:
833: while(c--) {
834: if(nleft == 0) {
835: in = 0;
836: while((rv=read(Input, &(((char *)Cbuf)[in]), Bufsize - in)) != Bufsize - in) {
837: if(rv <= 0) {
838: Input = chgreel(0, Input);
839: continue;
840: }
841: in += rv;
842: nleft += rv;
843: }
844: nleft += rv;
845: p = Cbuf;
846: ++Blocks;
847: }
848: *b++ = *p++;
849: --nleft;
850: }
851: ip = p;
852: }
853:
854: bwrite(rp, c)
855: register short *rp;
856: register c;
857: {
858: register short *wp = Wp;
859:
860: c = (c+1) >> 1;
861: while(c--) {
862: if(!Wct) {
863: again:
864: if(write(Output, Dbuf, Bufsize)<0) {
865: Output = chgreel(1, Output);
866: goto again;
867: }
868: Wct = Bufsize >> 1;
869: wp = Dbuf;
870: ++Blocks;
871: }
872: *wp++ = *rp++;
873: --Wct;
874: }
875: Wp = wp;
876: }
877:
878: writehdr(rp, c)
879: register char *rp;
880: register c;
881: {
882: register char *cp = Cp;
883:
884: while(c--) {
885: if(!Wc) {
886: again:
887: if(write(Output,Cbuf,Bufsize)<0) {
888: Output = chgreel(1,Output);
889: goto again;
890: }
891: Wc = Bufsize;
892: cp = Cbuf;
893: ++Blocks;
894: }
895: *cp++ = *rp++;
896: --Wc;
897: }
898: Cp = cp;
899: }
900:
901: postml(namep, np) /* linking funtion */
902: register char *namep, *np;
903: {
904: register i;
905: static struct ml {
906: short m_dev,
907: m_ino;
908: char m_name[2];
909: } *ml[LINKS];
910: static mlinks = 0;
911: char *mlp;
912: int ans;
913:
914: for(i = 0; i < mlinks; ++i) {
915: if(mlinks == LINKS) break;
916: if(ml[i]->m_ino==Hdr.h_ino &&
917: ml[i]->m_dev==Hdr.h_dev) {
918: if(Verbose)
919: printf("%s linked to %s\n", ml[i]->m_name,
920: np);
921: unlink(namep);
922: if(Option == IN && *ml[i]->m_name != '/') {
923: Fullname[Pathend] = '\0';
924: strcat(Fullname, ml[i]->m_name);
925: mlp = Fullname;
926: }
927: mlp = ml[i]->m_name;
928:
929: /* try linking (only twice) */
930: ans = 0;
931: do {
932: if(link(mlp, namep) < 0) {
933: ans += 1;
934: }else {
935: ans = 0;
936: break;
937: }
938: }while(ans < 2 && missdir(np) == 0);
939: if(ans == 1) {
940: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", np, errno);
941: return(0);
942: }else if(ans == 2) {
943: fprintf(stderr,"Cannot link <%s> & <%s>.\n", ml[i]->m_name, np);
944: return(0);
945: }
946:
947: set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
948: return 0;
949: }
950: }
951: if(mlinks == LINKS
952: || !(ml[mlinks] = (struct ml *)malloc(strlen(np) + 2 + sizeof(struct ml)))) {
953: static int first=1;
954:
955: if(first)
956: if(mlinks == LINKS)
957: fprintf(stderr,"Too many links\n");
958: else
959: fprintf(stderr,"No memory for links\n");
960: mlinks = LINKS;
961: first = 0;
962: return 1;
963: }
964: ml[mlinks]->m_dev = Hdr.h_dev;
965: ml[mlinks]->m_ino = Hdr.h_ino;
966: strcpy(ml[mlinks]->m_name, np);
967: ++mlinks;
968: return 1;
969: }
970:
971: pentry(namep) /* print verbose table of contents */
972: register char *namep;
973: {
974:
975: static short lastid = -1;
976: #include <pwd.h>
977: static struct passwd *pw;
978: struct passwd *getpwuid();
979: static char tbuf[32];
980: char *ctime();
981:
982: printf("%-7o", Hdr.h_mode & 0177777);
983: if(lastid != -1 && lastid == Hdr.h_uid)
984: printf("%-6s", pw->pw_name);
985: else {
986: setpwent();
987: if(pw = getpwuid((int)Hdr.h_uid)) {
988: lastid = Hdr.h_uid;
989: printf("%-6s", pw->pw_name);
990: } else {
991: printf("%-6d", Hdr.h_uid);
992: lastid = -1;
993: }
994: }
995: printf("%7ld ", mklong(Hdr.h_filesize));
996: U.l = mklong(Hdr.h_mtime);
997: strcpy(tbuf, ctime((long *)&U.l));
998: tbuf[24] = '\0';
999: printf(" %s %s\n", &tbuf[4], namep);
1000: }
1001:
1002: /* pattern matching functions */
1003: nmatch(s, pat)
1004: char *s, **pat;
1005: {
1006: if(EQ(*pat, "*"))
1007: return 1;
1008: while(*pat) {
1009: if((**pat == '!' && !gmatch(s, *pat+1))
1010: || gmatch(s, *pat))
1011: return 1;
1012: ++pat;
1013: }
1014: return 0;
1015: }
1016: gmatch(s, p)
1017: register char *s, *p;
1018: {
1019: register int c;
1020: register cc, ok, lc, scc;
1021:
1022: scc = *s;
1023: lc = 077777;
1024: switch (c = *p) {
1025:
1026: case '[':
1027: ok = 0;
1028: while (cc = *++p) {
1029: switch (cc) {
1030:
1031: case ']':
1032: if (ok)
1033: return(gmatch(++s, ++p));
1034: else
1035: return(0);
1036:
1037: case '-':
1038: ok |= ((lc <= scc) && (scc <= (cc=p[1])));
1039: }
1040: if (scc==(lc=cc)) ok++;
1041: }
1042: return(0);
1043:
1044: case '?':
1045: caseq:
1046: if(scc) return(gmatch(++s, ++p));
1047: return(0);
1048: case '*':
1049: return(umatch(s, ++p));
1050: case 0:
1051: return(!scc);
1052: }
1053: if (c==scc) goto caseq;
1054: return(0);
1055: }
1056:
1057: umatch(s, p)
1058: register char *s, *p;
1059: {
1060: if(*p==0) return(1);
1061: while(*s)
1062: if (gmatch(s++,p)) return(1);
1063: return(0);
1064: }
1065:
1066: makdir(namep) /* make needed directories */
1067: register char *namep;
1068: {
1069: static status;
1070: register pid;
1071:
1072: if(pid = fork())
1073: while(wait(&status) != pid);
1074: else {
1075: close(2);
1076: execl("/bin/mkdir", "mkdir", namep, 0);
1077: exit(2);
1078: }
1079: return ((status>>8) & 0377)? 1: 0;
1080: }
1081:
1082: swap(buf, ct) /* swap halfwords, bytes or both */
1083: register ct;
1084: register char *buf;
1085: {
1086: register char c;
1087: register union swp { long longw; short shortv[2]; char charv[4]; } *pbuf;
1088: int savect, n, i;
1089: char *savebuf;
1090: short cc;
1091:
1092: savect = ct; savebuf = buf;
1093: if(byteswap || bothswap) {
1094: if (ct % 2) buf[ct] = 0;
1095: ct = (ct + 1) / 2;
1096: while (ct--) {
1097: c = *buf;
1098: *buf = *(buf + 1);
1099: *(buf + 1) = c;
1100: buf += 2;
1101: }
1102: if (bothswap) {
1103: ct = savect;
1104: pbuf = (union swp *)savebuf;
1105: if (n = ct % sizeof(union swp)) {
1106: if(n % 2)
1107: for(i = ct + 1; i <= ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0;
1108: else
1109: for (i = ct; i < ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0;
1110: }
1111: ct = (ct + (sizeof(union swp) -1)) / sizeof(union swp);
1112: while(ct--) {
1113: cc = pbuf->shortv[0];
1114: pbuf->shortv[0] = pbuf->shortv[1];
1115: pbuf->shortv[1] = cc;
1116: ++pbuf;
1117: }
1118: }
1119: }
1120: else if (halfswap) {
1121: pbuf = (union swp *)buf;
1122: if (n = ct % sizeof(union swp))
1123: for (i = ct; i < ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0;
1124: ct = (ct + (sizeof(union swp) -1)) / sizeof(union swp);
1125: while (ct--) {
1126: cc = pbuf->shortv[0];
1127: pbuf->shortv[0] = pbuf->shortv[1];
1128: pbuf->shortv[1] = cc;
1129: ++pbuf;
1130: }
1131: }
1132: }
1133: set_time(namep, atime, mtime) /* set access and modification times */
1134: register *namep;
1135: long atime, mtime;
1136: {
1137: static long timevec[2];
1138:
1139: if(!Mod_time)
1140: return;
1141: timevec[0] = atime;
1142: timevec[1] = mtime;
1143: utime(namep, timevec);
1144: }
1145: chgreel(x, fl)
1146: {
1147: register f;
1148: char str[22];
1149: FILE *devtty;
1150: struct stat statb;
1151:
1152: fprintf(stderr,"errno: %d, ", errno);
1153: fprintf(stderr,"Can't %s\n", x? "write output": "read input");
1154: fstat(fl, &statb);
1155: #ifndef RT
1156: if((statb.st_mode&S_IFMT) != S_IFCHR)
1157: exit(2);
1158: #else
1159: if((statb.st_mode & (S_IFBLK|S_IFREC))==0)
1160: exit(2);
1161: #endif
1162: again:
1163: fprintf(stderr,"If you want to go on, type device/file name when ready\n");
1164: devtty = fopen("/dev/tty", "r");
1165: fgets(str, 20, devtty);
1166: str[strlen(str) - 1] = '\0';
1167: if(!*str)
1168: exit(2);
1169: close(fl);
1170: if((f = open(str, x? 1: 0)) < 0) {
1171: fprintf(stderr,"That didn't work");
1172: fclose(devtty);
1173: goto again;
1174: }
1175: return f;
1176: }
1177: missdir(namep)
1178: register char *namep;
1179: {
1180: register char *np;
1181: register ct = 2;
1182:
1183: for(np = namep; *np; ++np)
1184: if(*np == '/') {
1185: if(np == namep) continue; /* skip over 'root slash' */
1186: *np = '\0';
1187: if(stat(namep, &Xstatb) == -1) {
1188: if(Dir) {
1189: if((ct = makdir(namep)) != 0) {
1190: *np = '/';
1191: return(ct);
1192: }
1193: }else {
1194: fprintf(stderr,"missing 'd' option\n");
1195: return(-1);
1196: }
1197: }
1198: *np = '/';
1199: }
1200: if (ct == 2) ct = 0; /* the file already exists */
1201: return ct;
1202: }
1203:
1204: pwd() /* get working directory */
1205: {
1206: FILE *dir;
1207:
1208: dir = popen("pwd", "r");
1209: fgets(Fullname, 256, dir);
1210: if(pclose(dir))
1211: exit(2);
1212: Pathend = strlen(Fullname);
1213: Fullname[Pathend - 1] = '/';
1214: }
1215: char * cd(n) /* change directories */
1216: register char *n;
1217: {
1218: char *p_save = Name, *n_save = n, *p_end = 0;
1219: register char *p = Name;
1220: static char dotdot[]="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../";
1221: int slashes, ans;
1222:
1223: if(*n == '/') /* don't try to chdir on full pathnames */
1224: return n;
1225: for(; *p && *n == *p; ++p, ++n) { /* whatever part of strings == */
1226: if(*p == '/')
1227: p_save = p+1, n_save = n+1;
1228: }
1229:
1230: p = p_save;
1231: *p++ = '\0';
1232: for(slashes = 0; *p; ++p) { /* if prev is longer, chdir("..") */
1233: if(*p == '/')
1234: ++slashes;
1235: }
1236: p = p_save;
1237: if(slashes) {
1238: slashes = slashes * 3 - 1;
1239: dotdot[slashes] = '\0';
1240: chdir(dotdot);
1241: dotdot[slashes] = '/';
1242: }
1243:
1244: n = n_save;
1245: for(; *n; ++n, ++p) {
1246: *p = *n;
1247: if(*n == '/')
1248: p_end = p+1, n_save = n+1;
1249: }
1250: *p = '\0';
1251:
1252: if(p_end) {
1253: *p_end = '\0';
1254: if(chdir(p_save) == -1) {
1255: if((ans = missdir(p_save)) == -1) {
1256: fprintf(stderr,"Cannot chdir (no `d' option)\n");
1257: exit(2);
1258: } else if (ans > 0) {
1259: fprintf(stderr,"Cannot chdir - no write permission\n");
1260: exit(2);
1261: } else if(chdir(p_save) == -1) {
1262: fprintf(stderr,"Cannot chdir\n");
1263: exit(2);
1264: }
1265: }
1266: } else
1267: *p_save = '\0';
1268: return n_save;
1269: }
1270: #ifdef RT
1271: actsize(file)
1272: register int file;
1273: {
1274: long tlong;
1275: long fsize();
1276: register int tfile;
1277:
1278: Actual_size[0] = Hdr.h_filesize[0];
1279: Actual_size[1] = Hdr.h_filesize[1];
1280: if (!Extent)
1281: return;
1282: if (file)
1283: tfile = file;
1284: else if ((tfile = open(Hdr.h_name,0)) < 0)
1285: return;
1286: tlong = fsize(tfile);
1287: MKSHORT(Hdr.h_filesize,tlong);
1288: if (Cflag)
1289: bintochar(tlong);
1290: if (!file)
1291: close(tfile);
1292: }
1293: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.