int find_cmd_in_path(const char cmd[], size_t path_len, char path[]) { size_t i; size_t paths_count; char **paths; paths = get_paths(&paths_count); for(i = 0; i < paths_count; i++) { char tmp_path[PATH_MAX]; snprintf(tmp_path, sizeof(tmp_path), "%s/%s", paths[i], cmd); /* Need to check for executable, not just a file, as this additionally * checks for path with different executable extensions on Windows. */ if(executable_exists(tmp_path)) { if(path != NULL) { copy_str(path, path_len, tmp_path); } return 0; } } return 1; }
int external_command_exists(const char cmd[]) { char path[PATH_MAX]; if(get_cmd_path(cmd, sizeof(path), path) == 0) { return executable_exists(path); } return 0; }
/* Checks whether executable exists at absolute path orin directories listed in * $PATH when path isn't absolute. Checks for various executable extensions on * Windows. Returns boolean value describing result of the check. */ static var_t executable_builtin(const call_info_t *call_info) { int exists; char *str_val; str_val = var_to_string(call_info->argv[0]); if(is_path_absolute(str_val)) { exists = executable_exists(str_val); } else { exists = (find_cmd_in_path(str_val, 0UL, NULL) == 0); } free(str_val); return exists ? var_true() : var_false(); }
/* Checks whether executable exists at absolute path orin directories listed in * $PATH when path isn't absolute. Checks for various executable extensions on * Windows. Returns boolean value describing result of the check. */ static var_t executable_builtin(const call_info_t *call_info) { int exists; char *str_val; str_val = var_to_string(call_info->argv[0]); if(strpbrk(str_val, PATH_SEPARATORS) != NULL) { exists = executable_exists(str_val); } else { exists = (find_cmd_in_path(str_val, 0UL, NULL) == 0); } free(str_val); return var_from_bool(exists); }
int main(int argc, char **argv) { char *me = argv[0], *data, **new_argv; char *exe_path, *lib_path, *dll_path; int start, prog_end, end, count, fd, v, en, x11; int argpos, inpos, collcount = 1, fix_argv; if (config[7] == '[') { write_str(2, argv[0]); write_str(2, ": this is an unconfigured starter\n"); return 1; } if (me[0] == '/') { /* Absolute path */ } else if (has_slash(me)) { /* Relative path with a directory: */ char *buf; long buflen = 4096; buf = (char *)malloc(buflen); me = path_append(getcwd(buf, buflen), me); } else { /* We have to find the executable by searching PATH: */ char *path = copy_string(getenv("PATH")), *p, *m; int more; if (!path) { path = ""; } while (1) { /* Try each element of path: */ for (p = path; *p && (*p != ':'); p++) { } if (*p) { *p = 0; more = 1; } else more = 0; if (!*path) break; m = path_append(path, me); if (executable_exists(m)) { if (m[0] != '/') m = path_append(getcwd(NULL, 0), m); me = m; break; } free(m); if (more) path = p + 1; else break; } } /* me is now an absolute path to the binary */ /* resolve soft links */ while (1) { int len, bufsize = 127; char *buf; buf = (char *)malloc(bufsize + 1); len = readlink(me, buf, bufsize); if (len < 0) { if (errno == ENAMETOOLONG) { /* Increase buffer size and try again: */ bufsize *= 2; buf = (char *)malloc(bufsize + 1); } else break; } else { /* Resolve buf relative to me: */ buf[len] = 0; buf = absolutize(buf, me); me = buf; buf = (char *)malloc(bufsize + 1); } } start = as_int(config + 8); prog_end = as_int(config + 12); end = as_int(config + 16); count = as_int(config + 20); x11 = as_int(config + 24); fix_argv = try_elf_section(me, &start, &prog_end, &end); { int offset, len; offset = _coldir_offset; while (1) { len = strlen(_coldir + offset); offset += len + 1; if (!_coldir[offset]) break; collcount++; } } data = (char *)malloc(end - prog_end); new_argv = (char **)malloc((count + argc + (2 * collcount) + 8) * sizeof(char*)); fd = open(me, O_RDONLY, 0); lseek(fd, prog_end, SEEK_SET); { int expected_length = end - prog_end; if (expected_length != read(fd, data, expected_length)) { printf("read failed to read all %i bytes from file %s\n", expected_length, me); abort(); } } close(fd); exe_path = data; data = next_string(data); lib_path = data; data = next_string(data); exe_path = absolutize(exe_path, me); lib_path = absolutize(lib_path, me); # ifdef OS_X # define LD_LIB_PATH "DYLD_LIBRARY_PATH" # else # define LD_LIB_PATH "LD_LIBRARY_PATH" # endif if (*lib_path) { dll_path = getenv(LD_LIB_PATH); if (!dll_path) { dll_path = ""; } dll_path = string_append(dll_path, ":"); dll_path = string_append(lib_path, dll_path); dll_path = string_append(LD_LIB_PATH "=", dll_path); putenv(dll_path); } new_argv[0] = me; argpos = 1; inpos = 1; /* Keep all X11 flags to the front: */ if (x11) { int n; while (inpos < argc) { n = is_x_flag(argv[inpos]); if (!n) break; if (inpos + n > argc) { write_str(2, argv[0]); write_str(2, ": missing an argument for "); write_str(2, argv[inpos]); write_str(2, "\n"); return 1; } while (n--) { new_argv[argpos++] = argv[inpos++]; } } } /* Add -X and -S flags */ { int offset, len; offset = _coldir_offset; new_argv[argpos++] = "-X"; new_argv[argpos++] = absolutize(_coldir + offset, me); while (1) { len = strlen(_coldir + offset); offset += len + 1; if (!_coldir[offset]) break; new_argv[argpos++] = "-S"; new_argv[argpos++] = absolutize(_coldir + offset, me); } } if (fix_argv) { /* next three args are "-k" and numbers; fix the numbers to match start and prog_end */ fix_argv = argpos + 1; } /* Add built-in flags: */ while (count--) { new_argv[argpos++] = data; data = next_string(data); } /* Propagate new flags (after the X11 flags) */ while (inpos < argc) { new_argv[argpos++] = argv[inpos++]; } new_argv[argpos] = NULL; if (fix_argv) { new_argv[fix_argv] = num_to_string(start); new_argv[fix_argv+1] = num_to_string(prog_end); } /* Execute the original binary: */ v = execv(exe_path, new_argv); en = errno; write_str(2, argv[0]); write_str(2, ": failed to start "); write_str(2, exe_path); write_str(2, " ("); write_str(2, strerror(en)); write_str(2, ")\n"); if (*lib_path) { write_str(2, " used library path "); write_str(2, lib_path); write_str(2, "\n"); } return v; }