1 /* 2 * Copyright (C) 2010 Cyril Hrubis chrubis (at) suse.cz 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 */ 23 24 /* 25 * Looks for binary prog_name in $PATH. 26 * 27 * If such file exists and if you are able at least to read it, zero is 28 * returned and absolute path to the file is filled into buf. In case buf is 29 * too short to hold the absolute path + prog_name for the file we are looking 30 * for -1 is returned as well as when there is no such file in all paths in 31 * $PATH. 32 */ 33 34 #include "test.h" 35 36 #include <stdio.h> 37 #include <string.h> 38 #include <stdlib.h> 39 #include <unistd.h> 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 43 #ifndef MIN 44 #define MIN(a, b) ((a)<(b)?(a):(b)) 45 #endif 46 47 static int file_exist(const char *path) 48 { 49 struct stat st; 50 51 if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode)) 52 return 1; 53 54 return 0; 55 } 56 57 int tst_get_path(const char *prog_name, char *buf, size_t buf_len) 58 { 59 const char *path = (const char *)getenv("PATH"); 60 const char *start = path; 61 const char *end; 62 size_t size, ret; 63 64 if (path == NULL) 65 return -1; 66 67 do { 68 end = strchr(start, ':'); 69 70 if (end != NULL) 71 snprintf(buf, MIN(buf_len, (size_t) (end - start + 1)), 72 "%s", start); 73 else 74 snprintf(buf, buf_len, "%s", start); 75 76 size = strlen(buf); 77 78 /* 79 * "::" inside $PATH, $PATH ending with ':' or $PATH starting 80 * with ':' should be expanded into current working directory. 81 */ 82 if (size == 0) { 83 snprintf(buf, buf_len, "."); 84 size = strlen(buf); 85 } 86 87 /* 88 * If there is no '/' ad the end of path from $PATH add it. 89 */ 90 if (buf[size - 1] != '/') 91 ret = 92 snprintf(buf + size, buf_len - size, "/%s", 93 prog_name); 94 else 95 ret = 96 snprintf(buf + size, buf_len - size, "%s", 97 prog_name); 98 99 if (buf_len - size > ret && file_exist(buf)) 100 return 0; 101 102 start = end + 1; 103 104 } while (end != NULL); 105 106 return -1; 107 } 108