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