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