20773572fdb5e41f060dc2230de6e53ba3789abc
[apps/livebox/data-provider-master.git] / util_liveinfo / src / liveinfo.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.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/wait.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <termios.h>
27 #include <sys/shm.h>
28 #include <sys/ipc.h>
29
30 #include <X11/Xlib.h>
31 #include <X11/extensions/Xdamage.h>
32 #include <X11/extensions/Xfixes.h>
33 #include <X11/extensions/XShm.h>
34 #include <X11/Xutil.h>
35
36 #include <glib.h>
37 #include <glib-object.h>
38
39 #include <packet.h>
40 #include <com-core_packet.h>
41 #include <com-core.h>
42
43 #include <livebox-service.h>
44
45 #include <Ecore.h>
46
47 #include "liveinfo.h"
48 #include "node.h"
49
50 #define PROMPT "liveinfo "
51
52 struct package {
53         int primary;
54         char *pkgid;
55
56         int pid;
57         char *slavename;
58         char *abi;
59         int refcnt;
60         int fault_count;
61         int inst_count;
62 };
63
64 struct instance {
65         char *id;
66         char *cluster;
67         char *category;
68         double period;
69         char *state;
70         int width;
71         int height;
72 };
73
74 struct slave {
75         int pid;
76         char *pkgname;
77         char *abi;
78         int secured;
79         int refcnt;
80         int fault_count;
81         char *state;
82         int loaded_inst;
83         int loaded_pkg;
84         double ttl;
85 };
86
87 enum command {
88         NOP,
89         PKG_LIST,
90         INST_LIST,
91         SLAVE_LIST,     
92         INST_CTRL,
93         SLAVE_CTRL,
94         MASTER_CTRL,
95 };
96
97 static struct info {
98         int fifo_handle;
99         int fd;
100         Ecore_Fd_Handler *fd_handler;
101         Ecore_Fd_Handler *in_handler;
102
103         struct node *rootdir;
104         struct node *curdir;
105         struct node *targetdir;
106
107         enum command cmd;
108
109         int input_fd;
110         int verbose;
111
112         int age;
113
114         char *history[1024];
115         int history_top;
116         int history_idx;
117
118         struct node *quick_search_node;
119         int quick_idx;
120 } s_info = {
121         .fifo_handle = -EINVAL,
122         .fd = -EINVAL,
123         .fd_handler = NULL,
124         .in_handler = NULL,
125         .rootdir = NULL,
126         .curdir = NULL,
127         .targetdir = NULL,
128         .cmd = NOP,
129         .input_fd = STDIN_FILENO,
130         .verbose = 0,
131         .age = 0,
132         .history = { 0, },
133         .history_top = 0,
134         .history_idx = 0,
135         .quick_search_node = NULL,
136         .quick_idx = 0,
137 };
138
139 char *optarg;
140 int errno;
141 int optind;
142 int optopt;
143 int opterr;
144
145 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler);
146
147 static Eina_Bool process_line_cb(void *data)
148 {
149         input_cb(NULL, NULL);
150         return ECORE_CALLBACK_CANCEL;
151 }
152
153 static void prompt(const char *cmdline)
154 {
155         char *path;
156
157         if (s_info.input_fd != STDIN_FILENO) {
158                 /* To prevent recursive call, add function to the main loop (idler) */
159                 ecore_idler_add(process_line_cb, NULL);
160                 return;
161         }
162
163         path = node_to_abspath(s_info.curdir);
164         printf(PROMPT"%s # %s", path, cmdline ? cmdline : "");
165         free(path);
166 }
167
168 static void provider_del_cb(struct node *node)
169 {
170         struct slave *info;
171
172         info = node_data(node);
173         if (!info) {
174                 return;
175         }
176
177         free(info->pkgname);
178         free(info->abi);
179         free(info->state);
180         free(info);
181 }
182
183 static void package_del_cb(struct node *node)
184 {
185         struct package *info;
186
187         info = node_data(node);
188         if (!info) {
189                 return;
190         }
191
192         free(info->pkgid);
193         free(info->slavename);
194         free(info->abi);
195         free(info);
196 }
197
198 static void inst_del_cb(struct node *node)
199 {
200         struct instance *info;
201
202         info = node_data(node);
203         if (!info) {
204                 return;
205         }
206
207         free(info->id);
208         free(info->cluster);
209         free(info->category);
210         free(info->state);
211         free(info);
212 }
213
214 static void ls(void)
215 {
216         struct node *node;
217         int cnt = 0;
218         int is_package;
219         int is_provider;
220         int is_instance;
221         struct node *next_node;
222
223         if (!(node_mode(s_info.targetdir) & NODE_READ)) {
224                 printf("Access denied\n");
225                 return;
226         }
227
228         is_package = node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "package");
229         is_provider = !is_package && node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "provider");
230         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");
231
232         node = node_child(s_info.targetdir);
233         while (node) {
234                 if (is_package) {
235                         struct package *info;
236
237                         next_node = node_next_sibling(node);
238                         if (node_age(node) != s_info.age) {
239                                 node_delete(node, package_del_cb);
240                                 node = next_node;
241                                 continue;
242                         }
243
244                         info = node_data(node);
245                         printf(" %3d %20s %5s ", info->inst_count, info->slavename ? info->slavename : "(none)", info->abi ? info->abi : "?");
246                 } else if (is_provider) {
247                         struct slave *info;
248
249                         next_node = node_next_sibling(node);
250                         if (node_age(node) != s_info.age) {
251                                 node_delete(node, provider_del_cb);
252                                 node = next_node;
253                                 continue;
254                         }
255
256                         info = node_data(node);
257                         printf("%6d %3d %5s %5.2f ", info->pid, info->loaded_inst, info->abi ? info->abi : "?", info->ttl);
258                 } else if (is_instance) {
259                         struct instance *info;
260                         struct stat stat;
261                         char buf[4096];
262
263                         next_node = node_next_sibling(node);
264
265                         if (node_age(node) != s_info.age) {
266                                 node_delete(node, inst_del_cb);
267                                 node = next_node;
268                                 continue;
269                         }
270
271                         info = node_data(node);
272
273                         printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
274                         snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
275                         if (lstat(buf, &stat) < 0) {
276                                 printf("%3d ERR ", errno);
277                         } else {
278                                 printf("%2.2lf KB ", (double)stat.st_size / 1024.0f);
279                         }
280                 }
281
282                 if (node_type(node) == NODE_DIR) {
283                         printf("%s/", node_name(node));
284                 } else if (node_type(node) == NODE_FILE) {
285                         printf("%s", node_name(node));
286                 }
287
288                 printf("\n");
289                 node = node_next_sibling(node);
290                 cnt++;
291         }
292
293         printf("Total: %d\n", cnt);
294 }
295
296 static void send_slave_list(void)
297 {
298         struct packet *packet;
299         int ret;
300
301         if (s_info.cmd != NOP) {
302                 printf("Previous command is not finished\n");
303                 return;
304         }
305
306         packet = packet_create_noack("slave_list", "d", 0.0f);
307         if (!packet) {
308                 printf("Failed to create a packet\n");
309                 return;
310         }
311
312         ret = com_core_packet_send_only(s_info.fd, packet);
313         packet_destroy(packet);
314         if (ret < 0) {
315                 printf("Failed to send a packet: %d\n", ret);
316                 return;
317         }
318
319         s_info.cmd = SLAVE_LIST;
320         s_info.age++;
321 }
322
323 /*!
324  * var = debug, slave_max_load
325  * cmd = set / get
326  */
327 static void send_command(const char *cmd, const char *var, const char *val)
328 {
329         struct packet *packet;
330         int ret;
331
332         if (s_info.cmd != NOP) {
333                 printf("Previous command is not finished\n");
334                 return;
335         }
336
337         packet = packet_create_noack("master_ctrl", "sss", cmd, var, val);
338         if (!packet) {
339                 printf("Failed to create a ctrl packet\n");
340                 return;
341         }
342
343         ret = com_core_packet_send_only(s_info.fd, packet);
344         packet_destroy(packet);
345         if (ret < 0) {
346                 printf("Failed to send packet ctrl\n");
347                 return;
348         }
349
350         s_info.cmd = MASTER_CTRL;
351         s_info.age++;
352 }
353
354 static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
355 {
356         struct node *parent = data;
357         struct node *node;
358         struct package *info;
359
360         node = node_find(parent, lbid);
361         if (node) {
362                 info = node_data(node);
363                 if (!info) {
364                         printf("Invalid node\n");
365                         return -EINVAL;
366                 }
367
368                 free(info->pkgid);
369                 info->pkgid = strdup(appid);
370                 if (!info->pkgid) {
371                         printf("Error: %s\n", strerror(errno));
372                         return -ENOMEM;
373                 }
374
375                 node_set_age(node, s_info.age);
376                 return 0;
377         }
378
379         info = calloc(1, sizeof(*info));
380         if (!info) {
381                 printf("Error: %s\n", strerror(errno));
382                 return -ENOMEM;
383         }
384
385         info->pkgid = strdup(appid);
386         if (!info->pkgid) {
387                 printf("Error: %s\n", strerror(errno));
388                 free(info);
389                 return -ENOMEM;
390         }
391
392         info->primary = is_prime;
393
394         node = node_create(parent, lbid, NODE_DIR);
395         if (!node) {
396                 free(info->pkgid);
397                 free(info);
398                 return -ENOMEM;
399         }
400
401         node_set_mode(node, NODE_READ | NODE_EXEC);
402         node_set_data(node, info);
403         node_set_age(node, s_info.age);
404         return 0;
405 }
406
407 static void send_pkg_list(void)
408 {
409         struct packet *packet;
410         int ret;
411
412         if (s_info.cmd != NOP) {
413                 printf("Previous command is not finished\n");
414                 return;
415         }
416
417         packet = packet_create_noack("pkg_list", "d", 0.0f);
418         if (!packet) {
419                 printf("Failed to create a packet\n");
420                 return;
421         }
422
423         ret = com_core_packet_send_only(s_info.fd, packet);
424         packet_destroy(packet);
425         if (ret < 0) {
426                 printf("Failed to create a packet\n");
427                 return;
428         }
429
430         s_info.cmd = PKG_LIST;
431         s_info.age++;
432
433         livebox_service_get_pkglist(pkglist_cb, s_info.targetdir);
434 }
435
436 static void send_inst_delete(void)
437 {
438         struct packet *packet;
439         struct node *parent;
440         const char *name;
441         struct instance *inst;
442         int ret;
443
444         if (s_info.cmd != NOP) {
445                 printf("Previous command is not finished\n");
446                 return;
447         }
448
449         parent = node_parent(s_info.targetdir);
450         if (!parent) {
451                 printf("Invalid argument\n");
452                 return;
453         }
454
455         if (!node_parent(parent)) {
456                 printf("Invalid argument\n");
457                 return;
458         }
459
460         name = node_name(node_parent(parent));
461         if (!name || strcmp(name, "package")) {
462                 printf("Invalid argument\n");
463                 return;
464         }
465
466         inst = node_data(s_info.targetdir);
467         name = node_name(parent);
468
469         packet = packet_create_noack("pkg_ctrl", "sss", "rminst", name, inst->id);
470         if (!packet) {
471                 printf("Failed to create a packet\n");
472                 return;
473         }
474
475         ret = com_core_packet_send_only(s_info.fd, packet);
476         packet_destroy(packet);
477         if (ret < 0) {
478                 printf("Failed to send a packet: %d\n", ret);
479                 return;
480         }
481
482         s_info.cmd = INST_CTRL;
483         s_info.age++;
484 }
485
486 static void send_inst_fault(void)
487 {
488         struct packet *packet;
489         struct node *parent;
490         const char *name;
491         struct instance *inst;
492         int ret;
493
494         if (s_info.cmd != NOP) {
495                 printf("Previous command is not finished\n");
496                 return;
497         }
498
499         parent = node_parent(s_info.targetdir);
500         if (!parent) {
501                 printf("Invalid argument\n");
502                 return;
503         }
504
505         if (!node_parent(parent)) {
506                 printf("Invalid argument\n");
507                 return;
508         }
509
510         name = node_name(node_parent(parent));
511         if (!name || strcmp(name, "package")) {
512                 printf("Invalid argument\n");
513                 return;
514         }
515
516         inst = node_data(s_info.targetdir);
517         name = node_name(parent);
518
519         packet = packet_create_noack("pkg_ctrl", "sss", "faultinst", name, inst->id);
520         if (!packet) {
521                 printf("Failed to create a packet\n");
522                 return;
523         }
524
525         ret = com_core_packet_send_only(s_info.fd, packet);
526         packet_destroy(packet);
527         if (ret < 0) {
528                 printf("Failed to send a packet: %d\n", ret);
529                 return;
530         }
531
532         s_info.cmd = INST_CTRL;
533         s_info.age++;
534 }
535
536 static void send_inst_list(const char *pkgname)
537 {
538         struct packet *packet;
539         int ret;
540
541         if (s_info.cmd != NOP) {
542                 printf("Previous command is not finished\n");
543                 return;
544         }
545
546         packet = packet_create_noack("inst_list", "s", pkgname);
547         if (!packet) {
548                 printf("Failed to create a packet\n");
549                 return;
550         }
551
552         ret = com_core_packet_send_only(s_info.fd, packet);
553         packet_destroy(packet);
554         if (ret < 0) {
555                 printf("Failed to send a packet: %d\n", ret);
556                 return;
557         }
558
559         s_info.cmd = INST_LIST;
560         s_info.age++;
561 }
562
563 static void help(void)
564 {
565         printf("liveinfo - Livebox utility\n");
566         printf("------------------------------ [Option] ------------------------------\n");
567         printf("-b Batch mode\n");
568         printf("-x execute command\n");
569         printf("------------------------------ [Command list] ------------------------------\n");
570         printf("\e[32mcd [PATH] - Change directory\e[0m\n");
571         printf("\e[32mls [ | PATH] - List up content as a file\e[0m\n");
572         printf("\e[32mrm [PKG_ID|INST_ID] - Delete package or instance\e[0m\n");
573         printf("\e[32mstat [path] - Display the information of given path\e[0m\n");
574         printf("\e[32mset [debug] [on|off] Set the control variable of master provider\e[0m\n");
575         printf("\e[32mx damage Pix x y w h - Create damage event for given pixmap\e[0m\n");
576         printf("\e[32mx move Pix x y - Move the window\e[0m\n");
577         printf("\e[32mx resize Pix w h - Resize the window\e[0m\n");
578         printf("\e[32mx map Pix - Show the window\e[0m\n");
579         printf("\e[32mx unmap Pix - Hide the window\e[0m\n");
580         printf("\e[32mx capture Pix outfile - Capture pixmap and save it to outfile\e[0m\n");
581         printf("\e[32msh [command] Execute shell command, [command] should be abspath\e[0m\n");
582         printf("\e[32mexit - \e[0m\n");
583         printf("\e[32mquit - \e[0m\n");
584         printf("----------------------------------------------------------------------------\n");
585 }
586
587 static inline void init_directory(void)
588 {
589         struct node *node;
590         s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
591         if (!s_info.rootdir) {
592                 return;
593         }
594         node_set_mode(s_info.rootdir, NODE_READ | NODE_EXEC);
595
596         node = node_create(s_info.rootdir, "provider", NODE_DIR);
597         if (!node) {
598                 node_destroy(s_info.rootdir);
599                 s_info.rootdir = NULL;
600                 return;
601         }
602         node_set_mode(node, NODE_READ | NODE_EXEC);
603
604         node = node_create(s_info.rootdir, "package", NODE_DIR);
605         if (!node) {
606                 node_destroy(node_child(s_info.rootdir));
607                 node_destroy(s_info.rootdir);
608                 s_info.rootdir = NULL;
609                 return;
610         }
611         node_set_mode(node, NODE_READ | NODE_EXEC);
612
613         s_info.curdir = s_info.rootdir;
614         return;
615 }
616
617 static inline void fini_directory(void)
618 {
619 }
620
621 static struct node *update_target_dir(const char *cmd)
622 {
623         struct node *node;
624
625         node = (*cmd == '/') ? s_info.rootdir : s_info.curdir;
626         node = node_find(node, cmd);
627
628         return node;
629 }
630
631 static int get_token(const char *src, char *out)
632 {
633         int len = 0;
634         while (*src && *src == ' ') src++;
635
636         if (!*src) {
637                 return 0;
638         }
639
640         while (*src && *src != ' ') {
641                 *out++ = *src++;
642                 len++;
643         }
644
645         *out = '\0';
646         return len;
647 }
648
649 static inline int do_stat(const char *cmd)
650 {
651         int i;
652         struct node *node;
653         struct node *parent;
654         char *tmp;
655         enum stat_type {
656                 PKG_INSTANCE = 0x01,
657                 PKG,
658                 PROVIDER_INSTANCE,
659                 PROVIDER,
660                 ROOT,
661         } type;
662
663         cmd += 5;
664         while (*cmd && *cmd == ' ') cmd++;
665
666         if (!*cmd){
667                 printf("Invalid argument\n");
668                 return -EINVAL;
669         }
670
671         node = node_find(*cmd == '/' ? s_info.rootdir : s_info.curdir, cmd);
672         if (!node) {
673                 printf("Invalid path\n");
674                 return -EINVAL;
675         }
676
677         i = 0;
678         type = ROOT;
679         parent = node_parent(node);
680         while (parent) {
681                 if (!node_name(parent)) {
682                         printf("%s has no info\n", node_name(node));
683                         return -EINVAL;
684                 } else if (!strcmp(node_name(parent), "package")) {
685                         type = (i == 0) ? PKG : PKG_INSTANCE;
686                         break;
687                 } else if (!strcmp(node_name(parent), "provider")){
688                         type = (i == 0) ? PROVIDER : PROVIDER_INSTANCE;
689                         break;
690                 }
691
692                 parent = node_parent(parent);
693                 i++;
694                 if (i > 1) {
695                         printf("%s is invalid path\n", node_name(node));
696                         return -EINVAL;
697                 }
698         }
699
700         switch (type){
701         case PKG:
702                 tmp = livebox_service_i18n_name(node_name(node), NULL);
703                 printf("Name: %s (", tmp);
704                 free(tmp);
705
706                 i = livebox_service_is_enabled(node_name(node));
707                 printf("%s)\n", i ? "enabled" : "disabled");
708
709                 tmp = livebox_service_i18n_icon(node_name(node), NULL);
710                 printf("Icon: %s\n", tmp);
711                 free(tmp);
712
713                 tmp = livebox_service_provider_name(node_name(node));
714                 printf("Provider: %s (content:", tmp);
715                 free(tmp);
716
717                 tmp = livebox_service_content(node_name(node));
718                 printf("%s)\n", tmp);
719                 free(tmp);
720
721                 tmp = livebox_service_lb_script_path(node_name(node));
722                 printf("LB Script: %s (", tmp);
723                 free(tmp);
724
725                 tmp = livebox_service_lb_script_group(node_name(node));
726                 printf("%s)\n", tmp);
727                 free(tmp);
728
729                 tmp = livebox_service_pd_script_path(node_name(node));
730                 printf("PD Script: %s (", tmp);
731                 free(tmp);
732
733                 tmp = livebox_service_pd_script_group(node_name(node));
734                 printf("%s)\n", tmp);
735                 free(tmp);
736
737                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_1x1);
738                 printf("[1x1] Mouse event: %s\n", i ? "enabled" : "disabled");
739                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_2x1);
740                 printf("[2x1] Mouse event: %s\n", i ? "enabled" : "disabled");
741                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_2x2);
742                 printf("[2x2] Mouse event: %s\n", i ? "enabled" : "disabled");
743                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x1);
744                 printf("[4x1] Mouse event: %s\n", i ? "enabled" : "disabled");
745                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x2);
746                 printf("[4x2] Mouse event: %s\n", i ? "enabled" : "disabled");
747                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x3);
748                 printf("[4x3] Mouse event: %s\n", i ? "enabled" : "disabled");
749                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x4);
750                 printf("[4x4] Mouse event: %s\n", i ? "enabled" : "disabled");
751                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x5);
752                 printf("[4x5] Mouse event: %s\n", i ? "enabled" : "disabled");
753                 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x6);
754                 printf("[4x6] Mouse event: %s\n", i ? "enabled" : "disabled");
755
756                 break;
757         case PROVIDER:
758                 printf("Not supported yet\n");
759                 break;
760         case PKG_INSTANCE:
761                 printf("Not supported yet\n");
762                 break;
763         case PROVIDER_INSTANCE:
764                 printf("Not supported yet\n");
765                 break;
766         case ROOT:
767                 printf("Not supported yet\n");
768                 break;
769         }
770
771         return 0;
772 }
773
774 static int do_set(const char *cmd)
775 {
776         int i;
777         char variable[4096] = { '0', };
778
779         cmd += 4;
780         i = get_token(cmd, variable);
781
782         cmd += i;
783         while (*cmd && *cmd == ' ') {
784                 cmd++;
785         }
786
787         if (!i || !*cmd) {
788                 printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
789                 return -EINVAL;
790         }
791
792         send_command("set", variable, cmd);
793         return 0;
794 }
795
796 static inline int do_get(const char *cmd)
797 {
798         cmd += 4;
799
800         while (*cmd && *cmd == ' ') cmd++;
801         if (!*cmd) {
802                 printf("Invalid argument(%s): get [VAR]\n", cmd);
803                 return -EINVAL;
804         }
805
806         send_command("get", cmd, "");
807         return 0;
808 }
809
810 static inline int do_ls(const char *cmd)
811 {
812         const char *name;
813         struct node *parent;
814
815         cmd += 2;
816
817         while (*cmd && *cmd == ' ') {
818                 cmd++;
819         }
820
821         s_info.targetdir = *cmd ? update_target_dir(cmd) : s_info.curdir;
822         if (!s_info.targetdir) {
823                 printf("%s is not exists\n", cmd);
824                 return -ENOENT;
825         }
826
827         name = node_name(s_info.targetdir);
828         if (name) {
829                 if (!strcmp(name, "package")) {
830                         if (s_info.cmd == NOP) {
831                                 send_pkg_list();
832                                 return 0;
833                         }
834
835                         printf("Waiting the server response\n");
836                         return -EBUSY;
837                 } else if (!strcmp(name, "provider")) {
838                         if (s_info.cmd == NOP) {
839                                 send_slave_list();
840                                 return 0;
841                         }
842
843                         printf("Waiting the server response\n");
844                         return -EBUSY;
845                 }
846         }
847
848         parent = node_parent(s_info.targetdir);
849         if (parent && node_name(parent)) {
850                 if (!strcmp(node_name(parent), "package")) {
851                         if (s_info.cmd != NOP) {
852                                 printf("Waiting the server response\n");
853                                 return -EBUSY;
854                         }
855
856                         send_inst_list(name);
857                         return 0;
858                 }
859         }
860
861         ls();
862         return -1;
863 }
864
865 static inline int do_cd(const char *cmd)
866 {
867         cmd += 2;
868
869         while (*cmd && *cmd == ' ') {
870                  cmd++;
871         }
872
873         if (!*cmd) {
874                 return -1;
875         }
876
877         if (s_info.cmd != NOP) {
878                 printf("Waiting the server response\n");
879                 return -EBUSY;
880         }
881
882         s_info.targetdir = update_target_dir(cmd);
883         if (!s_info.targetdir) {
884                 printf("%s is not exists\n", cmd);
885                 return -ENOENT;
886         }
887
888         if (node_type(s_info.targetdir) != NODE_DIR) {
889                 printf("Unable change directory to %s\n", cmd);
890                 return -EINVAL;
891         }
892
893         if (!(node_mode(s_info.targetdir) & NODE_EXEC)) {
894                 printf("Access denied %s\n", cmd);
895                 return -EACCES;
896         }
897
898         s_info.curdir = s_info.targetdir;
899         return -1;
900 }
901
902 static inline int do_rm(const char *cmd)
903 {
904         cmd += 2;
905         while (*cmd && *cmd == ' ') cmd++;
906         if (!*cmd) {
907                 return -1;
908         }
909
910         if (s_info.cmd != NOP) {
911                 printf("Waiting the server response\n");
912                 return -EBUSY;
913         }
914
915         s_info.targetdir = update_target_dir(cmd);
916         if (!s_info.targetdir) {
917                 printf("%s is not exists\n", cmd);
918                 return -ENOENT;
919         }
920
921         if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
922                 printf("Access denied %s\n", cmd);
923                 return -EACCES;
924         }
925
926         send_inst_delete();
927         return 0;
928 }
929
930 static inline int do_fault(const char *cmd)
931 {
932         cmd += 5;
933         while (*cmd && *cmd == ' ') cmd++;
934         if (!*cmd) {
935                 return -1;
936         }
937
938         if (s_info.cmd != NOP) {
939                 printf("Waiting the server response\n");
940                 return -EBUSY;
941         }
942
943         s_info.targetdir = update_target_dir(cmd);
944         if (!s_info.targetdir) {
945                 printf("%s is not exists\n", cmd);
946                 return -ENOENT;
947         }
948
949         if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
950                 printf("Access denied %s\n", cmd);
951                 return -EACCES;
952         }
953
954         send_inst_fault();
955         return 0;
956 }
957
958 #if !defined(WCOREDUMP)
959 #define WCOREDUMP(a)    0
960 #endif
961
962 static void do_sh(const char *cmd)
963 {
964         pid_t pid;
965
966         cmd += 3;
967
968         while (*cmd && *cmd == ' ') {
969                 cmd++;
970         }
971
972         if (!*cmd) {
973                 return;
974         }
975
976         pid = fork();
977         if (pid == 0) {
978                 char command[256];
979                 int idx;
980                 idx = 0;
981
982                 while (idx < (sizeof(command) - 1) && *cmd && *cmd != ' ') {
983                         command[idx++] = *cmd++;
984                 }
985                 command[idx] = '\0';
986
987                 if (execl(command, cmd, NULL) < 0) {
988                         printf("Failed to execute: %s\n", strerror(errno));
989                 }
990
991                 exit(0);
992         } else if (pid < 0) {
993                 printf("Failed to create a new process: %s\n", strerror(errno));
994         } else {
995                 int status;
996                 if (waitpid(pid, &status, 0) < 0) {
997                         printf("error: %s\n", strerror(errno));
998                 } else {
999                         if (WIFEXITED(status)) {
1000                                 printf("Exit: %d\n", WEXITSTATUS(status));
1001                         } else if (WIFSIGNALED(status)) {
1002                                 printf("Terminated by %d %s\n", WTERMSIG(status), WCOREDUMP(status) ? " - core generated" : "");
1003                         } else if (WIFSTOPPED(status)) {
1004                                 printf("Stopped by %d\n", WSTOPSIG(status));
1005                         } else if (WIFCONTINUED(status)) {
1006                                 printf("Child is resumed\n");
1007                         }
1008                 }
1009         }
1010 }
1011
1012 static inline int get_pixmap_size(Display *disp, Pixmap id, int *x, int *y, unsigned int *w, unsigned int *h)
1013 {
1014         Window dummy_win;
1015         unsigned int dummy_border, dummy_depth;
1016         int _x;
1017         int _y;
1018
1019         if (!x) {
1020                 x = &_x;
1021         }
1022
1023         if (!y) {
1024                 y = &_y;
1025         }
1026
1027         if (!XGetGeometry(disp, id, &dummy_win, x, y, w, h, &dummy_border, &dummy_depth)) {
1028                 return -EFAULT;
1029         }
1030
1031         return 0;
1032 }
1033
1034 static inline int do_capture(Display *disp, Pixmap id, const char *filename)
1035 {
1036         XShmSegmentInfo si;
1037         XImage *xim;
1038         Visual *visual;
1039         unsigned int w;
1040         unsigned int h;
1041         int bufsz;
1042         int fd;
1043         Screen *screen;
1044
1045         screen = DefaultScreenOfDisplay(disp);
1046         visual = DefaultVisualOfScreen(screen);
1047
1048         if (get_pixmap_size(disp, id, NULL, NULL, &w, &h) < 0) {
1049                 printf("Failed to get size of a pixmap\n");
1050                 return -EINVAL;
1051         }
1052
1053         printf("Pixmap size: %dx%d\n", w, h);
1054         bufsz = w * h * sizeof(int);
1055
1056         si.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0666);
1057         if (si.shmid < 0) {
1058                 printf("shmget: %s\n", strerror(errno));
1059                 return -EFAULT;
1060         }
1061
1062         si.readOnly = False;
1063         si.shmaddr = shmat(si.shmid, NULL, 0);
1064         if (si.shmaddr == (void *)-1) {
1065
1066                 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1067                         printf("shmctl: %s\n", strerror(errno));
1068                 }
1069
1070                 return -EFAULT;
1071         }
1072
1073         /*!
1074          * \NOTE
1075          * Use the 24 bits Pixmap for Video player
1076          */
1077         xim = XShmCreateImage(disp, visual, 24 /* (depth << 3) */, ZPixmap, NULL, &si, w, h);
1078         if (xim == NULL) {
1079                 if (shmdt(si.shmaddr) < 0) {
1080                         printf("shmdt: %s\n", strerror(errno));
1081                 }
1082
1083                 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1084                         printf("shmctl: %s\n", strerror(errno));
1085                 }
1086
1087                 return -EFAULT;
1088         }
1089
1090         xim->data = si.shmaddr;
1091         XShmAttach(disp, &si);
1092
1093         XShmGetImage(disp, id, xim, 0, 0, 0xFFFFFFFF);
1094         XSync(disp, False);
1095
1096         fd = open(filename, O_CREAT | O_RDWR, 0644);
1097         if (fd >= 0) {
1098                 if (write(fd, xim->data, bufsz) != bufsz) {
1099                         printf("Data is not fully written\n");
1100                 }
1101
1102                 if (close(fd) < 0) {
1103                         printf("close: %s\n", strerror(errno));
1104                 }
1105         } else {
1106                 printf("Error: %sn\n", strerror(errno));
1107         }
1108
1109         XShmDetach(disp, &si);
1110         XDestroyImage(xim);
1111
1112         if (shmdt(si.shmaddr) < 0) {
1113                 printf("shmdt: %s\n", strerror(errno));
1114         }
1115
1116         if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1117                 printf("shmctl: %s\n", strerror(errno));
1118         }
1119
1120         return 0;
1121 }
1122
1123 static void do_x(const char *cmd)
1124 {
1125         Display *disp;
1126
1127         cmd += 2;
1128
1129         while (*cmd && *cmd == ' ') {
1130                 cmd++;
1131         }
1132
1133         if (!*cmd) {
1134                 return;
1135         }
1136
1137         disp = XOpenDisplay(NULL);
1138         if (!disp) {
1139                 printf("Failed to connect to the X\n");
1140                 return;
1141         }
1142
1143         if (!strncasecmp(cmd, "damage ", 7)) {
1144                 unsigned int winId;
1145                 XRectangle rect;
1146                 XserverRegion region;
1147                 int x, y, w, h;
1148
1149                 cmd += 7;
1150
1151                 if (sscanf(cmd, "%u %d %d %d %d", &winId, &x, &y, &w, &h) != 5) {
1152                         printf("Invalid argument\nx damage WINID_DEC X Y W H\n");
1153                         return;
1154                 }
1155                 rect.x = x;
1156                 rect.y = y;
1157                 rect.width = w;
1158                 rect.height = h;
1159                 region = XFixesCreateRegion(disp, &rect, 1);
1160                 XDamageAdd(disp, winId, region);
1161                 XFixesDestroyRegion(disp, region);
1162                 XFlush(disp);
1163
1164                 printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h);
1165         } else if (!strncasecmp(cmd, "capture ", 8)) {
1166                 unsigned int winId;
1167                 char filename[256];
1168
1169                 cmd += 8;
1170
1171                 if (sscanf(cmd, "%u %255[^ ]", &winId, filename) != 2) {
1172                         printf("Invalid argument\nx capture WINID_DEC FILENAME (%s)\n", cmd);
1173                         return;
1174                 }
1175                 if (do_capture(disp, winId, filename) == 0) {
1176                         printf("Captured: %s\n", filename);
1177                 }
1178         } else if (!strncasecmp(cmd, "resize ", 7)) {
1179                 unsigned int winId;
1180                 int w;
1181                 int h;
1182
1183                 cmd += 7;
1184
1185                 if (sscanf(cmd, "%u %d %d", &winId, &w, &h) != 3) {
1186                         printf("Invalid argument\nx resize WINID_DEC W H\n");
1187                         return;
1188                 }
1189
1190                 XResizeWindow(disp, winId, w, h);
1191                 printf("Resize: %u %d %d\n", winId, w, h);
1192         } else if (!strncasecmp(cmd, "move ", 5)) {
1193                 unsigned int winId;
1194                 int x;
1195                 int y;
1196
1197                 cmd += 5;
1198                 if (sscanf(cmd, "%u %d %d", &winId, &x, &y) != 3) {
1199                         printf("Invalid argument\nx move WINID_DEC X Y\n");
1200                         return;
1201                 }
1202
1203                 XMoveWindow(disp, winId, x, y);
1204                 printf("Move: %u %d %d\n", winId, x, y);
1205         } else if (!strncasecmp(cmd, "map ", 4)) {
1206                 unsigned int winId;
1207                 cmd += 4;
1208                 if (sscanf(cmd, "%u", &winId) != 1) {
1209                         printf("Invalid argument\nx map WINID_DEC\n");
1210                         return;
1211                 }
1212                 XMapRaised(disp, winId);
1213                 printf("Map: %u\n", winId);
1214         } else if (!strncasecmp(cmd, "unmap ", 6)) {
1215                 unsigned int winId;
1216                 cmd += 6;
1217                 if (sscanf(cmd, "%u", &winId) != 1) {
1218                         printf("Invalid argument\nx unmap WINID_DEC\n");
1219                         return;
1220                 }
1221                 XUnmapWindow(disp, winId);
1222                 printf("Unmap: %u\n", winId);
1223         } else {
1224                 printf("Unknown command\n");
1225         }
1226
1227         XCloseDisplay(disp);
1228 }
1229
1230 static inline void put_command(const char *cmd)
1231 {
1232         if (s_info.history[s_info.history_top]) {
1233                 free(s_info.history[s_info.history_top]);
1234                 s_info.history[s_info.history_top] = NULL;
1235         }
1236
1237         s_info.history[s_info.history_top] = strdup(cmd);
1238         s_info.history_top = (s_info.history_top + !!s_info.history[s_info.history_top]) % (sizeof(s_info.history) / sizeof(s_info.history[0]));
1239 }
1240
1241 static inline const char *get_command(int idx)
1242 {
1243         idx = s_info.history_top + idx;
1244         while (idx < 0) {
1245                 idx += (sizeof(s_info.history) / sizeof(s_info.history[0]));
1246         }
1247
1248         return s_info.history[idx];
1249 }
1250
1251 static inline void do_command(const char *cmd)
1252 {
1253         /* Skip the first spaces */
1254         while (*cmd && *cmd == ' ') {
1255                 cmd++;
1256         }
1257
1258         if (strlen(cmd) && *cmd != '#') {
1259                 if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "quit", 4)) {
1260                         ecore_main_loop_quit();
1261                 } else if (!strncasecmp(cmd, "set ", 4)) {
1262                         if (do_set(cmd) == 0) {
1263                                 return;
1264                         }
1265                 } else if (!strncasecmp(cmd, "stat ", 5)) {
1266                         do_stat(cmd);
1267                 } else if (!strncasecmp(cmd, "get ", 4)) {
1268                         if (do_get(cmd) == 0) {
1269                                 return;
1270                         }
1271                 } else if (!strncasecmp(cmd, "ls", 2)) {
1272                         if (do_ls(cmd) == 0) {
1273                                 return;
1274                         }
1275                 } else if (!strncasecmp(cmd, "cd", 2)) {
1276                         if (do_cd(cmd) == 0) {
1277                                 return;
1278                         }
1279                 } else if (!strncasecmp(cmd, "rm", 2)) {
1280                         if (do_rm(cmd) == 0) {
1281                                 return;
1282                         }
1283                 } else if (!strncasecmp(cmd, "fault", 5)) {
1284                         if (do_fault(cmd) == 0) {
1285                                 return;
1286                         }
1287                 } else if (!strncasecmp(cmd, "sh ", 3)) {
1288                         do_sh(cmd);
1289                 } else if (!strncasecmp(cmd, "x ", 2)) {
1290                         do_x(cmd);
1291                 } else {
1292                         help();
1293                 }
1294         }
1295
1296         prompt(NULL);
1297         return;
1298 }
1299
1300 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
1301 {
1302         static int idx = 0;
1303         static char cmd_buffer[256];
1304         char ch;
1305         int fd;
1306         int ret;
1307         const char escape_str[] = { 0x1b, 0x5b, 0x0 };
1308         const char *escape_ptr = escape_str;
1309         const char *tmp;
1310
1311         if (fd_handler) {
1312                 fd = ecore_main_fd_handler_fd_get(fd_handler);
1313                 if (fd < 0) {
1314                         printf("FD is not valid: %d\n", fd);
1315                         return ECORE_CALLBACK_CANCEL;
1316                 }
1317         } else {
1318                 fd = s_info.input_fd;
1319         }
1320
1321         /*!
1322          * \note
1323          * Using this routine, we can implement the command recommend algorithm.
1324          * When a few more characters are matched with history of command, we can show it to user
1325          * Then the user will choose one or write new command
1326          */
1327
1328         /* Silly.. Silly */
1329         while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) {
1330                 if (*escape_ptr == '\0') {
1331                         /* Function key */
1332                         switch (ch) {
1333                         case 0x41: /* UP */
1334                                 printf("%s2K%s1G", escape_str, escape_str);
1335                                 tmp = get_command(--s_info.history_idx);
1336                                 if (!tmp) {
1337                                         s_info.history_idx = 0;
1338                                         cmd_buffer[0] = '\0';
1339                                         prompt(NULL);
1340                                 } else {
1341                                         strcpy(cmd_buffer, tmp);
1342                                         idx = strlen(cmd_buffer);
1343                                         prompt(cmd_buffer);
1344                                 }
1345                                 break;
1346                         case 0x42: /* DOWN */
1347                                 if (s_info.history_idx >= 0) {
1348                                         break;
1349                                 }
1350
1351                                 printf("%s2K%s1G", escape_str, escape_str);
1352                                 tmp = get_command(++s_info.history_idx);
1353                                 if (s_info.history_idx == 0) {
1354                                         s_info.history_idx = 0;
1355                                         cmd_buffer[0] = '\0';
1356                                         prompt(NULL);
1357                                 } else {
1358                                         strcpy(cmd_buffer, tmp);
1359                                         idx = strlen(cmd_buffer);
1360                                         prompt(cmd_buffer);
1361                                 }
1362                                 break;
1363                         case 0x43: /* RIGHT */
1364                                 break;
1365                         case 0x44: /* LEFT */
1366                                 break;
1367                         default:
1368                                 break;
1369                         }
1370
1371                         escape_ptr = escape_str;
1372                         continue;
1373                 } else if (ch == *escape_ptr) {
1374                         escape_ptr++;
1375                         continue;
1376                 }
1377
1378                 switch (ch) {
1379                 case 0x08: /* BKSP */
1380                         cmd_buffer[idx] = '\0';
1381                         if (idx > 0) {
1382                                 idx--;
1383                                 cmd_buffer[idx] = ' ';
1384                                 putc('\r', stdout);
1385                                 prompt(cmd_buffer);
1386                         }
1387
1388                         cmd_buffer[idx] = '\0';
1389                         putc('\r', stdout);
1390                         prompt(cmd_buffer);
1391                         break;
1392                 case 0x09: /* TAB */
1393                         if (!s_info.quick_search_node) {
1394                                 s_info.quick_search_node = node_child(s_info.curdir);
1395                                 s_info.quick_idx = idx;
1396                         } else {
1397                                 s_info.quick_search_node = node_next_sibling(s_info.quick_search_node);
1398                                 idx = s_info.quick_idx;
1399                         }
1400
1401                         if (!s_info.quick_search_node) {
1402                                 break;
1403                         }
1404
1405                         printf("%s2K%s1G", escape_str, escape_str);
1406                         strcpy(cmd_buffer + idx, node_name(s_info.quick_search_node));
1407                         idx += strlen(node_name(s_info.quick_search_node));
1408                         prompt(cmd_buffer);
1409                         break;
1410                 case '\n':
1411                 case '\r':
1412                         cmd_buffer[idx] = '\0';
1413                         idx = 0;
1414                         if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1415                                 putc((int)'\n', stdout);
1416                         }
1417                         do_command(cmd_buffer);
1418                         put_command(cmd_buffer);
1419                         memset(cmd_buffer, 0, sizeof(cmd_buffer));
1420                         s_info.history_idx = 0;
1421                         s_info.quick_search_node = NULL;
1422
1423                         /* Make a main loop processing for command handling */
1424                         return ECORE_CALLBACK_RENEW;
1425                 default:
1426                         cmd_buffer[idx++] = ch;
1427
1428                         if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1429                                 putc((int)ch, stdout);
1430                         }
1431
1432                         if (idx == sizeof(cmd_buffer) - 1) {
1433                                 cmd_buffer[idx] = '\0';
1434                                 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
1435                                 idx = 0;
1436                         }
1437                         break;
1438                 }
1439         }
1440
1441         if (ret < 0 && !fd_handler) {
1442                 ecore_main_loop_quit();
1443         }
1444
1445         return ECORE_CALLBACK_RENEW;
1446 }
1447
1448 static void processing_line_buffer(const char *buffer)
1449 {
1450         int pid;
1451         char slavename[256];
1452         char pkgname[256];
1453         char abi[256];
1454         char inst_id[4096];
1455         char cluster[256];
1456         char category[256];
1457         char state[10];
1458         int refcnt;
1459         int fault_count;
1460         int list_count;
1461         int loaded_inst;
1462         int loaded_pkg;
1463         double ttl;
1464         int secured;
1465         double period;
1466         int width;
1467         int height;
1468         struct node *node;
1469         struct package *pkginfo;
1470         struct instance *instinfo;
1471         struct slave *slaveinfo;
1472         int i;
1473
1474         switch (s_info.cmd) {
1475         case PKG_LIST:
1476                 if (sscanf(buffer, "%d %255[^ ] %255[^ ] %255[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
1477                         printf("Invalid format : [%s]\n", buffer);
1478                         return;
1479                 }
1480
1481                 node = node_find(s_info.targetdir, pkgname);
1482                 if (!node) {
1483                         pkginfo = calloc(1, sizeof(*pkginfo));
1484                         if (!pkginfo) {
1485                                 printf("Error: %s\n", strerror(errno));
1486                                 return;
1487                         }
1488
1489                         pkginfo->pkgid = strdup("conf.file");
1490                         if (!pkginfo->pkgid) {
1491                                 printf("Error: %s\n", strerror(errno));
1492                         }
1493
1494                         pkginfo->primary = 1;
1495
1496                         node = node_create(s_info.targetdir, pkgname, NODE_DIR);
1497                         if (!node) {
1498                                 free(pkginfo->pkgid);
1499                                 free(pkginfo);
1500                                 printf("Failed to create a new node (%s)\n", pkgname);
1501                                 return;
1502                         }
1503
1504                         node_set_mode(node, NODE_READ | NODE_EXEC);
1505                         node_set_data(node, pkginfo);
1506                 } else {
1507                         pkginfo = node_data(node);
1508                         if (!pkginfo) {
1509                                 printf("Package info is inavlid\n");
1510                                 return;
1511                         }
1512
1513                         free(pkginfo->slavename);
1514                         free(pkginfo->abi);
1515
1516                         pkginfo->slavename = NULL;
1517                         pkginfo->abi = NULL;
1518                 }
1519
1520                 node_set_age(node, s_info.age);
1521
1522                 pkginfo->slavename = strdup(slavename);
1523                 if (!pkginfo->slavename) {
1524                         printf("Error: %s\n", strerror(errno));
1525                 }
1526
1527                 pkginfo->abi = strdup(abi);
1528                 if (!pkginfo->abi) {
1529                         printf("Error: %s\n", strerror(errno));
1530                 }
1531
1532                 pkginfo->pid = pid;
1533                 pkginfo->refcnt = refcnt;
1534                 pkginfo->fault_count = fault_count;
1535                 pkginfo->inst_count = list_count;
1536                 break;
1537         case SLAVE_LIST:
1538                 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) {
1539                         printf("Invalid format : [%s]\n", buffer);
1540                         return;
1541                 }
1542                 node = node_find(s_info.targetdir, slavename);
1543                 if (!node) {
1544                         slaveinfo = calloc(1, sizeof(*slaveinfo));
1545                         if (!slaveinfo) {
1546                                 printf("Error: %s\n", strerror(errno));
1547                                 return;
1548                         }
1549
1550                         node = node_create(s_info.targetdir, slavename, NODE_DIR);
1551                         if (!node) {
1552                                 free(slaveinfo);
1553                                 return;
1554                         }
1555
1556                         node_set_mode(node, NODE_READ | NODE_EXEC);
1557                         node_set_data(node, slaveinfo);
1558                 } else {
1559                         slaveinfo = node_data(node);
1560                 }
1561
1562                 node_set_age(node, s_info.age);
1563
1564                 free(slaveinfo->pkgname);
1565                 free(slaveinfo->abi);
1566                 free(slaveinfo->state);
1567
1568                 slaveinfo->pkgname = strdup(pkgname);
1569                 if (!slaveinfo->pkgname) {
1570                         printf("Error: %s\n", strerror(errno));
1571                 }
1572
1573                 slaveinfo->abi = strdup(abi);
1574                 if (!slaveinfo->abi) {
1575                         printf("Error: %s\n", strerror(errno));
1576                 }
1577
1578                 slaveinfo->state = strdup(state);
1579                 if (!slaveinfo->state) {
1580                         printf("Error: %s\n", strerror(errno));
1581                 }
1582
1583                 slaveinfo->pid = pid;
1584                 slaveinfo->secured = secured;
1585                 slaveinfo->refcnt = refcnt;
1586                 slaveinfo->fault_count = fault_count;
1587                 slaveinfo->loaded_inst = loaded_inst;
1588                 slaveinfo->loaded_pkg = loaded_pkg;
1589                 slaveinfo->ttl = ttl;
1590                 break;
1591         case INST_LIST:
1592                 if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
1593                         printf("Invalid format : [%s]\n", buffer);
1594                         return;
1595                 }
1596
1597                 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
1598                 i += (inst_id[i] == '/');
1599
1600                 node = node_find(s_info.targetdir, inst_id + i);
1601                 if (!node) {
1602                         instinfo = calloc(1, sizeof(*instinfo));
1603                         if (!instinfo) {
1604                                 printf("Error: %s\n", strerror(errno));
1605                                 return;
1606                         }
1607
1608                         node = node_create(s_info.targetdir, inst_id + i, NODE_FILE);
1609                         if (!node) {
1610                                 free(instinfo);
1611                                 return;
1612                         }
1613
1614                         node_set_mode(node, NODE_READ | NODE_WRITE);
1615                         node_set_data(node, instinfo);
1616                 } else {
1617                         instinfo = node_data(node);
1618                 }
1619
1620                 node_set_age(node, s_info.age);
1621
1622                 free(instinfo->id);
1623                 free(instinfo->cluster);
1624                 free(instinfo->category);
1625                 free(instinfo->state);
1626
1627                 instinfo->id = strdup(inst_id);
1628                 if (!instinfo->id) {
1629                         printf("Error: %s\n", strerror(errno));
1630                 }
1631
1632                 instinfo->cluster = strdup(cluster);
1633                 if (!instinfo->cluster) {
1634                         printf("Error: %s\n", strerror(errno));
1635                 }
1636
1637                 instinfo->category = strdup(category);
1638                 if (!instinfo->category) {
1639                         printf("Error: %s\n", strerror(errno));
1640                 }
1641
1642                 instinfo->state = strdup(state);
1643                 if (!instinfo->state) {
1644                         printf("Error: %s\n", strerror(errno));
1645                 }
1646
1647                 instinfo->period = period;
1648                 instinfo->width = width;
1649                 instinfo->height = height;
1650                 break;
1651         case INST_CTRL:
1652                 sscanf(buffer, "%d", &i);
1653                 printf("%s\n", strerror(i));
1654                 printf("Result: %d\n", i);
1655                 break;
1656         case SLAVE_CTRL:
1657                 sscanf(buffer, "%d", &i);
1658                 printf("Result: %d\n", i);
1659                 break;
1660         case MASTER_CTRL:
1661                 sscanf(buffer, "%d", &i);
1662                 printf("Result: %d\n", i);
1663                 break;
1664         default:
1665                 break;
1666         }
1667 }
1668
1669 static inline void do_line_command(void)
1670 {
1671         switch (s_info.cmd) {
1672         case PKG_LIST:
1673                 ls();
1674                 break;
1675         case INST_LIST:
1676                 ls();
1677                 break;
1678         case SLAVE_LIST:
1679                 ls();
1680                 break;
1681         case INST_CTRL:
1682                 break;
1683         case SLAVE_CTRL:
1684                 break;
1685         case MASTER_CTRL:
1686                 break;
1687         default:
1688                 break;
1689         }
1690         prompt(NULL);
1691 }
1692
1693 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
1694 {
1695         int fd;
1696         static char *line_buffer = NULL;
1697         static int line_index = 0;
1698         static int bufsz = 256;
1699         char ch;
1700
1701         fd = ecore_main_fd_handler_fd_get(fd_handler);
1702         if (fd < 0) {
1703                 printf("FD is not valid: %d\n", fd);
1704                 return ECORE_CALLBACK_CANCEL;
1705         }
1706
1707         if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
1708                 printf("Error: %s\n", strerror(errno));
1709                 return ECORE_CALLBACK_CANCEL;
1710         }
1711
1712         if (!line_buffer) {
1713                 line_index = 0;
1714                 line_buffer = malloc(bufsz);
1715                 if (!line_buffer) {
1716                         printf("Error: %s\n", strerror(errno));
1717                         return ECORE_CALLBACK_CANCEL;
1718                 }
1719         }       
1720
1721         if (ch == '\n') { /* End of a line */
1722                 if (line_index == bufsz - 1) {
1723                         char *new_buf;
1724                         new_buf = realloc(line_buffer, bufsz + 2);
1725                         if (!new_buf) {
1726                                 printf("Error: %s\n", strerror(errno));
1727                                 free(line_buffer);
1728                                 line_buffer = NULL;
1729                                 line_index = 0;
1730                                 bufsz = 256;
1731                                 return ECORE_CALLBACK_CANCEL;
1732                         }
1733
1734                         line_buffer = new_buf;
1735                 }
1736
1737                 line_buffer[line_index] = '\0';
1738
1739                 if (!strcmp(line_buffer, "EOD")) {
1740                         do_line_command();
1741                         s_info.cmd = NOP;
1742                 } else {
1743                         processing_line_buffer(line_buffer);
1744                 }
1745
1746                 free(line_buffer);
1747                 line_buffer = NULL;
1748                 line_index = 0;
1749                 bufsz = 256;
1750         } else {
1751                 char *new_buf;
1752
1753                 line_buffer[line_index++] = ch;
1754                 if (line_index == bufsz - 1) {
1755                         bufsz += 256;
1756                         new_buf = realloc(line_buffer, bufsz);
1757                         if (!new_buf) {
1758                                 printf("Error: %s\n", strerror(errno));
1759                                 free(line_buffer);
1760                                 line_buffer = NULL;
1761                                 line_index = 0;
1762                                 bufsz = 256;
1763                                 return ECORE_CALLBACK_CANCEL;
1764                         }
1765
1766                         line_buffer = new_buf;
1767                 }
1768         }
1769
1770         return ECORE_CALLBACK_RENEW;
1771 }
1772
1773 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1774 {
1775         const char *fifo_name;
1776         int ret;
1777
1778         if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
1779                 printf("Invalid packet\n");
1780                 return -EFAULT;
1781         }
1782
1783         if (ret != 0) {
1784                 printf("Returns %d\n", ret);
1785                 return ret;
1786         }
1787
1788         printf("FIFO: %s\n", fifo_name);
1789
1790         s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
1791         if (s_info.fifo_handle < 0) {
1792                 printf("Error: %s\n", strerror(errno));
1793                 s_info.fifo_handle = -EINVAL;
1794                 ecore_main_loop_quit();
1795                 return -EINVAL;
1796         }
1797
1798         s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
1799         if (!s_info.fd_handler) {
1800                 printf("Failed to add a fd handler\n");
1801                 if (close(s_info.fifo_handle) < 0) {
1802                         printf("close: %s\n", strerror(errno));
1803                 }
1804                 s_info.fifo_handle = -EINVAL;
1805                 ecore_main_loop_quit();
1806                 return -EFAULT;
1807         }
1808
1809         prompt(NULL);
1810
1811         if (s_info.input_fd == STDIN_FILENO) {
1812                 if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0) {
1813                         printf("Error: %s\n", strerror(errno));
1814                 }
1815
1816                 s_info.in_handler = ecore_main_fd_handler_add(s_info.input_fd, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
1817                 if (!s_info.in_handler) {
1818                         printf("Failed to add a input handler\n");
1819                         ecore_main_loop_quit();
1820                         return -EFAULT;
1821                 }
1822         }
1823
1824         return 0;
1825 }
1826
1827 static int disconnected_cb(int handle, void *data)
1828 {
1829         printf("Disconnected\n");
1830         ecore_main_loop_quit();
1831         return 0;
1832 }
1833
1834 static int connected_cb(int handle, void *data)
1835 {
1836         struct packet *packet;
1837
1838         printf("Connected\n");
1839
1840         packet = packet_create("liveinfo_hello", "d", 0.0f);
1841         if (!packet) {
1842                 printf("Failed to build a packet for hello\n");
1843                 com_core_packet_client_fini(s_info.fd);
1844                 s_info.fd = -EINVAL;
1845                 return -EFAULT;
1846         }
1847
1848         s_info.fd = handle;
1849
1850         if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
1851                 printf("Failed to send a packet hello\n");
1852                 packet_destroy(packet);
1853                 com_core_packet_client_fini(s_info.fd);
1854                 s_info.fd = -EINVAL;
1855                 return -EFAULT;
1856         }
1857
1858         packet_destroy(packet);
1859         return 0;
1860 }
1861
1862 int main(int argc, char *argv[])
1863 {
1864         struct termios ttystate;
1865         static struct method s_table[] = {
1866                 {
1867                         .cmd = NULL,
1868                         .handler = NULL,
1869                 },
1870         };
1871         static struct option long_options[] = {
1872                 { "batchmode", required_argument, 0, 'b' },
1873                 { "help", no_argument, 0, 'h' },
1874                 { "verbose", required_argument, 0, 'v' },
1875                 { "execute", required_argument, 0, 'x' },
1876                 { 0, 0, 0, 0 }
1877         };
1878         int option_index;
1879         int c;
1880
1881         do {
1882                 c = getopt_long(argc, argv, "b:hv:x:", long_options, &option_index);
1883                 switch (c) {
1884                 case 'b':
1885                         if (!optarg || !*optarg) {
1886                                 printf("Invalid argument\n");
1887                                 help();
1888                                 return -EINVAL;
1889                         }
1890
1891                         if (s_info.input_fd != STDIN_FILENO) {
1892                                 /* Close the previously, opened file */
1893                                 if (close(s_info.input_fd) < 0) {
1894                                         printf("close: %s\n", strerror(errno));
1895                                 }
1896                         }
1897
1898                         s_info.input_fd = open(optarg, O_RDONLY);
1899                         if (s_info.input_fd < 0) {
1900                                 printf("Unable to access %s (%s)\n", optarg, strerror(errno));
1901                                 return -EIO;
1902                         }
1903                         break;
1904                 case 'h':
1905                         help();
1906                         return 0;
1907                 case 'v':
1908                         if (!optarg || !*optarg) {
1909                                 printf("Invalid argument\n");
1910                                 help();
1911                                 return -EINVAL;
1912                         }
1913
1914                         s_info.verbose = !strcmp(optarg, "true");
1915                         break;
1916                 case 'x':
1917                         if (!optarg || !*optarg) {
1918                                 printf("Invalid argument\n");
1919                                 help();
1920                                 return -EINVAL;
1921                         }
1922                         break;
1923                 default:
1924                         break;
1925                 }
1926         } while (c != -1);
1927
1928         ecore_init();
1929
1930 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
1931         g_type_init();
1932 #endif
1933
1934         com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1935         com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1936         livebox_service_init();
1937
1938         s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
1939         if (s_info.fd < 0) {
1940                 printf("Failed to make a connection\n");
1941                 return -EIO;
1942         }
1943
1944         if (s_info.input_fd == STDIN_FILENO) {
1945                 printf("Type your command on below empty line\n");
1946
1947                 if (tcgetattr(s_info.input_fd, &ttystate) < 0) {
1948                         printf("Error: %s\n", strerror(errno));
1949                 } else {
1950                         ttystate.c_lflag &= ~(ICANON | ECHO);
1951                         ttystate.c_cc[VMIN] = 1;
1952
1953                         if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
1954                                 printf("Error: %s\n", strerror(errno));
1955                         }
1956                 }
1957         } else {
1958                 printf("Batch mode enabled\n");
1959         }
1960
1961         if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0) {
1962                 printf("Error: %s\n", strerror(errno));
1963         }
1964
1965         init_directory();
1966
1967         ecore_main_loop_begin();
1968
1969         fini_directory();
1970         livebox_service_fini();
1971
1972         if (s_info.fd > 0) {
1973                 com_core_packet_client_fini(s_info.fd);
1974                 s_info.fd = -EINVAL;
1975         }
1976
1977         if (s_info.fd_handler) {
1978                 ecore_main_fd_handler_del(s_info.fd_handler);
1979                 s_info.fd_handler = NULL;
1980         }
1981
1982         if (s_info.input_fd == STDIN_FILENO) {
1983                 ttystate.c_lflag |= ICANON | ECHO;
1984                 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
1985                         printf("Error: %s\n", strerror(errno));
1986                 }
1987         } else {
1988                 if (close(s_info.input_fd) < 0) {
1989                         printf("close: %s\n", strerror(errno));
1990                 }
1991         }
1992
1993         if (s_info.fifo_handle > 0) {
1994                 if (close(s_info.fifo_handle) < 0) {
1995                         printf("close: %s\n", strerror(errno));
1996                 }
1997                 s_info.fifo_handle = -EINVAL;
1998         }
1999
2000         if (s_info.in_handler) {
2001                 ecore_main_fd_handler_del(s_info.in_handler);
2002                 s_info.in_handler = NULL;
2003         }
2004
2005         ecore_shutdown();
2006         putc((int)'\n', stdout);
2007         return 0;
2008 }
2009
2010 /* End of a file */