GNUnet debian-0.24.3-29-g453fda2cf
 
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 tmp = NULL;
533 dirname = NULL;
534 if (4 == sizeof(void *))
535 {
536 GNUNET_asprintf (&dirname,
539 pd->project_dirname);
540 GNUNET_asprintf (&tmp,
541 "%s%s",
542 execpath,
543 dirname);
544 }
545 if (8 == sizeof(void *))
546 {
547 GNUNET_asprintf (&dirname,
550 pd->project_dirname);
551 GNUNET_asprintf (&tmp,
552 "%s%s",
553 execpath,
554 dirname);
555 }
556
557 if ((NULL != tmp) &&
558 (GNUNET_YES ==
560 GNUNET_YES)))
561 {
562 GNUNET_free (execpath);
563 GNUNET_free (dirname);
564 return tmp;
565 }
566 GNUNET_free (tmp);
567 GNUNET_free (dirname);
568 }
569 GNUNET_asprintf (&dirname,
571 pd->project_dirname);
572 break;
573
575 GNUNET_asprintf (&dirname,
578 pd->project_dirname);
579 break;
580
583 "locale" DIR_SEPARATOR_STR);
584 break;
585
588 "icons" DIR_SEPARATOR_STR);
589 break;
590
592 GNUNET_asprintf (&dirname,
596 pd->project_dirname);
597 break;
598
600 if (isbasedir)
601 {
602 GNUNET_asprintf (&dirname,
604 "libexec" DIR_SEPARATOR_STR,
605 pd->project_dirname);
606 GNUNET_asprintf (&tmp,
607 "%s%s%s%s",
608 execpath,
610 (NULL != multiarch) ? multiarch : "",
611 dirname);
612 GNUNET_free (dirname);
613 if (GNUNET_YES ==
615 true))
616 {
617 GNUNET_free (execpath);
618 return tmp;
619 }
620 GNUNET_free (tmp);
621 tmp = NULL;
622 dirname = NULL;
623 if (4 == sizeof(void *))
624 {
625 GNUNET_asprintf (&dirname,
628 "libexec" DIR_SEPARATOR_STR,
629 pd->project_dirname);
630 GNUNET_asprintf (&tmp,
631 "%s%s",
632 execpath,
633 dirname);
634 }
635 if (8 == 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 ((NULL != tmp) &&
648 (GNUNET_YES ==
650 true)))
651 {
652 GNUNET_free (execpath);
653 GNUNET_free (dirname);
654 return tmp;
655 }
656 GNUNET_free (tmp);
657 GNUNET_free (dirname);
658 }
659 GNUNET_asprintf (&dirname,
661 "libexec" DIR_SEPARATOR_STR,
662 pd->project_dirname);
663 break;
664
665 default:
666 GNUNET_free (execpath);
667 return NULL;
668 }
669 GNUNET_asprintf (&tmp,
670 "%s%s",
671 execpath,
672 dirname);
673 GNUNET_free (dirname);
674 GNUNET_free (execpath);
675 return tmp;
676}
677
678
679char *
681 const char *progname)
682{
683 static char *cache;
684 char *libexecdir;
685 char *binary;
686
687 if ((DIR_SEPARATOR == progname[0]) ||
688 (GNUNET_YES ==
690 GNUNET_NO,
691 NULL,
692 NULL)))
693 return GNUNET_strdup (progname);
694 if (NULL != cache)
695 libexecdir = cache;
696 else
697 libexecdir = GNUNET_OS_installation_get_path (pd,
699 if (NULL == libexecdir)
700 return GNUNET_strdup (progname);
701 GNUNET_asprintf (&binary,
702 "%s%s",
703 libexecdir,
704 progname);
705 cache = libexecdir;
706 return binary;
707}
708
709
710char *
712 const struct GNUNET_CONFIGURATION_Handle *cfg,
713 const char *progname)
714{
715 static char *cache;
716 char *binary = NULL;
717 char *path = NULL;
718 size_t path_len;
719
720 if (GNUNET_YES ==
722 GNUNET_NO,
723 NULL,
724 NULL))
725 {
726 return GNUNET_strdup (progname);
727 }
728 if (NULL != cache)
729 path = cache;
730 else
732 "PATHS",
733 "SUID_BINARY_PATH",
734 &path);
735 if ( (NULL == path) ||
736 (0 == strlen (path)) )
737 {
738 if (NULL != path)
739 GNUNET_free (path);
740 cache = NULL;
742 progname);
743 }
744 path_len = strlen (path);
745 GNUNET_asprintf (&binary,
746 "%s%s%s",
747 path,
748 (path[path_len - 1] == DIR_SEPARATOR) ? ""
750 progname);
751 cache = path;
752 return binary;
753}
754
755
757GNUNET_OS_check_helper_binary (const char *binary,
758 bool check_suid,
759 const char *params)
760{
761 struct stat statbuf;
762 char *p;
763 char *pf;
764
765 if ( (GNUNET_YES ==
767 GNUNET_NO,
768 NULL,
769 NULL)) ||
770 (0 == strncmp (binary, "./", 2)) )
771 {
772 p = GNUNET_strdup (binary);
773 }
774 else
775 {
776 p = get_path_from_PATH (binary);
777 if (NULL != p)
778 {
779 GNUNET_asprintf (&pf,
780 "%s/%s",
781 p,
782 binary);
783 GNUNET_free (p);
784 p = pf;
785 }
786 }
787
788 if (NULL == p)
789 {
791 _ ("Could not find binary `%s' in PATH!\n"),
792 binary);
793 return GNUNET_SYSERR;
794 }
795 if (0 != access (p,
796 X_OK))
797 {
799 "access",
800 p);
801 GNUNET_free (p);
802 return GNUNET_SYSERR;
803 }
804
805 if (0 == getuid ())
806 {
807 /* as we run as root, we don't insist on SUID */
808 GNUNET_free (p);
809 return GNUNET_YES;
810 }
811
812 if (0 != stat (p,
813 &statbuf))
814 {
816 "stat",
817 p);
818 GNUNET_free (p);
819 return GNUNET_SYSERR;
820 }
821 if (check_suid)
822 {
823 (void) params;
824 if ( (0 != (statbuf.st_mode & S_ISUID)) &&
825 (0 == statbuf.st_uid) )
826 {
827 GNUNET_free (p);
828 return GNUNET_YES;
829 }
831 _ ("Binary `%s' exists, but is not SUID\n"),
832 p);
833 /* binary exists, but not SUID */
834 }
835 GNUNET_free (p);
836 return GNUNET_NO;
837}
838
839
840/* 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:533
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition disk.c:454
#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:1001
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().