change temp_path's length
[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*2];
380                         if (getcwd(current_working_directory, PATH_MAX)) {
381                                 if (strlen(current_working_directory) + strlen(path) <= PATH_MAX*2) {
382                                         snprintf(temp_path, PATH_MAX*2, "%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
534         root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_BASE_TAG);
535         xmlDocSetRootElement(doc, root_node);
536
537         GSList *iter = NULL;
538         vc_client_info_s *client = NULL;
539
540         int i;
541         int count = g_slist_length(client_info_list);
542         iter = g_slist_nth(client_info_list, 0);
543
544         SLOG(LOG_DEBUG, vc_info_tag(), "client count : %d", count);
545         char temp[16] = {0, };
546
547         for (i = 0; i < count; i++) {
548                 if (NULL == iter)
549                         break;
550
551                 client = iter->data;
552
553                 if (NULL != client) {
554                         SLOG(LOG_DEBUG, vc_info_tag(), "[%dth] pid(%d) fgcmd(%d) bgcmd(%d) excmd(%d)",
555                                  i, client->pid, client->fg_cmd, client->bg_cmd, client->exclusive_cmd);
556
557                         /* Make new client node */
558                         client_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_CLIENT);
559
560                         memset(temp, 0, 16);
561                         snprintf(temp, 16, "%d", client->pid);
562
563                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_PID);
564                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
565                         xmlAddChild(client_node, tmp_node);
566
567                         memset(temp, 0, 16);
568                         snprintf(temp, 16, "%d", client->fg_cmd);
569
570                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_FGCMD);
571                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
572                         xmlAddChild(client_node, tmp_node);
573
574                         memset(temp, 0, 16);
575                         snprintf(temp, 16, "%d", client->bg_cmd);
576
577                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_BGCMD);
578                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
579                         xmlAddChild(client_node, tmp_node);
580
581                         memset(temp, 0, 16);
582                         snprintf(temp, 16, "%d", client->exclusive_cmd);
583
584                         tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CLIENT_EXCMD);
585                         xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
586                         xmlAddChild(client_node, tmp_node);
587
588                         xmlAddChild(root_node, client_node);
589                 }
590                 iter = g_slist_next(iter);
591         }
592
593         int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_CLIENT, doc, 1);
594         /*xmlFreeDoc(doc); */
595         if (0 >= ret) {
596                 SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save client file : %d", ret);
597                 return -1;
598         }
599
600         SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save client file");
601
602         return 0;
603 }
604
605 int vc_info_parser_get_client_info(GSList** client_info_list)
606 {
607         xmlDocPtr doc = NULL;
608         xmlNodePtr cur = NULL;
609         xmlChar *key;
610
611         doc = xmlParseFile(VC_RUNTIME_INFO_CLIENT);
612         if (doc == NULL) {
613                 SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_CLIENT);
614                 return -1;
615         }
616
617         cur = xmlDocGetRootElement(doc);
618         if (cur == NULL) {
619                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
620                 xmlFreeDoc(doc);
621                 return -1;
622         }
623
624         if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CLIENT_BASE_TAG)) {
625                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CLIENT_BASE_TAG);
626                 xmlFreeDoc(doc);
627                 return -1;
628         }
629
630         cur = cur->xmlChildrenNode;
631         if (cur == NULL) {
632                 SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
633                 xmlFreeDoc(doc);
634                 return -1;
635         }
636
637         GSList* temp_client_list = NULL;
638
639         while (cur != NULL) {
640                 cur = cur->next;
641
642                 if (NULL == cur) {
643                         break;
644                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
645                         continue;
646                 }
647
648                 xmlNodePtr client_node = NULL;
649                 client_node = cur->xmlChildrenNode;
650                 client_node = client_node->next;
651
652                 vc_client_info_s *client = NULL;
653                 client = (vc_client_info_s*)calloc(1, sizeof(vc_client_info_s));
654
655                 if (NULL == client) {
656                         SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
657
658                         if (NULL != temp_client_list) {
659                                 g_slist_free_full(temp_client_list, free);
660                                 temp_client_list = NULL;
661                         }
662                         xmlFreeDoc(doc);
663                         return -1;
664                 }
665
666                 /* PID */
667                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_PID)) {
668                         key = xmlNodeGetContent(client_node);
669                         if (NULL != key) {
670                                 SLOG(LOG_DEBUG, vc_info_tag(), "pid : %s", (char *)key);
671                                 client->pid = atoi((char*)key);
672                                 xmlFree(key);
673                         } else {
674                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_PID);
675                                 free(client);
676                                 break;
677                         }
678                 }
679
680                 client_node = client_node->next;
681                 client_node = client_node->next;
682
683                 /* Foreground command */
684                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_FGCMD)) {
685                         key = xmlNodeGetContent(client_node);
686                         if (NULL != key) {
687                                 SLOG(LOG_DEBUG, vc_info_tag(), "fgcmd : %s", (char *)key);
688                                 client->fg_cmd = atoi((char*)key);
689                                 xmlFree(key);
690                         } else {
691                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_FGCMD);
692                                 free(client);
693                                 break;
694                         }
695                 }
696
697                 client_node = client_node->next;
698                 client_node = client_node->next;
699
700                 /* Background command */
701                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_BGCMD)) {
702                         key = xmlNodeGetContent(client_node);
703                         if (NULL != key) {
704                                 SLOG(LOG_DEBUG, vc_info_tag(), "bgcmd : %s", (char *)key);
705                                 client->bg_cmd = atoi((char*)key);
706                                 xmlFree(key);
707                         } else {
708                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_BGCMD);
709                                 free(client);
710                                 break;
711                         }
712                 }
713
714                 client_node = client_node->next;
715                 client_node = client_node->next;
716
717                 /* Text */
718                 if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) {
719                         key = xmlNodeGetContent(client_node);
720                         if (NULL != key) {
721                                 SLOG(LOG_DEBUG, vc_info_tag(), "excmd : %s", (char *)key);
722                                 client->exclusive_cmd = atoi((char*)key);
723                                 xmlFree(key);
724                         } else {
725                                 SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT);
726                                 free(client);
727                                 break;
728                         }
729                 }
730
731                 temp_client_list = g_slist_append(temp_client_list, client);
732         }
733
734         xmlFreeDoc(doc);
735
736         *client_info_list = temp_client_list;
737
738         return 0;
739 }
740
741 int __vc_cmd_parser_print_commands(GSList* cmd_list)
742 {
743         int count = g_slist_length(cmd_list);
744         int i ;
745         GSList *iter = NULL;
746         vc_cmd_s *cmd;
747
748         iter = g_slist_nth(cmd_list, 0);
749
750         for (i = 0; i < count; i++) {
751                 if (NULL == iter)
752                         break;
753
754                 cmd = iter->data;
755
756                 if (NULL == cmd) {
757                         SLOG(LOG_WARN, vc_info_tag(), "[WARNING] NULL data from command list");
758                         iter = g_slist_next(iter);
759                         continue;
760                 }
761
762                 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)",
763                          i, cmd, cmd->pid, cmd->id, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed);
764
765                 iter = g_slist_next(iter);
766         }
767
768         return 0;
769 }