| 1 | /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
| 2 | |
| 3 | This program is free software; you can redistribute it and/or modify |
| 4 | it under the terms of the GNU General Public License as published by |
| 5 | the Free Software Foundation; version 2 of the License. |
| 6 | |
| 7 | This program is distributed in the hope that it will be useful, |
| 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | GNU General Public License for more details. |
| 11 | |
| 12 | You should have received a copy of the GNU General Public License |
| 13 | along with this program; if not, write to the Free Software |
| 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
| 15 | |
| 16 | #include "mysys_priv.h" |
| 17 | #include <m_string.h> |
| 18 | |
| 19 | static char *find_file_in_path(char *to,const char *name); |
| 20 | |
| 21 | /* Finds where program can find it's files. |
| 22 | pre_pathname is found by first locking at progname (argv[0]). |
| 23 | if progname contains path the path is returned. |
| 24 | else if progname is found in path, return it |
| 25 | else if progname is given and POSIX environment variable "_" is set |
| 26 | then path is taken from "_". |
| 27 | If filename doesn't contain a path append MY_BASEDIR_VERSION or |
| 28 | MY_BASEDIR if defined, else append "/my/running". |
| 29 | own_path_name_part is concatinated to result. |
| 30 | my_path puts result in to and returns to */ |
| 31 | |
| 32 | char * my_path(char * to, const char *progname, |
| 33 | const char *own_pathname_part) |
| 34 | { |
| 35 | char *start, *end, *prog; |
| 36 | size_t to_length; |
| 37 | DBUG_ENTER("my_path" ); |
| 38 | |
| 39 | start=to; /* Return this */ |
| 40 | if (progname && (dirname_part(to, progname, &to_length) || |
| 41 | find_file_in_path(to,progname) || |
| 42 | ((prog=getenv("_" )) != 0 && |
| 43 | dirname_part(to, prog, &to_length)))) |
| 44 | { |
| 45 | (void) intern_filename(to,to); |
| 46 | if (!test_if_hard_path(to)) |
| 47 | { |
| 48 | if (!my_getwd(curr_dir,FN_REFLEN,MYF(0))) |
| 49 | bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1); |
| 50 | } |
| 51 | } |
| 52 | else |
| 53 | { |
| 54 | if ((end = getenv("MY_BASEDIR_VERSION" )) == 0 && |
| 55 | (end = getenv("MY_BASEDIR" )) == 0) |
| 56 | { |
| 57 | #ifdef DEFAULT_BASEDIR |
| 58 | end= (char*) DEFAULT_BASEDIR; |
| 59 | #else |
| 60 | end= (char*) "/my/" ; |
| 61 | #endif |
| 62 | } |
| 63 | (void) intern_filename(to,end); |
| 64 | to=strend(to); |
| 65 | if (to != start && to[-1] != FN_LIBCHAR) |
| 66 | *to++ = FN_LIBCHAR; |
| 67 | (void) strmov(to,own_pathname_part); |
| 68 | } |
| 69 | DBUG_PRINT("exit" ,("to: '%s'" ,start)); |
| 70 | DBUG_RETURN(start); |
| 71 | } /* my_path */ |
| 72 | |
| 73 | |
| 74 | /* test if file without filename is found in path */ |
| 75 | /* Returns to if found and to has dirpart if found, else NullS */ |
| 76 | |
| 77 | #if defined(__WIN__) |
| 78 | #define F_OK 0 |
| 79 | #define PATH_SEP ';' |
| 80 | #define PROGRAM_EXTENSION ".exe" |
| 81 | #else |
| 82 | #define PATH_SEP ':' |
| 83 | #endif |
| 84 | |
| 85 | static char *find_file_in_path(char *to, const char *name) |
| 86 | { |
| 87 | char *path,*pos,dir[2]; |
| 88 | const char *ext="" ; |
| 89 | |
| 90 | if (!(path=getenv("PATH" ))) |
| 91 | return NullS; |
| 92 | dir[0]=FN_LIBCHAR; dir[1]=0; |
| 93 | #ifdef PROGRAM_EXTENSION |
| 94 | if (!fn_ext(name)[0]) |
| 95 | ext=PROGRAM_EXTENSION; |
| 96 | #endif |
| 97 | |
| 98 | for (pos=path ; (pos=strchr(pos,PATH_SEP)) ; path= ++pos) |
| 99 | { |
| 100 | if (path != pos) |
| 101 | { |
| 102 | strxmov(strnmov(to,path,(uint) (pos-path)),dir,name,ext,NullS); |
| 103 | if (!access(to,F_OK)) |
| 104 | { |
| 105 | to[(uint) (pos-path)+1]=0; /* Return path only */ |
| 106 | return to; |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | #ifdef __WIN__ |
| 111 | to[0]=FN_CURLIB; |
| 112 | strxmov(to+1,dir,name,ext,NullS); |
| 113 | if (!access(to,F_OK)) /* Test in current dir */ |
| 114 | { |
| 115 | to[2]=0; /* Leave ".\" */ |
| 116 | return to; |
| 117 | } |
| 118 | #endif |
| 119 | return NullS; /* File not found */ |
| 120 | } |
| 121 | |