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