|
|
1.1 root 1: static char *sccsid = "@(#)ar11.c 4.1 (Berkeley) 10/1/80";
2: /* ar11 - archiver for PDP-11 formatted archives */
3:
4: #include <signal.h>
5: #include <stdio.h>
6: #include <sys/types.h>
7: #include <sys/stat.h>
8: #define ARMAG -155 /* 017545 */
9: struct ar_hdr {
10: char ar_name[14];
11: short ar_date1;
12: short ar_date2;
13: char ar_uid;
14: char ar_gid;
15: short ar_mode;
16: short ar_size1;
17: short ar_size2;
18: };
19: int ar_date;
20: int ar_size;
21: #include <signal.h>
22: struct stat stbuf;
23: struct ar_hdr arbuf;
24: union ints
25: {
26: struct fun
27: {
28: short h1;
29: short h2;
30: };
31: int w1;
32: } x;
33:
34: #define SKIP 1
35: #define IODD 2
36: #define OODD 4
37: #define HEAD 8
38:
39: char *man = { "mrxtdp" };
40: char *opt = { "uvnbai" };
41:
42: int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
43: int sigdone();
44: int rcmd();
45: int dcmd();
46: int xcmd();
47: int tcmd();
48: int pcmd();
49: int mcmd();
50: int (*comfun)();
51: char flg[26];
52: char **namv;
53: int namc;
54: char *arnam;
55: char *ponam;
56: char *tfnam;
57: char *tf1nam;
58: char *tf2nam;
59: char *file;
60: char name[16];
61: int af;
62: int tf;
63: int tf1;
64: int tf2;
65: int bastate;
66: char buf[512];
67:
68: char *trim();
69: char *mktemp();
70: char *ctime();
71:
72: main(argc, argv)
73: char *argv[];
74: {
75: register i;
76: register char *cp;
77:
78: for(i=0; signum[i]; i++)
79: if(signal(signum[i], SIG_IGN) != SIG_IGN)
80: signal(signum[i], sigdone);
81: if(argc < 3)
82: usage();
83: cp = argv[1];
84: for(cp = argv[1]; *cp; cp++)
85: switch(*cp) {
86: case 'c':
87: case 'v':
88: case 'u':
89: case 'n':
90: case 'a':
91: case 'b':
92: case 'i':
93: flg[*cp - 'a']++;
94: continue;
95:
96: case 'r':
97: setcom(rcmd);
98: continue;
99:
100: case 'd':
101: setcom(dcmd);
102: continue;
103:
104: case 'x':
105: setcom(xcmd);
106: continue;
107:
108: case 't':
109: setcom(tcmd);
110: continue;
111:
112: case 'p':
113: setcom(pcmd);
114: continue;
115:
116: case 'm':
117: setcom(mcmd);
118: continue;
119:
120: default:
121: fprintf(stderr, "ar11: bad option `%c'\n", *cp);
122: done(1);
123: }
124: if(flg['i'-'a'])
125: flg['b'-'a']++;
126: if(flg['a'-'a'] || flg['b'-'a']) {
127: bastate = 1;
128: ponam = trim(argv[2]);
129: argv++;
130: argc--;
131: if(argc < 3)
132: usage();
133: }
134: arnam = argv[2];
135: namv = argv+3;
136: namc = argc-3;
137: if(comfun == 0) {
138: if(flg['u'-'a'] == 0) {
139: fprintf(stderr, "ar11: one of [%s] must be specified\n", man);
140: done(1);
141: }
142: setcom(rcmd);
143: }
144: (*comfun)();
145: done(notfound());
146: }
147:
148: setcom(fun)
149: int (*fun)();
150: {
151:
152: if(comfun != 0) {
153: fprintf(stderr, "ar11: only one of [%s] allowed\n", man);
154: done(1);
155: }
156: comfun = fun;
157: }
158:
159: rcmd()
160: {
161: register f;
162:
163: init();
164: if(getaf() && flg['c'-'a']==0) {
165: fprintf(stderr, "ar11: %s does not exist\n", arnam);
166: done(1);
167: }
168: while(!getdir()) {
169: bamatch();
170: if(namc == 0 || match()) {
171: f = stats();
172: if(f < 0) {
173: if(namc)
174: fprintf(stderr, "ar11: cannot open %s\n", file);
175: goto cp;
176: }
177: if(flg['u'-'a'])
178: if(stbuf.st_mtime <= ar_date) {
179: close(f);
180: goto cp;
181: }
182: mesg('r');
183: copyfil(af, -1, IODD+SKIP);
184: movefil(f);
185: continue;
186: }
187: cp:
188: mesg('c');
189: copyfil(af, tf, IODD+OODD+HEAD);
190: }
191: cleanup();
192: }
193:
194: dcmd()
195: {
196:
197: init();
198: if(getaf())
199: noar();
200: while(!getdir()) {
201: if(match()) {
202: mesg('d');
203: copyfil(af, -1, IODD+SKIP);
204: continue;
205: }
206: mesg('c');
207: copyfil(af, tf, IODD+OODD+HEAD);
208: }
209: install();
210: }
211:
212: xcmd()
213: {
214: register f;
215:
216: if(getaf())
217: noar();
218: while(!getdir()) {
219: if(namc == 0 || match()) {
220: f = creat(file, arbuf.ar_mode & 0777);
221: if(f < 0) {
222: fprintf(stderr, "ar11: %s cannot create\n", file);
223: goto sk;
224: }
225: mesg('x');
226: copyfil(af, f, IODD);
227: close(f);
228: continue;
229: }
230: sk:
231: mesg('c');
232: copyfil(af, -1, IODD+SKIP);
233: }
234: }
235:
236: pcmd()
237: {
238:
239: if(getaf())
240: noar();
241: while(!getdir()) {
242: if(namc == 0 || match()) {
243: if(flg['v'-'a']) {
244: printf("\n<%s>\n\n", file);
245: fflush(stdout);
246: }
247: copyfil(af, 1, IODD);
248: continue;
249: }
250: copyfil(af, -1, IODD+SKIP);
251: }
252: }
253:
254: mcmd()
255: {
256:
257: init();
258: if(getaf())
259: noar();
260: tf2nam = mktemp("/tmp/v2XXXXX");
261: close(creat(tf2nam, 0600));
262: tf2 = open(tf2nam, 2);
263: if(tf2 < 0) {
264: fprintf(stderr, "ar11: cannot create third temp\n");
265: done(1);
266: }
267: while(!getdir()) {
268: bamatch();
269: if(match()) {
270: mesg('m');
271: copyfil(af, tf2, IODD+OODD+HEAD);
272: continue;
273: }
274: mesg('c');
275: copyfil(af, tf, IODD+OODD+HEAD);
276: }
277: install();
278: }
279:
280: tcmd()
281: {
282:
283: if(getaf())
284: noar();
285: while(!getdir()) {
286: if(namc == 0 || match()) {
287: if(flg['v'-'a'])
288: longt();
289: printf("%s\n", trim(file));
290: }
291: copyfil(af, -1, IODD+SKIP);
292: }
293: }
294:
295: init()
296: {
297: static short mbuf = ARMAG;
298:
299: tfnam = mktemp("/tmp/vXXXXX");
300: close(creat(tfnam, 0600));
301: tf = open(tfnam, 2);
302: if(tf < 0) {
303: fprintf(stderr, "ar11: cannot create temp file\n");
304: done(1);
305: }
306: if (write(tf, (char *)&mbuf, sizeof(short)) != sizeof(short))
307: wrerr();
308: }
309:
310: getaf()
311: {
312: short mbuf;
313:
314: af = open(arnam, 0);
315: if(af < 0)
316: return(1);
317: if (read(af, (char *)&mbuf, sizeof(short)) != sizeof(short) || mbuf!=ARMAG) {
318: fprintf(stderr, "ar11: %s not in PDP-11 archive format\n", arnam);
319: done(1);
320: }
321: return(0);
322: }
323:
324: usage()
325: {
326: printf("usage: ar11 [%s][%s] archive files ...\n", opt, man);
327: done(1);
328: }
329:
330: noar()
331: {
332:
333: fprintf(stderr, "ar11: %s does not exist\n", arnam);
334: done(1);
335: }
336:
337: sigdone()
338: {
339: done(100);
340: }
341:
342: done(c)
343: {
344:
345: if(tfnam)
346: unlink(tfnam);
347: if(tf1nam)
348: unlink(tf1nam);
349: if(tf2nam)
350: unlink(tf2nam);
351: exit(c);
352: }
353:
354: notfound()
355: {
356: register i, n;
357:
358: n = 0;
359: for(i=0; i<namc; i++)
360: if(namv[i]) {
361: fprintf(stderr, "ar11: %s not found\n", namv[i]);
362: n++;
363: }
364: return(n);
365: }
366:
367: cleanup()
368: {
369: register i, f;
370:
371: for(i=0; i<namc; i++) {
372: file = namv[i];
373: if(file == 0)
374: continue;
375: namv[i] = 0;
376: mesg('a');
377: f = stats();
378: if(f < 0) {
379: fprintf(stderr, "ar11: %s cannot open\n", file);
380: continue;
381: }
382: movefil(f);
383: }
384: install();
385: }
386:
387: install()
388: {
389: register i;
390:
391: for(i=0; signum[i]; i++)
392: signal(signum[i], (int (*)())1);
393: close(af);
394: af = creat(arnam, 0666);
395: if(af < 0) {
396: fprintf(stderr, "ar11: cannot create %s\n", arnam);
397: done(1);
398: }
399: lseek(tf, 0l, 0);
400: while((i = read(tf, buf, 512)) > 0)
401: if (write(af, buf, i) != i)
402: wrerr();
403: if(tf2nam) {
404: lseek(tf2, 0l, 0);
405: while((i = read(tf2, buf, 512)) > 0)
406: if (write(af, buf, i) != i)
407: wrerr();
408: }
409: if(tf1nam) {
410: lseek(tf1, 0l, 0);
411: while((i = read(tf1, buf, 512)) > 0)
412: if (write(af, buf, i) != i)
413: wrerr();
414: }
415: }
416:
417: /*
418: * insert the file 'file'
419: * into the temporary file
420: */
421: movefil(f)
422: {
423: register char *cp;
424: register i;
425:
426: cp = trim(file);
427: for(i=0; i<14; i++)
428: if(arbuf.ar_name[i] = *cp)
429: cp++;
430: x.w1 = stbuf.st_size;
431: arbuf.ar_size1 = x.h2;
432: arbuf.ar_size2 = x.h1;
433: x.w1 = stbuf.st_mtime;
434: arbuf.ar_date1 = x.h2;
435: arbuf.ar_date2 = x.h1;
436: arbuf.ar_uid = stbuf.st_uid;
437: arbuf.ar_gid = stbuf.st_gid;
438: arbuf.ar_mode = stbuf.st_mode;
439: copyfil(f, tf, OODD+HEAD);
440: close(f);
441: }
442:
443: stats()
444: {
445: register f;
446:
447: f = open(file, 0);
448: if(f < 0)
449: return(f);
450: if(fstat(f, &stbuf) < 0) {
451: close(f);
452: return(-1);
453: }
454: return(f);
455: }
456:
457: /*
458: * copy next file
459: * size given in arbuf
460: */
461: copyfil(fi, fo, flag)
462: {
463: register i, o;
464: int pe;
465:
466: if(flag & HEAD)
467: if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf)
468: wrerr();
469: pe = 0;
470: while(ar_size > 0) {
471: i = o = 512;
472: if(ar_size < i) {
473: i = o = ar_size;
474: if(i&1) {
475: if(flag & IODD)
476: i++;
477: if(flag & OODD)
478: o++;
479: }
480: }
481: if(read(fi, buf, i) != i)
482: pe++;
483: if((flag & SKIP) == 0)
484: if (write(fo, buf, o) != o)
485: wrerr();
486: ar_size -= 512;
487: }
488: if(pe)
489: phserr();
490: }
491:
492: getdir()
493: {
494: register i;
495:
496: i = read(af, (char *)&arbuf, sizeof arbuf);
497: if(i != sizeof arbuf) {
498: if(tf1nam) {
499: i = tf;
500: tf = tf1;
501: tf1 = i;
502: }
503: return(1);
504: }
505: for(i=0; i<14; i++)
506: {
507: name[i] = arbuf.ar_name[i];
508: }
509: file = name;
510: ar_date = swap(&arbuf.ar_date1);
511: ar_size = swap(&arbuf.ar_size1);
512: return(0);
513: }
514:
515: match()
516: {
517: register i;
518:
519: for(i=0; i<namc; i++) {
520: if(namv[i] == 0)
521: continue;
522: if(strcmp(trim(namv[i]), file) == 0) {
523: file = namv[i];
524: namv[i] = 0;
525: return(1);
526: }
527: }
528: return(0);
529: }
530:
531: bamatch()
532: {
533: register f;
534:
535: switch(bastate) {
536:
537: case 1:
538: if(strcmp(file, ponam) != 0)
539: return;
540: bastate = 2;
541: if(flg['a'-'a'])
542: return;
543:
544: case 2:
545: bastate = 0;
546: tf1nam = mktemp("/tmp/v1XXXXX");
547: close(creat(tf1nam, 0600));
548: f = open(tf1nam, 2);
549: if(f < 0) {
550: fprintf(stderr, "ar11: cannot create second temp\n");
551: return;
552: }
553: tf1 = tf;
554: tf = f;
555: }
556: }
557:
558: phserr()
559: {
560:
561: fprintf(stderr, "ar11: phase error on %s\n", file);
562: }
563:
564: mesg(c)
565: {
566:
567: if(flg['v'-'a'])
568: if(c != 'c' || flg['v'-'a'] > 1)
569: printf("%c - %s\n", c, file);
570: }
571:
572: char *
573: trim(s)
574: char *s;
575: {
576: register char *p1, *p2;
577:
578: for(p1 = s; *p1; p1++)
579: ;
580: while(p1 > s) {
581: if(*--p1 != '/')
582: break;
583: *p1 = 0;
584: }
585: p2 = s;
586: for(p1 = s; *p1; p1++)
587: if(*p1 == '/')
588: p2 = p1+1;
589: return(p2);
590: }
591:
592: #define IFMT 060000
593: #define ISARG 01000
594: #define LARGE 010000
595: #define SUID 04000
596: #define SGID 02000
597: #define ROWN 0400
598: #define WOWN 0200
599: #define XOWN 0100
600: #define RGRP 040
601: #define WGRP 020
602: #define XGRP 010
603: #define ROTH 04
604: #define WOTH 02
605: #define XOTH 01
606: #define STXT 01000
607:
608: longt()
609: {
610: register char *cp;
611:
612: pmode();
613: printf("%3d/%1d", arbuf.ar_uid, arbuf.ar_gid);
614: printf("%7D", ar_size);
615: cp = ctime(&ar_date);
616: printf(" %-12.12s %-4.4s ", cp+4, cp+20);
617: }
618:
619: int m1[] = { 1, ROWN, 'r', '-' };
620: int m2[] = { 1, WOWN, 'w', '-' };
621: int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
622: int m4[] = { 1, RGRP, 'r', '-' };
623: int m5[] = { 1, WGRP, 'w', '-' };
624: int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
625: int m7[] = { 1, ROTH, 'r', '-' };
626: int m8[] = { 1, WOTH, 'w', '-' };
627: int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
628:
629: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
630:
631: pmode()
632: {
633: register int **mp;
634:
635: for (mp = &m[0]; mp < &m[9];)
636: select(*mp++);
637: }
638:
639: select(pairp)
640: int *pairp;
641: {
642: register int n, *ap;
643:
644: ap = pairp;
645: n = *ap++;
646: while (--n>=0 && (arbuf.ar_mode&*ap++)==0)
647: ap++;
648: putchar(*ap);
649: }
650:
651: wrerr()
652: {
653: perror("ar write error");
654: done(1);
655: }
656:
657: swap(word)
658: short *word;
659: {
660: x.h1 = ((struct fun *)word)->h2;
661: x.h2 = ((struct fun *)word)->h1;
662:
663: return(x.w1);
664: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.