X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=src%2Fclient.c;h=3cd88068d54aa65f282f9230c936b85681a3282b;hb=e331b7540595fc6e23151f2daec58aeca3fbcd62;hp=5258e39d8163860543b8c1d6a0fef5ae14e48da1;hpb=832a431fea2f4ac3b1c2fb04a61e75f91e8e0259;p=spider.git diff --git a/src/client.c b/src/client.c index 5258e39d..3cd88068 100644 --- a/src/client.c +++ b/src/client.c @@ -46,6 +46,7 @@ #define DEFPACLEN 128 #define MAXPACLEN 236 +#define MAXCALLSIGN 9 #define DBUF 1 #define DMSG 2 @@ -91,22 +92,22 @@ int tabsize = 8; /* default tabsize for text messages */ myregex_t iscallreg[] = { /* regexes to determine whether this is a reasonable callsign */ { - "^[A-Z]+[0-9]+[A-Z]+[1-9]?$", 0 + "^[A-Z]+[0-9]+[A-Z]+[1-9]?$", 0 /* G1TLH G1TLH1 */ }, { - "^[0-9]+[A-Z]+[0-9]+[A-Z]+[1-9]?$", 0 + "^[0-9]+[A-Z]+[0-9]+[A-Z]+[1-9]?$", 0 /* 2E0AAA 2E0AAA1 */ }, { - "^[A-Z]+[0-9]+[A-Z]+[1-9]?-[1-9]$", 0 + "^[A-Z]+[0-9]+[A-Z]+-[1-9]$", 0 /* G1TLH-2 */ }, { - "^[0-9]+[A-Z]+[0-9]+[A-Z]+[1-9]?-[1-9]$", 0 + "^[0-9]+[A-Z]+[0-9]+[A-Z]+-[1-9]$", 0 /* 2E0AAA-2 */ }, { - "^[A-Z]+[0-9]+[A-Z]+[1-9]?-1[0-5]$", 0 + "^[A-Z]+[0-9]+[A-Z]+-1[0-5]$", 0 /* G1TLH-11 */ }, { - "^[0-9]+[A-Z]+[0-9]+[A-Z]+[1-9]?-1[0-5]$", 0 + "^[0-9]+[A-Z]+[0-9]+[A-Z]+-1[0-5]$", 0 /* 2E0AAA-11 */ }, { 0, 0 @@ -168,6 +169,10 @@ int xopen(char *dir, char *name, int mode) int iscallsign(char *s) { myregex_t *rp; + + if (strlen(s) > MAXCALLSIGN) + return 0; + for (rp = iscallreg; rp->in; ++rp) { if (regexec(rp->regex, s, 0, 0, 0) == 0) return 1; @@ -212,6 +217,10 @@ void send_text(fcb_t *f, char *s, int l) f->obuf = mp = cmsg_new(paclen+1, f->sort, f); } + /* remove trailing spaces */ + while (l > 0 &&isspace(s[l-1])) + --l; + for (p = s; p < s+l; ) { if (mp->inp >= mp->data + paclen) { flush_text(f); @@ -223,29 +232,40 @@ void send_text(fcb_t *f, char *s, int l) flush_text(f); f->obuf = mp = cmsg_new(paclen+1, f->sort, f); } - *mp->inp++ = nl; + *mp->inp++ = '\n'; if (!f->buffer_it) flush_text(f); } -void send_msg(fcb_t *f, char let, char *s, int l) +void send_msg(fcb_t *f, char let, unsigned char *s, int l) { cmsg_t *mp; int ln; int myl = strlen(call)+2+l; mp = cmsg_new(myl+4+1, f->sort, f); - ln = htonl(myl); - memcpy(mp->inp, &ln, 4); - mp->inp += 4; *mp->inp++ = let; strcpy(mp->inp, call); mp->inp += strlen(call); *mp->inp++ = '|'; if (l > 0) { - memcpy(mp->inp, s, l); - mp->inp += l; - } + unsigned char *p; + for (p = s; p < s+l; ++p) { + if (mp->inp >= mp->data + (myl - 4)) { + int off = mp->inp - mp->data; + myl += 256; + mp = realloc(mp, myl); + mp->inp = mp->data + off; + } + + if (*p < 0x20 || *p > 0x7e || *p == '%') { + sprintf(mp->inp, "%%%02X", *p & 0xff); + mp->inp += strlen(mp->inp); + } else + *mp->inp++ = *p; + } + } + *mp->inp++ = '\n'; *mp->inp = 0; cmsg_send(f->outq, mp, 0); f->sp->flags |= SEL_OUTPUT; @@ -259,6 +279,7 @@ int fcb_handler(sel_t *sp, int in, int out, int err) { fcb_t *f = sp->fcb; cmsg_t *mp, *omp; + unsigned char c; /* input modes */ if (in) { @@ -274,14 +295,14 @@ int fcb_handler(sel_t *sp, int in, int out, int err) case EAGAIN: goto lout; default: - if (f->sort == MSG) - send_Z = 0; +/* if (f->sort == MSG) + send_Z = 0; */ ending++; return 0; } } else if (r == 0) { - if (f->sort == MSG) - send_Z = 0; +/* if (f->sort == MSG) + send_Z = 0; */ ending++; return 0; } @@ -363,30 +384,60 @@ int fcb_handler(sel_t *sp, int in, int out, int err) case MSG: p = buf; while (r > 0 && p < &buf[r]) { + unsigned char ch = *p++; + + if (mp->inp >= mp->data + (MAXBUFL-1)) { + mp->state = 0; + mp->inp = mp->data; + dbg(DMSG, "Message longer than %d received", MAXBUFL); + } - /* build up the size into the likely message length (yes I know it's a short) */ switch (mp->state) { - case 0: - case 1: - mp->state++; - break; - 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: - if (mp->inp - mp->data < mp->size) { - *mp->inp++ = *p++; - } - if (mp->inp - mp->data >= mp->size) { + case 0: + if (ch == '%') { + c = 0; + mp->state = 1; + } else if (ch == '\n') { /* kick it upstairs */ + *mp->inp = 0; dbgdump(DMSG, "QUEUE MSG", mp->data, mp->inp - mp->data); cmsg_send(f->inq, mp, 0); mp = f->in = cmsg_new(MAXBUFL+1, f->sort, f); + } else if (ch < 0x20 || ch > 0x7e) { + dbg(DMSG, "Illegal character (0x%02X) received", *p); + mp->inp = mp->data; + } else { + *mp->inp++ = ch; } + break; + + case 1: + mp->state = 2; + if (ch >= '0' && ch <= '9') + 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); + mp->inp = mp->data; + mp->state = 0; + } + break; + + case 2: + if (ch >= '0' && ch <= '9') + *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); + mp->inp = mp->data; + } + mp->state = 0; } } break; @@ -422,8 +473,8 @@ lout:; case EAGAIN: goto lend; default: - if (f->sort == MSG) - send_Z = 0; +/* if (f->sort == MSG) + send_Z = 0; */ ending++; return; } @@ -546,6 +597,7 @@ void term_timeout(int i) if (in && in->t_set) tcsetattr(0, TCSANOW, &in->t); if (node) { + shutdown(node->cnum, 3); close(node->cnum); } exit(i); @@ -554,7 +606,7 @@ void term_timeout(int i) void terminate(int i) { if (node && send_Z && call) { - send_msg(node, 'Z', "", 0); + send_msg(node, 'Z', "bye", 3); } signal(SIGALRM, term_timeout); @@ -566,8 +618,10 @@ void terminate(int i) } if (in && in->t_set) tcsetattr(0, TCSADRAIN, &in->t); - if (node) + if (node) { + shutdown(node->cnum, 3); close(node->cnum); + } exit(i); }