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