Add --usage/--help commandline options
[sdk/target/sdbd.git] / src / sdb.c
index 5634d55..d61cdc0 100644 (file)
--- a/src/sdb.c
+++ b/src/sdb.c
 #include <sys/time.h>
 #include <signal.h>
 #include <grp.h>
+#include <netdb.h>
+
 
 #include "sysdeps.h"
 #include "sdb.h"
+#include "strutils.h"
+#if !SDB_HOST
+#include "commandline_sdbd.h"
+#endif
 
 #if !SDB_HOST
-//#include <private/android_filesystem_config.h> eric
-#include <linux/capability.h>
 #include <linux/prctl.h>
 #define SDB_PIDPATH "/tmp/.sdbd.pid"
 #else
 #include "usb_vendors.h"
 #endif
-
+#include <system_info.h>
+#define PROC_CMDLINE_PATH "/proc/cmdline"
 #if SDB_TRACE
 SDB_MUTEX_DEFINE( D_lock );
 #endif
 
 int HOST = 0;
 
+#if !SDB_HOST
+SdbdCommandlineArgs sdbd_commandline_args;
+#endif
+
+int is_emulator(void) {
+#if SDB_HOST
+       return 0;
+#else
+       return sdbd_commandline_args.emulator.host != NULL;
+#endif
+}
+
 void handle_sig_term(int sig) {
 #ifdef SDB_PIDPATH
     if (access(SDB_PIDPATH, F_OK) == 0)
@@ -52,7 +69,7 @@ void handle_sig_term(int sig) {
 #endif
     //kill(getpgid(getpid()),SIGTERM);
     //killpg(getpgid(getpid()),SIGTERM);
-    if (access("/dev/samsung_sdb", F_OK) == 0) {
+    if (!is_emulator()) {
         exit(0);
     } else {
        // do nothing on a emulator
@@ -292,7 +309,7 @@ static void send_close(unsigned local, unsigned remote, atransport *t)
     p->msg.arg1 = remote;
     send_packet(p, t);
 }
-
+static int device_status = 0; // 0:online, 1: password locked later
 static void send_connect(atransport *t)
 {
     D("Calling send_connect \n");
@@ -300,9 +317,24 @@ static void send_connect(atransport *t)
     cp->msg.command = A_CNXN;
     cp->msg.arg0 = A_VERSION;
     cp->msg.arg1 = MAX_PAYLOAD;
-    snprintf((char*) cp->data, sizeof cp->data, "%s::",
-            HOST ? "host" : sdb_device_banner);
+
+    char device_name[256]={0,};
+    int r = 0;
+
+    if (is_emulator()) {
+        r = get_emulator_name(device_name, sizeof device_name);
+    } else {
+        r = get_device_name(device_name, sizeof device_name);
+    }
+    if (r < 0) {
+        snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, DEFAULT_DEVICENAME, device_status);
+    } else {
+        snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, device_name, device_status);
+    }
+
+    D("CNXN data:%s\n", (char*)cp->data);
     cp->msg.data_length = strlen((char*) cp->data) + 1;
+
     send_packet(cp, t);
 #if SDB_HOST
         /* XXX why sleep here? */
@@ -329,6 +361,79 @@ static char *connection_state_name(atransport *t)
     }
 }
 
+static int get_str_cmdline(char *src, char *dest, char str[], int str_size) {
+    char *s = strstr(src, dest);
+    if (s == NULL) {
+        return -1;
+    }
+    char *e = strstr(s, " ");
+    if (e == NULL) {
+        return -1;
+    }
+
+    int len = e-s-strlen(dest);
+
+    if (len >= str_size) {
+        D("buffer size(%d) should be bigger than %d\n", str_size, len+1);
+        return -1;
+    }
+
+    s_strncpy(str, s + strlen(dest), len);
+    return len;
+}
+
+int get_emulator_forward_port() {
+    SdbdCommandlineArgs *sdbd_args = &sdbd_commandline_args; /* alias */
+
+    if (sdbd_args->emulator.host == NULL) {
+        return -1;
+    }
+
+    return sdbd_args->emulator.port;
+}
+
+int get_emulator_name(char str[], int str_size) {
+    SdbdCommandlineArgs *sdbd_args = &sdbd_commandline_args; /* alias */
+
+    if (sdbd_args->emulator.host == NULL) {
+        return -1;
+    }
+
+    s_strncpy(str, sdbd_args->emulator.host, str_size);
+    return 0;
+}
+
+int get_device_name(char str[], int str_size) {
+    char *value = NULL;
+    int r = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &value);
+    if (r != SYSTEM_INFO_ERROR_NONE) {
+        D("fail to get system model:%d\n", errno);
+        return -1;
+    } else {
+        s_strncpy(str, value, str_size);
+        D("returns model_name:%s\n", value);
+        if (value != NULL) {
+            free(value);
+        }
+        return 0;
+    }
+    /*
+    int fd = unix_open(USB_SERIAL_PATH, O_RDONLY);
+    if (fd < 0) {
+        D("fail to read:%s (%d)\n", USB_SERIAL_PATH, errno);
+        return -1;
+    }
+
+    if(read_line(fd, str, str_size)) {
+        D("device serial name: %s\n", str);
+        sdb_close(fd);
+        return 0;
+    }
+    sdb_close(fd);
+    */
+    return -1;
+}
+
 void parse_banner(char *banner, atransport *t)
 {
     char *type, *product, *end;
@@ -691,7 +796,11 @@ static BOOL WINAPI ctrlc_handler(DWORD type)
 
 static void sdb_cleanup(void)
 {
+    clear_sdbd_commandline_args(&sdbd_commandline_args);
     usb_cleanup();
+//    if(required_pid > 0) {
+//        kill(required_pid, SIGKILL);
+//    }
 }
 
 void start_logging(void)
@@ -985,22 +1094,19 @@ int should_drop_privileges() {
 }
 
 int set_developer_privileges() {
-    gid_t groups[] = { SID_DEVELOPER, SID_APP_LOGGING, SID_SYS_LOGGING };
+    gid_t groups[] = { SID_DEVELOPER, SID_APP_LOGGING, SID_SYS_LOGGING, SID_INPUT };
     if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
-        fprintf(stderr, "set groups failed (errno: %d, %s)\n", errno, strerror(errno));
-        //exit(1);
+        D("set groups failed (errno: %d, %s)\n", errno, strerror(errno));
     }
 
     // then switch user and group to developer
     if (setgid(SID_DEVELOPER) != 0) {
-        fprintf(stderr, "set group id failed (errno: %d, %s)\n", errno, strerror(errno));
-        //exit(1);
+        D("set group id failed (errno: %d, %s)\n", errno, strerror(errno));
         return -1;
     }
 
     if (setuid(SID_DEVELOPER) != 0) {
-        fprintf(stderr, "set user id failed (errno: %d, %s)\n", errno, strerror(errno));
-        //exit(1);
+        D("set user id failed (errno: %d, %s)\n", errno, strerror(errno));
         return -1;
     }
 
@@ -1011,17 +1117,50 @@ int set_developer_privileges() {
             D("sdbd: unable to change working directory to /\n");
         }
     }
