1 static char *sccsid = "@(#)files.c 4.7 (Berkeley) 83/05/18"; 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 .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 #if defined(vax) || defined(sun) 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 .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 .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 (stat(filename, &buf) < 0) 151 return(0); 152 else return(buf.st_mtime); 153 } 154 155 156 TIMETYPE prestime() 157 { 158 TIMETYPE t; 159 time(&t); 160 return(t); 161 } 162 163 164 165 FSTATIC char nbuf[MAXNAMLEN + 1]; 166 FSTATIC char *nbufend = &nbuf[MAXNAMLEN]; 167 168 169 170 struct depblock *srchdir(pat, mkchain, nextdbl) 171 register char *pat; /* pattern to be matched in directory */ 172 int mkchain; /* nonzero if results to be remembered */ 173 struct depblock *nextdbl; /* final value for chain */ 174 { 175 DIR *dirf; 176 register int i; 177 int nread, cldir; 178 char *dirname, *dirpref, *endir, *filepat, *p, temp[100]; 179 char fullname[100], *p1, *p2; 180 struct nameblock *q; 181 struct depblock *thisdbl; 182 struct dirhdr *od; 183 struct pattern *patp; 184 185 struct direct *dptr; 186 187 188 thisdbl = 0; 189 190 if(mkchain == NO) 191 for(patp=firstpat ; patp ; patp = patp->nxtpattern) 192 if(! unequal(pat, patp->patval)) return(0); 193 194 patp = ALLOC(pattern); 195 patp->nxtpattern = firstpat; 196 firstpat = patp; 197 patp->patval = copys(pat); 198 199 endir = 0; 200 201 for(p=pat; *p!='\0'; ++p) 202 if(*p=='/') endir = p; 203 204 if(endir==0) 205 { 206 dirname = "."; 207 dirpref = ""; 208 filepat = pat; 209 } 210 else { 211 dirname = pat; 212 *endir = '\0'; 213 dirpref = concat(dirname, "/", temp); 214 filepat = endir+1; 215 } 216 217 dirf = NULL; 218 cldir = NO; 219 220 for(od = firstod; od; od = od->nxtopendir) 221 if(! unequal(dirname, od->dirn) ) 222 { 223 dirf = od->dirfc; 224 if (dirf != NULL) 225 rewinddir(dirf); /* start over at the beginning */ 226 break; 227 } 228 229 if(dirf == NULL) 230 { 231 dirf = opendir(dirname); 232 if(nopdir >= MAXDIR) 233 cldir = YES; 234 else { 235 ++nopdir; 236 od = ALLOC(dirhdr); 237 od->nxtopendir = firstod; 238 firstod = od; 239 od->dirfc = dirf; 240 od->dirn = copys(dirname); 241 } 242 } 243 244 if(dirf == NULL) 245 { 246 fprintf(stderr, "Directory %s: ", dirname); 247 fatal("Cannot open"); 248 } 249 250 else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf)) 251 { 252 p1 = dptr->d_name; 253 p2 = nbuf; 254 while( (p2<nbufend) && (*p2++ = *p1++)!='\0' ) 255 /* void */; 256 if( amatch(nbuf,filepat) ) 257 { 258 concat(dirpref,nbuf,fullname); 259 if( (q=srchname(fullname)) ==0) 260 q = makename(copys(fullname)); 261 if(mkchain) 262 { 263 thisdbl = ALLOC(depblock); 264 thisdbl->nxtdepblock = nextdbl; 265 thisdbl->depname = q; 266 nextdbl = thisdbl; 267 } 268 } 269 } 270 271 if(endir != 0) *endir = '/'; 272 273 if(cldir) { 274 closedir(dirf); 275 dirf = NULL; 276 } 277 return(thisdbl); 278 } 279 280 /* stolen from glob through find */ 281 282 static amatch(s, p) 283 char *s, *p; 284 { 285 register int cc, scc, k; 286 int c, lc; 287 288 scc = *s; 289 lc = 077777; 290 switch (c = *p) { 291 292 case '[': 293 k = 0; 294 while (cc = *++p) { 295 switch (cc) { 296 297 case ']': 298 if (k) 299 return(amatch(++s, ++p)); 300 else 301 return(0); 302 303 case '-': 304 k |= (lc <= scc) & (scc <= (cc=p[1]) ) ; 305 } 306 if (scc==(lc=cc)) k++; 307 } 308 return(0); 309 310 case '?': 311 caseq: 312 if(scc) return(amatch(++s, ++p)); 313 return(0); 314 case '*': 315 return(umatch(s, ++p)); 316 case 0: 317 return(!scc); 318 } 319 if (c==scc) goto caseq; 320 return(0); 321 } 322 323 static umatch(s, p) 324 char *s, *p; 325 { 326 if(*p==0) return(1); 327 while(*s) 328 if (amatch(s++,p)) return(1); 329 return(0); 330 } 331 332 #ifdef METERFILE 333 #include <pwd.h> 334 int meteron = 0; /* default: metering off */ 335 336 meter(file) 337 char *file; 338 { 339 TIMETYPE tvec; 340 char *p, *ctime(); 341 FILE * mout; 342 struct passwd *pwd, *getpwuid(); 343 344 if(file==0 || meteron==0) return; 345 346 pwd = getpwuid(getuid()); 347 348 time(&tvec); 349 350 if( (mout=fopen(file,"a")) != NULL ) 351 { 352 p = ctime(&tvec); 353 p[16] = '\0'; 354 fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4); 355 fclose(mout); 356 } 357 } 358 #endif 359 360 361 /* look inside archives for notations a(b) and a((b)) 362 a(b) is file member b in archive a 363 a((b)) is entry point _b in object archive a 364 */ 365 366 #ifdef ASCARCH 367 # include <ar.h> 368 #else 369 # include <ar.h> 370 #endif 371 #include <a.out.h> 372 373 static long arflen; 374 static long arfdate; 375 static char arfname[16]; 376 FILE *arfd; 377 long int arpos, arlen; 378 379 static struct exec objhead; 380 381 static struct nlist objentry; 382 383 384 TIMETYPE lookarch(filename) 385 char *filename; 386 { 387 char *p, *q, *send, s[MAXNAMLEN + 1]; 388 int i, nc, nsym, objarch; 389 390 for(p = filename; *p!= '(' ; ++p) 391 ; 392 *p = '\0'; 393 openarch(filename); 394 *p++ = '('; 395 396 if(*p == '(') 397 { 398 objarch = YES; 399 nc = 8; 400 ++p; 401 } 402 else 403 { 404 objarch = NO; 405 nc = MAXNAMLEN; 406 } 407 send = s + nc; 408 409 for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ ) 410 ; 411 while(q < send) 412 *q++ = '\0'; 413 while(getarch()) 414 { 415 if(objarch) 416 { 417 getobj(); 418 nsym = objhead.a_syms / sizeof(objentry); 419 for(i = 0; i<nsym ; ++i) 420 { 421 fread( (char *) &objentry, sizeof(objentry),1,arfd); 422 if( (objentry.n_type & N_EXT) 423 && ((objentry.n_type & ~N_EXT) || objentry.n_value) 424 && eqstr(objentry.n_un.n_name,s,nc)) 425 { 426 clarch(); 427 return(arfdate); 428 } 429 } 430 } 431 432 else if( eqstr(arfname, s, nc)) 433 { 434 clarch(); 435 return(arfdate); 436 } 437 } 438 439 clarch(); 440 return( 0L); 441 } 442 443 444 clarch() 445 { 446 fclose( arfd ); 447 } 448 449 450 openarch(f) 451 register char *f; 452 { 453 #ifdef ASCARCH 454 char magic[SARMAG]; 455 #endif 456 int word; 457 #include <sys/stat.h> 458 struct stat buf; 459 460 stat(f, &buf); 461 arlen = buf.st_size; 462 463 arfd = fopen(f, "r"); 464 if(arfd == NULL) 465 fatal1("cannot open %s", f); 466 467 fread( (char *) &word, sizeof(word), 1, arfd); 468 #ifdef ASCARCH 469 fseek(arfd, 0L, 0); 470 fread(magic, SARMAG, 1, arfd); 471 arpos = SARMAG; 472 if( ! eqstr(magic, ARMAG, SARMAG) ) 473 #else 474 arpos = sizeof(word); 475 if(word != ARMAG) 476 #endif 477 fatal1("%s is not an archive", f); 478 479 arflen = 0; 480 } 481 482 483 484 getarch() 485 { 486 struct ar_hdr arhead; 487 long atol(); 488 489 arpos += (arflen + 1) & ~1L; /* round archived file length up to even */ 490 if(arpos >= arlen) 491 return(0); 492 fseek(arfd, arpos, 0); 493 494 fread( (char *) &arhead, sizeof(arhead), 1, arfd); 495 arpos += sizeof(arhead); 496 #ifdef ASCARCH 497 arflen = atol(arhead.ar_size); 498 arfdate = atol(arhead.ar_date); 499 #else 500 arflen = arhead.ar_size; 501 arfdate = arhead.ar_date; 502 #endif 503 strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name)); 504 return(1); 505 } 506 507 508 getobj() 509 { 510 long int skip; 511 512 fread( (char *) &objhead, sizeof(objhead), 1, arfd); 513 if (N_BADMAG(objhead)) 514 fatal1("%s is not an object module", arfname); 515 skip = objhead.a_text + objhead.a_data; 516 #if defined(vax) || defined(sun) 517 skip += objhead.a_trsize + objhead.a_drsize; 518 #else 519 if(! objhead.a_flag ) 520 skip *= 2; 521 #endif 522 fseek(arfd, skip, 1); 523 } 524 525 526 eqstr(a,b,n) 527 register char *a, *b; 528 int n; 529 { 530 register int i; 531 for(i = 0 ; i < n ; ++i) 532 if(*a++ != *b++) 533 return(NO); 534 return(YES); 535 } 536