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