Update liveinfo utility.
authorSung-jae Park <nicesj.park@samsung.com>
Sat, 26 Jan 2013 14:24:03 +0000 (14:24 +0000)
committerSung-jae Park <nicesj.park@samsung.com>
Sun, 27 Jan 2013 04:10:30 +0000 (04:10 +0000)
Working like a common shell.

More command should be implemented.
such as "rm", "cat"

Update spec file

Change-Id: Ib5f62b52b0e84b420a0f712805c60d00be604351

packaging/org.tizen.data-provider-master.spec
src/server.c
util_liveinfo/CMakeLists.txt
util_liveinfo/include/node.h [new file with mode: 0644]
util_liveinfo/src/liveinfo.c
util_liveinfo/src/node.c [new file with mode: 0644]

index 7d46e67..d326f37 100644 (file)
@@ -1,8 +1,8 @@
 Name: org.tizen.data-provider-master
-Summary: Master data provider
+Summary: Master service provider for liveboxes.
 Version: 0.14.5
 Release: 1
-Group: main/app
+Group: framework/livebox
 License: Flora License
 Source0: %{name}-%{version}.tar.gz
 BuildRequires: cmake, gettext-tools, smack, coreutils
@@ -34,7 +34,8 @@ BuildRequires: pkgconfig(pkgmgr)
 BuildRequires: pkgconfig(livebox-service)
 
 %description
-Manage the slave data provider and communicate with client applications.
+Manage the 2nd stage livebox service provider and communicate with the viewer application.
+Keep trace on the life-cycle of the livebox and status of the service providers, viewer applications.
 
 %prep
 %setup -q
index d896eb8..10d4085 100644 (file)
@@ -4685,19 +4685,20 @@ static struct packet *liveinfo_slave_list(pid_t pid, int handle, const struct pa
        }
 
        liveinfo_open_fifo(info);
-
        fp = liveinfo_fifo(info);
