xref: /csrg-svn/local/local.cmd/cpio.c (revision 11240)
1*11240Smckusick /* Copyright (c) 1983 Regents of the University of California */
2*11240Smckusick 
3*11240Smckusick #ifndef lint
4*11240Smckusick static char sccsid[] = "@(#)cpio.c	4.1	(Berkeley)	02/23/83";
5*11240Smckusick #endif not lint
6*11240Smckusick 
7*11240Smckusick /*	cpio	COMPILE:	cc -O cpio.c -s -i -o cpio
8*11240Smckusick 	cpio -- copy file collections
9*11240Smckusick 
10*11240Smckusick */
11*11240Smckusick #include <stdio.h>
12*11240Smckusick #include <sys/types.h>
13*11240Smckusick #include <sys/stat.h>
14*11240Smckusick #include <signal.h>
15*11240Smckusick #ifdef RT
16*11240Smckusick #define S_IFEXT 0120000	/*  allocated by extents  */
17*11240Smckusick #define S_IF1EXT 0130000	/*  one extent  */
18*11240Smckusick #endif
19*11240Smckusick #define EQ(x,y)	(strcmp(x,y)==0)
20*11240Smckusick /* for VAX, Interdata, ... */
21*11240Smckusick #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}
22*11240Smckusick #define MAGIC	070707
23*11240Smckusick #define IN	1
24*11240Smckusick #define OUT	2
25*11240Smckusick #define PASS	3
26*11240Smckusick #define HDRSIZE	((sizeof Hdr)-256)
27*11240Smckusick #define LINKS	1000
28*11240Smckusick #define MERT 0
29*11240Smckusick #define CHARS 76
30*11240Smckusick #ifdef RT
31*11240Smckusick #define MERT 1	/* yes = 1 ;  no = 0 */
32*11240Smckusick extern long filespace;
33*11240Smckusick #endif
34*11240Smckusick 
35*11240Smckusick struct	stat	Statb, Xstatb;
36*11240Smckusick 
37*11240Smckusick struct header {
38*11240Smckusick 	short	h_magic,
39*11240Smckusick 		h_dev;
40*11240Smckusick 	unsigned short	h_ino,
41*11240Smckusick 		h_mode,
42*11240Smckusick 		h_uid,
43*11240Smckusick 		h_gid;
44*11240Smckusick 	short	h_nlink,
45*11240Smckusick 		h_rdev,
46*11240Smckusick 		h_mtime[2],
47*11240Smckusick 		h_namesize,
48*11240Smckusick 		h_filesize[2];
49*11240Smckusick 	char	h_name[256];
50*11240Smckusick } Hdr;
51*11240Smckusick 
52*11240Smckusick int	Bufsize = 512;
53*11240Smckusick short	Buf[256], *Dbuf;
54*11240Smckusick char    BBuf[512];
55*11240Smckusick char    *Cbuf;
56*11240Smckusick int	Wct,Wc;
57*11240Smckusick short	*Wp;
58*11240Smckusick char    *Cp;
59*11240Smckusick #ifdef RT
60*11240Smckusick short Actual_size[2];	/* MERT variable */
61*11240Smckusick struct{
62*11240Smckusick 	long long_size;
63*11240Smckusick };
64*11240Smckusick #endif
65*11240Smckusick 
66*11240Smckusick short	Option,
67*11240Smckusick 	Dir,
68*11240Smckusick 	Uncond,
69*11240Smckusick 	Link,
70*11240Smckusick 	Rename,
71*11240Smckusick 	Toc,
72*11240Smckusick 	Verbose,
73*11240Smckusick 	Select,
74*11240Smckusick 	Mod_time,
75*11240Smckusick 	Acc_time,
76*11240Smckusick 	Cflag,
77*11240Smckusick 	Swap;
78*11240Smckusick 
79*11240Smckusick int	Ifile,
80*11240Smckusick 	Ofile,
81*11240Smckusick 	Input = 0,
82*11240Smckusick 	Output = 1;
83*11240Smckusick long	Blocks,
84*11240Smckusick 	Longfile,
85*11240Smckusick 	Longtime;
86*11240Smckusick 
87*11240Smckusick char	Fullname[256],
88*11240Smckusick 	Name[256];
89*11240Smckusick int	Pathend;
90*11240Smckusick 
91*11240Smckusick FILE	*Rtty,
92*11240Smckusick 	*Wtty;
93*11240Smckusick 
94*11240Smckusick char	*Pattern[100];
95*11240Smckusick char	Strhdr[500];
96*11240Smckusick char	*Chdr = Strhdr;
97*11240Smckusick short	Dev,
98*11240Smckusick 	Uid,
99*11240Smckusick 	Gid,
100*11240Smckusick 	A_directory,
101*11240Smckusick 	A_special,
102*11240Smckusick #ifdef RT
103*11240Smckusick 	One_extent,
104*11240Smckusick 	Multi_extent,
105*11240Smckusick #endif
106*11240Smckusick 	Filetype = S_IFMT;
107*11240Smckusick #ifdef RT
108*11240Smckusick short Remove_mode = 0007777;
109*11240Smckusick short New_mode;
110*11240Smckusick #endif
111*11240Smckusick 
112*11240Smckusick extern	errno;
113*11240Smckusick char	*malloc();
114*11240Smckusick char 	*cd();
115*11240Smckusick char	*Cd_name;
116*11240Smckusick FILE 	*popen();
117*11240Smckusick 
118*11240Smckusick union { long l; short s[2]; char c[4]; } U;
119*11240Smckusick 
120*11240Smckusick /* for VAX, Interdata, ... */
121*11240Smckusick long mklong(v)
122*11240Smckusick short v[];
123*11240Smckusick {
124*11240Smckusick 	U.l = 1;
125*11240Smckusick 	if(U.c[0])
126*11240Smckusick 		U.s[0] = v[1], U.s[1] = v[0];
127*11240Smckusick 	else
128*11240Smckusick 		U.s[0] = v[0], U.s[1] = v[1];
129*11240Smckusick 	return U.l;
130*11240Smckusick }
131*11240Smckusick 
132*11240Smckusick main(argc, argv)
133*11240Smckusick char **argv;
134*11240Smckusick {
135*11240Smckusick 	register ct;
136*11240Smckusick 	long	filesz;
137*11240Smckusick 	long lng;
138*11240Smckusick 	register char *fullp;
139*11240Smckusick 	register i;
140*11240Smckusick 
141*11240Smckusick 	signal(SIGSYS, 1);
142*11240Smckusick 	if(*argv[1] != '-')
143*11240Smckusick 		usage();
144*11240Smckusick 	Uid = getuid();
145*11240Smckusick 	umask(0);
146*11240Smckusick 	Gid = getgid();
147*11240Smckusick 	Pattern[0] = "*";
148*11240Smckusick 
149*11240Smckusick 	while(*++argv[1]) {
150*11240Smckusick 		switch(*argv[1]) {
151*11240Smckusick 		case 'a':
152*11240Smckusick 			Acc_time++;
153*11240Smckusick 			break;
154*11240Smckusick 		case 'B':
155*11240Smckusick 			Bufsize = 5120;
156*11240Smckusick 			break;
157*11240Smckusick 		case 'i':
158*11240Smckusick 			Option = IN;
159*11240Smckusick 			if(argc > 2 ) {
160*11240Smckusick 				for(i = 0; (i+2) < argc; ++i)
161*11240Smckusick 					Pattern[i] = argv[i+2];
162*11240Smckusick 			}
163*11240Smckusick 			break;
164*11240Smckusick 		case 'o':
165*11240Smckusick 			if(argc != 2)
166*11240Smckusick 				usage();
167*11240Smckusick 			Option = OUT;
168*11240Smckusick 			break;
169*11240Smckusick 		case 'p':
170*11240Smckusick 			if(argc != 3)
171*11240Smckusick 				usage();
172*11240Smckusick 			if(access(argv[2], 2) == -1) {
173*11240Smckusick accerr:
174*11240Smckusick 				err("cannot write in <%s>\n", argv[2]);
175*11240Smckusick 				exit(2);
176*11240Smckusick 			}
177*11240Smckusick 			strcpy(Fullname, argv[2]);
178*11240Smckusick 			strcat(Fullname, "/");
179*11240Smckusick 			stat(Fullname, &Xstatb);
180*11240Smckusick 			if((Xstatb.st_mode&S_IFMT) != S_IFDIR)
181*11240Smckusick 				goto accerr;
182*11240Smckusick 			Option = PASS;
183*11240Smckusick 			Dev = Xstatb.st_dev;
184*11240Smckusick 			break;
185*11240Smckusick 		case 'c':
186*11240Smckusick 			Cflag++;
187*11240Smckusick 			break;
188*11240Smckusick 		case 'd':
189*11240Smckusick 			Dir++;
190*11240Smckusick 			break;
191*11240Smckusick 		case 'l':
192*11240Smckusick 			Link++;
193*11240Smckusick 			break;
194*11240Smckusick 		case 'm':
195*11240Smckusick 			Mod_time++;
196*11240Smckusick 			break;
197*11240Smckusick 		case 'r':
198*11240Smckusick 			Rename++;
199*11240Smckusick 			Rtty = fopen("/dev/tty", "r");
200*11240Smckusick 			Wtty = fopen("/dev/tty", "w");
201*11240Smckusick 			if(Rtty==NULL || Wtty==NULL) {
202*11240Smckusick 				err(
203*11240Smckusick 				  "Cannot rename (/dev/tty missing)\n");
204*11240Smckusick 				exit(2);
205*11240Smckusick 			}
206*11240Smckusick 			break;
207*11240Smckusick 		case 's':
208*11240Smckusick 			Swap++;
209*11240Smckusick 			break;
210*11240Smckusick 		case 't':
211*11240Smckusick 			Toc++;
212*11240Smckusick 			break;
213*11240Smckusick 		case 'u':
214*11240Smckusick 			Uncond++;
215*11240Smckusick 			break;
216*11240Smckusick 		case 'v':
217*11240Smckusick 			Verbose++;
218*11240Smckusick 			break;
219*11240Smckusick 		case '6':
220*11240Smckusick 			Filetype = 060000;
221*11240Smckusick 			break;
222*11240Smckusick 		default:
223*11240Smckusick 			usage();
224*11240Smckusick 		}
225*11240Smckusick 	}
226*11240Smckusick 	if(!Option) {
227*11240Smckusick 		err("Options must include o|i|p\n");
228*11240Smckusick 		exit(2);
229*11240Smckusick 	}
230*11240Smckusick 
231*11240Smckusick 	if (Cflag && Swap)  {
232*11240Smckusick 		err("Swap flag is ignored with Cflag\n");
233*11240Smckusick 		Swap = 0;
234*11240Smckusick 	}
235*11240Smckusick 
236*11240Smckusick 	if(Option != PASS)  {
237*11240Smckusick 		Wp = Dbuf = (short *)malloc(Bufsize);
238*11240Smckusick 		Cp = Cbuf = (char *)malloc(Bufsize);
239*11240Smckusick 	}
240*11240Smckusick 	     Wct = Bufsize >> 1;
241*11240Smckusick 	     Wc = Bufsize;
242*11240Smckusick 
243*11240Smckusick 	if(Option == PASS && Rename) {
244*11240Smckusick 		err("Pass and Rename cannot be used together");
245*11240Smckusick 		exit(2);
246*11240Smckusick 	}
247*11240Smckusick 	switch(Option) {
248*11240Smckusick 
249*11240Smckusick 	case OUT:
250*11240Smckusick 		while(getname()) {
251*11240Smckusick 			if( mklong(Hdr.h_filesize) == 0L) {
252*11240Smckusick 				if ( Cflag )
253*11240Smckusick 				     writehdr(Chdr,CHARS+Hdr.h_namesize);
254*11240Smckusick 				else
255*11240Smckusick 				     bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
256*11240Smckusick #ifdef RT
257*11240Smckusick 				if( (MERT) && (((Hdr.h_mode & Filetype) == S_IF1EXT)
258*11240Smckusick 					|| ((Hdr.h_mode & Filetype) == S_IFEXT))) {
259*11240Smckusick 					actsize();
260*11240Smckusick 					bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
261*11240Smckusick 				}
262*11240Smckusick #endif
263*11240Smckusick 				continue;
264*11240Smckusick 			}
265*11240Smckusick 			if((Ifile = open(Hdr.h_name, 0)) < 0) {
266*11240Smckusick 				err("<%s> ?\n", Hdr.h_name);
267*11240Smckusick 				continue;
268*11240Smckusick 			}
269*11240Smckusick 			if ( Cflag )
270*11240Smckusick 			     writehdr(Chdr,CHARS+Hdr.h_namesize);
271*11240Smckusick 			else
272*11240Smckusick 			     bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
273*11240Smckusick #ifdef RT
274*11240Smckusick 			if( (MERT) && (((Hdr.h_mode & Filetype) == S_IF1EXT)
275*11240Smckusick 				|| ((Hdr.h_mode & Filetype) == S_IFEXT))) {
276*11240Smckusick 				actsize();
277*11240Smckusick 				bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
278*11240Smckusick 			}
279*11240Smckusick #endif
280*11240Smckusick 			for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= 512){
281*11240Smckusick 				ct = filesz>512? 512: filesz;
282*11240Smckusick 				   if(read(Ifile, Cflag? BBuf: (char *)Buf, ct) < 0) {
283*11240Smckusick 					err("Cannot read %s\n", Hdr.h_name);
284*11240Smckusick 					continue;
285*11240Smckusick 				   }
286*11240Smckusick 				Cflag? writehdr(BBuf,ct): bwrite(Buf,ct);
287*11240Smckusick 			}
288*11240Smckusick 			close(Ifile);
289*11240Smckusick 			if(Acc_time)
290*11240Smckusick 				utime(Hdr.h_name, &Statb.st_atime);
291*11240Smckusick 			if(Verbose)
292*11240Smckusick 				err("%s\n", Hdr.h_name);
293*11240Smckusick 		}
294*11240Smckusick 		strcpy(Hdr.h_name, "TRAILER!!!");
295*11240Smckusick 		Hdr.h_magic = MAGIC;
296*11240Smckusick 		MKSHORT(Hdr.h_filesize, 0L);
297*11240Smckusick 		Hdr.h_namesize = strlen("TRAILER!!!") + 1;
298*11240Smckusick 		if ( Cflag )  {
299*11240Smckusick 		     lng = 0;
300*11240Smckusick 		     bintochar(lng);
301*11240Smckusick 		     writehdr(Chdr,CHARS+Hdr.h_namesize);
302*11240Smckusick 		}
303*11240Smckusick 		else
304*11240Smckusick 		     bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
305*11240Smckusick 		Cflag? writehdr(Cbuf, Bufsize): bwrite(Dbuf, Bufsize);
306*11240Smckusick 		break;
307*11240Smckusick 
308*11240Smckusick 	case IN:
309*11240Smckusick 		pwd();
310*11240Smckusick 		while(gethdr()) {
311*11240Smckusick 			Ofile = ckname(Hdr.h_name)? openout(Hdr.h_name): 0;
312*11240Smckusick 			for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= 512){
313*11240Smckusick 				ct = filesz>512? 512: filesz;
314*11240Smckusick 				Cflag? readhdr(BBuf, ct): bread(Buf, ct);
315*11240Smckusick 				if(Ofile) {
316*11240Smckusick 					if(Swap)
317*11240Smckusick 						swap(Buf, ct);
318*11240Smckusick 					   if(write(Ofile, Cflag? BBuf: (char *)Buf, ct) < 0) {
319*11240Smckusick 					      err("Cannot write %s\n", Hdr.h_name);
320*11240Smckusick 					      continue;
321*11240Smckusick 					   }
322*11240Smckusick 				}
323*11240Smckusick 			}
324*11240Smckusick 			if(Ofile) {
325*11240Smckusick 				close(Ofile);
326*11240Smckusick 				set_time(Cd_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
327*11240Smckusick 			}
328*11240Smckusick 			if(!Select)
329*11240Smckusick 				continue;
330*11240Smckusick 			if(Verbose)
331*11240Smckusick 				if(Toc)
332*11240Smckusick 					pentry(Hdr.h_name);
333*11240Smckusick 				else
334*11240Smckusick 					puts(Hdr.h_name);
335*11240Smckusick 			else if(Toc)
336*11240Smckusick 				puts(Hdr.h_name);
337*11240Smckusick 		}
338*11240Smckusick 		break;
339*11240Smckusick 
340*11240Smckusick 	case PASS:
341*11240Smckusick 		fullp = Fullname + strlen(Fullname);
342*11240Smckusick 
343*11240Smckusick 		while(getname()) {
344*11240Smckusick 			if(!ckname(Hdr.h_name))
345*11240Smckusick 				continue;
346*11240Smckusick 			strcpy(fullp, Hdr.h_name);
347*11240Smckusick 
348*11240Smckusick 			if(Link
349*11240Smckusick 			&& !A_directory
350*11240Smckusick 			&& Dev == Statb.st_dev) {
351*11240Smckusick /* ???			&& (Uid == Statb.st_uid || !Uid)) {*/
352*11240Smckusick 				if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */
353*11240Smckusick 					unlink(Fullname);
354*11240Smckusick 					missdir(Fullname);
355*11240Smckusick 					if(link(Hdr.h_name, Fullname) < 0) {
356*11240Smckusick 						err(
357*11240Smckusick 						 "Cannot link <%s> & <%s>\n",
358*11240Smckusick 						 Hdr.h_name, Fullname);
359*11240Smckusick 						continue;
360*11240Smckusick 					}
361*11240Smckusick 				}
362*11240Smckusick 				set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
363*11240Smckusick 				goto ckverbose;
364*11240Smckusick 			}
365*11240Smckusick 			if(!(Ofile = openout(Fullname)))
366*11240Smckusick 				continue;
367*11240Smckusick 			if((Ifile = open(Hdr.h_name, 0)) < 0) {
368*11240Smckusick 				err("<%s> ?\n", Hdr.h_name);
369*11240Smckusick 				close(Ofile);
370*11240Smckusick 				continue;
371*11240Smckusick 			}
372*11240Smckusick 			filesz = Statb.st_size;
373*11240Smckusick 			for(; filesz > 0; filesz -= 512) {
374*11240Smckusick 				ct = filesz>512? 512: filesz;
375*11240Smckusick 				    if(read(Ifile, Buf, ct) < 0) {
376*11240Smckusick 					err("Cannot read %s\n", Hdr.h_name);
377*11240Smckusick 					break;
378*11240Smckusick 				    }
379*11240Smckusick 				if(Ofile)
380*11240Smckusick 					if(write(Ofile, Buf, ct) < 0) {
381*11240Smckusick 					  err("Cannot write %s\n", Hdr.h_name);
382*11240Smckusick 					  break;
383*11240Smckusick 					}
384*11240Smckusick 				++Blocks;
385*11240Smckusick 			}
386*11240Smckusick 			close(Ifile);
387*11240Smckusick 			if(Acc_time)
388*11240Smckusick 				utime(Hdr.h_name, &Statb.st_atime);
389*11240Smckusick 			if(Ofile) {
390*11240Smckusick 				close(Ofile);
391*11240Smckusick 				set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime));
392*11240Smckusick ckverbose:
393*11240Smckusick 				if(Verbose)
394*11240Smckusick 					puts(Fullname);
395*11240Smckusick 			}
396*11240Smckusick 		}
397*11240Smckusick 	}
398*11240Smckusick 	err("%ld blocks\n", Blocks * (Bufsize>>9));
399*11240Smckusick 	exit(0);
400*11240Smckusick }
401*11240Smckusick usage()
402*11240Smckusick {
403*11240Smckusick 	err("Usage: cpio -o[acvB] <name-list >collection\n%s\n%s\n",
404*11240Smckusick 	"       cpio -i[cdmrstuvB6] [pattern ...] <collection",
405*11240Smckusick 	"       cpio -p[adlmruv] directory <name-list");
406*11240Smckusick 	exit(2);
407*11240Smckusick }
408*11240Smckusick 
409*11240Smckusick getname()
410*11240Smckusick {
411*11240Smckusick 	register char *namep = Name;
412*11240Smckusick 	long tlong;
413*11240Smckusick 
414*11240Smckusick 	for(;;) {
415*11240Smckusick 		if(gets(namep) == NULL)
416*11240Smckusick 			return 0;
417*11240Smckusick 		if(*namep == '.' && namep[1] == '/')
418*11240Smckusick 			namep += 2;
419*11240Smckusick 		strcpy(Hdr.h_name, namep);
420*11240Smckusick 		if(stat(namep, &Statb) < 0) {
421*11240Smckusick 			err("< %s > ?\n", Hdr.h_name);
422*11240Smckusick 			continue;
423*11240Smckusick 		}
424*11240Smckusick 		A_directory = (Statb.st_mode & Filetype) == S_IFDIR;
425*11240Smckusick 		A_special = ((Statb.st_mode & Filetype) == S_IFBLK)
426*11240Smckusick 			|| ((Statb.st_mode & Filetype) == S_IFCHR);
427*11240Smckusick #ifdef RT
428*11240Smckusick 		if(MERT) {
429*11240Smckusick 			One_extent = (Statb.st_mode & Filetype) == S_IF1EXT;
430*11240Smckusick 			Multi_extent = (Statb.st_mode & Filetype) == S_IFEXT;
431*11240Smckusick 		}
432*11240Smckusick #endif
433*11240Smckusick 		Hdr.h_magic = MAGIC;
434*11240Smckusick 		Hdr.h_namesize = strlen(Hdr.h_name) + 1;
435*11240Smckusick 		Hdr.h_uid = Statb.st_uid;
436*11240Smckusick 		Hdr.h_gid = Statb.st_gid;
437*11240Smckusick 		Hdr.h_dev = Statb.st_dev;
438*11240Smckusick 		Hdr.h_ino = Statb.st_ino;
439*11240Smckusick 		Hdr.h_mode = Statb.st_mode;
440*11240Smckusick 		MKSHORT(Hdr.h_mtime, Statb.st_mtime);
441*11240Smckusick 		Hdr.h_nlink = Statb.st_nlink;
442*11240Smckusick 		tlong = Hdr.h_mode & S_IFREG? Statb.st_size: 0L;
443*11240Smckusick 		MKSHORT(Hdr.h_filesize, tlong);
444*11240Smckusick 		Hdr.h_rdev = Statb.st_rdev;
445*11240Smckusick 		if(Cflag)
446*11240Smckusick 			bintochar(tlong);
447*11240Smckusick 		return 1;
448*11240Smckusick 	}
449*11240Smckusick }
450*11240Smckusick 
451*11240Smckusick bintochar(t)
452*11240Smckusick long t;
453*11240Smckusick {
454*11240Smckusick 	sprintf(Chdr,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s",
455*11240Smckusick 		MAGIC,Statb.st_dev,Statb.st_ino,Statb.st_mode,Statb.st_uid,
456*11240Smckusick 		Statb.st_gid,Statb.st_nlink,Statb.st_rdev & 00000177777,
457*11240Smckusick 		Statb.st_mtime,(short)strlen(Hdr.h_name)+1,t,Hdr.h_name);
458*11240Smckusick }
459*11240Smckusick 
460*11240Smckusick chartobin()
461*11240Smckusick {
462*11240Smckusick 	sscanf(Chdr,"%6o%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo",
463*11240Smckusick 		&Hdr.h_magic,&Hdr.h_dev,&Hdr.h_ino,&Hdr.h_mode,&Hdr.h_uid,
464*11240Smckusick 		&Hdr.h_gid,&Hdr.h_nlink,&Hdr.h_rdev,&Longtime,&Hdr.h_namesize,
465*11240Smckusick 		&Longfile);
466*11240Smckusick 	MKSHORT(Hdr.h_filesize, Longfile);
467*11240Smckusick 	MKSHORT(Hdr.h_mtime, Longtime);
468*11240Smckusick }
469*11240Smckusick 
470*11240Smckusick gethdr()
471*11240Smckusick {
472*11240Smckusick 
473*11240Smckusick 	if ( Cflag )  {
474*11240Smckusick 		readhdr(Chdr,CHARS);
475*11240Smckusick 		chartobin();
476*11240Smckusick 	}
477*11240Smckusick 	else
478*11240Smckusick 		bread(&Hdr, HDRSIZE);
479*11240Smckusick 
480*11240Smckusick 	if(Hdr.h_magic != MAGIC) {
481*11240Smckusick 		err("Out of phase--get help");
482*11240Smckusick 		exit(2);
483*11240Smckusick 	}
484*11240Smckusick 	if(!Cflag)
485*11240Smckusick 	     bread(Hdr.h_name, Hdr.h_namesize);
486*11240Smckusick 	else
487*11240Smckusick 	     readhdr(Hdr.h_name, Hdr.h_namesize);
488*11240Smckusick 	if(Swap)
489*11240Smckusick 		swap(Hdr.h_name, Hdr.h_namesize);
490*11240Smckusick 	if(EQ(Hdr.h_name, "TRAILER!!!"))
491*11240Smckusick 		return 0;
492*11240Smckusick 	A_directory = (Hdr.h_mode & Filetype) == S_IFDIR;
493*11240Smckusick 	A_special =((Hdr.h_mode & Filetype) == S_IFBLK)
494*11240Smckusick 		|| ((Hdr.h_mode & Filetype) == S_IFCHR);
495*11240Smckusick #ifdef RT
496*11240Smckusick 	if( (MERT) && (((Hdr.h_mode & Filetype) == S_IF1EXT)
497*11240Smckusick 		|| ((Hdr.h_mode & Filetype) == S_IFEXT))) {
498*11240Smckusick 		One_extent = (Hdr.h_mode & Filetype) == S_IF1EXT;
499*11240Smckusick 		Multi_extent = (Hdr.h_mode & Filetype) == S_IFEXT;
500*11240Smckusick 		Actual_size[0] = Hdr.h_filesize[0];
501*11240Smckusick 		Actual_size[1] = Hdr.h_filesize[1];
502*11240Smckusick 		bread(&Hdr, HDRSIZE);
503*11240Smckusick 		if(Hdr.h_magic != MAGIC) {
504*11240Smckusick 			err("Out of phase--get MERT help");
505*11240Smckusick 			exit(2);
506*11240Smckusick 		}
507*11240Smckusick 		bread(Hdr.h_name, Hdr.h_namesize);
508*11240Smckusick 	}
509*11240Smckusick #endif
510*11240Smckusick 	return 1;
511*11240Smckusick }
512*11240Smckusick 
513*11240Smckusick ckname(namep)
514*11240Smckusick register char *namep;
515*11240Smckusick {
516*11240Smckusick 	++Select;
517*11240Smckusick 	if(!nmatch(namep, Pattern)) {
518*11240Smckusick 		Select = 0;
519*11240Smckusick 		return 0;
520*11240Smckusick 	}
521*11240Smckusick 	if(Rename && !A_directory) {
522*11240Smckusick 		fprintf(Wtty, "Rename <%s>\n", namep);
523*11240Smckusick 		fflush(Wtty);
524*11240Smckusick 		fgets(namep, 128, Rtty);
525*11240Smckusick 		if(feof(Rtty))
526*11240Smckusick 			exit(2);
527*11240Smckusick 		namep[strlen(namep) - 1] = '\0';
528*11240Smckusick 		if(EQ(namep, "")) {
529*11240Smckusick 			printf("Skipped\n");
530*11240Smckusick 			return 0;
531*11240Smckusick 		}
532*11240Smckusick 	}
533*11240Smckusick 	return !Toc;
534*11240Smckusick }
535*11240Smckusick 
536*11240Smckusick openout(namep)
537*11240Smckusick register char *namep;
538*11240Smckusick {
539*11240Smckusick 	register f;
540*11240Smckusick 	register char *np;
541*11240Smckusick 
542*11240Smckusick 	if(!strncmp(namep, "./", 2))
543*11240Smckusick 		namep += 2;
544*11240Smckusick 	np = namep;
545*11240Smckusick 	if(Option == IN)
546*11240Smckusick 		Cd_name = namep = cd(namep);
547*11240Smckusick 	if(A_directory) {
548*11240Smckusick 		if(!Dir
549*11240Smckusick 		|| Rename
550*11240Smckusick 		|| EQ(namep, ".")
551*11240Smckusick 		|| EQ(namep, "..")
552*11240Smckusick 		|| stat(namep, &Xstatb) == 0)
553*11240Smckusick 			return 0;
554*11240Smckusick 
555*11240Smckusick 		if(!makdir(namep)) {
556*11240Smckusick 			missdir(namep);
557*11240Smckusick 		}
558*11240Smckusick ret:
559*11240Smckusick 		chmod(namep, Hdr.h_mode);
560*11240Smckusick 		if(Uid == 0)
561*11240Smckusick 			chown(namep, Hdr.h_uid, Hdr.h_gid);
562*11240Smckusick 		set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
563*11240Smckusick 		return 0;
564*11240Smckusick 	}
565*11240Smckusick 	if(Hdr.h_nlink > 1)
566*11240Smckusick 		if(!postml(namep, np))
567*11240Smckusick 			return 0;
568*11240Smckusick 	if(A_special) {
569*11240Smckusick s_again:
570*11240Smckusick 		if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) {
571*11240Smckusick 			if(missdir(namep))
572*11240Smckusick 				goto s_again;
573*11240Smckusick 			err("Cannot mknod <%s>\n", namep);
574*11240Smckusick 			return 0;
575*11240Smckusick 		}
576*11240Smckusick 		goto ret;
577*11240Smckusick 	}
578*11240Smckusick 	if(stat(namep, &Xstatb) == 0) {
579*11240Smckusick 		if(Uncond && !(Xstatb.st_mode & S_IWRITE))
580*11240Smckusick 			unlink(namep);
581*11240Smckusick 		if(!Uncond && (mklong(Hdr.h_mtime) < Xstatb.st_mtime)) {
582*11240Smckusick 			err("current <%s> newer\n", namep);
583*11240Smckusick 			return 0;
584*11240Smckusick 		}
585*11240Smckusick 	}
586*11240Smckusick 	if(Option == PASS
587*11240Smckusick 	&& Hdr.h_ino == Xstatb.st_ino
588*11240Smckusick 	&& Hdr.h_dev == Xstatb.st_dev) {
589*11240Smckusick 		err("Attempt to pass file to self!\n");
590*11240Smckusick 		exit(2);
591*11240Smckusick 	}
592*11240Smckusick #ifdef RT
593*11240Smckusick one_again:
594*11240Smckusick 	if(One_extent || Multi_extent) {
595*11240Smckusick 		if((f = falloc(namep, Hdr.h_mode, Hdr.h_filesize[0].long_size)) < 0) {
596*11240Smckusick 			if(missdir(namep))
597*11240Smckusick 				goto one_again;
598*11240Smckusick 			err("Cannot create <%s> (errno:%d)\n", namep, errno);
599*11240Smckusick 			return 0;
600*11240Smckusick 		}
601*11240Smckusick 		if(filespace < Hdr.h_filesize[0].long_size){
602*11240Smckusick 			err("Cannot create contiguous file <%s> proper size\n", namep);
603*11240Smckusick 			err("    <%s> will be created as a regular file\n", namep);
604*11240Smckusick 			if(unlink(Fullname) != 0)
605*11240Smckusick 				err("<%s> not removed\n", namep);
606*11240Smckusick 			New_mode = Hdr.h_mode & Remove_mode;
607*11240Smckusick 			New_mode = New_mode | S_IFREG;
608*11240Smckusick once_again:
609*11240Smckusick 			if((f = creat(namep, New_mode)) < 0){
610*11240Smckusick 				if(missdir(namep))
611*11240Smckusick 					goto once_again;
612*11240Smckusick 				err("Cannot create <%s> (errno:%d)\n", namep, errno);
613*11240Smckusick 				return (0);
614*11240Smckusick 			}
615*11240Smckusick 		}
616*11240Smckusick 	}
617*11240Smckusick #endif
618*11240Smckusick #ifdef RT
619*11240Smckusick 	if(MERT && (One_extent || Multi_extent))
620*11240Smckusick 		goto skip_c;
621*11240Smckusick #endif
622*11240Smckusick c_again:
623*11240Smckusick 	if((f = creat(namep, Hdr.h_mode)) < 0) {
624*11240Smckusick 		if(missdir(namep))
625*11240Smckusick 			goto c_again;
626*11240Smckusick 		err("Cannot create <%s> (errno:%d)\n", namep, errno);
627*11240Smckusick 		return 0;
628*11240Smckusick 	}
629*11240Smckusick #ifdef RT
630*11240Smckusick skip_c:
631*11240Smckusick #endif
632*11240Smckusick 	if(Uid == 0)
633*11240Smckusick 		chown(namep, Hdr.h_uid, Hdr.h_gid);
634*11240Smckusick 	return f;
635*11240Smckusick }
636*11240Smckusick 
637*11240Smckusick bread(b, c)
638*11240Smckusick register c;
639*11240Smckusick register short *b;
640*11240Smckusick {
641*11240Smckusick 	static nleft = 0;
642*11240Smckusick 	static short *ip;
643*11240Smckusick 	register short *p = ip;
644*11240Smckusick 
645*11240Smckusick 	c = (c+1)>>1;
646*11240Smckusick 	while(c--) {
647*11240Smckusick 		if(!nleft) {
648*11240Smckusick again:
649*11240Smckusick 			if(read(Input, Dbuf, Bufsize)!=Bufsize) {
650*11240Smckusick 				Input = chgreel(0, Input);
651*11240Smckusick 				goto again;
652*11240Smckusick 			}
653*11240Smckusick 			nleft = Bufsize >> 1;
654*11240Smckusick 			p = Dbuf;
655*11240Smckusick 			++Blocks;
656*11240Smckusick 		}
657*11240Smckusick 		*b++ = *p++;
658*11240Smckusick 		--nleft;
659*11240Smckusick 	}
660*11240Smckusick 	ip = p;
661*11240Smckusick }
662*11240Smckusick 
663*11240Smckusick readhdr(b, c)
664*11240Smckusick register c;
665*11240Smckusick register char *b;
666*11240Smckusick {
667*11240Smckusick 	static nleft = 0;
668*11240Smckusick 	static char *ip;
669*11240Smckusick 	register char *p = ip;
670*11240Smckusick 
671*11240Smckusick 	while(c--)  {
672*11240Smckusick 		if(!nleft)  {
673*11240Smckusick again:
674*11240Smckusick 			if(read(Input, Cbuf, Bufsize) != Bufsize)  {
675*11240Smckusick 				Input = chgreel(0, Input);
676*11240Smckusick 				goto again;
677*11240Smckusick 			}
678*11240Smckusick 			nleft = Bufsize;
679*11240Smckusick 			p = Cbuf;
680*11240Smckusick 			++Blocks;
681*11240Smckusick 		}
682*11240Smckusick 		*b++ = *p++;
683*11240Smckusick 		--nleft;
684*11240Smckusick 	}
685*11240Smckusick 	ip = p;
686*11240Smckusick }
687*11240Smckusick 
688*11240Smckusick bwrite(rp, c)
689*11240Smckusick register short *rp;
690*11240Smckusick register c;
691*11240Smckusick {
692*11240Smckusick 	register short *wp = Wp;
693*11240Smckusick 
694*11240Smckusick 	c = (c+1) >> 1;
695*11240Smckusick 	while(c--) {
696*11240Smckusick 		if(!Wct) {
697*11240Smckusick again:
698*11240Smckusick 			if(write(Output, Dbuf, Bufsize)<0) {
699*11240Smckusick 				Output = chgreel(1, Output);
700*11240Smckusick 				goto again;
701*11240Smckusick 			}
702*11240Smckusick 			Wct = Bufsize >> 1;
703*11240Smckusick 			wp = Dbuf;
704*11240Smckusick 			++Blocks;
705*11240Smckusick 		}
706*11240Smckusick 		*wp++ = *rp++;
707*11240Smckusick 		--Wct;
708*11240Smckusick 	}
709*11240Smckusick 	Wp = wp;
710*11240Smckusick }
711*11240Smckusick writehdr(rp,c)
712*11240Smckusick register char *rp;
713*11240Smckusick register c;
714*11240Smckusick {
715*11240Smckusick          register char *cp = Cp;
716*11240Smckusick 
717*11240Smckusick          while(c--)  {
718*11240Smckusick                  if(!Wc)  {
719*11240Smckusick again:
720*11240Smckusick                         if(write(Output,Cbuf,Bufsize)<0)  {
721*11240Smckusick                                 Output = chgreel(1, Output);
722*11240Smckusick                                 goto again;
723*11240Smckusick                         }
724*11240Smckusick                         Wc = Bufsize;
725*11240Smckusick                         cp = Cbuf;
726*11240Smckusick                         ++Blocks;
727*11240Smckusick                  }
728*11240Smckusick                  *cp++ = *rp++;
729*11240Smckusick                  --Wc;
730*11240Smckusick          }
731*11240Smckusick          Cp = cp;
732*11240Smckusick }
733*11240Smckusick 
734*11240Smckusick 
735*11240Smckusick postml(namep, np)
736*11240Smckusick register char *namep, *np;
737*11240Smckusick {
738*11240Smckusick 	register i;
739*11240Smckusick 	static struct ml {
740*11240Smckusick 		short	m_dev,
741*11240Smckusick 			m_ino;
742*11240Smckusick 		char	m_name[2];
743*11240Smckusick 	} *ml[LINKS];
744*11240Smckusick 	static	mlinks = 0;
745*11240Smckusick 	char *mlp;
746*11240Smckusick 
747*11240Smckusick 	for(i = 0; i < mlinks; ++i) {
748*11240Smckusick 		if(mlinks == LINKS) break;
749*11240Smckusick 		if(ml[i]->m_ino==Hdr.h_ino &&
750*11240Smckusick 			ml[i]->m_dev==Hdr.h_dev) {
751*11240Smckusick 			if(Verbose)
752*11240Smckusick 			  printf("%s linked to %s\n", ml[i]->m_name,
753*11240Smckusick 				np);
754*11240Smckusick 			unlink(namep);
755*11240Smckusick 			if(Option == IN) {
756*11240Smckusick 				Fullname[Pathend] = '\0';
757*11240Smckusick 				strcat(Fullname, ml[i]->m_name);
758*11240Smckusick 				mlp = Fullname;
759*11240Smckusick 			} else
760*11240Smckusick 				mlp = ml[i]->m_name;
761*11240Smckusick l_again:
762*11240Smckusick 			if(link(mlp, namep) < 0) {
763*11240Smckusick 				if(missdir(np))
764*11240Smckusick 					goto l_again;
765*11240Smckusick 				err("Cannot link <%s>&<%s>.\n",
766*11240Smckusick 					ml[i]->m_name, np);
767*11240Smckusick 			}
768*11240Smckusick 			set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
769*11240Smckusick 			return 0;
770*11240Smckusick 		}
771*11240Smckusick 	}
772*11240Smckusick 	if(mlinks == LINKS
773*11240Smckusick 	|| !(ml[mlinks] = (struct ml *)malloc(strlen(np) + 2 + sizeof(struct ml)))) {
774*11240Smckusick 		static int first=1;
775*11240Smckusick 
776*11240Smckusick 		if(first)
777*11240Smckusick 			if(mlinks == LINKS)
778*11240Smckusick 				err("Too many links\n");
779*11240Smckusick 			else
780*11240Smckusick 				err("No memory for links\n");
781*11240Smckusick 		mlinks = LINKS;
782*11240Smckusick 		first = 0;
783*11240Smckusick 		return 1;
784*11240Smckusick 	}
785*11240Smckusick 	ml[mlinks]->m_dev = Hdr.h_dev;
786*11240Smckusick 	ml[mlinks]->m_ino = Hdr.h_ino;
787*11240Smckusick 	strcpy(ml[mlinks]->m_name, np);
788*11240Smckusick 	++mlinks;
789*11240Smckusick 	return 1;
790*11240Smckusick }
791*11240Smckusick 
792*11240Smckusick pentry(namep)
793*11240Smckusick register char *namep;
794*11240Smckusick {
795*11240Smckusick 
796*11240Smckusick 	register i;
797*11240Smckusick 	static short lastid = -1;
798*11240Smckusick #include <pwd.h>
799*11240Smckusick 	static struct passwd *pw;
800*11240Smckusick 	struct passwd *getpwuid();
801*11240Smckusick 	static char tbuf[32];
802*11240Smckusick 
803*11240Smckusick 	printf("%-7o", Hdr.h_mode & 0177777);
804*11240Smckusick 	if(lastid == Hdr.h_uid)
805*11240Smckusick 		printf("%-6s", pw->pw_name);
806*11240Smckusick 	else {
807*11240Smckusick 		setpwent();
808*11240Smckusick 		if(pw = getpwuid(Hdr.h_uid)) {
809*11240Smckusick 			printf("%-6s", pw->pw_name);
810*11240Smckusick 			lastid = Hdr.h_uid;
811*11240Smckusick 		} else {
812*11240Smckusick 			printf("%-6d", Hdr.h_uid);
813*11240Smckusick 			lastid = -1;
814*11240Smckusick 		}
815*11240Smckusick 	}
816*11240Smckusick 	printf("%7ld ", mklong(Hdr.h_filesize));
817*11240Smckusick 	U.l = mklong(Hdr.h_mtime);
818*11240Smckusick 	strcpy(tbuf, ctime(&U.l));
819*11240Smckusick 	tbuf[24] = '\0';
820*11240Smckusick 	printf(" %s  %s\n", &tbuf[4], namep);
821*11240Smckusick }
822*11240Smckusick 
823*11240Smckusick nmatch(s, pat)
824*11240Smckusick char *s, **pat;
825*11240Smckusick {
826*11240Smckusick 	if(EQ(*pat, "*"))
827*11240Smckusick 		return 1;
828*11240Smckusick 	while(*pat) {
829*11240Smckusick 		if((**pat == '!' && !gmatch(s, *pat+1))
830*11240Smckusick 		|| gmatch(s, *pat))
831*11240Smckusick 			return 1;
832*11240Smckusick 		++pat;
833*11240Smckusick 	}
834*11240Smckusick 	return 0;
835*11240Smckusick }
836*11240Smckusick gmatch(s, p)
837*11240Smckusick register char *s, *p;
838*11240Smckusick {
839*11240Smckusick 	register int c;
840*11240Smckusick 	register cc, ok, lc, scc;
841*11240Smckusick 
842*11240Smckusick 	scc = *s;
843*11240Smckusick 	lc = 077777;
844*11240Smckusick 	switch (c = *p) {
845*11240Smckusick 
846*11240Smckusick 	case '[':
847*11240Smckusick 		ok = 0;
848*11240Smckusick 		while (cc = *++p) {
849*11240Smckusick 			switch (cc) {
850*11240Smckusick 
851*11240Smckusick 			case ']':
852*11240Smckusick 				if (ok)
853*11240Smckusick 					return(gmatch(++s, ++p));
854*11240Smckusick 				else
855*11240Smckusick 					return(0);
856*11240Smckusick 
857*11240Smckusick 			case '-':
858*11240Smckusick 				ok |= (lc <= scc & scc <= (cc=p[1]));
859*11240Smckusick 			}
860*11240Smckusick 			if (scc==(lc=cc)) ok++;
861*11240Smckusick 		}
862*11240Smckusick 		return(0);
863*11240Smckusick 
864*11240Smckusick 	case '?':
865*11240Smckusick 	caseq:
866*11240Smckusick 		if(scc) return(gmatch(++s, ++p));
867*11240Smckusick 		return(0);
868*11240Smckusick 	case '*':
869*11240Smckusick 		return(umatch(s, ++p));
870*11240Smckusick 	case 0:
871*11240Smckusick 		return(!scc);
872*11240Smckusick 	}
873*11240Smckusick 	if (c==scc) goto caseq;
874*11240Smckusick 	return(0);
875*11240Smckusick }
876*11240Smckusick 
877*11240Smckusick umatch(s, p)
878*11240Smckusick register char *s, *p;
879*11240Smckusick {
880*11240Smckusick 	if(*p==0) return(1);
881*11240Smckusick 	while(*s)
882*11240Smckusick 		if (gmatch(s++,p)) return(1);
883*11240Smckusick 	return(0);
884*11240Smckusick }
885*11240Smckusick 
886*11240Smckusick makdir(namep)
887*11240Smckusick register char *namep;
888*11240Smckusick {
889*11240Smckusick 	static status;
890*11240Smckusick 	register pid;
891*11240Smckusick 
892*11240Smckusick 	if(pid = fork())
893*11240Smckusick 		while(wait(&status) != pid);
894*11240Smckusick 	else {
895*11240Smckusick 		close(2);
896*11240Smckusick 		execl("/bin/mkdir", "mkdir", namep, 0);
897*11240Smckusick 		exit(2);
898*11240Smckusick 	}
899*11240Smckusick 	return ((status>>8) & 0377)? 0: 1;
900*11240Smckusick }
901*11240Smckusick 
902*11240Smckusick swap(buf, ct)
903*11240Smckusick register ct;
904*11240Smckusick register union swp { short	shortw; char	charv[2]; } *buf;
905*11240Smckusick {
906*11240Smckusick 	register char c;
907*11240Smckusick 
908*11240Smckusick 	ct = (ct + 1) >> 1;
909*11240Smckusick 
910*11240Smckusick 	while(ct--) {
911*11240Smckusick 		c = buf->charv[0];
912*11240Smckusick 		buf->charv[0] = buf->charv[1];
913*11240Smckusick 		buf->charv[1] = c;
914*11240Smckusick 		++buf;
915*11240Smckusick 	}
916*11240Smckusick }
917*11240Smckusick set_time(namep, atime, mtime)
918*11240Smckusick register *namep;
919*11240Smckusick long atime, mtime;
920*11240Smckusick {
921*11240Smckusick 	static long timevec[2];
922*11240Smckusick 
923*11240Smckusick 	if(!Mod_time)
924*11240Smckusick 		return;
925*11240Smckusick 	timevec[0] = atime;
926*11240Smckusick 	timevec[1] = mtime;
927*11240Smckusick 	utime(namep, timevec);
928*11240Smckusick }
929*11240Smckusick chgreel(x, fl)
930*11240Smckusick {
931*11240Smckusick 	register f;
932*11240Smckusick 	char str[22];
933*11240Smckusick 	FILE *devtty;
934*11240Smckusick 	struct stat statb;
935*11240Smckusick 
936*11240Smckusick 	err("errno: %d, ", errno);
937*11240Smckusick 	err("Can't %s\n", x? "write output": "read input");
938*11240Smckusick 	fstat(fl, &statb);
939*11240Smckusick #ifdef RT
940*11240Smckusick 	if(!MERT){
941*11240Smckusick 		if((statb.st_mode&S_IFMT) != S_IFCHR)
942*11240Smckusick 			exit(2);
943*11240Smckusick 	}
944*11240Smckusick 	else if((statb.st_mode & (S_IFBLK|S_IFREC))==0)
945*11240Smckusick 		exit(2);
946*11240Smckusick #endif
947*11240Smckusick #ifndef RT
948*11240Smckusick 	if((statb.st_mode&S_IFMT) != S_IFCHR)
949*11240Smckusick 		exit(2);
950*11240Smckusick #endif
951*11240Smckusick again:
952*11240Smckusick 	err("If you want to go on, type device/file name when ready\n");
953*11240Smckusick 	devtty = fopen("/dev/tty", "r");
954*11240Smckusick 	fgets(str, 20, devtty);
955*11240Smckusick 	str[strlen(str) - 1] = '\0';
956*11240Smckusick 	if(!*str)
957*11240Smckusick 		exit(2);
958*11240Smckusick 	close(fl);
959*11240Smckusick 	if((f = open(str, x? 1: 0)) < 0) {
960*11240Smckusick 		err("That didn't work");
961*11240Smckusick 		fclose(devtty);
962*11240Smckusick 		goto again;
963*11240Smckusick 	}
964*11240Smckusick 	return f;
965*11240Smckusick }
966*11240Smckusick missdir(namep)
967*11240Smckusick register char *namep;
968*11240Smckusick {
969*11240Smckusick 	register char *np;
970*11240Smckusick 	register ct = 0;
971*11240Smckusick 
972*11240Smckusick 	if(!Dir)
973*11240Smckusick 		return 0;
974*11240Smckusick 	for(np = namep; *np; ++np)
975*11240Smckusick 		if(*np == '/') {
976*11240Smckusick 			*np = '\0';
977*11240Smckusick 			if(stat(namep, &Xstatb) == -1)
978*11240Smckusick 				makdir(namep), ++ct;
979*11240Smckusick 			*np = '/';
980*11240Smckusick 		}
981*11240Smckusick 	return ct;
982*11240Smckusick }
983*11240Smckusick err(a, b, c)
984*11240Smckusick {
985*11240Smckusick 	fprintf(stderr, a, b, c);
986*11240Smckusick }
987*11240Smckusick pwd()
988*11240Smckusick {
989*11240Smckusick 	FILE *dir;
990*11240Smckusick 
991*11240Smckusick 	dir = popen("pwd", "r");
992*11240Smckusick 	fgets(Fullname, 256, dir);
993*11240Smckusick 	if(pclose(dir))
994*11240Smckusick 		exit(2);
995*11240Smckusick 	Pathend = strlen(Fullname);
996*11240Smckusick 	Fullname[Pathend - 1] = '/';
997*11240Smckusick }
998*11240Smckusick char * cd(n)
999*11240Smckusick register char *n;
1000*11240Smckusick {
1001*11240Smckusick 	char *p_save = Name, *n_save = n, *p_end = 0;
1002*11240Smckusick 	register char *p = Name;
1003*11240Smckusick 	static char dotdot[]="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../";
1004*11240Smckusick 	int slashes;
1005*11240Smckusick 
1006*11240Smckusick 	if(*n == '/') /* don't try to chdir on full pathnames */
1007*11240Smckusick 		return n;
1008*11240Smckusick 	for(; *p && *n == *p; ++p, ++n) { /* whatever part of strings == */
1009*11240Smckusick 		if(*p == '/')
1010*11240Smckusick 			p_save = p+1, n_save = n+1;
1011*11240Smckusick 	}
1012*11240Smckusick 
1013*11240Smckusick 	p = p_save;
1014*11240Smckusick 	*p++ = '\0';
1015*11240Smckusick 	for(slashes = 0; *p; ++p) { /* if prev is longer, chdir("..") */
1016*11240Smckusick 		if(*p == '/')
1017*11240Smckusick 			++slashes;
1018*11240Smckusick 	}
1019*11240Smckusick 	p = p_save;
1020*11240Smckusick 	if(slashes) {
1021*11240Smckusick 		slashes = slashes * 3 - 1;
1022*11240Smckusick 		dotdot[slashes] = '\0';
1023*11240Smckusick 		chdir(dotdot);
1024*11240Smckusick 		dotdot[slashes] = '/';
1025*11240Smckusick 	}
1026*11240Smckusick 
1027*11240Smckusick 	n = n_save;
1028*11240Smckusick 	for(; *n; ++n, ++p) {
1029*11240Smckusick 		*p = *n;
1030*11240Smckusick 		if(*n == '/')
1031*11240Smckusick 			p_end = p+1, n_save = n+1;
1032*11240Smckusick 	}
1033*11240Smckusick 	*p = '\0';
1034*11240Smckusick 
1035*11240Smckusick 	if(p_end) {
1036*11240Smckusick 		*p_end = '\0';
1037*11240Smckusick 		if(chdir(p_save) == -1) {
1038*11240Smckusick 			if(!missdir(p_save)) {
1039*11240Smckusick cd_err:
1040*11240Smckusick 				err("Cannot chdir (no `d' option)\n");
1041*11240Smckusick 				exit(2);
1042*11240Smckusick 			} else if(chdir(p_save) == -1)
1043*11240Smckusick 				goto cd_err;
1044*11240Smckusick 		}
1045*11240Smckusick 	} else
1046*11240Smckusick 		*p_save = '\0';
1047*11240Smckusick 	return n_save;
1048*11240Smckusick }
1049*11240Smckusick #ifdef RT
1050*11240Smckusick actsize()
1051*11240Smckusick {
1052*11240Smckusick }
1053*11240Smckusick #endif
1054