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>
32 #include <X11/extensions/Xdamage.h>
33 #include <X11/extensions/Xfixes.h>
34 #include <X11/extensions/XShm.h>
35 #include <X11/Xutil.h>
38 #include <glib-object.h>
41 #include <com-core_packet.h>
44 #include <dynamicbox_service.h>
51 #define PROMPT "liveinfo "
52 #define PROVIDER_FOLDER "provider"
53 #define PACKAGE_FOLDER "package"
104 Ecore_Fd_Handler *fd_handler;
105 Ecore_Fd_Handler *in_handler;
107 struct node *rootdir;
109 struct node *targetdir;
122 struct node *quick_search_node;
127 .fifo_handle = -EINVAL,
135 .input_fd = STDIN_FILENO,
141 .quick_search_node = NULL,
152 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler);
154 static Eina_Bool process_line_cb(void *data)
156 input_cb(NULL, NULL);
157 return ECORE_CALLBACK_CANCEL;
160 static inline void prompt(const char *cmdline)
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);
170 path = node_to_abspath(s_info.curdir);
171 printf(PROMPT"%s # %s", path, cmdline ? cmdline : "");
175 static void provider_del_cb(struct node *node)
179 info = node_data(node);
190 static void package_del_cb(struct node *node)
192 struct package *info;
194 info = node_data(node);
200 free(info->slavename);
205 static void inst_del_cb(struct node *node)
207 struct instance *info;
209 info = node_data(node);
217 free(info->category);
229 struct node *next_node;
231 if (!(node_mode(s_info.targetdir) & NODE_READ)) {
232 printf("Access denied\n");
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);
240 node = node_child(s_info.targetdir);
243 struct package *info;
245 next_node = node_next_sibling(node);
246 if (node_age(node) != s_info.age) {
247 node_delete(node, package_del_cb);
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) {
257 next_node = node_next_sibling(node);
258 if (node_age(node) != s_info.age) {
259 node_delete(node, provider_del_cb);
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;
271 next_node = node_next_sibling(node);
273 if (node_age(node) != s_info.age) {
274 node_delete(node, inst_del_cb);
279 info = node_data(node);
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);
286 printf("%2.2lf KB ", (double)stat.st_size / 1024.0f);
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));
297 node = node_next_sibling(node);
301 printf("Total: %d\n", cnt);
304 static void send_slave_list(void)
306 struct packet *packet;
309 if (s_info.cmd != NOP) {
310 printf("Previous command is not finished\n");
314 packet = packet_create_noack("slave_list", "d", 0.0f);
316 printf("Failed to create a packet\n");
320 ret = com_core_packet_send_only(s_info.fd, packet);
321 packet_destroy(packet);
323 printf("Failed to send a packet: %d\n", ret);
327 s_info.cmd = SLAVE_LIST;
332 * var = debug, slave_max_load
335 static void send_command(const char *cmd, const char *var, const char *val)
337 struct packet *packet;
340 if (s_info.cmd != NOP) {
341 printf("Previous command is not finished\n");
345 packet = packet_create_noack("master_ctrl", "sss", cmd, var, val);
347 printf("Failed to create a ctrl packet\n");
351 ret = com_core_packet_send_only(s_info.fd, packet);
352 packet_destroy(packet);
354 printf("Failed to send packet ctrl\n");
358 s_info.cmd = MASTER_CTRL;
362 static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
364 struct node *parent = data;
366 struct package *info;
368 node = node_find(parent, lbid);
370 info = node_data(node);
372 printf("Invalid node\n");
377 info->pkgid = strdup(appid);
379 printf("Error: %s\n", strerror(errno));
383 node_set_age(node, s_info.age);
387 info = calloc(1, sizeof(*info));
389 printf("Error: %s\n", strerror(errno));
393 info->pkgid = strdup(appid);
395 printf("Error: %s\n", strerror(errno));
400 info->primary = is_prime;
402 node = node_create(parent, lbid, NODE_DIR, NODE_READ | NODE_EXEC);
409 node_set_data(node, info);
410 node_set_age(node, s_info.age);
414 static void send_pkg_list(void)
416 struct packet *packet;
419 if (s_info.cmd != NOP) {
420 printf("Previous command is not finished\n");
424 packet = packet_create_noack("pkg_list", "d", 0.0f);
426 printf("Failed to create a packet\n");
430 ret = com_core_packet_send_only(s_info.fd, packet);
431 packet_destroy(packet);
433 printf("Failed to create a packet\n");
437 s_info.cmd = PKG_LIST;
440 dynamicbox_service_get_pkglist(pkglist_cb, s_info.targetdir);
443 static void send_inst_delete(void)
445 struct packet *packet;
448 struct instance *inst;
451 if (s_info.cmd != NOP) {
452 printf("Previous command is not finished\n");
456 parent = node_parent(s_info.targetdir);
458 printf("Invalid argument\n");
462 if (!node_parent(parent)) {
463 printf("Invalid argument\n");
467 name = node_name(node_parent(parent));
468 if (!name || strcmp(name, PACKAGE_FOLDER)) {
469 printf("Invalid argument\n");
473 inst = node_data(s_info.targetdir);
474 name = node_name(parent);
476 packet = packet_create_noack("pkg_ctrl", "sss", "rminst", name, inst->id);
478 printf("Failed to create a packet\n");
482 ret = com_core_packet_send_only(s_info.fd, packet);
483 packet_destroy(packet);
485 printf("Failed to send a packet: %d\n", ret);
489 s_info.cmd = INST_CTRL;
493 static void send_inst_fault(void)
495 struct packet *packet;
498 struct instance *inst;
501 if (s_info.cmd != NOP) {
502 printf("Previous command is not finished\n");
506 parent = node_parent(s_info.targetdir);
508 printf("Invalid argument\n");
512 if (!node_parent(parent)) {
513 printf("Invalid argument\n");
517 name = node_name(node_parent(parent));
518 if (!name || strcmp(name, PACKAGE_FOLDER)) {
519 printf("Invalid argument\n");
523 inst = node_data(s_info.targetdir);
524 name = node_name(parent);
526 packet = packet_create_noack("pkg_ctrl", "sss", "faultinst", name, inst->id);
528 printf("Failed to create a packet\n");
532 ret = com_core_packet_send_only(s_info.fd, packet);
533 packet_destroy(packet);
535 printf("Failed to send a packet: %d\n", ret);
539 s_info.cmd = INST_CTRL;
543 static void send_inst_list(const char *pkgname)
545 struct packet *packet;
548 if (s_info.cmd != NOP) {
549 printf("Previous command is not finished\n");
553 packet = packet_create_noack("inst_list", "s", pkgname);
555 printf("Failed to create a packet\n");
559 ret = com_core_packet_send_only(s_info.fd, packet);
560 packet_destroy(packet);
562 printf("Failed to send a packet: %d\n", ret);
566 s_info.cmd = INST_LIST;
570 static void help(void)
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");
594 static inline void init_directory(void)
597 s_info.rootdir = node_create(NULL, NULL, NODE_DIR, NODE_READ | NODE_EXEC);
598 if (!s_info.rootdir) {
602 node = node_create(s_info.rootdir, PROVIDER_FOLDER, NODE_DIR, NODE_READ | NODE_EXEC);
604 node_destroy(s_info.rootdir);
605 s_info.rootdir = NULL;
609 node = node_create(s_info.rootdir, PACKAGE_FOLDER, NODE_DIR, NODE_READ | NODE_EXEC);
611 node_destroy(node_child(s_info.rootdir));
612 node_destroy(s_info.rootdir);
613 s_info.rootdir = NULL;
617 s_info.curdir = s_info.rootdir;
621 static inline void fini_directory(void)
625 static struct node *update_target_dir(const char *cmd)
629 node = (*cmd == '/') ? s_info.rootdir : s_info.curdir;
630 node = node_find(node, cmd);
635 static int get_token(const char *src, char *out)
638 while (*src && *src == ' ') src++;
644 while (*src && *src != ' ') {
653 static inline int do_stat(const char *cmd)
668 while (*cmd && *cmd == ' ') cmd++;
671 printf("Invalid argument\n");
675 node = node_find(*cmd == '/' ? s_info.rootdir : s_info.curdir, cmd);
677 printf("Invalid path\n");
683 parent = node_parent(node);
685 if (!node_name(parent)) {
686 printf("%s has no info\n", node_name(node));
688 } else if (!strcmp(node_name(parent), PACKAGE_FOLDER)) {
689 type = (i == 0) ? PKG : PKG_INSTANCE;
691 } else if (!strcmp(node_name(parent), PROVIDER_FOLDER)){
692 type = (i == 0) ? PROVIDER : PROVIDER_INSTANCE;
696 parent = node_parent(parent);
699 printf("%s is invalid path\n", node_name(node));
706 tmp = dynamicbox_service_i18n_name(node_name(node), NULL);
707 printf("Name: %s (", tmp);
710 i = dynamicbox_service_is_enabled(node_name(node));
711 printf("%s)\n", i ? "enabled" : "disabled");
713 tmp = dynamicbox_service_i18n_icon(node_name(node), NULL);
714 printf("Icon: %s\n", tmp);
717 tmp = dynamicbox_service_provider_name(node_name(node));
718 printf("Provider: %s (content:", tmp);
721 tmp = dynamicbox_service_content(node_name(node));
722 printf("%s)\n", tmp);
725 tmp = dynamicbox_service_dbox_script_path(node_name(node));
726 printf("LB Script: %s (", tmp);
729 tmp = dynamicbox_service_dbox_script_group(node_name(node));
730 printf("%s)\n", tmp);
733 tmp = dynamicbox_service_gbar_script_path(node_name(node));
734 printf("PD Script: %s (", tmp);
737 tmp = dynamicbox_service_gbar_script_group(node_name(node));
738 printf("%s)\n", tmp);
743 printf("Not supported yet\n");
746 printf("Not supported yet\n");
748 case PROVIDER_INSTANCE:
749 printf("Not supported yet\n");
752 printf("Not supported yet\n");
759 static int do_set(const char *cmd)
762 char variable[4096] = { '0', };
765 i = get_token(cmd, variable);
768 while (*cmd && *cmd == ' ') {
773 printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
777 send_command("set", variable, cmd);
781 static inline int do_get(const char *cmd)
785 while (*cmd && *cmd == ' ') cmd++;
787 printf("Invalid argument(%s): get [VAR]\n", cmd);
791 send_command("get", cmd, "");
795 static inline int do_ls(const char *cmd)
802 while (*cmd && *cmd == ' ') {
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);
812 name = node_name(s_info.targetdir);
814 if (!strcmp(name, PACKAGE_FOLDER)) {
815 if (s_info.cmd == NOP) {
820 printf("Waiting the server response\n");
822 } else if (!strcmp(name, PROVIDER_FOLDER)) {
823 if (s_info.cmd == NOP) {
828 printf("Waiting the server response\n");
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");
841 send_inst_list(name);
850 static inline int do_cd(const char *cmd)
854 while (*cmd && *cmd == ' ') {
862 if (s_info.cmd != NOP) {
863 printf("Waiting the server response\n");
867 s_info.targetdir = update_target_dir(cmd);
868 if (!s_info.targetdir) {
869 printf("%s is not exists\n", cmd);
873 if (node_type(s_info.targetdir) != NODE_DIR) {
874 printf("Unable change directory to %s\n", cmd);
878 if (!(node_mode(s_info.targetdir) & NODE_EXEC)) {
879 printf("Access denied %s\n", cmd);
883 s_info.curdir = s_info.targetdir;
887 static inline int do_rm(const char *cmd)
890 while (*cmd && *cmd == ' ') cmd++;
895 if (s_info.cmd != NOP) {
896 printf("Waiting the server response\n");
900 s_info.targetdir = update_target_dir(cmd);
901 if (!s_info.targetdir) {
902 printf("%s is not exists\n", cmd);
906 if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
907 printf("Access denied %s\n", cmd);
915 static inline int do_fault(const char *cmd)
918 while (*cmd && *cmd == ' ') cmd++;
923 if (s_info.cmd != NOP) {
924 printf("Waiting the server response\n");
928 s_info.targetdir = update_target_dir(cmd);
929 if (!s_info.targetdir) {
930 printf("%s is not exists\n", cmd);
934 if (!(node_mode(s_info.targetdir) & NODE_WRITE)) {
935 printf("Access denied %s\n", cmd);
943 #if !defined(WCOREDUMP)
944 #define WCOREDUMP(a) 0
947 static void do_sh(const char *cmd)
953 while (*cmd && *cmd == ' ') {
967 while (idx < (sizeof(command) - 1) && *cmd && *cmd != ' ') {
968 command[idx++] = *cmd++;
972 if (execl(command, cmd, NULL) < 0) {
973 printf("Failed to execute: %s\n", strerror(errno));
977 } else if (pid < 0) {
978 printf("Failed to create a new process: %s\n", strerror(errno));
981 if (waitpid(pid, &status, 0) < 0) {
982 printf("error: %s\n", strerror(errno));
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");
997 static inline int get_pixmap_size(Display *disp, Pixmap id, int *x, int *y, unsigned int *w, unsigned int *h)
1000 unsigned int dummy_border, dummy_depth;
1012 if (!XGetGeometry(disp, id, &dummy_win, x, y, w, h, &dummy_border, &dummy_depth)) {
1019 static inline int do_capture(Display *disp, Pixmap id, const char *filename)
1030 screen = DefaultScreenOfDisplay(disp);
1031 visual = DefaultVisualOfScreen(screen);
1033 if (get_pixmap_size(disp, id, NULL, NULL, &w, &h) < 0) {
1034 printf("Failed to get size of a pixmap\n");
1038 printf("Pixmap size: %dx%d\n", w, h);
1039 bufsz = w * h * sizeof(int);
1041 si.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0666);
1043 printf("shmget: %s\n", strerror(errno));
1047 si.readOnly = False;
1048 si.shmaddr = shmat(si.shmid, NULL, 0);
1049 if (si.shmaddr == (void *)-1) {
1051 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1052 printf("shmctl: %s\n", strerror(errno));
1060 * Use the 24 bits Pixmap for Video player
1062 xim = XShmCreateImage(disp, visual, 24 /* (depth << 3) */, ZPixmap, NULL, &si, w, h);
1064 if (shmdt(si.shmaddr) < 0) {
1065 printf("shmdt: %s\n", strerror(errno));
1068 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1069 printf("shmctl: %s\n", strerror(errno));
1075 xim->data = si.shmaddr;
1076 XShmAttach(disp, &si);
1078 XShmGetImage(disp, id, xim, 0, 0, 0xFFFFFFFF);
1081 fd = open(filename, O_CREAT | O_RDWR, 0644);
1083 if (write(fd, xim->data, bufsz) != bufsz) {
1084 printf("Data is not fully written\n");
1087 if (close(fd) < 0) {
1088 printf("close: %s\n", strerror(errno));
1091 printf("Error: %sn\n", strerror(errno));
1094 XShmDetach(disp, &si);
1097 if (shmdt(si.shmaddr) < 0) {
1098 printf("shmdt: %s\n", strerror(errno));
1101 if (shmctl(si.shmid, IPC_RMID, 0) < 0) {
1102 printf("shmctl: %s\n", strerror(errno));
1108 static void do_dump(const char *cmd)
1113 struct node *curdir;
1114 struct node *target;
1118 while (*cmd && *cmd == ' ') {
1126 curdir = s_info.curdir;
1130 while (cmd[idx] != '/' && cmd[idx] != '\0' && cmd[idx] != ' ') {
1138 strncpy(path, cmd, idx);
1142 node = node_child(curdir);
1144 if (!strcmp(node_name(node), path)) {
1150 node = node_next_sibling(node);
1158 if (target && node_type(target) != NODE_DIR) {
1159 struct instance *instinfo;
1161 if (node_type(target) == NODE_LINK) {
1162 /* Follow up node */
1165 instinfo = node_data(target);
1167 while (*cmd == ' ') {
1171 if (sscanf(cmd, "%255[^ ]", path) != 1) {
1172 printf("dump file OUT_FILENAME\n");
1176 if (instinfo->buf_id) {
1177 unsigned int pixmap;
1179 if (sscanf(instinfo->buf_id, "pixmap://%u:%d", &pixmap, &pixel_size) == 2) {
1182 disp = XOpenDisplay(NULL);
1184 printf("Failed to connect to the X\n");
1188 if (do_capture(disp, (Pixmap)pixmap, path) == 0) {
1189 printf("Captured: %s\n", path);
1191 XCloseDisplay(disp);
1193 printf("Unsupported type\n");
1196 printf("Buffer is not exists\n");
1200 printf("target only can be a filename\n");
1204 static void do_x(const char *cmd)
1210 while (*cmd && *cmd == ' ') {
1218 disp = XOpenDisplay(NULL);
1220 printf("Failed to connect to the X\n");
1224 if (!strncasecmp(cmd, "damage ", 7)) {
1227 XserverRegion region;
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");
1240 region = XFixesCreateRegion(disp, &rect, 1);
1241 XDamageAdd(disp, winId, region);
1242 XFixesDestroyRegion(disp, region);
1245 printf("Damage: %u %d %d %d %d\n", winId, x, y, w, h);
1246 } else if (!strncasecmp(cmd, "capture ", 8)) {
1252 if (sscanf(cmd, "%u %255[^ ]", &winId, filename) != 2) {
1253 printf("Invalid argument\nx capture WINID_DEC FILENAME (%s)\n", cmd);
1256 if (do_capture(disp, winId, filename) == 0) {
1257 printf("Captured: %s\n", filename);
1259 } else if (!strncasecmp(cmd, "resize ", 7)) {
1266 if (sscanf(cmd, "%u %d %d", &winId, &w, &h) != 3) {
1267 printf("Invalid argument\nx resize WINID_DEC W H\n");
1271 XResizeWindow(disp, winId, w, h);
1272 printf("Resize: %u %d %d\n", winId, w, h);
1273 } else if (!strncasecmp(cmd, "move ", 5)) {
1279 if (sscanf(cmd, "%u %d %d", &winId, &x, &y) != 3) {
1280 printf("Invalid argument\nx move WINID_DEC X Y\n");
1284 XMoveWindow(disp, winId, x, y);
1285 printf("Move: %u %d %d\n", winId, x, y);
1286 } else if (!strncasecmp(cmd, "map ", 4)) {
1289 if (sscanf(cmd, "%u", &winId) != 1) {
1290 printf("Invalid argument\nx map WINID_DEC\n");
1293 XMapRaised(disp, winId);
1294 printf("Map: %u\n", winId);
1295 } else if (!strncasecmp(cmd, "unmap ", 6)) {
1298 if (sscanf(cmd, "%u", &winId) != 1) {
1299 printf("Invalid argument\nx unmap WINID_DEC\n");
1302 XUnmapWindow(disp, winId);
1303 printf("Unmap: %u\n", winId);
1305 printf("Unknown command\n");
1308 XCloseDisplay(disp);
1311 static inline void put_command(const char *cmd)
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;
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]));
1322 static inline const char *get_command(int idx)
1324 idx = s_info.history_top + idx;
1326 idx += (sizeof(s_info.history) / sizeof(s_info.history[0]));
1329 return s_info.history[idx];
1332 static void do_command(const char *cmd)
1334 /* Skip the first spaces */
1335 while (*cmd && *cmd == ' ') {
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) {
1346 } else if (!strncasecmp(cmd, "stat ", 5)) {
1348 } else if (!strncasecmp(cmd, "get ", 4)) {
1349 if (do_get(cmd) == 0) {
1352 } else if (!strncasecmp(cmd, "ls", 2)) {
1353 if (do_ls(cmd) == 0) {
1356 } else if (!strncasecmp(cmd, "cd", 2)) {
1357 if (do_cd(cmd) == 0) {
1360 } else if (!strncasecmp(cmd, "rm", 2)) {
1361 if (do_rm(cmd) == 0) {
1364 } else if (!strncasecmp(cmd, "fault", 5)) {
1365 if (do_fault(cmd) == 0) {
1368 } else if (!strncasecmp(cmd, "sh ", 3)) {
1370 } else if (!strncasecmp(cmd, "x ", 2)) {
1372 } else if (!strncasecmp(cmd, "dump", 4)) {
1383 #define CMD_BUFFER_SIZE 256
1385 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
1388 static char cmd_buffer[CMD_BUFFER_SIZE];
1392 const char escape_str[] = { 0x1b, 0x5b, 0x0 };
1393 const char *escape_ptr = escape_str;
1397 fd = ecore_main_fd_handler_fd_get(fd_handler);
1399 printf("FD is not valid: %d\n", fd);
1400 return ECORE_CALLBACK_CANCEL;
1403 fd = s_info.input_fd;
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
1414 while ((ret = read(fd, &ch, sizeof(ch))) == sizeof(ch)) {
1415 if (*escape_ptr == '\0') {
1419 printf("%s2K%s1G", escape_str, escape_str);
1420 tmp = get_command(--s_info.history_idx);
1422 s_info.history_idx = 0;
1423 cmd_buffer[0] = '\0';
1426 strcpy(cmd_buffer, tmp);
1427 idx = strlen(cmd_buffer);
1431 case 0x42: /* DOWN */
1432 if (s_info.history_idx >= 0) {
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';
1443 strncpy(cmd_buffer, tmp, CMD_BUFFER_SIZE - 1);
1444 cmd_buffer[CMD_BUFFER_SIZE - 1] = '\0';
1445 idx = strlen(cmd_buffer);
1449 case 0x43: /* RIGHT */
1451 case 0x44: /* LEFT */
1457 escape_ptr = escape_str;
1459 } else if (ch == *escape_ptr) {
1465 case 0x7F: /* BKSP */
1467 cmd_buffer[idx] = '\0';
1470 cmd_buffer[idx] = ' ';
1475 cmd_buffer[idx] = '\0';
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;
1484 s_info.quick_search_node = node_next_sibling(s_info.quick_search_node);
1485 idx = s_info.quick_idx;
1488 if (!s_info.quick_search_node) {
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));
1499 cmd_buffer[idx] = '\0';
1501 if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1502 putc((int)'\n', stdout);
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;
1510 /* Make a main loop processing for command handling */
1511 return ECORE_CALLBACK_RENEW;
1514 cmd_buffer[idx++] = ch;
1516 if (s_info.input_fd == STDIN_FILENO || s_info.verbose) {
1517 putc((int)ch, stdout);
1520 if (idx == sizeof(cmd_buffer) - 1) {
1521 cmd_buffer[idx] = '\0';
1522 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
1526 printf("Unknown character: 0x%X\n", (unsigned int)ch);
1532 if (ret < 0 && !fd_handler) {
1533 ecore_main_loop_quit();
1536 return ECORE_CALLBACK_RENEW;
1539 static void processing_line_buffer(const char *buffer)
1542 char slavename[256];
1549 char str_period[64];
1562 struct package *pkginfo;
1563 struct instance *instinfo;
1564 struct slave *slaveinfo;
1567 switch (s_info.cmd) {
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);
1574 node = node_find(s_info.targetdir, pkgname);
1576 pkginfo = calloc(1, sizeof(*pkginfo));
1578 printf("Error: %s\n", strerror(errno));
1582 pkginfo->pkgid = strdup("conf.file");
1583 if (!pkginfo->pkgid) {
1584 printf("Error: %s\n", strerror(errno));
1587 pkginfo->primary = 1;
1589 node = node_create(s_info.targetdir, pkgname, NODE_DIR, NODE_READ | NODE_EXEC);
1591 free(pkginfo->pkgid);
1593 printf("Failed to create a new node (%s)\n", pkgname);
1597 node_set_data(node, pkginfo);
1599 pkginfo = node_data(node);
1601 printf("Package info is inavlid\n");
1605 free(pkginfo->slavename);
1608 pkginfo->slavename = NULL;
1609 pkginfo->abi = NULL;
1612 node_set_age(node, s_info.age);
1614 pkginfo->slavename = strdup(slavename);
1615 if (!pkginfo->slavename) {
1616 printf("Error: %s\n", strerror(errno));
1619 pkginfo->abi = strdup(abi);
1620 if (!pkginfo->abi) {
1621 printf("Error: %s\n", strerror(errno));
1625 pkginfo->refcnt = refcnt;
1626 pkginfo->fault_count = fault_count;
1627 pkginfo->inst_count = list_count;
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);
1634 node = node_find(s_info.targetdir, slavename);
1636 slaveinfo = calloc(1, sizeof(*slaveinfo));
1638 printf("Error: %s\n", strerror(errno));
1642 node = node_create(s_info.targetdir, slavename, NODE_DIR, NODE_READ | NODE_EXEC);
1648 node_set_data(node, slaveinfo);
1650 slaveinfo = node_data(node);
1653 node_set_age(node, s_info.age);
1655 free(slaveinfo->pkgname);
1656 free(slaveinfo->abi);
1657 free(slaveinfo->state);
1659 slaveinfo->pkgname = strdup(pkgname);
1660 if (!slaveinfo->pkgname) {
1661 printf("Error: %s\n", strerror(errno));
1664 slaveinfo->abi = strdup(abi);
1665 if (!slaveinfo->abi) {
1666 printf("Error: %s\n", strerror(errno));
1669 slaveinfo->state = strdup(state);
1670 if (!slaveinfo->state) {
1671 printf("Error: %s\n", strerror(errno));
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;
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);
1688 period = strtod(str_period, NULL);
1690 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
1691 i += (inst_id[i] == '/');
1693 node = node_find(s_info.targetdir, inst_id + i);
1695 instinfo = calloc(1, sizeof(*instinfo));
1697 printf("Error: %s\n", strerror(errno));
1701 node = node_create(s_info.targetdir, inst_id + i, NODE_FILE, NODE_READ | NODE_WRITE);
1707 node_set_data(node, instinfo);
1709 instinfo = node_data(node);
1712 node_set_age(node, s_info.age);
1715 free(instinfo->buf_id);
1716 free(instinfo->cluster);
1717 free(instinfo->category);
1718 free(instinfo->state);
1720 instinfo->id = strdup(inst_id);
1721 if (!instinfo->id) {
1722 printf("Error: %s\n", strerror(errno));
1725 instinfo->cluster = strdup(cluster);
1726 if (!instinfo->cluster) {
1727 printf("Error: %s\n", strerror(errno));
1730 instinfo->category = strdup(category);
1731 if (!instinfo->category) {
1732 printf("Error: %s\n", strerror(errno));
1735 instinfo->state = strdup(state);
1736 if (!instinfo->state) {
1737 printf("Error: %s\n", strerror(errno));
1740 if (strlen(buf_id)) {
1741 instinfo->buf_id = strdup(buf_id);
1744 instinfo->period = period;
1745 instinfo->width = width;
1746 instinfo->height = height;
1749 sscanf(buffer, "%d", &i);
1750 printf("%s\n", strerror(i));
1751 printf("Result: %d\n", i);
1754 sscanf(buffer, "%d", &i);
1755 printf("Result: %d\n", i);
1758 sscanf(buffer, "%d", &i);
1759 printf("Result: %d\n", i);
1766 static inline void do_line_command(void)
1768 switch (s_info.cmd) {
1790 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
1793 static char *line_buffer = NULL;
1794 static int line_index = 0;
1795 static int bufsz = 256;
1798 fd = ecore_main_fd_handler_fd_get(fd_handler);
1800 printf("FD is not valid: %d\n", fd);
1801 return ECORE_CALLBACK_CANCEL;
1804 if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
1805 printf("Error: %s\n", strerror(errno));
1806 return ECORE_CALLBACK_CANCEL;
1811 line_buffer = malloc(bufsz);
1813 printf("Error: %s\n", strerror(errno));
1814 return ECORE_CALLBACK_CANCEL;
1818 if (ch == '\n') { /* End of a line */
1819 if (line_index == bufsz - 1) {
1821 new_buf = realloc(line_buffer, bufsz + 2);
1823 printf("Error: %s\n", strerror(errno));
1828 return ECORE_CALLBACK_CANCEL;
1831 line_buffer = new_buf;
1834 line_buffer[line_index] = '\0';
1836 if (!strcmp(line_buffer, "EOD")) {
1840 processing_line_buffer(line_buffer);
1850 line_buffer[line_index++] = ch;
1851 if (line_index == bufsz - 1) {
1853 new_buf = realloc(line_buffer, bufsz);
1855 printf("Error: %s\n", strerror(errno));
1860 return ECORE_CALLBACK_CANCEL;
1863 line_buffer = new_buf;
1867 return ECORE_CALLBACK_RENEW;
1870 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1872 const char *fifo_name;
1875 if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
1876 printf("Invalid packet\n");
1881 printf("Returns %d\n", ret);
1885 printf("FIFO: %s\n", fifo_name);
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();
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));
1901 s_info.fifo_handle = -EINVAL;
1902 ecore_main_loop_quit();
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));
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();
1924 static int disconnected_cb(int handle, void *data)
1926 printf("Disconnected\n");
1927 ecore_main_loop_quit();
1931 static int connected_cb(int handle, void *data)
1933 struct packet *packet;
1935 printf("Connected\n");
1937 packet = packet_create("liveinfo_hello", "d", 0.0f);
1939 printf("Failed to build a packet for hello\n");
1940 com_core_packet_client_fini(s_info.fd);
1941 s_info.fd = -EINVAL;
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;
1955 packet_destroy(packet);
1959 int main(int argc, char *argv[])
1961 struct termios ttystate;
1962 static struct method s_table[] = {
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' },
1979 c = getopt_long(argc, argv, "b:hv:x:d", long_options, &option_index);
1982 if (!optarg || !*optarg) {
1983 printf("Invalid argument\n");
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));
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));
2005 if (!optarg || !*optarg) {
2006 printf("Invalid argument\n");
2011 s_info.verbose = !strcmp(optarg, "true");
2014 if (!optarg || !*optarg) {
2015 printf("Invalid argument\n");
2021 /** Dump all buffer to a files */
2031 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
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();
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");
2045 if (s_info.input_fd == STDIN_FILENO) {
2046 printf("Type your command on below empty line\n");
2048 if (tcgetattr(s_info.input_fd, &ttystate) < 0) {
2049 printf("Error: %s\n", strerror(errno));
2051 ttystate.c_lflag &= ~(ICANON | ECHO);
2052 ttystate.c_cc[VMIN] = 1;
2054 if (tcsetattr(s_info.input_fd, TCSANOW, &ttystate) < 0) {
2055 printf("Error: %s\n", strerror(errno));
2059 printf("Batch mode enabled\n");
2062 if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0) {
2063 printf("Error: %s\n", strerror(errno));
2068 ecore_main_loop_begin();
2071 dynamicbox_service_fini();
2073 if (s_info.fd > 0) {
2074 com_core_packet_client_fini(s_info.fd);
2075 s_info.fd = -EINVAL;
2078 if (s_info.fd_handler) {
2079 ecore_main_fd_handler_del(s_info.fd_handler);
2080 s_info.fd_handler = NULL;
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));
2089 if (close(s_info.input_fd) < 0) {
2090 printf("close: %s\n", strerror(errno));
2094 if (s_info.fifo_handle > 0) {
2095 if (close(s_info.fifo_handle) < 0) {
2096 printf("close: %s\n", strerror(errno));
2098 s_info.fifo_handle = -EINVAL;
2101 if (s_info.in_handler) {
2102 ecore_main_fd_handler_del(s_info.in_handler);
2103 s_info.in_handler = NULL;
2107 putc((int)'\n', stdout);