Changeset 582


Ignore:
Timestamp:
12/22/2011 17:21:11 (5 months ago)
Author:
blee
Message:

Merge fix for #153 into confman-1.9.

See #153

Location:
branches/confman-1.9
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/confman-1.9

    • Property svn:ignore
      •  

        old new  
        2323confsync 
        2424install-sh 
         25libfiledb.sh 
        2526missing 
    • Property svn:mergeinfo changed
      /trunkmerged: 574-579,​581
  • branches/confman-1.9/Makefile.am

    r580 r582  
    1313                                         abspath \ 
    1414                                         confman_precommit 
    15 pkgdata_SCRIPTS = confmancommon.sh confmanlib.sh  
     15pkgdata_SCRIPTS = confmancommon.sh confmanlib.sh libfiledb.sh 
    1616dist_pkgdata_SCRIPTS = confmandoc.sh confadmindoc.sh 
    1717sysconf_DATA = confman.conf.sample 
     
    4949                confman.8.in \ 
    5050                confman.conf.5.in \ 
     51                libfiledb.sh.in \ 
    5152                LICENSE 
    5253 
     
    121122        $(do_subst) < confman.conf.5.in > confman.conf.5 
    122123 
     124libfiledb.sh: libfiledb.sh.in Makefile 
     125        $(do_subst) < libfiledb.sh.in > libfiledb.sh 
     126 
  • branches/confman-1.9/libfiledb.sh.in

    r574 r582  
    2525# $Id$ 
    2626# 
    27 # libfiledb.sh is a command-line tool for file-backed key-value stores. 
     27# libfiledb.sh is a shell library for file-backed key-value stores. 
    2828# 
    29 # libfiledb.sh uses the null character as its internal delimiter, so null 
    30 # characters are stripped from keys and values before being inserted into 
    31 # the database. 
     29# libfiledb.sh does not do any locking -- locking must be managed by the 
     30# caller as appropriate. 
     31# 
     32# The on-disk storage format uses the tab character as the field delimiter 
     33# and the new line character as the record delimiter.  Tab characters and 
     34# new lines are accepted in both keys and values and recorded as "\t" and 
     35# "\n" respectively. 
    3236 
    33 FILEDB_VERSION="1.0" 
    34 OS_UNAME=`/usr/bin/uname` 
    35 CONFLOCK="@pkglibexecdir@/conflock" 
     37# Purpose: Load a filedb into an array 
     38# Inputs: filedb, array 
     39# Prints: N/A 
     40# Returns: 0 if the filedb was loaded into the array, 1 on error 
     41filedb_load() 
     42{ 
     43        if [ -z "${1-}" -o -z "${2-}" ]; then 
     44                return 1 
     45        fi 
    3646 
    37 # Purpose: Runs sed differently based on the running OS 
    38 # Inputs: Arguments to sed 
    39 # Prints: Output of sed 
    40 # Returns: 0 on success, 2 on error 
    41 os_sed() 
    42 { 
    43         case ${OS_UNAME} in 
    44                 FreeBSD) 
    45                         /usr/bin/sed -i '' "$@" || return 2;; 
    46                 Linux) 
    47                         /bin/sed -i "$@" || return 2;; 
    48                 *) 
    49                         return 2;; 
    50         esac 
     47        local filedb="$1" 
     48        local array="$2" 
    5149 
     50        local key 
     51        local value 
     52 
     53        [ -r "${filedb}" ] && 
     54        [ -v "${array}" ] && 
     55        local IFS="     " 
     56        while read -r key value; do 
     57                eval "`echo "${array}"`[\"`echo -e "${key}"`\"]=\"`echo -e "${value}"`\"" 
     58        done <"${filedb}" && 
    5259        return 0 
     60 
     61        return 1 
    5362} 
    5463 
    55 # Purpose: Create a filedb 
    56 # Inputs: filedb 
     64# Purpose: Write an array into a filedb 
     65# Inputs: array, filedb 
    5766# Prints: N/A 
    58 # Returns: 0 if the filedb was created, 2 on error 
    59 filedb_create() 
     67# Returns: 0 if the array was written into the filedb, 1 on error 
     68filedb_write() 
    6069{ 
    61         local filedb="$1" 
    62  
    63         local lock_type 
    64  
    65         lock_type=`filedb_lock "${filedb}"` || return 2 
    66  
    67         ! [ -f "${filedb}" ] && 
    68                 touch "${filedb}" && 
    69                 filedb_set_value "${filedb}" "filedb:version" "${FILEDB_VERSION}" && 
    70                 filedb_unlock "${filedb}" "${lock_type}" && 
    71                 return 0 
    72  
    73         filedb_unlock "${filedb}" "${lock_type}" 
    74         return 2 
    75 } 
    76  
    77 # Purpose: Recursively lock a filedb 
    78 # Inputs: filedb 
    79 # Prints: "recursive" or "original" depending on the type of lock acquired 
    80 # Returns: 0 if the filedb was locked, 2 on error 
    81 filedb_lock() 
    82 { 
    83         local filedb="$1" 
    84  
    85         local lock_type 
    86  
    87         # If this process already has the lock, this is a recursive lock 
    88         if filedb_is_locked "${filedb}"; then 
    89                 lock_type="recursive" 
    90         else 
    91                 lock_type="original" 
     70        if [ -z "${1-}" -o -z "${2-}" ]; then 
     71                return 1 
    9272        fi 
    9373 
    94         "${CONFLOCK}" lock $$ "${filedb}.lock" || return 2 
     74        local array="$1" 
     75        local filedb="$2" 
    9576 
    96         echo "${lock_type}" 
    97         return 0 
    98 } 
    99  
    100 # Purpose: Unlock a filedb 
    101 # Inputs: filedb, lock type 
    102 # Prints: N/A 
    103 # Returns: 0 if the filedb was unlocked, 2 on error 
    104 filedb_unlock() 
    105 { 
    106         local filedb="$1" 
    107         local lock_type="$2" 
    108  
    109         case "${lock_type}" in 
    110                 recursive) 
    111                         return 0;; 
    112                 original) 
    113                         "${CONFLOCK}" unlock $$ "${filedb}.lock" || return 2;; 
    114                 *) 
    115                         return 2;; 
    116         esac 
    117  
    118         return 0 
    119 } 
    120  
    121 # Purpose: Test whether a filedb is locked 
    122 # Inputs: filedb 
    123 # Prints: N/A 
    124 # Returns: 0 if the filedb is locked, 1 if the filedb is not locked, 2 on error 
    125 filedb_is_locked() 
    126 { 
    127         local filedb="$1" 
    128  
    129         local rv 
    130  
    131         "${CONFLOCK}" haslock $$ "${filedb}.lock" 
    132         rv=$? 
    133          
    134         case ${rv} in 
    135                 0|1) 
    136                         return ${rv};; 
    137                 *) 
    138                         return 2;; 
    139         esac 
    140 } 
    141  
    142 # Purpose: Get the list of keys 
    143 # Inputs: filedb 
    144 # Prints: The list of keys 
    145 # Returns: 0 on success, 2 on error 
    146 filedb_get_keys() 
    147 { 
    148         local filedb="$1" 
    149  
    150         local lock_type 
    151  
    152         lock_type=`filedb_lock "${filedb}"` || return 2 
    153  
    154         awk -F '\0' '{print $1}' "${filedb}" && 
    155                 filedb_unlock "${filedb}" "${lock_type}" && 
    156                 return 0 
    157  
    158         filedb_unlock "${filedb}" "${lock_type}" 
    159         return 2 
    160 } 
    161  
    162 # Purpose: Get the list of values 
    163 # Inputs: filedb 
    164 # Prints: The list of values 
    165 # Returns: 0 on success, 2 on error 
    166 filedb_get_values() 
    167 { 
    168         local filedb="$1" 
    169  
    170         local lock_type 
    171  
    172         lock_type=`filedb_lock "${filedb}"` || return 2 
    173  
    174         awk -F '\0' '{print $2}' "${filedb}" && 
    175                 filedb_unlock "${filedb}" "${lock_type}" && 
    176                 return 0 
    177  
    178         filedb_unlock "${filedb}" "${lock_type}" 
    179         return 2 
    180 } 
    181  
    182 # Purpose: Test whether a key exists 
    183 # Inputs: filedb, key 
    184 # Prints: N/A 
    185 # Returns: 0 if the key exists, 1 if the key does not exist, 2 on error 
    186 filedb_key_exists() 
    187 { 
    188         local filedb="$1" 
    189         local key=`echo "$2" | tr -d '\0'` 
    190  
    191         local lock_type 
    192         local rv 
    193  
    194         lock_type=`filedb_lock "${filedb}"` || return 2 
    195  
    196         awk -F '\0' '{if ($1 == "'"${key}"'") {_assert_exit = 1; exit}}; END {if (_assert_exit) exit 0; exit 1}' "${filedb}" 
    197         rv=$? 
    198  
    199         case ${rv} in 
    200                 0|1) 
    201                         filedb_unlock "${filedb}" "${lock_type}" || return 2 
    202                         return ${rv};; 
    203         esac 
    204  
    205         filedb_unlock "${filedb}" "${lock_type}" 
    206         return 2 
    207 } 
    208  
    209 # Purpose: Get the value for a key 
    210 # Inputs: filedb, key 
    211 # Prints: The value for the key 
    212 # Returns: 0 if the value was retrieved, 2 on error 
    213 filedb_get_value() 
    214 { 
    215         local filedb="$1" 
    216         local key=`echo "$2" | tr -d '\0'` 
    217  
    218         local lock_type 
     77        local i 
     78        local key 
    21979        local value 
    22080 
    221         lock_type=`filedb_lock "${filedb}"` || return 2 
     81        [ -w "${filedb}" -o -w "`dirname "${filedb}"`" ] && 
     82        [ -v "${array}" ] && 
     83        eval 'for i in "'"\${!${array}"'[@]}"; do 
     84                i="${i//\\/\\\\}" 
     85                i="${i// 
     86/\\n}" 
     87                echo -E "${i}" 
     88        done' | while read -r key; do 
     89                eval "value=\"\${${array}[\"`echo -e "${key}"`\"]}\"" 
     90                value="${value//\\/\\\\}" 
     91                value="${value// 
     92/\\n}" 
     93                echo -nE "${key%%       *}" 
     94                while [ "${key}" != "${key#*    }" ]; do 
     95                        key="${key#*    }" 
     96                        echo -nE "\\t${key%%    *}" 
     97                done 
     98                echo -n "       " 
     99                echo -nE "${value%%     *}" 
     100                while [ "${value}" != "${value#*        }" ]; do 
     101                        value="${value#*        }" 
     102                        echo -nE "\\t${value%%  *}" 
     103                done 
     104                echo 
     105        done > "${filedb}" && 
     106        return 0 
    222107 
    223         filedb_key_exists "${filedb}" "${key}" && 
    224                 value=`awk -F '\0' '{if ($1 == "'"${key}"'") print $2}' "${filedb}"` && 
    225                 echo "${value}" && 
    226                 filedb_unlock "${filedb}" "${lock_type}" && 
    227                 return 0 
    228  
    229         filedb_unlock "${filedb}" "${lock_type}" 
    230         return 2 
     108        return 1 
    231109} 
    232  
    233 # Purpose: Delete a key 
    234 # Inputs: filedb, key 
    235 # Prints: N/A 
    236 # Returns: 0 if the key was deleted, 2 on error 
    237 filedb_delete_key() 
    238 { 
    239         local filedb="$1" 
    240         local key=`echo "$2" | tr -d '\0'` 
    241  
    242         local lock_type 
    243         local line 
    244  
    245         lock_type=`filedb_lock "${filedb}"` || return 2 
    246  
    247         line=`awk -F '\0' '{if ($1 == "'"${key}"'") print NR}' "${filedb}"` && 
    248                 [ -n "${line}" ] && 
    249                 os_sed "${line} d" "${filedb}" && 
    250                 filedb_unlock "${filedb}" "${lock_type}" && 
    251                 return 0 
    252  
    253         filedb_unlock "${filedb}" "${lock_type}" 
    254         return 2 
    255 } 
    256  
    257 # Purpose: Set a value for a key 
    258 # Inputs: filedb, key, value 
    259 # Prints: N/A 
    260 # Returns: 0 if the value was set, 2 on error 
    261 filedb_set_value() 
    262 { 
    263         local filedb="$1" 
    264         local key=`echo "$2" | tr -d '\0'` 
    265         local value=`echo "$3" | tr -d '\0'` 
    266  
    267         local lock_type 
    268         local rv 
    269  
    270         lock_type=`filedb_lock "${filedb}"` || return 2 
    271  
    272         filedb_key_exists "${filedb}" "${key}" 
    273         rv=$? 
    274          
    275         case ${rv} in 
    276                 0) 
    277                         if ! filedb_delete_key "${filedb}" "${key}"; then 
    278                                 filedb_unlock "${filedb}" "${lock_type}" 
    279                                 return 2 
    280                         fi;; 
    281                 1) 
    282                         :;; 
    283                 *) 
    284                         filedb_unlock "${filedb}" "${lock_type}" 
    285                         return 2;; 
    286         esac 
    287  
    288         printf "${key}\\000${value}\\n" >> "${filedb}" && 
    289                 filedb_unlock "${filedb}" "${lock_type}" && 
    290                 return 0 
    291  
    292         filedb_unlock "${filedb}" "${lock_type}" 
    293         return 2 
    294 } 
Note: See TracChangeset for help on using the changeset viewer.