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