25e28ce1d896bd68ce43a5cc7c0dcc2bc6d60db8
[platform/core/uifw/voice-control.git] / common / vc_info_parser.c
1 /*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <app_manager.h>
18 #include <dlog.h>
19 #include <libxml/parser.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include "vc_cmd_db.h"
24 #include "vc_defs.h"
25 #include "vc_info_parser.h"
26 #include "vc_main.h"
27 #include "voice_control_command.h"
28 #include "voice_control_common.h"
29
30
31 #define VC_TAG_CMD_BASE_TAG             "vc_commands"
32
33 #define VC_TAG_CMD_COMMAND              "command"
34 #define VC_TAG_CMD_ID                   "cmd_id"
35 #define VC_TAG_CMD_PID                  "cmd_pid"
36 #define VC_TAG_CMD_TYPE                 "cmd_type"
37 #define VC_TAG_CMD_FORMAT               "cmd_format"
38 #define VC_TAG_CMD_COMMAND_TEXT         "cmd_cmd_text"
39 #define VC_TAG_CMD_PARAMETER_TEXT       "cmd_param_text"
40 #define VC_TAG_CMD_DOMAIN               "cmd_domain"
41 #define VC_TAG_CMD_KEY                  "cmd_key"
42 #define VC_TAG_CMD_MODIFIER             "cmd_modifier"
43 #define VC_TAG_CMD_IS_ACTION            "cmd_is_action"
44
45 #define VC_TAG_RESULT_BASE_TAG          "vc_results"
46 #define VC_TAG_RESULT_TEXT              "result_text"
47 #define VC_TAG_RESULT_EVENT             "result_event"
48 #define VC_TAG_RESULT_MESSAGE           "result_message"
49
50 #define VC_TAG_INFO_BASE_TAG            "vc_info_option"
51 #define VC_TAG_INFO_FOREGROUND          "foreground_pid"
52
53 #define VC_TAG_DEMANDABLE_CLIENT_BASE_TAG       "vc_demandable_client"
54 #define VC_TAG_DEMANDABLE_CLIENT_APPID          "appid"
55
56 #define VC_TAG_CLIENT_BASE_TAG          "vc_client_info"
57 #define VC_TAG_CLIENT_CLIENT            "client"
58 #define VC_TAG_CLIENT_PID               "pid"
59 #define VC_TAG_CLIENT_FGCMD             "fgcmd"
60 #define VC_TAG_CLIENT_BGCMD             "bgcmd"
61 #define VC_TAG_CLIENT_EXCMD             "excmd"
62
63
64 const char* vc_info_tag()
65 {
66         return TAG_VCINFO;
67 }
68
69 int __vc_cmd_parser_print_commands(GSList* cmd_list);
70
71
72 static int __vc_info_parser_set_file_mode(const char* filename)
73 {
74         if (NULL == filename) {
75                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Invalid parameter");
76                 return -1;
77         }
78
79         if (0 > chmod(filename, 0600)) {
80                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to change file mode");
81                 return -1;
82         }
83         return 0;
84 }
85
86 int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name)
87 {
88         if (0 >= g_slist_length(cmd_list)) {
89                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command list is invalid");
90                 return -1;
91         }
92
93         int ret = vc_db_insert_commands_list(pid, type, cmd_list, invocation_name, false);
94         if (0 != ret) {
95                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret);
96         }
97         return ret;
98 }
99
100 int vc_cmd_parser_delete_file(int pid, vc_cmd_type_e type)
101 {
102         int ret = 0;
103         char* appid = NULL;
104
105         if (-1 != pid) {
106                 // Get appid by pid using app control
107                 ret = app_manager_get_app_id(pid, &appid);
108                 if (APP_MANAGER_ERROR_NONE != ret) {
109                         SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] fail to get app id, ret(%d)", ret);
110                 } else {
111                         SLOG(LOG_DEBUG, vc_info_tag(), "Background cmd: appid = %s", appid);
112                 }
113         }
114
115         ret = vc_db_delete_commands(pid, type, appid);
116         if (0 != ret) {
117                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] get commands from db is failed, ret = %d", ret);
118         }
119
120         if (NULL != appid) {
121                 free(appid);
122                 appid = NULL;
123         }
124         return ret;
125 }
126
127 int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list)
128 {
129         int ret = vc_db_get_commands(pid, type, cmd_list);
130         if (0 != ret) {
131                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] get commands from db is failed, ret = %d", ret);
132         }
133         __vc_cmd_parser_print_commands(*cmd_list);
134         return ret;
135 }
136
137 int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_cmd_list)
138 {
139         int ret = vc_db_append_commands(pid, type, vc_cmd_list);
140         if (0 != ret) {
141                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] get commands from db is failed, ret = %d", ret);
142         }
143         vc_cmd_print_list(vc_cmd_list);
144         return ret;
145 }
146
147 void __vc_info_parser_demandable_client_free(void* data)
148 {
149         vc_demandable_client_s* d_client = (vc_demandable_client_s*)data;
150
151         if (NULL != d_client) {
152                 if (NULL != d_client->appid) {
153                         free(d_client->appid);
154                         d_client->appid = NULL;
155                 }
156
157                 free(d_client);
158         }
159 }
160
161 int vc_info_parser_get_demandable_clients(GSList** client_list)
162 {
163         /* Check file */
164         xmlDocPtr doc = NULL;
165         xmlNodePtr cur = NULL;
166         xmlChar *key;
167
168         doc = xmlParseFile(VC_RUNTIME_INFO_DEMANDABLE_LIST);
169         if (doc == NULL) {
170                 SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_FOREGROUND);
171                 return -1;
172         }
173
174         cur = xmlDocGetRootElement(doc);
175         if (cur == NULL) {
176                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
177                 xmlFreeDoc(doc);
178                 return -1;
179         }
180
181         if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) {
182                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG);
183                 xmlFreeDoc(doc);
184                 return -1;
185         }
186
187         cur = cur->xmlChildrenNode;
188         if (cur == NULL) {
189                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
190                 xmlFreeDoc(doc);
191                 return -1;
192         }
193
194         GSList* temp_client_list = NULL;
195
196         while (cur != NULL) {
197                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) {
198                         key = xmlNodeGetContent(cur);
199                         if (NULL != key) {
200                                 SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key);
201
202                                 vc_demandable_client_s* temp_client;
203                                 temp_client = (vc_demandable_client_s*)calloc(1, sizeof(vc_demandable_client_s));
204
205                                 if (NULL == temp_client) {
206                                         SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
207
208                                         if (NULL != temp_client_list) {
209                                                 g_slist_free_full(temp_client_list, __vc_info_parser_demandable_client_free);
210                                                 temp_client_list = NULL;
211                                         }
212                                         xmlFree(key);
213                                         xmlFreeDoc(doc);
214                                         return -1;
215                                 }
216
217                                 if (0 < xmlStrlen(key)) {
218                                         temp_client->appid = strdup((char*)key);
219                                 } else {
220                                         /* NULL for appid is available */
221                                         temp_client->appid = NULL;
222                                 }
223                                 xmlFree(key);
224
225                                 temp_client_list = g_slist_append(temp_client_list, temp_client);
226                         } else {
227                                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL");
228                         }
229                 }
230                 cur = cur->next;
231         }
232
233         xmlFreeDoc(doc);
234
235         *client_list = temp_client_list;
236
237         if (0 != remove(VC_RUNTIME_INFO_DEMANDABLE_LIST)) {
238                 SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_DEMANDABLE_LIST);
239         }
240
241         return 0;
242 }
243
244 int vc_info_parser_set_demandable_client(const char* filepath)
245 {
246         if (NULL == filepath) {
247                 if (0 != remove(VC_RUNTIME_INFO_DEMANDABLE_LIST)) {
248                         SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_DEMANDABLE_LIST);
249                 }
250                 return 0;
251         }
252
253         /* Check file */
254         xmlDocPtr doc = NULL;
255         xmlNodePtr cur = NULL;
256         xmlChar *key;
257
258         doc = xmlParseFile(filepath);
259         if (doc == NULL) {
260                 SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath);
261                 return -1;
262         }
263
264         cur = xmlDocGetRootElement(doc);
265         if (cur == NULL) {
266                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
267                 xmlFreeDoc(doc);
268                 return -1;
269         }
270
271         if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) {
272                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG);
273                 xmlFreeDoc(doc);
274                 return -1;
275         }
276
277         cur = cur->xmlChildrenNode;
278         if (cur == NULL) {
279                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
280                 xmlFreeDoc(doc);
281                 return -1;
282         }
283
284         while (cur != NULL) {
285                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) {
286                         key = xmlNodeGetContent(cur);
287                         if (NULL != key) {
288                                 SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key);
289                                 xmlFree(key);
290                         } else {
291                                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL");
292                                 xmlFreeDoc(doc);
293                                 return -1;
294                         }
295                 }
296                 cur = cur->next;
297         }
298
299         int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_DEMANDABLE_LIST, doc, 1);
300         SLOG(LOG_DEBUG, vc_info_tag(), "Save demandable file info : %d", ret);
301
302         xmlFreeDoc(doc);
303         return 0;
304 }
305
306 int vc_info_parser_set_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive)
307 {
308         char* temp_text = NULL;
309         if (NULL == result_text) {
310                 temp_text = strdup("#NULL");
311         } else {
312                 temp_text = strdup(result_text);
313         }
314
315         int ret = vc_db_insert_result(temp_text, event, msg, vc_cmd_list, exclusive);
316         if (0 != ret) {
317                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret);
318         }
319         SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save result command file");
320
321         if (NULL != temp_text) {
322                 free(temp_text);
323                 temp_text = NULL;
324         }
325
326         return ret;
327 }
328
329 int vc_info_parser_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive)
330 {
331         if (NULL == result_text || NULL == event || NULL == vc_cmd_list) {
332                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Input parameter is NULL");
333                 return -1;
334         }
335
336         char* temp_text = NULL;
337         int ret = vc_db_get_result(&temp_text, event, result_message, pid, vc_cmd_list, exclusive);
338         if (0 != ret) {
339                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret);
340         }
341
342         if (NULL == temp_text || !strcmp(temp_text, "#NULL")) {
343                 *result_text = NULL;
344         } else {
345                 *result_text = strdup(temp_text);
346         }
347
348         if (NULL != temp_text) {
349                 free(temp_text);
350                 temp_text = NULL;
351         }
352
353         return ret;
354 }
355
356 int vc_info_parser_unset_result(bool exclusive)
357 {
358         int ret = 0;
359         ret = vc_db_delete_table(VC_RESULT_TABLE);
360         if (0 != ret) {
361                 SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to delete result table");
362         }
363         return ret;
364 }
365
366 static int __is_symbolic_link(const char* path, bool* is_symbolic)
367 {
368         extern int errno;
369         int ret = VC_ERROR_NONE;
370         *is_symbolic = true;
371         char real_path[PATH_MAX];
372         SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] path: %s ", path);
373         if (realpath(path, real_path) != NULL) {
374                 if (strncmp(path, real_path, strlen(path) + 1) == 0) {
375                         SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] %s is real file, not symbolic link", path);
376                         *is_symbolic = false;
377                 } else {
378                         char current_working_directory[PATH_MAX];
379                         char temp_path[PATH_MAX];
380                         if (getcwd(current_working_directory, PATH_MAX)) {
381                                 if (strlen(current_working_directory) + strlen(path) <= PATH_MAX) {
382                                         snprintf(temp_path, PATH_MAX, "%s/%s", current_working_directory, path);
383                                         if (strncmp(temp_path, real_path, strlen(temp_path) + 1) == 0) {
384                                                 SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] %s is real file, not symbolic link", path);
385                                                 *is_symbolic = false;
386                                         }
387                                 }
388                         }
389                 }
390
391                 if (*is_symbolic == true)
392                         SLOG(LOG_ERROR, vc_info_tag(), "[INFO] %s is symbolic link", path);
393                 return VC_ERROR_NONE;
394         } else {
395                 *is_symbolic = false;
396                 if (errno == ENOENT) {
397                         SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] No such file or directory: %s", path);
398                         return VC_ERROR_OPERATION_REJECTED;
399                 } else {
400                         SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] error is %d", errno);
401                         return VC_ERROR_OPERATION_FAILED;
402                 }
403         }
404         return ret;
405 }
406
407 int vc_info_parser_set_nlu_result(const char* nlu_result)
408 {
409         if (NULL == nlu_result) {
410                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] nlu result is NULL");
411                 return -1;
412         }
413
414         if (0 != remove(VC_RUNTIME_INFO_NLU_RESULT)) {
415                 SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_NLU_RESULT);
416         }
417
418         SLOG(LOG_DEBUG, vc_info_tag(), "[RESULT] %s", nlu_result);
419
420         FILE* fp = NULL;
421         int write_size = -1;
422
423         bool is_symbolic = true;
424         int ret = __is_symbolic_link(VC_RUNTIME_INFO_NLU_RESULT, &is_symbolic);
425         if (is_symbolic || VC_ERROR_OPERATION_FAILED == ret) {
426                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file, it is symbolic link : %s", VC_RUNTIME_INFO_NLU_RESULT);
427                 return -1;
428         }
429
430         fp = fopen(VC_RUNTIME_INFO_NLU_RESULT, "w+");
431         if (NULL == fp) {
432                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file %s", VC_RUNTIME_INFO_NLU_RESULT);
433                 return -1;
434         }
435
436         /* Write size */
437         fprintf(fp, "size(%d)\n", (int)strlen(nlu_result));
438
439         write_size = fwrite(nlu_result, 1, strlen(nlu_result), fp);
440         fclose(fp);
441
442         if (0 >= write_size) {
443                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to write file");
444                 return -1;
445         }
446
447         if (0 != __vc_info_parser_set_file_mode(VC_RUNTIME_INFO_NLU_RESULT)) {
448                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_NLU_RESULT);
449         }
450
451         SLOG(LOG_DEBUG, vc_info_tag(), "[SUCCESS] Write file (%s) size (%zu)", VC_RUNTIME_INFO_NLU_RESULT, strlen(nlu_result));
452
453         return 0;
454 }
455
456 int vc_info_parser_get_nlu_result(char** nlu_result)
457 {
458         if (NULL == nlu_result) {
459                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] nlu_result is NULL");
460                 return -1;
461         }
462
463         FILE* fp = NULL;
464         int readn = 0;
465
466         fp = fopen(VC_RUNTIME_INFO_NLU_RESULT, "r");
467         if (NULL == fp) {
468                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file %s", VC_RUNTIME_INFO_NLU_RESULT);
469                 return -1;
470         }
471
472         int ret;
473         ret = fscanf(fp, "size(%d)\n", &readn);
474         if (ret <= 0) {
475                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to get buffer size");
476                 fclose(fp);
477                 return -1;
478         }
479
480         SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] buffer size (%d)", readn);
481         if (10000000 < readn || 0 > readn) {
482                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Invalid buffer size");
483                 fclose(fp);
484                 return -1;
485         }
486         int tmp_readn = readn + 10;
487
488         *nlu_result = (char*)calloc(tmp_readn, sizeof(char));
489         if (NULL == *nlu_result) {
490                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Out of memory");
491                 fclose(fp);
492                 return -1;
493         }
494
495         readn = fread(*nlu_result, 1, readn, fp);
496         fclose(fp);
497
498         SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] Read buffer (%d)", readn);
499
500         /* remove(VC_RUNTIME_INFO_NLU_RESULT); */
501
502         return 0;
503 }
504
505 int vc_info_parser_get_result_pid_list(GSList** pid_list, const char* result)
506 {
507         int ret = vc_db_get_result_pid_list(result, pid_list);
508         if (0 != ret) {
509                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to delete result table");
510                 return -1;
511         }
512         return 0;
513 }
514
515 int vc_info_parser_set_client_info(GSList* client_info_list)
516 {
517         if (0 >= g_slist_length(client_info_list)) {
518                 SLOG(LOG_WARN, vc_info_tag(), "[WARNING] client list is empty");
519                 return 0;
520         }
521
522         /* Remove file */
523         if (0 != remove(VC_RUNTIME_INFO_CLIENT)) {
524                 SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_CLIENT);
525         }
526
527         xmlDocPtr doc;
528         xmlNodePtr root_node;
529         xmlNodePtr client_node;
530         xmlNodePtr tmp_node;
531
532         doc = xmlNewDoc((const xmlChar*)"1.0");
533         doc->encoding = (const xmlChar*)"utf-8";
534         doc->charset = 1;
535
536         root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_BASE_TAG);
537         xmlDocSetRootElement(doc, root_node);
538
539         GSList *iter = NULL;
540         vc_client_info_s *client = NULL;
541
542         int i;
543         int count = g_slist_length(client_info_list);
544         iter = g_slist_nth(client_info_list, 0);
545
546         SLOG(LOG_DEBUG, vc_info_tag(), "client count : %d", count);
547         char temp[16] = {0, };
548
549         for (i = 0; i < count; i++) {
550                 if (NULL == iter)
551                         break;
552
553                 client = iter->data;
554
555                 if (NULL != client) {
556                         SLOG(LOG_DEBUG, vc_info_tag(), "[%dth] pid(%d) fgcmd(%d) bgcmd(%d) excmd(%d)",
557                                  i, client->pid, client->fg_cmd, client->bg_cmd, client->exclusive_cmd);
558
559                         /* Make new client node */
560                         client_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_CLIENT);
561
562                         memset(temp, 0, 16);
563                         snprintf(temp, 16, "%d", client->pid);
564
565                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_PID);
566                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
567                         xmlAddChild(client_node, tmp_node);
568
569                         memset(temp, 0, 16);
570                         snprintf(temp, 16, "%d", client->fg_cmd);
571
572                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_FGCMD);
573                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
574                         xmlAddChild(client_node, tmp_node);
575
576                         memset(temp, 0, 16);
577                         snprintf(temp, 16, "%d", client->bg_cmd);
578
579                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_BGCMD);
580                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
581                         xmlAddChild(client_node, tmp_node);
582
583                         memset(temp, 0, 16);
584                         snprintf(temp, 16, "%d", client->exclusive_cmd);
585
586                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_EXCMD);
587                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
588                         xmlAddChild(client_node, tmp_node);
589
590                         xmlAddChild(root_node, client_node);
591                 }
592                 iter = g_slist_next(iter);
593         }
594
595         int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_CLIENT, doc, 1);
596         /*xmlFreeDoc(doc); */
597         if (0 >= ret) {
598                 SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save client file : %d", ret);
599                 return -1;
600         }
601
602         SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save client file");
603
604         return 0;
605 }
606
607 int vc_info_parser_get_client_info(GSList** client_info_list)
608 {
609         xmlDocPtr doc = NULL;
610         xmlNodePtr cur = NULL;
611         xmlChar *key;
612
613         doc = xmlParseFile(VC_RUNTIME_INFO_CLIENT);
614         if (doc == NULL) {
615                 SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_CLIENT);
616                 return -1;
617         }
618
619         cur = xmlDocGetRootElement(doc);
620         if (cur == NULL) {
621                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
622                 xmlFreeDoc(doc);
623                 return -1;
624         }
625
626         if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CLIENT_BASE_TAG)) {
627                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CLIENT_BASE_TAG);
628                 xmlFreeDoc(doc);
629                 return -1;
630         }
631
632         cur = cur->xmlChildrenNode;
633         if (cur == NULL) {
634                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
635                 xmlFreeDoc(doc);
636                 return -1;
637         }
638
639         GSList* temp_client_list = NULL;
640
641         while (cur != NULL) {
642                 cur = cur->next;
643
644                 if (NULL == cur) {
645                         break;
646                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
647                         continue;
648                 }
649
650                 xmlNodePtr client_node = NULL;
651                 client_node = cur->xmlChildrenNode;
652                 client_node = client_node->next;
653
654                 vc_client_info_s *client = NULL;
655                 client = (vc_client_info_s*)calloc(1, sizeof(vc_client_info_s));
656
657                 if (NULL == client) {
658                         SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
659
660                         if (NULL != temp_client_list) {
661                                 g_slist_free_full(temp_client_list, free);
662                                 temp_client_list = NULL;
663                         }
664                         xmlFreeDoc(doc);
665                         return -1;
666                 }
667
668                 /* PID */
669                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_PID)) {
670                         key = xmlNodeGetContent(client_node);
671                         if (NULL != key) {
672                                 SLOG(LOG_DEBUG, vc_info_tag(), "pid : %s", (char *)key);
673                                 client->pid = atoi((char*)key);
674                                 xmlFree(key);
675                         } else {
676                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_PID);
677                                 free(client);
678                                 break;
679                         }
680                 }
681
682                 client_node = client_node->next;
683                 client_node = client_node->next;
684
685                 /* Foreground command */
686                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_FGCMD)) {
687                         key = xmlNodeGetContent(client_node);
688                         if (NULL != key) {
689                                 SLOG(LOG_DEBUG, vc_info_tag(), "fgcmd : %s", (char *)key);
690                                 client->fg_cmd = atoi((char*)key);
691                                 xmlFree(key);
692                         } else {
693                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_FGCMD);
694                                 free(client);
695                                 break;
696                         }
697                 }
698
699                 client_node = client_node->next;
700                 client_node = client_node->next;
701
702                 /* Background command */
703                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_BGCMD)) {
704                         key = xmlNodeGetContent(client_node);
705                         if (NULL != key) {
706                                 SLOG(LOG_DEBUG, vc_info_tag(), "bgcmd : %s", (char *)key);
707                                 client->bg_cmd = atoi((char*)key);
708                                 xmlFree(key);
709                         } else {
710                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_BGCMD);
711                                 free(client);
712                                 break;
713                         }
714                 }
715
716                 client_node = client_node->next;
717                 client_node = client_node->next;
718
719                 /* Text */
720                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) {
721                         key = xmlNodeGetContent(client_node);
722                         if (NULL != key) {
723                                 SLOG(LOG_DEBUG, vc_info_tag(), "excmd : %s", (char *)key);
724                                 client->exclusive_cmd = atoi((char*)key);
725                                 xmlFree(key);
726                         } else {
727                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT);
728                                 free(client);
729                                 break;
730                         }
731                 }
732
733                 temp_client_list = g_slist_append(temp_client_list, client);
734         }
735
736         xmlFreeDoc(doc);
737
738         *client_info_list = temp_client_list;
739
740         return 0;
741 }
742
743 int __vc_cmd_parser_print_commands(GSList* cmd_list)
744 {
745         int count = g_slist_length(cmd_list);
746         int i ;
747         GSList *iter = NULL;
748         vc_cmd_s *cmd;
749
750         iter = g_slist_nth(cmd_list, 0);
751
752         for (i = 0; i < count; i++) {
753                 if (NULL == iter)
754                         break;
755
756                 cmd = iter->data;
757
758                 if (NULL == cmd) {
759                         SLOG(LOG_WARN, vc_info_tag(), "[WARNING] NULL data from command list");
760                         iter = g_slist_next(iter);
761                         continue;
762                 }
763
764                 SLOG(LOG_DEBUG, vc_info_tag(), "  [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Command(%s) Param(%s), Appid(%s), Invocation(%s), Fixed(%s)",
765                          i, cmd, cmd->pid, cmd->id, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed);
766
767                 iter = g_slist_next(iter);
768         }
769
770         return 0;
771 }