1 /*
2 Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
3
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation. The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License, version 2.0, for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26
27 #include <NDBT_Find.hpp>
28 #include <NdbEnv.h>
29
30 #ifndef _WIN32
31 #define PATH_SEPARATOR ":"
32 #else
33 #define PATH_SEPARATOR ";"
34 #endif
35
36 void
NDBT_find_binary_from_path(BaseString & name,const char * binary_name,const char * _path)37 NDBT_find_binary_from_path(BaseString& name,
38 const char* binary_name,
39 const char * _path)
40 {
41 char * copy = strdup(_path);
42
43 // Loop the list of paths and see if the binary exists
44 char *n = copy;
45 while (n != NULL)
46 {
47 char * s = n;
48 n = strstr(s, PATH_SEPARATOR);
49 if (n != NULL)
50 {
51 * n = 0;
52 n += strlen(PATH_SEPARATOR);
53 }
54 BaseString path;
55 path.assfmt("%s/%s", s, binary_name);
56 if (access(path.c_str(), F_OK) == 0)
57 {
58 // Sucess, found the binary. Convert path to absolute and return it
59 char realpath_buf[PATH_MAX];
60 #ifndef _WIN32
61 if (realpath(path.c_str(), realpath_buf) == NULL)
62 {
63 fprintf(stderr, "Could not convert '%s' to realpath\n", path.c_str());
64 abort();
65 }
66 #else
67 int ret= GetFullPathName(path.c_str(), sizeof(realpath_buf),
68 realpath_buf, NULL);
69 if (ret == 0 || ret >= sizeof(realpath_buf))
70 {
71 fprintf(stderr, "Could not convert '%s' with GetFullPathName\n",
72 path.c_str());
73 abort();
74 }
75 #endif
76
77 name.assign(realpath_buf);
78 free(copy);
79 printf("found %s\n", name.c_str());
80 return;
81 }
82 }
83
84 // Failed to find the binary in any of the supplied paths
85 fprintf(stderr, "Could not find '%s' in '%s'\n",
86 binary_name, _path);
87 free(copy);
88 abort();
89 }
90
91 void
NDBT_find_binary(BaseString & name,const char * binary_name,const char * first_path,...)92 NDBT_find_binary(BaseString& name, const char* binary_name,
93 const char* first_path, ...)
94 {
95 BaseString path(first_path);
96
97 // Push all the different paths to a list
98 const char* str = first_path;
99 va_list args;
100 va_start(args, first_path);
101 while ((str = va_arg(args, const char*)) != NULL)
102 {
103 path.appfmt("%s%s", PATH_SEPARATOR, str);
104 }
105 va_end(args);
106
107 NDBT_find_binary_from_path(name, binary_name, path.c_str());
108 }
109
110 extern const char * my_progname;
111
112 void
NDBT_find_ndb_mgmd(BaseString & path)113 NDBT_find_ndb_mgmd(BaseString& path)
114 {
115 char pathbuf[1024];
116
117 /**
118 * 1) avoid using dirname/basename since they are not around on WIN
119 * 2) define single character SEP to be able to use strrchr
120 */
121 BaseString copy(my_progname);
122 #ifdef NDB_WIN
123 char SEP = '\\';
124 #else
125 char SEP = '/';
126 #endif
127 char * basename = const_cast<char*>(strrchr(copy.c_str(), SEP));
128 if (basename == 0)
129 {
130 /**
131 * No directory part in argv[0]
132 * => found in $PATH => search for ndb_mgmd in $PATH
133 */
134 NDBT_find_binary(path,
135 "ndb_mgmd",
136 NdbEnv_GetEnv("PATH", pathbuf, sizeof(pathbuf)),
137 NULL);
138 }
139 else
140 {
141 /**
142 * Directory part in argv[0] (e.g storage/ndb/test/ndbapi/testMgmd)
143 * => don't add $PATH
144 * => search in relative places relative argv[0]
145 */
146 * basename = 0;
147 const char * places[] = {
148 "../../src/mgmsrv",
149 "../storage/ndb/src/mgmsrv",
150 "../libexec",
151 "../sbin",
152 "../bin",
153 0
154 };
155 BaseString searchpath = "";
156 for (int i = 0; places[i] != 0; i++) {
157 searchpath.appfmt("%s%s%c%s",
158 (i == 0 ? "" : PATH_SEPARATOR),
159 copy.c_str(),
160 SEP,
161 places[i]);
162 }
163 NDBT_find_binary(path,
164 "ndb_mgmd",
165 searchpath.c_str(),
166 NULL);
167 }
168 }
169
170