dbio.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  begin       : Wed Mar 31 2004
00003  copyright   : (C) 2004-2010 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 
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029 
00030 #define DISABLE_DEBUGLOG
00031 
00032 #include "dbio_p.h"
00033 #include <gwenhywfar/gwenhywfar.h>
00034 #include <gwenhywfar/misc.h>
00035 #include <gwenhywfar/debug.h>
00036 #include <gwenhywfar/path.h>
00037 #include <gwenhywfar/text.h>
00038 #include <gwenhywfar/directory.h>
00039 #include <gwenhywfar/syncio.h>
00040 #include <gwenhywfar/syncio_file.h>
00041 #include <gwenhywfar/syncio_memory.h>
00042 #include <gwenhywfar/fslock.h>
00043 #include <gwenhywfar/pathmanager.h>
00044 
00045 
00046 /* TODO: #include <gwenhywfar/plugin.h> */
00047 
00048 #include <stdlib.h>
00049 #include <assert.h>
00050 #include <string.h>
00051 #include <errno.h>
00052 #include <ctype.h>
00053 
00054 #include <sys/types.h>
00055 #ifdef HAVE_SYS_STAT_H
00056 # include <sys/stat.h>
00057 #endif
00058 #ifdef HAVE_FCNTL_H
00059 # include <fcntl.h>
00060 #endif
00061 #ifdef HAVE_UNISTD_H
00062 # include <unistd.h>
00063 #endif
00064 
00065 
00066 #ifdef OS_WIN32
00067 # define DIRSEP "\\"
00068 # include <windows.h>
00069 #else
00070 # define DIRSEP "/"
00071 #endif
00072 
00073 
00074 
00075 GWEN_LIST_FUNCTIONS(GWEN_DBIO, GWEN_DBIO)
00076 GWEN_INHERIT_FUNCTIONS(GWEN_DBIO)
00077 
00078 GWEN_INHERIT(GWEN_PLUGIN, GWEN_DBIO_PLUGIN)
00079 
00080 
00081 int GWEN_DBIO_ModuleInit(void){
00082   GWEN_PLUGIN_MANAGER *pm;
00083   int err;
00084   GWEN_STRINGLIST *sl;
00085 
00086   pm=GWEN_PluginManager_new("dbio", GWEN_PM_LIBNAME);
00087   err=GWEN_PluginManager_Register(pm);
00088   if (err) {
00089     DBG_ERROR(GWEN_LOGDOMAIN, "Could not register DBIO plugin manager");
00090     return err;
00091   }
00092 
00093   /* create plugin paths */
00094   sl=GWEN_PathManager_GetPaths(GWEN_PM_LIBNAME, GWEN_PM_PLUGINDIR);
00095   if (sl) {
00096     GWEN_STRINGLISTENTRY *se;
00097     GWEN_BUFFER *pbuf;
00098 
00099     pbuf=GWEN_Buffer_new(0, 256, 0, 1);
00100 
00101     se=GWEN_StringList_FirstEntry(sl);
00102     while(se) {
00103       GWEN_Buffer_AppendString(pbuf, GWEN_StringListEntry_Data(se));
00104       GWEN_Buffer_AppendString(pbuf, DIRSEP GWEN_DBIO_FOLDER);
00105       DBG_INFO(GWEN_LOGDOMAIN, "Adding plugin path [%s]",
00106                GWEN_Buffer_GetStart(pbuf));
00107       GWEN_PluginManager_AddPath(pm, GWEN_PM_LIBNAME,
00108                                  GWEN_Buffer_GetStart(pbuf));
00109       GWEN_Buffer_Reset(pbuf);
00110       se=GWEN_StringListEntry_Next(se);
00111     }
00112     GWEN_Buffer_free(pbuf);
00113     GWEN_StringList_free(sl);
00114   }
00115 
00116   return 0;
00117 }
00118 
00119 
00120 
00121 int GWEN_DBIO_ModuleFini(void){
00122   GWEN_PLUGIN_MANAGER *pm;
00123 
00124   pm=GWEN_PluginManager_FindPluginManager("dbio");
00125   if (pm) {
00126     int rv;
00127 
00128     rv=GWEN_PluginManager_Unregister(pm);
00129     if (rv) {
00130       DBG_ERROR(GWEN_LOGDOMAIN,
00131                 "Could not unregister DBIO plugin manager (%d)", rv);
00132       return rv;
00133     }
00134     else
00135       GWEN_PluginManager_free(pm);
00136   }
00137 
00138   return 0;
00139 }
00140 
00141 
00142 
00143 
00144 
00145 GWEN_PLUGIN *GWEN_DBIO_Plugin_new(GWEN_PLUGIN_MANAGER *pm,
00146                                   const char *name,
00147                                   const char *fileName) {
00148   GWEN_PLUGIN *pl;
00149   GWEN_DBIO_PLUGIN *pldbio;
00150 
00151   pl=GWEN_Plugin_new(pm, name, fileName);
00152   GWEN_NEW_OBJECT(GWEN_DBIO_PLUGIN, pldbio);
00153   GWEN_INHERIT_SETDATA(GWEN_PLUGIN, GWEN_DBIO_PLUGIN, pl, pldbio,
00154                        GWEN_DBIO_Plugin_FreeData);
00155 
00156   return pl;
00157 }
00158 
00159 
00160 
00161 void GWENHYWFAR_CB GWEN_DBIO_Plugin_FreeData(GWEN_UNUSED void *bp, void *p) {
00162   GWEN_DBIO_PLUGIN *pldbio;
00163 
00164   pldbio=(GWEN_DBIO_PLUGIN*)p;
00165   GWEN_FREE_OBJECT(pldbio);
00166 }
00167 
00168 
00169 
00170 GWEN_DBIO *GWEN_DBIO_Plugin_Factory(GWEN_PLUGIN *pl) {
00171   GWEN_DBIO_PLUGIN *pldbio;
00172 
00173   assert(pl);
00174   pldbio=GWEN_INHERIT_GETDATA(GWEN_PLUGIN, GWEN_DBIO_PLUGIN, pl);
00175   assert(pldbio);
00176 
00177   assert(pldbio->factoryFn);
00178   return pldbio->factoryFn(pl);
00179 }
00180 
00181 
00182 
00183 void GWEN_DBIO_Plugin_SetFactoryFn(GWEN_PLUGIN *pl,
00184                                    GWEN_DBIO_PLUGIN_FACTORYFN f) {
00185   GWEN_DBIO_PLUGIN *pldbio;
00186 
00187   assert(pl);
00188   pldbio=GWEN_INHERIT_GETDATA(GWEN_PLUGIN, GWEN_DBIO_PLUGIN, pl);
00189   assert(pldbio);
00190 
00191   pldbio->factoryFn=f;
00192 }
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 GWEN_DBIO *GWEN_DBIO_new(const char *name, const char *descr){
00202   GWEN_DBIO *dbio;
00203 
00204   assert(name);
00205   GWEN_NEW_OBJECT(GWEN_DBIO, dbio);
00206   GWEN_LIST_INIT(GWEN_DBIO, dbio);
00207   GWEN_INHERIT_INIT(GWEN_DBIO, dbio);
00208   dbio->name=strdup(name);
00209   if (descr)
00210     dbio->descr=strdup(descr);
00211 
00212   dbio->usage=1;
00213   return dbio;
00214 }
00215 
00216 
00217 
00218 void GWEN_DBIO_free(GWEN_DBIO *dbio){
00219   if (dbio) {
00220     assert(dbio->usage);
00221     if (--(dbio->usage)==0) {
00222       GWEN_INHERIT_FINI(GWEN_DBIO, dbio);
00223       GWEN_LIST_FINI(GWEN_DBIO, dbio);
00224 
00225       free(dbio->name);
00226       free(dbio->descr);
00227 
00228       GWEN_FREE_OBJECT(dbio);
00229     }
00230   }
00231 }
00232 
00233 
00234 
00235 void GWEN_DBIO_Attach(GWEN_DBIO *dbio){
00236   assert(dbio);
00237   dbio->usage++;
00238 }
00239 
00240 
00241 
00242 int GWEN_DBIO_Import(GWEN_DBIO *dbio,
00243                      GWEN_SYNCIO *sio,
00244                      GWEN_DB_NODE *db,
00245                      GWEN_DB_NODE *params,
00246                      uint32_t flags) {
00247   assert(dbio);
00248   assert(sio);
00249   assert(db);
00250 
00251   if (GWEN_SyncIo_GetStatus(sio) != GWEN_SyncIo_Status_Connected) {
00252     DBG_ERROR(GWEN_LOGDOMAIN, "GWEN_SYNCIO %s not connected; did you forget to call GWEN_SyncIo_Connect()?", GWEN_SyncIo_GetTypeName(sio));
00253     return -1;
00254   }
00255 
00256   if (dbio->importFn)
00257     return dbio->importFn(dbio, sio, db, params, flags);
00258   else {
00259     DBG_INFO(GWEN_LOGDOMAIN, "No import function set");
00260     return -1;
00261   }
00262 }
00263 
00264 
00265 
00266 int GWEN_DBIO_Export(GWEN_DBIO *dbio,
00267                      GWEN_SYNCIO *sio,
00268                      GWEN_DB_NODE *db,
00269                      GWEN_DB_NODE *params,
00270                      uint32_t flags) {
00271   assert(dbio);
00272   assert(sio);
00273   assert(db);
00274 
00275   if (dbio->exportFn)
00276     return dbio->exportFn(dbio, sio, db, params, flags);
00277   else {
00278     DBG_INFO(GWEN_LOGDOMAIN, "No export function set");
00279     return -1;
00280   }
00281 }
00282 
00283 
00284 
00285 GWEN_DBIO_CHECKFILE_RESULT GWEN_DBIO_CheckFile(GWEN_DBIO *dbio,
00286                                                const char *fname) {
00287   assert(dbio);
00288   assert(fname);
00289 
00290   if (dbio->checkFileFn)
00291     return dbio->checkFileFn(dbio, fname);
00292   else {
00293     DBG_INFO(GWEN_LOGDOMAIN, "No checkFile function set");
00294     return GWEN_DBIO_CheckFileResultUnknown;
00295   }
00296 }
00297 
00298 
00299 
00300 const char *GWEN_DBIO_GetName(const GWEN_DBIO *dbio){
00301   assert(dbio);
00302   return dbio->name;
00303 }
00304 
00305 
00306 
00307 const char *GWEN_DBIO_GetDescription(const GWEN_DBIO *dbio){
00308   assert(dbio);
00309   return dbio->descr;
00310 }
00311 
00312 
00313 
00314 void GWEN_DBIO_SetImportFn(GWEN_DBIO *dbio, GWEN_DBIO_IMPORTFN f){
00315   assert(dbio);
00316   dbio->importFn=f;
00317 }
00318 
00319 
00320 
00321 void GWEN_DBIO_SetExportFn(GWEN_DBIO *dbio, GWEN_DBIO_EXPORTFN f){
00322   assert(dbio);
00323   dbio->exportFn=f;
00324 }
00325 
00326 
00327 void GWEN_DBIO_SetCheckFileFn(GWEN_DBIO *dbio, GWEN_DBIO_CHECKFILEFN f){
00328   assert(dbio);
00329   dbio->checkFileFn=f;
00330 }
00331 
00332 
00333 
00334 GWEN_DBIO *GWEN_DBIO_GetPlugin(const char *modname){
00335   GWEN_PLUGIN_MANAGER *pm;
00336   GWEN_PLUGIN *pl;
00337   GWEN_DBIO *dbio;
00338 
00339   pm=GWEN_PluginManager_FindPluginManager("dbio");
00340   if (!pm) {
00341     DBG_ERROR(GWEN_LOGDOMAIN, "No plugin manager for \"dbio\" found");
00342     return 0;
00343   }
00344 
00345   pl=GWEN_PluginManager_GetPlugin(pm, modname);
00346   if (!pl) {
00347     DBG_INFO(GWEN_LOGDOMAIN, "DBIO-Plugin \"%s\" not found", modname);
00348     return 0;
00349   }
00350 
00351   dbio=GWEN_DBIO_Plugin_Factory(pl);
00352   if (!dbio) {
00353     DBG_INFO(GWEN_LOGDOMAIN,
00354              "Plugin did not create a GWEN_DBIO");
00355   }
00356   return dbio;
00357 }
00358 
00359 
00360 
00361 int GWEN_DBIO_ExportToFile(GWEN_DBIO *dbio,
00362                            const char *fname,
00363                            GWEN_DB_NODE *db,
00364                            GWEN_DB_NODE *params,
00365                            uint32_t dbflags) {
00366   int rv;
00367   GWEN_FSLOCK *lck=0;
00368   GWEN_SYNCIO *sio;
00369 
00370   /* if locking requested */
00371   if (dbflags & GWEN_DB_FLAGS_LOCKFILE) {
00372     GWEN_FSLOCK_RESULT res;
00373 
00374     lck=GWEN_FSLock_new(fname, GWEN_FSLock_TypeFile);
00375     assert(lck);
00376     res=GWEN_FSLock_Lock(lck, GWEN_DB_DEFAULT_LOCK_TIMEOUT, 0);
00377     if (res!=GWEN_FSLock_ResultOk) {
00378       DBG_ERROR(GWEN_LOGDOMAIN,
00379                 "Could not apply lock to file \"%s\" (%d)",
00380                 fname, res);
00381       GWEN_FSLock_free(lck);
00382       return -1;
00383     }
00384   }
00385 
00386   /* open file */
00387   sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateAlways);
00388   if (dbflags & GWEN_DB_FLAGS_APPEND_FILE)
00389     GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_APPEND);
00390   GWEN_SyncIo_AddFlags(sio,
00391                        GWEN_SYNCIO_FILE_FLAGS_READ |
00392                        GWEN_SYNCIO_FILE_FLAGS_WRITE |
00393                        GWEN_SYNCIO_FILE_FLAGS_UREAD |
00394                        GWEN_SYNCIO_FILE_FLAGS_UWRITE);
00395   rv=GWEN_SyncIo_Connect(sio);
00396   if (rv<0) {
00397     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00398     GWEN_SyncIo_free(sio);
00399     if (lck) {
00400       GWEN_FSLock_Unlock(lck);
00401       GWEN_FSLock_free(lck);
00402     }
00403     return rv;
00404   }
00405 
00406   rv=GWEN_DBIO_Export(dbio, sio, db, params, dbflags);
00407   if (rv<0) {
00408     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00409     GWEN_SyncIo_Disconnect(sio);
00410     GWEN_SyncIo_free(sio);
00411     if (lck) {
00412       GWEN_FSLock_Unlock(lck);
00413       GWEN_FSLock_free(lck);
00414     }
00415     return rv;
00416   }
00417 
00418   rv=GWEN_SyncIo_Disconnect(sio);
00419   if (rv<0) {
00420     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00421     GWEN_SyncIo_free(sio);
00422     if (lck) {
00423       GWEN_FSLock_Unlock(lck);
00424       GWEN_FSLock_free(lck);
00425     }
00426     return rv;
00427   }
00428   GWEN_SyncIo_free(sio);
00429 
00430   /* remove lock, if any */
00431   if (lck) {
00432     GWEN_FSLOCK_RESULT res;
00433 
00434     res=GWEN_FSLock_Unlock(lck);
00435     if (res!=GWEN_FSLock_ResultOk) {
00436       DBG_WARN(GWEN_LOGDOMAIN,
00437                "Could not remove lock on file \"%s\" (%d)",
00438                fname, res);
00439     }
00440     GWEN_FSLock_free(lck);
00441   }
00442 
00443   return 0;
00444 }
00445 
00446 
00447 
00448 int GWEN_DBIO_ExportToBuffer(GWEN_DBIO *dbio,
00449                              GWEN_BUFFER *buf,
00450                              GWEN_DB_NODE *db,
00451                              GWEN_DB_NODE *params,
00452                              uint32_t flags) {
00453   GWEN_SYNCIO *sio;
00454   int rv;
00455 
00456   /* create SyncIO, don't take over buf */
00457   sio=GWEN_SyncIo_Memory_new(buf, 0);
00458   rv=GWEN_DBIO_Export(dbio, sio, db, params, flags);
00459   if (rv<0) {
00460     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00461     GWEN_SyncIo_free(sio);
00462     return rv;
00463   }
00464 
00465   GWEN_SyncIo_free(sio);
00466   return 0;
00467 }
00468 
00469 
00470 
00471 int GWEN_DBIO_ImportFromFile(GWEN_DBIO *dbio,
00472                              const char *fname,
00473                              GWEN_DB_NODE *db,
00474                              GWEN_DB_NODE *params,
00475                              uint32_t dbflags) {
00476   GWEN_SYNCIO *sio;
00477   int rv;
00478   GWEN_FSLOCK *lck=0;
00479 
00480   /* if locking requested */
00481   if (dbflags & GWEN_DB_FLAGS_LOCKFILE) {
00482     GWEN_FSLOCK_RESULT res;
00483 
00484     lck=GWEN_FSLock_new(fname, GWEN_FSLock_TypeFile);
00485     assert(lck);
00486     res=GWEN_FSLock_Lock(lck, GWEN_DB_DEFAULT_LOCK_TIMEOUT, 0);
00487     if (res!=GWEN_FSLock_ResultOk) {
00488       DBG_ERROR(GWEN_LOGDOMAIN,
00489                 "Could not apply lock to file \"%s\" (%d)",
00490                 fname, res);
00491       GWEN_FSLock_free(lck);
00492       return GWEN_ERROR_IO;
00493     }
00494   }
00495 
00496   sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
00497   GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ);
00498   rv=GWEN_SyncIo_Connect(sio);
00499   if (rv<0) {
00500     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00501     GWEN_SyncIo_free(sio);
00502     if (lck) {
00503       GWEN_FSLock_Unlock(lck);
00504       GWEN_FSLock_free(lck);
00505     }
00506     return rv;
00507   }
00508 
00509   /* read from file */
00510   rv=GWEN_DBIO_Import(dbio, sio, db, params, dbflags);
00511   if (rv<0) {
00512     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00513     GWEN_SyncIo_Disconnect(sio);
00514     GWEN_SyncIo_free(sio);
00515     if (lck) {
00516       GWEN_FSLock_Unlock(lck);
00517       GWEN_FSLock_free(lck);
00518     }
00519     return rv;
00520   }
00521 
00522   /* close io layer */
00523   GWEN_SyncIo_Disconnect(sio);
00524   GWEN_SyncIo_free(sio);
00525 
00526   /* remove lock, if any */
00527   if (lck) {
00528     GWEN_FSLOCK_RESULT res;
00529 
00530     res=GWEN_FSLock_Unlock(lck);
00531     if (res!=GWEN_FSLock_ResultOk) {
00532       DBG_WARN(GWEN_LOGDOMAIN,
00533                "Could not remove lock on file \"%s\" (%d)",
00534                fname, res);
00535     }
00536     GWEN_FSLock_free(lck);
00537   }
00538 
00539   return 0;
00540 }
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554