reft *inq; /* input queue */
reft *outq; /* output queue */
sel_t *sp; /* my select fcb address */
- int echo; /* echo characters back to this cnum */
struct termios t; /* any termios associated with this cnum */
+ char echo; /* echo characters back to this cnum */
+ char t_set; /* the termios structure is valid */
} fcb_t;
char *node_addr = "localhost"; /* the node tcp address */
int ln;
int myl = strlen(call)+2+l;
- mp = cmsg_new(myl+4, f->sort, f);
+ mp = cmsg_new(myl+4+1, f->sort, f);
ln = htonl(myl);
memcpy(mp->inp, &ln, 4);
mp->inp += 4;
strcpy(mp->inp, call);
mp->inp += strlen(call);
*mp->inp++ = '|';
- if (l) {
+ if (l > 0) {
memcpy(mp->inp, s, l);
mp->inp += l;
}
f->sp->flags |= SEL_OUTPUT;
}
+/*
+ * the callback (called by sel_run) that handles all the inputs and outputs
+ */
+
int fcb_handler(sel_t *sp, int in, int out, int err)
{
fcb_t *f = sp->fcb;
/* create a new message buffer if required */
if (!f->in)
- f->in = cmsg_new(MAXBUFL, f->sort, f);
+ f->in = cmsg_new(MAXBUFL+1, f->sort, f);
mp = f->in;
switch (f->sort) {
case TEXT:
p = buf;
if (f->echo)
- omp = cmsg_new(3*r, f->sort, f);
+ omp = cmsg_new(3*r+1, f->sort, f);
while (r > 0 && p < &buf[r]) {
/* echo processing */
++p;
break;
default:
- if (*p == nl) {
+ if (nl == '\n' && *p == '\r') { /* ignore \r in telnet mode (ugh) */
+ p++;
+ } else if (*p == nl) {
if (mp->inp == mp->data)
*mp->inp++ = ' ';
*mp->inp = 0; /* zero terminate it, but don't include it in the length */
dbgdump(DMSG, "QUEUE TEXT", mp->data, mp->inp-mp->data);
cmsg_send(f->inq, mp, 0);
- f->in = mp = cmsg_new(MAXBUFL, f->sort, f);
+ f->in = mp = cmsg_new(MAXBUFL+1, f->sort, f);
++p;
} else {
if (mp->inp < &mp->data[MAXBUFL])
case 2:
case 3:
mp->size = (mp->size << 8) | (*p++ & 0xff);
+ if (mp->size > MAXBUFL)
+ die("Message size too big from node (%d > %d)", mp->size, MAXBUFL);
mp->state++;
break;
default:
/* kick it upstairs */
dbgdump(DMSG, "QUEUE MSG", mp->data, mp->inp - mp->data);
cmsg_send(f->inq, mp, 0);
- mp = f->in = cmsg_new(MAXBUFL, f->sort, f);
+ mp = f->in = cmsg_new(MAXBUFL+1, f->sort, f);
}
}
}
if (mp->inp - mp->data >= mp->size) {
cmsg_callback(mp, 0);
f->out = 0;
-/* if (is_chain_empty(f->outq))
- sp->flags &= ~SEL_OUTPUT; */
}
}
lend:;
{
int i, c, err = 0;
- while ((c = getopt(argc, argv, "x:")) > 0) {
+ while ((c = getopt(argc, argv, "h:p:x:")) > 0) {
switch (c) {
+ case 'h':
+ node_addr = optarg;
+ break;
+ case 'p':
+ node_port = atoi(optarg);
+ break;
case 'x':
dbginit("client");
dbgset(atoi(optarg));
lerr:
if (err) {
- die("usage: client [-x nn] <call>|login [local|telnet|ax25]");
+ die("usage: client [-x n|-h<host>|-p<port>] <call>|login [local|telnet|ax25]");
}
if (optind < argc) {
void term_timeout(int i)
{
/* none of this is going to be reused so don't bother cleaning up properly */
- if (in)
+ if (in && in->t_set)
tcsetattr(0, TCSANOW, &in->t);
if (node) {
close(node->cnum);
(node && !is_chain_empty(node->outq))) {
sel_run();
}
- if (in)
+ if (in && in->t_set)
tcsetattr(0, TCSANOW, &in->t);
if (node)
close(node->cnum);
if (p) {
int l = mp->inp - (unsigned char *) p;
send_text(in, p, l);
- }
+ }
break;
default:
break;
signal(SIGINT, terminate);
signal(SIGQUIT, terminate);
signal(SIGTERM, terminate);
+#ifdef SIGPWR
signal(SIGPWR, terminate);
+#endif
/* connect up stdin, stdout and message system */
in = fcb_new(0, TEXT);
in->sp = sel_open(0, in, "STDIN", fcb_handler, TEXT, SEL_INPUT);
- if (tcgetattr(0, &in->t) < 0)
- die("tcgetattr (%d)", errno);
- {
+ if (tcgetattr(0, &in->t) < 0) {
+ echo = 0;
+ in->t_set = 0;
+ } else {
struct termios t = in->t;
t.c_lflag &= ~(ECHO|ECHONL|ICANON);
if (tcsetattr(0, TCSANOW, &t) < 0)
die("tcsetattr (%d)", errno);
in->echo = echo;
+ in->t_set = 1;
}
connect_to_node();