aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-11-10 13:42:01 +0000
committerChristian Grothoff <christian@grothoff.org>2012-11-10 13:42:01 +0000
commitee15f03a4e6c354c307ebc7d8314b90a1af4f548 (patch)
treed1344e3773fc7ba338a661fba0e370bcecc17314
parent010f4adf0bc407801bee532505d7f2e50b71fba8 (diff)
downloadgnunet-gtk-ee15f03a4e6c354c307ebc7d8314b90a1af4f548.tar.gz
gnunet-gtk-ee15f03a4e6c354c307ebc7d8314b90a1af4f548.zip
unify os_installation implementation with the one from GNUnet-main
-rw-r--r--src/lib/os_installation.c185
1 files changed, 152 insertions, 33 deletions
diff --git a/src/lib/os_installation.c b/src/lib/os_installation.c
index c74d3454..aca3f133 100644
--- a/src/lib/os_installation.c
+++ b/src/lib/os_installation.c
@@ -40,6 +40,8 @@
40#if LINUX 40#if LINUX
41/** 41/**
42 * Try to determine path by reading /proc/PID/exe 42 * Try to determine path by reading /proc/PID/exe
43 *
44 * @return NULL on error
43 */ 45 */
44static char * 46static char *
45get_path_from_proc_maps () 47get_path_from_proc_maps ()
@@ -51,8 +53,7 @@ get_path_from_proc_maps ()
51 char *lgu; 53 char *lgu;
52 54
53 GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/maps", getpid ()); 55 GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/maps", getpid ());
54 f = fopen (fn, "r"); 56 if (NULL == (f = FOPEN (fn, "r")))
55 if (f == NULL)
56 return NULL; 57 return NULL;
57 while (NULL != fgets (line, sizeof (line), f)) 58 while (NULL != fgets (line, sizeof (line), f))
58 { 59 {
@@ -69,8 +70,11 @@ get_path_from_proc_maps ()
69 return NULL; 70 return NULL;
70} 71}
71 72
73
72/** 74/**
73 * Try to determine path by reading /proc/PID/exe 75 * Try to determine path by reading /proc/PID/exe
76 *
77 * @return NULL on error
74 */ 78 */
75static char * 79static char *
76get_path_from_proc_exe () 80get_path_from_proc_exe ()
@@ -90,6 +94,11 @@ get_path_from_proc_exe ()
90 lnk[size] = '\0'; 94 lnk[size] = '\0';
91 while ((lnk[size] != '/') && (size > 0)) 95 while ((lnk[size] != '/') && (size > 0))
92 size--; 96 size--;
97 /* test for being in lib/gnunet/libexec/ */
98 if ( (size > strlen ("/gnunet/libexec/")) &&
99 (0 == strcmp ("/gnunet/libexec/",
100 &lnk[size - strlen ("/gnunet/libexec/")])) )
101 size -= strlen ("gnunet/libexec/");
93 if ((size < 4) || (lnk[size - 4] != '/')) 102 if ((size < 4) || (lnk[size - 4] != '/'))
94 { 103 {
95 /* not installed in "/bin/" -- binary path probably useless */ 104 /* not installed in "/bin/" -- binary path probably useless */
@@ -100,28 +109,108 @@ get_path_from_proc_exe ()
100} 109}
101#endif 110#endif
102 111
112
103#if WINDOWS 113#if WINDOWS
104/** 114/**
105 * Try to determine path with win32-specific function 115 * Try to determine path with win32-specific function
116 *
117 * @return NULL on error
106 */ 118 */
107static char * 119static char *
108get_path_from_module_filename () 120get_path_from_module_filename ()
109{ 121{
110 char path[4097]; 122 size_t pathlen = 512;
111 char *idx; 123 DWORD real_pathlen;
112 124 wchar_t *idx;
113 GetModuleFileName (NULL, path, sizeof (path) - 1); 125 wchar_t *modulepath = NULL;
114 idx = path + strlen (path); 126 char *upath;
115 while ((idx > path) && (*idx != '\\') && (*idx != '/')) 127 uint8_t *u8_string;
128 size_t u8_string_length;
129
130 /* This braindead function won't tell us how much space it needs, so
131 * we start at 1024 and double the space up if it doesn't fit, until
132 * it fits, or we exceed the threshold.
133 */
134 do
135 {
136 pathlen = pathlen * 2;
137 modulepath = GNUNET_realloc (modulepath, pathlen * sizeof (wchar_t));
138 SetLastError (0);
139 real_pathlen = GetModuleFileNameW (dll_instance, modulepath, pathlen * sizeof (wchar_t));
140 } while (real_pathlen >= pathlen && pathlen < 16*1024);
141 if (real_pathlen >= pathlen)
142 GNUNET_abort ();
143 /* To be safe */
144 modulepath[real_pathlen] = '\0';
145
146 idx = modulepath + real_pathlen;
147 while ((idx > modulepath) && (*idx != L'\\') && (*idx != L'/'))
116 idx--; 148 idx--;
117 *idx = '\0'; 149 *idx = L'\0';
118 return GNUNET_strdup (path); 150
151 /* Now modulepath holds full path to the directory where libgnunetutil is.
152 * This directory should look like <GNUNET_PREFIX>/bin or <GNUNET_PREFIX>.
153 */
154 if (wcschr (modulepath, L'/') || wcschr (modulepath, L'\\'))
155 {
156 /* At least one directory component (i.e. we're not in a root directory) */
157 wchar_t *dirname = idx;
158 while ((dirname > modulepath) && (*dirname != L'\\') && (*dirname != L'/'))
159 dirname--;
160 *dirname = L'\0';
161 if (dirname > modulepath)
162 {
163 dirname++;
164 /* Now modulepath holds full path to the parent directory of the directory
165 * where libgnunetutil is.
166 * dirname holds the name of the directory where libgnunetutil is.
167 */
168 if (wcsicmp (dirname, L"bin") == 0)
169 {
170 /* pass */
171 }
172 else
173 {
174 /* Roll back our changes to modulepath */
175 dirname--;
176 *dirname = L'/';
177 }
178 }
179 }
180
181 /* modulepath is GNUNET_PREFIX */
182 u8_string = u16_to_u8 (modulepath, wcslen (modulepath), NULL, &u8_string_length);
183 if (NULL == u8_string)
184 GNUNET_abort ();
185
186 upath = GNUNET_malloc (u8_string_length + 1);
187 memcpy (upath, u8_string, u8_string_length);
188 upath[u8_string_length] = '\0';
189
190 free (u8_string);
191 GNUNET_free (modulepath);
192
193 return upath;
119} 194}
120#endif 195#endif
121 196
122#if DARWIN 197#if DARWIN
198
199/**
200 * Signature of the '_NSGetExecutablePath" function.
201 *
202 * @param buf where to write the path
203 * @param number of bytes available in 'buf'
204 * @return 0 on success, otherwise desired number of bytes is stored in 'bufsize'
205 */
123typedef int (*MyNSGetExecutablePathProto) (char *buf, size_t * bufsize); 206typedef int (*MyNSGetExecutablePathProto) (char *buf, size_t * bufsize);
124 207
208
209/**
210 * Try to obtain the path of our executable using '_NSGetExecutablePath'.
211 *
212 * @return NULL on error
213 */
125static char * 214static char *
126get_path_from_NSGetExecutablePath () 215get_path_from_NSGetExecutablePath ()
127{ 216{
@@ -132,9 +221,8 @@ get_path_from_NSGetExecutablePath ()
132 int ret; 221 int ret;
133 222
134 path = NULL; 223 path = NULL;
135 func = 224 if (NULL == (func =
136 (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, "_NSGetExecutablePath"); 225 (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, "_NSGetExecutablePath")))
137 if (!func)
138 return NULL; 226 return NULL;
139 path = &zero; 227 path = &zero;
140 len = 0; 228 len = 0;
@@ -156,37 +244,49 @@ get_path_from_NSGetExecutablePath ()
156 return path; 244 return path;
157} 245}
158 246
247
248/**
249 * Try to obtain the path of our executable using '_dyld_image' API.
250 *
251 * @return NULL on error
252 */
159static char * 253static char *
160get_path_from_dyld_image () 254get_path_from_dyld_image ()
161{ 255{
162 const char *path; 256 const char *path;
163 char *p, *s; 257 char *p;
164 int i; 258 char *s;
259 unsigned int i;
165 int c; 260 int c;
166 261
167 p = NULL;
168 c = _dyld_image_count (); 262 c = _dyld_image_count ();
169 for (i = 0; i < c; i++) 263 for (i = 0; i < c; i++)
170 { 264 {
171 if (_dyld_get_image_header (i) == &_mh_dylib_header) 265 if (_dyld_get_image_header (i) != &_mh_dylib_header)
172 { 266 continue;
173 path = _dyld_get_image_name (i); 267 path = _dyld_get_image_name (i);
174 if (path != NULL && strlen (path) > 0) 268 if ( (NULL == path) || (0 == strlen (path)) )
175 { 269 continue;
176 p = strdup (path); 270 p = GNUNET_strdup (path);
177 s = p + strlen (p); 271 s = p + strlen (p);
178 while ((s > p) && (*s != '/')) 272 while ((s > p) && ('/' != *s))
179 s--; 273 s--;
180 s++; 274 s++;
181 *s = '\0'; 275 *s = '\0';
182 } 276 return p;
183 break;
184 }
185 } 277 }
186 return p; 278 return NULL;
187} 279}
188#endif 280#endif
189 281
282
283/**
284 * Return the actual path to a file found in the current
285 * PATH environment variable.
286 *
287 * @param binary the name of the file to find
288 * @return path to binary, NULL if not found
289 */
190static char * 290static char *
191get_path_from_PATH () 291get_path_from_PATH ()
192{ 292{
@@ -229,6 +329,13 @@ get_path_from_PATH ()
229 return NULL; 329 return NULL;
230} 330}
231 331
332
333/**
334 * Try to obtain the installation path using the "GNUNET_PREFIX" environment
335 * variable.
336 *
337 * @return NULL on error (environment variable not set)
338 */
232static char * 339static char *
233get_path_from_GNUNET_PREFIX () 340get_path_from_GNUNET_PREFIX ()
234{ 341{
@@ -240,6 +347,7 @@ get_path_from_GNUNET_PREFIX ()
240 return NULL; 347 return NULL;
241} 348}
242 349
350
243/* 351/*
244 * @brief get the path to GNUnet bin/ or lib/, prefering the lib/ path 352 * @brief get the path to GNUnet bin/ or lib/, prefering the lib/ path
245 * @author Milan 353 * @author Milan
@@ -343,7 +451,7 @@ GNUNET_GTK_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
343 if (execpath == NULL) 451 if (execpath == NULL)
344 execpath = os_get_gnunet_path (); 452 execpath = os_get_gnunet_path ();
345 453
346 if (execpath == NULL) 454 if (NULL == execpath)
347 return NULL; 455 return NULL;
348 456
349 n = strlen (execpath); 457 n = strlen (execpath);
@@ -362,7 +470,8 @@ GNUNET_GTK_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
362 ((0 == strcasecmp (&execpath[n - 5], "lib32")) || 470 ((0 == strcasecmp (&execpath[n - 5], "lib32")) ||
363 (0 == strcasecmp (&execpath[n - 5], "lib64")))) 471 (0 == strcasecmp (&execpath[n - 5], "lib64"))))
364 { 472 {
365 if (dirkind != GNUNET_OS_IPK_LIBDIR) 473 if ( (GNUNET_OS_IPK_LIBDIR != dirkind) &&
474 (GNUNET_OS_IPK_LIBEXECDIR != dirkind) )
366 { 475 {
367 /* strip '/lib32' or '/lib64' */ 476 /* strip '/lib32' or '/lib64' */
368 execpath[n - 5] = '\0'; 477 execpath[n - 5] = '\0';
@@ -412,6 +521,16 @@ GNUNET_GTK_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
412 dirname = 521 dirname =
413 DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "locale" DIR_SEPARATOR_STR; 522 DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "locale" DIR_SEPARATOR_STR;
414 break; 523 break;
524 case GNUNET_OS_IPK_LIBEXECDIR:
525 if (isbasedir)
526 dirname =
527 DIR_SEPARATOR_STR "lib" DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR \
528 "libexec" DIR_SEPARATOR_STR;
529 else
530 dirname =
531 DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR \
532 "libexec" DIR_SEPARATOR_STR;
533 break;
415 default: 534 default:
416 GNUNET_free (execpath); 535 GNUNET_free (execpath);
417 return NULL; 536 return NULL;