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 #include <stdio.h>
00026 #include <strings.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <sys/stat.h>
00030 #include <errno.h>
00031 #include <unistd.h>
00032 #include <sys/types.h>
00033 #include <pwd.h>
00034 #include <grp.h>
00035 #include <langinfo.h>
00036 
00037 #include "kdb.h"
00038 #include "kdbprivate.h"
00039 
00040 extern int errno;
00041 
00042 
00046 size_t strblen(const char *s) {
00047     char *found=index(s,0);
00048     if (found) return found-s+1;
00049     return 0;
00050 }
00051 
00052 
00123 int keyInit(Key *key) {
00124     if (!key) return errno=KDB_RET_NULLKEY;
00125 
00126     memset(key,0,sizeof(Key));
00127     key->type=KEY_TYPE_UNDEFINED;
00128     key->uid=getuid();
00129     key->gid=getgid();
00130     key->access=umask(0); umask(key->access);
00131     key->access=0666 & ~key->access;
00132 
00133     key->flags |= KEY_FLAG_INITIALIZED | KEY_FLAG_ACTIVE;
00134 
00135     return 0;
00136 }
00137 
00138 
00139 
00140 
00149 int keyClose(Key *key) {
00150     if (!key) return errno=KDB_RET_NULLKEY;
00151     if (!keyIsInitialized(key)) return 0;
00152 
00153     free(key->key);
00154     free(key->data);
00155     free(key->comment);
00156     free(key->userDomain);
00157     memset(key,0,sizeof(Key));
00158     return 0;
00159 }
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00176 int keyIsInitialized(const Key *key) {
00177     if (!key) return 0;
00178     return ((key->flags & KEY_FLAG_INITMASK)==KEY_FLAG_INITIALIZED);
00179 }
00180 
00181 
00182 
00188 int keyNeedsSync(const Key *key) {
00189     if (!key) return 0;
00190     return (key->flags & KEY_FLAG_NEEDSYNC);
00191 }
00192 
00193 
00194 
00203 u_int8_t keyGetType(const Key *key) {
00204     if (!key || !keyIsInitialized(key)) {
00205         errno=KDB_RET_UNINITIALIZED;
00206         return KEY_TYPE_UNDEFINED;
00207     }
00208 
00209     return key->type;
00210 }
00211 
00212 
00276 u_int8_t keySetType(Key *key,u_int8_t newType) {
00277     mode_t dirSwitch=0111;
00278 
00279     if (!key) {
00280         errno=KDB_RET_UNINITIALIZED;
00281         return KEY_TYPE_UNDEFINED;
00282     }
00283     if (!keyIsInitialized(key)) keyInit(key);
00284 
00285     switch (newType) {
00286         case KEY_TYPE_DIR:
00287             key->type=KEY_TYPE_DIR;
00288             dirSwitch=umask(0); umask(dirSwitch);
00289             dirSwitch=0111 & ~dirSwitch;
00290             key->access|=dirSwitch | S_IFDIR;
00291             keySetRaw(key,0,0); 
00292             break;
00293         default:
00294             key->type=newType;
00295             key->access &= ~(S_IFDIR | dirSwitch);
00296             key->flags |= KEY_FLAG_NEEDSYNC;
00297     }
00298     return key->type;
00299 }
00300 
00301 
00302 
00311 size_t keyGetDataSize(const Key *key) {
00312     if (!key || !keyIsInitialized(key)) {
00313         errno=KDB_RET_UNINITIALIZED;
00314         return -1;
00315     }
00316 
00317     return key->dataSize;
00318 }
00319 
00320 
00321 size_t keyGetRecordSize(const Key *key) {
00322     if (!key || !keyIsInitialized(key)) {
00323         errno=KDB_RET_UNINITIALIZED;
00324         return -1;
00325     }
00326 
00327     return key->recordSize;
00328 }
00329 
00330 
00331 
00332 
00340 size_t keyGetNameSize(const Key *key) {
00341     if (!key || !keyIsInitialized(key)) {
00342         errno=KDB_RET_UNINITIALIZED;
00343         return 0;
00344     }
00345 
00346     if (key->key) return strblen(key->key);
00347     else return 0;
00348 }
00349 
00350 
00351 
00352 
00360 size_t keyGetFullNameSize(const Key *key) {
00361     size_t returnedSize;
00362 
00363     if (!key || !keyIsInitialized(key)) {
00364         errno=KDB_RET_UNINITIALIZED;
00365         return -1;
00366     }
00367 
00368     if (!key->key) return 0;
00369 
00370     returnedSize=strblen(key->key);
00371 
00372     if (!strncmp("user",key->key,sizeof("user")-1) && key->userDomain)
00373         returnedSize+=strblen(key->userDomain);
00374 
00375     return returnedSize;
00376 }
00377 
00378 
00379 
00388 size_t keyGetFullName(const Key *key, char *returnedName, size_t maxSize) {
00389     size_t userSize=sizeof("user")-1;
00390     size_t userDomainSize,length;
00391     char *cursor;
00392 
00393     length=keyGetFullNameSize(key);
00394     if (length < 0) return length;
00395     if (length > maxSize) {
00396         errno=KDB_RET_TRUNC;
00397         return -1;
00398     }
00399 
00400     cursor=returnedName;
00401     if (!strncmp("user",key->key,userSize)) {
00402         strncpy(cursor,key->key,userSize);
00403         cursor+=userSize;
00404         if (key->userDomain) {
00405             *cursor=':'; ++cursor;
00406             userDomainSize=strblen(key->userDomain)-1;
00407             strcpy(cursor,key->userDomain);
00408             cursor+=userDomainSize;
00409         }
00410         strcpy(cursor,key->key+userSize);
00411     } else strcpy(cursor,key->key);
00412 
00413     return length;
00414 }
00415 
00416 
00417 
00418 
00427 size_t keyGetName(const Key *key, char *returnedName, size_t maxSize) {
00428     size_t bytes;
00429 
00430     if (!key || !keyIsInitialized(key)) {
00431         errno=KDB_RET_UNINITIALIZED;
00432         return 0;
00433     }
00434 
00435     if (!key->key) {
00436         errno=KDB_RET_NOKEY;
00437         return 0;
00438     }
00439 
00440     bytes=strblen(strncpy(returnedName,key->key,maxSize));
00441     if (maxSize < strblen(key->key)) {
00442         errno=KDB_RET_TRUNC;
00443         return 0;
00444     }
00445     return bytes;
00446 }
00447 
00448 
00449 
00450 
00451 
00474 size_t keySetName(Key *key, const char *newName) {
00475     size_t length;
00476     size_t rootLength, userLength, systemLength, userDomainLength;
00477     size_t keyNameSize=1; 
00478 
00479     if (!key) {
00480         errno=KDB_RET_UNINITIALIZED;
00481         return 0;
00482     }
00483     if (!keyIsInitialized(key)) keyInit(key);
00484 
00485     
00486     if (!newName || !(length=strlen(newName))) {
00487         if (key->key) {
00488             free(key->key);
00489             key->key=0;
00490         }
00491         key->flags &= ~(KEY_FLAG_HASKEY | KEY_FLAG_NEEDSYNC);
00492         return 0;
00493     }
00494 
00495     
00496     while (newName[length]==RG_KEY_DELIM) {
00497         length--;
00498     }
00499 
00500     rootLength=keyNameGetRootNameSize(newName);
00501     if (!rootLength) {
00502         errno=KDB_RET_INVALIDKEY;
00503         return 0;
00504     }
00505     userLength=sizeof("user")-1;
00506     systemLength=sizeof("system")-1;
00507     userDomainLength=rootLength-userLength-1;
00508     if (userDomainLength<0) userDomainLength=0;
00509 
00510     if (!strncmp("user",newName,userLength<length?userLength:length)) {
00511         
00512         if (length > userLength) {
00513             
00514             if (*(newName+userLength)==':') {
00515                 
00516                 if (userDomainLength > 0) {
00517                     key->userDomain=realloc(key->userDomain,userDomainLength+1);
00518                     strncpy(key->userDomain,newName+userLength+1,userDomainLength);
00519                     key->userDomain[userDomainLength]=0;
00520                 }
00521                 keyNameSize+=length-userDomainLength-1;  
00522             } else if (*(newName+userLength)!=RG_KEY_DELIM) {
00523                 
00524                 errno=KDB_RET_INVALIDKEY;
00525                 return 0;
00526             } else {
00527                 
00528                 keyNameSize+=length;
00529             }
00530         } else {
00531             
00532             keyNameSize+=userLength;
00533         }
00534 
00535         key->key=realloc(key->key,keyNameSize);
00536 
00537         
00538         if (!key->key) return 0;
00539 
00540         strcpy(key->key,"user");
00541         strncpy(key->key+userLength,newName+rootLength,length-rootLength);
00542         key->key[keyNameSize-1]=0;
00543 
00544         if (!key->userDomain) {
00545             size_t bsize=strblen(getenv("USER"));
00546 
00547             if (!bsize) {}
00548             else {
00549                 key->userDomain=malloc(bsize);
00550                 strncpy(key->userDomain,getenv("USER"),bsize);
00551             }
00552         }
00553 
00554     } else if (!strncmp("system",newName,systemLength<length?systemLength:length)) {
00555         
00556         if (length > systemLength && *(newName+systemLength)!=RG_KEY_DELIM) {
00557             
00558             errno=KDB_RET_INVALIDKEY;
00559             return 0;
00560         }
00561         keyNameSize+=length;
00562         key->key=realloc(key->key,keyNameSize);
00563 
00564         
00565         if (!key->key) return 0;
00566 
00567         strncpy(key->key,newName,length);
00568         key->key[keyNameSize-1]=0;
00569     } else {
00570         
00571         errno=KDB_RET_INVALIDKEY;
00572         return 0;
00573     }
00574 
00575     key->flags |= KEY_FLAG_HASKEY | KEY_FLAG_NEEDSYNC;
00576 
00577     return keyNameSize;
00578 }
00579 
00580 
00581 
00603 size_t keyGetOwner(const Key *key, char *returned, size_t maxSize) {
00604     size_t bytes;
00605 
00606     if (!key || !keyIsInitialized(key)) {
00607         errno=KDB_RET_UNINITIALIZED;
00608         return 0;
00609     }
00610 
00611     if (!key->userDomain) {
00612         errno=KDB_RET_NODOMAIN;
00613         return 0;
00614     }
00615 
00616     if (maxSize < (bytes=strblen(key->userDomain))) {
00617         errno=KDB_RET_TRUNC;
00618         return 0;
00619     } else strcpy(returned,key->userDomain);
00620     return bytes;
00621 }
00622 
00623 
00636 size_t keySetOwner(Key *key, const char *userDomain) {
00637     size_t size;
00638 
00639     if (!key) {
00640         errno=KDB_RET_UNINITIALIZED; 
00641         return -1;
00642     }
00643     if (!keyIsInitialized(key)) keyInit(key);
00644 
00645     if ((size=strblen(userDomain)) > 0) {
00646         if (key->userDomain) {
00647             key->userDomain=realloc(key->userDomain,size);
00648         } else {
00649             key->userDomain=malloc(size);
00650         }
00651         if (!key->userDomain) return -1; 
00652 
00653         strcpy(key->userDomain,userDomain);
00654         key->flags |= KEY_FLAG_HASDOMAIN | KEY_FLAG_NEEDSYNC;
00655         return size;
00656     } else if (key->userDomain) {
00657         free(key->userDomain);
00658         key->userDomain=0;
00659         key->flags &= ~(KEY_FLAG_HASDOMAIN | KEY_FLAG_NEEDSYNC);
00660     }
00661     return 0;
00662 }
00663 
00664 
00665 
00666 
00678 size_t keyGetComment(const Key *key, char *returnedDesc, size_t maxSize) {
00679     size_t bytes;
00680 
00681     if (!key || !keyIsInitialized(key)) {
00682         errno=KDB_RET_UNINITIALIZED;
00683         return 0;
00684     }
00685 
00686     if (!key->comment) {
00687         errno=KDB_RET_NODESC;
00688         return 0;
00689     }
00690 
00691     bytes=strblen(strncpy(returnedDesc,key->comment,maxSize));
00692     if (maxSize < strblen(key->comment)) {
00693         errno=KDB_RET_TRUNC;
00694         return 0;
00695     }
00696     return bytes;
00697 }
00698 
00699 
00700 
00711 size_t keySetComment(Key *key, const char *newComment) {
00712     size_t size;
00713 
00714     if (!key) {
00715         errno=KDB_RET_UNINITIALIZED; 
00716         return 0;
00717     }
00718     if (!keyIsInitialized(key)) keyInit(key);
00719 
00720     if (newComment && (size=strblen(newComment)) > 0) {
00721         if (key->flags & KEY_FLAG_HASCOMMENT) {
00722             key->comment=realloc(key->comment,size);
00723         } else {
00724             key->comment=malloc(size);
00725         }
00726         if (!key->comment) return 0;
00727 
00728         strcpy(key->comment,newComment);
00729         key->flags |= KEY_FLAG_HASCOMMENT | KEY_FLAG_NEEDSYNC;
00730         return key->commentSize=size;
00731     } else if (key->flags & KEY_FLAG_HASCOMMENT) {
00732         free(key->comment);
00733         key->comment=0;
00734         key->flags &= ~(KEY_FLAG_HASCOMMENT | KEY_FLAG_NEEDSYNC);
00735     }
00736     return key->commentSize=0;
00737 }
00738 
00739 
00740 
00751 size_t keyGetCommentSize(const Key *key) {
00752     if (!key || !keyIsInitialized(key)) {
00753         errno=KDB_RET_UNINITIALIZED;
00754         return 0;
00755     }
00756 
00757     if (!key->comment) {
00758         errno=KDB_RET_NODESC;
00759         return 0;
00760     }
00761 
00762     return strblen(key->comment);
00763 }
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 
00797 
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00867 size_t keyGetString(const Key *key, char *returnedString, size_t maxSize) {
00868     if (!key || !keyIsInitialized(key)) {
00869         errno=KDB_RET_UNINITIALIZED;
00870         return 0;
00871     }
00872 
00873     if (!key->data) {
00874         *returnedString=0;
00875         errno=KDB_RET_NODATA;
00876         return 0;
00877     }
00878 
00879     if (key->dataSize > maxSize) {
00880         errno=KDB_RET_TRUNC;
00881         return 0;
00882     }
00883 
00884     if (key->type < KEY_TYPE_STRING) {
00885         errno=KDB_RET_TYPEMISMATCH;
00886         return 0;
00887     }
00888 
00889     strcpy(returnedString,key->data);
00890     return key->dataSize;
00891 }
00892 
00893 
00894 
00895 
00896 
00906 size_t keySetString(Key *key, const char *newString) {
00907     size_t ret=newString?strblen(newString):0;
00908 
00909     if (!newString || !ret) ret=keySetRaw(key,0,0);
00910     else keySetRaw(key,newString,ret);
00911 
00912     keySetType(key,KEY_TYPE_STRING);
00913 
00914     return ret;
00915 }
00916 
00917 
00918 
00919 
00929 size_t keyGetBinary(const Key *key, void *returnedBinary, size_t maxSize) {
00930     if (!key || !keyIsInitialized(key))
00931         return errno=KDB_RET_UNINITIALIZED;
00932 
00933     if (!key->data) {
00934         errno=KDB_RET_NODATA;
00935         return 0;
00936     }
00937 
00938     if (key->dataSize > maxSize) {
00939         errno=KDB_RET_TRUNC;
00940         return 0;
00941     }
00942 
00943     memcpy(returnedBinary,key->data,key->dataSize);
00944     return key->dataSize;
00945 }
00946 
00947 
00948 
00949 
00966 size_t keySetBinary(Key *key, const void *newBinary, size_t dataSize) {
00967     size_t ret=keySetRaw(key,newBinary,dataSize);
00968 
00969     keySetType(key,KEY_TYPE_BINARY);
00970 
00971     return ret;
00972 }
00973 
00974 
00975 
00976 
00989 size_t keySetRaw(Key *key, const void *newBinary, size_t dataSize) {
00990     if (!key) {
00991         errno=KDB_RET_UNINITIALIZED;
00992         return 0;
00993     }
00994     if (!keyIsInitialized(key)) keyInit(key);
00995 
00996     if (!dataSize || !newBinary) {
00997         if (key->data) {
00998             free(key->data);
00999             key->data=0;
01000         }
01001         key->flags &= ~(KEY_FLAG_HASDATA);
01002         key->flags |= KEY_FLAG_NEEDSYNC;
01003         return 0;
01004     }
01005 
01006     key->dataSize=dataSize;
01007     if (key->data) key->data=realloc(key->data,key->dataSize);
01008     else key->data=malloc(key->dataSize);
01009 
01010     if (!key->data) return 0;
01011 
01012     memcpy(key->data,newBinary,key->dataSize);
01013     key->flags |= KEY_FLAG_HASDATA | KEY_FLAG_NEEDSYNC;
01014     return key->dataSize;
01015 }
01016 
01017 
01018 
01019 
01020 size_t keyGetLink(const Key *key, char *returnedTarget, size_t maxSize) {
01021     if (!key || !keyIsInitialized(key))
01022         return errno=KDB_RET_UNINITIALIZED;
01023 
01024     if (!key->data) {
01025         errno=KDB_RET_NODATA;
01026         return 0;
01027     }
01028 
01029     if (key->type != KEY_TYPE_LINK) {
01030         errno=KDB_RET_TYPEMISMATCH;
01031         return 0;
01032     }
01033 
01034     if (key->dataSize > maxSize) {
01035         errno=KDB_RET_TRUNC;
01036         return 0;
01037     }
01038 
01039     strcpy(returnedTarget,key->data);
01040     return key->dataSize;
01041 }
01042 
01043 
01044 
01045 
01046 
01047 size_t keySetLink(Key *key, const char *target) {
01048     size_t ret=target?strblen(target):0;
01049 
01050     if (!target || !ret) ret=keySetRaw(key,0,0);
01051     else keySetRaw(key,target,ret);
01052 
01053     keySetType(key,KEY_TYPE_LINK);
01054 
01055     return ret;
01056 }
01057 
01058 
01059 
01074 int keyDup(const Key *source, Key *dest) {
01075 
01076     
01077     keyClose(dest);
01078 
01079     
01080     *dest=*source;
01081 
01082     
01083     dest->key=
01084     dest->comment=
01085     dest->userDomain=
01086     dest->data=0;
01087 
01088     
01089     keySetName(dest,source->key);
01090     keySetComment(dest,source->comment);
01091     keySetOwner(dest,source->userDomain);
01092     keySetRaw(dest,source->data,source->dataSize);
01093 
01094     dest->flags=source->flags;
01095 
01096     return 0;
01097 }
01098 
01099 
01100 
01112 uid_t keyGetUID(const Key *key) {
01113     if (!key || !keyIsInitialized(key)) {
01114         errno=KDB_RET_UNINITIALIZED;
01115         return -1;
01116     }
01117 
01118     
01119 
01120     return key->uid;
01121 }
01122 
01123 
01124 
01125 
01137 int keySetUID(Key *key, uid_t uid) {
01138     if (!key) return errno=KDB_RET_UNINITIALIZED;
01139     if (!keyIsInitialized(key)) keyInit(key);
01140 
01141     key->uid=uid;
01142     key->flags |= KEY_FLAG_HASUID | KEY_FLAG_NEEDSYNC;
01143 
01144     return 0;
01145 }
01146 
01147 
01148 
01156 gid_t keyGetGID(const Key *key) {
01157     if (!key || !keyIsInitialized(key)) {
01158         errno=KDB_RET_UNINITIALIZED;
01159         return -1;
01160     }
01161 
01162     
01163 
01164     return key->gid;
01165 }
01166 
01167 
01168 
01176 int keySetGID(Key *key, gid_t gid) {
01177     if (!key) return errno=KDB_RET_UNINITIALIZED;
01178     if (!keyIsInitialized(key)) keyInit(key);
01179 
01180     key->gid=gid;
01181     key->flags |= KEY_FLAG_HASGID | KEY_FLAG_NEEDSYNC;
01182 
01183     return 0;
01184 }
01185 
01186 
01187 
01191 mode_t keyGetAccess(const Key *key) {
01192     if (!key || !keyIsInitialized(key)) {
01193         errno=KDB_RET_UNINITIALIZED;
01194         return -1;
01195     }
01196 
01197     
01198 
01199     return key->access;
01200 }
01201 
01202 
01203 
01204 
01208 int keySetAccess(Key *key, mode_t mode) {
01209     if (!key) return errno=KDB_RET_UNINITIALIZED;
01210     if (!keyIsInitialized(key)) keyInit(key);
01211 
01212     key->access=mode;
01213     key->flags |= KEY_FLAG_HASPRM | KEY_FLAG_NEEDSYNC;
01214 
01215     return 0;
01216 }
01217 
01218 
01219 
01220 
01221 
01225 time_t keyGetMTime(const Key *key) {
01226     if (!key || !keyIsInitialized(key)) {
01227         errno=KDB_RET_UNINITIALIZED;
01228         return -1;
01229     }
01230     
01231 
01232     return key->mtime;
01233 }
01234 
01235 
01236 
01240 time_t keyGetATime(const Key *key) {
01241     if (!key || !keyIsInitialized(key)) {
01242         errno=KDB_RET_UNINITIALIZED;
01243         return -1;
01244     }
01245     
01246 
01247     return key->atime;
01248 }
01249 
01250 
01254 time_t keyGetCTime(const Key *key) {
01255     if (!key || !keyIsInitialized(key)) {
01256         errno=KDB_RET_UNINITIALIZED;
01257         return -1;
01258     }
01259     
01260 
01261     return key->ctime;
01262 }
01263 
01264 
01265 
01270 size_t keyGetParentSize(const Key *key) {
01271     char *parentNameEnd;
01272 
01273     if (!key || !keyIsInitialized(key)) {
01274         errno=KDB_RET_UNINITIALIZED;
01275         return 0;
01276     }
01277 
01278     if (!key->key) {
01279         errno=KDB_RET_NOKEY;
01280         return 0;
01281     }
01282 
01283     
01284 
01285 
01286 
01287 
01288 
01289     parentNameEnd=rindex(key->key,RG_KEY_DELIM);
01290 
01291     if (!parentNameEnd || parentNameEnd==key->key) {
01292         
01293         return 0;
01294     }
01295 
01296     
01297     if ((parentNameEnd-key->key) == (strlen(key->key)-1)) {
01298         parentNameEnd--;
01299         while (*parentNameEnd!=RG_KEY_DELIM) parentNameEnd--;
01300     }
01301 
01302     return parentNameEnd - key->key;
01303 }
01304 
01305 
01306 
01314 size_t keyGetParent(const Key *key, char *returnedParent, size_t maxSize) {
01315     size_t parentSize;
01316 
01317     parentSize=keyGetParentSize(key);
01318 
01319     if (parentSize > maxSize) {
01320         errno=KDB_RET_TRUNC;
01321         return 0;
01322     } else strncpy(returnedParent,key->key,parentSize);
01323 
01324     return parentSize;
01325 }
01326 
01327 
01328 
01339 u_int32_t keyCompare(const Key *key1, const Key *key2) {
01340     u_int32_t ret=0;
01341 
01342 
01343     
01344     if (key1->uid != key2->uid)                    ret|=KEY_FLAG_HASUID;
01345     if (key1->gid != key2->gid)                    ret|=KEY_FLAG_HASGID;
01346     if (key1->type != key2->type)                  ret|=KEY_FLAG_HASTYPE;
01347     if ((key1->access & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
01348         (key2->access & (S_IRWXU|S_IRWXG|S_IRWXO))) ret|=KEY_FLAG_HASPRM;
01349 
01350     
01351 
01352     if (key1->key && key2->key) {
01353         if (strcmp(key1->key,key2->key))            ret|=KEY_FLAG_HASKEY;
01354     } else {
01355         if (key1->key)                              ret|=KEY_FLAG_HASKEY;
01356         else if (key2->key)                         ret|=KEY_FLAG_HASKEY;
01357     }
01358 
01359     if (key1->comment && key2->comment) {
01360         if (strcmp(key1->comment,key2->comment))    ret|=KEY_FLAG_HASCOMMENT;
01361     } else {
01362         if (key1->comment)                          ret|=KEY_FLAG_HASCOMMENT;
01363         else if (key2->comment)                     ret|=KEY_FLAG_HASCOMMENT;
01364     }
01365 
01366     if (key1->userDomain && key2->userDomain) {
01367         if (strcmp(key1->userDomain,key2->userDomain)) ret|=KEY_FLAG_HASDOMAIN;
01368     } else {
01369         if (key1->userDomain)                       ret|=KEY_FLAG_HASDOMAIN;
01370         else if (key2->comment)                     ret|=KEY_FLAG_HASDOMAIN;
01371     }
01372 
01373 
01374     
01375     if (memcmp(key1->data,key2->data,
01376             (key1->dataSize<=key2->dataSize?key1->dataSize:key2->dataSize)))
01377         ret|=KEY_FLAG_HASDATA;
01378 
01379     return ret;
01380 }
01381 
01382 
01383 
01384 
01385 
01386 
01412 size_t keyToStream(const Key *key, FILE* stream, unsigned long options) {
01413     size_t written=0;
01414     char buffer[800];
01415     struct passwd *pwd=0;
01416     struct group *grp=0;
01417 
01418 
01419     if (!key || !keyIsInitialized(key) || !key->key) {
01420         errno=KDB_RET_UNINITIALIZED;
01421         return 0;
01422     }
01423 
01424     keyGetFullName(key,buffer,sizeof(buffer));
01425 
01426     if (!(options & KDB_O_NUMBERS)) {
01427         pwd=getpwuid(keyGetUID(key));
01428         grp=getgrgid(keyGetGID(key));
01429     }
01430 
01431     
01432     written+=fprintf(stream,"<key name=\"%s\"", buffer);
01433 
01434     if (options & KDB_O_CONDENSED) written+=fprintf(stream," ");
01435     else written+=fprintf(stream,"\n     ");
01436 
01437 
01438 
01439 
01440     
01441     if (options & KDB_O_NUMBERS) {
01442         written+=fprintf(stream,"type=\"%d\"", keyGetType(key));
01443     } else {
01444         u_int8_t type=keyGetType(key);
01445         buffer[0]=0;
01446 
01447         switch (type) {
01448             case KEY_TYPE_STRING:
01449                 strcpy(buffer,"string");
01450                 break;
01451             case KEY_TYPE_BINARY:
01452                 strcpy(buffer,"binary");
01453                 break;
01454             case KEY_TYPE_LINK:
01455                 strcpy(buffer,"link");
01456                 break;
01457             case KEY_TYPE_DIR:
01458                 strcpy(buffer,"directory");
01459                 break;
01460         }
01461         if (buffer[0]) written+=fprintf(stream,"type=\"%s\"", buffer);
01462         else written+=fprintf(stream,"type=\"%d\"", type);
01463     }
01464 
01465 
01466 
01467     
01468     if (pwd) written+=fprintf(stream," uid=\"%s\"",pwd->pw_name);
01469     else  written+=fprintf(stream,   " uid=\"%d\"",keyGetUID(key));
01470 
01471     if (grp) written+=fprintf(stream," gid=\"%s\"",grp->gr_name);
01472     else  written+=fprintf(stream,   " gid=\"%d\"",keyGetGID(key));
01473 
01474     written+=fprintf(stream," mode=\"0%o\">",
01475         keyGetAccess(key) & (S_IRWXU|S_IRWXG|S_IRWXO));
01476 
01477 
01478 
01479     if (!(options & KDB_O_CONDENSED) && (key->data || key->comment))
01480         written+=fprintf(stream,"\n\n     ");
01481 
01482     if (key->data)
01483         written+=
01484             fprintf(stream,"<value><![CDATA[%s]]></value>",(char *)key->data);
01485 
01486 
01487 
01488     if (!(options & KDB_O_CONDENSED)) {
01489         written+=fprintf(stream,"\n");
01490         if (key->comment) written+=fprintf(stream,"     ");
01491     }
01492 
01493     if (key->comment) {
01494         written+=fprintf(stream,"<comment><![CDATA[%s]]></comment>", key->comment);
01495         if (!(options & KDB_O_CONDENSED))
01496             written+=fprintf(stream,"\n");
01497     }
01498 
01499     written+=fprintf(stream,"</key>");
01500 
01501     if (!(options & KDB_O_CONDENSED))
01502         written+=fprintf(stream,"\n\n\n\n\n\n");
01503 
01504     return written;
01505 }
01506 
01507 
01508 
01509 
01510 
01511 
01512 
01513 
01514 
01515 
01516 
01517 
01518 
01519 
01520 
01521 
01522 
01523 
01524 
01525 
01526 
01527 
01528 
01529 
01530 
01531 
01532 
01533 
01534 
01535 
01536 
01537 
01538 
01539 
01540 
01541 
01542 
01543 
01544 
01545 
01546 
01547 
01548 
01549 
01550 
01551 
01552 
01553 
01554 
01555 
01556 
01557 
01558 
01559 
01560 
01561 
01562 
01563 
01564 
01565 
01566 
01567 
01568 
01569 
01570 
01571 
01572 
01573 
01574 
01575 
01576 
01577 
01578 
01579 
01580 
01581 
01582 
01583 
01584 
01585 
01586 
01587 
01588 
01589 
01590 
01591 
01592 
01593 
01594 
01595 
01596 
01597 
01598 
01599 
01600 
01601 
01602 
01603 
01604 
01605 
01606 
01607 
01608 
01609 
01610 
01611 
01612 
01613 
01614 
01615 
01616 
01617 
01618 
01619 
01620 
01621 
01622 
01623 
01624 
01625 
01626 
01627 
01628 
01629 
01630 
01631 
01632 
01633 
01634 
01635 
01636 
01637 
01638 
01639 
01640 
01641 
01642 
01643 
01644 
01645 
01646 
01647 
01648 
01649 
01650 
01651 
01652 
01653 
01654 
01665 int keyNameIsSystem(const char *keyName) {
01666     if (!keyName) return 0;
01667     if (!strlen(keyName)) return 0;
01668 
01669     if (!strncmp("system",keyName,sizeof("system")-1)) return 1;
01670     return 0;
01671 }
01672 
01673 
01684 int keyNameIsUser(const char *keyName) {
01685     if (!keyName) return 0;
01686     if (!strlen(keyName)) return 0;
01687 
01688     if (!strncmp("user",keyName,sizeof("user")-1)) return 1;
01689     return 0;
01690 }
01691 
01692 
01693 
01703 int keyIsSystem(const Key *key) {
01704     if (!key) return 0;
01705     if (!keyIsInitialized(key)) return 0;
01706 
01707     return keyNameIsSystem(key->key);
01708 }
01709 
01710 
01711 
01721 int keyIsUser(const Key *key) {
01722     if (!key) return 0;
01723     if (!keyIsInitialized(key)) return 0;
01724 
01725     return keyNameIsUser(key->key);
01726 }
01727 
01728 
01729 
01730 
01743 int keyNameGetNamespace(const char *keyName) {
01744     if (keyNameIsSystem(keyName)) return KEY_NS_SYSTEM;
01745     if (keyNameIsUser(keyName)) return KEY_NS_USER;
01746     return 0;
01747 }
01748 
01749 
01750 
01763 int keyGetNamespace(const Key *key) {
01764     if (!key) return 0;
01765     if (!keyIsInitialized(key)) return 0;
01766 
01767     return keyNameGetNamespace(key->key);
01768 }
01769 
01770 
01780 int keyIsDir(const Key *key) {
01781     if (!key) return 0;
01782     if (!keyIsInitialized(key)) return 0;
01783 
01784     return (S_ISDIR(key->access) || (key->type==KEY_TYPE_DIR));
01785 }
01786 
01787 
01797 int keyIsLink(const Key *key) {
01798     if (!key) return 0;
01799     if (!keyIsInitialized(key)) return 0;
01800 
01801     return (S_ISLNK(key->access) || (key->type==KEY_TYPE_LINK));
01802 }
01803 
01804 
01814 size_t keyNameGetRootNameSize(const char *keyName) {
01815     char *end;
01816     int length=strlen(keyName);
01817 
01818     if (!length) return 0;
01819 
01820     
01821 
01822 
01823 
01824 
01825 
01826 
01827 
01828 
01829 
01830     end=strchr(keyName,RG_KEY_DELIM);
01831     if (!end) 
01832         end = (char *)keyName + length;
01833 
01834     return end-keyName;
01835 }
01836 
01837 
01838 
01839 
01850 size_t keyGetRootNameSize(const Key *key) {
01851     if (!key) return 0;
01852     if (!keyIsInitialized(key)) return 0;
01853     if (!key->key) return 0;
01854 
01855     return keyNameGetRootNameSize(key->key);
01856 }
01857 
01858 
01859 
01860 
01861 
01873 size_t keyGetFullRootNameSize(const Key *key) {
01874     size_t size=0;
01875 
01876     if (keyIsUser(key)) {
01877         if (key->userDomain) size=strblen(key->userDomain);
01878         else size=strblen(getenv("USER"));
01879     }
01880 
01881     return size+keyNameGetRootNameSize(key->key);
01882 }
01883 
01884 
01885 
01896 size_t keyNameGetBaseNameSize(const char *keyName) {
01897     char *end;
01898     size_t size,keySize;
01899     unsigned char found=0;
01900 
01901     if (!(keySize=strblen(keyName))) return 0;
01902 
01903     size=keyNameGetRootNameSize(keyName);
01904     if (!size || size==keySize) return 0; 
01905 
01906     
01907 
01908 
01909 
01910 
01911 
01912     end=strrchr(keyName,RG_KEY_DELIM);
01913     if (*(end-1)!='\\') return keyName+keySize-(end+1);
01914 
01915     
01916     
01917 
01918 
01919 
01920 
01921 
01922     while (!found) {
01923         end--;
01924         if (*end=='.') found=1;
01925     }
01926     return keyName+keySize-(end+1);
01927 }
01928 
01929 
01930 
01931 
01942 size_t keyGetBaseNameSize(const Key *key) {
01943     if (!key) return 0;
01944     if (!keyIsInitialized(key)) return 0;
01945     if (!key->key) return 0;
01946 
01947     return keyNameGetBaseNameSize(key->key);
01948 }
01949 
01950 
01951 
01952 
01971 size_t keyGetRootName(const Key *key, char *returned, size_t maxSize) {
01972     size_t size;
01973 
01974     if (!key || !keyIsInitialized(key)) {
01975         errno=KDB_RET_UNINITIALIZED;
01976         return -1;
01977     }
01978 
01979     if (!key->key) {
01980         errno=KDB_RET_NOKEY;
01981         return -1;
01982     }
01983 
01984     if (!(size=keyGetRootNameSize(key))) {
01985         errno=KDB_RET_NOKEY;
01986         return -1;
01987     }
01988 
01989     if (maxSize < size) {
01990         errno=KDB_RET_TRUNC;
01991         return -1;
01992     } else strncpy(returned,key->key,size);
01993     return size;
01994 }
01995 
01996 
01997 
02015 size_t keyGetFullRootName(const Key *key, char *returned, size_t maxSize) {
02016     size_t size;
02017 
02018     if (!key || !keyIsInitialized(key)) {
02019         errno=KDB_RET_UNINITIALIZED;
02020         return 0;
02021     }
02022 
02023     if (!key->key) {
02024         errno=KDB_RET_NOKEY;
02025         return 0;
02026     }
02027 
02028     if (!(size=keyGetFullRootNameSize(key))) {
02029         errno=KDB_RET_NOKEY;
02030         return 0;
02031     }
02032 
02033     if (maxSize < size) {
02034         errno=KDB_RET_TRUNC;
02035         return 0;
02036     } else strncpy(returned,key->key,size);
02037     return size;
02038 }
02039 
02040 
02041 
02055 size_t keyGetBaseName(const Key *key, char *returned, size_t maxSize) {
02056     size_t size;
02057     size_t keySize;
02058 
02059     if (!key) {
02060         errno=KDB_RET_NULLKEY;
02061         return 0;
02062     }
02063 
02064     if (!keyIsInitialized(key)) {
02065         errno=KDB_RET_UNINITIALIZED;
02066         return 0;
02067     }
02068 
02069     if (!(size=keyGetBaseNameSize(key))) {
02070         errno=KDB_RET_NOKEY;
02071         return 0;
02072     }
02073 
02074     keySize=strblen(key->key);
02075 
02076     if (maxSize < size) {
02077         strncpy(returned,key->key+keySize-size,maxSize);
02078         errno=KDB_RET_TRUNC;
02079         return size;
02080     } else strncpy(returned,key->key+keySize-size,size);
02081 
02082     return size;
02083 }
02084 
02085 
02086 
02096 int keySetFlag(Key *key) {
02097     if (!key || !keyIsInitialized(key)) {
02098         errno=KDB_RET_UNINITIALIZED;
02099         return -1;
02100     }
02101 
02102     key->flags|=KEY_FLAG_FLAG;
02103 
02104     return 0;
02105 }
02106 
02107 
02108 
02118 int keyClearFlag(Key *key) {
02119     if (!key || !keyIsInitialized(key)) {
02120         errno=KDB_RET_UNINITIALIZED;
02121         return -1;
02122     }
02123 
02124     key->flags &= ~KEY_FLAG_FLAG;
02125 
02126     return 0;
02127 }
02128 
02129 
02130 
02131 
02132 
02133 
02143 int keyGetFlag(const Key *key) {
02144     if (!key || !keyIsInitialized(key)) {
02145         errno=KDB_RET_UNINITIALIZED;
02146         return 0;
02147     }
02148 
02149     return (key->flags | KEY_FLAG_FLAG) ? 1:0;
02150 }
02151 
02184 int ksInit(KeySet *ks) {
02185     ks->start=ks->end=ks->cursor=0;
02186     ks->size=0;
02187     
02188     return 0;
02189 }
02190 
02191 
02202 int ksClose(KeySet *ks) {
02203     if (ks->size) {
02204         Key *cursor=ks->start;
02205         while (ks->size) {
02206             Key *destroyer=cursor;
02207             cursor=cursor->next;
02208             keyClose(destroyer);
02209             free(destroyer);
02210             --ks->size;
02211         }
02212     }
02213     ks->start=ks->end=ks->cursor;
02214     return 0;
02215 }
02216 
02217 
02232 Key *ksNext(KeySet *ks) {
02233     if (!ks->cursor) ks->cursor=ks->start;
02234     else ks->cursor=ks->cursor->next;
02235 
02236     return ks->cursor;
02237 }
02238 
02239 
02240 
02251 int ksRewind(KeySet *ks) {
02252     ks->cursor=0;
02253     return 0;
02254 }
02255 
02256 
02257 
02266 Key *ksCurrent(const KeySet *ks) {
02267     return ks->cursor;
02268 }
02269 
02270 
02271 
02272 
02285 size_t ksInsert(KeySet *ks, Key *toInsert) {
02286     toInsert->next=ks->start;
02287     ks->start=toInsert;
02288     if (!ks->end) ks->end=toInsert;
02289     return ++ks->size;
02290 }
02291 
02292 
02293 
02294 
02308 size_t ksInsertKeys(KeySet *ks, KeySet *toInsert) {
02309     if (toInsert->size) {
02310         toInsert->end->next=ks->start;
02311         ks->start=toInsert->start;
02312 
02313         ks->size+=toInsert->size;
02314 
02315         
02316         toInsert->start=toInsert->end=0;
02317         toInsert->size=0;
02318     }
02319     return ks->size;
02320 }
02321 
02322 
02323 
02336 size_t ksAppend(KeySet *ks, Key *toAppend) {
02337     toAppend->next=0;
02338     if (ks->end) ks->end->next=toAppend;
02339     if (!ks->start) ks->start=toAppend;
02340     ks->end=toAppend;
02341     return ++ks->size;
02342 }
02343 
02344 
02345 
02359 size_t ksAppendKeys(KeySet *ks, KeySet *toAppend) {
02360     if (toAppend->size) {
02361         if (ks->end) {
02362             ks->end->next=toAppend->start;
02363             ks->end=toAppend->end;
02364         } else {
02365             ks->end=toAppend->end;
02366             ks->start=toAppend->start;
02367         }
02368 
02369         ks->size+=toAppend->size;
02370         
02371         
02372         toAppend->start=toAppend->end=0;
02373         toAppend->size=0;
02374     }
02375     return ks->size;
02376 }
02377 
02378 
02379 
02380 
02381 
02382 
02383 
02411 int ksCompare(KeySet *ks1, KeySet *ks2, KeySet *removed) {
02412     int flagRemoved=1;
02413     Key *ks1Cursor=0;
02414     Key *ks2Cursor=0;
02415 
02416     Key *ks1PrevCursor=0;
02417 
02418     ks1Cursor=ks1->start;
02419     while (ks1Cursor) {
02420         Key *ks2PrevCursor=0;
02421         flagRemoved=1;
02422         
02423         for (ks2Cursor=ks2->start; ks2Cursor; ks2Cursor=ks2Cursor->next) {
02424             u_int32_t flags=keyCompare(ks1Cursor,ks2Cursor);
02425             
02426             if (!(flags & (KEY_FLAG_HASKEY | KEY_FLAG_HASDOMAIN))) {
02427                 
02428                 flagRemoved=0; 
02429                     
02430                 
02431                 if (ks2PrevCursor) ks2PrevCursor->next=ks2Cursor->next;
02432                 else ks2->start=ks2Cursor->next;
02433                 if (ks2->end==ks2Cursor) ks2->end=ks2PrevCursor;
02434                 ks2->size--;
02435                     
02436                 if (flags) {
02437                     
02438                     
02439                     
02440                     if (ks1PrevCursor) ks1PrevCursor->next=ks2Cursor;
02441                     else ks1->start=ks2Cursor;
02442                     if (ks1->end==ks1Cursor) ks1->end=ks2Cursor;
02443                     ks2Cursor->next=ks1Cursor->next;
02444                     
02445                     
02446                     keyClose(ks1Cursor); free(ks1Cursor);
02447                     
02448                     
02449                     ks1Cursor=ks2Cursor;
02450                 } else {
02451                     
02452 
02453                     
02454                     keyClose(ks2Cursor);
02455                     free(ks2Cursor);
02456                 }
02457                 
02458                 break;
02459             }
02460             ks2PrevCursor=ks2Cursor;
02461             
02462         } 
02463         
02464         if (flagRemoved) {
02465             
02466             
02467             
02468             
02469             if (ks1PrevCursor) ks1PrevCursor->next=ks1Cursor->next;
02470             else ks1->start=ks1Cursor->next;
02471             if (ks1->end==ks1Cursor) ks1->end=ks1PrevCursor;
02472             ks1->size--;
02473 
02474             
02475             ksAppend(removed,ks1Cursor);
02476             
02477             
02478             if (ks1PrevCursor) ks1Cursor=ks1PrevCursor->next;
02479             else ks1Cursor=ks1->start;
02480         } else {
02481             ks1PrevCursor=ks1Cursor;
02482             ks1Cursor=ks1Cursor->next;
02483         }
02484     } 
02485     
02486     
02487     ksAppendKeys(ks1,ks2);
02488     
02489     return 0;
02490 }
02491 
02492 
02493 
02494 
02509 size_t ksToStream(const KeySet *ks, FILE* stream, unsigned long options) {
02510     size_t written=0;
02511     Key *key=0;
02512 
02513     if (options & KDB_O_XMLHEADERS) {
02514         written+=fprintf(stream,"<?xml version=\"1.0\" encoding=\"%s\"?>\n",
02515             nl_langinfo(CODESET));
02516         written+=fprintf(stream,
02517             "<!DOCTYPE keyset PUBLIC \"-//Avi Alkalay//DTD Elektra 0.1.0//EN\" \"http://registry.sf.net/dtd/registry.dtd\">\n\n\n");
02518         written+=fprintf(stream,
02519             "<!-- Generated by Elektra API. Total of %d keys. -->\n\n\n\n",ks->size);
02520     }
02521 
02522     written+=fprintf(stream,"<keyset>\n\n\n");
02523     
02524     for (key=ks->start; key; key=key->next)
02525         written+=keyToStream(key,stream,options);
02526     
02527     written+=fprintf(stream,"</keyset>\n");
02528     return written;
02529 }
02530 
02531