GNUnet 0.26.2-121-g5a30f508f
 
Loading...
Searching...
No Matches
os_installation.c File Reference
#include "platform.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <unistr.h>
#include "gnunet_util_lib.h"
Include dependency graph for os_installation.c:

Go to the source code of this file.

Macros

#define LOG(kind, ...)    GNUNET_log_from (kind, "util-os-installation", __VA_ARGS__)
 
#define LOG_STRERROR_FILE(kind, syscall, filename)
 

Functions

const struct GNUNET_OS_ProjectDataGNUNET_OS_project_data_gnunet (void)
 Return default project data used by 'libgnunetutil' for GNUnet.
 
void GNUNET_OS_init (const char *package_name, const struct GNUNET_OS_ProjectData *pd)
 Setup OS subsystem for the given project data and package.
 
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 * 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 * os_get_exec_path (const struct GNUNET_OS_ProjectData *pd)
 get the path to current app's bin/
 
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, the current running apps installation directory.
 
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 libexec/-directory to get the full path.
 
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 SUID_BINARY_PATH in the PATHS section of the configuration.
 
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.
 

Variables

static const struct GNUNET_OS_ProjectData default_pd
 Default project data used for installation path detection for GNUnet (core).
 

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)     GNUNET_log_from (kind, "util-os-installation", __VA_ARGS__)

Definition at line 46 of file os_installation.c.

