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 *argData=0;
00070 char *argKeyName=0;
00071 char *argDomain=0;
00072 uid_t *argUID=0;
00073 uid_t *argGID=0;
00074 int argCommand=0;
00075 int argRecursive=0;
00076 int argLong=0;
00077 int argValue=0;
00078 int argAll=0;
00079 int argSort=1;
00080 int argDescriptive=0;
00081 int argFullName=0;
00082 int argShow=1;
00083 int argShell=0;
00084 int argXML=0;
00085 mode_t argMode=0;
00086 int argType=KEY_TYPE_UNDEFINED;
00087
00088
00089 int parseCommandLine(int argc, char *argv[]) {
00090 char sargType[ARGSIZE],argUser[ARGSIZE],argGroup[ARGSIZE];
00091 char sargMode[ARGSIZE],sargCommand[ARGSIZE];
00092
00093 int opt;
00094
00095 int test;
00096
00097 *sargType=*argUser=*argGroup=*sargCommand=*sargMode=0;
00098
00099 while ((opt=getopt(argc,argv,"-t:c:u:g:m:raflvRdxsi"))!=-1) {
00100 switch (opt) {
00101 case 't':
00102 strncpy(sargType,optarg,ARGSIZE);
00103 break;
00104 case 'c':
00105 argComment=realloc(argComment,strlen(optarg)+1);
00106 strcpy(argComment,optarg);
00107 break;
00108 case 'u':
00109 strncpy(argUser,optarg,ARGSIZE);
00110 break;
00111 case 'g':
00112 strncpy(argGroup,optarg,ARGSIZE);
00113 break;
00114 case 'm':
00115 strncpy(sargMode,optarg,ARGSIZE);
00116 break;
00117 case 'R':
00118 argRecursive=KDB_O_RECURSIVE;
00119 break;
00120 case 'l':
00121 argLong=1;
00122 break;
00123 case 'v':
00124 argValue=1;
00125 break;
00126 case 'd':
00127 argDescriptive=1;
00128 argLong=1;
00129 break;
00130 case 'a':
00131 argAll=1;
00132 break;
00133 case 's':
00134 argShell=1;
00135 break;
00136 case 'f':
00137 argFullName=1;
00138 break;
00139 case 'n':
00140 argSort=0;
00141 break;
00142 case 'i':
00143 argShow=0;
00144 break;
00145 case 'x':
00146 argXML=1;
00147 break;
00148 case 1: {
00149 test=optind;
00150 if (*sargCommand==0) {
00151 strncpy(sargCommand,optarg,ARGSIZE);
00152 } else if (!argKeyName) {
00153 argKeyName=realloc(argKeyName,strlen(optarg)+1);
00154 strcpy(argKeyName,optarg);
00155 } else if (!argData) {
00156 argData=realloc(argData,strlen(optarg)+1);
00157 strcpy(argData,optarg);
00158 }
00159 break;
00160 }
00161 }
00162 }
00163 test=optind;
00164
00165
00166 if (!strcmp(argv[optind-1],"--") && optind<argc) {
00167 int wordind=optind;
00168 size_t valueLength=0;
00169
00170 while (wordind<argc) valueLength+=strlen(argv[wordind++])+1;
00171 argData=realloc(argData,valueLength);
00172 strcpy(argData,argv[optind++]);
00173
00174 while (optind<argc) sprintf(argData,"%s %s",argData,argv[optind++]);
00175 }
00176
00177
00178
00179
00180 if (!strcmp(sargCommand,"ls")) argCommand=CMD_LIST;
00181 else if (!strcmp(sargCommand,"set")) argCommand=CMD_SET;
00182 else if (!strcmp(sargCommand,"get")) argCommand=CMD_GET;
00183 else if (!strcmp(sargCommand,"ln")) argCommand=CMD_LINK;
00184 else if (!strcmp(sargCommand,"rm")) argCommand=CMD_REMOVE;
00185 else if (!strcmp(sargCommand,"vi")) argCommand=CMD_EDIT;
00186 else if (!strcmp(sargCommand,"edit")) argCommand=CMD_EDIT;
00187 else if (!strcmp(sargCommand,"load")) argCommand=CMD_LOAD;
00188 else if (!strcmp(sargCommand,"import")) argCommand=CMD_LOAD;
00189 else if (!strcmp(sargCommand,"save")) argCommand=CMD_SAVE;
00190 else if (!strcmp(sargCommand,"export")) argCommand=CMD_SAVE;
00191 else if (!strcmp(sargCommand,"mon")) argCommand=CMD_MONITOR;
00192 else if (!strcmp(sargCommand,"monitor")) argCommand=CMD_MONITOR;
00193 else {
00194 fprintf(stderr,"Invalid subcommand\n");
00195 exit(1);
00196 }
00197
00198
00199 if (*sargType!=0) {
00200
00201 if (!strcmp(sargType,"string")) argType=KEY_TYPE_STRING;
00202 else if (!strcmp(sargType,"bin")) argType=KEY_TYPE_BINARY;
00203 else if (!strcmp(sargType,"binary")) argType=KEY_TYPE_BINARY;
00204 else if (!strcmp(sargType,"dir")) argType=KEY_TYPE_DIR;
00205 else if (!strcmp(sargType,"link")) argType=KEY_TYPE_LINK;
00206 } else if (argCommand==CMD_SET) {
00207 argType=KEY_TYPE_STRING;
00208 }
00209
00210
00211
00212 if (*argUser) {
00213 if (isdigit(*argUser)) {
00214 argUID=malloc(sizeof(uid_t));
00215 *argUID=atoi(argUser);
00216 } else {
00217 struct passwd *pwd;
00218 pwd=getpwnam(argUser);
00219 if (pwd) {
00220 argUID=malloc(sizeof(uid_t));
00221 *argUID=pwd->pw_uid;
00222 } else {
00223 fprintf(stderr,"kdb: Invalid user %s. Ignoring\n", argUser);
00224 }
00225 }
00226 }
00227
00228
00229
00230 if (*argGroup) {
00231 if (isdigit(*argGroup)) {
00232 argGID=malloc(sizeof(gid_t));
00233 *argGID=atoi(argGroup);
00234 } else {
00235 struct group *grp;
00236 grp=getgrnam(argGroup);
00237 if (grp) {
00238 argGID=malloc(sizeof(gid_t));
00239 *argGID=grp->gr_gid;
00240 } else {
00241 fprintf(stderr,"kdb: Invalid group %s. Ignoring\n",argGroup);
00242 }
00243 }
00244 }
00245
00246
00247
00248
00249 if (*sargMode!=0) argMode=strtol(sargMode,0,8);
00250
00251 return argCommand;
00252 }
00253
00254
00255 void listAccess(Key *key,char *readable) {
00256 mode_t mode=keyGetAccess(key);
00257
00258 if (S_ISDIR(mode)) readable[0]='d';
00259 else if (S_ISLNK(mode)) readable[0]='l';
00260 else readable[0]='-';
00261
00262 readable[1] = mode & S_IRUSR ? 'r' : '-';
00263 readable[2] = mode & S_IWUSR ? 'w' : '-';
00264 readable[3] = mode & S_IXUSR ? 'x' : '-';
00265 readable[4] = mode & S_IRGRP ? 'r' : '-';
00266 readable[5] = mode & S_IWGRP ? 'w' : '-';
00267 readable[6] = mode & S_IXGRP ? 'x' : '-';
00268 readable[7] = mode & S_IROTH ? 'r' : '-';
00269 readable[8] = mode & S_IWOTH ? 'w' : '-';
00270 readable[9] = mode & S_IXOTH ? 'x' : '-';
00271 readable[10]= 0;
00272 }
00273
00274
00275 void listTime(time_t when,char *readable) {
00276 time_t current_time=time(0);
00277 char buf[400];
00278 time_t six_months_ago;
00279 int recent;
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 six_months_ago = current_time - 31556952 / 2;
00290 recent = (six_months_ago <= when) && (when <= current_time);
00291
00292 ctime_r(&when,buf);
00293 memcpy(readable,buf+4,7);
00294 if (recent) {
00295 memcpy(readable,buf+4,12);
00296 readable[12]=0;
00297 } else {
00298 memcpy(readable,buf+4,7);
00299 readable[7]=' ';
00300 memcpy(readable+8,buf+20,4);
00301 readable[12]=0;
00302 }
00303 }
00304
00305
00306
00307 void listSingleKey(Key *key) {
00308 char buffer[400];
00309 char *p=buffer;
00310
00311 if (argLong) {
00312 struct passwd *pwd;
00313 struct group *grp;
00314
00315 listAccess(key,p);
00316 p+=strlen(p);
00317 *p=' '; p++;
00318 *p=' '; p++;
00319 *p=' '; p++;
00320
00321 pwd=getpwuid(keyGetUID(key));
00322 strcpy(p,pwd->pw_name);
00323 p+=strlen(p);
00324 *p=' '; p++;
00325 *p=' '; p++;
00326
00327 grp=getgrgid(keyGetGID(key));
00328 strcpy(p,grp->gr_name);
00329 p+=strlen(p);
00330 *p=' '; p++;
00331
00332 sprintf(p,"%*d ",5,keyGetRecordSize(key));
00333 p+=strlen(p);
00334
00335 listTime(keyGetMTime(key),p);
00336 p+=strlen(p);
00337 *p=' '; p++;
00338 }
00339 if (argFullName) keyGetFullName(key,p,sizeof(buffer)-(p-buffer));
00340 else keyGetName(key,p,sizeof(buffer)-(p-buffer));
00341 if (argValue && (keyGetDataSize(key)>0)) {
00342 u_int8_t ktype;
00343
00344 p+=strlen(p);
00345 *p='='; p++;
00346
00347 ktype=keyGetType(key);
00348 if (ktype >= KEY_TYPE_STRING)
00349 p+=keyGetString(key,p,sizeof(buffer)-(p-buffer));
00350 else if (ktype >= KEY_TYPE_BINARY)
00351 p+=sprintf(p,"<BINARY VALUE>");
00352 else if (ktype == KEY_TYPE_LINK)
00353 p+=keyGetLink(key,p,sizeof(buffer)-(p-buffer));
00354
00355 *p=0;
00356 }
00357 puts(buffer);
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00377 int commandRemove() {
00378 if (!argKeyName) {
00379 fprintf(stderr,"kdb rm: No key name\n");
00380 return -1;
00381 }
00382
00383 if (kdbRemove(argKeyName)) {
00384 perror("kdb rm");
00385 return -1;
00386 }
00387 return 0;
00388 }
00389
00390
00391
00392
00393
00394
00413 int commandSet() {
00414 Key key;
00415 int ret;
00416 char error[200];
00417
00418
00419
00420 if (!argKeyName) {
00421 fprintf(stderr,"kdb set: No key name\n");
00422 return -1;
00423 }
00424
00425 keyInit(&key);
00426 keySetName(&key,argKeyName);
00427 ret=kdbGetKey(&key);
00428 if (!ret) {
00429 if (argComment) keySetComment(&key,argComment);
00430 if (argType==KEY_TYPE_UNDEFINED) argType=keyGetType(&key);
00431 } else if (errno!=KDB_RET_NOTFOUND) {
00432 sprintf(error,"kdb set: %s",argKeyName);
00433 perror(error);
00434 }
00435
00436 if (argUID) keySetUID(&key,*argUID);
00437 if (argGID) keySetGID(&key,*argGID);
00438
00439 if (argMode) keySetAccess(&key,argMode);
00440
00441 switch (argType) {
00442 case KEY_TYPE_DIR: keySetType(&key,KEY_TYPE_DIR);
00443 break;
00444 case KEY_TYPE_STRING:
00445 if (argData) keySetString(&key,argData);
00446 break;
00447 case KEY_TYPE_BINARY:
00448 if (argData) keySetBinary(&key,argData,strblen(argData));
00449 break;
00450 case KEY_TYPE_LINK: keySetLink(&key,argData);
00451 break;
00452 }
00453
00454 ret=kdbSetKey(&key);
00455 if (ret) {
00456 sprintf(error,"kdb set: %s",argKeyName);
00457 perror(error);
00458 }
00459 return ret;
00460 }
00461
00462
00463
00464
00465
00466
00480 int commandLink() {
00481 int rc;
00482
00483
00484 if (!argKeyName) {
00485 fprintf(stderr,"kdb ln: No target specified\n");
00486 return -1;
00487 }
00488
00489 if (!argData) {
00490 fprintf(stderr,"kdb ln: %s: No destination specified",argKeyName);
00491 return -1;
00492 }
00493
00494 if ((rc=kdbLink(argKeyName,argData))) {
00495 perror("kdb ln");
00496 }
00497
00498 return rc;
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00537 int commandList() {
00538 KeySet ks;
00539 Key *key=0;
00540 int ret;
00541
00542 ksInit(&ks);
00543
00544 if (!argKeyName) {
00545 KeySet roots;
00546
00547
00548 ksInit(&roots);
00549 kdbGetRootKeys(&roots);
00550
00551 if (argRecursive) {
00552 key=roots.start;
00553 while (key) {
00554 char rootName[200];
00555 KeySet thisRoot;
00556 Key *temp;
00557
00558 ksInit(&thisRoot);
00559 keyGetFullName(key,rootName,sizeof(rootName));
00560 if (argValue) ret=kdbGetChildKeys(rootName,&thisRoot,
00561 (argSort?KDB_O_SORT:0) | argRecursive | KDB_O_DIR |
00562 (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00563 else ret=kdbGetChildKeys(rootName,&thisRoot,
00564 (argSort?KDB_O_SORT:0) | KDB_O_STATONLY | argRecursive |
00565 KDB_O_DIR | (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00566 temp=key->next;
00567 ksAppend(&ks,key);
00568 ksAppendKeys(&ks,&thisRoot);
00569 key=temp;
00570 }
00571 } else ksAppendKeys(&ks,&roots);
00572 } else {
00573
00574
00575 if (argValue) ret=kdbGetChildKeys(argKeyName,&ks,
00576 (argSort?KDB_O_SORT:0) | argRecursive | KDB_O_DIR |
00577 (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00578 else ret=kdbGetChildKeys(argKeyName,&ks,
00579 (argSort?KDB_O_SORT:0) | KDB_O_STATONLY | argRecursive |
00580 KDB_O_DIR | (argAll?KDB_O_INACTIVE:0) | KDB_O_NFOLLOWLINK);
00581
00582 if (ret) {
00583
00584 if (errno==ENOTDIR) {
00585
00586 key=(Key *)malloc(sizeof(Key));
00587 keyInit(key);
00588 keySetName(key,argKeyName);
00589 if (argValue) ret=kdbGetKey(key);
00590 else ret=kdbStatKey(key);
00591 if (ret) {
00592 char error[200];
00593
00594 keyClose(key); free(key);
00595 ksClose(&ks);
00596
00597 sprintf(error,"kdb ls: %s",argKeyName);
00598 perror(error);
00599 return ret;
00600 }
00601 } else {
00602 char error[200];
00603
00604 ksClose(&ks);
00605
00606 sprintf(error,"kdb ls: %s",argKeyName);
00607 perror(error);
00608 return ret;
00609 }
00610 }
00611 }
00612
00613 if (argShow) {
00614 if (argXML) {
00615 if (key) keyToStream(key,stdout,0);
00616 else if (ks.size)
00617 ksToStream(&ks,stdout,KDB_O_XMLHEADERS);
00618 } else {
00619 if (key) listSingleKey(key);
00620 else if (ks.size) {
00621 ksRewind(&ks);
00622 while ((key=ksNext(&ks)))
00623 listSingleKey(key);
00624 }
00625 }
00626 }
00627
00628 ksClose(&ks);
00629 if (key) {
00630 keyClose(key);
00631 free(key);
00632 }
00633 return 0;
00634 }
00635
00636
00637
00638
00639
00640
00641
00664 int commandGet() {
00665 int ret;
00666 Key key;
00667 char *buffer;
00668 char *p;
00669 size_t size,cs=0;
00670
00671 if (!argKeyName) {
00672 fprintf(stderr,"kdb get: No key name\n");
00673 return -1;
00674 }
00675
00676 keyInit(&key);
00677 keySetName(&key,argKeyName);
00678
00679 ret=kdbGetKey(&key);
00680 if (ret) {
00681 char error[200];
00682
00683 sprintf(error,"kdb get: %s",argKeyName);
00684 perror(error);
00685 return ret;
00686 }
00687 size=keyGetDataSize(&key);
00688 if (argDescriptive) {
00689 cs=keyGetCommentSize(&key);
00690 if (cs) size+=cs+3;
00691 }
00692 if (argShell) {
00693 size+=keyGetBaseNameSize(&key);
00694 size+=2;
00695 } else if (argLong) {
00696 if (argFullName) size+=keyGetFullNameSize(&key);
00697 else size+=keyGetNameSize(&key);
00698 }
00699
00700
00701 if (keyGetType(&key)<=KEY_TYPE_BINARY) p=buffer=malloc(size+1);
00702 else p=buffer=malloc(size);
00703
00704
00705 if (argDescriptive) {
00706 if (cs) {
00707 p+=sprintf(p,"# ");
00708 p+=keyGetComment(&key,p,size-(p-buffer));
00709 *--p='\n'; p++;
00710 }
00711 }
00712 if (argShell) {
00713 p+=keyGetBaseName(&key,p,size-(p-buffer));
00714 *--p='='; p++;
00715 *p='\"'; p++;
00716 } else if (argLong) {
00717 if (argFullName) p+=keyGetFullName(&key,p,size-(p-buffer));
00718 else p+=keyGetName(&key,p,size-(p-buffer));
00719 *--p='='; p++;
00720 }
00721
00722 p+=keyGetString(&key,p,size-(p-buffer));
00723 if (argShell) {
00724 *--p='\"'; p++;
00725 *p=0;
00726 }
00727 if (keyGetType(&key)<=KEY_TYPE_BINARY) {
00728 p+=keyGetDataSize(&key);
00729 *p=0;
00730 }
00731
00732 printf("%s\n",buffer);
00733 free(buffer);
00734
00735 return 0;
00736 }
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 int processNode(KeySet *ks, xmlTextReaderPtr reader) {
00752 xmlChar *nodeName=0;
00753 xmlChar *buffer=0;
00754 Key *newKey=0;
00755
00756 nodeName=xmlTextReaderName(reader);
00757 if (!strcmp(nodeName,"key")) {
00758 int end=0;
00759
00760 newKey=malloc(sizeof(Key));
00761 keyInit(newKey);
00762
00763 xmlFree(nodeName); nodeName=0;
00764
00765 buffer=xmlTextReaderGetAttribute(reader,"name");
00766 keySetName(newKey,(char *)buffer);
00767 xmlFree(buffer); buffer=0;
00768
00769 buffer=xmlTextReaderGetAttribute(reader,"type");
00770 if (!strcmp(buffer,"string"))
00771 keySetType(newKey,KEY_TYPE_STRING);
00772 else if (!strcmp(buffer,"binary"))
00773 keySetType(newKey,KEY_TYPE_BINARY);
00774 else if (!strcmp(buffer,"link"))
00775 keySetType(newKey,KEY_TYPE_LINK);
00776 else if (!strcmp(buffer,"directory"))
00777 keySetType(newKey,KEY_TYPE_DIR);
00778 xmlFree(buffer); buffer=0;
00779
00780
00781
00782 buffer=xmlTextReaderGetAttribute(reader,"uid");
00783 if (isdigit(*buffer)) {
00784 keySetUID(newKey,atoi(buffer));
00785 } else {
00786 struct passwd *pwd;
00787 pwd=getpwnam(buffer);
00788 if (pwd) keySetUID(newKey,pwd->pw_uid);
00789 else fprintf(stderr,"kdb: Ignoring invalid user %s.\n", buffer);
00790 }
00791 xmlFree(buffer); buffer=0;
00792
00793
00794
00795 buffer=xmlTextReaderGetAttribute(reader,"gid");
00796 if (isdigit(*buffer)) {
00797 keySetGID(newKey,atoi(buffer));
00798 } else {
00799 struct group *grp;
00800 grp=getgrnam(buffer);
00801 if (grp) keySetGID(newKey,grp->gr_gid);
00802 else fprintf(stderr,"kdb: Ignoring invalid group %s.\n",buffer);
00803 }
00804 xmlFree(buffer); buffer=0;
00805
00806
00807
00808 buffer=xmlTextReaderGetAttribute(reader,"mode");
00809 if (buffer) keySetAccess(newKey,strtol(buffer,0,8));
00810 xmlFree(buffer); buffer=0;
00811
00812
00813
00814 while (!end) {
00815 xmlFree(nodeName); nodeName=0;
00816 xmlTextReaderRead(reader);
00817 nodeName=xmlTextReaderName(reader);
00818
00819 if (!strcmp(nodeName,"value")) {
00820 if (xmlTextReaderIsEmptyElement(reader) ||
00821 xmlTextReaderNodeType(reader)==15) continue;
00822 xmlTextReaderRead(reader);
00823 buffer=xmlTextReaderValue(reader);
00824 if (buffer) {
00825 switch (keyGetType(newKey)) {
00826 case KEY_TYPE_STRING:
00827 keySetString(newKey,buffer);
00828 break;
00829 case KEY_TYPE_BINARY:
00830 keySetBinary(newKey,buffer,strlen(buffer)+1);
00831 break;
00832 case KEY_TYPE_LINK:
00833 keySetLink(newKey,buffer);
00834 break;
00835 }
00836 }
00837 } else if (!strcmp(nodeName,"comment")) {
00838 if (xmlTextReaderIsEmptyElement(reader) ||
00839 xmlTextReaderNodeType(reader)==15) continue;
00840 xmlTextReaderRead(reader);
00841 buffer=xmlTextReaderValue(reader);
00842
00843 keySetComment(newKey,buffer);
00844 } else if (!strcmp(nodeName,"key")) {
00845 if (xmlTextReaderNodeType(reader)==15) end=1;
00846 }
00847
00848 xmlFree(buffer); buffer=0;
00849 }
00850 }
00851
00852 if (nodeName) xmlFree(nodeName),nodeName=0;
00853
00854 if (newKey) ksAppend(ks,newKey);
00855 return 0;
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 int ksFromXMLReader(KeySet *ks,xmlTextReaderPtr reader) {
00868 int ret;
00869
00870 ret = xmlTextReaderRead(reader);
00871 ret = xmlTextReaderRead(reader);
00872 while (ret == 1) {
00873 processNode(ks, reader);
00874 ret = xmlTextReaderRead(reader);
00875 }
00876 xmlFreeTextReader(reader);
00877 if (ret) fprintf(stderr,"kdb: Failed to parse XML input\n");
00878
00879 return ret;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 int ksFromXMLfile(KeySet *ks,char *filename) {
00891 xmlTextReaderPtr reader;
00892 int ret;
00893
00894 reader = xmlNewTextReaderFilename(filename);
00895 if (reader) {
00896 ret=ksFromXMLReader(ks,reader);
00897 } else {
00898 perror("kdb");
00899 return 1;
00900 }
00901 return ret;
00902 }
00903
00904
00905
00906
00907
00908
00909 int ksFromXML(KeySet *ks,int fd) {
00910
00911 char filename[]="/var/tmp/rgeditXXXXXX";
00912 FILE *xmlfile=0;
00913 xmlfile=fdopen(mkstemp(filename),"rw+");
00914 while (! feof(xmlfile)) {
00915 char buffer[1000];
00916 ssize_t readed, writen;
00917
00918 readed=read(fd,buffer,sizeof(buffer));
00919 if (readed<0) {
00920 perror("kdb");
00921 fclose(xmlfile);
00922 remove(filename);
00923 return 1;
00924 }
00925
00926 writen=write(fileno(xmlfile),buffer,readed);
00927 if (writen<0) {
00928 perror("kdb");
00929 fclose(xmlfile);
00930 remove(filename);
00931 return 1;
00932 }
00933 }
00934 fclose(xmlfile);
00935 return ksFromXMLfile(ks,filename);
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00999 int commandEdit() {
01000 KeySet ks;
01001 KeySet ksEdited;
01002 KeySet toRemove;
01003 Key *current;
01004 char filename[]="/var/tmp/rgeditXXXXXX";
01005 char command[300];
01006 FILE *xmlfile=0;
01007
01008 ksInit(&ks);
01009
01010 kdbGetChildKeys(argKeyName,&ks, KDB_O_SORT | KDB_O_NFOLLOWLINK |
01011 (argAll?KDB_O_INACTIVE:0) | (argRecursive?KDB_O_RECURSIVE:0));
01012
01013 if (!ks.size) {
01014
01015 current=malloc(sizeof(Key));
01016 keyInit(current);
01017 keySetName(current,argKeyName);
01018 if (kdbGetKey(current)) {
01019
01020 keyClose(current);
01021 free(current);
01022 current=0;
01023 } else {
01024
01025 ksAppend(&ks,current);
01026 current=0;
01027 }
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038 xmlfile=fdopen(mkstemp(filename),"rw+");
01039
01040 ksToStream(&ks,xmlfile,KDB_O_XMLHEADERS);
01041 fclose(xmlfile);
01042
01043 sprintf(command,"[ -z \"$EDITOR\" ] && EDITOR=vi; $EDITOR %s",filename);
01044 system(command);
01045
01046 ksInit(&toRemove);
01047 ksInit(&ksEdited);
01048
01049
01050
01051
01052
01053 ksFromXMLfile(&ksEdited,filename);
01054 remove(filename);
01055
01056 ksCompare(&ks,&ksEdited,&toRemove);
01057
01058 kdbSetKeys(&ks);
01059
01060 ksRewind(&toRemove);
01061 while ((current=ksNext(&toRemove))) {
01062 char keyName[800];
01063
01064 keyGetFullName(current,keyName,sizeof(keyName));
01065 kdbRemove(keyName);
01066 }
01067
01068 return 0;
01069 }
01070
01071
01072
01073
01088 int commandImport() {
01089 KeySet ks;
01090
01091 ksInit(&ks);
01092
01093
01094 if (argKeyName) ksFromXMLfile(&ks,argKeyName);
01095 else ksFromXML(&ks,fileno(stdin) );
01096
01097 return kdbSetKeys(&ks);
01098 }
01099
01100
01101
01102
01103
01121 int commandExport() {
01122
01123
01124
01125
01126 argSort=1;
01127 argRecursive=1;
01128 argAll=1;
01129 argXML=1;
01130 argShow=1;
01131 argValue=1;
01132 argFullName=1;
01133
01134
01135 setlocale(LC_ALL,"en_US.UTF-8");
01136
01137 return commandList();
01138 }
01139
01140
01155 int commandMonitor() {
01156 Key toMonitor;
01157 u_int32_t diff;
01158 char *newData=0;
01159 size_t dataSize;
01160
01161 keyInit(&toMonitor);
01162 keySetName(&toMonitor,argKeyName);
01163 kdbGetKey(&toMonitor);
01164
01165 diff=kdbMonitorKey(
01166 &toMonitor,
01167 KEY_FLAG_HASDATA,
01168 0,
01169 500 );
01170
01171
01172
01173
01174
01175
01176 newData=malloc(dataSize=keyGetDataSize(&toMonitor));
01177 keyGetString(&toMonitor,newData,dataSize);
01178 printf("New value is %s\n",newData);
01179 return 0;
01180 }
01181
01182
01183 int doCommand(int command) {
01184 switch (command) {
01185 case CMD_SET: return commandSet();
01186 case CMD_LIST: return commandList();
01187 case CMD_LINK: return commandLink();
01188 case CMD_GET: return commandGet();
01189 case CMD_REMOVE: return commandRemove();
01190 case CMD_EDIT: return commandEdit();
01191 case CMD_LOAD: return commandImport();
01192 case CMD_SAVE: return commandExport();
01193 case CMD_MONITOR: return commandMonitor();
01194 }
01195 return 0;
01196 }
01197
01198
01199 int main(int argc, char **argv) {
01200 int command=0;
01201 int ret=0;
01202
01203 command=parseCommandLine(argc,argv);
01204
01205 kdbOpen();
01206 ret=doCommand(command);
01207 kdbClose();
01208
01209 return ret;
01210 }
01211