X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=src%2Fclient.c;h=5c2dd063f589da5e7a1f51d53259e2c2e564dca4;hb=630127263d91ec7f91ec247a8b8beccebd486475;hp=7864e9d13dc70cfab79b90f3f98e118ea7c7e47d;hpb=1debfcd0628924293008d4c91bc372499d9ece87;p=spider.git diff --git a/src/client.c b/src/client.c index 7864e9d1..5c2dd063 100644 --- a/src/client.c +++ b/src/client.c @@ -16,9 +16,10 @@ * $Id$ */ +#include #include #include -#include +#include #include #include #include @@ -34,6 +35,7 @@ #include "sel.h" #include "cmsg.h" +#include "chain.h" #include "debug.h" #define TEXT 1 @@ -44,7 +46,7 @@ #define MAXPATHLEN 256 #endif -#define DEFPACLEN 128 +#define DEFPACLEN 236 #define MAXPACLEN 236 #define MAXCALLSIGN 9 @@ -95,14 +97,16 @@ 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 */ #define CONNECTED 100 #define WAITLOGIN 1 #define WAITPASSWD 2 #define WAITINPUT 10 - +#define DOCHAT 20 myregex_t iscallreg[] = { /* regexes to determine whether this is a reasonable callsign */ { @@ -112,10 +116,10 @@ myregex_t iscallreg[] = { /* regexes to determine whether this is a reasonable "^[0-9]+[A-Z]+[0-9]+[A-Z]+[1-9]?$", 0 /* 2E0AAA 2E0AAA1 */ }, { - "^[A-Z]+[0-9]+[A-Z]+-[1-9]$", 0 /* G1TLH-2 */ + "^[A-Z]+[0-9]+[A-Z]+-[0-9]$", 0 /* G1TLH-2 */ }, { - "^[0-9]+[A-Z]+[0-9]+[A-Z]+-[1-9]$", 0 /* 2E0AAA-2 */ + "^[0-9]+[A-Z]+[0-9]+[A-Z]+-[0-9]$", 0 /* 2E0AAA-2 */ }, { "^[A-Z]+[0-9]+[A-Z]+-1[0-5]$", 0 /* G1TLH-11 */ @@ -201,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 */ @@ -221,7 +233,24 @@ fcb_t *fcb_new(int cnum, int sort) void flush_text(fcb_t *f) { if (f->obuf) { - cmsg_send(f->outq, f->obuf, 0); + /* save this onto the front of the echo chain */ + cmsg_t *imp = f->obuf; + int size = imp->inp - imp->data; + cmsg_t *emp = cmsg_new(size, imp->sort, imp->portp); + + emp->size = size; + memcpy(emp->data, imp->data, size); + emp->inp = emp->data + size; /* just in case */ + if (echocancel) { + chain_add(&echobase, emp); + if (++echon > maxecho) { + emp = cmsg_prev(&echobase); + cmsg_free(emp); + } + } + + /* queue it for sending */ + cmsg_send(f->outq, imp, 0); f->sp->flags |= SEL_OUTPUT; f->obuf = 0; } @@ -300,6 +329,26 @@ void send_msg(fcb_t *f, char let, UC *s, int l) f->sp->flags |= SEL_OUTPUT; } +/* + * send a file out to the user + */ +void send_file(char *name) +{ + int i; + char buf[MAXPACLEN+1]; + + FILE *f = xopen("data", name, "r"); + if (f) { + while (fgets(buf, paclen, f)) { + i = strlen(buf); + if (i && buf[i-1] == '\n') + buf[--i] = 0; + send_text(in, buf, i, 1); + } + fclose(f); + } +} + /* * the callback (called by sel_run) that handles all the inputs and outputs */ @@ -387,6 +436,8 @@ int fcb_handler(sel_t *sp, int in, int out, int err) default: if (nl == '\n' && *p == '\r') { /* ignore \r in telnet mode (ugh) */ p++; + } else if (nl == '\r' && *p == '\n') { /* and ignore \n in ax25 mode (double ugh) */ + p++; } else if (*p == nl) { if (mp->inp == mp->data) *mp->inp++ = ' '; @@ -450,10 +501,8 @@ int fcb_handler(sel_t *sp, int in, int out, int err) c = (ch - '0') << 4; else if (ch >= 'A' && ch <= 'F') c = (ch - 'A' + 10) << 4; - else if (ch >= 'a' && ch <= 'a') - c = (ch - 'a' + 10) << 4; else { - dbg(DMSG, "Illegal hex char (%c) received in state %d", ch, mp->state); + dbg(DMSG, "Illegal hex char (%c) received in state 1", ch); mp->inp = mp->data; mp->state = 0; } @@ -464,10 +513,8 @@ int fcb_handler(sel_t *sp, int in, int out, int err) *mp->inp++ = c | (ch - '0'); else if (ch >= 'A' && ch <= 'F') *mp->inp++ = c | (ch - 'A' + 10); - else if (ch >= 'a' && ch <= 'a') - *mp->inp++ = c | (ch - 'a' + 10); else { - dbg(DMSG, "Illegal hex char (%c) received in state %d", ch, mp->state); + dbg(DMSG, "Illegal hex char (%c) received in state 2", ch); mp->inp = mp->data; } mp->state = 0; @@ -527,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")) { @@ -554,12 +601,22 @@ void setmode(char *m) void process_stdin() { - cmsg_t *mp = cmsg_next(in->inq); + cmsg_t *wmp, *mp = cmsg_next(in->inq); char *p, hasa, hasn, i; char callsign[MAXCALLSIGN+1]; if (mp) { dbg(DMSG, "MSG size: %d", mp->size); + + /* check for echos */ + if (echocancel) { + for (wmp = 0; wmp = chain_get_next(&echobase, wmp); ) { + if (!memcmp(wmp->data, mp->data, wmp->size)) { + cmsg_callback(mp, 0); + return; + } + } + } switch (state) { case CONNECTED: @@ -595,6 +652,11 @@ void process_stdin() if (!iscallsign(call)) { die("Sorry, %s isn't a valid callsign", call); } + + /* strip off a '-0' at the end */ + i = strlen(call); + if (call[i-1] == '0' && call[i-2] == '-') + call[i-2] = 0; alarm(0); signal(SIGALRM, SIG_IGN); @@ -603,6 +665,12 @@ void process_stdin() send_msg(node, 'A', connsort, strlen(connsort)); chgstate(CONNECTED); + send_file("connected"); + break; + + case DOCHAT: + + break; } cmsg_callback(mp, 0); @@ -700,8 +768,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; @@ -727,7 +798,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) { @@ -738,9 +809,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! */ @@ -830,6 +901,9 @@ 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); @@ -854,34 +928,29 @@ main(int argc, char *argv[]) /* is this a login? */ if (eq(call, "LOGIN") || eq(call, "login")) { - - char buf[MAXPACLEN+1]; - int r, i; - FILE *f = xopen("data", "issue", "r"); - if (f) { - while (fgets(buf, paclen, f)) { - i = strlen(buf); - if (i && buf[i-1] == '\n') - buf[--i] = 0; - send_text(in, buf, i, 1); - } - fclose(f); - } + send_file("issue"); signal(SIGALRM, login_timeout); alarm(timeout); send_text(in, "login: ", 7, 0); chgstate(WAITLOGIN); } else { - + int i; + /* check the callsign against the regexes */ if (!iscallsign(call)) { die("Sorry, %s isn't a valid callsign", call); } + /* strip off a '-0' at the end */ + i = strlen(call); + if (call[i-1] == '0' && call[i-2] == '-') + call[i-2] = 0; + /* tell the cluster who I am */ send_msg(node, 'A', connsort, strlen(connsort)); chgstate(CONNECTED); + send_file("connected"); }