diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-11-10 13:42:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-11-10 13:42:01 +0000 |
commit | ee15f03a4e6c354c307ebc7d8314b90a1af4f548 (patch) | |
tree | d1344e3773fc7ba338a661fba0e370bcecc17314 | |
parent | 010f4adf0bc407801bee532505d7f2e50b71fba8 (diff) | |
download | gnunet-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.c | 185 |
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 | */ |
44 | static char * | 46 | static char * |
45 | get_path_from_proc_maps () | 47 | get_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 | */ |
75 | static char * | 79 | static char * |
76 | get_path_from_proc_exe () | 80 | get_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 | */ |
107 | static char * | 119 | static char * |
108 | get_path_from_module_filename () | 120 | get_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 | */ | ||
123 | typedef int (*MyNSGetExecutablePathProto) (char *buf, size_t * bufsize); | 206 | typedef 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 | */ | ||
125 | static char * | 214 | static char * |
126 | get_path_from_NSGetExecutablePath () | 215 | get_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 | */ | ||
159 | static char * | 253 | static char * |
160 | get_path_from_dyld_image () | 254 | get_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 | */ | ||
190 | static char * | 290 | static char * |
191 | get_path_from_PATH () | 291 | get_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 | */ | ||
232 | static char * | 339 | static char * |
233 | get_path_from_GNUNET_PREFIX () | 340 | get_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; |