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