X-Git-Url: http://dxcluster.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=src%2Fclient.c;h=edd2a0ff1a7cee651d695d4f13df517751c2911b;hb=652f5fb4391306230ef158211dafd4662ff3f85e;hp=3dadfc59785c3dcab353538d14e7aa4e04c85384;hpb=3b52d4a1eb273c6e6eff14223baf69c0a309899c;p=spider.git diff --git a/src/client.c b/src/client.c index 3dadfc59..edd2a0ff 100644 --- a/src/client.c +++ b/src/client.c @@ -51,8 +51,9 @@ typedef struct 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 */ @@ -145,7 +146,7 @@ void send_msg(fcb_t *f, char let, char *s, int l) 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; @@ -153,7 +154,7 @@ void send_msg(fcb_t *f, char let, char *s, int l) strcpy(mp->inp, call); mp->inp += strlen(call); *mp->inp++ = '|'; - if (l) { + if (l > 0) { memcpy(mp->inp, s, l); mp->inp += l; } @@ -162,6 +163,10 @@ void send_msg(fcb_t *f, char let, char *s, int 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; @@ -197,14 +202,14 @@ int fcb_handler(sel_t *sp, int in, int out, int err) /* 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 */ @@ -229,13 +234,15 @@ int fcb_handler(sel_t *sp, int in, int out, int err) ++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]) @@ -269,6 +276,8 @@ int fcb_handler(sel_t *sp, int in, int out, int err) 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: @@ -279,7 +288,7 @@ int fcb_handler(sel_t *sp, int in, int out, int err) /* 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); } } } @@ -329,8 +338,6 @@ lout:; 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:; @@ -345,8 +352,14 @@ void initargs(int argc, char *argv[]) { 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)); @@ -359,7 +372,7 @@ void initargs(int argc, char *argv[]) lerr: if (err) { - die("usage: client [-x nn] |login [local|telnet|ax25]"); + die("usage: client [-x n|-h|-p] |login [local|telnet|ax25]"); } if (optind < argc) { @@ -423,7 +436,7 @@ void connect_to_node() 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); @@ -444,7 +457,7 @@ void terminate(int i) (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); @@ -491,7 +504,7 @@ void process_node() if (p) { int l = mp->inp - (unsigned char *) p; send_text(in, p, l); - } + } break; default: break; @@ -515,19 +528,23 @@ main(int argc, char *argv[]) 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();