2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
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.
22 #include <sys/types.h>
31 #include <X11/extensions/Xdamage.h>
32 #include <X11/extensions/Xfixes.h>
33 #include <X11/extensions/XShm.h>
34 #include <X11/Xutil.h>
37 #include <glib-object.h>
40 #include <com-core_packet.h>
43 #include <livebox-service.h>
50 #define PROMPT "liveinfo "
100 Ecore_Fd_Handler *fd_handler;
101 Ecore_Fd_Handler *in_handler;
103 struct node *rootdir;
105 struct node *targetdir;
118 struct node *quick_search_node;
121 .fifo_handle = -EINVAL,
129 .input_fd = STDIN_FILENO,
135 .quick_search_node = NULL,
145 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler);
147 static Eina_Bool process_line_cb(void *data)
149 input_cb(NULL, NULL);
150 return ECORE_CALLBACK_CANCEL;
153 static inline void prompt(const char *cmdline)
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);
163 path = node_to_abspath(s_info.curdir);
164 printf(PROMPT"%s # %s", path, cmdline ? cmdline : "");
168 static void provider_del_cb(struct node *node)
172 info = node_data(node);
182 static void package_del_cb(struct node *node)
184 struct package *info;
186 info = node_data(node);
191 free(info->slavename);
196 static void inst_del_cb(struct node *node)
198 struct instance *info;
200 info = node_data(node);
206 free(info->category);
211 static inline void ls(void)
218 struct node *next_node;
220 if (!(node_mode(s_info.targetdir) & NODE_READ)) {
221 printf("Access denied\n");
225 is_package = node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "package");
226 is_provider = !is_package && node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "provider");
227 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");
229 node = node_child(s_info.targetdir);
232 struct package *info;
234 next_node = node_next_sibling(node);
235 if (node_age(node) != s_info.age) {
236 node_delete(node, package_del_cb);
241 info = node_data(node);
242 printf(" %3d %20s %5s ", info->inst_count, info->slavename ? info->slavename : "(none)", info->abi ? info->abi : "?");
243 } else if (is_provider) {
246 next_node = node_next_sibling(node);
247 if (node_age(node) != s_info.age) {
248 node_delete(node, provider_del_cb);
253 info = node_data(node);
254 printf("%6d %3d %5s %5.2f ", info->pid, info->loaded_inst, info->abi ? info->abi : "?", info->ttl);
255 } else if (is_instance) {
256 struct instance *info;
260 next_node = node_next_sibling(node);
262 if (node_age(node) != s_info.age) {
263 node_delete(node, inst_del_cb);
268 info = node_data(node);
270 printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
271 snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
272 if (lstat(buf, &stat) < 0)
273 printf("%3d ERR ", errno);
275 printf("%2.2lf KB ", (double)stat.st_size / 1024.0f);
278 if (node_type(node) == NODE_DIR)
279 printf("%s/", node_name(node));
280 else if (node_type(node) == NODE_FILE)
281 printf("%s", node_name(node));
284 node = node_next_sibling(node);
288 printf("Total: %d\n", cnt);
291 static void send_slave_list(void)
293 struct packet *packet;
295 if (s_info.cmd != NOP) {
296 printf("Previous command is not finished\n");
300 packet = packet_create_noack("slave_list", "d", 0.0f);
302 printf("Failed to create a packet\n");
306 com_core_packet_send_only(s_info.fd, packet);
307 packet_destroy(packet);
308 s_info.cmd = SLAVE_LIST;
313 * var = debug, slave_max_load
316 static void send_command(const char *cmd, const char *var, const char *val)
318 struct packet *packet;
320 if (s_info.cmd != NOP) {
321 printf("Previous command is not finished\n");
325 packet = packet_create_noack("master_ctrl", "sss", cmd, var, val);
326 com_core_packet_send_only(s_info.fd, packet);
327 packet_destroy(packet);
328 s_info.cmd = MASTER_CTRL;
332 static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
334 struct node *parent = data;
336 struct package *info;
338 node = node_find(parent, lbid);
340 info = node_data(node);
342 printf("Invalid node\n");
347 info->pkgid = strdup(appid);
349 printf("Error: %s\n", strerror(errno));
353 node_set_age(node, s_info.age);
357 info = calloc(1, sizeof(*info));
359 printf("Error: %s\n", strerror(errno));
363 info->pkgid = strdup(appid);
365 printf("Error: %s\n", strerror(errno));
370 info->primary = is_prime;
372 node = node_create(parent, lbid, NODE_DIR);
379 node_set_mode(node, NODE_READ | NODE_EXEC);
380 node_set_data(node, info);
381 node_set_age(node, s_info.age);
385 static void send_pkg_list(void)
387 struct packet *packet;
389 if (s_info.cmd != NOP) {
390 printf("Previous command is not finished\n");
394 packet = packet_create_noack("pkg_list", "d", 0.0f);
396 printf("Failed to create a packet\n");
400 com_core_packet_send_only(s_info.fd, packet);
401 packet_destroy(packet);
402 s_info.cmd = PKG_LIST;
405 livebox_service_get_pkglist(pkglist_cb, s_info.targetdir);
408 static void send_inst_delete(void)
410 struct packet *packet;
413 struct instance *inst;
415 if (s_info.cmd != NOP) {
416 printf("Previous command is not finished\n");
420 parent = node_parent(s_info.targetdir);
422 printf("Invalid argument\n");
426 if (!node_parent(parent)) {
427 printf("Invalid argument\n");
431 name = node_name(node_parent(parent));
432 if (!name || strcmp(name, "package")) {
433 printf("Invalid argument\n");
437 inst = node_data(s_info.targetdir);
438 name = node_name(parent);
440 packet = packet_create_noack("pkg_ctrl", "sss", "rminst", name, inst->id);
442 printf("Failed to create a packet\n");
446 com_core_packet_send_only(s_info.fd, packet);
447 packet_destroy(packet);
448 s_info.cmd = INST_CTRL;
452 static void send_inst_list(const char *pkgname)
454 struct packet *packet;
456 if (s_info.cmd != NOP) {
457 printf("Previous command is not finished\n");
461 packet = packet_create_noack("inst_list", "s", pkgname);
463 printf("Failed to create a packet\n");
467 com_core_packet_send_only(s_info.fd, packet);
468 packet_destroy(packet);
469 s_info.cmd = INST_LIST;
473 static inline void help(void)
475 printf("liveinfo - Livebox utility\n");
476 printf("------------------------------ [Option] ------------------------------\n");
477 printf("-b Batch mode\n");
478 printf("------------------------------ [Command list] ------------------------------\n");
479 printf("
\e[32mcd [PATH] - Change directory
\e[0m\n");
480 printf("
\e[32mls [ | PATH] - List up content as a file
\e[0m\n");
481 printf("
\e[32mrm [PKG_ID|INST_ID] - Delete package or instance
\e[0m\n");
482 printf("
\e[32mstat [path] - Display the information of given path
\e[0m\n");
483 printf("
\e[32mset [debug] [on|off] Set the control variable of master provider
\e[0m\n");
484 printf("
\e[32mx damage Pix x y w h - Create damage event for given pixmap
\e[0m\n");
485 printf("
\e[32mx move Pix x y - Move the window
\e[0m\n");
486 printf("
\e[32mx resize Pix w h - Resize the window
\e[0m\n");
487 printf("
\e[32mx map Pix - Show the window
\e[0m\n");
488 printf("
\e[32mx unmap Pix - Hide the window
\e[0m\n");
489 printf("
\e[32msh [command] Execute shell command, [command] should be abspath
\e[0m\n");
490 printf("
\e[32mexit -
\e[0m\n");
491 printf("
\e[32mquit -
\e[0m\n");
492 printf("----------------------------------------------------------------------------\n");
495 static inline void init_directory(void)
498 s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
501 node_set_mode(s_info.rootdir, NODE_READ | NODE_EXEC);
503 node = node_create(s_info.rootdir, "provider", NODE_DIR);
505 node_destroy(s_info.rootdir);
506 s_info.rootdir = NULL;
509 node_set_mode(node, NODE_READ | NODE_EXEC);
511 node = node_create(s_info.rootdir, "package", NODE_DIR);
513 node_destroy(node_child(s_info.rootdir));
514 node_destroy(s_info.rootdir);
515 s_info.rootdir = NULL;
518 node_set_mode(node, NODE_READ | NODE_EXEC);
520 s_info.curdir = s_info.rootdir;
524 static inline void fini_directory(void)
528 static inline struct node *update_target_dir(const char *cmd)
532 node = (*cmd == '/') ? s_info.rootdir : s_info.curdir;
533 node = node_find(node, cmd);
538 static int get_token(const char *src, char *out)
541 while (*src && *src == ' ') src++;
546 while (*src && *src != ' ') {
555 static inline int do_stat(const char *cmd)
570 while (*cmd && *cmd == ' ') cmd++;
573 printf("Invalid argument\n");
577 node = node_find(*cmd == '/' ? s_info.rootdir : s_info.curdir, cmd);
579 printf("Invalid path\n");
585 parent = node_parent(node);
587 if (!node_name(parent)) {
588 printf("%s has no info\n", node_name(node));
590 } else if (!strcmp(node_name(parent), "package")) {
591 type = (i == 0) ? PKG : PKG_INSTANCE;
593 } else if (!strcmp(node_name(parent), "provider")){
594 type = (i == 0) ? PROVIDER : PROVIDER_INSTANCE;
598 parent = node_parent(parent);
601 printf("%s is invalid path\n", node_name(node));
608 tmp = livebox_service_i18n_name(node_name(node), NULL);
609 printf("Name: %s (", tmp);
612 i = livebox_service_is_enabled(node_name(node));
613 printf("%s)\n", i ? "enabled" : "disabled");
615 tmp = livebox_service_i18n_icon(node_name(node), NULL);
616 printf("Icon: %s\n", tmp);
619 tmp = livebox_service_provider_name(node_name(node));
620 printf("Provider: %s (content:", tmp);
623 tmp = livebox_service_content(node_name(node));
624 printf("%s)\n", tmp);
627 tmp = livebox_service_lb_script_path(node_name(node));
628 printf("LB Script: %s (", tmp);
631 tmp = livebox_service_lb_script_group(node_name(node));
632 printf("%s)\n", tmp);
635 tmp = livebox_service_pd_script_path(node_name(node));
636 printf("PD Script: %s (", tmp);
639 tmp = livebox_service_pd_script_group(node_name(node));
640 printf("%s)\n", tmp);
643 i = livebox_service_mouse_event(node_name(node));
644 printf("Mouse event: %s\n", i ? "enabled" : "disabled");
646 i = livebox_service_touch_effect(node_name(node));
647 printf("Touch effect: %s\n", i ? "enabled" : "disabled");
650 printf("Not supported yet\n");
653 printf("Not supported yet\n");
655 case PROVIDER_INSTANCE:
656 printf("Not supported yet\n");
659 printf("Not supported yet\n");
666 static inline int do_set(const char *cmd)
669 char variable[4096] = { '0', };
672 i = get_token(cmd, variable);
675 while (*cmd && *cmd == ' ') cmd++;
678 printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
682 send_command("set", variable, cmd);
686 static inline int do_get(const char *cmd)
690 while (*cmd && *cmd == ' ') cmd++;
692 printf("Invalid argument(%s): get [VAR]\n", cmd);
696 send_command("get", cmd, "");
700 static inline int do_ls(const char *cmd)
707 while (*cmd && *cmd == ' ')
710 s_info.targetdir = *cmd ? update_target_dir(cmd) : s_info.curdir;
711 if (!s_info.targetdir) {
712 printf("%s is not exists\n", cmd);
716 name = node_name(s_info.targetdir);
718 if (!strcmp(name, "package")) {
719 if (s_info.cmd == NOP) {
724 printf("Waiting the server response\n");
726 } else if (!strcmp(name, "provider")) {
727 if (s_info.cmd == NOP) {
732 printf("Waiting the server response\n");
737 parent = node_parent(s_info.targetdir);
738 if (parent && node_name(parent)) {
739 if (!strcmp(node_name(parent), "package")) {
740 if (s_info.cmd != NOP) {
741 printf("Waiting the server response\n");
745 send_inst_list(name);
754 static inline int do_cd(const char *cmd)
758 while (*cmd && *cmd == ' ')
764 if (s_info.cmd != NOP) {
765 printf("Waiting the server response\n");
769 s_info.targetdir = update_target_dir(cmd);
770 if (!s_info.targetdir) {
771 printf("%s is not exists\n", cmd);
775 if (node_type(s_info.targetdir) != NODE_DIR) {
776 printf("Unable change directory to %s\n", cmd);
780 if (!(node_mode(s_info.targetdir) & NODE_EXEC)) {
781 printf("Access denied %s\n", cmd);
785 s_info.curdir = s_info.targetdir;
789 static inline int do_rm(const char *cmd)
792 while (*cmd && *cmd == ' ') cmd++;
796 if (s_info.cmd != NOP) {
797 printf("Waiting the server response\n");
801 s_info.targetdir = update_target_dir(cmd);
802 if (!s_info.targetdir) {
803 printf("%s is not exists\n", cmd);
807 if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
808 printf("Access denied %s\n", cmd);
816 #if !defined(WCOREDUMP)
817 #define WCOREDUMP(a) 0
820 static inline void do_sh(const char *cmd)
826 while (*cmd && *cmd == ' ') cmd++;
836 while (idx < (sizeof(command) - 1) && *cmd && *cmd != ' ')
837 command[idx++] = *cmd++;
840 if (execl(command, cmd, NULL) < 0)
841 printf("Failed to execute: %s\n", strerror(errno));
844 } else if (pid < 0) {
845 printf("Failed to create a new process: %s\n", strerror(errno));
848 if (waitpid(pid, &status, 0) < 0) {
849 printf("error: %s\n", strerror(errno));
851 if (WIFEXITED(status)) {
852 printf("Exit: %d\n", WEXITSTATUS(status));
853 } else if (WIFSIGNALED(status)) {
854 printf("Terminated by %d %s\n", WTERMSIG(status), WCOREDUMP(status) ? " - core generated" : "");
855 } else if (WIFSTOPPED(status)) {
856 printf("Stopped by %d\n", WSTOPSIG(status));
857 } else if (WIFCONTINUED(status)) {
858 printf("Child is resumed\n");
864 static inline int get_pixmap_size(Display *disp, Pixmap id, int *x, int *y, unsigned int *w, unsigned int *h)
867 unsigned int dummy_border, dummy_depth;
876 if (!XGetGeometry(disp, id, &dummy_win, x, y, w, h, &dummy_border, &dummy_depth))
882 static inline int do_capture(Display *disp, Pixmap id, const char *filename)
893 screen = DefaultScreenOfDisplay(disp);
894 visual = DefaultVisualOfScreen(screen);
896 if (get_pixmap_size(disp, id, NULL, NULL, &w, &h) < 0) {
897 printf("Failed to get size of a pixmap\n");
901 printf("Pixmap size: %dx%d\n", w, h);
902 bufsz = w * h * sizeof(int);
904 si.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0666);
906 printf("shmget: %s\n", strerror(errno));
911 si.shmaddr = shmat(si.shmid, NULL, 0);
912 if (si.shmaddr == (void *)-1) {
914 if (shmctl(si.shmid, IPC_RMID, 0) < 0)
915 printf("shmctl: %s\n", strerror(errno));
922 * Use the 24 bits Pixmap for Video player
924 xim = XShmCreateImage(disp, visual, 24 /* (depth << 3) */, ZPixmap, NULL, &si, w, h);
926 if (shmdt(si.shmaddr) < 0)
927 printf("shmdt: %s\n", strerror(errno));
929 if (shmctl(si.shmid, IPC_RMID, 0) < 0)
930 printf("shmctl: %s\n", strerror(errno));
935 xim->data = si.shmaddr;
936 XShmAttach(disp, &si);
938 XShmGetImage(disp, id, xim, 0, 0, 0xFFFFFFFF);
941 fd = open(filename, O_CREAT | O_RDWR, 0644);
943 if (write(fd, xim->data, bufsz) != bufsz)
944 printf("Data is not fully written\n");
948 printf("Error: %sn\n", strerror(errno));
951 XShmDetach(disp, &si);
954 if (shmdt(si.shmaddr) < 0)
955 printf("shmdt: %s\n", strerror(errno));
957 if (shmctl(si.shmid, IPC_RMID, 0) < 0)
958 printf("shmctl: %s\n", strerror(errno));
963 static inline void do_x(const char *cmd)
969 while (*cmd && *cmd == ' ') cmd++;
973 disp = XOpenDisplay(NULL);
975 printf("Failed to connect to the X\n");
979 if (!strncasecmp(cmd, "damage ", 7)) {
982 XserverRegion region;
987 if (sscanf(cmd, "%u %d %d %d %d", &winId, &x, &y, &w, &h) != 5) {
988 printf("Invalid argument\nx damage WINID_DEC X Y W H\n");
995 region = XFixesCreateRegion(disp, &rect, 1);
996 XDamageAdd(disp, winId, region);
997 XFixesDestroyRegion(disp, region);
1000 printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h);
1001 } else if (!strncasecmp(cmd, "capture ", 8)) {
1007 if (sscanf(cmd, "%u %255[^ ]", &winId, filename) != 2) {
1008 printf("Invalid argument\nx capture WINID_DEC FILENAME (%s)\n", cmd);
1011 if (do_capture(disp, winId, filename) == 0)
1012 printf("Captured: %s\n", filename);
1013 } else if (!strncasecmp(cmd, "resize ", 7)) {
1020 if (sscanf(cmd, "%u %d %d", &winId, &w, &h) != 3) {
1021 printf("Invalid argument\nx resize WINID_DEC W H\n");
1025 XResizeWindow(disp, winId, w, h);
1026 printf("Resize: %u %d %d\n", winId, w, h);
1027 } else if (!strncasecmp(cmd, "move ", 5)) {
1033 if (sscanf(cmd, "%u %d %d", &winId, &x, &y) != 3) {
1034 printf("Invalid argument\nx move WINID_DEC X Y\n");
1038 XMoveWindow(disp, winId, x, y);
1039 printf("Move: %u %d %d\n", winId, x, y);
1040 } else if (!strncasecmp(cmd, "map ", 4)) {
1043 if (sscanf(cmd, "%u", &winId) != 1) {
1044 printf("Invalid argument\nx map WINID_DEC\n");
1047 XMapRaised(disp, winId);
1048 printf("Map: %u\n", winId);
1049 } else if (!strncasecmp(cmd, "unmap ", 6)) {
1052 if (sscanf(cmd, "%u", &winId) != 1) {
1053 printf("Invalid argument\nx unmap WINID_DEC\n");
1056 XUnmapWindow(disp, winId);
1057 printf("Unmap: %u\n", winId);
1059 printf("Unknown command\n");
1062 XCloseDisplay(disp);
1065 static inline void put_command(const char *cmd)
1067 if (s_info.history[s_info.history_top]) {
1068 free(s_info.history[s_info.history_top]);
1069 s_info.history[s_info.history_top] = NULL;
1072 s_info.history[s_info.history_top] = strdup(cmd);
1073 s_info.history_top = (s_info.history_top + !!s_info.history[s_info.history_top]) % (sizeof(s_info.history) / sizeof(s_info.history[0]));
1076 static inline const char *get_command(int idx)
1078 idx = s_info.history_top + idx;
1080 idx += (sizeof(s_info.history) / sizeof(s_info.history[0]));
1082 return s_info.history[idx];
1085 static inline void do_command(const char *cmd)
1087 /* Skip the first spaces */
1088 while (*cmd && *cmd == ' ') cmd++;
1090 if (strlen(cmd) && *cmd != '#') {
1091 if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "quit", 4)) {
1092 ecore_main_loop_quit();
1093 } else if (!strncasecmp(cmd, "set ", 4)) {
1094 if (do_set(cmd) == 0)
1096 } else if (!strncasecmp(cmd, "stat ", 5)) {
1098 } else if (!strncasecmp(cmd, "get ", 4)) {
1099 if (do_get(cmd) == 0)
1101 } else if (!strncasecmp(cmd, "ls", 2)) {
1102 if (do_ls(cmd) == 0)
1104 } else if (!strncasecmp(cmd, "cd", 2)) {
1105 if (do_cd(cmd) == 0)
1107 } else if (!strncasecmp(cmd, "rm", 2)) {
1108 if (do_rm(cmd) == 0)
1110 } else if (!strncasecmp(cmd, "sh ", 3)) {
1112 } else if (!strncasecmp(cmd, "x ", 2)) {
1123 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
1126 static char cmd_buffer[256];
1130 const char escape_str[] = { 0x1b, 0x5b, 0x0 };
1131 const char *escape_ptr = escape_str;
1135 fd = ecore_main_fd_handler_fd_get(fd_handler);
1137 printf("FD is not valid: %d\n", fd);
1138 return ECORE_CALLBACK_CANCEL;
1141 fd = s_info.input_fd;
1146 * Using this routine, we can implement the command recommend algorithm.
1147 * When a few more characters are matched with history of command, we can show it to user
1148 * Then the user will choose one or write new command
1152 while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) {
1153 if (*escape_ptr == '\0') {
1157 printf("%s2K%s1G", escape_str, escape_str);
1158 tmp = get_command(--s_info.history_idx);
1160 s_info.history_idx = 0;
1161 cmd_buffer[0] = '\0';
1164 strcpy(cmd_buffer, tmp);
1165 idx = strlen(cmd_buffer);
1169 case 0x42: /* DOWN */
1170 if (s_info.history_idx >= 0)
1173 printf("%s2K%s1G", escape_str, escape_str);
1174 tmp = get_command(++s_info.history_idx);
1175 if (s_info.history_idx == 0) {
1176 s_info.history_idx = 0;
1177 cmd_buffer[0] = '\0';
1180 strcpy(cmd_buffer, tmp);
1181 idx = strlen(cmd_buffer);
1185 case 0x43: /* RIGHT */
1187 case 0x44: /* LEFT */
1193 escape_ptr = escape_str;
1195 } else if (ch == *escape_ptr) {
1201 case 0x08: /* BKSP */
1202 cmd_buffer[idx] = '\0';
1205 cmd_buffer[idx] = ' ';
1210 cmd_buffer[idx] = '\0';
1214 case 0x09: /* TAB */
1215 if (!s_info.quick_search_node) {
1216 s_info.quick_search_node = node_child(s_info.curdir);
1217 s_info.quick_idx = idx;
1219 s_info.quick_search_node = node_next_sibling(s_info.quick_search_node);
1220 idx = s_info.quick_idx;
1223 if (!s_info.quick_search_node)
1226 printf("%s2K%s1G", escape_str, escape_str);
1227 strcpy(cmd_buffer + idx, node_name(s_info.quick_search_node));
1228 idx += strlen(node_name(s_info.quick_search_node));
1233 cmd_buffer[idx] = '\0';
1235 if (s_info.input_fd == STDIN_FILENO || s_info.verbose)
1236 putc((int)'\n', stdout);
1237 do_command(cmd_buffer);
1238 put_command(cmd_buffer);
1239 memset(cmd_buffer, 0, sizeof(cmd_buffer));
1240 s_info.history_idx = 0;
1241 s_info.quick_search_node = NULL;
1243 /* Make a main loop processing for command handling */
1244 return ECORE_CALLBACK_RENEW;
1246 cmd_buffer[idx++] = ch;
1248 if (s_info.input_fd == STDIN_FILENO || s_info.verbose)
1249 putc((int)ch, stdout);
1251 if (idx == sizeof(cmd_buffer) - 1) {
1252 cmd_buffer[idx] = '\0';
1253 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
1260 if (ret < 0 && !fd_handler)
1261 ecore_main_loop_quit();
1263 return ECORE_CALLBACK_RENEW;
1266 static void processing_line_buffer(const char *buffer)
1269 char slavename[256];
1287 struct package *pkginfo;
1288 struct instance *instinfo;
1289 struct slave *slaveinfo;
1292 switch (s_info.cmd) {
1294 if (sscanf(buffer, "%d %255[^ ] %255[^ ] %255[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
1295 printf("Invalid format : [%s]\n", buffer);
1299 node = node_find(s_info.targetdir, pkgname);
1301 pkginfo = calloc(1, sizeof(*pkginfo));
1303 printf("Error: %s\n", strerror(errno));
1307 pkginfo->pkgid = strdup("conf.file");
1308 if (!pkginfo->pkgid)
1309 printf("Error: %s\n", strerror(errno));
1311 pkginfo->primary = 1;
1313 node = node_create(s_info.targetdir, pkgname, NODE_DIR);
1315 free(pkginfo->pkgid);
1317 printf("Failed to create a new node (%s)\n", pkgname);
1321 node_set_mode(node, NODE_READ | NODE_EXEC);
1322 node_set_data(node, pkginfo);
1324 pkginfo = node_data(node);
1326 printf("Package info is inavlid\n");
1330 free(pkginfo->slavename);
1333 pkginfo->slavename = NULL;
1334 pkginfo->abi = NULL;
1337 node_set_age(node, s_info.age);
1339 pkginfo->slavename = strdup(slavename);
1340 if (!pkginfo->slavename)
1341 printf("Error: %s\n", strerror(errno));
1343 pkginfo->abi = strdup(abi);
1345 printf("Error: %s\n", strerror(errno));
1348 pkginfo->refcnt = refcnt;
1349 pkginfo->fault_count = fault_count;
1350 pkginfo->inst_count = list_count;
1353 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) {
1354 printf("Invalid format : [%s]\n", buffer);
1357 node = node_find(s_info.targetdir, slavename);
1359 slaveinfo = calloc(1, sizeof(*slaveinfo));
1361 printf("Error: %s\n", strerror(errno));
1365 node = node_create(s_info.targetdir, slavename, NODE_DIR);
1371 node_set_mode(node, NODE_READ | NODE_EXEC);
1372 node_set_data(node, slaveinfo);
1374 slaveinfo = node_data(node);
1377 node_set_age(node, s_info.age);
1379 free(slaveinfo->pkgname);
1380 free(slaveinfo->abi);
1381 free(slaveinfo->state);
1383 slaveinfo->pkgname = strdup(pkgname);
1384 if (!slaveinfo->pkgname)
1385 printf("Error: %s\n", strerror(errno));
1387 slaveinfo->abi = strdup(abi);
1388 if (!slaveinfo->abi)
1389 printf("Error: %s\n", strerror(errno));
1391 slaveinfo->state = strdup(state);
1392 if (!slaveinfo->state)
1393 printf("Error: %s\n", strerror(errno));
1395 slaveinfo->pid = pid;
1396 slaveinfo->secured = secured;
1397 slaveinfo->refcnt = refcnt;
1398 slaveinfo->fault_count = fault_count;
1399 slaveinfo->loaded_inst = loaded_inst;
1400 slaveinfo->loaded_pkg = loaded_pkg;
1401 slaveinfo->ttl = ttl;
1404 if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
1405 printf("Invalid format : [%s]\n", buffer);
1409 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
1410 i += (inst_id[i] == '/');
1412 node = node_find(s_info.targetdir, inst_id + i);
1414 instinfo = calloc(1, sizeof(*instinfo));
1416 printf("Error: %s\n", strerror(errno));
1420 node = node_create(s_info.targetdir, inst_id + i, NODE_FILE);
1426 node_set_mode(node, NODE_READ | NODE_WRITE);
1427 node_set_data(node, instinfo);
1429 instinfo = node_data(node);
1432 node_set_age(node, s_info.age);
1435 free(instinfo->cluster);
1436 free(instinfo->category);
1437 free(instinfo->state);
1439 instinfo->id = strdup(inst_id);
1441 printf("Error: %s\n", strerror(errno));
1443 instinfo->cluster = strdup(cluster);
1444 if (!instinfo->cluster)
1445 printf("Error: %s\n", strerror(errno));
1447 instinfo->category = strdup(category);
1448 if (!instinfo->category)
1449 printf("Error: %s\n", strerror(errno));
1451 instinfo->state = strdup(state);
1452 if (!instinfo->state)
1453 printf("Error: %s\n", strerror(errno));
1455 instinfo->period = period;
1456 instinfo->width = width;
1457 instinfo->height = height;
1460 sscanf(buffer, "%d", &i);
1461 printf("%s\n", strerror(i));
1462 printf("Result: %d\n", i);
1465 sscanf(buffer, "%d", &i);
1466 printf("Result: %d\n", i);
1469 sscanf(buffer, "%d", &i);
1470 printf("Result: %d\n", i);
1477 static inline void do_line_command(void)
1479 switch (s_info.cmd) {
1501 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
1504 static char *line_buffer = NULL;
1505 static int line_index = 0;
1506 static int bufsz = 256;
1509 fd = ecore_main_fd_handler_fd_get(fd_handler);
1511 printf("FD is not valid: %d\n", fd);
1512 return ECORE_CALLBACK_CANCEL;
1515 if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
1516 printf("Error: %s\n", strerror(errno));
1517 return ECORE_CALLBACK_CANCEL;
1522 line_buffer = malloc(bufsz);
1524 printf("Error: %s\n", strerror(errno));
1525 return ECORE_CALLBACK_CANCEL;
1529 if (ch == '\n') { /* End of a line */
1530 if (line_index == bufsz - 1) {
1532 new_buf = realloc(line_buffer, bufsz + 2);
1534 printf("Error: %s\n", strerror(errno));
1539 return ECORE_CALLBACK_CANCEL;
1542 line_buffer = new_buf;
1545 line_buffer[line_index] = '\0';
1547 if (!strcmp(line_buffer, "EOD")) {
1551 processing_line_buffer(line_buffer);
1561 line_buffer[line_index++] = ch;
1562 if (line_index == bufsz - 1) {
1564 new_buf = realloc(line_buffer, bufsz);
1566 printf("Error: %s\n", strerror(errno));
1571 return ECORE_CALLBACK_CANCEL;
1574 line_buffer = new_buf;
1578 return ECORE_CALLBACK_RENEW;
1581 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1583 const char *fifo_name;
1586 if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
1587 printf("Invalid packet\n");
1592 printf("Returns %d\n", ret);
1596 printf("FIFO: %s\n", fifo_name);
1598 s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
1599 if (s_info.fifo_handle < 0) {
1600 printf("Error: %s\n", strerror(errno));
1601 s_info.fifo_handle = -EINVAL;
1602 ecore_main_loop_quit();
1606 s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
1607 if (!s_info.fd_handler) {
1608 printf("Failed to add a fd handler\n");
1609 close(s_info.fifo_handle);
1610 s_info.fifo_handle = -EINVAL;
1611 ecore_main_loop_quit();
1617 if (s_info.input_fd == STDIN_FILENO) {
1618 if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0)
1619 printf("Error: %s\n", strerror(errno));
1621 s_info.in_handler = ecore_main_fd_handler_add(s_info.input_fd, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
1622 if (!s_info.in_handler) {
1623 printf("Failed to add a input handler\n");
1624 ecore_main_loop_quit();
1632 static int disconnected_cb(int handle, void *data)
1634 printf("Disconnected\n");
1635 ecore_main_loop_quit();
1639 static int connected_cb(int handle, void *data)
1641 struct packet *packet;
1643 printf("Connected\n");
1645 packet = packet_create("liveinfo_hello", "d", 0.0f);
1647 printf("Failed to build a packet for hello\n");
1648 com_core_packet_client_fini(s_info.fd);
1649 s_info.fd = -EINVAL;
1655 if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
1656 printf("Failed to send a packet hello\n");
1657 packet_destroy(packet);
1658 com_core_packet_client_fini(s_info.fd);
1659 s_info.fd = -EINVAL;
1663 packet_destroy(packet);
1667 int main(int argc, char *argv[])
1669 struct termios ttystate;
1670 static struct method s_table[] = {
1676 static struct option long_options[] = {
1677 { "batchmode", required_argument, 0, 'b' },
1678 { "help", no_argument, 0, 'h' },
1679 { "verbose", required_argument, 0, 'v' },
1686 c = getopt_long(argc, argv, "b:hv:", long_options, &option_index);
1689 if (!optarg || !*optarg) {
1690 printf("Invalid argument\n");
1695 if (s_info.input_fd != STDIN_FILENO) {
1696 /* Close the previously, opened file */
1697 close(s_info.input_fd);
1700 s_info.input_fd = open(optarg, O_RDONLY);
1701 if (s_info.input_fd < 0) {
1702 printf("Unable to access %s (%s)\n", optarg, strerror(errno));
1710 if (!optarg || !*optarg) {
1711 printf("Invalid argument\n");
1716 s_info.verbose = !strcmp(optarg, "true");
1726 com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1727 com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1728 livebox_service_init();
1730 s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
1731 if (s_info.fd < 0) {
1732 printf("Failed to make a connection\n");
1736 if (s_info.input_fd == STDIN_FILENO) {
1737 printf("Type your command on below empty line\n");
1739 if (tcgetattr(s_info.input_fd, &ttystate) < 0) {
1740 printf("Error: %s\n", strerror(errno));
1742 ttystate.c_lflag &= ~(ICANON | ECHO);
1743 ttystate.c_cc[VMIN] = 1;
1745 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0)
1746 printf("Error: %s\n", strerror(errno));
1749 printf("Batch mode enabled\n");
1752 if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0)
1753 printf("Error: %s\n", strerror(errno));
1757 ecore_main_loop_begin();
1760 livebox_service_fini();
1762 if (s_info.fd > 0) {
1763 com_core_packet_client_fini(s_info.fd);
1764 s_info.fd = -EINVAL;
1767 if (s_info.fd_handler) {
1768 ecore_main_fd_handler_del(s_info.fd_handler);
1769 s_info.fd_handler = NULL;
1772 if (s_info.input_fd == STDIN_FILENO) {
1773 ttystate.c_lflag |= ICANON | ECHO;
1774 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0)
1775 printf("Error: %s\n", strerror(errno));
1777 close(s_info.input_fd);
1780 if (s_info.fifo_handle > 0) {
1781 close(s_info.fifo_handle);
1782 s_info.fifo_handle = -EINVAL;
1785 if (s_info.in_handler) {
1786 ecore_main_fd_handler_del(s_info.in_handler);
1787 s_info.in_handler = NULL;
1791 putc((int)'\n', stdout);