xref: /plan9/sys/src/ape/cmd/make/files.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier /* POSIX DEPENDENT PROCEDURES */
2*219b2ee8SDavid du Colombier #include "defs.h"
3*219b2ee8SDavid du Colombier #include <sys/stat.h>
4*219b2ee8SDavid du Colombier #include <ar.h>
5*219b2ee8SDavid du Colombier 
6*219b2ee8SDavid du Colombier #define NAMESPERBLOCK	32
7*219b2ee8SDavid du Colombier 
8*219b2ee8SDavid du Colombier /* DEFAULT RULES FOR POSIX */
9*219b2ee8SDavid du Colombier 
10*219b2ee8SDavid du Colombier char *dfltmacro[] =
11*219b2ee8SDavid du Colombier 	{
12*219b2ee8SDavid du Colombier 	".SUFFIXES : .o .c .y .l .a .sh .f",
13*219b2ee8SDavid du Colombier 	"MAKE=make",
14*219b2ee8SDavid du Colombier 	"AR=ar",
15*219b2ee8SDavid du Colombier 	"ARFLAGS=rv",
16*219b2ee8SDavid du Colombier 	"YACC=yacc",
17*219b2ee8SDavid du Colombier 	"YFLAGS=",
18*219b2ee8SDavid du Colombier 	"LEX=lex",
19*219b2ee8SDavid du Colombier 	"LFLAGS=",
20*219b2ee8SDavid du Colombier 	"LDFLAGS=",
21*219b2ee8SDavid du Colombier 	"CC=c89",
22*219b2ee8SDavid du Colombier 	"CFLAGS=-O",
23*219b2ee8SDavid du Colombier 	"FC=fort77",
24*219b2ee8SDavid du Colombier 	"FFLAGS=-O 1",
25*219b2ee8SDavid du Colombier 	0 };
26*219b2ee8SDavid du Colombier 
27*219b2ee8SDavid du Colombier char *dfltpat[] =
28*219b2ee8SDavid du Colombier 	{
29*219b2ee8SDavid du Colombier 	"%.o : %.c",
30*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) -c $<",
31*219b2ee8SDavid du Colombier 
32*219b2ee8SDavid du Colombier 	"%.o : %.y",
33*219b2ee8SDavid du Colombier 	"\t$(YACC) $(YFLAGS) $<",
34*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) -c y.tab.c",
35*219b2ee8SDavid du Colombier 	"\trm y.tab.c",
36*219b2ee8SDavid du Colombier 	"\tmv y.tab.o $@",
37*219b2ee8SDavid du Colombier 
38*219b2ee8SDavid du Colombier 	"%.o : %.l",
39*219b2ee8SDavid du Colombier 	"\t$(LEX) $(LFLAGS) $<",
40*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) -c lex.yy.c",
41*219b2ee8SDavid du Colombier 	"\trm lex.yy.c",
42*219b2ee8SDavid du Colombier 	"\tmv lex.yy.o $@",
43*219b2ee8SDavid du Colombier 
44*219b2ee8SDavid du Colombier 	"%.c : %.y",
45*219b2ee8SDavid du Colombier 	"\t$(YACC) $(YFLAGS) $<",
46*219b2ee8SDavid du Colombier 	"\tmv y.tab.c $@",
47*219b2ee8SDavid du Colombier 
48*219b2ee8SDavid du Colombier 	"%.c : %.l",
49*219b2ee8SDavid du Colombier 	"\t$(LEX) $(LFLAGS) $<",
50*219b2ee8SDavid du Colombier 	"\tmv lex.yy.c $@",
51*219b2ee8SDavid du Colombier 
52*219b2ee8SDavid du Colombier 	"% : %.o",
53*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<",
54*219b2ee8SDavid du Colombier 
55*219b2ee8SDavid du Colombier 	"% : %.c",
56*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<",
57*219b2ee8SDavid du Colombier 
58*219b2ee8SDavid du Colombier 	0 };
59*219b2ee8SDavid du Colombier 
60*219b2ee8SDavid du Colombier 
61*219b2ee8SDavid du Colombier 
62*219b2ee8SDavid du Colombier char *dfltsuff[] =
63*219b2ee8SDavid du Colombier 	{
64*219b2ee8SDavid du Colombier 	".SUFFIXES : .o .c .y .l .a .sh .f",
65*219b2ee8SDavid du Colombier 	".c.o :",
66*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) -c $<",
67*219b2ee8SDavid du Colombier 
68*219b2ee8SDavid du Colombier 	".f.o :",
69*219b2ee8SDavid du Colombier 	"\t$(FC) $(FFLAGS) -c $<",
70*219b2ee8SDavid du Colombier 
71*219b2ee8SDavid du Colombier 	".y.o :",
72*219b2ee8SDavid du Colombier 	"\t$(YACC) $(YFLAGS) $<",
73*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) -c y.tab.c",
74*219b2ee8SDavid du Colombier 	"\trm -f y.tab.c",
75*219b2ee8SDavid du Colombier 	"\tmv y.tab.o $@",
76*219b2ee8SDavid du Colombier 
77*219b2ee8SDavid du Colombier 	".l.o :",
78*219b2ee8SDavid du Colombier 	"\t$(LEX) $(LFLAGS) $<",
79*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) -c lex.yy.c",
80*219b2ee8SDavid du Colombier 	"\trm -f lex.yy.c",
81*219b2ee8SDavid du Colombier 	"\tmv lex.yy.o $@",
82*219b2ee8SDavid du Colombier 
83*219b2ee8SDavid du Colombier 	".y.c :",
84*219b2ee8SDavid du Colombier 	"\t$(YACC) $(YFLAGS) $<",
85*219b2ee8SDavid du Colombier 	"\tmv y.tab.c $@",
86*219b2ee8SDavid du Colombier 
87*219b2ee8SDavid du Colombier 	".l.c :",
88*219b2ee8SDavid du Colombier 	"\t$(LEX) $(LFLAGS) $<",
89*219b2ee8SDavid du Colombier 	"\tmv lex.yy.c $@",
90*219b2ee8SDavid du Colombier 
91*219b2ee8SDavid du Colombier 	".c.a:",
92*219b2ee8SDavid du Colombier 	"\t$(CC) -c $(CFLAGS) $<",
93*219b2ee8SDavid du Colombier 	"\t$(AR) $(ARFLAGS) $@ $*.o",
94*219b2ee8SDavid du Colombier 	"\trm -f $*.o",
95*219b2ee8SDavid du Colombier 
96*219b2ee8SDavid du Colombier 	".f.a:",
97*219b2ee8SDavid du Colombier 	"\t$(FC) -c $(FFLAGS) $<",
98*219b2ee8SDavid du Colombier 	"\t$(AR) $(ARFLAGS) $@ $*.o",
99*219b2ee8SDavid du Colombier 	"\trm -f $*.o",
100*219b2ee8SDavid du Colombier 
101*219b2ee8SDavid du Colombier 	".c:",
102*219b2ee8SDavid du Colombier 	"\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<",
103*219b2ee8SDavid du Colombier 
104*219b2ee8SDavid du Colombier 	".f:",
105*219b2ee8SDavid du Colombier 	"\t$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<",
106*219b2ee8SDavid du Colombier 
107*219b2ee8SDavid du Colombier 	".sh:",
108*219b2ee8SDavid du Colombier 	"\tcp $< $@",
109*219b2ee8SDavid du Colombier 	"\tchmod a+x $@",
110*219b2ee8SDavid du Colombier 
111*219b2ee8SDavid du Colombier 	0 };
112*219b2ee8SDavid du Colombier 
113*219b2ee8SDavid du Colombier 
114*219b2ee8SDavid du Colombier static struct dirhd	*opdir(char *, int);
115*219b2ee8SDavid du Colombier static void		cldir(struct dirhd *, int);
116*219b2ee8SDavid du Colombier static int		amatch(char *, char *);
117*219b2ee8SDavid du Colombier static int		umatch(char *, char *);
118*219b2ee8SDavid du Colombier static void		clarch(void);
119*219b2ee8SDavid du Colombier static int		openarch(char *);
120*219b2ee8SDavid du Colombier static int		getarch(void);
121*219b2ee8SDavid du Colombier 
122*219b2ee8SDavid du Colombier time_t
exists(char * filename)123*219b2ee8SDavid du Colombier exists(char *filename)
124*219b2ee8SDavid du Colombier {
125*219b2ee8SDavid du Colombier struct stat buf;
126*219b2ee8SDavid du Colombier char *s;
127*219b2ee8SDavid du Colombier 
128*219b2ee8SDavid du Colombier for(s = filename ; *s!='\0' && *s!='(' &&  *s!=')' ; ++s)
129*219b2ee8SDavid du Colombier 	;
130*219b2ee8SDavid du Colombier 
131*219b2ee8SDavid du Colombier if(*s != '\0')
132*219b2ee8SDavid du Colombier 	return lookarch(filename);
133*219b2ee8SDavid du Colombier 
134*219b2ee8SDavid du Colombier if(stat(filename,&buf) < 0)
135*219b2ee8SDavid du Colombier 	return 0;
136*219b2ee8SDavid du Colombier else	return buf.st_mtime;
137*219b2ee8SDavid du Colombier }
138*219b2ee8SDavid du Colombier 
139*219b2ee8SDavid du Colombier 
140*219b2ee8SDavid du Colombier time_t
prestime(void)141*219b2ee8SDavid du Colombier prestime(void)
142*219b2ee8SDavid du Colombier {
143*219b2ee8SDavid du Colombier time_t t;
144*219b2ee8SDavid du Colombier time(&t);
145*219b2ee8SDavid du Colombier return t;
146*219b2ee8SDavid du Colombier }
147*219b2ee8SDavid du Colombier 
148*219b2ee8SDavid du Colombier static char nmtemp[MAXNAMLEN+1];	/* guarantees a null after the name */
149*219b2ee8SDavid du Colombier static char *tempend = nmtemp + MAXNAMLEN;
150*219b2ee8SDavid du Colombier 
151*219b2ee8SDavid du Colombier 
152*219b2ee8SDavid du Colombier 
153*219b2ee8SDavid du Colombier depblkp
srchdir(char * pat,int mkchain,depblkp nextdbl)154*219b2ee8SDavid du Colombier srchdir(char *pat, int mkchain, depblkp nextdbl)
155*219b2ee8SDavid du Colombier {
156*219b2ee8SDavid du Colombier DIR *dirf;
157*219b2ee8SDavid du Colombier struct dirhd *dirptr;
158*219b2ee8SDavid du Colombier char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
159*219b2ee8SDavid du Colombier char fullname[100];
160*219b2ee8SDavid du Colombier nameblkp q;
161*219b2ee8SDavid du Colombier depblkp thisdbl;
162*219b2ee8SDavid du Colombier struct pattern *patp;
163*219b2ee8SDavid du Colombier 
164*219b2ee8SDavid du Colombier struct dirent *dptr;
165*219b2ee8SDavid du Colombier 
166*219b2ee8SDavid du Colombier thisdbl = 0;
167*219b2ee8SDavid du Colombier 
168*219b2ee8SDavid du Colombier if(mkchain == NO)
169*219b2ee8SDavid du Colombier 	for(patp=firstpat ; patp ; patp = patp->nxtpattern)
170*219b2ee8SDavid du Colombier 		if(equal(pat, patp->patval)) return 0;
171*219b2ee8SDavid du Colombier 
172*219b2ee8SDavid du Colombier patp = ALLOC(pattern);
173*219b2ee8SDavid du Colombier patp->nxtpattern = firstpat;
174*219b2ee8SDavid du Colombier firstpat = patp;
175*219b2ee8SDavid du Colombier patp->patval = copys(pat);
176*219b2ee8SDavid du Colombier 
177*219b2ee8SDavid du Colombier endir = 0;
178*219b2ee8SDavid du Colombier 
179*219b2ee8SDavid du Colombier for(p=pat; *p!='\0'; ++p)
180*219b2ee8SDavid du Colombier 	if(*p=='/') endir = p;
181*219b2ee8SDavid du Colombier 
182*219b2ee8SDavid du Colombier if(endir==0)
183*219b2ee8SDavid du Colombier 	{
184*219b2ee8SDavid du Colombier 	dirname = ".";
185*219b2ee8SDavid du Colombier 	dirpref = "";
186*219b2ee8SDavid du Colombier 	filepat = pat;
187*219b2ee8SDavid du Colombier 	}
188*219b2ee8SDavid du Colombier else	{
189*219b2ee8SDavid du Colombier 	dirname = pat;
190*219b2ee8SDavid du Colombier 	*endir = '\0';
191*219b2ee8SDavid du Colombier 	dirpref = concat(dirname, "/", temp);
192*219b2ee8SDavid du Colombier 	filepat = endir+1;
193*219b2ee8SDavid du Colombier 	}
194*219b2ee8SDavid du Colombier 
195*219b2ee8SDavid du Colombier dirptr = opdir(dirname,YES);
196*219b2ee8SDavid du Colombier dirf = dirptr->dirfc;
197*219b2ee8SDavid du Colombier 
198*219b2ee8SDavid du Colombier for( dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )
199*219b2ee8SDavid du Colombier 	{
200*219b2ee8SDavid du Colombier 	char *p1, *p2;
201*219b2ee8SDavid du Colombier 	p1 = dptr->d_name;
202*219b2ee8SDavid du Colombier 	p2 = nmtemp;
203*219b2ee8SDavid du Colombier 	while( (p2<tempend) && (*p2++ = *p1++)!='\0')
204*219b2ee8SDavid du Colombier 		;
205*219b2ee8SDavid du Colombier 	if( amatch(nmtemp,filepat) )
206*219b2ee8SDavid du Colombier 		{
207*219b2ee8SDavid du Colombier 		concat(dirpref,nmtemp,fullname);
208*219b2ee8SDavid du Colombier 		if( (q=srchname(fullname)) ==0)
209*219b2ee8SDavid du Colombier 			q = makename(copys(fullname));
210*219b2ee8SDavid du Colombier 		if(mkchain)
211*219b2ee8SDavid du Colombier 			{
212*219b2ee8SDavid du Colombier 			thisdbl = ALLOC(depblock);
213*219b2ee8SDavid du Colombier 			thisdbl->nxtdepblock = nextdbl;
214*219b2ee8SDavid du Colombier 			thisdbl->depname = q;
215*219b2ee8SDavid du Colombier 			nextdbl = thisdbl;
216*219b2ee8SDavid du Colombier 			}
217*219b2ee8SDavid du Colombier 		}
218*219b2ee8SDavid du Colombier 	}
219*219b2ee8SDavid du Colombier 
220*219b2ee8SDavid du Colombier 
221*219b2ee8SDavid du Colombier if(endir)
222*219b2ee8SDavid du Colombier 	*endir = '/';
223*219b2ee8SDavid du Colombier 
224*219b2ee8SDavid du Colombier cldir(dirptr, YES);
225*219b2ee8SDavid du Colombier 
226*219b2ee8SDavid du Colombier return thisdbl;
227*219b2ee8SDavid du Colombier }
228*219b2ee8SDavid du Colombier 
229*219b2ee8SDavid du Colombier static struct dirhd *
opdir(char * dirname,int stopifbad)230*219b2ee8SDavid du Colombier opdir(char *dirname, int stopifbad)
231*219b2ee8SDavid du Colombier {
232*219b2ee8SDavid du Colombier struct dirhd *od;
233*219b2ee8SDavid du Colombier 
234*219b2ee8SDavid du Colombier for(od = firstod; od; od = od->nxtdirhd)
235*219b2ee8SDavid du Colombier 	if(equal(dirname, od->dirn) )
236*219b2ee8SDavid du Colombier 		break;
237*219b2ee8SDavid du Colombier 
238*219b2ee8SDavid du Colombier if(od == NULL)
239*219b2ee8SDavid du Colombier 	{
240*219b2ee8SDavid du Colombier 	++nopdir;
241*219b2ee8SDavid du Colombier 	od = ALLOC(dirhd);
242*219b2ee8SDavid du Colombier 	od->nxtdirhd = firstod;
243*219b2ee8SDavid du Colombier 	firstod = od;
244*219b2ee8SDavid du Colombier 	od->dirn = copys(dirname);
245*219b2ee8SDavid du Colombier 	}
246*219b2ee8SDavid du Colombier 
247*219b2ee8SDavid du Colombier if(od->dirfc==NULL && (od->dirfc = opendir(dirname)) == NULL && stopifbad)
248*219b2ee8SDavid du Colombier 	{
249*219b2ee8SDavid du Colombier 	fprintf(stderr, "Directory %s: ", dirname);
250*219b2ee8SDavid du Colombier 	fatal("Cannot open");
251*219b2ee8SDavid du Colombier 	}
252*219b2ee8SDavid du Colombier 
253*219b2ee8SDavid du Colombier return od;
254*219b2ee8SDavid du Colombier }
255*219b2ee8SDavid du Colombier 
256*219b2ee8SDavid du Colombier 
257*219b2ee8SDavid du Colombier static void
cldir(struct dirhd * dp,int used)258*219b2ee8SDavid du Colombier cldir(struct dirhd *dp, int used)
259*219b2ee8SDavid du Colombier {
260*219b2ee8SDavid du Colombier if(nopdir >= MAXDIR)
261*219b2ee8SDavid du Colombier 	{
262*219b2ee8SDavid du Colombier 	closedir(dp->dirfc);
263*219b2ee8SDavid du Colombier 	dp->dirfc = NULL;
264*219b2ee8SDavid du Colombier 	}
265*219b2ee8SDavid du Colombier else if(used)
266*219b2ee8SDavid du Colombier 	rewinddir(dp->dirfc); /* start over at the beginning  */
267*219b2ee8SDavid du Colombier }
268*219b2ee8SDavid du Colombier 
269*219b2ee8SDavid du Colombier /* stolen from glob through find */
270*219b2ee8SDavid du Colombier 
271*219b2ee8SDavid du Colombier static int
amatch(char * s,char * p)272*219b2ee8SDavid du Colombier amatch(char *s, char *p)
273*219b2ee8SDavid du Colombier {
274*219b2ee8SDavid du Colombier 	int cc, scc, k;
275*219b2ee8SDavid du Colombier 	int c, lc;
276*219b2ee8SDavid du Colombier 
277*219b2ee8SDavid du Colombier 	scc = *s;
278*219b2ee8SDavid du Colombier 	lc = 077777;
279*219b2ee8SDavid du Colombier 	switch (c = *p) {
280*219b2ee8SDavid du Colombier 
281*219b2ee8SDavid du Colombier 	case '[':
282*219b2ee8SDavid du Colombier 		k = 0;
283*219b2ee8SDavid du Colombier 		while (cc = *++p) {
284*219b2ee8SDavid du Colombier 			switch (cc) {
285*219b2ee8SDavid du Colombier 
286*219b2ee8SDavid du Colombier 			case ']':
287*219b2ee8SDavid du Colombier 				if (k)
288*219b2ee8SDavid du Colombier 					return amatch(++s, ++p);
289*219b2ee8SDavid du Colombier 				else
290*219b2ee8SDavid du Colombier 					return 0;
291*219b2ee8SDavid du Colombier 
292*219b2ee8SDavid du Colombier 			case '-':
293*219b2ee8SDavid du Colombier 				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
294*219b2ee8SDavid du Colombier 			}
295*219b2ee8SDavid du Colombier 			if (scc==(lc=cc)) k++;
296*219b2ee8SDavid du Colombier 		}
297*219b2ee8SDavid du Colombier 		return 0;
298*219b2ee8SDavid du Colombier 
299*219b2ee8SDavid du Colombier 	case '?':
300*219b2ee8SDavid du Colombier 	caseq:
301*219b2ee8SDavid du Colombier 		if(scc) return amatch(++s, ++p);
302*219b2ee8SDavid du Colombier 		return 0;
303*219b2ee8SDavid du Colombier 	case '*':
304*219b2ee8SDavid du Colombier 		return umatch(s, ++p);
305*219b2ee8SDavid du Colombier 	case 0:
306*219b2ee8SDavid du Colombier 		return !scc;
307*219b2ee8SDavid du Colombier 	}
308*219b2ee8SDavid du Colombier 	if (c==scc) goto caseq;
309*219b2ee8SDavid du Colombier 	return 0;
310*219b2ee8SDavid du Colombier }
311*219b2ee8SDavid du Colombier 
312*219b2ee8SDavid du Colombier static int
umatch(char * s,char * p)313*219b2ee8SDavid du Colombier umatch(char *s, char *p)
314*219b2ee8SDavid du Colombier {
315*219b2ee8SDavid du Colombier 	if(*p==0) return 1;
316*219b2ee8SDavid du Colombier 	while(*s)
317*219b2ee8SDavid du Colombier 		if (amatch(s++,p)) return 1;
318*219b2ee8SDavid du Colombier 	return 0;
319*219b2ee8SDavid du Colombier }
320*219b2ee8SDavid du Colombier 
321*219b2ee8SDavid du Colombier #ifdef METERFILE
322*219b2ee8SDavid du Colombier #include <pwd.h>
323*219b2ee8SDavid du Colombier int meteron	= 0;	/* default: metering off */
324*219b2ee8SDavid du Colombier 
meter(char * file)325*219b2ee8SDavid du Colombier extern void meter(char *file)
326*219b2ee8SDavid du Colombier {
327*219b2ee8SDavid du Colombier time_t tvec;
328*219b2ee8SDavid du Colombier char *p;
329*219b2ee8SDavid du Colombier FILE * mout;
330*219b2ee8SDavid du Colombier struct passwd *pwd;
331*219b2ee8SDavid du Colombier 
332*219b2ee8SDavid du Colombier if(file==0 || meteron==0) return;
333*219b2ee8SDavid du Colombier 
334*219b2ee8SDavid du Colombier pwd = getpwuid(getuid());
335*219b2ee8SDavid du Colombier 
336*219b2ee8SDavid du Colombier time(&tvec);
337*219b2ee8SDavid du Colombier 
338*219b2ee8SDavid du Colombier if( mout = fopen(file,"a") )
339*219b2ee8SDavid du Colombier 	{
340*219b2ee8SDavid du Colombier 	p = ctime(&tvec);
341*219b2ee8SDavid du Colombier 	p[16] = '\0';
342*219b2ee8SDavid du Colombier 	fprintf(mout, "User %s, %s\n", pwd->pw_name, p+4);
343*219b2ee8SDavid du Colombier 	fclose(mout);
344*219b2ee8SDavid du Colombier 	}
345*219b2ee8SDavid du Colombier }
346*219b2ee8SDavid du Colombier #endif
347*219b2ee8SDavid du Colombier 
348*219b2ee8SDavid du Colombier 
349*219b2ee8SDavid du Colombier /* look inside archives for notation a(b)
350*219b2ee8SDavid du Colombier 	a(b)	is file member   b   in archive a
351*219b2ee8SDavid du Colombier */
352*219b2ee8SDavid du Colombier 
353*219b2ee8SDavid du Colombier static long arflen;
354*219b2ee8SDavid du Colombier static long arfdate;
355*219b2ee8SDavid du Colombier static char arfname[16];
356*219b2ee8SDavid du Colombier FILE *arfd;
357*219b2ee8SDavid du Colombier long int arpos, arlen;
358*219b2ee8SDavid du Colombier 
359*219b2ee8SDavid du Colombier time_t
lookarch(char * filename)360*219b2ee8SDavid du Colombier lookarch(char *filename)
361*219b2ee8SDavid du Colombier {
362*219b2ee8SDavid du Colombier char *p, *q, *send, s[15], pad;
363*219b2ee8SDavid du Colombier int i, nc, nsym;
364*219b2ee8SDavid du Colombier 
365*219b2ee8SDavid du Colombier for(p = filename; *p!= '(' ; ++p)
366*219b2ee8SDavid du Colombier 	;
367*219b2ee8SDavid du Colombier 
368*219b2ee8SDavid du Colombier *p = '\0';
369*219b2ee8SDavid du Colombier if( ! openarch(filename) )
370*219b2ee8SDavid du Colombier 	{
371*219b2ee8SDavid du Colombier 	*p = '(';
372*219b2ee8SDavid du Colombier 	return 0L;
373*219b2ee8SDavid du Colombier 	}
374*219b2ee8SDavid du Colombier *p++ = '(';
375*219b2ee8SDavid du Colombier nc = 14;
376*219b2ee8SDavid du Colombier pad = ' ';
377*219b2ee8SDavid du Colombier 
378*219b2ee8SDavid du Colombier send = s + nc;
379*219b2ee8SDavid du Colombier for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
380*219b2ee8SDavid du Colombier 	;
381*219b2ee8SDavid du Colombier if(p[0]==')' && p[1]!='\0')	/* forbid stuff after the paren */
382*219b2ee8SDavid du Colombier 	{
383*219b2ee8SDavid du Colombier 	clarch();
384*219b2ee8SDavid du Colombier 	return 0L;
385*219b2ee8SDavid du Colombier 	}
386*219b2ee8SDavid du Colombier while(q < send)
387*219b2ee8SDavid du Colombier 	*q++ = pad;
388*219b2ee8SDavid du Colombier while(getarch())
389*219b2ee8SDavid du Colombier 	{
390*219b2ee8SDavid du Colombier 	if( !strncmp(arfname, s, nc))
391*219b2ee8SDavid du Colombier 		{
392*219b2ee8SDavid du Colombier 		clarch();
393*219b2ee8SDavid du Colombier /*TEMP fprintf(stderr, "found archive member %14s, time=%d\n", s, arfdate); */
394*219b2ee8SDavid du Colombier 		return arfdate;
395*219b2ee8SDavid du Colombier 		}
396*219b2ee8SDavid du Colombier 	}
397*219b2ee8SDavid du Colombier 
398*219b2ee8SDavid du Colombier clarch();
399*219b2ee8SDavid du Colombier return  0L;
400*219b2ee8SDavid du Colombier }
401*219b2ee8SDavid du Colombier 
402*219b2ee8SDavid du Colombier static void
clarch(void)403*219b2ee8SDavid du Colombier clarch(void)
404*219b2ee8SDavid du Colombier {
405*219b2ee8SDavid du Colombier fclose( arfd );
406*219b2ee8SDavid du Colombier }
407*219b2ee8SDavid du Colombier 
408*219b2ee8SDavid du Colombier static int
openarch(char * f)409*219b2ee8SDavid du Colombier openarch(char *f)
410*219b2ee8SDavid du Colombier {
411*219b2ee8SDavid du Colombier char magic[SARMAG];
412*219b2ee8SDavid du Colombier int word;
413*219b2ee8SDavid du Colombier struct stat buf;
414*219b2ee8SDavid du Colombier nameblkp p;
415*219b2ee8SDavid du Colombier 
416*219b2ee8SDavid du Colombier stat(f, &buf);
417*219b2ee8SDavid du Colombier arlen = buf.st_size;
418*219b2ee8SDavid du Colombier 
419*219b2ee8SDavid du Colombier arfd = fopen(f, "r");
420*219b2ee8SDavid du Colombier if(arfd == NULL)
421*219b2ee8SDavid du Colombier 	return NO;
422*219b2ee8SDavid du Colombier 	/* fatal1("cannot open %s", f); */
423*219b2ee8SDavid du Colombier 
424*219b2ee8SDavid du Colombier fread( (char *) &word, sizeof(word), 1, arfd);
425*219b2ee8SDavid du Colombier 
426*219b2ee8SDavid du Colombier fseek(arfd, 0L, 0);
427*219b2ee8SDavid du Colombier fread(magic, SARMAG, 1, arfd);
428*219b2ee8SDavid du Colombier arpos = SARMAG;
429*219b2ee8SDavid du Colombier if( strncmp(magic, ARMAG, SARMAG) )
430*219b2ee8SDavid du Colombier 	fatal1("%s is not an archive", f);
431*219b2ee8SDavid du Colombier 
432*219b2ee8SDavid du Colombier if( !(p = srchname(f)) )
433*219b2ee8SDavid du Colombier 	p = makename( copys(f) );
434*219b2ee8SDavid du Colombier p->isarch = YES;
435*219b2ee8SDavid du Colombier arflen = 0;
436*219b2ee8SDavid du Colombier return YES;
437*219b2ee8SDavid du Colombier }
438*219b2ee8SDavid du Colombier 
439*219b2ee8SDavid du Colombier 
440*219b2ee8SDavid du Colombier static int
getarch(void)441*219b2ee8SDavid du Colombier getarch(void)
442*219b2ee8SDavid du Colombier {
443*219b2ee8SDavid du Colombier struct ar_hdr arhead;
444*219b2ee8SDavid du Colombier 
445*219b2ee8SDavid du Colombier arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
446*219b2ee8SDavid du Colombier if(arpos >= arlen)
447*219b2ee8SDavid du Colombier 	return 0;
448*219b2ee8SDavid du Colombier fseek(arfd, arpos, 0);
449*219b2ee8SDavid du Colombier 
450*219b2ee8SDavid du Colombier fread( (char *) &arhead, sizeof(arhead), 1, arfd);
451*219b2ee8SDavid du Colombier arpos += sizeof(arhead);
452*219b2ee8SDavid du Colombier arflen = atol(arhead.ar_size);
453*219b2ee8SDavid du Colombier arfdate = atol(arhead.ar_date);
454*219b2ee8SDavid du Colombier strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
455*219b2ee8SDavid du Colombier return 1;
456*219b2ee8SDavid du Colombier }
457*219b2ee8SDavid du Colombier 
458*219b2ee8SDavid du Colombier /* find the directory containing name.
459*219b2ee8SDavid du Colombier    read it into the hash table if it hasn't been used before or if
460*219b2ee8SDavid du Colombier    if might have changed since last reference
461*219b2ee8SDavid du Colombier */
462*219b2ee8SDavid du Colombier 
463*219b2ee8SDavid du Colombier void
dirsrch(char * name)464*219b2ee8SDavid du Colombier dirsrch(char *name)
465*219b2ee8SDavid du Colombier {
466*219b2ee8SDavid du Colombier DIR *dirf;
467*219b2ee8SDavid du Colombier struct dirhd *dirp;
468*219b2ee8SDavid du Colombier time_t dirt, objt;
469*219b2ee8SDavid du Colombier int dirused, hasparen;
470*219b2ee8SDavid du Colombier char *dirname, *lastslash;
471*219b2ee8SDavid du Colombier char *fullname, *filepart, *fileend, *s;
472*219b2ee8SDavid du Colombier struct dirent *dptr;
473*219b2ee8SDavid du Colombier 
474*219b2ee8SDavid du Colombier lastslash = NULL;
475*219b2ee8SDavid du Colombier hasparen = NO;
476*219b2ee8SDavid du Colombier 
477*219b2ee8SDavid du Colombier for(s=name; *s; ++s)
478*219b2ee8SDavid du Colombier 	if(*s == '/')
479*219b2ee8SDavid du Colombier 		lastslash = s;
480*219b2ee8SDavid du Colombier 	else if(*s=='(' || *s==')')
481*219b2ee8SDavid du Colombier 		hasparen = YES;
482*219b2ee8SDavid du Colombier 
483*219b2ee8SDavid du Colombier if(hasparen)
484*219b2ee8SDavid du Colombier 	{
485*219b2ee8SDavid du Colombier 	if(objt = lookarch(name))
486*219b2ee8SDavid du Colombier 		makename(name)->modtime = objt;
487*219b2ee8SDavid du Colombier 	return;
488*219b2ee8SDavid du Colombier 	}
489*219b2ee8SDavid du Colombier 
490*219b2ee8SDavid du Colombier if(lastslash)
491*219b2ee8SDavid du Colombier 	{
492*219b2ee8SDavid du Colombier 	dirname = name;
493*219b2ee8SDavid du Colombier 	*lastslash = '\0';
494*219b2ee8SDavid du Colombier 	}
495*219b2ee8SDavid du Colombier else
496*219b2ee8SDavid du Colombier 	dirname = ".";
497*219b2ee8SDavid du Colombier 
498*219b2ee8SDavid du Colombier dirused = NO;
499*219b2ee8SDavid du Colombier dirp = opdir(dirname, NO);
500*219b2ee8SDavid du Colombier dirf = dirp->dirfc;
501*219b2ee8SDavid du Colombier if(dirp->dirok || !dirf)
502*219b2ee8SDavid du Colombier 	goto ret;
503*219b2ee8SDavid du Colombier dirt = exists(dirname);
504*219b2ee8SDavid du Colombier if(dirp->dirtime == dirt)
505*219b2ee8SDavid du Colombier 	goto ret;
506*219b2ee8SDavid du Colombier 
507*219b2ee8SDavid du Colombier dirp->dirok = YES;
508*219b2ee8SDavid du Colombier dirp->dirtime = dirt;
509*219b2ee8SDavid du Colombier dirused = YES;
510*219b2ee8SDavid du Colombier 
511*219b2ee8SDavid du Colombier /* allocate buffer to hold full file name */
512*219b2ee8SDavid du Colombier if(lastslash)
513*219b2ee8SDavid du Colombier 	{
514*219b2ee8SDavid du Colombier 	fullname = (char *) ckalloc(strlen(dirname)+MAXNAMLEN+2);
515*219b2ee8SDavid du Colombier 	concat(dirname, "/", fullname);
516*219b2ee8SDavid du Colombier 	filepart = fullname + strlen(fullname);
517*219b2ee8SDavid du Colombier 	}
518*219b2ee8SDavid du Colombier else
519*219b2ee8SDavid du Colombier 	filepart = fullname = (char *) ckalloc(MAXNAMLEN+1);
520*219b2ee8SDavid du Colombier 
521*219b2ee8SDavid du Colombier 
522*219b2ee8SDavid du Colombier fileend = filepart + MAXNAMLEN;
523*219b2ee8SDavid du Colombier *fileend = '\0';
524*219b2ee8SDavid du Colombier for(dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )
525*219b2ee8SDavid du Colombier 	{
526*219b2ee8SDavid du Colombier 	char *p1, *p2;
527*219b2ee8SDavid du Colombier 	p1 = dptr->d_name;
528*219b2ee8SDavid du Colombier 	p2 = filepart;
529*219b2ee8SDavid du Colombier 	while( (p2<fileend) && (*p2++ = *p1++)!='\0')
530*219b2ee8SDavid du Colombier 		;
531*219b2ee8SDavid du Colombier 	if( ! srchname(fullname) )
532*219b2ee8SDavid du Colombier 		(void) makename(copys(fullname));
533*219b2ee8SDavid du Colombier 	}
534*219b2ee8SDavid du Colombier 
535*219b2ee8SDavid du Colombier free(fullname);
536*219b2ee8SDavid du Colombier 
537*219b2ee8SDavid du Colombier ret:
538*219b2ee8SDavid du Colombier 	cldir(dirp, dirused);
539*219b2ee8SDavid du Colombier 	if(lastslash)
540*219b2ee8SDavid du Colombier 		*lastslash = '/';
541*219b2ee8SDavid du Colombier }
542*219b2ee8SDavid du Colombier 
543*219b2ee8SDavid du Colombier 
544*219b2ee8SDavid du Colombier 
545*219b2ee8SDavid du Colombier void
baddirs(void)546*219b2ee8SDavid du Colombier baddirs(void)
547*219b2ee8SDavid du Colombier {
548*219b2ee8SDavid du Colombier struct dirhd *od;
549*219b2ee8SDavid du Colombier 
550*219b2ee8SDavid du Colombier for(od = firstod; od; od = od->nxtdirhd)
551*219b2ee8SDavid du Colombier 	od->dirok = NO;
552*219b2ee8SDavid du Colombier }
553