Main Page | Modules | Data Structures | File List | Data Fields

libkdb.c

00001 /***************************************************************************
00002             localkdb.c  -  Methods for accessing the Key Database
00003                              -------------------
00004     begin                : Mon Dec 29 2003
00005     copyright            : (C) 2003 by Avi Alkalay
00006     email                : avi@unix.sh
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the BSD License (revised).                      *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 
00017 
00018 
00019 /* Subversion stuff
00020 
00021 $Id: libkdb.c 601 2006-02-15 02:32:13Z aviram $
00022 
00023 */
00024 
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029 #include "kdb.h"
00030 #include "kdbbackend.h"
00031 #include "kdbprivate.h"
00032 
00033 #include <stdlib.h>
00034 #include <stdarg.h>
00035 #include "kdbLibLoader.h"
00036 
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040 #include <errno.h>
00041 #include <stdio.h>
00042 #ifdef HAVE_ICONV
00043 #include <iconv.h>
00044 #endif
00045 #ifdef HAVE_LOCALE_H
00046 #include <locale.h>
00047 #endif
00048 #ifdef HAVE_LANGINFO_H
00049 #include <langinfo.h>
00050 #endif
00051 #include <ctype.h>
00052 #include <string.h>
00053 
00054 /* usleep doesn't exist on win32, so we use Sleep() */
00055 #ifdef WIN32
00056 #define usleep(x) Sleep(x)
00057 #endif
00058 
00059 /*extern int errno;*/
00060 
00090 /*
00091  * @defgroup internals Elektra internals
00092  * @brief These methods are not to be used by your application.
00093  *
00094  */
00095 
00096 
00097 
00098 
00099 struct _KDBBackend {
00100     kdbLibHandle dlHandle;
00101     
00102     char *name;
00103     
00104     /* These are the must-have methods */
00105     
00106     kdbOpenPtr kdbOpen;
00107     kdbClosePtr kdbClose;
00108     
00109     kdbGetKeyPtr kdbGetKey;
00110     kdbSetKeyPtr kdbSetKey;
00111     kdbStatKeyPtr kdbStatKey;
00112     kdbRenamePtr kdbRename;
00113     kdbRemoveKeyPtr kdbRemoveKey;
00114     kdbGetChildKeysPtr kdbGetKeyChildKeys;
00115     
00116     
00117     /* These are the optional methods */
00118     
00119     kdbSetKeysPtr kdbSetKeys;
00120     kdbMonitorKeyPtr kdbMonitorKey;
00121     kdbMonitorKeysPtr kdbMonitorKeys;
00122 };
00123 
00124 
00125 
00126 
00127 KDBBackend *backend;
00128 
00129 
00130 
00160 int kdbOpen() {
00161     char *backendName=0;
00162     
00163     backendName=getenv("KDB_BACKEND");
00164     if (backendName) return kdbOpenBackend(backendName);
00165     else return kdbOpenBackend(DEFAULT_BACKEND);
00166 }
00167 
00168 
00169 
00188 int kdbOpenDefault() {
00189     return kdbOpenBackend(DEFAULT_BACKEND);
00190 }
00191 
00192 
00193 
00194 
00244 int kdbOpenBackend(char *backendName) {
00245     kdbLibHandle dlhandle=0;
00246     char backendlib[300];
00247     KDBBackendFactory kdbBackendNew=0;
00248     int rc=0;
00249     
00250     backend=0;
00251     
00252     /* load the environment and make us aware of codeset conversions */
00253     #ifdef HAVE_SETLOCALE
00254     setlocale(LC_ALL,"");
00255     #endif
00256     
00257     /* init */
00258     if ( (rc = kdbLibInit()) ) {
00259         errno=KDB_RET_NOSYS;
00260         return 1; /* error */
00261     }   
00262     
00263     sprintf(backendlib,"libelektra-%s",backendName);
00264     dlhandle=kdbLibLoad(backendlib);
00265     if (dlhandle == 0) {
00266         errno=KDB_RET_NOSYS;
00267         return 1; /* error */
00268     }
00269     
00270     kdbBackendNew=(KDBBackendFactory)kdbLibSym(dlhandle,"kdbBackendFactory");
00271     if (kdbBackendNew == 0) {
00272         errno=KDB_RET_NOSYS;
00273         return 2; /* error */
00274     }
00275     
00276     backend=(*kdbBackendNew)();
00277     if (backend == 0) {
00278         fprintf(stderr,"libelektra: Can't initialize \"%s\" backend\n",
00279             backendName);
00280         errno=KDB_RET_NOSYS;
00281         return 3; /* error */
00282     }
00283 
00284     /* save the handle for future use */
00285     backend->dlHandle=dlhandle;
00286     
00287     /* let the backend initialize itself */
00288     if (backend->kdbOpen) rc=backend->kdbOpen();
00289     else {
00290         errno=KDB_RET_NOSYS;
00291         rc=4;
00292     }
00293     return rc;
00294 }
00295 
00296 
00297 
00311 int kdbClose() {
00312     int rc=0;
00313     
00314     if (backend && backend->kdbClose) rc=backend->kdbClose();
00315     else {
00316         errno=KDB_RET_NOSYS;
00317         return -1;
00318     }
00319     
00320     if (rc == 0) {
00321         if (backend->name) free(backend->name);
00322         kdbLibClose(backend->dlHandle);
00323         free(backend); backend=0;
00324     }
00325     
00326     return rc;
00327 }
00328 
00329 
00330 
00331 
00349 ssize_t unencode(char *encoded,void *returned) {
00350     char byteInHexa[5]="0x";
00351     char *readCursor=encoded;
00352     char *writeCursor=returned;
00353 
00354     if (!encoded) {
00355         if (returned) *(char *)returned=0;
00356         return 0;
00357     }
00358 
00359     byteInHexa[4]=0;
00360     while (*readCursor) {
00361         if (isspace((int)*readCursor)) 
00362         {
00363         readCursor++;
00364         continue;
00365         }
00366         if (isxdigit((int)*readCursor)) {
00367             long int converted;
00368             byteInHexa[2]=readCursor[0];
00369             byteInHexa[3]=readCursor[1];
00370             converted=strtol(byteInHexa,0,16); /* convert from hexa to a byte */
00371             *writeCursor=(unsigned char)converted;
00372 
00373             readCursor+=2;
00374             writeCursor++;
00375         } else {
00376             /* This is suposed to be a hex-digit stream. But is not, so return. */
00377             errno=KDB_RET_TYPEMISMATCH;
00378             return -1;
00379         }
00380     }
00381     return (long int)writeCursor-(long int)returned;
00382 }
00383 
00395 int kdbNeedsUTF8Conversion() {
00396 #if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV) && defined(CODESET)
00397     return strcmp(nl_langinfo(CODESET),"UTF-8");
00398 #else
00399     return 0;     
00400 #endif
00401 }
00402 
00403 
00428 int UTF8Engine(int direction, char **string, size_t *inputOutputByteSize) {
00429 /* Current solution is not very complete.
00430  * Iconv might well be available when a usable nl_langinfo is not.
00431  * In this case we it should be possible to determine charset through other means
00432  * See http://www.cl.cam.ac.uk/~mgk25/unicode.html#activate for more info on a possible solution */
00433  
00434 #if defined(HAVE_ICONV_H) && defined(HAVE_NL_LANGINFO) && defined(CODESET)
00435     char *currentCharset=0;
00436     char *converted=0;
00437     char *readCursor, *writeCursor;
00438     size_t bufferSize;
00439     iconv_t converter;
00440     
00441     if (kdbNeedsUTF8Conversion()) currentCharset=nl_langinfo(CODESET);
00442     else return 0;
00443 
00444     if (direction==UTF8_TO) converter=iconv_open("UTF-8",currentCharset);
00445     else converter=iconv_open(currentCharset,"UTF-8");
00446 
00447     if (converter == (iconv_t)(-1)) return -1;
00448 
00449     /* work with worst case, when all chars are wide */
00450     bufferSize=*inputOutputByteSize * 4;
00451     converted=malloc(bufferSize);
00452     if (!converted) return -1;
00453 
00454     readCursor=*string;
00455     writeCursor=converted;
00456     /* On some systems and with libiconv, arg1 is const char **. 
00457      * ICONV_CONST is defined by configure if the system needs this */
00458     if (iconv(converter,
00459             (ICONV_CONST char **)&readCursor,inputOutputByteSize,
00460             &writeCursor,&bufferSize) == (size_t)(-1)) {
00461         free(converted);
00462         iconv_close(converter);
00463         return -1;
00464     }
00465 
00466     /* calculate the UTF-8 string byte size, that will be returned */
00467     *inputOutputByteSize=writeCursor-converted;
00468     /* store the current unencoded string for future free */
00469     readCursor=*string;
00470     /* allocate an optimal size area to store the converted string */
00471     *string=malloc(*inputOutputByteSize);
00472     /* copy all that matters for returning */
00473     memcpy(*string,converted,*inputOutputByteSize);
00474     /* release memory used by passed string */
00475     free(readCursor);
00476     /* release buffer memory */
00477     free(converted);
00478     /* release the conversor engine */
00479     iconv_close(converter);
00480 #endif
00481     return 0;
00482 }
00483 
00484 
00485 
00504 ssize_t encode(void *unencoded, size_t size, char *returned) {
00505     char *readCursor=unencoded;
00506     char *writeCursor=returned;
00507     int blockStep=4; /* 4 bytes per block */
00508     int lineStep=8*blockStep; /* 8 blocks per line */
00509     int currentInBlock=0;
00510     int currentInLine=0;
00511 
00512     while ((readCursor-(char *)unencoded)<size) {
00513         sprintf(writeCursor,"%02x",*(unsigned char *)readCursor);
00514         readCursor++;
00515         writeCursor+=2;
00516         currentInBlock++;
00517         currentInLine++;
00518         if (currentInLine==lineStep) {
00519             *writeCursor='\n'; writeCursor++;
00520             currentInLine=0;
00521             currentInBlock=0;
00522         }
00523         if (currentInBlock==blockStep) {
00524             *writeCursor=' '; writeCursor++;
00525             currentInBlock=0;
00526         }
00527     }
00528     *writeCursor='\n';
00529     *++writeCursor=0;
00530     return writeCursor-returned;
00531 }
00532 
00533 
00534 
00535 
00536 
00550 int kdbGetValue(const char *keyname, char *returned,size_t maxSize) {
00551     Key *key;
00552     int rc=0;
00553 
00554     key=keyNew(keyname,KEY_SWITCH_END);
00555     rc=kdbGetKey(key);
00556     if (rc == 0) keyGetString(key,returned,maxSize);
00557     else rc=errno; /* store errno before a possible change */
00558     keyDel(key);
00559     errno=rc;
00560     return rc;
00561 }
00562 
00563 
00564 
00578 int kdbSetValue(const char *keyname, const char *value) {
00579     Key *key;
00580     int rc;
00581 
00582 /* TODO: check key type first */
00583     key=keyNew(keyname,KEY_SWITCH_END);
00584     rc=kdbGetKey(key);
00585     keySetString(key,value);
00586     rc=kdbSetKey(key);
00587     keyDel(key);
00588     return rc;
00589 }
00590 
00591 
00592 
00619 int kdbGetValueByParent(const char *parentName, const char *baseName, char *returned, size_t maxSize) {
00620     char *name;
00621     int retval=0;
00622     name = (char *)malloc(sizeof(char)*(strblen(parentName)+strblen(baseName)));
00623 
00624     sprintf(name,"%s/%s",parentName,baseName);
00625     retval = kdbGetValue(name,returned,maxSize);
00626     free(name);
00627     return retval;
00628 }
00629 
00630 
00631 
00642 int kdbSetValueByParent(const char *parentName, const char *baseName, const char *value) {
00643     char *name;
00644     int retval=0;
00645     name = (char *)malloc(sizeof(char)*(strblen(parentName)+strblen(baseName)));
00646 
00647     sprintf(name,"%s/%s",parentName,baseName);
00648     retval = kdbSetValue(name,value);
00649     free(name);
00650     return retval;
00651 }
00652 
00653 
00654 
00669 int kdbGetKeyByParent(const char *parentName, const char *baseName, Key *returned) {
00670     char *name;
00671     name = (char *)malloc(sizeof(char) * (strblen(parentName)+strblen(baseName)));
00672 
00673     sprintf(name,"%s/%s",parentName,baseName);  
00674     keySetName(returned,name);
00675   free(name);
00676     return kdbGetKey(returned);
00677 }
00678 
00679 
00687 int kdbGetKeyByParentKey(const Key *parent, const char *baseName, Key *returned) {
00688     size_t size=keyGetFullNameSize(parent);
00689     char *name;
00690     name = (char *)malloc(sizeof(char) * (size+strblen(baseName)));
00691 
00692     keyGetFullName(parent,name,size);
00693     name[size-1]='/';
00694     strcpy((char *)(name+size),baseName);
00695 
00696     keySetName(returned,name);
00697   free(name);
00698     return kdbGetKey(returned);
00699 }
00700 
00701 
00702 
00703 
00704 
00793 ssize_t kdbGetKeyChildKeys(const Key *parentKey, KeySet *returned, unsigned long options) {
00794     
00795     if (backend && backend->kdbGetKeyChildKeys)
00796         return backend->kdbGetKeyChildKeys(parentKey,returned,options);
00797     else {
00798         errno=KDB_RET_NOSYS;
00799         return -1;
00800     }
00801 }
00802 
00803 
00804 
00810 ssize_t kdbGetChildKeys(const char *parentName, KeySet *returned, unsigned long options) {
00811     Key *parentKey;
00812     ssize_t rc;
00813     
00814     parentKey=keyNew(parentName,KEY_SWITCH_END);
00815     rc=kdbGetKeyChildKeys(parentKey,returned,options);
00816     
00817     keyDel(parentKey);
00818     
00819     return rc;
00820 }
00821 
00822 
00823 
00835 ssize_t kdbGetRootKeys(KeySet *returned) {
00836     Key *system=0,*user=0;
00837 
00838     user=keyNew("user",KEY_SWITCH_NEEDSYNC,KEY_SWITCH_END);
00839     if (user->flags & KEY_SWITCH_FLAG) {
00840         keyDel(user);
00841         user=0;
00842     } else ksInsert(returned,user);
00843 
00844     system=keyNew("system",KEY_SWITCH_NEEDSYNC,KEY_SWITCH_END);
00845     if (system->flags & KEY_SWITCH_FLAG) {
00846         keyDel(system);
00847         system=0;
00848     } else ksInsert(returned,system);
00849 
00850     return returned->size;
00851 }
00852 
00853 
00854 
00873 int kdbStatKey(Key *key) {
00874     int rc=0;
00875     
00876     if (backend && backend->kdbStatKey)
00877         rc=backend->kdbStatKey(key);
00878     else {
00879         errno=KDB_RET_NOSYS;
00880         return -1;
00881     }
00882     
00883     return rc;
00884 }
00885 
00886 
00887 
00897 int kdbGetKey(Key *key) {
00898     int rc=0;
00899     
00900     if (backend && backend->kdbGetKey)
00901         rc=backend->kdbGetKey(key);
00902     else {
00903         errno=KDB_RET_NOSYS;
00904         return -1;
00905     }
00906     
00907     return rc;
00908 }
00909 
00910 
00911 
00931 int kdbSetKeys(KeySet *ks) {
00932     int rc=0;
00933     
00934     if (backend) {
00935         if(backend->kdbSetKeys)
00936             rc=backend->kdbSetKeys(ks);
00937       else 
00938             /* If backend doesn't provide kdbSetKeys, use the default */
00939             rc=kdbSetKeys_default(ks);  
00940     }
00941     else {
00942         errno=KDB_RET_NOSYS;
00943         return -1;
00944     }
00945     
00946     return rc;
00947 }
00948 
00949 
00950 
00961 int kdbSetKeys_default(KeySet *ks) {
00962     Key *current=ksCurrent(ks);
00963     int ret;
00964 
00965     if (!current) current=ksNext(ks);
00966     while (current) {
00967         if (keyNeedsSync(current))
00968             if ((ret=kdbSetKey(current))) /* check error */
00969                 return ret;
00970         
00971         current=ksNext(ks);
00972     }
00973 
00974     return 0;
00975 }
00976 
00977 
00978 
00987 int kdbSetKey(Key *key) {
00988     int rc=0;
00989     
00990     if (backend && backend->kdbSetKey)
00991         rc=backend->kdbSetKey(key);
00992     else {
00993         errno=KDB_RET_NOSYS;
00994         return -1;
00995     }
00996     
00997     return rc;
00998 }
00999 
01000 
01001 
01002 
01012 int kdbRename(Key *key, const char *newName) {
01013     int rc=0;
01014     
01015     if (backend && backend->kdbRename)
01016         rc=backend->kdbRename(key,newName);
01017     else {
01018         errno=KDB_RET_NOSYS;
01019         return -1;
01020     }
01021     
01022     return rc;
01023 }
01024 
01025 
01026 
01040 int kdbRemoveKey(const Key *key) {
01041     int rc=0;
01042     
01043     if (backend && backend->kdbRemoveKey)
01044         rc=backend->kdbRemoveKey(key);
01045     else {
01046         errno=KDB_RET_NOSYS;
01047         return -1;
01048     }
01049     
01050     return rc;
01051 }
01052 
01053 
01054 
01065 int kdbRemove(const char *keyName) {
01066     int rc=0;
01067     Key *key=0;
01068     
01069     key=keyNew(KEY_SWITCH_END);
01070     rc=keySetName(key,keyName);
01071     if (rc == 0) {
01072         keyDel(key);
01073         return -1; /* error */
01074     }
01075     
01076     rc=kdbRemoveKey(key);
01077     keyDel(key);
01078     
01079     return rc;
01080 }
01081 
01082 
01083 
01084 
01085 
01097 int kdbLink(const char *oldPath, const char *newKeyName) {
01098     Key *key;
01099     int rc;
01100 
01101     key=keyNew(newKeyName,KEY_SWITCH_END);
01102     keySetLink(key,oldPath);
01103 
01104     rc=kdbSetKey(key);
01105     keyDel(key);
01106 
01107     return rc;
01108 }
01109 
01110 
01111 
01112 
01171 uint32_t kdbMonitorKeys(KeySet *interests, uint32_t diffMask,
01172         unsigned long iterations, unsigned sleep) {
01173     
01174     uint32_t rc=0;
01175     
01176     if (backend) {
01177         if(backend->kdbMonitorKeys) 
01178             rc=backend->kdbMonitorKeys(interests,diffMask,iterations,sleep);
01179         else 
01180             /* If backend doesn't provide kdbMonitorKeys, then use the default */
01181             rc = kdbMonitorKeys_default(interests,diffMask,iterations,sleep);
01182     }
01183     else {
01184         errno=KDB_RET_NOSYS;
01185         return 0;
01186     }
01187     
01188     return rc;
01189 }
01190 
01191 
01199 uint32_t kdbMonitorKeys_default(KeySet *interests, uint32_t diffMask,
01200         unsigned long iterations, unsigned sleeptime) {
01201     Key *start,*current;
01202     uint32_t diff;
01203     int infinitum=0;
01204 
01205     if (!interests || !interests->size) return 0;
01206 
01207     /* Unacceptable 0 usecs sleep. Defaults to 1 second */
01208     if (!sleeptime) sleeptime=1000;
01209 
01210     if (!iterations) infinitum=1;
01211     else infinitum=0;
01212 
01213     current=start=ksCurrent(interests);
01214 
01215     while (infinitum || --iterations) {
01216         do {
01217             diff=kdbMonitorKey(current,diffMask,1,0);
01218             if (diff) return diff;
01219             current=ksNext(interests);
01220         } while (current!=start);
01221 
01222         /* Test if some iterations left . . . */
01223         if (infinitum || iterations) usleep(sleeptime);
01224     }
01225     return 0;
01226 }
01227 
01228 
01229 
01269 uint32_t kdbMonitorKey(Key *interest, uint32_t diffMask,
01270         unsigned long iterations, unsigned sleep) {
01271     
01272     int rc=0;
01273     
01274     if (backend) {
01275         if(backend->kdbMonitorKey)
01276           rc=backend->kdbMonitorKey(interest,diffMask,iterations,sleep);
01277         else
01278             rc=kdbMonitorKey_default(interest,diffMask,iterations,sleep);
01279     }
01280     else {
01281         errno=KDB_RET_NOSYS;
01282         return 0;
01283     }
01284     
01285     return rc;
01286 }
01287 
01288 
01289 
01290 
01298 uint32_t kdbMonitorKey_default(Key *interest, uint32_t diffMask,
01299         unsigned long iterations, unsigned sleeptime) {
01300     Key *tested;
01301     int rc;
01302     uint32_t diff;
01303     int infinitum=0;
01304 
01305     /* consistency */
01306     if (!interest || !keyGetNameSize(interest)) return 0;
01307 
01308     /* Unacceptable 0 usecs sleep. Defaults to 1 second */
01309     if (!sleeptime) sleeptime=1000;
01310 
01311     if (!iterations) infinitum=1;
01312     else infinitum=0;
01313 
01314     /* Work with a copy of the key */
01315     tested=keyNew(0);
01316     keyDup(interest,tested);
01317 
01318     while (infinitum || --iterations) {
01319         rc=kdbGetKey(tested);
01320         if (rc) {
01321             /* check what type of problem happened.... */
01322             switch (errno) {
01323                 case KDB_RET_NOCRED:
01324                     keyDel(tested);
01325                     return KEY_SWITCH_NEEDSYNC;
01326                 case KDB_RET_NOTFOUND:
01327                     keyDel(tested);
01328                     return KEY_SWITCH_FLAG;
01329             }
01330         }
01331         
01332         diff=keyCompare(tested,interest);
01333         
01334         if (diff & diffMask) {
01335             /* If differences interests us, return it, otherwise cycle again.
01336              * We don't loose the original key context in a KeySet because
01337              * we worked with a copy of the key.
01338              */
01339             keyDup(tested,interest);
01340             keyDel(tested);
01341             return diff;
01342         }
01343         /* Test if some iterations left . . . */
01344         if (infinitum || iterations) usleep(sleeptime);
01345     }
01346     
01347     keyDel(tested);
01348 
01349     return 0;
01350 }
01351 
01352 
01353 
01425 KDBBackend *kdbBackendExport(const char *backendName, ...) {
01426     va_list va;
01427     KDBBackend *returned;
01428     uint32_t method=0;
01429 
01430     if (backendName == 0) return 0;
01431     
01432     returned=malloc(sizeof(KDBBackend));
01433     memset(returned,0,sizeof(KDBBackend));
01434     
01435     returned->name=(char *)malloc(strblen(backendName));
01436     strcpy(returned->name,backendName);
01437     
01438     /* Start processing parameters */
01439     
01440     va_start(va,backendName);
01441 
01442     while ((method=va_arg(va,uint32_t))) {
01443         switch (method) {
01444             case KDB_BE_OPEN:
01445                 returned->kdbOpen=va_arg(va,kdbOpenPtr);
01446                 break;
01447             case KDB_BE_CLOSE:
01448                 returned->kdbClose=va_arg(va,kdbClosePtr);
01449                 break;
01450             case KDB_BE_STATKEY:
01451                 returned->kdbStatKey=va_arg(va,kdbStatKeyPtr);
01452                 break;
01453             case KDB_BE_GETKEY:
01454                 returned->kdbGetKey=va_arg(va,kdbGetKeyPtr);
01455                 break;
01456             case KDB_BE_SETKEY:
01457                 returned->kdbSetKey=va_arg(va,kdbSetKeyPtr);
01458                 break;
01459             case KDB_BE_RENAME:
01460                 returned->kdbRename=va_arg(va,kdbRenamePtr);
01461                 break;
01462             case KDB_BE_REMOVEKEY:
01463                 returned->kdbRemoveKey=va_arg(va,kdbRemoveKeyPtr);
01464                 break;
01465             case KDB_BE_GETCHILD:
01466                 returned->kdbGetKeyChildKeys=
01467                     va_arg(va,kdbGetChildKeysPtr);
01468                 break;
01469             case KDB_BE_SETKEYS:
01470                 returned->kdbSetKeys=va_arg(va,kdbSetKeysPtr);
01471                 break;
01472             case KDB_BE_MONITORKEY:
01473                 returned->kdbMonitorKey=
01474                     va_arg(va,kdbMonitorKeyPtr);
01475                 break;
01476             case KDB_BE_MONITORKEYS:
01477                 returned->kdbMonitorKeys=
01478                     va_arg(va,kdbMonitorKeysPtr);
01479                 break;
01480         }
01481     }
01482     va_end(va);
01483     
01484     return returned;
01485 }
01486 
01513 KDBInfo *kdbGetInfo(void) {
01514     KDBInfo *info=0;
01515 
01516     info=malloc(sizeof(struct _KDBInfo));
01517     memset(info,0,sizeof(struct _KDBInfo));
01518 
01519 #ifdef HAVE_CONFIG_H
01520     info->version=VERSION;
01521 #endif
01522 
01523     if (backend) {
01524         info->backendName=backend->name;
01525         info->backendIsOpen=1;
01526     } else {
01527         info->backendName=getenv("KDB_BACKEND");
01528         if (!info->backendName) info->backendName="default";
01529 
01530         info->backendIsOpen=0;
01531     }
01532 
01533     return info;
01534 }
01535 
01536 
01537 
01548 void kdbFreeInfo(KDBInfo *info) {
01549     free(info);
01550     info=0;
01551 }
01552 
01553 
01581 int kdbInfoToString(KDBInfo *info,char *string,size_t maxSize) {
01582     if (!info) {
01583         strncpy(string,"No info",maxSize);
01584         return -1;
01585     }
01586 
01587     snprintf(string,maxSize,
01588         "Elektra version: %s\nBackend name: %s\nBackend open: %s",
01589         info->version,
01590         info->backendName,
01591         info->backendIsOpen?"yes":"no");
01592 
01593     return 0;
01594 }
01595 

Generated on Sun Feb 19 10:05:37 2006 for Elektra Project by  doxygen 1.3.9.1