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