2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.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 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);
183 static void package_del_cb(struct node *node)
185 struct package *info;
187 info = node_data(node);
193 free(info->slavename);
198 static void inst_del_cb(struct node *node)
200 struct instance *info;
202 info = node_data(node);
209 free(info->category);
221 struct node *next_node;
223 if (!(node_mode(s_info.targetdir) & NODE_READ)) {
224 printf("Access denied\n");
228 is_package = node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "package");
229 is_provider = !is_package && node_name(s_info.targetdir) && !strcmp(node_name(s_info.targetdir), "provider");
230 is_instance = !is_package && !is_provider && node_parent(s_info.targetdir) && node_name(node_parent(s_info.targetdir)) && !strcmp(node_name(node_parent(s_info.targetdir)), "package");
232 node = node_child(s_info.targetdir);
235 struct package *info;
237 next_node = node_next_sibling(node);
238 if (node_age(node) != s_info.age) {
239 node_delete(node, package_del_cb);
244 info = node_data(node);
245 printf(" %3d %20s %5s ", info->inst_count, info->slavename ? info->slavename : "(none)", info->abi ? info->abi : "?");
246 } else if (is_provider) {
249 next_node = node_next_sibling(node);
250 if (node_age(node) != s_info.age) {
251 node_delete(node, provider_del_cb);
256 info = node_data(node);
257 printf("%6d %3d %5s %5.2f ", info->pid, info->loaded_inst, info->abi ? info->abi : "?", info->ttl);
258 } else if (is_instance) {
259 struct instance *info;
263 next_node = node_next_sibling(node);
265 if (node_age(node) != s_info.age) {
266 node_delete(node, inst_del_cb);
271 info = node_data(node);
273 printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
274 snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
275 if (lstat(buf, &stat) < 0) {
276 printf("%3d ERR ", errno);
278 printf("%2.2lf KB ", (double)stat.st_size / 1024.0f);
282 if (node_type(node) == NODE_DIR) {
283 printf("%s/", node_name(node));
284 } else if (node_type(node) == NODE_FILE) {
285 printf("%s", node_name(node));
289 node = node_next_sibling(node);
293 printf("Total: %d\n", cnt);
296 static void send_slave_list(void)
298 struct packet *packet;
301 if (s_info.cmd != NOP) {
302 printf("Previous command is not finished\n");
306 packet = packet_create_noack("slave_list", "d", 0.0f);
308 printf("Failed to create a packet\n");
312 ret = com_core_packet_send_only(s_info.fd, packet);
313 packet_destroy(packet);
315 printf("Failed to send a packet: %d\n", ret);
319 s_info.cmd = SLAVE_LIST;
324 * var = debug, slave_max_load
327 static void send_command(const char *cmd, const char *var, const char *val)
329 struct packet *packet;
332 if (s_info.cmd != NOP) {
333 printf("Previous command is not finished\n");
337 packet = packet_create_noack("master_ctrl", "sss", cmd, var, val);
339 printf("Failed to create a ctrl packet\n");
343 ret = com_core_packet_send_only(s_info.fd, packet);
344 packet_destroy(packet);
346 printf("Failed to send packet ctrl\n");
350 s_info.cmd = MASTER_CTRL;
354 static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
356 struct node *parent = data;
358 struct package *info;
360 node = node_find(parent, lbid);
362 info = node_data(node);
364 printf("Invalid node\n");
369 info->pkgid = strdup(appid);
371 printf("Error: %s\n", strerror(errno));
375 node_set_age(node, s_info.age);
379 info = calloc(1, sizeof(*info));
381 printf("Error: %s\n", strerror(errno));
385 info->pkgid = strdup(appid);
387 printf("Error: %s\n", strerror(errno));
392 info->primary = is_prime;
394 node = node_create(parent, lbid, NODE_DIR);
401 node_set_mode(node, NODE_READ | NODE_EXEC);
402 node_set_data(node, info);
403 node_set_age(node, s_info.age);
407 static void send_pkg_list(void)
409 struct packet *packet;
412 if (s_info.cmd != NOP) {
413 printf("Previous command is not finished\n");
417 packet = packet_create_noack("pkg_list", "d", 0.0f);
419 printf("Failed to create a packet\n");
423 ret = com_core_packet_send_only(s_info.fd, packet);
424 packet_destroy(packet);
426 printf("Failed to create a packet\n");
430 s_info.cmd = PKG_LIST;
433 livebox_service_get_pkglist(pkglist_cb, s_info.targetdir);
436 static void send_inst_delete(void)
438 struct packet *packet;
441 struct instance *inst;
444 if (s_info.cmd != NOP) {
445 printf("Previous command is not finished\n");
449 parent = node_parent(s_info.targetdir);
451 printf("Invalid argument\n");
455 if (!node_parent(parent)) {
456 printf("Invalid argument\n");
460 name = node_name(node_parent(parent));
461 if (!name || strcmp(name, "package")) {
462 printf("Invalid argument\n");
466 inst = node_data(s_info.targetdir);
467 name = node_name(parent);
469 packet = packet_create_noack("pkg_ctrl", "sss", "rminst", name, inst->id);
471 printf("Failed to create a packet\n");
475 ret = com_core_packet_send_only(s_info.fd, packet);
476 packet_destroy(packet);
478 printf("Failed to send a packet: %d\n", ret);
482 s_info.cmd = INST_CTRL;
486 static void send_inst_fault(void)
488 struct packet *packet;
491 struct instance *inst;
494 if (s_info.cmd != NOP) {
495 printf("Previous command is not finished\n");
499 parent = node_parent(s_info.targetdir);
501 printf("Invalid argument\n");
505 if (!node_parent(parent)) {
506 printf("Invalid argument\n");
510 name = node_name(node_parent(parent));
511 if (!name || strcmp(name, "package")) {
512 printf("Invalid argument\n");
516 inst = node_data(s_info.targetdir);
517 name = node_name(parent);
519 packet = packet_create_noack("pkg_ctrl", "sss", "faultinst", name, inst->id);
521 printf("Failed to create a packet\n");
525 ret = com_core_packet_send_only(s_info.fd, packet);
526 packet_destroy(packet);
528 printf("Failed to send a packet: %d\n", ret);
532 s_info.cmd = INST_CTRL;
536 static void send_inst_list(const char *pkgname)
538 struct packet *packet;
541 if (s_info.cmd != NOP) {
542 printf("Previous command is not finished\n");
546 packet = packet_create_noack("inst_list", "s", pkgname);
548 printf("Failed to create a packet\n");
552 ret = com_core_packet_send_only(s_info.fd, packet);
553 packet_destroy(packet);
555 printf("Failed to send a packet: %d\n", ret);
559 s_info.cmd = INST_LIST;
563 static void help(void)
565 printf("liveinfo - Livebox utility\n");
566 printf("------------------------------ [Option] ------------------------------\n");
567 printf("-b Batch mode\n");
568 printf("-x execute command\n");
569 printf("------------------------------ [Command list] ------------------------------\n");
570 printf("
\e[32mcd [PATH] - Change directory
\e[0m\n");
571 printf("
\e[32mls [ | PATH] - List up content as a file
\e[0m\n");
572 printf("
\e[32mrm [PKG_ID|INST_ID] - Delete package or instance
\e[0m\n");
573 printf("
\e[32mstat [path] - Display the information of given path
\e[0m\n");
574 printf("
\e[32mset [debug] [on|off] Set the control variable of master provider
\e[0m\n");
575 printf("
\e[32mx damage Pix x y w h - Create damage event for given pixmap
\e[0m\n");
576 printf("
\e[32mx move Pix x y - Move the window
\e[0m\n");
577 printf("
\e[32mx resize Pix w h - Resize the window
\e[0m\n");
578 printf("
\e[32mx map Pix - Show the window
\e[0m\n");
579 printf("
\e[32mx unmap Pix - Hide the window
\e[0m\n");
580 printf("
\e[32mx capture Pix outfile - Capture pixmap and save it to outfile
\e[0m\n");
581 printf("
\e[32msh [command] Execute shell command, [command] should be abspath
\e[0m\n");
582 printf("
\e[32mexit -
\e[0m\n");
583 printf("
\e[32mquit -
\e[0m\n");
584 printf("----------------------------------------------------------------------------\n");
587 static inline void init_directory(void)
590 s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
591 if (!s_info.rootdir) {
594 node_set_mode(s_info.rootdir, NODE_READ | NODE_EXEC);
596 node = node_create(s_info.rootdir, "provider", NODE_DIR);
598 node_destroy(s_info.rootdir);
599 s_info.rootdir = NULL;
602 node_set_mode(node, NODE_READ | NODE_EXEC);
604 node = node_create(s_info.rootdir, "package", NODE_DIR);
606 node_destroy(node_child(s_info.rootdir));
607 node_destroy(s_info.rootdir);
608 s_info.rootdir = NULL;
611 node_set_mode(node, NODE_READ | NODE_EXEC);
613 s_info.curdir = s_info.rootdir;
617 static inline void fini_directory(void)
621 static struct node *update_target_dir(const char *cmd)
625 node = (*cmd == '/') ? s_info.rootdir : s_info.curdir;
626 node = node_find(node, cmd);
631 static int get_token(const char *src, char *out)
634 while (*src && *src == ' ') src++;
640 while (*src && *src != ' ') {
649 static inline int do_stat(const char *cmd)
664 while (*cmd && *cmd == ' ') cmd++;
667 printf("Invalid argument\n");
671 node = node_find(*cmd == '/' ? s_info.rootdir : s_info.curdir, cmd);
673 printf("Invalid path\n");
679 parent = node_parent(node);
681 if (!node_name(parent)) {
682 printf("%s has no info\n", node_name(node));
684 } else if (!strcmp(node_name(parent), "package")) {
685 type = (i == 0) ? PKG : PKG_INSTANCE;
687 } else if (!strcmp(node_name(parent), "provider")){
688 type = (i == 0) ? PROVIDER : PROVIDER_INSTANCE;
692 parent = node_parent(parent);
695 printf("%s is invalid path\n", node_name(node));
702 tmp = livebox_service_i18n_name(node_name(node), NULL);
703 printf("Name: %s (", tmp);
706 i = livebox_service_is_enabled(node_name(node));
707 printf("%s)\n", i ? "enabled" : "disabled");
709 tmp = livebox_service_i18n_icon(node_name(node), NULL);
710 printf("Icon: %s\n", tmp);
713 tmp = livebox_service_provider_name(node_name(node));
714 printf("Provider: %s (content:", tmp);
717 tmp = livebox_service_content(node_name(node));
718 printf("%s)\n", tmp);
721 tmp = livebox_service_lb_script_path(node_name(node));
722 printf("LB Script: %s (", tmp);
725 tmp = livebox_service_lb_script_group(node_name(node));
726 printf("%s)\n", tmp);
729 tmp = livebox_service_pd_script_path(node_name(node));
730 printf("PD Script: %s (", tmp);
733 tmp = livebox_service_pd_script_group(node_name(node));
734 printf("%s)\n", tmp);
737 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_1x1);
738 printf("[1x1] Mouse event: %s\n", i ? "enabled" : "disabled");
739 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_2x1);
740 printf("[2x1] Mouse event: %s\n", i ? "enabled" : "disabled");
741 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_2x2);
742 printf("[2x2] Mouse event: %s\n", i ? "enabled" : "disabled");
743 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x1);
744 printf("[4x1] Mouse event: %s\n", i ? "enabled" : "disabled");
745 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x2);
746 printf("[4x2] Mouse event: %s\n", i ? "enabled" : "disabled");
747 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x3);
748 printf("[4x3] Mouse event: %s\n", i ? "enabled" : "disabled");
749 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x4);
750 printf("[4x4] Mouse event: %s\n", i ? "enabled" : "disabled");
751 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x5);
752 printf("[4x5] Mouse event: %s\n", i ? "enabled" : "disabled");
753 i = livebox_service_mouse_event(node_name(node), LB_SIZE_TYPE_4x6);
754 printf("[4x6] Mouse event: %s\n", i ? "enabled" : "disabled");
758 printf("Not supported yet\n");
761 printf("Not supported yet\n");
763 case PROVIDER_INSTANCE:
764 printf("Not supported yet\n");
767 printf("Not supported yet\n");
774 static int do_set(const char *cmd)
777 char variable[4096] = { '0', };
780 i = get_token(cmd, variable);
783 while (*cmd && *cmd == ' ') {
788 printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
792 send_command("set", variable, cmd);
796 static inline int do_get(const char *cmd)
800 while (*cmd && *cmd == ' ') cmd++;
802 printf("Invalid argument(%s): get [VAR]\n", cmd);
806 send_command("get", cmd, "");
810 static inline int do_ls(const char *cmd)
817 while (*cmd && *cmd == ' ') {
821 s_info.targetdir = *cmd ? update_target_dir(cmd) : s_info.curdir;
822 if (!s_info.targetdir) {
823 printf("%s is not exists\n", cmd);
827 name = node_name(s_info.targetdir);
829 if (!strcmp(name, "package")) {
830 if (s_info.cmd == NOP) {
835 printf("Waiting the server response\n");
837 } else if (!strcmp(name, "provider")) {
838 if (s_info.cmd == NOP) {
843 printf("Waiting the server response\n");
848 parent = node_parent(s_info.targetdir);
849 if (parent && node_name(parent)) {
850 if (!strcmp(node_name(parent), "package")) {
851 if (s_info.cmd != NOP) {
852 printf("Waiting the server response\n");
856 send_inst_list(name);
865 static inline int do_cd(const char *cmd)
869 while (*cmd && *cmd == ' ') {
877 if (s_info.cmd != NOP) {
878 printf("Waiting the server response\n");
882 s_info.targetdir = update_target_dir(cmd);
883 if (!s_info.targetdir) {
884 printf("%s is not exists\n", cmd);
888 if (node_type(s_info.targetdir) != NODE_DIR) {
889 printf("Unable change directory to %s\n", cmd);
893 if (!(node_mode(s_info.targetdir) & NODE_EXEC)) {
894 printf("Access denied %s\n", cmd);
898 s_info.curdir = s_info.targetdir;
902 static inline int do_rm(const char *cmd)
905 while (*cmd && *cmd == ' ') cmd++;
910 if (s_info.cmd != NOP) {
911 printf("Waiting the server response\n");
915 s_info.targetdir = update_target_dir(cmd);
916 if (!s_info.targetdir) {
917 printf("%s is not exists\n", cmd);
921 if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
922 printf("Access denied %s\n", cmd);
930 static inline int do_fault(const char *cmd)
933 while (*cmd && *cmd == ' ') cmd++;
938 if (s_info.cmd != NOP) {
939 printf("Waiting the server response\n");
943 s_info.targetdir = update_target_dir(cmd);
944 if (!s_info.targetdir) {
945 printf("%s is not exists\n", cmd);
949 if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
950 printf("Access denied %s\n", cmd);
958 #if !defined(WCOREDUMP)
959 #define WCOREDUMP(a) 0
962 static void do_sh(const char *cmd)
968 while (*cmd && *cmd == ' ') {
982 while (idx < (sizeof(command) - 1) && *cmd && *cmd != ' ') {
983 command[idx++] = *cmd++;
987 if (execl(command, cmd, NULL) < 0) {
988 printf("Failed to execute: %s\n", strerror(errno));
992 } else if (pid < 0) {
993 printf("Failed to create a new process: %s\n", strerror(errno));
996 if (waitpid(pid, &status, 0) < 0) {
997 printf("error: %s\n", strerror(errno));
999 if (WIFEXITED(status)) {
1000 printf("Exit: %d\n", WEXITSTATUS(status));
1001 } else if (WIFSIGNALED(status)) {
1002 printf("Terminated by %d %s\n", WTERMSIG(status), WCOREDUMP(status) ? " - core generated" : "");
1003 } else if (WIFSTOPPED(status)) {
1004 printf("Stopped by %d\n", WSTOPSIG(status));
1005 } else if (WIFCONTINUED(status)) {
1006 printf("Child is resumed\n");
1012 static inline int get_pixmap_size(Display *disp, Pixmap id, int *x, int *y, unsigned int *w, unsigned int *h)
1015 unsigned int dummy_border, dummy_depth;
1027 if (!XGetGeometry(disp, id, &dummy_win, x, y, w, h, &dummy_border, &dummy_depth)) {
1034 static inline int do_capture(Display *disp, Pixmap id, const char *filename)
1045 screen = DefaultScreenOfDisplay(disp);
1046 visual = DefaultVisualOfScreen(screen);
1048 if (get_pixmap_size(disp, id, NULL, NULL, &w, &h) < 0) {
1049 printf("Failed to get size of a pixmap\n");
1053 printf("Pixmap size: %dx%d\n", w, h);
1054 bufsz = w * h * sizeof(int);
1056 si.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0666);
1058 printf("shmget: %s\n", strerror(errno));
1062 si.readOnly = False;
1063 si.shmaddr = shmat(si.shmid, NULL, 0);
1064 if (si.shmaddr == (void *)-1) {
1066 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1067 printf("shmctl: %s\n", strerror(errno));
1075 * Use the 24 bits Pixmap for Video player
1077 xim = XShmCreateImage(disp, visual, 24 /* (depth << 3) */, ZPixmap, NULL, &si, w, h);
1079 if (shmdt(si.shmaddr) < 0) {
1080 printf("shmdt: %s\n", strerror(errno));
1083 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1084 printf("shmctl: %s\n", strerror(errno));
1090 xim->data = si.shmaddr;
1091 XShmAttach(disp, &si);
1093 XShmGetImage(disp, id, xim, 0, 0, 0xFFFFFFFF);
1096 fd = open(filename, O_CREAT | O_RDWR, 0644);
1098 if (write(fd, xim->data, bufsz) != bufsz) {
1099 printf("Data is not fully written\n");
1102 if (close(fd) < 0) {
1103 printf("close: %s\n", strerror(errno));
1106 printf("Error: %sn\n", strerror(errno));
1109 XShmDetach(disp, &si);
1112 if (shmdt(si.shmaddr) < 0) {
1113 printf("shmdt: %s\n", strerror(errno));
1116 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1117 printf("shmctl: %s\n", strerror(errno));
1123 static void do_x(const char *cmd)
1129 while (*cmd && *cmd == ' ') {
1137 disp = XOpenDisplay(NULL);
1139 printf("Failed to connect to the X\n");
1143 if (!strncasecmp(cmd, "damage ", 7)) {
1146 XserverRegion region;
1151 if (sscanf(cmd, "%u %d %d %d %d", &winId, &x, &y, &w, &h) != 5) {
1152 printf("Invalid argument\nx damage WINID_DEC X Y W H\n");
1159 region = XFixesCreateRegion(disp, &rect, 1);
1160 XDamageAdd(disp, winId, region);
1161 XFixesDestroyRegion(disp, region);
1164 printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h);
1165 } else if (!strncasecmp(cmd, "capture ", 8)) {
1171 if (sscanf(cmd, "%u %255[^ ]", &winId, filename) != 2) {
1172 printf("Invalid argument\nx capture WINID_DEC FILENAME (%s)\n", cmd);
1175 if (do_capture(disp, winId, filename) == 0) {
1176 printf("Captured: %s\n", filename);
1178 } else if (!strncasecmp(cmd, "resize ", 7)) {
1185 if (sscanf(cmd, "%u %d %d", &winId, &w, &h) != 3) {
1186 printf("Invalid argument\nx resize WINID_DEC W H\n");
1190 XResizeWindow(disp, winId, w, h);
1191 printf("Resize: %u %d %d\n", winId, w, h);
1192 } else if (!strncasecmp(cmd, "move ", 5)) {
1198 if (sscanf(cmd, "%u %d %d", &winId, &x, &y) != 3) {
1199 printf("Invalid argument\nx move WINID_DEC X Y\n");
1203 XMoveWindow(disp, winId, x, y);
1204 printf("Move: %u %d %d\n", winId, x, y);
1205 } else if (!strncasecmp(cmd, "map ", 4)) {
1208 if (sscanf(cmd, "%u", &winId) != 1) {
1209 printf("Invalid argument\nx map WINID_DEC\n");
1212 XMapRaised(disp, winId);
1213 printf("Map: %u\n", winId);
1214 } else if (!strncasecmp(cmd, "unmap ", 6)) {
1217 if (sscanf(cmd, "%u", &winId) != 1) {
1218 printf("Invalid argument\nx unmap WINID_DEC\n");
1221 XUnmapWindow(disp, winId);
1222 printf("Unmap: %u\n", winId);
1224 printf("Unknown command\n");
1227 XCloseDisplay(disp);
1230 static inline void put_command(const char *cmd)
1232 if (s_info.history[s_info.history_top]) {
1233 free(s_info.history[s_info.history_top]);
1234 s_info.history[s_info.history_top] = NULL;
1237 s_info.history[s_info.history_top] = strdup(cmd);
1238 s_info.history_top = (s_info.history_top + !!s_info.history[s_info.history_top]) % (sizeof(s_info.history) / sizeof(s_info.history[0]));
1241 static inline const char *get_command(int idx)
1243 idx = s_info.history_top + idx;
1245 idx += (sizeof(s_info.history) / sizeof(s_info.history[0]));
1248 return s_info.history[idx];
1251 static inline void do_command(const char *cmd)
1253 /* Skip the first spaces */
1254 while (*cmd && *cmd == ' ') {
1258 if (strlen(cmd) && *cmd != '#') {
1259 if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "quit", 4)) {
1260 ecore_main_loop_quit();
1261 } else if (!strncasecmp(cmd, "set ", 4)) {
1262 if (do_set(cmd) == 0) {
1265 } else if (!strncasecmp(cmd, "stat ", 5)) {
1267 } else if (!strncasecmp(cmd, "get ", 4)) {
1268 if (do_get(cmd) == 0) {
1271 } else if (!strncasecmp(cmd, "ls", 2)) {
1272 if (do_ls(cmd) == 0) {
1275 } else if (!strncasecmp(cmd, "cd", 2)) {
1276 if (do_cd(cmd) == 0) {
1279 } else if (!strncasecmp(cmd, "rm", 2)) {
1280 if (do_rm(cmd) == 0) {
1283 } else if (!strncasecmp(cmd, "fault", 5)) {
1284 if (do_fault(cmd) == 0) {
1287 } else if (!strncasecmp(cmd, "sh ", 3)) {
1289 } else if (!strncasecmp(cmd, "x ", 2)) {
1300 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
1303 static char cmd_buffer[256];
1307 const char escape_str[] = { 0x1b, 0x5b, 0x0 };
1308 const char *escape_ptr = escape_str;
1312 fd = ecore_main_fd_handler_fd_get(fd_handler);
1314 printf("FD is not valid: %d\n", fd);
1315 return ECORE_CALLBACK_CANCEL;
1318 fd = s_info.input_fd;
1323 * Using this routine, we can implement the command recommend algorithm.
1324 * When a few more characters are matched with history of command, we can show it to user
1325 * Then the user will choose one or write new command
1329 while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) {
1330 if (*escape_ptr == '\0') {
1334 printf("%s2K%s1G", escape_str, escape_str);
1335 tmp = get_command(--s_info.history_idx);
1337 s_info.history_idx = 0;
1338 cmd_buffer[0] = '\0';
1341 strcpy(cmd_buffer, tmp);
1342 idx = strlen(cmd_buffer);
1346 case 0x42: /* DOWN */
1347 if (s_info.history_idx >= 0) {
1351 printf("%s2K%s1G", escape_str, escape_str);
1352 tmp = get_command(++s_info.history_idx);
1353 if (s_info.history_idx == 0) {
1354 s_info.history_idx = 0;
1355 cmd_buffer[0] = '\0';
1358 strcpy(cmd_buffer, tmp);
1359 idx = strlen(cmd_buffer);
1363 case 0x43: /* RIGHT */
1365 case 0x44: /* LEFT */
1371 escape_ptr = escape_str;
1373 } else if (ch == *escape_ptr) {
1379 case 0x08: /* BKSP */
1380 cmd_buffer[idx] = '\0';
1383 cmd_buffer[idx] = ' ';
1388 cmd_buffer[idx] = '\0';
1392 case 0x09: /* TAB */
1393 if (!s_info.quick_search_node) {
1394 s_info.quick_search_node = node_child(s_info.curdir);
1395 s_info.quick_idx = idx;
1397 s_info.quick_search_node = node_next_sibling(s_info.quick_search_node);
1398 idx = s_info.quick_idx;
1401 if (!s_info.quick_search_node) {
1405 printf("%s2K%s1G", escape_str, escape_str);
1406 strcpy(cmd_buffer + idx, node_name(s_info.quick_search_node));
1407 idx += strlen(node_name(s_info.quick_search_node));
1412 cmd_buffer[idx] = '\0';
1414 if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1415 putc((int)'\n', stdout);
1417 do_command(cmd_buffer);
1418 put_command(cmd_buffer);
1419 memset(cmd_buffer, 0, sizeof(cmd_buffer));
1420 s_info.history_idx = 0;
1421 s_info.quick_search_node = NULL;
1423 /* Make a main loop processing for command handling */
1424 return ECORE_CALLBACK_RENEW;
1426 cmd_buffer[idx++] = ch;
1428 if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1429 putc((int)ch, stdout);
1432 if (idx == sizeof(cmd_buffer) - 1) {
1433 cmd_buffer[idx] = '\0';
1434 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
1441 if (ret < 0 && !fd_handler) {
1442 ecore_main_loop_quit();
1445 return ECORE_CALLBACK_RENEW;
1448 static void processing_line_buffer(const char *buffer)
1451 char slavename[256];
1469 struct package *pkginfo;
1470 struct instance *instinfo;
1471 struct slave *slaveinfo;
1474 switch (s_info.cmd) {
1476 if (sscanf(buffer, "%d %255[^ ] %255[^ ] %255[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
1477 printf("Invalid format : [%s]\n", buffer);
1481 node = node_find(s_info.targetdir, pkgname);
1483 pkginfo = calloc(1, sizeof(*pkginfo));
1485 printf("Error: %s\n", strerror(errno));
1489 pkginfo->pkgid = strdup("conf.file");
1490 if (!pkginfo->pkgid) {
1491 printf("Error: %s\n", strerror(errno));
1494 pkginfo->primary = 1;
1496 node = node_create(s_info.targetdir, pkgname, NODE_DIR);
1498 free(pkginfo->pkgid);
1500 printf("Failed to create a new node (%s)\n", pkgname);
1504 node_set_mode(node, NODE_READ | NODE_EXEC);
1505 node_set_data(node, pkginfo);
1507 pkginfo = node_data(node);
1509 printf("Package info is inavlid\n");
1513 free(pkginfo->slavename);
1516 pkginfo->slavename = NULL;
1517 pkginfo->abi = NULL;
1520 node_set_age(node, s_info.age);
1522 pkginfo->slavename = strdup(slavename);
1523 if (!pkginfo->slavename) {
1524 printf("Error: %s\n", strerror(errno));
1527 pkginfo->abi = strdup(abi);
1528 if (!pkginfo->abi) {
1529 printf("Error: %s\n", strerror(errno));
1533 pkginfo->refcnt = refcnt;
1534 pkginfo->fault_count = fault_count;
1535 pkginfo->inst_count = list_count;
1538 if (sscanf(buffer, "%d %[^ ] %[^ ] %[^ ] %d %d %d %[^ ] %d %d %lf", &pid, slavename, pkgname, abi, &secured, &refcnt, &fault_count, state, &loaded_inst, &loaded_pkg, &ttl) != 11) {
1539 printf("Invalid format : [%s]\n", buffer);
1542 node = node_find(s_info.targetdir, slavename);
1544 slaveinfo = calloc(1, sizeof(*slaveinfo));
1546 printf("Error: %s\n", strerror(errno));
1550 node = node_create(s_info.targetdir, slavename, NODE_DIR);
1556 node_set_mode(node, NODE_READ | NODE_EXEC);
1557 node_set_data(node, slaveinfo);
1559 slaveinfo = node_data(node);
1562 node_set_age(node, s_info.age);
1564 free(slaveinfo->pkgname);
1565 free(slaveinfo->abi);
1566 free(slaveinfo->state);
1568 slaveinfo->pkgname = strdup(pkgname);
1569 if (!slaveinfo->pkgname) {
1570 printf("Error: %s\n", strerror(errno));
1573 slaveinfo->abi = strdup(abi);
1574 if (!slaveinfo->abi) {
1575 printf("Error: %s\n", strerror(errno));
1578 slaveinfo->state = strdup(state);
1579 if (!slaveinfo->state) {
1580 printf("Error: %s\n", strerror(errno));
1583 slaveinfo->pid = pid;
1584 slaveinfo->secured = secured;
1585 slaveinfo->refcnt = refcnt;
1586 slaveinfo->fault_count = fault_count;
1587 slaveinfo->loaded_inst = loaded_inst;
1588 slaveinfo->loaded_pkg = loaded_pkg;
1589 slaveinfo->ttl = ttl;
1592 if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
1593 printf("Invalid format : [%s]\n", buffer);
1597 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
1598 i += (inst_id[i] == '/');
1600 node = node_find(s_info.targetdir, inst_id + i);
1602 instinfo = calloc(1, sizeof(*instinfo));
1604 printf("Error: %s\n", strerror(errno));
1608 node = node_create(s_info.targetdir, inst_id + i, NODE_FILE);
1614 node_set_mode(node, NODE_READ | NODE_WRITE);
1615 node_set_data(node, instinfo);
1617 instinfo = node_data(node);
1620 node_set_age(node, s_info.age);
1623 free(instinfo->cluster);
1624 free(instinfo->category);
1625 free(instinfo->state);
1627 instinfo->id = strdup(inst_id);
1628 if (!instinfo->id) {
1629 printf("Error: %s\n", strerror(errno));
1632 instinfo->cluster = strdup(cluster);
1633 if (!instinfo->cluster) {
1634 printf("Error: %s\n", strerror(errno));
1637 instinfo->category = strdup(category);
1638 if (!instinfo->category) {
1639 printf("Error: %s\n", strerror(errno));
1642 instinfo->state = strdup(state);
1643 if (!instinfo->state) {
1644 printf("Error: %s\n", strerror(errno));
1647 instinfo->period = period;
1648 instinfo->width = width;
1649 instinfo->height = height;
1652 sscanf(buffer, "%d", &i);
1653 printf("%s\n", strerror(i));
1654 printf("Result: %d\n", i);
1657 sscanf(buffer, "%d", &i);
1658 printf("Result: %d\n", i);
1661 sscanf(buffer, "%d", &i);
1662 printf("Result: %d\n", i);
1669 static inline void do_line_command(void)
1671 switch (s_info.cmd) {
1693 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
1696 static char *line_buffer = NULL;
1697 static int line_index = 0;
1698 static int bufsz = 256;
1701 fd = ecore_main_fd_handler_fd_get(fd_handler);
1703 printf("FD is not valid: %d\n", fd);
1704 return ECORE_CALLBACK_CANCEL;
1707 if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
1708 printf("Error: %s\n", strerror(errno));
1709 return ECORE_CALLBACK_CANCEL;
1714 line_buffer = malloc(bufsz);
1716 printf("Error: %s\n", strerror(errno));
1717 return ECORE_CALLBACK_CANCEL;
1721 if (ch == '\n') { /* End of a line */
1722 if (line_index == bufsz - 1) {
1724 new_buf = realloc(line_buffer, bufsz + 2);
1726 printf("Error: %s\n", strerror(errno));
1731 return ECORE_CALLBACK_CANCEL;
1734 line_buffer = new_buf;
1737 line_buffer[line_index] = '\0';
1739 if (!strcmp(line_buffer, "EOD")) {
1743 processing_line_buffer(line_buffer);
1753 line_buffer[line_index++] = ch;
1754 if (line_index == bufsz - 1) {
1756 new_buf = realloc(line_buffer, bufsz);
1758 printf("Error: %s\n", strerror(errno));
1763 return ECORE_CALLBACK_CANCEL;
1766 line_buffer = new_buf;
1770 return ECORE_CALLBACK_RENEW;
1773 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1775 const char *fifo_name;
1778 if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
1779 printf("Invalid packet\n");
1784 printf("Returns %d\n", ret);
1788 printf("FIFO: %s\n", fifo_name);
1790 s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
1791 if (s_info.fifo_handle < 0) {
1792 printf("Error: %s\n", strerror(errno));
1793 s_info.fifo_handle = -EINVAL;
1794 ecore_main_loop_quit();
1798 s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
1799 if (!s_info.fd_handler) {
1800 printf("Failed to add a fd handler\n");
1801 if (close(s_info.fifo_handle) < 0) {
1802 printf("close: %s\n", strerror(errno));
1804 s_info.fifo_handle = -EINVAL;
1805 ecore_main_loop_quit();
1811 if (s_info.input_fd == STDIN_FILENO) {
1812 if (fcntl(s_info.input_fd, F_SETFL, O_NONBLOCK) < 0) {
1813 printf("Error: %s\n", strerror(errno));
1816 s_info.in_handler = ecore_main_fd_handler_add(s_info.input_fd, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
1817 if (!s_info.in_handler) {
1818 printf("Failed to add a input handler\n");
1819 ecore_main_loop_quit();
1827 static int disconnected_cb(int handle, void *data)
1829 printf("Disconnected\n");
1830 ecore_main_loop_quit();
1834 static int connected_cb(int handle, void *data)
1836 struct packet *packet;
1838 printf("Connected\n");
1840 packet = packet_create("liveinfo_hello", "d", 0.0f);
1842 printf("Failed to build a packet for hello\n");
1843 com_core_packet_client_fini(s_info.fd);
1844 s_info.fd = -EINVAL;
1850 if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
1851 printf("Failed to send a packet hello\n");
1852 packet_destroy(packet);
1853 com_core_packet_client_fini(s_info.fd);
1854 s_info.fd = -EINVAL;
1858 packet_destroy(packet);
1862 int main(int argc, char *argv[])
1864 struct termios ttystate;
1865 static struct method s_table[] = {
1871 static struct option long_options[] = {
1872 { "batchmode", required_argument, 0, 'b' },
1873 { "help", no_argument, 0, 'h' },
1874 { "verbose", required_argument, 0, 'v' },
1875 { "execute", required_argument, 0, 'x' },
1882 c = getopt_long(argc, argv, "b:hv:x:", long_options, &option_index);
1885 if (!optarg || !*optarg) {
1886 printf("Invalid argument\n");
1891 if (s_info.input_fd != STDIN_FILENO) {
1892 /* Close the previously, opened file */
1893 if (close(s_info.input_fd) < 0) {
1894 printf("close: %s\n", strerror(errno));
1898 s_info.input_fd = open(optarg, O_RDONLY);
1899 if (s_info.input_fd < 0) {
1900 printf("Unable to access %s (%s)\n", optarg, strerror(errno));
1908 if (!optarg || !*optarg) {
1909 printf("Invalid argument\n");
1914 s_info.verbose = !strcmp(optarg, "true");
1917 if (!optarg || !*optarg) {
1918 printf("Invalid argument\n");
1930 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
1934 com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1935 com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1936 livebox_service_init();
1938 s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
1939 if (s_info.fd < 0) {
1940 printf("Failed to make a connection\n");
1944 if (s_info.input_fd == STDIN_FILENO) {
1945 printf("Type your command on below empty line\n");
1947 if (tcgetattr(s_info.input_fd, &ttystate) < 0) {
1948 printf("Error: %s\n", strerror(errno));
1950 ttystate.c_lflag &= ~(ICANON | ECHO);
1951 ttystate.c_cc[VMIN] = 1;
1953 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
1954 printf("Error: %s\n", strerror(errno));
1958 printf("Batch mode enabled\n");
1961 if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0) {
1962 printf("Error: %s\n", strerror(errno));
1967 ecore_main_loop_begin();
1970 livebox_service_fini();
1972 if (s_info.fd > 0) {
1973 com_core_packet_client_fini(s_info.fd);
1974 s_info.fd = -EINVAL;
1977 if (s_info.fd_handler) {
1978 ecore_main_fd_handler_del(s_info.fd_handler);
1979 s_info.fd_handler = NULL;
1982 if (s_info.input_fd == STDIN_FILENO) {
1983 ttystate.c_lflag |= ICANON | ECHO;
1984 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
1985 printf("Error: %s\n", strerror(errno));
1988 if (close(s_info.input_fd) < 0) {
1989 printf("close: %s\n", strerror(errno));
1993 if (s_info.fifo_handle > 0) {
1994 if (close(s_info.fifo_handle) < 0) {
1995 printf("close: %s\n", strerror(errno));
1997 s_info.fifo_handle = -EINVAL;
2000 if (s_info.in_handler) {
2001 ecore_main_fd_handler_del(s_info.in_handler);
2002 s_info.in_handler = NULL;
2006 putc((int)'\n', stdout);