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