gwenhywfar
4.3.1
|
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