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 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032
00033 #include "pathmanager_p.h"
00034 #ifndef OS_WIN32
00035 # include "binreloc.h"
00036 #endif
00037 #include <gwenhywfar/db.h>
00038 #include <gwenhywfar/debug.h>
00039 #include <gwenhywfar/directory.h>
00040
00041
00042 #include <stdlib.h>
00043 #include <stdio.h>
00044 #include <assert.h>
00045 #include <string.h>
00046 #include <unistd.h>
00047 #include <errno.h>
00048
00049 #ifdef OS_WIN32
00050 # include <windows.h>
00051 # define DIRSEP "\\"
00052 # define DIRSEP_C '\\'
00053 #else
00054 # define DIRSEP "/"
00055 # define DIRSEP_C '/'
00056 #endif
00057
00058
00059 static GWEN_DB_NODE *gwen__paths=0;
00060
00061
00062 int GWEN_PathManager_ModuleInit(){
00063 gwen__paths=GWEN_DB_Group_new("paths");
00064
00065 return 0;
00066 }
00067
00068
00069
00070 int GWEN_PathManager_ModuleFini(){
00071 GWEN_DB_Group_free(gwen__paths);
00072 gwen__paths=0;
00073 return 0;
00074 }
00075
00076
00077
00078 int GWEN_PathManager_DefinePath(const char *destLib,
00079 const char *pathName) {
00080 GWEN_DB_NODE *dbT;
00081
00082 assert(destLib);
00083 assert(pathName);
00084 assert(gwen__paths);
00085 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_DB_FLAGS_DEFAULT,
00086 destLib);
00087 assert(dbT);
00088 if (GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST, pathName)) {
00089 DBG_ERROR(GWEN_LOGDOMAIN,
00090 "Path \"%s/%s\" already exists",
00091 destLib, pathName);
00092 return GWEN_ERROR_INVALID;
00093 }
00094 dbT=GWEN_DB_GetGroup(dbT,
00095 GWEN_DB_FLAGS_DEFAULT,
00096 pathName);
00097 return 0;
00098 }
00099
00100
00101
00102 int GWEN_PathManager_UndefinePath(const char *destLib,
00103 const char *pathName) {
00104 GWEN_DB_NODE *dbT;
00105
00106 assert(destLib);
00107 assert(pathName);
00108 assert(gwen__paths);
00109 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00110 destLib);
00111 if (!dbT)
00112 return GWEN_ERROR_NOT_FOUND;
00113
00114 dbT=GWEN_DB_GetGroup(dbT, GWEN_DB_FLAGS_DEFAULT,
00115 pathName);
00116 if (!dbT)
00117 return GWEN_ERROR_NOT_FOUND;
00118 GWEN_DB_UnlinkGroup(dbT);
00119 GWEN_DB_Group_free(dbT);
00120 return 0;
00121 }
00122
00123
00124
00125
00126 int GWEN_PathManager_AddPath(const char *callingLib,
00127 const char *destLib,
00128 const char *pathName,
00129 const char *pathValue) {
00130 GWEN_DB_NODE *dbT;
00131 GWEN_BUFFER *buf;
00132
00133 assert(destLib);
00134 assert(pathName);
00135 assert(pathValue);
00136 assert(gwen__paths);
00137 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00138 destLib);
00139 if (!dbT)
00140 return GWEN_ERROR_NOT_FOUND;
00141 dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00142 pathName);
00143 if (!dbT)
00144 return GWEN_ERROR_NOT_FOUND;
00145 dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_CREATE_GROUP,
00146 "pair");
00147 assert(dbT);
00148
00149 if (callingLib) {
00150 GWEN_DB_SetCharValue(dbT, GWEN_DB_FLAGS_DEFAULT,
00151 "lib", callingLib);
00152 }
00153
00154 buf=GWEN_Buffer_new(0, 256, 0, 1);
00155 GWEN_Directory_OsifyPath(pathValue, buf, 1);
00156
00157 GWEN_DB_SetCharValue(dbT, GWEN_DB_FLAGS_DEFAULT,
00158 "path",
00159 GWEN_Buffer_GetStart(buf));
00160 GWEN_Buffer_free(buf);
00161
00162 return 0;
00163 }
00164
00165
00166
00167 int GWEN_PathManager_AddRelPath(const char *callingLib,
00168 const char *destLib,
00169 const char *pathName,
00170 const char *pathValue,
00171 GWEN_PATHMANAGER_RELMODE rm) {
00172 char cwd[256];
00173
00174 switch(rm) {
00175 case GWEN_PathManager_RelModeCwd: {
00176 const char *pcwd;
00177
00178 pcwd=getcwd(cwd, sizeof(cwd)-1);
00179 if (pcwd) {
00180 GWEN_BUFFER *buf;
00181 int rv;
00182
00183 buf=GWEN_Buffer_new(0, 256, 0, 1);
00184 GWEN_Buffer_AppendString(buf, cwd);
00185 if (*pathValue!=DIRSEP_C)
00186 GWEN_Buffer_AppendString(buf, DIRSEP);
00187 GWEN_Buffer_AppendString(buf, pathValue);
00188 rv=GWEN_PathManager_AddPath(callingLib, destLib, pathName,
00189 GWEN_Buffer_GetStart(buf));
00190 GWEN_Buffer_free(buf);
00191 return rv;
00192 }
00193 else {
00194 DBG_ERROR(GWEN_LOGDOMAIN, "getcwd(): %s", strerror(errno));
00195 return GWEN_ERROR_IO;
00196 }
00197 break;
00198 }
00199
00200 case GWEN_PathManager_RelModeExe: {
00201 #ifndef OS_WIN32
00202 char *exeDir;
00203 GWEN_BUFFER *buf;
00204 int rv;
00205
00206 exeDir=br_find_prefix(NULL);
00207 if (exeDir==(char*)NULL) {
00208 DBG_INFO(GWEN_LOGDOMAIN,
00209 "Unable to determine exe folder");
00210 return GWEN_ERROR_GENERIC;
00211 }
00212 buf=GWEN_Buffer_new(0, 256, 0, 1);
00213 GWEN_Buffer_AppendString(buf, exeDir);
00214 free(exeDir);
00215 if (*pathValue!=DIRSEP_C)
00216 GWEN_Buffer_AppendString(buf, DIRSEP);
00217 GWEN_Buffer_AppendString(buf, pathValue);
00218 DBG_INFO(GWEN_LOGDOMAIN,
00219 "Adding path [%s]",
00220 GWEN_Buffer_GetStart(buf));
00221 rv=GWEN_PathManager_AddPath(callingLib, destLib, pathName,
00222 GWEN_Buffer_GetStart(buf));
00223 GWEN_Buffer_free(buf);
00224 return rv;
00225 #else
00226 DWORD rv;
00227 char *p;
00228 GWEN_BUFFER *buf;
00229
00230
00231 rv=GetModuleFileName(NULL, cwd, sizeof(cwd)-1);
00232 if (rv==0) {
00233 DBG_ERROR(GWEN_LOGDOMAIN,
00234 "GetModuleFileName(): %d",
00235 (int)GetLastError());
00236 return GWEN_ERROR_IO;
00237 }
00238
00239
00240
00241 p=strrchr(cwd, '\\');
00242 if (p) {
00243 *p=0;
00244 }
00245
00246
00247
00248 p=strrchr(cwd, '\\');
00249 if (p) {
00250
00251
00252
00253 if ((strcmp(p+1, "bin") == 0) || (strcmp(p+1, "lib") == 0)) {
00254
00255
00256 *p=0;
00257 }
00258 }
00259
00260
00261 buf=GWEN_Buffer_new(0, 256, 0, 1);
00262 GWEN_Buffer_AppendString(buf, cwd);
00263 if (*pathValue!=DIRSEP_C)
00264 GWEN_Buffer_AppendString(buf, DIRSEP);
00265 GWEN_Buffer_AppendString(buf, pathValue);
00266 DBG_INFO(GWEN_LOGDOMAIN,
00267 "Adding path [%s]",
00268 GWEN_Buffer_GetStart(buf));
00269 rv=GWEN_PathManager_AddPath(callingLib, destLib, pathName,
00270 GWEN_Buffer_GetStart(buf));
00271 GWEN_Buffer_free(buf);
00272 return rv;
00273 #endif
00274 }
00275
00276 case GWEN_PathManager_RelModeHome: {
00277 GWEN_BUFFER *buf;
00278 int rv;
00279
00280 rv=GWEN_Directory_GetHomeDirectory(cwd, sizeof(cwd)-1);
00281 if (rv) {
00282 DBG_ERROR(GWEN_LOGDOMAIN,
00283 "Could not determine HOME directory (%d)",
00284 rv);
00285 return rv;
00286 }
00287 buf=GWEN_Buffer_new(0, 256, 0, 1);
00288 GWEN_Buffer_AppendString(buf, cwd);
00289 if (*pathValue!=DIRSEP_C)
00290 GWEN_Buffer_AppendString(buf, DIRSEP);
00291 GWEN_Buffer_AppendString(buf, pathValue);
00292 rv=GWEN_PathManager_AddPath(callingLib, destLib, pathName,
00293 GWEN_Buffer_GetStart(buf));
00294 GWEN_Buffer_free(buf);
00295 return rv;
00296 }
00297
00298 default:
00299 DBG_INFO(GWEN_LOGDOMAIN, "Unknown relative mode %d", rm);
00300 return GWEN_ERROR_INVALID;
00301 }
00302
00303 }
00304
00305
00306
00307 int GWEN_PathManager_InsertPath(const char *callingLib,
00308 const char *destLib,
00309 const char *pathName,
00310 const char *pathValue) {
00311 GWEN_DB_NODE *dbT;
00312
00313 assert(destLib);
00314 assert(pathName);
00315 assert(pathValue);
00316 assert(gwen__paths);
00317 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00318 destLib);
00319 if (!dbT)
00320 return GWEN_ERROR_NOT_FOUND;
00321 dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00322 pathName);
00323 if (!dbT)
00324 return GWEN_ERROR_NOT_FOUND;
00325
00326 dbT=GWEN_DB_GetGroup(dbT,
00327 GWEN_PATH_FLAGS_CREATE_GROUP |
00328 GWEN_DB_FLAGS_INSERT,
00329 "pair");
00330 assert(dbT);
00331
00332 if (callingLib) {
00333 GWEN_DB_SetCharValue(dbT, GWEN_DB_FLAGS_DEFAULT,
00334 "lib", callingLib);
00335 }
00336 GWEN_DB_SetCharValue(dbT, GWEN_DB_FLAGS_DEFAULT,
00337 "path", pathValue);
00338
00339 return 0;
00340 }
00341
00342
00343
00344 int GWEN_PathManager_RemovePath(const char *callingLib,
00345 const char *destLib,
00346 const char *pathName,
00347 const char *pathValue) {
00348 GWEN_DB_NODE *dbT;
00349 const char *s;
00350 const char *p;
00351
00352 assert(gwen__paths);
00353 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00354 destLib);
00355 if (!dbT)
00356 return GWEN_ERROR_NOT_FOUND;
00357 dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00358 pathName);
00359 if (!dbT)
00360 return GWEN_ERROR_NOT_FOUND;
00361
00362 dbT=GWEN_DB_FindFirstGroup(dbT, "pair");
00363 while(dbT) {
00364 p=GWEN_DB_GetCharValue(dbT, "path", 0, 0);
00365 assert(p);
00366 s=GWEN_DB_GetCharValue(dbT, "lib", 0, 0);
00367
00368 if (
00369 (
00370 (!callingLib && !s) ||
00371 (callingLib && s && strcasecmp(s, callingLib)==0)
00372 ) &&
00373 strcasecmp(p, pathValue)==0
00374 )
00375 break;
00376 dbT=GWEN_DB_FindNextGroup(dbT, "pair");
00377 }
00378
00379 if (dbT) {
00380 GWEN_DB_UnlinkGroup(dbT);
00381 GWEN_DB_Group_free(dbT);
00382 return 0;
00383 }
00384 else
00385 return 1;
00386
00387 }
00388
00389
00390
00391 int GWEN_PathManager_RemovePaths(const char *callingLib) {
00392 GWEN_DB_NODE *dbT;
00393 const char *s;
00394
00395 assert(gwen__paths);
00396 GWEN_DB_DeleteGroup(gwen__paths, callingLib);
00397
00398 dbT=GWEN_DB_GetFirstGroup(gwen__paths);
00399 while(dbT) {
00400 GWEN_DB_NODE *dbN;
00401
00402 dbN=GWEN_DB_GetFirstGroup(dbT);
00403 while(dbN) {
00404 GWEN_DB_NODE *dbNN;
00405
00406 dbNN=GWEN_DB_FindFirstGroup(dbN, "pair");
00407 while(dbNN) {
00408 GWEN_DB_NODE *dbNext;
00409
00410 dbNext=GWEN_DB_FindNextGroup(dbNN, "pair");
00411 s=GWEN_DB_GetCharValue(dbNN, "lib", 0, 0);
00412 assert(s);
00413
00414 if (s && strcasecmp(s, callingLib)==0) {
00415 GWEN_DB_UnlinkGroup(dbNN);
00416 GWEN_DB_Group_free(dbNN);
00417 }
00418 dbNN=dbNext;
00419 }
00420 dbN=GWEN_DB_GetNextGroup(dbN);
00421 }
00422 dbT=GWEN_DB_GetNextGroup(dbT);
00423 }
00424
00425 return 0;
00426 }
00427
00428
00429
00430 int GWEN_PathManager_PathChanged(const char *destLib,
00431 const char *pathName) {
00432 GWEN_DB_NODE *dbT;
00433
00434 assert(gwen__paths);
00435 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00436 destLib);
00437 if (!dbT)
00438 return GWEN_ERROR_NOT_FOUND;
00439
00440 dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00441 pathName);
00442 if (!dbT)
00443 return GWEN_ERROR_NOT_FOUND;
00444
00445 if ((GWEN_DB_GetNodeFlags(dbT) & GWEN_DB_NODE_FLAGS_DIRTY))
00446 return 1;
00447
00448 return 0;
00449 }
00450
00451
00452
00453 GWEN_STRINGLIST *GWEN_PathManager_GetPaths(const char *destLib,
00454 const char *pathName) {
00455 GWEN_DB_NODE *dbT;
00456
00457 assert(gwen__paths);
00458 dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00459 destLib);
00460 if (dbT) {
00461 dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
00462 pathName);
00463 if (dbT) {
00464 GWEN_STRINGLIST *sl;
00465 int i;
00466 const char *s;
00467 GWEN_DB_NODE *dbN;
00468
00469 sl=GWEN_StringList_new();
00470
00471
00472 dbN=GWEN_DB_FindFirstGroup(dbT, "pair");
00473 while(dbN) {
00474 for (i=0; ; i++) {
00475 s=GWEN_DB_GetCharValue(dbN, "path", i, 0);
00476 if (!s)
00477 break;
00478 GWEN_StringList_AppendString(sl, s, 0, 1);
00479 }
00480
00481 dbN=GWEN_DB_FindNextGroup(dbN, "pair");
00482 }
00483
00484 if (GWEN_StringList_Count(sl)==0) {
00485 GWEN_StringList_free(sl);
00486 DBG_DEBUG(GWEN_LOGDOMAIN, "no entries");
00487 return 0;
00488 }
00489
00490 return sl;
00491 }
00492 }
00493
00494 return 0;
00495 }
00496
00497
00498
00499 int GWEN_PathManager_AddPathFromWinReg(const char *callingLib,
00500 const char *destLib,
00501 const char *pathName,
00502 const char *keypath,
00503 const char *varname){
00504 #ifdef OS_WIN32
00505 HKEY hkey;
00506 TCHAR nbuffer[MAX_PATH];
00507 BYTE vbuffer[MAX_PATH];
00508 DWORD nsize;
00509 DWORD vsize;
00510 DWORD typ;
00511 int i;
00512
00513 snprintf(nbuffer, sizeof(nbuffer), keypath);
00514
00515
00516 if (RegOpenKey(HKEY_LOCAL_MACHINE, nbuffer, &hkey)){
00517 DBG_INFO(GWEN_LOGDOMAIN, "RegOpenKey %s failed.", keypath);
00518 return 1;
00519 }
00520
00521
00522 for (i=0;; i++) {
00523 nsize=sizeof(nbuffer);
00524 vsize=sizeof(vbuffer);
00525 if (ERROR_SUCCESS!=RegEnumValue(hkey,
00526 i,
00527 nbuffer,
00528 &nsize,
00529 0,
00530 &typ,
00531 vbuffer,
00532 &vsize))
00533 break;
00534 if (strcasecmp(nbuffer, varname)==0 && typ==REG_SZ) {
00535
00536 RegCloseKey(hkey);
00537 return GWEN_PathManager_AddPath(callingLib,
00538 destLib,
00539 pathName,
00540 (char*)vbuffer);
00541 }
00542 }
00543
00544 RegCloseKey(hkey);
00545 DBG_INFO(GWEN_LOGDOMAIN,
00546 "In RegKey \"%s\" the variable \"%s\" does not exist",
00547 keypath, varname);
00548 return 1;
00549
00550 #else
00551 return 0;
00552 #endif
00553 }
00554
00555
00556
00557
00558
00559
00560