gwenhywfar 4.0.3

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(){
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(){
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 (dbio->importFn)
00252     return dbio->importFn(dbio, sio, db, params, flags);
00253   else {
00254     DBG_INFO(GWEN_LOGDOMAIN, "No import function set");
00255     return -1;
00256   }
00257 }
00258 
00259 
00260 
00261 int GWEN_DBIO_Export(GWEN_DBIO *dbio,
00262                      GWEN_SYNCIO *sio,
00263                      GWEN_DB_NODE *db,
00264                      GWEN_DB_NODE *params,
00265                      uint32_t flags) {
00266   assert(dbio);
00267   assert(sio);
00268   assert(db);
00269 
00270   if (dbio->exportFn)
00271     return dbio->exportFn(dbio, sio, db, params, flags);
00272   else {
00273     DBG_INFO(GWEN_LOGDOMAIN, "No export function set");
00274     return -1;
00275   }
00276 }
00277 
00278 
00279 
00280 GWEN_DBIO_CHECKFILE_RESULT GWEN_DBIO_CheckFile(GWEN_DBIO *dbio,
00281                                                const char *fname) {
00282   assert(dbio);
00283   assert(fname);
00284 
00285   if (dbio->checkFileFn)
00286     return dbio->checkFileFn(dbio, fname);
00287   else {
00288     DBG_INFO(GWEN_LOGDOMAIN, "No checkFile function set");
00289     return GWEN_DBIO_CheckFileResultUnknown;
00290   }
00291 }
00292 
00293 
00294 
00295 const char *GWEN_DBIO_GetName(const GWEN_DBIO *dbio){
00296   assert(dbio);
00297   return dbio->name;
00298 }
00299 
00300 
00301 
00302 const char *GWEN_DBIO_GetDescription(const GWEN_DBIO *dbio){
00303   assert(dbio);
00304   return dbio->descr;
00305 }
00306 
00307 
00308 
00309 void GWEN_DBIO_SetImportFn(GWEN_DBIO *dbio, GWEN_DBIO_IMPORTFN f){
00310   assert(dbio);
00311   dbio->importFn=f;
00312 }
00313 
00314 
00315 
00316 void GWEN_DBIO_SetExportFn(GWEN_DBIO *dbio, GWEN_DBIO_EXPORTFN f){
00317   assert(dbio);
00318   dbio->exportFn=f;
00319 }
00320 
00321 
00322 void GWEN_DBIO_SetCheckFileFn(GWEN_DBIO *dbio, GWEN_DBIO_CHECKFILEFN f){
00323   assert(dbio);
00324   dbio->checkFileFn=f;
00325 }
00326 
00327 
00328 
00329 GWEN_DBIO *GWEN_DBIO_GetPlugin(const char *modname){
00330   GWEN_PLUGIN_MANAGER *pm;
00331   GWEN_PLUGIN *pl;
00332   GWEN_DBIO *dbio;
00333 
00334   pm=GWEN_PluginManager_FindPluginManager("dbio");
00335   if (!pm) {
00336     DBG_ERROR(GWEN_LOGDOMAIN, "No plugin manager for \"dbio\" found");
00337     return 0;
00338   }
00339 
00340   pl=GWEN_PluginManager_GetPlugin(pm, modname);
00341   if (!pl) {
00342     DBG_INFO(GWEN_LOGDOMAIN, "DBIO-Plugin \"%s\" not found", modname);
00343     return 0;
00344   }
00345 
00346   dbio=GWEN_DBIO_Plugin_Factory(pl);
00347   if (!dbio) {
00348     DBG_INFO(GWEN_LOGDOMAIN,
00349              "Plugin did not create a GWEN_DBIO");
00350   }
00351   return dbio;
00352 }
00353 
00354 
00355 
00356 int GWEN_DBIO_ExportToFile(GWEN_DBIO *dbio,
00357                            const char *fname,
00358                            GWEN_DB_NODE *db,
00359                            GWEN_DB_NODE *params,
00360                            uint32_t dbflags) {
00361   int rv;
00362   GWEN_FSLOCK *lck=0;
00363   GWEN_SYNCIO *sio;
00364 
00365   /* if locking requested */
00366   if (dbflags & GWEN_DB_FLAGS_LOCKFILE) {
00367     GWEN_FSLOCK_RESULT res;
00368 
00369     lck=GWEN_FSLock_new(fname, GWEN_FSLock_TypeFile);
00370     assert(lck);
00371     res=GWEN_FSLock_Lock(lck, GWEN_DB_DEFAULT_LOCK_TIMEOUT, 0);
00372     if (res!=GWEN_FSLock_ResultOk) {
00373       DBG_ERROR(GWEN_LOGDOMAIN,
00374                 "Could not apply lock to file \"%s\" (%d)",
00375                 fname, res);
00376       GWEN_FSLock_free(lck);
00377       return -1;
00378     }
00379   }
00380 
00381   /* open file */
00382   sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateAlways);
00383   if (dbflags & GWEN_DB_FLAGS_APPEND_FILE)
00384     GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_APPEND);
00385   GWEN_SyncIo_AddFlags(sio,
00386                        GWEN_SYNCIO_FILE_FLAGS_READ |
00387                        GWEN_SYNCIO_FILE_FLAGS_WRITE |
00388                        GWEN_SYNCIO_FILE_FLAGS_UREAD |
00389                        GWEN_SYNCIO_FILE_FLAGS_UWRITE);
00390   rv=GWEN_SyncIo_Connect(sio);
00391   if (rv<0) {
00392     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00393     GWEN_SyncIo_free(sio);
00394     if (lck) {
00395       GWEN_FSLock_Unlock(lck);
00396       GWEN_FSLock_free(lck);
00397     }
00398     return rv;
00399   }
00400 
00401   rv=GWEN_DBIO_Export(dbio, sio, db, params, dbflags);
00402   if (rv<0) {
00403     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00404     GWEN_SyncIo_Disconnect(sio);
00405     GWEN_SyncIo_free(sio);
00406     if (lck) {
00407       GWEN_FSLock_Unlock(lck);
00408       GWEN_FSLock_free(lck);
00409     }
00410     return rv;
00411   }
00412 
00413   rv=GWEN_SyncIo_Disconnect(sio);
00414   if (rv<0) {
00415     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00416     GWEN_SyncIo_free(sio);
00417     if (lck) {
00418       GWEN_FSLock_Unlock(lck);
00419       GWEN_FSLock_free(lck);
00420     }
00421     return rv;
00422   }
00423   GWEN_SyncIo_free(sio);
00424 
00425   /* remove lock, if any */
00426   if (lck) {
00427     GWEN_FSLOCK_RESULT res;
00428 
00429     res=GWEN_FSLock_Unlock(lck);
00430     if (res!=GWEN_FSLock_ResultOk) {
00431       DBG_WARN(GWEN_LOGDOMAIN,
00432                "Could not remove lock on file \"%s\" (%d)",
00433                fname, res);
00434     }
00435     GWEN_FSLock_free(lck);
00436   }
00437 
00438   return 0;
00439 }
00440 
00441 
00442 
00443 int GWEN_DBIO_ExportToBuffer(GWEN_DBIO *dbio,
00444                              GWEN_BUFFER *buf,
00445                              GWEN_DB_NODE *db,
00446                              GWEN_DB_NODE *params,
00447                              uint32_t flags) {
00448   GWEN_SYNCIO *sio;
00449   int rv;
00450 
00451   /* create SyncIO, don't take over buf */
00452   sio=GWEN_SyncIo_Memory_new(buf, 0);
00453   rv=GWEN_DBIO_Export(dbio, sio, db, params, flags);
00454   if (rv<0) {
00455     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00456     GWEN_SyncIo_free(sio);
00457     return rv;
00458   }
00459 
00460   GWEN_SyncIo_free(sio);
00461   return 0;
00462 }
00463 
00464 
00465 
00466 int GWEN_DBIO_ImportFromFile(GWEN_DBIO *dbio,
00467                              const char *fname,
00468                              GWEN_DB_NODE *db,
00469                              GWEN_DB_NODE *params,
00470                              uint32_t dbflags) {
00471   GWEN_SYNCIO *sio;
00472   int rv;
00473   GWEN_FSLOCK *lck=0;
00474 
00475   /* if locking requested */
00476   if (dbflags & GWEN_DB_FLAGS_LOCKFILE) {
00477     GWEN_FSLOCK_RESULT res;
00478 
00479     lck=GWEN_FSLock_new(fname, GWEN_FSLock_TypeFile);
00480     assert(lck);
00481     res=GWEN_FSLock_Lock(lck, GWEN_DB_DEFAULT_LOCK_TIMEOUT, 0);
00482     if (res!=GWEN_FSLock_ResultOk) {
00483       DBG_ERROR(GWEN_LOGDOMAIN,
00484                 "Could not apply lock to file \"%s\" (%d)",
00485                 fname, res);
00486       GWEN_FSLock_free(lck);
00487       return GWEN_ERROR_IO;
00488     }
00489   }
00490 
00491   sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
00492   GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ);
00493   rv=GWEN_SyncIo_Connect(sio);
00494   if (rv<0) {
00495     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00496     GWEN_SyncIo_free(sio);
00497     if (lck) {
00498       GWEN_FSLock_Unlock(lck);
00499       GWEN_FSLock_free(lck);
00500     }
00501     return rv;
00502   }
00503 
00504   /* read from file */
00505   rv=GWEN_DBIO_Import(dbio, sio, db, params, dbflags);
00506   if (rv<0) {
00507     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00508     GWEN_SyncIo_Disconnect(sio);
00509     GWEN_SyncIo_free(sio);
00510     if (lck) {
00511       GWEN_FSLock_Unlock(lck);
00512       GWEN_FSLock_free(lck);
00513     }
00514     return rv;
00515   }
00516 
00517   /* close io layer */
00518   GWEN_SyncIo_Disconnect(sio);
00519   GWEN_SyncIo_free(sio);
00520 
00521   /* remove lock, if any */
00522   if (lck) {
00523     GWEN_FSLOCK_RESULT res;
00524 
00525     res=GWEN_FSLock_Unlock(lck);
00526     if (res!=GWEN_FSLock_ResultOk) {
00527       DBG_WARN(GWEN_LOGDOMAIN,
00528                "Could not remove lock on file \"%s\" (%d)",
00529                fname, res);
00530     }
00531     GWEN_FSLock_free(lck);
00532   }
00533 
00534   return 0;
00535 }
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549