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