xref: /csrg-svn/old/make/files.c (revision 16212)
1 static	char *sccsid = "@(#)files.c	4.9 (Berkeley) 84/03/21";
2 #include <fcntl.h>
3 
4 /* UNIX DEPENDENT PROCEDURES */
5 
6 
7 /* DEFAULT RULES FOR UNIX */
8 
9 char *builtin[] =
10 	{
11 #ifdef pwb
12 	".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
13 #else
14 	".SUFFIXES : .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p",
15 #endif
16 	"YACC=yacc",
17 	"YACCR=yacc -r",
18 	"YACCE=yacc -e",
19 	"YFLAGS=",
20 	"LEX=lex",
21 	"LFLAGS=",
22 	"CC=cc",
23 #if defined(vax) || defined(sun)
24 	"AS=as",
25 #else
26 	"AS=as -",
27 #endif
28 	"PC=pc",
29 	"PFLAGS=",
30 	"CFLAGS=",
31 	"RC=f77",
32 	"RFLAGS=",
33 	"FC=f77",
34 	"EFLAGS=",
35 	"FFLAGS=",
36 	"LOADLIBES=",
37 #ifdef pwb
38 	"SCOMP=scomp",
39 	"SCFLAGS=",
40 	"CMDICT=cmdict",
41 	"CMFLAGS=",
42 #endif
43 
44 	".c.o :",
45 	"\t$(CC) $(CFLAGS) -c $<",
46 
47 	".p.o :",
48 	"\t$(PC) $(PFLAGS) -c $<",
49 
50 	".cl.o :",
51 	"\tclass -c $<",
52 
53 	".e.o .r.o .F.o .f.o :",
54 	"\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
55 
56 	".s.o :",
57 	"\t$(AS) -o $@ $<",
58 
59 	".y.o :",
60 	"\t$(YACC) $(YFLAGS) $<",
61 	"\t$(CC) $(CFLAGS) -c y.tab.c",
62 	"\trm y.tab.c",
63 	"\tmv y.tab.o $@",
64 
65 	".yr.o:",
66 	"\t$(YACCR) $(YFLAGS) $<",
67 	"\t$(RC) $(RFLAGS) -c y.tab.r",
68 	"\trm y.tab.r",
69 	"\tmv y.tab.o $@",
70 
71 	".ye.o :",
72 	"\t$(YACCE) $(YFLAGS) $<",
73 	"\t$(EC) $(RFLAGS) -c y.tab.e",
74 	"\trm y.tab.e",
75 	"\tmv y.tab.o $@",
76 
77 	".l.o :",
78 	"\t$(LEX) $(LFLAGS) $<",
79 	"\t$(CC) $(CFLAGS) -c lex.yy.c",
80 	"\trm lex.yy.c",
81 	"\tmv lex.yy.o $@",
82 
83 	".y.c :",
84 	"\t$(YACC) $(YFLAGS) $<",
85 	"\tmv y.tab.c $@",
86 
87 	".l.c :",
88 	"\t$(LEX) $(LFLAGS) $<",
89 	"\tmv lex.yy.c $@",
90 
91 	".yr.r:",
92 	"\t$(YACCR) $(YFLAGS) $<",
93 	"\tmv y.tab.r $@",
94 
95 	".ye.e :",
96 	"\t$(YACCE) $(YFLAGS) $<",
97 	"\tmv y.tab.e $@",
98 
99 #ifdef pwb
100 	".o.L .c.L .t.L:",
101 	"\t$(SCOMP) $(SCFLAGS) $<",
102 
103 	".t.o:",
104 	"\t$(SCOMP) $(SCFLAGS) -c $<",
105 
106 	".t.c:",
107 	"\t$(SCOMP) $(SCFLAGS) -t $<",
108 
109 	".h.z .t.z:",
110 	"\t$(CMDICT) $(CMFLAGS) $<",
111 
112 	".h.x .t.x:",
113 	"\t$(CMDICT) $(CMFLAGS) -c $<",
114 #endif
115 
116 	".s.out .c.out .o.out :",
117 	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
118 
119 	".f.out .F.out .r.out .e.out :",
120 	"\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
121 	"\t-rm $*.o",
122 
123 	".y.out :",
124 	"\t$(YACC) $(YFLAGS) $<",
125 	"\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
126 	"\trm y.tab.c",
127 
128 	".l.out :",
129 	"\t$(LEX) $(LFLAGS) $<",
130 	"\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
131 	"\trm lex.yy.c",
132 
133 	0 };
134 
135 #include "defs"
136 
137 
138 TIMETYPE exists(filename)
139 char *filename;
140 {
141 #include <sys/stat.h>
142 struct stat buf;
143 register char *s;
144 TIMETYPE lookarch();
145 
146 for(s = filename ; *s!='\0' && *s!='(' ; ++s)
147 	;
148 
149 if(*s == '(')
150 	return(lookarch(filename));
151 
152 if (stat(filename, &buf) < 0)
153 	return(0);
154 else	return(buf.st_mtime);
155 }
156 
157 
158 TIMETYPE prestime()
159 {
160 TIMETYPE t;
161 time(&t);
162 return(t);
163 }
164 
165 
166 
167 FSTATIC char nbuf[MAXNAMLEN + 1];
168 FSTATIC char *nbufend	= &nbuf[MAXNAMLEN];
169 
170 
171 
172 struct depblock *srchdir(pat, mkchain, nextdbl)
173 register char *pat; /* pattern to be matched in directory */
174 int mkchain;  /* nonzero if results to be remembered */
175 struct depblock *nextdbl;  /* final value for chain */
176 {
177 DIR *dirf;
178 register int i;
179 int nread, cldir;
180 char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
181 char fullname[100], *p1, *p2;
182 struct nameblock *q;
183 struct depblock *thisdbl;
184 struct dirhdr *od;
185 struct pattern *patp;
186 
187 struct direct *dptr;
188 
189 
190 thisdbl = 0;
191 
192 if(mkchain == NO)
193 	for(patp=firstpat ; patp ; patp = patp->nxtpattern)
194 		if(! unequal(pat, patp->patval)) return(0);
195 
196 patp = ALLOC(pattern);
197 patp->nxtpattern = firstpat;
198 firstpat = patp;
199 patp->patval = copys(pat);
200 
201 endir = 0;
202 
203 for(p=pat; *p!='\0'; ++p)
204 	if(*p=='/') endir = p;
205 
206 if(endir==0)
207 	{
208 	dirname = ".";
209 	dirpref = "";
210 	filepat = pat;
211 	}
212 else	{
213 	dirname = pat;
214 	*endir = '\0';
215 	dirpref = concat(dirname, "/", temp);
216 	filepat = endir+1;
217 	}
218 
219 dirf = NULL;
220 cldir = NO;
221 
222 for(od = firstod; od; od = od->nxtopendir)
223 	if(! unequal(dirname, od->dirn) )
224 		{
225 		dirf = od->dirfc;
226 		if (dirf != NULL)
227 			rewinddir(dirf); /* start over at the beginning  */
228 		break;
229 		}
230 
231 if(dirf == NULL)
232 	{
233 	dirf = opendir(dirname);
234 	if(nopdir >= MAXDIR)
235 		cldir = YES;
236 	else	{
237 		++nopdir;
238 		od = ALLOC(dirhdr);
239 		od->nxtopendir = firstod;
240 		firstod = od;
241 		od->dirfc = dirf;
242 		od->dirn = copys(dirname);
243 		fcntl(dirf->dd_fd, F_SETFD, 1);
244 		}
245 	}
246 
247 if(dirf == NULL)
248 	{
249 	fprintf(stderr, "Directory %s: ", dirname);
250 	fatal("Cannot open");
251 	}
252 
253 else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
254 	{
255 	p1 = dptr->d_name;
256 	p2 = nbuf;
257 	while( (p2<nbufend) && (*p2++ = *p1++)!='\0' )
258 		/* void */;
259 	if( amatch(nbuf,filepat) )
260 		{
261 		concat(dirpref,nbuf,fullname);
262 		if( (q=srchname(fullname)) ==0)
263 			q = makename(copys(fullname));
264 		if(mkchain)
265 			{
266 			thisdbl = ALLOC(depblock);
267 			thisdbl->nxtdepblock = nextdbl;
268 			thisdbl->depname = q;
269 			nextdbl = thisdbl;
270 			}
271 		}
272 	}
273 
274 if(endir != 0)  *endir = '/';
275 
276 if(cldir) {
277 	closedir(dirf);
278 	dirf = NULL;
279 }
280 return(thisdbl);
281 }
282 
283 /* stolen from glob through find */
284 
285 static amatch(s, p)
286 char *s, *p;
287 {
288 	register int cc, scc, k;
289 	int c, lc;
290 
291 	scc = *s;
292 	lc = 077777;
293 	switch (c = *p) {
294 
295 	case '[':
296 		k = 0;
297 		while (cc = *++p) {
298 			switch (cc) {
299 
300 			case ']':
301 				if (k)
302 					return(amatch(++s, ++p));
303 				else
304 					return(0);
305 
306 			case '-':
307 				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
308 			}
309 			if (scc==(lc=cc)) k++;
310 		}
311 		return(0);
312 
313 	case '?':
314 	caseq:
315 		if(scc) return(amatch(++s, ++p));
316 		return(0);
317 	case '*':
318 		return(umatch(s, ++p));
319 	case 0:
320 		return(!scc);
321 	}
322 	if (c==scc) goto caseq;
323 	return(0);
324 }
325 
326 static umatch(s, p)
327 char *s, *p;
328 {
329 	if(*p==0) return(1);
330 	while(*s)
331 		if (amatch(s++,p)) return(1);
332 	return(0);
333 }
334 
335 #ifdef METERFILE
336 #include <pwd.h>
337 int meteron	= 0;	/* default: metering off */
338 
339 meter(file)
340 char *file;
341 {
342 TIMETYPE tvec;
343 char *p, *ctime();
344 FILE * mout;
345 struct passwd *pwd, *getpwuid();
346 
347 if(file==0 || meteron==0) return;
348 
349 pwd = getpwuid(getuid());
350 
351 time(&tvec);
352 
353 if( (mout=fopen(file,"a")) != NULL )
354 	{
355 	p = ctime(&tvec);
356 	p[16] = '\0';
357 	fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
358 	fclose(mout);
359 	}
360 }
361 #endif
362 
363 
364 /* look inside archives for notations a(b) and a((b))
365 	a(b)	is file member   b   in archive a
366 	a((b))	is entry point  _b  in object archive a
367 */
368 
369 #ifdef ASCARCH
370 #	include <ar.h>
371 #else
372 #	include <ar.h>
373 #endif
374 #include <a.out.h>
375 
376 static long arflen;
377 static long arfdate;
378 static char arfname[16];
379 FILE *arfd;
380 long int arpos, arlen;
381 
382 static struct exec objhead;
383 
384 static struct nlist objentry;
385 
386 
387 TIMETYPE lookarch(filename)
388 char *filename;
389 {
390 char *p, *q, *send, s[MAXNAMLEN + 1];
391 int i, nc, nsym, objarch;
392 
393 for(p = filename; *p!= '(' ; ++p)
394 	;
395 *p = '\0';
396 openarch(filename);
397 *p++ = '(';
398 
399 if(*p == '(')
400 	{
401 	objarch = YES;
402 	nc = 8;
403 	++p;
404 	}
405 else
406 	{
407 	objarch = NO;
408 	nc = MAXNAMLEN;
409 	}
410 send = s + nc;
411 
412 for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
413 	;
414 while(q < send)
415 	*q++ = '\0';
416 while(getarch())
417 	{
418 	if(objarch)
419 		{
420 		getobj();
421 		nsym = objhead.a_syms / sizeof(objentry);
422 		for(i = 0; i<nsym ; ++i)
423 			{
424 			fread( (char *) &objentry, sizeof(objentry),1,arfd);
425 			if( (objentry.n_type & N_EXT)
426 			   && ((objentry.n_type & ~N_EXT) || objentry.n_value)
427 			   && eqstr(objentry.n_un.n_name,s,nc))
428 				{
429 				clarch();
430 				return(arfdate);
431 				}
432 			}
433 		}
434 
435 	else if( eqstr(arfname, s, nc))
436 		{
437 		clarch();
438 		return(arfdate);
439 		}
440 	}
441 
442 clarch();
443 return( 0L);
444 }
445 
446 
447 clarch()
448 {
449 fclose( arfd );
450 }
451 
452 
453 openarch(f)
454 register char *f;
455 {
456 #ifdef ASCARCH
457 char magic[SARMAG];
458 #endif
459 int word;
460 #include <sys/stat.h>
461 struct stat buf;
462 
463 stat(f, &buf);
464 arlen = buf.st_size;
465 
466 arfd = fopen(f, "r");
467 if(arfd == NULL)
468 	fatal1("cannot open %s", f);
469 
470 	fread( (char *) &word, sizeof(word), 1, arfd);
471 #ifdef ASCARCH
472 	fseek(arfd, 0L, 0);
473 	fread(magic, SARMAG, 1, arfd);
474 	arpos = SARMAG;
475 	if( ! eqstr(magic, ARMAG, SARMAG) )
476 #else
477 	arpos = sizeof(word);
478 	if(word != ARMAG)
479 #endif
480 		fatal1("%s is not an archive", f);
481 
482 arflen = 0;
483 }
484 
485 
486 
487 getarch()
488 {
489 	struct ar_hdr arhead;
490 	long atol();
491 
492 arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
493 if(arpos >= arlen)
494 	return(0);
495 fseek(arfd, arpos, 0);
496 
497 	fread( (char *) &arhead, sizeof(arhead), 1, arfd);
498 	arpos += sizeof(arhead);
499 #ifdef ASCARCH
500 	arflen = atol(arhead.ar_size);
501 	arfdate = atol(arhead.ar_date);
502 #else
503 	arflen = arhead.ar_size;
504 	arfdate = arhead.ar_date;
505 #endif
506 	strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
507 return(1);
508 }
509 
510 
511 getobj()
512 {
513 long int skip;
514 
515 fread( (char *) &objhead, sizeof(objhead), 1, arfd);
516 if (N_BADMAG(objhead))
517 	fatal1("%s is not an object module", arfname);
518 skip = objhead.a_text + objhead.a_data;
519 #if defined(vax) || defined(sun)
520 skip += objhead.a_trsize + objhead.a_drsize;
521 #else
522 if(! objhead.a_flag )
523 	skip *= 2;
524 #endif
525 fseek(arfd, skip, 1);
526 }
527 
528 
529 eqstr(a,b,n)
530 register char *a, *b;
531 int n;
532 {
533 register int i;
534 for(i = 0 ; i < n ; ++i)
535 	if(*a++ != *b++)
536 		return(NO);
537 return(YES);
538 }
539