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