(root)/
man-db-2.12.0/
lib/
pathsearch.c
       1  /*
       2   * pathsearch.c: $PATH-searching functions.
       3   *
       4   * Copyright (C) 2004, 2007, 2008, 2009, 2011 Colin Watson.
       5   *
       6   * This file is part of man-db.
       7   *
       8   * man-db is free software; you can redistribute it and/or modify it
       9   * under the terms of the GNU General Public License as published by
      10   * the Free Software Foundation; either version 2 of the License, or
      11   * (at your option) any later version.
      12   *
      13   * man-db is distributed in the hope that it will be useful, but
      14   * WITHOUT ANY WARRANTY; without even the implied warranty of
      15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16   * GNU General Public License for more details.
      17   *
      18   * You should have received a copy of the GNU General Public License
      19   * along with man-db; if not, write to the Free Software Foundation,
      20   * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
      21   */
      22  
      23  #ifdef HAVE_CONFIG_H
      24  #  include "config.h"
      25  #endif /* HAVE_CONFIG_H */
      26  
      27  #include <assert.h>
      28  #include <errno.h>
      29  #include <stdbool.h>
      30  #include <string.h>
      31  #include <stdlib.h>
      32  
      33  #include <sys/types.h>
      34  #include <sys/stat.h>
      35  #include <unistd.h>
      36  
      37  #include "gettext.h"
      38  #define _(String) gettext (String)
      39  
      40  #include "xalloc.h"
      41  #include "xgetcwd.h"
      42  #include "xvasprintf.h"
      43  
      44  #include "manconfig.h"
      45  
      46  #include "fatal.h"
      47  #include "pathsearch.h"
      48  
      49  static bool pathsearch (const char *name, const mode_t bits)
      50  {
      51  	char *cwd = NULL;
      52  	char *path = getenv ("PATH");
      53  	char *pathtok;
      54  	const char *element;
      55  	struct stat st;
      56  	bool ret = false;
      57  
      58  	if (!path)
      59  		/* Eh? Oh well. */
      60  		return false;
      61  
      62  	if (strchr (name, '/')) {
      63  		/* Qualified name; look directly. */
      64  		if (stat (name, &st) == -1)
      65  			return false;
      66  		if (S_ISREG (st.st_mode) && (st.st_mode & bits))
      67  			return true;
      68  		return false;
      69  	}
      70  
      71  	pathtok = path = xstrdup (path);
      72  
      73  	/* Unqualified name; iterate over $PATH looking for it. */
      74  	for (element = strsep (&pathtok, ":"); element;
      75  	     element = strsep (&pathtok, ":")) {
      76  		char *filename;
      77  
      78  		if (!*element) {
      79  			if (!cwd)
      80  				cwd = xgetcwd ();
      81  			if (!cwd)
      82  				fatal (errno,
      83  				       _("can't determine current directory"));
      84  			element = cwd;
      85  		}
      86  
      87  		filename = xasprintf ("%s/%s", element, name);
      88  		assert (filename);
      89  		if (stat (filename, &st) == -1) {
      90  			free (filename);
      91  			continue;
      92  		}
      93  
      94  		free (filename);
      95  
      96  		if (S_ISREG (st.st_mode) && (st.st_mode & bits)) {
      97  			ret = true;
      98  			break;
      99  		}
     100  	}
     101  
     102  	free (path);
     103  	free (cwd);
     104  	return ret;
     105  }
     106  
     107  bool pathsearch_executable (const char *name)
     108  {
     109  	return pathsearch (name, 0111);
     110  }
     111  
     112  bool directory_on_path (const char *dir)
     113  {
     114  	char *cwd = NULL;
     115  	char *path = getenv ("PATH");
     116  	char *pathtok;
     117  	const char *element;
     118  	bool ret = false;
     119  
     120  	if (!path)
     121  		/* Eh? Oh well. */
     122  		return false;
     123  
     124  	pathtok = path = xstrdup (path);
     125  
     126  	for (element = strsep (&pathtok, ":"); element;
     127  	     element = strsep (&pathtok, ":")) {
     128  		if (!*element) {
     129  			if (!cwd)
     130  				cwd = xgetcwd ();
     131  			if (!cwd)
     132  				fatal (errno,
     133  				       _("can't determine current directory"));
     134  			element = cwd;
     135  		}
     136  
     137  		if (STREQ (element, dir)) {
     138  			ret = true;
     139  			break;
     140  		}
     141  	}
     142  
     143  	free (path);
     144  	free (cwd);
     145  	return ret;
     146  }