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