return 0;
}
-#define CAPBUF_SIZE 4096
int get_capability(int argc, char ** argv) {
char full_cmd[16] = {0,};
char cap_buffer[CAPBUF_SIZE] = {0,};
#define PATH_MAX 4096
#endif
+#define CAPBUF_SIZE 4096
+
int da(int argc, char ** argv);
int oprofile(int argc, char ** argv);
int profile(int argc, char ** argv);
static void create_cmd_list(LIST_NODE** cmd_list);
static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
+static int ishell_fd = -1;
+static int enable_sync_winsz = 0;
+static void sync_winsz(void);
+
#ifdef HAVE_TERMIO_H
static __inline__ void stdin_raw_init(int fd, struct termios* tio_save);
return;
}
- if(!SetConsoleMode(input_t_handle, 0)) {
+ if(!SetConsoleMode(input_t_handle, ENABLE_MOUSE_INPUT)) {
fprintf(stdout, "error: fail to set console mode\n");
return;
}
}
buf = NULL;
}
+ } else if(i_record.EventType == MOUSE_EVENT) {
+ if (i_record.Event.MouseEvent.dwEventFlags == 0) {
+ if (enable_sync_winsz == 1) {
+ sync_winsz();
+ }
+ }
}
}
}
return 0;
}
+
+static void sig_winch_handler(int sig) {
+ if (sig != SIGWINCH) {
+ return;
+ }
+
+ if (enable_sync_winsz == 1) {
+ sync_winsz();
+ }
+}
+
#else // for Windows
static int get_screensize(int* lines, int* columns)
{
}
#endif
+static void sync_winsz() {
+ int lines, columns;
+ int fd = -1;
+ int remote_id = -1;
+ char full_cmd[64] = {0,};
+ char *ret_str;
+ struct sockaddr_in addr;
+ int sockaddr_len = sizeof(addr);
+
+ if (get_screensize(&lines, &columns) == 0) {
+ memset(&addr, 0, sizeof(addr));
+ 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), "host:get-remote-id:%d:%d",
+ addr.sin_port, addr.sin_addr.s_addr);
+ ret_str = sdb_query(full_cmd);
+ if(ret_str == NULL) {
+ D("failed to sdb query.\n");
+ return;
+ }
+
+ if (sscanf(ret_str, "remote-id:%d", &remote_id) != 1 || remote_id == -1) {
+ D("failed to get remote-id\n");
+ return;
+ }
+
+ memset(full_cmd, 0, sizeof(full_cmd));
+ snprintf(full_cmd, sizeof(full_cmd), "shellconf:syncwinsz:%d:%d:%d", remote_id, lines, columns);
+ fd = sdb_connect(full_cmd);
+ if(fd < 0) {
+ enable_sync_winsz = 0;
+ D("failed to syncwinsz.\n");
+ return;
+ }
+
+ sdb_close(fd);
+ }
+}
+
+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 = -1;
+
+ if (cap == NULL || key == NULL || value == NULL) {
+ return -1;
+ }
+
+ while ((p_str = strchr(cap+offset, ':')) != NULL) {
+ p_str[0] = 0;
+ k = cap+offset;
+ offset += strlen(cap+offset)+1;
+
+ p_str = strchr(cap+offset, '\n');
+ if (p_str != NULL) {
+ p_str[0] = 0;
+ v = cap+offset;
+ offset += strlen(cap+offset)+1;
+ }
+
+ if (k == NULL || v == NULL) {
+ k = NULL;
+ v = NULL;
+ continue;
+ }
+
+ if (!strcmp(k, key) && !strcmp(v, value)) {
+ matched = 1;
+ break;
+ }
+
+ k = NULL;
+ v = NULL;
+ }
+
+ return matched;
+}
+
+static int check_syncwinsz_support() {
+ char full_cmd[16] = {0,};
+ char cap_buffer[CAPBUF_SIZE] = {0,};
+ uint16_t len = 0;
+ int supported = -1;
+
+ snprintf(full_cmd, sizeof(full_cmd), "capability:");
+ int fd = sdb_connect(full_cmd);
+ if (fd >= 0) {
+ readx(fd, &len, sizeof(uint16_t));
+ if (len > CAPBUF_SIZE-1) {
+ len = CAPBUF_SIZE-1;
+ }
+ readx(fd, cap_buffer, len);
+ sdb_close(fd);
+
+ supported = match_capability_key_value(cap_buffer, "syncwinsz_support", "enabled");
+ }
+ return supported;
+}
+
int interactive_shell()
{
sdb_thread_t thr;
int lines, columns;
int fd = -1;
- if (get_screensize(&lines, &columns) == 0) {
+ 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);
int* fd_p = malloc(sizeof(int));
*fd_p = fd;
+ ishell_fd = fd;
+ if(check_syncwinsz_support() == 1) {
+ D("Support sync window size with remote\n");
+ enable_sync_winsz = 1;
+ }
#ifdef HAVE_TERMIO_H
void** args = (void**)malloc(sizeof(void*)*2);
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;
+
+ // 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");
+ }
#else
void** args = (void**)malloc(sizeof(void*)*3);
stdin_raw_init(args);
sdb_mutex_unlock(&transport_lock, "transport unregister_all_tcp_transports");
}
+static int find_remote_id(int port, int ip)
+{
+ int remote_id = -1;
+ struct sockaddr_in peer_addr;
+ int sockaddr_len = sizeof(peer_addr);
+
+ LIST_NODE* curptr = local_socket_list;
+ while(curptr != NULL) {
+ SDB_SOCKET* s = curptr->data;
+ curptr = curptr->next_ptr;
+
+ memset(&peer_addr, 0, sizeof(peer_addr));
+ if (sdb_getpeername(s->fd, (struct sockaddr *)&peer_addr, &sockaddr_len) < 0) {
+ LOG_ERROR("Failed to get peer name. errno=%d, %s\n", errno, strerror(errno));
+ return -1;
+ }
+
+ if (port == peer_addr.sin_port && ip == peer_addr.sin_addr.s_addr) {
+ LOG_DEBUG("get-remote-id : remote_id=%d\n", s->remote_id);
+ remote_id = s->remote_id;
+ break;
+ }
+ }
+
+ return remote_id;
+}
+
static int handle_host_request(char *service, SDB_SOCKET* socket)
{
LOG_INFO("LS(%X)\n", socket->fd);
return 0;
}
+ // return a remote id
+ if (!strncmp(service, "get-remote-id:", 14)) {
+ int remote_id = -1;
+ int port = -1;
+ int ip = -1;
+
+ if (sscanf(service+14, "%d:%d", &port, &ip) == 2) {
+ remote_id = find_remote_id(port, ip);
+ } else {
+ LOG_ERROR("Invalid argument\n");
+ }
+
+ snprintf(cmd_buf, cbuf_size, "remote-id:%d", remote_id);
+ sendokmsg(socket->fd, cmd_buf);
+ return 0;
+ }
+
// add a new TCP transport, device or emulator
if (!strncmp(service, "connect:", 8)) {
char* host = service + 8;
return utils_backend->disable_tcp_nagle(fd);
}
+int sdb_getsockname(int fd, struct sockaddr *addr, int *sockaddr_len) {
+ return utils_backend->sdb_getsockname(fd, addr, sockaddr_len);
+}
+
+int sdb_getpeername(int fd, struct sockaddr *addr, int *sockaddr_len) {
+ return utils_backend->sdb_getpeername(fd, addr, sockaddr_len);
+}
+
int sdb_thread_create(sdb_thread_t *pthread, sdb_thread_func_t start, void* arg) {
return utils_backend->sdb_thread_create(pthread, start, arg);
}
char* sdb_dirstop(const char* path);
int sdb_socket_setbufsize(int fd, int bufsize);
void disable_tcp_nagle(int fd);
+int sdb_getsockname(int fd, struct sockaddr *addr, int *sockaddr_len);
+int sdb_getpeername(int fd, struct sockaddr *addr, int *sockaddr_len);
// sockets
#define LISTEN_BACKLOG 4
char* (*sdb_dirstop)(const char* path);
int (*sdb_socket_setbufsize)(int fd, int bufsize);
void (*disable_tcp_nagle)(int fd);
+ int (*sdb_getsockname)(int fd, struct sockaddr *addr, int *sockaddr_len);
+ int (*sdb_getpeername)(int fd, struct sockaddr *addr, int *sockaddr_len);
// simple implementation of pthread
int (*sdb_thread_create)(sdb_thread_t *pthread, sdb_thread_func_t start, void* arg);
int (*sdb_mutex_lock)(sdb_mutex_t *mutex);
LOG_ERROR("failed to set the file descriptor '%d': %s\n", fd, strerror(errno));
}
+int _sdb_getsockname(int fd, struct sockaddr *addr, int *sockaddr_len) {
+ return getsockname(fd, addr, sockaddr_len);
+}
+
+int _sdb_getpeername(int fd, struct sockaddr *addr, int *sockaddr_len) {
+ return getpeername(fd, addr, sockaddr_len);
+}
+
static int _sdb_thread_create( sdb_thread_t *pthread, sdb_thread_func_t start, void* arg )
{
pthread_attr_t attr;
.sdb_dirstop = _sdb_dirstop,
.sdb_socket_setbufsize = _sdb_socket_setbufsize,
.disable_tcp_nagle = _disable_tcp_nagle,
+ .sdb_getsockname = _sdb_getsockname,
+ .sdb_getpeername = _sdb_getpeername,
// simple pthread implementations
.sdb_thread_create = _sdb_thread_create,
.sdb_mutex_lock = _sdb_mutex_lock,
return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char*) &opt, sizeof(opt));
}
+int _sdb_getsockname(int fd, struct sockaddr *addr, int *sockaddr_len) {
+ SDB_HANDLE* sdb_handle = sdb_handle_map_get(fd);
+ SOCKET s = sdb_handle->u.socket;
+ return getsockname(s, (SOCKADDR *)addr, sockaddr_len);
+}
+
+int _sdb_getpeername(int fd, struct sockaddr *addr, int *sockaddr_len) {
+ SDB_HANDLE* sdb_handle = sdb_handle_map_get(fd);
+ SOCKET s = sdb_handle->u.socket;
+ return getpeername(s, (SOCKADDR *)addr, sockaddr_len);
+}
+
static char* _sdb_dirstart(const char* path) {
char* p = strchr(path, '/');
char* p2 = strchr(path, '\\');
.sdb_dirstop = _sdb_dirstop,
.sdb_socket_setbufsize = _sdb_socket_setbufsize,
.disable_tcp_nagle = _disable_tcp_nagle,
+ .sdb_getsockname = _sdb_getsockname,
+ .sdb_getpeername = _sdb_getpeername,
// simple pthread implementations
.sdb_thread_create = _sdb_thread_create,
.sdb_mutex_lock = _pthread_mutex_lock,