home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume24 / pucc-mk / part04 < prev    next >
Text File  |  1991-03-19  |  57KB  |  2,174 lines

  1. Subject:  v24i060:  Purdue shell turbo charger and manual installer, Part04/06
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 8e7064d8 a638ed11 0afb9f05 aea98c9c
  5.  
  6. Submitted-by: Kevin Braunsdorf <ksb@cc.purdue.edu>
  7. Posting-number: Volume 24, Issue 60
  8. Archive-name: pucc-mk/part04
  9.  
  10. #!/bin/sh
  11. # This is part 04 of pucc-1c
  12. # ============= mkcat/pt.c ==============
  13. if test ! -d 'mkcat'; then
  14.     echo 'x - creating directory mkcat'
  15.     mkdir 'mkcat'
  16. fi
  17. if test -f 'mkcat/pt.c' -a X"$1" != X"-c"; then
  18.     echo 'x - skipping mkcat/pt.c (File already exists)'
  19. else
  20. echo 'x - extracting mkcat/pt.c (Text)'
  21. sed 's/^X//' << 'Purdue' > 'mkcat/pt.c' &&
  22. /*
  23. X * an abstraction for a UNIX path name
  24. X * $Id: pt.c,v 3.1 90/11/28 09:44:01 ksb Exp $
  25. X *
  26. X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
  27. X * 47907.  All rights reserved.
  28. X *
  29. X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
  30. X *
  31. X * This software is not subject to any license of the American Telephone
  32. X * and Telegraph Company or the Regents of the University of California.
  33. X *
  34. X * Permission is granted to anyone to use this software for any purpose on
  35. X * any computer system, and to alter it and redistribute it freely, subject
  36. X * to the following restrictions:
  37. X *
  38. X * 1. Neither the authors nor Purdue University are responsible for any
  39. X *    consequences of the use of this software.
  40. X *
  41. X * 2. The origin of this software must not be misrepresented, either by
  42. X *    explicit claim or by omission.  Credit to the authors and Purdue
  43. X *    University must appear in documentation and sources.
  44. X *
  45. X * 3. Altered versions must be plainly marked as such, and must not be
  46. X *    misrepresented as being the original software.
  47. X *
  48. X * 4. This notice may not be removed or altered.
  49. X */
  50. X
  51. /*
  52. X * pull a path in it's parts, bent toward what I needed a little    (ksb)
  53. X *
  54. X * $Compile: ${cc-cc} -DTEST ${cc_debug--g} %f -o %F
  55. X * $Cc: ${cc-cc} ${cc_debug--O} -c %f
  56. X */
  57. #include <stdio.h>
  58. #include <ctype.h>
  59. #include <sys/types.h>
  60. #include <sys/file.h>
  61. #include <sys/param.h>
  62. X
  63. #if !defined(MAXPATHLEN)
  64. #define MAXPATHLEN    1024
  65. #endif
  66. X
  67. #include "machine.h"
  68. #include "pt.h"
  69. X
  70. extern int strlen();
  71. extern char *strrchr(), *strcpy();
  72. X
  73. static char acDotZ[] =        /* compresses extender            */
  74. X    ".Z";
  75. X
  76. /*
  77. X * build a path structure, a nice abstraction for a UNIX file name    (ksb)
  78. X * if you pass pcFile a a null you'd better have filled acname with a
  79. X * path name...  /a//b is OK now too (/a & b)
  80. X */
  81. void
  82. PTInit(pPT, pcFile)
  83. PATH *pPT;
  84. char *pcFile;
  85. {
  86. X    register char *pcScan;
  87. X    if ((char *)0 != pcFile) {
  88. X        (void)strcpy(pPT->acname, pcFile);
  89. X    }
  90. X    pcScan = pPT->acname;
  91. X    while ((char *)0 != (pPT->pcdir = strrchr(pcScan, '/'))) {
  92. X        pcScan = pPT->pcdir+1;
  93. X        if ('\000' != pcScan[1])
  94. X            break;
  95. X        *pcScan = '\000';
  96. X        pcScan = pPT->acname;
  97. X    }
  98. X    while (pPT->pcdir > pPT->acname && '/' == pPT->pcdir[-1]) {
  99. X        --pPT->pcdir;
  100. X    }
  101. X    pPT->pcbase = pcScan;
  102. X    if ((char *)0 == (pPT->pccomp = strrchr(pcScan, acDotZ[0])) ||
  103. X        0 != strcmp(acDotZ, pPT->pccomp)) {
  104. X        pPT->pccomp = (char *)0;
  105. X        pPT->istate = PS_NONE;
  106. X    } else {
  107. X        *pPT->pccomp = '\000';
  108. X        pPT->istate = PS_COMP;
  109. X    }
  110. X    pPT->pcext = strrchr(pcScan, '.');
  111. }
  112. X
  113. /*
  114. X * return the local path name of the file (no directory part)        (ksb)
  115. X */
  116. char *
  117. PTLocal(pPT)
  118. PATH *pPT;
  119. {
  120. X    if ((char *)0 != pPT->pcext && 0 != (pPT->istate & PS_EXT)) {
  121. X        pPT->istate &= ~PS_EXT;
  122. X        *pPT->pcext = '.';
  123. X    }
  124. X    if ((char *)0 != pPT->pccomp && 0 != (pPT->istate & PS_COMP)) {
  125. X        pPT->istate &= ~PS_COMP;
  126. X        *pPT->pccomp = acDotZ[0];
  127. X    }
  128. X    return pPT->pcbase;
  129. }
  130. X
  131. /*
  132. X * return the full path name                         (ksb)
  133. X */
  134. char *
  135. PTFull(pPT)
  136. PATH *pPT;
  137. {
  138. X    (void) PTLocal(pPT);
  139. X    if ((char *)0 != pPT->pcdir && 0 != (pPT->istate & PS_DIR)) {
  140. X        pPT->istate &= ~PS_DIR;
  141. X        *pPT->pcdir = '/';
  142. X    }
  143. X    return pPT->acname;
  144. }
  145. X
  146. static char acDot[] = ".";
  147. static char acSlash[] = "/";
  148. X
  149. /*
  150. X * return the directory prefix of the file name                (ksb)
  151. X * handles no dir part (.), and /foo (/)
  152. X * you can check for these cases with a pointer compare (acDot, acSlash)
  153. X */
  154. char *
  155. PTDir(pPT)
  156. PATH *pPT;
  157. {
  158. X    if ((char *)0 == pPT->pcdir) {
  159. X        return acDot;
  160. X    }
  161. X    if (pPT->pcdir == pPT->acname) {
  162. X        return acSlash;
  163. X    }
  164. X    if (0 == (pPT->istate & PS_DIR)) {
  165. X        pPT->istate |= PS_DIR;
  166. X        *pPT->pcdir = '\000';
  167. X    }
  168. X    return pPT->acname;
  169. }
  170. X
  171. /*
  172. X * return the base name, no extender                    (ksb)
  173. X */
  174. char *
  175. PTBase(pPT)
  176. PATH *pPT;
  177. {
  178. X    if ((char *)0 != pPT->pcext) {
  179. X        if (0 == (pPT->istate & PS_EXT)) {
  180. X            pPT->istate |= PS_EXT;
  181. X            *pPT->pcext = '\000';
  182. X        }
  183. X    } else if ((char *)0 != pPT->pccomp && 0 == (pPT->istate & PS_COMP)) {
  184. X        pPT->istate |= PS_COMP;
  185. X        *pPT->pccomp = '\000';
  186. X    }
  187. X    return pPT->pcbase;
  188. }
  189. X
  190. /*
  191. X * return the exender on the path                    (ksb)
  192. X */
  193. char *
  194. PTExt(pPT)
  195. PATH *pPT;
  196. {
  197. X    if ((char *)0 != pPT->pccomp && 0 == (pPT->istate & PS_COMP)) {
  198. X        pPT->istate |= PS_COMP;
  199. X        *pPT->pccomp = '\000';
  200. X    }
  201. X    return (char *)0 != pPT->pcext ? pPT->pcext + 1 : "";
  202. }
  203. X
  204. /*
  205. X * make the file compress'd (add a .Z) return if there was one        (ksb)
  206. X */
  207. int
  208. PTComp(pPT)
  209. PATH *pPT;
  210. {
  211. X    if ((char *)0 != pPT->pccomp)
  212. X        return 1;
  213. X    pPT->pccomp = PTLocal(pPT);
  214. X    pPT->pccomp += strlen(pPT->pccomp);
  215. X    (void)strcpy(pPT->pccomp, acDotZ);
  216. X    return 0;
  217. }
  218. X
  219. /*
  220. X * make the file name be uncompressed (remove the .Z)            (ksb)
  221. X * return 1 if the file *was* uncompressed
  222. X */
  223. int
  224. PTUnComp(pPT)
  225. PATH *pPT;
  226. {
  227. X    if ((char *)0 == pPT->pccomp)
  228. X        return 1;
  229. X    if (0 == (pPT->istate & PS_COMP))
  230. X        *pPT->pccomp = '\000';
  231. X    pPT->pccomp = (char *)0;
  232. X    return 0;
  233. }
  234. X
  235. X
  236. #if defined(TEST)
  237. X
  238. /* Crack, simple configuration file parser                (ksb)
  239. X */
  240. char *
  241. Crack(pcText, ppcVar)
  242. char *pcText;
  243. char **ppcVar;
  244. {
  245. X    register char ***pppc;
  246. X    register char **ppc;
  247. X
  248. X    pppc = & ppcVar;
  249. X    while ((char **)0 != (ppc = *pppc++)) {
  250. X        if ('\000' == *pcText) {
  251. X            *ppc = (char *)0;
  252. X            continue;
  253. X        }
  254. X        *ppc = pcText;
  255. X        while (!isspace(*pcText) && '\000' != *pcText)
  256. X            ++pcText;
  257. X        if (isspace(*pcText)) {
  258. X            *pcText++ = '\000';
  259. X        }
  260. X        while (isspace(*pcText))
  261. X            ++pcText;
  262. X    }
  263. X    return pcText;
  264. }
  265. X
  266. extern int errno;
  267. extern char *sys_errlist[];
  268. #define strerror(Me) (sys_errlist[Me])
  269. X
  270. X
  271. /*
  272. X * test driver for path splitting part                    (ksb)
  273. X */
  274. int
  275. main(argc, argv)
  276. int argc;
  277. char **argv;
  278. {
  279. X    auto char acLine[1045], *pc;
  280. X    auto char *pcOrig, *pcDir, *pcLocal, *pcBase, *pcExt, *pcComp, *pcComm;
  281. X    auto PATH PTTest;
  282. X    register int e = 0;
  283. X
  284. X    switch (argc) {
  285. X    case 1:
  286. X        break;
  287. X    case 2:
  288. X        if (NULL == freopen(argv[1], "r", stdin)) {
  289. X            fprintf(stderr, "%s: freopen: %s: %s\n", argv[0], argv[1], strerror(errno));
  290. X            exit(1);
  291. X        }
  292. X        break;
  293. X    default:
  294. X        printf("%s: usage [file]\n", argv[0]);
  295. X        exit(1);
  296. X    }
  297. X
  298. X    while (NULL != gets(acLine)) {
  299. X        pcOrig = acLine;
  300. X        while (isspace(*pcOrig))
  301. X            ++pcOrig;
  302. X        if ('#' == *pcOrig || '\000' == *pcOrig)
  303. X            continue;
  304. X        pcComm = Crack(pcOrig, &pcOrig, &pcDir, &pcLocal, &pcBase, &pcExt, &pcComp, (char **)0);
  305. X        PTInit(pcOrig, & PTTest);
  306. X        if (0 != strcmp(pcOrig, (pc = PTFull(& PTTest)))) {
  307. X            printf("pt: Full: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcOrig, pc);
  308. X            ++e;
  309. X        }
  310. X        if (0 != strcmp(pcDir, (pc = PTDir(& PTTest)))) {
  311. X            printf("pt: Dir: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcDir, pc);
  312. X            ++e;
  313. X        }
  314. X        if (0 != strcmp(pcLocal, (pc = PTLocal(& PTTest))) && '~' != pcLocal[0] && '\000' != pc[0]) {
  315. X            printf("pt: Local: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcLocal, pc);
  316. X            ++e;
  317. X        }
  318. X        if (0 != strcmp(pcBase, (pc = PTBase(& PTTest))) && '~' != pcBase[0] && '\000' != pc[0]) {
  319. X            printf("pt: Base: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcBase, pc);
  320. X            ++e;
  321. X        }
  322. X        if (0 != strcmp(pcExt, (pc = PTExt(& PTTest))) && '~' != pcExt[0] && '\000' != pc[0]) {
  323. X            printf("pt: Ext: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcExt, pc);
  324. X            ++e;
  325. X        }
  326. X        if (PTIsComp(&PTTest) != ('y' == *pcComp || 'Y' == *pcComp)) {
  327. X            printf("pt: IsComp: broken\n", pcOrig);
  328. X            ++e;
  329. X        }
  330. X        if (0 != strcmp(pcOrig, (pc = PTFull(& PTTest)))) {
  331. X            printf("pt: Full: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcOrig, pc);
  332. X            ++e;
  333. X        }
  334. X        if (0 != strcmp(pcBase, (pc = PTBase(& PTTest))) && '~' != pcBase[0] && '\000' != pc[0]) {
  335. X            printf("pt: Base: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcBase, pc);
  336. X            ++e;
  337. X        }
  338. X        if (0 != strcmp(pcLocal, (pc = PTLocal(& PTTest))) && '~' != pcLocal[0] && '\000' != pc[0]) {
  339. X            printf("pt: Local: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcLocal, pc);
  340. X            ++e;
  341. X        }
  342. X        if (0 != strcmp(pcDir, (pc = PTDir(& PTTest)))) {
  343. X            printf("pt: Dir: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcDir, pc);
  344. X            ++e;
  345. X        }
  346. X        if (0 != strcmp(pcOrig, (pc = PTFull(& PTTest)))) {
  347. X            printf("pt: Full: `%s\' is broken, `%s\' != `%s\'\n", pcOrig, pcOrig, pc);
  348. X            ++e;
  349. X        }
  350. X    }
  351. X
  352. X    exit(e != 0);
  353. }
  354. X
  355. #endif    /* test driver code */
  356. Purdue
  357. chmod 0444 mkcat/pt.c ||
  358. echo 'restore of mkcat/pt.c failed'
  359. Wc_c="`wc -c < 'mkcat/pt.c'`"
  360. test 7922 -eq "$Wc_c" ||
  361.     echo 'mkcat/pt.c: original size 7922, current size' "$Wc_c"
  362. fi
  363. # ============= mk/rlimsys.c ==============
  364. if test ! -d 'mk'; then
  365.     echo 'x - creating directory mk'
  366.     mkdir 'mk'
  367. fi
  368. if test -f 'mk/rlimsys.c' -a X"$1" != X"-c"; then
  369.     echo 'x - skipping mk/rlimsys.c (File already exists)'
  370. else
  371. echo 'x - extracting mk/rlimsys.c (Text)'
  372. sed 's/^X//' << 'Purdue' > 'mk/rlimsys.c' &&
  373. /*
  374. X * resource limited system    Kevin S Braunsdorf        (ksb)
  375. X */
  376. #include "machine.h"
  377. X
  378. #if RESOURCE
  379. X
  380. #include <sys/types.h>
  381. #include <sys/time.h>
  382. #include <sys/resource.h>
  383. #if defined(bsd)
  384. #include <sys/wait.h>
  385. #endif
  386. #include <signal.h>
  387. #include <stdio.h>
  388. #include <ctype.h>
  389. X
  390. #include "mk.h"
  391. #include "rlimsys.h"
  392. X
  393. X
  394. /*
  395. X * resource records
  396. X */
  397. typedef struct RRnode {
  398. X    int rtype;        /* resource type from resource.h    */
  399. X    int fsys;        /* done by kernel or us?        */
  400. X    char *pchrname;        /* user name                */
  401. X    int rlen;        /* lenght of user name            */
  402. X    int fset;        /* was given by user?            */
  403. X    struct rlimit ourlim;    /* rlim_cur, rlim_max            */
  404. } RES_REC;
  405. X
  406. #if RLIM_NLIMITS != 6
  407. error_more_or_fewer_resources error_more_or_fewer_resources
  408. #endif
  409. X
  410. #define MY_CLOCK    0
  411. /*
  412. X * resources we know about in alpha order
  413. X */
  414. RES_REC sbRRLimits[] = {
  415. X    { MY_CLOCK,    0, "clock",    5 },
  416. X    { RLIMIT_CORE,    1, "core",    4 },
  417. X    { RLIMIT_CPU,    1, "cpu",    3 },
  418. X    { RLIMIT_DATA,    1, "data",    4 },
  419. X    { RLIMIT_FSIZE,    1, "fsize",    5 },
  420. X    { RLIMIT_RSS,    1, "rss",    3 },
  421. X    { RLIMIT_STACK,    1, "stack",    5 }
  422. };
  423. X
  424. /*
  425. X * we need to know how many limits we can set
  426. X */
  427. #define MY_NLIMITS    7
  428. X
  429. X
  430. /*
  431. X * init the resource limit stuff, make mongo syscalls            (ksb)
  432. X */
  433. void
  434. rinit()
  435. {
  436. X    register int i;
  437. X    register RES_REC *pRR;
  438. X
  439. X    for (i = 0; i < MY_NLIMITS; ++i) {
  440. X        pRR = & sbRRLimits[i];
  441. X        pRR->fset = 0;
  442. X        if (pRR->fsys) {
  443. X            getrlimit(pRR->rtype, & pRR->ourlim);
  444. X        } else {
  445. X            pRR->ourlim.rlim_cur = RLIM_INFINITY;
  446. X            pRR->ourlim.rlim_max = RLIM_INFINITY;
  447. X        }
  448. X    }
  449. }
  450. X
  451. /*
  452. X * parse a resource limit statement of the form                (ksb)
  453. X *    <resource>=number_cur/number_max
  454. X * (we eat leading blanks, as all good cvt routines should)
  455. X */
  456. char *
  457. rparse(pchState)
  458. register char *pchState;
  459. {
  460. X    extern char *strchr();
  461. X    extern long atol();
  462. X    register int i;
  463. X    register char *pchTemp;
  464. X    register RES_REC *pRR;
  465. X    register int fSetMax = 0, fSetCur = 0;
  466. X
  467. X    while (isspace(*pchState)) {
  468. X        ++pchState;
  469. X    }
  470. X    if ((char *)0 == (pchTemp = strchr(pchState, '='))) {
  471. X        return pchState;
  472. X    }
  473. X
  474. X    for (i = 0; i < MY_NLIMITS; ++i) {
  475. X        pRR = & sbRRLimits[i];
  476. X        if (0 == strncmp(pRR->pchrname, pchState, pRR->rlen)) {
  477. X            break;
  478. X        }
  479. X    }
  480. X    if (MY_NLIMITS == i) {
  481. X        return pchState;
  482. X    }
  483. X
  484. X    do {
  485. X        ++pchTemp;
  486. X    } while (isspace(*pchTemp));
  487. X    if (isdigit(*pchTemp)) {
  488. X        pRR->fset = 1;
  489. X        pRR->ourlim.rlim_cur = atol(pchTemp);
  490. X        fSetCur = 1;
  491. X        do {
  492. X            ++pchTemp;
  493. X        } while (isdigit(*pchTemp));
  494. X    }
  495. X    if ('/' == *pchTemp)
  496. X        ++pchTemp;
  497. X    while (isspace(*pchTemp))
  498. X        ++pchTemp;
  499. X
  500. X    if (isdigit(*pchTemp)) {
  501. X        pRR->fset = 1;
  502. X        pRR->ourlim.rlim_max = atol(pchTemp);
  503. X        fSetMax = 1;
  504. X        do {
  505. X            ++pchTemp;
  506. X        } while (isdigit(*pchTemp));
  507. X    }
  508. X    while (isspace(*pchTemp))
  509. X        ++pchTemp;
  510. X    if (fSetMax != fSetCur) {    /* only one set, set both same    */
  511. X        if (fSetMax) {
  512. X            pRR->ourlim.rlim_cur = pRR->ourlim.rlim_max;
  513. X        } else {
  514. X            pRR->ourlim.rlim_max = pRR->ourlim.rlim_cur;
  515. X        }
  516. X    }
  517. X    return pchTemp;
  518. }
  519. X
  520. int r_fTrace = 0;
  521. static int iChildPid, fWarned;
  522. X
  523. /*
  524. X * trap a time out for a "real time" alarm
  525. X */
  526. int
  527. do_alarm()
  528. {
  529. X    register unsigned next;
  530. X    if (kill(iChildPid, fWarned++ ? SIGALRM : SIGKILL) < 0) {
  531. X        fprintf(stderr, "%s: %d: ", "rlimsys", iChildPid);
  532. X        perror("kill");
  533. X        exit(1);
  534. X    }
  535. X    next = (unsigned)(sbRRLimits[MY_CLOCK].ourlim.rlim_max -
  536. X        sbRRLimits[MY_CLOCK].ourlim.rlim_cur);
  537. X    if (0 == next) {
  538. X        next = 2;
  539. X    }
  540. X    alarm(next);
  541. }
  542. X
  543. /*
  544. X * emulate "system" with a CPU limit
  545. X */
  546. int
  547. rlimsys(pchCmd)
  548. char *pchCmd;
  549. {
  550. #if defined(bsd)
  551. X    auto union wait waitbuf;
  552. #else
  553. X    auto int waitbuf;
  554. #endif
  555. X    register int wret;
  556. #if SUNOS >= 40
  557. X    register void (*atrap)(), (*itrap)(), (*qtrap)();
  558. #else /* !SUNOS40 */
  559. X    register int (*atrap)(), (*itrap)(), (*qtrap)();
  560. #endif /* SUNOS40 */
  561. X    register int i;
  562. X    register RES_REC *pRR;
  563. X    auto int iRetCode;
  564. X
  565. X    iChildPid = vfork();
  566. X    switch (iChildPid) {
  567. X    case 0:
  568. X        for (i = 0; i < MY_NLIMITS; ++i) {
  569. X            pRR = & sbRRLimits[i];
  570. X            if (pRR->fset && pRR->fsys) {
  571. X                setrlimit(pRR->rtype, & pRR->ourlim);
  572. X            }
  573. X        }
  574. X        execl("/bin/sh", "sh", r_fTrace ? "-cx" : "-c", pchCmd, 0);
  575. X        _exit(127);
  576. X    case -1:
  577. X        perror("rlimsys: fork");
  578. X        return 1;
  579. X    default:
  580. X        break;
  581. X    }
  582. X
  583. X    itrap = signal(SIGINT, SIG_IGN);
  584. X    qtrap = signal(SIGQUIT, SIG_IGN);
  585. X
  586. X    if (sbRRLimits[MY_CLOCK].fset) {
  587. X        atrap = signal(SIGALRM, do_alarm);
  588. X        alarm((unsigned)sbRRLimits[MY_CLOCK].ourlim.rlim_cur);
  589. X    }
  590. X    for (;;) {
  591. X        if (iChildPid == (wret = wait3(& waitbuf, WUNTRACED, (struct rusage *)0))) {
  592. X            if (WIFSTOPPED(waitbuf)) {
  593. X                if (kill(iChildPid, SIGCONT) < 0) {
  594. X                    break;
  595. X                }
  596. X                continue;
  597. X            }
  598. X            if (WIFSIGNALED(waitbuf)) {
  599. X                iRetCode = waitbuf.w_termsig;
  600. X            } else {
  601. X                iRetCode = waitbuf.w_retcode;
  602. X            }
  603. X            break;
  604. X        }
  605. X        if (wret == -1) {
  606. X            fprintf(stderr, "rlimsys: lost child %d\n", iChildPid);
  607. X            perror("rlimsys: wait");
  608. X            iRetCode = 1;
  609. X            break;
  610. X        }
  611. X    }
  612. X
  613. X    (void) signal(SIGINT, itrap);
  614. X    (void) signal(SIGQUIT, qtrap);
  615. X    if (sbRRLimits[MY_CLOCK].fset) {
  616. X        alarm((unsigned)0);
  617. X        (void) signal(SIGALRM, atrap);
  618. X    }
  619. X    return iRetCode;
  620. }
  621. X
  622. #endif /* resource usage */
  623. Purdue
  624. chmod 0444 mk/rlimsys.c ||
  625. echo 'restore of mk/rlimsys.c failed'
  626. Wc_c="`wc -c < 'mk/rlimsys.c'`"
  627. test 4889 -eq "$Wc_c" ||
  628.     echo 'mk/rlimsys.c: original size 4889, current size' "$Wc_c"
  629. fi
  630. # ============= mk-lib/mk.5l ==============
  631. if test ! -d 'mk-lib'; then
  632.     echo 'x - creating directory mk-lib'
  633.     mkdir 'mk-lib'
  634. fi
  635. if test -f 'mk-lib/mk.5l' -a X"$1" != X"-c"; then
  636.     echo 'x - skipping mk-lib/mk.5l (File already exists)'
  637. else
  638. echo 'x - extracting mk-lib/mk.5l (Text)'
  639. sed 's/^X//' << 'Purdue' > 'mk-lib/mk.5l' &&
  640. .\" how to code an mk marker line
  641. .TH MK 5L LOCAL
  642. .SH NAME
  643. mk \- how to write and embed \fBmk\fP commands
  644. .SH SYNOPSIS
  645. \fB$\fP \fImarker\fP[\fB(\fP\fIsubmarker\fP\fB)\fP] [\fB=\fP[\fB~\fP]\fIexit\-status\fP] [\fB,\fP\fIresource\fP\fB=\fP[\fIlimit\fP][\fB/\fP\fImaximum\fP]] \fB:\fP \fIcommand\fP [ \fB$$\fP ]
  646. .SH COMMANDS
  647. .I Mk
  648. is a utility for detecting and executing shell commands within files.
  649. Normally, when the named files contain source language statements,
  650. the commands are contained in lines that appear as comments to
  651. the language processor.
  652. This is merely a convention, however, and is not a
  653. .I mk
  654. requirement.
  655. .PP
  656. .I Mk
  657. commands are always given to \fIsh\fP(1) for execution.
  658. It is the convention of the authors to use an indirect
  659. name for the \*(lqkey\*(rq UNIX tools in each command.
  660. For example when a command requires the use of a language processor,
  661. like cc(1), one might use the shell form
  662. .sp 1
  663. X    ${cc-cc} ...
  664. .sp 1
  665. so that different versions of the compiler (cc or gcc) or cross
  666. compilers might be used in place of the default compiler.
  667. .PP
  668. Some compilers required a special optimization level for debugging.
  669. A hook for this option is usually provided by a variable whose
  670. name ends in the string \*(lq_debug\*(rq
  671. .sp 1
  672. X    ${cc-cc} ${cc_debug-\-O} ...
  673. .sp 1
  674. This allows the user to simply set an environment variable when
  675. debugging a product.
  676. .PP
  677. The default load name, \*(lqa.out\*(rq, should \fBnot\fP be used as an
  678. output file, if it can be avoided,
  679. (such default actions are available via the compiler itself).
  680. .I Mk
  681. rules generally use the basename of the given file as an output
  682. file (see \fImk\fP(1l) for a description of all the percent escapes).
  683. .sp 1
  684. X    ${cc-cc} ${cc_debug-\-O} \-o %F ...
  685. .sp 1
  686. .PP
  687. If any special flags must be included to compile this program,
  688. or several options cause different versions to be built they should
  689. be specified next:
  690. .sp 1
  691. X    ${cc-cc} ${cc_debug-\-O} \-o %F ...
  692. .br
  693. X    ${cc-cc} ${cc_debug-\-g} \-o %F \-DDEBUG ...
  694. .sp 1
  695. .PP
  696. The name of the source file should be followed by any libraries
  697. that the product needs to load against.
  698. .sp 1
  699. X    ${cc-cc} ${cc_debug-\-O} \-o %F \-DNORMAL %f \-lm
  700. .sp 1
  701. .PP
  702. Sometimes recursive calls to \fImk\fP are the best way to
  703. solve a complex problem.
  704. The escapes \fImk\fP provides for recursive calls (%b, %o, %\fIoption\fP)
  705. are used to pass down the command line switches that might be important:
  706. .sp 1
  707. X    %b %o \-mStep1 %f && %b %o \-mStep2 %f
  708. .sp 1
  709. Sometimes one might want to force an option to a recursive call, but
  710. leave the others as given (in this case we force \-a):
  711. .sp 1
  712. X    %b \-a%C%I%N%V \-m%m %f
  713. .sp 1
  714. .SH "MARKED LINES"
  715. .PP
  716. The default \fImarker\fP \fBmk\fP searches for is \*(lqCompile\*(rq.
  717. A marker is, in effect, a verb that is applied to a file, these are
  718. the markers \fImk\fP has conventions for (by default):
  719. .sp 1
  720. .RS
  721. .TS
  722. l l.
  723. Clean    remove any junk this file might produce
  724. Compile    produce an binary from this file
  725. Display    produce an output from this file
  726. Info    output a description of what \fBmk\fP thinks is in the file
  727. Laser    format this file to produce a hard copy
  728. Run    execute this file (if possible)
  729. Mkcat    format a manual page for the \fImkcat\fP(8l) program
  730. .TE
  731. .RE
  732. .sp 1
  733. Other markers will be added as needed.
  734. .PP
  735. A submarker is a modifier on the verb.
  736. These are used to choose marked lines when more than on marked
  737. line might server.
  738. Submarkers are still primitive.
  739. .PP
  740. Currently few submarkers have a defined meaning to \fImk\fP:
  741. .RS
  742. .TS
  743. l l.
  744. debug    generate a debugging version
  745. test    generate a test program for this module
  746. verbose    be more verbose
  747. \fIos\fP    generate a version for the given operating system
  748. X    SYSV, bsd, hpux, posix
  749. .TE
  750. .RE
  751. .SH "MATCHING"
  752. .PP
  753. These rules cause a match for marked lines in any file \fImk\fP searches:
  754. .RS
  755. \(bu the special marker \*(lq*\*(rq matches any \fImarker\fP
  756. .br
  757. \(bu the special submarker \*(lq*\*(rq matches any \fIsubmarker\fP
  758. .br
  759. \(bu the marker from the line must match \fImarker\fP
  760. .br
  761. \(bu if a \fIsubmarker\fP was given on the command line it must be matched
  762. .br
  763. \(bu case differentiates markers and submarkers unless \-\fBi\fP was given
  764. .br
  765. .RE
  766. .PP
  767. Thus we have a table of \fImk\fP invokations versus markers:
  768. .RS
  769. .TS
  770. l l l l
  771. l c c c.
  772. Marker    \-mTest    \-mTest \-ddebug    \-mTest -d'*'
  773. $Fail    no    no    no
  774. $Test    yes    no    no
  775. $Test(bsd)    yes    no    yes
  776. $Test(debug)    yes    yes    yes
  777. $Test(*)    yes    yes    yes
  778. $*    yes    no    no
  779. $*(bsd)    yes    no    yes
  780. $*(debug)    yes    yes    yes
  781. $*(*)    yes    yes    yes
  782. .TE
  783. .RE
  784. .PP
  785. When coding a template file the $\fImarker\fP(*): form is used to
  786. assure a match.
  787. .SH TEMPLATES
  788. .PP
  789. By using \fImk\fP's template's options
  790. the user might build a default rule for a given application.
  791. \fIMk\fP will expand each element of the template path as if
  792. it were a \fIcommand\fP, then try to read the generated filename.
  793. If the file exists and contains a marked line that matches
  794. the current marker \fImk\fP will use that command.
  795. .PP
  796. \fIMk\fP has a set of default templates under some directory
  797. (likely \fI/usr/local/lib/mk\fP) these are scanned if no other
  798. \-\fBe\fP or \-\fBt\fP options are given.
  799. The root of this directory is provided by the %~ escape to
  800. allow users to reference these templates.
  801. .PP
  802. The default list of templates may be examined with ``\fImk\fP \-\fBV\fP''.
  803. .PP
  804. The default \fImk\fP templates have a naming convention which also
  805. determines the order in which they are searched.
  806. .RS
  807. .TS
  808. l l.
  809. type-%y    trap based on file type
  810. pre-%x    trap extenders that represent nontext files
  811. comma-%U    trap RCS files
  812. file-%F    trap files with special names
  813. dot-%x    trap text file extenders
  814. m-%M    trap based on marker given
  815. .TE
  816. .RE
  817. .SH FAILURE
  818. .PP
  819. Some markers can detect that they have failed and that the user might
  820. want to take corrective or special action in this case.
  821. The convention in such cases is to call the shell form:
  822. .sp 1
  823. X    ${false-false}
  824. .sp 1
  825. to allow the user a ``hook'' with which to trap the error.
  826. .SH EXAMPLES
  827. .TP
  828. $\&All: %b %o \-mCompile *.c
  829. Compile all the C source files in this directory using their own
  830. rules.
  831. .TP
  832. $\e&Compile: ...
  833. A trick to avoid letting mk see a marked line in an examples
  834. section of a manual page.
  835. .TP
  836. $\&Compile(debug): ${cc-cc} ${cc_debug-\-g} \-o %F \-DDEBUG %f \-lm
  837. This line will match only if \-\fBd\fPdebug or \-\fBd\fP'*' were given.
  838. .TP
  839. $\&Compile(*): ${cc-cc} ${cc_debug-\-O} \-o %F %f \-lm
  840. This line will match any default request.
  841. .TP
  842. $\&*(*): echo \'%B: %m: unknown marker\' && ${false-false}
  843. This marked line will output an error message for any marker, and fail.
  844. .SH BUGS
  845. .PP
  846. Use of \fIrcs\fP(1) keywords as markers
  847. (Author, Date, Header, Id, Locker, Log, RCSfile, Revision, Source, State)
  848. might give unexpected results.
  849. .SH AUTHORS
  850. S. McGeady, Intel, Inc., mcg@mipon2.intel.com
  851. .sp 1
  852. Kevin Braunsdorf, Purdue University Computing Center (ksb@cc.purdue.edu)
  853. .SH "SEE ALSO"
  854. mk(1l), sh(1),
  855. printf(3)
  856. Purdue
  857. chmod 0444 mk-lib/mk.5l ||
  858. echo 'restore of mk-lib/mk.5l failed'
  859. Wc_c="`wc -c < 'mk-lib/mk.5l'`"
  860. test 6777 -eq "$Wc_c" ||
  861.     echo 'mk-lib/mk.5l: original size 6777, current size' "$Wc_c"
  862. fi
  863. # ============= mkcat/mkcat.8l ==============
  864. if test -f 'mkcat/mkcat.8l' -a X"$1" != X"-c"; then
  865.     echo 'x - skipping mkcat/mkcat.8l (File already exists)'
  866. else
  867. echo 'x - extracting mkcat/mkcat.8l (Text)'
  868. sed 's/^X//' << 'Purdue' > 'mkcat/mkcat.8l' &&
  869. .\" Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
  870. .\" 47907.  All rights reserved.
  871. .\"
  872. .\" Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
  873. .\"           Jeff Smith, jsmith@cc.purdue.edu, purdue!jsmith
  874. .\"
  875. .\" This software is not subject to any license of the American Telephone
  876. .\" and Telegraph Company or the Regents of the University of California.
  877. .\"
  878. .\" Permission is granted to anyone to use this software for any purpose on
  879. .\" any computer system, and to alter it and redistribute it freely, subject
  880. .\" to the following restrictions:
  881. .\"
  882. .\" 1. Neither the authors nor Purdue University are responsible for any
  883. .\"    consequences of the use of this software.
  884. .\"
  885. .\" 2. The origin of this software must not be misrepresented, either by
  886. .\"    explicit claim or by omission.  Credit to the authors and Purdue
  887. .\"    University must appear in documentation and sources.
  888. .\"
  889. .\" 3. Altered versions must be plainly marked as such, and must not be
  890. .\"    misrepresented as being the original software.
  891. .\"
  892. .\" 4. This notice may not be removed or altered.
  893. .\"
  894. .\" $Id: mkcat.8l,v 3.2 90/06/12 14:29:45 ksb Exp $
  895. .\"
  896. .\" $Laser: ${tbl-tbl} %f | ${ltroff-ltroff} -man
  897. .\" $Compile: ${tbl-tbl} %f | ${nroff-nroff} -man | ${PAGER-${more-more}}
  898. .TH MKCAT 8L LOCAL
  899. .SH NAME
  900. mkcat \- update and format a manual page
  901. .SH SYNOPSIS
  902. \fBmkcat\fP [-\fBDIfnsv\fP] [-\fBc\fP \fIcatdirs\fP] [-\fBm\fP \fIman\fP] [-\fBr\fP \fIroot\fP] [-\fBw\fP \fIdatabase\fP] \fIpages\fP
  903. .br
  904. \fBmkcat\fP [-\fBVLRWh\fP] [-\fBc\fP \fIcatdirs\fP] [-\fBm\fP \fIman\fP] [-\fBr\fP \fIroot\fP] [-\fBw\fP \fIdatabase\fP]
  905. .SH DESCRIPTION
  906. \fIMkcat\fP formats the given \fIpages\fP and installs them in the standard
  907. manual structure.
  908. \fIMkcat\fP updates the \fIwhatis\fP(1) database and creates links
  909. to the installed page to represent alternate names for the page
  910. given in the \fBNAME\fP section of the formatted page.
  911. .PP
  912. \fIMkcat\fP depends heavily on the \fBmk\fP(1l) program to extract
  913. shell commands to format each page.
  914. The \fImk\fP program extracts any special format directive from the first 99
  915. lines of the manual page source file which are marked with the
  916. \*(lqMkcat\*(rq marker.
  917. See the examples below.
  918. .PP
  919. Under the \fB\-D\fP option \fImkcat\fP deletes antiquated pages.
  920. .SH OPTIONS
  921. .TP
  922. .BI \-c catdirs
  923. Specify \fIcatdirs\fP as the prefix for all the cat directories.
  924. The default is \*(lqcat\*(rq which makes the standard manual system
  925. directories \*(lqcat1\*(rq, \*(lqcat2\*(rq, \*(lqcat3\*(rq, ... etc.
  926. These are used to store manual pages from the corresponding section of
  927. the manual.
  928. .TP
  929. .BI \-D
  930. Delete (rather than install) the given \fIpages\fP.
  931. The associated \fIwhatis\fP(1) entries are removed as
  932. well as any links.
  933. .TP
  934. .BI \-f
  935. The given manual pages are already formatted, simply install (delete) them.
  936. .TP
  937. .BI \-h
  938. Print a short help message.
  939. .TP
  940. .BI \-I
  941. Install the given manual page and update the whatis database.
  942. (This is the default action.)
  943. .TP
  944. .BI \-L
  945. Only rebuild missing links to the cat pages.
  946. .TP
  947. .BI \-m man
  948. When this option is specified \fImkcat\fP copies the manual page
  949. source into a parallel \fIman\fP directory.
  950. This mocks the old manual system.
  951. .TP
  952. .BI \-n
  953. Do not really run any commands.
  954. This option outputs the approximate actions of \fImkcat\fP in
  955. shell commands.
  956. .TP
  957. .BI \-r root
  958. Specify a user defined root for the manual system.
  959. The default is \*(lq\fI/usr/man\fP\*(rq.
  960. This allows users to make their own manual systems in their accounts.
  961. .TP
  962. .BI \-s
  963. Do not output descriptions of the shell commands as they are run.
  964. This is the default.
  965. .TP
  966. .BI \-v
  967. Be verbose by displaying shell commands as they are run.
  968. .TP
  969. .BI \-V
  970. Show the current configuration of the manual system.
  971. .TP
  972. .BI \-w database
  973. Specify a \fIwhatis\fP(1) database to update.
  974. The default \fIdatabase\fP is \*(lqwhatis\*(rq from the \fIroot\fP
  975. of the manual system.
  976. If this is a full path name \fIroot\fP is not prepended to it.
  977. .TP
  978. .BI \-R
  979. Install a new root manual system, specify the new root with \-\fBr\fP.
  980. If a options file exits in that directory it is used as the defaults
  981. for the new system.
  982. .TP
  983. .BI \-W
  984. Just rebuild the whatis database.
  985. .TP
  986. .BI \-Z
  987. Verify that all the cat pages are (un)compressed.
  988. .SH EXAMPLES
  989. .TP
  990. mkcat -v -r/usr/man -R
  991. Install mkcat's configuration file in /usr/man.
  992. .TP
  993. mkcat ls.1
  994. Update the \fIls\fP(1) manual page and \fIwhatis\fP(1) entry.
  995. .TP
  996. mkcat -cnew sleep.1 sleep.3
  997. Update both \fIsleep\fP(1) manual pages and \fIwhatis\fP(1) entries
  998. in the \*(lqnew\*(rq cat directory.
  999. .TP
  1000. mkcat -D catman.8
  1001. Delete the outdated \fIcatman\fP(8) manual page.
  1002. .TP
  1003. mkcat -r $HOME/man myprog.1g
  1004. Update the \fImyprog\fP(1g) manual page in the user\'s own manual system.
  1005. X
  1006. .TP
  1007. \&.\e" $\&Mkcat: tbl %f | nroff -man.nopage
  1008. \fBUltrix\fP manual pages require the nopage macro package.
  1009. .TP
  1010. \&.\e" $\&Mkcat: neqn %f | tbl | nroff -man | colcrt
  1011. This line runs the \fIneqn\fP(1) processor in addition to \fItbl\fP(1) and
  1012. \fInroff\fP(1).
  1013. .TP
  1014. \&.\e" $\&Mkcat: nroff -mlocal %f | cat -s
  1015. This manual page uses a local macro package, and doesn't use \fItbl\fP.
  1016. .SH FILES
  1017. .TS
  1018. l l.
  1019. /usr/man/whatis    the default \fIwhatis\fP(1) database
  1020. /usr/man/cat[1-8]    the default cat directories
  1021. /usr/man/.mkcat-opts    the manual system configuration
  1022. .TE
  1023. .SH BUGS
  1024. .PP
  1025. Under the \fB\-n\fP option \fImkcat\fP cannot always predict the links
  1026. it would make.
  1027. .SH AUTHOR
  1028. Kevin Braunsdorf
  1029. .br
  1030. Purdue UNIX Group
  1031. .br
  1032. ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
  1033. .SH "SEE ALSO"
  1034. apropos(1), colcrt(1), compress(1), man(1), mk(1l), neqn(1), nroff(1),
  1035. tbl(1), whatis(1),
  1036. catman(8)
  1037. Purdue
  1038. chmod 0444 mkcat/mkcat.8l ||
  1039. echo 'restore of mkcat/mkcat.8l failed'
  1040. Wc_c="`wc -c < 'mkcat/mkcat.8l'`"
  1041. test 5555 -eq "$Wc_c" ||
  1042.     echo 'mkcat/mkcat.8l: original size 5555, current size' "$Wc_c"
  1043. fi
  1044. # ============= mkcat/sym2hard.c ==============
  1045. if test -f 'mkcat/sym2hard.c' -a X"$1" != X"-c"; then
  1046.     echo 'x - skipping mkcat/sym2hard.c (File already exists)'
  1047. else
  1048. echo 'x - extracting mkcat/sym2hard.c (Text)'
  1049. sed 's/^X//' << 'Purdue' > 'mkcat/sym2hard.c' &&
  1050. /*
  1051. X * $Id: sym2hard.c,v 3.1 90/11/28 09:44:14 ksb Exp $
  1052. X *
  1053. X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
  1054. X * 47907.  All rights reserved.
  1055. X *
  1056. X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
  1057. X *
  1058. X * This software is not subject to any license of the American Telephone
  1059. X * and Telegraph Company or the Regents of the University of California.
  1060. X *
  1061. X * Permission is granted to anyone to use this software for any purpose on
  1062. X * any computer system, and to alter it and redistribute it freely, subject
  1063. X * to the following restrictions:
  1064. X *
  1065. X * 1. Neither the authors nor Purdue University are responsible for any
  1066. X *    consequences of the use of this software.
  1067. X *
  1068. X * 2. The origin of this software must not be misrepresented, either by
  1069. X *    explicit claim or by omission.  Credit to the authors and Purdue
  1070. X *    University must appear in documentation and sources.
  1071. X *
  1072. X * 3. Altered versions must be plainly marked as such, and must not be
  1073. X *    misrepresented as being the original software.
  1074. X *
  1075. X * 4. This notice may not be removed or altered.
  1076. X */
  1077. X
  1078. /*
  1079. X * this code replaces a symbolic link with a hard link            (ksb)
  1080. X *
  1081. X * N.B. this is questionable code in any case....
  1082. X */
  1083. X
  1084. #include "machine.h"
  1085. X
  1086. #include <stdio.h>
  1087. #include <errno.h>
  1088. #include <sys/types.h>
  1089. #include <sys/param.h>
  1090. #include <sys/file.h>
  1091. #include <sys/stat.h>
  1092. X
  1093. #include "main.h"
  1094. X
  1095. #if !defined(MAXPATHLEN)
  1096. #define MAXPATHLEN    1024
  1097. #endif
  1098. X
  1099. #if !defined(ELOOP)
  1100. #define ELOOP    ENOENT
  1101. #endif    /* ZZZZ ETA kludge ZZZZ */
  1102. X
  1103. #if HAVE_SLINKS
  1104. X
  1105. extern int errno;
  1106. extern char *sys_errlist[];
  1107. #define strerror(Me) sys_errlist[Me]
  1108. X
  1109. X
  1110. extern char *getwd();
  1111. typedef struct SRnode {
  1112. X    struct stat *pst;
  1113. X    struct SRnode *psr;
  1114. } STREC;
  1115. X
  1116. /*
  1117. X * copy the parrent directory of pcFile to pcDir, which is a buffer    (ksb)
  1118. X * given by the user. returns the `tail part'
  1119. X */
  1120. static char *
  1121. getparent(pcFile, pcDir)
  1122. char *pcFile, *pcDir;
  1123. {
  1124. X    register char *pcTail;
  1125. X    extern char *strcpy(), *strrchr();
  1126. X
  1127. X    if ((char *)0 == (pcTail = strrchr(pcFile, '/'))) {
  1128. X        (void)strcpy(pcDir, ".");
  1129. X        return pcFile;
  1130. X    } else if (pcFile == pcTail) {
  1131. X        (void)strcpy(pcDir, "/");
  1132. X        return pcFile+1;
  1133. X    }
  1134. X    *pcTail = '\000';
  1135. X    (void)strcpy(pcDir, pcFile);
  1136. X    *pcTail = '/';
  1137. X    return pcTail+1;
  1138. }
  1139. X
  1140. /*
  1141. X * do one level of sym2hard                        (ksb)
  1142. X *
  1143. X * pcLink is a symbolic link that should be a hard link
  1144. X * (we convert all interveining symbolic links while we are at it)
  1145. X *
  1146. X * stat the symbolic link, is it a file? we are done.
  1147. X * check for loops, maybe return ELOOP
  1148. X * record pwd so we can get back
  1149. X * read the link into acRead
  1150. X * cd to acRead's parrent directory
  1151. X * recurse on acRead's tail
  1152. X * cd back
  1153. X * stat acRead, on the same device, and a plain file? not -> bomb out
  1154. X * remove pcLink, and re-link to acRead
  1155. X */
  1156. static int
  1157. sym1Hard(pcLink, pSRPrev)
  1158. char *pcLink;
  1159. STREC *pSRPrev;
  1160. {
  1161. X    auto char acRead[MAXPATHLEN+1];
  1162. X    auto char acNext[MAXPATHLEN+1];
  1163. X    auto char acPwd[MAXPATHLEN+1];
  1164. X    auto struct stat stLink, stRead;
  1165. X    auto STREC SR, *pSR;
  1166. X    register int i;
  1167. X    register char *pcTail;
  1168. X
  1169. X    if (0 != lstat(pcLink, & stLink)) {
  1170. X        fprintf(stderr, "%s: lstat: %s: %s\n", progname, pcLink, strerror(errno));
  1171. X        return -1;
  1172. X    }
  1173. X    for (pSR = pSRPrev; (STREC *)0 != pSR; pSR = pSR->psr) {
  1174. X        if (pSR->pst->st_dev == stLink.st_dev &&
  1175. X            pSR->pst->st_ino == stLink.st_ino) {
  1176. X            errno = ELOOP;
  1177. X            return -1;
  1178. X        }
  1179. X    }
  1180. X    SR.pst = & stLink;
  1181. X    SR.psr = pSRPrev;
  1182. X    switch (stLink.st_mode & S_IFMT) {
  1183. X    default:
  1184. X        errno = EEXIST;
  1185. X        return -1;
  1186. X    case 0:
  1187. X    case S_IFREG:    /* regular */
  1188. X        return 0;
  1189. X    case S_IFLNK:    /* symbolic link */
  1190. X        break;
  1191. X    }
  1192. X
  1193. X    if (-1 == (i = readlink(pcLink, acRead, MAXPATHLEN))) {
  1194. X        fprintf(stderr, "%s: readlink: %s: %s\n", progname, pcLink, strerror(errno));
  1195. X        return -1;
  1196. X    }
  1197. X    acRead[i] = '\000';
  1198. X
  1199. X    if ((char *)0 == getwd(acPwd)) {
  1200. X        fprintf(stderr, "%s: getwd: %s\n", progname, acPwd);
  1201. X        return -1;
  1202. X    }
  1203. X
  1204. X    pcTail = getparent(acRead, acNext);
  1205. X    if (-1 == chdir(acNext)) {
  1206. X        return -1;
  1207. X    }
  1208. X    if (-1 == sym1Hard(pcTail, & SR)) {
  1209. X        return -1;
  1210. X    }
  1211. X    if (-1 == chdir(acPwd)) {
  1212. X        return -1;
  1213. X    }
  1214. X
  1215. X    if (0 != stat(acRead, & stRead)) {
  1216. X        fprintf(stderr, "%s: stat: %s: %s\n", progname, pcLink, strerror(errno));
  1217. X        return -1;
  1218. X    }
  1219. X    if (stLink.st_dev != stRead.st_dev || S_IFREG != (stRead.st_mode & S_IFMT)) {
  1220. X        errno = EXDEV;
  1221. X        return -1;
  1222. X    }
  1223. X
  1224. X    if (fVerbose) {
  1225. X        printf("%s: rm -f %s\n", progname, pcLink);
  1226. X    }
  1227. X    if (fExec && unlink(pcLink)) {
  1228. X        fprintf(stderr, "%s: unlink: %s: %s\n", progname, pcLink, strerror(errno));
  1229. X        return     -1;
  1230. X    }
  1231. X    if (fVerbose) {
  1232. X        printf("%s: ln %s %s\n", progname, acRead, pcLink);
  1233. X    }
  1234. X    if (fExec && link(acRead, pcLink)) {
  1235. X        fprintf(stderr, "%s: link: %s to %s: %s\n", progname, acRead, pcLink, strerror(errno));
  1236. X        return     -1;
  1237. X    }
  1238. X
  1239. X    return 0;
  1240. }
  1241. X
  1242. /*
  1243. X * we need a wrapper around sym1Hard to restore the top level directory    (ksb)
  1244. X */
  1245. int
  1246. sym2Hard(pcLink)
  1247. char *pcLink;
  1248. {
  1249. X    auto char acNext[MAXPATHLEN+1];
  1250. X    auto char acPwd[MAXPATHLEN+1];
  1251. X    register int i;
  1252. X    register char *pcTail;
  1253. X
  1254. X    if ((char *)0 == getwd(acPwd)) {
  1255. X        fprintf(stderr, "%s: getwd: %s\n", progname, acPwd);
  1256. X        return -1;
  1257. X    }
  1258. X
  1259. X    pcTail = getparent(pcLink, acNext);
  1260. X    if (-1 == chdir(acNext)) {
  1261. X        return -1;
  1262. X    }
  1263. X
  1264. X    i = sym1Hard(pcTail, (STREC *)0);
  1265. X
  1266. X    (void) chdir(acPwd);
  1267. X    return i;
  1268. }
  1269. X
  1270. #endif
  1271. Purdue
  1272. chmod 0444 mkcat/sym2hard.c ||
  1273. echo 'restore of mkcat/sym2hard.c failed'
  1274. Wc_c="`wc -c < 'mkcat/sym2hard.c'`"
  1275. test 5149 -eq "$Wc_c" ||
  1276.     echo 'mkcat/sym2hard.c: original size 5149, current size' "$Wc_c"
  1277. fi
  1278. # ============= mkcat/mkcat-opts.5l ==============
  1279. if test -f 'mkcat/mkcat-opts.5l' -a X"$1" != X"-c"; then
  1280.     echo 'x - skipping mkcat/mkcat-opts.5l (File already exists)'
  1281. else
  1282. echo 'x - extracting mkcat/mkcat-opts.5l (Text)'
  1283. sed 's/^X//' << 'Purdue' > 'mkcat/mkcat-opts.5l' &&
  1284. .\" Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
  1285. .\" 47907.  All rights reserved.
  1286. .\"
  1287. .\" Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
  1288. .\"
  1289. .\" This software is not subject to any license of the American Telephone
  1290. .\" and Telegraph Company or the Regents of the University of California.
  1291. .\"
  1292. .\" Permission is granted to anyone to use this software for any purpose on
  1293. .\" any computer system, and to alter it and redistribute it freely, subject
  1294. .\" to the following restrictions:
  1295. .\"
  1296. .\" 1. Neither the authors nor Purdue University are responsible for any
  1297. .\"    consequences of the use of this software.
  1298. .\"
  1299. .\" 2. The origin of this software must not be misrepresented, either by
  1300. .\"    explicit claim or by omission.  Credit to the authors and Purdue
  1301. .\"    University must appear in documentation and sources.
  1302. .\"
  1303. .\" 3. Altered versions must be plainly marked as such, and must not be
  1304. .\"    misrepresented as being the original software.
  1305. .\"
  1306. .\" 4. This notice may not be removed or altered.
  1307. .\"
  1308. .\" $Id: mkcat-opts.5l,v 3.0 90/06/01 11:47:31 ksb Exp $
  1309. .\"
  1310. .\" $Laser: ${tbl-tbl} %f | ${ltroff-ltroff} -man
  1311. .\" $Compile: ${tbl-tbl} %f | ${nroff-nroff} -man | ${PAGER-${more-more}}
  1312. .TH MKCAT-OPTS 5L PUCC
  1313. .SH NAME
  1314. mkcat-opts \- manual system configuration file
  1315. .SH SYNOPSIS
  1316. .B /usr/man/.mkcat-opts
  1317. .SH DESCRIPTION
  1318. .PP
  1319. The manual system is a complex database built on top of the UNIX file
  1320. system which is updated almost entirely by the \fImkcat\fP(8L) program.
  1321. So that each user of \fImkcat\fP doesn't have to specify many options
  1322. to update a single manual page, many defaults are kept in a single file
  1323. at the root of the manual system.
  1324. The paragraphs below describe the options available in this file.
  1325. .PP
  1326. Any line which begins with a pounds sign (`#') is taken to be a comment.
  1327. .PP
  1328. The formatted manual pages (called \*(lqcat\*(rq pages) may either be
  1329. stored compressed or as plain ASCII files.
  1330. Compressed files usually save disk space, uncompressed (ASCII) files
  1331. save a little CPU time when a user runs \fIman\fP(1).
  1332. To enable compression the options file may contain a line like:
  1333. .sp 1
  1334. X    compress: y
  1335. .sp 1
  1336. to keep the files as plain ASCII:
  1337. .sp 1
  1338. X    compress: n
  1339. .PP
  1340. Manual pages which contain descriptions of more than one command
  1341. (have multiple words before the `\-' in the NAME section)
  1342. are made available under all their names.
  1343. This service is provided by linking all the names to the formatted
  1344. manual page (see \fIln\fP(1)).
  1345. Either hard links or symbolic links may be used for the auxiliary
  1346. names for the pages.
  1347. For symbolic links:
  1348. .sp 1
  1349. X    links: S
  1350. .sp 1
  1351. for hard links:
  1352. .sp 1
  1353. X    links: H
  1354. .PP
  1355. When \fImkcat\fP installs a file in the manual system it
  1356. uses the \fIinstall\fP(1L) program.
  1357. If the system administrator prefers special modes on the manual
  1358. system's files, these modes may specified in the options file.
  1359. For example to change the mode and group on the installed cat pages:
  1360. .sp 1
  1361. X    pagemode: 0660
  1362. .br
  1363. X    pagegroup: mandoc
  1364. .sp 1
  1365. The \*(lqpage\*(rq above may be replaced by any of \*(lqwhatis\*(rq,
  1366. \*(lqdir\*(rq, or \*(lqman\*(rq which \fImkcat\fP uses respectively
  1367. for the whatis database, any directories, or the man page sources.
  1368. The owner may be specified as:
  1369. .sp 1
  1370. X    whatisowner: root
  1371. .br
  1372. X    dirowner: root
  1373. .sp 1
  1374. .PP
  1375. If the default \fB\-m\fP \fIman\fP directory compiled into \fImkcat\fP
  1376. is not acceptable one may be specified as:
  1377. .sp 1
  1378. X    man: \fIman\fP
  1379. .sp 1
  1380. likewise for the \fB\-w\fP \fIwhatis\fP and \fB\-c\fP \fIcat\fP options.
  1381. .PP
  1382. \fIMkcat\fP checks to be sure that each installed page is unique in its
  1383. section.
  1384. Some pages are purposely \fBnot\fP unique in a section; for example
  1385. getc.3f and getc.3s.
  1386. These may be explicitly exempted based on either the basename (getc)
  1387. or the extenders (3f, 3s).
  1388. To exempt all pages with conflict which end in 3f and 3s a line:
  1389. .sp 1
  1390. X    OKext: {3f,3s}
  1391. .sp 1
  1392. is placed in the options file.
  1393. To exempt just the getc pages:
  1394. .sp 1
  1395. X    OKbase: getc
  1396. .sp 1
  1397. .SH EXAMPLE
  1398. .RS
  1399. .nf
  1400. # mkcat install options (ksb)
  1401. compress: y
  1402. links: S
  1403. # allow group write, see install(1L)
  1404. pagemode: 0644/020
  1405. dirmode: 0755/020
  1406. whatismode: 0644/020
  1407. OKext: {3s,3f}
  1408. OKbase: intro
  1409. .fi
  1410. .RE
  1411. .SH FILES
  1412. .TS
  1413. l l.
  1414. /usr/man/.mkcat-opts    modes for installed files, link type, compression flag
  1415. .TE
  1416. .SH AUTHOR
  1417. Kevin Braunsdorf, PUCC UNIX Group, ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
  1418. .br
  1419. Copyright \*(co 1990 Purdue Research Foundation.  All rights reserved.
  1420. .SH "SEE ALSO"
  1421. compress(1), install(1L), ln(1), man(1), mkcat(8L), uncompress(1), zcat(1)
  1422. Purdue
  1423. chmod 0444 mkcat/mkcat-opts.5l ||
  1424. echo 'restore of mkcat/mkcat-opts.5l failed'
  1425. Wc_c="`wc -c < 'mkcat/mkcat-opts.5l'`"
  1426. test 4487 -eq "$Wc_c" ||
  1427.     echo 'mkcat/mkcat-opts.5l: original size 4487, current size' "$Wc_c"
  1428. fi
  1429. # ============= mk/Tests/file.x,y ==============
  1430. if test ! -d 'mk/Tests'; then
  1431.     echo 'x - creating directory mk/Tests'
  1432.     mkdir 'mk/Tests'
  1433. fi
  1434. if test -f 'mk/Tests/file.x,y' -a X"$1" != X"-c"; then
  1435.     echo 'x - skipping mk/Tests/file.x,y (File already exists)'
  1436. else
  1437. echo 'x - extracting mk/Tests/file.x,y (Text)'
  1438. sed 's/^X//' << 'Purdue' > 'mk/Tests/file.x,y' &&
  1439. $Compile: [ %f = "file.x,y" ] && for marker in Base Ext Cut Type\n\tdo\n\t\t%b %o -a -m$marker %f && echo "$marker test OK"\n\tdone
  1440. X
  1441. # base names
  1442. $Base(1): [ "file" = "%F" ]
  1443. $Base(2): [ "file" = "%P" ]
  1444. $Base(3): [ "file" = "%p" ]
  1445. X
  1446. # extentions
  1447. $Ext(1): [ "x,y" = "%x" ]
  1448. $Ext(2): [ "x,y" = "%X" ]
  1449. X
  1450. # Cuts on non-dot extenders that fail
  1451. $Cut(1): [ -z "%u@" ]
  1452. $Cut(2): [ "file.x,y" = "%q@" ]
  1453. $Cut(3)=~*: exit 1 # %U@
  1454. $Cut(4)=~*: exit 1 # %Q@
  1455. X
  1456. # Cuts on non-dot extenders that work
  1457. $Cut(5): [ "file.x" = "%q," ]
  1458. $Cut(6): [ "y" = "%u," ]
  1459. $Cut(7): [ "file.x" = "%Q," ]
  1460. $Cut(8): [ "y" = "%U," ]
  1461. X
  1462. # file type flags
  1463. $Type(1): [ "f" = "%y" ]%Yf
  1464. $Type(2)=~*: exit 1 # %Yd should stop xlation
  1465. $Type(3)=~*: exit 1 # %Y. should stop error
  1466. Purdue
  1467. chmod 0644 mk/Tests/file.x,y ||
  1468. echo 'restore of mk/Tests/file.x,y failed'
  1469. Wc_c="`wc -c < 'mk/Tests/file.x,y'`"
  1470. test 725 -eq "$Wc_c" ||
  1471.     echo 'mk/Tests/file.x,y: original size 725, current size' "$Wc_c"
  1472. fi
  1473. # ============= mk-lib/m-info ==============
  1474. if test -f 'mk-lib/m-info' -a X"$1" != X"-c"; then
  1475.     echo 'x - skipping mk-lib/m-info (File already exists)'
  1476. else
  1477. echo 'x - extracting mk-lib/m-info (Text)'
  1478. sed 's/^X//' << 'Purdue' > 'mk-lib/m-info' &&
  1479. # the Info target outputs a descriptive message                (ksb)
  1480. X
  1481. $Info(*): ${file-file} %f
  1482. $Info(*): ${echo-echo} type %y, extender %X
  1483. $Info(*): ${echo-echo} type %y
  1484. Purdue
  1485. chmod 0444 mk-lib/m-info ||
  1486. echo 'restore of mk-lib/m-info failed'
  1487. Wc_c="`wc -c < 'mk-lib/m-info'`"
  1488. test 159 -eq "$Wc_c" ||
  1489.     echo 'mk-lib/m-info: original size 159, current size' "$Wc_c"
  1490. fi
  1491. # ============= mkcat/main.c ==============
  1492. if test -f 'mkcat/main.c' -a X"$1" != X"-c"; then
  1493.     echo 'x - skipping mkcat/main.c (File already exists)'
  1494. else
  1495. echo 'x - extracting mkcat/main.c (Text)'
  1496. sed 's/^X//' << 'Purdue' > 'mkcat/main.c' &&
  1497. /*
  1498. X * machine generated cmd line parser
  1499. X */
  1500. X
  1501. #include "getopt.h"
  1502. #include <stdio.h>
  1503. #include "machine.h"
  1504. #include "mkcat.h"
  1505. X
  1506. char
  1507. X    *progname = "$Id$",
  1508. X    u_terse[] = " [-ADILRVWZfhnsv] [-c cat] [-m man] [-r root] [-w whatis] [pages]",
  1509. X    *u_help[] = {
  1510. X        "A        scan the formatted pages for SEE ALSO errors",
  1511. X        "D        delete the given pages from the cat directories",
  1512. X        "I        install the given pages (default action)",
  1513. X        "L        rebuild auxiliary links to cat pages",
  1514. X        "R        install a new manual root",
  1515. X        "V        show the version and configuration of this program",
  1516. X        "W        rebuild the whatis database from the cat pages",
  1517. X        "Z        check file compression and update",
  1518. X        "c cat    specify the prefix for cat directories (cat1 cat2 cat3...)",
  1519. X        "f        the given pages are already formatted, just use them",
  1520. X        "h        print this help message",
  1521. X        "m man    save the manual page source in parallel with the cat page",
  1522. X        "n        do not really change the manual system",
  1523. X        "r root   specify a user defined root for the manual system",
  1524. X        "s        be silent",
  1525. X        "v        be verbose by displaying shell commands as they are run",
  1526. X        "w whatis specify a whatis database to update",
  1527. X        "pages    the manual pages to be updated",
  1528. X        (char *)0
  1529. X    };
  1530. int
  1531. X    iExit = 0,
  1532. X    fCkAlso = 0,
  1533. X    fDelete = 0,
  1534. X    fGenInstck = 0,
  1535. X    fInstall = 0,
  1536. X    fMkLinks = 0,
  1537. X    fInitNew = 0,
  1538. X    fVersion = 0,
  1539. X    fMkWhatis = 0,
  1540. X    fJustComp = 0;
  1541. char
  1542. X    copyright[] = "@(#) Copyright 1990 Purdue Research Foundation.\nAll rights reserved.\n",
  1543. X    *pcCat = acCat;
  1544. int
  1545. X    fFormat = 1;
  1546. char
  1547. X    *pcMan = (char *)0;
  1548. int
  1549. X    fExec = 1;
  1550. char
  1551. X    *pcRoot = acRoot;
  1552. int
  1553. X    fVerbose = 0;
  1554. char
  1555. X    *pcWhatis = acWhatis;
  1556. X
  1557. static int sbiOnly['w'-'*'+1];
  1558. static char sbForbid[] = "%s: option `%c\' forbidden by `%c\'\n";
  1559. X
  1560. static void
  1561. chkonly(chOpt, fDup)
  1562. int chOpt, fDup;
  1563. {
  1564. X    register int chWas;
  1565. X
  1566. X    chWas = sbiOnly[chOpt-'*'];
  1567. X    if (fDup && chOpt == chWas) {
  1568. X        fprintf(stderr, "%s: option `%c\' cannot be given more than once\n", progname, chWas);
  1569. X        exit(1);
  1570. X    } else if (chWas < 0) {
  1571. X        fprintf(stderr, sbForbid, progname, chOpt, -chWas);
  1572. X        exit(1);
  1573. X    }
  1574. X    sbiOnly[chOpt-'*'] = chOpt;
  1575. }
  1576. X
  1577. static void
  1578. chkforbid(chOpt, pchList)
  1579. int chOpt;
  1580. char *pchList;
  1581. {
  1582. X    register int chCur;
  1583. X
  1584. X    while ('\000' != (chCur = *pchList++)) {
  1585. X        if (sbiOnly[chCur-'*'] > 0) {
  1586. X            fprintf(stderr, sbForbid, progname, chCur, chOpt);
  1587. X            exit(1);
  1588. X        }        
  1589. X        sbiOnly[chCur-'*'] = -chOpt;
  1590. X    }
  1591. }
  1592. X
  1593. /*
  1594. X * parser
  1595. X */
  1596. int
  1597. main(argc, argv)
  1598. int argc;
  1599. char **argv;
  1600. {
  1601. X    static char
  1602. X        sbOpt[] = "ADGILRVWZc:fhm:nr:svw:",
  1603. X        *u_pch = (char *)0;
  1604. X    static int
  1605. X        u_loop = 0;
  1606. X    register int curopt;
  1607. X    register char *pchEnv;
  1608. X    extern char *getenv();
  1609. X    extern char *strncpy();
  1610. X    extern int atoi();
  1611. X    extern char *strrchr();
  1612. X
  1613. X    progname = strrchr(argv[0], '/');
  1614. X    if ((char *)0 == progname)
  1615. X        progname = argv[0];
  1616. X    else
  1617. X        ++progname;
  1618. X    if ((char *)0 != (pchEnv = getenv("MKCAT")))
  1619. X        envopt(pchEnv);
  1620. X    while (EOF != (curopt = getopt(argc, argv, sbOpt))) {
  1621. X        switch (curopt) {
  1622. X        case BADARG:
  1623. X            fprintf(stderr, "%s: option %c needs a parameter\n", progname, optopt);
  1624. X            exit(1);
  1625. X        case BADCH:
  1626. X            fprintf(stderr, "%s: usage%s\n", progname, u_terse);
  1627. X            exit(1);
  1628. X        case 'A':
  1629. X            chkforbid('A', "IR");
  1630. X            fCkAlso = ! 0;
  1631. X            continue;
  1632. X        case 'D':
  1633. X            chkonly('D', 0);
  1634. X            chkforbid('D', "WIZLVR");
  1635. X            fDelete = ! 0;
  1636. X            continue;
  1637. X        case 'G':
  1638. X            fGenInstck = ! 0;
  1639. X            continue;
  1640. X        case 'I':
  1641. X            chkonly('I', 0);
  1642. X            chkforbid('I', "DLWZVR");
  1643. X            fInstall = ! 0;
  1644. X            continue;
  1645. X        case 'L':
  1646. X            chkonly('L', 0);
  1647. X            chkforbid('L', "DIZVR");
  1648. X            fMkLinks = ! 0;
  1649. X            continue;
  1650. X        case 'R':
  1651. X            chkonly('R', 0);
  1652. X            chkforbid('R', "WIZL");
  1653. X            fInitNew = ! 0;
  1654. X            continue;
  1655. X        case 'V':
  1656. X            chkonly('V', 0);
  1657. X            chkforbid('V', "WIZLD");
  1658. X            fVersion = ! 0;
  1659. X            continue;
  1660. X        case 'W':
  1661. X            chkonly('W', 0);
  1662. X            chkforbid('W', "DIZVR");
  1663. X            fMkWhatis = ! 0;
  1664. X            continue;
  1665. X        case 'Z':
  1666. X            chkonly('Z', 0);
  1667. X            chkforbid('Z', "DILWVR");
  1668. X            fJustComp = ! 0;
  1669. X            continue;
  1670. X        case 'c':
  1671. X            pcCat = optarg;
  1672. X            continue;
  1673. X        case 'f':
  1674. X            fFormat = ! 1;
  1675. X            continue;
  1676. X        case 'h':
  1677. X            fprintf(stdout, "%s: usage%s\n", progname, u_terse);
  1678. X            for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
  1679. X                fprintf(stdout, "%s\n", u_pch);
  1680. X            }
  1681. X            exit(0);
  1682. X        case 'm':
  1683. X            pcMan = optarg;
  1684. X            continue;
  1685. X        case 'n':
  1686. X            fExec = 0;
  1687. X            fVerbose = 1;
  1688. X            continue;
  1689. X        case 'r':
  1690. X            pcRoot = optarg;
  1691. X            continue;
  1692. X        case 's':
  1693. X            fVerbose = 0;
  1694. X            continue;
  1695. X        case 'v':
  1696. X            fVerbose = 1;
  1697. X            continue;
  1698. X        case 'w':
  1699. X            pcWhatis = optarg;
  1700. X            continue;
  1701. X        }
  1702. X        break;
  1703. X    }
  1704. X    iExit = doMkCat(argc-optind, & argv[optind]);
  1705. X    return iExit;
  1706. }
  1707. Purdue
  1708. chmod 0644 mkcat/main.c ||
  1709. echo 'restore of mkcat/main.c failed'
  1710. Wc_c="`wc -c < 'mkcat/main.c'`"
  1711. test 4513 -eq "$Wc_c" ||
  1712.     echo 'mkcat/main.c: original size 4513, current size' "$Wc_c"
  1713. fi
  1714. # ============= mk/Makefile.mkcmd ==============
  1715. if test -f 'mk/Makefile.mkcmd' -a X"$1" != X"-c"; then
  1716.     echo 'x - skipping mk/Makefile.mkcmd (File already exists)'
  1717. else
  1718. echo 'x - extracting mk/Makefile.mkcmd (Text)'
  1719. sed 's/^X//' << 'Purdue' > 'mk/Makefile.mkcmd' &&
  1720. # Written by S. McGeady, Intel, Inc., mcg@mipon2.intel.com        (sm)
  1721. #         Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb        (ksb)
  1722. #
  1723. # This software is not subject to any license of the American Telephone
  1724. # and Telegraph Company or the Regents of the University of California.
  1725. #
  1726. # Permission is granted to anyone to use this software for any purpose on
  1727. # any computer system, and to alter it and redistribute it freely, subject
  1728. # to the following restrictions:
  1729. #
  1730. # 1. The authors are not held responsible for any consequences of the
  1731. #    use of this software.
  1732. #
  1733. # 2. The origin of this software must not be misrepresented, either by
  1734. #    explicit claim or by omission.  Credit to the authors must appear
  1735. #    in documentation and sources.
  1736. #
  1737. # 3. Altered versions must be plainly marked as such, and must not be
  1738. #    misrepresented as being the original software.
  1739. #
  1740. # 4. This notice may not be removed or altered.
  1741. #
  1742. # Makefile for mk
  1743. #
  1744. # $Id: Makefile,v 4.6 90/11/19 13:56:36 ksb Exp $
  1745. X
  1746. PROG=    mk
  1747. BIN=    ${DESTDIR}/usr/local/bin
  1748. X
  1749. L=../libopt
  1750. #L=/usr/include/local
  1751. I=/usr/include
  1752. S=/usr/include/sys
  1753. P=
  1754. X
  1755. INCLUDE= -I$L
  1756. DEBUG=    -O
  1757. CDEFS=     
  1758. CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
  1759. X
  1760. HDR=    mk.h optaccum.h machine.h rlimsys.h
  1761. SRC=    mk.c rcsname.c setenv.c optaccum.c rlimsys.c
  1762. GENh=    main.h
  1763. GENc=    main.c
  1764. GEN=    ${GENh} ${GENc}
  1765. DEP=    ${SRC} ${GENc}
  1766. OBJ=    main.o mk.o rcsname.o setenv.o optaccum.o rlimsys.o
  1767. MAN=    mk.1l
  1768. SOURCE=    Makefile Makefile.plain README mk.m ${MAN} ${HDR} ${SRC}
  1769. X
  1770. all: ${PROG}
  1771. X
  1772. ${PROG}:$P ${OBJ}
  1773. #    ${CC} -o $@ ${CFLAGS} ${OBJ} -lopt
  1774. #    ${CC} -o $@ ${CFLAGS} ${OBJ} -L /usr/local/lib -lopt
  1775. X    ${CC} -o $@ ${CFLAGS} ${OBJ} ../libopt/libopt.a
  1776. X
  1777. main.h: main.c
  1778. X
  1779. main.c: mk.m
  1780. X    mkcmd std_help.m mk.m
  1781. X    -(cmp -s prog.c main.c || (mv prog.c main.c && echo main.c updated))
  1782. X    -(cmp -s prog.h main.h || (mv prog.h main.h && echo main.h updated))
  1783. X    rm -rf prog.[ch]
  1784. X
  1785. self-test: ${PROG}
  1786. X    cd Tests; ../${PROG} -mCompile *
  1787. X
  1788. swap: ${HDR} ${SRC} ${GEN} Makefile.plain
  1789. X    mv Makefile Makefile.mkcmd
  1790. X    mv Makefile.plain Makefile
  1791. X
  1792. clean: FRC
  1793. X    rm -f Makefile.bak *.o prog.[ch] ${GEN} ${PROG} a.out core errs tags
  1794. X
  1795. depend: ${HDR} ${SRC} ${GEN} FRC
  1796. X    maketd ${CDEFS} ${INCLUDE} ${DEP}
  1797. X
  1798. install: all FRC
  1799. X    install -cs ${PROG} ${BIN}/${PROG}
  1800. X
  1801. lint: ${HDR} ${SRC} ${GEN} FRC
  1802. X    lint -h ${CDEFS} ${INCLUDE} ${DEP}
  1803. X
  1804. mkcat: ${MAN}
  1805. X    mkcat ${MAN}
  1806. X
  1807. print: source FRC
  1808. X    lpr -J'${PROG} source' ${SOURCE}
  1809. X
  1810. source: ${SOURCE}
  1811. X
  1812. spotless: clean
  1813. X    rcsclean ${SOURCE}
  1814. X
  1815. tags: ${HDR} ${SRC} ${GEN}
  1816. X    ctags -t ${HDR} ${SRC} ${GEN}
  1817. X
  1818. ${SOURCE}:
  1819. X    co -q $@
  1820. X
  1821. FRC:
  1822. X
  1823. # DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
  1824. X
  1825. main.o: machine.h main.c optaccum.h
  1826. X
  1827. mk.o: machine.h main.h mk.c mk.h rlimsys.h
  1828. X
  1829. rcsname.o: machine.h rcsname.c
  1830. X
  1831. setenv.o: machine.h setenv.c
  1832. X
  1833. optaccum.o: machine.h optaccum.c
  1834. X
  1835. rlimsys.o: machine.h mk.h rlimsys.c rlimsys.h
  1836. X
  1837. # *** Do not add anything here - It will go away. ***
  1838. Purdue
  1839. chmod 0644 mk/Makefile.mkcmd ||
  1840. echo 'restore of mk/Makefile.mkcmd failed'
  1841. Wc_c="`wc -c < 'mk/Makefile.mkcmd'`"
  1842. test 2823 -eq "$Wc_c" ||
  1843.     echo 'mk/Makefile.mkcmd: original size 2823, current size' "$Wc_c"
  1844. fi
  1845. # ============= mk/main.c ==============
  1846. if test -f 'mk/main.c' -a X"$1" != X"-c"; then
  1847.     echo 'x - skipping mk/main.c (File already exists)'
  1848. else
  1849. echo 'x - extracting mk/main.c (Text)'
  1850. sed 's/^X//' << 'Purdue' > 'mk/main.c' &&
  1851. /*
  1852. X * machine generated cmd line parser
  1853. X */
  1854. X
  1855. #include "getopt.h"
  1856. #include <stdio.h>
  1857. #include "machine.h"
  1858. #include "optaccum.h"
  1859. #include "mk.h"
  1860. X
  1861. char
  1862. X    *progname = "$Id$",
  1863. X    uline[] = " [-Aachinsv] [-D defn] [-U undef] [-d submarker] [-e templates] [-l lines] [-m marker] [-t templates] [files]",
  1864. X    *help[] = {
  1865. X        "A           find the first matched command that succeeds",
  1866. X        "D defn      give a definition of an environment variable",
  1867. X        "U undef     remove a definition for an envoronment variable",
  1868. X        "a           find all matched commands",
  1869. X        "c           confirm the action before running it",
  1870. X        "d submarker look for the string \"$marker(submarker):\" in file",
  1871. X        "e templates scan templates before given files",
  1872. X        "h           print this help message",
  1873. X        "i           ignore case for markers and submarkers",
  1874. X        "l lines     specify the max number of lines to search",
  1875. X        "m marker    look for the string \"$marker:\" in file",
  1876. X        "n           do not really do it",
  1877. X        "s           silent operation",
  1878. X        "t templates look for marker in template file",
  1879. X        "v           be verbose",
  1880. X        "files       search for commands in these files",
  1881. X        (char *)0
  1882. X    },
  1883. X    *pathname = (char *)0;
  1884. int
  1885. X    fFirst = 0,
  1886. X    debug = 0,
  1887. X    fAll = 0,
  1888. X    fConfirm = 0;
  1889. char
  1890. X    *submark = (char *)0,
  1891. X    *pchExamine = (char *)0;
  1892. int
  1893. X    fCase = 0,
  1894. X    lines = 99;
  1895. char
  1896. X    *markstr = (char *)0;
  1897. int
  1898. X    fExec = 1;
  1899. char
  1900. X    *pchTemplates = (char *)0;
  1901. int
  1902. X    fVerbose = 1;
  1903. X
  1904. /*
  1905. X * a usage function
  1906. X */
  1907. int
  1908. usage()
  1909. {
  1910. X    register char **ppch;
  1911. X
  1912. X    for (ppch = help; (char *)0 != *ppch; ++ppch)
  1913. X        printf("%s\n", *ppch);
  1914. }
  1915. X
  1916. /*
  1917. X * parser
  1918. X */
  1919. int
  1920. main(argc, argv)
  1921. int argc;
  1922. char **argv;
  1923. {
  1924. X    static char
  1925. X        sbOpt[] = "AD:U:Vacd:e:hil:m:nst:v";
  1926. X    static int
  1927. X        retval = 0;
  1928. X    static char
  1929. X        *u_pch = (char *)0;
  1930. X    static int
  1931. X        u_loop = 0;
  1932. X    register int curopt, fNoArgs = 1;
  1933. X    register char *pchEnv;
  1934. X    extern char *getenv();
  1935. X    extern int atoi();
  1936. X    extern char *strrchr();
  1937. X
  1938. X    progname = strrchr(argv[0], '/');
  1939. X    if ((char *)0 == progname)
  1940. X        progname = argv[0];
  1941. X    else
  1942. X        ++progname;
  1943. X    if ((char *)0 != (pchEnv = getenv("MK")))
  1944. X        envopt(pchEnv);
  1945. X    pathname = argv[0];
  1946. X    for (;;) {
  1947. X        if (EOF != (curopt = getopt(argc, argv, sbOpt))) {
  1948. X            /* fallthrough */;
  1949. X        } else if (EOF != getarg(argc, argv)) {
  1950. X            retval += process(optarg);
  1951. X            fNoArgs = 0;
  1952. X            continue;
  1953. X        } else {
  1954. X            break;
  1955. X        }
  1956. X        switch (curopt) {
  1957. X        case BADARG:
  1958. X            fprintf(stderr, "%s: option %c needs a parameter\n", progname, optopt);
  1959. X            exit(1);
  1960. X        case BADCH:
  1961. X            fprintf(stderr, "%s: usage%s\n", progname, uline);
  1962. X            exit(1);
  1963. X        case 'A':
  1964. X            fFirst = ! 0;
  1965. X            continue;
  1966. X        case 'D':
  1967. X            define(optarg);
  1968. X            continue;
  1969. X        case 'U':
  1970. X            undefine(optarg);
  1971. X            continue;
  1972. X        case 'V':
  1973. X            debug = ! 0;
  1974. X            continue;
  1975. X        case 'a':
  1976. X            fAll = ! 0;
  1977. X            continue;
  1978. X        case 'c':
  1979. X            fConfirm = ! 0;
  1980. X            continue;
  1981. X        case 'd':
  1982. X            submark = optarg;
  1983. X            continue;
  1984. X        case 'e':
  1985. X            pchExamine = OptAccum(pchExamine, optarg, ":");
  1986. X            continue;
  1987. X        case 'h':
  1988. X            fprintf(stdout, "%s: usage%s\n", progname, uline);
  1989. X            for (u_loop = 0; (char *)0 != (u_pch = help[u_loop]); ++u_loop) {
  1990. X                fprintf(stdout, "%s\n", u_pch);
  1991. X            }
  1992. X            exit(0);
  1993. X        case 'i':
  1994. X            fCase = ! 0;
  1995. X            continue;
  1996. X        case 'l':
  1997. X            lines = atoi(optarg);
  1998. X            continue;
  1999. X        case 'm':
  2000. X            markstr = optarg;
  2001. X            continue;
  2002. X        case 'n':
  2003. X            fExec = ! 1;
  2004. X            continue;
  2005. X        case 's':
  2006. X            fVerbose = 0;
  2007. X            continue;
  2008. X        case 't':
  2009. X            pchTemplates = OptAccum(pchTemplates, optarg, ":");
  2010. X            continue;
  2011. X        case 'v':
  2012. X            fVerbose = 1;
  2013. X            continue;
  2014. X        }
  2015. X        break;
  2016. X    }
  2017. X    if (fNoArgs) {
  2018. X        if (debug) {
  2019. X            Version();
  2020. X        }
  2021. X    }
  2022. X
  2023. X    /* we just exit now */
  2024. X    exit(retval);
  2025. }
  2026. Purdue
  2027. chmod 0644 mk/main.c ||
  2028. echo 'restore of mk/main.c failed'
  2029. Wc_c="`wc -c < 'mk/main.c'`"
  2030. test 3495 -eq "$Wc_c" ||
  2031.     echo 'mk/main.c: original size 3495, current size' "$Wc_c"
  2032. fi
  2033. # ============= mk-lib/Makefile ==============
  2034. if test -f 'mk-lib/Makefile' -a X"$1" != X"-c"; then
  2035.     echo 'x - skipping mk-lib/Makefile (File already exists)'
  2036. else
  2037. echo 'x - extracting mk-lib/Makefile (Text)'
  2038. sed 's/^X//' << 'Purdue' > 'mk-lib/Makefile' &&
  2039. # Makefile for mk default rules
  2040. #        Kevin S Braunsdorf, PUCC
  2041. X
  2042. LIB=    ${DESTDIR}/usr/local/lib
  2043. X
  2044. MANUAL=    dot-1c dot-1g dot-1l dot-1u dot-1v \
  2045. X    dot-2 dot-2l \
  2046. X    dot-3 dot-3c dot-3f dot-3l dot-3m dot-3n dot-3s dot-3x \
  2047. X    dot-4 dot-4f dot-4l dot-4n dot-4p \
  2048. X    dot-5 dot-5l \
  2049. X    dot-6 dot-6l \
  2050. X    dot-7 dot-7l \
  2051. X    dot-8 dot-8c dot-8l dot-8v
  2052. USECC=    dot-s m-cc
  2053. USEFORTRAN=dot-f77 m-fc
  2054. USEMAKE=file-Makefile file-makefile dot-make
  2055. USEMAN=    dot-ms dot-me dot-mm
  2056. USEM2=     dot-m2
  2057. USENDBM= pre-pag
  2058. USENONE=dot-i
  2059. USENROFF=dot-nro
  2060. USEPASCAL= m-pc
  2061. USEPATCH=pre-diff
  2062. USESH=    dot-csh dot-tcsh dot-ksh
  2063. USEUU= pre-uue
  2064. USEVALID=file-Valid dot-v
  2065. REAL=    m-clean m-compile m-display m-info m-mkcat m-run \
  2066. X    type-b type-c type-d type-p type-s \
  2067. X    file-valid file-gmon.out \
  2068. X    pre-a pre-C pre-dir pre-ln pre-o pre-out pre-patch \
  2069. X    pre-tar pre-uu pre-Z pre-z pre-zoo \
  2070. X    dot- dot-1 dot-c dot-C dot-dvi dot-e dot-el dot-f dot-h dot-l \
  2071. X    dot-m4 dot-m dot-man dot-mk dot-p dot-ph dot-pl dot-ps dot-r \
  2072. X    dot-sh dot-shar dot-t dot-xbm dot-y \
  2073. X    comma-v
  2074. IGNORE=    pre-MW pre-cpio
  2075. MAN=    mk.5l
  2076. SOURCE=    Makefile README ${MAN} ${REAL} ${IGNORE}
  2077. X
  2078. all: source
  2079. X
  2080. ${LIB}/mk:
  2081. X    install -d -r $@
  2082. X
  2083. clean: FRC
  2084. X    rm -f Makefile.bak a.out core errs tags
  2085. X
  2086. depend: FRC
  2087. X    : 'no depend'
  2088. X
  2089. deinstall: ${MAN}
  2090. X    rm -rf ${LIB}/mk
  2091. X    mkcat -D ${MAN}
  2092. X
  2093. dirs: ${LIB}/mk
  2094. X
  2095. install: all dirs FRC
  2096. X    install -c -m 644 ${REAL} ${LIB}/mk
  2097. X    -cd ${LIB}/mk; for file in ${USEVALID}; do \
  2098. X        [ -f $$file ] || (ln -s file-valid $$file && echo $$file);\
  2099. X    done
  2100. X    -cd ${LIB}/mk; for file in ${USEPATCH}; do \
  2101. X        [ -f $$file ] || (ln -s pre-patch $$file && echo $$file);\
  2102. X    done
  2103. X    -cd ${LIB}/mk; for file in ${USENDBM}; do \
  2104. X        [ -f $$file ] || (ln -s pre-dir $$file && echo $$file);\
  2105. X    done
  2106. X    -cd ${LIB}/mk; for file in ${USEUU}; do \
  2107. X        [ -f $$file ] || (ln -s pre-uu $$file && echo $$file);\
  2108. X    done
  2109. X    -cd ${LIB}/mk; for file in ${MANUAL}; do \
  2110. X        [ -f $$file ] || (ln -s dot-1 $$file && echo $$file);\
  2111. X    done
  2112. X    -cd ${LIB}/mk; for file in ${USEMAN}; do \
  2113. X        [ -f $$file ] || (ln -s dot-man $$file && echo $$file);\
  2114. X    done
  2115. X    -cd ${LIB}/mk; for file in ${USESH}; do \
  2116. X        [ -f $$file ] || (ln -s dot-sh $$file && echo $$file);\
  2117. X    done
  2118. X    -cd ${LIB}/mk; for file in ${USECC}; do \
  2119. X        [ -f $$file ] || (ln -s dot-c $$file && echo $$file);\
  2120. X    done
  2121. X    -cd ${LIB}/mk; for file in ${USEMAKE}; do \
  2122. X        [ -f $$file ] || (ln -s dot-mk $$file && echo $$file);\
  2123. X    done
  2124. X    -cd ${LIB}/mk; for file in ${USENONE}; do \
  2125. X        [ -f $$file ] || (ln -s dot-h $$file && echo $$file);\
  2126. X    done
  2127. X    -cd ${LIB}/mk; for file in ${USEM2}; do \
  2128. X        [ -f $$file ] || (ln -s dot-m $$file && echo $$file);\
  2129. X    done
  2130. X    -cd ${LIB}/mk; for file in ${USEPASCAL}; do \
  2131. X        [ -f $$file ] || (ln -s dot-p $$file && echo $$file);\
  2132. X    done
  2133. X    -cd ${LIB}/mk; for file in ${USEFORTRAN}; do \
  2134. X        [ -f $$file ] || (ln -s dot-f $$file && echo $$file);\
  2135. X    done
  2136. X    -cd ${LIB}/mk; for file in ${USENROFF}; do \
  2137. X        [ -f $$file ] || (ln -s dot-t $$file && echo $$file);\
  2138. X    done
  2139. X
  2140. lint: FRC
  2141. X    : 'nothing to lint'
  2142. X
  2143. mkcat: ${MAN}
  2144. X    mkcat ${MAN}
  2145. X
  2146. print: source FRC
  2147. X    lpr -J'mk templates' ${SOURCE}
  2148. X
  2149. source: ${SOURCE}
  2150. X
  2151. spotless: clean
  2152. X    rcsclean ${SOURCE}
  2153. X
  2154. tags: FRC
  2155. X    : 'no tags'
  2156. X
  2157. ${SOURCE}:
  2158. X    co -q $@
  2159. X
  2160. FRC:
  2161. X
  2162. Purdue
  2163. chmod 0644 mk-lib/Makefile ||
  2164. echo 'restore of mk-lib/Makefile failed'
  2165. Wc_c="`wc -c < 'mk-lib/Makefile'`"
  2166. test 3088 -eq "$Wc_c" ||
  2167.     echo 'mk-lib/Makefile: original size 3088, current size' "$Wc_c"
  2168. fi
  2169. true || echo 'restore of mkcat/strcasecmp.c failed'
  2170. echo End of part 4, continue with part 5
  2171. exit 0
  2172.  
  2173. exit 0 # Just in case...
  2174.