diff options
Diffstat (limited to 'src/util/os_installation.c')
-rw-r--r-- | src/util/os_installation.c | 289 |
1 files changed, 148 insertions, 141 deletions
diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 1f4c5f000..688cc448e 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c | |||
@@ -38,6 +38,10 @@ | |||
38 | #include <mach-o/dyld.h> | 38 | #include <mach-o/dyld.h> |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | ||
42 | |||
43 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | ||
44 | |||
41 | #if LINUX | 45 | #if LINUX |
42 | /** | 46 | /** |
43 | * Try to determine path by reading /proc/PID/exe | 47 | * Try to determine path by reading /proc/PID/exe |
@@ -56,16 +60,16 @@ get_path_from_proc_maps () | |||
56 | if (f == NULL) | 60 | if (f == NULL) |
57 | return NULL; | 61 | return NULL; |
58 | while (NULL != fgets (line, sizeof (line), f)) | 62 | while (NULL != fgets (line, sizeof (line), f)) |
59 | { | ||
60 | if ((1 == | ||
61 | sscanf (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", dir)) && | ||
62 | (NULL != (lgu = strstr (dir, "libgnunetutil")))) | ||
63 | { | 63 | { |
64 | lgu[0] = '\0'; | 64 | if ((1 == |
65 | fclose (f); | 65 | sscanf (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", |
66 | return GNUNET_strdup (dir); | 66 | dir)) && (NULL != (lgu = strstr (dir, "libgnunetutil")))) |
67 | { | ||
68 | lgu[0] = '\0'; | ||
69 | fclose (f); | ||
70 | return GNUNET_strdup (dir); | ||
71 | } | ||
67 | } | 72 | } |
68 | } | ||
69 | fclose (f); | 73 | fclose (f); |
70 | return NULL; | 74 | return NULL; |
71 | } | 75 | } |
@@ -83,19 +87,19 @@ get_path_from_proc_exe () | |||
83 | GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/exe", getpid ()); | 87 | GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/exe", getpid ()); |
84 | size = readlink (fn, lnk, sizeof (lnk) - 1); | 88 | size = readlink (fn, lnk, sizeof (lnk) - 1); |
85 | if (size <= 0) | 89 | if (size <= 0) |
86 | { | 90 | { |
87 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "readlink", fn); | 91 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "readlink", fn); |
88 | return NULL; | 92 | return NULL; |
89 | } | 93 | } |
90 | GNUNET_assert (size < sizeof (lnk)); | 94 | GNUNET_assert (size < sizeof (lnk)); |
91 | lnk[size] = '\0'; | 95 | lnk[size] = '\0'; |
92 | while ((lnk[size] != '/') && (size > 0)) | 96 | while ((lnk[size] != '/') && (size > 0)) |
93 | size--; | 97 | size--; |
94 | if ((size < 4) || (lnk[size - 4] != '/')) | 98 | if ((size < 4) || (lnk[size - 4] != '/')) |
95 | { | 99 | { |
96 | /* not installed in "/bin/" -- binary path probably useless */ | 100 | /* not installed in "/bin/" -- binary path probably useless */ |
97 | return NULL; | 101 | return NULL; |
98 | } | 102 | } |
99 | lnk[size] = '\0'; | 103 | lnk[size] = '\0'; |
100 | return GNUNET_strdup (lnk); | 104 | return GNUNET_strdup (lnk); |
101 | } | 105 | } |
@@ -134,7 +138,7 @@ get_path_from_NSGetExecutablePath () | |||
134 | 138 | ||
135 | path = NULL; | 139 | path = NULL; |
136 | func = | 140 | func = |
137 | (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, "_NSGetExecutablePath"); | 141 | (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, "_NSGetExecutablePath"); |
138 | if (!func) | 142 | if (!func) |
139 | return NULL; | 143 | return NULL; |
140 | path = &zero; | 144 | path = &zero; |
@@ -146,10 +150,10 @@ get_path_from_NSGetExecutablePath () | |||
146 | path = GNUNET_malloc (len); | 150 | path = GNUNET_malloc (len); |
147 | ret = func (path, &len); | 151 | ret = func (path, &len); |
148 | if (ret != 0) | 152 | if (ret != 0) |
149 | { | 153 | { |
150 | GNUNET_free (path); | 154 | GNUNET_free (path); |
151 | return NULL; | 155 | return NULL; |
152 | } | 156 | } |
153 | len = strlen (path); | 157 | len = strlen (path); |
154 | while ((path[len] != '/') && (len > 0)) | 158 | while ((path[len] != '/') && (len > 0)) |
155 | len--; | 159 | len--; |
@@ -168,22 +172,22 @@ get_path_from_dyld_image () | |||
168 | p = NULL; | 172 | p = NULL; |
169 | c = _dyld_image_count (); | 173 | c = _dyld_image_count (); |
170 | for (i = 0; i < c; i++) | 174 | for (i = 0; i < c; i++) |
171 | { | ||
172 | if (_dyld_get_image_header (i) == &_mh_dylib_header) | ||
173 | { | 175 | { |
174 | path = _dyld_get_image_name (i); | 176 | if (_dyld_get_image_header (i) == &_mh_dylib_header) |
175 | if (path != NULL && strlen (path) > 0) | 177 | { |
176 | { | 178 | path = _dyld_get_image_name (i); |
177 | p = strdup (path); | 179 | if (path != NULL && strlen (path) > 0) |
178 | s = p + strlen (p); | 180 | { |
179 | while ((s > p) && (*s != '/')) | 181 | p = strdup (path); |
180 | s--; | 182 | s = p + strlen (p); |
181 | s++; | 183 | while ((s > p) && (*s != '/')) |
182 | *s = '\0'; | 184 | s--; |
183 | } | 185 | s++; |
184 | break; | 186 | *s = '\0'; |
187 | } | ||
188 | break; | ||
189 | } | ||
185 | } | 190 | } |
186 | } | ||
187 | return p; | 191 | return p; |
188 | } | 192 | } |
189 | #endif | 193 | #endif |
@@ -207,30 +211,30 @@ get_path_from_PATH (const char *binary) | |||
207 | p = getenv ("PATH"); | 211 | p = getenv ("PATH"); |
208 | if (p == NULL) | 212 | if (p == NULL) |
209 | return NULL; | 213 | return NULL; |
210 | path = GNUNET_strdup (p); /* because we write on it */ | 214 | path = GNUNET_strdup (p); /* because we write on it */ |
211 | buf = GNUNET_malloc (strlen (path) + 20); | 215 | buf = GNUNET_malloc (strlen (path) + 20); |
212 | pos = path; | 216 | pos = path; |
213 | while (NULL != (end = strchr (pos, PATH_SEPARATOR))) | 217 | while (NULL != (end = strchr (pos, PATH_SEPARATOR))) |
214 | { | 218 | { |
215 | *end = '\0'; | 219 | *end = '\0'; |
216 | sprintf (buf, "%s/%s", pos, binary); | 220 | sprintf (buf, "%s/%s", pos, binary); |
217 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | 221 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) |
222 | { | ||
223 | pos = GNUNET_strdup (pos); | ||
224 | GNUNET_free (buf); | ||
225 | GNUNET_free (path); | ||
226 | return pos; | ||
227 | } | ||
228 | pos = end + 1; | ||
229 | } | ||
230 | sprintf (buf, "%s/%s", pos, binary); | ||
231 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
218 | { | 232 | { |
219 | pos = GNUNET_strdup (pos); | 233 | pos = GNUNET_strdup (pos); |
220 | GNUNET_free (buf); | 234 | GNUNET_free (buf); |
221 | GNUNET_free (path); | 235 | GNUNET_free (path); |
222 | return pos; | 236 | return pos; |
223 | } | 237 | } |
224 | pos = end + 1; | ||
225 | } | ||
226 | sprintf (buf, "%s/%s", pos, binary); | ||
227 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
228 | { | ||
229 | pos = GNUNET_strdup (pos); | ||
230 | GNUNET_free (buf); | ||
231 | GNUNET_free (path); | ||
232 | return pos; | ||
233 | } | ||
234 | GNUNET_free (buf); | 238 | GNUNET_free (buf); |
235 | GNUNET_free (path); | 239 | GNUNET_free (path); |
236 | return NULL; | 240 | return NULL; |
@@ -286,10 +290,10 @@ os_get_gnunet_path () | |||
286 | if (ret != NULL) | 290 | if (ret != NULL) |
287 | return ret; | 291 | return ret; |
288 | /* other attempts here */ | 292 | /* other attempts here */ |
289 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 293 | LOG (GNUNET_ERROR_TYPE_ERROR, |
290 | _ | 294 | _ |
291 | ("Could not determine installation path for %s. Set `%s' environment variable.\n"), | 295 | ("Could not determine installation path for %s. Set `%s' environment variable.\n"), |
292 | "GNUnet", "GNUNET_PREFIX"); | 296 | "GNUnet", "GNUNET_PREFIX"); |
293 | return NULL; | 297 | return NULL; |
294 | } | 298 | } |
295 | 299 | ||
@@ -355,11 +359,11 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) | |||
355 | 359 | ||
356 | n = strlen (execpath); | 360 | n = strlen (execpath); |
357 | if (n == 0) | 361 | if (n == 0) |
358 | { | 362 | { |
359 | /* should never happen, but better safe than sorry */ | 363 | /* should never happen, but better safe than sorry */ |
360 | GNUNET_free (execpath); | 364 | GNUNET_free (execpath); |
361 | return NULL; | 365 | return NULL; |
362 | } | 366 | } |
363 | /* remove filename itself */ | 367 | /* remove filename itself */ |
364 | while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR)) | 368 | while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR)) |
365 | execpath[--n] = '\0'; | 369 | execpath[--n] = '\0'; |
@@ -368,59 +372,62 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) | |||
368 | if ((n > 5) && | 372 | if ((n > 5) && |
369 | ((0 == strcasecmp (&execpath[n - 5], "lib32")) || | 373 | ((0 == strcasecmp (&execpath[n - 5], "lib32")) || |
370 | (0 == strcasecmp (&execpath[n - 5], "lib64")))) | 374 | (0 == strcasecmp (&execpath[n - 5], "lib64")))) |
371 | { | ||
372 | if (dirkind != GNUNET_OS_IPK_LIBDIR) | ||
373 | { | 375 | { |
374 | /* strip '/lib32' or '/lib64' */ | 376 | if (dirkind != GNUNET_OS_IPK_LIBDIR) |
375 | execpath[n - 5] = '\0'; | 377 | { |
376 | n -= 5; | 378 | /* strip '/lib32' or '/lib64' */ |
379 | execpath[n - 5] = '\0'; | ||
380 | n -= 5; | ||
381 | } | ||
382 | else | ||
383 | isbasedir = 0; | ||
377 | } | 384 | } |
378 | else | ||
379 | isbasedir = 0; | ||
380 | } | ||
381 | else if ((n > 3) && | 385 | else if ((n > 3) && |
382 | ((0 == strcasecmp (&execpath[n - 3], "bin")) || | 386 | ((0 == strcasecmp (&execpath[n - 3], "bin")) || |
383 | (0 == strcasecmp (&execpath[n - 3], "lib")))) | 387 | (0 == strcasecmp (&execpath[n - 3], "lib")))) |
384 | { | 388 | { |
385 | /* strip '/bin' or '/lib' */ | 389 | /* strip '/bin' or '/lib' */ |
386 | execpath[n - 3] = '\0'; | 390 | execpath[n - 3] = '\0'; |
387 | n -= 3; | 391 | n -= 3; |
388 | } | 392 | } |
389 | /* in case this was a directory named foo-bin, remove "foo-" */ | 393 | /* in case this was a directory named foo-bin, remove "foo-" */ |
390 | while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR)) | 394 | while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR)) |
391 | execpath[--n] = '\0'; | 395 | execpath[--n] = '\0'; |
392 | switch (dirkind) | 396 | switch (dirkind) |
393 | { | 397 | { |
394 | case GNUNET_OS_IPK_PREFIX: | 398 | case GNUNET_OS_IPK_PREFIX: |
395 | case GNUNET_OS_IPK_SELF_PREFIX: | 399 | case GNUNET_OS_IPK_SELF_PREFIX: |
396 | dirname = DIR_SEPARATOR_STR; | 400 | dirname = DIR_SEPARATOR_STR; |
397 | break; | 401 | break; |
398 | case GNUNET_OS_IPK_BINDIR: | 402 | case GNUNET_OS_IPK_BINDIR: |
399 | dirname = DIR_SEPARATOR_STR "bin" DIR_SEPARATOR_STR; | 403 | dirname = DIR_SEPARATOR_STR "bin" DIR_SEPARATOR_STR; |
400 | break; | 404 | break; |
401 | case GNUNET_OS_IPK_LIBDIR: | 405 | case GNUNET_OS_IPK_LIBDIR: |
402 | if (isbasedir) | 406 | if (isbasedir) |
407 | dirname = | ||
408 | DIR_SEPARATOR_STR "lib" DIR_SEPARATOR_STR "gnunet" | ||
409 | DIR_SEPARATOR_STR; | ||
410 | else | ||
411 | dirname = DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR; | ||
412 | break; | ||
413 | case GNUNET_OS_IPK_DATADIR: | ||
403 | dirname = | 414 | dirname = |
404 | DIR_SEPARATOR_STR "lib" DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR; | 415 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "gnunet" |
405 | else | 416 | DIR_SEPARATOR_STR; |
406 | dirname = DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR; | 417 | break; |
407 | break; | 418 | case GNUNET_OS_IPK_LOCALEDIR: |
408 | case GNUNET_OS_IPK_DATADIR: | 419 | dirname = |
409 | dirname = | 420 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "locale" |
410 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR; | 421 | DIR_SEPARATOR_STR; |
411 | break; | 422 | break; |
412 | case GNUNET_OS_IPK_LOCALEDIR: | 423 | case GNUNET_OS_IPK_ICONDIR: |
413 | dirname = | 424 | dirname = |
414 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "locale" DIR_SEPARATOR_STR; | 425 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "icons" DIR_SEPARATOR_STR; |
415 | break; | 426 | break; |
416 | case GNUNET_OS_IPK_ICONDIR: | 427 | default: |
417 | dirname = | 428 | GNUNET_free (execpath); |
418 | DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "icons" DIR_SEPARATOR_STR; | 429 | return NULL; |
419 | break; | 430 | } |
420 | default: | ||
421 | GNUNET_free (execpath); | ||
422 | return NULL; | ||
423 | } | ||
424 | tmp = GNUNET_malloc (strlen (execpath) + strlen (dirname) + 1); | 431 | tmp = GNUNET_malloc (strlen (execpath) + strlen (dirname) + 1); |
425 | sprintf (tmp, "%s%s", execpath, dirname); | 432 | sprintf (tmp, "%s%s", execpath, dirname); |
426 | GNUNET_free (execpath); | 433 | GNUNET_free (execpath); |
@@ -453,59 +460,59 @@ GNUNET_OS_check_helper_binary (const char *binary) | |||
453 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | 460 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); |
454 | p = get_path_from_PATH (binaryexe); | 461 | p = get_path_from_PATH (binaryexe); |
455 | if (p != NULL) | 462 | if (p != NULL) |
456 | { | 463 | { |
457 | GNUNET_asprintf (&pf, "%s/%s", p, binaryexe); | 464 | GNUNET_asprintf (&pf, "%s/%s", p, binaryexe); |
458 | GNUNET_free (p); | 465 | GNUNET_free (p); |
459 | p = pf; | 466 | p = pf; |
460 | } | 467 | } |
461 | free (binaryexe); | 468 | free (binaryexe); |
462 | #else | 469 | #else |
463 | p = get_path_from_PATH (binary); | 470 | p = get_path_from_PATH (binary); |
464 | if (p != NULL) | 471 | if (p != NULL) |
465 | { | 472 | { |
466 | GNUNET_asprintf (&pf, "%s/%s", p, binary); | 473 | GNUNET_asprintf (&pf, "%s/%s", p, binary); |
467 | GNUNET_free (p); | 474 | GNUNET_free (p); |
468 | p = pf; | 475 | p = pf; |
469 | } | 476 | } |
470 | #endif | 477 | #endif |
471 | if (p == NULL) | 478 | if (p == NULL) |
472 | { | 479 | { |
473 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 480 | LOG (GNUNET_ERROR_TYPE_INFO, |
474 | _("Could not find binary `%s' in PATH!\n"), binary); | 481 | _("Could not find binary `%s' in PATH!\n"), binary); |
475 | return GNUNET_SYSERR; | 482 | return GNUNET_SYSERR; |
476 | } | 483 | } |
477 | if (0 != STAT (p, &statbuf)) | 484 | if (0 != STAT (p, &statbuf)) |
478 | { | 485 | { |
479 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("stat (%s) failed: %s\n"), p, | 486 | LOG (GNUNET_ERROR_TYPE_WARNING, _("stat (%s) failed: %s\n"), p, |
480 | STRERROR (errno)); | 487 | STRERROR (errno)); |
481 | GNUNET_free (p); | 488 | GNUNET_free (p); |
482 | return GNUNET_SYSERR; | 489 | return GNUNET_SYSERR; |
483 | } | 490 | } |
484 | #ifndef MINGW | 491 | #ifndef MINGW |
485 | if ((0 != (statbuf.st_mode & S_ISUID)) && (statbuf.st_uid == 0)) | 492 | if ((0 != (statbuf.st_mode & S_ISUID)) && (statbuf.st_uid == 0)) |
486 | { | 493 | { |
487 | GNUNET_free (p); | 494 | GNUNET_free (p); |
488 | return GNUNET_YES; | 495 | return GNUNET_YES; |
489 | } | 496 | } |
490 | if (0 == ACCESS (p, X_OK)) | 497 | if (0 == ACCESS (p, X_OK)) |
491 | { | 498 | { |
492 | GNUNET_free (p); | 499 | GNUNET_free (p); |
493 | return GNUNET_NO; | 500 | return GNUNET_NO; |
494 | } | 501 | } |
495 | GNUNET_free (p); | 502 | GNUNET_free (p); |
496 | return GNUNET_SYSERR; | 503 | return GNUNET_SYSERR; |
497 | #else | 504 | #else |
498 | GNUNET_free (p); | 505 | GNUNET_free (p); |
499 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 506 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); |
500 | if (INVALID_SOCKET == rawsock) | 507 | if (INVALID_SOCKET == rawsock) |
501 | { | 508 | { |
502 | DWORD err = GetLastError (); | 509 | DWORD err = GetLastError (); |
503 | 510 | ||
504 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 511 | LOG (GNUNET_ERROR_TYPE_INFO, |
505 | "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", | 512 | "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", |
506 | err); | 513 | err); |
507 | return GNUNET_NO; /* not running as administrator */ | 514 | return GNUNET_NO; /* not running as administrator */ |
508 | } | 515 | } |
509 | closesocket (rawsock); | 516 | closesocket (rawsock); |
510 | return GNUNET_YES; | 517 | return GNUNET_YES; |
511 | #endif | 518 | #endif |