Sync with the latest code of phone profile
[platform/framework/web/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 inline 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));
738                 printf("Mouse event: %s\n", i ? "enabled" : "disabled");
739
740                 break;
741         case PROVIDER:
742                 printf("Not supported yet\n");
743                 break;
744         case PKG_INSTANCE:
745                 printf("Not supported yet\n");
746                 break;
747         case PROVIDER_INSTANCE:
748                 printf("Not supported yet\n");
749                 break;
750         case ROOT:
751                 printf("Not supported yet\n");
752                 break;
753         }
754
755         return 0;
756 }
757
758 static int do_set(const char *cmd)
759 {
760         int i;
761         char variable[4096] = { '0', };
762
763         cmd += 4;
764         i = get_token(cmd, variable);
765
766         cmd += i;
767         while (*cmd && *cmd == ' ') {
768                 cmd++;
769         }
770
771         if (!i || !*cmd) {
772                 printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
773                 return -EINVAL;
774         }
775
776         send_command("set", variable, cmd);
777         return 0;
778 }
779
780 static inline int do_get(const char *cmd)
781 {
782         cmd += 4;
783
784         while (*cmd && *cmd == ' ') cmd++;
785         if (!*cmd) {
786                 printf("Invalid argument(%s): get [VAR]\n", cmd);
787                 return -EINVAL;
788         }
789
790         send_command("get", cmd, "");
791         return 0;
792 }
793
794 static inline int do_ls(const char *cmd)
795 {
796         const char *name;
797         struct node *parent;
798
799         cmd += 2;
800
801         while (*cmd && *cmd == ' ') {
802                 cmd++;
803         }
804
805         s_info.targetdir = *cmd ? update_target_dir(cmd) : s_info.curdir;
806         if (!s_info.targetdir) {
807                 printf("%s is not exists\n", cmd);
808                 return -ENOENT;
809         }
810
811         name = node_name(s_info.targetdir);
812         if (name) {
813                 if (!strcmp(name, "package")) {
814                         if (s_info.cmd == NOP) {
815                                 send_pkg_list();
816                                 return 0;
817                         }
818
819                         printf("Waiting the server response\n");
820                         return -EBUSY;
821                 } else if (!strcmp(name, "provider")) {
822                         if (s_info.cmd == NOP) {
823                                 send_slave_list();
824                                 return 0;
825                         }
826
827                         printf("Waiting the server response\n");
828                         return -EBUSY;
829                 }
830         }
831
832         parent = node_parent(s_info.targetdir);
833         if (parent && node_name(parent)) {
834                 if (!strcmp(node_name(parent), "package")) {
835                         if (s_info.cmd != NOP) {
836                                 printf("Waiting the server response\n");
837                                 return -EBUSY;
838                         }
839
840                         send_inst_list(name);
841                         return 0;
842                 }
843         }
844
845         ls();
846         return -1;
847 }
848
849 static inline int do_cd(const char *cmd)
850 {
851         cmd += 2;
852
853         while (*cmd && *cmd == ' ') {
854                  cmd++;
855         }
856
857         if (!*cmd) {
858                 return -1;
859         }
860
861         if (s_info.cmd != NOP) {
862                 printf("Waiting the server response\n");
863                 return -EBUSY;
864         }
865
866         s_info.targetdir = update_target_dir(cmd);
867         if (!s_info.targetdir) {
868                 printf("%s is not exists\n", cmd);
869                 return -ENOENT;
870         }
871
872         if (node_type(s_info.targetdir) != NODE_DIR) {
873                 printf("Unable change directory to %s\n", cmd);
874                 return -EINVAL;
875         }
876
877         if (!(node_mode(s_info.targetdir) & NODE_EXEC)) {
878                 printf("Access denied %s\n", cmd);
879                 return -EACCES;
880         }
881
882         s_info.curdir = s_info.targetdir;
883         return -1;
884 }
885
886 static inline int do_rm(const char *cmd)
887 {
888         cmd += 2;
889         while (*cmd && *cmd == ' ') cmd++;
890         if (!*cmd) {
891                 return -1;
892         }
893
894         if (s_info.cmd != NOP) {
895                 printf("Waiting the server response\n");
896                 return -EBUSY;
897         }
898
899         s_info.targetdir = update_target_dir(cmd);
900         if (!s_info.targetdir) {
901                 printf("%s is not exists\n", cmd);
902                 return -ENOENT;
903         }
904
905         if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
906                 printf("Access denied %s\n", cmd);
907                 return -EACCES;
908         }
909
910         send_inst_delete();
911         return 0;
912 }
913
914 static inline int do_fault(const char *cmd)
915 {
916         cmd += 5;
917         while (*cmd && *cmd == ' ') cmd++;
918         if (!*cmd) {
919                 return -1;
920         }
921
922         if (s_info.cmd != NOP) {
923                 printf("Waiting the server response\n");
924                 return -EBUSY;
925         }
926
927         s_info.targetdir = update_target_dir(cmd);
928         if (!s_info.targetdir) {
929                 printf("%s is not exists\n", cmd);
930                 return -ENOENT;
931         }
932
933         if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
934                 printf("Access denied %s\n", cmd);
935                 return -EACCES;
936         }
937
938         send_inst_fault();
939         return 0;
940 }
941
942 #if !defined(WCOREDUMP)
943 #define WCOREDUMP(a)    0
944 #endif
945
946 static void do_sh(const char *cmd)
947 {
948         pid_t pid;
949
950         cmd += 3;
951
952         while (*cmd && *cmd == ' ') {
953                 cmd++;
954         }
955
956         if (!*cmd) {
957                 return;
958         }
959
960         pid = fork();
961         if (pid == 0) {
962                 char command[256];
963                 int idx;
964                 idx = 0;
965
966                 while (idx < (sizeof(command) - 1) && *cmd && *cmd != ' ') {
967                         command[idx++] = *cmd++;
968                 }
969                 command[idx] = '\0';
970
971                 if (execl(command, cmd, NULL) < 0) {
972                         printf("Failed to execute: %s\n", strerror(errno));
973                 }
974
975                 exit(0);
976         } else if (pid < 0) {
977                 printf("Failed to create a new process: %s\n", strerror(errno));
978         } else {
979                 int status;
980                 if (waitpid(pid, &status, 0) < 0) {
981                         printf("error: %s\n", strerror(errno));
982                 } else {
983                         if (WIFEXITED(status)) {
984                                 printf("Exit: %d\n", WEXITSTATUS(status));
985                         } else if (WIFSIGNALED(status)) {
986                                 printf("Terminated by %d %s\n", WTERMSIG(status), WCOREDUMP(status) ? " - core generated" : "");
987                         } else if (WIFSTOPPED(status)) {
988                                 printf("Stopped by %d\n", WSTOPSIG(status));
989                         } else if (WIFCONTINUED(status)) {
990                                 printf("Child is resumed\n");
991                         }
992                 }
993         }
994 }
995
996 static inline int get_pixmap_size(Display *disp, Pixmap id, int *x, int *y, unsigned int *w, unsigned int *h)
997 {
998         Window dummy_win;
999         unsigned int dummy_border, dummy_depth;
1000         int _x;
1001         int _y;
1002
1003         if (!x) {
1004                 x = &_x;
1005         }
1006
1007         if (!y) {
1008                 y = &_y;
1009         }
1010
1011         if (!XGetGeometry(disp, id, &dummy_win, x, y, w, h, &dummy_border, &dummy_depth)) {
1012                 return -EFAULT;
1013         }
1014
1015         return 0;
1016 }
1017
1018 static inline int do_capture(Display *disp, Pixmap id, const char *filename)
1019 {
1020         XShmSegmentInfo si;
1021         XImage *xim;
1022         Visual *visual;
1023         unsigned int w;
1024         unsigned int h;
1025         int bufsz;
1026         int fd;
1027         Screen *screen;
1028
1029         screen = DefaultScreenOfDisplay(disp);
1030         visual = DefaultVisualOfScreen(screen);
1031
1032         if (get_pixmap_size(disp, id, NULL, NULL, &w, &h) < 0) {
1033                 printf("Failed to get size of a pixmap\n");
1034                 return -EINVAL;
1035         }
1036
1037         printf("Pixmap size: %dx%d\n", w, h);
1038         bufsz = w * h * sizeof(int);
1039
1040         si.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0666);
1041         if (si.shmid < 0) {
1042                 printf("shmget: %s\n", strerror(errno));
1043                 return -EFAULT;
1044         }
1045
1046         si.readOnly = False;
1047         si.shmaddr = shmat(si.shmid, NULL, 0);
1048         if (si.shmaddr == (void *)-1) {
1049
1050                 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1051                         printf("shmctl: %s\n", strerror(errno));
1052                 }
1053
1054                 return -EFAULT;
1055         }
1056
1057         /*!
1058          * \NOTE
1059          * Use the 24 bits Pixmap for Video player
1060          */
1061         xim = XShmCreateImage(disp, visual, 24 /* (depth << 3) */, ZPixmap, NULL, &si, w, h);
1062         if (xim == NULL) {
1063                 if (shmdt(si.shmaddr) < 0) {
1064                         printf("shmdt: %s\n", strerror(errno));
1065                 }
1066
1067                 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1068                         printf("shmctl: %s\n", strerror(errno));
1069                 }
1070
1071                 return -EFAULT;
1072         }
1073
1074         xim->data = si.shmaddr;
1075         XShmAttach(disp, &si);
1076
1077         XShmGetImage(disp, id, xim, 0, 0, 0xFFFFFFFF);
1078         XSync(disp, False);
1079
1080         fd = open(filename, O_CREAT | O_RDWR, 0644);
1081         if (fd >= 0) {
1082                 if (write(fd, xim->data, bufsz) != bufsz) {
1083                         printf("Data is not fully written\n");
1084                 }
1085
1086                 if (close(fd) < 0) {
1087                         printf("close: %s\n", strerror(errno));
1088                 }
1089         } else {
1090                 printf("Error: %sn\n", strerror(errno));
1091         }
1092
1093         XShmDetach(disp, &si);
1094         XDestroyImage(xim);
1095
1096         if (shmdt(si.shmaddr) < 0) {
1097                 printf("shmdt: %s\n", strerror(errno));
1098         }
1099
1100         if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1101                 printf("shmctl: %s\n", strerror(errno));
1102         }
1103
1104         return 0;
1105 }
1106
1107 static void do_x(const char *cmd)
1108 {
1109         Display *disp;
1110
1111         cmd += 2;
1112
1113         while (*cmd && *cmd == ' ') {
1114                 cmd++;
1115         }
1116
1117         if (!*cmd) {
1118                 return;
1119         }
1120
1121         disp = XOpenDisplay(NULL);
1122         if (!disp) {
1123                 printf("Failed to connect to the X\n");
1124                 return;
1125         }
1126
1127         if (!strncasecmp(cmd, "damage ", 7)) {
1128                 unsigned int winId;
1129                 XRectangle rect;
1130                 XserverRegion region;
1131                 int x, y, w, h;
1132
1133                 cmd += 7;
1134
1135                 if (sscanf(cmd, "%u %d %d %d %d", &winId, &x, &y, &w, &h) != 5) {
1136                         printf("Invalid argument\nx damage WINID_DEC X Y W H\n");
1137                         return;
1138                 }
1139                 rect.x = x;
1140                 rect.y = y;
1141                 rect.width = w;
1142                 rect.height = h;
1143                 region = XFixesCreateRegion(disp, &rect, 1);
1144                 XDamageAdd(disp, winId, region);
1145                 XFixesDestroyRegion(disp, region);
1146                 XFlush(disp);
1147
1148                 printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h);
1149         } else if (!strncasecmp(cmd, "capture ", 8)) {
1150                 unsigned int winId;
1151                 char filename[256];
1152
1153                 cmd += 8;
1154
1155                 if (sscanf(cmd, "%u %255[^ ]", &winId, filename) != 2) {
1156                         printf("Invalid argument\nx capture WINID_DEC FILENAME (%s)\n", cmd);
1157                         return;
1158                 }
1159                 if (do_capture(disp, winId, filename) == 0) {
1160                         printf("Captured: %s\n", filename);
1161                 }
1162         } else if (!strncasecmp(cmd, "resize ", 7)) {
1163                 unsigned int winId;
1164                 int w;
1165                 int h;
1166
1167                 cmd += 7;
1168
1169                 if (sscanf(cmd, "%u %d %d", &winId, &w, &h) != 3) {
1170                         printf("Invalid argument\nx resize WINID_DEC W H\n");
1171                         return;
1172                 }
1173
1174                 XResizeWindow(disp, winId, w, h);
1175                 printf("Resize: %u %d %d\n", winId, w, h);
1176         } else if (!strncasecmp(cmd, "move ", 5)) {
1177                 unsigned int winId;
1178                 int x;
1179                 int y;
1180
1181                 cmd += 5;
1182                 if (sscanf(cmd, "%u %d %d", &winId, &x, &y) != 3) {
1183                         printf("Invalid argument\nx move WINID_DEC X Y\n");
1184                         return;
1185                 }
1186
1187                 XMoveWindow(disp, winId, x, y);
1188                 printf("Move: %u %d %d\n", winId, x, y);
1189         } else if (!strncasecmp(cmd, "map ", 4)) {
1190                 unsigned int winId;
1191                 cmd += 4;
1192                 if (sscanf(cmd, "%u", &winId) != 1) {
1193                         printf("Invalid argument\nx map WINID_DEC\n");
1194                         return;
1195                 }
1196                 XMapRaised(disp, winId);
1197                 printf("Map: %u\n", winId);
1198         } else if (!strncasecmp(cmd, "unmap ", 6)) {
1199                 unsigned int winId;
1200                 cmd += 6;
1201                 if (sscanf(cmd, "%u", &winId) != 1) {
1202                         printf("Invalid argument\nx unmap WINID_DEC\n");
1203                         return;
1204                 }
1205                 XUnmapWindow(disp, winId);
1206                 printf("Unmap: %u\n", winId);
1207         } else {
1208                 printf("Unknown command\n");
1209         }
1210
1211         XCloseDisplay(disp);
1212 }
1213
1214 static inline void put_command(const char *cmd)
1215 {
1216         if (s_info.history[s_info.history_top]) {
1217                 free(s_info.history[s_info.history_top]);
1218                 s_info.history[s_info.history_top] = NULL;
1219         }
1220
1221         s_info.history[s_info.history_top] = strdup(cmd);
1222         s_info.history_top = (s_info.history_top + !!s_info.history[s_info.history_top]) % (sizeof(s_info.history) / sizeof(s_info.history[0]));
1223 }
1224
1225 static inline const char *get_command(int idx)
1226 {
1227         idx = s_info.history_top + idx;
1228         while (idx < 0) {
1229                 idx += (sizeof(s_info.history) / sizeof(s_info.history[0]));
1230         }
1231
1232         return s_info.history[idx];
1233 }
1234
1235 static inline void do_command(const char *cmd)
1236 {
1237         /* Skip the first spaces */
1238         while (*cmd && *cmd == ' ') {
1239                 cmd++;
1240         }
1241
1242         if (strlen(cmd) && *cmd != '#') {
1243                 if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "quit", 4)) {
1244                         ecore_main_loop_quit();
1245                 } else if (!strncasecmp(cmd, "set ", 4)) {
1246                         if (do_set(cmd) == 0) {
1247                                 return;
1248                         }
1249                 } else if (!strncasecmp(cmd, "stat ", 5)) {
1250                         do_stat(cmd);
1251                 } else if (!strncasecmp(cmd, "get ", 4)) {
1252                         if (do_get(cmd) == 0) {
1253                                 return;
1254                         }
1255                 } else if (!strncasecmp(cmd, "ls", 2)) {
1256                         if (do_ls(cmd) == 0) {
1257                                 return;
1258                         }
1259                 } else if (!strncasecmp(cmd, "cd", 2)) {
1260                         if (do_cd(cmd) == 0) {
1261                                 return;
1262                         }
1263                 } else if (!strncasecmp(cmd, "rm", 2)) {
1264                         if (do_rm(cmd) == 0) {
1265                                 return;
1266                         }
1267                 } else if (!strncasecmp(cmd, "fault", 5)) {
1268                         if (do_fault(cmd) == 0) {
1269                                 return;
1270                         }
1271                 } else if (!strncasecmp(cmd, "sh ", 3)) {
1272                         do_sh(cmd);
1273                 } else if (!strncasecmp(cmd, "x ", 2)) {
1274                         do_x(cmd);
1275                 } else {
1276                         help();
1277                 }
1278         }
1279
1280         prompt(NULL);
1281         return;
1282 }
1283
1284 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
1285 {
1286         static int idx = 0;
1287         static char cmd_buffer[256];
1288         char ch;
1289         int fd;
1290         int ret;
1291         const char escape_str[] = { 0x1b, 0x5b, 0x0 };
1292         const char *escape_ptr = escape_str;
1293         const char *tmp;
1294
1295         if (fd_handler) {
1296                 fd = ecore_main_fd_handler_fd_get(fd_handler);
1297                 if (fd < 0) {
1298                         printf("FD is not valid: %d\n", fd);
1299                         return ECORE_CALLBACK_CANCEL;
1300                 }
1301         } else {
1302                 fd = s_info.input_fd;
1303         }
1304
1305         /*!
1306          * \note
1307          * Using this routine, we can implement the command recommend algorithm.
1308          * When a few more characters are matched with history of command, we can show it to user
1309          * Then the user will choose one or write new command
1310          */
1311
1312         /* Silly.. Silly */
1313         while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) {
1314                 if (*escape_ptr == '\0') {
1315                         /* Function key */
1316                         switch (ch) {
1317                         case 0x41: /* UP */
1318                                 printf("%s2K%s1G", escape_str, escape_str);
1319                                 tmp = get_command(--s_info.history_idx);
1320                                 if (!tmp) {
1321                                         s_info.history_idx = 0;
1322                                         cmd_buffer[0] = '\0';
1323                                         prompt(NULL);
1324                                 } else {
1325                                         strcpy(cmd_buffer, tmp);
1326                                         idx = strlen(cmd_buffer);
1327                                         prompt(cmd_buffer);
1328                                 }
1329                                 break;
1330                         case 0x42: /* DOWN */
1331                                 if (s_info.history_idx >= 0) {
1332                                         break;
1333                                 }
1334
1335                                 printf("%s2K%s1G", escape_str, escape_str);
1336                                 tmp = get_command(++s_info.history_idx);
1337                                 if (s_info.history_idx == 0) {
1338                                         s_info.history_idx = 0;
1339                                         cmd_buffer[0] = '\0';
1340                                         prompt(NULL);
1341                                 } else {
1342                                         strcpy(cmd_buffer, tmp);
1343                                         idx = strlen(cmd_buffer);
1344                                         prompt(cmd_buffer);
1345                                 }
1346                                 break;
1347                         case 0x43: /* RIGHT */
1348                                 break;
1349                         case 0x44: /* LEFT */
1350                                 break;
1351                         default:
1352                                 break;
1353                         }
1354
1355                         escape_ptr = escape_str;
1356                         continue;
1357                 } else if (ch == *escape_ptr) {
1358                         escape_ptr++;
1359                         continue;
1360                 }
1361
1362                 switch (ch) {
1363                 case 0x08: /* BKSP */
1364                         cmd_buffer[idx] = '\0';
1365                         if (idx > 0) {
1366                                 idx--;
1367                                 cmd_buffer[idx] = ' ';
1368                                 putc('\r', stdout);
1369                                 prompt(cmd_buffer);
1370                         }
1371
1372                         cmd_buffer[idx] = '\0';
1373                         putc('\r', stdout);
1374                         prompt(cmd_buffer);
1375                         break;
1376                 case 0x09: /* TAB */
1377                         if (!s_info.quick_search_node) {
1378                                 s_info.quick_search_node = node_child(s_info.curdir);
1379                                 s_info.quick_idx = idx;
1380                         } else {
1381                                 s_info.quick_search_node = node_next_sibling(s_info.quick_search_node);
1382                                 idx = s_info.quick_idx;
1383                         }
1384
1385                         if (!s_info.quick_search_node) {
1386                                 break;
1387                         }
1388
1389                         printf("%s2K%s1G", escape_str, escape_str);
1390                         strcpy(cmd_buffer + idx, node_name(s_info.quick_search_node));
1391                         idx += strlen(node_name(s_info.quick_search_node));
1392                         prompt(cmd_buffer);
1393                         break;
1394                 case '\n':
1395                 case '\r':
1396                         cmd_buffer[idx] = '\0';
1397                         idx = 0;
1398                         if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1399                                 putc((int)'\n', stdout);
1400                         }
1401                         do_command(cmd_buffer);
1402                         put_command(cmd_buffer);
1403                         memset(cmd_buffer, 0, sizeof(cmd_buffer));
1404                         s_info.history_idx = 0;
1405                         s_info.quick_search_node = NULL;
1406
1407                         /* Make a main loop processing for command handling */
1408                         return ECORE_CALLBACK_RENEW;
1409                 default:
1410                         cmd_buffer[idx++] = ch;
1411
1412                         if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1413                                 putc((int)ch, stdout);
1414                         }
1415
1416                         if (idx == sizeof(cmd_buffer) - 1) {
1417                                 cmd_buffer[idx] = '\0';
1418                                 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
1419                                 idx = 0;
1420                         }
1421                         break;
1422                 }
1423         }
1424
1425         if (ret < 0 && !fd_handler) {
1426                 ecore_main_loop_quit();
1427         }
1428
1429         return ECORE_CALLBACK_RENEW;
1430 }
1431
1432 static void processing_line_buffer(const char *buffer)
1433 {
1434         int pid;
1435         char slavename[256];
1436         char pkgname[256];
1437         char abi[256];
1438         char inst_id[4096];
1439         char cluster[256];
1440         char category[256];
1441         char state[10];
1442         int refcnt;
1443         int fault_count;
1444         int list_count;
1445         int loaded_inst;
1446         int loaded_pkg;
1447         double ttl;
1448         int secured;
1449         double period;
1450         int width;
1451         int height;
1452         struct node *node;
1453         struct package *pkginfo;
1454         struct instance *instinfo;
1455         struct slave *slaveinfo;
1456         int i;
1457
1458         switch (s_info.cmd) {
1459         case PKG_LIST:
1460                 if (sscanf(buffer, "%d %255[^ ] %255[^ ] %255[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
1461                         printf("Invalid format : [%s]\n", buffer);
1462                         return;
1463                 }
1464
1465                 node = node_find(s_info.targetdir, pkgname);
1466                 if (!node) {
1467                         pkginfo = calloc(1, sizeof(*pkginfo));
1468                         if (!pkginfo) {
1469                                 printf("Error: %s\n", strerror(errno));
1470                                 return;
1471                         }
1472
1473                         pkginfo->pkgid = strdup("conf.file");
1474                         if (!pkginfo->pkgid) {
1475                                 printf("Error: %s\n", strerror(errno));
1476                         }
1477
1478                         pkginfo->primary = 1;
1479
1480                         node = node_create(s_info.targetdir, pkgname, NODE_DIR);
1481                         if (!node) {
1482                                 free(pkginfo->pkgid);
1483                                 free(pkginfo);
1484                                 printf("Failed to create a new node (%s)\n", pkgname);
1485                                 return;
1486                         }
1487
1488                         node_set_mode(node, NODE_READ | NODE_EXEC);
1489                         node_set_data(node, pkginfo);
1490                 } else {
1491                         pkginfo = node_data(node);
1492                         if (!pkginfo) {
1493                                 printf("Package info is inavlid\n");
1494                                 return;
1495                         }
1496
1497                         free(pkginfo->slavename);
1498                         free(pkginfo->abi);
1499
1500                         pkginfo->slavename = NULL;
1501                         pkginfo->abi = NULL;
1502                 }
1503
1504                 node_set_age(node, s_info.age);
1505
1506                 pkginfo->slavename = strdup(slavename);
1507                 if (!pkginfo->slavename) {
1508                         printf("Error: %s\n", strerror(errno));
1509                 }
1510
1511                 pkginfo->abi = strdup(abi);
1512                 if (!pkginfo->abi) {
1513                         printf("Error: %s\n", strerror(errno));
1514                 }
1515
1516                 pkginfo->pid = pid;
1517                 pkginfo->refcnt = refcnt;
1518                 pkginfo->fault_count = fault_count;
1519                 pkginfo->inst_count = list_count;
1520                 break;
1521         case SLAVE_LIST:
1522                 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) {
1523                         printf("Invalid format : [%s]\n", buffer);
1524                         return;
1525                 }
1526                 node = node_find(s_info.targetdir, slavename);
1527                 if (!node) {
1528                         slaveinfo = calloc(1, sizeof(*slaveinfo));
1529                         if (!slaveinfo) {
1530                                 printf("Error: %s\n", strerror(errno));
1531                                 return;
1532                         }
1533
1534                         node = node_create(s_info.targetdir, slavename, NODE_DIR);
1535                         if (!node) {
1536                                 free(slaveinfo);
1537                                 return;
1538                         }
1539
1540                         node_set_mode(node, NODE_READ | NODE_EXEC);
1541                         node_set_data(node, slaveinfo);
1542                 } else {
1543                         slaveinfo = node_data(node);
1544                 }
1545
1546                 node_set_age(node, s_info.age);
1547
1548                 free(slaveinfo->pkgname);
1549                 free(slaveinfo->abi);
1550                 free(slaveinfo->state);
1551
1552                 slaveinfo->pkgname = strdup(pkgname);
1553                 if (!slaveinfo->pkgname) {
1554                         printf("Error: %s\n", strerror(errno));
1555                 }
1556
1557                 slaveinfo->abi = strdup(abi);
1558                 if (!slaveinfo->abi) {
1559                         printf("Error: %s\n", strerror(errno));
1560                 }
1561
1562                 slaveinfo->state = strdup(state);
1563                 if (!slaveinfo->state) {
1564                         printf("Error: %s\n", strerror(errno));
1565                 }
1566
1567                 slaveinfo->pid = pid;
1568                 slaveinfo->secured = secured;
1569                 slaveinfo->refcnt = refcnt;
1570                 slaveinfo->fault_count = fault_count;
1571                 slaveinfo->loaded_inst = loaded_inst;
1572                 slaveinfo->loaded_pkg = loaded_pkg;
1573                 slaveinfo->ttl = ttl;
1574                 break;
1575         case INST_LIST:
1576                 if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
1577                         printf("Invalid format : [%s]\n", buffer);
1578                         return;
1579                 }
1580
1581                 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
1582                 i += (inst_id[i] == '/');
1583
1584                 node = node_find(s_info.targetdir, inst_id + i);
1585                 if (!node) {
1586                         instinfo = calloc(1, sizeof(*instinfo));
1587                         if (!instinfo) {
1588                                 printf("Error: %s\n", strerror(errno));
1589                                 return;
1590                         }
1591
1592                         node = node_create(s_info.targetdir, inst_id + i, NODE_FILE);
1593                         if (!node) {
1594                                 free(instinfo);
1595                                 return;
1596                         }
1597
1598                         node_set_mode(node, NODE_READ | NODE_WRITE);
1599                         node_set_data(node, instinfo);
1600                 } else {
1601                         instinfo = node_data(node);
1602                 }
1603
1604                 node_set_age(node, s_info.age);
1605
1606                 free(instinfo->id);
1607                 free(instinfo->cluster);
1608                 free(instinfo->category);
1609                 free(instinfo->state);
1610
1611                 instinfo->id = strdup(inst_id);
1612                 if (!instinfo->id) {
1613                         printf("Error: %s\n", strerror(errno));
1614                 }
1615
1616                 instinfo->cluster = strdup(cluster);
1617                 if (!instinfo->cluster) {
1618                         printf("Error: %s\n", strerror(errno));
1619                 }
1620
1621                 instinfo->category = strdup(category);
1622                 if (!instinfo->category) {
1623                         printf("Error: %s\n", strerror(errno));
1624                 }
1625
1626                 instinfo->state = strdup(state);
1627                 if (!instinfo->state) {
1628                         printf("Error: %s\n", strerror(errno));
1629                 }
1630
1631                 instinfo->period = period;
1632                 instinfo->width = width;
1633                 instinfo->height = height;
1634                 break;
1635         case INST_CTRL:
1636                 sscanf(buffer, "%d", &i);
1637                 printf("%s\n", strerror(i));
1638                 printf("Result: %d\n", i);
1639                 break;
1640         case SLAVE_CTRL:
1641                 sscanf(buffer, "%d", &i);
1642                 printf("Result: %d\n", i);
1643                 break;
1644         case MASTER_CTRL:
1645                 sscanf(buffer, "%d", &i);
1646                 printf("Result: %d\n", i);
1647                 break;
1648         default:
1649                 break;
1650         }
1651 }
1652
1653 static inline void do_line_command(void)
1654 {
1655         switch (s_info.cmd) {
1656         case PKG_LIST:
1657                 ls();
1658                 break;
1659         case INST_LIST:
1660                 ls();
1661                 break;
1662         case SLAVE_LIST:
1663                 ls();
1664                 break;
1665         case INST_CTRL:
1666                 break;
1667         case SLAVE_CTRL:
1668                 break;
1669         case MASTER_CTRL:
1670                 break;
1671         default:
1672                 break;
1673         }
1674         prompt(NULL);
1675 }
1676
1677 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
1678 {
1679         int fd;
1680         static char *line_buffer = NULL;
1681         static int line_index = 0;
1682         static int bufsz = 256;
1683         char ch;
1684
1685         fd = ecore_main_fd_handler_fd_get(fd_handler);
1686         if (fd < 0) {
1687                 printf("FD is not valid: %d\n", fd);
1688                 return ECORE_CALLBACK_CANCEL;
1689         }
1690
1691         if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
1692                 printf("Error: %s\n", strerror(errno));
1693                 return ECORE_CALLBACK_CANCEL;
1694         }
1695
1696         if (!line_buffer) {
1697                 line_index = 0;
1698                 line_buffer = malloc(bufsz);
1699                 if (!line_buffer) {
1700                         printf("Error: %s\n", strerror(errno));
1701                         return ECORE_CALLBACK_CANCEL;
1702                 }
1703         }       
1704
1705         if (ch == '\n') { /* End of a line */
1706                 if (line_index == bufsz - 1) {
1707                         char *new_buf;
1708                         new_buf = realloc(line_buffer, bufsz + 2);
1709                         if (!new_buf) {
1710                                 printf("Error: %s\n", strerror(errno));
1711                                 free(line_buffer);
1712                                 line_buffer = NULL;
1713                                 line_index = 0;
1714                                 bufsz = 256;
1715                                 return ECORE_CALLBACK_CANCEL;
1716                         }
1717
1718                         line_buffer = new_buf;
1719                 }
1720
1721                 line_buffer[line_index] = '\0';
1722
1723                 if (!strcmp(line_buffer, "EOD")) {
1724                         do_line_command();
1725                         s_info.cmd = NOP;
1726                 } else {
1727                         processing_line_buffer(line_buffer);
1728                 }
1729
1730                 free(line_buffer);
1731                 line_buffer = NULL;
1732                 line_index = 0;
1733                 bufsz = 256;
1734         } else {
1735                 char *new_buf;
1736
1737                 line_buffer[line_index++] = ch;
1738                 if (line_index == bufsz - 1) {
1739                         bufsz += 256;
1740                         new_buf = realloc(line_buffer, bufsz);
1741                         if (!new_buf) {
1742                                 printf("Error: %s\n", strerror(errno));
1743                                 free(line_buffer);
1744                                 line_buffer = NULL;
1745                                 line_index = 0;
1746                                 bufsz = 256;
1747                                 return ECORE_CALLBACK_CANCEL;
1748                         }
1749
1750                         line_buffer = new_buf;
1751                 }
1752         }
1753
1754         return ECORE_CALLBACK_RENEW;
1755 }
1756
1757 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1758 {
1759         const char *fifo_name;
1760         int ret;
1761
1762         if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
1763                 printf("Invalid packet\n");
1764                 return -EFAULT;
1765         }
1766
1767         if (ret != 0) {
1768                 printf("Returns %d\n", ret);
1769                 return ret;
1770         }
1771
1772         printf("FIFO: %s\n", fifo_name);
1773
1774         s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
1775         if (s_info.fifo_handle < 0) {
1776                 printf("Error: %s\n", strerror(errno));
1777                 s_info.fifo_handle = -EINVAL;
1778                 ecore_main_loop_quit();
1779                 return -EINVAL;
1780         }
1781
1782         s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
1783         if (!s_info.fd_handler) {
1784                 printf("Failed to add a fd handler\n");
1785                 if (close(s_info.fifo_handle) < 0) {
1786                         printf("close: %s\n", strerror(errno));
1787                 }
1788                 s_info.fifo_handle = -EINVAL;
1789                 ecore_main_loop_quit();
1790                 return -EFAULT;
1791         }
1792
1793         prompt(NULL);
1794
1795         if (s_info.input_fd == STDIN_FILENO) {
1796                 if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0) {
1797                         printf("Error: %s\n", strerror(errno));
1798                 }
1799
1800                 s_info.in_handler = ecore_main_fd_handler_add(s_info.input_fd, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
1801                 if (!s_info.in_handler) {
1802                         printf("Failed to add a input handler\n");
1803                         ecore_main_loop_quit();
1804                         return -EFAULT;
1805                 }
1806         }
1807
1808         return 0;
1809 }
1810
1811 static int disconnected_cb(int handle, void *data)
1812 {
1813         printf("Disconnected\n");
1814         ecore_main_loop_quit();
1815         return 0;
1816 }
1817
1818 static int connected_cb(int handle, void *data)
1819 {
1820         struct packet *packet;
1821
1822         printf("Connected\n");
1823
1824         packet = packet_create("liveinfo_hello", "d", 0.0f);
1825         if (!packet) {
1826                 printf("Failed to build a packet for hello\n");
1827                 com_core_packet_client_fini(s_info.fd);
1828                 s_info.fd = -EINVAL;
1829                 return -EFAULT;
1830         }
1831
1832         s_info.fd = handle;
1833
1834         if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
1835                 printf("Failed to send a packet hello\n");
1836                 packet_destroy(packet);
1837                 com_core_packet_client_fini(s_info.fd);
1838                 s_info.fd = -EINVAL;
1839                 return -EFAULT;
1840         }
1841
1842         packet_destroy(packet);
1843         return 0;
1844 }
1845
1846 int main(int argc, char *argv[])
1847 {
1848         struct termios ttystate;
1849         static struct method s_table[] = {
1850                 {
1851                         .cmd = NULL,
1852                         .handler = NULL,
1853                 },
1854         };
1855         static struct option long_options[] = {
1856                 { "batchmode", required_argument, 0, 'b' },
1857                 { "help", no_argument, 0, 'h' },
1858                 { "verbose", required_argument, 0, 'v' },
1859                 { "execute", required_argument, 0, 'x' },
1860                 { 0, 0, 0, 0 }
1861         };
1862         int option_index;
1863         int c;
1864
1865         do {
1866                 c = getopt_long(argc, argv, "b:hv:", long_options, &option_index);
1867                 switch (c) {
1868                 case 'b':
1869                         if (!optarg || !*optarg) {
1870                                 printf("Invalid argument\n");
1871                                 help();
1872                                 return -EINVAL;
1873                         }
1874
1875                         if (s_info.input_fd != STDIN_FILENO) {
1876                                 /* Close the previously, opened file */
1877                                 if (close(s_info.input_fd) < 0) {
1878                                         printf("close: %s\n", strerror(errno));
1879                                 }
1880                         }
1881
1882                         s_info.input_fd = open(optarg, O_RDONLY);
1883                         if (s_info.input_fd < 0) {
1884                                 printf("Unable to access %s (%s)\n", optarg, strerror(errno));
1885                                 return -EIO;
1886                         }
1887                         break;
1888                 case 'h':
1889                         help();
1890                         return 0;
1891                 case 'v':
1892                         if (!optarg || !*optarg) {
1893                                 printf("Invalid argument\n");
1894                                 help();
1895                                 return -EINVAL;
1896                         }
1897
1898                         s_info.verbose = !strcmp(optarg, "true");
1899                         break;
1900                 case 'x':
1901                         if (!optarg || !*optarg) {
1902                                 printf("Invalid argument\n");
1903                                 help();
1904                                 return -EINVAL;
1905                         }
1906                         break;
1907                 default:
1908                         break;
1909                 }
1910         } while (c != -1);
1911
1912         ecore_init();
1913
1914 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
1915         g_type_init();
1916 #endif
1917
1918         com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1919         com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1920         livebox_service_init();
1921
1922         s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
1923         if (s_info.fd < 0) {
1924                 printf("Failed to make a connection\n");
1925                 return -EIO;
1926         }
1927
1928         if (s_info.input_fd == STDIN_FILENO) {
1929                 printf("Type your command on below empty line\n");
1930
1931                 if (tcgetattr(s_info.input_fd, &ttystate) < 0) {
1932                         printf("Error: %s\n", strerror(errno));
1933                 } else {
1934                         ttystate.c_lflag &= ~(ICANON | ECHO);
1935                         ttystate.c_cc[VMIN] = 1;
1936
1937                         if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
1938                                 printf("Error: %s\n", strerror(errno));
1939                         }
1940                 }
1941         } else {
1942                 printf("Batch mode enabled\n");
1943         }
1944
1945         if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0) {
1946                 printf("Error: %s\n", strerror(errno));
1947         }
1948
1949         init_directory();
1950
1951         ecore_main_loop_begin();
1952
1953         fini_directory();
1954         livebox_service_fini();
1955
1956         if (s_info.fd > 0) {
1957                 com_core_packet_client_fini(s_info.fd);
1958                 s_info.fd = -EINVAL;
1959         }
1960
1961         if (s_info.fd_handler) {
1962                 ecore_main_fd_handler_del(s_info.fd_handler);
1963                 s_info.fd_handler = NULL;
1964         }
1965
1966         if (s_info.input_fd == STDIN_FILENO) {
1967                 ttystate.c_lflag |= ICANON | ECHO;
1968                 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
1969                         printf("Error: %s\n", strerror(errno));
1970                 }
1971         } else {
1972                 if (close(s_info.input_fd) < 0) {
1973                         printf("close: %s\n", strerror(errno));
1974                 }
1975         }
1976
1977         if (s_info.fifo_handle > 0) {
1978                 if (close(s_info.fifo_handle) < 0) {
1979                         printf("close: %s\n", strerror(errno));
1980                 }
1981                 s_info.fifo_handle = -EINVAL;
1982         }
1983
1984         if (s_info.in_handler) {
1985                 ecore_main_fd_handler_del(s_info.in_handler);
1986                 s_info.in_handler = NULL;
1987         }
1988
1989         ecore_shutdown();
1990         putc((int)'\n', stdout);
1991         return 0;
1992 }
1993
1994 /* End of a file */