00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00080 #ifdef HAVE_CONFIG_H
00081 #include "config.h"
00082 #endif
00083
00084 #ifdef HAVE_UNISTD_H
00085 #include <unistd.h>
00086 #endif
00087
00088 #ifdef HAVE_ICONV
00089 #include <iconv.h>
00090 #endif
00091
00092 #ifdef HAVE_LOCALE_H
00093 #include <locale.h>
00094 #endif
00095
00096 #ifdef HAVE_LANGINFO_H
00097 #include <langinfo.h>
00098 #endif
00099
00100 #ifdef HAVE_SYS_TYPES_H
00101 #include <sys/types.h>
00102 #endif
00103
00104 #ifdef HAVE_SYS_STAT_H
00105 #include <sys/stat.h>
00106 #endif
00107
00108
00109 #include <stdlib.h>
00110 #include <stdarg.h>
00111 #include <ctype.h>
00112 #include <string.h>
00113 #include <errno.h>
00114 #include <stdio.h>
00115
00116
00117
00118 #include "kdbbackend.h"
00119 #include "kdbprivate.h"
00120 #include "kdbLibLoader.h"
00121
00122
00123 #ifdef WIN32
00124 #define usleep(x) Sleep(x)
00125 #endif
00126
00127
00128
00129 struct _KDBBackend {
00130
00131 pid_t pid;
00132 pthread_t tid;
00133 uid_t uid;
00134 gid_t gid;
00135 mode_t umask;
00136 char *userName;
00137
00138
00139 void *backendData;
00140
00141
00142 char *name;
00143
00144
00145
00146
00147 kdbOpenPtr kdbOpen;
00148 kdbClosePtr kdbClose;
00149
00150 kdbGetKeyPtr kdbGetKey;
00151 kdbSetKeyPtr kdbSetKey;
00152 kdbStatKeyPtr kdbStatKey;
00153 kdbRenamePtr kdbRename;
00154 kdbRemoveKeyPtr kdbRemoveKey;
00155 kdbGetChildKeysPtr kdbGetKeyChildKeys;
00156
00157
00158
00159
00160 kdbSetKeysPtr kdbSetKeys;
00161 kdbMonitorKeyPtr kdbMonitorKey;
00162 kdbMonitorKeysPtr kdbMonitorKeys;
00163
00164
00165 kdbLibHandle dlHandle;
00166 };
00167
00168
00169
00170
00200 int kdbOpen(KDBHandle *handle) {
00201 char *backendName=0;
00202
00203 backendName=getenv("KDB_BACKEND");
00204 if (backendName) return kdbOpenBackend(handle,backendName);
00205 else return kdbOpenBackend(handle,DEFAULT_BACKEND);
00206 }
00207
00208
00209
00231 int kdbOpenDefault(KDBHandle *handle) {
00232 return kdbOpenBackend(handle,DEFAULT_BACKEND);
00233 }
00234
00235
00236
00237
00291 int kdbOpenBackend(KDBHandle *handle, char *backendName) {
00292
00293 kdbLibHandle dlhandle=0;
00294 char backendlib[300];
00295 KDBBackendFactory kdbBackendFactory=0;
00296 int rc=0;
00297
00298 *handle=0;
00299
00300
00301 #ifdef HAVE_SETLOCALE
00302 setlocale(LC_ALL,"");
00303 #endif
00304
00305
00306 if ( (rc = kdbLibInit()) ) {
00307 errno=KDB_RET_NOSYS;
00308 return -1;
00309 }
00310
00311 sprintf(backendlib,"libelektra-%s",backendName);
00312 dlhandle=kdbLibLoad(backendlib);
00313 if (dlhandle == 0) {
00314 errno=KDB_RET_EBACKEND;
00315 return -1;
00316 }
00317
00318
00319
00320
00321 kdbBackendFactory=kdbLibSym(dlhandle,
00322 "kdbBackendFactory");
00323 if (kdbBackendFactory == 0) {
00324 errno=KDB_RET_NOSYS;
00325 return -1;
00326 }
00327
00328 *handle=(*kdbBackendFactory)();
00329 if ((*handle) == 0) {
00330 fprintf(stderr,"libelektra: Can't initialize \"%s\" backend\n",
00331 backendName);
00332 errno=KDB_RET_NOSYS;
00333 return -1;
00334 }
00335
00336
00337 (*handle)->dlHandle=dlhandle;
00338
00339
00340 (*handle)->pid = getpid();
00341 (*handle)->uid = getuid();
00342 (*handle)->gid = getgid();
00343 kdbhSetUserName(*handle, getenv("USER"));
00344 (*handle)->umask = umask(0); umask((*handle)->umask);
00345
00346
00347 if ((*handle)->kdbOpen) rc=(*handle)->kdbOpen(handle);
00348 else {
00349 errno=KDB_RET_NOSYS;
00350 rc=-1;
00351 }
00352 return rc;
00353 }
00354
00355
00356
00379 int kdbClose(KDBHandle *handle) {
00380 int rc=0;
00381
00382 if (*handle && (*handle)->kdbClose) rc=(*handle)->kdbClose(handle);
00383 else {
00384 errno=KDB_RET_NOSYS;
00385 return -1;
00386 }
00387
00388 if (rc == 0) {
00389 kdbLibClose((*handle)->dlHandle);
00390 free((*handle)->name);
00391 free((*handle)->userName);
00392 free(*handle); *handle=0;
00393 }
00394
00395 return rc;
00396 }
00397
00398
00399
00400
00401
00402
00496 ssize_t kdbGetKeyChildKeys(KDBHandle handle, const Key *parentKey,
00497 KeySet *returned, unsigned long options) {
00498
00499 if (handle && handle->kdbGetKeyChildKeys)
00500 return handle->kdbGetKeyChildKeys(handle,parentKey,returned,options);
00501 else {
00502 errno=KDB_RET_NOSYS;
00503 return -1;
00504 }
00505 }
00506
00507
00508
00527 int kdbStatKey(KDBHandle handle, Key *key) {
00528 int rc=0;
00529
00530 if (handle && handle->kdbStatKey)
00531 rc=handle->kdbStatKey(handle,key);
00532 else {
00533 errno=KDB_RET_NOSYS;
00534 return -1;
00535 }
00536
00537 return rc;
00538 }
00539
00540
00541
00554 int kdbGetKey(KDBHandle handle, Key *key) {
00555 int rc=0;
00556
00557 if (handle && handle->kdbGetKey)
00558 rc=handle->kdbGetKey(handle,key);
00559 else {
00560 errno=KDB_RET_NOSYS;
00561 return -1;
00562 }
00563
00564 return rc;
00565 }
00566
00567
00568
00611 int kdbSetKeys(KDBHandle handle, KeySet *ks) {
00612 int rc=0;
00613
00614 if (handle) {
00615 if(handle->kdbSetKeys)
00616 rc=handle->kdbSetKeys(handle,ks);
00617 else
00618
00619 rc=kdbSetKeys_default(handle,ks);
00620 }
00621 else {
00622 errno=KDB_RET_NOSYS;
00623 return -1;
00624 }
00625
00626 return rc;
00627 }
00628
00629
00630
00631
00644 int kdbSetKey(KDBHandle handle, Key *key) {
00645 int rc=0;
00646
00647 if (handle && handle->kdbSetKey)
00648 rc=handle->kdbSetKey(handle,key);
00649 else {
00650 errno=KDB_RET_NOSYS;
00651 return -1;
00652 }
00653
00654 return rc;
00655 }
00656
00657
00658
00659
00676 int kdbRename(KDBHandle handle, Key *key, const char *newName) {
00677 int rc=0;
00678
00679 if (handle) {
00680 if ( handle->kdbRename )
00681 rc=handle->kdbRename(handle,key,newName);
00682 else
00683 rc=kdbRename_default(handle, key, newName);
00684
00685 } else {
00686 errno=KDB_RET_NOSYS;
00687 return -1;
00688 }
00689
00690 return rc;
00691 }
00692
00693
00694
00709 int kdbRemoveKey(KDBHandle handle, const Key *key) {
00710 int rc=0;
00711
00712 if (handle && handle->kdbRemoveKey)
00713 rc=handle->kdbRemoveKey(handle,key);
00714 else {
00715 errno=KDB_RET_NOSYS;
00716 return -1;
00717 }
00718
00719 return rc;
00720 }
00721
00722
00723
00724
00736 int kdbLink(KDBHandle handle, const char *oldPath, const char *newKeyName) {
00737 Key *key;
00738 int rc;
00739
00740 key=keyNew(newKeyName,KEY_SWITCH_END);
00741 keySetLink(key,oldPath);
00742
00743 rc=kdbSetKey(handle,key);
00744 keyDel(key);
00745
00746 return rc;
00747 }
00748
00749
00750
00751
00814 uint32_t kdbMonitorKeys(KDBHandle handle, KeySet *interests, uint32_t diffMask,
00815 unsigned long iterations, unsigned sleep) {
00816
00817 uint32_t rc=0;
00818
00819 if (handle) {
00820 if(handle->kdbMonitorKeys)
00821 rc=handle->kdbMonitorKeys(handle,interests,diffMask,iterations,
00822 sleep);
00823 else
00824
00825 rc = kdbMonitorKeys_default(handle,interests,diffMask,iterations,
00826 sleep);
00827 }
00828 else {
00829 errno=KDB_RET_NOSYS;
00830 return 0;
00831 }
00832
00833 return rc;
00834 }
00835
00836
00846 uint32_t kdbMonitorKeys_default(KDBHandle handle, KeySet *interests,
00847 uint32_t diffMask, unsigned long iterations, unsigned sleeptime) {
00848 Key *start,*current;
00849 uint32_t diff;
00850 int infinitum=0;
00851
00852 if (!interests || !interests->size) return 0;
00853
00854
00855 if (!sleeptime) sleeptime=1000;
00856
00857 if (!iterations) infinitum=1;
00858 else infinitum=0;
00859
00860 current=start=ksCurrent(interests);
00861
00862 while (infinitum || --iterations) {
00863 do {
00864 diff=kdbMonitorKey(handle,current,diffMask,1,0);
00865 if (diff) return diff;
00866 current=ksNext(interests);
00867 } while (current!=start);
00868
00869
00870 if (infinitum || iterations) usleep(sleeptime);
00871 }
00872 return 0;
00873 }
00874
00875
00876
00918 uint32_t kdbMonitorKey(KDBHandle handle, Key *interest, uint32_t diffMask,
00919 unsigned long iterations, unsigned sleep) {
00920
00921 int rc=0;
00922
00923 if (handle) {
00924 if(handle->kdbMonitorKey)
00925 rc=handle->kdbMonitorKey(handle,interest,diffMask,iterations,sleep);
00926 else
00927 rc=kdbMonitorKey_default(handle,interest,diffMask,iterations,sleep);
00928 }
00929 else {
00930 errno=KDB_RET_NOSYS;
00931 return 0;
00932 }
00933
00934 return rc;
00935 }
00936
00937
00938
00939
00968 KDBInfo *kdbGetInfo(KDBHandle handle) {
00969 KDBInfo *info=0;
00970
00971 info=malloc(sizeof(struct _KDBInfo));
00972 memset(info,0,sizeof(struct _KDBInfo));
00973
00974 #ifdef HAVE_CONFIG_H
00975 info->version=VERSION;
00976 #endif
00977
00978 if (handle) {
00979 info->backendName=handle->name;
00980 info->backendIsOpen=1;
00981 } else {
00982 info->backendName=getenv("KDB_BACKEND");
00983 if (!info->backendName) info->backendName="default";
00984
00985 info->backendIsOpen=0;
00986 }
00987
00988 return info;
00989 }
00990
00991
00992
01003 void kdbFreeInfo(KDBInfo *info) {
01004 free(info);
01005 info=0;
01006 }
01007
01008
01009
01010
01011
01022 void *kdbhSetBackendData(KDBHandle handle, void *data) {
01023 return handle->backendData = data;
01024 }
01025
01026
01088 void *kdbhGetBackendData(const KDBHandle handle) {
01089 return handle->backendData;
01090 }
01091
01096 pid_t kdbhGetPID(const KDBHandle handle) {
01097 return handle->pid;
01098 }
01099
01105 pid_t kdbhSetPID(KDBHandle handle,pid_t pid) {
01106 return handle->pid=pid;
01107 }
01108
01113 pthread_t kdbhGetTID(const KDBHandle handle) {
01114 return handle->tid;
01115 }
01116
01122 pthread_t kdbhSetTID(KDBHandle handle,pthread_t tid) {
01123 return handle->tid=tid;
01124 }
01125
01126
01131 uid_t kdbhGetUID(const KDBHandle handle) {
01132 return handle->uid;
01133 }
01134
01140 uid_t kdbhSetUID(KDBHandle handle,uid_t uid) {
01141 return handle->uid=uid;
01142 }
01143
01148 gid_t kdbhGetGID(const KDBHandle handle) {
01149 return handle->gid;
01150 }
01151
01157 gid_t kdbhSetGID(KDBHandle handle,gid_t gid) {
01158 return handle->gid=gid;
01159 }
01160
01165 mode_t kdbhGetUMask(const KDBHandle handle) {
01166 return handle->umask;
01167 }
01168
01174 mode_t kdbhSetUMask(KDBHandle handle,mode_t umask) {
01175 return handle->umask=umask;
01176 }
01177
01183 char *kdbhGetUserName(const KDBHandle handle) {
01184 return handle->userName;
01185 }
01186
01193 char *kdbhSetUserName(KDBHandle handle,char *userName) {
01194 char *tmp;
01195 size_t size;
01196
01197 if ( userName ) {
01198 size = strblen(userName);
01199 tmp = realloc(handle->userName, size);
01200 if ( tmp ) {
01201 handle->userName = tmp;
01202 memcpy(handle->userName, userName, size);
01203 }
01204 } else {
01205 free(handle->userName);
01206 handle->userName = NULL;
01207 }
01208
01209 return handle->userName;
01210 }
01211
01218 char *kdbhSetBackendName(KDBHandle handle,char *backendName) {
01219 char *tmp;
01220 size_t size;
01221
01222 if ( backendName ) {
01223 size = strblen(backendName);
01224 tmp = realloc(handle->name, size);
01225 if ( tmp ) {
01226 handle->name = tmp;
01227 memcpy(handle->name, backendName, size);
01228 }
01229 } else {
01230 free(handle->name);
01231 handle->name = NULL;
01232 }
01233
01234 return handle->name;
01235 }
01236
01241 char *kdbhGetBackendName(KDBHandle handle) {
01242 return handle->name;
01243 }
01244
01274 int kdbInfoToString(KDBInfo *info,char *string,size_t maxSize) {
01275 if (!info) {
01276 strncpy(string,"No info",maxSize);
01277 return -1;
01278 }
01279
01280 snprintf(string,maxSize,
01281 "Elektra version: %s\nBackend name: %s\nBackend open: %s",
01282 info->version,
01283 info->backendName,
01284 info->backendIsOpen?"yes":"no");
01285
01286 return 0;
01287 }
01288
01289
01290
01361 KDBBackend *kdbBackendExport(const char *backendName, ...) {
01362 va_list va;
01363 KDBBackend *returned;
01364 uint32_t method=0;
01365
01366 if (backendName == 0) return 0;
01367
01368 returned=malloc(sizeof(KDBBackend));
01369 memset(returned,0,sizeof(KDBBackend));
01370
01371 returned->name=(char *)malloc(strblen(backendName));
01372 strcpy(returned->name,backendName);
01373
01374
01375
01376 va_start(va,backendName);
01377
01378 while ((method=va_arg(va,uint32_t))) {
01379 switch (method) {
01380 case KDB_BE_OPEN:
01381 returned->kdbOpen=va_arg(va,kdbOpenPtr);
01382 break;
01383 case KDB_BE_CLOSE:
01384 returned->kdbClose=va_arg(va,kdbClosePtr);
01385 break;
01386 case KDB_BE_STATKEY:
01387 returned->kdbStatKey=va_arg(va,kdbStatKeyPtr);
01388 break;
01389 case KDB_BE_GETKEY:
01390 returned->kdbGetKey=va_arg(va,kdbGetKeyPtr);
01391 break;
01392 case KDB_BE_SETKEY:
01393 returned->kdbSetKey=va_arg(va,kdbSetKeyPtr);
01394 break;
01395 case KDB_BE_RENAME:
01396 returned->kdbRename=va_arg(va,kdbRenamePtr);
01397 break;
01398 case KDB_BE_REMOVEKEY:
01399 returned->kdbRemoveKey=va_arg(va,kdbRemoveKeyPtr);
01400 break;
01401 case KDB_BE_GETCHILD:
01402 returned->kdbGetKeyChildKeys=
01403 va_arg(va,kdbGetChildKeysPtr);
01404 break;
01405 case KDB_BE_SETKEYS:
01406 returned->kdbSetKeys=va_arg(va,kdbSetKeysPtr);
01407 break;
01408 case KDB_BE_MONITORKEY:
01409 returned->kdbMonitorKey=
01410 va_arg(va,kdbMonitorKeyPtr);
01411 break;
01412 case KDB_BE_MONITORKEYS:
01413 returned->kdbMonitorKeys=
01414 va_arg(va,kdbMonitorKeysPtr);
01415 break;
01416 }
01417 }
01418 va_end(va);
01419
01420 return returned;
01421 }
01422
01437 static int kdbResolveKey(KDBHandle handle, const Key *key, char **resolvedKeyName) {
01438 Key *resolvedKey;
01439 char *kName, *tmp, *ptr;
01440 size_t size;
01441 int ret;
01442
01443 resolvedKey = keyNew(KEY_SWITCH_END);
01444 if ( resolvedKey == NULL ) return -1;
01445
01446 size = keyGetFullNameSize(key);
01447 kName = (char *) malloc(size);
01448 tmp = (char *) malloc(size);
01449 if ( (kName == NULL) || (tmp == NULL) ) {
01450 keyDel(resolvedKey);
01451 free(tmp);
01452 free(kName);
01453 return -1;
01454 }
01455
01456 if ( keyGetFullName(key, tmp, size) == -1 ) {
01457 keyDel(resolvedKey);
01458 free(tmp);
01459 free(kName);
01460 return -1;
01461 }
01462
01463 size = 0;
01464 ptr = tmp;
01465 while ( *(ptr = keyNameGetOneLevel(ptr+size, &size)) != 0 ) {
01466 strncpy(kName, ptr, size);
01467 kName[size] = '\0';
01468
01469 if ( keyAddBaseName(resolvedKey, kName) == -1 ) {
01470
01471 keyDel(resolvedKey);
01472 free(tmp);
01473 free(kName);
01474 return -1;
01475 }
01476
01477
01478 for(;;) {
01479 ret = kdbStatKey(handle, resolvedKey);
01480 if ( (ret == 0) && !keyIsLink(resolvedKey) ) {
01481
01482 break;
01483
01484 } else if ( (ret == -1) && (errno == KDB_RET_NOTFOUND) ) {
01485
01486 break;
01487
01488 } else if ( ret == -1 ) {
01489
01490
01491 keyDel(resolvedKey);
01492 free(tmp);
01493 free(kName);
01494 return -1;
01495 }
01496
01497
01498
01499 ret = keySetName(resolvedKey, keyStealValue(resolvedKey));
01500 if ( ret == 0 ) {
01501
01502
01503 keyDel(resolvedKey);
01504 free(tmp);
01505 free(kName);
01506 return -1;
01507 }
01508
01509
01510
01511 }
01512 }
01513 free(tmp);
01514 free(kName);
01515
01516 size = keyGetFullNameSize(resolvedKey);
01517 *resolvedKeyName = (char *) malloc(size);
01518 if ( *resolvedKeyName == NULL ) {
01519 keyDel(resolvedKey);
01520 return -1;
01521 }
01522
01523 keyGetFullName(resolvedKey, *resolvedKeyName, size);
01524 keyDel(resolvedKey);
01525
01526 return 0;
01527 }