home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2554 < prev    next >
Encoding:
Text File  |  1992-11-18  |  22.1 KB  |  824 lines

  1. Newsgroups: alt.sources
  2. Path: sparky!uunet!ornl!sunova!linac!pacific.mps.ohio-state.edu!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!agate!netsys!ibmpcug!rachel.ibmpcug.co.uk!gtoal
  3. From: gtoal@rachel.ibmpcug.co.uk (Graham Toal)
  4. Subject: [386BSD] Source: hacked man that works on .Z man pages
  5. Organization: The IBM PC User Group, Harrow, England
  6. Date: Thu, 19 Nov 1992 03:07:25 GMT
  7. Message-ID: <Bxy0oE.EJA@ibmpcug.co.uk>
  8. Followup-To: alt.sources.d
  9. Sender: news@ibmpcug.co.uk (News System Administration)
  10. Nntp-Posting-Host: rachel.ibmpcug.co.uk
  11. Lines: 811
  12.  
  13. Archive-name: bsd386/zman.shar
  14.  
  15. # This is a shell archive.  Save it in a file, remove anything before
  16. # this line, and then unpack it by entering "sh file".  Note, it may
  17. # create directories; files and directories will be owned by you and
  18. # have default permissions.
  19. #
  20. # This archive contains:
  21. #
  22. #    README
  23. #    man.c
  24. #    pathnames.h
  25. #    config.c
  26. #
  27. echo x - README
  28. sed 's/^X//' >README << 'END-of-README'
  29. XThis is a *very* quick hack to man to allow you to compress all the
  30. Xman pages with unix compress and still be able to read them.
  31. X
  32. XJust go to /usr/man and do   compress */*.0 */*/*.0
  33. X
  34. XThere will be a lot of linked man pages that compress refuses to touch.
  35. XEither leave them as is (I did) or unlink them, compress one by hand,
  36. Xand relink all the .Z versions.  (Pref '-s' so you can see in future
  37. Xwhich files were linked to what)
  38. X
  39. XI hope I haven't broken it.  Seems to work on everything I've tried.
  40. X
  41. XI started from the net2 man only because that's the only one I could
  42. Xfind unpacked anywhere - the bsd src distribution is too big for me
  43. Xto unpack on my machine (hey - if I had space, I wouldn't be compressing
  44. Xthe man pages, right?)  If the 386bsd man is changed in any way from
  45. Xthe net2 man, you'll have to fold in the mods yourself.
  46. X
  47. XIn the places in the code where I've been dirty, I've put comments
  48. Xtelling people what to change if they want to spend the time to do
  49. Xthe job properly.
  50. X
  51. XThis was a two-hour hack for my own benefit; if anyone else finds it
  52. Xuseful they're welcome to it.  I won't be supporting it after this.
  53. XIdeally the .Z compression should be done transparently by the filing
  54. Xsystem, which I think is how bsd4.4 will do it? - in which case this
  55. Xhack will be redundant.
  56. X
  57. XGraham Toal <gtoal@gtoal.com>
  58. XPS Create a directory /usr/local/src/man/man for this, and
  59. Xln -s /usr/local/src/man/man/man /usr/bin/man to install it.
  60. XBuild this with cc -o man man.c config.c
  61. X[config.c is straight off the net2 tape - only man.c and pathnames.h were
  62. Xhacked]
  63. END-of-README
  64. echo x - man.c
  65. sed 's/^X//' >man.c << 'END-of-man.c'
  66. X/*
  67. X * Copyright (c) 1987 Regents of the University of California.
  68. X * All rights reserved.
  69. X *
  70. X * Redistribution and use in source and binary forms, with or without
  71. X * modification, are permitted provided that the following conditions
  72. X * are met:
  73. X * 1. Redistributions of source code must retain the above copyright
  74. X *    notice, this list of conditions and the following disclaimer.
  75. X * 2. Redistributions in binary form must reproduce the above copyright
  76. X *    notice, this list of conditions and the following disclaimer in the
  77. X *    documentation and/or other materials provided with the distribution.
  78. X * 3. All advertising materials mentioning features or use of this software
  79. X *    must display the following acknowledgement:
  80. X *    This product includes software developed by the University of
  81. X *    California, Berkeley and its contributors.
  82. X * 4. Neither the name of the University nor the names of its contributors
  83. X *    may be used to endorse or promote products derived from this software
  84. X *    without specific prior written permission.
  85. X *
  86. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  87. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  88. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  89. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  90. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  91. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  92. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  93. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  94. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  95. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  96. X * SUCH DAMAGE.
  97. X */
  98. X
  99. X/* A hack to man.c to allow compressed man pages - simply go to
  100. X   /usr/share/man as root and compress *<slash>*.0 *<slash>*<slash>*.0
  101. X   -- don't worry too much about the ones it doesn't compress because of
  102. X   multiple links.  */
  103. X
  104. X#ifndef lint
  105. Xchar copyright[] =
  106. X"@(#) Copyright (c) 1987 Regents of the University of California.\n\
  107. X All rights reserved.\n";
  108. X#endif /* not lint */
  109. X
  110. X#ifndef lint
  111. Xstatic char sccsid[] = "@(#)man.c    5.24 (Berkeley) 7/21/90";
  112. X#endif /* not lint */
  113. X
  114. X#include <sys/param.h>
  115. X#include <sys/file.h>
  116. X#include <errno.h>
  117. X#include <stdio.h>
  118. X#include <ctype.h>
  119. X#include <string.h>
  120. X#include <stdlib.h>
  121. X#include <unistd.h> /* For mktemp */
  122. X#include "pathnames.h"
  123. X
  124. Xextern int errno;
  125. X
  126. Xint f_all, f_cat, f_how, f_where;
  127. Xchar *command, *machine, *p_augment, *p_path, *pager, *progname;
  128. Xextern char **arorder, *pathbuf;
  129. X
  130. Xtypedef struct strlist {
  131. X    char *fname;
  132. X    struct strlist *next;
  133. X} STRLIST;
  134. X
  135. XSTRLIST *delete_list = NULL;
  136. X
  137. Xvoid *
  138. Xqueue_delete(fname)
  139. Xchar *fname;
  140. X{
  141. X    STRLIST *l;
  142. X    l = malloc(sizeof(STRLIST));
  143. X    if (l == NULL) enomem();
  144. X    l->fname = malloc(strlen(fname)+1);
  145. X    if (l->fname == NULL) enomem();
  146. X    strcpy(l->fname, fname);
  147. X    l->next = delete_list; delete_list = l;
  148. X}
  149. X
  150. Xvoid delete_temps(void)
  151. X{
  152. X    while (delete_list != NULL) {
  153. X        remove(delete_list->fname);
  154. X        free(delete_list->fname);
  155. X        delete_list = delete_list->next;
  156. X    }
  157. X}
  158. X
  159. XFILE *
  160. Xmanopen(fname)
  161. Xchar *fname;
  162. X{
  163. X    FILE *fp;
  164. X    int l = strlen(fname);
  165. X    if ((l > 2) && (strcmp(fname+l-2, ".Z") == 0)) {
  166. X        /* Should really look up env var first and stick in a variable */
  167. X        command = malloc(strlen(_PATH_ZCAT)+1+strlen(fname)+1);
  168. X        if (command == NULL) enomem();
  169. X        sprintf(command, "%s %s", _PATH_ZCAT, fname);
  170. X        /* should really do a check_zcat() like check_pager() -
  171. X           but why bother.  1) it had better be there if people
  172. X           have gone around compressing man pages, and 2) the
  173. X           popen() will fail cleanly enough to give some sort
  174. X           of error message...  Another alternative is my ZFILE *
  175. X           interface which allows a zfopen(filename, mode)
  176. X           and does all the decompressin itself without popen(),
  177. X           but again, since this is for 386bsd and we always
  178. X           have popen(), why bother? */
  179. X        if ((fp = popen(command, "r")) == NULL) {
  180. X            (void)fprintf(stderr, "man: %s: %s\n", fname, strerror(errno));
  181. X            exit(1);
  182. X        }
  183. X    } else if ((fp = fopen(fname, "r")) == NULL) {
  184. X        (void)fprintf(stderr, "man: %s: %s\n", fname, strerror(errno));
  185. X        exit(1);
  186. X    } else {
  187. X    }
  188. X    if (command != NULL) free(command); command = NULL;
  189. X    return(fp);
  190. X}
  191. X
  192. Xint
  193. Xmain(argc, argv)
  194. X    int argc;
  195. X    register char **argv;
  196. X{
  197. X    extern char *optarg;
  198. X    extern int optind;
  199. X    int ch, res;
  200. X    char *section[2], *check_pager(), *getpath(), **getorder(), *tmp;
  201. X
  202. X    atexit(delete_temps);
  203. X    progname = "man";
  204. X    while ((ch = getopt(argc, argv, "-acfhkM:m:P:w")) != EOF)
  205. X        switch((char)ch) {
  206. X        case 'a':
  207. X            f_all = 1;
  208. X            break;
  209. X        case 'c':
  210. X        case '-':        /* deprecated */
  211. X            f_cat = 1;
  212. X            break;
  213. X        case 'h':
  214. X            f_how = 1;
  215. X            break;
  216. X        case 'm':
  217. X            p_augment = optarg;
  218. X            break;
  219. X        case 'M':
  220. X        case 'P':        /* backward compatibility */
  221. X            p_path = optarg;
  222. X            break;
  223. X        /*
  224. X         * "man -f" and "man -k" are backward compatible, undocumented
  225. X         * ways of calling whatis(1) and apropos(1).
  226. X         */
  227. X        case 'f':
  228. X            jump(argv, "-f", "whatis");
  229. X            /* NOTREACHED */
  230. X        case 'k':
  231. X            jump(argv, "-k", "apropos");
  232. X            /* NOTREACHED */
  233. X        case 'w':
  234. X            f_all = f_where = 1;
  235. X            break;
  236. X        case '?':
  237. X        default:
  238. X            usage();
  239. X        }
  240. X    argv += optind;
  241. X
  242. X    if (!*argv)
  243. X        usage();
  244. X
  245. X    if (!f_cat && !f_how)
  246. X        if (!isatty(1))
  247. X            f_cat = 1;
  248. X        else if (pager = getenv("PAGER"))
  249. X            pager = check_pager(pager);
  250. X        else
  251. X            pager = _PATH_PAGER;
  252. X
  253. X    if (!(machine = getenv("MACHINE")))
  254. X        machine = MACHINE;
  255. X
  256. X    /* see if checking in a specific section */
  257. X    if (argc > 1 && getsection(*argv)) {
  258. X        section[0] = *argv++;
  259. X        section[1] = (char *)NULL;
  260. X    } else {
  261. X        section[0] = "_default";
  262. X        section[1] = (char *)NULL;
  263. X    }
  264. X
  265. X    arorder = getorder();
  266. X    if (p_path || (p_path = getenv("MANPATH"))) {
  267. X        char buf[MAXPATHLEN], **av;
  268. X
  269. X        tmp = strtok(p_path, ":"); 
  270. X        while (tmp) {
  271. X            (void)sprintf(buf, "%s/", tmp);
  272. X            for (av = arorder; *av; ++av)
  273. X                        cadd(buf, strlen(buf), *av);
  274. X            tmp = strtok((char *)NULL, ":"); 
  275. X        }
  276. X        p_path = pathbuf;
  277. X    } else if (!(p_path = getpath(section)) && !p_augment) {
  278. X        (void)fprintf(stderr,
  279. X            "man: no place to search for those manual pages.\n");
  280. X        exit(1);
  281. X    }
  282. X
  283. X    for (; *argv; ++argv) {
  284. X        if (p_augment)
  285. X            res = manual(p_augment, *argv);
  286. X        res = manual(p_path, *argv);
  287. X        if (res || f_where)
  288. X            continue;
  289. X        (void)fprintf(stderr,
  290. X            "man: no entry for %s in the manual.\n", *argv);
  291. X        exit(1);
  292. X    }
  293. X
  294. X    /* use system(3) in case someone's pager is "pager arg1 arg2" */
  295. X    if (command)
  296. X        (void)system(command);
  297. X    exit(0);
  298. X}
  299. X
  300. X/*
  301. X * manual --
  302. X *    given a path, a directory list and a file name, find a file
  303. X *    that matches; check ${directory}/${dir}/{file name} and
  304. X *    ${directory}/${dir}/${machine}/${file name}.
  305. X */
  306. Xmanual(path, name)
  307. X    char *path, *name;
  308. X{
  309. X    register int res;
  310. X    register char *end;
  311. X    char fname[MAXPATHLEN + 1];
  312. X
  313. X    for (res = 0;; path = end + 1) {
  314. X        if (!*path)                /* foo: */
  315. X            break;
  316. X        if (end = index(path, ':')) {
  317. X            if (end == path + 1)        /* foo::bar */
  318. X                continue;
  319. X            *end = '\0';
  320. X        }
  321. X        (void)sprintf(fname, "%s/%s.0", path, name);
  322. X        if (access(fname, R_OK)) {
  323. X            (void)sprintf(fname, "%s/%s.0.Z", path, name);
  324. X            if (access(fname, R_OK)) {
  325. X                (void)sprintf(fname, "%s/%s/%s.0", path, machine, name);
  326. X                if (access(fname, R_OK)) {
  327. X                    (void)sprintf(fname, "%s/%s/%s.0.Z", path, machine, name);
  328. X                    if (access(fname, R_OK)) {
  329. X                        continue;
  330. X                    }
  331. X                }
  332. X            }
  333. X        }
  334. X
  335. X        if (f_where)
  336. X            (void)printf("man: found in %s.\n", fname);
  337. X        else if (f_cat)
  338. X            cat(fname);
  339. X        else if (f_how)
  340. X            how(fname);
  341. X        else
  342. X            add(fname);
  343. X        if (!f_all)
  344. X            return(1);
  345. X        res = 1;
  346. X        if (!end)
  347. X            break;
  348. X        *end = ':';
  349. X    }
  350. X    return(res);
  351. X}
  352. X
  353. X/*
  354. X * how --
  355. X *    display how information
  356. X */
  357. Xhow(fname)
  358. X    char *fname;
  359. X{
  360. X    register FILE *fp;
  361. X
  362. X    register int lcnt, print;
  363. X    register char *p;
  364. X    char buf[BUFSIZ];
  365. X
  366. X    if (!(fp = manopen(fname))) {
  367. X        (void)fprintf(stderr, "man: %s: %s\n", fname, strerror(errno));
  368. X        exit(1);
  369. X    }
  370. X#define    S1    "SYNOPSIS"
  371. X#define    S2    "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"
  372. X#define    D1    "DESCRIPTION"
  373. X#define    D2    "D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN"
  374. X    for (lcnt = print = 0; fgets(buf, sizeof(buf), fp);) {
  375. X        if (!strncmp(buf, S1, sizeof(S1) - 1) ||
  376. X            !strncmp(buf, S2, sizeof(S2) - 1)) {
  377. X            print = 1;
  378. X            continue;
  379. X        } else if (!strncmp(buf, D1, sizeof(D1) - 1) ||
  380. X            !strncmp(buf, D2, sizeof(D2) - 1))
  381. X            return;
  382. X        if (!print)
  383. X            continue;
  384. X        if (*buf == '\n')
  385. X            ++lcnt;
  386. X        else {
  387. X            for(; lcnt; --lcnt)
  388. X                (void)putchar('\n');
  389. X            for (p = buf; isspace(*p); ++p);
  390. X            (void)fputs(p, stdout);
  391. X        }
  392. X    }
  393. X    (void)fclose(fp);
  394. X}
  395. X/*
  396. X * cat --
  397. X *    cat out the file
  398. X */
  399. Xcat(fname)
  400. X    char *fname;
  401. X{
  402. X    register int n;
  403. X    FILE *fp;
  404. X    char buf[BUFSIZ];
  405. X
  406. X    fp = manopen(fname);
  407. X    for (;;) {
  408. X        n = fread(buf, 1, sizeof(buf), fp);
  409. X        if (n <= 0) break;
  410. X        if (fwrite(buf, 1, n, stdout) != n) {
  411. X            (void)fprintf(stderr,
  412. X                "man: write: %s\n", strerror(errno));
  413. X            exit(1);
  414. X        }
  415. X    }
  416. X    (void)fclose(fp);
  417. X}
  418. X
  419. X/*
  420. X * add --
  421. X *    add a file name to the list for future paging
  422. X */
  423. Xadd(fname)
  424. X    char *fname;
  425. X{
  426. X    static u_int buflen;
  427. X    static int len;
  428. X    static char *cp;
  429. X    int flen;
  430. X
  431. X    if (!command) {
  432. X        if (!(command = malloc(buflen = 1024)))
  433. X            enomem();
  434. X        len = strlen(strcpy(command, pager));
  435. X        cp = command + len;
  436. X    }
  437. X    /* If filename ends in .Z, decompress it and more the tmp file */
  438. X    flen = strlen(fname);
  439. X    if (strcmp(fname+flen-2, ".Z") == 0) {
  440. X        /* These local arrays should be off the heap, but this
  441. X           is one of those quick hack programs that works and
  442. X           I can't be bothered.  Someone else do it if it's a
  443. X           problem.  Sorry folks. */
  444. X        char temp[256];
  445. X        char cmnd[256];
  446. X        char rootname[256];
  447. X        char *s;
  448. X        s = fname+flen-2-1;
  449. X        for (;;) {
  450. X            if (s == fname) break;
  451. X            if (*(s-1) == '/') break;
  452. X            s -= 1;
  453. X        }
  454. X        strcpy(rootname, s); rootname[strlen(rootname)-2] = '\0';
  455. X        sprintf(temp, "/tmp/%s.XXXX", rootname);
  456. X        (void)mktemp(temp);
  457. X        queue_delete(temp);
  458. X        sprintf(cmnd, "%s %s > %s", _PATH_ZCAT, fname, temp);
  459. X        system(cmnd);
  460. X        free(fname);
  461. X        fname = malloc(strlen(temp)+1); if (fname == NULL) enomem();
  462. X        strcpy(fname, temp);
  463. X        /* And queue temp file for deletion */
  464. X    }
  465. X    flen = strlen(fname);
  466. X    if (len + flen + 2 > buflen) {        /* +2 == space, EOS */
  467. X        if (!(command = realloc(command, buflen += 1024)))
  468. X            enomem();
  469. X        cp = command + len;
  470. X    }
  471. X    *cp++ = ' ';
  472. X    len += flen + 1;            /* +1 = space */
  473. X    (void)strcpy(cp, fname);
  474. X    cp += flen;
  475. X}
  476. X
  477. X/*
  478. X * check_pager --
  479. X *    check the user supplied page information
  480. X */
  481. Xchar *
  482. Xcheck_pager(name)
  483. X    char *name;
  484. X{
  485. X    register char *p;
  486. X    char *save;
  487. X
  488. X    /*
  489. X     * if the user uses "more", we make it "more -s"; watch out for
  490. X     * PAGER = "mypager /usr/ucb/more"
  491. X     */
  492. X    for (p = name; *p && !isspace(*p); ++p);
  493. X    for (; p > name && *p != '/'; --p);
  494. X    if (p != name)
  495. X        ++p;
  496. X
  497. X    /* make sure it's "more", not "morex" */
  498. X    if (!strncmp(p, "more", 4) && (!p[4] || isspace(p[4]))){
  499. X        save = name;
  500. X        /* allocate space to add the "-s" */
  501. X        if (!(name =
  502. X            malloc((u_int)(strlen(save) + sizeof("-s") + 1))))
  503. X            enomem();
  504. X        (void)sprintf(name, "%s %s", save, "-s");
  505. X    }
  506. X    return(name);
  507. X}
  508. X
  509. X/*
  510. X * jump --
  511. X *    strip out flag argument and jump
  512. X */
  513. Xjump(argv, flag, name)
  514. X    char **argv, *name;
  515. X    register char *flag;
  516. X{
  517. X    register char **arg;
  518. X
  519. X    argv[0] = name;
  520. X    for (arg = argv + 1; *arg; ++arg)
  521. X        if (!strcmp(*arg, flag))
  522. X            break;
  523. X    for (; *arg; ++arg)
  524. X        arg[0] = arg[1];
  525. X    execvp(name, argv);
  526. X    (void)fprintf(stderr, "%s: Command not found.\n", name);
  527. X    exit(1);
  528. X}
  529. X
  530. X/*
  531. X * usage --
  532. X *    print usage message and die
  533. X */
  534. Xusage()
  535. X{
  536. X    (void)fprintf(stderr,
  537. X        "usage: man [-ac] [-M path] [-m path] [section] title ...\n");
  538. X    exit(1);
  539. X}
  540. END-of-man.c
  541. echo x - pathnames.h
  542. sed 's/^X//' >pathnames.h << 'END-of-pathnames.h'
  543. X/*
  544. X * Copyright (c) 1989 The Regents of the University of California.
  545. X * All rights reserved.
  546. X *
  547. X * Redistribution and use in source and binary forms, with or without
  548. X * modification, are permitted provided that the following conditions
  549. X * are met:
  550. X * 1. Redistributions of source code must retain the above copyright
  551. X *    notice, this list of conditions and the following disclaimer.
  552. X * 2. Redistributions in binary form must reproduce the above copyright
  553. X *    notice, this list of conditions and the following disclaimer in the
  554. X *    documentation and/or other materials provided with the distribution.
  555. X * 3. All advertising materials mentioning features or use of this software
  556. X *    must display the following acknowledgement:
  557. X *    This product includes software developed by the University of
  558. X *    California, Berkeley and its contributors.
  559. X * 4. Neither the name of the University nor the names of its contributors
  560. X *    may be used to endorse or promote products derived from this software
  561. X *    without specific prior written permission.
  562. X *
  563. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  564. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  565. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  566. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  567. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  568. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  569. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  570. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  571. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  572. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  573. X * SUCH DAMAGE.
  574. X *
  575. X *    @(#)pathnames.h    5.4 (Berkeley) 6/1/90
  576. X */
  577. X
  578. X#define    _PATH_MANCONF    "/etc/man.conf"
  579. X#define    _PATH_PAGER    "/usr/bin/more -s"
  580. X#define    _PATH_WHATIS    "whatis.db"
  581. X#define    _PATH_ZCAT    "/usr/bin/zcat"
  582. END-of-pathnames.h
  583. echo x - config.c
  584. sed 's/^X//' >config.c << 'END-of-config.c'
  585. X/*
  586. X * Copyright (c) 1989 The Regents of the University of California.
  587. X * All rights reserved.
  588. X *
  589. X * Redistribution and use in source and binary forms, with or without
  590. X * modification, are permitted provided that the following conditions
  591. X * are met:
  592. X * 1. Redistributions of source code must retain the above copyright
  593. X *    notice, this list of conditions and the following disclaimer.
  594. X * 2. Redistributions in binary form must reproduce the above copyright
  595. X *    notice, this list of conditions and the following disclaimer in the
  596. X *    documentation and/or other materials provided with the distribution.
  597. X * 3. All advertising materials mentioning features or use of this software
  598. X *    must display the following acknowledgement:
  599. X *    This product includes software developed by the University of
  600. X *    California, Berkeley and its contributors.
  601. X * 4. Neither the name of the University nor the names of its contributors
  602. X *    may be used to endorse or promote products derived from this software
  603. X *    without specific prior written permission.
  604. X *
  605. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  606. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  607. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  608. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  609. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  610. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  611. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  612. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  613. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  614. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  615. X * SUCH DAMAGE.
  616. X */
  617. X
  618. X#ifndef lint
  619. Xstatic char sccsid[] = "@(#)config.c    5.6 (Berkeley) 3/1/91";
  620. X#endif /* not lint */
  621. X
  622. X#include <sys/param.h>
  623. X#include <stdio.h>
  624. X#include <errno.h>
  625. X#include <string.h>
  626. X#include <stdlib.h>
  627. X#include <pwd.h>
  628. X#include "pathnames.h"
  629. X
  630. X#define    MAXLINE        1024
  631. X
  632. Xextern char *progname;
  633. Xchar *pathbuf, **arorder;
  634. X
  635. Xstatic FILE *cfp;
  636. X
  637. X/*
  638. X * getpath --
  639. X *    read in the configuration file, calling a function with the line
  640. X *    from each matching section.
  641. X */
  642. Xchar *
  643. Xgetpath(sects)
  644. X    char **sects;
  645. X{
  646. X    register char **av, *p;
  647. X    size_t len;
  648. X    char line[MAXLINE];
  649. X    static int openconfig();
  650. X
  651. X    openconfig();
  652. X    while (fgets(line, sizeof(line), cfp)) {
  653. X        if (!index(line, '\n')) {
  654. X            (void)fprintf(stderr, "%s: config line too long.\n",
  655. X                progname);
  656. X            exit(1);
  657. X        }
  658. X        p = strtok(line, " \t\n");
  659. X        if (!p || *p == '#')
  660. X            continue;
  661. X        for (av = sects; *av; ++av)
  662. X            if (!strcmp(p, *av))
  663. X                break;
  664. X        if (!*av)
  665. X            continue;
  666. X        while (p = strtok((char *)NULL, " \t\n")) {
  667. X            len = strlen(p);
  668. X            if (p[len - 1] == '/')
  669. X                for (av = arorder; *av; ++av)
  670. X                            cadd(p, len, *av);
  671. X            else
  672. X                cadd(p, len, (char *)NULL);
  673. X        }
  674. X    }
  675. X    return(pathbuf);
  676. X}
  677. X
  678. Xcadd(add1, len1, add2)
  679. Xchar *add1, *add2;
  680. Xregister size_t len1;
  681. X{
  682. X    static size_t buflen;
  683. X    static char *bp, *endp;
  684. X    register size_t len2;
  685. X
  686. X    len2 = add2 ? strlen(add2) : 0;
  687. X    if (!bp || bp + len1 + len2 + 2 >= endp) {
  688. X        if (!(pathbuf = realloc(pathbuf, buflen += 1024)))
  689. X            enomem();
  690. X        if (!bp)
  691. X            bp = pathbuf;
  692. X        endp = pathbuf + buflen;
  693. X    }
  694. X    bcopy(add1, bp, len1);
  695. X    bp += len1;
  696. X    if (len2) {
  697. X        bcopy(add2, bp, len2);
  698. X        bp += len2;
  699. X    }
  700. X    *bp++ = ':';
  701. X    *bp = '\0';
  702. X}
  703. X
  704. Xstatic
  705. Xopenconfig()
  706. X{
  707. X    if (cfp) {
  708. X        rewind(cfp);
  709. X        return;
  710. X    }
  711. X    if (!(cfp = fopen(_PATH_MANCONF, "r"))) {
  712. X        (void)fprintf(stderr, "%s: no configuration file %s.\n",
  713. X            progname, _PATH_MANCONF);
  714. X        exit(1);
  715. X    }
  716. X}
  717. X
  718. Xchar **
  719. Xgetdb()
  720. X{
  721. X    register char *p;
  722. X    int cnt, num;
  723. X    char **ar, line[MAXLINE];
  724. X
  725. X    ar = NULL;
  726. X    num = 0;
  727. X    cnt = -1;
  728. X    openconfig();
  729. X    while (fgets(line, sizeof(line), cfp)) {
  730. X        if (!index(line, '\n')) {
  731. X            (void)fprintf(stderr, "%s: config line too long.\n",
  732. X                progname);
  733. X            exit(1);
  734. X        }
  735. X        p = strtok(line, " \t\n");
  736. X#define    WHATDB    "_whatdb"
  737. X        if (!p || *p == '#' || strcmp(p, WHATDB))
  738. X            continue;
  739. X        while (p = strtok((char *)NULL, " \t\n")) {
  740. X            if (cnt == num - 1 &&
  741. X                !(ar = realloc(ar, (num += 30) * sizeof(char **))))
  742. X                enomem();
  743. X            if (!(ar[++cnt] = strdup(p)))
  744. X                enomem();
  745. X        }
  746. X    }
  747. X    if (ar) {
  748. X        if (cnt == num - 1 &&
  749. X            !(ar = realloc(ar, ++num * sizeof(char **))))
  750. X            enomem();
  751. X        ar[++cnt] = NULL;
  752. X    }
  753. X    return(ar);
  754. X}
  755. X
  756. Xchar **
  757. Xgetorder()
  758. X{
  759. X    register char *p;
  760. X    int cnt, num;
  761. X    char **ar, line[MAXLINE];
  762. X
  763. X    ar = NULL;
  764. X    num = 0;
  765. X    cnt = -1;
  766. X    openconfig();
  767. X    while (fgets(line, sizeof(line), cfp)) {
  768. X        if (!index(line, '\n')) {
  769. X            (void)fprintf(stderr, "%s: config line too long.\n",
  770. X                progname);
  771. X            exit(1);
  772. X        }
  773. X        p = strtok(line, " \t\n");
  774. X#define    SUBDIR    "_subdir"
  775. X        if (!p || *p == '#' || strcmp(p, SUBDIR))
  776. X            continue;
  777. X        while (p = strtok((char *)NULL, " \t\n")) {
  778. X            if (cnt == num - 1 &&
  779. X                !(ar = realloc(ar, (num += 30) * sizeof(char **))))
  780. X                enomem();
  781. X            if (!(ar[++cnt] = strdup(p)))
  782. X                enomem();
  783. X        }
  784. X    }
  785. X    if (ar) {
  786. X        if (cnt == num - 1 &&
  787. X            !(ar = realloc(ar, ++num * sizeof(char **))))
  788. X            enomem();
  789. X        ar[++cnt] = NULL;
  790. X    }
  791. X    return(ar);
  792. X}
  793. X
  794. Xgetsection(sect)
  795. X    char *sect;
  796. X{
  797. X    register char *p;
  798. X    char line[MAXLINE];
  799. X
  800. X    openconfig();
  801. X    while (fgets(line, sizeof(line), cfp)) {
  802. X        if (!index(line, '\n')) {
  803. X            (void)fprintf(stderr, "%s: config line too long.\n",
  804. X                progname);
  805. X            exit(1);
  806. X        }
  807. X        p = strtok(line, " \t\n");
  808. X        if (!p || *p == '#')
  809. X            continue;
  810. X        if (!strcmp(p, sect))
  811. X            return(1);
  812. X    }
  813. X    return(0);
  814. X}
  815. X
  816. Xenomem()
  817. X{
  818. X    (void)fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
  819. X    exit(1);
  820. X}
  821. END-of-config.c
  822. exit
  823.  
  824.