|
|
1.1 root 1: static char *sccsid = "@(#)files.c 4.17 (Berkeley) 87/12/21";
2: #include <fcntl.h>
3:
4: /* UNIX DEPENDENT PROCEDURES */
5:
6:
7: /* DEFAULT RULES FOR UNIX */
8:
9: char *builtin[] =
10: {
11: #ifdef pwb
12: ".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
13: #else
14: ".SUFFIXES : .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p",
15: #endif
16: "YACC=yacc",
17: "YACCR=yacc -r",
18: "YACCE=yacc -e",
19: "YFLAGS=",
20: "LEX=lex",
21: "LFLAGS=",
22: "CC=cc",
23: #if defined(vax) || defined(sun) || defined(tahoe)
24: "AS=as",
25: #else
26: "AS=as -",
27: #endif
28: "PC=pc",
29: "PFLAGS=",
30: "CFLAGS=",
31: "RC=f77",
32: "RFLAGS=",
33: "FC=f77",
34: "EFLAGS=",
35: "FFLAGS=",
36: "LOADLIBES=",
37: #ifdef pwb
38: "SCOMP=scomp",
39: "SCFLAGS=",
40: "CMDICT=cmdict",
41: "CMFLAGS=",
42: #endif
43:
44: ".c.o :",
45: "\t$(CC) $(CFLAGS) -c $<",
46:
47: ".p.o :",
48: "\t$(PC) $(PFLAGS) -c $<",
49:
50: ".cl.o :",
51: "\tclass -c $<",
52:
53: ".e.o .r.o .F.o .f.o :",
54: "\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
55:
56: ".s.o :",
57: "\t$(AS) -o $@ $<",
58:
59: ".y.o :",
60: "\t$(YACC) $(YFLAGS) $<",
61: "\t$(CC) $(CFLAGS) -c y.tab.c",
62: "\trm y.tab.c",
63: "\tmv y.tab.o $@",
64:
65: ".yr.o:",
66: "\t$(YACCR) $(YFLAGS) $<",
67: "\t$(RC) $(RFLAGS) -c y.tab.r",
68: "\trm y.tab.r",
69: "\tmv y.tab.o $@",
70:
71: ".ye.o :",
72: "\t$(YACCE) $(YFLAGS) $<",
73: "\t$(EC) $(RFLAGS) -c y.tab.e",
74: "\trm y.tab.e",
75: "\tmv y.tab.o $@",
76:
77: ".l.o :",
78: "\t$(LEX) $(LFLAGS) $<",
79: "\t$(CC) $(CFLAGS) -c lex.yy.c",
80: "\trm lex.yy.c",
81: "\tmv lex.yy.o $@",
82:
83: ".y.c :",
84: "\t$(YACC) $(YFLAGS) $<",
85: "\tmv y.tab.c $@",
86:
87: ".l.c :",
88: "\t$(LEX) $(LFLAGS) $<",
89: "\tmv lex.yy.c $@",
90:
91: ".yr.r:",
92: "\t$(YACCR) $(YFLAGS) $<",
93: "\tmv y.tab.r $@",
94:
95: ".ye.e :",
96: "\t$(YACCE) $(YFLAGS) $<",
97: "\tmv y.tab.e $@",
98:
99: #ifdef pwb
100: ".o.L .c.L .t.L:",
101: "\t$(SCOMP) $(SCFLAGS) $<",
102:
103: ".t.o:",
104: "\t$(SCOMP) $(SCFLAGS) -c $<",
105:
106: ".t.c:",
107: "\t$(SCOMP) $(SCFLAGS) -t $<",
108:
109: ".h.z .t.z:",
110: "\t$(CMDICT) $(CMFLAGS) $<",
111:
112: ".h.x .t.x:",
113: "\t$(CMDICT) $(CMFLAGS) -c $<",
114: #endif
115:
116: ".s.out .c.out .o.out :",
117: "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
118:
119: ".f.out .F.out .r.out .e.out :",
120: "\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
121: "\t-rm $*.o",
122:
123: ".y.out :",
124: "\t$(YACC) $(YFLAGS) $<",
125: "\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
126: "\trm y.tab.c",
127:
128: ".l.out :",
129: "\t$(LEX) $(LFLAGS) $<",
130: "\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
131: "\trm lex.yy.c",
132:
133: 0 };
134:
135: #include "defs"
136: #include <sys/stat.h>
137:
138:
139:
140: TIMETYPE
141: exists(pname)
142: struct nameblock *pname;
143: {
144: struct stat buf;
145: register char *s, *filename;
146: TIMETYPE lookarch();
147: extern char *findfl();
148:
149: filename = pname->namep;
150:
151: for(s = filename ; *s!='\0' && *s!='(' ; ++s)
152: ;
153:
154: if(*s == '(')
155: return(lookarch(filename));
156:
157: if (stat(filename, &buf) < 0)
158: {
159: s = findfl(filename);
160: if(s != (char *)-1)
161: {
162: pname->alias = copys(s);
163: if(stat(pname->alias, &buf) == 0)
164: return(buf.st_mtime);
165: }
166: return(0);
167: }
168: else return(buf.st_mtime);
169: }
170:
171:
172: TIMETYPE prestime()
173: {
174: TIMETYPE t;
175: time(&t);
176: return(t);
177: }
178:
179:
180:
181: FSTATIC char nbuf[MAXNAMLEN + 1];
182: FSTATIC char *nbufend = &nbuf[MAXNAMLEN];
183:
184:
185:
186: struct depblock *srchdir(pat, mkchain, nextdbl)
187: register char *pat; /* pattern to be matched in directory */
188: int mkchain; /* nonzero if results to be remembered */
189: struct depblock *nextdbl; /* final value for chain */
190: {
191: DIR *dirf;
192: register int i;
193: int nread, cldir;
194: char *dirname, *dirpref, *endir, *filepat, *p, temp[BUFSIZ];
195: char fullname[BUFSIZ], *p1, *p2;
196: struct nameblock *q;
197: struct depblock *thisdbl;
198: struct dirhdr *od;
199: struct pattern *patp;
200: struct varblock *cp, *varptr();
201: char *path, pth[BUFSIZ], *strcpy();
202: struct direct *dptr;
203:
204:
205: thisdbl = 0;
206:
207: if(mkchain == NO)
208: for(patp=firstpat ; patp ; patp = patp->nxtpattern)
209: if(! unequal(pat, patp->patval)) return(0);
210:
211: patp = ALLOC(pattern);
212: patp->nxtpattern = firstpat;
213: firstpat = patp;
214: patp->patval = copys(pat);
215:
216: endir = 0;
217:
218: for(p=pat; *p!='\0'; ++p)
219: if(*p=='/') endir = p;
220:
221: if(endir==0)
222: {
223: dirpref = "";
224: filepat = pat;
225: cp = varptr("VPATH");
226: if (cp->varval == NULL) path = ".";
227: else {
228: path = pth;
229: *path = '\0';
230: if (strncmp(cp->varval, ".:", 2) != 0) strcpy(pth,".:");
231: strcat(pth, cp->varval);
232: }
233: }
234: else {
235: *endir = '\0';
236: path = strcpy(pth, pat);
237: dirpref = concat(pat, "/", temp);
238: filepat = endir+1;
239: }
240:
241: while (*path) { /* Loop thru each VPATH directory */
242: dirname = path;
243: for (; *path; path++)
244: if (*path == ':') {
245: *path++ = '\0';
246: break;
247: }
248:
249: dirf = NULL;
250: cldir = NO;
251:
252: for(od = firstod; od; od = od->nxtopendir)
253: if(! unequal(dirname, od->dirn) )
254: {
255: dirf = od->dirfc;
256: if (dirf != NULL)
257: rewinddir(dirf); /* start over at the beginning */
258: break;
259: }
260:
261: if(dirf == NULL)
262: {
263: dirf = opendir(dirname);
264: if(nopdir >= MAXDIR)
265: cldir = YES;
266: else {
267: ++nopdir;
268: od = ALLOC(dirhdr);
269: od->nxtopendir = firstod;
270: firstod = od;
271: od->dirfc = dirf;
272: od->dirn = copys(dirname);
273: fcntl(dirfd(dirf), F_SETFD, 1);
274: }
275: }
276:
277: if(dirf == NULL)
278: {
279: fprintf(stderr, "Directory %s: ", dirname);
280: fatal("Cannot open");
281: }
282:
283: else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
284: {
285: p1 = dptr->d_name;
286: p2 = nbuf;
287: while( (p2<nbufend) && (*p2++ = *p1++)!='\0' )
288: /* void */;
289: if( amatch(nbuf,filepat) )
290: {
291: concat(dirpref,nbuf,fullname);
292: if( (q=srchname(fullname)) ==0)
293: q = makename(copys(fullname));
294: if(mkchain)
295: {
296: thisdbl = ALLOC(depblock);
297: thisdbl->nxtdepblock = nextdbl;
298: thisdbl->depname = q;
299: nextdbl = thisdbl;
300: }
301: }
302: }
303:
304: if(endir != 0) *endir = '/';
305:
306: if(cldir) {
307: closedir(dirf);
308: dirf = NULL;
309: }
310: } /* End of VPATH loop */
311: return(thisdbl);
312: }
313:
314: /* stolen from glob through find */
315:
316: static amatch(s, p)
317: char *s, *p;
318: {
319: register int cc, scc, k;
320: int c, lc;
321:
322: scc = *s;
323: lc = 077777;
324: switch (c = *p) {
325:
326: case '[':
327: k = 0;
328: while (cc = *++p) {
329: switch (cc) {
330:
331: case ']':
332: if (k)
333: return(amatch(++s, ++p));
334: else
335: return(0);
336:
337: case '-':
338: k |= (lc <= scc) & (scc <= (cc=p[1]) ) ;
339: }
340: if (scc==(lc=cc)) k++;
341: }
342: return(0);
343:
344: case '?':
345: caseq:
346: if(scc) return(amatch(++s, ++p));
347: return(0);
348: case '*':
349: return(umatch(s, ++p));
350: case 0:
351: return(!scc);
352: }
353: if (c==scc) goto caseq;
354: return(0);
355: }
356:
357: static umatch(s, p)
358: char *s, *p;
359: {
360: if(*p==0) return(1);
361: while(*s)
362: if (amatch(s++,p)) return(1);
363: return(0);
364: }
365:
366: #ifdef METERFILE
367: #include <pwd.h>
368: int meteron = 0; /* default: metering off */
369:
370: meter(file)
371: char *file;
372: {
373: TIMETYPE tvec;
374: char *p, *ctime();
375: FILE * mout;
376: struct passwd *pwd, *getpwuid();
377:
378: if(file==0 || meteron==0) return;
379:
380: pwd = getpwuid(getuid());
381:
382: time(&tvec);
383:
384: if( (mout=fopen(file,"a")) != NULL )
385: {
386: p = ctime(&tvec);
387: p[16] = '\0';
388: fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
389: fclose(mout);
390: }
391: }
392: #endif
393:
394:
395: /* look inside archives for notations a(b) and a((b))
396: a(b) is file member b in archive a
397: a((b)) is entry point _b in object archive a
398: */
399:
400: #ifdef ASCARCH
401: # include <ar.h>
402: #else
403: # include <ar.h>
404: #endif
405: #include <a.out.h>
406:
407: static long arflen;
408: static long arfdate;
409: static char arfname[16];
410: FILE *arfd;
411: long int arpos, arlen;
412:
413: static struct exec objhead;
414:
415: static struct nlist objentry;
416:
417:
418: TIMETYPE lookarch(filename)
419: char *filename;
420: {
421: char *p, *q, *send, s[MAXNAMLEN + 1];
422: int i, nc, nsym, objarch;
423:
424: for(p = filename; *p!= '(' ; ++p)
425: ;
426: *p = '\0';
427: openarch(filename);
428: *p++ = '(';
429:
430: if(*p == '(')
431: {
432: objarch = YES;
433: nc = 8;
434: ++p;
435: }
436: else
437: {
438: objarch = NO;
439: nc = MAXNAMLEN;
440: }
441: send = s + nc;
442:
443: for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
444: ;
445: while(q < send)
446: *q++ = '\0';
447: while(getarch())
448: {
449: if(objarch)
450: {
451: getobj();
452: nsym = objhead.a_syms / sizeof(objentry);
453: for(i = 0; i<nsym ; ++i)
454: {
455: fread( (char *) &objentry, sizeof(objentry),1,arfd);
456: if( (objentry.n_type & N_EXT)
457: && ((objentry.n_type & ~N_EXT) || objentry.n_value)
458: && eqstr(objentry.n_un.n_name,s,nc))
459: {
460: clarch();
461: return(arfdate);
462: }
463: }
464: }
465:
466: else if( eqstr(arfname, s, nc))
467: {
468: clarch();
469: return(arfdate);
470: }
471: }
472:
473: clarch();
474: return( 0L);
475: }
476:
477:
478: clarch()
479: {
480: fclose( arfd );
481: }
482:
483:
484: openarch(f)
485: register char *f;
486: {
487: #ifdef ASCARCH
488: char magic[SARMAG];
489: #endif
490: int word;
491: #include <sys/stat.h>
492: struct stat buf;
493:
494: stat(f, &buf);
495: arlen = buf.st_size;
496:
497: arfd = fopen(f, "r");
498: if(arfd == NULL)
499: fatal1("cannot open %s", f);
500:
501: fread( (char *) &word, sizeof(word), 1, arfd);
502: #ifdef ASCARCH
503: fseek(arfd, 0L, 0);
504: fread(magic, SARMAG, 1, arfd);
505: arpos = SARMAG;
506: if( ! eqstr(magic, ARMAG, SARMAG) )
507: #else
508: arpos = sizeof(word);
509: if(word != ARMAG)
510: #endif
511: fatal1("%s is not an archive", f);
512:
513: arflen = 0;
514: }
515:
516:
517:
518: getarch()
519: {
520: struct ar_hdr arhead;
521: long atol();
522:
523: arpos += (arflen + 1) & ~1L; /* round archived file length up to even */
524: if(arpos >= arlen)
525: return(0);
526: fseek(arfd, arpos, 0);
527:
528: fread( (char *) &arhead, sizeof(arhead), 1, arfd);
529: arpos += sizeof(arhead);
530: #ifdef ASCARCH
531: arflen = atol(arhead.ar_size);
532: arfdate = atol(arhead.ar_date);
533: #else
534: arflen = arhead.ar_size;
535: arfdate = arhead.ar_date;
536: #endif
537: strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
538: return(1);
539: }
540:
541:
542: getobj()
543: {
544: long int skip;
545:
546: fread( (char *) &objhead, sizeof(objhead), 1, arfd);
547: if (N_BADMAG(objhead))
548: fatal1("%s is not an object module", arfname);
549: skip = objhead.a_text + objhead.a_data;
550: #ifndef pdp11
551: skip += objhead.a_trsize + objhead.a_drsize;
552: #else
553: if(! objhead.a_flag )
554: skip *= 2;
555: #endif
556: fseek(arfd, skip, 1);
557: }
558:
559:
560: eqstr(a,b,n)
561: register char *a, *b;
562: int n;
563: {
564: register int i;
565: for(i = 0 ; i < n ; ++i)
566: if(*a++ != *b++)
567: return(NO);
568: return(YES);
569: }
570:
571:
572: /*
573: * findfl(name) (like execvp, but does path search and finds files)
574: */
575: static char fname[128];
576:
577: char *execat();
578:
579: char *findfl(name)
580: register char *name;
581: {
582: register char *p;
583: register struct varblock *cp;
584: struct stat buf;
585: struct varblock *varptr();
586:
587: for (p = name; *p; p++)
588: if(*p == '/') return(name);
589:
590: cp = varptr("VPATH");
591: if(cp->varval == NULL || *cp->varval == 0)
592: p = ":";
593: else
594: p = cp->varval;
595:
596: do
597: {
598: p = execat(p, name, fname);
599: if(stat(fname,&buf) >= 0)
600: return(fname);
601: } while (p);
602: return((char *)-1);
603: }
604:
605: char *execat(s1, s2, si)
606: register char *s1, *s2;
607: char *si;
608: {
609: register char *s;
610:
611: s = si;
612: while (*s1 && *s1 != ':' && *s1 != '-')
613: *s++ = *s1++;
614: if (si != s)
615: *s++ = '/';
616: while (*s2)
617: *s++ = *s2++;
618: *s = '\0';
619: return(*s1? ++s1: 0);
620: }
621:
622:
623: /* copy s to d, changing file names to file aliases */
624: fixname(s, d)
625: char *s, *d;
626: {
627: register char *r, *q;
628: struct nameblock *pn;
629: char name[BUFSIZ];
630:
631: while (*s) {
632: if (isspace(*s)) *d++ = *s++;
633: else {
634: r = name;
635: while (*s) {
636: if (isspace(*s)) break;
637: *r++ = *s++;
638: }
639: *r = '\0';
640:
641: if (((pn = srchname(name)) != 0) && (pn->alias))
642: q = pn->alias;
643: else q = name;
644:
645: while (*q) *d++ = *q++;
646: }
647: }
648: *d = '\0';
649: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.