|
|
1.1 root 1: /* @(#)/usr/src/cmd/make/files.c 3.4 */
2:
3: #include "defs"
4: #include <sys/types.h>
5: #include <sys/stat.h>
6: #include <sys/dir.h>
7: #include <pwd.h>
8: #include <ar.h>
9: #include <a.out.h>
10: /* UNIX DEPENDENT PROCEDURES */
11:
12:
13: char archmem[16];
14: char archname[64]; /* name of archive library */
15:
16:
17: TIMETYPE exists(pname)
18: NAMEBLOCK pname;
19: {
20: register CHARSTAR s;
21: struct stat buf;
22: TIMETYPE lookarch();
23: CHARSTAR filename;
24:
25: filename = pname->namep;
26:
27: if(any(filename, LPAREN))
28: return(lookarch(filename));
29:
30: if(stat(filename,&buf) < 0)
31: {
32: s = findfl(filename);
33: if(s != (CHARSTAR )-1)
34: {
35: pname->alias = copys(s);
36: if(stat(pname->alias, &buf) == 0)
37: return(buf.st_mtime);
38: }
39: return(0);
40: }
41: else
42: return(buf.st_mtime);
43: }
44:
45:
46: TIMETYPE prestime()
47: {
48: TIMETYPE t;
49: time(&t);
50: return(t);
51: }
52:
53:
54:
55: FSTATIC char n15[15];
56: FSTATIC CHARSTAR n15end = &n15[14];
57:
58:
59:
60: DEPBLOCK srchdir(pat, mkchain, nextdbl)
61: register CHARSTAR pat; /* pattern to be matched in directory */
62: int mkchain; /* nonzero if results to be remembered */
63: DEPBLOCK nextdbl; /* final value for chain */
64: {
65: FILE * dirf;
66: int i, nread;
67: CHARSTAR dirname, dirpref, endir, filepat, p;
68: char temp[100];
69: char fullname[100];
70: CHARSTAR p1, p2;
71: NAMEBLOCK q;
72: DEPBLOCK thisdbl;
73: OPENDIR od;
74: int dirofl = 0;
75: static opendirs = 0;
76: PATTERN patp;
77:
78: struct direct entry[32];
79:
80:
81: thisdbl = 0;
82:
83: if(mkchain == NO)
84: for(patp=firstpat ; patp!=0 ; patp = patp->nextpattern)
85: if(equal(pat,patp->patval))
86: return(0);
87:
88: patp = ALLOC(pattern);
89: patp->nextpattern = firstpat;
90: firstpat = patp;
91: patp->patval = copys(pat);
92:
93: endir = 0;
94:
95: for(p=pat; *p!=CNULL; ++p)
96: if(*p==SLASH)
97: endir = p;
98:
99: if(endir==0)
100: {
101: dirname = ".";
102: dirpref = "";
103: filepat = pat;
104: }
105: else
106: {
107: *endir = CNULL;
108: dirpref = concat(pat, "/", temp);
109: filepat = endir+1;
110: dirname = temp;
111: }
112:
113: dirf = NULL;
114:
115: for(od=firstod ; od!=0; od = od->nextopendir)
116: if(equal(dirname, od->dirn))
117: {
118: dirf = od->dirfc;
119: fseek(dirf,0L,0); /* start over at the beginning */
120: break;
121: }
122:
123: if(dirf == NULL)
124: {
125: dirf = fopen(dirname, "r");
126: if(++opendirs < MAXODIR)
127: {
128: od = ALLOC(opendir);
129: od->nextopendir = firstod;
130: firstod = od;
131: od->dirfc = dirf;
132: od->dirn = copys(dirname);
133: }
134: else
135: dirofl = 1;
136: }
137:
138: if(dirf == NULL)
139: {
140: fprintf(stderr, "Directory %s: ", dirname);
141: fatal("Cannot open");
142: }
143:
144: else do
145: {
146: nread = fread(entry,sizeof(entry[0]),32,dirf) ;
147: for(i=0; i<nread; ++i)
148: if(entry[i].d_ino!= 0)
149: {
150: p1 = entry[i].d_name;
151: p2 = n15;
152: while( (p2<n15end) &&
153: (*p2++ = *p1++)!=CNULL );
154: if( amatch(n15,filepat) )
155: {
156: concat(dirpref,n15,fullname);
157: if( (q=srchname(fullname)) ==0)
158: q = makename(copys(fullname));
159: if(mkchain)
160: {
161: thisdbl = ALLOC(depblock);
162: thisdbl->nextdep = nextdbl;
163: thisdbl->depname = q;
164: nextdbl = thisdbl;
165: }
166: }
167: }
168: } while(nread==32);
169:
170: if(endir != 0)
171: *endir = SLASH;
172: if(dirofl)
173: fclose(dirf);
174:
175: return(thisdbl);
176: }
177:
178: /* stolen from glob through find */
179:
180: amatch(s, p)
181: CHARSTAR s, p;
182: {
183: register int cc, scc, k;
184: int c, lc;
185:
186: scc = *s;
187: lc = 077777;
188: switch (c = *p)
189: {
190:
191: case LSQUAR:
192: k = 0;
193: while (cc = *++p)
194: {
195: switch (cc)
196: {
197:
198: case RSQUAR:
199: if (k)
200: return(amatch(++s, ++p));
201: else
202: return(0);
203:
204: case MINUS:
205: k |= lc <= scc & scc <= (cc=p[1]);
206: }
207: if(scc==(lc=cc))
208: k++;
209: }
210: return(0);
211:
212: case QUESTN:
213: caseq:
214: if(scc)
215: return(amatch(++s, ++p));
216: return(0);
217: case STAR:
218: return(umatch(s, ++p));
219: case 0:
220: return(!scc);
221: }
222: if(c==scc)
223: goto caseq;
224: return(0);
225: }
226:
227: umatch(s, p)
228: register CHARSTAR s, p;
229: {
230: if(*p==0)
231: return(1);
232: while(*s)
233: if(amatch(s++,p))
234: return(1);
235: return(0);
236: }
237:
238: #ifdef METERFILE
239: int meteron 0; /* default: metering off */
240:
241: meter(file)
242: CHARSTAR file;
243: {
244: TIMETYPE tvec;
245: CHARSTAR p, ctime();
246: FILE * mout;
247: struct passwd *pwd, *getpwuid();
248:
249: if(file==0 || meteron==0)
250: return;
251:
252: pwd = getpwuid(getuid());
253:
254: time(&tvec);
255:
256: if( (mout=fopen(file,"a")) != NULL )
257: {
258: p = ctime(&tvec);
259: p[16] = CNULL;
260: fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
261: fclose(mout);
262: }
263: }
264: #endif
265:
266:
267: /* look inside archives for notations a(b) and a((b))
268: a(b) is file member b in archive a
269: a((b)) is entry point _b in object archive a
270: */
271:
272: static struct ar_hdr arhead;
273: FILE *arfd;
274: long int arpos, arlen;
275:
276: static struct exec objhead;
277:
278: static struct nlist objentry;
279:
280:
281: TIMETYPE lookarch(filename)
282: register CHARSTAR filename;
283: {
284: register int i;
285: CHARSTAR p, q, send;
286: char s[15];
287: int nc, nsym, objarch;
288:
289: for(p = filename; *p!= LPAREN ; ++p);
290: q = p++;
291:
292: if(*p == LPAREN)
293: {
294: objarch = YES;
295: nc = 8;
296: ++p;
297: }
298: else
299: {
300: objarch = NO;
301: nc = 14;
302: for(i = 0; i < 14; i++)
303: {
304: if(p[i] == RPAREN)
305: {
306: i--;
307: break;
308: }
309: archmem[i] = p[i];
310: }
311: archmem[++i] = 0;
312: if(archmem[0] == CNULL)
313: fatal1("Null archive member name `%s'", filename);
314: }
315: *q = CNULL;
316: copstr(archname, filename);
317: if(archname[0] == CNULL)
318: fatal1("Null archive name `%s'", archmem);
319: i = openarch(filename);
320: *q = LPAREN;
321: if(i == -1)
322: return(0);
323: send = s + nc;
324:
325: for( q = s ; q<send && *p!=CNULL && *p!=RPAREN ; *q++ = *p++ );
326:
327: while(q < send)
328: *q++ = CNULL;
329: while(getarch())
330: {
331: if(objarch)
332: {
333: getobj();
334: nsym = objhead.a_syms / sizeof(objentry);
335: for(i = 0; i<nsym ; ++i)
336: {
337: fread(&objentry, sizeof(objentry),1,arfd);
338: if( (objentry.n_type & N_EXT)
339: && eqstr(objentry.n_name,s,nc))
340: {
341: for(i = 0; i < 14; i++)
342: archmem[i] = arhead.ar_name[i];
343: archmem[++i] = 0;
344: out:
345: clarch();
346: return(arhead.ar_date);
347: }
348: }
349: }
350:
351: else if( eqstr(arhead.ar_name, s, nc))
352: goto out;
353: }
354:
355: clarch();
356: return( 0L);
357: }
358:
359:
360: clarch()
361: {
362: fclose( arfd );
363: }
364:
365:
366: openarch(f)
367: register CHARSTAR f;
368: {
369: int word = 0;
370: struct stat buf;
371:
372: if(stat(f, &buf) == -1)
373: return(-1);
374: arlen = buf.st_size;
375:
376: arfd = fopen(f, "r");
377: if(arfd == NULL)
378: return(-1);
379: fread(&word, sizeof(word), 1, arfd);
380: if(word != ARMAG)
381: fatal1("%s is not an archive", f);
382: /*
383: * trick getarch() into jumping to the first archive member.
384: */
385: arpos = sizeof(word);
386: arhead.ar_size = -(int)sizeof(arhead);
387: return(0);
388: }
389:
390:
391:
392: getarch()
393: {
394: arpos += sizeof(arhead);
395: arpos += (arhead.ar_size + 1 ) & ~1L;
396: if(arpos >= arlen)
397: return(0);
398: fseek(arfd, arpos, 0);
399: fread(&arhead, sizeof(arhead), 1, arfd);
400: return(1);
401: }
402:
403:
404: getobj()
405: {
406: long int skip;
407:
408: fread(&objhead, sizeof(objhead), 1, arfd);
409: /*
410: if( objhead.a_magic != A_MAGIC1 &&
411: objhead.a_magic != A_MAGIC2 &&
412: objhead.a_magic != A_MAGIC3 )
413: fatal1("%s is not an object module", arhead.ar_name);
414: */
415: skip = objhead.a_text + objhead.a_data;
416: #if vax || u370
417: skip += objhead.a_trsize + objhead.a_drsize;
418: #else
419: if(! objhead.a_flag )
420: skip *= 2;
421: #endif
422: fseek(arfd, skip, 1);
423: }
424:
425:
426: eqstr(a,b,n)
427: register CHARSTAR a, b;
428: register int n;
429: {
430: register int i;
431: for(i = 0 ; i < n ; ++i)
432: if(*a++ != *b++)
433: return(NO);
434: return(YES);
435: }
436: /*
437: * Used when unlinking files. If file cannot be stat'ed or it is
438: * a directory, then do not remove it.
439: */
440: isdir(p)
441: char *p;
442: {
443: struct stat statbuf;
444:
445: if(stat(p, &statbuf) == -1)
446: return(1); /* no stat, no remove */
447: if((statbuf.st_mode&S_IFMT) == S_IFDIR)
448: return(1);
449: return(0);
450: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.