GNUnet 0.22.2
os_installation.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2006-2018, 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
31#include "platform.h"
32#include <sys/stat.h>
33#include <stdlib.h>
34#include <string.h>
35#include <unistd.h>
36#include <unistr.h> /* for u16_to_u8 */
37
38
39#include "gnunet_util_lib.h"
40#if DARWIN
41#include <mach-o/ldsyms.h>
42#include <mach-o/dyld.h>
43#endif
44
45
46#define LOG(kind, ...) \
47 GNUNET_log_from (kind, "util-os-installation", __VA_ARGS__)
48
49#define LOG_STRERROR_FILE(kind, syscall, filename) \
50 GNUNET_log_from_strerror_file (kind, \
51 "util-os-installation", \
52 syscall, \
53 filename)
54
55
60static const struct GNUNET_OS_ProjectData default_pd = {
61 .libname = "libgnunetutil",
62 .project_dirname = "gnunet",
63 .binary_name = "gnunet-arm",
64 .version = PACKAGE_VERSION " " VCS_VERSION,
65 .env_varname = "GNUNET_PREFIX",
66 .base_config_varname = "GNUNET_BASE_CONFIG",
67 .bug_email = "gnunet-developers@gnu.org",
68 .homepage = "http://www.gnu.org/s/gnunet/",
69 .config_file = "gnunet.conf",
70 .user_config_file = "~/.config/gnunet.conf",
71 .is_gnu = 1,
72 .gettext_domain = "gnunet",
73 .gettext_path = NULL,
74 .agpl_url = GNUNET_AGPL_URL,
75};
76
77
81const struct GNUNET_OS_ProjectData *
83{
84 return &default_pd;
85}
86
87
88void
89GNUNET_OS_init (const char *package_name,
90 const struct GNUNET_OS_ProjectData *pd)
91{
92 char *path;
93
96 if (NULL != path)
97 bindtextdomain (package_name,
98 path);
99 GNUNET_free (path);
100}
101
102
103#ifdef __linux__
110static char *
111get_path_from_proc_maps (const struct GNUNET_OS_ProjectData *pd)
112{
113 char fn[64];
114 char line[1024];
115 char dir[1024];
116 FILE *f;
117 char *lgu;
118
119 if (NULL == pd->libname)
120 return NULL;
121 GNUNET_snprintf (fn,
122 sizeof(fn),
123 "/proc/%u/maps",
124 getpid ());
125 if (NULL == (f = fopen (fn, "r")))
126 return NULL;
127 while (NULL != fgets (line, sizeof(line), f))
128 {
129 if ((1 == sscanf (line,
130 "%*p-%*p %*c%*c%*c%*c %*x %*x:%*x %*u%*[ ]%1023s",
131 dir)) &&
132 (NULL != (lgu = strstr (dir,
133 pd->libname))))
134 {
135 lgu[0] = '\0';
136 fclose (f);
137 return GNUNET_strdup (dir);
138 }
139 }
140 fclose (f);
141 return NULL;
142}
143
144
151static char *
152get_path_from_proc_exe (const struct GNUNET_OS_ProjectData *pd)
153{
154 char fn[64];
155 char lnk[1024];
156 ssize_t size;
157 char *lep;
158
159 GNUNET_snprintf (fn,
160 sizeof(fn),
161 "/proc/%u/exe",
162 getpid ());
163 size = readlink (fn,
164 lnk,
165 sizeof(lnk) - 1);
166 if (size <= 0)
167 {
169 "readlink",
170 fn);
171 return NULL;
172 }
173 GNUNET_assert (((size_t) size) < sizeof(lnk));
174 lnk[size] = '\0';
175 while ((lnk[size] != '/') && (size > 0))
176 size--;
177 GNUNET_asprintf (&lep,
178 "/%s/libexec/",
179 pd->project_dirname);
180 /* test for being in lib/gnunet/libexec/ or lib/MULTIARCH/gnunet/libexec */
181 if ((((size_t) size) > strlen (lep)) &&
182 (0 == strcmp (lep,
183 &lnk[size - strlen (lep)])))
184 size -= strlen (lep) - 1;
185 GNUNET_free (lep);
186 if ((size < 4) || (lnk[size - 4] != '/'))
187 {
188 /* not installed in "/bin/" -- binary path probably useless */
189 return NULL;
190 }
191 lnk[size] = '\0';
192 return GNUNET_strdup (lnk);
193}
194
195
196#endif
197
198
199#if DARWIN
207typedef int (*MyNSGetExecutablePathProto) (char *buf,
208 size_t *bufsize);
209
210
216static char *
217get_path_from_NSGetExecutablePath (void)
218{
219 static char zero = '\0';
220 char *path;
221 size_t len;
222 MyNSGetExecutablePathProto func;
223
224 path = NULL;
225 if (NULL ==
226 (func = (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT,
227 "_NSGetExecutablePath")))
228 return NULL;
229 path = &zero;
230 len = 0;
231 /* get the path len, including the trailing \0 */
232 (void) func (path, &len);
233 if (0 == len)
234 return NULL;
235 path = GNUNET_malloc (len);
236 if (0 != func (path, &len))
237 {
238 GNUNET_free (path);
239 return NULL;
240 }
241 len = strlen (path);
242 while ((path[len] != '/') && (len > 0))
243 len--;
244 path[len] = '\0';
245 return path;
246}
247
248
254static char *
255get_path_from_dyld_image (void)
256{
257 const char *path;
258 char *p;
259 char *s;
260 unsigned int i;
261 int c;
262
263 c = _dyld_image_count ();
264 for (i = 0; i < c; i++)
265 {
266 if (((const void *) _dyld_get_image_header (i)) !=
267 ((const void *) &_mh_dylib_header))
268 continue;
269 path = _dyld_get_image_name (i);
270 if ((NULL == path) || (0 == strlen (path)))
271 continue;
272 p = GNUNET_strdup (path);
273 s = p + strlen (p);
274 while ((s > p) && ('/' != *s))
275 s--;
276 s++;
277 *s = '\0';
278 return p;
279 }
280 return NULL;
281}
282
283
284#endif
285
286
294static char *
295get_path_from_PATH (const char *binary)
296{
297 char *path;
298 char *pos;
299 char *end;
300 char *buf;
301 const char *p;
302
303 if (NULL == (p = getenv ("PATH")))
304 return NULL;
305
306 path = GNUNET_strdup (p); /* because we write on it */
307 buf = GNUNET_malloc (strlen (path) + strlen (binary) + 1 + 1);
308 pos = path;
309 while (NULL != (end = strchr (pos,
311 {
312 *end = '\0';
313 sprintf (buf,
314 "%s/%s",
315 pos,
316 binary);
317 if (GNUNET_YES ==
319 {
320 pos = GNUNET_strdup (pos);
321 GNUNET_free (buf);
322 GNUNET_free (path);
323 return pos;
324 }
325 pos = end + 1;
326 }
327 sprintf (buf,
328 "%s/%s",
329 pos,
330 binary);
331 if (GNUNET_YES ==
333 {
334 pos = GNUNET_strdup (pos);
335 GNUNET_free (buf);
336 GNUNET_free (path);
337 return pos;
338 }
339 GNUNET_free (buf);
340 GNUNET_free (path);
341 return NULL;
342}
343
344
352static char *
354{
355 const char *p;
356
357 if ((NULL != pd->env_varname) &&
358 (NULL != (p = getenv (pd->env_varname))))
359 return GNUNET_strdup (p);
360 if ((NULL != pd->env_varname_alt) &&
361 (NULL != (p = getenv (pd->env_varname_alt))))
362 return GNUNET_strdup (p);
363 return NULL;
364}
365
366
374static char *
376{
377 char *ret;
378
379 if (NULL != (ret = get_path_from_GNUNET_PREFIX (pd)))
380 return ret;
381#ifdef __linux__
382 if (NULL != (ret = get_path_from_proc_maps (pd)))
383 return ret;
384 /* try path *first*, before /proc/exe, as /proc/exe can be wrong */
385 if ((NULL != pd->binary_name) &&
386 (NULL != (ret = get_path_from_PATH (pd->binary_name))))
387 return ret;
388 if (NULL != (ret = get_path_from_proc_exe (pd)))
389 return ret;
390#endif
391#if DARWIN
392 if (NULL != (ret = get_path_from_dyld_image ()))
393 return ret;
394 if (NULL != (ret = get_path_from_NSGetExecutablePath ()))
395 return ret;
396#endif
397 if ((NULL != pd->binary_name) &&
398 (NULL != (ret = get_path_from_PATH (pd->binary_name))))
399 return ret;
400 /* other attempts here */
402 "Could not determine installation path for %s. Set `%s' environment variable.\n",
403 pd->project_dirname,
404 pd->env_varname);
405 return NULL;
406}
407
408
415static char *
417{
418 char *ret = NULL;
419
420#ifdef __linux__
421 if (NULL != (ret = get_path_from_proc_exe (pd)))
422 return ret;
423#endif
424#if DARWIN
425 if (NULL != (ret = get_path_from_NSGetExecutablePath ()))
426 return ret;
427#endif
428 /* other attempts here */
429 return ret;
430}
431
432
433char *
436{
437 size_t n;
438 char *dirname;
439 char *execpath = NULL;
440 char *tmp;
441 char *multiarch;
442 char *libdir;
443 int isbasedir;
444
445 /* if wanted, try to get the current app's bin/ */
446 if (dirkind == GNUNET_OS_IPK_SELF_PREFIX)
447 execpath = os_get_exec_path (pd);
448
449 /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some
450 * guess for the current app */
451 if (NULL == execpath)
452 execpath = os_get_gnunet_path (pd);
453 if (NULL == execpath)
454 return NULL;
455
456 n = strlen (execpath);
457 if (0 == n)
458 {
459 /* should never happen, but better safe than sorry */
460 GNUNET_free (execpath);
461 return NULL;
462 }
463 /* remove filename itself */
464 while ((n > 1) && (DIR_SEPARATOR == execpath[n - 1]))
465 execpath[--n] = '\0';
466
467 isbasedir = 1;
468 if ((n > 6) && ((0 == strcasecmp (&execpath[n - 6], "/lib32")) ||
469 (0 == strcasecmp (&execpath[n - 6], "/lib64"))))
470 {
471 if ((GNUNET_OS_IPK_LIBDIR != dirkind) &&
472 (GNUNET_OS_IPK_LIBEXECDIR != dirkind))
473 {
474 /* strip '/lib32' or '/lib64' */
475 execpath[n - 6] = '\0';
476 n -= 6;
477 }
478 else
479 isbasedir = 0;
480 }
481 else if ((n > 4) && ((0 == strcasecmp (&execpath[n - 4], "/bin")) ||
482 (0 == strcasecmp (&execpath[n - 4], "/lib"))))
483 {
484 /* strip '/bin' or '/lib' */
485 execpath[n - 4] = '\0';
486 n -= 4;
487 }
488 multiarch = NULL;
489 if (NULL != (libdir = strstr (execpath, "/lib/")))
490 {
491 /* test for multi-arch path of the form "PREFIX/lib/MULTIARCH/";
492 here we need to re-add 'multiarch' to lib and libexec paths later! */
493 multiarch = &libdir[5];
494 if (NULL == strchr (multiarch, '/'))
495 libdir[0] =
496 '\0'; /* Debian multiarch format, cut of from 'execpath' but preserve in multicarch */
497 else
498 multiarch =
499 NULL; /* maybe not, multiarch still has a '/', which is not OK */
500 }
501 /* in case this was a directory named foo-bin, remove "foo-" */
502 while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR))
503 execpath[--n] = '\0';
504 switch (dirkind)
505 {
509 break;
510
513 break;
514
516 if (isbasedir)
517 {
518 GNUNET_asprintf (&tmp,
519 "%s%s%s%s%s%s%s",
520 execpath,
521 DIR_SEPARATOR_STR "lib",
522 (NULL != multiarch) ? DIR_SEPARATOR_STR : "",
523 (NULL != multiarch) ? multiarch : "",
525 pd->project_dirname,
528 {
529 GNUNET_free (execpath);
530 return tmp;
531 }
532 GNUNET_free (tmp);
533 tmp = NULL;
534 dirname = NULL;
535 if (4 == sizeof(void *))
536 {
537 GNUNET_asprintf (&dirname,
540 pd->project_dirname);
541 GNUNET_asprintf (&tmp,
542 "%s%s",
543 execpath,
544 dirname);
545 }
546 if (8 == sizeof(void *))
547 {
548 GNUNET_asprintf (&dirname,
551 pd->project_dirname);
552 GNUNET_asprintf (&tmp,
553 "%s%s",
554 execpath,
555 dirname);
556 }
557
558 if ((NULL != tmp) &&
559 (GNUNET_YES ==
561 GNUNET_YES)))
562 {
563 GNUNET_free (execpath);
564 GNUNET_free (dirname);
565 return tmp;
566 }
567 GNUNET_free (tmp);
568 GNUNET_free (dirname);
569 }
570 GNUNET_asprintf (&dirname,
572 pd->project_dirname);
573 break;
574
576 GNUNET_asprintf (&dirname,
579 pd->project_dirname);
580 break;
581
584 "locale" DIR_SEPARATOR_STR);
585 break;
586
589 "icons" DIR_SEPARATOR_STR);
590 break;
591
593 GNUNET_asprintf (&dirname,
597 pd->project_dirname);
598 break;
599
601 if (isbasedir)
602 {
603 GNUNET_asprintf (&dirname,
605 "libexec" DIR_SEPARATOR_STR,
606 pd->project_dirname);
607 GNUNET_asprintf (&tmp,
608 "%s%s%s%s",
609 execpath,
611 (NULL != multiarch) ? multiarch : "",
612 dirname);
613 GNUNET_free (dirname);
614 if (GNUNET_YES ==
616 true))
617 {
618 GNUNET_free (execpath);
619 return tmp;
620 }
621 GNUNET_free (tmp);
622 tmp = NULL;
623 dirname = NULL;
624 if (4 == sizeof(void *))
625 {
626 GNUNET_asprintf (&dirname,
629 "libexec" DIR_SEPARATOR_STR,
630 pd->project_dirname);
631 GNUNET_asprintf (&tmp,
632 "%s%s",
633 execpath,
634 dirname);
635 }
636 if (8 == sizeof(void *))
637 {
638 GNUNET_asprintf (&dirname,
641 "libexec" DIR_SEPARATOR_STR,
642 pd->project_dirname);
643 GNUNET_asprintf (&tmp,
644 "%s%s",
645 execpath,
646 dirname);
647 }
648 if ((NULL != tmp) &&
649 (GNUNET_YES ==
651 true)))
652 {
653 GNUNET_free (execpath);
654 GNUNET_free (dirname);
655 return tmp;
656 }
657 GNUNET_free (tmp);
658 GNUNET_free (dirname);
659 }
660 GNUNET_asprintf (&dirname,
662 "libexec" DIR_SEPARATOR_STR,
663 pd->project_dirname);
664 break;
665
666 default:
667 GNUNET_free (execpath);
668 return NULL;
669 }
670 GNUNET_asprintf (&tmp,
671 "%s%s",
672 execpath,
673 dirname);
674 GNUNET_free (dirname);
675 GNUNET_free (execpath);
676 return tmp;
677}
678
679
680char *
682 const char *progname)
683{
684 static char *cache;
685 char *libexecdir;
686 char *binary;
687
688 if ((DIR_SEPARATOR == progname[0]) ||
689 (GNUNET_YES ==
691 GNUNET_NO,
692 NULL,
693 NULL)))
694 return GNUNET_strdup (progname);
695 if (NULL != cache)
696 libexecdir = cache;
697 else
698 libexecdir = GNUNET_OS_installation_get_path (pd,
700 if (NULL == libexecdir)
701 return GNUNET_strdup (progname);
702 GNUNET_asprintf (&binary,
703 "%s%s",
704 libexecdir,
705 progname);
706 cache = libexecdir;
707 return binary;
708}
709
710
711char *
713 const struct GNUNET_CONFIGURATION_Handle *cfg,
714 const char *progname)
715{
716 static char *cache;
717 char *binary = NULL;
718 char *path = NULL;
719 size_t path_len;
720
721 if (GNUNET_YES ==
723 GNUNET_NO,
724 NULL,
725 NULL))
726 {
727 return GNUNET_strdup (progname);
728 }
729 if (NULL != cache)
730 path = cache;
731 else
733 "PATHS",
734 "SUID_BINARY_PATH",
735 &path);
736 if ( (NULL == path) ||
737 (0 == strlen (path)) )
738 {
739 if (NULL != path)
740 GNUNET_free (path);
741 cache = NULL;
743 progname);
744 }
745 path_len = strlen (path);
746 GNUNET_asprintf (&binary,
747 "%s%s%s",
748 path,
749 (path[path_len - 1] == DIR_SEPARATOR) ? ""
751 progname);
752 cache = path;
753 return binary;
754}
755
756
759 bool check_suid,
760 const char *params)
761{
762 struct stat statbuf;
763 char *p;
764 char *pf;
765
766 if ( (GNUNET_YES ==
768 GNUNET_NO,
769 NULL,
770 NULL)) ||
771 (0 == strncmp (binary, "./", 2)) )
772 {
773 p = GNUNET_strdup (binary);
774 }
775 else
776 {
777 p = get_path_from_PATH (binary);
778 if (NULL != p)
779 {
780 GNUNET_asprintf (&pf,
781 "%s/%s",
782 p,
783 binary);
784 GNUNET_free (p);
785 p = pf;
786 }
787 }
788
789 if (NULL == p)
790 {
792 _ ("Could not find binary `%s' in PATH!\n"),
793 binary);
794 return GNUNET_SYSERR;
795 }
796 if (0 != access (p,
797 X_OK))
798 {
800 "access",
801 p);
802 GNUNET_free (p);
803 return GNUNET_SYSERR;
804 }
805
806 if (0 == getuid ())
807 {
808 /* as we run as root, we don't insist on SUID */
809 GNUNET_free (p);
810 return GNUNET_YES;
811 }
812
813 if (0 != stat (p,
814 &statbuf))
815 {
817 "stat",
818 p);
819 GNUNET_free (p);
820 return GNUNET_SYSERR;
821 }
822 if (check_suid)
823 {
824 (void) params;
825 if ( (0 != (statbuf.st_mode & S_ISUID)) &&
826 (0 == statbuf.st_uid) )
827 {
828 GNUNET_free (p);
829 return GNUNET_YES;
830 }
832 _ ("Binary `%s' exists, but is not SUID\n"),
833 p);
834 /* binary exists, but not SUID */
835 }
836 GNUNET_free (p);
837 return GNUNET_NO;
838}
839
840
841/* end of os_installation.c */
char * getenv()
#define bindtextdomain(Domainname, Dirname)
Definition: gettext.h:62
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:88
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static char * line
Desired phone line (string to be converted to a hash).
static const struct GNUNET_CRYPTO_PrivateKey zero
Public key of all zeros.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
#define GNUNET_AGPL_URL
NOTE: You MUST adjust this URL to point to the location of a publicly accessible repository (or TGZ) ...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:520
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:441
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
char * GNUNET_OS_installation_get_path(const struct GNUNET_OS_ProjectData *pd, enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX,...
void GNUNET_OS_init(const char *package_name, const struct GNUNET_OS_ProjectData *pd)
Setup OS subsystem for the given project data and package.
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_OS_ProjectData *pd, const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
GNUNET_OS_InstallationPathKind
Possible installation paths to request.
char * GNUNET_OS_get_libexec_binary_path(const struct GNUNET_OS_ProjectData *pd, const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
@ GNUNET_OS_IPK_SELF_PREFIX
Return the installation directory of this application, not the one of the overall GNUnet installation...
@ GNUNET_OS_IPK_ICONDIR
Return the prefix of the path with application icons (share/icons/).
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
@ GNUNET_OS_IPK_DOCDIR
Return the prefix of the path with documentation files, including the license (share/doc/gnunet/).
@ GNUNET_OS_IPK_LOCALEDIR
Return the directory where translations are installed (share/locale/)
@ GNUNET_OS_IPK_LIBDIR
Return the directory where libraries are installed.
@ GNUNET_OS_IPK_PREFIX
Return the "PREFIX" directory given to configure.
@ GNUNET_OS_IPK_BINDIR
Return the directory where the program binaries are installed.
@ GNUNET_OS_IPK_LIBEXECDIR
Return the directory where helper binaries are installed (lib/gnunet/libexec/)
enum GNUNET_GenericReturnValue GNUNET_STRINGS_path_is_absolute(const char *filename, int can_be_uri, int *r_is_uri, char **r_uri_scheme)
Check whether filename is absolute or not, and if it's an URI.
Definition: strings.c:981
static char * os_get_exec_path(const struct GNUNET_OS_ProjectData *pd)
get the path to current app's bin/
#define LOG_STRERROR_FILE(kind, syscall, filename)
static const struct GNUNET_OS_ProjectData default_pd
Default project data used for installation path detection for GNUnet (core).
static char * get_path_from_GNUNET_PREFIX(const struct GNUNET_OS_ProjectData *pd)
Try to obtain the installation path using the "GNUNET_PREFIX" environment variable.
static char * os_get_gnunet_path(const struct GNUNET_OS_ProjectData *pd)
get the path to GNUnet bin/ or lib/, preferring the lib/ path
static char * get_path_from_PATH(const char *binary)
Return the actual path to a file found in the current PATH environment variable.
#define LOG(kind,...)
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define DIR_SEPARATOR
Definition: platform.h:166
#define DIR_SEPARATOR_STR
Definition: platform.h:167
#define PATH_SEPARATOR
Definition: platform.h:168
#define _(String)
GNU gettext support macro.
Definition: platform.h:179
Project-specific data used to help the OS subsystem find installation paths.
const char * binary_name
Name of a project-specific binary that should be in "$PREFIX/bin/".
const char * env_varname
Name of an environment variable that can be used to override installation path detection,...
const char * env_varname_alt
Alternative name of an environment variable that can be used to override installation path detection,...
const char * libname
Name of a library that is installed in the "lib/" directory of the project, such as "libgnunetutil".
const char * project_dirname
Name of the project that is used in the "libexec" prefix, For example, "gnunet".