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