files.c 8.5 KB

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