00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026
00027 #ifndef HASGETOPT
00028 #include "BSDgetopt.h"
00029 #endif
00030
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033 #include <stdio.h>
00034 #include <time.h>
00035 #include <locale.h>
00036 #include <unistd.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #ifdef HAVE_GRP_H
00040 #include <grp.h>
00041 #endif
00042 #ifdef HAVE_PWD_H
00043 #include <pwd.h>
00044 #endif
00045 #include <ctype.h>
00046 #include <ltdl.h>
00047 #include <assert.h>
00048
00049 #ifdef HAVE_WIN32
00050 #include <fcntl.h>
00051 #endif
00052
00053 #include "kdb.h"
00054 #include "kdbLibLoader.h"
00055
00056 #define CMD_GET 1
00057 #define CMD_SET 2
00058 #define CMD_REMOVE 3
00059 #define CMD_LIST 4
00060 #define CMD_LINK 5
00061 #define CMD_EDIT 6
00062 #define CMD_LOAD 7
00063 #define CMD_SAVE 8
00064 #define CMD_MONITOR 9
00065 #define CMD_MOVE 10
00066 #define CMD_INFO 25
00067 #define CMD_HELP 30
00068
00069 #define ARGSIZE 30
00070
00071
00072 #ifdef HAVE_WIN32
00073 #define mkstemp(m) open(mktemp(m), O_RDWR)
00074 #endif
00075
00076
00077 ssize_t unencode(char *encoded, void *returned);
00078
00079
00080
00081 int (*ksFromXMLfile)(KeySet *ks,char *filename);
00082 int (*ksFromXML)(KeySet *ks,int fd);
00083
00084
00085
00091 char *argComment=0;
00092 char *argFile=0;
00093 char *argData=0;
00094 char *argKeyName=0;
00095 char *argDomain=0;
00096 uid_t *argUID=0;
00097 uid_t *argGID=0;
00098 int argCommand=0;
00099 int argRecursive=0;
00100 int argLong=0;
00101 int argValue=0;
00102 int argAll=0;
00103 int argSort=1;
00104 int argDescriptive=0;
00105 int argFullName=0;
00106 int argShow=1;
00107 int argShell=0;
00108 int argXML=0;
00109 int argDir=0;
00110 int argHelp=0;
00111 mode_t argMode=0;
00112 int argType=KEY_TYPE_UNDEFINED;
00113
00114
00115
00116 int commandHelp();
00117 int helpCommand(int command);
00118
00119
00120 int parseCommandLine(int argc, char *argv[]) {
00121 char sargType[ARGSIZE],argUser[ARGSIZE],argGroup[ARGSIZE];
00122 char sargMode[ARGSIZE],sargCommand[ARGSIZE];
00123 char * keyEnv;
00124 size_t keyEnvLength=0, keyOptLength=0, keyOldLength;
00125
00126 int opt;
00127
00128 *sargType=*argUser=*argGroup=*sargCommand=*sargMode=0;
00129
00130 while ((opt=getopt(argc,argv,"ab:c:dfg:hilm:nrRst:u:vx"))!=-1)
00131 {
00132 if (opt == EOF)
00133 break;
00134 switch (opt)
00135 {
00136 case 'a':
00137 argAll=1;
00138 break;
00139 case 'b':
00140 argFile=realloc(argFile,strlen(optarg)+1);
00141 assert(argFile!=NULL);
00142 strcpy(argFile,optarg);
00143 break;
00144 case 'c':
00145 argComment=realloc(argComment,strlen(optarg)+1);
00146 assert(argComment!=NULL);
00147 strcpy(argComment,optarg);
00148 break;
00149 case 'd':
00150 argDescriptive=1;
00151 argLong=1;
00152 argDir=1;
00153 break;
00154 case 'f':
00155 argFullName=1;
00156 break;
00157 case 'g':
00158 strncpy(argGroup,optarg,ARGSIZE);
00159 break;
00160 case 'h':
00161 argHelp=1;
00162 break;
00163 case 'i':
00164 argShow=0;
00165 break;
00166 case 'l':
00167 argLong=1;
00168 break;
00169 case 'm':
00170 strncpy(sargMode,optarg,ARGSIZE);
00171 break;
00172 case 'n':
00173 argSort=0;
00174 break;
00175 case 'R':
00176 case 'r':
00177 argRecursive=KDB_O_RECURSIVE;
00178 break;
00179 case 's':
00180 argShell=1;
00181 break;
00182 case 't':
00183 strncpy(sargType,optarg,ARGSIZE);
00184 break;
00185 case 'u':
00186 strncpy(argUser,optarg,ARGSIZE);
00187 break;
00188 case 'v':
00189 argValue=1;
00190 break;
00191 case 'x':
00192 argXML=1;
00193 break;
00194 default:
00195 fprintf(stderr, "Unknown error (%d %c) in parsing arguments\n",
00196 opt,opt);
00197 break;
00198 }
00199 }
00200
00201 if (optind < argc)
00202 {
00203 strncpy(sargCommand,argv[optind],ARGSIZE);
00204 optind ++;
00205 } else {
00206 commandHelp();
00207 exit(0);
00208 }
00209
00211 keyEnv = getenv ("KDB_ROOT");
00212 if (keyEnv) keyEnvLength = strblen (keyEnv);
00213 else keyEnvLength = 0;
00214 if (optind < argc)
00215 {
00216 keyOptLength = strblen (argv[optind]);
00217 argKeyName=realloc(argKeyName,
00218 keyEnvLength + keyOptLength + 1);
00219 assert(argKeyName!=NULL);
00220 if (keyEnv) strncpy (argKeyName, keyEnv, keyEnvLength);
00221 strncpy(argKeyName + keyEnvLength, argv[optind], keyOptLength);
00222 if (keyEnv) *(argKeyName+keyEnvLength-1) = '/';
00223 optind ++;
00224 } else if (keyEnv) {
00225 argKeyName=realloc(argKeyName, keyEnvLength + 1);
00226 assert(argKeyName!=NULL);
00227 if (keyEnv) strncpy (argKeyName, keyEnv, keyEnvLength);
00228 }
00229
00230
00231 keyOptLength = 0;
00232 keyOldLength = 0;
00233 while (optind < argc)
00234 {
00235 keyOptLength += strblen(argv[optind]);
00236 argData=realloc(argData,keyOptLength + 1);
00237 assert(argData!=NULL);
00238 if (keyOldLength > 0) *(argData+keyOldLength-1) = ' ';
00239 strcpy(argData+keyOldLength, argv[optind]);
00240 optind ++;
00241 keyOldLength = keyOptLength;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 if (!strcmp(sargCommand,"ls")) argCommand=CMD_LIST;
00255 else if (!strcmp(sargCommand,"set")) argCommand=CMD_SET;
00256 else if (!strcmp(sargCommand,"get")) argCommand=CMD_GET;
00257 else if (!strcmp(sargCommand,"ln")) argCommand=CMD_LINK;
00258 else if (!strcmp(sargCommand,"rm")) argCommand=CMD_REMOVE;
00259 else if (!strcmp(sargCommand,"vi")) argCommand=CMD_EDIT;
00260 else if (!strcmp(sargCommand,"edit")) argCommand=CMD_EDIT;
00261 else if (!strcmp(sargCommand,"load")) argCommand=CMD_LOAD;
00262 else if (!strcmp(sargCommand,"import")) argCommand=CMD_LOAD;
00263 else if (!strcmp(sargCommand,"save")) argCommand=CMD_SAVE;
00264 else if (!strcmp(sargCommand,"export")) argCommand=CMD_SAVE;
00265 else if (!strcmp(sargCommand,"mon")) argCommand=CMD_MONITOR;
00266 else if (!strcmp(sargCommand,"monitor")) argCommand=CMD_MONITOR;
00267 else if (!strcmp(sargCommand,"mv")) argCommand=CMD_MOVE;
00268 else if (!strcmp(sargCommand,"info")) argCommand=CMD_INFO;
00269 else if (!strcmp(sargCommand,"help")) argCommand=CMD_HELP;
00270 else {
00271 fprintf(stderr,"kdb: Invalid subcommand.\n");
00272 exit(1);
00273 }
00274
00275
00276 if (*sargType!=0) {
00277
00278 if (!strcmp(sargType,"string")) argType=KEY_TYPE_STRING;
00279 else if (!strcmp(sargType,"bin")) argType=KEY_TYPE_BINARY;
00280 else if (!strcmp(sargType,"binary")) argType=KEY_TYPE_BINARY;
00281 else if (!strcmp(sargType,"dir")) argDir=1;
00282 else if (!strcmp(sargType,"link")) argType=KEY_TYPE_LINK;
00283 else {
00284 argType=strtol(sargType,0,10);
00285 if (errno == ERANGE || errno == EINVAL)
00286
00287 argType=KEY_TYPE_UNDEFINED;
00288 }
00289 } else if (argCommand==CMD_SET) {
00290 argType=KEY_TYPE_STRING;
00291 }
00292
00293 #ifdef HAVE_PWD_H
00294
00295 if (*argUser) {
00296 if (isdigit(*argUser)) {
00297 argUID=malloc(sizeof(uid_t));
00298 *argUID=atoi(argUser);
00299 } else {
00300 struct passwd *pwd;
00301 pwd=getpwnam(argUser);
00302 if (pwd) {
00303 argUID=malloc(sizeof(uid_t));
00304 *argUID=pwd->pw_uid;
00305 } else {
00306 fprintf(stderr,"kdb: Invalid user \'%s\'. Ignoring\n", argUser);
00307 }
00308 }
00309 }
00310 #endif
00311 #ifdef HAVE_GRP_H
00312
00313 if (*argGroup) {
00314 if (isdigit(*argGroup)) {
00315 argGID=malloc(sizeof(gid_t));
00316 *argGID=atoi(argGroup);
00317 } else {
00318 struct group *grp;
00319 grp=getgrnam(argGroup);
00320 if (grp) {
00321 argGID=malloc(sizeof(gid_t));
00322 *argGID=grp->gr_gid;
00323 } else {
00324 fprintf(stderr,"kdb: Invalid group \'%s\'. Ignoring\n",argGroup);
00325 }
00326 }
00327 }
00328 #endif
00329
00330
00331
00332 if (*sargMode!=0) argMode=strtol(sargMode,0,8);
00333
00334 return argCommand;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 void listAccess(Key *key,char *readable) {
00347 mode_t mode=keyGetAccess(key);
00348
00349 if (keyIsDir(key)) readable[0]='d';
00350 #ifdef S_ISLNK
00351 else if (keyIsLink(key)) readable[0]='l';
00352 #endif
00353 else readable[0]='-';
00354
00355 readable[1] = mode & S_IRUSR ? 'r' : '-';
00356 readable[2] = mode & S_IWUSR ? 'w' : '-';
00357 readable[3] = mode & S_IXUSR ? 'x' : '-';
00358 #ifdef HAVE_WIN32
00359 readable[4] = 0;
00360 #else
00361 readable[4] = mode & S_IRGRP ? 'r' : '-';
00362 readable[5] = mode & S_IWGRP ? 'w' : '-';
00363 readable[6] = mode & S_IXGRP ? 'x' : '-';
00364 readable[7] = mode & S_IROTH ? 'r' : '-';
00365 readable[8] = mode & S_IWOTH ? 'w' : '-';
00366 readable[9] = mode & S_IXOTH ? 'x' : '-';
00367 readable[10]= 0;
00368 #endif
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378 void listTime(time_t when,char *readable) {
00379 time_t current_time=time(0);
00380 char buf[400];
00381 #ifndef HAVE_CTIME_R
00382 char *ctimep = NULL;
00383 #endif
00384 time_t six_months_ago;
00385 int recent;
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 six_months_ago = current_time - 31556952 / 2;
00396 recent = (six_months_ago <= when) && (when <= current_time);
00397 #ifdef HAVE_CTIME_R
00398 ctime_r(&when,buf);
00399 #else
00400 ctimep = ctime(&when);
00401 strncpy(buf, ctimep, sizeof(buf));
00402 #endif
00403 memcpy(readable,buf+4,7);
00404 if (recent) {
00405 memcpy(readable,buf+4,12);
00406 readable[12]=0;
00407 } else {
00408 memcpy(readable,buf+4,7);
00409 readable[7]=' ';
00410 memcpy(readable+8,buf+20,4);
00411 readable[12]=0;
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420
00421 void listSingleKey(Key *key) {
00422 char buffer[400];
00423 char *p=buffer;
00424
00425 if (argLong) {
00426 struct passwd *pwd;
00427 struct group *grp;
00428
00429 listAccess(key,p);
00430 p+=strlen(p);
00431 *p=' '; p++;
00432 *p=' '; p++;
00433 *p=' '; p++;
00434 #ifdef HAVE_PWD_H
00435 if ( (pwd=getpwuid(keyGetUID(key))) != NULL ) {
00436 strcpy(p,pwd->pw_name);
00437 p+=strlen(p);
00438 *p=' '; p++;
00439 *p=' '; p++;
00440 } else {
00441 strcpy(p, "<unknown>");
00442 p+=strlen(p);
00443 *p=' '; p++;
00444 *p=' '; p++;
00445 }
00446 #endif
00447 #ifdef HAVE_GRP_H
00448 if ( (grp=getgrgid(keyGetGID(key))) != NULL ) {
00449 strcpy(p,grp->gr_name);
00450 p+=strlen(p);
00451 *p=' '; p++;
00452 } else {
00453 strcpy(p, "<unknow>");
00454 p+=strlen(p);
00455 *p=' '; p++;
00456 *p=' '; p++;
00457 }
00458 #endif
00459 sprintf(p,"%*d ",5,keyGetRecordSize(key));
00460 p+=strlen(p);
00461
00462 listTime(keyGetMTime(key),p);
00463 p+=strlen(p);
00464 *p=' '; p++;
00465 }
00466 if (argFullName) keyGetFullName(key,p,sizeof(buffer)-(p-buffer));
00467 else keyGetName(key,p,sizeof(buffer)-(p-buffer));
00468 if (argValue && (keyGetValueSize(key)>0)) {
00469 uint8_t ktype;
00470
00471 p+=strlen(p);
00472 *p='='; p++;
00473
00474 ktype=keyGetType(key);
00475 if (ktype >= KEY_TYPE_STRING)
00476 p+=keyGetString(key,p,sizeof(buffer)-(p-buffer));
00477 else if (ktype >= KEY_TYPE_BINARY)
00478 p+=sprintf(p,"<BINARY VALUE>");
00479 else if (ktype == KEY_TYPE_LINK)
00480 p+=keyGetLink(key,p,sizeof(buffer)-(p-buffer));
00481
00482 *p=0;
00483 }
00484 puts(buffer);
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494 void listAllKeys (KeySet * ks) {
00495 size_t listSize=ksGetSize(ks);
00496 Key *walker;
00497
00498 if (listSize == 1) listSingleKey(ksHead(ks));
00499 else if (listSize > 1) {
00500 ksRewind(ks);
00501 while ((walker=ksNext(ks)))
00502 listSingleKey(walker);
00503 }
00504 }
00505
00506
00507
00508
00509
00510
00511
00512 void listAllKeysForShell(KeySet *ks) {
00513 Key *walker=0;
00514 int isParent=0;
00515 size_t parentNameSize=strlen(argKeyName);
00516 char *keyName=0;
00517 void *keyValue=0;
00518 char *child=0;
00519
00520 ksRewind(ks);
00521 while ((walker=ksNext(ks))) {
00522 keyName=keyStealName(walker);
00523 isParent=(int)strstr(keyName,argKeyName);
00524
00525 if (isParent) {
00526 keyName+=parentNameSize;
00527 while (*keyName && *keyName == '/') keyName++;
00528 } else {
00529 keyName=0;
00530 }
00531
00532
00533
00534 if (keyName) {
00535
00536 while ((child=strchr(keyName,'/'))) {
00537 fwrite(keyName,child-keyName,1,stdout);
00538 fputc('_',stdout);
00539 keyName=child+1;
00540 }
00541 fputs(keyName,stdout);
00542
00543
00544 fputs("=\"",stdout);
00545 keyValue=keyStealValue(walker);
00546 if (keyValue) fputs(keyValue,stdout);
00547 fputs("\";\n",stdout);
00548 }
00549 }
00550 }
00551
00552
00553
00554
00565 int commandRemove(KDBHandle handle) {
00566 if (!argKeyName) {
00567 fprintf(stderr,"kdb rm: No key name\n");
00568 return -1;
00569 }
00570
00571 if (kdbRemove(handle,argKeyName)) {
00572 char error[300];
00573
00574 sprintf(error,"kdb rm: \'%s\'",argKeyName);
00575 kdbPrintError(error);
00576 return -1;
00577 }
00578 return 0;
00579 }
00580
00581
00582
00596 int commandMove(KDBHandle handle) {
00597 Key *key;
00598 size_t size=0;
00599 int rc;
00600
00601
00602 if (!argKeyName) {
00603 fprintf(stderr,"kdb mv: No target specified\n");
00604 return -1;
00605 }
00606
00607 if (!argData) {
00608 fprintf(stderr,"kdb mv: \'%s\': No destination specified\n",argKeyName);
00609 return -1;
00610 }
00611
00612 key=keyNew(argKeyName,KEY_SWITCH_END);
00613 size=keyGetNameSize(key);
00614
00615 if (size == 0) {
00616 char error[100];
00617
00618 sprintf(error,"kdb mv: \'%s\'", argKeyName);
00619 kdbPrintError(error);
00620
00621 keyDel(key);
00622 return 1;
00623 }
00624
00625 rc=kdbRename(handle,key,argData);
00626 if (rc != 0) {
00627
00628 switch (errno) {
00629
00630 }
00631 }
00632
00633 keyDel(key);
00634
00635 return rc;
00636 }
00637
00638
00639
00659 int commandSet(KDBHandle handle) {
00660 Key *key=0;
00661 int ret=0;
00662 char error[200];
00663 size_t offset=0;
00664
00665
00666
00667 if (!argKeyName) {
00668 fprintf(stderr,"kdb set: No key name\n");
00669 return -1;
00670 }
00671
00672 key=keyNew(argKeyName,KEY_SWITCH_END);
00673 ret=kdbGetKey(handle,key);
00674 if (ret == 0) {
00675
00676 if (argType==KEY_TYPE_UNDEFINED) argType=keyGetType(key);
00677 } else if (errno!=KDB_RET_NOTFOUND) {
00678
00679 sprintf(error,"kdb set: %s",argKeyName);
00680 kdbPrintError(error);
00681
00682 return -1;
00683 }
00684
00685
00686
00687 if (argUID) keySetUID(key,*argUID);
00688 if (argGID) keySetGID(key,*argGID);
00689 if (argMode) keySetAccess(key,argMode);
00690 if (argDir) {
00691 mode_t mask=umask(0);
00692 umask(mask);
00693 keySetDir(key,mask);
00694 }
00695
00696 if (argComment) keySetComment(key,argComment);
00697
00698 if (argFile) {
00699 FILE *f;
00700 int end=0;
00701
00702 if (argData) free(argData);
00703 argData=0;
00704 f=fopen(argFile,"r");
00705
00706 if (!f) {
00707 sprintf(error,"kdb set: \'%s\'",argFile);
00708 kdbPrintError(error);
00709 return -1;
00710 }
00711 while (! end) {
00712 char buffer[100];
00713 ssize_t r;
00714
00715 r=read(fileno(f),buffer,sizeof(buffer));
00716 switch (r) {
00717 case 0:
00718 r=lseek(fileno(f),0,SEEK_END)-offset;
00719 end=1;
00720 break;
00721 case -1:
00722
00723 fprintf(stderr,"kdb set: \'%s\': problem reading file\n",argFile);
00724 fclose(f);
00725 return -1;
00726 }
00727 argData=realloc(argData,offset+r);
00728 assert(argData!=NULL);
00729 memcpy(argData+offset,buffer,r);
00730 offset+=r;
00731 }
00732 fclose(f);
00733 }
00734
00735
00736
00737 if (argType == KEY_TYPE_UNDEFINED)
00738 keySetString(key,argData);
00739 else if (argType == KEY_TYPE_LINK)
00740 keySetLink(key,argData);
00741 else if (argData) {
00742
00743
00744 if (offset) keySetRaw(key,argData,offset);
00745 else if (KEY_TYPE_BINARY <= argType && argType < KEY_TYPE_STRING)
00746
00747 keySetRaw(key,argData,strblen(argData)-1);
00748 else keySetRaw(key,argData,strblen(argData));
00749
00750
00751 keySetType(key,argType);
00752 }
00753
00754
00755 ret=kdbSetKey(handle,key);
00756 if (ret) {
00757 sprintf(error,"kdb set: \'%s\'",argKeyName);
00758 kdbPrintError(error);
00759 }
00760
00761 keyDel(key);
00762
00763 return ret;
00764 }
00765
00766
00767
00768
00769
00770
00783 int commandLink(KDBHandle handle) {
00784 int rc;
00785
00786
00787 if (!argKeyName) {
00788 fprintf(stderr,"kdb ln: No target specified\n");
00789 return -1;
00790 }
00791
00792 if (!argData) {
00793 fprintf(stderr,"kdb ln: \'%s\': No destination specified\n",argKeyName);
00794 return -1;
00795 }
00796
00797 if ((rc=kdbLink(handle,argKeyName,argData))) {
00798 kdbPrintError("kdb ln");
00799 }
00800
00801 return rc;
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00838 int commandList(KDBHandle handle) {
00839 KeySet *ks;
00840 KeySet *tmp;
00841 ssize_t ret;
00842 unsigned long options=0;
00843 char * buffer;
00844 Key *walker=0;
00845
00846
00847
00848 if (argSort) options |= KDB_O_SORT;
00849 if (argRecursive) options |= KDB_O_RECURSIVE;
00850 if (argAll) options |= KDB_O_INACTIVE;
00851 if (!argValue) options |= KDB_O_STATONLY;
00852
00853
00854 if (argFullName) options |= KDB_O_FULLNAME | KDB_O_FULLUGID;
00855 options |= KDB_O_XMLHEADERS | KDB_O_HIER;
00856
00857
00858 if (!argShell) options |= KDB_O_DIR | KDB_O_NFOLLOWLINK;
00859
00860 ks=ksNew();
00861
00862 if (!argKeyName || strcmp(argKeyName, "/") == 0) {
00863
00864
00865 tmp=ksNew();
00866 kdbGetRootKeys(handle,tmp);
00867
00868 if (argRecursive) {
00869
00870 while ((walker=ksPop(tmp))) {
00871
00872
00873
00874 KeySet *thisRoot=ksNew();
00875
00876 ret=kdbGetKeyChildKeys(handle,walker,thisRoot,options);
00877
00878
00879
00880
00881 ksAppend(ks,walker);
00882 ksAppendKeys(ks,thisRoot);
00883 ksDel(thisRoot);
00884 }
00885 } else ksAppendKeys(ks,tmp);
00886 ksDel(tmp);
00887 } else {
00888
00889
00890 if (argKeyName[0] == '/')
00891 {
00892 buffer = malloc (strlen (argKeyName)+sizeof("system\0"));
00893
00894 tmp = ksNew ();
00895 strcpy (buffer, "system\0");
00896 ret=kdbGetChildKeys(handle,strcat (buffer, argKeyName),tmp,options);
00897
00898 ksAppendKeys (ks,tmp);
00899 ksDel (tmp);
00900
00901 tmp = ksNew ();
00902 strcpy (buffer, "user\0");
00903 ret=kdbGetChildKeys(handle,strcat (buffer, argKeyName),tmp,options);
00904
00905 ksAppendKeys (ks,tmp);
00906 ksDel (tmp);
00907
00908 free (buffer);
00909 } else {
00910 ret=kdbGetChildKeys(handle,argKeyName,ks,options);
00911 }
00912
00913 if (ret<0) {
00914
00915 if (errno==ENOTDIR) {
00916
00917 Key *key=keyNew(argKeyName,KEY_SWITCH_END);
00918
00919 if (argValue)
00920
00921 ret=kdbGetKey(handle,key);
00922 else ret=kdbStatKey(handle,key);
00923
00924 if (ret == 0) ksAppend(ks,key);
00925 else {
00926
00927 char error[200];
00928
00929 keyDel(key);
00930 ksDel(ks);
00931
00932 sprintf(error,"kdb ls: %s",argKeyName);
00933 kdbPrintError(error);
00934 return ret;
00935 }
00936
00937 } else {
00938 char error[200];
00939
00940 ksDel(ks);
00941
00942 sprintf(error,"kdb ls: %s",argKeyName);
00943 kdbPrintError(error);
00944 return ret;
00945 }
00946 }
00947 }
00948
00949 if (argShow) {
00950 if (argXML) ksToStream(ks,stdout,options);
00951 else if (argShell) listAllKeysForShell(ks);
00952 else listAllKeys(ks);
00953 }
00954
00955 ksDel(ks);
00956 return 0;
00957 }
00958
00959
00960
00961
00962
00963
00964
00984 int commandGet(KDBHandle handle) {
00985 int ret;
00986 Key *key = 0;
00987 char *buffer = 0;
00988 char *p;
00989 size_t size,cs=0;
00990 uint8_t keyType;
00991 char error[200];
00992
00993
00994 if (!argKeyName) {
00995 fprintf(stderr,"kdb get: No key name\n");
00996 fprintf(stderr,"run kdb get -h for more info\n");
00997 return -1;
00998 }
00999
01000 key=keyNew(argKeyName,KEY_SWITCH_END);
01001
01002 if (argKeyName[0] == '/')
01003 {
01004 buffer = malloc (strlen (argKeyName)+sizeof("system\0"));
01005
01006 strcpy (buffer, "user\0");
01007 keySetName(key, strcat (buffer, argKeyName));
01008 ret=kdbGetKey(handle,key);
01009 if (ret == 0) goto done;
01010
01011 strcpy (buffer, "system\0");
01012 keySetName(key, strcat (buffer, argKeyName));
01013 ret=kdbGetKey(handle,key);
01014 if (ret == 0) goto done;
01015 } else {
01016 ret=kdbGetKey(handle,key);
01017 }
01018
01019 if (ret) {
01020 sprintf(error,"kdb get: %s",argKeyName);
01021 kdbPrintError(error);
01022 goto cleanup;
01023 }
01024 done:
01025 size=keyGetValueSize(key);
01026 if (argDescriptive) {
01027 cs=keyGetCommentSize(key);
01028 if (cs) size+=cs+3;
01029 }
01030 if (argShell) {
01031 size+=keyGetBaseNameSize(key);
01032 size+=2;
01033 } else if (argLong) {
01034 if (argFullName) size+=keyGetFullNameSize(key);
01035 else size+=keyGetNameSize(key);
01036 }
01037
01038
01039 if (buffer) free (buffer);
01040 p=buffer=malloc(size);
01041
01042
01043 if (argDescriptive) {
01044 if (cs) {
01045 p+=sprintf(p,"# ");
01046 p+=keyGetComment(key,p,size-(p-buffer));
01047 *--p='\n'; p++;
01048 }
01049 }
01050 if (argShell) {
01051 p+=keyGetBaseName(key,p,size-(p-buffer));
01052 *--p='='; p++;
01053 *p='\"'; p++;
01054 } else if (argLong) {
01055 if (argFullName) p+=keyGetFullName(key,p,size-(p-buffer));
01056 else p+=keyGetName(key,p,size-(p-buffer));
01057 *--p='='; p++;
01058 }
01059
01060 keyType=keyGetType(key);
01061
01062 if (keyIsBin(key)) p+=keyGetBinary(key,p,size-(p-buffer));
01063 else p+=keyGetString(key,p,size-(p-buffer));
01064 if (argShell) {
01065 *--p='\"'; p++;
01066 *p=0;
01067 }
01068 if (keyIsBin(key)) fwrite(buffer,size,1,stdout);
01069 else printf("%s\n",buffer);
01070
01071 ret = 0;
01072
01073 cleanup:
01074 free(buffer);
01075 keyDel(key);
01076
01077 return ret;
01078 }
01079
01080
01081
01082
01083
01084
01113 int commandEdit(KDBHandle handle) {
01114 KeySet *ks;
01115 KeySet *ksEdited;
01116 KeySet *toRemove;
01117 Key *current;
01118 int ret;
01119 char filename[]="/var/tmp/kdbeditXXXXXX";
01120 char command[300];
01121 FILE *xmlfile=0;
01122 char choice[5];
01123
01124 if (!ksFromXMLfile) return 1;
01125
01126 ks=ksNew();
01127
01128 kdbGetChildKeys(handle,argKeyName,ks, KDB_O_SORT | KDB_O_NFOLLOWLINK |
01129 (argAll?KDB_O_INACTIVE:0) | (argRecursive?KDB_O_RECURSIVE:0));
01130
01131 if (! ksGetSize(ks)) {
01132
01133 current=keyNew(argKeyName,KEY_SWITCH_END);
01134 if (kdbGetKey(handle,current)) {
01135
01136 keyDel(current);
01137 current=0;
01138 } else {
01139
01140 ksAppend(ks,current);
01141 current=0;
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 xmlfile=fdopen(mkstemp(filename),"rw+");
01154
01155 ksToStream(ks,xmlfile,KDB_O_XMLHEADERS | KDB_O_HIER |
01156 KDB_O_FULLNAME | KDB_O_FULLUGID);
01157 fclose(xmlfile);
01158
01159 do {
01160
01161 sprintf(command,"[ -z \"$EDITOR\" ] && EDITOR=vi; $EDITOR %s",filename);
01162 system(command);
01163
01164 toRemove=ksNew();
01165 ksEdited=ksNew();
01166
01167
01168
01169
01170
01171 ret=ksFromXMLfile(ksEdited,filename);
01172 if (ret!=0) {
01173 printf("kdb cannot import this file, because it is not valid !\n");
01174 strcpy(choice,"");
01175 while (choice[0]!='E' && choice[0]!='C') {
01176 printf("Do you want to edit it again or to cancel ? (E/C) : ");
01177 fgets(choice,4, stdin );
01178 }
01179 }
01180 } while (ret!=0 && choice[0]=='E');
01181 remove(filename);
01182
01183 if (ret==0) {
01184 ksCompare(ks,ksEdited,toRemove);
01185
01186
01187
01188 ksDel(ksEdited);
01189
01190
01191 ksRewind(ks);
01192 while ((ret=kdbSetKeys(handle,ks))) {
01193
01194 Key *problem;
01195 char error[500];
01196 char keyname[300]="";
01197
01198 problem=ksCurrent(ks);
01199 if (problem) keyGetFullName(problem,keyname,sizeof(keyname));
01200 sprintf(error,"kdb edit: while setting/updating %s", keyname);
01201 kdbPrintError(error);
01202
01203
01204
01205 if (ksNext(ks) == 0) break;
01206 }
01207
01208 ksDel(ks);
01209
01210
01211 ksRewind(toRemove);
01212 while ((current=ksNext(toRemove))) {
01213 char keyName[800];
01214
01215 keyGetFullName(current,keyName,sizeof(keyName));
01216 ret=kdbRemove(handle,keyName);
01217 if (ret != 0) {
01218 char error[850];
01219
01220 sprintf(error,"kdb edit: while removing %s",keyName);
01221 kdbPrintError(error);
01222 }
01223 }
01224
01225
01226 ksDel(toRemove);
01227 }
01228
01229 return 0;
01230 }
01231
01232
01244 int commandInfo(KDBHandle handle) {
01245 KDBInfo *libraryInfo;
01246 char textInfo[200];
01247
01248 libraryInfo=kdbGetInfo(handle);
01249 kdbInfoToString(libraryInfo, textInfo, sizeof(textInfo));
01250
01251 printf("%s\n", textInfo);
01252
01253 return 0;
01254 }
01255
01256
01270 int commandImport(KDBHandle handle) {
01271 KeySet *ks;
01272 int ret;
01273
01274 if (!ksFromXMLfile || !ksFromXML) return 1;
01275
01276
01277 ks=ksNew();
01278
01279
01280 if (argKeyName) ksFromXMLfile(ks,argKeyName);
01281 else ksFromXML(ks,fileno(stdin) );
01282
01283 ksRewind(ks);
01284 while ((ret=kdbSetKeys(handle,ks))) {
01285
01286 Key *problem;
01287 char error[500]="";
01288 char keyname[300]="";
01289
01290 problem=ksCurrent(ks);
01291 if (problem) keyGetFullName(problem,keyname,sizeof(keyname));
01292 sprintf(error,"kdb import: while importing %s", keyname);
01293 kdbPrintError(error);
01294
01295
01296
01297 if (ksNext(ks) == 0) break;
01298 }
01299
01300 ksDel(ks);
01301
01302 return ret;
01303 }
01304
01305
01306
01307
01308
01325 int commandExport(KDBHandle *handle) {
01326
01327
01328
01329
01330 argSort=1;
01331 argRecursive=1;
01332 argAll=1;
01333 argXML=1;
01334 argShow=1;
01335 argValue=1;
01336
01337
01338
01339
01340 putenv("LANG=en_US.UTF-8");
01341
01342
01343
01344 kdbClose(handle);
01345 kdbOpen(handle);
01346
01347 return commandList(*handle);
01348 }
01349
01350
01364 int commandMonitor(KDBHandle handle) {
01365 Key *toMonitor;
01366 uint32_t diff;
01367
01368 toMonitor=keyNew(argKeyName,KEY_SWITCH_NEEDSYNC,handle,KEY_SWITCH_END);
01369
01370 diff=kdbMonitorKey(handle,
01371 toMonitor,
01372 KEY_SWITCH_VALUE,
01373 0,
01374 500 );
01375
01376
01377
01378
01379
01380
01381 printf("New value is %s\n",(char *)keyStealValue(toMonitor));
01382
01383 keyDel(toMonitor);
01384 return 0;
01385 }
01386
01387
01388 int loadToolsLib(void) {
01389 kdbLibHandle dlhandle=0;
01390
01391 kdbLibInit();
01392
01393 dlhandle=kdbLibLoad("libelektratools");
01394 if (dlhandle == 0) {
01395 return 1;
01396 }
01397
01398 ksFromXMLfile=kdbLibSym(dlhandle,"ksFromXMLfile");
01399 ksFromXML=kdbLibSym(dlhandle,"ksFromXML");
01400
01401 return 0;
01402 }
01403
01404
01405 int doCommand(int command, KDBHandle *handle) {
01406 switch (command) {
01407 case CMD_SET: return commandSet(*handle);
01408 case CMD_LIST: return commandList(*handle);
01409 case CMD_LINK: return commandLink(*handle);
01410 case CMD_GET: return commandGet(*handle);
01411 case CMD_REMOVE: return commandRemove(*handle);
01412 case CMD_EDIT: return commandEdit(*handle);
01413 case CMD_LOAD: return commandImport(*handle);
01414 case CMD_SAVE: return commandExport(handle);
01415 case CMD_MONITOR: return commandMonitor(*handle);
01416 case CMD_MOVE: return commandMove(*handle);
01417 case CMD_INFO: return commandInfo(*handle);
01418 case CMD_HELP: return commandHelp(*handle);
01419 }
01420 return 0;
01421 }
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 int main(int argc, char **argv) {
01433 KDBHandle handle=0;
01434 int command=0;
01435 int ret=0;
01436
01437
01438 if (loadToolsLib())
01439 fprintf(stderr,"kdb: XML importing and editing disabled\n");
01440
01441
01442 command=parseCommandLine(argc,argv);
01443
01444
01445 if (argHelp) helpCommand(command);
01446
01447
01448
01449
01450
01451 kdbOpen(&handle);
01452
01453
01454 ret=doCommand(command,&handle);
01455
01456 kdbClose(&handle);
01457
01458 exit(ret);
01459 }
01460