Improved mode computation
[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   [[ -z "$label" ]] || buxton_set_label "$layer" "$group" "$label"
164 }
165
166 buxton_ensure_ready() {
167   if ! buxton_is_ready
168   then
169     error "can not connect to buxton service"
170     exit
171   fi
172 }
173
174 buxton_unset() {
175   local layer="$1" group="$2" name="$3"
176   
177   # unset the value
178   if ! buxton_has_key "$layer" "$group" "$name"
179   then
180     info "key $name in group $group of layer $layer is already unset"
181   elif ! buxton "unset-value" "$layer" "$group" "$name" > /dev/null
182   then
183     error "can not unset key $name in group $group of layer $layer"
184   elif buxton_has_key "$layer" "$group" "$name"
185   then
186     error "check failed when unsetting key $name in group $group of layer $layer"
187   else
188     info "key $name in group $group of layer $layer is unset"
189   fi
190   exit
191 }
192
193 #############################################################################################
194
195 group=vconf
196
197
198 # get the layer of the key
199 layer_of_key() {
200   case "$1/" in
201   user/*) echo -n "user";;
202   memory/*)
203     if [[ "$buxmode" = '-d' ]]
204     then
205       error "the layer temp isn't available in direct mode"
206       exit
207     fi
208     echo -n "temp"
209     ;;
210   *) echo -n "base";;
211   esac
212 }
213
214 # get the standard value
215 stdval() {
216   local typ="$1" val="$2"
217   case "$typ:${val,,}" in
218   bool:0|bool:false|bool:off) echo -n "false";;
219   bool:1|bool:true|bool:on) echo -n "true";;
220   *) echo -n "$val";;
221   esac
222 }
223
224 # get buxton-type from vconf-type
225 v2btype() {
226   case "${1,,}" in
227   int) echo -n "int32";;
228   string) echo -n "string";;
229   double) echo -n "double";;
230   bool) echo -n "bool";;
231   *) error "unknown vconf-type $1"; exit;;
232   esac
233 }
234
235 # get vconf-type from buxton-type
236 b2vtype() {
237   case "${1,,}" in
238   int32) echo -n "int";;
239   string) echo -n "string";;
240   double) echo -n "double";;
241   bool) echo -n "bool";;
242   *) error "unknown buxton-type $1"; exit;;
243   esac
244 }
245
246 #set a key
247 setkey() {
248   local typ="$1" name="$2" value="$3" smack="$4" layer=
249
250   layer="$(layer_of_key "$name")"
251   typ="$(v2btype "$typ")"
252   value="$(stdval "$typ" "$value")"
253   
254   if buxton "set-$typ" "$layer" "$group" "$name" "$value" > /dev/null
255   then
256     info "key $name in group $group of layer $layer set to $typ: $value"
257     [[ -z "$smack" ]] || buxton_set_label "$layer" "$group" "$name" "$smack"
258   else
259     error "can not set key $name in group $group of layer $layer with $typ: $value"
260   fi
261 }
262
263 # calls getopt with negative numbers protection
264 mygetopt() {
265   local name="$exe $1" long="$2" short="$3" x=
266   shift 3
267   eval set -- $(
268     for x; do
269       echo -n "'$x'" |
270       sed "s:\(.\)'\(.\):\\1\\\\'\\2:g ; s/^'\(-[0-9.]*\)'\$/'protect-sign:\1'/ ; s/^.*/& /"
271     done
272   )
273   getopt -n "$name" -l "$long" -o "$short" -- "$@" |
274   sed "s/'protect-sign:/'/g"
275 }
276
277 #
278 # ensure existing the group for vconf
279 #
280 buxton_ensure_group "base" "$group" || exit
281
282 # set the value
283 doset() {
284   local typ= name= layer= value= smack= force=false instal=false
285
286   # scan arguments
287   eval set -- $(mygetopt set force,install,type:,smack:,group:,user: fit:s:g:u: "$@")
288   while :
289   do
290     case "$1" in
291     -t|--type)
292       typ="$2"
293       shift 2
294       ;;
295     -s|--smack)
296       smack="$2"
297       shift 2
298       ;;
299     -f|--force)
300       force=true
301       shift
302       ;;
303     -i|--install)
304       instal=true
305       shift
306       ;;
307     -u|-g|--user|--group)
308       info "option $1 $2 ignored!"
309       shift 2
310       ;;
311     --)
312       shift
313       break
314       ;;
315     *)
316       badargs set "$*"
317       ;;
318     esac
319   done
320   [[ "$#" -eq 2 ]] || badargs set "$*"
321   name="$1"
322   value="$2"
323   [[ -n "$typ" ]] || badargs set no type given
324   [[ -n "$name" ]] || badargs set no keyname given
325
326   # process
327   if $instal
328   then
329     if expr "$name" : memory/ >/dev/null
330     then
331       setkey "$typ" "memory_init/$name" "$value" "$smack" || exit
332       [[ "$buxmode" = -d ]] && exit
333     else
334       warning only keys beginning with memory/ are allowing option -i
335     fi
336   fi
337   setkey "$typ" "$name" "$value" "$smack"
338   exit
339 }
340
341 # get the value
342 doget() {
343   local name= layer= rec=false val=
344
345   # scan arguments
346   eval set -- $(mygetopt get recursive r "$@")
347   if [[ "$1" = "-r" || "$1" = "--recursive" ]]
348   then
349     rec=true
350     shift
351   fi
352   [[ "$1" = -- ]] || badargs get unexpected error
353   shift
354   [[ $# -eq 1 && -n "$1" ]] || badargs get "$@"
355   name="$1"
356
357   # process
358   layer="$(layer_of_key "$name")"
359   if $rec
360   then
361     set -- $(buxton list-keys "$layer" "$group" "$name" 2> /dev/null |
362              grep "found key" |
363              sed 's:.* ::')
364   else
365     set -- "$name"
366   fi
367   for name
368   do
369     val="$(buxton get "$layer" "$group" "$name" 2> /dev/null |
370          grep "\[$layer] $group:$name = " |
371          sed 's/.* = // ; s/^int32:/int:/ ; s/^\(.*\): \(.*\)$/\2 (\1)/')"
372     if [[ -z "$val" ]]
373     then
374       error "key $name not found in group $group of layer $layer"
375     else
376       echo "$name, value = $val"
377     fi
378   done
379   exit
380 }
381
382 # unset the value
383 dounset() {
384   local name= layer=
385
386   # scan arguments
387   [[ $# -eq 1 && -n "$name" ]] || badargs unset
388   name="$1"
389   layer="$(layer_of_key "$name")"
390
391   # process
392   buxton_unset "$layer" "$group" "$name"
393   exit
394 }
395
396 # set the label
397 dolabel() {
398   local name= smack= layer=
399   
400   # scan arguments
401   [[ $# -eq 2 && -n "$name" && -n "$smack" ]] || badargs label
402   name="$1"
403   smack="$2"
404   layer="$(layer_of_key "$name")"
405
406   # process
407   buxton_set_label "$layer" "$group" "$name"
408   exit
409 }
410
411
412
413
414
415
416 cmd="${1,,}"
417 shift
418
419 case "${cmd}" in
420 -v|--verbose) verbose=true; cmd="${1,,}"; shift;;
421 -q|--quiet) quiet=true; cmd="${1,,}"; shift;;
422 esac
423
424 case "${cmd}" in
425 get) doget "$@";;
426 set) doset "$@";;
427 unset) dounset "$@";;
428 label) dolabel "$@";;
429 help|-h|--help) cat << EOC
430
431 Usage: $exe [-v|--verbose|-q|--quiet] command ...
432
433 Command set: set a value (create or update)
434
435    $exe set -t <TYPE> <KEY-NAME> <VALUE> <OPTIONS>
436
437        <TYPE> = int | bool | double | string
438
439        <OPTIONS>
440
441           -u, --user    <UID>    ignored! (compatibility)
442           -g, --group   <GID>    ignored! (compatibility)
443           -i, --install          for keys starting with memory/
444                                  installs in db the startup value
445           -s, --smack   <LABEL>  tells to set the security label <LABEL>
446           -f, --force            tells force updating the value
447
448        Ex) $exe set -t string db/testapp/key1 "This is test" 
449
450 Command get: get a value
451
452    $exe get <OPTIONS> <KEY-NAME>
453
454        <OPTIONS>
455
456           -r, --recursive        retrieve all keys having the given prefix
457
458        Ex) $exe get db/testapp/key1
459            $exe get -r db/testapp/
460
461 Command unset: remove a value
462
463    $exe unset <KEY-NAME>
464
465        Ex) $exe unset db/testapp/key1
466
467 Command label: set the security label
468
469    $exe label <KEY-NAME> <SMACK-LABEL>
470
471        Ex) $exe label db/testapp/key1 User::Share
472
473 EOC
474 esac
475