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