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