2 * Copyright 2012 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.
21 #include <sys/types.h>
27 #include <glib-object.h>
30 #include <com-core_packet.h>
33 #include <livebox-service.h>
40 #define PROMPT "liveinfo "
87 Ecore_Fd_Handler *fd_handler;
88 Ecore_Fd_Handler *in_handler;
96 .fifo_handle = -EINVAL,
106 static inline void ls(void)
115 is_package = node_name(s_info.curdir) && !strcmp(node_name(s_info.curdir), "package");
116 is_provider = !is_package && node_name(s_info.curdir) && !strcmp(node_name(s_info.curdir), "provider");
117 is_instance = !is_package && !is_provider && node_parent(s_info.curdir) && node_name(node_parent(s_info.curdir)) && !strcmp(node_name(node_parent(s_info.curdir)), "package");
119 node = node_child(s_info.curdir);
122 struct package *info;
123 info = node_data(node);
124 printf(" %3d %20s %5s ", info->inst_count, info->slavename ? info->slavename : "-", info->abi ? info->abi : "-");
125 } else if (is_provider) {
127 info = node_data(node);
128 printf(" %3d %5s %5.2f ", info->loaded_inst, info->abi ? info->abi : "-", info->ttl);
129 } else if (is_instance) {
130 struct instance *info;
133 info = node_data(node);
135 printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
136 snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
137 if (lstat(buf, &stat) < 0)
138 printf("%3d ERR ", errno);
140 printf("%2.2lf MB ", (double)stat.st_size / 1024.0f / 1024.0f);
143 if (node_type(node) == NODE_DIR)
144 printf("%s/", node_name(node));
145 else if (node_type(node) == NODE_FILE)
146 printf("%s", node_name(node));
149 node = node_next_sibling(node);
152 printf("Total: %d\n", cnt);
153 path = node_to_abspath(s_info.curdir);
154 printf(PROMPT"%s # ", path);
158 static void send_slave_list(void)
160 struct packet *packet;
162 if (s_info.cmd != NOP) {
163 printf("Previous command is not finished\n");
167 packet = packet_create_noack("slave_list", "d", 0.0f);
169 printf("Failed to create a packet\n");
173 com_core_packet_send_only(s_info.fd, packet);
174 packet_destroy(packet);
175 s_info.cmd = SLAVE_LIST;
178 static void send_pkg_list(void)
180 struct packet *packet;
182 if (s_info.cmd != NOP) {
183 printf("Previous command is not finished\n");
187 packet = packet_create_noack("pkg_list", "d", 0.0f);
189 printf("Failed to create a packet\n");
193 com_core_packet_send_only(s_info.fd, packet);
194 packet_destroy(packet);
195 s_info.cmd = PKG_LIST;
198 static void send_toggle_debug(void)
200 struct packet *packet;
202 if (s_info.cmd != NOP) {
203 printf("Previous command is not finished\n");
207 packet = packet_create_noack("toggle_debug", "d", 0.0f);
209 printf("Failed to create a packet\n");
213 com_core_packet_send_only(s_info.fd, packet);
214 packet_destroy(packet);
215 s_info.cmd = TOGGLE_DEBUG;
218 static void send_inst_list(const char *pkgname)
220 struct packet *packet;
222 if (s_info.cmd != NOP) {
223 printf("Previous command is not finished\n");
227 packet = packet_create_noack("inst_list", "s", pkgname);
229 printf("Failed to create a packet\n");
233 com_core_packet_send_only(s_info.fd, packet);
234 packet_destroy(packet);
235 s_info.cmd = INST_LIST;
238 static inline void help(void)
240 printf("liveinfo - Livebox utility\n");
241 printf("------------------------------ [Command list] ------------------------------\n");
242 printf("
\e[32cd - Change directory
\e[0m\n");
243 printf("
\e[32ls - List up content as a file
\e[0m\n");
244 printf("
\e[32cat - Open a file to get some detail information
\e[0m\n");
245 printf("
\e[32mexit -
\e[0m\n");
246 printf("
\e[32mquit -
\e[0m\n");
247 printf("----------------------------------------------------------------------------\n");
250 static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
252 struct node *parent = data;
254 struct package *info;
256 info = calloc(1, sizeof(*info));
258 printf("Error: %s\n", strerror(errno));
262 info->pkgid = strdup(appid);
264 printf("Error: %s\n", strerror(errno));
269 info->primary = is_prime;
271 node = node_create(parent, lbid, NODE_DIR);
278 node_set_mode(node, NODE_READ | NODE_EXEC);
279 node_set_data(node, info);
283 static inline void init_directory(void)
286 s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
290 node = node_create(s_info.rootdir, "provider", NODE_DIR);
292 node_destroy(s_info.rootdir);
293 s_info.rootdir = NULL;
296 node_set_mode(node, NODE_READ | NODE_EXEC);
298 node = node_create(s_info.rootdir, "package", NODE_DIR);
300 node_destroy(node_child(s_info.rootdir));
301 node_destroy(s_info.rootdir);
302 s_info.rootdir = NULL;
305 node_set_mode(node, NODE_READ | NODE_EXEC);
307 s_info.curdir = s_info.rootdir;
308 livebox_service_get_pkglist(pkglist_cb, node);
312 static inline void fini_directory(void)
316 static inline void do_command(const char *cmd)
319 char argument[4096] = { '\0', };
324 path = node_to_abspath(s_info.curdir);
325 printf(PROMPT"%s # ", path);
330 if (sscanf(cmd, "%255[^ ] %4095s", command, argument) == 2)
333 if (!strcasecmp(cmd, "exit") || !strcasecmp(cmd, "quit")) {
334 ecore_main_loop_quit();
335 } else if (!strcasecmp(cmd, "toggle_debug")) {
336 if (s_info.cmd != NOP) {
337 printf("Waiting the server response\n");
342 } else if (!strcasecmp(cmd, "ls")) {
343 if (node_name(s_info.curdir)) {
344 if (!strcmp(node_name(s_info.curdir), "package")) {
345 if (s_info.cmd != NOP) {
346 printf("Waiting the server response\n");
351 } else if (!strcmp(node_name(s_info.curdir), "provider")) {
352 if (s_info.cmd != NOP) {
353 printf("Waiting the server response\n");
361 if (node_parent(s_info.curdir) && node_name(node_parent(s_info.curdir))) {
362 if (!strcmp(node_name(node_parent(s_info.curdir)), "package")) {
363 if (s_info.cmd != NOP) {
364 printf("Waiting the server response\n");
367 send_inst_list(node_name(s_info.curdir));
373 } else if (!strcasecmp(cmd, "cd")) {
376 if (!strcmp(argument, "."))
379 if (s_info.cmd != NOP) {
380 printf("Waiting the server response\n");
384 if (!strcmp(argument, "..")) {
385 if (node_parent(s_info.curdir) == NULL)
388 s_info.curdir = node_parent(s_info.curdir);
391 node = node_child(s_info.curdir);
393 if (!strcmp(node_name(node), argument)) {
394 if (node_type(node) != NODE_DIR)
395 printf("Unable to go into the %s\n", node_name(node));
397 s_info.curdir = node;
402 node = node_next_sibling(node);
405 printf("Not found: %s\n", argument);
407 path = node_to_abspath(s_info.curdir);
408 printf(PROMPT"%s # ", path);
410 } else if (!strcasecmp(cmd, "help")) {
413 printf("Unknown command - \"help\"\n");
414 path = node_to_abspath(s_info.curdir);
415 printf(PROMPT"%s # ", path);
423 path = node_to_abspath(s_info.curdir);
424 printf(PROMPT"%s # ", path);
428 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
431 static char cmd_buffer[256];
436 fd = ecore_main_fd_handler_fd_get(fd_handler);
438 printf("FD is not valid: %d\n", fd);
439 return ECORE_CALLBACK_CANCEL;
444 * Using this routine, we can implement the command recommend algorithm.
445 * When a few more characters are matched with history of command, we can show it to user
446 * Then the user will choose one or write new command
450 if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
451 printf("Failed to get a byte: %s\n", strerror(errno));
452 return ECORE_CALLBACK_CANCEL;
456 case 0x08: /* BKSP */
457 cmd_buffer[idx] = '\0';
460 cmd_buffer[idx] = ' ';
461 path = node_to_abspath(s_info.curdir);
462 printf("\r"PROMPT"%s # %s", path, cmd_buffer);
463 cmd_buffer[idx] = '\0';
464 printf("\r"PROMPT"%s # %s", path, cmd_buffer);
469 cmd_buffer[idx] = '\0';
471 putc((int)'\n', stdout);
472 do_command(cmd_buffer);
473 memset(cmd_buffer, 0, sizeof(cmd_buffer));
476 cmd_buffer[idx++] = ch;
477 putc((int)ch, stdout);
478 if (idx == sizeof(cmd_buffer) - 1) {
479 cmd_buffer[idx] = '\0';
480 printf("\nCommand buffer is overflow: %s\n", cmd_buffer);
486 return ECORE_CALLBACK_RENEW;
489 static void processing_line_buffer(const char *buffer)
511 struct package *pkginfo;
512 struct instance *instinfo;
513 struct slave *slaveinfo;
516 switch (s_info.cmd) {
518 if (sscanf(buffer, "%d %[^ ] %[^ ] %[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
519 printf("Invalid format : [%s]\n", buffer);
523 node = node_find(s_info.curdir, pkgname);
525 pkginfo = malloc(sizeof(*pkginfo));
527 printf("Error: %s\n", strerror(errno));
531 pkginfo->pkgid = strdup("conf.file");
533 printf("Error: %s\n", strerror(errno));
535 pkginfo->primary = 1;
537 node = node_create(s_info.curdir, pkgname, NODE_DIR);
539 free(pkginfo->pkgid);
541 printf("Failed to create a new node (%s)\n", pkgname);
545 node_set_data(node, pkginfo);
547 pkginfo = node_data(node);
549 free(pkginfo->slavename);
552 pkginfo->slavename = NULL;
556 pkginfo->slavename = strdup(slavename);
557 if (!pkginfo->slavename)
558 printf("Error: %s\n", strerror(errno));
560 pkginfo->abi = strdup(abi);
562 printf("Error: %s\n", strerror(errno));
565 pkginfo->refcnt = refcnt;
566 pkginfo->fault_count = fault_count;
567 pkginfo->inst_count = list_count;
570 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) {
571 printf("Invalid format : [%s]\n", buffer);
574 node = node_find(s_info.curdir, slavename);
576 slaveinfo = calloc(1, sizeof(*slaveinfo));
578 printf("Error: %s\n", strerror(errno));
582 node = node_create(s_info.curdir, slavename, NODE_DIR);
588 node_set_data(node, slaveinfo);
590 slaveinfo = node_data(node);
592 free(slaveinfo->pkgname);
593 free(slaveinfo->abi);
594 free(slaveinfo->state);
596 slaveinfo->pkgname = strdup(pkgname);
597 slaveinfo->abi = strdup(abi);
598 slaveinfo->state = strdup(state);
600 slaveinfo->pid = pid;
601 slaveinfo->secured = secured;
602 slaveinfo->refcnt = refcnt;
603 slaveinfo->fault_count = fault_count;
604 slaveinfo->loaded_inst = loaded_inst;
605 slaveinfo->loaded_pkg = loaded_pkg;
606 slaveinfo->ttl = ttl;
609 if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
610 printf("Invalid format : [%s]\n", buffer);
614 for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
615 i += (inst_id[i] == '/');
617 node = node_find(s_info.curdir, inst_id + i);
619 instinfo = calloc(1, sizeof(*instinfo));
621 printf("Error: %s\n", strerror(errno));
625 node = node_create(s_info.curdir, inst_id + i, NODE_FILE);
631 node_set_data(node, instinfo);
633 instinfo = node_data(node);
636 free(instinfo->cluster);
637 free(instinfo->category);
638 free(instinfo->state);
640 instinfo->cluster = strdup(cluster);
641 if (!instinfo->cluster)
642 printf("Error: %s\n", strerror(errno));
644 instinfo->category = strdup(category);
645 if (!instinfo->category)
646 printf("Error: %s\n", strerror(errno));
648 instinfo->state = strdup(state);
649 instinfo->period = period;
650 instinfo->width = width;
651 instinfo->height = height;
654 sscanf(buffer, "%d", &debug);
661 static inline void do_line_command(void)
663 switch (s_info.cmd) {
680 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
683 static char *line_buffer = NULL;
684 static int line_index = 0;
685 static int bufsz = 256;
688 fd = ecore_main_fd_handler_fd_get(fd_handler);
690 printf("FD is not valid: %d\n", fd);
691 return ECORE_CALLBACK_CANCEL;
694 if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
695 printf("Error: %s\n", strerror(errno));
696 return ECORE_CALLBACK_CANCEL;
701 line_buffer = malloc(bufsz);
703 printf("Error: %s\n", strerror(errno));
704 return ECORE_CALLBACK_CANCEL;
708 if (ch == '\n') { /* End of a line */
709 line_buffer[line_index] = '\0';
711 if (!strcmp(line_buffer, "EOD")) {
715 processing_line_buffer(line_buffer);
725 line_buffer[line_index++] = ch;
726 if (line_index == bufsz - 1) {
728 new_buf = realloc(line_buffer, bufsz);
730 printf("Error: %s\n", strerror(errno));
735 return ECORE_CALLBACK_CANCEL;
738 line_buffer = new_buf;
742 return ECORE_CALLBACK_RENEW;
745 static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data)
747 const char *fifo_name;
751 if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
752 printf("Invalid packet\n");
757 printf("Returns %d\n", ret);
761 printf("FIFO: %s\n", fifo_name);
763 s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
764 if (s_info.fifo_handle < 0) {
765 printf("Error: %s\n", strerror(errno));
766 s_info.fifo_handle = -EINVAL;
767 ecore_main_loop_quit();
771 s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
772 if (!s_info.fd_handler) {
773 printf("Failed to add a fd handler\n");
774 close(s_info.fifo_handle);
775 s_info.fifo_handle = -EINVAL;
776 ecore_main_loop_quit();
780 path = node_to_abspath(s_info.curdir);
781 printf(PROMPT"%s # ", path);
784 if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) < 0)
785 printf("Error: %s\n", strerror(errno));
787 s_info.in_handler = ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
788 if (!s_info.in_handler) {
789 printf("Failed to add a input handler\n");
790 ecore_main_loop_quit();
797 static int disconnected_cb(int handle, void *data)
799 printf("Disconnected\n");
800 ecore_main_loop_quit();
804 static int connected_cb(int handle, void *data)
806 struct packet *packet;
808 printf("Connected\n");
810 packet = packet_create("liveinfo_hello", "d", 0.0f);
812 printf("Failed to build a packet for hello\n");
813 com_core_packet_client_fini(s_info.fd);
820 if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
821 printf("Failed to send a packet hello\n");
822 packet_destroy(packet);
823 com_core_packet_client_fini(s_info.fd);
828 packet_destroy(packet);
832 int main(int argc, char *argv[])
834 struct termios ttystate;
835 static struct method s_table[] = {
845 com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
846 com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
847 livebox_service_init();
849 s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
851 printf("Failed to make a connection\n");
855 printf("Type your command on below empty line\n");
857 if (tcgetattr(STDIN_FILENO, &ttystate) < 0) {
858 printf("Error: %s\n", strerror(errno));
860 ttystate.c_lflag &= ~(ICANON | ECHO);
861 ttystate.c_cc[VMIN] = 1;
863 if (tcsetattr(STDIN_FILENO, TCSANOW, &ttystate) < 0)
864 printf("Error: %s\n", strerror(errno));
867 if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0)
868 printf("Error: %s\n", strerror(errno));
872 ecore_main_loop_begin();
875 livebox_service_fini();
877 ttystate.c_lflag |= ICANON | ECHO;
878 if (tcsetattr(STDIN_FILENO, TCSANOW, &ttystate) < 0)
879 printf("Error: %s\n", strerror(errno));
882 com_core_packet_client_fini(s_info.fd);
886 if (s_info.fd_handler) {
887 ecore_main_fd_handler_del(s_info.fd_handler);
888 s_info.fd_handler = NULL;
891 if (s_info.fifo_handle > 0) {
892 close(s_info.fifo_handle);
893 s_info.fifo_handle = -EINVAL;
896 if (s_info.in_handler) {
897 ecore_main_fd_handler_del(s_info.in_handler);
898 s_info.in_handler = NULL;