tizen 2.3 release
[external/buxton.git] / src / cli / client.c
1 /*
2  * This file is part of buxton.
3  *
4  * Copyright (C) 2013 Intel Corporation
5  *
6  * buxton is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1
9  * of the License, or (at your option) any later version.
10  */
11
12 #ifdef HAVE_CONFIG_H
13         #include "config.h"
14 #endif
15
16 #include <errno.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include "buxton.h"
22 #include "buxtonarray.h"
23 #include "buxtonresponse.h"
24 #include "client.h"
25 #include "direct.h"
26 #include "hashmap.h"
27 #include "protocol.h"
28 #include "util.h"
29
30 static char *nv(char *s)
31 {
32         if (s) {
33                 return s;
34         }
35         return "(null)";
36 }
37
38 bool cli_create_db(BuxtonControl *control,
39                    __attribute__((unused)) BuxtonDataType type,
40                    char *one,
41                    __attribute__((unused)) char *two,
42                    __attribute__((unused)) char *three,
43                    __attribute__((unused)) char *four)
44 {
45         BuxtonString layer_name;
46         bool ret;
47
48         if (!control->client.direct) {
49                 printf("Unable to create db in non direct mode\n");
50         }
51
52         layer_name = buxton_string_pack(one);
53
54         ret = buxton_direct_init_db(control, &layer_name);
55
56         return ret;
57 }
58
59 bool cli_set_label(BuxtonControl *control, BuxtonDataType type,
60                    char *one, char *two, char *three, char *four)
61 {
62         BuxtonString label;
63         BuxtonKey key;
64         bool ret = false;
65
66         if (four != NULL) {
67                 key = buxton_key_create(two, three, one, type);
68         } else {
69                 key = buxton_key_create(two, NULL, one, type);
70         }
71
72         if (!key) {
73                 return ret;
74         }
75
76         if (four != NULL) {
77                 label = buxton_string_pack(four);
78         } else {
79                 label = buxton_string_pack(three);
80         }
81
82         if (control->client.direct) {
83                 ret = buxton_direct_set_label(control, (_BuxtonKey *)key, &label);
84         } else {
85                 ret = !buxton_set_label(&control->client, key, label.value,
86                                         NULL, NULL, true);
87         }
88
89         if (!ret) {
90                 char *name = get_name(key);
91                 printf("Failed to update key \'%s:%s\' label in layer '%s'\n",
92                        two, nv(name), one);
93                 free(name);
94         }
95         buxton_key_free(key);
96         return ret;
97 }
98
99 bool cli_create_group(BuxtonControl *control, BuxtonDataType type,
100                       char *one, char *two, char *three, char *four)
101 {
102         BuxtonKey key;
103         bool ret = false;
104
105         key = buxton_key_create(two, NULL, one, type);
106         if (!key) {
107                 return ret;
108         }
109
110         if (control->client.direct) {
111                 ret = buxton_direct_create_group(control, (_BuxtonKey *)key, NULL);
112         } else {
113                 ret = !buxton_create_group(&control->client, key, NULL, NULL, true);
114         }
115
116         if (!ret) {
117                 char *group = get_group(key);
118                 printf("Failed to create group \'%s\' in layer '%s'\n",
119                        nv(group), one);
120                 free(group);
121         }
122         buxton_key_free(key);
123         return ret;
124 }
125
126 bool cli_remove_group(BuxtonControl *control, BuxtonDataType type,
127                       char *one, char *two, char *three, char *four)
128 {
129         BuxtonKey key;
130         bool ret = false;
131
132         key = buxton_key_create(two, NULL, one, type);
133         if (!key) {
134                 return ret;
135         }
136
137         if (control->client.direct) {
138                 ret = buxton_direct_remove_group(control, (_BuxtonKey *)key, NULL);
139         } else {
140                 ret = !buxton_remove_group(&control->client, key, NULL, NULL, true);
141         }
142
143         if (!ret) {
144                 char *group = get_group(key);
145                 printf("Failed to remove group \'%s\' in layer '%s'\n",
146                        nv(group), one);
147                 free(group);
148         }
149         buxton_key_free(key);
150         return ret;
151 }
152
153 bool cli_get_label(BuxtonControl *control, BuxtonDataType type,
154                    char *one, char *two, char *three,
155                    __attribute__((unused)) char *four)
156 {
157         /* Not yet implemented */
158         return false;
159 }
160
161 bool cli_set_value(BuxtonControl *control, BuxtonDataType type,
162                    char *one, char *two, char *three, char *four)
163 {
164         BuxtonString value;
165         BuxtonKey key;
166         BuxtonData set;
167         bool ret = false;
168
169         memzero((void*)&set, sizeof(BuxtonData));
170         key = buxton_key_create(two, three, one, type);
171         if (!key) {
172                 return ret;
173         }
174
175         value.value = four;
176         value.length = (uint32_t)strlen(four) + 1;
177
178         set.type = type;
179         switch (set.type) {
180         case STRING:
181                 set.store.d_string.value = value.value;
182                 set.store.d_string.length = value.length;
183                 if (control->client.direct) {
184                         ret = buxton_direct_set_value(control,
185                                                       (_BuxtonKey *)key,
186                                                       &set, NULL);
187                 } else {
188                         ret = !buxton_set_value(&control->client, key,
189                                                 four, NULL, NULL, true);
190                 }
191                 break;
192         case INT32:
193                 set.store.d_int32 = (int32_t)strtol(four, NULL, 10);
194                 if (errno) {
195                         printf("Invalid int32_t value\n");
196                         return ret;
197                 }
198                 if (control->client.direct) {
199                         ret = buxton_direct_set_value(control,
200                                                       (_BuxtonKey *)key,
201                                                       &set, NULL);
202                 } else {
203                         ret = !buxton_set_value(&control->client, key,
204                                                 &set.store.d_int32, NULL,
205                                                 NULL, true);
206                 }
207                 break;
208         case UINT32:
209                 set.store.d_uint32 = (uint32_t)strtol(value.value, NULL, 10);
210                 if (errno) {
211                         printf("Invalid uint32_t value\n");
212                         return ret;
213                 }
214                 if (control->client.direct) {
215                         ret = buxton_direct_set_value(control,
216                                                       (_BuxtonKey *)key,
217                                                       &set, NULL);
218                 } else {
219                         ret = !buxton_set_value(&control->client, key,
220                                                 &set.store.d_uint32, NULL,
221                                                 NULL, true);
222                 }
223                 break;
224         case INT64:
225                 set.store.d_int64 = strtoll(value.value, NULL, 10);
226                 if (errno) {
227                         printf("Invalid int64_t value\n");
228                         return ret;
229                 }
230                 if (control->client.direct) {
231                         ret = buxton_direct_set_value(control,
232                                                       (_BuxtonKey *)key,
233                                                       &set, NULL);
234                 } else {
235                         ret = !buxton_set_value(&control->client, key,
236                                                 &set.store.d_int64, NULL,
237                                                 NULL, true);
238                 }
239                 break;
240         case UINT64:
241                 set.store.d_uint64 = strtoull(value.value, NULL, 10);
242                 if (errno) {
243                         printf("Invalid uint64_t value\n");
244                         return ret;
245                 }
246                 if (control->client.direct) {
247                         ret = buxton_direct_set_value(control,
248                                                       (_BuxtonKey *)key,
249                                                       &set, NULL);
250                 } else {
251                         ret = !buxton_set_value(&control->client, key,
252                                                 &set.store.d_uint64, NULL,
253                                                 NULL, true);
254                 }
255                 break;
256         case FLOAT:
257                 set.store.d_float = strtof(value.value, NULL);
258                 if (errno) {
259                         printf("Invalid float value\n");
260                         return ret;
261                 }
262                 if (control->client.direct) {
263                         ret = buxton_direct_set_value(control,
264                                                       (_BuxtonKey *)key,
265                                                       &set, NULL);
266                 } else {
267                         ret = !buxton_set_value(&control->client, key,
268                                                 &set.store.d_float, NULL,
269                                                 NULL, true);
270                 }
271                 break;
272         case DOUBLE:
273                 set.store.d_double = strtod(value.value, NULL);
274                 if (errno) {
275                         printf("Invalid double value\n");
276                         return ret;
277                 }
278                 if (control->client.direct) {
279                         ret = buxton_direct_set_value(control,
280                                                       (_BuxtonKey *)key,
281                                                       &set, NULL);
282                 } else {
283                         ret = !buxton_set_value(&control->client, key,
284                                                 &set.store.d_double, NULL,
285                                                 NULL, true);
286                 }
287                 break;
288         case BOOLEAN:
289                 if (strcaseeq(value.value, "true") ||
290                     strcaseeq(value.value, "on") ||
291                     strcaseeq(value.value, "enable") ||
292                     strcaseeq(value.value, "yes") ||
293                     strcaseeq(value.value, "y") ||
294                     strcaseeq(value.value, "t") ||
295                     strcaseeq(value.value, "1")) {
296                         set.store.d_boolean = true;
297                 } else if (strcaseeq(value.value, "false") ||
298                          strcaseeq(value.value, "off") ||
299                          strcaseeq(value.value, "disable") ||
300                          strcaseeq(value.value, "no") ||
301                          strcaseeq(value.value, "n") ||
302                          strcaseeq(value.value, "f") ||
303                          strcaseeq(value.value, "0")) {
304                         set.store.d_boolean = false;
305                 } else {
306                         printf("Invalid bool value\n");
307                         return ret;
308                 }
309                 if (control->client.direct) {
310                         ret = buxton_direct_set_value(control,
311                                                       (_BuxtonKey *)key,
312                                                       &set, NULL);
313                 } else {
314                         ret = !buxton_set_value(&control->client, key,
315                                                 &set.store.d_boolean,
316                                                 NULL, NULL, true);
317                 }
318                 break;
319         default:
320                 break;
321         }
322
323         if (!ret) {
324                 char *group = get_group(key);
325                 char *name = get_name(key);
326                 char *layer = get_layer(key);
327
328                 printf("Failed to update key \'%s:%s\' in layer '%s'\n",
329                        nv(group), nv(name), nv(layer));
330                 free(group);
331                 free(name);
332                 free(layer);
333         }
334
335         return ret;
336 }
337
338 void get_value_callback(BuxtonResponse response, void *data)
339 {
340         BuxtonKey key;
341         BuxtonData *r = (BuxtonData *)data;
342         void *p;
343
344         if (buxton_response_status(response) != 0) {
345                 return;
346         }
347
348         p = buxton_response_value(response);
349         if (!p) {
350                 return;
351         }
352         key = buxton_response_key(response);
353         if (!key) {
354                 free(p);
355                 return;
356         }
357
358         switch (buxton_key_get_type(key)) {
359         case STRING:
360                 r->store.d_string.value = (char *)p;
361                 r->store.d_string.length = (uint32_t)strlen(r->store.d_string.value) + 1;
362                 r->type = STRING;
363                 break;
364         case INT32:
365                 r->store.d_int32 = *(int32_t *)p;
366                 r->type = INT32;
367                 break;
368         case UINT32:
369                 r->store.d_uint32 = *(uint32_t *)p;
370                 r->type = UINT32;
371                 break;
372         case INT64:
373                 r->store.d_int64 = *(int64_t *)p;
374                 r->type = INT64;
375                 break;
376         case UINT64:
377                 r->store.d_uint64 = *(uint64_t *)p;
378                 r->type = UINT64;
379                 break;
380         case FLOAT:
381                 r->store.d_float = *(float *)p;
382                 r->type = FLOAT;
383                 break;
384         case DOUBLE:
385                 memcpy(&r->store.d_double, p, sizeof(double));
386                 r->type = DOUBLE;
387                 break;
388         case BOOLEAN:
389                 r->store.d_boolean = *(bool *)p;
390                 r->type = BOOLEAN;
391                 break;
392         default:
393                 break;
394         }
395
396         if (buxton_key_get_type(key) != STRING) {
397                 free(p);
398         }
399         free(key);
400 }
401
402 bool cli_get_value(BuxtonControl *control, BuxtonDataType type,
403                    char *one, char *two, char *three, __attribute__((unused)) char * four)
404 {
405         BuxtonKey key;
406         BuxtonData get;
407         _cleanup_free_ char *prefix = NULL;
408         _cleanup_free_ char *group = NULL;
409         _cleanup_free_ char *name = NULL;
410         BuxtonString dlabel;
411         bool ret = false;
412         int32_t ret_val;
413         int r;
414
415         memzero((void*)&get, sizeof(BuxtonData));
416         if (three != NULL) {
417                 key = buxton_key_create(two, three, one, type);
418                 r = asprintf(&prefix, "[%s] ", one);
419                 if (!r) {
420                         abort();
421                 }
422         } else {
423                 key = buxton_key_create(one, two, NULL, type);
424                 r = asprintf(&prefix, " ");
425                 if (!r) {
426                         abort();
427                 }
428         }
429
430         if (!key) {
431                 return false;
432         }
433
434         if (three != NULL) {
435                 if (control->client.direct) {
436                         ret = buxton_direct_get_value_for_layer(control, key,
437                                                                 &get, &dlabel,
438                                                                 NULL);
439                 } else {
440                         ret = buxton_get_value(&control->client,
441                                                       key,
442                                                       get_value_callback,
443                                                       &get, true);
444                 }
445                 if (ret) {
446                         group = get_group(key);
447                         name = get_name(key);
448                         printf("Requested key was not found in layer \'%s\': %s:%s\n",
449                                one, nv(group), nv(name));
450                         return false;
451                 }
452         } else {
453                 if (control->client.direct) {
454                         ret_val = buxton_direct_get_value(control, key, &get, &dlabel, NULL);
455                         if (ret_val == 0) {
456                                 ret = true;
457                         }
458                 } else {
459                         ret = buxton_get_value(&control->client, key,
460                                                       get_value_callback, &get,
461                                                       true);
462                 }
463                 if (ret) {
464                         group = get_group(key);
465                         name = get_name(key);
466                         printf("Requested key was not found: %s:%s\n", nv(group),
467                                nv(name));
468                         return false;
469                 }
470         }
471
472         group = get_group(key);
473         name = get_name(key);
474         switch (get.type) {
475         case STRING:
476                 printf("%s%s:%s = %s\n", prefix, nv(group), nv(name),
477                        get.store.d_string.value ? get.store.d_string.value : "");
478                 break;
479         case INT32:
480                 printf("%s%s:%s = %" PRId32 "\n", prefix, nv(group),
481                        nv(name), get.store.d_int32);
482                 break;
483         case UINT32:
484                 printf("%s%s:%s = %" PRIu32 "\n", prefix, nv(group),
485                        nv(name), get.store.d_uint32);
486                 break;
487         case INT64:
488                 printf("%s%s:%s = %" PRId64 "\n", prefix, nv(group),
489                        nv(name), get.store.d_int64);
490                 break;
491         case UINT64:
492                 printf("%s%s:%s = %" PRIu64 "\n", prefix, nv(group),
493                        nv(name), get.store.d_uint64);
494                 break;
495         case FLOAT:
496                 printf("%s%s:%s = %f\n", prefix, nv(group),
497                        nv(name), get.store.d_float);
498                 break;
499         case DOUBLE:
500                 printf("%s%s:%s = %f\n", prefix, nv(group),
501                        nv(name), get.store.d_double);
502                 break;
503         case BOOLEAN:
504                 if (get.store.d_boolean == true) {
505                         printf("%s%s:%s = true\n", prefix, nv(group),
506                                nv(name));
507                 } else {
508                         printf("%s%s:%s = false\n", prefix, nv(group),
509                                nv(name));
510                 }
511                 break;
512         case BUXTON_TYPE_MIN:
513                 printf("Requested key was not found: %s:%s\n", nv(group),
514                                nv(name));
515                 return false;
516         default:
517                 printf("unknown type\n");
518                 return false;
519         }
520
521         if (get.type == STRING) {
522                 free(get.store.d_string.value);
523         }
524         return true;
525 }
526
527 bool cli_list_keys(BuxtonControl *control,
528                    __attribute__((unused))BuxtonDataType type,
529                    char *one, char *two, char *three,
530                    __attribute__((unused)) char *four)
531 {
532         /* not yet implemented */
533         return false;
534 }
535
536 void unset_value_callback(BuxtonResponse response, void *data)
537 {
538         BuxtonKey key = buxton_response_key(response);
539         char *group, *name;
540
541         if (!key) {
542                 return;
543         }
544
545         group = buxton_key_get_group(key);
546         name = buxton_key_get_name(key);
547         printf("unset key %s:%s\n", nv(group), nv(name));
548
549         free(group);
550         free(name);
551         buxton_key_free(key);
552 }
553
554 bool cli_unset_value(BuxtonControl *control,
555                      BuxtonDataType type,
556                      char *one, char *two, char *three,
557                      __attribute__((unused)) char *four)
558 {
559         BuxtonKey key;
560
561         key = buxton_key_create(two, three, one, type);
562
563         if (!key) {
564                 return false;
565         }
566
567         if (control->client.direct) {
568                 return buxton_direct_unset_value(control, key, NULL);
569         } else {
570                 return !buxton_unset_value(&control->client,
571                                            key, unset_value_callback,
572                                            NULL, true);
573         }
574 }
575 /*
576  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
577  *
578  * Local variables:
579  * c-basic-offset: 8
580  * tab-width: 8
581  * indent-tabs-mode: t
582  * End:
583  *
584  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
585  * :indentSize=8:tabSize=8:noTabs=false:
586  */