Update the liveinfo
[apps/livebox/data-provider-master.git] / util_liveinfo / src / liveinfo.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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 <stdio.h>
18 #include <unistd.h>
19 #include <getopt.h>
20 #include <errno.h>
21 #include <libgen.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <termios.h>
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 #include <packet.h>
31 #include <com-core_packet.h>
32 #include <com-core.h>
33
34 #include <livebox-service.h>
35
36 #include <Ecore.h>
37
38 #include "liveinfo.h"
39 #include "node.h"
40
41 #define PROMPT "liveinfo "
42
43 struct package {
44         int primary;
45         char *pkgid;
46
47         int pid;
48         char *slavename;
49         char *abi;
50         int refcnt;
51         int fault_count;
52         int inst_count;
53 };
54
55 struct instance {
56         char *id;
57         char *cluster;
58         char *category;
59         double period;
60         char *state;
61         int width;
62         int height;
63 };
64
65 struct slave {
66         int pid;
67         char *pkgname;
68         char *abi;
69         int secured;
70         int refcnt;
71         int fault_count;
72         char *state;
73         int loaded_inst;
74         int loaded_pkg;
75         double ttl;
76 };
77
78 enum command {
79         NOP,
80         PKG_LIST,
81         INST_LIST,
82         SLAVE_LIST,     
83         INST_CTRL,
84         SLAVE_CTRL,
85         MASTER_CTRL,
86 };
87
88 static struct info {
89         int fifo_handle;
90         int fd;
91         Ecore_Fd_Handler *fd_handler;
92         Ecore_Fd_Handler *in_handler;
93
94         struct node *rootdir;
95         struct node *curdir;
96         struct node *targetdir;
97
98         enum command cmd;
99
100         int input_fd;
101         int verbose;
102
103         int age;
104 } s_info = {
105         .fifo_handle = -EINVAL,
106         .fd = -EINVAL,
107         .fd_handler = NULL,
108         .in_handler = NULL,
109         .rootdir = NULL,
110         .curdir = NULL,
111         .targetdir = NULL,
112         .cmd = NOP,
113         .input_fd = STDIN_FILENO,
114         .verbose = 0,
115         .age = 0,
116 };
117
118 char *optarg;
119 int errno;
120 int optind;
121 int optopt;
122 int opterr;
123
124 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler);
125
126 static Eina_Bool process_line_cb(void *data)
127 {
128         input_cb(NULL, NULL);
129         return ECORE_CALLBACK_CANCEL;
130 }
131
132 static inline void prompt(const char *cmdline)
133 {
134         char *path;
135
136         if (s_info.input_fd != STDIN_FILENO) {
137                 /* To prevent recursive call, add function to the main loop (idler) */
138                 ecore_idler_add(process_line_cb, NULL);
139                 return;
140         }
141
142         path = node_to_abspath(s_info.curdir);
143         printf(PROMPT"%s # %s", path, cmdline ? cmdline : "");
144         free(path);
145 }
146
147 static void provider_del_cb(struct node *node)
148 {
149         struct slave *info;
150
151         info = node_data(node);
152         if (!info)
153                 return;
154
155         free(info->pkgname);
156         free(info->abi);
157         free(info->state);
158         free(info);
159 }
160
161 static void package_del_cb(struct node *node)
162 {
163         struct package *info;
164
165         info = node_data(node);
166         if (!info)
167                 return;
168
169         free(info->pkgid);
170         free(info->slavename);
171         free(info->abi);
172         free(info);
173 }
174
175 static void inst_del_cb(struct node *node)
176 {
177         struct instance *info;
178
179         info = node_data(node);
180         if (!info)
181                 return;
182
183         free(info->id);
184         free(info->cluster);
185         free(info->category);
186         free(info->state);
187         free(info);
188 }
189
190 static inline void ls(void)
191 {
192         struct node *node;
193         int cnt = 0;
194         int is_package;
195         int is_provider;
196         int is_instance;
197         struct node *next_node;
198
199         if (!(node_mode(s_info.targetdir) & NODE_READ)) {
200                 printf("Access denied\n");
201                 return;
202         }
203
204         is_package = node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "package");
205         is_provider = !is_package && node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "provider");
206         is_instance = !is_package && !is_provider && node_parent(s_info.targetdir) && node_name(node_parent(s_info.targetdir)) && !strcmp(node_name(node_parent(s_info.targetdir)), "package");
207
208         node = node_child(s_info.targetdir);
209         while (node) {
210                 if (is_package) {
211                         struct package *info;
212
213                         next_node = node_next_sibling(node);
214                         if (node_age(node) != s_info.age) {
215                                 node_delete(node, package_del_cb);
216                                 node = next_node;
217                                 continue;
218                         }
219
220                         info = node_data(node);
221                         printf(" %3d %20s %5s ", info->inst_count, info->slavename ? info->slavename : "-", info->abi ? info->abi : "-");
222                 } else if (is_provider) {
223                         struct slave *info;
224
225                         next_node = node_next_sibling(node);
226                         if (node_age(node) != s_info.age) {
227                                 node_delete(node, provider_del_cb);
228                                 node = next_node;
229                                 continue;
230                         }
231
232                         info = node_data(node);
233                         printf(" %3d %5s %5.2f ", info->loaded_inst, info->abi ? info->abi : "-", info->ttl);
234                 } else if (is_instance) {
235                         struct instance *info;
236                         struct stat stat;
237                         char buf[4096];
238
239                         next_node = node_next_sibling(node);
240
241                         if (node_age(node) != s_info.age) {
242                                 node_delete(node, inst_del_cb);
243                                 node = next_node;
244                                 continue;
245                         }
246
247                         info = node_data(node);
248
249                         printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
250                         snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
251                         if (lstat(buf, &stat) < 0)
252                                 printf("%3d ERR ", errno);
253                         else
254                                 printf("%2.2lf KB ", (double)stat.st_size / 1024.0f);
255                 }
256
257                 if (node_type(node) == NODE_DIR)
258                         printf("%s/", node_name(node));
259                 else if (node_type(node) == NODE_FILE)
260                         printf("%s", node_name(node));
261
262                 printf("\n");
263                 node = node_next_sibling(node);
264                 cnt++;
265         }
266
267         printf("Total: %d\n", cnt);
268 }
269
270 static void send_slave_list(void)
271 {
272         struct packet *packet;
273
274         if (s_info.cmd != NOP) {
275                 printf("Previous command is not finished\n");
276                 return;
277         }
278
279         packet = packet_create_noack("slave_list", "d", 0.0f);
280         if (!packet) {
281                 printf("Failed to create a packet\n");
282                 return;
283         }
284
285         com_core_packet_send_only(s_info.fd, packet);
286         packet_destroy(packet);
287         s_info.cmd = SLAVE_LIST;
288         s_info.age++;
289 }
290
291 /*!
292  * var = debug, slave_max_load
293  * cmd = set / get
294  */
295 static void send_command(const char *cmd, const char *var, const char *val)
296 {
297         struct packet *packet;
298
299         if (s_info.cmd != NOP) {
300                 printf("Previous command is not finished\n");
301                 return;
302         }
303
304         packet = packet_create_noack("master_ctrl", "sss", cmd, var, val);
305         com_core_packet_send_only(s_info.fd, packet);
306         packet_destroy(packet);
307         s_info.cmd = MASTER_CTRL;
308         s_info.age++;
309 }
310
311 static void send_pkg_list(void)
312 {
313         struct packet *packet;
314
315         if (s_info.cmd != NOP) {
316                 printf("Previous command is not finished\n");
317                 return;
318         }
319
320         packet = packet_create_noack("pkg_list", "d", 0.0f);
321         if (!packet) {
322                 printf("Failed to create a packet\n");
323                 return;
324         }
325
326         com_core_packet_send_only(s_info.fd, packet);
327         packet_destroy(packet);
328         s_info.cmd = PKG_LIST;
329         s_info.age++;
330 }
331
332 static void send_inst_delete(void)
333 {
334         struct packet *packet;
335         struct node *parent;
336         const char *name;
337         struct instance *inst;
338
339         if (s_info.cmd != NOP) {
340                 printf("Previous command is not finished\n");
341                 return;
342         }
343
344         parent = node_parent(s_info.targetdir);
345         if (!parent) {
346                 printf("Invalid argument\n");
347                 return;
348         }
349
350         if (!node_parent(parent)) {
351                 printf("Invalid argument\n");
352                 return;
353         }
354
355         name = node_name(node_parent(parent));
356         if (!name || strcmp(name, "package")) {
357                 printf("Invalid argument\n");
358                 return;
359         }
360
361         inst = node_data(s_info.targetdir);
362         name = node_name(parent);
363
364         packet = packet_create_noack("pkg_ctrl", "sss", "rminst", name, inst->id);
365         com_core_packet_send_only(s_info.fd, packet);
366         packet_destroy(packet);
367         s_info.cmd = INST_CTRL;
368         s_info.age++;
369 }
370
371 static void send_inst_list(const char *pkgname)
372 {
373         struct packet *packet;
374
375         if (s_info.cmd != NOP) {
376                 printf("Previous command is not finished\n");
377                 return;
378         }
379
380         packet = packet_create_noack("inst_list", "s", pkgname);
381         if (!packet) {
382                 printf("Failed to create a packet\n");
383                 return;
384         }
385
386         com_core_packet_send_only(s_info.fd, packet);
387         packet_destroy(packet);
388         s_info.cmd = INST_LIST;
389         s_info.age++;
390 }
391
392 static inline void help(void)
393 {
394         printf("liveinfo - Livebox utility\n");
395         printf("------------------------------ [Command list] ------------------------------\n");
396         printf("\e[32mcd [PATH] - Change directory\e[0m\n");
397         printf("\e[32mls [ | PATH] - List up content as a file\e[0m\n");
398         printf("\e[32mrm [PKG_ID|INST_ID] - Delete package or instance\e[0m\n");
399         printf("\e[32mcat [FILE] - Open a file to get some detail information\e[0m\n");
400         printf("\e[32mpull [FILE] - Pull given file to host dir\e[0m\n");
401         printf("\e[32mset [debug] [on|off] Set the control variable of master provider\e[0m\n");
402         printf("\e[32mexit - \e[0m\n");
403         printf("\e[32mquit - \e[0m\n");
404         printf("----------------------------------------------------------------------------\n");
405 }
406
407 static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
408 {
409         struct node *parent = data;
410         struct node *node;
411         struct package *info;
412
413         info = calloc(1, sizeof(*info));
414         if (!info) {
415                 printf("Error: %s\n", strerror(errno));
416                 return -ENOMEM;
417         }
418
419         info->pkgid = strdup(appid);
420         if (!info->pkgid) {
421                 printf("Error: %s\n", strerror(errno));
422                 free(info);
423                 return -ENOMEM;
424         }
425
426         info->primary = is_prime;
427
428         node = node_create(parent, lbid, NODE_DIR);
429         if (!node) {
430                 free(info->pkgid);
431                 free(info);
432                 return -ENOMEM;
433         }
434
435         node_set_mode(node, NODE_READ | NODE_EXEC);
436         node_set_data(node, info);
437         return 0;
438 }
439
440 static inline void init_directory(void)
441 {
442         struct node *node;
443         s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
444         if (!s_info.rootdir)
445                 return;
446         node_set_mode(s_info.rootdir, NODE_READ | NODE_EXEC);
447
448         node = node_create(s_info.rootdir, "provider", NODE_DIR);
449         if (!node) {
450                 node_destroy(s_info.rootdir);
451                 s_info.rootdir = NULL;
452                 return;
453         }
454         node_set_mode(node, NODE_READ | NODE_EXEC);
455
456         node = node_create(s_info.rootdir, "package", NODE_DIR);
457         if (!node) {
458                 node_destroy(node_child(s_info.rootdir));
459                 node_destroy(s_info.rootdir);
460                 s_info.rootdir = NULL;
461                 return;
462         }
463         node_set_mode(node, NODE_READ | NODE_EXEC);
464
465         s_info.curdir = s_info.rootdir;
466         livebox_service_get_pkglist(pkglist_cb, node);
467         return;
468 }
469
470 static inline void fini_directory(void)
471 {
472 }
473
474 static inline void do_command(const char *cmd)
475 {
476         char command[256];
477         char argument[4096] = { '\0', };
478
479         if (!strlen(cmd) || *cmd == '#') {
480                 prompt(NULL);
481                 return;
482         }
483
484         if (sscanf(cmd, "%255[^ ] %4095[^\\0]", command, argument) == 2)
485                 cmd = command;
486
487         if (!strcasecmp(cmd, "exit") || !strcasecmp(cmd, "quit")) {
488                 ecore_main_loop_quit();
489         } else if (!strcasecmp(cmd, "set")) {
490                 char variable[4096] = { '0', };
491                 char value[4096] = { '0', };
492
493                 if (sscanf(argument, "%4095[^ ] %4095[^ ]", variable, value) != 2) {
494                         printf("Invalid argument(%s): set [VAR] [VAL]\n", argument);
495                         goto out;
496                 }
497
498                 send_command(cmd, variable, value);
499         } else if (!strcasecmp(cmd, "get")) {
500                 send_command(cmd, argument, "");
501         } else if (!strcasecmp(cmd, "ls")) {
502                 const char *name;
503                 struct node *parent;
504
505                 if (*argument) {
506                         s_info.targetdir = (*argument == '/') ? s_info.rootdir : s_info.curdir;
507                         s_info.targetdir = node_find(s_info.targetdir, argument);
508                 } else {
509                         s_info.targetdir = s_info.curdir;
510                 }
511
512                 if (!s_info.targetdir) {
513                         printf("%s is not exists\n", argument);
514                         goto out;
515                 }
516
517                 name = node_name(s_info.targetdir);
518                 if (name) {
519                         if (!strcmp(name, "package")) {
520                                 if (s_info.cmd == NOP) {
521                                         send_pkg_list();
522                                         return;
523                                 }
524
525                                 printf("Waiting the server response\n");
526                                 goto out;
527                         } else if (!strcmp(name, "provider")) {
528                                 if (s_info.cmd == NOP) {
529                                         send_slave_list();
530                                         return;
531                                 }
532
533                                 printf("Waiting the server response\n");
534                                 goto out;
535                         }
536                 }
537
538                 parent = node_parent(s_info.targetdir);
539                 if (parent && node_name(parent)) {
540                         if (!strcmp(node_name(parent), "package")) {
541                                 if (s_info.cmd != NOP) {
542                                         printf("Waiting the server response\n");
543                                         goto out;
544                                 }
545                                 send_inst_list(name);
546                                 return;
547                         }
548                 }
549
550                 ls();
551         } else if (!strcasecmp(cmd, "cd")) {
552                 if (!*argument)
553                         goto out;
554
555                 if (s_info.cmd != NOP) {
556                         printf("Waiting the server response\n");
557                         goto out;
558                 }
559
560                 s_info.targetdir = (*argument == '/') ? s_info.rootdir : s_info.curdir;
561                 s_info.targetdir = node_find(s_info.targetdir, argument);
562                 if (!s_info.targetdir) {
563                         printf("%s is not exists\n", argument);
564                         goto out;
565                 }
566
567                 if (node_type(s_info.targetdir) != NODE_DIR) {
568                         printf("Unable change directory to %s\n", argument);
569                         goto out;
570                 }
571
572                 if (!(node_mode(s_info.targetdir) & NODE_EXEC)) {
573                         printf("Access denied %s\n", argument);
574                         goto out;
575                 }
576
577                 s_info.curdir = s_info.targetdir;
578         } else if (!strcasecmp(cmd, "rm")) {
579                 if (!*argument)
580                         goto out;
581
582                 if (s_info.cmd != NOP) {
583                         printf("Waiting the server response\n");
584                         goto out;
585                 }
586
587                 s_info.targetdir = (*argument == '/') ? s_info.rootdir : s_info.curdir;
588                 s_info.targetdir = node_find(s_info.targetdir, argument);
589                 if (!s_info.targetdir) {
590                         printf("%s is not exists\n", argument);
591                         goto out;
592                 }
593
594                 if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
595                         printf("Access denied %s\n", argument);
596                         goto out;
597                 }
598
599                 send_inst_delete();
600         } else if (!strcasecmp(cmd, "help")) {
601                 help();
602         } else {
603                 printf("Unknown command - \"help\"\n");
604         }
605
606 out:
607         prompt(NULL);
608         return;
609 }
610
611 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
612 {
613         static int idx = 0;
614         static char cmd_buffer[256];
615         char ch;
616         int fd;
617         int ret;
618
619         if (fd_handler) {
620                 fd = ecore_main_fd_handler_fd_get(fd_handler);
621                 if (fd < 0) {
622                         printf("FD is not valid: %d\n", fd);
623                         return ECORE_CALLBACK_CANCEL;
624                 }
625         } else {
626                 fd = s_info.input_fd;
627         }
628
629         /*!
630          * \note
631          * Using this routine, we can implement the command recommend algorithm.
632          * When a few more characters are matched with history of command, we can show it to user
633          * Then the user will choose one or write new command
634          */
635
636         /* Silly.. Silly */
637         while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) {
638                 switch (ch) {
639                 case 0x08: /* BKSP */
640                         cmd_buffer[idx] = '\0';
641                         if (idx > 0) {
642                                 idx--;
643                                 cmd_buffer[idx] = ' ';
644                                 putc('\r', stdout);
645                                 prompt(cmd_buffer);
646                         }
647
648                         cmd_buffer[idx] = '\0';
649                         putc('\r', stdout);
650                         prompt(cmd_buffer);
651                         break;
652                 case '\n':
653                 case '\r':
654                         cmd_buffer[idx] = '\0';
655                         idx = 0;
656                         if (s_info.input_fd == STDIN_FILENO || s_info.verbose)
657                                 putc((int)'\n', stdout);
658                         do_command(cmd_buffer);
659                         memset(cmd_buffer, 0, sizeof(cmd_buffer));
660
661                         /* Make a main loop processing for command handling */
662                         return ECORE_CALLBACK_RENEW;
663                 default:
664                         cmd_buffer[idx++] = ch;
665
666                         if (s_info.input_fd == STDIN_FILENO || s_info.verbose)
667                                 putc((int)ch, stdout);
668
669                         if (idx == sizeof(cmd_buffer) - 1) {
670                                 cmd_buffer[idx] = '\0';
671                                 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
672                                 idx = 0;
673                         }
674                         break;
675                 }
676         }
677
678         if (ret < 0 && !fd_handler)
679                 ecore_main_loop_quit();
680
681         return ECORE_CALLBACK_RENEW;
682 }
683
684 static void processing_line_buffer(const char *buffer)
685 {
686         int pid;
687         char slavename[256];
688         char pkgname[256];
689         char abi[256];
690         char inst_id[4096];
691         char cluster[256];
692         char category[256];
693         char state[10];
694         int refcnt;
695         int fault_count;
696         int list_count;
697         int loaded_inst;
698         int loaded_pkg;
699         double ttl;
700         int secured;
701         double period;
702         int width;
703         int height;
704         struct node *node;
705         struct package *pkginfo;
706         struct instance *instinfo;
707         struct slave *slaveinfo;
708         int i;
709
710         switch (s_info.cmd) {
711         case PKG_LIST:
712                 if (sscanf(buffer, "%d %[^ ] %[^ ] %[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
713                         printf("Invalid format : [%s]\n", buffer);
714                         return;
715                 }
716
717                 node = node_find(s_info.targetdir, pkgname);
718                 if (!node) {
719                         pkginfo = malloc(sizeof(*pkginfo));
720                         if (!pkginfo) {
721                                 printf("Error: %s\n", strerror(errno));
722                                 return;
723                         }
724
725                         pkginfo->pkgid = strdup("conf.file");
726                         if (!pkginfo->pkgid)
727                                 printf("Error: %s\n", strerror(errno));
728
729                         pkginfo->primary = 1;
730
731                         node = node_create(s_info.targetdir, pkgname, NODE_DIR);
732                         if (!node) {
733                                 free(pkginfo->pkgid);
734                                 free(pkginfo);
735                                 printf("Failed to create a new node (%s)\n", pkgname);
736                                 return;
737                         }
738
739                         node_set_mode(node, NODE_READ | NODE_EXEC);
740                         node_set_data(node, pkginfo);
741                 } else {
742                         pkginfo = node_data(node);
743
744                         free(pkginfo->slavename);
745                         free(pkginfo->abi);
746
747                         pkginfo->slavename = NULL;
748                         pkginfo->abi = NULL;
749                 }
750
751                 node_set_age(node, s_info.age);
752
753                 pkginfo->slavename = strdup(slavename);
754                 if (!pkginfo->slavename)
755                         printf("Error: %s\n", strerror(errno));
756
757                 pkginfo->abi = strdup(abi);
758                 if (!pkginfo->abi)
759                         printf("Error: %s\n", strerror(errno));
760
761                 pkginfo->pid = pid;
762                 pkginfo->refcnt = refcnt;
763                 pkginfo->fault_count = fault_count;
764                 pkginfo->inst_count = list_count;
765                 break;
766         case SLAVE_LIST:
767                 if (sscanf(buffer, "%d %[^ ] %[^ ] %[^ ] %d %d %d %[^ ] %d %d %lf", &pid, slavename, pkgname, abi, &secured, &refcnt, &fault_count, state, &loaded_inst, &loaded_pkg, &ttl) != 11) {
768                         printf("Invalid format : [%s]\n", buffer);
769                         return;
770                 }
771                 node = node_find(s_info.targetdir, slavename);
772                 if (!node) {
773                         slaveinfo = calloc(1, sizeof(*slaveinfo));
774                         if (!slaveinfo) {
775                                 printf("Error: %s\n", strerror(errno));
776                                 return;
777                         }
778
779                         node = node_create(s_info.targetdir, slavename, NODE_DIR);
780                         if (!node) {
781                                 free(slaveinfo);
782                                 return;
783                         }
784
785                         node_set_mode(node, NODE_READ | NODE_EXEC);
786                         node_set_data(node, slaveinfo);
787                 } else {
788                         slaveinfo = node_data(node);
789                 }
790
791                 node_set_age(node, s_info.age);
792
793                 free(slaveinfo->pkgname);
794                 free(slaveinfo->abi);
795                 free(slaveinfo->state);
796
797                 slaveinfo->pkgname = strdup(pkgname);
798                 if (!slaveinfo->pkgname)
799                         printf("Error: %s\n", strerror(errno));
800
801                 slaveinfo->abi = strdup(abi);
802                 if (!slaveinfo->abi)
803                         printf("Error: %s\n", strerror(errno));
804
805                 slaveinfo->state = strdup(state);
806                 if (!slaveinfo->state)
807                         printf("Error: %s\n", strerror(errno));
808
809                 slaveinfo->pid = pid;
810                 slaveinfo->secured = secured;
811                 slaveinfo->refcnt = refcnt;
812                 slaveinfo->fault_count = fault_count;
813                 slaveinfo->loaded_inst = loaded_inst;
814                 slaveinfo->loaded_pkg = loaded_pkg;
815                 slaveinfo->ttl = ttl;
816                 break;
817         case INST_LIST:
818                 if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
819                         printf("Invalid format : [%s]\n", buffer);
820                         return;
821                 }
822
823                 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
824                 i += (inst_id[i] == '/');
825
826                 node = node_find(s_info.targetdir, inst_id + i);
827                 if (!node) {
828                         instinfo = calloc(1, sizeof(*instinfo));
829                         if (!instinfo) {
830                                 printf("Error: %s\n", strerror(errno));
831                                 return;
832                         }
833
834                         node = node_create(s_info.targetdir, inst_id + i, NODE_FILE);
835                         if (!node) {
836                                 free(instinfo);
837                                 return;
838                         }
839
840                         node_set_mode(node, NODE_READ | NODE_WRITE);
841                         node_set_data(node, instinfo);
842                 } else {
843                         instinfo = node_data(node);
844                 }
845
846                 node_set_age(node, s_info.age);
847
848                 free(instinfo->id);
849                 free(instinfo->cluster);
850                 free(instinfo->category);
851                 free(instinfo->state);
852
853                 instinfo->id = strdup(inst_id);
854                 if (!instinfo->id)
855                         printf("Error: %s\n", strerror(errno));
856
857                 instinfo->cluster = strdup(cluster);
858                 if (!instinfo->cluster)
859                         printf("Error: %s\n", strerror(errno));
860
861                 instinfo->category = strdup(category);
862                 if (!instinfo->category)
863                         printf("Error: %s\n", strerror(errno));
864
865                 instinfo->state = strdup(state);
866                 if (!instinfo->state)
867                         printf("Error: %s\n", strerror(errno));
868
869                 instinfo->period = period;
870                 instinfo->width = width;
871                 instinfo->height = height;
872                 break;
873         case INST_CTRL:
874                 sscanf(buffer, "%d", &i);
875                 printf("%s\n", strerror(i));
876                 printf("Result: %d\n", i);
877                 break;
878         case SLAVE_CTRL:
879                 sscanf(buffer, "%d", &i);
880                 printf("Result: %d\n", i);
881                 break;
882         case MASTER_CTRL:
883                 sscanf(buffer, "%d", &i);
884                 printf("Result: %d\n", i);
885                 break;
886         default:
887                 break;
888         }
889 }
890
891 static inline void do_line_command(void)
892 {
893         switch (s_info.cmd) {
894         case PKG_LIST:
895                 ls();
896                 break;
897         case INST_LIST:
898                 ls();
899                 break;
900         case SLAVE_LIST:
901                 ls();
902                 break;
903         case INST_CTRL:
904                 break;
905         case SLAVE_CTRL:
906                 break;
907         case MASTER_CTRL:
908                 break;
909         default:
910                 break;
911         }
912         prompt(NULL);
913 }
914
915 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
916 {
917         int fd;
918         static char *line_buffer = NULL;
919         static int line_index = 0;
920         static int bufsz = 256;
921         char ch;
922
923         fd = ecore_main_fd_handler_fd_get(fd_handler);
924         if (fd < 0) {
925                 printf("FD is not valid: %d\n", fd);
926                 return ECORE_CALLBACK_CANCEL;
927         }
928
929         if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
930                 printf("Error: %s\n", strerror(errno));
931                 return ECORE_CALLBACK_CANCEL;
932         }
933
934         if (!line_buffer) {
935                 line_index = 0;
936                 line_buffer = malloc(bufsz);
937                 if (!line_buffer) {
938                         printf("Error: %s\n", strerror(errno));
939                         return ECORE_CALLBACK_CANCEL;
940                 }
941         }       
942
943         if (ch == '\n') { /* End of a line */
944                 line_buffer[line_index] = '\0';
945
946                 if (!strcmp(line_buffer, "EOD")) {
947                         do_line_command();
948                         s_info.cmd = NOP;
949                 } else {
950                         processing_line_buffer(line_buffer);
951                 }
952
953                 free(line_buffer);
954                 line_buffer = NULL;
955                 line_index = 0;
956                 bufsz = 256;
957         } else {
958                 char *new_buf;
959
960                 line_buffer[line_index++] = ch;
961                 if (line_index == bufsz - 1) {
962                         bufsz += 256;
963                         new_buf = realloc(line_buffer, bufsz);
964                         if (!new_buf) {
965                                 printf("Error: %s\n", strerror(errno));
966                                 free(line_buffer);
967                                 line_buffer = 0;
968                                 line_index = 0;
969                                 bufsz = 256;
970                                 return ECORE_CALLBACK_CANCEL;
971                         }
972
973                         line_buffer = new_buf;
974                 }
975         }
976
977         return ECORE_CALLBACK_RENEW;
978 }
979
980 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
981 {
982         const char *fifo_name;
983         int ret;
984
985         if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
986                 printf("Invalid packet\n");
987                 return -EFAULT;
988         }
989
990         if (ret != 0) {
991                 printf("Returns %d\n", ret);
992                 return ret;
993         }
994
995         printf("FIFO: %s\n", fifo_name);
996
997         s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
998         if (s_info.fifo_handle < 0) {
999                 printf("Error: %s\n", strerror(errno));
1000                 s_info.fifo_handle = -EINVAL;
1001                 ecore_main_loop_quit();
1002                 return -EINVAL;
1003         }
1004
1005         s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
1006         if (!s_info.fd_handler) {
1007                 printf("Failed to add a fd handler\n");
1008                 close(s_info.fifo_handle);
1009                 s_info.fifo_handle = -EINVAL;
1010                 ecore_main_loop_quit();
1011                 return -EFAULT;
1012         }
1013
1014         prompt(NULL);
1015
1016         if (s_info.input_fd == STDIN_FILENO) {
1017                 if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0)
1018                         printf("Error: %s\n", strerror(errno));
1019
1020                 s_info.in_handler = ecore_main_fd_handler_add(s_info.input_fd, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
1021                 if (!s_info.in_handler) {
1022                         printf("Failed to add a input handler\n");
1023                         ecore_main_loop_quit();
1024                         return -EFAULT;
1025                 }
1026         }
1027
1028         return 0;
1029 }
1030
1031 static int disconnected_cb(int handle, void *data)
1032 {
1033         printf("Disconnected\n");
1034         ecore_main_loop_quit();
1035         return 0;
1036 }
1037
1038 static int connected_cb(int handle, void *data)
1039 {
1040         struct packet *packet;
1041
1042         printf("Connected\n");
1043
1044         packet = packet_create("liveinfo_hello", "d", 0.0f);
1045         if (!packet) {
1046                 printf("Failed to build a packet for hello\n");
1047                 com_core_packet_client_fini(s_info.fd);
1048                 s_info.fd = -EINVAL;
1049                 return -EFAULT;
1050         }
1051
1052         s_info.fd = handle;
1053
1054         if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
1055                 printf("Failed to send a packet hello\n");
1056                 packet_destroy(packet);
1057                 com_core_packet_client_fini(s_info.fd);
1058                 s_info.fd = -EINVAL;
1059                 return -EFAULT;
1060         }
1061
1062         packet_destroy(packet);
1063         return 0;
1064 }
1065
1066 int main(int argc, char *argv[])
1067 {
1068         struct termios ttystate;
1069         static struct method s_table[] = {
1070                 {
1071                         .cmd = NULL,
1072                         .handler = NULL,
1073                 },
1074         };
1075         static struct option long_options[] = {
1076                 { "batchmode", required_argument, 0, 'b' },
1077                 { "help", no_argument, 0, 'h' },
1078                 { "verbose", required_argument, 0, 'v' },
1079                 { 0, 0, 0, 0 }
1080         };
1081         int option_index;
1082         int c;
1083
1084         do {
1085                 c = getopt_long(argc, argv, "b:hv:", long_options, &option_index);
1086                 switch (c) {
1087                 case 'b':
1088                         if (!optarg || !*optarg) {
1089                                 printf("Invalid argument\n");
1090                                 help();
1091                                 return -EINVAL;
1092                         }
1093
1094                         if (s_info.input_fd != STDIN_FILENO) {
1095                                 /* Close the previously, opened file */
1096                                 close(s_info.input_fd);
1097                         }
1098
1099                         s_info.input_fd = open(optarg, O_RDONLY);
1100                         if (s_info.input_fd < 0) {
1101                                 printf("Unable to access %s (%s)\n", optarg, strerror(errno));
1102                                 return -EIO;
1103                         }
1104                         break;
1105                 case 'h':
1106                         help();
1107                         return 0;
1108                 case 'v':
1109                         if (!optarg || !*optarg) {
1110                                 printf("Invalid argument\n");
1111                                 help();
1112                                 return -EINVAL;
1113                         }
1114
1115                         s_info.verbose = !strcmp(optarg, "true");
1116                         break;
1117                 default:
1118                         break;
1119                 }
1120         } while (c != -1);
1121
1122         ecore_init();
1123         g_type_init();
1124
1125         com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1126         com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1127         livebox_service_init();
1128
1129         s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
1130         if (s_info.fd < 0) {
1131                 printf("Failed to make a connection\n");
1132                 return -EIO;
1133         }
1134
1135         if (s_info.input_fd == STDIN_FILENO) {
1136                 printf("Type your command on below empty line\n");
1137
1138                 if (tcgetattr(s_info.input_fd, &ttystate) < 0) {
1139                         printf("Error: %s\n", strerror(errno));
1140                 } else {
1141                         ttystate.c_lflag &= ~(ICANON | ECHO);
1142                         ttystate.c_cc[VMIN] = 1;
1143
1144                         if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0)
1145                                 printf("Error: %s\n", strerror(errno));
1146                 }
1147         } else {
1148                 printf("Batch mode enabled\n");
1149         }
1150
1151         if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0)
1152                 printf("Error: %s\n", strerror(errno));
1153
1154         init_directory();
1155
1156         ecore_main_loop_begin();
1157
1158         fini_directory();
1159         livebox_service_fini();
1160
1161         if (s_info.fd > 0) {
1162                 com_core_packet_client_fini(s_info.fd);
1163                 s_info.fd = -EINVAL;
1164         }
1165
1166         if (s_info.fd_handler) {
1167                 ecore_main_fd_handler_del(s_info.fd_handler);
1168                 s_info.fd_handler = NULL;
1169         }
1170
1171         if (s_info.input_fd == STDIN_FILENO) {
1172                 ttystate.c_lflag |= ICANON | ECHO;
1173                 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0)
1174                         printf("Error: %s\n", strerror(errno));
1175         } else {
1176                 close(s_info.input_fd);
1177         }
1178
1179         if (s_info.fifo_handle > 0) {
1180                 close(s_info.fifo_handle);
1181                 s_info.fifo_handle = -EINVAL;
1182         }
1183
1184         if (s_info.in_handler) {
1185                 ecore_main_fd_handler_del(s_info.in_handler);
1186                 s_info.in_handler = NULL;
1187         }
1188
1189         ecore_shutdown();
1190         putc((int)'\n', stdout);
1191         return 0;
1192 }
1193
1194 /* End of a file */