pathmanager.c

Go to the documentation of this file.
00001 /***************************************************************************
00002     begin       : Mon Mar 01 2004
00003     copyright   : (C) 2004 by Martin Preuss
00004     email       : martin@libchipcard.de
00005 
00006  ***************************************************************************
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or         *
00009  *   modify it under the terms of the GNU Lesser General Public            *
00010  *   License as published by the Free Software Foundation; either          *
00011  *   version 2.1 of the License, or (at your option) any later version.    *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00016  *   Lesser General Public License for more details.                       *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU Lesser General Public      *
00019  *   License along with this library; if not, write to the Free Software   *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
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       } /* while pairs */
00361       dbN=GWEN_DB_GetNextGroup(dbN);
00362     } /* while paths */
00363     dbT=GWEN_DB_GetNextGroup(dbT);
00364   } /* while destLibs */
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       /* then add all paths from other libs */
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       /* check all paths */
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       /* check all paths */
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   /* open the key */
00574   if (RegOpenKey(HKEY_LOCAL_MACHINE, nbuffer, &hkey)){
00575     DBG_INFO(GWEN_LOGDOMAIN, "RegOpenKey %s failed.", keypath);
00576     return 1;
00577   }
00578 
00579   /* find the variablename  */
00580   for (i=0;; i++) {
00581     nsize=sizeof(nbuffer);
00582     vsize=sizeof(vbuffer);
00583     if (ERROR_SUCCESS!=RegEnumValue(hkey,
00584                                     i,    /* index */
00585                                     nbuffer,
00586                                     &nsize,
00587                                     0,       /* reserved */
00588                                     &typ,
00589                                     vbuffer,
00590                                     &vsize))
00591       break;
00592     if (strcasecmp(nbuffer, varname)==0 && typ==REG_SZ) {
00593       /* variable found */
00594       RegCloseKey(hkey);
00595       return GWEN_PathManager_AddPath(callingLib,
00596                                       destLib,
00597                                       pathName,
00598                                       (char*)vbuffer);
00599     }
00600   } /* for */
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 /* OS_WIN32 */
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 /* OS_WIN32 */
00621 
00622