-       if (!fp)
+       if (!fp) {
+               liveinfo_close_fifo(info);
                goto out;
+       }
 
        list = (Eina_List *)slave_list();
        EINA_LIST_FOREACH(list, l, slave) {
-               fprintf(fp, "  %7d   %20s   %39s   %7s   %7s   %6d   %5d   %21s   %4d   %3d   %3.4lf  \n", 
+               fprintf(fp, "%d %s %s %s %d %d %d %s %d %d %lf\n", 
                        slave_pid(slave),
                        slave_name(slave),
                        slave_pkgname(slave),
                        slave_abi(slave),
-                       slave_is_secured(slave) ? "true" : "false",
+                       slave_is_secured(slave),
                        slave_refcnt(slave),
                        slave_fault_count(slave),
                        slave_state_string(slave),
@@ -4706,55 +4707,9 @@ static struct packet *liveinfo_slave_list(pid_t pid, int handle, const struct pa
                        slave_ttl(slave)
                );
        }
-       fprintf(fp, "EOD\n");
-       liveinfo_close_fifo(info);
-
-out:
-       return NULL;
-}
-
-static struct packet *liveinfo_slave_load(pid_t pid, int handle, const struct packet *packet)
-{
-       struct liveinfo *info;
-       pid_t slave_pid;
-       struct slave_node *slave;
-       struct pkg_info *pkg;
-       Eina_List *pkg_list;
-       Eina_List *l;
-       FILE *fp;
-
-       if (packet_get(packet, "i", &slave_pid) != 1) {
-               ErrPrint("Invalid argument\n");
-               goto out;
-       }
-
-       info = liveinfo_find_by_pid(pid);
-       if (!info) {
-               ErrPrint("Invalid request\n");
-               goto out;
-       }
-
-       slave = slave_find_by_pid(slave_pid);
-       if (!slave) {
-               ErrPrint("Slave is not exists\n");
-               goto out;
-       }
-
-       liveinfo_open_fifo(info);
-       fp = liveinfo_fifo(info);
-       if (!fp)
-               goto out;
-
-       fprintf(fp, "%s = { ", slave_name(slave));
-       pkg_list = (Eina_List *)package_list();
-       EINA_LIST_FOREACH(pkg_list, l, pkg) {
-               if (package_slave(pkg) == slave)
-                       fprintf(fp, "%s, ", package_name(pkg));
-       }
-       fprintf(fp, "}\nEOD\n");
 
+       fprintf(fp, "EOD\n");
        liveinfo_close_fifo(info);
-
 out:
        return NULL;
 }
@@ -4790,17 +4745,6 @@ static struct packet *liveinfo_inst_list(pid_t pid, int handle, const struct pac
                goto out;
        }
 
-       if (!package_is_lb_pkgname(pkgname)) {
-               ErrPrint("Invalid package name\n");
-               goto out;
-       }
-
-       pkg = package_find(pkgname);
-       if (!pkg) {
-               ErrPrint("Package is not exists\n");
-               goto out;
-       }
-
        info = liveinfo_find_by_pid(pid);
        if (!info) {
                ErrPrint("Invalid request\n");
@@ -4808,25 +4752,37 @@ static struct packet *liveinfo_inst_list(pid_t pid, int handle, const struct pac
        }
 
        liveinfo_open_fifo(info);
-
        fp = liveinfo_fifo(info);
        if (!fp) {
                ErrPrint("Invalid fp\n");
+               liveinfo_close_fifo(info);
                goto out;
        }
 
+       if (!package_is_lb_pkgname(pkgname)) {
+               ErrPrint("Invalid package name\n");
+               goto close_out;
+       }
+
+       pkg = package_find(pkgname);
+       if (!pkg) {
+               ErrPrint("Package is not exists\n");
+               goto close_out;
+       }
+
        inst_list = package_instance_list(pkg);
        EINA_LIST_FOREACH(inst_list, l, inst) {
-               fprintf(fp, " %18s %18s %18s %3.3lf %10s %5d %6d\n",
-                                               instance_id(inst),
-                                               instance_cluster(inst),
-                                               instance_category(inst),
-                                               instance_period(inst),
-                                               visible_state_string(instance_visible_state(inst)),
-                                               instance_lb_width(inst),
-                                               instance_lb_height(inst));
+               fprintf(fp, "%s %s %s %lf %s %d %d\n",
+                       instance_id(inst),
+                       instance_cluster(inst),
+                       instance_category(inst),
+                       instance_period(inst),
+                       visible_state_string(instance_visible_state(inst)),
+                       instance_lb_width(inst),
+                       instance_lb_height(inst));
        }
 
+close_out:
        fprintf(fp, "EOD\n");
        liveinfo_close_fifo(info);
 
@@ -4858,10 +4814,11 @@ static struct packet *liveinfo_pkg_list(pid_t pid, int handle, const struct pack
        }
 
        liveinfo_open_fifo(info);
-
        fp = liveinfo_fifo(info);
-       if (!fp)
+       if (!fp) {
+               liveinfo_close_fifo(info);
                goto out;
+       }
 
        list = (Eina_List *)package_list();
        EINA_LIST_FOREACH(list, l, pkg) {
@@ -4876,10 +4833,9 @@ static struct packet *liveinfo_pkg_list(pid_t pid, int handle, const struct pack
                }
 
                inst_list = (Eina_List *)package_instance_list(pkg);
-
-               fprintf(fp, "  %7d   %20s   %39s   %7s   %6d   %5d   %4d  \n",
+               fprintf(fp, "%d %s %s %s %d %d %d\n",
                        pid,
-                       slavename,
+                       strlen(slavename) ? slavename : "(none)",
                        package_name(pkg),
                        package_abi(pkg),
                        package_refcnt(pkg),
@@ -4887,9 +4843,9 @@ static struct packet *liveinfo_pkg_list(pid_t pid, int handle, const struct pack
                        eina_list_count(inst_list)
                );
        }
+
        fprintf(fp, "EOD\n");
        liveinfo_close_fifo(info);
-
 out:
        return NULL;
 }
@@ -4923,11 +4879,13 @@ static struct packet *liveinfo_toggle_debug(pid_t pid, int handle, const struct
 
        liveinfo_open_fifo(info);
        fp = liveinfo_fifo(info);
-       if (!fp)
+       if (!fp) {
+               liveinfo_close_fifo(info);
                goto out;
+       }
 
        g_conf.debug_mode = !g_conf.debug_mode;
-       fprintf(fp, "Debug mode is %s\nEOD\n", g_conf.debug_mode ? "enabled" : "disabled");
+       fprintf(fp, "%d\nEOD\n", g_conf.debug_mode);
        liveinfo_close_fifo(info);
 
 out:
@@ -4952,10 +4910,6 @@ static struct method s_info_table[] = {
                .handler = liveinfo_inst_list,
        },
        {
-               .cmd = "slave_load",
-               .handler = liveinfo_slave_load,
-       },
-       {
                .cmd = "slave_ctrl",
                .handler = liveinfo_slave_ctrl,
        },
index 7b26041..86cae09 100644 (file)
@@ -10,6 +10,7 @@ pkg_check_modules(info_pkgs REQUIRED
        ecore
        glib-2.0
        gio-2.0
+       livebox-service
 )
 
 FOREACH(flag ${info_pkgs_CFLAGS})
@@ -23,6 +24,7 @@ ADD_DEFINITIONS("-DSOCKET_FILE=\"/opt/usr/share/live_magazine/.live.socket\"")
 
 ADD_EXECUTABLE(${PROJECT_NAME}
        src/liveinfo.c
+       src/node.c
 )
 
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${info_pkgs_LDFLAGS})
diff --git a/util_liveinfo/include/node.h b/util_liveinfo/include/node.h
new file mode 100644 (file)
index 0000000..61a5922
--- /dev/null
@@ -0,0 +1,36 @@
+
+enum node_type {
+       NODE_DIR,
+       NODE_FILE,
+       NODE_LINK,
+};
+
+struct node;
+
+#define NODE_READ      0x01
+#define NODE_WRITE     0x02
+#define NODE_EXEC      0x04
+
+extern struct node *node_find(const struct node *node, char *path);
+extern struct node *node_create(struct node *parent, const char *name, enum node_type type);
+extern void node_destroy(struct node *node);
+
+extern struct node * const node_next_sibling(const struct node *node);
+extern struct node * const node_prev_sibling(const struct node *node);
+
+extern struct node * const node_child(const struct node *node);
+extern struct node * const node_parent(const struct node *node);
+
+extern void node_set_mode(struct node *node, int mode);
+extern void node_set_data(struct node *node, void *data);
+
+extern const int const node_mode(const struct node *node);
+extern void * const node_data(const struct node *node);
+
+extern void node_set_type(struct node *node, enum node_type type);
+extern const enum node_type const node_type(const struct node *node);
+
+extern const char * const node_name(const struct node *node);
+
+extern char *node_to_abspath(struct node *node);
+/* End of a file */
index 41f82ad..e181820 100644 (file)
 #include <com-core_packet.h>
 #include <com-core.h>
 
+#include <livebox-service.h>
+
 #include <Ecore.h>
 
-#define PROMPT "liveinfo) "
+#include "liveinfo.h"
+#include "node.h"
+
+#define PROMPT "liveinfo "
+
+struct package {
+       int primary;
+       char *pkgid;
+
+       int pid;
+       char *slavename;
+       char *abi;
+       int refcnt;
+       int fault_count;
+       int inst_count;
+};
+
+struct instance {
+       char *cluster;
+       char *category;
+       double period;
+       char *state;
+       int width;
+       int height;
+};
+
+struct slave {
+       int pid;
+       char *pkgname;
+       char *abi;
+       int secured;
+       int refcnt;
+       int fault_count;
+       char *state;
+       int loaded_inst;
+       int loaded_pkg;
+       double ttl;
+};
+
+enum command {
+       NOP,
+       PKG_LIST,
+       INST_LIST,
+       TOGGLE_DEBUG,
+       SLAVE_LIST,     
+};
 
 static struct info {
        int fifo_handle;
@@ -40,158 +87,357 @@ static struct info {
        Ecore_Fd_Handler *fd_handler;
        Ecore_Fd_Handler *in_handler;
        int input_fd;
+
+       struct node *rootdir;
+       struct node *curdir;
+
+       enum command cmd;
 } s_info = {
        .fifo_handle = -EINVAL,
        .fd = -EINVAL,
        .fd_handler = NULL,
        .in_handler = NULL,
        .input_fd = -1,
+       .rootdir = NULL,
+       .curdir = NULL,
+       .cmd = NOP,
 };
 
+static inline void ls(void)
+{
+       struct node *node;
+       int cnt = 0;
+       int is_package;
+       int is_provider;
+       int is_instance;
+       char *path;
+
+       is_package = node_name(s_info.curdir) && !strcmp(node_name(s_info.curdir), "package");
+       is_provider = !is_package && node_name(s_info.curdir) && !strcmp(node_name(s_info.curdir), "provider");
+       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");
+
+       node = node_child(s_info.curdir);
+       while (node) {
+               if (is_package) {
+                       struct package *info;
+                       info = node_data(node);
+                       printf(" %3d %20s %5s ", info->inst_count, info->slavename ? info->slavename : "-", info->abi ? info->abi : "-");
+               } else if (is_provider) {
+                       struct slave *info;
+                       info = node_data(node);
+                       printf(" %3d %5s %5.2f ", info->loaded_inst, info->abi ? info->abi : "-", info->ttl);
+               } else if (is_instance) {
+                       struct instance *info;
+                       struct stat stat;
+                       char buf[4096];
+                       info = node_data(node);
+
+                       printf(" %5.2f %6s %10s %10s %4dx%-4d ", info->period, info->state, info->cluster, info->category, info->width, info->height);
+                       snprintf(buf, sizeof(buf), "/opt/usr/share/live_magazine/reader/%s", node_name(node));
+                       if (lstat(buf, &stat) < 0)
+                               printf("%3d ERR ", errno);
+                       else
+                               printf("%2.2lf MB ", (double)stat.st_size / 1024.0f / 1024.0f);
+               }
+
+               if (node_type(node) == NODE_DIR)
+                       printf("%s/", node_name(node));
+               else if (node_type(node) == NODE_FILE)
+                       printf("%s", node_name(node));
+
+               printf("\n");
+               node = node_next_sibling(node);
+               cnt++;
+       }
+       printf("Total: %d\n", cnt);
+       path = node_to_abspath(s_info.curdir);
+       printf(PROMPT"%s # ", path);
+       free(path);
+}
+
 static void send_slave_list(void)
 {
        struct packet *packet;
 
+       if (s_info.cmd != NOP) {
+               printf("Previous command is not finished\n");
+               return;
+       }
+
        packet = packet_create_noack("slave_list", "d", 0.0f);
        if (!packet) {
-               fprintf(stderr, "Failed to create a packet\n");
+               printf("Failed to create a packet\n");
                return;
        }
 
        com_core_packet_send_only(s_info.fd, packet);
        packet_destroy(packet);
-
-       printf("----------------------------------------------------------------------[Slave List]------------------------------------------------------------------------------\n");
-       printf("    pid          slave name                     package name                   abi     secured   refcnt   fault           state           inst   pkg     ttl    \n");
-       printf("----------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
+       s_info.cmd = SLAVE_LIST;
 }
 
 static void send_pkg_list(void)
 {
        struct packet *packet;
 
+       if (s_info.cmd != NOP) {
+               printf("Previous command is not finished\n");
+               return;
+       }
+
        packet = packet_create_noack("pkg_list", "d", 0.0f);
        if (!packet) {
-               fprintf(stderr, "Failed to create a packet\n");
+               printf("Failed to create a packet\n");
                return;
        }
 
        com_core_packet_send_only(s_info.fd, packet);
        packet_destroy(packet);
-
-       printf("+----------------------------------------------[Package List]------------------------------------------------+\n");
-       printf("    pid          slave name                     package name                   abi     refcnt   fault   inst  \n");
-       printf("+------------------------------------------------------------------------------------------------------------+\n");
+       s_info.cmd = PKG_LIST;
 }
 
 static void send_toggle_debug(void)
 {
        struct packet *packet;
 
-       packet = packet_create_noack("toggle_debug", "d", 0.0f);
-       if (!packet) {
-               fprintf(stderr, "Failed to create a packet\n");
+       if (s_info.cmd != NOP) {
+               printf("Previous command is not finished\n");
                return;
        }
 
-       com_core_packet_send_only(s_info.fd, packet);
-       packet_destroy(packet);
-}
-
-static void send_slave_load(pid_t pid)
-{
-       struct packet *packet;
-
-       packet = packet_create_noack("slave_load", "i", pid);
+       packet = packet_create_noack("toggle_debug", "d", 0.0f);
        if (!packet) {
-               fprintf(stderr, "Failed to create a packet\n");
+               printf("Failed to create a packet\n");
                return;
        }
 
        com_core_packet_send_only(s_info.fd, packet);
        packet_destroy(packet);
+       s_info.cmd = TOGGLE_DEBUG;
 }
 
 static void send_inst_list(const char *pkgname)
 {
        struct packet *packet;
 
+       if (s_info.cmd != NOP) {
+               printf("Previous command is not finished\n");
+               return;
+       }
+
        packet = packet_create_noack("inst_list", "s", pkgname);
        if (!packet) {
-               fprintf(stderr, "Failed to create a packet\n");
+               printf("Failed to create a packet\n");
                return;
        }
 
        com_core_packet_send_only(s_info.fd, packet);
        packet_destroy(packet);
-
-       printf("-----------------------------------------------[Instance List]---------------------------------------\n");
-       printf("         ID         |      Cluster ID    |   Sub cluster ID   | Period | Visibility | Width | Height \n");
-       printf("-----------------------------------------------------------------------------------------------------\n");
+       s_info.cmd = INST_LIST;
 }
 
 static inline void help(void)
 {
        printf("liveinfo - Livebox utility\n");
        printf("------------------------------ [Command list] ------------------------------\n");
-       printf("\e[33mpkg_list\e[0m - Display the installed package list\n");
-       printf("\e[33mslave_list\e[0m - Display the slave list\n");
-       printf("\e[33minst_list\e[0m \e[37mLIVEBOX_PKGNAME\e[0m - Display the instance list of this LIVEBOX_PKGNAME\n");
-       printf("\e[33mslave_load\e[0m \e[37mSLAVE_PID\e[0m - Display the loaded livebox instance list on the given slave\n");
-       printf("\e[33mtoggle_debug\e[0m - Enable/Disable debug mode\n");
+       printf("\e[32cd - Change directory\e[0m\n");
+       printf("\e[32ls - List up content as a file\e[0m\n");
+       printf("\e[32cat - Open a file to get some detail information\e[0m\n");
        printf("\e[32mexit - \e[0m\n");
        printf("\e[32mquit - \e[0m\n");
        printf("----------------------------------------------------------------------------\n");
 }
 
+static int pkglist_cb(const char *appid, const char *lbid, int is_prime, void *data)
+{
+       struct node *parent = data;
+       struct node *node;
+       struct package *info;
+
+       info = calloc(1, sizeof(*info));
+       if (!info) {
+               printf("Error: %s\n", strerror(errno));
+               return -ENOMEM;
+       }
+
+       info->pkgid = strdup(appid);
+       if (!info->pkgid) {
+               printf("Error: %s\n", strerror(errno));
+               free(info);
+               return -ENOMEM;
+       }
+
+       info->primary = is_prime;
+
+       node = node_create(parent, lbid, NODE_DIR);
+       if (!node) {
+               free(info->pkgid);
+               free(info);
+               return -ENOMEM;
+       }
+
+       node_set_mode(node, NODE_READ | NODE_EXEC);
+       node_set_data(node, info);
+       return 0;
+}
+
+static inline void init_directory(void)
+{
+       struct node *node;
+       s_info.rootdir = node_create(NULL, NULL, NODE_DIR);
+       if (!s_info.rootdir)
+               return;
+
+       node = node_create(s_info.rootdir, "provider", NODE_DIR);
+       if (!node) {
+               node_destroy(s_info.rootdir);
+               s_info.rootdir = NULL;
+               return;
+       }
+       node_set_mode(node, NODE_READ | NODE_EXEC);
+
+       node = node_create(s_info.rootdir, "package", NODE_DIR);
+       if (!node) {
+               node_destroy(node_child(s_info.rootdir));
+               node_destroy(s_info.rootdir);
+               s_info.rootdir = NULL;
+               return;
+       }
+       node_set_mode(node, NODE_READ | NODE_EXEC);
+
+       s_info.curdir = s_info.rootdir;
+       livebox_service_get_pkglist(pkglist_cb, node);
+       return;
+}
+
+static inline void fini_directory(void)
+{
+}
+
 static inline void do_command(const char *cmd)
 {
        char command[256];
-       char argument[256] = { '\0', };
+       char argument[4096] = { '\0', };
+       char *path;
+
+       if (!strlen(cmd)) {
+               char *path;
+               path = node_to_abspath(s_info.curdir);
+               printf(PROMPT"%s # ", path);
+               free(path);
+               return;
+       }
 
-       if (sscanf(cmd, "%255[^ ] %255s", command, argument) == 2)
+       if (sscanf(cmd, "%255[^ ] %4095s", command, argument) == 2)
                cmd = command;
 
-       if (!strcasecmp(cmd, "inst_list") && *argument) {
-               send_inst_list(argument);
-       } else if (!strcasecmp(cmd, "slave_load") && *argument) {
-               pid_t pid;
-
-               if (sscanf(argument, "%d", &pid) == 1)
-                       send_slave_load(pid);
-               else
-                       goto errout;
-       } else if (!strcasecmp(cmd, "pkg_list")) {
-               send_pkg_list();
-       } else if (!strcasecmp(cmd, "slave_list")) {
-               send_slave_list();
-       } else if (!strcasecmp(cmd, "exit") || !strcasecmp(cmd, "quit")) {
+       if (!strcasecmp(cmd, "exit") || !strcasecmp(cmd, "quit")) {
                ecore_main_loop_quit();
        } else if (!strcasecmp(cmd, "toggle_debug")) {
+               if (s_info.cmd != NOP) {
+                       printf("Waiting the server response\n");
+                       return;
+               }
+
                send_toggle_debug();
+       } else if (!strcasecmp(cmd, "ls")) {
+               if (node_name(s_info.curdir)) {
+                       if (!strcmp(node_name(s_info.curdir), "package")) {
+                               if (s_info.cmd != NOP) {
+                                       printf("Waiting the server response\n");
+                                       return;
+                               }
+                               send_pkg_list();
+                               return;
+                       } else if (!strcmp(node_name(s_info.curdir), "provider")) {
+                               if (s_info.cmd != NOP) {
+                                       printf("Waiting the server response\n");
+                                       return;
+                               }
+                               send_slave_list();
+                               return;
+                       }
+               }
+
+               if (node_parent(s_info.curdir) && node_name(node_parent(s_info.curdir))) {
+                       if (!strcmp(node_name(node_parent(s_info.curdir)), "package")) {
+                               if (s_info.cmd != NOP) {
+                                       printf("Waiting the server response\n");
+                                       return;
+                               }
+                               send_inst_list(node_name(s_info.curdir));
+                               return;
+                       }
+               }
+
+               ls();
+       } else if (!strcasecmp(cmd, "cd")) {
+               struct node *node;
+
+               if (!strcmp(argument, "."))
+                       return;
+
+               if (s_info.cmd != NOP) {
+                       printf("Waiting the server response\n");
+                       return;
+               }
+
+               if (!strcmp(argument, "..")) {
+                       if (node_parent(s_info.curdir) == NULL)
+                               return;
+
+                       s_info.curdir = node_parent(s_info.curdir);
+               }
+
+               node = node_child(s_info.curdir);
+               while (node) {
+                       if (!strcmp(node_name(node), argument)) {
+                               if (node_type(node) != NODE_DIR)
+                                       printf("Unable to go into the %s\n", node_name(node));
+                               else
+                                       s_info.curdir = node;
+
+                               break;
+                       }
+
+                       node = node_next_sibling(node);
+               }
+               if (!node)
+                       printf("Not found: %s\n", argument);
+
+               path = node_to_abspath(s_info.curdir);
+               printf(PROMPT"%s # ", path);
+               free(path);
        } else if (!strcasecmp(cmd, "help")) {
                goto errout;
        } else {
                printf("Unknown command - \"help\"\n");
-               fputs(PROMPT, stdout);
+               path = node_to_abspath(s_info.curdir);
+               printf(PROMPT"%s # ", path);
+               free(path);
        }
 
        return;
 
 errout:
        help();
-       fputs(PROMPT, stdout);
+       path = node_to_abspath(s_info.curdir);
+       printf(PROMPT"%s # ", path);
+       free(path);
 }
 
 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
 {
        static int idx = 0;
        static char cmd_buffer[256];
+       char *path;
        char ch;
-       int ret;
        int fd;
 
        fd = ecore_main_fd_handler_fd_get(fd_handler);
+       if (fd < 0) {
+               printf("FD is not valid: %d\n", fd);
+               return ECORE_CALLBACK_CANCEL;
+       }
 
        /*!
         * \note
@@ -201,10 +447,9 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
         */
 
        /* Silly.. Silly */
-       ret = read(fd, &ch, 1);
-       if (ret != 1 || ret < 0) {
-               fprintf(stderr, "Failed to get a byte: %s\n", strerror(errno));
-               return ECORE_CALLBACK_RENEW;
+       if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
+               printf("Failed to get a byte: %s\n", strerror(errno));
+               return ECORE_CALLBACK_CANCEL;
        }
 
        switch (ch) {
@@ -213,9 +458,11 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
                if (idx > 0)
                        idx--;
                cmd_buffer[idx] = ' ';
-               printf("\r"PROMPT"%s", cmd_buffer); /* Cleare the last bytes */
+               path = node_to_abspath(s_info.curdir);
+               printf("\r"PROMPT"%s # %s", path, cmd_buffer);
                cmd_buffer[idx] = '\0';
-               printf("\r"PROMPT"%s", cmd_buffer); /* Cleare the last bytes */
+               printf("\r"PROMPT"%s # %s", path, cmd_buffer);
+               free(path);
                break;
        case '\n':
        case '\r':
@@ -239,29 +486,257 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
        return ECORE_CALLBACK_RENEW;
 }
 
+static void processing_line_buffer(const char *buffer)
+{
+       int pid;
+       char slavename[256];
+       char pkgname[256];
+       char abi[256];
+       char inst_id[4096];
+       char cluster[256];
+       char category[256];
+       char state[10];
+       int refcnt;
+       int fault_count;
+       int list_count;
+       int loaded_inst;
+       int loaded_pkg;
+       double ttl;
+       int secured;
+       double period;
+       int width;
+       int height;
+       int debug;
+       struct node *node;
+       struct package *pkginfo;
+       struct instance *instinfo;
+       struct slave *slaveinfo;
+       int i;
+
+       switch (s_info.cmd) {
+       case PKG_LIST:
+               if (sscanf(buffer, "%d %[^ ] %[^ ] %[^ ] %d %d %d", &pid, slavename, pkgname, abi, &refcnt, &fault_count, &list_count) != 7) {
+                       printf("Invalid format : [%s]\n", buffer);
+                       return;
+               }
+
+               node = node_find(s_info.curdir, pkgname);
+               if (!node) {
+                       pkginfo = malloc(sizeof(*pkginfo));
+                       if (!pkginfo) {
+                               printf("Error: %s\n", strerror(errno));
+                               return;
+                       }
+
+                       pkginfo->pkgid = strdup("conf.file");
+                       if (!pkginfo->pkgid)
+                               printf("Error: %s\n", strerror(errno));
+
+                       pkginfo->primary = 1;
+
+                       node = node_create(s_info.curdir, pkgname, NODE_DIR);
+                       if (!node) {
+                               free(pkginfo->pkgid);
+                               free(pkginfo);
+                               printf("Failed to create a new node (%s)\n", pkgname);
+                               return;
+                       }
+
+                       node_set_data(node, pkginfo);
+               } else {
+                       pkginfo = node_data(node);
+
+                       free(pkginfo->slavename);
+                       free(pkginfo->abi);
+
+                       pkginfo->slavename = NULL;
+                       pkginfo->abi = NULL;
+               }
+
+               pkginfo->slavename = strdup(slavename);
+               if (!pkginfo->slavename)
+                       printf("Error: %s\n", strerror(errno));
+
+               pkginfo->abi = strdup(abi);
+               if (!pkginfo->abi)
+                       printf("Error: %s\n", strerror(errno));
+
+               pkginfo->pid = pid;
+               pkginfo->refcnt = refcnt;
+               pkginfo->fault_count = fault_count;
+               pkginfo->inst_count = list_count;
+               break;
+       case SLAVE_LIST:
+               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) {
+                       printf("Invalid format : [%s]\n", buffer);
+                       return;
+               }
+               node = node_find(s_info.curdir, slavename);
+               if (!node) {
+                       slaveinfo = calloc(1, sizeof(*slaveinfo));
+                       if (!slaveinfo) {
+                               printf("Error: %s\n", strerror(errno));
+                               return;
+                       }
+
+                       node = node_create(s_info.curdir, slavename, NODE_DIR);
+                       if (!node) {
+                               free(slaveinfo);
+                               return;
+                       }
+
+                       node_set_data(node, slaveinfo);
+               } else {
+                       slaveinfo = node_data(node);
+               }
+               free(slaveinfo->pkgname);
+               free(slaveinfo->abi);
+               free(slaveinfo->state);
+
+               slaveinfo->pkgname = strdup(pkgname);
+               slaveinfo->abi = strdup(abi);
+               slaveinfo->state = strdup(state);
+
+               slaveinfo->pid = pid;
+               slaveinfo->secured = secured;
+               slaveinfo->refcnt = refcnt;
+               slaveinfo->fault_count = fault_count;
+               slaveinfo->loaded_inst = loaded_inst;
+               slaveinfo->loaded_pkg = loaded_pkg;
+               slaveinfo->ttl = ttl;
+               break;
+       case INST_LIST:
+               if (sscanf(buffer, "%[^ ] %[^ ] %[^ ] %lf %[^ ] %d %d", inst_id, cluster, category, &period, state, &width, &height) != 7) {
+                       printf("Invalid format : [%s]\n", buffer);
+                       return;
+               }
+
+               for (i = strlen(inst_id); i > 0 && inst_id[i] != '/'; i--);
+               i += (inst_id[i] == '/');
+
+               node = node_find(s_info.curdir, inst_id + i);
+               if (!node) {
+                       instinfo = calloc(1, sizeof(*instinfo));
+                       if (!instinfo) {
+                               printf("Error: %s\n", strerror(errno));
+                               return;
+                       }
+
+                       node = node_create(s_info.curdir, inst_id + i, NODE_FILE);
+                       if (!node) {
+                               free(instinfo);
+                               return;
+                       }
+
+                       node_set_data(node, instinfo);
+               } else {
+                       instinfo = node_data(node);
+               }
+
+               free(instinfo->cluster);
+               free(instinfo->category);
+               free(instinfo->state);
+
+               instinfo->cluster = strdup(cluster);
+               if (!instinfo->cluster)
+                       printf("Error: %s\n", strerror(errno));
+
+               instinfo->category = strdup(category);
+               if (!instinfo->category)
+                       printf("Error: %s\n", strerror(errno));
+
+               instinfo->state = strdup(state);
+               instinfo->period = period;
+               instinfo->width = width;
+               instinfo->height = height;
+               break;
+       case TOGGLE_DEBUG:
+               sscanf(buffer, "%d", &debug);
+               break;
+       default:
+               break;
+       }
+}
+
+static inline void do_line_command(void)
+{
+       switch (s_info.cmd) {
+       case PKG_LIST:
+               ls();
+               break;
+       case INST_LIST:
+               ls();
+               break;
+       case SLAVE_LIST:
+               ls();
+               break;
+       case TOGGLE_DEBUG:
+               break;
+       default:
+               break;
+       }
+}
+
 static Eina_Bool read_cb(void *data, Ecore_Fd_Handler *fd_handler)
 {
        int fd;
-       static const char *eod = "EOD\n";
+       static char *line_buffer = NULL;
+       static int line_index = 0;
+       static int bufsz = 256;
        char ch;
 
        fd = ecore_main_fd_handler_fd_get(fd_handler);
        if (fd < 0) {
-               fprintf(stderr, "FD is not valid: %d\n", fd);
-               return ECORE_CALLBACK_RENEW;
+               printf("FD is not valid: %d\n", fd);
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       if (read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
+               printf("Error: %s\n", strerror(errno));
+               return ECORE_CALLBACK_CANCEL;
        }
 
-       read(fd, &ch, sizeof(ch));
-       if (ch == *eod)
-               eod++;
-       else
-               eod = "EOD\n";
+       if (!line_buffer) {
+               line_index = 0;
+               line_buffer = malloc(bufsz);
+               if (!line_buffer) {
+                       printf("Error: %s\n", strerror(errno));
+                       return ECORE_CALLBACK_CANCEL;
+               }
+       }       
+
+       if (ch == '\n') { /* End of a line */
+               line_buffer[line_index] = '\0';
 
-       putc(ch, stdout);
+               if (!strcmp(line_buffer, "EOD")) {
+                       do_line_command();
+                       s_info.cmd = NOP;
+               } else {
+                       processing_line_buffer(line_buffer);
+               }
 
-       if (*eod == '\0') {
-               fputs(PROMPT, stdout);
-               eod = "EOD\n";
+               free(line_buffer);
+               line_buffer = NULL;
+               line_index = 0;
+               bufsz = 256;
+       } else {
+               char *new_buf;
+
+               line_buffer[line_index++] = ch;
+               if (line_index == bufsz - 1) {
+                       bufsz += 256;
+                       new_buf = realloc(line_buffer, bufsz);
+                       if (!new_buf) {
+                               printf("Error: %s\n", strerror(errno));
+                               free(line_buffer);
+                               line_buffer = 0;
+                               line_index = 0;
+                               bufsz = 256;
+                               return ECORE_CALLBACK_CANCEL;
+                       }
+
+                       line_buffer = new_buf;
+               }
        }
 
        return ECORE_CALLBACK_RENEW;
@@ -271,14 +746,15 @@ static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data
 {
        const char *fifo_name;
        int ret;
+       char *path;
 
        if (packet_get(packet, "si", &fifo_name, &ret) != 2) {
-               fprintf(stderr, "Invalid packet\n");
+               printf("Invalid packet\n");
                return -EFAULT;
        }
 
        if (ret != 0) {
-               fprintf(stderr, "Returns %d\n", ret);
+               printf("Returns %d\n", ret);
                return ret;
        }
 
@@ -286,7 +762,7 @@ static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data
 
        s_info.fifo_handle = open(fifo_name, O_RDONLY | O_NONBLOCK);
        if (s_info.fifo_handle < 0) {
-               fprintf(stderr, "Error: %s\n", strerror(errno));
+               printf("Error: %s\n", strerror(errno));
                s_info.fifo_handle = -EINVAL;
                ecore_main_loop_quit();
                return -EINVAL;
@@ -294,20 +770,23 @@ static int ret_cb(pid_t pid, int handle, const struct packet *packet, void *data
 
        s_info.fd_handler = ecore_main_fd_handler_add(s_info.fifo_handle, ECORE_FD_READ, read_cb, NULL, NULL, NULL);
        if (!s_info.fd_handler) {
-               fprintf(stderr, "Failed to add a fd handler\n");
+               printf("Failed to add a fd handler\n");
                close(s_info.fifo_handle);
                s_info.fifo_handle = -EINVAL;
                ecore_main_loop_quit();
                return -EFAULT;
        }
 
-       fputs(PROMPT, stdout);
+       path = node_to_abspath(s_info.curdir);
+       printf(PROMPT"%s # ", path);
+       free(path);
+
         if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) < 0)
-                fprintf(stderr, "Error: %s\n", strerror(errno));
+                printf("Error: %s\n", strerror(errno));
 
        s_info.in_handler = ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, input_cb, NULL, NULL, NULL);
        if (!s_info.in_handler) {
-               fprintf(stderr, "Failed to add a input handler\n");
+               printf("Failed to add a input handler\n");
                ecore_main_loop_quit();
                return -EFAULT;
        }
@@ -330,7 +809,7 @@ static int connected_cb(int handle, void *data)
 
        packet = packet_create("liveinfo_hello", "d", 0.0f);
        if (!packet) {
-               fprintf(stderr, "Failed to build a packet for hello\n");
+               printf("Failed to build a packet for hello\n");
                com_core_packet_client_fini(s_info.fd);
                s_info.fd = -EINVAL;
                return -EFAULT;
@@ -339,7 +818,7 @@ static int connected_cb(int handle, void *data)
        s_info.fd = handle;
 
        if (com_core_packet_async_send(s_info.fd, packet, 0.0f, ret_cb, NULL) < 0) {
-               fprintf(stderr, "Failed to send a packet hello\n");
+               printf("Failed to send a packet hello\n");
                packet_destroy(packet);
                com_core_packet_client_fini(s_info.fd);
                s_info.fd = -EINVAL;
@@ -365,33 +844,39 @@ int main(int argc, char *argv[])
 
        com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
        com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
+       livebox_service_init();
 
        s_info.fd = com_core_packet_client_init(SOCKET_FILE, 0, s_table);
        if (s_info.fd < 0) {
-               fprintf(stderr, "Failed to make a connection\n");
+               printf("Failed to make a connection\n");
                return -EIO;
        }
 
        printf("Type your command on below empty line\n");
 
        if (tcgetattr(STDIN_FILENO, &ttystate) < 0) {
-               fprintf(stderr, "Error: %s\n", strerror(errno));
+               printf("Error: %s\n", strerror(errno));
        } else {
                ttystate.c_lflag &= ~(ICANON | ECHO);
                ttystate.c_cc[VMIN] = 1;
 
                if (tcsetattr(STDIN_FILENO, TCSANOW, &ttystate) < 0)
-                       fprintf(stderr, "Error: %s\n", strerror(errno));
+                       printf("Error: %s\n", strerror(errno));
        }
 
        if (setvbuf(stdout, (char *)NULL, _IONBF, 0) != 0)
-               fprintf(stderr, "Error: %s\n", strerror(errno));
+               printf("Error: %s\n", strerror(errno));
+
+       init_directory();
 
        ecore_main_loop_begin();
 
+       fini_directory();
+       livebox_service_fini();
+
        ttystate.c_lflag |= ICANON | ECHO;
        if (tcsetattr(STDIN_FILENO, TCSANOW, &ttystate) < 0)
-               fprintf(stderr, "Error: %s\n", strerror(errno));
+               printf("Error: %s\n", strerror(errno));
 
        if (s_info.fd > 0) {
                com_core_packet_client_fini(s_info.fd);
diff --git a/util_liveinfo/src/node.c b/util_liveinfo/src/node.c
new file mode 100644 (file)
index 0000000..02d18a2
--- /dev/null
@@ -0,0 +1,259 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "node.h"
+
+struct node {
+       char *name;
+       enum node_type type;
+
+       void *data;
+
+       struct node *parent;
+       unsigned char mode;
+
+       struct {
+               struct node *next;
+               struct node *prev;
+       } sibling;
+
+       struct node *child;
+};
+
+int errno; /* External symbol */
+
+char *node_to_abspath(struct node *node)
+{
+       char *path;
+       char *ptr;
+       struct node *tmp;
+       int len = 0;
+
+       tmp = node;
+       while (tmp && node_name(tmp)) {
+               len += strlen(node_name(tmp)) + 1;
+               tmp = node_parent(tmp);
+       }
+
+       path = malloc(len + 2);
+       if (!path)
+               return NULL;
+
+       if (!len) {
+               path[0] = '/';
+               path[1] = '\0';
+       } else {
+               ptr = path + len;
+               *ptr = '\0';
+               tmp = node;
+               while (tmp && node_name(tmp)) {
+                       ptr -= (strlen(node_name(tmp)) + 1);
+                       *ptr = '/';
+                       strncpy(ptr + 1, node_name(tmp), strlen(node_name(tmp)));
+                       tmp = node_parent(tmp);
+               }
+       }
+
+       return path;
+}
+
+static inline int next_state(int from, char ch)
+{
+       switch ( ch )
+       {
+               case '/':
+                       return 1;
+               case '.':
+                       if ( from == 1 ) return 2;
+                       if ( from == 2 ) return 3;
+       }
+
+       return 4;
+}
+
+static inline void abspath(char* pBuffer, char* pRet)
+{
+       int idx=0;
+       int state = 1;
+       int from;
+       int src_idx = 0;
+       int src_len = strlen(pBuffer);
+       pRet[idx] = '/';
+       idx ++;
+
+       while (src_idx <= src_len) {
+               from = state;
+               state = next_state(from, pBuffer[src_idx]);
+
+               switch (from) {
+                       case 1:
+                               if ( state != 1 ) {
+                                       pRet[idx] = pBuffer[src_idx];
+                                       idx ++;
+                               }
+                               break;
+                       case 2:
+                               if ( state == 1 ) {
+                                       if ( idx > 0 ) idx --;
+                               } else {
+                                       pRet[idx] = pBuffer[src_idx];
+                                       idx ++;
+                               }
+                               break;
+                       case 3:
+                               // Only can go to the 1 or 4
+                               if ( state == 1 ) {
+                                       idx -= 2;
+                                       if ( idx < 0 ) idx = 0;
+
+                                       while ( idx > 0 && pRet[idx] != '/' ) idx --;
+                                       if ( idx > 0 && pRet[idx] == '/' ) idx --;
+                                       while ( idx > 0 && pRet[idx] != '/' ) idx --;
+                               }
+                       case 4:
+                               pRet[idx] = pBuffer[src_idx];
+                               idx ++;
+                               break;
+               }
+
+               pRet[idx] = '\0';
+               src_idx ++;
+       }
+}
+
+struct node *node_find(const struct node *node, char *path)
+{
+       int len;
+       char *ptr = path;
+
+       do {
+               node = node->child;
+               if (!node)
+                       return NULL;
+
+               if (*ptr == '/') ptr++;
+               for (len = 0; ptr[len] && ptr[len] != '/'; len++);
+               while (node) {
+                       if (!strncmp(node->name, ptr, len) && node->name[len] == '\0') {
+                               ptr += len;
+                               ptr += (*ptr == '/');
+                               break;
+                       }
+
+                       node = node->sibling.next;
+               }
+       } while (*ptr && node);
+
+       return (struct node *)node;
+}
+
+struct node *node_create(struct node *parent, const char *name, enum node_type type)
+{
+       struct node *node;
+
+       node = malloc(sizeof(*node));
+       if (!node) {
+               printf("Error: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       node->parent = parent;
+
+       if (name) {
+               node->name = strdup(name);
+               if (!node->name) {
+                       printf("Error: %s\n", strerror(errno));
+                       return NULL;
+               }
+       } else {
+               node->name = NULL;
+       }
+
+       node->type = type;
+
+       node->sibling.next = NULL;
+       node->sibling.prev = NULL;
+
+       node->child = NULL;
+       node->data = NULL;
+
+       if (parent) {
+               if (parent->child) {
+                       struct node *tmp;
+                       tmp = parent->child;
+                       while (tmp->sibling.next)
+                               tmp = tmp->sibling.next;
+
+                       tmp->sibling.next = node;
+                       node->sibling.prev = tmp;
+               } else {
+                       parent->child = node;
+               }
+       }
+       return node;
+}
+
+void node_destroy(struct node *node)
+{
+       free(node->name);
+       free(node);
+}
+
+struct node * const node_next_sibling(const struct node *node)
+{
+       return node->sibling.next;
+}
+
+struct node * const node_prev_sibling(const struct node *node)
+{
+       return node->sibling.prev;
+}
+
+void node_set_mode(struct node *node, int mode)
+{
+       node->mode = mode;
+}
+
+void node_set_data(struct node *node, void *data)
+{
+       node->data = data;
+}
+
+void node_set_type(struct node *node, enum node_type type)
+{
+       node->type = type;
+}
+
+struct node * const node_child(const struct node *node)
+{
+       return node->child;
+}
+
+struct node * const node_parent(const struct node *node)
+{
+       return node->parent;
+}
+
+const int const node_mode(const struct node *node)
+{
+       return node->mode;
+}
+
+void * const node_data(const struct node *node)
+{
+       return node->data;
+}
+
+const enum node_type const node_type(const struct node *node)
+{
+       return node->type;
+}
+
+const char * const node_name(const struct node *node)
+{
+       return node->name;
+}
+
+/* End of a file */