home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / editor / man / src / manpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-06  |  10.8 KB  |  542 lines

  1. /*
  2.  * manpath.c
  3.  *
  4.  * Copyright (c) 1990, 1991, John W. Eaton.
  5.  *
  6.  * You may distribute under the terms of the GNU General Public
  7.  * License as specified in the file COPYING that comes with the man
  8.  * distribution.  
  9.  *
  10.  * John W. Eaton
  11.  * jwe@che.utexas.edu
  12.  * Department of Chemical Engineering
  13.  * The University of Texas at Austin
  14.  * Austin, Texas  78712
  15.  */
  16.  
  17. #define MANPATH_MAIN
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include "config.h"
  24. #include "manpath.h"
  25. #include "gripes.h"
  26.  
  27. #ifdef STDC_HEADERS
  28. #include <stdlib.h>
  29. #else
  30. extern int fprintf ();
  31. extern int strcmp ();
  32. extern int strncmp ();
  33. extern char *memcpy ();
  34. extern char *getenv();
  35. extern char *malloc();
  36. extern void free ();
  37. extern int exit ();
  38. #endif
  39.  
  40. extern char *strdup ();
  41. extern int is_directory ();
  42.  
  43. #ifndef MAIN
  44. extern int debug;
  45. #endif
  46.  
  47. #ifdef MAIN
  48.  
  49. #ifndef STDC_HEADERS
  50. extern char *strcpy ();
  51. extern int fflush ();
  52. #endif
  53.  
  54. char *prognam;
  55. int debug;
  56.  
  57. /*
  58.  * Examine user's PATH and print a reasonable MANPATH.
  59.  */
  60. int
  61. main(argc, argv)
  62.      int argc;
  63.      char **argv;
  64. {
  65.   int c;
  66.   int quiet;
  67.   char *mp;
  68.   extern int getopt ();
  69.   extern char *mkprogname ();
  70.   void usage ();
  71.   char *manpath ();
  72.  
  73.   quiet = 1;
  74.  
  75.   prognam = mkprogname (argv[0]);
  76.  
  77.   while ((c = getopt (argc, argv, "dhq?")) != EOF)
  78.     {
  79.       switch (c)
  80.     {
  81.     case 'd':
  82.       debug++;
  83.       break;
  84.     case 'q':
  85.       quiet = 0;
  86.       break;
  87.     case '?':
  88.     case 'h':
  89.     default:
  90.       usage();
  91.           break;
  92.     }
  93.     }
  94.  
  95.   mp = manpath (quiet);
  96.  
  97.   fprintf (stdout, "%s\n", mp);
  98.   fflush (stdout);
  99.  
  100.   return 0;
  101. }
  102.  
  103. void
  104. usage ()
  105. {
  106.   fprintf (stderr, "usage: %s [-q]\n", prognam);
  107.   exit (1);
  108. }
  109. #endif /* MAIN */
  110.  
  111. /*
  112.  * If the environment variable MANPATH is set, return it.
  113.  * If the environment variable PATH is set and has a nonzero length,
  114.  * try to determine the corresponding manpath, otherwise, return the
  115.  * default manpath.
  116.  *
  117.  * The manpath.config file is used to map system wide /bin directories
  118.  * to top level man page directories.
  119.  *
  120.  * For directories which are in the user's path but not in the
  121.  * manpath.config file, see if there is a subdirectory `man' or `MAN'.
  122.  * If so, add that directory to the path.  Example:  user has
  123.  * $HOME/bin in his path and the directory $HOME/bin/man exists -- the
  124.  * directory $HOME/bin/man will be added to the manpath.
  125.  */
  126. char *
  127. manpath (perrs)
  128.      register int perrs;
  129. {
  130.   register int len;
  131.   register char *manpathlist;
  132.   register char *path;
  133.   int  get_dirlist ();
  134.   char *def_path ();
  135.   char *get_manpath ();
  136.  
  137.   if (get_dirlist ())
  138.       gripe_reading_mp_config ();
  139.  
  140.   if ((manpathlist = getenv ("MANPATH")) != NULL)
  141.     /*
  142.      * This must be it.
  143.      */
  144.     {
  145.       if (perrs)
  146.     fprintf (stderr, "(Warning: MANPATH environment variable set)\n");
  147.       return strdup (manpathlist);
  148.     }
  149.   else if ((path = getenv ("PATH")) == NULL)
  150.     /*
  151.      * Things aren't going to work well, but hey...
  152.      */
  153.     {
  154.       if (perrs)
  155.     fprintf (stderr, "Warning: path not set\n");
  156.       return def_path (perrs);
  157.     }
  158.   else
  159.     {
  160.       if ((len = strlen (path)) == 0)
  161.     /*
  162.      * Things aren't going to work well here either...
  163.      */
  164.     {
  165.       if (perrs)
  166.         fprintf (stderr, "Warning: path set but has zero length\n");
  167.       return def_path (perrs);
  168.     }
  169.       return get_manpath (perrs, path);
  170.     }
  171. }
  172.  
  173. /*
  174.  * Get the list of bin directories and the corresponding man
  175.  * directories from the manpath.config file.
  176.  *
  177.  * This is ugly.
  178.  */
  179. int
  180. get_dirlist ()
  181. {
  182.   int i;
  183.   char *bp;
  184.   char *p;
  185.   char buf[BUFSIZ];
  186.   DIRLIST *dlp = list;
  187.   FILE *config;
  188.  
  189. #ifdef OS2
  190.   char *config_file_sp[] = {"INIT", "DPATH", "PATH", NULL};
  191.  
  192.   for (i = 0; config_file_sp[i]; i++) {
  193.     _searchenv(config_file, config_file_sp[i], buf);
  194.     if (*buf) break;
  195.   }
  196. #else
  197.   *buf = '\0';
  198. #endif
  199.   if (*buf == '\0')
  200.     strcpy(buf, config_file);
  201.  
  202.   if ((config = fopen (buf, "r")) == NULL)
  203.     gripe_getting_mp_config (buf);
  204.  
  205.   while ((bp = fgets (buf, BUFSIZ, config)) != NULL)
  206.     {
  207.       while (*bp && (*bp == ' ' || *bp == '\t'))
  208.     bp++;
  209.  
  210.       if (*bp == '#' || *bp == '\n')
  211.     continue;
  212.  
  213.       if (!strncmp ("MANBIN", bp, 6))
  214.     continue;
  215.  
  216.       if (!strncmp ("MANDATORY_MANPATH", bp, 17))
  217.     {
  218.       if ((p = strchr (bp, ' ')) == NULL)
  219.         if ((p = strchr (bp, '\t')) == NULL)
  220.           return -1;
  221.  
  222.       bp = p;
  223.  
  224.       dlp->mandatory = 1;
  225.  
  226.       while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
  227.         bp++;
  228.  
  229.       i = 0;
  230.       while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
  231.         dlp->mandir[i++] = *bp++;
  232.       dlp->mandir[i] = '\0';
  233.  
  234.       if (debug)
  235.         fprintf (stderr, "found mandatory man directory %s\n",
  236.              dlp->mandir);
  237.     }
  238.       else if (!strncmp ("MANPATH_MAP", bp, 11))
  239.     {
  240.       if ((p = strchr (bp, ' ')) == NULL)
  241.         if ((p = strchr (bp, '\t')) == NULL)
  242.           return -1;
  243.  
  244.       bp = p;
  245.  
  246.       dlp->mandatory = 0;
  247.  
  248.       while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
  249.         bp++;
  250.  
  251.       i = 0;
  252.       while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
  253.         dlp->bin[i++] = *bp++;
  254.       dlp->bin[i] = '\0';
  255.  
  256.       while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
  257.         bp++;
  258.  
  259.       i = 0;
  260.       while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
  261.         dlp->mandir[i++] = *bp++;
  262.       dlp->mandir[i] = '\0';
  263.  
  264.       if (debug)
  265.         fprintf (stderr, "found manpath map %s --> %s\n",
  266.              dlp->bin, dlp->mandir);
  267.     }
  268.       else
  269.     {
  270.       gripe_reading_mp_config ();
  271.     }
  272.       dlp++;
  273.     }
  274.  
  275.   dlp->bin[0] = '\0';
  276.   dlp->mandir[0] = '\0';
  277.   dlp->mandatory = 0;
  278.  
  279.   return 0;
  280. }
  281.  
  282. /*
  283.  * Construct the default manpath.  This picks up mandatory manpaths
  284.  * only.
  285.  */
  286. char *
  287. def_path (perrs)
  288.      int perrs;
  289. {
  290.   register int len;
  291.   register char *manpathlist, *p;
  292.   register DIRLIST *dlp;
  293.  
  294.   len = 0;
  295.   dlp = list;
  296.   while (dlp->mandatory != 0)
  297.     {
  298.       len += strlen (dlp->mandir) + 1;
  299.       dlp++;
  300.     }
  301.  
  302.   manpathlist = (char *) malloc (len);
  303.   if (manpathlist == NULL)
  304.     gripe_alloc (len, "manpathlist");
  305.  
  306.   *manpathlist = '\0';
  307.  
  308.   dlp = list;
  309.   p = manpathlist;
  310.   while (dlp->mandatory != 0)
  311.     {
  312.       int status;
  313.       char *path = dlp->mandir;
  314.  
  315.       status = is_directory(path);
  316.  
  317.       if (status < 0 && perrs)
  318.     {
  319.       fprintf (stderr, "Warning: couldn't stat file %s!\n", path);
  320.     }
  321.       else if (status == 0 && perrs)
  322.     {
  323.       fprintf (stderr, "Warning: standard directory %s doesn't exist!\n",
  324.            path);
  325.     }
  326.       else if (status == 1)
  327.     {
  328.       len = strlen (path);
  329.       memcpy (p, path, len);
  330.       p += len;
  331.       *p++ = PATHSEP;
  332.       dlp++;
  333.     }
  334.     }
  335.  
  336.   p[-1] = '\0';
  337.  
  338.   return manpathlist;
  339. }
  340.  
  341. /*
  342.  * For each directory in the user's path, see if it is one of the
  343.  * directories listed in the manpath.config file.  If so, and it is
  344.  * not already in the manpath, add it.  If the directory is not listed
  345.  * in the manpath.config file, see if there is a subdirectory `man' or
  346.  * `MAN'.  If so, and it is not already in the manpath, add it.
  347.  * Example:  user has $HOME/bin in his path and the directory
  348.  * $HOME/bin/man exists -- the directory $HOME/bin/man will be added
  349.  * to the manpath.
  350.  */
  351. char *
  352. get_manpath (perrs, path)
  353.      register int perrs;
  354.      register char *path;
  355. {
  356.   register int len;
  357.   register char *tmppath;
  358.   register char *t;
  359.   register char *p;
  360.   register char **lp;
  361.   register char *end;
  362.   register char *manpathlist;
  363.   register DIRLIST *dlp;
  364.   void add_dir_to_list ();
  365.   char *has_subdirs ();
  366.  
  367.   tmppath = strdup (path);
  368. #ifdef OS2
  369.   for (p = tmppath; p = strchr(p, '\\'); p++) *p = '/';
  370. #endif
  371.   for (p = tmppath; ; p = end+1)
  372.     {
  373.       if (end = strchr(p, PATHSEP))
  374.     *end = '\0';
  375.  
  376.       if (debug)
  377.     fprintf (stderr, "\npath directory %s ", p);
  378.  
  379.       /*
  380.        * The directory we're working on is in the config file.
  381.        * If we haven't added it to the list yet, do.
  382.        */
  383.       for (dlp = list; dlp->mandir[0] != '\0'; dlp++)
  384.     if (dlp->bin[0] != '\0' &&
  385. #ifdef OS2
  386.         !stricmp (p, dlp->bin))
  387. #else
  388.         !strcmp (p, dlp->bin))
  389. #endif
  390.       {
  391.         if (debug)
  392.           fprintf (stderr, "is in the config file\n");
  393.  
  394.         add_dir_to_list (tmplist, dlp->mandir, perrs);
  395.         goto found;
  396.       }
  397.  
  398.       /*
  399.        * The directory we're working on isn't in the config file.  See
  400.        * if it has man or MAN subdirectories.  If so, and it hasn't
  401.        * been added to the list, do.
  402.        */
  403.       if (debug)
  404.     fprintf (stderr, "is not in the config file\n");
  405.  
  406.       t = has_subdirs (p);
  407.       if (t != NULL)
  408.     {
  409.       if (debug)
  410.         fprintf (stderr, "but it does have a man or MAN subdirectory\n");
  411.  
  412.       add_dir_to_list (tmplist, t, perrs);
  413.       free (t);
  414.     }
  415.       else
  416.     {
  417.       if (debug)
  418.         fprintf (stderr, "and doesn't have man or MAN subdirectories\n");
  419.     }
  420.  
  421.     found:
  422.  
  423.       if (!end)
  424.     break;
  425.     }
  426.  
  427.   if (debug)
  428.     fprintf (stderr, "\nadding mandatory man directories\n\n");
  429.  
  430.   dlp = list;
  431.   while (dlp->mandatory != 0)
  432.     {
  433.       add_dir_to_list (tmplist, dlp->mandir, perrs);
  434.       dlp++;
  435.     }
  436.  
  437.   len = 0;
  438.   lp = tmplist;
  439.   while (*lp != NULL)
  440.     {
  441.       len += strlen (*lp) + 1;
  442.       lp++;
  443.     }
  444.  
  445.   manpathlist = (char *) malloc (len+1);
  446.   if (manpathlist == NULL)
  447.     gripe_alloc (len, "manpathlist");
  448.  
  449.   *manpathlist = '\0';
  450.  
  451.   lp = tmplist;
  452.   p = manpathlist;
  453.   while (*lp != NULL)
  454.     {
  455.       len = strlen (*lp);
  456.       memcpy (p, *lp, len);
  457.       p += len;
  458.       *p++ = PATHSEP;
  459.       lp++;
  460.     }
  461.  
  462.   if (p > manpathlist)
  463.     p[-1] = '\0';
  464.  
  465.   return manpathlist;
  466. }
  467.  
  468. /*
  469.  * Add a directory to the manpath list if it isn't already there.
  470.  */
  471. void
  472. add_dir_to_list (lp, dir, perrs)
  473.      char **lp;
  474.      char *dir;
  475.      int perrs;
  476. {
  477.   extern char *strdup ();
  478.   int status;
  479.  
  480.   while (*lp != NULL)
  481.     {
  482.       if (!strcmp (*lp, dir))
  483.     {
  484.       if (debug)
  485.         fprintf (stderr, "%s is already in the manpath\n", dir);
  486.       return;
  487.     }
  488.       lp++;
  489.     }
  490.   /*
  491.    * Not found -- add it.
  492.    */
  493.   status = is_directory(dir);
  494.  
  495.   if (status < 0 && perrs)
  496.     {
  497.       fprintf (stderr, "Warning: couldn't stat file %s!\n", dir);
  498.     }
  499.   else if (status == 0 && perrs)
  500.     {
  501.       fprintf (stderr, "Warning: %s isn't a directory!\n", dir);
  502.     }
  503.   else if (status == 1)
  504.     {
  505.       if (debug)
  506.     fprintf (stderr, "adding %s to manpath\n", dir);
  507.  
  508.       *lp = strdup (dir);
  509.     }
  510. }
  511.  
  512. /*
  513.  * Check to see if the current directory has man or MAN
  514.  * subdirectories. 
  515.  */
  516. char *
  517. has_subdirs (p)
  518.      register char *p;
  519. {
  520.   int len;
  521.   register char *t;
  522.  
  523.   len = strlen (p);
  524.  
  525.   t = (char *) malloc ((unsigned) len + 5);
  526.   if (t == NULL)
  527.     gripe_alloc (len+5, "p\n");
  528.  
  529.   memcpy (t, p, len);
  530.   strcpy (t + len, "/man");
  531.   
  532.   if (is_directory (t) == 1)
  533.     return t;
  534.  
  535.   strcpy (t + len, "/MAN");
  536.   
  537.   if (is_directory (t) == 1)
  538.     return t;
  539.  
  540.   return NULL;
  541. }
  542.