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