X-Git-Url: http://dxcluster.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=src%2Fclient.c;h=5ff3401097726493f6a0c7b0533a0698139e336e;hb=refs%2Fheads%2Fip_address;hp=8df624494b3c7879cc60480458ff860369d4fe92;hpb=c20a2c1e01d707d6c3fa25067df93d491aba8fff;p=spider.git diff --git a/src/client.c b/src/client.c index 8df62449..5ff34010 100644 --- a/src/client.c +++ b/src/client.c @@ -16,9 +16,10 @@ * $Id$ */ +#include #include #include -#include +#include #include #include #include @@ -96,6 +97,7 @@ int tabsize = 8; /* default tabsize for text messages */ char *connsort = "local"; /* the connection variety */ int state = 0; /* the current state of the connection */ int laststate = 0; /* the last state we were in */ +char echocancel = 1; /* echo cancelling */ reft echobase; /* the anti echo queue */ int maxecho = 5; /* the depth of the anti echo queue */ int echon; /* no of entries in the anti echo queue */ @@ -104,7 +106,7 @@ int echon; /* no of entries in the anti echo queue */ #define WAITLOGIN 1 #define WAITPASSWD 2 #define WAITINPUT 10 - +#define DOCHAT 20 myregex_t iscallreg[] = { /* regexes to determine whether this is a reasonable callsign */ { @@ -203,6 +205,14 @@ int iscallsign(char *s) return 0; } +void reaper(int i) +{ + pid_t mypid; + while ((mypid = waitpid(-1, 0, WNOHANG)) > 0) { + ; + } +} + /* * higher level send and receive routines */ @@ -231,10 +241,12 @@ void flush_text(fcb_t *f) emp->size = size; memcpy(emp->data, imp->data, size); emp->inp = emp->data + size; /* just in case */ - chain_add(&echobase, emp); - if (++echon > maxecho) { - emp = cmsg_prev(&echobase); - cmsg_free(emp); + if (echocancel) { + chain_add(&echobase, emp); + if (++echon > maxecho) { + emp = cmsg_prev(&echobase); + cmsg_free(emp); + } } /* queue it for sending */ @@ -363,12 +375,12 @@ int fcb_handler(sel_t *sp, int in, int out, int err) default: dbg(DBUF,"got errno %d in input", errno); ending++; - return 0; + return 1; } } else if (r == 0) { dbg(DBUF, "ending normally"); ending++; - return 0; + return 1; } dbgdump(DBUF, "in ->", buf, r); @@ -562,7 +574,7 @@ lend:; /* * set up the various mode flags, NL endings and things */ -void setmode(char *m) +void setconntype(char *m) { connsort = strlower(m); if (eq(connsort, "telnet") || eq(connsort, "local") || eq(connsort, "nlonly")) { @@ -597,10 +609,12 @@ void process_stdin() dbg(DMSG, "MSG size: %d", mp->size); /* check for echos */ - for (wmp = 0; wmp = chain_get_next(&echobase, wmp); ) { - if (!memcmp(wmp->data, mp->data, wmp->size)) { - cmsg_callback(mp, 0); - return; + if (echocancel) { + for (wmp = 0; wmp = chain_get_next(&echobase, wmp); ) { + if (!memcmp(wmp->data, mp->data, wmp->size)) { + cmsg_callback(mp, 0); + return; + } } } @@ -652,6 +666,11 @@ void process_stdin() chgstate(CONNECTED); send_file("connected"); + break; + + case DOCHAT: + + break; } cmsg_callback(mp, 0); @@ -704,13 +723,9 @@ void process_node() void term_timeout(int i) { /* none of this is going to be reused so don't bother cleaning up properly */ - if (in && in->t_set) - tcsetattr(0, TCSANOW, &in->t); - if (node) { - shutdown(node->cnum, 3); - close(node->cnum); - } - exit(i); + if (isatty(0)) + tcflush(0, TCIOFLUSH); + kill(getpid(), 9); /* commit suicide */ } void terminate(int i) @@ -718,16 +733,22 @@ void terminate(int i) signal(SIGALRM, term_timeout); alarm(10); - while ((in && !is_chain_empty(in->outq)) || - (node && !is_chain_empty(node->outq))) { + if (node && node->sp->sort) { + sel_close(node->sp); + } + while (in && in->sp->sort && !is_chain_empty(in->outq)) { sel_run(); } + sel_run(); + sel_run(); + sel_run(); + sel_run(); + sel_run(); + sel_run(); + sel_run(); + sel_run(); if (in && in->t_set) tcsetattr(0, TCSADRAIN, &in->t); - if (node) { - shutdown(node->cnum, 3); - close(node->cnum); - } exit(i); } @@ -735,10 +756,7 @@ void login_timeout(int i) { write(0, "Timed Out", 10); write(0, &nl, 1); - sel_run(); /* force a coordination */ - if (in && in->t_set) - tcsetattr(0, TCSANOW, &in->t); - exit(i); + terminate(0); } /* @@ -749,8 +767,11 @@ void initargs(int argc, char *argv[]) { int i, c, err = 0; - while ((c = getopt(argc, argv, "h:p:x:")) > 0) { + while ((c = getopt(argc, argv, "eh:l:p:x:")) > 0) { switch (c) { + case 'e': + echocancel ^= 1; + break; case 'h': node_addr = optarg; break; @@ -776,7 +797,7 @@ void initargs(int argc, char *argv[]) lerr: if (err) { - die("usage: client [-x n|-h|-p|-l] |login [local|telnet|ax25]"); + die("usage: client [-e|-x n|-h|-p|-l] |login [local|telnet|ax25]"); } if (optind < argc) { @@ -787,9 +808,9 @@ lerr: die("Must have at least a callsign (for now)"); if (optind < argc) { - setmode(argv[optind]); + setconntype(argv[optind]); } else { - setmode("local"); + setconntype("local"); } /* this is kludgy, but hey so is the rest of this! */ @@ -803,8 +824,10 @@ void connect_to_node() struct hostent *hp, *gethostbyname(); struct sockaddr_in server; int nodef; + int one = 1; sel_t *sp; - + struct linger lg; + if ((hp = gethostbyname(node_addr)) == 0) die("Unknown host tcp host %s for printer", node_addr); @@ -820,6 +843,15 @@ void connect_to_node() if (connect(nodef, (struct sockaddr *) &server, sizeof server) < 0) { die("Error on connect to %s port %d (%d)", node_addr, node_port, errno); } + + memset(&lg, 0, sizeof lg); + if (setsockopt(nodef, SOL_SOCKET, SO_LINGER, &lg, sizeof lg) < 0) { + die("Error on SO_LINGER to %s port %d (%d)", node_addr, node_port, errno); + } + if (setsockopt(nodef, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one) < 0) { + die("Error on SO_KEEPALIVE to %s port %d (%d)", node_addr, node_port, errno); + } + node = fcb_new(nodef, MSG); node->sp = sel_open(nodef, node, "Msg System", fcb_handler, MSG, SEL_INPUT); @@ -879,14 +911,14 @@ main(int argc, char *argv[]) #ifdef SIGPWR signal(SIGPWR, terminate); #endif + /* init a few things */ chain_init(&echobase); /* connect up stdin */ in = fcb_new(0, TEXT); in->sp = sel_open(0, in, "STDIN", fcb_handler, TEXT, SEL_INPUT); - if (tcgetattr(0, &in->t) < 0) { -/* echo = 0; */ + if (!isatty(0) || tcgetattr(0, &in->t) < 0) { in->echo = echo; in->t_set = 0; } else {