diff options
Diffstat (limited to 'src/util/os_installation.c')
-rw-r--r-- | src/util/os_installation.c | 1005 |
1 files changed, 509 insertions, 496 deletions
diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 3e5a99811..656468707 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c | |||
@@ -16,7 +16,7 @@ | |||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file src/util/os_installation.c | 22 | * @file src/util/os_installation.c |
@@ -45,13 +45,13 @@ | |||
45 | 45 | ||
46 | 46 | ||
47 | #define LOG(kind, ...) \ | 47 | #define LOG(kind, ...) \ |
48 | GNUNET_log_from (kind, "util-os-installation", __VA_ARGS__) | 48 | GNUNET_log_from(kind, "util-os-installation", __VA_ARGS__) |
49 | 49 | ||
50 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ | 50 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ |
51 | GNUNET_log_from_strerror_file (kind, \ | 51 | GNUNET_log_from_strerror_file(kind, \ |
52 | "util-os-installation", \ | 52 | "util-os-installation", \ |
53 | syscall, \ | 53 | syscall, \ |
54 | filename) | 54 | filename) |
55 | 55 | ||
56 | 56 | ||
57 | /** | 57 | /** |
@@ -91,7 +91,7 @@ static int gettextinit = 0; | |||
91 | * Return default project data used by 'libgnunetutil' for GNUnet. | 91 | * Return default project data used by 'libgnunetutil' for GNUnet. |
92 | */ | 92 | */ |
93 | const struct GNUNET_OS_ProjectData * | 93 | const struct GNUNET_OS_ProjectData * |
94 | GNUNET_OS_project_data_default (void) | 94 | GNUNET_OS_project_data_default(void) |
95 | { | 95 | { |
96 | return &default_pd; | 96 | return &default_pd; |
97 | } | 97 | } |
@@ -101,16 +101,16 @@ GNUNET_OS_project_data_default (void) | |||
101 | * @return current project data. | 101 | * @return current project data. |
102 | */ | 102 | */ |
103 | const struct GNUNET_OS_ProjectData * | 103 | const struct GNUNET_OS_ProjectData * |
104 | GNUNET_OS_project_data_get () | 104 | GNUNET_OS_project_data_get() |
105 | { | 105 | { |
106 | if (0 == gettextinit) | 106 | if (0 == gettextinit) |
107 | { | 107 | { |
108 | char *path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR); | 108 | char *path = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR); |
109 | if (NULL != path) | 109 | if (NULL != path) |
110 | bindtextdomain (PACKAGE, path); | 110 | bindtextdomain(PACKAGE, path); |
111 | GNUNET_free (path); | 111 | GNUNET_free(path); |
112 | gettextinit = 1; | 112 | gettextinit = 1; |
113 | } | 113 | } |
114 | return current_pd; | 114 | return current_pd; |
115 | } | 115 | } |
116 | 116 | ||
@@ -121,17 +121,17 @@ GNUNET_OS_project_data_get () | |||
121 | * @param pd project data used to determine paths | 121 | * @param pd project data used to determine paths |
122 | */ | 122 | */ |
123 | void | 123 | void |
124 | GNUNET_OS_init (const struct GNUNET_OS_ProjectData *pd) | 124 | GNUNET_OS_init(const struct GNUNET_OS_ProjectData *pd) |
125 | { | 125 | { |
126 | if (0 == gettextinit) | 126 | if (0 == gettextinit) |
127 | { | 127 | { |
128 | char *path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR); | 128 | char *path = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR); |
129 | if (NULL != path) | 129 | if (NULL != path) |
130 | bindtextdomain (PACKAGE, path); | 130 | bindtextdomain(PACKAGE, path); |
131 | GNUNET_free (path); | 131 | GNUNET_free(path); |
132 | gettextinit = 1; | 132 | gettextinit = 1; |
133 | } | 133 | } |
134 | GNUNET_assert (NULL != pd); | 134 | GNUNET_assert(NULL != pd); |
135 | current_pd = pd; | 135 | current_pd = pd; |
136 | } | 136 | } |
137 | 137 | ||
@@ -143,7 +143,7 @@ GNUNET_OS_init (const struct GNUNET_OS_ProjectData *pd) | |||
143 | * @return NULL on error | 143 | * @return NULL on error |
144 | */ | 144 | */ |
145 | static char * | 145 | static char * |
146 | get_path_from_proc_maps () | 146 | get_path_from_proc_maps() |
147 | { | 147 | { |
148 | char fn[64]; | 148 | char fn[64]; |
149 | char line[1024]; | 149 | char line[1024]; |
@@ -151,22 +151,22 @@ get_path_from_proc_maps () | |||
151 | FILE *f; | 151 | FILE *f; |
152 | char *lgu; | 152 | char *lgu; |
153 | 153 | ||
154 | GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/maps", getpid ()); | 154 | GNUNET_snprintf(fn, sizeof(fn), "/proc/%u/maps", getpid()); |
155 | if (NULL == (f = fopen (fn, "r"))) | 155 | if (NULL == (f = fopen(fn, "r"))) |
156 | return NULL; | 156 | return NULL; |
157 | while (NULL != fgets (line, sizeof (line), f)) | 157 | while (NULL != fgets(line, sizeof(line), f)) |
158 | { | ||
159 | if ((1 == SSCANF (line, | ||
160 | "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%1023s", | ||
161 | dir)) && | ||
162 | (NULL != (lgu = strstr (dir, current_pd->libname)))) | ||
163 | { | 158 | { |
164 | lgu[0] = '\0'; | 159 | if ((1 == SSCANF(line, |
165 | fclose (f); | 160 | "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%1023s", |
166 | return GNUNET_strdup (dir); | 161 | dir)) && |
162 | (NULL != (lgu = strstr(dir, current_pd->libname)))) | ||
163 | { | ||
164 | lgu[0] = '\0'; | ||
165 | fclose(f); | ||
166 | return GNUNET_strdup(dir); | ||
167 | } | ||
167 | } | 168 | } |
168 | } | 169 | fclose(f); |
169 | fclose (f); | ||
170 | return NULL; | 170 | return NULL; |
171 | } | 171 | } |
172 | 172 | ||
@@ -177,37 +177,37 @@ get_path_from_proc_maps () | |||
177 | * @return NULL on error | 177 | * @return NULL on error |
178 | */ | 178 | */ |
179 | static char * | 179 | static char * |
180 | get_path_from_proc_exe () | 180 | get_path_from_proc_exe() |
181 | { | 181 | { |
182 | char fn[64]; | 182 | char fn[64]; |
183 | char lnk[1024]; | 183 | char lnk[1024]; |
184 | ssize_t size; | 184 | ssize_t size; |
185 | char *lep; | 185 | char *lep; |
186 | 186 | ||
187 | GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/exe", getpid ()); | 187 | GNUNET_snprintf(fn, sizeof(fn), "/proc/%u/exe", getpid()); |
188 | size = readlink (fn, lnk, sizeof (lnk) - 1); | 188 | size = readlink(fn, lnk, sizeof(lnk) - 1); |
189 | if (size <= 0) | 189 | if (size <= 0) |
190 | { | 190 | { |
191 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "readlink", fn); | 191 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "readlink", fn); |
192 | return NULL; | 192 | return NULL; |
193 | } | 193 | } |
194 | GNUNET_assert (((size_t) size) < sizeof (lnk)); | 194 | GNUNET_assert(((size_t)size) < sizeof(lnk)); |
195 | lnk[size] = '\0'; | 195 | lnk[size] = '\0'; |
196 | while ((lnk[size] != '/') && (size > 0)) | 196 | while ((lnk[size] != '/') && (size > 0)) |
197 | size--; | 197 | size--; |
198 | GNUNET_asprintf (&lep, "/%s/libexec/", current_pd->project_dirname); | 198 | GNUNET_asprintf(&lep, "/%s/libexec/", current_pd->project_dirname); |
199 | /* test for being in lib/gnunet/libexec/ or lib/MULTIARCH/gnunet/libexec */ | 199 | /* test for being in lib/gnunet/libexec/ or lib/MULTIARCH/gnunet/libexec */ |
200 | if ((((size_t) size) > strlen (lep)) && | 200 | if ((((size_t)size) > strlen(lep)) && |
201 | (0 == strcmp (lep, &lnk[size - strlen (lep)]))) | 201 | (0 == strcmp(lep, &lnk[size - strlen(lep)]))) |
202 | size -= strlen (lep) - 1; | 202 | size -= strlen(lep) - 1; |
203 | GNUNET_free (lep); | 203 | GNUNET_free(lep); |
204 | if ((size < 4) || (lnk[size - 4] != '/')) | 204 | if ((size < 4) || (lnk[size - 4] != '/')) |
205 | { | 205 | { |
206 | /* not installed in "/bin/" -- binary path probably useless */ | 206 | /* not installed in "/bin/" -- binary path probably useless */ |
207 | return NULL; | 207 | return NULL; |
208 | } | 208 | } |
209 | lnk[size] = '\0'; | 209 | lnk[size] = '\0'; |
210 | return GNUNET_strdup (lnk); | 210 | return GNUNET_strdup(lnk); |
211 | } | 211 | } |
212 | #endif | 212 | #endif |
213 | 213 | ||
@@ -222,20 +222,23 @@ static HINSTANCE dll_instance; | |||
222 | * and hInstance saving. | 222 | * and hInstance saving. |
223 | */ | 223 | */ |
224 | BOOL WINAPI | 224 | BOOL WINAPI |
225 | DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | 225 | DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) |
226 | { | 226 | { |
227 | switch (fdwReason) | 227 | switch (fdwReason) |
228 | { | 228 | { |
229 | case DLL_PROCESS_ATTACH: | 229 | case DLL_PROCESS_ATTACH: |
230 | dll_instance = hinstDLL; | 230 | dll_instance = hinstDLL; |
231 | break; | 231 | break; |
232 | case DLL_THREAD_ATTACH: | 232 | |
233 | break; | 233 | case DLL_THREAD_ATTACH: |
234 | case DLL_THREAD_DETACH: | 234 | break; |
235 | break; | 235 | |
236 | case DLL_PROCESS_DETACH: | 236 | case DLL_THREAD_DETACH: |
237 | break; | 237 | break; |
238 | } | 238 | |
239 | case DLL_PROCESS_DETACH: | ||
240 | break; | ||
241 | } | ||
239 | return TRUE; | 242 | return TRUE; |
240 | } | 243 | } |
241 | 244 | ||
@@ -246,7 +249,7 @@ DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | |||
246 | * @return NULL on error | 249 | * @return NULL on error |
247 | */ | 250 | */ |
248 | static char * | 251 | static char * |
249 | get_path_from_module_filename () | 252 | get_path_from_module_filename() |
250 | { | 253 | { |
251 | size_t pathlen = 512; | 254 | size_t pathlen = 512; |
252 | DWORD real_pathlen; | 255 | DWORD real_pathlen; |
@@ -261,15 +264,16 @@ get_path_from_module_filename () | |||
261 | * it fits, or we exceed the threshold. | 264 | * it fits, or we exceed the threshold. |
262 | */ | 265 | */ |
263 | do | 266 | do |
264 | { | 267 | { |
265 | pathlen = pathlen * 2; | 268 | pathlen = pathlen * 2; |
266 | modulepath = GNUNET_realloc (modulepath, pathlen * sizeof (wchar_t)); | 269 | modulepath = GNUNET_realloc(modulepath, pathlen * sizeof(wchar_t)); |
267 | SetLastError (0); | 270 | SetLastError(0); |
268 | real_pathlen = | 271 | real_pathlen = |
269 | GetModuleFileNameW (dll_instance, modulepath, pathlen * sizeof (wchar_t)); | 272 | GetModuleFileNameW(dll_instance, modulepath, pathlen * sizeof(wchar_t)); |
270 | } while (real_pathlen >= pathlen && pathlen < 16 * 1024); | 273 | } |
274 | while (real_pathlen >= pathlen && pathlen < 16 * 1024); | ||
271 | if (real_pathlen >= pathlen) | 275 | if (real_pathlen >= pathlen) |
272 | GNUNET_assert (0); | 276 | GNUNET_assert(0); |
273 | /* To be safe */ | 277 | /* To be safe */ |
274 | modulepath[real_pathlen] = '\0'; | 278 | modulepath[real_pathlen] = '\0'; |
275 | 279 | ||
@@ -281,45 +285,45 @@ get_path_from_module_filename () | |||
281 | /* Now modulepath holds full path to the directory where libgnunetutil is. | 285 | /* Now modulepath holds full path to the directory where libgnunetutil is. |
282 | * This directory should look like <GNUNET_PREFIX>/bin or <GNUNET_PREFIX>. | 286 | * This directory should look like <GNUNET_PREFIX>/bin or <GNUNET_PREFIX>. |
283 | */ | 287 | */ |
284 | if (wcschr (modulepath, L'/') || wcschr (modulepath, L'\\')) | 288 | if (wcschr(modulepath, L'/') || wcschr(modulepath, L'\\')) |
285 | { | ||
286 | /* At least one directory component (i.e. we're not in a root directory) */ | ||
287 | wchar_t *dirname = idx; | ||
288 | while ((dirname > modulepath) && (*dirname != L'\\') && (*dirname != L'/')) | ||
289 | dirname--; | ||
290 | *dirname = L'\0'; | ||
291 | if (dirname > modulepath) | ||
292 | { | 289 | { |
293 | dirname++; | 290 | /* At least one directory component (i.e. we're not in a root directory) */ |
294 | /* Now modulepath holds full path to the parent directory of the directory | 291 | wchar_t *dirname = idx; |
295 | * where libgnunetutil is. | 292 | while ((dirname > modulepath) && (*dirname != L'\\') && (*dirname != L'/')) |
296 | * dirname holds the name of the directory where libgnunetutil is. | ||
297 | */ | ||
298 | if (wcsicmp (dirname, L"bin") == 0) | ||
299 | { | ||
300 | /* pass */ | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | /* Roll back our changes to modulepath */ | ||
305 | dirname--; | 293 | dirname--; |
306 | *dirname = L'/'; | 294 | *dirname = L'\0'; |
307 | } | 295 | if (dirname > modulepath) |
296 | { | ||
297 | dirname++; | ||
298 | /* Now modulepath holds full path to the parent directory of the directory | ||
299 | * where libgnunetutil is. | ||
300 | * dirname holds the name of the directory where libgnunetutil is. | ||
301 | */ | ||
302 | if (wcsicmp(dirname, L"bin") == 0) | ||
303 | { | ||
304 | /* pass */ | ||
305 | } | ||
306 | else | ||
307 | { | ||
308 | /* Roll back our changes to modulepath */ | ||
309 | dirname--; | ||
310 | *dirname = L'/'; | ||
311 | } | ||
312 | } | ||
308 | } | 313 | } |
309 | } | ||
310 | 314 | ||
311 | /* modulepath is GNUNET_PREFIX */ | 315 | /* modulepath is GNUNET_PREFIX */ |
312 | u8_string = | 316 | u8_string = |
313 | u16_to_u8 (modulepath, wcslen (modulepath), NULL, &u8_string_length); | 317 | u16_to_u8(modulepath, wcslen(modulepath), NULL, &u8_string_length); |
314 | if (NULL == u8_string) | 318 | if (NULL == u8_string) |
315 | GNUNET_assert (0); | 319 | GNUNET_assert(0); |
316 | 320 | ||
317 | upath = GNUNET_malloc (u8_string_length + 1); | 321 | upath = GNUNET_malloc(u8_string_length + 1); |
318 | GNUNET_memcpy (upath, u8_string, u8_string_length); | 322 | GNUNET_memcpy(upath, u8_string, u8_string_length); |
319 | upath[u8_string_length] = '\0'; | 323 | upath[u8_string_length] = '\0'; |
320 | 324 | ||
321 | free (u8_string); | 325 | free(u8_string); |
322 | GNUNET_free (modulepath); | 326 | GNUNET_free(modulepath); |
323 | 327 | ||
324 | return upath; | 328 | return upath; |
325 | } | 329 | } |
@@ -343,7 +347,7 @@ typedef int (*MyNSGetExecutablePathProto) (char *buf, size_t *bufsize); | |||
343 | * @return NULL on error | 347 | * @return NULL on error |
344 | */ | 348 | */ |
345 | static char * | 349 | static char * |
346 | get_path_from_NSGetExecutablePath () | 350 | get_path_from_NSGetExecutablePath() |
347 | { | 351 | { |
348 | static char zero = '\0'; | 352 | static char zero = '\0'; |
349 | char *path; | 353 | char *path; |
@@ -352,22 +356,22 @@ get_path_from_NSGetExecutablePath () | |||
352 | 356 | ||
353 | path = NULL; | 357 | path = NULL; |
354 | if (NULL == | 358 | if (NULL == |
355 | (func = (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, | 359 | (func = (MyNSGetExecutablePathProto)dlsym(RTLD_DEFAULT, |
356 | "_NSGetExecutablePath"))) | 360 | "_NSGetExecutablePath"))) |
357 | return NULL; | 361 | return NULL; |
358 | path = &zero; | 362 | path = &zero; |
359 | len = 0; | 363 | len = 0; |
360 | /* get the path len, including the trailing \0 */ | 364 | /* get the path len, including the trailing \0 */ |
361 | (void) func (path, &len); | 365 | (void)func(path, &len); |
362 | if (0 == len) | 366 | if (0 == len) |
363 | return NULL; | 367 | return NULL; |
364 | path = GNUNET_malloc (len); | 368 | path = GNUNET_malloc(len); |
365 | if (0 != func (path, &len)) | 369 | if (0 != func(path, &len)) |
366 | { | 370 | { |
367 | GNUNET_free (path); | 371 | GNUNET_free(path); |
368 | return NULL; | 372 | return NULL; |
369 | } | 373 | } |
370 | len = strlen (path); | 374 | len = strlen(path); |
371 | while ((path[len] != '/') && (len > 0)) | 375 | while ((path[len] != '/') && (len > 0)) |
372 | len--; | 376 | len--; |
373 | path[len] = '\0'; | 377 | path[len] = '\0'; |
@@ -381,7 +385,7 @@ get_path_from_NSGetExecutablePath () | |||
381 | * @return NULL on error | 385 | * @return NULL on error |
382 | */ | 386 | */ |
383 | static char * | 387 | static char * |
384 | get_path_from_dyld_image () | 388 | get_path_from_dyld_image() |
385 | { | 389 | { |
386 | const char *path; | 390 | const char *path; |
387 | char *p; | 391 | char *p; |
@@ -389,23 +393,23 @@ get_path_from_dyld_image () | |||
389 | unsigned int i; | 393 | unsigned int i; |
390 | int c; | 394 | int c; |
391 | 395 | ||
392 | c = _dyld_image_count (); | 396 | c = _dyld_image_count(); |
393 | for (i = 0; i < c; i++) | 397 | for (i = 0; i < c; i++) |
394 | { | 398 | { |
395 | if (((const void *) _dyld_get_image_header (i)) != | 399 | if (((const void *)_dyld_get_image_header(i)) != |
396 | ((const void *) &_mh_dylib_header)) | 400 | ((const void *)&_mh_dylib_header)) |
397 | continue; | 401 | continue; |
398 | path = _dyld_get_image_name (i); | 402 | path = _dyld_get_image_name(i); |
399 | if ((NULL == path) || (0 == strlen (path))) | 403 | if ((NULL == path) || (0 == strlen(path))) |
400 | continue; | 404 | continue; |
401 | p = GNUNET_strdup (path); | 405 | p = GNUNET_strdup(path); |
402 | s = p + strlen (p); | 406 | s = p + strlen(p); |
403 | while ((s > p) && ('/' != *s)) | 407 | while ((s > p) && ('/' != *s)) |
404 | s--; | 408 | s--; |
405 | s++; | 409 | s++; |
406 | *s = '\0'; | 410 | *s = '\0'; |
407 | return p; | 411 | return p; |
408 | } | 412 | } |
409 | return NULL; | 413 | return NULL; |
410 | } | 414 | } |
411 | #endif | 415 | #endif |
@@ -419,7 +423,7 @@ get_path_from_dyld_image () | |||
419 | * @return path to binary, NULL if not found | 423 | * @return path to binary, NULL if not found |
420 | */ | 424 | */ |
421 | static char * | 425 | static char * |
422 | get_path_from_PATH (const char *binary) | 426 | get_path_from_PATH(const char *binary) |
423 | { | 427 | { |
424 | char *path; | 428 | char *path; |
425 | char *pos; | 429 | char *pos; |
@@ -427,39 +431,39 @@ get_path_from_PATH (const char *binary) | |||
427 | char *buf; | 431 | char *buf; |
428 | const char *p; | 432 | const char *p; |
429 | 433 | ||
430 | if (NULL == (p = getenv ("PATH"))) | 434 | if (NULL == (p = getenv("PATH"))) |
431 | return NULL; | 435 | return NULL; |
432 | #if WINDOWS | 436 | #if WINDOWS |
433 | /* On W32 look in CWD first. */ | 437 | /* On W32 look in CWD first. */ |
434 | GNUNET_asprintf (&path, ".%c%s", PATH_SEPARATOR, p); | 438 | GNUNET_asprintf(&path, ".%c%s", PATH_SEPARATOR, p); |
435 | #else | 439 | #else |
436 | path = GNUNET_strdup (p); /* because we write on it */ | 440 | path = GNUNET_strdup(p); /* because we write on it */ |
437 | #endif | 441 | #endif |
438 | buf = GNUNET_malloc (strlen (path) + strlen (binary) + 1 + 1); | 442 | buf = GNUNET_malloc(strlen(path) + strlen(binary) + 1 + 1); |
439 | pos = path; | 443 | pos = path; |
440 | while (NULL != (end = strchr (pos, PATH_SEPARATOR))) | 444 | while (NULL != (end = strchr(pos, PATH_SEPARATOR))) |
441 | { | ||
442 | *end = '\0'; | ||
443 | sprintf (buf, "%s/%s", pos, binary); | ||
444 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
445 | { | 445 | { |
446 | pos = GNUNET_strdup (pos); | 446 | *end = '\0'; |
447 | GNUNET_free (buf); | 447 | sprintf(buf, "%s/%s", pos, binary); |
448 | GNUNET_free (path); | 448 | if (GNUNET_DISK_file_test(buf) == GNUNET_YES) |
449 | { | ||
450 | pos = GNUNET_strdup(pos); | ||
451 | GNUNET_free(buf); | ||
452 | GNUNET_free(path); | ||
453 | return pos; | ||
454 | } | ||
455 | pos = end + 1; | ||
456 | } | ||
457 | sprintf(buf, "%s/%s", pos, binary); | ||
458 | if (GNUNET_YES == GNUNET_DISK_file_test(buf)) | ||
459 | { | ||
460 | pos = GNUNET_strdup(pos); | ||
461 | GNUNET_free(buf); | ||
462 | GNUNET_free(path); | ||
449 | return pos; | 463 | return pos; |
450 | } | 464 | } |
451 | pos = end + 1; | 465 | GNUNET_free(buf); |
452 | } | 466 | GNUNET_free(path); |
453 | sprintf (buf, "%s/%s", pos, binary); | ||
454 | if (GNUNET_YES == GNUNET_DISK_file_test (buf)) | ||
455 | { | ||
456 | pos = GNUNET_strdup (pos); | ||
457 | GNUNET_free (buf); | ||
458 | GNUNET_free (path); | ||
459 | return pos; | ||
460 | } | ||
461 | GNUNET_free (buf); | ||
462 | GNUNET_free (path); | ||
463 | return NULL; | 467 | return NULL; |
464 | } | 468 | } |
465 | 469 | ||
@@ -471,16 +475,16 @@ get_path_from_PATH (const char *binary) | |||
471 | * @return NULL on error (environment variable not set) | 475 | * @return NULL on error (environment variable not set) |
472 | */ | 476 | */ |
473 | static char * | 477 | static char * |
474 | get_path_from_GNUNET_PREFIX () | 478 | get_path_from_GNUNET_PREFIX() |
475 | { | 479 | { |
476 | const char *p; | 480 | const char *p; |
477 | 481 | ||
478 | if ((NULL != current_pd->env_varname) && | 482 | if ((NULL != current_pd->env_varname) && |
479 | (NULL != (p = getenv (current_pd->env_varname)))) | 483 | (NULL != (p = getenv(current_pd->env_varname)))) |
480 | return GNUNET_strdup (p); | 484 | return GNUNET_strdup(p); |
481 | if ((NULL != current_pd->env_varname_alt) && | 485 | if ((NULL != current_pd->env_varname_alt) && |
482 | (NULL != (p = getenv (current_pd->env_varname_alt)))) | 486 | (NULL != (p = getenv(current_pd->env_varname_alt)))) |
483 | return GNUNET_strdup (p); | 487 | return GNUNET_strdup(p); |
484 | return NULL; | 488 | return NULL; |
485 | } | 489 | } |
486 | 490 | ||
@@ -492,41 +496,41 @@ get_path_from_GNUNET_PREFIX () | |||
492 | * @return a pointer to the executable path, or NULL on error | 496 | * @return a pointer to the executable path, or NULL on error |
493 | */ | 497 | */ |
494 | static char * | 498 | static char * |
495 | os_get_gnunet_path () | 499 | os_get_gnunet_path() |
496 | { | 500 | { |
497 | char *ret; | 501 | char *ret; |
498 | 502 | ||
499 | if (NULL != (ret = get_path_from_GNUNET_PREFIX ())) | 503 | if (NULL != (ret = get_path_from_GNUNET_PREFIX())) |
500 | return ret; | 504 | return ret; |
501 | #if LINUX | 505 | #if LINUX |
502 | if (NULL != (ret = get_path_from_proc_maps ())) | 506 | if (NULL != (ret = get_path_from_proc_maps())) |
503 | return ret; | 507 | return ret; |
504 | /* try path *first*, before /proc/exe, as /proc/exe can be wrong */ | 508 | /* try path *first*, before /proc/exe, as /proc/exe can be wrong */ |
505 | if ((NULL != current_pd->binary_name) && | 509 | if ((NULL != current_pd->binary_name) && |
506 | (NULL != (ret = get_path_from_PATH (current_pd->binary_name)))) | 510 | (NULL != (ret = get_path_from_PATH(current_pd->binary_name)))) |
507 | return ret; | 511 | return ret; |
508 | if (NULL != (ret = get_path_from_proc_exe ())) | 512 | if (NULL != (ret = get_path_from_proc_exe())) |
509 | return ret; | 513 | return ret; |
510 | #endif | 514 | #endif |
511 | #if WINDOWS | 515 | #if WINDOWS |
512 | if (NULL != (ret = get_path_from_module_filename ())) | 516 | if (NULL != (ret = get_path_from_module_filename())) |
513 | return ret; | 517 | return ret; |
514 | #endif | 518 | #endif |
515 | #if DARWIN | 519 | #if DARWIN |
516 | if (NULL != (ret = get_path_from_dyld_image ())) | 520 | if (NULL != (ret = get_path_from_dyld_image())) |
517 | return ret; | 521 | return ret; |
518 | if (NULL != (ret = get_path_from_NSGetExecutablePath ())) | 522 | if (NULL != (ret = get_path_from_NSGetExecutablePath())) |
519 | return ret; | 523 | return ret; |
520 | #endif | 524 | #endif |
521 | if ((NULL != current_pd->binary_name) && | 525 | if ((NULL != current_pd->binary_name) && |
522 | (NULL != (ret = get_path_from_PATH (current_pd->binary_name)))) | 526 | (NULL != (ret = get_path_from_PATH(current_pd->binary_name)))) |
523 | return ret; | 527 | return ret; |
524 | /* other attempts here */ | 528 | /* other attempts here */ |
525 | LOG (GNUNET_ERROR_TYPE_ERROR, | 529 | LOG(GNUNET_ERROR_TYPE_ERROR, |
526 | _ ( | 530 | _( |
527 | "Could not determine installation path for %s. Set `%s' environment variable.\n"), | 531 | "Could not determine installation path for %s. Set `%s' environment variable.\n"), |
528 | current_pd->project_dirname, | 532 | current_pd->project_dirname, |
529 | current_pd->env_varname); | 533 | current_pd->env_varname); |
530 | return NULL; | 534 | return NULL; |
531 | } | 535 | } |
532 | 536 | ||
@@ -536,20 +540,20 @@ os_get_gnunet_path () | |||
536 | * @return a pointer to the executable path, or NULL on error | 540 | * @return a pointer to the executable path, or NULL on error |
537 | */ | 541 | */ |
538 | static char * | 542 | static char * |
539 | os_get_exec_path () | 543 | os_get_exec_path() |
540 | { | 544 | { |
541 | char *ret = NULL; | 545 | char *ret = NULL; |
542 | 546 | ||
543 | #if LINUX | 547 | #if LINUX |
544 | if (NULL != (ret = get_path_from_proc_exe ())) | 548 | if (NULL != (ret = get_path_from_proc_exe())) |
545 | return ret; | 549 | return ret; |
546 | #endif | 550 | #endif |
547 | #if WINDOWS | 551 | #if WINDOWS |
548 | if (NULL != (ret = get_path_from_module_filename ())) | 552 | if (NULL != (ret = get_path_from_module_filename())) |
549 | return ret; | 553 | return ret; |
550 | #endif | 554 | #endif |
551 | #if DARWIN | 555 | #if DARWIN |
552 | if (NULL != (ret = get_path_from_NSGetExecutablePath ())) | 556 | if (NULL != (ret = get_path_from_NSGetExecutablePath())) |
553 | return ret; | 557 | return ret; |
554 | #endif | 558 | #endif |
555 | /* other attempts here */ | 559 | /* other attempts here */ |
@@ -563,7 +567,7 @@ os_get_exec_path () | |||
563 | * @return a pointer to the dir path (to be freed by the caller) | 567 | * @return a pointer to the dir path (to be freed by the caller) |
564 | */ | 568 | */ |
565 | char * | 569 | char * |
566 | GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) | 570 | GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind) |
567 | { | 571 | { |
568 | size_t n; | 572 | size_t n; |
569 | char *dirname; | 573 | char *dirname; |
@@ -575,207 +579,215 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) | |||
575 | 579 | ||
576 | /* if wanted, try to get the current app's bin/ */ | 580 | /* if wanted, try to get the current app's bin/ */ |
577 | if (dirkind == GNUNET_OS_IPK_SELF_PREFIX) | 581 | if (dirkind == GNUNET_OS_IPK_SELF_PREFIX) |
578 | execpath = os_get_exec_path (); | 582 | execpath = os_get_exec_path(); |
579 | 583 | ||
580 | /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some | 584 | /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some |
581 | * guess for the current app */ | 585 | * guess for the current app */ |
582 | if (NULL == execpath) | 586 | if (NULL == execpath) |
583 | execpath = os_get_gnunet_path (); | 587 | execpath = os_get_gnunet_path(); |
584 | 588 | ||
585 | if (NULL == execpath) | 589 | if (NULL == execpath) |
586 | return NULL; | 590 | return NULL; |
587 | 591 | ||
588 | n = strlen (execpath); | 592 | n = strlen(execpath); |
589 | if (0 == n) | 593 | if (0 == n) |
590 | { | 594 | { |
591 | /* should never happen, but better safe than sorry */ | 595 | /* should never happen, but better safe than sorry */ |
592 | GNUNET_free (execpath); | 596 | GNUNET_free(execpath); |
593 | return NULL; | 597 | return NULL; |
594 | } | 598 | } |
595 | /* remove filename itself */ | 599 | /* remove filename itself */ |
596 | while ((n > 1) && (DIR_SEPARATOR == execpath[n - 1])) | 600 | while ((n > 1) && (DIR_SEPARATOR == execpath[n - 1])) |
597 | execpath[--n] = '\0'; | 601 | execpath[--n] = '\0'; |
598 | 602 | ||
599 | isbasedir = 1; | 603 | isbasedir = 1; |
600 | if ((n > 6) && ((0 == strcasecmp (&execpath[n - 6], "/lib32")) || | 604 | if ((n > 6) && ((0 == strcasecmp(&execpath[n - 6], "/lib32")) || |
601 | (0 == strcasecmp (&execpath[n - 6], "/lib64")))) | 605 | (0 == strcasecmp(&execpath[n - 6], "/lib64")))) |
602 | { | 606 | { |
603 | if ((GNUNET_OS_IPK_LIBDIR != dirkind) && | 607 | if ((GNUNET_OS_IPK_LIBDIR != dirkind) && |
604 | (GNUNET_OS_IPK_LIBEXECDIR != dirkind)) | 608 | (GNUNET_OS_IPK_LIBEXECDIR != dirkind)) |
609 | { | ||
610 | /* strip '/lib32' or '/lib64' */ | ||
611 | execpath[n - 6] = '\0'; | ||
612 | n -= 6; | ||
613 | } | ||
614 | else | ||
615 | isbasedir = 0; | ||
616 | } | ||
617 | else if ((n > 4) && ((0 == strcasecmp(&execpath[n - 4], "/bin")) || | ||
618 | (0 == strcasecmp(&execpath[n - 4], "/lib")))) | ||
605 | { | 619 | { |
606 | /* strip '/lib32' or '/lib64' */ | 620 | /* strip '/bin' or '/lib' */ |
607 | execpath[n - 6] = '\0'; | 621 | execpath[n - 4] = '\0'; |
608 | n -= 6; | 622 | n -= 4; |
609 | } | 623 | } |
610 | else | ||
611 | isbasedir = 0; | ||
612 | } | ||
613 | else if ((n > 4) && ((0 == strcasecmp (&execpath[n - 4], "/bin")) || | ||
614 | (0 == strcasecmp (&execpath[n - 4], "/lib")))) | ||
615 | { | ||
616 | /* strip '/bin' or '/lib' */ | ||
617 | execpath[n - 4] = '\0'; | ||
618 | n -= 4; | ||
619 | } | ||
620 | multiarch = NULL; | 624 | multiarch = NULL; |
621 | if (NULL != (libdir = strstr (execpath, "/lib/"))) | 625 | if (NULL != (libdir = strstr(execpath, "/lib/"))) |
622 | { | 626 | { |
623 | /* test for multi-arch path of the form "PREFIX/lib/MULTIARCH/"; | 627 | /* test for multi-arch path of the form "PREFIX/lib/MULTIARCH/"; |
624 | here we need to re-add 'multiarch' to lib and libexec paths later! */ | 628 | here we need to re-add 'multiarch' to lib and libexec paths later! */ |
625 | multiarch = &libdir[5]; | 629 | multiarch = &libdir[5]; |
626 | if (NULL == strchr (multiarch, '/')) | 630 | if (NULL == strchr(multiarch, '/')) |
627 | libdir[0] = | 631 | libdir[0] = |
628 | '\0'; /* Debian multiarch format, cut of from 'execpath' but preserve in multicarch */ | 632 | '\0'; /* Debian multiarch format, cut of from 'execpath' but preserve in multicarch */ |
629 | else | 633 | else |
630 | multiarch = | 634 | multiarch = |
631 | NULL; /* maybe not, multiarch still has a '/', which is not OK */ | 635 | NULL; /* maybe not, multiarch still has a '/', which is not OK */ |
632 | } | 636 | } |
633 | /* in case this was a directory named foo-bin, remove "foo-" */ | 637 | /* in case this was a directory named foo-bin, remove "foo-" */ |
634 | while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR)) | 638 | while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR)) |
635 | execpath[--n] = '\0'; | 639 | execpath[--n] = '\0'; |
636 | switch (dirkind) | 640 | switch (dirkind) |
637 | { | ||
638 | case GNUNET_OS_IPK_PREFIX: | ||
639 | case GNUNET_OS_IPK_SELF_PREFIX: | ||
640 | dirname = GNUNET_strdup (DIR_SEPARATOR_STR); | ||
641 | break; | ||
642 | case GNUNET_OS_IPK_BINDIR: | ||
643 | dirname = GNUNET_strdup (DIR_SEPARATOR_STR "bin" DIR_SEPARATOR_STR); | ||
644 | break; | ||
645 | case GNUNET_OS_IPK_LIBDIR: | ||
646 | if (isbasedir) | ||
647 | { | ||
648 | GNUNET_asprintf (&tmp, | ||
649 | "%s%s%s%s%s%s%s", | ||
650 | execpath, | ||
651 | DIR_SEPARATOR_STR "lib", | ||
652 | (NULL != multiarch) ? DIR_SEPARATOR_STR : "", | ||
653 | (NULL != multiarch) ? multiarch : "", | ||
654 | DIR_SEPARATOR_STR, | ||
655 | current_pd->project_dirname, | ||
656 | DIR_SEPARATOR_STR); | ||
657 | if (GNUNET_YES == GNUNET_DISK_directory_test (tmp, GNUNET_YES)) | ||
658 | { | ||
659 | GNUNET_free (execpath); | ||
660 | return tmp; | ||
661 | } | ||
662 | GNUNET_free (tmp); | ||
663 | tmp = NULL; | ||
664 | dirname = NULL; | ||
665 | if (4 == sizeof (void *)) | ||
666 | { | ||
667 | GNUNET_asprintf (&dirname, | ||
668 | DIR_SEPARATOR_STR "lib32" DIR_SEPARATOR_STR | ||
669 | "%s" DIR_SEPARATOR_STR, | ||
670 | current_pd->project_dirname); | ||
671 | GNUNET_asprintf (&tmp, "%s%s", execpath, dirname); | ||
672 | } | ||
673 | if (8 == sizeof (void *)) | ||
674 | { | ||
675 | GNUNET_asprintf (&dirname, | ||
676 | DIR_SEPARATOR_STR "lib64" DIR_SEPARATOR_STR | ||
677 | "%s" DIR_SEPARATOR_STR, | ||
678 | current_pd->project_dirname); | ||
679 | GNUNET_asprintf (&tmp, "%s%s", execpath, dirname); | ||
680 | } | ||
681 | |||
682 | if ((NULL != tmp) && | ||
683 | (GNUNET_YES == GNUNET_DISK_directory_test (tmp, GNUNET_YES))) | ||
684 | { | ||
685 | GNUNET_free (execpath); | ||
686 | GNUNET_free_non_null (dirname); | ||
687 | return tmp; | ||
688 | } | ||
689 | GNUNET_free (tmp); | ||
690 | GNUNET_free_non_null (dirname); | ||
691 | } | ||
692 | GNUNET_asprintf (&dirname, | ||
693 | DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR, | ||
694 | current_pd->project_dirname); | ||
695 | break; | ||
696 | case GNUNET_OS_IPK_DATADIR: | ||
697 | GNUNET_asprintf (&dirname, | ||
698 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
699 | "%s" DIR_SEPARATOR_STR, | ||
700 | current_pd->project_dirname); | ||
701 | break; | ||
702 | case GNUNET_OS_IPK_LOCALEDIR: | ||
703 | dirname = GNUNET_strdup (DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
704 | "locale" DIR_SEPARATOR_STR); | ||
705 | break; | ||
706 | case GNUNET_OS_IPK_ICONDIR: | ||
707 | dirname = GNUNET_strdup (DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
708 | "icons" DIR_SEPARATOR_STR); | ||
709 | break; | ||
710 | case GNUNET_OS_IPK_DOCDIR: | ||
711 | GNUNET_asprintf (&dirname, | ||
712 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
713 | "doc" DIR_SEPARATOR_STR | ||
714 | "%s" DIR_SEPARATOR_STR, | ||
715 | current_pd->project_dirname); | ||
716 | break; | ||
717 | case GNUNET_OS_IPK_LIBEXECDIR: | ||
718 | if (isbasedir) | ||
719 | { | 641 | { |
720 | GNUNET_asprintf (&dirname, | 642 | case GNUNET_OS_IPK_PREFIX: |
721 | DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR | 643 | case GNUNET_OS_IPK_SELF_PREFIX: |
722 | "libexec" DIR_SEPARATOR_STR, | 644 | dirname = GNUNET_strdup(DIR_SEPARATOR_STR); |
723 | current_pd->project_dirname); | 645 | break; |
724 | GNUNET_asprintf (&tmp, | 646 | |
725 | "%s%s%s%s", | 647 | case GNUNET_OS_IPK_BINDIR: |
726 | execpath, | 648 | dirname = GNUNET_strdup(DIR_SEPARATOR_STR "bin" DIR_SEPARATOR_STR); |
727 | DIR_SEPARATOR_STR "lib" DIR_SEPARATOR_STR, | 649 | break; |
728 | (NULL != multiarch) ? multiarch : "", | 650 | |
729 | dirname); | 651 | case GNUNET_OS_IPK_LIBDIR: |
730 | if (GNUNET_YES == GNUNET_DISK_directory_test (tmp, GNUNET_YES)) | 652 | if (isbasedir) |
731 | { | 653 | { |
732 | GNUNET_free (execpath); | 654 | GNUNET_asprintf(&tmp, |
733 | GNUNET_free (dirname); | 655 | "%s%s%s%s%s%s%s", |
734 | return tmp; | 656 | execpath, |
735 | } | 657 | DIR_SEPARATOR_STR "lib", |
736 | GNUNET_free (tmp); | 658 | (NULL != multiarch) ? DIR_SEPARATOR_STR : "", |
737 | tmp = NULL; | 659 | (NULL != multiarch) ? multiarch : "", |
738 | dirname = NULL; | 660 | DIR_SEPARATOR_STR, |
739 | if (4 == sizeof (void *)) | 661 | current_pd->project_dirname, |
740 | { | 662 | DIR_SEPARATOR_STR); |
741 | GNUNET_asprintf (&dirname, | 663 | if (GNUNET_YES == GNUNET_DISK_directory_test(tmp, GNUNET_YES)) |
742 | DIR_SEPARATOR_STR "lib32" DIR_SEPARATOR_STR | 664 | { |
743 | "%s" DIR_SEPARATOR_STR | 665 | GNUNET_free(execpath); |
744 | "libexec" DIR_SEPARATOR_STR, | 666 | return tmp; |
745 | current_pd->project_dirname); | 667 | } |
746 | GNUNET_asprintf (&tmp, "%s%s", execpath, dirname); | 668 | GNUNET_free(tmp); |
747 | } | 669 | tmp = NULL; |
748 | if (8 == sizeof (void *)) | 670 | dirname = NULL; |
749 | { | 671 | if (4 == sizeof(void *)) |
750 | GNUNET_asprintf (&dirname, | 672 | { |
751 | DIR_SEPARATOR_STR "lib64" DIR_SEPARATOR_STR | 673 | GNUNET_asprintf(&dirname, |
752 | "%s" DIR_SEPARATOR_STR | 674 | DIR_SEPARATOR_STR "lib32" DIR_SEPARATOR_STR |
753 | "libexec" DIR_SEPARATOR_STR, | 675 | "%s" DIR_SEPARATOR_STR, |
754 | current_pd->project_dirname); | 676 | current_pd->project_dirname); |
755 | GNUNET_asprintf (&tmp, "%s%s", execpath, dirname); | 677 | GNUNET_asprintf(&tmp, "%s%s", execpath, dirname); |
756 | } | 678 | } |
757 | if ((NULL != tmp) && | 679 | if (8 == sizeof(void *)) |
758 | (GNUNET_YES == GNUNET_DISK_directory_test (tmp, GNUNET_YES))) | 680 | { |
759 | { | 681 | GNUNET_asprintf(&dirname, |
760 | GNUNET_free (execpath); | 682 | DIR_SEPARATOR_STR "lib64" DIR_SEPARATOR_STR |
761 | GNUNET_free_non_null (dirname); | 683 | "%s" DIR_SEPARATOR_STR, |
762 | return tmp; | 684 | current_pd->project_dirname); |
763 | } | 685 | GNUNET_asprintf(&tmp, "%s%s", execpath, dirname); |
764 | GNUNET_free (tmp); | 686 | } |
765 | GNUNET_free_non_null (dirname); | 687 | |
688 | if ((NULL != tmp) && | ||
689 | (GNUNET_YES == GNUNET_DISK_directory_test(tmp, GNUNET_YES))) | ||
690 | { | ||
691 | GNUNET_free(execpath); | ||
692 | GNUNET_free_non_null(dirname); | ||
693 | return tmp; | ||
694 | } | ||
695 | GNUNET_free(tmp); | ||
696 | GNUNET_free_non_null(dirname); | ||
697 | } | ||
698 | GNUNET_asprintf(&dirname, | ||
699 | DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR, | ||
700 | current_pd->project_dirname); | ||
701 | break; | ||
702 | |||
703 | case GNUNET_OS_IPK_DATADIR: | ||
704 | GNUNET_asprintf(&dirname, | ||
705 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
706 | "%s" DIR_SEPARATOR_STR, | ||
707 | current_pd->project_dirname); | ||
708 | break; | ||
709 | |||
710 | case GNUNET_OS_IPK_LOCALEDIR: | ||
711 | dirname = GNUNET_strdup(DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
712 | "locale" DIR_SEPARATOR_STR); | ||
713 | break; | ||
714 | |||
715 | case GNUNET_OS_IPK_ICONDIR: | ||
716 | dirname = GNUNET_strdup(DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
717 | "icons" DIR_SEPARATOR_STR); | ||
718 | break; | ||
719 | |||
720 | case GNUNET_OS_IPK_DOCDIR: | ||
721 | GNUNET_asprintf(&dirname, | ||
722 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR | ||
723 | "doc" DIR_SEPARATOR_STR | ||
724 | "%s" DIR_SEPARATOR_STR, | ||
725 | current_pd->project_dirname); | ||
726 | break; | ||
727 | |||
728 | case GNUNET_OS_IPK_LIBEXECDIR: | ||
729 | if (isbasedir) | ||
730 | { | ||
731 | GNUNET_asprintf(&dirname, | ||
732 | DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR | ||
733 | "libexec" DIR_SEPARATOR_STR, | ||
734 | current_pd->project_dirname); | ||
735 | GNUNET_asprintf(&tmp, | ||
736 | "%s%s%s%s", | ||
737 | execpath, | ||
738 | DIR_SEPARATOR_STR "lib" DIR_SEPARATOR_STR, | ||
739 | (NULL != multiarch) ? multiarch : "", | ||
740 | dirname); | ||
741 | if (GNUNET_YES == GNUNET_DISK_directory_test(tmp, GNUNET_YES)) | ||
742 | { | ||
743 | GNUNET_free(execpath); | ||
744 | GNUNET_free(dirname); | ||
745 | return tmp; | ||
746 | } | ||
747 | GNUNET_free(tmp); | ||
748 | tmp = NULL; | ||
749 | dirname = NULL; | ||
750 | if (4 == sizeof(void *)) | ||
751 | { | ||
752 | GNUNET_asprintf(&dirname, | ||
753 | DIR_SEPARATOR_STR "lib32" DIR_SEPARATOR_STR | ||
754 | "%s" DIR_SEPARATOR_STR | ||
755 | "libexec" DIR_SEPARATOR_STR, | ||
756 | current_pd->project_dirname); | ||
757 | GNUNET_asprintf(&tmp, "%s%s", execpath, dirname); | ||
758 | } | ||
759 | if (8 == sizeof(void *)) | ||
760 | { | ||
761 | GNUNET_asprintf(&dirname, | ||
762 | DIR_SEPARATOR_STR "lib64" DIR_SEPARATOR_STR | ||
763 | "%s" DIR_SEPARATOR_STR | ||
764 | "libexec" DIR_SEPARATOR_STR, | ||
765 | current_pd->project_dirname); | ||
766 | GNUNET_asprintf(&tmp, "%s%s", execpath, dirname); | ||
767 | } | ||
768 | if ((NULL != tmp) && | ||
769 | (GNUNET_YES == GNUNET_DISK_directory_test(tmp, GNUNET_YES))) | ||
770 | { | ||
771 | GNUNET_free(execpath); | ||
772 | GNUNET_free_non_null(dirname); | ||
773 | return tmp; | ||
774 | } | ||
775 | GNUNET_free(tmp); | ||
776 | GNUNET_free_non_null(dirname); | ||
777 | } | ||
778 | GNUNET_asprintf(&dirname, | ||
779 | DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR | ||
780 | "libexec" DIR_SEPARATOR_STR, | ||
781 | current_pd->project_dirname); | ||
782 | break; | ||
783 | |||
784 | default: | ||
785 | GNUNET_free(execpath); | ||
786 | return NULL; | ||
766 | } | 787 | } |
767 | GNUNET_asprintf (&dirname, | 788 | GNUNET_asprintf(&tmp, "%s%s", execpath, dirname); |
768 | DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR | 789 | GNUNET_free(dirname); |
769 | "libexec" DIR_SEPARATOR_STR, | 790 | GNUNET_free(execpath); |
770 | current_pd->project_dirname); | ||
771 | break; | ||
772 | default: | ||
773 | GNUNET_free (execpath); | ||
774 | return NULL; | ||
775 | } | ||
776 | GNUNET_asprintf (&tmp, "%s%s", execpath, dirname); | ||
777 | GNUNET_free (dirname); | ||
778 | GNUNET_free (execpath); | ||
779 | return tmp; | 791 | return tmp; |
780 | } | 792 | } |
781 | 793 | ||
@@ -789,7 +801,7 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) | |||
789 | * @return full path to the binary, if possible, otherwise copy of 'progname' | 801 | * @return full path to the binary, if possible, otherwise copy of 'progname' |
790 | */ | 802 | */ |
791 | char * | 803 | char * |
792 | GNUNET_OS_get_libexec_binary_path (const char *progname) | 804 | GNUNET_OS_get_libexec_binary_path(const char *progname) |
793 | { | 805 | { |
794 | static char *cache; | 806 | static char *cache; |
795 | char *libexecdir; | 807 | char *libexecdir; |
@@ -797,15 +809,15 @@ GNUNET_OS_get_libexec_binary_path (const char *progname) | |||
797 | 809 | ||
798 | if ((DIR_SEPARATOR == progname[0]) || | 810 | if ((DIR_SEPARATOR == progname[0]) || |
799 | (GNUNET_YES == | 811 | (GNUNET_YES == |
800 | GNUNET_STRINGS_path_is_absolute (progname, GNUNET_NO, NULL, NULL))) | 812 | GNUNET_STRINGS_path_is_absolute(progname, GNUNET_NO, NULL, NULL))) |
801 | return GNUNET_strdup (progname); | 813 | return GNUNET_strdup(progname); |
802 | if (NULL != cache) | 814 | if (NULL != cache) |
803 | libexecdir = cache; | 815 | libexecdir = cache; |
804 | else | 816 | else |
805 | libexecdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBEXECDIR); | 817 | libexecdir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LIBEXECDIR); |
806 | if (NULL == libexecdir) | 818 | if (NULL == libexecdir) |
807 | return GNUNET_strdup (progname); | 819 | return GNUNET_strdup(progname); |
808 | GNUNET_asprintf (&binary, "%s%s", libexecdir, progname); | 820 | GNUNET_asprintf(&binary, "%s%s", libexecdir, progname); |
809 | cache = libexecdir; | 821 | cache = libexecdir; |
810 | return binary; | 822 | return binary; |
811 | } | 823 | } |
@@ -824,8 +836,8 @@ GNUNET_OS_get_libexec_binary_path (const char *progname) | |||
824 | * otherwise | 836 | * otherwise |
825 | */ | 837 | */ |
826 | char * | 838 | char * |
827 | GNUNET_OS_get_suid_binary_path (const struct GNUNET_CONFIGURATION_Handle *cfg, | 839 | GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, |
828 | const char *progname) | 840 | const char *progname) |
829 | { | 841 | { |
830 | static char *cache; | 842 | static char *cache; |
831 | char *binary = NULL; | 843 | char *binary = NULL; |
@@ -833,26 +845,26 @@ GNUNET_OS_get_suid_binary_path (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
833 | size_t path_len; | 845 | size_t path_len; |
834 | 846 | ||
835 | if (GNUNET_YES == | 847 | if (GNUNET_YES == |
836 | GNUNET_STRINGS_path_is_absolute (progname, GNUNET_NO, NULL, NULL)) | 848 | GNUNET_STRINGS_path_is_absolute(progname, GNUNET_NO, NULL, NULL)) |
837 | { | 849 | { |
838 | return GNUNET_strdup (progname); | 850 | return GNUNET_strdup(progname); |
839 | } | 851 | } |
840 | if (NULL != cache) | 852 | if (NULL != cache) |
841 | path = cache; | 853 | path = cache; |
842 | else | 854 | else |
843 | GNUNET_CONFIGURATION_get_value_string (cfg, | 855 | GNUNET_CONFIGURATION_get_value_string(cfg, |
844 | "PATHS", | 856 | "PATHS", |
845 | "SUID_BINARY_PATH", | 857 | "SUID_BINARY_PATH", |
846 | &path); | 858 | &path); |
847 | if ((NULL == path) || (0 == strlen (path))) | 859 | if ((NULL == path) || (0 == strlen(path))) |
848 | return GNUNET_OS_get_libexec_binary_path (progname); | 860 | return GNUNET_OS_get_libexec_binary_path(progname); |
849 | path_len = strlen (path); | 861 | path_len = strlen(path); |
850 | GNUNET_asprintf (&binary, | 862 | GNUNET_asprintf(&binary, |
851 | "%s%s%s", | 863 | "%s%s%s", |
852 | path, | 864 | path, |
853 | (path[path_len - 1] == DIR_SEPARATOR) ? "" | 865 | (path[path_len - 1] == DIR_SEPARATOR) ? "" |
854 | : DIR_SEPARATOR_STR, | 866 | : DIR_SEPARATOR_STR, |
855 | progname); | 867 | progname); |
856 | cache = path; | 868 | cache = path; |
857 | return binary; | 869 | return binary; |
858 | } | 870 | } |
@@ -875,143 +887,144 @@ GNUNET_OS_get_suid_binary_path (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
875 | * #GNUNET_SYSERR on error (no such binary or not executable) | 887 | * #GNUNET_SYSERR on error (no such binary or not executable) |
876 | */ | 888 | */ |
877 | int | 889 | int |
878 | GNUNET_OS_check_helper_binary (const char *binary, | 890 | GNUNET_OS_check_helper_binary(const char *binary, |
879 | int check_suid, | 891 | int check_suid, |
880 | const char *params) | 892 | const char *params) |
881 | { | 893 | { |
882 | struct stat statbuf; | 894 | struct stat statbuf; |
883 | char *p; | 895 | char *p; |
884 | char *pf; | 896 | char *pf; |
897 | |||
885 | #ifdef MINGW | 898 | #ifdef MINGW |
886 | char *binaryexe; | 899 | char *binaryexe; |
887 | 900 | ||
888 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | 901 | GNUNET_asprintf(&binaryexe, "%s.exe", binary); |
889 | if ((GNUNET_YES == | 902 | if ((GNUNET_YES == |
890 | GNUNET_STRINGS_path_is_absolute (binaryexe, GNUNET_NO, NULL, NULL)) || | 903 | GNUNET_STRINGS_path_is_absolute(binaryexe, GNUNET_NO, NULL, NULL)) || |
891 | (0 == strncmp (binary, "./", 2))) | 904 | (0 == strncmp(binary, "./", 2))) |
892 | p = GNUNET_strdup (binaryexe); | 905 | p = GNUNET_strdup(binaryexe); |
893 | else | 906 | else |
894 | { | ||
895 | p = get_path_from_PATH (binaryexe); | ||
896 | if (NULL != p) | ||
897 | { | 907 | { |
898 | GNUNET_asprintf (&pf, "%s/%s", p, binaryexe); | 908 | p = get_path_from_PATH(binaryexe); |
899 | GNUNET_free (p); | 909 | if (NULL != p) |
900 | p = pf; | 910 | { |
911 | GNUNET_asprintf(&pf, "%s/%s", p, binaryexe); | ||
912 | GNUNET_free(p); | ||
913 | p = pf; | ||
914 | } | ||
901 | } | 915 | } |
902 | } | 916 | GNUNET_free(binaryexe); |
903 | GNUNET_free (binaryexe); | ||
904 | #else | 917 | #else |
905 | if ((GNUNET_YES == | 918 | if ((GNUNET_YES == |
906 | GNUNET_STRINGS_path_is_absolute (binary, GNUNET_NO, NULL, NULL)) || | 919 | GNUNET_STRINGS_path_is_absolute(binary, GNUNET_NO, NULL, NULL)) || |
907 | (0 == strncmp (binary, "./", 2))) | 920 | (0 == strncmp(binary, "./", 2))) |
908 | { | 921 | { |
909 | p = GNUNET_strdup (binary); | 922 | p = GNUNET_strdup(binary); |
910 | } | 923 | } |
911 | else | 924 | else |
912 | { | ||
913 | p = get_path_from_PATH (binary); | ||
914 | if (NULL != p) | ||
915 | { | 925 | { |
916 | GNUNET_asprintf (&pf, "%s/%s", p, binary); | 926 | p = get_path_from_PATH(binary); |
917 | GNUNET_free (p); | 927 | if (NULL != p) |
918 | p = pf; | 928 | { |
929 | GNUNET_asprintf(&pf, "%s/%s", p, binary); | ||
930 | GNUNET_free(p); | ||
931 | p = pf; | ||
932 | } | ||
919 | } | 933 | } |
920 | } | ||
921 | #endif | 934 | #endif |
922 | if (NULL == p) | 935 | if (NULL == p) |
923 | { | ||
924 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
925 | _ ("Could not find binary `%s' in PATH!\n"), | ||
926 | binary); | ||
927 | return GNUNET_SYSERR; | ||
928 | } | ||
929 | if (0 != access (p, X_OK)) | ||
930 | { | ||
931 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", p); | ||
932 | GNUNET_free (p); | ||
933 | return GNUNET_SYSERR; | ||
934 | } | ||
935 | #ifndef MINGW | ||
936 | if (0 == getuid ()) | ||
937 | { | ||
938 | /* as we run as root, we don't insist on SUID */ | ||
939 | GNUNET_free (p); | ||
940 | return GNUNET_YES; | ||
941 | } | ||
942 | #endif | ||
943 | if (0 != stat (p, &statbuf)) | ||
944 | { | ||
945 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", p); | ||
946 | GNUNET_free (p); | ||
947 | return GNUNET_SYSERR; | ||
948 | } | ||
949 | if (check_suid) | ||
950 | { | ||
951 | #ifndef MINGW | ||
952 | (void) params; | ||
953 | if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid)) | ||
954 | { | 936 | { |
955 | GNUNET_free (p); | 937 | LOG(GNUNET_ERROR_TYPE_INFO, |
956 | return GNUNET_YES; | 938 | _("Could not find binary `%s' in PATH!\n"), |
939 | binary); | ||
940 | return GNUNET_SYSERR; | ||
957 | } | 941 | } |
958 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 942 | if (0 != access(p, X_OK)) |
959 | _ ("Binary `%s' exists, but is not SUID\n"), | ||
960 | p); | ||
961 | /* binary exists, but not SUID */ | ||
962 | #else | ||
963 | STARTUPINFO start; | ||
964 | char parameters[512]; | ||
965 | PROCESS_INFORMATION proc; | ||
966 | DWORD exit_value; | ||
967 | |||
968 | GNUNET_snprintf (parameters, sizeof (parameters), "-d %s", params); | ||
969 | memset (&start, 0, sizeof (start)); | ||
970 | start.cb = sizeof (start); | ||
971 | memset (&proc, 0, sizeof (proc)); | ||
972 | |||
973 | |||
974 | // Start the child process. | ||
975 | if (! (CreateProcess ( | ||
976 | p, // current windows (2k3 and up can handle / instead of \ in paths)) | ||
977 | parameters, // execute dryrun/priviliege checking mode | ||
978 | NULL, // Process handle not inheritable | ||
979 | NULL, // Thread handle not inheritable | ||
980 | FALSE, // Set handle inheritance to FALSE | ||
981 | CREATE_DEFAULT_ERROR_MODE, // No creation flags | ||
982 | NULL, // Use parent's environment block | ||
983 | NULL, // Use parent's starting directory | ||
984 | &start, // Pointer to STARTUPINFO structure | ||
985 | &proc) // Pointer to PROCESS_INFORMATION structure | ||
986 | )) | ||
987 | { | 943 | { |
988 | LOG (GNUNET_ERROR_TYPE_ERROR, | 944 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "access", p); |
989 | _ ("CreateProcess failed for binary %s (%d).\n"), | 945 | GNUNET_free(p); |
990 | p, | ||
991 | GetLastError ()); | ||
992 | return GNUNET_SYSERR; | 946 | return GNUNET_SYSERR; |
993 | } | 947 | } |
994 | 948 | #ifndef MINGW | |
995 | // Wait until child process exits. | 949 | if (0 == getuid()) |
996 | WaitForSingleObject (proc.hProcess, INFINITE); | 950 | { |
997 | 951 | /* as we run as root, we don't insist on SUID */ | |
998 | if (! GetExitCodeProcess (proc.hProcess, &exit_value)) | 952 | GNUNET_free(p); |
953 | return GNUNET_YES; | ||
954 | } | ||
955 | #endif | ||
956 | if (0 != stat(p, &statbuf)) | ||
999 | { | 957 | { |
1000 | LOG (GNUNET_ERROR_TYPE_ERROR, | 958 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "stat", p); |
1001 | _ ("GetExitCodeProcess failed for binary %s (%d).\n"), | 959 | GNUNET_free(p); |
1002 | p, | ||
1003 | GetLastError ()); | ||
1004 | return GNUNET_SYSERR; | 960 | return GNUNET_SYSERR; |
1005 | } | 961 | } |
1006 | // Close process and thread handles. | 962 | if (check_suid) |
1007 | CloseHandle (proc.hProcess); | 963 | { |
1008 | CloseHandle (proc.hThread); | 964 | #ifndef MINGW |
1009 | 965 | (void)params; | |
1010 | if (! exit_value) | 966 | if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid)) |
1011 | return GNUNET_YES; | 967 | { |
968 | GNUNET_free(p); | ||
969 | return GNUNET_YES; | ||
970 | } | ||
971 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
972 | _("Binary `%s' exists, but is not SUID\n"), | ||
973 | p); | ||
974 | /* binary exists, but not SUID */ | ||
975 | #else | ||
976 | STARTUPINFO start; | ||
977 | char parameters[512]; | ||
978 | PROCESS_INFORMATION proc; | ||
979 | DWORD exit_value; | ||
980 | |||
981 | GNUNET_snprintf(parameters, sizeof(parameters), "-d %s", params); | ||
982 | memset(&start, 0, sizeof(start)); | ||
983 | start.cb = sizeof(start); | ||
984 | memset(&proc, 0, sizeof(proc)); | ||
985 | |||
986 | |||
987 | // Start the child process. | ||
988 | if (!(CreateProcess( | ||
989 | p, // current windows (2k3 and up can handle / instead of \ in paths)) | ||
990 | parameters, // execute dryrun/priviliege checking mode | ||
991 | NULL, // Process handle not inheritable | ||
992 | NULL, // Thread handle not inheritable | ||
993 | FALSE, // Set handle inheritance to FALSE | ||
994 | CREATE_DEFAULT_ERROR_MODE, // No creation flags | ||
995 | NULL, // Use parent's environment block | ||
996 | NULL, // Use parent's starting directory | ||
997 | &start, // Pointer to STARTUPINFO structure | ||
998 | &proc) // Pointer to PROCESS_INFORMATION structure | ||
999 | )) | ||
1000 | { | ||
1001 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1002 | _("CreateProcess failed for binary %s (%d).\n"), | ||
1003 | p, | ||
1004 | GetLastError()); | ||
1005 | return GNUNET_SYSERR; | ||
1006 | } | ||
1007 | |||
1008 | // Wait until child process exits. | ||
1009 | WaitForSingleObject(proc.hProcess, INFINITE); | ||
1010 | |||
1011 | if (!GetExitCodeProcess(proc.hProcess, &exit_value)) | ||
1012 | { | ||
1013 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1014 | _("GetExitCodeProcess failed for binary %s (%d).\n"), | ||
1015 | p, | ||
1016 | GetLastError()); | ||
1017 | return GNUNET_SYSERR; | ||
1018 | } | ||
1019 | // Close process and thread handles. | ||
1020 | CloseHandle(proc.hProcess); | ||
1021 | CloseHandle(proc.hThread); | ||
1022 | |||
1023 | if (!exit_value) | ||
1024 | return GNUNET_YES; | ||
1012 | #endif | 1025 | #endif |
1013 | } | 1026 | } |
1014 | GNUNET_free (p); | 1027 | GNUNET_free(p); |
1015 | return GNUNET_NO; | 1028 | return GNUNET_NO; |
1016 | } | 1029 | } |
1017 | 1030 | ||