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