|
|
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: if(strcmp(arnam, "-") == 0) {
353: if(comfun != pcmd && comfun != tcmd && comfun != xcmd) {
354: fprintf(stderr, "ar: archive on stdin only with [pxt]\n");
355: done(1);
356: }
357: af = 0;
358: }
359: else af = open(arnam, 0);
360: if(af < 0)
361: return(1);
362: if (READ(af, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) {
363: fprintf(stderr, "ar: %s not in archive format\n", arnam);
364: done(1);
365: }
366: return(0);
367: }
368:
369: getqf()
370: {
371: char mbuf[SARMAG];
372:
373: if ((qf = open(arnam, 2)) < 0) {
374: if(!flg['c'-'a'])
375: fprintf(stderr, "ar: creating %s\n", arnam);
376: if ((qf = creat(arnam, 0666)) < 0) {
377: fprintf(stderr, "ar: cannot create %s\n", arnam);
378: done(1);
379: }
380: if (write(qf, ARMAG, SARMAG) != SARMAG)
381: wrerr();
382: } else if (read(qf, mbuf, SARMAG) != SARMAG
383: || strncmp(mbuf, ARMAG, SARMAG)) {
384: fprintf(stderr, "ar: %s not in archive format\n", arnam);
385: done(1);
386: }
387: }
388:
389: usage()
390: {
391: printf("usage: ar [%s][%s] archive files ...\n", opt, man);
392: done(1);
393: }
394:
395: noar()
396: {
397:
398: fprintf(stderr, "ar: %s does not exist\n", arnam);
399: done(1);
400: }
401:
402: sigdone()
403: {
404: done(100);
405: }
406:
407: done(c)
408: {
409:
410: if(tfnam)
411: unlink(tfnam);
412: if(tf1nam)
413: unlink(tf1nam);
414: if(tf2nam)
415: unlink(tf2nam);
416: exit(c);
417: }
418:
419: notfound()
420: {
421: register i, n;
422:
423: n = 0;
424: for(i=0; i<namc; i++)
425: if(namv[i]) {
426: fprintf(stderr, "ar: %s not found\n", namv[i]);
427: n++;
428: }
429: return(n);
430: }
431:
432: morefil()
433: {
434: register i, n;
435:
436: n = 0;
437: for(i=0; i<namc; i++)
438: if(namv[i])
439: n++;
440: return(n);
441: }
442:
443: cleanup()
444: {
445: register i, f;
446:
447: for(i=0; i<namc; i++) {
448: file = namv[i];
449: if(file == 0)
450: continue;
451: namv[i] = 0;
452: mesg('a');
453: f = stats();
454: if(f < 0) {
455: fprintf(stderr, "ar: %s cannot open\n", file);
456: continue;
457: }
458: movefil(f);
459: }
460: install();
461: }
462:
463: install()
464: {
465: register i;
466:
467: for(i=0; signum[i]; i++)
468: signal(signum[i], SIG_IGN);
469: if(af < 0)
470: if(!flg['c'-'a'])
471: fprintf(stderr, "ar: creating %s\n", arnam);
472: close(af);
473: af = creat(arnam, 0666);
474: if(af < 0) {
475: fprintf(stderr, "ar: cannot create %s\n", arnam);
476: done(1);
477: }
478: if(tfnam) {
479: lseek(tf, 0l, 0);
480: while((i = read(tf, buf, BUFSIZ)) > 0)
481: if (write(af, buf, i) != i)
482: wrerr();
483: }
484: if(tf2nam) {
485: lseek(tf2, 0l, 0);
486: while((i = read(tf2, buf, BUFSIZ)) > 0)
487: if (write(af, buf, i) != i)
488: wrerr();
489: }
490: if(tf1nam) {
491: lseek(tf1, 0l, 0);
492: while((i = read(tf1, buf, BUFSIZ)) > 0)
493: if (write(af, buf, i) != i)
494: wrerr();
495: }
496: }
497:
498: /*
499: * insert the file 'file'
500: * into the temporary file
501: */
502: movefil(f)
503: {
504: char buf[SAR_HDR+1];
505:
506: sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%-2s",
507: trim(file),
508: stbuf.st_mtime,
509: stbuf.st_uid,
510: stbuf.st_gid,
511: stbuf.st_mode,
512: stbuf.st_size,
513: ARFMAG);
514: strncpy((char *)&arbuf, buf, SAR_HDR);
515: larbuf.lar_size = stbuf.st_size;
516: copyfil(f, tf, OODD+HEAD);
517: close(f);
518: }
519:
520: stats()
521: {
522: register f;
523:
524: f = open(file, 0);
525: if(f < 0)
526: return(f);
527: if(fstat(f, &stbuf) < 0) {
528: close(f);
529: return(-1);
530: }
531: return(f);
532: }
533:
534: /*
535: * copy next file
536: * size given in arbuf
537: */
538: copyfil(fi, fo, flag)
539: {
540: register i, o;
541: int pe;
542:
543: if(flag & HEAD) {
544: for (i=sizeof(arbuf.ar_name)-1; i>=0; i--) {
545: if (arbuf.ar_name[i]==' ')
546: continue;
547: else if (arbuf.ar_name[i]=='\0')
548: arbuf.ar_name[i] = ' ';
549: else
550: break;
551: }
552: if (write(fo, (char *)&arbuf, SAR_HDR) != SAR_HDR)
553: wrerr();
554: }
555: pe = 0;
556: while(larbuf.lar_size > 0) {
557: i = o = BUFSIZ;
558: if(larbuf.lar_size < i) {
559: i = o = larbuf.lar_size;
560: if(i&1) {
561: buf[i] = '\n';
562: if(flag & IODD)
563: i++;
564: if(flag & OODD)
565: o++;
566: }
567: }
568: if(READ(fi, buf, i) != i)
569: pe++;
570: if((flag & SKIP) == 0)
571: if (write(fo, buf, o) != o)
572: wrerr();
573: larbuf.lar_size -= BUFSIZ;
574: }
575: if(pe)
576: phserr();
577: }
578:
579: getdir()
580: {
581: register char *cp;
582: register i;
583:
584: i = READ(af, (char *)&arbuf, SAR_HDR);
585: if(i != SAR_HDR) {
586: if(tf1nam) {
587: i = tf;
588: tf = tf1;
589: tf1 = i;
590: }
591: return(1);
592: }
593: if (strncmp(arbuf.ar_fmag, ARFMAG, sizeof(arbuf.ar_fmag))) {
594: fprintf(stderr, "ar: malformed archive (at %ld)\n", lseek(af, 0L, 1));
595: done(1);
596: }
597: cp = arbuf.ar_name + sizeof(arbuf.ar_name);
598: while (*--cp==' ')
599: ;
600: *++cp = '\0';
601: strncpy(name, arbuf.ar_name, sizeof(arbuf.ar_name));
602: file = name;
603: strncpy(larbuf.lar_name, name, sizeof(larbuf.lar_name));
604: sscanf(arbuf.ar_date, "%ld", &larbuf.lar_date);
605: sscanf(arbuf.ar_uid, "%hd", &larbuf.lar_uid);
606: sscanf(arbuf.ar_gid, "%hd", &larbuf.lar_gid);
607: sscanf(arbuf.ar_mode, "%ho", &larbuf.lar_mode);
608: sscanf(arbuf.ar_size, "%ld", &larbuf.lar_size);
609: return(0);
610: }
611:
612: match()
613: {
614: register i;
615:
616: for(i=0; i<namc; i++) {
617: if(namv[i] == 0)
618: continue;
619: if(strcmp(trim(namv[i]), file) == 0) {
620: file = namv[i];
621: namv[i] = 0;
622: return(1);
623: }
624: }
625: return(0);
626: }
627:
628: bamatch()
629: {
630: register f;
631:
632: switch(bastate) {
633:
634: case 1:
635: if(strcmp(file, ponam) != 0)
636: return;
637: bastate = 2;
638: if(flg['a'-'a'])
639: return;
640:
641: case 2:
642: bastate = 0;
643: tf1nam = mktemp(tmp1nam);
644: close(creat(tf1nam, 0600));
645: f = open(tf1nam, 2);
646: if(f < 0) {
647: fprintf(stderr, "ar: cannot create second temp\n");
648: return;
649: }
650: tf1 = tf;
651: tf = f;
652: }
653: }
654:
655: phserr()
656: {
657:
658: fprintf(stderr, "ar: phase error on %s\n", file);
659: }
660:
661: mesg(c)
662: {
663:
664: if(flg['v'-'a'])
665: if(c != 'c' || flg['v'-'a'] > 1)
666: printf("%c - %s\n", c, file);
667: }
668:
669: char *
670: trim(s)
671: char *s;
672: {
673: register char *p1, *p2;
674:
675: for(p1 = s; *p1; p1++)
676: ;
677: while(p1 > s) {
678: if(*--p1 != '/')
679: break;
680: *p1 = 0;
681: }
682: p2 = s;
683: for(p1 = s; *p1; p1++)
684: if(*p1 == '/')
685: p2 = p1+1;
686: return(p2);
687: }
688:
689: #define IFMT 060000
690: #define ISARG 01000
691: #define LARGE 010000
692: #define SUID 04000
693: #define SGID 02000
694: #define ROWN 0400
695: #define WOWN 0200
696: #define XOWN 0100
697: #define RGRP 040
698: #define WGRP 020
699: #define XGRP 010
700: #define ROTH 04
701: #define WOTH 02
702: #define XOTH 01
703: #define STXT 01000
704:
705: longt()
706: {
707: register char *cp;
708:
709: pmode();
710: printf("%3d/%1d", larbuf.lar_uid, larbuf.lar_gid);
711: printf("%7ld", larbuf.lar_size);
712: cp = ctime(&larbuf.lar_date);
713: printf(" %-12.12s %-4.4s ", cp+4, cp+20);
714: }
715:
716: int m1[] = { 1, ROWN, 'r', '-' };
717: int m2[] = { 1, WOWN, 'w', '-' };
718: int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
719: int m4[] = { 1, RGRP, 'r', '-' };
720: int m5[] = { 1, WGRP, 'w', '-' };
721: int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
722: int m7[] = { 1, ROTH, 'r', '-' };
723: int m8[] = { 1, WOTH, 'w', '-' };
724: int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
725:
726: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
727:
728: pmode()
729: {
730: register int **mp;
731:
732: for (mp = &m[0]; mp < &m[9];)
733: select(*mp++);
734: }
735:
736: select(pairp)
737: int *pairp;
738: {
739: register int n, *ap;
740:
741: ap = pairp;
742: n = *ap++;
743: while (--n>=0 && (larbuf.lar_mode&*ap++)==0)
744: ap++;
745: putchar(*ap);
746: }
747:
748: wrerr()
749: {
750: perror("ar write error");
751: done(1);
752: }
753: READ(a, b, c)
754: char *b;
755: {
756: int i, j;
757: for(i = 0; i < c && (j = read(a, b+i, c-i)) > 0; i += j);
758: return i;
759: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.