Improvement of vconftool/buxton_ensure_group
[platform/core/appfw/vconf-buxton.git] / src / vconf-buxton-tool.sh
1 #!/bin/bash
2 #
3 #     This script emulate the behaviour of vconftool
4 #
5 # author: jose.bollo@open.eurogiciel.org
6
7 exe="$(basename "$0")"
8 verbose=false
9 quiet=false
10
11 #
12 # prompting
13 #
14 if [[ -t 1 ]]
15 then
16   reset=$(printf '\e[0m')
17   red=$(printf '\e[1;31m')
18   yellow=$(printf '\e[1;33m')
19   green=$(printf '\e[1;32m')
20 else
21   reset=
22   red=
23   yellow=
24   green=
25 fi
26
27 info() {
28   $verbose && echo "${green}$*${reset}"
29   return 0
30 }
31
32 warning() {
33   $quiet || echo "${yellow}WARNING: $*${reset}"
34   return 0
35 }
36
37 error() {
38   $quiet || echo "${red}ERROR: $*${reset}" >&2
39   return 1
40 }
41
42 badargs() {
43   local cmd="$1"
44   shift
45   error "$exe $cmd: bad arguments $*"
46   exit
47 }
48
49 #
50 # detects buxton mode
51 #
52 buxmode=
53 if buxtonctl -s check >/dev/null 2>&1
54 then
55   buxmode=-s
56 elif buxtonctl -d check >/dev/null 2>&1
57 then
58   buxmode=-d
59 else
60   error "unable to detect buxton mode"
61   exit
62 fi
63
64 #
65 # calls to buxton
66 #
67 buxton() {
68   buxtonctl $buxmode -- "$@"
69 }
70
71 buxton_is_ready() {
72   buxton check > /dev/null
73 }
74
75 buxton_has_group() {
76   local layer="$1" group="$2"
77   buxton list-groups "${layer}" 2>/dev/null |
78   grep -q "found group ${group}\$"
79 }
80
81 buxton_has_key() {
82   local layer="$1" group="$2" name="$3"
83   buxton list-keys "${layer}" "${group}" 2>/dev/null |
84   grep -q "found key ${name}\$"
85 }
86
87 buxton_make_group() {
88   local layer="$1" group="$2"
89   if buxton create-group "$layer" "$group" > /dev/null
90   then
91     info "group $group succesfully created for layer $layer"
92   else
93     error "can not create group $group for layer $layer"
94   fi
95 }
96
97 buxton_get_label() {
98   if [[ $# -eq 2 ]]
99   then
100     local layer="$1" group="$2" result=
101     if ! result=$(buxton get-label "$layer" "$group" 2> /dev/null | 
102                   grep "\[$layer] $group:(null) - " |
103                   sed 's:.* - ::')
104     then
105       error "can not get the label $label of group $group of layer $layer"
106     elif [[ -z "$result" ]]
107     then
108       error "invalid label gotten for group $group of layer $layer"
109     else
110       echo -n "$result"
111     fi
112   else
113     local layer="$1" group="$2" name="$3" result=
114     if ! result=$(buxton get-label "$layer" "$group" "$name" 2> /dev/null | 
115                   grep "\[$layer] $group:$name - " |
116                   sed 's:.* - ::')
117     then
118       error "can not get the label $label of key $name in group $group of layer $layer"
119     elif [[ -z "$result" ]]
120     then
121       error "invalid label gotten for key $name in group $group of layer $layer"
122     else
123       echo -n "$result"
124     fi
125   fi
126 }
127
128 buxton_set_label() {
129   if [[ $# -eq 3 ]]
130   then
131     local layer="$1" group="$2" label="$3"
132     if ! buxton set-label "$layer" "$group" "$label" > /dev/null
133     then
134       error "can not set label $label to group $group of layer $layer"
135     elif [[ "$label" != "$(buxton_get_label "$layer" "$group")" ]]
136     then
137       error "check failed when setting label $label to group $group of layer $layer"
138     else
139       info "label $label set to group $group of layer $layer"
140     fi
141   else
142     local layer="$1" group="$2" name="$3" label="$4"
143     if ! buxton set-label "$layer" "$group" "$name" "$label" > /dev/null
144     then
145       error "can not set label $label to key $name in group $group of layer $layer"
146     elif [[ "$label" != "$(buxton_get_label "$layer" "$group" "$name")" ]]
147     then
148       error "check failed when setting label $label to key $name in group $group of layer $layer"
149     else
150       info "label $label set to key $name in group $group of layer $layer"
151     fi
152   fi
153 }
154
155 buxton_ensure_group() {
156   local layer="$1" group="$2" label="$3"
157   if buxton_has_group "$layer" "$group"
158   then
159     info "group $group exists in layer $layer"
160   else
161     buxton_make_group "$layer" "$group" || return
162   fi
163   if [[ -n "$label" ]] && [[ "$label" != "$(buxton_get_label "$layer" "$group")" ]]
164   then
165     buxton_set_label "$layer" "$group" "$label"
166   else
167     info "group $group in layer $layer already has label $label"
168   fi
169 }
170
171 buxton_ensure_ready() {
172   if ! buxton_is_ready
173   then
174     error "can not connect to buxton service"
175     exit
176   fi
177 }
178
179 buxton_unset() {
180   local layer="$1" group="$2" name="$3"
181   
182   # unset the value
183   if ! buxton_has_key "$layer" "$group" "$name"
184   then
185     info "key $name in group $group of layer $layer is already unset"
186   elif ! buxton "unset-value" "$layer" "$group" "$name" > /dev/null
187   then
188     error "can not unset key $name in group $group of layer $layer"
189   elif buxton_has_key "$layer" "$group" "$name"
190   then
191     error "check failed when unsetting key $name in group $group of layer $layer"
192   else
193     info "key $name in group $group of layer $layer is unset"
194   fi
195   exit
196 }
197
198 #############################################################################################
199
200 group=vconf
201 context=User
202
203
204 # get the layer of the key
205 layer_of_key() {
206   case "$1/" in
207   user/*) echo -n "user";;
208   memory/*)
209     if [[ "$buxmode" = '-d' ]]
210     then
211       error "the layer temp isn't available in direct mode"
212       exit
213     fi
214     echo -n "temp"
215     ;;
216   *) echo -n "base";;
217   esac
218 }
219
220 # get the standard value
221 stdval() {
222   local typ="$1" val="$2"
223   case "$typ:${val,,}" in
224   bool:0|bool:false|bool:off) echo -n "false";;
225   bool:1|bool:true|bool:on) echo -n "true";;
226   *) echo -n "$val";;
227   esac
228 }
229
230 # get buxton-type from vconf-type
231 v2btype() {
232   case "${1,,}" in
233   int) echo -n "int32";;
234   string) echo -n "string";;
235   double) echo -n "double";;
236   bool) echo -n "bool";;
237   *) error "unknown vconf-type $1"; exit;;
238   esac
239 }
240
241 # get vconf-type from buxton-type
242 b2vtype() {
243   case "${1,,}" in
244   int32) echo -n "int";;
245   string) echo -n "string";;
246   double) echo -n "double";;
247   bool) echo -n "bool";;
248   *) error "unknown buxton-type $1"; exit;;
249   esac
250 }
251
252 #set a key
253 setkey() {
254   local typ="$1" name="$2" value="$3" smack="$4" layer=
255
256   layer="$(layer_of_key "$name")"
257   typ="$(v2btype "$typ")"
258   value="$(stdval "$typ" "$value")"
259   
260   if buxton "set-$typ" "$layer" "$group" "$name" "$value" > /dev/null
261   then
262     info "key $name in group $group of layer $layer set to $typ: $value"
263     [[ -z "$smack" ]] || buxton_set_label "$layer" "$group" "$name" "$smack"
264   else
265     error "can not set key $name in group $group of layer $layer with $typ: $value"
266   fi
267 }
268
269 # calls getopt with negative numbers protection
270 mygetopt() {
271   local name="$exe $1" long="$2" short="$3" x=
272   shift 3
273   eval set -- $(
274     for x; do
275       echo -n "'$x'" |
276       sed "s:\(.\)'\(.\):\\1\\\\'\\2:g ; s/^'\(-[0-9.]*\)'\$/'protect-sign:\1'/ ; s/^.*/& /"
277     done
278   )
279   getopt -n "$name" -l "$long" -o "$short" -- "$@" |
280   sed "s/'protect-sign:/'/g"
281 }
282
283 #
284 # ensure existing the group for vconf
285 #
286 buxton_ensure_group "base" "$group" "$context" || exit
287
288 # set the value
289 doset() {
290   local typ= name= layer= value= smack= force=false instal=false
291
292   # scan arguments
293   eval set -- $(mygetopt set force,install,type:,smack:,group:,user: fit:s:g:u: "$@")
294   while :
295   do
296     case "$1" in
297     -t|--type)
298       typ="$2"
299       shift 2
300       ;;
301     -s|--smack)
302       smack="$2"
303       shift 2
304       ;;
305     -f|--force)
306       force=true
307       shift
308       ;;
309     -i|--install)
310       instal=true
311       shift
312       ;;
313     -u|-g|--user|--group)
314       info "option $1 $2 ignored!"
315       shift 2
316       ;;
317     --)
318       shift
319       break
320       ;;
321     *)
322       badargs set "$*"
323       ;;
324     esac
325   done
326   [[ "$#" -eq 2 ]] || badargs set "$*"
327   name="$1"
328   value="$2"
329   [[ -n "$typ" ]] || badargs set no type given
330   [[ -n "$name" ]] || badargs set no keyname given
331
332   # process
333   if $instal
334   then
335     if expr "$name" : memory/ >/dev/null
336     then
337       setkey "$typ" "memory_init/$name" "$value" "$smack" || exit
338       [[ "$buxmode" = -d ]] && exit
339     else
340       warning only keys beginning with memory/ are allowing option -i
341     fi
342   fi
343   setkey "$typ" "$name" "$value" "$smack"
344   exit
345 }
346
347 # get the value
348 doget() {
349   local name= layer= rec=false val=
350
351   # scan arguments
352   eval set -- $(mygetopt get recursive r "$@")
353   if [[ "$1" = "-r" || "$1" = "--recursive" ]]
354   then
355     rec=true
356     shift
357   fi
358   [[ "$1" = -- ]] || badargs get unexpected error
359   shift
360   [[ $# -eq 1 && -n "$1" ]] || badargs get "$@"
361   name="$1"
362
363   # process
364   layer="$(layer_of_key "$name")"
365   if $rec
366   then
367     set -- $(buxton list-keys "$layer" "$group" "$name" 2> /dev/null |
368              grep "found key" |
369              sed 's:.* ::')
370   else
371     set -- "$name"
372   fi
373   for name
374   do
375     val="$(buxton get "$layer" "$group" "$name" 2> /dev/null |
376          grep "\[$layer] $group:$name = " |
377          sed 's/.* = // ; s/^int32:/int:/ ; s/^\(.*\): \(.*\)$/\2 (\1)/')"
378     if [[ -z "$val" ]]
379     then
380       error "key $name not found in group $group of layer $layer"
381     else
382       echo "$name, value = $val"
383     fi
384   done
385   exit
386 }
387
388 # unset the value
389 dounset() {
390   local name= layer=
391
392   # scan arguments
393   [[ $# -eq 1 && -n "$name" ]] || badargs unset
394   name="$1"
395   layer="$(layer_of_key "$name")"
396
397   # process
398   buxton_unset "$layer" "$group" "$name"
399   exit
400 }
401
402 # set the label
403 dolabel() {
404   local name= smack= layer=
405   
406   # scan arguments
407   [[ $# -eq 2 && -n "$name" && -n "$smack" ]] || badargs label
408   name="$1"
409   smack="$2"
410   layer="$(layer_of_key "$name")"
411
412   # process
413   buxton_set_label "$layer" "$group" "$name"
414   exit
415 }
416
417
418
419
420
421
422 cmd="${1,,}"
423 shift
424
425 case "${cmd}" in
426 -v|--verbose) verbose=true; cmd="${1,,}"; shift;;
427 -q|--quiet) quiet=true; cmd="${1,,}"; shift;;
428 esac
429
430 case "${cmd}" in
431 get) doget "$@";;
432 set) doset "$@";;
433 unset) dounset "$@";;
434 label) dolabel "$@";;
435 help|-h|--help) cat << EOC
436
437 Usage: $exe [-v|--verbose|-q|--quiet] command ...
438
439 Command set: set a value (create or update)
440
441    $exe set -t <TYPE> <KEY-NAME> <VALUE> <OPTIONS>
442
443        <TYPE> = int | bool | double | string
444
445        <OPTIONS>
446
447           -u, --user    <UID>    ignored! (compatibility)
448           -g, --group   <GID>    ignored! (compatibility)
449           -i, --install          for keys starting with memory/
450                                  installs in db the startup value
451           -s, --smack   <LABEL>  tells to set the security label <LABEL>
452           -f, --force            tells force updating the value
453
454        Ex) $exe set -t string db/testapp/key1 "This is test" 
455
456 Command get: get a value
457
458    $exe get <OPTIONS> <KEY-NAME>
459
460        <OPTIONS>
461
462           -r, --recursive        retrieve all keys having the given prefix
463
464        Ex) $exe get db/testapp/key1
465            $exe get -r db/testapp/
466
467 Command unset: remove a value
468
469    $exe unset <KEY-NAME>
470
471        Ex) $exe unset db/testapp/key1
472
473 Command label: set the security label
474
475    $exe label <KEY-NAME> <SMACK-LABEL>
476
477        Ex) $exe label db/testapp/key1 User::Share
478
479 EOC
480 esac
481