GNUnet  0.19.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 
60 static 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 
82 
88 static const struct GNUNET_OS_ProjectData *gettextinit;
89 
90 
94 const struct GNUNET_OS_ProjectData *
96 {
97  return &default_pd;
98 }
99 
100 
104 const struct GNUNET_OS_ProjectData *
106 {
107  if (current_pd != gettextinit)
108  {
110 
111  if (NULL != path)
112  bindtextdomain (PACKAGE,
113  path);
114  GNUNET_free (path);
116  }
117  return current_pd;
118 }
119 
120 
121 void
123 {
124  GNUNET_assert (NULL != pd);
125  current_pd = pd;
126  if (pd != gettextinit)
127  {
129 
130  if (NULL != path)
131  bindtextdomain (PACKAGE,
132  path);
133  GNUNET_free (path);
134  gettextinit = pd;
135  }
136 }
137 
138 
139 #ifdef __linux__
145 static char *
146 get_path_from_proc_maps (void)
147 {
148  char fn[64];
149  char line[1024];
150  char dir[1024];
151  FILE *f;
152  char *lgu;
153 
154  if (NULL == current_pd->libname)
155  return NULL;
156  GNUNET_snprintf (fn,
157  sizeof(fn),
158  "/proc/%u/maps",
159  getpid ());
160  if (NULL == (f = fopen (fn, "r")))
161  return NULL;
162  while (NULL != fgets (line, sizeof(line), f))
163  {
164  if ((1 == sscanf (line,
165  "%*p-%*p %*c%*c%*c%*c %*x %*x:%*x %*u%*[ ]%1023s",
166  dir)) &&
167  (NULL != (lgu = strstr (dir,
168  current_pd->libname))))
169  {
170  lgu[0] = '\0';
171  fclose (f);
172  return GNUNET_strdup (dir);
173  }
174  }
175  fclose (f);
176  return NULL;
177 }
178 
179 
185 static char *
186 get_path_from_proc_exe (void)
187 {
188  char fn[64];
189  char lnk[1024];
190  ssize_t size;
191  char *lep;
192 
193  GNUNET_snprintf (fn, sizeof(fn), "/proc/%u/exe", getpid ());
194  size = readlink (fn, lnk, sizeof(lnk) - 1);
195  if (size <= 0)
196  {
197  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "readlink", fn);
198  return NULL;
199  }
200  GNUNET_assert (((size_t) size) < sizeof(lnk));
201  lnk[size] = '\0';
202  while ((lnk[size] != '/') && (size > 0))
203  size--;
204  GNUNET_asprintf (&lep, "/%s/libexec/", current_pd->project_dirname);
205  /* test for being in lib/gnunet/libexec/ or lib/MULTIARCH/gnunet/libexec */
206  if ((((size_t) size) > strlen (lep)) &&
207  (0 == strcmp (lep, &lnk[size - strlen (lep)])))
208  size -= strlen (lep) - 1;
209  GNUNET_free (lep);
210  if ((size < 4) || (lnk[size - 4] != '/'))
211  {
212  /* not installed in "/bin/" -- binary path probably useless */
213  return NULL;
214  }
215  lnk[size] = '\0';
216  return GNUNET_strdup (lnk);
217 }
218 
219 
220 #endif
221 
222 
223 #if DARWIN
231 typedef int (*MyNSGetExecutablePathProto) (char *buf, size_t *bufsize);
232 
233 
239 static char *
240 get_path_from_NSGetExecutablePath (void)
241 {
242  static char zero = '\0';
243  char *path;
244  size_t len;
245  MyNSGetExecutablePathProto func;
246 
247  path = NULL;
248  if (NULL ==
249  (func = (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT,
250  "_NSGetExecutablePath")))
251  return NULL;
252  path = &zero;
253  len = 0;
254  /* get the path len, including the trailing \0 */
255  (void) func (path, &len);
256  if (0 == len)
257  return NULL;
258  path = GNUNET_malloc (len);
259  if (0 != func (path, &len))
260  {
261  GNUNET_free (path);
262  return NULL;
263  }
264  len = strlen (path);
265  while ((path[len] != '/') && (len > 0))
266  len--;
267  path[len] = '\0';
268  return path;
269 }
270 
271 
277 static char *
278 get_path_from_dyld_image (void)
279 {
280  const char *path;
281  char *p;
282  char *s;
283  unsigned int i;
284  int c;
285 
286  c = _dyld_image_count ();
287  for (i = 0; i < c; i++)
288  {
289  if (((const void *) _dyld_get_image_header (i)) !=
290  ((const void *) &_mh_dylib_header))
291  continue;
292  path = _dyld_get_image_name (i);
293  if ((NULL == path) || (0 == strlen (path)))
294  continue;
295  p = GNUNET_strdup (path);
296  s = p + strlen (p);
297  while ((s > p) && ('/' != *s))
298  s--;
299  s++;
300  *s = '\0';
301  return p;
302  }
303  return NULL;
304 }
305 
306 
307 #endif
308 
309 
317 static char *
318 get_path_from_PATH (const char *binary)
319 {
320  char *path;
321  char *pos;
322  char *end;
323  char *buf;
324  const char *p;
325 
326  if (NULL == (p = getenv ("PATH")))
327  return NULL;
328 
329  path = GNUNET_strdup (p); /* because we write on it */
330 
331  buf = GNUNET_malloc (strlen (path) + strlen (binary) + 1 + 1);
332  pos = path;
333  while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
334  {
335  *end = '\0';
336  sprintf (buf, "%s/%s", pos, binary);
338  {
339  pos = GNUNET_strdup (pos);
340  GNUNET_free (buf);
341  GNUNET_free (path);
342  return pos;
343  }
344  pos = end + 1;
345  }
346  sprintf (buf, "%s/%s", pos, binary);
348  {
349  pos = GNUNET_strdup (pos);
350  GNUNET_free (buf);
351  GNUNET_free (path);
352  return pos;
353  }
354  GNUNET_free (buf);
355  GNUNET_free (path);
356  return NULL;
357 }
358 
359 
366 static char *
368 {
369  const char *p;
370 
371  if ((NULL != current_pd->env_varname) &&
372  (NULL != (p = getenv (current_pd->env_varname))))
373  return GNUNET_strdup (p);
374  if ((NULL != current_pd->env_varname_alt) &&
375  (NULL != (p = getenv (current_pd->env_varname_alt))))
376  return GNUNET_strdup (p);
377  return NULL;
378 }
379 
380 
387 static char *
389 {
390  char *ret;
391 
392  if (NULL != (ret = get_path_from_GNUNET_PREFIX ()))
393  return ret;
394 #ifdef __linux__
395  if (NULL != (ret = get_path_from_proc_maps ()))
396  return ret;
397  /* try path *first*, before /proc/exe, as /proc/exe can be wrong */
398  if ((NULL != current_pd->binary_name) &&
399  (NULL != (ret = get_path_from_PATH (current_pd->binary_name))))
400  return ret;
401  if (NULL != (ret = get_path_from_proc_exe ()))
402  return ret;
403 #endif
404 #if DARWIN
405  if (NULL != (ret = get_path_from_dyld_image ()))
406  return ret;
407  if (NULL != (ret = get_path_from_NSGetExecutablePath ()))
408  return ret;
409 #endif
410  if ((NULL != current_pd->binary_name) &&
411  (NULL != (ret = get_path_from_PATH (current_pd->binary_name))))
412  return ret;
413  /* other attempts here */
415  _ (
416  "Could not determine installation path for %s. Set `%s' environment variable.\n"),
419  return NULL;
420 }
421 
422 
427 static char *
429 {
430  char *ret = NULL;
431 
432 #ifdef __linux__
433  if (NULL != (ret = get_path_from_proc_exe ()))
434  return ret;
435 #endif
436 #if DARWIN
437  if (NULL != (ret = get_path_from_NSGetExecutablePath ()))
438  return ret;
439 #endif
440  /* other attempts here */
441  return ret;
442 }
443 
444 
450 char *
452 {
453  size_t n;
454  char *dirname;
455  char *execpath = NULL;
456  char *tmp;
457  char *multiarch;
458  char *libdir;
459  int isbasedir;
460 
461  /* if wanted, try to get the current app's bin/ */
462  if (dirkind == GNUNET_OS_IPK_SELF_PREFIX)
463  execpath = os_get_exec_path ();
464 
465  /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some
466  * guess for the current app */
467  if (NULL == execpath)
468  execpath = os_get_gnunet_path ();
469  if (NULL == execpath)
470  return NULL;
471 
472  n = strlen (execpath);
473  if (0 == n)
474  {
475  /* should never happen, but better safe than sorry */
476  GNUNET_free (execpath);
477  return NULL;
478  }
479  /* remove filename itself */
480  while ((n > 1) && (DIR_SEPARATOR == execpath[n - 1]))
481  execpath[--n] = '\0';
482 
483  isbasedir = 1;
484  if ((n > 6) && ((0 == strcasecmp (&execpath[n - 6], "/lib32")) ||
485  (0 == strcasecmp (&execpath[n - 6], "/lib64"))))
486  {
487  if ((GNUNET_OS_IPK_LIBDIR != dirkind) &&
488  (GNUNET_OS_IPK_LIBEXECDIR != dirkind))
489  {
490  /* strip '/lib32' or '/lib64' */
491  execpath[n - 6] = '\0';
492  n -= 6;
493  }
494  else
495  isbasedir = 0;
496  }
497  else if ((n > 4) && ((0 == strcasecmp (&execpath[n - 4], "/bin")) ||
498  (0 == strcasecmp (&execpath[n - 4], "/lib"))))
499  {
500  /* strip '/bin' or '/lib' */
501  execpath[n - 4] = '\0';
502  n -= 4;
503  }
504  multiarch = NULL;
505  if (NULL != (libdir = strstr (execpath, "/lib/")))
506  {
507  /* test for multi-arch path of the form "PREFIX/lib/MULTIARCH/";
508  here we need to re-add 'multiarch' to lib and libexec paths later! */
509  multiarch = &libdir[5];
510  if (NULL == strchr (multiarch, '/'))
511  libdir[0] =
512  '\0'; /* Debian multiarch format, cut of from 'execpath' but preserve in multicarch */
513  else
514  multiarch =
515  NULL; /* maybe not, multiarch still has a '/', which is not OK */
516  }
517  /* in case this was a directory named foo-bin, remove "foo-" */
518  while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR))
519  execpath[--n] = '\0';
520  switch (dirkind)
521  {
524  dirname = GNUNET_strdup (DIR_SEPARATOR_STR);
525  break;
526 
529  break;
530 
532  if (isbasedir)
533  {
534  GNUNET_asprintf (&tmp,
535  "%s%s%s%s%s%s%s",
536  execpath,
537  DIR_SEPARATOR_STR "lib",
538  (NULL != multiarch) ? DIR_SEPARATOR_STR : "",
539  (NULL != multiarch) ? multiarch : "",
544  {
545  GNUNET_free (execpath);
546  return tmp;
547  }
548  GNUNET_free (tmp);
549  tmp = NULL;
550  dirname = NULL;
551  if (4 == sizeof(void *))
552  {
553  GNUNET_asprintf (&dirname,
555  "%s" DIR_SEPARATOR_STR,
557  GNUNET_asprintf (&tmp, "%s%s", execpath, dirname);
558  }
559  if (8 == sizeof(void *))
560  {
561  GNUNET_asprintf (&dirname,
563  "%s" DIR_SEPARATOR_STR,
565  GNUNET_asprintf (&tmp, "%s%s", execpath, dirname);
566  }
567 
568  if ((NULL != tmp) &&
570  {
571  GNUNET_free (execpath);
572  GNUNET_free (dirname);
573  return tmp;
574  }
575  GNUNET_free (tmp);
576  GNUNET_free (dirname);
577  }
578  GNUNET_asprintf (&dirname,
581  break;
582 
584  GNUNET_asprintf (&dirname,
586  "%s" DIR_SEPARATOR_STR,
588  break;
589 
592  "locale" DIR_SEPARATOR_STR);
593  break;
594 
597  "icons" DIR_SEPARATOR_STR);
598  break;
599 
601  GNUNET_asprintf (&dirname,
603  "doc" DIR_SEPARATOR_STR
604  "%s" DIR_SEPARATOR_STR,
606  break;
607 
609  if (isbasedir)
610  {
611  GNUNET_asprintf (&dirname,
613  "libexec" DIR_SEPARATOR_STR,
615  GNUNET_asprintf (&tmp,
616  "%s%s%s%s",
617  execpath,
619  (NULL != multiarch) ? multiarch : "",
620  dirname);
621  GNUNET_free (dirname);
623  {
624  GNUNET_free (execpath);
625  return tmp;
626  }
627  GNUNET_free (tmp);
628  tmp = NULL;
629  dirname = NULL;
630  if (4 == sizeof(void *))
631  {
632  GNUNET_asprintf (&dirname,
634  "%s" DIR_SEPARATOR_STR
635  "libexec" DIR_SEPARATOR_STR,
637  GNUNET_asprintf (&tmp, "%s%s", execpath, dirname);
638  }
639  if (8 == sizeof(void *))
640  {
641  GNUNET_asprintf (&dirname,
643  "%s" DIR_SEPARATOR_STR
644  "libexec" DIR_SEPARATOR_STR,
646  GNUNET_asprintf (&tmp, "%s%s", execpath, dirname);
647  }
648  if ((NULL != tmp) &&
650  {
651  GNUNET_free (execpath);
652  GNUNET_free (dirname);
653  return tmp;
654  }
655  GNUNET_free (tmp);
656  GNUNET_free (dirname);
657  }
658  GNUNET_asprintf (&dirname,
660  "libexec" DIR_SEPARATOR_STR,
662  break;
663 
664  default:
665  GNUNET_free (execpath);
666  return NULL;
667  }
668  GNUNET_asprintf (&tmp, "%s%s", execpath, dirname);
669  GNUNET_free (dirname);
670  GNUNET_free (execpath);
671  return tmp;
672 }
673 
674 
683 char *
684 GNUNET_OS_get_libexec_binary_path (const char *progname)
685 {
686  static char *cache;
687  char *libexecdir;
688  char *binary;
689 
690  if ((DIR_SEPARATOR == progname[0]) ||
691  (GNUNET_YES ==
692  GNUNET_STRINGS_path_is_absolute (progname, GNUNET_NO, NULL, NULL)))
693  return GNUNET_strdup (progname);
694  if (NULL != cache)
695  libexecdir = cache;
696  else
698  if (NULL == libexecdir)
699  return GNUNET_strdup (progname);
700  GNUNET_asprintf (&binary, "%s%s", libexecdir, progname);
701  cache = libexecdir;
702  return binary;
703 }
704 
705 
718 char *
720  const char *progname)
721 {
722  static char *cache;
723  char *binary = NULL;
724  char *path = NULL;
725  size_t path_len;
726 
727  if (GNUNET_YES ==
728  GNUNET_STRINGS_path_is_absolute (progname, GNUNET_NO, NULL, NULL))
729  {
730  return GNUNET_strdup (progname);
731  }
732  if (NULL != cache)
733  path = cache;
734  else
736  "PATHS",
737  "SUID_BINARY_PATH",
738  &path);
739  if ((NULL == path) || (0 == strlen (path)))
740  {
741  if (NULL != path)
742  GNUNET_free (path);
743  cache = NULL;
744  return GNUNET_OS_get_libexec_binary_path (progname);
745  }
746  path_len = strlen (path);
747  GNUNET_asprintf (&binary,
748  "%s%s%s",
749  path,
750  (path[path_len - 1] == DIR_SEPARATOR) ? ""
752  progname);
753  cache = path;
754  return binary;
755 }
756 
757 
759 GNUNET_OS_check_helper_binary (const char *binary,
760  bool check_suid,
761  const char *params)
762 {
763  struct stat statbuf;
764  char *p;
765  char *pf;
766 
767  if ((GNUNET_YES ==
768  GNUNET_STRINGS_path_is_absolute (binary, GNUNET_NO, NULL, NULL)) ||
769  (0 == strncmp (binary, "./", 2)))
770  {
771  p = GNUNET_strdup (binary);
772  }
773  else
774  {
775  p = get_path_from_PATH (binary);
776  if (NULL != p)
777  {
778  GNUNET_asprintf (&pf, "%s/%s", p, binary);
779  GNUNET_free (p);
780  p = pf;
781  }
782  }
783 
784  if (NULL == p)
785  {
787  _ ("Could not find binary `%s' in PATH!\n"),
788  binary);
789  return GNUNET_SYSERR;
790  }
791  if (0 != access (p, X_OK))
792  {
794  GNUNET_free (p);
795  return GNUNET_SYSERR;
796  }
797 
798  if (0 == getuid ())
799  {
800  /* as we run as root, we don't insist on SUID */
801  GNUNET_free (p);
802  return GNUNET_YES;
803  }
804 
805  if (0 != stat (p, &statbuf))
806  {
808  GNUNET_free (p);
809  return GNUNET_SYSERR;
810  }
811  if (check_suid)
812  {
813  (void) params;
814  if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid))
815  {
816  GNUNET_free (p);
817  return GNUNET_YES;
818  }
820  _ ("Binary `%s' exists, but is not SUID\n"),
821  p);
822  /* binary exists, but not SUID */
823  }
824  GNUNET_free (p);
825  return GNUNET_NO;
826 }
827 
828 
829 /* end of os_installation.c */
char * getenv()
#define bindtextdomain(Domainname, Dirname)
Definition: gettext.h:58
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:89
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static char * line
Desired phone line (string to be converted to a hash).
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.
static struct GNUNET_CONTAINER_MultiHashMap32 * cache
Hashmap to maintain cache.
static char buf[2048]
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:481
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:403
#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.
char * GNUNET_OS_get_suid_binary_path(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 ...
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_default(void)
Return default project data used by 'libgnunetutil' for GNUnet.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get()
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_installation_get_path(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 struct GNUNET_OS_ProjectData *pd)
Setup OS subsystem with project data.
GNUNET_OS_InstallationPathKind
Possible installation paths to request.
@ 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:958
static char * get_path_from_PATH(const char *binary)
Return the actual path to a file found in the current PATH environment variable.
static char * os_get_gnunet_path(void)
get the path to GNUnet bin/ or lib/, preferring the lib/ path
static const struct GNUNET_OS_ProjectData * gettextinit
PD for which gettext has been initialized last.
static char * os_get_exec_path()
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(void)
Try to obtain the installation path using the "GNUNET_PREFIX" environment variable.
static const struct GNUNET_OS_ProjectData * current_pd
Which project data do we currently use for installation path detection? Never NULL.
#define LOG(kind,...)
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define DIR_SEPARATOR
Definition: platform.h:164
#define DIR_SEPARATOR_STR
Definition: platform.h:165
#define PATH_SEPARATOR
Definition: platform.h:166
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
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".