summaryrefslogtreecommitdiff
path: root/src/util/os_installation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/os_installation.c')
-rw-r--r--src/util/os_installation.c1005
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 */
93const struct GNUNET_OS_ProjectData * 93const struct GNUNET_OS_ProjectData *
94GNUNET_OS_project_data_default (void) 94GNUNET_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 */
103const struct GNUNET_OS_ProjectData * 103const struct GNUNET_OS_ProjectData *
104GNUNET_OS_project_data_get () 104GNUNET_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 */
123void 123void
124GNUNET_OS_init (const struct GNUNET_OS_ProjectData *pd) 124GNUNET_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 */
145static char * 145static char *
146get_path_from_proc_maps () 146get_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 */
179static char * 179static char *
180get_path_from_proc_exe () 180get_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 */
224BOOL WINAPI 224BOOL WINAPI
225DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 225DllMain(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 */
248static char * 251static char *
249get_path_from_module_filename () 252get_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 */
345static char * 349static char *
346get_path_from_NSGetExecutablePath () 350get_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 */
383static char * 387static char *
384get_path_from_dyld_image () 388get_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 */
421static char * 425static char *
422get_path_from_PATH (const char *binary) 426get_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 */
473static char * 477static char *
474get_path_from_GNUNET_PREFIX () 478get_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 */
494static char * 498static char *
495os_get_gnunet_path () 499os_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 */
538static char * 542static char *
539os_get_exec_path () 543os_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 */
565char * 569char *
566GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) 570GNUNET_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 */
791char * 803char *
792GNUNET_OS_get_libexec_binary_path (const char *progname) 804GNUNET_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 */
826char * 838char *
827GNUNET_OS_get_suid_binary_path (const struct GNUNET_CONFIGURATION_Handle *cfg, 839GNUNET_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 */
877int 889int
878GNUNET_OS_check_helper_binary (const char *binary, 890GNUNET_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