file reorg, pathnames.h, paths.h
[unix-history] / usr / src / old / ar11 / ar11.c
CommitLineData
7abf8d65 1static char *sccsid = "@(#)ar11.c 4.6 (Berkeley) %G%";
c2ef410e
BJ
2/* ar11 - archiver for PDP-11 formatted archives */
3
c2ef410e 4#include <sys/types.h>
7abf8d65 5#include <sys/signal.h>
c2ef410e 6#include <sys/stat.h>
7abf8d65
KB
7#include <stdio.h>
8#include "pathnames.h"
9
a396975a 10#define ARMAG ((short)0177545)
c2ef410e 11struct ar_hdr {
a396975a
TL
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];
c2ef410e 18};
a396975a
TL
19long ar_date;
20long 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
d1ee2886 28#if defined(mc68000) || defined(tahoe)
a396975a
TL
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)
33struct ar_hdr swaphdr();
34#endif
35
c2ef410e
BJ
36struct stat stbuf;
37struct ar_hdr arbuf;
c2ef410e
BJ
38
39#define SKIP 1
40#define IODD 2
41#define OODD 4
42#define HEAD 8
43
44char *man = { "mrxtdp" };
45char *opt = { "uvnbai" };
46
47int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
48int sigdone();
49int rcmd();
50int dcmd();
51int xcmd();
52int tcmd();
53int pcmd();
54int mcmd();
55int (*comfun)();
56char flg[26];
57char **namv;
58int namc;
59char *arnam;
60char *ponam;
61char *tfnam;
62char *tf1nam;
63char *tf2nam;
64char *file;
65char name[16];
66int af;
67int tf;
68int tf1;
69int tf2;
70int bastate;
71char buf[512];
72
73char *trim();
74char *mktemp();
75char *ctime();
76
77main(argc, argv)
78char *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
153setcom(fun)
154int (*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
164rcmd()
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
199dcmd()
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
217xcmd()
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
241pcmd()
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
259mcmd()
260{
7abf8d65 261 static char name2[] = _PATH_TMP2;
c2ef410e
BJ
262
263 init();
264 if(getaf())
265 noar();
95a49fdb 266 tf2nam = mktemp(name2);
c2ef410e
BJ
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
286tcmd()
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
301init()
302{
7abf8d65 303 static char name0[] = _PATH_TMP0;
a396975a 304 static short mbuf = fixshort(ARMAG);
c2ef410e 305
95a49fdb 306 tfnam = mktemp(name0);
c2ef410e
BJ
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
317getaf()
318{
319 short mbuf;
320
321 af = open(arnam, 0);
322 if(af < 0)
323 return(1);
a396975a
TL
324 if (read(af, (char *)&mbuf, sizeof(short)) != sizeof(short) ||
325 mbuf != fixshort(ARMAG)) {
c2ef410e
BJ
326 fprintf(stderr, "ar11: %s not in PDP-11 archive format\n", arnam);
327 done(1);
328 }
329 return(0);
330}
331
332usage()
333{
334 printf("usage: ar11 [%s][%s] archive files ...\n", opt, man);
335 done(1);
336}
337
338noar()
339{
340
341 fprintf(stderr, "ar11: %s does not exist\n", arnam);
342 done(1);
343}
344
345sigdone()
346{
347 done(100);
348}
349
350done(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
362notfound()
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
375cleanup()
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
395install()
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 */
429movefil(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++;
a396975a
TL
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);
c2ef410e
BJ
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
449stats()
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 */
467copyfil(fi, fo, flag)
468{
469 register i, o;
470 int pe;
471
a396975a
TL
472 if(flag & HEAD) {
473 struct ar_hdr tmpbuf;
474
475 tmpbuf = fixhdr(arbuf);
476 if (write(fo, (char *)&tmpbuf, sizeof arbuf) != sizeof arbuf)
c2ef410e 477 wrerr();
a396975a 478 }
c2ef410e
BJ
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
502getdir()
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 }
a396975a 515 arbuf = fixhdr(arbuf);
c2ef410e 516 for(i=0; i<14; i++)
c2ef410e 517 name[i] = arbuf.ar_name[i];
c2ef410e 518 file = name;
a396975a
TL
519 ar_date = mklong(arbuf.ar_sdate);
520 ar_size = mklong(arbuf.ar_ssize);
c2ef410e
BJ
521 return(0);
522}
523
524match()
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
540bamatch()
541{
7abf8d65 542 static char name1[] = _PATH_TMP1;
c2ef410e
BJ
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;
95a49fdb 556 tf1nam = mktemp(name1);
c2ef410e
BJ
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
568phserr()
569{
570
571 fprintf(stderr, "ar11: phase error on %s\n", file);
572}
573
574mesg(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
582char *
583trim(s)
584char *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
618longt()
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
629int m1[] = { 1, ROWN, 'r', '-' };
630int m2[] = { 1, WOWN, 'w', '-' };
631int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
632int m4[] = { 1, RGRP, 'r', '-' };
633int m5[] = { 1, WGRP, 'w', '-' };
634int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
635int m7[] = { 1, ROTH, 'r', '-' };
636int m8[] = { 1, WOTH, 'w', '-' };
637int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
638
639int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
640
641pmode()
642{
643 register int **mp;
644
645 for (mp = &m[0]; mp < &m[9];)
646 select(*mp++);
647}
648
649select(pairp)
650int *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
661wrerr()
662{
663 perror("ar write error");
664 done(1);
665}
666
d1ee2886 667#if defined(mc68000) || defined(tahoe)
a396975a
TL
668struct ar_hdr
669swaphdr(hdr)
670 struct ar_hdr hdr;
c2ef410e 671{
a396975a
TL
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);
c2ef410e 678}
a396975a 679#endif