| 1 | /* -*- Mode: C; c-basic-offset:4 ; -*- */ |
|---|
| 2 | /* |
|---|
| 3 | * (C) 2008 by Argonne National Laboratory. |
|---|
| 4 | * See COPYRIGHT in top-level directory. |
|---|
| 5 | */ |
|---|
| 6 | |
|---|
| 7 | #include "hydra_utils.h" |
|---|
| 8 | |
|---|
| 9 | static int exists(char *filename) |
|---|
| 10 | { |
|---|
| 11 | struct stat file_stat; |
|---|
| 12 | |
|---|
| 13 | if ((stat(filename, &file_stat) < 0) || !(S_ISREG(file_stat.st_mode))) { |
|---|
| 14 | return 0; /* no such file, or not a regular file */ |
|---|
| 15 | } |
|---|
| 16 | |
|---|
| 17 | return 1; |
|---|
| 18 | } |
|---|
| 19 | |
|---|
| 20 | HYD_Status HYDU_find_in_path(const char *execname, char **path) |
|---|
| 21 | { |
|---|
| 22 | char *user_path = NULL, *tmp[HYD_NUM_TMP_STRINGS], *path_loc = NULL, *test_loc; |
|---|
| 23 | HYD_Status status = HYD_SUCCESS; |
|---|
| 24 | |
|---|
| 25 | HYDU_FUNC_ENTER(); |
|---|
| 26 | |
|---|
| 27 | /* The executable is somewhere in the user's path. We need to find |
|---|
| 28 | * it. */ |
|---|
| 29 | if (getenv("PATH")) { /* If the PATH environment exists */ |
|---|
| 30 | user_path = HYDU_strdup(getenv("PATH")); |
|---|
| 31 | test_loc = strtok(user_path, ";:"); |
|---|
| 32 | do { |
|---|
| 33 | tmp[0] = HYDU_strdup(test_loc); |
|---|
| 34 | tmp[1] = HYDU_strdup("/"); |
|---|
| 35 | tmp[2] = HYDU_strdup(execname); |
|---|
| 36 | tmp[3] = NULL; |
|---|
| 37 | |
|---|
| 38 | status = HYDU_str_alloc_and_join(tmp, &path_loc); |
|---|
| 39 | HYDU_ERR_POP(status, "unable to join strings\n"); |
|---|
| 40 | HYDU_free_strlist(tmp); |
|---|
| 41 | |
|---|
| 42 | if (exists(path_loc)) { |
|---|
| 43 | tmp[0] = HYDU_strdup(test_loc); |
|---|
| 44 | tmp[1] = HYDU_strdup("/"); |
|---|
| 45 | tmp[2] = NULL; |
|---|
| 46 | |
|---|
| 47 | status = HYDU_str_alloc_and_join(tmp, path); |
|---|
| 48 | HYDU_ERR_POP(status, "unable to join strings\n"); |
|---|
| 49 | HYDU_free_strlist(tmp); |
|---|
| 50 | |
|---|
| 51 | goto fn_exit; /* We are done */ |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | HYDU_FREE(path_loc); |
|---|
| 55 | path_loc = NULL; |
|---|
| 56 | } while ((test_loc = strtok(NULL, ";:"))); |
|---|
| 57 | } |
|---|
| 58 | |
|---|
| 59 | /* There is either no PATH environment or we could not find the |
|---|
| 60 | * file in the PATH. Just return an empty path */ |
|---|
| 61 | *path = HYDU_strdup(""); |
|---|
| 62 | |
|---|
| 63 | fn_exit: |
|---|
| 64 | if (user_path) |
|---|
| 65 | HYDU_FREE(user_path); |
|---|
| 66 | if (path_loc) |
|---|
| 67 | HYDU_FREE(path_loc); |
|---|
| 68 | HYDU_FUNC_EXIT(); |
|---|
| 69 | return status; |
|---|
| 70 | |
|---|
| 71 | fn_fail: |
|---|
| 72 | goto fn_exit; |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | HYD_Status HYDU_get_base_path(const char *execname, char *wdir, char **path) |
|---|
| 76 | { |
|---|
| 77 | char *loc, *post; |
|---|
| 78 | char *tmp[HYD_NUM_TMP_STRINGS]; |
|---|
| 79 | HYD_Status status = HYD_SUCCESS; |
|---|
| 80 | |
|---|
| 81 | HYDU_FUNC_ENTER(); |
|---|
| 82 | |
|---|
| 83 | /* Find the last '/' in the executable name */ |
|---|
| 84 | post = HYDU_strdup(execname); |
|---|
| 85 | loc = strrchr(post, '/'); |
|---|
| 86 | if (!loc) { /* If there is no path */ |
|---|
| 87 | *path = NULL; |
|---|
| 88 | status = HYDU_find_in_path(execname, path); |
|---|
| 89 | HYDU_ERR_POP(status, "error while searching for executable in the user path\n"); |
|---|
| 90 | } |
|---|
| 91 | else { /* There is a path */ |
|---|
| 92 | *(++loc) = 0; |
|---|
| 93 | |
|---|
| 94 | /* Check if its absolute or relative */ |
|---|
| 95 | if (post[0] != '/') { /* relative */ |
|---|
| 96 | tmp[0] = HYDU_strdup(wdir); |
|---|
| 97 | tmp[1] = HYDU_strdup("/"); |
|---|
| 98 | tmp[2] = HYDU_strdup(post); |
|---|
| 99 | tmp[3] = NULL; |
|---|
| 100 | status = HYDU_str_alloc_and_join(tmp, path); |
|---|
| 101 | HYDU_ERR_POP(status, "unable to join strings\n"); |
|---|
| 102 | HYDU_free_strlist(tmp); |
|---|
| 103 | } |
|---|
| 104 | else { /* absolute */ |
|---|
| 105 | *path = HYDU_strdup(post); |
|---|
| 106 | } |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | fn_exit: |
|---|
| 110 | if (post) |
|---|
| 111 | HYDU_FREE(post); |
|---|
| 112 | HYDU_FUNC_EXIT(); |
|---|
| 113 | return status; |
|---|
| 114 | |
|---|
| 115 | fn_fail: |
|---|
| 116 | goto fn_exit; |
|---|
| 117 | } |
|---|