1*16212Sralph static char *sccsid = "@(#)files.c 4.9 (Berkeley) 84/03/21"; 2*16212Sralph #include <fcntl.h> 3*16212Sralph 42805Swnj /* UNIX DEPENDENT PROCEDURES */ 52805Swnj 62805Swnj 72805Swnj /* DEFAULT RULES FOR UNIX */ 82805Swnj 92805Swnj char *builtin[] = 102805Swnj { 112805Swnj #ifdef pwb 122805Swnj ".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl", 132805Swnj #else 1413463Snicklin ".SUFFIXES : .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p", 152805Swnj #endif 162805Swnj "YACC=yacc", 172805Swnj "YACCR=yacc -r", 182805Swnj "YACCE=yacc -e", 192805Swnj "YFLAGS=", 202805Swnj "LEX=lex", 212805Swnj "LFLAGS=", 222805Swnj "CC=cc", 2310803Ssam #if defined(vax) || defined(sun) 242805Swnj "AS=as", 252805Swnj #else 262805Swnj "AS=as -", 272805Swnj #endif 282805Swnj "PC=pc", 292805Swnj "PFLAGS=", 302805Swnj "CFLAGS=", 312805Swnj "RC=f77", 322805Swnj "RFLAGS=", 332811Swnj "FC=f77", 342805Swnj "EFLAGS=", 352805Swnj "FFLAGS=", 362805Swnj "LOADLIBES=", 372805Swnj #ifdef pwb 382805Swnj "SCOMP=scomp", 392805Swnj "SCFLAGS=", 402805Swnj "CMDICT=cmdict", 412805Swnj "CMFLAGS=", 422805Swnj #endif 432805Swnj 442805Swnj ".c.o :", 452805Swnj "\t$(CC) $(CFLAGS) -c $<", 462805Swnj 472805Swnj ".p.o :", 482805Swnj "\t$(PC) $(PFLAGS) -c $<", 492805Swnj 502805Swnj ".cl.o :", 512805Swnj "\tclass -c $<", 522805Swnj 5312525Snicklin ".e.o .r.o .F.o .f.o :", 542805Swnj "\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<", 552805Swnj 562805Swnj ".s.o :", 572805Swnj "\t$(AS) -o $@ $<", 582805Swnj 592805Swnj ".y.o :", 602805Swnj "\t$(YACC) $(YFLAGS) $<", 612805Swnj "\t$(CC) $(CFLAGS) -c y.tab.c", 622805Swnj "\trm y.tab.c", 632805Swnj "\tmv y.tab.o $@", 642805Swnj 652805Swnj ".yr.o:", 662805Swnj "\t$(YACCR) $(YFLAGS) $<", 672805Swnj "\t$(RC) $(RFLAGS) -c y.tab.r", 682805Swnj "\trm y.tab.r", 692805Swnj "\tmv y.tab.o $@", 702805Swnj 712805Swnj ".ye.o :", 722805Swnj "\t$(YACCE) $(YFLAGS) $<", 732805Swnj "\t$(EC) $(RFLAGS) -c y.tab.e", 742805Swnj "\trm y.tab.e", 752805Swnj "\tmv y.tab.o $@", 762805Swnj 772805Swnj ".l.o :", 782805Swnj "\t$(LEX) $(LFLAGS) $<", 792805Swnj "\t$(CC) $(CFLAGS) -c lex.yy.c", 802805Swnj "\trm lex.yy.c", 812805Swnj "\tmv lex.yy.o $@", 822805Swnj 832805Swnj ".y.c :", 842805Swnj "\t$(YACC) $(YFLAGS) $<", 852805Swnj "\tmv y.tab.c $@", 862805Swnj 872805Swnj ".l.c :", 882805Swnj "\t$(LEX) $(LFLAGS) $<", 892805Swnj "\tmv lex.yy.c $@", 902805Swnj 912805Swnj ".yr.r:", 922805Swnj "\t$(YACCR) $(YFLAGS) $<", 932805Swnj "\tmv y.tab.r $@", 942805Swnj 952805Swnj ".ye.e :", 962805Swnj "\t$(YACCE) $(YFLAGS) $<", 972805Swnj "\tmv y.tab.e $@", 982805Swnj 992805Swnj #ifdef pwb 1002805Swnj ".o.L .c.L .t.L:", 1012805Swnj "\t$(SCOMP) $(SCFLAGS) $<", 1022805Swnj 1032805Swnj ".t.o:", 1042805Swnj "\t$(SCOMP) $(SCFLAGS) -c $<", 1052805Swnj 1062805Swnj ".t.c:", 1072805Swnj "\t$(SCOMP) $(SCFLAGS) -t $<", 1082805Swnj 1092805Swnj ".h.z .t.z:", 1102805Swnj "\t$(CMDICT) $(CMFLAGS) $<", 1112805Swnj 1122805Swnj ".h.x .t.x:", 1132805Swnj "\t$(CMDICT) $(CMFLAGS) -c $<", 1142805Swnj #endif 1152805Swnj 1162805Swnj ".s.out .c.out .o.out :", 1172805Swnj "\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@", 1182805Swnj 11912525Snicklin ".f.out .F.out .r.out .e.out :", 1202805Swnj "\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@", 1212805Swnj "\t-rm $*.o", 1222805Swnj 1232805Swnj ".y.out :", 1242805Swnj "\t$(YACC) $(YFLAGS) $<", 1252805Swnj "\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@", 1262805Swnj "\trm y.tab.c", 1272805Swnj 1282805Swnj ".l.out :", 1292805Swnj "\t$(LEX) $(LFLAGS) $<", 1302805Swnj "\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@", 1312805Swnj "\trm lex.yy.c", 1322805Swnj 1332805Swnj 0 }; 1342805Swnj 1352805Swnj #include "defs" 1362805Swnj 1372805Swnj 1382805Swnj TIMETYPE exists(filename) 1392805Swnj char *filename; 1402805Swnj { 1412805Swnj #include <sys/stat.h> 1422805Swnj struct stat buf; 1432805Swnj register char *s; 1442805Swnj TIMETYPE lookarch(); 1452805Swnj 1462805Swnj for(s = filename ; *s!='\0' && *s!='(' ; ++s) 1472805Swnj ; 1482805Swnj 1492805Swnj if(*s == '(') 1502805Swnj return(lookarch(filename)); 1512805Swnj 1527208Sroot if (stat(filename, &buf) < 0) 1532805Swnj return(0); 1542805Swnj else return(buf.st_mtime); 1552805Swnj } 1562805Swnj 1572805Swnj 1582805Swnj TIMETYPE prestime() 1592805Swnj { 1602805Swnj TIMETYPE t; 1612805Swnj time(&t); 1622805Swnj return(t); 1632805Swnj } 1642805Swnj 1652805Swnj 1662805Swnj 1676578Smckusick FSTATIC char nbuf[MAXNAMLEN + 1]; 1686578Smckusick FSTATIC char *nbufend = &nbuf[MAXNAMLEN]; 1692805Swnj 1702805Swnj 1712805Swnj 1722805Swnj struct depblock *srchdir(pat, mkchain, nextdbl) 1732805Swnj register char *pat; /* pattern to be matched in directory */ 1742805Swnj int mkchain; /* nonzero if results to be remembered */ 1752805Swnj struct depblock *nextdbl; /* final value for chain */ 1762805Swnj { 1776578Smckusick DIR *dirf; 1782805Swnj register int i; 1792805Swnj int nread, cldir; 1802805Swnj char *dirname, *dirpref, *endir, *filepat, *p, temp[100]; 1812805Swnj char fullname[100], *p1, *p2; 1822805Swnj struct nameblock *q; 1832805Swnj struct depblock *thisdbl; 1846578Smckusick struct dirhdr *od; 1852805Swnj struct pattern *patp; 1862805Swnj 1876578Smckusick struct direct *dptr; 1882805Swnj 1892805Swnj 1902805Swnj thisdbl = 0; 1912805Swnj 1922805Swnj if(mkchain == NO) 1932805Swnj for(patp=firstpat ; patp ; patp = patp->nxtpattern) 1942805Swnj if(! unequal(pat, patp->patval)) return(0); 1952805Swnj 1962805Swnj patp = ALLOC(pattern); 1972805Swnj patp->nxtpattern = firstpat; 1982805Swnj firstpat = patp; 1992805Swnj patp->patval = copys(pat); 2002805Swnj 2012805Swnj endir = 0; 2022805Swnj 2032805Swnj for(p=pat; *p!='\0'; ++p) 2042805Swnj if(*p=='/') endir = p; 2052805Swnj 2062805Swnj if(endir==0) 2072805Swnj { 2082805Swnj dirname = "."; 2092805Swnj dirpref = ""; 2102805Swnj filepat = pat; 2112805Swnj } 2122805Swnj else { 2132805Swnj dirname = pat; 2142805Swnj *endir = '\0'; 2152805Swnj dirpref = concat(dirname, "/", temp); 2162805Swnj filepat = endir+1; 2172805Swnj } 2182805Swnj 2192805Swnj dirf = NULL; 2202805Swnj cldir = NO; 2212805Swnj 2222805Swnj for(od = firstod; od; od = od->nxtopendir) 2232805Swnj if(! unequal(dirname, od->dirn) ) 2242805Swnj { 2252805Swnj dirf = od->dirfc; 2266578Smckusick if (dirf != NULL) 2276578Smckusick rewinddir(dirf); /* start over at the beginning */ 2282805Swnj break; 2292805Swnj } 2302805Swnj 2312805Swnj if(dirf == NULL) 2322805Swnj { 2336578Smckusick dirf = opendir(dirname); 2342805Swnj if(nopdir >= MAXDIR) 2352805Swnj cldir = YES; 2362805Swnj else { 2372805Swnj ++nopdir; 2386578Smckusick od = ALLOC(dirhdr); 2392805Swnj od->nxtopendir = firstod; 2402805Swnj firstod = od; 2412805Swnj od->dirfc = dirf; 2422805Swnj od->dirn = copys(dirname); 243*16212Sralph fcntl(dirf->dd_fd, F_SETFD, 1); 2442805Swnj } 2452805Swnj } 2462805Swnj 2472805Swnj if(dirf == NULL) 2482805Swnj { 2492805Swnj fprintf(stderr, "Directory %s: ", dirname); 2502805Swnj fatal("Cannot open"); 2512805Swnj } 2522805Swnj 2536578Smckusick else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf)) 2542805Swnj { 2556578Smckusick p1 = dptr->d_name; 2566578Smckusick p2 = nbuf; 2576578Smckusick while( (p2<nbufend) && (*p2++ = *p1++)!='\0' ) 2586578Smckusick /* void */; 2596578Smckusick if( amatch(nbuf,filepat) ) 2606578Smckusick { 2616578Smckusick concat(dirpref,nbuf,fullname); 2626578Smckusick if( (q=srchname(fullname)) ==0) 2636578Smckusick q = makename(copys(fullname)); 2646578Smckusick if(mkchain) 2652805Swnj { 2666578Smckusick thisdbl = ALLOC(depblock); 2676578Smckusick thisdbl->nxtdepblock = nextdbl; 2686578Smckusick thisdbl->depname = q; 2696578Smckusick nextdbl = thisdbl; 2702805Swnj } 2716578Smckusick } 2726578Smckusick } 2732805Swnj 2742805Swnj if(endir != 0) *endir = '/'; 2752805Swnj 2766578Smckusick if(cldir) { 2776578Smckusick closedir(dirf); 2786578Smckusick dirf = NULL; 2796578Smckusick } 2802805Swnj return(thisdbl); 2812805Swnj } 2822805Swnj 2832805Swnj /* stolen from glob through find */ 2842805Swnj 2852805Swnj static amatch(s, p) 2862805Swnj char *s, *p; 2872805Swnj { 2882805Swnj register int cc, scc, k; 2892805Swnj int c, lc; 2902805Swnj 2912805Swnj scc = *s; 2922805Swnj lc = 077777; 2932805Swnj switch (c = *p) { 2942805Swnj 2952805Swnj case '[': 2962805Swnj k = 0; 2972805Swnj while (cc = *++p) { 2982805Swnj switch (cc) { 2992805Swnj 3002805Swnj case ']': 3012805Swnj if (k) 3022805Swnj return(amatch(++s, ++p)); 3032805Swnj else 3042805Swnj return(0); 3052805Swnj 3062805Swnj case '-': 3072805Swnj k |= (lc <= scc) & (scc <= (cc=p[1]) ) ; 3082805Swnj } 3092805Swnj if (scc==(lc=cc)) k++; 3102805Swnj } 3112805Swnj return(0); 3122805Swnj 3132805Swnj case '?': 3142805Swnj caseq: 3152805Swnj if(scc) return(amatch(++s, ++p)); 3162805Swnj return(0); 3172805Swnj case '*': 3182805Swnj return(umatch(s, ++p)); 3192805Swnj case 0: 3202805Swnj return(!scc); 3212805Swnj } 3222805Swnj if (c==scc) goto caseq; 3232805Swnj return(0); 3242805Swnj } 3252805Swnj 3262805Swnj static umatch(s, p) 3272805Swnj char *s, *p; 3282805Swnj { 3292805Swnj if(*p==0) return(1); 3302805Swnj while(*s) 3312805Swnj if (amatch(s++,p)) return(1); 3322805Swnj return(0); 3332805Swnj } 3342805Swnj 3352805Swnj #ifdef METERFILE 3362805Swnj #include <pwd.h> 3372805Swnj int meteron = 0; /* default: metering off */ 3382805Swnj 3392805Swnj meter(file) 3402805Swnj char *file; 3412805Swnj { 3422805Swnj TIMETYPE tvec; 3432805Swnj char *p, *ctime(); 3442805Swnj FILE * mout; 3452805Swnj struct passwd *pwd, *getpwuid(); 3462805Swnj 3472805Swnj if(file==0 || meteron==0) return; 3482805Swnj 3492805Swnj pwd = getpwuid(getuid()); 3502805Swnj 3512805Swnj time(&tvec); 3522805Swnj 3532805Swnj if( (mout=fopen(file,"a")) != NULL ) 3542805Swnj { 3552805Swnj p = ctime(&tvec); 3562805Swnj p[16] = '\0'; 3572805Swnj fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4); 3582805Swnj fclose(mout); 3592805Swnj } 3602805Swnj } 3612805Swnj #endif 3622805Swnj 3632805Swnj 3642805Swnj /* look inside archives for notations a(b) and a((b)) 3652805Swnj a(b) is file member b in archive a 3662805Swnj a((b)) is entry point _b in object archive a 3672805Swnj */ 3682805Swnj 3692805Swnj #ifdef ASCARCH 3702805Swnj # include <ar.h> 3712805Swnj #else 3722805Swnj # include <ar.h> 3732805Swnj #endif 3742805Swnj #include <a.out.h> 3752805Swnj 3762805Swnj static long arflen; 3772805Swnj static long arfdate; 3782805Swnj static char arfname[16]; 3792805Swnj FILE *arfd; 3802805Swnj long int arpos, arlen; 3812805Swnj 3822805Swnj static struct exec objhead; 3832805Swnj 3842805Swnj static struct nlist objentry; 3852805Swnj 3862805Swnj 3872805Swnj TIMETYPE lookarch(filename) 3882805Swnj char *filename; 3892805Swnj { 3906578Smckusick char *p, *q, *send, s[MAXNAMLEN + 1]; 3912805Swnj int i, nc, nsym, objarch; 3922805Swnj 3932805Swnj for(p = filename; *p!= '(' ; ++p) 3942805Swnj ; 3952805Swnj *p = '\0'; 3962805Swnj openarch(filename); 3972805Swnj *p++ = '('; 3982805Swnj 3992805Swnj if(*p == '(') 4002805Swnj { 4012805Swnj objarch = YES; 4022805Swnj nc = 8; 4032805Swnj ++p; 4042805Swnj } 4052805Swnj else 4062805Swnj { 4072805Swnj objarch = NO; 4086578Smckusick nc = MAXNAMLEN; 4092805Swnj } 4102805Swnj send = s + nc; 4112805Swnj 4122805Swnj for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ ) 4132805Swnj ; 4142805Swnj while(q < send) 4152805Swnj *q++ = '\0'; 4162805Swnj while(getarch()) 4172805Swnj { 4182805Swnj if(objarch) 4192805Swnj { 4202805Swnj getobj(); 4212805Swnj nsym = objhead.a_syms / sizeof(objentry); 4222805Swnj for(i = 0; i<nsym ; ++i) 4232805Swnj { 4242805Swnj fread( (char *) &objentry, sizeof(objentry),1,arfd); 4252805Swnj if( (objentry.n_type & N_EXT) 4262805Swnj && ((objentry.n_type & ~N_EXT) || objentry.n_value) 4272805Swnj && eqstr(objentry.n_un.n_name,s,nc)) 4282805Swnj { 4292805Swnj clarch(); 4302805Swnj return(arfdate); 4312805Swnj } 4322805Swnj } 4332805Swnj } 4342805Swnj 4352805Swnj else if( eqstr(arfname, s, nc)) 4362805Swnj { 4372805Swnj clarch(); 4382805Swnj return(arfdate); 4392805Swnj } 4402805Swnj } 4412805Swnj 4422805Swnj clarch(); 4432805Swnj return( 0L); 4442805Swnj } 4452805Swnj 4462805Swnj 4472805Swnj clarch() 4482805Swnj { 4492805Swnj fclose( arfd ); 4502805Swnj } 4512805Swnj 4522805Swnj 4532805Swnj openarch(f) 4542805Swnj register char *f; 4552805Swnj { 4562805Swnj #ifdef ASCARCH 4572805Swnj char magic[SARMAG]; 4582805Swnj #endif 4592805Swnj int word; 4602805Swnj #include <sys/stat.h> 4612805Swnj struct stat buf; 4622805Swnj 4632805Swnj stat(f, &buf); 4642805Swnj arlen = buf.st_size; 4652805Swnj 4662805Swnj arfd = fopen(f, "r"); 4672805Swnj if(arfd == NULL) 4682805Swnj fatal1("cannot open %s", f); 4692805Swnj 4702805Swnj fread( (char *) &word, sizeof(word), 1, arfd); 4712805Swnj #ifdef ASCARCH 4722805Swnj fseek(arfd, 0L, 0); 4732805Swnj fread(magic, SARMAG, 1, arfd); 4742805Swnj arpos = SARMAG; 4752805Swnj if( ! eqstr(magic, ARMAG, SARMAG) ) 4762805Swnj #else 4772805Swnj arpos = sizeof(word); 4782805Swnj if(word != ARMAG) 4792805Swnj #endif 4802805Swnj fatal1("%s is not an archive", f); 4812805Swnj 4822805Swnj arflen = 0; 4832805Swnj } 4842805Swnj 4852805Swnj 4862805Swnj 4872805Swnj getarch() 4882805Swnj { 4892805Swnj struct ar_hdr arhead; 4902805Swnj long atol(); 4912805Swnj 4922805Swnj arpos += (arflen + 1) & ~1L; /* round archived file length up to even */ 4932805Swnj if(arpos >= arlen) 4942805Swnj return(0); 4952805Swnj fseek(arfd, arpos, 0); 4962805Swnj 4972805Swnj fread( (char *) &arhead, sizeof(arhead), 1, arfd); 4982805Swnj arpos += sizeof(arhead); 4992805Swnj #ifdef ASCARCH 5002805Swnj arflen = atol(arhead.ar_size); 5012805Swnj arfdate = atol(arhead.ar_date); 5022805Swnj #else 5032805Swnj arflen = arhead.ar_size; 5042805Swnj arfdate = arhead.ar_date; 5052805Swnj #endif 5062805Swnj strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name)); 5072805Swnj return(1); 5082805Swnj } 5092805Swnj 5102805Swnj 5112805Swnj getobj() 5122805Swnj { 5132805Swnj long int skip; 5142805Swnj 5152805Swnj fread( (char *) &objhead, sizeof(objhead), 1, arfd); 5162805Swnj if (N_BADMAG(objhead)) 5172805Swnj fatal1("%s is not an object module", arfname); 5182805Swnj skip = objhead.a_text + objhead.a_data; 51910803Ssam #if defined(vax) || defined(sun) 5202805Swnj skip += objhead.a_trsize + objhead.a_drsize; 5212805Swnj #else 5222805Swnj if(! objhead.a_flag ) 5232805Swnj skip *= 2; 5242805Swnj #endif 5252805Swnj fseek(arfd, skip, 1); 5262805Swnj } 5272805Swnj 5282805Swnj 5292805Swnj eqstr(a,b,n) 5302805Swnj register char *a, *b; 5312805Swnj int n; 5322805Swnj { 5332805Swnj register int i; 5342805Swnj for(i = 0 ; i < n ; ++i) 5352805Swnj if(*a++ != *b++) 5362805Swnj return(NO); 5372805Swnj return(YES); 5382805Swnj } 539