+    // TODO: use pam later
+    putenv("HOME=/home/developer");
+
     return 1;
 }
 #define ONDEMAND_ROOT_PATH "/home/developer"
 
+static void execute_required_process() {
+
+    FILE *pre_proc_file = popen("pidof debug_launchpad_preloading_preinitializing_daemon", "r");
+
+    if(pre_proc_file == NULL) {
+        D("fail to get the pidof debug_launchpad_preloading_preinitializing_daemon");
+        return;
+    }
+
+    int result = 0;
+    while(!feof(pre_proc_file)) {
+        int pid = 0;
+        result += fscanf(pre_proc_file, "%d", &pid);
+        if(pid > 0) {
+            kill(pid, SIGKILL);
+        }
+    }
+    D("Kill %d debug launchpad daemon", result);
+
+    pclose(pre_proc_file);
+
+    system("/usr/bin/debug_launchpad_preloading_preinitializing_daemon &");
+}
+
 static void init_sdk_requirements() {
     struct stat st;
 
+    // set env variable for temporary
+    // TODO: should use pam instead later!!
     if (!getenv("TERM")) {
         putenv("TERM=linux");
     }
 
+    if (!getenv("HOME")) {
+        putenv("HOME=/root");
+    }
+
     if (stat(ONDEMAND_ROOT_PATH, &st) == -1) {
         return;
     }
@@ -1032,13 +1171,14 @@ static void init_sdk_requirements() {
             D("failed to change ownership to developer to %s\n", ONDEMAND_ROOT_PATH);
         }
     }
+
+    execute_required_process();
 }
 #endif /* !SDB_HOST */
 
 int sdb_main(int is_daemon, int server_port)
 {
 #if !SDB_HOST
-
     init_drop_privileges();
     init_sdk_requirements();
     umask(000);
@@ -1111,7 +1251,7 @@ int sdb_main(int is_daemon, int server_port)
         }
     }
 
-    if (access("/dev/samsung_sdb", F_OK) == 0) {
+    if (!is_emulator()) {
         // listen on USB
         usb_init();
         // listen on tcp
@@ -1139,6 +1279,7 @@ int sdb_main(int is_daemon, int server_port)
 #endif
         start_logging();
     }
+
     D("Event loop starting\n");
 
     fdevent_loop();
@@ -1462,6 +1603,25 @@ int main(int argc, char **argv)
         recovery_mode = 1;
     }
 #endif
+
+    apply_sdbd_commandline_defaults(&sdbd_commandline_args);
+    int parse_ret = parse_sdbd_commandline(&sdbd_commandline_args, argc, argv);
+
+    // TODO: Add detailed error messages
+    // TODO: Add individual messages for help and usage
+    if(parse_ret != SDBD_COMMANDLINE_SUCCESS) {
+        if (parse_ret == SDBD_COMMANDLINE_HELP
+                || parse_ret == SDBD_COMMANDLINE_USAGE) {
+            // User requested help or usage
+            print_sdbd_usage_message(stdout);
+            return EXIT_SUCCESS;
+        }
+
+        // Print usage message because of invalid options
+        print_sdbd_usage_message(stderr);
+        return EXIT_FAILURE;
+    }
+
 #if !SDB_HOST
     if (daemonize() < 0)
         fatal("daemonize() failed: %.200s", strerror(errno));