return do_sync_copy(argv[1], argv[2], &info, 0);
}
-static int shell_connect()
-{
- int fd = -1;
- char shell_cmd[SHELLCMD_BUF_SIZE] = {0,};
- struct sdb_version version;
-
- /* eshell */
- if(!get_platform_version(&version) && is_support_eshell(&version)) {
- int lines, columns;
- if(!get_screensize(&lines, &columns)) {
- snprintf(shell_cmd, sizeof(shell_cmd), "eshell:%d:%d", lines, columns);
- D("interactive shell : eshell command=%s\n", shell_cmd);
- fd = sdb_connect(shell_cmd);
- }
- }
-
- /* retry basic shell service */
- if(fd < 0){
- fd = sdb_connect("shell:");
- }
-
- return fd;
-}
-
-static int shell_connect_args(int argc, char ** argv)
-{
- int fd = -1;
- char shell_cmd[SHELLCMD_BUF_SIZE] = {0,};
-
- snprintf(shell_cmd, sizeof(shell_cmd), "shell:%s", argv[1]);
- argc -= 2;
- argv += 2;
- while(argc-- > 0) {
- strcat(shell_cmd, " ");
-
- /* quote empty strings and strings with spaces */
- int quote = (**argv == 0 || strchr(*argv, ' '));
- if (quote)
- strcat(shell_cmd, "\"");
- strcat(shell_cmd, *argv++);
- if (quote)
- strcat(shell_cmd, "\"");
- }
-
- fd = sdb_connect(shell_cmd);
-
- return fd;
-}
-
int shell(int argc, char ** argv) {
- int fd = -1;
+ char buf[4096];
- if(argc < 2) {
- fd = shell_connect();
- } else {
- fd = shell_connect_args(argc, argv);
- }
+ int r;
+ int fd;
- if (fd < 0) {
- return 1;
- }
+ if(argc < 2) {
+ D("starting interactive shell\n");
+ r = interactive_shell();
+ return r;
+ }
- sdb_execute_shell(fd, SDB_STDIN_ON);
- sdb_close(fd);
+ snprintf(buf, sizeof buf, "shell:%s", argv[1]);
+ argc -= 2;
+ argv += 2;
+ while(argc-- > 0) {
+ strcat(buf, " ");
+
+ /* quote empty strings and strings with spaces */
+ int quote = (**argv == 0 || strchr(*argv, ' '));
+ if (quote)
+ strcat(buf, "\"");
+ strcat(buf, *argv++);
+ if (quote)
+ strcat(buf, "\"");
+ }
- return 0;
+ D("interactive shell loop. buff=%s\n", buf);
+ fd = sdb_connect(buf);
+ if(fd >= 0) {
+ D("about to read_and_dump(fd=%d)\n", fd);
+ read_and_dump(fd);
+ D("read_and_dump() done.\n");
+ sdb_close(fd);
+ r = 0;
+ } else {
+ r = 1;
+ }
+
+ D("interactive shell loop. return r=%d\n", r);
+ return r;
}
int forkserver(int argc, char** argv) {
}
static int is_support_debug_option(void){
- int supported = 0;
+ int is_support = 0;
char buf[512] = {};
const char* SHELL_GET_PROFILE_VER_CMD ="shell:/usr/bin/profile_command getversion";
if (sscanf(buf, "%d.%d", &major, &minor) == 2) {
// major version number at least 4
if (major >= 4) {
- supported = 1;
+ is_support = 1;
}
}
}
sdb_close(fd);
- return supported;
+ return is_support;
}
static int is_support_whitespace_pkgname(void){
- int supported = 0;
- struct sdb_version version;
- int ret = -1;
-
- ret = get_platform_version(&version);
- if(ret < 0) {
+ int is_support = 0;
+ int version = 0;
+ int major = 0;
+ int minor = 0;
+ int patch = 0;
+
+ version = get_platform_version();
+ if(!version) {
// default : not support whitespace for package file name.
return 0;
}
- D("Platform version : %d.%d.%d\n", version.major, version.minor, version.patch);
+ major = MK_PLATFORM_MAJOR(version);
+ minor = MK_PLATFORM_MINOR(version);
+ patch = MK_PLATFORM_PATCH(version);
+
+ D("Platform version : %d.%d.%d\n", major, minor, patch);
// version number at least 2.4.0
- if (version.major >= 3 || (version.major >= 2 && version.minor >=4)) {
- supported = 1;
+ if (major >= 3 || (major >= 2 && minor >=4)) {
+ is_support = 1;
}
- return supported;
+ return is_support;
}
int install(int argc, char **argv) {
#include "fdevent.h"
#include "strutils.h"
-#if defined(OS_LINUX) || defined(OS_DARWIN) // for UNIX
+#ifdef HAVE_TERMIO_H
#include <termios.h>
#include <sys/ioctl.h>
#endif
static void create_opt_list(LIST_NODE** opt_list);
static void create_cmd_list(LIST_NODE** cmd_list);
static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
-static void sync_winsz(void);
-struct sdb_stdin_info g_stdin_info;
+static int ishell_fd = -1;
+static int enable_sync_winsz = 0;
+static void sync_winsz(void);
#define INFOBUF_MAXLEN 64
typedef struct platform_info {
char profile_name[INFOBUF_MAXLEN]; // 2.2.1
} pinfo;
-int get_platform_version(struct sdb_version *pversion) {
+int get_platform_version(void) {
struct platform_info pinfo;
- const char* GET_SYSTEM_INFO_CMD = "sysinfo:";
- int fd = -1;
- int ret = -1;
- if (pversion == NULL) {
- return -1;
- }
+ const char* GET_SYSTEM_INFO_CMD = "sysinfo:";
+ int fd = sdb_connect(GET_SYSTEM_INFO_CMD);
+ int version = 0;
- fd = sdb_connect(GET_SYSTEM_INFO_CMD);
if(fd < 0) {
- return -1;
+ return 0;
}
if (readx(fd, &pinfo, sizeof(struct platform_info)) == 0) {
int minor = 0;
int patch = 0;
if (sscanf(pinfo.platform_version, "%d.%d.%d", &major, &minor, &patch) == 3) {
- pversion->major = major;
- pversion->minor = minor;
- pversion->patch = patch;
- ret = 0;
+ if (major < 1024 && minor < 1024 && patch < 1024) {
+ version |= (major << 20);
+ version |= (minor << 10);
+ version |= patch;
+ } else {
+ LOG_ERROR("Unexpected version : %d.%d.%d\n", major, minor, patch);
+ }
}
}
- D("Platform version : %d.%d.%d\n", pversion->major, pversion->minor, pversion->patch);
+ D("Platform version : %s(%x)\n", pinfo.platform_version, version);
sdb_close(fd);
- return ret;
+ return version;
}
-void read_and_dump(int fd)
-{
- char buf[PATH_MAX];
- int len;
+#ifdef HAVE_TERMIO_H
- while(fd >= 0) {
- D("read_and_dump(): pre sdb_read(fd=%d)\n", fd);
- len = sdb_read(fd, buf, PATH_MAX);
- D("read_and_dump(): post sdb_read(fd=%d): len=%d\n", fd, len);
- if(len == 0) {
- break;
- }
+static __inline__ void stdin_raw_init(int fd, struct termios* tio_save);
+static __inline__ void stdin_raw_restore(int fd, struct termios* tio_save);
- if(len < 0) {
- if(errno == EINTR) continue;
- break;
- }
- fwrite(buf, 1, len, stdout);
- fflush(stdout);
- }
+static __inline__ void stdin_raw_init(int fd, struct termios* tio_save)
+{
+ struct termios tio;
-}
+ if(tcgetattr(fd, &tio)) return;
+ memcpy(tio_save, &tio, sizeof(struct termios));
-// TODO: move the following functions to util file for each OS.
-void sdb_shell_stdin_init(int fd);
-void sdb_shell_stdin_restore(int fd);
-void *stdin_read_thread(void *args);
-int get_screensize(int* lines, int* columns);
+ tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
-#if defined(OS_WINDOWS) // for Windows
-HANDLE g_input_handle = NULL;
-DWORD g_console_mode_save = NULL;
+ /* no timeout but request at least one character per read */
+ tio.c_cc[VTIME] = 0;
+ tio.c_cc[VMIN] = 1;
-static char arrow_up[3] = {27, 91, 65};
-static char arrow_down[3] = {27, 91, 66};
-static char arrow_right[3] = {27, 91, 67};
-static char arrow_left[3] = {27, 91, 68};
+ tcsetattr(fd, TCSANOW, &tio);
+ tcflush(fd, TCIFLUSH);
+}
-void sdb_shell_stdin_init(int fd)
+static __inline__ void stdin_raw_restore(int fd, struct termios* tio_save)
{
- if (fd != INPUT_FD) {
- return;
- }
+ tcsetattr(fd, TCSANOW, tio_save);
+ tcflush(fd, TCIFLUSH);
+}
+#else
+static __inline__ void stdin_raw_init(void** args);
+static __inline__ void stdin_raw_restore(void** args);
- g_input_handle = GetStdHandle(STD_INPUT_HANDLE);
+static __inline__ void stdin_raw_init(void** args) {
+ HANDLE input_t_handle = GetStdHandle(STD_INPUT_HANDLE);
+ args[1] = NULL;
- if(g_input_handle == INVALID_HANDLE_VALUE) {
+ if(input_t_handle == INVALID_HANDLE_VALUE) {
fprintf(stdout, "error: fail to get the stdin handle\n");
- g_input_handle = NULL;
return;
}
- if(!GetConsoleMode(g_input_handle, &g_console_mode_save)) {
+ DWORD console_mode_save;
+ if(!GetConsoleMode(input_t_handle, &console_mode_save)) {
fprintf(stdout, "error: fail to get the stdin console mode\n");
- g_input_handle = NULL;
return;
}
- if(!SetConsoleMode(g_input_handle, ENABLE_MOUSE_INPUT)) {
+ if(!SetConsoleMode(input_t_handle, ENABLE_MOUSE_INPUT)) {
fprintf(stdout, "error: fail to set console mode\n");
return;
}
+
+ DWORD* cms_ptr = malloc(sizeof(DWORD));
+ *cms_ptr = console_mode_save;
+ args[1] = cms_ptr;
+
+ HANDLE* input_t_ptr = malloc(sizeof(HANDLE));
+ *input_t_ptr = input_t_handle;
+ args[2] = input_t_ptr;
+}
+
+static __inline__ void stdin_raw_restore(void** args) {
+ DWORD* cms_ptr = args[1];
+ if(cms_ptr != NULL) {
+ HANDLE* input_t_ptr = args[2];
+
+ if(!SetConsoleMode(*input_t_ptr, *cms_ptr)) {
+ fprintf(stdout, "error: fail to restore console mode\n");
+ }
+ }
}
-void sdb_shell_stdin_restore(int fd)
+#endif
+
+void read_and_dump(int fd)
{
- if (fd != INPUT_FD) {
- return;
+ char buf[PATH_MAX];
+ int len;
+
+ while(fd >= 0) {
+ D("read_and_dump(): pre sdb_read(fd=%d)\n", fd);
+ len = sdb_read(fd, buf, PATH_MAX);
+ D("read_and_dump(): post sdb_read(fd=%d): len=%d\n", fd, len);
+ if(len == 0) {
+ break;
+ }
+
+ if(len < 0) {
+ if(errno == EINTR) continue;
+ break;
+ }
+ fwrite(buf, 1, len, stdout);
+ fflush(stdout);
}
- if (g_input_handle != NULL) {
- if(!SetConsoleMode(g_input_handle, g_console_mode_save)) {
- fprintf(stdout, "error: fail to restore console mode\n");
+}
+
+#ifdef HAVE_TERMIO_H
+static void *stdin_read_thread(void *x)
+{
+ unsigned char buf[1024];
+ int r, n;
+
+ void** args = (void**) x;
+ int fd = *(int*)args[0];
+ struct termios* tio_save = args[1];
+ free(args[0]);
+ free(args);
+ for(;;) {
+ /* fdi is really the client's stdin, so use read, not sdb_read here */
+ D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", INPUT_FD);
+ r = unix_read(INPUT_FD, buf, 1024);
+ D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", INPUT_FD);
+ if(r == 0) break;
+ if(r < 0) {
+ if(errno == EINTR) continue;
+ break;
+ }
+ for(n = 0; n < r; n++){
+ if(buf[n] == '\n' || buf[n] == '\r') {
+ n++;
+ if(buf[n] == '~') {
+ n++;
+ if(buf[n] == '.') {
+ fprintf(stderr,"\n* disconnect *\n");
+ stdin_raw_restore(INPUT_FD, tio_save);
+ free(tio_save);
+ exit(0);
+ }
+ }
+ }
+ }
+ r = sdb_write(fd, buf, r);
+ if(r <= 0) {
+ break;
}
- g_input_handle = NULL;
}
+ return 0;
}
+#else
-void *stdin_read_thread(void *args)
+static char arrow_up[3] = {27, 91, 65};
+static char arrow_down[3] = {27, 91, 66};
+static char arrow_right[3] = {27, 91, 67};
+static char arrow_left[3] = {27, 91, 68};
+
+static void *stdin_read_thread(void *x)
{
+ void** args = (void**) x;
+ int fd = *(int*)args[0];
char* buf = NULL;
int buf_len;
+ HANDLE* console_input_handle_ptr = args[2];
INPUT_RECORD i_record;
DWORD cNumRead;
+ SAFE_FREE(args[0]);
- if(g_console_mode_save != NULL) {
+ if(args[1] != NULL) {
while(1) {
- if(!ReadConsoleInput(g_input_handle, &i_record, 1, &cNumRead)) {
+ if(!ReadConsoleInput(*console_input_handle_ptr, &i_record, 1, &cNumRead)) {
fprintf(stdout, "error: fail to read console standard input\n");
break;
}
}
}
if(buf) {
- if(sdb_write(g_stdin_info.remote_fd, buf, buf_len) <= 0) {
+ if(sdb_write(fd, buf, buf_len) <= 0) {
break;
}
}
}
} else if(i_record.EventType == MOUSE_EVENT) {
if (i_record.Event.MouseEvent.dwEventFlags == 0) {
- if (g_stdin_info.enable_sync_winsz == SYNCWINSZ_SUPPORTED) {
+ if (enable_sync_winsz == 1) {
sync_winsz();
}
}
else {
while(1) {
unsigned char buf[1024];
- int r = unix_read(g_stdin_info.stdin_fd, buf, 1024);
+ int r = unix_read(INPUT_FD, buf, 1024);
if(r == 0) break;
if(r < 0) {
if(errno == EINTR) continue;
break;
}
- r = sdb_write(g_stdin_info.remote_fd, buf, r);
+ r = sdb_write(fd, buf, r);
if(r <= 0) {
break;
}
}
return 0;
}
+#endif
-int get_screensize(int* lines, int* columns)
-{
- HANDLE hConOut;
- CONSOLE_SCREEN_BUFFER_INFO scr;
-
- hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
- if (hConOut != INVALID_HANDLE_VALUE)
- {
- if (GetConsoleScreenBufferInfo (hConOut, &scr))
- {
- *columns = scr.dwSize.X;
- *lines = scr.srWindow.Bottom - scr.srWindow.Top + 1;
- return 0;
- }
- }
-
- D("failed to get windows size\n");
- return -1;
-}
-
-#else // for UNIX
-struct termios g_tio_save;
-static void sig_winch_handler(int sig);
-
-void sdb_shell_stdin_init(int fd)
-{
- struct termios tio;
-
- if(tcgetattr(fd, &tio)) return;
- memcpy(&g_tio_save, &tio, sizeof(struct termios));
-
- /* disable CANON, ECHO*, etc */
- tio.c_lflag = 0;
- /* no timeout but request at least one character per read */
- tio.c_cc[VTIME] = 0;
- tio.c_cc[VMIN] = 1;
-
- tcsetattr(fd, TCSANOW, &tio);
- tcflush(fd, TCIFLUSH);
-
- /* register SIGWINCH signal handler. */
- struct sigaction sa_winch;
- sigemptyset(&sa_winch.sa_mask);
- sa_winch.sa_flags = 0;
- sa_winch.sa_handler = sig_winch_handler;
- if (sigaction(SIGWINCH, &sa_winch, NULL) < -1) {
- D("failed to register the SIGWINCH signal handler.\n");
- }
-}
-
-void sdb_shell_stdin_restore(int fd)
-{
- tcsetattr(fd, TCSANOW, &g_tio_save);
- tcflush(fd, TCIFLUSH);
-}
-
-void *stdin_read_thread(void *args)
-{
- unsigned char buf[1024];
- int r, n;
-
- for(;;) {
- /* fdi is really the client's stdin, so use read, not sdb_read here */
- D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", INPUT_FD);
- r = unix_read(g_stdin_info.stdin_fd, buf, 1024);
- D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", INPUT_FD);
- if(r == 0) break;
- if(r < 0) {
- if(errno == EINTR) continue;
- break;
- }
- for(n = 0; n < r; n++){
- if(buf[n] == '\n' || buf[n] == '\r') {
- n++;
- if(buf[n] == '~') {
- n++;
- if(buf[n] == '.') {
- fprintf(stderr,"\n* disconnect *\n");
- sdb_shell_stdin_restore(g_stdin_info.stdin_fd);
- exit(0);
- }
- }
- }
- }
- r = sdb_write(g_stdin_info.remote_fd, buf, r);
- if(r <= 0) {
- break;
- }
- }
- return 0;
-}
-
-int get_screensize(int* lines, int* columns)
+#ifdef HAVE_TERMIO_H
+static int get_screensize(int* lines, int* columns)
{
struct winsize win_sz;
return;
}
- if (g_stdin_info.enable_sync_winsz == SYNCWINSZ_SUPPORTED) {
+ if (enable_sync_winsz == 1) {
sync_winsz();
}
}
+
+#else // for Windows
+static int get_screensize(int* lines, int* columns)
+{
+ HANDLE hConOut;
+ CONSOLE_SCREEN_BUFFER_INFO scr;
+
+ hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
+ if (hConOut != INVALID_HANDLE_VALUE)
+ {
+ if (GetConsoleScreenBufferInfo (hConOut, &scr))
+ {
+ *columns = scr.dwSize.X;
+ *lines = scr.srWindow.Bottom - scr.srWindow.Top + 1;
+ return 0;
+ }
+ }
+
+ D("failed to get windows size\n");
+ return -1;
+}
#endif
static void sync_winsz() {
if (get_screensize(&lines, &columns) == 0) {
memset(&addr, 0, sizeof(addr));
- if (sdb_getsockname(g_stdin_info.remote_fd, (struct sockaddr *)&addr, &sockaddr_len) < 0) {
+ if (sdb_getsockname(ishell_fd, (struct sockaddr *)&addr, &sockaddr_len) < 0) {
D("failed to get sock name. errno=%d, %s\n", errno, strerror(errno));
return;
}
snprintf(full_cmd, sizeof(full_cmd), "shellconf:syncwinsz:%d:%d:%d", remote_id, lines, columns);
fd = sdb_connect(full_cmd);
if(fd < 0) {
- g_stdin_info.enable_sync_winsz = SYNCWINSZ_UNSUPPORTED;
+ enable_sync_winsz = 0;
D("failed to syncwinsz.\n");
return;
}
}
}
-/* Check whether the key/value matches with the platform capability.
- * Return value
- * 1 : if key/value matches with capability.
- * 0 : if there is no match. */
static int match_capability_key_value(char* cap, char* key, char* value) {
char *p_str = NULL;
int offset = 0;
char *k = NULL;
char *v = NULL;
- int matched = 0;
+ int matched = -1;
if (cap == NULL || key == NULL || value == NULL) {
return -1;
char full_cmd[16] = {0,};
char cap_buffer[CAPBUF_SIZE] = {0,};
uint16_t len = 0;
- int supported = SYNCWINSZ_UNSUPPORTED;
- int fd = -1;
+ int supported = -1;
snprintf(full_cmd, sizeof(full_cmd), "capability:");
- fd = sdb_connect(full_cmd);
+ int fd = sdb_connect(full_cmd);
if (fd >= 0) {
readx(fd, &len, sizeof(uint16_t));
if (len > CAPBUF_SIZE-1) {
readx(fd, cap_buffer, len);
sdb_close(fd);
- if (match_capability_key_value(cap_buffer, "syncwinsz_support", "enabled")) {
- supported = SYNCWINSZ_SUPPORTED;
- }
+ supported = match_capability_key_value(cap_buffer, "syncwinsz_support", "enabled");
}
return supported;
}
-static void stdin_info_init(int fd)
-{
- g_stdin_info.stdin_fd = INPUT_FD;
- g_stdin_info.remote_fd = fd;
- g_stdin_info.enable_sync_winsz = check_syncwinsz_support();
-}
-
-void sdb_execute_shell(int fd, int stdin_on)
+int interactive_shell()
{
- stdin_info_init(fd);
-
- if (stdin_on == SDB_STDIN_ON) {
- sdb_thread_t thr;
-
- sdb_shell_stdin_init(INPUT_FD);
-
- sdb_thread_create(&thr, stdin_read_thread, NULL);
- read_and_dump(fd);
+ sdb_thread_t thr;
+ char eshell[32] = "eshell:";
+ int lines, columns;
+ int fd = -1;
+ int major = 0;
+ int minor = 0;
+ int patch = 0;
+ int version = 0;
+
+ version = get_platform_version();
+ major = MK_PLATFORM_MAJOR(version);
+ minor = MK_PLATFORM_MINOR(version);
+ patch = MK_PLATFORM_PATCH(version);
+
+ // eshell to support from the 2.4.0 version.
+ if (major >= 3 || (major >= 2 && minor >=4)) {
+ if(get_screensize(&lines, &columns) == 0) {
+ snprintf(eshell+7, sizeof(eshell)-7, "%d:%d", lines, columns);
+ D("interactive shell : eshell command=%s\n", eshell);
+ fd = sdb_connect(eshell);
+ if(fd < 0) {
+ fprintf(stdout, "failed environment shell, so it will retry shell command.\n");
+ return 1;
+ }
+ }
- sdb_shell_stdin_restore(INPUT_FD);
+ if(check_syncwinsz_support() == 1) {
+ D("Support sync window size with remote\n");
+ enable_sync_winsz = 1;
+ }
} else {
- read_and_dump(fd);
+ fd = sdb_connect("shell:");
+ if(fd < 0) {
+ return 1;
+ }
}
-}
-int is_support_eshell(struct sdb_version *pversion)
-{
- int supported = 0;
+ int* fd_p = malloc(sizeof(int));
+ *fd_p = fd;
+ ishell_fd = fd;
- if (pversion == NULL) {
- return 0;
- }
+#ifdef HAVE_TERMIO_H
+ void** args = (void**)malloc(sizeof(void*)*2);
+ struct termios tio_save;
+ stdin_raw_init(INPUT_FD, &tio_save);
+ struct termios* tio_save_p = (struct termios*)malloc(sizeof(struct termios));
+ memcpy(tio_save_p, &tio_save, sizeof(struct termios));
+ args[1] = tio_save_p;
- /* eshell to support from the 2.4.0 version. */
- if (pversion->major >= 3 || (pversion->major >= 2 && pversion->minor >=4)) {
- /* It must be checked whether it can be obtained window size from the terminal. */
- int lines, columns;
- if(get_screensize(&lines, &columns) == 0) {
- supported = 1;
- }
+ // register SIGWINCH signal handler.
+ struct sigaction sa_winch;
+ sigemptyset(&sa_winch.sa_mask);
+ sa_winch.sa_flags = 0;
+ sa_winch.sa_handler = sig_winch_handler;
+ if (sigaction(SIGWINCH, &sa_winch, NULL) < -1) {
+ D("failed to register the SIGWINCH signal handler.\n");
}
-
- return supported;
+#else
+ void** args = (void**)malloc(sizeof(void*)*3);
+ stdin_raw_init(args);
+#endif
+ args[0] = fd_p;
+ sdb_thread_create(&thr, stdin_read_thread, args);
+ read_and_dump(fd);
+#ifdef HAVE_TERMIO_H
+ stdin_raw_restore(INPUT_FD, &tio_save);
+#else
+ stdin_raw_restore(args);
+#endif
+ return 0;
}
int send_shellcommand(char* buf)