diff options
Diffstat (limited to 'gnu/usr.bin/man/manpath/manpath.c')
| -rw-r--r-- | gnu/usr.bin/man/manpath/manpath.c | 520 | 
1 files changed, 520 insertions, 0 deletions
| diff --git a/gnu/usr.bin/man/manpath/manpath.c b/gnu/usr.bin/man/manpath/manpath.c new file mode 100644 index 000000000000..ccf7a5568434 --- /dev/null +++ b/gnu/usr.bin/man/manpath/manpath.c @@ -0,0 +1,520 @@ +/* + * manpath.c + * + * Copyright (c) 1990, 1991, John W. Eaton. + * + * You may distribute under the terms of the GNU General Public + * License as specified in the file COPYING that comes with the man + * distribution.   + * + * John W. Eaton + * jwe@che.utexas.edu + * Department of Chemical Engineering + * The University of Texas at Austin + * Austin, Texas  78712 + */ + +#define MANPATH_MAIN + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "manpath.h" +#include "gripes.h" + +#ifdef STDC_HEADERS +#include <stdlib.h> +#else +extern int fprintf (); +extern int strcmp (); +extern int strncmp (); +extern char *memcpy (); +extern char *getenv(); +extern char *malloc(); +extern void free (); +extern int exit (); +#endif + +extern char *strdup (); +extern int is_directory (); + +#ifndef MAIN +extern int debug; +#endif + +#ifdef MAIN + +#ifndef STDC_HEADERS +extern char *strcpy (); +extern int fflush (); +#endif + +char *prognam; +int debug; + +/* + * Examine user's PATH and print a reasonable MANPATH. + */ +int +main(argc, argv) +     int argc; +     char **argv; +{ +  int c; +  int quiet; +  char *mp; +  extern int getopt (); +  extern char *mkprogname (); +  void usage (); +  char *manpath (); + +  quiet = 1; + +  prognam = mkprogname (argv[0]); + +  while ((c = getopt (argc, argv, "dhq?")) != EOF) +    { +      switch (c) +	{ +	case 'd': +	  debug++; +	  break; +	case 'q': +	  quiet = 0; +	  break; +	case '?': +	case 'h': +	default: +	  usage(); +          break; +	} +    } + +  mp = manpath (quiet); + +  fprintf (stdout, "%s\n", mp); +  fflush (stdout); + +  return 0; +} + +void +usage () +{ +  fprintf (stderr, "usage: %s [-q]\n", prognam); +  exit (1); +} +#endif /* MAIN */ + +/* + * If the environment variable MANPATH is set, return it. + * If the environment variable PATH is set and has a nonzero length, + * try to determine the corresponding manpath, otherwise, return the + * default manpath. + * + * The manpath.config file is used to map system wide /bin directories + * to top level man page directories. + * + * For directories which are in the user's path but not in the + * manpath.config file, see if there is a subdirectory `man' or `MAN'. + * If so, add that directory to the path.  Example:  user has + * $HOME/bin in his path and the directory $HOME/bin/man exists -- the + * directory $HOME/bin/man will be added to the manpath. + */ +char * +manpath (perrs) +     register int perrs; +{ +  register int len; +  register char *manpathlist; +  register char *path; +  int  get_dirlist (); +  char *def_path (); +  char *get_manpath (); + +  if (get_dirlist ()) +      gripe_reading_mp_config (); + +  if ((manpathlist = getenv ("MANPATH")) != NULL) +    /* +     * This must be it. +     */ +    { +      if (perrs) +	fprintf (stderr, "(Warning: MANPATH environment variable set)\n"); +      return strdup (manpathlist); +    } +  else if ((path = getenv ("PATH")) == NULL) +    /* +     * Things aren't going to work well, but hey... +     */ +    { +      if (perrs) +	fprintf (stderr, "Warning: path not set\n"); +      return def_path (perrs); +    } +  else +    { +      if ((len = strlen (path)) == 0) +	/* +	 * Things aren't going to work well here either... +	 */ +	{ +	  if (perrs) +	    fprintf (stderr, "Warning: path set but has zero length\n"); +	  return def_path (perrs); +	} +      return get_manpath (perrs, path); +    } +} + +/* + * Get the list of bin directories and the corresponding man + * directories from the manpath.config file. + * + * This is ugly. + */ +int +get_dirlist () +{ +  int i; +  char *bp; +  char *p; +  char buf[BUFSIZ]; +  DIRLIST *dlp = list; +  FILE *config; + +  if ((config = fopen (config_file, "r")) == NULL) +    gripe_getting_mp_config (config_file); + +  while ((bp = fgets (buf, BUFSIZ, config)) != NULL) +    { +      while (*bp && (*bp == ' ' || *bp == '\t')) +	bp++; + +      if (*bp == '#' || *bp == '\n') +	continue; + +      if (!strncmp ("MANBIN", bp, 6)) +	continue; + +      if (!strncmp ("MANDATORY_MANPATH", bp, 17)) +	{ +	  if ((p = strchr (bp, ' ')) == NULL) +	    if ((p = strchr (bp, '\t')) == NULL) +	      return -1; + +	  bp = p; + +	  dlp->mandatory = 1; + +	  while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t')) +	    bp++; + +	  i = 0; +	  while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t') +	    dlp->mandir[i++] = *bp++; +	  dlp->mandir[i] = '\0'; + +	  if (debug) +	    fprintf (stderr, "found mandatory man directory %s\n", +		     dlp->mandir); +	} +      else if (!strncmp ("MANPATH_MAP", bp, 11)) +	{ +	  if ((p = strchr (bp, ' ')) == NULL) +	    if ((p = strchr (bp, '\t')) == NULL) +	      return -1; + +	  bp = p; + +	  dlp->mandatory = 0; + +	  while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t')) +	    bp++; + +	  i = 0; +	  while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t') +	    dlp->bin[i++] = *bp++; +	  dlp->bin[i] = '\0'; + +	  while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t')) +	    bp++; + +	  i = 0; +	  while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t') +	    dlp->mandir[i++] = *bp++; +	  dlp->mandir[i] = '\0'; + +	  if (debug) +	    fprintf (stderr, "found manpath map %s --> %s\n", +		     dlp->bin, dlp->mandir); +	} +      else +	{ +	  gripe_reading_mp_config (); +	} +      dlp++; +    } + +  dlp->bin[0] = '\0'; +  dlp->mandir[0] = '\0'; +  dlp->mandatory = 0; + +  return 0; +} + +/* + * Construct the default manpath.  This picks up mandatory manpaths + * only. + */ +char * +def_path (perrs) +     int perrs; +{ +  register int len; +  register char *manpathlist, *p; +  register DIRLIST *dlp; + +  len = 0; +  dlp = list; +  while (dlp->mandatory != 0) +    { +      len += strlen (dlp->mandir) + 1; +      dlp++; +    } + +  manpathlist = (char *) malloc (len); +  if (manpathlist == NULL) +    gripe_alloc (len, "manpathlist"); + +  *manpathlist = '\0'; + +  dlp = list; +  p = manpathlist; +  while (dlp->mandatory != 0) +    { +      int status; +      char *path = dlp->mandir; + +      status = is_directory(path); + +      if (status < 0 && perrs) +	{ +	  fprintf (stderr, "Warning: couldn't stat file %s!\n", path); +	} +      else if (status == 0 && perrs) +	{ +	  fprintf (stderr, "Warning: standard directory %s doesn't exist!\n", +		   path); +	} +      else if (status == 1) +	{ +	  len = strlen (path); +	  memcpy (p, path, len); +	  p += len; +	  *p++ = ':'; +	  dlp++; +	} +    } + +  p[-1] = '\0'; + +  return manpathlist; +} + +/* + * For each directory in the user's path, see if it is one of the + * directories listed in the manpath.config file.  If so, and it is + * not already in the manpath, add it.  If the directory is not listed + * in the manpath.config file, see if there is a subdirectory `man' or + * `MAN'.  If so, and it is not already in the manpath, add it. + * Example:  user has $HOME/bin in his path and the directory + * $HOME/bin/man exists -- the directory $HOME/bin/man will be added + * to the manpath. + */ +char * +get_manpath (perrs, path) +     register int perrs; +     register char *path; +{ +  register int len; +  register char *tmppath; +  register char *t; +  register char *p; +  register char **lp; +  register char *end; +  register char *manpathlist; +  register DIRLIST *dlp; +  void add_dir_to_list (); +  char *has_subdirs (); + +  tmppath = strdup (path); + +  for (p = tmppath; ; p = end+1) +    { +      if (end = strchr(p, ':')) +	*end = '\0'; + +      if (debug) +	fprintf (stderr, "\npath directory %s ", p); + +      /* +       * The directory we're working on is in the config file. +       * If we haven't added it to the list yet, do. +       */ +      for (dlp = list; dlp->mandir[0] != '\0'; dlp++) +	if (dlp->bin[0] != '\0' && !strcmp (p, dlp->bin)) +	  { +	    if (debug) +	      fprintf (stderr, "is in the config file\n"); + +	    add_dir_to_list (tmplist, dlp->mandir, perrs); +	    goto found; +	  } + +      /* +       * The directory we're working on isn't in the config file.  See +       * if it has man or MAN subdirectories.  If so, and it hasn't +       * been added to the list, do. +       */ +      if (debug) +	fprintf (stderr, "is not in the config file\n"); + +      t = has_subdirs (p); +      if (t != NULL) +	{ +	  if (debug) +	    fprintf (stderr, "but it does have a man or MAN subdirectory\n"); + +	  add_dir_to_list (tmplist, t, perrs); +	  free (t); +	} +      else +	{ +	  if (debug) +	    fprintf (stderr, "and doesn't have man or MAN subdirectories\n"); +	} + +    found: + +      if (!end) +	break; +    } + +  if (debug) +    fprintf (stderr, "\nadding mandatory man directories\n\n"); + +  dlp = list; +  while (dlp->mandatory != 0) +    { +      add_dir_to_list (tmplist, dlp->mandir, perrs); +      dlp++; +    } + +  len = 0; +  lp = tmplist; +  while (*lp != NULL) +    { +      len += strlen (*lp) + 1; +      lp++; +    } + +  manpathlist = (char *) malloc (len); +  if (manpathlist == NULL) +    gripe_alloc (len, "manpathlist"); + +  *manpathlist = '\0'; + +  lp = tmplist; +  p = manpathlist; +  while (*lp != NULL) +    { +      len = strlen (*lp); +      memcpy (p, *lp, len); +      p += len; +      *p++ = ':'; +      lp++; +    } + +  p[-1] = '\0'; + +  return manpathlist; +} + +/* + * Add a directory to the manpath list if it isn't already there. + */ +void +add_dir_to_list (lp, dir, perrs) +     char **lp; +     char *dir; +     int perrs; +{ +  extern char *strdup (); +  int status; + +  while (*lp != NULL) +    { +      if (!strcmp (*lp, dir)) +	{ +	  if (debug) +	    fprintf (stderr, "%s is already in the manpath\n", dir); +	  return; +	} +      lp++; +    } +  /* +   * Not found -- add it. +   */ +  status = is_directory(dir); + +  if (status < 0 && perrs) +    { +      fprintf (stderr, "Warning: couldn't stat file %s!\n", dir); +    } +  else if (status == 0 && perrs) +    { +      fprintf (stderr, "Warning: %s isn't a directory!\n", dir); +    } +  else if (status == 1) +    { +      if (debug) +	fprintf (stderr, "adding %s to manpath\n", dir); + +      *lp = strdup (dir); +    } +} + +/* + * Check to see if the current directory has man or MAN + * subdirectories.  + */ +char * +has_subdirs (p) +     register char *p; +{ +  int len; +  register char *t; + +  len = strlen (p); + +  t = (char *) malloc ((unsigned) len + 5); +  if (t == NULL) +    gripe_alloc (len+5, "p\n"); + +  memcpy (t, p, len); +  strcpy (t + len, "/man"); +   +  if (is_directory (t) == 1) +    return t; + +  strcpy (t + len, "/MAN"); +   +  if (is_directory (t) == 1) +    return t; + +  return NULL; +} | 
