Main Page | Modules | Data Structures | File List | Data Fields

key.c

00001 /***************************************************************************
00002                           key.c  -  Methods for Key manipulation
00003                              -------------------
00004     begin                : Mon Dec 29 2003
00005     copyright            : (C) 2003 by Avi Alkalay
00006     email                : avi@unix.sh
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the BSD License (revised).                      *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 /* Subversion stuff
00017 
00018 $Id: key.c 610 2006-02-16 03:05:24Z aviram $
00019 
00020 */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025 
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028 #ifdef HAVE_STRINGS_H
00029 #include <strings.h>
00030 #endif
00031 #include <string.h>
00032 #include <stdlib.h>
00033 #include <sys/stat.h>
00034 #include <errno.h>
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038 #ifdef WIN32
00039 #include <io.h>
00040 #endif
00041 #include <sys/types.h>
00042 #ifdef HAVE_PWD_H
00043 #include <pwd.h>
00044 #endif
00045 #ifdef HAVE_GRP_H
00046 #include <grp.h>
00047 #endif
00048 
00049 #ifdef HAVE_LANGINFO_H
00050 #include <langinfo.h>
00051 #endif
00052 
00053 #include "kdb.h"
00054 #include "kdbprivate.h"
00055 
00065 size_t strblen(const char *s) {
00066     char *found=strchr(s,0);
00067     if (found) return found-s+1;
00068     return 0;
00069 }
00070 
00071 
00072 
00340 Key *keyNew(const char *keyName, ...) {
00341     va_list va;
00342     Key *key;
00343     uint32_t action=0;
00344     uint8_t keyType=KEY_TYPE_UNDEFINED;
00345     uint8_t keyTypeBinary=0; /* a boolean shortcut */
00346     size_t valueSize=0;
00347     
00348     key=(Key *)malloc(sizeof(Key));
00349     if (!key) return 0;
00350     keyInit(key);
00351     
00352     if (keyName) {
00353         size_t nameSize;
00354         
00355         nameSize=keySetName(key,keyName);
00356         if (! nameSize) {
00357             free(key);
00358             return 0;
00359         }
00360         
00361         va_start(va,keyName);
00362         
00363         action=va_arg(va,uint32_t);
00364         while (action) {
00365             switch (action) {
00366                 case KEY_SWITCH_TYPE:
00367                     /* We are waiting for 1 or 2 parameters
00368                      * following this action */
00369                     
00370                     /* First is the type */
00371                     keyType=(uint8_t)va_arg(va,unsigned int);
00372                     
00373                     keyTypeBinary=(KEY_TYPE_BINARY <= keyType &&
00374                         keyType < KEY_TYPE_STRING);
00375                     
00376                     keySetType(key,keyType);
00377                     
00378                     break;
00379                 case KEY_SWITCH_VALUE:
00380                     if (keyType == KEY_TYPE_UNDEFINED)
00381                         keyType=KEY_TYPE_STRING;
00382 
00383                     if (!keyTypeBinary) {
00384                         /* most popular cases */
00385                         keySetString(key,va_arg(va,char *));
00386                         /* reset the type due to the
00387                          * above keySetString override */
00388                         keySetType(key,keyType);
00389                     } else {
00390                         /* Binary val: we need first the size of the value */
00391                         valueSize=va_arg(va,size_t);
00392                         keySetRaw(key,va_arg(va,void *),valueSize);
00393                     }
00394 
00395                     break;
00396                 case KEY_SWITCH_UID:
00397                     keySetUID(key,va_arg(va,uid_t));
00398                     break;
00399                 case KEY_SWITCH_GID:
00400                     keySetGID(key,va_arg(va,gid_t));
00401                     break;
00402                 case KEY_SWITCH_MODE:
00403                     keySetAccess(key,va_arg(va,mode_t));
00404                     break;
00405                 case KEY_SWITCH_DOMAIN:
00406                     keySetOwner(key,va_arg(va,char *));
00407                     break;
00408                 case KEY_SWITCH_COMMENT:
00409                     keySetComment(key,va_arg(va,char *));
00410                     break;
00411                 case KEY_SWITCH_NEEDSYNC: {
00412                     int rc=0;
00413                     rc=kdbGetKey(key);
00414                     if (rc)
00415                         /* Flag the key to indicate an error in
00416                          * kdbGetKey(). Propagated errno will indicate
00417                          * the error ocurred. */
00418                         key->flags|=KEY_SWITCH_FLAG; /* same as keySetFlag(key) */
00419                 } break;
00420             }
00421             action=va_arg(va,uint32_t);
00422         }
00423         va_end(va);
00424     }
00425     return key;
00426 }
00427  
00428  
00429  
00430  
00443 int keyDel(Key *key) {
00444     int rc;
00445     
00446     rc=keyClose(key);
00447     free(key);
00448     
00449     return rc;
00450  }
00451 
00452  
00453 
00454 
00455 
00466 int keyIsInitialized(const Key *key) {
00467     /* if (!key) return 0; */ /* removing to activate stupid mode */
00468     return ((key->flags & KEY_SWITCH_INITMASK)==KEY_SWITCH_INITIALIZED);
00469 }
00470 
00471 
00472 /******************************************* 
00473  *    General name manipulation methods    *
00474  *******************************************/
00475 
00476 
00505 ssize_t keySetName(Key *key, const char *newName) {
00506     size_t length;
00507     size_t rootLength, userLength, systemLength, userDomainLength;
00508     size_t keyNameSize=1; /* equal to length plus a space for \0 */
00509     char *p;
00510 
00511 /*
00512     if (!key) {
00513         errno=KDB_RET_UNINITIALIZED;
00514         return 0;
00515     }
00516     if (!keyIsInitialized(key)) keyInit(key); */ /* commented for stupidity */
00517 
00518     /* handle null new key name, removing the old key */
00519     if (!newName || !(length=strblen(newName)-1)) {
00520         if (key->key) {
00521             free(key->key);
00522             key->key=0;
00523         }
00524         key->flags &= ~(KEY_SWITCH_NAME | KEY_SWITCH_NEEDSYNC |
00525                         KEY_SWITCH_ISSYSTEM | KEY_SWITCH_ISUSER);
00526         return 0;
00527     }
00528 
00529     /* Remove trailing  '/' if caller passed some */
00530     while (length && newName[length]==RG_KEY_DELIM) {
00531         length--;
00532     }
00533 
00534     rootLength=keyNameGetRootNameSize(newName);
00535     if (!rootLength) {
00536         errno=KDB_RET_INVALIDKEY;
00537         return -1;
00538     }
00539     userLength=sizeof("user")-1;
00540     systemLength=sizeof("system")-1;
00541     userDomainLength=rootLength-userLength-1;
00542     if (userDomainLength<0) userDomainLength=0;
00543 
00544     if (!strncmp("user",newName,userLength<length?userLength:length)) {
00545         /* handle "user*" */
00546         if (length > userLength) {
00547             /* handle "user?*" */
00548             if (*(newName+userLength)==':') {
00549                 /* handle "user:*" */
00550                 if (userDomainLength > 0) {
00551                                         p=realloc(key->userDomain,userDomainLength+1);
00552                                         if (NULL==p) goto error_mem;
00553                     key->userDomain=p;
00554                     strncpy(key->userDomain,newName+userLength+1,userDomainLength);
00555                     key->userDomain[userDomainLength]=0;
00556                 }
00557                 keyNameSize+=length-userDomainLength-1;  /* -1 is for the ':' */
00558             } else if (*(newName+userLength)!=RG_KEY_DELIM) {
00559                 /* handle when != "user/ *" */
00560                 errno=KDB_RET_INVALIDKEY;
00561                 return -1;
00562             } else {
00563                 /* handle regular "user/ *" */
00564                 keyNameSize+=length;
00565             }
00566         } else {
00567             /* handle "user" */
00568             keyNameSize+=userLength;
00569         }
00570 
00571         p=realloc(key->key,keyNameSize);
00572         if (NULL==p) goto error_mem;
00573         key->key=p;
00574 
00575         /* here key->key must have a correct size allocated buffer */
00576         if (!key->key) return -1;
00577 
00578         strcpy(key->key,"user");
00579         strncpy(key->key+userLength,newName+rootLength,length-rootLength);
00580         key->key[keyNameSize-1]=0;
00581 
00582         if (!key->userDomain) {
00583             size_t bsize=strblen(getenv("USER"));
00584 
00585             if (!bsize) {}
00586             else {
00587                 key->userDomain=malloc(bsize);
00588                 strncpy(key->userDomain,getenv("USER"),bsize);
00589             }
00590         }
00591         key->flags |= KEY_SWITCH_ISUSER;
00592         key->flags &= ~KEY_SWITCH_ISSYSTEM;
00593     } else if (!strncmp("system",newName,systemLength<length?systemLength:length)) {
00594         /* handle "system*" */
00595         if (length > systemLength && *(newName+systemLength)!=RG_KEY_DELIM) {
00596             /* handle when != "system/ *" */
00597             errno=KDB_RET_INVALIDKEY;
00598             return -1;
00599         }
00600         keyNameSize+=length;
00601         p=realloc(key->key,keyNameSize);
00602         if (NULL==p) goto error_mem;
00603         key->key=p;
00604 
00605 
00606         /* here key->key must have a correct size allocated buffer */
00607         if (!key->key) return -1;
00608 
00609         strncpy(key->key,newName,length);
00610         key->key[keyNameSize-1]=0;
00611         
00612         key->flags |= KEY_SWITCH_ISSYSTEM;
00613         key->flags &= ~KEY_SWITCH_ISUSER;
00614     } else {
00615         /* Passed name is neither "system" or "user" */
00616         errno=KDB_RET_INVALIDKEY;
00617         return -1;
00618     }
00619 
00620     key->flags |= KEY_SWITCH_NAME | KEY_SWITCH_NEEDSYNC;
00621 
00622     return keyNameSize;
00623 
00624     error_mem:
00625         errno=KDB_RET_NOMEM;
00626         return -1;
00627 }
00628 
00629 
00630 
00646 ssize_t keyAddBaseName(Key *key,const char *baseName) {
00647     size_t nameSize=0;
00648     size_t newSize=0;
00649     int ndelim=0;
00650     char *p;
00651 
00652     if (key->key) nameSize=strblen(key->key)-1;
00653     if (baseName) newSize=strblen(baseName);
00654     else return nameSize;
00655     
00656     if (newSize==0) return nameSize;
00657     
00658     if (key->key) {
00659         /* Remove trailing '/' if caller passed some */
00660         while (nameSize-2 && key->key[nameSize-1]==RG_KEY_DELIM &&
00661                key->key[nameSize-2]!=RG_KEY_DELIM) {
00662             key->key[--nameSize]=0;
00663         }
00664         
00665         if (key->key[nameSize-1] != RG_KEY_DELIM) nameSize++;
00666         
00667         /* Remove all '/' in the begining of baseName */
00668         while (baseName[ndelim] && baseName[ndelim] == RG_KEY_DELIM) {
00669             newSize--;
00670             ndelim++;
00671         }
00672         
00673         /* Now we know the final key size */
00674         newSize+=nameSize;
00675         p=realloc(key->key,newSize);
00676         if (NULL == p) {
00677             errno=KDB_RET_NOMEM;
00678             return -1;
00679         }
00680         key->key=p;
00681 
00682         if (key->key[nameSize-1] != RG_KEY_DELIM && baseName[ndelim])
00683             strcat(key->key,"/");
00684         
00685         strcat(key->key,baseName+ndelim);
00686         
00687     } else return keySetName(key,baseName);
00688     
00689     return newSize;
00690 }
00691 
00692 
00693 
00694 
00710 ssize_t keySetBaseName(Key *key, const char *baseName) {
00711     size_t newSize=strblen(baseName);
00712     char *end;
00713     char *p;
00714     
00715     end=strrchr(key->key,'/');
00716     
00717     if (end) {
00718         newSize+=end-key->key;
00719         end[1]=0;
00720         p=realloc(key->key,newSize);
00721         if (NULL == p) {
00722             errno=KDB_RET_NOMEM;
00723             return -1;
00724         }
00725         key->key=p;
00726         strcat(key->key,baseName);
00727         return newSize;
00728     } else return keySetName(key,baseName);
00729 }
00730 
00731 
00732 
00733 
00741 ssize_t keyGetNameSize(const Key *key) {
00742     /* if (!key || !keyIsInitialized(key)) {
00743         errno=KDB_RET_UNINITIALIZED;
00744         return 0;
00745     } */
00746 
00747     if (key->key) return strblen(key->key);
00748     else return 0;
00749 }
00750 
00751 
00752 
00753 
00764 ssize_t keyGetName(const Key *key, char *returnedName, size_t maxSize) {
00765     size_t bytes;
00766 
00767     /* if (!key || !keyIsInitialized(key)) {
00768         errno=KDB_RET_UNINITIALIZED;
00769         return 0;
00770     } */
00771 
00772     if (!key->key) {
00773         errno=KDB_RET_NOKEY;
00774         returnedName[0]=0;
00775         return 0;
00776     }
00777 
00778     bytes=strblen(strncpy(returnedName,key->key,maxSize));
00779     if (maxSize < strblen(key->key)) {
00780         errno=KDB_RET_TRUNC;
00781         return -1;
00782     }
00783     return bytes;
00784 }
00785 
00786 
00787 
00799 char *keyStealName(const Key *key) {
00800     return key->key;
00801 }
00802 
00803 
00804 
00805 
00806 
00807 
00815 ssize_t keyGetFullNameSize(const Key *key) {
00816     size_t returnedSize;
00817 
00818     /* if (!key || !keyIsInitialized(key)) {
00819         errno=KDB_RET_UNINITIALIZED;
00820         return -1;
00821     } */
00822 
00823     if (!key->key) return 0;
00824 
00825     returnedSize=strblen(key->key);
00826 
00827     if (!strncmp("user",key->key,sizeof("user")-1) && key->userDomain)
00828         returnedSize+=strblen(key->userDomain);
00829 
00830     return returnedSize;
00831 }
00832 
00833 
00834 
00835 
00845 ssize_t keyGetFullName(const Key *key, char *returnedName, size_t maxSize) {
00846     size_t userSize=sizeof("user")-1;
00847     size_t userDomainSize;
00848     ssize_t length;
00849     char *cursor;
00850 
00851     length=keyGetFullNameSize(key);
00852     if (length == 0) {
00853         errno=KDB_RET_NOKEY;
00854         returnedName[0]=0;
00855         return length;
00856     }
00857     if (length < 0) return length;
00858     if (length > maxSize) {
00859         errno=KDB_RET_TRUNC;
00860         return -1;
00861     }
00862 
00863     cursor=returnedName;
00864     if (!strncmp("user",key->key,userSize)) {
00865         strncpy(cursor,key->key,userSize);
00866         cursor+=userSize;
00867         if (key->userDomain) {
00868             *cursor=':'; ++cursor;
00869             userDomainSize=strblen(key->userDomain)-1;
00870             strcpy(cursor,key->userDomain);
00871             cursor+=userDomainSize;
00872         }
00873         strcpy(cursor,key->key+userSize);
00874     } else strcpy(cursor,key->key);
00875 
00876     return length;
00877 }
00878 
00879 
00880 
00881 
00882 
00894 int keyNameGetNamespace(const char *keyName) {
00895     if (keyNameIsSystem(keyName)) return KEY_NS_SYSTEM;
00896     if (keyNameIsUser(keyName)) return KEY_NS_USER;
00897     return 0;
00898 }
00899 
00900 
00901 
00912 int keyGetNamespace(const Key *key) {
00913     /* if (!key) return 0;
00914     if (!keyIsInitialized(key)) return 0; */
00915 
00916     if (key->flags & KEY_SWITCH_ISSYSTEM) return KEY_NS_SYSTEM;
00917     if (key->flags & KEY_SWITCH_ISUSER) return KEY_NS_USER;
00918     return 0;
00919 }
00920 
00921 
00922 
00932 int keyNameIsSystem(const char *keyName) {
00933     /* if (!keyName) return 0;
00934     if (!strlen(keyName)) return 0; */
00935 
00936     if (!strncmp("system",keyName,sizeof("system")-1)) return 1;
00937     return 0;
00938 }
00939 
00940 
00941 
00950 int keyIsSystem(const Key *key) {
00951     /* if (!key) return 0;
00952     if (!keyIsInitialized(key)) return 0; */
00953 
00954     return (key->flags & KEY_SWITCH_ISSYSTEM)?1:0;
00955 }
00956 
00957 
00958 
00968 int keyNameIsUser(const char *keyName) {
00969     /* if (!keyName) return 0;
00970     if (!strlen(keyName)) return 0; */
00971 
00972     if (!strncmp("user",keyName,sizeof("user")-1)) return 1;
00973     return 0;
00974 }
00975 
00976 
00977 
00986 int keyIsUser(const Key *key) {
00987     /* if (!key) return 0;
00988     if (!keyIsInitialized(key)) return 0; */
00989 
00990     return (key->flags & KEY_SWITCH_ISUSER)?1:0;
00991 }
00992 
00993 
00994 
01005 ssize_t keyNameGetRootNameSize(const char *keyName) {
01006     char *end;
01007     int length=strlen(keyName);
01008 
01009     if (!length) return 0;
01010 
01011     /*
01012         Possible situations:
01013         user:someuser
01014         user:someuser/
01015         user:someuser/key/name
01016         user:some.user/key/name
01017         .
01018         \.
01019         (empty)
01020     */
01021     end=strchr(keyName,RG_KEY_DELIM);
01022     if (!end) /* Reached end of string. Root is entire key. */
01023         end = (char *)keyName + length;
01024 
01025     return end-keyName;
01026 }
01027 
01028 
01029 
01040 ssize_t keyGetRootNameSize(const Key *key) {
01041     /* if (!key) return 0;
01042     if (!keyIsInitialized(key)) return 0; */
01043     if (!key->key) return 0;
01044 
01045     return keyNameGetRootNameSize(key->key);
01046 }
01047 
01048 
01049 
01067 ssize_t keyGetRootName(const Key *key, char *returned, size_t maxSize) {
01068     size_t size;
01069 
01070     /* if (!key || !keyIsInitialized(key)) {
01071         errno=KDB_RET_UNINITIALIZED;
01072         return -1;
01073     } */
01074 
01075     if (!key->key) {
01076         errno=KDB_RET_NOKEY;
01077         return -1;
01078     }
01079 
01080     if (!(size=keyGetRootNameSize(key))) {
01081         errno=KDB_RET_NOKEY;
01082         return -1;
01083     }
01084 
01085     if (maxSize < size) {
01086         errno=KDB_RET_TRUNC;
01087         return -1;
01088     } else strncpy(returned,key->key,size);
01089     return size;
01090 }
01091 
01092 
01093 
01105 ssize_t keyGetFullRootNameSize(const Key *key) {
01106     size_t size=0;
01107 
01108     if (keyIsUser(key)) {
01109         if (key->userDomain) size=strblen(key->userDomain);
01110         else size=strblen(getenv("USER"));
01111     }
01112 
01113     return size+keyNameGetRootNameSize(key->key);
01114 }
01115 
01116 
01134 ssize_t keyGetFullRootName(const Key *key, char *returned, size_t maxSize) {
01135     size_t size;
01136     size_t userSize;
01137     char *cursor;
01138 
01139     /* if (!key || !keyIsInitialized(key)) {
01140         errno=KDB_RET_UNINITIALIZED;
01141         return 0;
01142     } */
01143 
01144     if (!key->key) {
01145         errno=KDB_RET_NOKEY;
01146         return 0;
01147     }
01148 
01149     if (!(size=keyGetFullRootNameSize(key))) {
01150         errno=KDB_RET_NOKEY;
01151         return 0;
01152     }
01153 
01154     if (maxSize < size) {
01155         errno=KDB_RET_TRUNC;
01156         return -1;
01157     }
01158     
01159     userSize = keyGetRootNameSize(key);
01160     strncpy(returned,key->key, userSize); /* copy "user" or "system" */
01161     if (keyIsUser(key)) {
01162         cursor = returned + userSize;
01163         *cursor = ':'; cursor++;
01164         if (key->userDomain)
01165             strncpy (cursor, key->userDomain, size - userSize);
01166         else
01167             strncpy (cursor, getenv("USER"),  size - userSize);
01168     }
01169 
01170     return size;
01171 }
01172 
01173 
01174 
01175 
01176 
01177 
01185 ssize_t keyGetParentNameSize(const Key *key) {
01186     char *parentNameEnd;
01187 
01188     /* if (!key || !keyIsInitialized(key)) {
01189         errno=KDB_RET_UNINITIALIZED;
01190         return 0;
01191     } */
01192 
01193     if (!key->key) {
01194         errno=KDB_RET_NOKEY;
01195         return 0;
01196     }
01197 
01198     /*
01199         user   (size=0)
01200         user/parent/base
01201         user/parent/base/ (size=sizeof("user/parent"))
01202     */
01203 
01204     parentNameEnd=strrchr(key->key,RG_KEY_DELIM);
01205 
01206     if (!parentNameEnd || parentNameEnd==key->key) {
01207         /* handle NULL or /something */
01208         return 0;
01209     }
01210 
01211     /* handle system/parent/base/ */
01212     if ((parentNameEnd-key->key) == (strblen(key->key)-2)) {
01213         parentNameEnd--;
01214         while (*parentNameEnd!=RG_KEY_DELIM) parentNameEnd--;
01215     }
01216 
01217     return parentNameEnd - key->key;
01218 }
01219 
01220 
01221 
01240 ssize_t keyGetParentName(const Key *key, char *returnedParent, size_t maxSize) {
01241     ssize_t parentSize;
01242 
01243     parentSize=keyGetParentNameSize(key);
01244 
01245     if (parentSize+1 > maxSize) {
01246         errno=KDB_RET_TRUNC;
01247         return 0;
01248     } else strncpy(returnedParent,key->key,parentSize);
01249 
01250     returnedParent[parentSize]=0; /* ending NULL */
01251     
01252     return parentSize;
01253 }
01254 
01255 
01256 
01257 
01258 
01259 
01274 ssize_t keyNameGetBaseNameSize(const char *keyName) {
01275     char *end;
01276 
01277     end=strrchr(keyName,RG_KEY_DELIM);
01278     if (end) return keyName+strblen(keyName)-1-end;
01279     else return 0;
01280 }
01281 
01282 
01283 
01298 ssize_t keyGetBaseNameSize(const Key *key) {
01299     /* if (!key) return 0;
01300     if (!keyIsInitialized(key)) return 0; */
01301     if (!key->key) return 0;
01302 
01303     return keyNameGetBaseNameSize(key->key);
01304 }
01305 
01306 
01307 
01322 ssize_t keyGetBaseName(const Key *key, char *returned, size_t maxSize) {
01323     ssize_t size;
01324     size_t keySize;
01325 
01326     /* if (!key) {
01327         errno=KDB_RET_NULLKEY;
01328         return 0;
01329     }
01330 
01331     if (!keyIsInitialized(key)) {
01332         errno=KDB_RET_UNINITIALIZED;
01333         return 0;
01334     } */
01335 
01336     if (!(size=keyGetBaseNameSize(key))) {
01337         errno=KDB_RET_NOKEY;
01338         return 0;
01339     }
01340 
01341     keySize=strblen(key->key);
01342 
01343     if (maxSize < size) {
01344         strncpy(returned,key->key+keySize-size,maxSize);
01345         errno=KDB_RET_TRUNC;
01346         return size;
01347     } else strncpy(returned,key->key+keySize-size,size);
01348 
01349     return size;
01350 }
01351 
01352 
01362 char *keyStealBaseName(const Key *key) {
01363     char *end=strrchr(key->key,RG_KEY_DELIM);
01364     
01365     if (++end) return end;
01366     else return 0;
01367 }
01368 
01369 
01370 /******************************************* 
01371  *    General value manipulation methods   *
01372  *******************************************/
01373 
01374 
01375 
01376 
01382 ssize_t keyGetDataSize(const Key *key) {
01383     return keyGetValueSize(key);
01384 }
01385 
01386 
01387 
01398 ssize_t keyGetValueSize(const Key *key) {
01399     /* if (!key || !keyIsInitialized(key)) {
01400         errno=KDB_RET_UNINITIALIZED;
01401         return -1;
01402     } */
01403 
01404     return key->dataSize;
01405 }
01406 
01407 
01408 
01426 ssize_t keySetString(Key *key, const char *newStringValue) {
01427     ssize_t ret=newStringValue?strblen(newStringValue):0;
01428 
01429     if (!newStringValue || !ret) ret=keySetRaw(key,0,0);
01430     else ret=keySetRaw(key,newStringValue,ret);
01431 
01432     keySetType(key,KEY_TYPE_STRING);
01433 
01434     return ret;
01435 }
01436 
01437 
01438 
01463 ssize_t keyGetString(const Key *key, char *returnedString, size_t maxSize) {
01464     /* if (!key || !keyIsInitialized(key)) {
01465         errno=KDB_RET_UNINITIALIZED;
01466         return 0;
01467     } */
01468 
01469     if (!key->data) {
01470         *returnedString=0;
01471         errno=KDB_RET_NODATA;
01472         return 0;
01473     }
01474 
01475     if (key->dataSize > maxSize) {
01476         errno=KDB_RET_TRUNC;
01477         return -1;
01478     }
01479 
01480     if (key->type < KEY_TYPE_STRING) {
01481         errno=KDB_RET_TYPEMISMATCH;
01482         return -1;
01483     }
01484 
01485     strcpy(returnedString,key->data);
01486     return key->dataSize;
01487 }
01488 
01489 
01490 
01491 
01492 
01493 
01543 void *keyStealValue(const Key *key) {
01544     return key->data;
01545 }
01546 
01547 
01548 
01549 
01550 
01551 
01552 
01553 
01563 ssize_t keySetLink(Key *key, const char *target) {
01564     ssize_t ret=target?strblen(target):0;
01565 
01566     if (!target || !ret) ret=keySetRaw(key,0,0);
01567     else ret=keySetRaw(key,target,ret);
01568 
01569     keySetType(key,KEY_TYPE_LINK);
01570 
01571     return ret;
01572 }
01573 
01574 
01575 
01586 ssize_t keyGetLink(const Key *key, char *returnedTarget, size_t maxSize) {
01590     /* if (!key || !keyIsInitialized(key)) {
01591         errno=KDB_RET_UNINITIALIZED;
01592         return 0;
01593     } */
01594 
01595     if (!key->data) {
01596         errno=KDB_RET_NODATA;
01597         return 0;
01598     }
01599 
01600     if (key->type != KEY_TYPE_LINK) {
01601         errno=KDB_RET_TYPEMISMATCH;
01602         return -1;
01603     }
01604 
01605     if (key->dataSize > maxSize) {
01606         errno=KDB_RET_TRUNC;
01607         return -1;
01608     }
01609 
01610     strcpy(returnedTarget,key->data);
01611     return key->dataSize;
01612 }
01613 
01614 
01615 
01625 int keyIsLink(const Key *key) {
01626   /* Shouldn't we completely get rid of the following two lines? -Jens */
01627     /* if (!key) return 0;
01628     if (!keyIsInitialized(key)) return 0; */
01629 
01630     return (key->type==KEY_TYPE_LINK);
01631 }
01632 
01633 
01634 
01644 int keyIsDir(const Key *key) {
01645     /* if (!key) return 0;
01646     if (!keyIsInitialized(key)) return 0; */
01647 
01648   return key->type==KEY_TYPE_DIR;
01649 }
01650 
01651 
01652 
01660 int keyIsBin(const Key *key) {
01661     /* if (!key) return 0;
01662     if (!keyIsInitialized(key)) return 0; */
01663 
01664     return (KEY_TYPE_BINARY <= key->type && key->type < KEY_TYPE_STRING);
01665 }
01666 
01667 
01675 int keyIsString(const Key *key) {
01676     /* if (!key) return 0;
01677     if (!keyIsInitialized(key)) return 0; */
01678 
01679     return (key->type >= KEY_TYPE_STRING);
01680 }
01681 
01682 
01683 
01684 
01694 ssize_t keyGetBinary(const Key *key, void *returnedValue, size_t maxSize) {
01695     /* if (!key || !keyIsInitialized(key)) {
01696         errno=KDB_RET_UNINITIALIZED;
01697         return 0;
01698     } */
01699 
01700     if (!key->data) {
01701         errno=KDB_RET_NODATA;
01702         return 0;
01703     }
01704 
01705     if (key->dataSize > maxSize) {
01706         errno=KDB_RET_TRUNC;
01707         return -1;
01708     }
01709 
01710     memcpy(returnedValue,key->data,key->dataSize);
01711     return key->dataSize;
01712 }
01713 
01714 
01715 
01735 ssize_t keySetBinary(Key *key, const void *newBinary, size_t dataSize) {
01736     ssize_t ret=keySetRaw(key,newBinary,dataSize);
01737 
01738     keySetType(key,KEY_TYPE_BINARY);
01739 
01740     return ret;
01741 }
01742 
01743 
01744 
01753 int keyNeedsSync(const Key *key) {
01754     /* if (!key) return 0; */
01755     return (key->flags & KEY_SWITCH_NEEDSYNC);
01756 }
01757 
01758 
01759 
01769 uint8_t keyGetType(const Key *key) {
01770     /* if (!key || !keyIsInitialized(key)) {
01771         errno=KDB_RET_UNINITIALIZED;
01772         return KEY_TYPE_UNDEFINED;
01773     } */
01774 
01775     return key->type;
01776 }
01777 
01778 
01779 
01848 uint8_t keySetType(Key *key,uint8_t newType) {
01849     mode_t dirSwitch=0111;
01850 
01851     /* if (!key) {
01852         errno=KDB_RET_UNINITIALIZED;
01853         return KEY_TYPE_UNDEFINED;
01854     }
01855     if (!keyIsInitialized(key)) keyInit(key); */
01856 
01857     switch (newType) {
01858         case KEY_TYPE_DIR:
01859             key->type=KEY_TYPE_DIR;
01860             dirSwitch=umask(0); umask(dirSwitch);
01861             dirSwitch=0111 & ~dirSwitch;
01862             key->access|=dirSwitch | 0040000; /*S_IFDIR (is directory)*/
01863             keySetRaw(key,0,0); /* remove data */
01864             break;
01865         default:
01866             key->type=newType;
01867             key->access &= ~(0040000 | dirSwitch);
01868             /*remove bits directory and dirSwitch*/
01869             key->flags |= KEY_SWITCH_NEEDSYNC;
01870     }
01871     return key->type;
01872 }
01873 
01874 
01875 
01888 ssize_t keySetRaw(Key *key, const void *newBinary, size_t dataSize) {
01889     /* if (!key) {
01890         errno=KDB_RET_UNINITIALIZED;
01891         return 0;
01892     }
01893     if (!keyIsInitialized(key)) keyInit(key); */
01894 
01895     if (!dataSize || !newBinary) {
01896         if (key->data) {
01897             free(key->data);
01898             key->data=0;
01899         }
01900         key->flags &= ~(KEY_SWITCH_VALUE);
01901         key->flags |= KEY_SWITCH_NEEDSYNC;
01902         return 0;
01903     }
01904 
01905     key->dataSize=dataSize;
01906     if (key->data) {
01907         char *p;
01908         p=realloc(key->data,key->dataSize);
01909         if (NULL==p) return -1;
01910         key->data=p;
01911     } else {
01912         key->data=malloc(key->dataSize);
01913         }
01914 
01915     if (!key->data) return -1;
01916 
01917     memcpy(key->data,newBinary,key->dataSize);
01918     key->flags |= KEY_SWITCH_VALUE | KEY_SWITCH_NEEDSYNC;
01919     return key->dataSize;
01920 }
01921 
01922 
01923 
01924 
01925 
01926 
01927 
01928 
01929 /***************************************************** 
01930  *    General owner or domain manipulation methods   *
01931  *****************************************************/
01932 
01933 
01934 
01946 ssize_t keySetOwner(Key *key, const char *userDomain) {
01947     ssize_t size;
01948 
01949     /* if (!key) {
01950         errno=KDB_RET_UNINITIALIZED; // KDB_RET_NULLKEY
01951         return -1;
01952     }
01953     if (!keyIsInitialized(key)) keyInit(key); */
01954     
01955     if (userDomain == 0) {
01956         if (key->userDomain) {
01957             free(key->userDomain);
01958             key->userDomain=0;
01959         }
01960         return 0;
01961     }
01962 
01963     if ((size=strblen(userDomain)) > 0) {
01964         if (key->userDomain) {
01965             char *p;
01966             p=realloc(key->userDomain,size);
01967             if (NULL==p) {
01968                 errno=KDB_RET_NOMEM;
01969                 return -1;
01970             }
01971             key->userDomain=p;
01972         } else {
01973             key->userDomain=malloc(size);
01974         }
01975         if (!key->userDomain) return -1; /* propagate errno */
01976 
01977         strcpy(key->userDomain,userDomain);
01978         key->flags |= KEY_SWITCH_DOMAIN | KEY_SWITCH_NEEDSYNC;
01979         return size;
01980     } else if (key->userDomain) {
01981         free(key->userDomain);
01982         key->userDomain=0;
01983         key->flags &= ~(KEY_SWITCH_DOMAIN | KEY_SWITCH_NEEDSYNC);
01984     }
01985     return 0;
01986 }
01987 
01988 
01989 
01997 ssize_t keyGetOwnerSize(const Key *key) {
01998     
01999     /* if (!key || !keyIsInitialized(key)) {
02000         errno=KDB_RET_UNINITIALIZED;
02001         return 0;
02002     } */
02003 
02004     if (!key->userDomain) {
02005         errno=KDB_RET_NODOMAIN;
02006         return 0;
02007     }
02008 
02009     return strblen(key->userDomain);
02010 }
02011 
02012 
02013 
02034 ssize_t keyGetOwner(const Key *key, char *returned, size_t maxSize) {
02035     ssize_t bytes;
02036 
02037     /* if (!key || !keyIsInitialized(key)) {
02038         errno=KDB_RET_UNINITIALIZED;
02039         return 0;
02040     } */
02041 
02042     if (!key->userDomain) {
02043         errno=KDB_RET_NODOMAIN;
02044         return 0;
02045     }
02046 
02047     if (maxSize < (bytes=strblen(key->userDomain))) {
02048         errno=KDB_RET_TRUNC;
02049         return -1;
02050     } else strcpy(returned,key->userDomain);
02051     return bytes;
02052 }
02053 
02054 
02055 
02056 
02066 char *keyStealOwner(const Key *key) {
02067     return key->userDomain;
02068 }
02069 
02070 
02071 
02072 
02073 
02074 
02075 /********************************************* 
02076  *    General comment manipulation methods   *
02077  *********************************************/
02078 
02079 
02080 
02092 ssize_t keySetComment(Key *key, const char *newComment) {
02093     ssize_t size;
02094 
02095     /* if (!key) {
02096         errno=KDB_RET_UNINITIALIZED; // KDB_RET_NULLKEY 
02097         return 0;
02098     } 
02099     if (!keyIsInitialized(key)) keyInit(key); */
02100 
02101     if (newComment && (size=strblen(newComment)) > 0) {
02102         if (key->flags & KEY_SWITCH_COMMENT) {
02103             char *p;
02104             p=realloc(key->comment,size);
02105             if (NULL==p) {
02106                 errno=KDB_RET_NOMEM;
02107                 return -1;
02108             }
02109             key->comment=p;
02110         } else {
02111             key->comment=malloc(size);
02112         }
02113         if (!key->comment) return -1;
02114 
02115         strcpy(key->comment,newComment);
02116         key->flags |= KEY_SWITCH_COMMENT | KEY_SWITCH_NEEDSYNC;
02117         return key->commentSize=size;
02118     } else if (key->flags & KEY_SWITCH_COMMENT) {
02119         free(key->comment);
02120         key->comment=0;
02121         key->flags &= ~(KEY_SWITCH_COMMENT | KEY_SWITCH_NEEDSYNC);
02122     }
02123     return key->commentSize=0;
02124 }
02125 
02126 
02127 
02138 ssize_t keyGetCommentSize(const Key *key) {
02139     /*  if (!key || !keyIsInitialized(key)) {
02140         errno=KDB_RET_UNINITIALIZED;
02141         return 0;
02142     } */
02143 
02144     if (!key->comment) {
02145         errno=KDB_RET_NODESC;
02146         return 0;
02147     }
02148 
02149     return strblen(key->comment);
02150 }
02151 
02152 
02153 
02165 ssize_t keyGetComment(const Key *key, char *returnedDesc, size_t maxSize) {
02166     ssize_t bytes;
02167 
02168     /* if (!key || !keyIsInitialized(key)) {
02169         errno=KDB_RET_UNINITIALIZED;
02170         return 0;
02171     } */
02172 
02173     if (!key->comment) {
02174         errno=KDB_RET_NODESC;
02175         return 0;
02176     }
02177 
02178     bytes=strblen(strncpy(returnedDesc,key->comment,maxSize));
02179     if (maxSize < strblen(key->comment)) {
02180         errno=KDB_RET_TRUNC;
02181         return -1;
02182     }
02183     return bytes;
02184 }
02185 
02186 
02197 char *keyStealComment(const Key *key) {
02198     return key->comment;
02199 }
02200 
02201 
02202 
02203 
02204 
02205 
02206 ssize_t keyGetRecordSize(const Key *key) {
02207     /* if (!key || !keyIsInitialized(key)) {
02208         errno=KDB_RET_UNINITIALIZED;
02209         return -1;
02210     } */
02211 
02212     return key->recordSize;
02213 }
02214 
02215 
02221 Key *keyNext(Key *key) {
02222     return key->next;
02223 }
02224 
02225 
02226 
02227 
02228 
02229 
02230 
02231 
02248 int keyDup(const Key *source, Key *dest) {
02249     
02250     /* Copy the struct data, including the "next" pointer */
02251     *dest=*source;
02252 
02253     /* prepare to set dynamic properties */
02254     dest->key=
02255     dest->comment=
02256     dest->userDomain=
02257     dest->data=0;
02258 
02259     /* Set properties that need memory allocation */
02260     keySetName(dest,source->key);
02261     keySetComment(dest,source->comment);
02262     keySetOwner(dest,source->userDomain);
02263     keySetRaw(dest,source->data,source->dataSize);
02264 
02265     dest->flags=source->flags;
02266 
02267     return 0;
02268 }
02269 
02270 
02271 
02282 uid_t keyGetUID(const Key *key) {
02283     /* if (!key || !keyIsInitialized(key)) {
02284         errno=KDB_RET_UNINITIALIZED;
02285         return -1;
02286     } */
02287 
02288     /*if (!(key->flags & KEY_SWITCH_UID)) return KDB_RET_NOCRED;*/
02289 
02290     return key->uid;
02291 }
02292 
02293 
02294 
02305 int keySetUID(Key *key, uid_t uid) {
02306     /* if (!key) return errno=KDB_RET_UNINITIALIZED;
02307     if (!keyIsInitialized(key)) keyInit(key); */
02308 
02309     key->uid=uid;
02310     key->flags |= KEY_SWITCH_UID | KEY_SWITCH_NEEDSYNC;
02311 
02312     return 0;
02313 }
02314 
02315 
02316 
02324 gid_t keyGetGID(const Key *key) {
02325     /* if (!key || !keyIsInitialized(key)) {
02326         errno=KDB_RET_UNINITIALIZED;
02327         return -1;
02328     } */
02329 
02330     /*if (!(key->flags & KEY_SWITCH_GID)) return KDB_RET_NOCRED;*/
02331 
02332     return key->gid;
02333 }
02334 
02335 
02336 
02344 int keySetGID(Key *key, gid_t gid) {
02345     /* if (!key) return errno=KDB_RET_UNINITIALIZED;
02346     if (!keyIsInitialized(key)) keyInit(key); */
02347 
02348     key->gid=gid;
02349     key->flags |= KEY_SWITCH_GID | KEY_SWITCH_NEEDSYNC;
02350 
02351     return 0;
02352 }
02353 
02354 
02355 
02361 mode_t keyGetAccess(const Key *key) {
02362     /* if (!key || !keyIsInitialized(key)) {
02363         errno=KDB_RET_UNINITIALIZED;
02364         return -1;
02365     } */
02366 
02367     /*if (!(key->flags & KEY_SWITCH_MODE)) return KDB_RET_NOCRED;*/
02368 
02369     return key->access;
02370 }
02371 
02372 
02373 
02381 int keySetAccess(Key *key, mode_t mode) {
02382     /* if (!key) return errno=KDB_RET_UNINITIALIZED;
02383     if (!keyIsInitialized(key)) keyInit(key); */
02384 
02385     key->access=mode;
02386     key->flags |= KEY_SWITCH_MODE | KEY_SWITCH_NEEDSYNC;
02387 
02388     return 0;
02389 }
02390 
02391 
02392 
02397 time_t keyGetMTime(const Key *key) {
02398     /* if (!key || !keyIsInitialized(key)) {
02399         errno=KDB_RET_UNINITIALIZED;
02400         return -1;
02401     } */
02402     /*if (!(key->flags & KEY_SWITCH_TIME)) return KDB_RET_NOTIME;*/
02403 
02404     return key->mtime;
02405 }
02406 
02407 
02408 
02413 time_t keyGetATime(const Key *key) {
02414     /* if (!key || !keyIsInitialized(key)) {
02415         errno=KDB_RET_UNINITIALIZED;
02416         return -1;
02417     } */
02418     /*if (!(key->flags & KEY_SWITCH_TIME)) return KDB_RET_NOTIME;*/
02419 
02420     return key->atime;
02421 }
02422 
02423 
02424 
02429 time_t keyGetCTime(const Key *key) {
02430     /* if (!key || !keyIsInitialized(key)) {
02431         errno=KDB_RET_UNINITIALIZED;
02432         return -1;
02433     } */
02434     /*if (!(key->flags & KEY_SWITCH_TIME)) return KDB_RET_NOTIME;*/
02435 
02436     return key->ctime;
02437 }
02438 
02439 
02440 
02513 uint32_t keyCompare(const Key *key1, const Key *key2) {
02514     uint32_t ret=0;
02515 
02516 
02517     /* Compare these numeric properties */
02518     if (key1->uid != key2->uid)                    ret|=KEY_SWITCH_UID;
02519     if (key1->gid != key2->gid)                    ret|=KEY_SWITCH_GID;
02520     if (key1->type != key2->type)                  ret|=KEY_SWITCH_TYPE;
02521 #if defined(S_IRWXU) && defined(S_IRWXG) && defined(S_IRWXO)
02522     if ((key1->access & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
02523         (key2->access & (S_IRWXU|S_IRWXG|S_IRWXO))) ret|=KEY_SWITCH_MODE;
02524 #else
02525     if ((key1->access) !=
02526         (key2->access)) ret|=KEY_SWITCH_MODE;
02527 #endif
02528 
02529     /* Compare these string properties.
02530        A lot of decisions because strcmp can't handle NULL pointers */
02531     if (key1->key && key2->key) {
02532         if (strcmp(key1->key,key2->key))            ret|=KEY_SWITCH_NAME;
02533     } else {
02534         if (key1->key)                              ret|=KEY_SWITCH_NAME;
02535         else if (key2->key)                         ret|=KEY_SWITCH_NAME;
02536     }
02537 
02538     if (key1->comment && key2->comment) {
02539         if (strcmp(key1->comment,key2->comment))    ret|=KEY_SWITCH_COMMENT;
02540     } else {
02541         if (key1->comment)                          ret|=KEY_SWITCH_COMMENT;
02542         else if (key2->comment)                     ret|=KEY_SWITCH_COMMENT;
02543     }
02544 
02545     if (key1->userDomain && key2->userDomain) {
02546         if (strcmp(key1->userDomain,key2->userDomain)) ret|=KEY_SWITCH_DOMAIN;
02547     } else {
02548         if (key1->userDomain)                       ret|=KEY_SWITCH_DOMAIN;
02549         else if (key2->comment)                     ret|=KEY_SWITCH_DOMAIN;
02550     }
02551 
02552     /* compare and select some flags */
02553     ret|=(key1->flags ^ key2->flags) & (KEY_SWITCH_FLAG | KEY_SWITCH_NEEDSYNC);
02554     
02555     /* Compare data */
02556     if (key1->dataSize != key2->dataSize)          ret|=KEY_SWITCH_VALUE;
02557     else if (memcmp(key1->data,key2->data,
02558             (key1->dataSize<=key2->dataSize?key1->dataSize:key2->dataSize)))
02559                                                     ret|=KEY_SWITCH_VALUE;
02560 
02561     return ret;
02562 }
02563 
02564 
02565 
02566 
02567 
02568 
02603 ssize_t keyToStream(const Key *key, FILE* stream, unsigned long options) {
02604     return keyToStreamBasename(key,stream,0,0,options);
02605 }
02606 
02607 
02608 
02609 
02610 
02633 ssize_t keyToStreamBasename(const Key *key, FILE *stream, const char *parent,
02634         const size_t parentSize, unsigned long options) {
02635     ssize_t written=0;
02636     char buffer[800];
02637     struct passwd *pwd=0;
02638     struct group *grp=0;
02639 
02640     /* Write key name */
02641     if (parent) {
02642         /* some logic to see if we should print only the relative basename */
02643         int found;
02644         size_t skip=parentSize ? parentSize : strblen(parent)-1;
02645 
02646         found=memcmp(parent,key->key,skip);
02647         if (found == 0) {
02648             while (*(key->key+skip) == RG_KEY_DELIM) ++skip;
02649 
02650             if (*(key->key+skip) != 0) /* we don't want a null basename */
02651                 written+=fprintf(stream,"<key basename=\"%s\"",
02652                     key->key+skip);
02653         }
02654     }
02655 
02656     if (written == 0) { /* no "<key basename=..." was written so far */
02657         if (options & KDB_O_FULLNAME) {
02658             keyGetFullName(key,buffer,sizeof(buffer));
02659             written+=fprintf(stream,"<key name=\"%s\"", buffer);
02660         } else written+=fprintf(stream,"<key name=\"%s\"", key->key);
02661     }
02662 
02663 
02664     if (options & KDB_O_CONDENSED) written+=fprintf(stream," ");
02665     else written+=fprintf(stream,"\n     ");
02666 
02667 
02668 
02669     /* Key type */
02670     if (options & KDB_O_NUMBERS) {
02671         written+=fprintf(stream,"type=\"%d\"", key->type);
02672     } else {
02673         buffer[0]=0;
02674 
02675         switch (key->type) {
02676             case KEY_TYPE_STRING:
02677                 strcpy(buffer,"string");
02678                 break;
02679             case KEY_TYPE_BINARY:
02680                 strcpy(buffer,"binary");
02681                 break;
02682             case KEY_TYPE_LINK:
02683                 strcpy(buffer,"link");
02684                 break;
02685             case KEY_TYPE_DIR:
02686                 strcpy(buffer,"directory");
02687                 break;
02688             case KEY_TYPE_UNDEFINED:
02689                 strcpy(buffer,"undefined");
02690                 break;
02691         }
02692         if (buffer[0]) written+=fprintf(stream,"type=\"%s\"", buffer);
02693         else written+=fprintf(stream,"type=\"%d\"", key->type);
02694     }
02695 
02696 #ifdef HAVE_PWD_H
02697     if (keyIsUser(key)) {
02698         struct passwd *domainPwd=0;
02699         int uidMatch,gidMatch;
02700         
02701         domainPwd=getpwnam(key->userDomain);
02702         pwd=getpwuid(key->uid);
02703         grp=getgrgid(key->gid);
02704         
02705         uidMatch=(key->uid == domainPwd->pw_uid);
02706         gidMatch=(key->gid == domainPwd->pw_gid);
02707         
02708         if (options & KDB_O_FULLUGID) {
02709             if (pwd && !(options & KDB_O_NUMBERS))
02710                 written+=fprintf(stream," uid=\"%s\"",pwd->pw_name);
02711             else written+=fprintf(stream,   " uid=\"%d\"",key->uid);
02712         
02713             if (grp && !(options & KDB_O_NUMBERS))
02714                 written+=fprintf(stream," gid=\"%s\"",grp->gr_name);
02715             else written+=fprintf(stream," gid=\"%d\"",key->gid);
02716         } else {
02717             if (!uidMatch) {
02718                 if (pwd && !(options & KDB_O_NUMBERS))
02719                     written+=fprintf(stream," uid=\"%s\"",pwd->pw_name);
02720                 else written+=fprintf(stream,   " uid=\"%d\"",key->uid);
02721             }
02722 
02723             if (!gidMatch) {
02724                 if (grp && !(options & KDB_O_NUMBERS))
02725                     written+=fprintf(stream," gid=\"%s\"",grp->gr_name);
02726                 else written+=fprintf(stream,   " gid=\"%d\"",key->gid);
02727             }
02728         }
02729     } else {
02730         if (!(options & KDB_O_NUMBERS)) {
02731             pwd=getpwuid(key->uid);
02732             grp=getgrgid(key->gid);
02733         }
02734 
02735         /* UID, GID, mode */
02736         if (pwd) written+=fprintf(stream," uid=\"%s\"",pwd->pw_name);
02737         else  written+=fprintf(stream,   " uid=\"%d\"",key->uid);
02738 
02739         if (grp) written+=fprintf(stream," gid=\"%s\"",grp->gr_name);
02740         else  written+=fprintf(stream,   " gid=\"%d\"",key->gid);
02741     }
02742 #endif
02743     written+=fprintf(stream," mode=\"0%o\"",
02744 #if defined(S_IRWXU) && defined(S_IRWXG) && defined(S_IRWXO)
02745         key->access & (S_IRWXU|S_IRWXG|S_IRWXO));
02746 #else
02747         key->access);
02748 #endif
02749 
02750 
02751     if (!key->data && !key->comment) { /* no data AND no comment */
02752         written+=fprintf(stream,"/>");
02753         if (!(options & KDB_O_CONDENSED))
02754             written+=fprintf(stream,"\n\n\n\n\n\n");
02755         
02756         return written; /* end of <key/> */
02757     } else {
02758         if (key->data) {
02759             if ((key->dataSize <= 16) &&
02760                     key->type >= KEY_TYPE_STRING &&
02761                     !strchr(key->data,'\n')) {
02762 
02763                 /* we'll use a "value" attribute instead of a <value> node,
02764                    for readability, so the cut size will be 16, which is
02765                    the maximum size of an IPv4 address */
02766 
02767                 if (options & KDB_O_CONDENSED) written+=fprintf(stream," ");
02768                 else written+=fprintf(stream,"\n     ");
02769                 
02770                 written+=fprintf(stream,"value=\"%s\"",key->data);
02771                 
02772                 if (key->comment) written+=fprintf(stream,">\n");
02773                 else {
02774                     written+=fprintf(stream,"/>");
02775                     if (!(options & KDB_O_CONDENSED))
02776                         written+=fprintf(stream,"\n\n\n\n\n\n");
02777                 
02778                     return written;
02779                 }
02780             } else { /* value is bigger than 16 bytes: deserves own <value> */
02781                 written+=fprintf(stream,">");
02782                 if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n\n     ");
02783                 
02784                 written+=fprintf(stream,"<value>");
02785                 if (key->type >= KEY_TYPE_STRING || key->type < KEY_TYPE_BINARY) {
02786                     written+=fprintf(stream,"<![CDATA[");
02787                     fflush(stream);
02788                     /* must chop ending \0 */
02789                     written+=write(fileno(stream),key->data,key->dataSize-1);
02790                     written+=fprintf(stream,"]]>");
02791                 } else {
02792                     /* Binary values */
02793                     char *encoded=malloc(3*key->dataSize);
02794                     size_t encodedSize;
02795 
02796                     written+=fprintf(stream,"\n");
02797                     encodedSize=encode(key->data,key->dataSize,encoded);
02798                     fflush(stream);
02799                     written+=write(fileno(stream),encoded,encodedSize);
02800                     free(encoded);
02801                     written+=fprintf(stream,"\n");
02802                 }
02803                 /* fflush(stream); */
02804                 written+=fprintf(stream,"</value>");
02805             }
02806         } else { /* we have no data */
02807             if (key->comment) {
02808                 written+=fprintf(stream,">");
02809                 if (!(options & KDB_O_CONDENSED))
02810                     written+=fprintf(stream,"\n");
02811             } else {
02812                 written+=fprintf(stream,"/>");
02813                 if (!(options & KDB_O_CONDENSED))
02814                     written+=fprintf(stream,"\n\n\n\n\n\n");
02815             
02816                 return written;
02817             }
02818         }
02819     }
02820 
02821     if (!(options & KDB_O_CONDENSED)) {
02822         written+=fprintf(stream,"\n");
02823         if (key->comment) written+=fprintf(stream,"     ");
02824     }
02825 
02826     if (key->comment) {
02827         written+=fprintf(stream,"<comment><![CDATA[%s]]></comment>", key->comment);
02828         if (!(options & KDB_O_CONDENSED))
02829             written+=fprintf(stream,"\n");
02830     }
02831 
02832     written+=fprintf(stream,"</key>");
02833 
02834     if (!(options & KDB_O_CONDENSED))
02835         written+=fprintf(stream,"\n\n\n\n\n\n");
02836 
02837     return written;
02838 }
02839 
02840 
02841 /*
02842 size_t keyGetSerializedSizeWithoutName(Key *key) {
02843     return sizeof(KeyInfo)+
02844         key->dataSize+
02845         key->groupSize+
02846         key->commentSize;
02847 }
02848 */
02849 
02850 /*
02851 size_t keyGetSerializedSize(Key *key) {
02852     size_t totalSize;
02853 
02854     totalSize=(key->key)+1+keyGetSerializedSizeWithoutName(key);
02855     if (key->userDomain) totalSize+=strlen(key->userDomain)+1;
02856     return totalSize;
02857 }*/
02858 
02859 
02860 
02861 
02862 
02863 
02875 int keySetFlag(Key *key) {
02876     /* if (!key || !keyIsInitialized(key)) {
02877         errno=KDB_RET_UNINITIALIZED;
02878         return -1;
02879     } */
02880 
02881     key->flags|=KEY_SWITCH_FLAG;
02882 
02883     return 0;
02884 }
02885 
02886 
02887 
02899 int keyClearFlag(Key *key) {
02900     /* if (!key || !keyIsInitialized(key)) {
02901         errno=KDB_RET_UNINITIALIZED;
02902         return -1;
02903     } */
02904 
02905     key->flags &= ~KEY_SWITCH_FLAG;
02906 
02907     return 0;
02908 }
02909 
02910 
02911 
02924 int keyGetFlag(const Key *key) {
02925     /* if (!key || !keyIsInitialized(key)) {
02926         errno=KDB_RET_UNINITIALIZED;
02927         return 0;
02928     } */
02929 
02930     return (key->flags & KEY_SWITCH_FLAG) ? 1:0;
02931 }
02932 
02933 
02934 
02935 
02936 
02973 int keyInit(Key *key) {
02974     /* if (!key) return errno=KDB_RET_NULLKEY; */
02975 
02976     memset(key,0,sizeof(Key));
02977     key->type=KEY_TYPE_UNDEFINED;
02978     /* If we lack the getuid() and getgid() functions we leave uid and gid at 0 */
02979     #if defined(HAVE_GETUID) && defined(HAVE_GETGID)
02980     key->uid=getuid();
02981     key->gid=getgid();
02982     #endif
02983     key->access=umask(0); 
02984     umask(key->access);
02985     key->access=DEFFILEMODE & ~key->access;
02986 
02987     key->flags = KEY_SWITCH_INITIALIZED;
02988 
02989     return 0;
02990 }
02991 
02992 
02993 
02994 
03015 int keyClose(Key *key) {
03016     /* if (!key) return errno=KDB_RET_NULLKEY;
03017     if (!keyIsInitialized(key)) return 0; */
03018 
03019     if (key->key) free(key->key);
03020     if (key->data) free(key->data);
03021     if (key->comment) free(key->comment);
03022     if (key->userDomain) free(key->userDomain);
03023     memset(key,0,sizeof(Key));
03024     return 0;
03025 }
03026 

Generated on Sun Feb 19 10:05:36 2006 for Elektra Project by  doxygen 1.3.9.1