You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							167 lines
						
					
					
						
							4.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							167 lines
						
					
					
						
							4.7 KiB
						
					
					
				
								/**
							 | 
						|
								  @file
							 | 
						|
								
							 | 
						|
								  @ingroup util
							 | 
						|
								
							 | 
						|
								  @brief Search in PATH.
							 | 
						|
								
							 | 
						|
								  @copyright@parblock
							 | 
						|
								  Copyright (c) 1994-1998 The Regents of the Univ. of California.
							 | 
						|
								  All rights reserved.
							 | 
						|
								
							 | 
						|
								  Permission is hereby granted, without written agreement and without license
							 | 
						|
								  or royalty fees, to use, copy, modify, and distribute this software and its
							 | 
						|
								  documentation for any purpose, provided that the above copyright notice and
							 | 
						|
								  the following two paragraphs appear in all copies of this software.
							 | 
						|
								
							 | 
						|
								  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
							 | 
						|
								  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
							 | 
						|
								  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
							 | 
						|
								  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								
							 | 
						|
								  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
							 | 
						|
								  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
							 | 
						|
								  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
							 | 
						|
								  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
							 | 
						|
								  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
							 | 
						|
								  @endparblock
							 | 
						|
								
							 | 
						|
								  @copyright@parblock
							 | 
						|
								  Copyright (c) 1999-2015, Regents of the University of Colorado
							 | 
						|
								
							 | 
						|
								  All rights reserved.
							 | 
						|
								
							 | 
						|
								  Redistribution and use in source and binary forms, with or without
							 | 
						|
								  modification, are permitted provided that the following conditions
							 | 
						|
								  are met:
							 | 
						|
								
							 | 
						|
								  Redistributions of source code must retain the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer.
							 | 
						|
								
							 | 
						|
								  Redistributions in binary form must reproduce the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer in the
							 | 
						|
								  documentation and/or other materials provided with the distribution.
							 | 
						|
								
							 | 
						|
								  Neither the name of the University of Colorado nor the names of its
							 | 
						|
								  contributors may be used to endorse or promote products derived from
							 | 
						|
								  this software without specific prior written permission.
							 | 
						|
								
							 | 
						|
								  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
							 | 
						|
								  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
							 | 
						|
								  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
							 | 
						|
								  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
							 | 
						|
								  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
							 | 
						|
								  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
							 | 
						|
								  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
							 | 
						|
								  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
							 | 
						|
								  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
							 | 
						|
								  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
							 | 
						|
								  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
							 | 
						|
								  POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								  @endparblock
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								
							 | 
						|
								#include "util.h"
							 | 
						|
								
							 | 
						|
								/** \cond */
							 | 
						|
								
							 | 
						|
								static int check_file (char const *, char const *);
							 | 
						|
								
							 | 
						|
								/** \endcond */
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * @brief Looks for a program in the directories specified by PATH.
							 | 
						|
								 */
							 | 
						|
								char *
							 | 
						|
								util_path_search(char const *prog)
							 | 
						|
								{
							 | 
						|
								#ifdef UNIX
							 | 
						|
								    return util_file_search(prog, getenv("PATH"), (char *) "x");
							 | 
						|
								#else
							 | 
						|
								    return util_file_search(prog, NIL(char), (char *) "x");
							 | 
						|
								#endif
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * @brief Searches for a file given a set of paths.
							 | 
						|
								 */
							 | 
						|
								char *
							 | 
						|
								util_file_search(
							 | 
						|
								  char const *file,		/**< file we're looking for */
							 | 
						|
								  char *path,			/**< search path, colon separated */
							 | 
						|
								  char const *mode		/**< "r", "w", or "x" */)
							 | 
						|
								{
							 | 
						|
								    int quit;
							 | 
						|
								    char *buffer, *filename, *save_path, *cp;
							 | 
						|
								
							 | 
						|
								    if (path == 0 || strcmp(path, "") == 0) {
							 | 
						|
									path = (char *) ".";	/* just look in the current directory */
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    save_path = path = util_strsav(path);
							 | 
						|
								    quit = 0;
							 | 
						|
								    do {
							 | 
						|
									cp = strchr(path, ':');
							 | 
						|
									if (cp != 0) {
							 | 
						|
									    *cp = '\0';
							 | 
						|
									} else {
							 | 
						|
									    quit = 1;
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									/* cons up the filename out of the path and file name */
							 | 
						|
									if (strcmp(path, ".") == 0) {
							 | 
						|
									    buffer = util_strsav(file);
							 | 
						|
									} else {
							 | 
						|
									    buffer = ALLOC(char, strlen(path) + strlen(file) + 4);
							 | 
						|
									    (void) sprintf(buffer, "%s/%s", path, file);
							 | 
						|
									}
							 | 
						|
									filename = util_tilde_expand(buffer);
							 | 
						|
									FREE(buffer);
							 | 
						|
								
							 | 
						|
									/* see if we can access it */
							 | 
						|
									if (check_file(filename, mode)) {
							 | 
						|
									    FREE(save_path);
							 | 
						|
									    return filename;
							 | 
						|
									}
							 | 
						|
									FREE(filename);
							 | 
						|
									path = ++cp;
							 | 
						|
								    } while (! quit); 
							 | 
						|
								
							 | 
						|
								    FREE(save_path);
							 | 
						|
								    return 0;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * @brief Checks user permissions for a file.
							 | 
						|
								 */
							 | 
						|
								static int
							 | 
						|
								check_file(char const *filename, char const *mode)
							 | 
						|
								{
							 | 
						|
								#ifdef UNIX
							 | 
						|
								    int access_mode = /*F_OK*/ 0;
							 | 
						|
								
							 | 
						|
								    if (strcmp(mode, "r") == 0) {
							 | 
						|
									access_mode = /*R_OK*/ 4;
							 | 
						|
								    } else if (strcmp(mode, "w") == 0) {
							 | 
						|
									access_mode = /*W_OK*/ 2;
							 | 
						|
								    } else if (strcmp(mode, "x") == 0) {
							 | 
						|
									access_mode = /*X_OK*/ 1;
							 | 
						|
								    }
							 | 
						|
								    return access(filename, access_mode) == 0;
							 | 
						|
								#else
							 | 
						|
								    FILE *fp;
							 | 
						|
								    int got_file;
							 | 
						|
								
							 | 
						|
								    if (strcmp(mode, "x") == 0) {
							 | 
						|
									mode = "r";
							 | 
						|
								    }
							 | 
						|
								    fp = fopen(filename, mode);
							 | 
						|
								    got_file = (fp != 0);
							 | 
						|
								    if (fp != 0) {
							 | 
						|
									(void) fclose(fp);
							 | 
						|
								    }
							 | 
						|
								    return got_file;
							 | 
						|
								#endif
							 | 
						|
								}
							 |