summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--amtterm.c28
-rw-r--r--gamt.c103
-rw-r--r--redir.c69
-rw-r--r--redir.h17
5 files changed, 176 insertions, 43 deletions
diff --git a/GNUmakefile b/GNUmakefile
index aec0067..cd65580 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -52,7 +52,7 @@ distclean: clean
#################################################################
amtterm: amtterm.o redir.o tcp.o
-gamt: gamt.o
+gamt: gamt.o redir.o tcp.o
#################################################################
diff --git a/amtterm.c b/amtterm.c
index f49cd33..e78a5bd 100644
--- a/amtterm.c
+++ b/amtterm.c
@@ -8,7 +8,6 @@
#include <signal.h>
#include <sys/ioctl.h>
-#include "tcp.h"
#include "redir.h"
#define APPNAME "amtterm"
@@ -30,10 +29,11 @@ static void state_tty(void *cb_data, enum redir_state old, enum redir_state new)
if (!r->verbose)
return;
- fprintf(stderr, APPNAME " state: %s -> %s\n",
- redir_strstate(old), redir_strstate(new));
+ fprintf(stderr, APPNAME ": %s -> %s (%s)\n",
+ redir_state_name(old), redir_state_name(new),
+ redir_state_desc(new));
switch (new) {
- case REDIR_CONN_SOL:
+ case REDIR_RUN_SOL:
fprintf(stderr, "serial-over-lan redirection ok\n");
fprintf(stderr, "connected now, use ^] to escape\n");
break;
@@ -55,7 +55,7 @@ static int redir_loop(struct redir *r)
break;
FD_ZERO(&set);
- if (r->state == REDIR_CONN_SOL)
+ if (r->state == REDIR_RUN_SOL)
FD_SET(0,&set);
FD_SET(r->sock,&set);
tv.tv_sec = HEARTBEAT_INTERVAL * 4 / 1000;
@@ -164,10 +164,7 @@ static void usage(FILE *fp)
int main(int argc, char *argv[])
{
- struct addrinfo ai;
struct redir r;
- char *port = "16994";
- char *host = NULL;
char *h;
int c;
@@ -211,10 +208,10 @@ int main(int argc, char *argv[])
}
if (optind < argc)
- host = argv[optind];
+ snprintf(r.host, sizeof(r.host), "%s", argv[optind]);
if (optind+1 < argc)
- port = argv[optind+1];
- if (NULL == host) {
+ snprintf(r.port, sizeof(r.port), "%s", argv[optind+1]);
+ if (0 == strlen(r.host)) {
usage(stderr);
exit(1);
}
@@ -222,7 +219,7 @@ int main(int argc, char *argv[])
tty_save();
if (0 == strlen(r.pass)) {
tty_noecho();
- fprintf(stderr, "AMT password for host %s: ", host);
+ fprintf(stderr, "AMT password for host %s: ", r.host);
fgets(r.pass, sizeof(r.pass), stdin);
fprintf(stderr, "\n");
if (NULL != (h = strchr(r.pass, '\r')))
@@ -231,12 +228,7 @@ int main(int argc, char *argv[])
*h = 0;
}
- memset(&ai, 0, sizeof(ai));
- ai.ai_socktype = SOCK_STREAM;
- ai.ai_family = PF_UNSPEC;
- tcp_verbose = r.verbose;
- r.sock = tcp_connect(&ai, NULL, NULL, host, port);
- if (-1 == r.sock) {
+ if (-1 == redir_connect(&r)) {
tty_restore();
exit(1);
}
diff --git a/gamt.c b/gamt.c
index 28e8d52..0fd32c6 100644
--- a/gamt.c
+++ b/gamt.c
@@ -10,6 +10,8 @@
#include <gtk/gtk.h>
#include <vte/vte.h>
+#include "redir.h"
+
struct gamt_window {
/* gtk stuff */
GtkActionGroup *ag;
@@ -17,6 +19,11 @@ struct gamt_window {
GtkWidget *win;
GtkWidget *vte;
GtkWidget *status;
+
+ /* sol stuff */
+ struct redir redir;
+ GIOChannel *ch;
+ guint id;
};
/* ------------------------------------------------------------------ */
@@ -38,6 +45,41 @@ static void destroy_cb(GtkWidget *widget, gpointer data)
/* ------------------------------------------------------------------ */
+static int recv_gtk(void *cb_data, unsigned char *buf, int len)
+{
+ struct gamt_window *gamt = cb_data;
+ vte_terminal_feed(VTE_TERMINAL(gamt->vte), buf, len);
+ return 0;
+}
+
+static void state_gtk(void *cb_data, enum redir_state old, enum redir_state new)
+{
+ struct gamt_window *gamt = cb_data;
+ unsigned char buf[128];
+
+ switch (new) {
+ case REDIR_ERROR:
+ snprintf(buf, sizeof(buf), "%s: %s FAILED", gamt->redir.host,
+ redir_state_desc(old));
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "%s: %s", gamt->redir.host,
+ redir_state_desc(new));
+ break;
+ }
+ gtk_label_set_text(GTK_LABEL(gamt->status), buf);
+}
+
+static void user_input(VteTerminal *vte, gchar *buf, guint len,
+ gpointer data)
+{
+ struct gamt_window *gamt = data;
+
+ redir_sol_send(&gamt->redir, buf, len);
+}
+
+/* ------------------------------------------------------------------ */
+
static const GtkActionEntry entries[] = {
{
.name = "FileMenu",
@@ -66,6 +108,51 @@ static char ui_xml[] =
/* ------------------------------------------------------------------ */
+static gboolean gamt_data(GIOChannel *source, GIOCondition condition,
+ gpointer data)
+{
+ struct gamt_window *gamt = data;
+
+ redir_data(&gamt->redir);
+
+ if (gamt->redir.state == REDIR_CLOSED ||
+ gamt->redir.state == REDIR_ERROR) {
+ g_source_destroy(g_main_context_find_source_by_id
+ (g_main_context_default(), gamt->id));
+ gamt->id = 0;
+ gamt->ch = NULL;
+ }
+ return TRUE;
+}
+
+static int gamt_connect(struct gamt_window *gamt, char *host, char *port)
+{
+ char *h;
+
+ memset(&gamt->redir, 0, sizeof(gamt->redir));
+ memcpy(&gamt->redir.type, "SOL ", 4);
+ strcpy(gamt->redir.user, "admin");
+ if (NULL != (h = getenv("AMT_PASSWORD")))
+ snprintf(gamt->redir.pass, sizeof(gamt->redir.pass), "%s", h);
+
+ snprintf(gamt->redir.host, sizeof(gamt->redir.host), "%s", host);
+ if (port)
+ snprintf(gamt->redir.port, sizeof(gamt->redir.port), "%s", port);
+
+ gamt->redir.verbose = 1;
+ gamt->redir.cb_data = gamt;
+ gamt->redir.cb_recv = recv_gtk;
+ gamt->redir.cb_state = state_gtk;
+
+ if (-1 == redir_connect(&gamt->redir))
+ return -1;
+
+ gamt->ch = g_io_channel_unix_new(gamt->redir.sock);
+ gamt->id = g_io_add_watch(gamt->ch, G_IO_IN, gamt_data, gamt);
+ redir_start(&gamt->redir);
+ return 0;
+}
+
static struct gamt_window *gamt_window()
{
GtkWidget *vbox, *frame, *item;
@@ -100,9 +187,11 @@ static struct gamt_window *gamt_window()
/* vte terminal */
gamt->vte = vte_terminal_new();
+ g_signal_connect(gamt->vte, "commit", G_CALLBACK(user_input), gamt);
+
/* other widgets */
- gamt->status = gtk_label_new("status line");
+ gamt->status = gtk_label_new("idle");
gtk_misc_set_alignment(GTK_MISC(gamt->status), 0, 0.5);
gtk_misc_set_padding(GTK_MISC(gamt->status), 3, 1);
@@ -141,6 +230,7 @@ static void usage(FILE *fp)
int
main(int argc, char *argv[])
{
+ struct gamt_window *gamt;
int debug = 0;
int c;
@@ -161,15 +251,12 @@ main(int argc, char *argv[])
}
}
-#if 0
- if (optind+1 > argc) {
- usage(stderr);
+ gamt = gamt_window();
+ if (NULL == gamt)
exit(1);
- }
-#endif
- if (NULL == gamt_window())
- exit(1);
+ if (optind+1 <= argc)
+ gamt_connect(gamt, argv[optind], NULL);
gtk_main();
exit(0);
diff --git a/redir.c b/redir.c
index 16250fe..1ea46ee 100644
--- a/redir.c
+++ b/redir.c
@@ -3,21 +3,37 @@
#include <unistd.h>
#include <string.h>
+#include "tcp.h"
#include "redir.h"
-static const char *state_names[] = {
+static const char *state_name[] = {
[ REDIR_NONE ] = "NONE",
+ [ REDIR_CONNECT ] = "CONNECT",
[ REDIR_INIT ] = "INIT",
[ REDIR_AUTH ] = "AUTH",
[ REDIR_INIT_SOL ] = "INIT_SOL",
- [ REDIR_CONN_SOL ] = "CONN_SOL",
+ [ REDIR_RUN_SOL ] = "RUN_SOL",
[ REDIR_INIT_IDER ] = "INIT_IDER",
- [ REDIR_CONN_IDER ] = "CONN_IDER",
+ [ REDIR_RUN_IDER ] = "RUN_IDER",
[ REDIR_CLOSING ] = "CLOSING",
[ REDIR_CLOSED ] = "CLOSED",
[ REDIR_ERROR ] = "ERROR",
};
+static const char *state_desc[] = {
+ [ REDIR_NONE ] = "disconnected",
+ [ REDIR_CONNECT ] = "connection to host",
+ [ REDIR_INIT ] = "redirection initialization",
+ [ REDIR_AUTH ] = "session authentication",
+ [ REDIR_INIT_SOL ] = "serial-over-lan initialization",
+ [ REDIR_RUN_SOL ] = "serial-over-lan active",
+ [ REDIR_INIT_IDER ] = "IDE redirect initialization",
+ [ REDIR_RUN_IDER ] = "IDE redirect active",
+ [ REDIR_CLOSING ] = "redirection shutdown",
+ [ REDIR_CLOSED ] = "connection closed",
+ [ REDIR_ERROR ] = "failure",
+};
+
/* ------------------------------------------------------------------ */
static void redir_state(struct redir *r, enum redir_state new)
@@ -31,17 +47,47 @@ static void redir_state(struct redir *r, enum redir_state new)
/* ------------------------------------------------------------------ */
-const char *redir_strstate(enum redir_state state)
+const char *redir_state_name(enum redir_state state)
{
const char *name = NULL;
- if (state < sizeof(state_names)/sizeof(state_names[0]))
- name = state_names[state];
+ if (state < sizeof(state_name)/sizeof(state_name[0]))
+ name = state_name[state];
if (NULL == name)
name = "unknown";
return name;
}
+const char *redir_state_desc(enum redir_state state)
+{
+ const char *desc = NULL;
+
+ if (state < sizeof(state_desc)/sizeof(state_desc[0]))
+ desc = state_desc[state];
+ if (NULL == desc)
+ desc = "unknown";
+ return desc;
+}
+
+int redir_connect(struct redir *r)
+{
+ static unsigned char *defport = "16994";
+ struct addrinfo ai;
+
+ memset(&ai, 0, sizeof(ai));
+ ai.ai_socktype = SOCK_STREAM;
+ ai.ai_family = PF_UNSPEC;
+ tcp_verbose = r->verbose;
+ redir_state(r, REDIR_CONNECT);
+ r->sock = tcp_connect(&ai, NULL, NULL, r->host,
+ strlen(r->port) ? r->port : defport);
+ if (-1 == r->sock) {
+ redir_state(r, REDIR_ERROR);
+ return -1;
+ }
+ return 0;
+}
+
int redir_start(struct redir *r)
{
unsigned char request[START_REDIRECTION_SESSION_LENGTH] = {
@@ -60,7 +106,9 @@ int redir_stop(struct redir *r)
};
redir_state(r, REDIR_CLOSED);
- return write(r->sock, request, sizeof(request));
+ write(r->sock, request, sizeof(request));
+ close(r->sock);
+ return 0;
}
int redir_auth(struct redir *r)
@@ -172,8 +220,9 @@ int redir_data(struct redir *r)
int rc;
rc = read(r->sock, request, sizeof(request));
- if (rc < 4)
+ if (rc != 4)
goto err;
+
switch (request[0]) {
case START_REDIRECTION_SESSION_REPLY:
if (rc != START_REDIRECTION_SESSION_REPLY_LENGTH) {
@@ -197,13 +246,13 @@ int redir_data(struct redir *r)
fprintf(stderr, "serial-over-lan redirection failed\n");
goto err;
}
- redir_state(r, REDIR_CONN_SOL);
+ redir_state(r, REDIR_RUN_SOL);
return 0;
case SOL_HEARTBEAT:
case SOL_KEEP_ALIVE_PING:
case IDER_HEARTBEAT:
case IDER_KEEP_ALIVE_PING:
- if (rc != HEARTBEAT_LENGTH) {
+ if (rc < HEARTBEAT_LENGTH) {
fprintf(stderr,"HEARTBEAT: got %d, expected %d bytes\n",
rc, HEARTBEAT_LENGTH);
goto err;
diff --git a/redir.h b/redir.h
index fe785b8..c57c1ea 100644
--- a/redir.h
+++ b/redir.h
@@ -2,20 +2,23 @@
enum redir_state {
REDIR_NONE = 0,
- REDIR_INIT = 1,
- REDIR_AUTH = 2,
+ REDIR_CONNECT = 1,
+ REDIR_INIT = 2,
+ REDIR_AUTH = 3,
REDIR_INIT_SOL = 10,
- REDIR_CONN_SOL = 11,
+ REDIR_RUN_SOL = 11,
REDIR_INIT_IDER = 20,
- REDIR_CONN_IDER = 21,
+ REDIR_RUN_IDER = 21,
REDIR_CLOSING = 30,
REDIR_CLOSED = 31,
- REDIR_ERROR = 99,
+ REDIR_ERROR = 40,
};
struct redir {
int sock;
int verbose;
+ unsigned char host[64];
+ unsigned char port[16];
unsigned char type[4];
unsigned char user[16];
unsigned char pass[16];
@@ -27,8 +30,10 @@ struct redir {
int (*cb_recv)(void *cb_data, unsigned char *buf, int len);
};
-const char *redir_strstate(enum redir_state state);
+const char *redir_state_name(enum redir_state state);
+const char *redir_state_desc(enum redir_state state);
+int redir_connect(struct redir *r);
int redir_start(struct redir *r);
int redir_stop(struct redir *r);
int redir_auth(struct redir *r);