59 {
60 .libname = "libgnunetutil",
61 .project_dirname = "gnunet",
62 .binary_name = "gnunet-arm",
63 .version = PACKAGE_VERSION,
64 .env_varname = "GNUNET_PREFIX",
65 .base_config_varname = "GNUNET_BASE_CONFIG",
66 .bug_email = "gnunet-developers@gnu.org",
67 .homepage = "http://www.gnu.org/s/gnunet/",
68 .config_file = "gnunet.conf",
69 .user_config_file = "~/.config/gnunet.conf",
70 .is_gnu = 1,
71 .gettext_domain = "gnunet",
72 .gettext_path = NULL,
73 .agpl_url = GNUNET_AGPL_URL,
74};
75
76
80const struct GNUNET_OS_ProjectData *
82{
83 return &default_pd;
84}
85
86
87void
88GNUNET_OS_init (const char *package_name,
89 const struct GNUNET_OS_ProjectData *pd)
90{
91 char *path;
92
95 if (NULL != path)
96 bindtextdomain (package_name,
97 path);
98 GNUNET_free (path);
99}
100
101
102#ifdef __linux__
109static char *
110get_path_from_proc_maps (const struct GNUNET_OS_ProjectData *pd)
111{
112 char fn[64];
113 char line[1024];
114 char dir[1024];
115 FILE *f;
116 char *lgu;
117
118 if (NULL == pd->libname)
119 return NULL;
120 GNUNET_snprintf (fn,
121 sizeof(fn),
122 "/proc/%u/maps",
123 getpid ());
124 if (NULL == (f = fopen (fn, "r")))
125 return NULL;
126 while (NULL != fgets (line, sizeof(line), f))
127 {
128 if ((1 == sscanf (line,
129 "%*p-%*p %*c%*c%*c%*c %*x %*x:%*x %*u%*[ ]%1023s",
130 dir)) &&
131 (NULL != (lgu = strstr (dir,
132 pd->libname))))
133 {
134 lgu[0] = '\0';
135 fclose (f);
136 return GNUNET_strdup (dir);
137 }
138 }
139 fclose (f);
140 return NULL;
141}
142
143
150static char *
151get_path_from_proc_exe (const struct GNUNET_OS_ProjectData *pd)
152{
153 char fn[64];
154 char lnk[1024];
155 ssize_t size;
156 char *lep;
157
158 GNUNET_snprintf (fn,
159 sizeof(fn),
160 "/proc/%u/exe",
161 getpid ());
162 size = readlink (fn,
163 lnk,
164 sizeof(lnk) - 1);
165 if (size <= 0)
166 {
168 "readlink",
169 fn);
170 return NULL;
171 }
172 GNUNET_assert (((size_t) size) < sizeof(lnk));
173 lnk[size] = '\0';
174 while ((lnk[size] != '/') && (size > 0))
175 size--;
176 GNUNET_asprintf (&lep,
177 "/%s/libexec/",
178 pd->project_dirname);
179 /* test for being in lib/gnunet/libexec/ or lib/MULTIARCH/gnunet/libexec */
180 if ((((size_t) size) > strlen (lep)) &&
181 (0 == strcmp (lep,
182 &lnk[size - strlen (lep)])))
183 size -= strlen (lep) - 1;
184 GNUNET_free (lep);
185 if ((size < 4) || (lnk[size - 4] != '/'))
186 {
187 /* not installed in "/bin/" -- binary path probably useless */
188 return NULL;
189 }
190 lnk[size] = '\0';
191 return GNUNET_strdup (lnk);
192}
193
194
195#endif
196
197
198#if DARWIN
206typedef int (*MyNSGetExecutablePathProto) (char *buf,
207 size_t *bufsize);
208
209
215static char *
216get_path_from_NSGetExecutablePath (void)
217{
218 static char zero = '\0';
219 char *path;
220 size_t len;
221 MyNSGetExecutablePathProto func;
222
223 path = NULL;
224 if (NULL ==
225 (func = (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT,
226 "_NSGetExecutablePath")))
227 return NULL;
228 path = &zero;
229 len = 0;
230 /* get the path len, including the trailing \0 */
231 (void) func (path, &len);
232 if (0 == len)
233 return NULL;
234 path = GNUNET_malloc (len);
235 if (0 != func (path, &len))
236 {
237 GNUNET_free (path);
238 return NULL;
239 }
240 len = strlen (path);
241 while ((path[len] != '/') && (len > 0))
242 len--;
243 path[len] = '\0';
244 return path;
245}
246
247
253static char *
254get_path_from_dyld_image (void)
255{
256 const char *path;
257 char *p;
258 char *s;
259 unsigned int i;
260 int c;
261
262 c = _dyld_image_count ();
263 for (i = 0; i < c; i++)
264 {
265 if (((const void *) _dyld_get_image_header (i)) !=
266 ((const void *) &_mh_dylib_header))
267 continue;
268 path = _dyld_get_image_name (i);
269 if ((NULL == path) || (0 == strlen (path)))
270 continue;
271 p = GNUNET_strdup (path);
272 s = p + strlen (p);
273 while ((s > p) && ('/' != *s))
274 s--;
275 s++;
276 *s = '\0';
277 return p;
278 }
279 return NULL;
280}
281
282
283#endif
284
285
293static char *
294get_path_from_PATH (const char *binary)
295{
296 char *path;
297 char *pos;
298 char *end;
299 char *buf;
300 const char *p;
301
302 if (NULL == (p = getenv ("PATH")))
303 return NULL;
304
305 path = GNUNET_strdup (p); /* because we write on it */
306 buf = GNUNET_malloc (strlen (path) + strlen (binary) + 1 + 1);
307 pos = path;
308 while (NULL != (end = strchr (pos,
310 {
311 *end = '\0';
312 sprintf (buf,
313 "%s/%s",
314 pos,
315 binary);
316 if (GNUNET_YES ==
318 {
319 pos = GNUNET_strdup (pos);
320 GNUNET_free (buf);
321 GNUNET_free (path);
322 return pos;
323 }
324 pos = end + 1;
325 }
326 sprintf (buf,
327 "%s/%s",
328 pos,
329 binary);
330 if (GNUNET_YES ==
332 {
333 pos = GNUNET_strdup (pos);
334 GNUNET_free (buf);
335 GNUNET_free (path);
336 return pos;
337 }
338 GNUNET_free (buf);
339 GNUNET_free (path);
340 return NULL;
341}
342
343
351static char *
353{
354 const char *p;
355
356 if ((NULL != pd->env_varname) &&
357 (NULL != (p = getenv (pd->env_varname))))
358 return GNUNET_strdup (p);
359 if ((NULL != pd->env_varname_alt) &&
360 (NULL != (p = getenv (pd->env_varname_alt))))
361 return GNUNET_strdup (p);
362 return NULL;
363}
364
365
373static char *
375{
376 char *ret;
377
378 if (NULL != (ret = get_path_from_GNUNET_PREFIX (pd)))
379 return ret;
380#ifdef __linux__
381 if (NULL != (ret = get_path_from_proc_maps (pd)))
382 return ret;
383 /* try path *first*, before /proc/exe, as /proc/exe can be wrong */
384 if ((NULL != pd->binary_name) &&
385 (NULL != (ret = get_path_from_PATH (pd->binary_name))))
386 return ret;
387 if (NULL != (ret = get_path_from_proc_exe (pd)))
388 return ret;
389#endif
390#if DARWIN
391 if (NULL != (ret = get_path_from_dyld_image ()))
392 return ret;
393 if (NULL != (ret = get_path_from_NSGetExecutablePath ()))
394 return ret;
395#endif
396 if ((NULL != pd->binary_name) &&
397 (NULL != (ret = get_path_from_PATH (pd->binary_name))))
398 return ret;
399 /* other attempts here */
401 "Could not determine installation path for %s. Set `%s' environment variable.\n",
402 pd->project_dirname,
403 pd->env_varname);
404 return NULL;
405}
406
407
414static char *
416{
417 char *ret = NULL;
418
419#ifdef __linux__
420 if (NULL != (ret = get_path_from_proc_exe (pd)))
421 return ret;
422#endif
423#if DARWIN
424 if (NULL != (ret = get_path_from_NSGetExecutablePath ()))
425 return ret;
426#endif
427 /* other attempts here */
428 return ret;
429}
430
431
432char *
435{
436 size_t n;
437 char *dirname;
438 char *execpath = NULL;
439 char *tmp;
440 char *multiarch;
441 char *libdir;
442 int isbasedir;
443
444 /* if wanted, try to get the current app's bin/ */
445 if (dirkind == GNUNET_OS_IPK_SELF_PREFIX)
446 execpath = os_get_exec_path (pd);
447
448 /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some
449 * guess for the current app */
450 if (NULL == execpath)
451 execpath = os_get_gnunet_path (pd);
452 if (NULL == execpath)
453 return NULL;
454
455 n = strlen (execpath);
456 if (0 == n)
457 {
458 /* should never happen, but better safe than sorry */
459 GNUNET_free (execpath);
460 return NULL;
461 }
462 /* remove filename itself */
463 while ((n > 1) && (DIR_SEPARATOR == execpath[n - 1]))
464 execpath[--n] = '\0';
465
466 isbasedir = 1;
467 if ((n > 6) && ((0 == strcasecmp (&execpath[n - 6], "/lib32")) ||
468 (0 == strcasecmp (&execpath[n - 6], "/lib64"))))
469 {
470 if ((GNUNET_OS_IPK_LIBDIR != dirkind) &&
471 (GNUNET_OS_IPK_LIBEXECDIR != dirkind))
472 {
473 /* strip '/lib32' or '/lib64' */
474 execpath[n - 6] = '\0';
475 n -= 6;
476 }
477 else
478 isbasedir = 0;
479 }
480 else if ((n > 4) && ((0 == strcasecmp (&execpath[n - 4], "/bin")) ||
481 (0 == strcasecmp (&execpath[n - 4], "/lib"))))
482 {
483 /* strip '/bin' or '/lib' */
484 execpath[n - 4] = '\0';
485 n -= 4;
486 }
487 multiarch = NULL;
488 if (NULL != (libdir = strstr (execpath, "/lib/")))
489 {
490 /* test for multi-arch path of the form "PREFIX/lib/MULTIARCH/";
491 here we need to re-add 'multiarch' to lib and libexec paths later! */
492 multiarch = &libdir[5];
493 if (NULL == strchr (multiarch, '/'))
494 libdir[0] =
495 '\0'; /* Debian multiarch format, cut of from 'execpath' but preserve in multicarch */
496 else
497 multiarch =
498 NULL; /* maybe not, multiarch still has a '/', which is not OK */
499 }
500 /* in case this was a directory named foo-bin, remove "foo-" */
501 while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR))
502 execpath[--n] = '\0';
503 switch (dirkind)
504 {
508 break;
509
512 break;
513
515 if (isbasedir)
516 {
517 GNUNET_asprintf (&tmp,
518 "%s%s%s%s%s%s%s",
519 execpath,
520 DIR_SEPARATOR_STR "lib",
521 (NULL != multiarch) ? DIR_SEPARATOR_STR : "",
522 (NULL != multiarch) ? multiarch : "",
524 pd->project_dirname,
527 {
528 GNUNET_free (execpath);
529 return tmp;
530 }
531 GNUNET_free (tmp);
532 GNUNET_asprintf (&tmp,
533 "%s%s%s%s%s",
534 execpath,
535 DIR_SEPARATOR_STR RELATIVE_LIBDIR,
537 pd->project_dirname,
540 {
541 GNUNET_free (execpath);
542 return tmp;
543 }
544 GNUNET_free (tmp);
545 dirname = NULL;
546 if (4 == sizeof(void *))
547 {
548 GNUNET_asprintf (&dirname,
551 pd->project_dirname);
552 GNUNET_asprintf (&tmp,
553 "%s%s",
554 execpath,
555 dirname);
556 }
557 if (8 == sizeof(void *))
558 {
559 GNUNET_asprintf (&dirname,
562 pd->project_dirname);
563 GNUNET_asprintf (&tmp,
564 "%s%s",
565 execpath,
566 dirname);
567 }
568
569 if ((NULL != tmp) &&
570 (GNUNET_YES ==
572 GNUNET_YES)))
573 {
574 GNUNET_free (execpath);
575 GNUNET_free (dirname);
576 return tmp;
577 }
578 GNUNET_free (tmp);
579 GNUNET_free (dirname);
580 }
581 GNUNET_asprintf (&dirname,
583 pd->project_dirname);
584 break;
585
587 GNUNET_asprintf (&dirname,
590 pd->project_dirname);
591 break;
592
595 "locale" DIR_SEPARATOR_STR);
596 break;
597
600 "icons" DIR_SEPARATOR_STR);
601 break;
602
604 GNUNET_asprintf (&dirname,
608 pd->project_dirname);
609 break;
610
612 if (isbasedir)
613 {
614 GNUNET_asprintf (&dirname,
616 "libexec" DIR_SEPARATOR_STR,
617 pd->project_dirname);
618 GNUNET_asprintf (&tmp,
619 "%s%s%s%s",
620 execpath,
622 (NULL != multiarch) ? multiarch : "",
623 dirname);
624 GNUNET_free (dirname);
625 if (GNUNET_YES ==
627 true))
628 {
629 GNUNET_free (execpath);
630 return tmp;
631 }
632 GNUNET_free (tmp);
633 tmp = NULL;
634 dirname = NULL;
635 if (4 == sizeof(void *))
636 {
637 GNUNET_asprintf (&dirname,
640 "libexec" DIR_SEPARATOR_STR,
641 pd->project_dirname);
642 GNUNET_asprintf (&tmp,
643 "%s%s",
644 execpath,
645 dirname);
646 }
647 if (8 == sizeof(void *))
648 {
649 GNUNET_asprintf (&dirname,
652 "libexec" DIR_SEPARATOR_STR,
653 pd->project_dirname);
654 GNUNET_asprintf (&tmp,
655 "%s%s",
656 execpath,
657 dirname);
658 }
659 if ((NULL != tmp) &&
660 (GNUNET_YES ==
662 true)))
663 {
664 GNUNET_free (execpath);
665 GNUNET_free (dirname);
666 return tmp;
667 }
668 GNUNET_free (tmp);
669 GNUNET_free (dirname);
670 }
671 GNUNET_asprintf (&dirname,
673 "libexec" DIR_SEPARATOR_STR,
674 pd->project_dirname);
675 break;
676
677 default:
678 GNUNET_free (execpath);
679 return NULL;
680 }
681 GNUNET_asprintf (&tmp,
682 "%s%s",
683 execpath,
684 dirname);
685 GNUNET_free (dirname);
686 GNUNET_free (execpath);
687 return tmp;
688}
689
690
691char *
693 const char *progname)
694{
695 static char *cache;
696 char *libexecdir;
697 char *binary;
698
699 if ((DIR_SEPARATOR == progname[0]) ||
700 (GNUNET_YES ==
702 GNUNET_NO,
703 NULL,
704 NULL)))
705 return GNUNET_strdup (progname);
706 if (NULL != cache)
707 libexecdir = cache;
708 else
709 libexecdir = GNUNET_OS_installation_get_path (pd,
711 if (NULL == libexecdir)
712 return GNUNET_strdup (progname);
713 GNUNET_asprintf (&binary,
714 "%s%s",
715 libexecdir,
716 progname);
717 cache = libexecdir;
718 return binary;
719}
720
721
722char *
724 const struct GNUNET_CONFIGURATION_Handle *cfg,
725 const char *progname)
726{
727 static char *cache;
728 char *binary = NULL;
729 char *path = NULL;
730 size_t path_len;
731
732 if (GNUNET_YES ==
734 GNUNET_NO,
735 NULL,
736 NULL))
737 {
738 return GNUNET_strdup (progname);
739 }
740 if (NULL != cache)
741 path = cache;
742 else
744 "PATHS",
745 "SUID_BINARY_PATH",
746 &path);
747 if ( (NULL == path) ||
748 (0 == strlen (path)) )
749 {
750 if (NULL != path)
751 GNUNET_free (path);
752 cache = NULL;
754 progname);
755 }
756 path_len = strlen (path);
757 GNUNET_asprintf (&binary,
758 "%s%s%s",
759 path,
760 (path[path_len - 1] == DIR_SEPARATOR) ? ""
762 progname);
763 cache = path;
764 return binary;
765}
766
767
769GNUNET_OS_check_helper_binary (const char *binary,
770 bool check_suid,
771 const char *params)
772{
773 struct stat statbuf;
774 char *p;
775 char *pf;
776
777 if ( (GNUNET_YES ==
779 GNUNET_NO,
780 NULL,
781 NULL)) ||
782 (0 == strncmp (binary, "./", 2)) )
783 {
784 p = GNUNET_strdup (binary);
785 }
786 else
787 {
788 p = get_path_from_PATH (binary);
789 if (NULL != p)
790 {
791 GNUNET_asprintf (&pf,
792 "%s/%s",
793 p,
794 binary);
795 GNUNET_free (p);
796 p = pf;
797 }
798 }
799
800 if (NULL == p)
801 {
803 _ ("Could not find binary `%s' in PATH!\n"),
804 binary);
805 return GNUNET_SYSERR;
806 }
807 if (0 != access (p,
808 X_OK))
809 {
811 "access",
812 p);
813 GNUNET_free (p);
814 return GNUNET_SYSERR;
815 }
816
817 if (0 == getuid ())
818 {
819 /* as we run as root, we don't insist on SUID */
820 GNUNET_free (p);
821 return GNUNET_YES;
822 }
823
824 if (0 != stat (p,
825 &statbuf))
826 {
828 "stat",
829 p);
830 GNUNET_free (p);
831 return GNUNET_SYSERR;
832 }
833 if (check_suid)
834 {
835 (void) params;
836 if ( (0 != (statbuf.st_mode & S_ISUID)) &&
837 (0 == statbuf.st_uid) )
838 {
839 GNUNET_free (p);
840 return GNUNET_YES;
841 }
843 _ ("Binary `%s' exists, but is not SUID\n"),
844 p);
845 /* binary exists, but not SUID */
846 }
847 GNUNET_free (p);
848 return GNUNET_NO;
849}
850
851
852/* 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_BlindablePrivateKey zero
Public key of all zeros.
static struct GNUNET_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:557
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition disk.c:466
#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:1006
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".

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)
Value:
"util-os-installation", \
syscall, \
static char * filename
#define GNUNET_log_from_strerror_file(level, component, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

Definition at line 49 of file os_installation.c.

Function Documentation

◆ get_path_from_PATH()

static char * get_path_from_PATH ( const char *  binary)
static

Return the actual path to a file found in the current PATH environment variable.

Parameters
binarythe name of the file to find
Returns
path to binary, NULL if not found

Definition at line 295 of file os_installation.c.

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}

References end, getenv(), GNUNET_DISK_file_test(), GNUNET_free, GNUNET_malloc, GNUNET_strdup, GNUNET_YES, p, and PATH_SEPARATOR.

Referenced by GNUNET_OS_check_helper_binary(), and os_get_gnunet_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_path_from_GNUNET_PREFIX()

static char * get_path_from_GNUNET_PREFIX ( const struct GNUNET_OS_ProjectData pd)
static

Try to obtain the installation path using the "GNUNET_PREFIX" environment variable.

Parameters
pdproject data to use to determine paths
Returns
NULL on error (environment variable not set)

Definition at line 353 of file os_installation.c.

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}

References GNUNET_OS_ProjectData::env_varname, GNUNET_OS_ProjectData::env_varname_alt, getenv(), GNUNET_strdup, and p.

Referenced by os_get_gnunet_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ os_get_gnunet_path()

static char * os_get_gnunet_path ( const struct GNUNET_OS_ProjectData pd)
static

get the path to GNUnet bin/ or lib/, preferring the lib/ path

Author
Milan
Parameters
pdproject data to use to determine paths
Returns
a pointer to the executable path, or NULL on error

Definition at line 375 of file os_installation.c.

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}

References GNUNET_OS_ProjectData::binary_name, GNUNET_OS_ProjectData::env_varname, get_path_from_GNUNET_PREFIX(), get_path_from_PATH(), GNUNET_ERROR_TYPE_ERROR, LOG, GNUNET_OS_ProjectData::project_dirname, and ret.

Referenced by GNUNET_OS_installation_get_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ os_get_exec_path()

static char * os_get_exec_path ( const struct GNUNET_OS_ProjectData pd)
static

get the path to current app's bin/

Parameters
pdproject data to use to determine paths
Returns
a pointer to the executable path, or NULL on error

Definition at line 416 of file os_installation.c.

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}

References ret.

Referenced by GNUNET_OS_installation_get_path().

Here is the caller graph for this function:

Variable Documentation

◆ default_pd

const struct GNUNET_OS_ProjectData default_pd
static
Initial value:
= {
.libname = "libgnunetutil",
.project_dirname = "gnunet",
.binary_name = "gnunet-arm",
.version = PACKAGE_VERSION,
.env_varname = "GNUNET_PREFIX",
.base_config_varname = "GNUNET_BASE_CONFIG",
.bug_email = "gnunet-developers@gnu.org",
.homepage = "http://www.gnu.org/s/gnunet/",
.config_file = "gnunet.conf",
.user_config_file = "~/.config/gnunet.conf",
.is_gnu = 1,
.gettext_domain = "gnunet",
.gettext_path = NULL,
.agpl_url = GNUNET_AGPL_URL,
}

Default project data used for installation path detection for GNUnet (core).

Definition at line 60 of file os_installation.c.

60 {
61 .libname = "libgnunetutil",
62 .project_dirname = "gnunet",
63 .binary_name = "gnunet-arm",
64 .version = PACKAGE_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};

Referenced by GNUNET_OS_project_data_gnunet().