add new directory access routines
[unix-history] / usr / src / old / make / files.c
CommitLineData
b342e078 1static char *sccsid = "@(#)files.c 4.4 (Berkeley) 82/04/20";
fbf6641c
BJ
2/* UNIX DEPENDENT PROCEDURES */
3
4
5/* DEFAULT RULES FOR UNIX */
6
7char *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=",
0609ddad 31 "FC=f77",
fbf6641c
BJ
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\f
133#include "defs"
fbf6641c
BJ
134
135
136TIMETYPE exists(filename)
137char *filename;
138{
139#include <sys/stat.h>
140struct stat buf;
141register char *s;
142TIMETYPE lookarch();
143
144for(s = filename ; *s!='\0' && *s!='(' ; ++s)
145 ;
146
147if(*s == '(')
148 return(lookarch(filename));
149
0b9fa52c
SL
150#if vax
151if (lstat(filename, &buf) < 0)
152#else
fbf6641c 153if(stat(filename,&buf) < 0)
0b9fa52c 154#endif
fbf6641c
BJ
155 return(0);
156else return(buf.st_mtime);
157}
158
159
160TIMETYPE prestime()
161{
162TIMETYPE t;
163time(&t);
164return(t);
165}
166
167\f
168
b342e078
KM
169FSTATIC char nbuf[MAXNAMLEN + 1];
170FSTATIC char *nbufend = &nbuf[MAXNAMLEN];
fbf6641c
BJ
171
172
173
174struct depblock *srchdir(pat, mkchain, nextdbl)
175register char *pat; /* pattern to be matched in directory */
176int mkchain; /* nonzero if results to be remembered */
177struct depblock *nextdbl; /* final value for chain */
178{
b342e078 179DIR *dirf;
fbf6641c
BJ
180register int i;
181int nread, cldir;
182char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
183char fullname[100], *p1, *p2;
184struct nameblock *q;
185struct depblock *thisdbl;
b342e078 186struct dirhdr *od;
fbf6641c
BJ
187struct pattern *patp;
188
b342e078 189struct direct *dptr;
fbf6641c
BJ
190
191
192thisdbl = 0;
193
194if(mkchain == NO)
195 for(patp=firstpat ; patp ; patp = patp->nxtpattern)
196 if(! unequal(pat, patp->patval)) return(0);
197
198patp = ALLOC(pattern);
199patp->nxtpattern = firstpat;
200firstpat = patp;
201patp->patval = copys(pat);
202
203endir = 0;
204
205for(p=pat; *p!='\0'; ++p)
206 if(*p=='/') endir = p;
207
208if(endir==0)
209 {
210 dirname = ".";
211 dirpref = "";
212 filepat = pat;
213 }
214else {
215 dirname = pat;
216 *endir = '\0';
217 dirpref = concat(dirname, "/", temp);
218 filepat = endir+1;
219 }
220
221dirf = NULL;
222cldir = NO;
223
224for(od = firstod; od; od = od->nxtopendir)
225 if(! unequal(dirname, od->dirn) )
226 {
227 dirf = od->dirfc;
b342e078
KM
228 if (dirf != NULL)
229 rewinddir(dirf); /* start over at the beginning */
fbf6641c
BJ
230 break;
231 }
232
233if(dirf == NULL)
234 {
b342e078 235 dirf = opendir(dirname);
fbf6641c
BJ
236 if(nopdir >= MAXDIR)
237 cldir = YES;
238 else {
239 ++nopdir;
b342e078 240 od = ALLOC(dirhdr);
fbf6641c
BJ
241 od->nxtopendir = firstod;
242 firstod = od;
243 od->dirfc = dirf;
244 od->dirn = copys(dirname);
245 }
246 }
247
248if(dirf == NULL)
249 {
250 fprintf(stderr, "Directory %s: ", dirname);
251 fatal("Cannot open");
252 }
253
b342e078 254else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
fbf6641c 255 {
b342e078
KM
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)
fbf6641c 266 {
b342e078
KM
267 thisdbl = ALLOC(depblock);
268 thisdbl->nxtdepblock = nextdbl;
269 thisdbl->depname = q;
270 nextdbl = thisdbl;
fbf6641c 271 }
b342e078
KM
272 }
273 }
fbf6641c
BJ
274
275if(endir != 0) *endir = '/';
276
b342e078
KM
277if(cldir) {
278 closedir(dirf);
279 dirf = NULL;
280}
fbf6641c
BJ
281return(thisdbl);
282}
283\f
284/* stolen from glob through find */
285
286static amatch(s, p)
287char *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
327static umatch(s, p)
328char *s, *p;
329{
330 if(*p==0) return(1);
331 while(*s)
332 if (amatch(s++,p)) return(1);
333 return(0);
334}
335\f
336#ifdef METERFILE
337#include <pwd.h>
338int meteron = 0; /* default: metering off */
339
340meter(file)
341char *file;
342{
343TIMETYPE tvec;
344char *p, *ctime();
345FILE * mout;
346struct passwd *pwd, *getpwuid();
347
348if(file==0 || meteron==0) return;
349
350pwd = getpwuid(getuid());
351
352time(&tvec);
353
354if( (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\f
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
377static long arflen;
378static long arfdate;
379static char arfname[16];
380FILE *arfd;
381long int arpos, arlen;
382
383static struct exec objhead;
384
385static struct nlist objentry;
386
387
388TIMETYPE lookarch(filename)
389char *filename;
390{
b342e078 391char *p, *q, *send, s[MAXNAMLEN + 1];
fbf6641c
BJ
392int i, nc, nsym, objarch;
393
394for(p = filename; *p!= '(' ; ++p)
395 ;
396*p = '\0';
397openarch(filename);
398*p++ = '(';
399
400if(*p == '(')
401 {
402 objarch = YES;
403 nc = 8;
404 ++p;
405 }
406else
407 {
408 objarch = NO;
b342e078 409 nc = MAXNAMLEN;
fbf6641c
BJ
410 }
411send = s + nc;
412
413for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
414 ;
415while(q < send)
416 *q++ = '\0';
417while(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
443clarch();
444return( 0L);
445}
446
447
448clarch()
449{
450fclose( arfd );
451}
452
453
454openarch(f)
455register char *f;
456{
457#ifdef ASCARCH
458char magic[SARMAG];
459#endif
460int word;
461#include <sys/stat.h>
462struct stat buf;
463
0b9fa52c
SL
464#if vax
465lstat(f, &buf);
466#else
fbf6641c 467stat(f, &buf);
0b9fa52c 468#endif
fbf6641c
BJ
469arlen = buf.st_size;
470
471arfd = fopen(f, "r");
472if(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
487arflen = 0;
488}
489
490
491
492getarch()
493{
494 struct ar_hdr arhead;
495 long atol();
496
497arpos += (arflen + 1) & ~1L; /* round archived file length up to even */
498if(arpos >= arlen)
499 return(0);
500fseek(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));
512return(1);
513}
514
515
516getobj()
517{
518long int skip;
519
520fread( (char *) &objhead, sizeof(objhead), 1, arfd);
521if (N_BADMAG(objhead))
522 fatal1("%s is not an object module", arfname);
523skip = objhead.a_text + objhead.a_data;
524#ifdef vax
525skip += objhead.a_trsize + objhead.a_drsize;
526#else
527if(! objhead.a_flag )
528 skip *= 2;
529#endif
530fseek(arfd, skip, 1);
531}
532
533
534eqstr(a,b,n)
535register char *a, *b;
536int n;
537{
538register int i;
539for(i = 0 ; i < n ; ++i)
540 if(*a++ != *b++)
541 return(NO);
542return(YES);
543}