disallow unlink of directory which will succeed if use is root
[unix-history] / usr / src / old / make / files.c
CommitLineData
824d99d6 1static char *sccsid = "@(#)files.c 4.6 (Berkeley) 83/02/09";
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",
824d99d6 21#if defined(vax) || defined(sun)
fbf6641c
BJ
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
0e7207aa 150if (stat(filename, &buf) < 0)
fbf6641c
BJ
151 return(0);
152else return(buf.st_mtime);
153}
154
155
156TIMETYPE prestime()
157{
158TIMETYPE t;
159time(&t);
160return(t);
161}
162
163\f
164
b342e078
KM
165FSTATIC char nbuf[MAXNAMLEN + 1];
166FSTATIC char *nbufend = &nbuf[MAXNAMLEN];
fbf6641c
BJ
167
168
169
170struct depblock *srchdir(pat, mkchain, nextdbl)
171register char *pat; /* pattern to be matched in directory */
172int mkchain; /* nonzero if results to be remembered */
173struct depblock *nextdbl; /* final value for chain */
174{
b342e078 175DIR *dirf;
fbf6641c
BJ
176register int i;
177int nread, cldir;
178char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
179char fullname[100], *p1, *p2;
180struct nameblock *q;
181struct depblock *thisdbl;
b342e078 182struct dirhdr *od;
fbf6641c
BJ
183struct pattern *patp;
184
b342e078 185struct direct *dptr;
fbf6641c
BJ
186
187
188thisdbl = 0;
189
190if(mkchain == NO)
191 for(patp=firstpat ; patp ; patp = patp->nxtpattern)
192 if(! unequal(pat, patp->patval)) return(0);
193
194patp = ALLOC(pattern);
195patp->nxtpattern = firstpat;
196firstpat = patp;
197patp->patval = copys(pat);
198
199endir = 0;
200
201for(p=pat; *p!='\0'; ++p)
202 if(*p=='/') endir = p;
203
204if(endir==0)
205 {
206 dirname = ".";
207 dirpref = "";
208 filepat = pat;
209 }
210else {
211 dirname = pat;
212 *endir = '\0';
213 dirpref = concat(dirname, "/", temp);
214 filepat = endir+1;
215 }
216
217dirf = NULL;
218cldir = NO;
219
220for(od = firstod; od; od = od->nxtopendir)
221 if(! unequal(dirname, od->dirn) )
222 {
223 dirf = od->dirfc;
b342e078
KM
224 if (dirf != NULL)
225 rewinddir(dirf); /* start over at the beginning */
fbf6641c
BJ
226 break;
227 }
228
229if(dirf == NULL)
230 {
b342e078 231 dirf = opendir(dirname);
fbf6641c
BJ
232 if(nopdir >= MAXDIR)
233 cldir = YES;
234 else {
235 ++nopdir;
b342e078 236 od = ALLOC(dirhdr);
fbf6641c
BJ
237 od->nxtopendir = firstod;
238 firstod = od;
239 od->dirfc = dirf;
240 od->dirn = copys(dirname);
241 }
242 }
243
244if(dirf == NULL)
245 {
246 fprintf(stderr, "Directory %s: ", dirname);
247 fatal("Cannot open");
248 }
249
b342e078 250else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
fbf6641c 251 {
b342e078
KM
252 p1 = dptr->d_name;
253 p2 = nbuf;
254 while( (p2<nbufend) && (*p2++ = *p1++)!='\0' )
255 /* void */;
256 if( amatch(nbuf,filepat) )
257 {
258 concat(dirpref,nbuf,fullname);
259 if( (q=srchname(fullname)) ==0)
260 q = makename(copys(fullname));
261 if(mkchain)
fbf6641c 262 {
b342e078
KM
263 thisdbl = ALLOC(depblock);
264 thisdbl->nxtdepblock = nextdbl;
265 thisdbl->depname = q;
266 nextdbl = thisdbl;
fbf6641c 267 }
b342e078
KM
268 }
269 }
fbf6641c
BJ
270
271if(endir != 0) *endir = '/';
272
b342e078
KM
273if(cldir) {
274 closedir(dirf);
275 dirf = NULL;
276}
fbf6641c
BJ
277return(thisdbl);
278}
279\f
280/* stolen from glob through find */
281
282static amatch(s, p)
283char *s, *p;
284{
285 register int cc, scc, k;
286 int c, lc;
287
288 scc = *s;
289 lc = 077777;
290 switch (c = *p) {
291
292 case '[':
293 k = 0;
294 while (cc = *++p) {
295 switch (cc) {
296
297 case ']':
298 if (k)
299 return(amatch(++s, ++p));
300 else
301 return(0);
302
303 case '-':
304 k |= (lc <= scc) & (scc <= (cc=p[1]) ) ;
305 }
306 if (scc==(lc=cc)) k++;
307 }
308 return(0);
309
310 case '?':
311 caseq:
312 if(scc) return(amatch(++s, ++p));
313 return(0);
314 case '*':
315 return(umatch(s, ++p));
316 case 0:
317 return(!scc);
318 }
319 if (c==scc) goto caseq;
320 return(0);
321}
322
323static umatch(s, p)
324char *s, *p;
325{
326 if(*p==0) return(1);
327 while(*s)
328 if (amatch(s++,p)) return(1);
329 return(0);
330}
331\f
332#ifdef METERFILE
333#include <pwd.h>
334int meteron = 0; /* default: metering off */
335
336meter(file)
337char *file;
338{
339TIMETYPE tvec;
340char *p, *ctime();
341FILE * mout;
342struct passwd *pwd, *getpwuid();
343
344if(file==0 || meteron==0) return;
345
346pwd = getpwuid(getuid());
347
348time(&tvec);
349
350if( (mout=fopen(file,"a")) != NULL )
351 {
352 p = ctime(&tvec);
353 p[16] = '\0';
354 fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
355 fclose(mout);
356 }
357}
358#endif
359\f
360
361/* look inside archives for notations a(b) and a((b))
362 a(b) is file member b in archive a
363 a((b)) is entry point _b in object archive a
364*/
365
366#ifdef ASCARCH
367# include <ar.h>
368#else
369# include <ar.h>
370#endif
371#include <a.out.h>
372
373static long arflen;
374static long arfdate;
375static char arfname[16];
376FILE *arfd;
377long int arpos, arlen;
378
379static struct exec objhead;
380
381static struct nlist objentry;
382
383
384TIMETYPE lookarch(filename)
385char *filename;
386{
b342e078 387char *p, *q, *send, s[MAXNAMLEN + 1];
fbf6641c
BJ
388int i, nc, nsym, objarch;
389
390for(p = filename; *p!= '(' ; ++p)
391 ;
392*p = '\0';
393openarch(filename);
394*p++ = '(';
395
396if(*p == '(')
397 {
398 objarch = YES;
399 nc = 8;
400 ++p;
401 }
402else
403 {
404 objarch = NO;
b342e078 405 nc = MAXNAMLEN;
fbf6641c
BJ
406 }
407send = s + nc;
408
409for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
410 ;
411while(q < send)
412 *q++ = '\0';
413while(getarch())
414 {
415 if(objarch)
416 {
417 getobj();
418 nsym = objhead.a_syms / sizeof(objentry);
419 for(i = 0; i<nsym ; ++i)
420 {
421 fread( (char *) &objentry, sizeof(objentry),1,arfd);
422 if( (objentry.n_type & N_EXT)
423 && ((objentry.n_type & ~N_EXT) || objentry.n_value)
424 && eqstr(objentry.n_un.n_name,s,nc))
425 {
426 clarch();
427 return(arfdate);
428 }
429 }
430 }
431
432 else if( eqstr(arfname, s, nc))
433 {
434 clarch();
435 return(arfdate);
436 }
437 }
438
439clarch();
440return( 0L);
441}
442
443
444clarch()
445{
446fclose( arfd );
447}
448
449
450openarch(f)
451register char *f;
452{
453#ifdef ASCARCH
454char magic[SARMAG];
455#endif
456int word;
457#include <sys/stat.h>
458struct stat buf;
459
460stat(f, &buf);
461arlen = buf.st_size;
462
463arfd = fopen(f, "r");
464if(arfd == NULL)
465 fatal1("cannot open %s", f);
466
467 fread( (char *) &word, sizeof(word), 1, arfd);
468#ifdef ASCARCH
469 fseek(arfd, 0L, 0);
470 fread(magic, SARMAG, 1, arfd);
471 arpos = SARMAG;
472 if( ! eqstr(magic, ARMAG, SARMAG) )
473#else
474 arpos = sizeof(word);
475 if(word != ARMAG)
476#endif
477 fatal1("%s is not an archive", f);
478
479arflen = 0;
480}
481
482
483
484getarch()
485{
486 struct ar_hdr arhead;
487 long atol();
488
489arpos += (arflen + 1) & ~1L; /* round archived file length up to even */
490if(arpos >= arlen)
491 return(0);
492fseek(arfd, arpos, 0);
493
494 fread( (char *) &arhead, sizeof(arhead), 1, arfd);
495 arpos += sizeof(arhead);
496#ifdef ASCARCH
497 arflen = atol(arhead.ar_size);
498 arfdate = atol(arhead.ar_date);
499#else
500 arflen = arhead.ar_size;
501 arfdate = arhead.ar_date;
502#endif
503 strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
504return(1);
505}
506
507
508getobj()
509{
510long int skip;
511
512fread( (char *) &objhead, sizeof(objhead), 1, arfd);
513if (N_BADMAG(objhead))
514 fatal1("%s is not an object module", arfname);
515skip = objhead.a_text + objhead.a_data;
824d99d6 516#if defined(vax) || defined(sun)
fbf6641c
BJ
517skip += objhead.a_trsize + objhead.a_drsize;
518#else
519if(! objhead.a_flag )
520 skip *= 2;
521#endif
522fseek(arfd, skip, 1);
523}
524
525
526eqstr(a,b,n)
527register char *a, *b;
528int n;
529{
530register int i;
531for(i = 0 ; i < n ; ++i)
532 if(*a++ != *b++)
533 return(NO);
534return(YES);
535}