xref: /original-bsd/old/make/files.c (revision 6c57d260)
1 static	char *sccsid = "@(#)files.c	4.2 (Berkeley) 81/02/28";
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 #include <sys/types.h>
135 
136 
137 TIMETYPE exists(filename)
138 char *filename;
139 {
140 #include <sys/stat.h>
141 struct stat buf;
142 register char *s;
143 TIMETYPE lookarch();
144 
145 for(s = filename ; *s!='\0' && *s!='(' ; ++s)
146 	;
147 
148 if(*s == '(')
149 	return(lookarch(filename));
150 
151 if(stat(filename,&buf) < 0)
152 	return(0);
153 else	return(buf.st_mtime);
154 }
155 
156 
157 TIMETYPE prestime()
158 {
159 TIMETYPE t;
160 time(&t);
161 return(t);
162 }
163 
164 
165 
166 #include <sys/dir.h>
167 FSTATIC char n15[15];
168 FSTATIC char *n15end	= &n15[14];
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 FILE * 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 opendir *od;
185 struct pattern *patp;
186 
187 struct direct entry[32];
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 		fseek(dirf, 0L, 0); /* start over at the beginning  */
227 		break;
228 		}
229 
230 if(dirf == NULL)
231 	{
232 	dirf = fopen(dirname, "r");
233 	if(nopdir >= MAXDIR)
234 		cldir = YES;
235 	else	{
236 		++nopdir;
237 		od = ALLOC(opendir);
238 		od->nxtopendir = firstod;
239 		firstod = od;
240 		od->dirfc = dirf;
241 		od->dirn = copys(dirname);
242 		}
243 	}
244 
245 if(dirf == NULL)
246 	{
247 	fprintf(stderr, "Directory %s: ", dirname);
248 	fatal("Cannot open");
249 	}
250 
251 else do
252 	{
253 	nread = fread( (char *) &entry[0], sizeof(struct direct), 32, dirf) ;
254 	for(i=0; i<nread; ++i)
255 		if(entry[i].d_ino!= 0)
256 			{
257 			p1 = entry[i].d_name;
258 			p2 = n15;
259 			while( (p2<n15end) &&
260 			  (*p2++ = *p1++)!='\0' );
261 			if( amatch(n15,filepat) )
262 				{
263 				concat(dirpref,n15,fullname);
264 				if( (q=srchname(fullname)) ==0)
265 					q = makename(copys(fullname));
266 				if(mkchain)
267 					{
268 					thisdbl = ALLOC(depblock);
269 					thisdbl->nxtdepblock = nextdbl;
270 					thisdbl->depname = q;
271 					nextdbl = thisdbl;
272 					}
273 				}
274 			}
275 
276 	} while(nread==32);
277 
278 if(endir != 0)  *endir = '/';
279 
280 if(cldir)
281 	fclose(dirf);
282 return(thisdbl);
283 }
284 
285 /* stolen from glob through find */
286 
287 static amatch(s, p)
288 char *s, *p;
289 {
290 	register int cc, scc, k;
291 	int c, lc;
292 
293 	scc = *s;
294 	lc = 077777;
295 	switch (c = *p) {
296 
297 	case '[':
298 		k = 0;
299 		while (cc = *++p) {
300 			switch (cc) {
301 
302 			case ']':
303 				if (k)
304 					return(amatch(++s, ++p));
305 				else
306 					return(0);
307 
308 			case '-':
309 				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
310 			}
311 			if (scc==(lc=cc)) k++;
312 		}
313 		return(0);
314 
315 	case '?':
316 	caseq:
317 		if(scc) return(amatch(++s, ++p));
318 		return(0);
319 	case '*':
320 		return(umatch(s, ++p));
321 	case 0:
322 		return(!scc);
323 	}
324 	if (c==scc) goto caseq;
325 	return(0);
326 }
327 
328 static umatch(s, p)
329 char *s, *p;
330 {
331 	if(*p==0) return(1);
332 	while(*s)
333 		if (amatch(s++,p)) return(1);
334 	return(0);
335 }
336 
337 #ifdef METERFILE
338 #include <pwd.h>
339 int meteron	= 0;	/* default: metering off */
340 
341 meter(file)
342 char *file;
343 {
344 TIMETYPE tvec;
345 char *p, *ctime();
346 FILE * mout;
347 struct passwd *pwd, *getpwuid();
348 
349 if(file==0 || meteron==0) return;
350 
351 pwd = getpwuid(getuid());
352 
353 time(&tvec);
354 
355 if( (mout=fopen(file,"a")) != NULL )
356 	{
357 	p = ctime(&tvec);
358 	p[16] = '\0';
359 	fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
360 	fclose(mout);
361 	}
362 }
363 #endif
364 
365 
366 /* look inside archives for notations a(b) and a((b))
367 	a(b)	is file member   b   in archive a
368 	a((b))	is entry point  _b  in object archive a
369 */
370 
371 #ifdef ASCARCH
372 #	include <ar.h>
373 #else
374 #	include <ar.h>
375 #endif
376 #include <a.out.h>
377 
378 static long arflen;
379 static long arfdate;
380 static char arfname[16];
381 FILE *arfd;
382 long int arpos, arlen;
383 
384 static struct exec objhead;
385 
386 static struct nlist objentry;
387 
388 
389 TIMETYPE lookarch(filename)
390 char *filename;
391 {
392 char *p, *q, *send, s[15];
393 int i, nc, nsym, objarch;
394 
395 for(p = filename; *p!= '(' ; ++p)
396 	;
397 *p = '\0';
398 openarch(filename);
399 *p++ = '(';
400 
401 if(*p == '(')
402 	{
403 	objarch = YES;
404 	nc = 8;
405 	++p;
406 	}
407 else
408 	{
409 	objarch = NO;
410 	nc = 14;
411 	}
412 send = s + nc;
413 
414 for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
415 	;
416 while(q < send)
417 	*q++ = '\0';
418 while(getarch())
419 	{
420 	if(objarch)
421 		{
422 		getobj();
423 		nsym = objhead.a_syms / sizeof(objentry);
424 		for(i = 0; i<nsym ; ++i)
425 			{
426 			fread( (char *) &objentry, sizeof(objentry),1,arfd);
427 			if( (objentry.n_type & N_EXT)
428 			   && ((objentry.n_type & ~N_EXT) || objentry.n_value)
429 			   && eqstr(objentry.n_un.n_name,s,nc))
430 				{
431 				clarch();
432 				return(arfdate);
433 				}
434 			}
435 		}
436 
437 	else if( eqstr(arfname, s, nc))
438 		{
439 		clarch();
440 		return(arfdate);
441 		}
442 	}
443 
444 clarch();
445 return( 0L);
446 }
447 
448 
449 clarch()
450 {
451 fclose( arfd );
452 }
453 
454 
455 openarch(f)
456 register char *f;
457 {
458 #ifdef ASCARCH
459 char magic[SARMAG];
460 #endif
461 int word;
462 #include <sys/stat.h>
463 struct stat buf;
464 
465 stat(f, &buf);
466 arlen = buf.st_size;
467 
468 arfd = fopen(f, "r");
469 if(arfd == NULL)
470 	fatal1("cannot open %s", f);
471 
472 	fread( (char *) &word, sizeof(word), 1, arfd);
473 #ifdef ASCARCH
474 	fseek(arfd, 0L, 0);
475 	fread(magic, SARMAG, 1, arfd);
476 	arpos = SARMAG;
477 	if( ! eqstr(magic, ARMAG, SARMAG) )
478 #else
479 	arpos = sizeof(word);
480 	if(word != ARMAG)
481 #endif
482 		fatal1("%s is not an archive", f);
483 
484 arflen = 0;
485 }
486 
487 
488 
489 getarch()
490 {
491 	struct ar_hdr arhead;
492 	long atol();
493 
494 arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
495 if(arpos >= arlen)
496 	return(0);
497 fseek(arfd, arpos, 0);
498 
499 	fread( (char *) &arhead, sizeof(arhead), 1, arfd);
500 	arpos += sizeof(arhead);
501 #ifdef ASCARCH
502 	arflen = atol(arhead.ar_size);
503 	arfdate = atol(arhead.ar_date);
504 #else
505 	arflen = arhead.ar_size;
506 	arfdate = arhead.ar_date;
507 #endif
508 	strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
509 return(1);
510 }
511 
512 
513 getobj()
514 {
515 long int skip;
516 
517 fread( (char *) &objhead, sizeof(objhead), 1, arfd);
518 if (N_BADMAG(objhead))
519 	fatal1("%s is not an object module", arfname);
520 skip = objhead.a_text + objhead.a_data;
521 #ifdef vax
522 skip += objhead.a_trsize + objhead.a_drsize;
523 #else
524 if(! objhead.a_flag )
525 	skip *= 2;
526 #endif
527 fseek(arfd, skip, 1);
528 }
529 
530 
531 eqstr(a,b,n)
532 register char *a, *b;
533 int n;
534 {
535 register int i;
536 for(i = 0 ; i < n ; ++i)
537 	if(*a++ != *b++)
538 		return(NO);
539 return(YES);
540 }
541