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