|
|
1.1 root 1: static char *sccsid = "@(#)files.c 8th Edition (Bell Labs) 85/10/23";
2: /* UNIX DEPENDENT PROCEDURES */
3:
4: #define NAMESPERBLOCK 32
5:
6: /* DEFAULT RULES FOR UNIX */
7:
8: char *dfltmacro[] =
9: {
10: #ifdef pwb
11: ".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
12: #else
13: ".SUFFIXES :",
14: #endif
15: "YACC=yacc",
16: "YACCR=yacc -r",
17: "YACCE=yacc -e",
18: "YFLAGS=",
19: "LEX=lex",
20: "LFLAGS=",
21: "CC=cc",
22: "XI=xi",
23: "AR=ar",
24: "AS=as",
25: "PC=pc",
26: "PFLAGS=",
27: "CFLAGS=",
28: "XIFLAGS=",
29: "FC=f77",
30: "RC=f77",
31: "RFLAGS=",
32: "EC=f77",
33: "EFLAGS=",
34: "FFLAGS=",
35: "LOADLIBES=",
36: #ifdef pwb
37: "SCOMP=scomp",
38: "SCFLAGS=",
39: "CMDICT=cmdict",
40: "CMFLAGS=",
41: #endif
42:
43: #ifdef pwb
44: ".o.L .c.L .t.L:",
45: "\t$(SCOMP) $(SCFLAGS) $<",
46:
47: ".t.o:",
48: "\t$(SCOMP) $(SCFLAGS) -c $<",
49:
50: ".t.c:",
51: "\t$(SCOMP) $(SCFLAGS) -t $<",
52:
53: ".h.z .t.z:",
54: "\t$(CMDICT) $(CMFLAGS) $<",
55:
56: ".h.x .t.x:",
57: "\t$(CMDICT) $(CMFLAGS) -c $<",
58: #endif
59: 0 };
60:
61: char *dfltpat[] =
62: {
63: "%.o : %.c",
64: "\t$(CC) $(CFLAGS) -c $<",
65:
66: "%.s : %.c",
67: "\t$(CC) $(CFLAGS) -S $<",
68:
69: "%.o : %.xi",
70: "\t$(XI) $(XIFLAGS) -c $<",
71:
72: "%.o : %.p",
73: "\t$(PC) $(PFLAGS) -c $<",
74:
75: "%.o : %.cl",
76: "\tclass -c $<",
77:
78: "%.o : %.e",
79: "\t$(FC) $(EFLAGS) -c $<",
80:
81: "%.o : %.r",
82: "\t$(FC) $(RFLAGS) -c $<",
83:
84: "%.o : %.f",
85: "\t$(FC) $(FFLAGS) -c $<",
86:
87: "%.o : %.s",
88: "\t$(AS) -o $@ $<",
89:
90: "%.o : %.y",
91: "\t$(YACC) $(YFLAGS) $<",
92: "\t$(CC) $(CFLAGS) -c y.tab.c",
93: "\trm y.tab.c",
94: "\tmv y.tab.o $@",
95:
96: "%.o : %.yr",
97: "\t$(YACCR) $(YFLAGS) $<",
98: "\t$(RC) $(RFLAGS) -c y.tab.r",
99: "\trm y.tab.r",
100: "\tmv y.tab.o $@",
101:
102: "%.o : %.ye",
103: "\t$(YACCE) $(YFLAGS) $<",
104: "\t$(EC) $(RFLAGS) -c y.tab.e",
105: "\trm y.tab.e",
106: "\tmv y.tab.o $@",
107:
108: "%.o : %.l",
109: "\t$(LEX) $(LFLAGS) $<",
110: "\t$(CC) $(CFLAGS) -c lex.yy.c",
111: "\trm lex.yy.c",
112: "\tmv lex.yy.o $@",
113:
114: "%.c : %.y",
115: "\t$(YACC) $(YFLAGS) $<",
116: "\tmv y.tab.c $@",
117:
118: "%.c : %.l",
119: "\t$(LEX) $(LFLAGS) $<",
120: "\tmv lex.yy.c $@",
121:
122: "%.r : %.yr",
123: "\t$(YACCR) $(YFLAGS) $<",
124: "\tmv y.tab.r $@",
125:
126: "%.e : %.ye",
127: "\t$(YACCE) $(YFLAGS) $<",
128: "\tmv y.tab.e $@",
129:
130: "% : %.o",
131: "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
132:
133: "% : %.s",
134: "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
135:
136: "% : %.c",
137: "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
138:
139: "% : %.f",
140: "\t$(FC) $(FFLAGS) $< $(LOADLIBES) -o $@",
141: "\t-rm $*.o",
142:
143: "% : %.r",
144: "\t$(FC) $(RFLAGS) $< $(LOADLIBES) -o $@",
145: "\t-rm $*.o",
146:
147: "% : %.e",
148: "\t$(FC) $(EFLAGS) $< $(LOADLIBES) -o $@",
149: "\t-rm $*.o",
150:
151: "% : %.y",
152: "\t$(YACC) $(YFLAGS) $<",
153: "\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
154: "\trm y.tab.c",
155:
156: "% : %.l",
157: "\t$(LEX) $(LFLAGS) $<",
158: "\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
159: "\trm lex.yy.c",
160:
161: "% : %.xi",
162: "\t$(XI) $(XIFLAGS) $< -o $@",
163:
164: 0 };
165:
166:
167:
168: char *dfltsuff[] =
169: {
170: #ifdef pwb
171: ".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
172: #else
173: ".SUFFIXES : .out .o .c .f .e .r .y .yr .ye .l .s .cl .p",
174: #endif
175: ".c.o :",
176: "\t$(CC) $(CFLAGS) -c $<",
177:
178: ".p.o :",
179: "\t$(PC) $(PFLAGS) -c $<",
180:
181: ".cl.o :",
182: "\tclass -c $<",
183:
184: ".e.o .r.o .f.o :",
185: "\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
186:
187: ".s.o :",
188: "\t$(AS) -o $@ $<",
189:
190: ".y.o :",
191: "\t$(YACC) $(YFLAGS) $<",
192: "\t$(CC) $(CFLAGS) -c y.tab.c",
193: "\trm y.tab.c",
194: "\tmv y.tab.o $@",
195:
196: ".yr.o:",
197: "\t$(YACCR) $(YFLAGS) $<",
198: "\t$(RC) $(RFLAGS) -c y.tab.r",
199: "\trm y.tab.r",
200: "\tmv y.tab.o $@",
201:
202: ".ye.o :",
203: "\t$(YACCE) $(YFLAGS) $<",
204: "\t$(EC) $(RFLAGS) -c y.tab.e",
205: "\trm y.tab.e",
206: "\tmv y.tab.o $@",
207:
208: ".l.o :",
209: "\t$(LEX) $(LFLAGS) $<",
210: "\t$(CC) $(CFLAGS) -c lex.yy.c",
211: "\trm lex.yy.c",
212: "\tmv lex.yy.o $@",
213:
214: ".xi.o :",
215: "\t$(XI) -c $<",
216:
217: ".y.c :",
218: "\t$(YACC) $(YFLAGS) $<",
219: "\tmv y.tab.c $@",
220:
221: ".l.c :",
222: "\t$(LEX) $(LFLAGS) $<",
223: "\tmv lex.yy.c $@",
224:
225: ".yr.r:",
226: "\t$(YACCR) $(YFLAGS) $<",
227: "\tmv y.tab.r $@",
228:
229: ".ye.e :",
230: "\t$(YACCE) $(YFLAGS) $<",
231: "\tmv y.tab.e $@",
232:
233: #ifdef pwb
234: ".o.L .c.L .t.L:",
235: "\t$(SCOMP) $(SCFLAGS) $<",
236:
237: ".t.o:",
238: "\t$(SCOMP) $(SCFLAGS) -c $<",
239:
240: ".t.c:",
241: "\t$(SCOMP) $(SCFLAGS) -t $<",
242:
243: ".h.z .t.z:",
244: "\t$(CMDICT) $(CMFLAGS) $<",
245:
246: ".h.x .t.x:",
247: "\t$(CMDICT) $(CMFLAGS) -c $<",
248: #endif
249:
250: ".s.out .c.out .o.out :",
251: "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
252:
253: ".f.out .r.out .e.out :",
254: "\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
255: "\t-rm $*.o",
256:
257: ".y.out :",
258: "\t$(YACC) $(YFLAGS) $<",
259: "\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
260: "\trm y.tab.c",
261:
262: ".l.out :",
263: "\t$(LEX) $(LFLAGS) $<",
264: "\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
265: "\trm lex.yy.c",
266:
267: 0 };
268:
269: #include "defs"
270:
271:
272: #include <sys/stat.h>
273:
274: TIMETYPE exists(filename)
275: char *filename;
276: {
277: struct stat buf;
278: register char *s;
279: TIMETYPE lookarch();
280:
281: for(s = filename ; *s!='\0' && *s!='(' && *s!=')' ; ++s)
282: ;
283:
284: if(*s != '\0')
285: return lookarch(filename);
286:
287: if(stat(filename,&buf) < 0)
288: return 0;
289: else return buf.st_mtime;
290: }
291:
292:
293: TIMETYPE prestime()
294: {
295: TIMETYPE t;
296: time(&t);
297: return t;
298: }
299:
300: FSTATIC char nmtemp[MAXNAMLEN+1]; /* guarantees a null after the name */
301: FSTATIC char *tempend = nmtemp + MAXNAMLEN;
302:
303:
304:
305: depblkp srchdir(pat, mkchain, nextdbl)
306: register char *pat; /* pattern to be matched in directory */
307: int mkchain; /* nonzero if results to be remembered */
308: depblkp nextdbl; /* final value for chain */
309: {
310: DIR *dirf;
311: struct dirhd *dirptr, *opdir();
312: char *dirname, *dirpref, *endir, *filepat, *p, temp[100];
313: char fullname[100];
314: nameblkp q;
315: depblkp thisdbl;
316: struct pattern *patp;
317:
318: struct direct *dptr;
319:
320:
321: thisdbl = 0;
322:
323: if(mkchain == NO)
324: for(patp=firstpat ; patp ; patp = patp->nxtpattern)
325: if(equal(pat, patp->patval)) return 0;
326:
327: patp = ALLOC(pattern);
328: patp->nxtpattern = firstpat;
329: firstpat = patp;
330: patp->patval = copys(pat);
331:
332: endir = 0;
333:
334: for(p=pat; *p!='\0'; ++p)
335: if(*p=='/') endir = p;
336:
337: if(endir==0)
338: {
339: dirname = ".";
340: dirpref = "";
341: filepat = pat;
342: }
343: else {
344: dirname = pat;
345: *endir = '\0';
346: dirpref = concat(dirname, "/", temp);
347: filepat = endir+1;
348: }
349:
350: dirptr = opdir(dirname,YES);
351: dirf = dirptr->dirfc;
352:
353: for( dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )
354: {
355: register char *p1, *p2;
356: p1 = dptr->d_name;
357: p2 = nmtemp;
358: while( (p2<tempend) && (*p2++ = *p1++)!='\0')
359: ;
360: if( amatch(nmtemp,filepat) )
361: {
362: concat(dirpref,nmtemp,fullname);
363: if( (q=srchname(fullname)) ==0)
364: q = makename(copys(fullname));
365: if(mkchain)
366: {
367: thisdbl = ALLOC(depblock);
368: thisdbl->nxtdepblock = nextdbl;
369: thisdbl->depname = q;
370: nextdbl = thisdbl;
371: }
372: }
373: }
374:
375:
376: if(endir)
377: *endir = '/';
378:
379: cldir(dirptr, YES);
380:
381: return thisdbl;
382: }
383:
384: struct dirhd *opdir(dirname, stopifbad)
385: char *dirname;
386: int stopifbad;
387: {
388: register struct dirhd *od;
389:
390: for(od = firstod; od; od = od->nxtdirhd)
391: if(equal(dirname, od->dirn) )
392: break;
393:
394: if(od == NULL)
395: {
396: ++nopdir;
397: od = ALLOC(dirhd);
398: od->nxtdirhd = firstod;
399: firstod = od;
400: od->dirn = copys(dirname);
401: }
402:
403: if(od->dirfc==NULL && (od->dirfc = opendir(dirname)) == NULL && stopifbad)
404: {
405: fprintf(stderr, "Directory %s: ", dirname);
406: fatal("Cannot open");
407: }
408:
409: return od;
410: }
411:
412:
413:
414: cldir(dp, used)
415: register struct dirhd *dp;
416: int used;
417: {
418: if(nopdir >= MAXDIR)
419: {
420: closedir(dp->dirfc);
421: dp->dirfc = NULL;
422: }
423: else if(used)
424: rewinddir(dp->dirfc); /* start over at the beginning */
425: }
426:
427: /* stolen from glob through find */
428:
429: static amatch(s, p)
430: char *s, *p;
431: {
432: register int cc, scc, k;
433: int c, lc;
434:
435: scc = *s;
436: lc = 077777;
437: switch (c = *p) {
438:
439: case '[':
440: k = 0;
441: while (cc = *++p) {
442: switch (cc) {
443:
444: case ']':
445: if (k)
446: return amatch(++s, ++p);
447: else
448: return 0;
449:
450: case '-':
451: k |= (lc <= scc) & (scc <= (cc=p[1]) ) ;
452: }
453: if (scc==(lc=cc)) k++;
454: }
455: return 0;
456:
457: case '?':
458: caseq:
459: if(scc) return amatch(++s, ++p);
460: return 0;
461: case '*':
462: return umatch(s, ++p);
463: case 0:
464: return !scc;
465: }
466: if (c==scc) goto caseq;
467: return 0;
468: }
469:
470: static umatch(s, p)
471: char *s, *p;
472: {
473: if(*p==0) return 1;
474: while(*s)
475: if (amatch(s++,p)) return 1;
476: return 0;
477: }
478:
479: #ifdef METERFILE
480: #include <pwd.h>
481: int meteron = 0; /* default: metering off */
482:
483: meter(file)
484: char *file;
485: {
486: TIMETYPE tvec;
487: char *p, *ctime();
488: FILE * mout;
489: struct passwd *pwd, *getpwuid();
490:
491: if(file==0 || meteron==0) return;
492:
493: pwd = getpwuid(getuid());
494:
495: time(&tvec);
496:
497: if( mout = fopen(file,"a") )
498: {
499: p = ctime(&tvec);
500: p[16] = '\0';
501: fprintf(mout, "User %s, %s\n", pwd->pw_name, p+4);
502: fclose(mout);
503: }
504: }
505: #endif
506:
507:
508: /* look inside archives for notations a(b) and a((b))
509: a(b) is file member b in archive a
510: a((b)) is entry point _b in object archive a
511: */
512:
513: #ifdef ASCARCH
514: # include <ar.h>
515: #else
516: # include <ar.h>
517: #endif
518: #include <a.out.h>
519:
520: static long arflen;
521: static long arfdate;
522: static char arfname[16];
523: FILE *arfd;
524: long int arpos, arlen;
525:
526: static struct exec objhead;
527:
528: static struct nlist objentry;
529:
530:
531: TIMETYPE lookarch(filename)
532: char *filename;
533: {
534: char *p, *q, *send, s[15], pad;
535: int i, nc, nsym, objarch;
536:
537: for(p = filename; *p!= '(' ; ++p)
538: ;
539:
540: *p = '\0';
541: if( ! openarch(filename) )
542: {
543: *p = '(';
544: return 0L;
545: }
546: *p++ = '(';
547: if(*p == '(')
548: {
549: objarch = YES;
550: nc = 8;
551: pad = '\0';
552: ++p;
553: }
554: else
555: {
556: objarch = NO;
557: nc = 14;
558: pad = ' ';
559: }
560:
561: send = s + nc;
562: for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
563: ;
564: if(p[0]==')' && p[1]!='\0') /* forbid stuff after the paren */
565: {
566: clarch();
567: return 0L;
568: }
569: while(q < send)
570: *q++ = pad;
571: while(getarch())
572: {
573: if(objarch)
574: {
575: getobj();
576: nsym = objhead.a_syms / sizeof(objentry);
577: for(i = 0; i<nsym ; ++i)
578: {
579: fread( (char *) &objentry, sizeof(objentry),1,arfd);
580: if( (objentry.n_type & N_EXT)
581: && ((objentry.n_type & ~N_EXT) || objentry.n_value)
582: && eqstr(objentry.n_un.n_name,s,nc))
583: {
584: clarch();
585: return arfdate;
586: }
587: }
588: }
589:
590: else if( eqstr(arfname, s, nc))
591: {
592: clarch();
593: /*TEMP fprintf(stderr, "found archive member %14s, time=%d\n", s, arfdate); */
594: return arfdate;
595: }
596: }
597:
598: clarch();
599: return 0L;
600: }
601:
602:
603: clarch()
604: {
605: fclose( arfd );
606: }
607:
608:
609: openarch(f)
610: register char *f;
611: {
612: #ifdef ASCARCH
613: char magic[SARMAG];
614: #endif
615: int word;
616: struct stat buf;
617: nameblkp p;
618:
619: stat(f, &buf);
620: arlen = buf.st_size;
621:
622: arfd = fopen(f, "r");
623: if(arfd == NULL)
624: return NO;
625: /* fatal1("cannot open %s", f); */
626:
627: fread( (char *) &word, sizeof(word), 1, arfd);
628:
629: #ifdef ASCARCH
630: fseek(arfd, 0L, 0);
631: fread(magic, SARMAG, 1, arfd);
632: arpos = SARMAG;
633: if( ! eqstr(magic, ARMAG, SARMAG) )
634: fatal1("%s is not an archive", f);
635: #else
636: arpos = sizeof(word);
637: if(word != ARMAG)
638: fatal1("%s is not an archive", f);
639: #endif
640:
641: if( !(p = srchname(f)) )
642: p = makename( copys(f) );
643: p->isarch = YES;
644: arflen = 0;
645: return YES;
646: }
647:
648:
649:
650: getarch()
651: {
652: struct ar_hdr arhead;
653: long atol();
654:
655: arpos += (arflen + 1) & ~1L; /* round archived file length up to even */
656: if(arpos >= arlen)
657: return 0;
658: fseek(arfd, arpos, 0);
659:
660: fread( (char *) &arhead, sizeof(arhead), 1, arfd);
661: arpos += sizeof(arhead);
662: #ifdef ASCARCH
663: arflen = atol(arhead.ar_size);
664: arfdate = atol(arhead.ar_date);
665: #else
666: arflen = arhead.ar_size;
667: arfdate = arhead.ar_date;
668: #endif
669: strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
670: return 1;
671: }
672:
673:
674: getobj()
675: {
676: long int skip;
677:
678: fread( (char *) &objhead, sizeof(objhead), 1, arfd);
679: if (N_BADMAG(objhead))
680: fatal1("%s is not an object module", arfname);
681: skip = objhead.a_text + objhead.a_data;
682: skip += objhead.a_trsize + objhead.a_drsize;
683: fseek(arfd, skip, 1);
684: }
685:
686:
687: eqstr(a,b,n)
688: register char *a, *b;
689: int n;
690: {
691: register int i;
692: for(i = 0 ; i < n ; ++i)
693: if(*a++ != *b++)
694: return NO;
695: return YES;
696: }
697:
698: /* find the directory containing name.
699: read it into the hash table if it hasn't been used before or if
700: if might have changed since last reference
701: */
702:
703: dirsrch(name)
704: char *name;
705: {
706: DIR *dirf;
707: struct dirhd *opdir(), *dirp;
708: TIMETYPE dirt, objt, lookarch();
709: int dirused, hasparen;
710: char *dirname, *lastslash;
711: char *fullname, *filepart, *fileend, *s;
712: struct direct *dptr;
713:
714: lastslash = NULL;
715: hasparen = NO;
716:
717: for(s=name; *s; ++s)
718: if(*s == '/')
719: lastslash = s;
720: else if(*s=='(' || *s==')')
721: hasparen = YES;
722:
723: if(hasparen)
724: {
725: if(objt = lookarch(name))
726: makename(name)->modtime = objt;
727: return;
728: }
729:
730: if(lastslash)
731: {
732: dirname = name;
733: *lastslash = '\0';
734: }
735: else
736: dirname = ".";
737:
738: dirused = NO;
739: dirp = opdir(dirname, NO);
740: dirf = dirp->dirfc;
741: if(dirp->dirok || !dirf)
742: goto ret;
743: dirt = exists(dirname);
744: if(dirp->dirtime == dirt)
745: goto ret;
746:
747: dirp->dirok = YES;
748: dirp->dirtime = dirt;
749: dirused = YES;
750:
751: /* allocate buffer to hold full file name */
752: if(lastslash)
753: {
754: fullname = (char *) ckalloc(strlen(dirname)+MAXNAMLEN+2);
755: concat(dirname, "/", fullname);
756: filepart = fullname + strlen(fullname);
757: }
758: else
759: filepart = fullname = (char *) ckalloc(MAXNAMLEN+1);
760:
761:
762: fileend = filepart + MAXNAMLEN;
763: *fileend = '\0';
764: for(dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )
765: {
766: register char *p1, *p2;
767: p1 = dptr->d_name;
768: p2 = filepart;
769: while( (p2<fileend) && (*p2++ = *p1++)!='\0')
770: ;
771: if( ! srchname(fullname) )
772: (void) makename(copys(fullname));
773: }
774:
775: free(fullname);
776:
777: ret:
778: cldir(dirp, dirused);
779: if(lastslash)
780: *lastslash = '/';
781: }
782:
783:
784:
785:
786: baddirs()
787: {
788: register struct dirhd *od;
789:
790: for(od = firstod; od; od = od->nxtdirhd)
791: od->dirok = NO;
792: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.