aboutsummaryrefslogtreecommitdiff
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.c289
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