pathmanager.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: pathmanager.c 1393 2007-11-22 18:26:05Z martin $
00005     begin       : Mon Mar 01 2004
00006     copyright   : (C) 2004 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
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     /* Get the absolute path to the executable, including its name */
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     /* Find the last DIRSEP and set it to NULL so that we now have the
00240        bindir. */
00241     p=strrchr(cwd, '\\');
00242     if (p) {
00243       *p=0;
00244     }
00245 
00246     /* Find again the last DIRSEP to check whether the path ends in
00247        "bin" or "lib". */
00248     p=strrchr(cwd, '\\');
00249     if (p) {
00250       /* DIRSEP was found and p points to it. p+1 points either to the
00251          rest of the string or the '\0' byte, so we can use it
00252          here. */
00253       if ((strcmp(p+1, "bin") == 0) || (strcmp(p+1, "lib") == 0)) {
00254         /* The path ends in "bin" or "lib", hence we strip that suffix
00255            so that we now only have the prefix. */
00256         *p=0;
00257       }
00258     }
00259 
00260     /* And append the given subdirectory to that prefix. */
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       } /* while pairs */
00420       dbN=GWEN_DB_GetNextGroup(dbN);
00421     } /* while paths */
00422     dbT=GWEN_DB_GetNextGroup(dbT);
00423   } /* while destLibs */
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       /* then add all paths from other libs */
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   /* open the key */
00516   if (RegOpenKey(HKEY_LOCAL_MACHINE, nbuffer, &hkey)){
00517     DBG_INFO(GWEN_LOGDOMAIN, "RegOpenKey %s failed.", keypath);
00518     return 1;
00519   }
00520 
00521   /* find the variablename  */
00522   for (i=0;; i++) {
00523     nsize=sizeof(nbuffer);
00524     vsize=sizeof(vbuffer);
00525     if (ERROR_SUCCESS!=RegEnumValue(hkey,
00526                                     i,    /* index */
00527                                     nbuffer,
00528                                     &nsize,
00529                                     0,       /* reserved */
00530                                     &typ,
00531                                     vbuffer,
00532                                     &vsize))
00533       break;
00534     if (strcasecmp(nbuffer, varname)==0 && typ==REG_SZ) {
00535       /* variable found */
00536       RegCloseKey(hkey);
00537       return GWEN_PathManager_AddPath(callingLib,
00538                                       destLib,
00539                                       pathName,
00540                                       (char*)vbuffer);
00541     }
00542   } /* for */
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 /* OS_WIN32 */
00551   return 0;
00552 #endif /* OS_WIN32 */
00553 }
00554 
00555 
00556 
00557 
00558 
00559 
00560 

Generated on Fri Apr 11 01:53:47 2008 for gwenhywfar by  doxygen 1.5.5