00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #include "config.h"
00073 #include "system.h"
00074 #if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
00075 #include <windows.h>
00076 #endif
00077 #include "prefix.h"
00078
00079 #ifdef SGI_MONGOOSE
00080 #undef PREFIX
00081 #define PREFIX ""
00082 #endif
00083
00084 static const char *std_prefix = PREFIX;
00085
00086 static const char *get_key_value PARAMS ((char *));
00087 static char *translate_name PARAMS ((char *));
00088 static char *save_string PARAMS ((const char *, int));
00089 static void tr PARAMS ((char *, int, int));
00090
00091 #if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
00092 static char *lookup_key PARAMS ((char *));
00093 static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE;
00094 #endif
00095
00096
00097
00098 static const char *
00099 get_key_value (key)
00100 char *key;
00101 {
00102 const char *prefix = 0;
00103 char *temp = 0;
00104
00105 #if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
00106 prefix = lookup_key (key);
00107 #endif
00108
00109 if (prefix == 0)
00110 prefix = getenv (temp = concat (key, "_ROOT", NULL));
00111
00112 if (prefix == 0)
00113 prefix = std_prefix;
00114
00115 if (temp)
00116 free (temp);
00117
00118 return prefix;
00119 }
00120
00121
00122
00123 static char *
00124 save_string (s, len)
00125 const char *s;
00126 int len;
00127 {
00128 char *result = xmalloc (len + 1);
00129
00130 memcpy (result, s, len);
00131 result[len] = 0;
00132 return result;
00133 }
00134
00135 #if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
00136
00137
00138
00139 static char *
00140 lookup_key (key)
00141 char *key;
00142 {
00143 char *dst;
00144 DWORD size;
00145 DWORD type;
00146 LONG res;
00147
00148 if (reg_key == (HKEY) INVALID_HANDLE_VALUE)
00149 {
00150 res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE", 0,
00151 KEY_READ, ®_key);
00152
00153 if (res == ERROR_SUCCESS)
00154 res = RegOpenKeyExA (reg_key, "Free Software Foundation", 0,
00155 KEY_READ, ®_key);
00156
00157 if (res == ERROR_SUCCESS)
00158 res = RegOpenKeyExA (reg_key, WIN32_REGISTRY_KEY, 0,
00159 KEY_READ, ®_key);
00160
00161 if (res != ERROR_SUCCESS)
00162 {
00163 reg_key = (HKEY) INVALID_HANDLE_VALUE;
00164 return 0;
00165 }
00166 }
00167
00168 size = 32;
00169 dst = (char *) xmalloc (size);
00170
00171 res = RegQueryValueExA (reg_key, key, 0, &type, dst, &size);
00172 if (res == ERROR_MORE_DATA && type == REG_SZ)
00173 {
00174 dst = (char *) xrealloc (dst, size);
00175 res = RegQueryValueExA (reg_key, key, 0, &type, dst, &size);
00176 }
00177
00178 if (type != REG_SZ || res != ERROR_SUCCESS)
00179 {
00180 free (dst);
00181 dst = 0;
00182 }
00183
00184 return dst;
00185 }
00186 #endif
00187
00188
00189
00190
00191
00192 static char *
00193 translate_name (name)
00194 char *name;
00195 {
00196 char code;
00197 char *key, *old_name;
00198 const char *prefix;
00199 int keylen;
00200
00201 for (;;)
00202 {
00203 code = name[0];
00204 if (code != '@' && code != '$')
00205 break;
00206
00207 for (keylen = 0;
00208 (name[keylen + 1] != 0 && !IS_DIR_SEPARATOR (name[keylen + 1]));
00209 keylen++)
00210 ;
00211
00212 key = (char *) alloca (keylen + 1);
00213 strncpy (key, &name[1], keylen);
00214 key[keylen] = 0;
00215
00216 if (code == '@')
00217 {
00218 prefix = get_key_value (key);
00219 if (prefix == 0)
00220 prefix = std_prefix;
00221 }
00222 else
00223 prefix = getenv (key);
00224
00225 if (prefix == 0)
00226 prefix = PREFIX;
00227
00228
00229
00230
00231
00232
00233 old_name = name;
00234 name = concat (prefix, &name[keylen + 1], NULL);
00235 free (old_name);
00236 }
00237
00238 return name;
00239 }
00240
00241
00242 static void
00243 tr (string, c1, c2)
00244 char *string;
00245 int c1, c2;
00246 {
00247 do
00248 {
00249 if (*string == c1)
00250 *string = c2;
00251 }
00252 while (*string++);
00253 }
00254
00255
00256
00257
00258
00259 char *
00260 update_path (path, key)
00261 const char *path;
00262 const char *key;
00263 {
00264 char *result, *p;
00265
00266 if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0)
00267 {
00268 bool free_key = false;
00269
00270 if (key[0] != '$')
00271 {
00272 key = concat ("@", key, NULL);
00273 free_key = true;
00274 }
00275
00276 result = concat (key, &path[strlen (std_prefix)], NULL);
00277 if (free_key)
00278 free ((char *) key);
00279 result = translate_name (result);
00280 }
00281 else
00282 result = xstrdup (path);
00283
00284 #ifndef ALWAYS_STRIP_DOTDOT
00285 #define ALWAYS_STRIP_DOTDOT 0
00286 #endif
00287
00288 p = result;
00289 while (1)
00290 {
00291 char *src, *dest;
00292
00293 p = strchr (p, '.');
00294 if (p == NULL)
00295 break;
00296
00297 if (p[1] == '.'
00298 && IS_DIR_SEPARATOR (p[2])
00299 && (p != result && IS_DIR_SEPARATOR (p[-1])))
00300 {
00301 *p = 0;
00302 if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0)
00303 {
00304 *p = '.';
00305 break;
00306 }
00307 else
00308 {
00309
00310
00311
00312 dest = p;
00313 do
00314 {
00315 --dest;
00316 while (dest != result && IS_DIR_SEPARATOR (*dest))
00317 --dest;
00318 while (dest != result && !IS_DIR_SEPARATOR (dest[-1]))
00319 --dest;
00320 }
00321 while (dest != result && *dest == '.');
00322
00323
00324 if (*dest == '.' || IS_DIR_SEPARATOR (*dest))
00325 {
00326 *p = '.';
00327 break;
00328 }
00329 src = p + 3;
00330 while (IS_DIR_SEPARATOR (*src))
00331 ++src;
00332 p = dest;
00333 while ((*dest++ = *src++) != 0)
00334 ;
00335 }
00336 }
00337 else
00338 ++p;
00339 }
00340
00341 #ifdef UPDATE_PATH_HOST_CANONICALIZE
00342
00343 UPDATE_PATH_HOST_CANONICALIZE (result);
00344 #endif
00345
00346 #ifdef DIR_SEPARATOR_2
00347
00348 if (DIR_SEPARATOR_2 != DIR_SEPARATOR)
00349 tr (result, DIR_SEPARATOR_2, DIR_SEPARATOR);
00350 #endif
00351
00352 #if defined (DIR_SEPARATOR) && !defined (DIR_SEPARATOR_2)
00353 if (DIR_SEPARATOR != '/')
00354 tr (result, '/', DIR_SEPARATOR);
00355 #endif
00356
00357 return result;
00358 }
00359
00360
00361 void
00362 set_std_prefix (prefix, len)
00363 const char *prefix;
00364 int len;
00365 {
00366 std_prefix = save_string (prefix, len);
00367 }