00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00038 #include "kdb.h"
00039
00040 #include <sys/types.h>
00041 #include <sys/stat.h>
00042 #include <unistd.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <stdio.h>
00046 #include <grp.h>
00047 #include <pwd.h>
00048 #include <time.h>
00049 #include <ctype.h>
00050 #include <locale.h>
00051
00052
00053 #include <libxml/xmlreader.h>
00054
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
00066 #define ARGSIZE 30
00067
00068 char *argComment=0;
00069 char *argFile=0;
00070 char *argData=0;
00071 char *argKeyName=0;
00072 char *argDomain=0;
00073 uid_t *argUID=0;
00074 uid_t *argGID=0;
00075 int argCommand=0;
00076 int argRecursive=0;
00077 int argLong=0;
00078 int argValue=0;
00079 int argAll=0;
00080 int argSort=1;
00081 int argDescriptive=0;
00082 int argFullName=0;
00083 int argShow=1;
00084 int argShell=0;
00085 int argXML=0;
00086 mode_t argMode=0;
00087 int argType=KEY_TYPE_UNDEFINED;
00088
00089
00090 int parseCommandLine(int argc, char *argv[]) {
00091 char sargType[ARGSIZE],argUser[ARGSIZE],argGroup[ARGSIZE];
00092 char sargMode[ARGSIZE],sargCommand[ARGSIZE];
00093
00094 int opt;
00095
00096 int test;
00097
00098 *sargType=*argUser=*argGroup=*sargCommand=*sargMode=0;
00099
00100 while ((opt=getopt(argc,argv,"-t:c:u:g:m:b:raflvRdxsi"))!=-1) {
00101 switch (opt) {
00102 case 't':
00103 strncpy(sargType,optarg,ARGSIZE);
00104 break;
00105 case 'c':
00106 argComment=realloc(argComment,strlen(optarg)+1);
00107 strcpy(argComment,optarg);
00108 break;
00109 case 'b':
00110 argFile=realloc(argFile,strlen(optarg)+1);
00111 strcpy(argFile,optarg);
00112 break;
00113 case 'u':
00114 strncpy(argUser,optarg,ARGSIZE);
00115 break;
00116 case 'g':
00117 strncpy(argGroup,optarg,ARGSIZE);
00118 break;
00119 case 'm':
00120 strncpy(sargMode,optarg,ARGSIZE);
00121 break;
00122 case 'R':
00123 argRecursive=KDB_O_RECURSIVE;
00124 break;
00125 case 'l':
00126 argLong=1;
00127 break;
00128 case 'v':
00129 argValue=1;
00130 break;
00131 case 'd':
00132 argDescriptive=1;
00133 argLong=1;
00134 break;
00135 case 'a':
00136 argAll=1;
00137 break;
00138 case 's':
00139 argShell=1;
00140 break;
00141 case 'f':
00142 argFullName=1;
00143 break;
00144 case 'n':
00145 argSort=0;
00146 break;
00147 case 'i':
00148 argShow=0;
00149 break;
00150 case 'x':
00151 argXML=1;
00152 break;
00153 case 1: {
00154 test=optind;
00155 if (*sargCommand==0) {
00156 strncpy(sargCommand,optarg,ARGSIZE);
00157 } else if (!argKeyName) {
00158 argKeyName=realloc(argKeyName,strlen(optarg)+1);
00159 strcpy(argKeyName,optarg);
00160 } else if (!argData) {
00161 argData=realloc(argData,strlen(optarg)+1);
00162 strcpy(argData,optarg);
00163 }
00164 break;
00165 }
00166 }
00167 }
00168 test=optind;
00169
00170
00171 if (!strcmp(argv[optind-1],"--") && optind<argc) {
00172 int wordind=optind;
00173 size_t valueLength=0;
00174
00175 while (wordind<argc) valueLength+=strlen(argv[wordind++])+1;
00176 argData=realloc(argData,valueLength);
00177 strcpy(argData,argv[optind++]);
00178
00179 while (optind<argc) sprintf(argData,"%s %s",argData,argv[optind++]);
00180 }
00181
00182
00183
00184
00185 if (!strcmp(sargCommand,"ls")) argCommand=CMD_LIST;
00186 else if (!strcmp(sargCommand,"set")) argCommand=CMD_SET;
00187 else if (!strcmp(sargCommand,"get")) argCommand=CMD_GET;
00188 else if (!strcmp(sargCommand,"ln")) argCommand=CMD_LINK;
00189 else if (!strcmp(sargCommand,"rm")) argCommand=CMD_REMOVE;
00190 else if (!strcmp(sargCommand,"vi")) argCommand=CMD_EDIT;
00191 else if (!strcmp(sargCommand,"edit")) argCommand=CMD_EDIT;
00192 else if (!strcmp(sargCommand,"load")) argCommand=CMD_LOAD;
00193 else if (!strcmp(sargCommand,"import")) argCommand=CMD_LOAD;
00194 else if (!strcmp(sargCommand,"save")) argCommand=CMD_SAVE;
00195 else if (!strcmp(sargCommand,"export")) argCommand=CMD_SAVE;
00196 else if (!strcmp(sargCommand,"mon")) argCommand=CMD_MONITOR;
00197 else if (!strcmp(sargCommand,"monitor")) argCommand=CMD_MONITOR;
00198 else {
00199 fprintf(stderr,"Invalid subcommand\n");
00200 exit(1);
00201 }
00202
00203
00204 if (*sargType!=0) {
00205
00206 if (!strcmp(sargType,"string")) argType=KEY_TYPE_STRING;
00207 else if (!strcmp(sargType,"bin")) argType=KEY_TYPE_BINARY;
00208 else if (!strcmp(sargType,"binary")) argType=KEY_TYPE_BINARY;
00209 else if (!strcmp(sargType,"dir")) argType=KEY_TYPE_DIR;
00210 else if (!strcmp(sargType,"link")) argType=KEY_TYPE_LINK;
00211 } else if (argCommand==CMD_SET) {
00212 argType=KEY_TYPE_STRING;
00213 }
00214
00215
00216
00217 if (*argUser) {
00218 if (isdigit(*argUser)) {
00219 argUID=malloc(sizeof(uid_t));
00220 *argUID=atoi(argUser);
00221 } else {
00222 struct passwd *pwd;
00223 pwd=getpwnam(argUser);
00224 if (pwd) {
00225 argUID=malloc(sizeof(uid_t));
00226 *argUID=pwd->pw_uid;
00227 } else {
00228 fprintf(stderr,"kdb: Invalid user %s. Ignoring\n", argUser);
00229 }
00230 }
00231 }
00232
00233
00234
00235 if (*argGroup) {
00236 if (isdigit(*argGroup)) {
00237 argGID=malloc(sizeof(gid_t));
00238 *argGID=atoi(argGroup);
00239 } else {
00240 struct group *grp;
00241 grp=getgrnam(argGroup);
00242 if (grp) {
00243 argGID=malloc(sizeof(gid_t));
00244 *argGID=grp->gr_gid;
00245 } else {
00246 fprintf(stderr,"kdb: Invalid group %s. Ignoring\n",argGroup);
00247 }
00248 }
00249 }
00250
00251
00252
00253
00254 if (*sargMode!=0) argMode=strtol(sargMode,0,8);
00255
00256 return argCommand;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 void listAccess(Key *key,char *readable) {
00269 mode_t mode=keyGetAccess(key);
00270
00271 if (S_ISDIR(mode)) readable[0]='d';
00272 else if (S_ISLNK(mode)) readable[0]='l';
00273 else readable[0]='-';
00274
00275 readable[1] = mode & S_IRUSR ? 'r' : '-';
00276 readable[2] = mode & S_IWUSR ? 'w' : '-';
00277 readable[3] = mode & S_IXUSR ? 'x' : '-';
00278 readable[4] = mode & S_IRGRP ? 'r' : '-';
00279 readable[5] = mode & S_IWGRP ? 'w' : '-';
00280 readable[6] = mode & S_IXGRP ? 'x' : '-';
00281 readable[7] = mode & S_IROTH ? 'r' : '-';
00282 readable[8] = mode & S_IWOTH ? 'w' : '-';
00283 readable[9] = mode & S_IXOTH ? 'x' : '-';
00284 readable[10]= 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294 void listTime(time_t when,char *readable) {
00295 time_t current_time=time(0);
00296 char buf[400];
00297 time_t six_months_ago;
00298 int recent;
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 six_months_ago = current_time - 31556952 / 2;
00309 recent = (six_months_ago <= when) && (when <= current_time);
00310
00311 ctime_r(&when,buf);
00312 memcpy(readable,buf+4,7);
00313 if (recent) {
00314 memcpy(readable,buf+4,12);
00315 readable[12]=0;
00316 } else {
00317 memcpy(readable,buf+4,7);
00318 readable[7]=' ';
00319 memcpy(readable+8,buf+20,4);
00320 readable[12]=0;
00321 }
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 void listSingleKey(Key *key) {
00331 char buffer[400];
00332 char *p=buffer;
00333
00334 if (argLong) {
00335 struct passwd *pwd;
00336 struct group *grp;
00337
00338 listAccess(key,p);
00339 p+=strlen(p);
00340 *p=' '; p++;
00341 *p=' '; p++;
00342 *p=' '; p++;
00343
00344 pwd=getpwuid(keyGetUID(key));
00345 strcpy(p,pwd->pw_name);
00346 p+=strlen(p);
00347 *p=' '; p++;
00348 *p=' '; p++;
00349
00350 grp=getgrgid(keyGetGID(key));
00351 strcpy(p,grp->gr_name);
00352 p+=strlen(p);
00353 *p=' '; p++;
00354
00355 sprintf(p,"%*d ",5,keyGetRecordSize(key));
00356 p+=strlen(p);
00357
00358 listTime(keyGetMTime(key),p);
00359 p+=strlen(p);
00360 *p=' '; p++;
00361 }
00362 if (argFullName) keyGetFullName(key,p,sizeof(buffer)-(p-buffer));
00363 else keyGetName(key,p,sizeof(buffer)-(p-buffer));
00364 if (argValue && (keyGetDataSize(key)>0)) {
00365 u_int8_t ktype;
00366
00367 p+=strlen(p);
00368 *p='='; p++;
00369
00370 ktype=keyGetType(key);
00371 if (ktype >= KEY_TYPE_STRING)
00372 p+=keyGetString(key,p,sizeof(buffer)-(p-buffer));
00373 else if (ktype >= KEY_TYPE_BINARY)
00374 p+=sprintf(p,"<BINARY VALUE>");
00375 else if (ktype == KEY_TYPE_LINK)
00376 p+=keyGetLink(key,p,sizeof(buffer)-(p-buffer));
00377
00378 *p=0;
00379 }
00380 puts(buffer);
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00400 int commandRemove() {
00401 if (!argKeyName) {
00402 fprintf(stderr,"kdb rm: No key name\n");
00403 return -1;
00404 }
00405
00406 if (kdbRemove(argKeyName)) {
00407 perror("kdb rm");
00408 return -1;
00409 }
00410 return 0;
00411 }
00412
00413
00414
00415
00416
00417
00437 int commandSet() {
00438 Key key;
00439 int ret;
00440 char error[200];
00441 size_t offset=0;
00442
00443
00444
00445 if (!argKeyName) {
00446 fprintf(stderr,"kdb set: No key name\n");
00447 return -1;
00448 }
00449
00450 keyInit(&key);
00451 keySetName(&key,argKeyName);
00452 ret=kdbGetKey(&key);
00453 if (!ret) {
00454 if (argComment) keySetComment(&key,argComment);
00455 if (argType==KEY_TYPE_UNDEFINED) argType=keyGetType(&key);
00456 } else if (errno!=KDB_RET_NOTFOUND) {
00457 sprintf(error,"kdb set: %s",argKeyName);
00458 perror(error);
00459 }
00460
00461 if (argUID) keySetUID(&key,*argUID);
00462 if (argGID) keySetGID(&key,*argGID);
00463
00464 if (argMode) keySetAccess(&key,argMode);
00465
00466 if (argFile) {
00467 FILE *f;
00468 int end=0;
00469
00470 if (argData) free(argData);
00471 argData=0;
00472 f=fopen(argFile,"r");
00473
00474 if (!f) {
00475 sprintf(error,"kdb set: %s",argFile);
00476 perror(error);
00477 return -1;
00478 }
00479 while (! end) {
00480 char buffer[100];
00481 ssize_t r;
00482
00483 r=read(fileno(f),buffer,sizeof(buffer));
00484 if (r == 0) {
00485 r=lseek(fileno(f),0,SEEK_END)-offset;
00486 end=1;
00487 }
00488 argData=realloc(argData,offset+r);
00489 memcpy(argData+offset,buffer,r);
00490 offset+=r;
00491 }
00492 fclose(f);
00493 }
00494
00495 switch (argType) {
00496 case KEY_TYPE_DIR: keySetType(&key,KEY_TYPE_DIR);
00497 break;
00498 case KEY_TYPE_STRING:
00499 if (argData) keySetString(&key,argData);
00500 break;
00501 case KEY_TYPE_BINARY:
00502 if (argData) {
00503 if (offset) keySetBinary(&key,argData,offset);
00504 else keySetBinary(&key,argData,strblen(argData));
00505 }
00506 break;
00507 case KEY_TYPE_LINK: keySetLink(&key,argData);
00508 break;
00509 }
00510
00511 ret=kdbSetKey(&key);
00512 if (ret) {
00513 sprintf(error,"kdb set: %s",argKeyName);
00514 perror(error);
00515 }
00516 return ret;
00517 }
00518
00519
00520
00521
00522
00523
00537 int commandLink() {
00538 int rc;
00539
00540
00541 if (!argKeyName) {
00542 fprintf(stderr,"kdb ln: No target specified\n");
00543 return -1;
00544 }
00545
00546 if (!argData) {
00547 fprintf(stderr,"kdb ln: %s: No destination specified",argKeyName);
00548 return -1;
00549 }
00550
00551 if ((rc=kdbLink(argKeyName,argData))) {
00552 perror("kdb ln");
00553 }
00554
00555 return rc;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00594 int commandList() {
00595 KeySet ks;
00596 Key *key=0;
00597 int ret;
00598
00599 ksInit(&ks);
00600
00601 if (!argKeyName) {
00602 KeySet roots;
00603
00604
00605 ksInit(&roots);
00606 kdbGetRootKeys(&roots);
00607
00608 if (argRecursive) {
00609 key=roots.start;
00610 while (key) {
00611 char rootName[200];
00612 KeySet thisRoot;
00613 Key *temp;
00614
00615 ksInit(&thisRoot);
00616 keyGetFullName(key,rootName,sizeof(rootName));
00617 if (argValue) ret=kdbGetChildKeys(rootName,&thisRoot,
00618 (argSort?KDB_O_SORT:0) | argRecursive | KDB_O_DIR |
00619 (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00620 else ret=kdbGetChildKeys(rootName,&thisRoot,
00621 (argSort?KDB_O_SORT:0) | KDB_O_STATONLY | argRecursive |
00622 KDB_O_DIR | (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00623 temp=key->next;
00624 ksAppend(&ks,key);
00625 ksAppendKeys(&ks,&thisRoot);
00626 key=temp;
00627 }
00628 } else ksAppendKeys(&ks,&roots);
00629 } else {
00630
00631
00632 if (argValue) ret=kdbGetChildKeys(argKeyName,&ks,
00633 (argSort?KDB_O_SORT:0) | argRecursive | KDB_O_DIR |
00634 (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00635 else ret=kdbGetChildKeys(argKeyName,&ks,
00636 (argSort?KDB_O_SORT:0) | KDB_O_STATONLY | argRecursive |
00637 KDB_O_DIR | (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00638
00639 if (ret) {
00640
00641 if (errno==ENOTDIR) {
00642
00643 key=(Key *)malloc(sizeof(Key));
00644 keyInit(key);
00645 keySetName(key,argKeyName);
00646 if (argValue) ret=kdbGetKey(key);
00647 else ret=kdbStatKey(key);
00648 if (ret) {
00649 char error[200];
00650
00651 keyClose(key); free(key);
00652 ksClose(&ks);
00653
00654 sprintf(error,"kdb ls: %s",argKeyName);
00655 perror(error);
00656 return ret;
00657 }
00658 } else {
00659 char error[200];
00660
00661 ksClose(&ks);
00662
00663 sprintf(error,"kdb ls: %s",argKeyName);
00664 perror(error);
00665 return ret;
00666 }
00667 }
00668 }
00669
00670 if (argShow) {
00671 if (argXML) {
00672 if (key) keyToStream(key,stdout,0);
00673 else if (ks.size)
00674 ksToStream(&ks,stdout,KDB_O_XMLHEADERS);
00675 } else {
00676 if (key) listSingleKey(key);
00677 else if (ks.size) {
00678 ksRewind(&ks);
00679 while ((key=ksNext(&ks)))
00680 listSingleKey(key);
00681 }
00682 }
00683 }
00684
00685 ksClose(&ks);
00686 if (key) {
00687 keyClose(key);
00688 free(key);
00689 }
00690 return 0;
00691 }
00692
00693
00694
00695
00696
00697
00698
00721 int commandGet() {
00722 int ret;
00723 Key key;
00724 char *buffer;
00725 char *p;
00726 size_t size,cs=0;
00727 u_int8_t keyType;
00728
00729 if (!argKeyName) {
00730 fprintf(stderr,"kdb get: No key name\n");
00731 return -1;
00732 }
00733
00734 keyInit(&key);
00735 keySetName(&key,argKeyName);
00736
00737 ret=kdbGetKey(&key);
00738 if (ret) {
00739 char error[200];
00740
00741 sprintf(error,"kdb get: %s",argKeyName);
00742 perror(error);
00743 return ret;
00744 }
00745 size=keyGetDataSize(&key);
00746 if (argDescriptive) {
00747 cs=keyGetCommentSize(&key);
00748 if (cs) size+=cs+3;
00749 }
00750 if (argShell) {
00751 size+=keyGetBaseNameSize(&key);
00752 size+=2;
00753 } else if (argLong) {
00754 if (argFullName) size+=keyGetFullNameSize(&key);
00755 else size+=keyGetNameSize(&key);
00756 }
00757
00758
00759 p=buffer=malloc(size);
00760
00761
00762 if (argDescriptive) {
00763 if (cs) {
00764 p+=sprintf(p,"# ");
00765 p+=keyGetComment(&key,p,size-(p-buffer));
00766 *--p='\n'; p++;
00767 }
00768 }
00769 if (argShell) {
00770 p+=keyGetBaseName(&key,p,size-(p-buffer));
00771 *--p='='; p++;
00772 *p='\"'; p++;
00773 } else if (argLong) {
00774 if (argFullName) p+=keyGetFullName(&key,p,size-(p-buffer));
00775 else p+=keyGetName(&key,p,size-(p-buffer));
00776 *--p='='; p++;
00777 }
00778
00779 keyType=keyGetType(&key);
00780
00781 if (keyType<KEY_TYPE_STRING) p+=keyGetBinary(&key,p,size-(p-buffer));
00782 else p+=keyGetString(&key,p,size-(p-buffer));
00783 if (argShell) {
00784 *--p='\"'; p++;
00785 *p=0;
00786 }
00787 if (keyType<KEY_TYPE_STRING) fwrite(buffer,size,1,stdout);
00788 else printf("%s\n",buffer);
00789
00790
00791 free(buffer);
00792
00793 return 0;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 int processNode(KeySet *ks, xmlTextReaderPtr reader) {
00810 xmlChar *nodeName=0;
00811 xmlChar *buffer=0;
00812 Key *newKey=0;
00813
00814 nodeName=xmlTextReaderName(reader);
00815 if (!strcmp(nodeName,"key")) {
00816 int end=0;
00817
00818 newKey=malloc(sizeof(Key));
00819 keyInit(newKey);
00820
00821 xmlFree(nodeName); nodeName=0;
00822
00823 buffer=xmlTextReaderGetAttribute(reader,"name");
00824 keySetName(newKey,(char *)buffer);
00825 xmlFree(buffer); buffer=0;
00826
00827 buffer=xmlTextReaderGetAttribute(reader,"type");
00828 if (!strcmp(buffer,"string"))
00829 keySetType(newKey,KEY_TYPE_STRING);
00830 else if (!strcmp(buffer,"binary"))
00831 keySetType(newKey,KEY_TYPE_BINARY);
00832 else if (!strcmp(buffer,"link"))
00833 keySetType(newKey,KEY_TYPE_LINK);
00834 else if (!strcmp(buffer,"directory"))
00835 keySetType(newKey,KEY_TYPE_DIR);
00836 xmlFree(buffer); buffer=0;
00837
00838
00839
00840 buffer=xmlTextReaderGetAttribute(reader,"uid");
00841 if (isdigit(*buffer)) {
00842 keySetUID(newKey,atoi(buffer));
00843 } else {
00844 struct passwd *pwd;
00845 pwd=getpwnam(buffer);
00846 if (pwd) keySetUID(newKey,pwd->pw_uid);
00847 else fprintf(stderr,"kdb: Ignoring invalid user %s.\n", buffer);
00848 }
00849 xmlFree(buffer); buffer=0;
00850
00851
00852
00853 buffer=xmlTextReaderGetAttribute(reader,"gid");
00854 if (isdigit(*buffer)) {
00855 keySetGID(newKey,atoi(buffer));
00856 } else {
00857 struct group *grp;
00858 grp=getgrnam(buffer);
00859 if (grp) keySetGID(newKey,grp->gr_gid);
00860 else fprintf(stderr,"kdb: Ignoring invalid group %s.\n",buffer);
00861 }
00862 xmlFree(buffer); buffer=0;
00863
00864
00865
00866 buffer=xmlTextReaderGetAttribute(reader,"mode");
00867 if (buffer) keySetAccess(newKey,strtol(buffer,0,8));
00868 xmlFree(buffer); buffer=0;
00869
00870
00871
00872 while (!end) {
00873 xmlFree(nodeName); nodeName=0;
00874 xmlTextReaderRead(reader);
00875 nodeName=xmlTextReaderName(reader);
00876
00877 if (!strcmp(nodeName,"value")) {
00878 if (xmlTextReaderIsEmptyElement(reader) ||
00879 xmlTextReaderNodeType(reader)==15) continue;
00880 xmlTextReaderRead(reader);
00881 buffer=xmlTextReaderValue(reader);
00882 if (buffer) {
00883 switch (keyGetType(newKey)) {
00884 case KEY_TYPE_STRING:
00885 keySetString(newKey,buffer);
00886 break;
00887 case KEY_TYPE_BINARY:
00888 keySetBinary(newKey,buffer,strlen(buffer)+1);
00889 break;
00890 case KEY_TYPE_LINK:
00891 keySetLink(newKey,buffer);
00892 break;
00893 }
00894 }
00895 } else if (!strcmp(nodeName,"comment")) {
00896 if (xmlTextReaderIsEmptyElement(reader) ||
00897 xmlTextReaderNodeType(reader)==15) continue;
00898 xmlTextReaderRead(reader);
00899 buffer=xmlTextReaderValue(reader);
00900
00901 keySetComment(newKey,buffer);
00902 } else if (!strcmp(nodeName,"key")) {
00903 if (xmlTextReaderNodeType(reader)==15) end=1;
00904 }
00905
00906 xmlFree(buffer); buffer=0;
00907 }
00908 }
00909
00910 if (nodeName) xmlFree(nodeName),nodeName=0;
00911
00912 if (newKey) ksAppend(ks,newKey);
00913 return 0;
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 int ksFromXMLReader(KeySet *ks,xmlTextReaderPtr reader) {
00926 int ret;
00927
00928 ret = xmlTextReaderRead(reader);
00929 ret = xmlTextReaderRead(reader);
00930 while (ret == 1) {
00931 processNode(ks, reader);
00932 ret = xmlTextReaderRead(reader);
00933 }
00934 xmlFreeTextReader(reader);
00935 if (ret) fprintf(stderr,"kdb: Failed to parse XML input\n");
00936
00937 return ret;
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 int ksFromXMLfile(KeySet *ks,char *filename) {
00949 xmlTextReaderPtr reader;
00950 int ret;
00951
00952 reader = xmlNewTextReaderFilename(filename);
00953 if (reader) {
00954 ret=ksFromXMLReader(ks,reader);
00955 } else {
00956 perror("kdb");
00957 return 1;
00958 }
00959 return ret;
00960 }
00961
00962
00963
00964
00965
00966
00967 int ksFromXML(KeySet *ks,int fd) {
00968
00969 char filename[]="/var/tmp/rgeditXXXXXX";
00970 FILE *xmlfile=0;
00971 xmlfile=fdopen(mkstemp(filename),"rw+");
00972 while (! feof(xmlfile)) {
00973 char buffer[1000];
00974 ssize_t readed, writen;
00975
00976 readed=read(fd,buffer,sizeof(buffer));
00977 if (readed<0) {
00978 perror("kdb");
00979 fclose(xmlfile);
00980 remove(filename);
00981 return 1;
00982 }
00983
00984 writen=write(fileno(xmlfile),buffer,readed);
00985 if (writen<0) {
00986 perror("kdb");
00987 fclose(xmlfile);
00988 remove(filename);
00989 return 1;
00990 }
00991 }
00992 fclose(xmlfile);
00993 return ksFromXMLfile(ks,filename);
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01057 int commandEdit() {
01058 KeySet ks;
01059 KeySet ksEdited;
01060 KeySet toRemove;
01061 Key *current;
01062 int ret;
01063 char filename[]="/var/tmp/rgeditXXXXXX";
01064 char command[300];
01065 FILE *xmlfile=0;
01066
01067 ksInit(&ks);
01068
01069 kdbGetChildKeys(argKeyName,&ks, KDB_O_SORT | KDB_O_NFOLLOWLINK |
01070 (argAll?KDB_O_INACTIVE:0) | (argRecursive?KDB_O_RECURSIVE:0));
01071
01072 if (!ks.size) {
01073
01074 current=malloc(sizeof(Key));
01075 keyInit(current);
01076 keySetName(current,argKeyName);
01077 if (kdbGetKey(current)) {
01078
01079 keyClose(current);
01080 free(current);
01081 current=0;
01082 } else {
01083
01084 ksAppend(&ks,current);
01085 current=0;
01086 }
01087 }
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097 xmlfile=fdopen(mkstemp(filename),"rw+");
01098
01099 ksToStream(&ks,xmlfile,KDB_O_XMLHEADERS);
01100 fclose(xmlfile);
01101
01102 sprintf(command,"[ -z \"$EDITOR\" ] && EDITOR=vi; $EDITOR %s",filename);
01103 system(command);
01104
01105 ksInit(&toRemove);
01106 ksInit(&ksEdited);
01107
01108
01109
01110
01111
01112 ksFromXMLfile(&ksEdited,filename);
01113 remove(filename);
01114
01115 ksCompare(&ks,&ksEdited,&toRemove);
01116
01117 ksRewind(&ks);
01118 ret=kdbSetKeys(&ks);
01119 if (ret != 0) {
01120 Key *problem;
01121 char error[500];
01122 char keyname[300]="";
01123
01124 problem=ksCurrent(&ks);
01125 if (problem) keyGetFullName(problem,keyname,sizeof(keyname));
01126 sprintf(error,"kdb edit: when commiting %s",keyname);
01127 perror(error);
01128 }
01129
01130 ksRewind(&toRemove);
01131 while ((current=ksNext(&toRemove))) {
01132 char keyName[800];
01133
01134 keyGetFullName(current,keyName,sizeof(keyName));
01135 kdbRemove(keyName);
01136 }
01137
01138 return 0;
01139 }
01140
01141
01142
01143
01158 int commandImport() {
01159 KeySet ks;
01160 int ret;
01161
01162 ksInit(&ks);
01163
01164
01165 if (argKeyName) ksFromXMLfile(&ks,argKeyName);
01166 else ksFromXML(&ks,fileno(stdin) );
01167
01168 ksRewind(&ks);
01169 ret=kdbSetKeys(&ks);
01170
01171 if (ret != 0) {
01172 Key *problem;
01173 char error[500];
01174 char keyname[300]="";
01175
01176 problem=ksCurrent(&ks);
01177 if (problem) keyGetFullName(problem,keyname,sizeof(keyname));
01178 sprintf(error,"kdb import: when commiting %s",keyname);
01179 perror(error);
01180 }
01181
01182 return ret;
01183 }
01184
01185
01186
01187
01188
01206 int commandExport() {
01207
01208
01209
01210
01211 argSort=1;
01212 argRecursive=1;
01213 argAll=1;
01214 argXML=1;
01215 argShow=1;
01216 argValue=1;
01217 argFullName=1;
01218
01219
01220 setenv("LANG","en_US.UTF-8",1);
01221
01222
01223 kdbClose();
01224 kdbOpen();
01225
01226 return commandList();
01227 }
01228
01229
01244 int commandMonitor() {
01245 Key toMonitor;
01246 u_int32_t diff;
01247 char *newData=0;
01248 size_t dataSize;
01249
01250 keyInit(&toMonitor);
01251 keySetName(&toMonitor,argKeyName);
01252 kdbGetKey(&toMonitor);
01253
01254 diff=kdbMonitorKey(
01255 &toMonitor,
01256 KEY_FLAG_HASDATA,
01257 0,
01258 500 );
01259
01260
01261
01262
01263
01264
01265 newData=malloc(dataSize=keyGetDataSize(&toMonitor));
01266 keyGetString(&toMonitor,newData,dataSize);
01267 printf("New value is %s\n",newData);
01268 return 0;
01269 }
01270
01271
01272 int doCommand(int command) {
01273 switch (command) {
01274 case CMD_SET: return commandSet();
01275 case CMD_LIST: return commandList();
01276 case CMD_LINK: return commandLink();
01277 case CMD_GET: return commandGet();
01278 case CMD_REMOVE: return commandRemove();
01279 case CMD_EDIT: return commandEdit();
01280 case CMD_LOAD: return commandImport();
01281 case CMD_SAVE: return commandExport();
01282 case CMD_MONITOR: return commandMonitor();
01283 }
01284 return 0;
01285 }
01286
01287
01288 int main(int argc, char **argv) {
01289 int command=0;
01290 int ret=0;
01291
01292 command=parseCommandLine(argc,argv);
01293
01294 kdbOpen();
01295 ret=doCommand(command);
01296 kdbClose();
01297
01298 return ret;
01299 }
01300