/***************************************************************************** * * $Id$ * Purpose ...............: Fidonet mailer - modem chat * ***************************************************************************** * Copyright (C) 1997-2002 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * MBSE BBS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ #include "../config.h" #include "../lib/libs.h" #include "../lib/memwatch.h" #include "../lib/structs.h" #include "../lib/users.h" #include "../lib/records.h" #include "../lib/common.h" #include "../lib/clcomm.h" #include "config.h" #include "chat.h" #include "ttyio.h" char *tranphone(char *Phone) { static char trp[21]; char buf[21]; char *p; int ln, i, j; if (Phone == NULL) return NULL; strncpy(trp,Phone,sizeof(trp)-1); for (i = 0; i < 40; i++) if (strlen(CFG.phonetrans[i].match) || strlen(CFG.phonetrans[i].repl)) { memset(&buf, 0, sizeof(buf)); strncpy(buf,CFG.phonetrans[i].match,strlen(CFG.phonetrans[i].match)); ln=strlen(buf); p = xstrcpy(CFG.phonetrans[i].repl); if (strncmp(Phone,buf,ln) == 0) { strcpy(trp,p); strncat(trp,Phone+ln,sizeof(trp)-strlen(p)-1); free(p); break; } else { free(p); } } if (modem.stripdash) { j = 0; for (i = 0; i < strlen(trp); i++) { if (trp[i] != '-') { trp[j] = trp[i]; j++; } } trp[j] = '\0'; } return trp; } int send_str(char *, char *); int send_str(char *str, char *Phone) { char *p, *q; static char logs[81]; p = str; memset(&logs, 0, sizeof(logs)); q = logs; while (*p) { if (*p == '\\') { switch (*++p) { case '\0': p--; break; case '\\': PUTCHAR('\\'); *q++ = '\\'; break; case 'r': PUTCHAR('\r'); *q++ = '\\'; *q++ = 'r'; break; case 'n': PUTCHAR('\n'); *q++ = '\\'; *q++ = 'n'; break; case 't': PUTCHAR('\t'); *q++ = '\\'; *q++ = 't'; break; case 'b': PUTCHAR('\b'); *q++ = '\\'; *q++ = 'b'; break; case 's': PUTCHAR(' '); *q++ = ' '; break; case ' ': PUTCHAR(' '); *q++ = ' '; break; case 'd': sleep(1); *q++ = '\\'; *q++ = 'd'; break; case 'p': usleep(250000L); *q++ = '\\'; *q++ = 'p'; break; case 'D': if (Phone) { PUTSTR(Phone); sprintf(q, "%s", Phone); } break; case 'T': if (Phone) { PUTSTR(tranphone(Phone)); sprintf(q, "%s", tranphone(Phone)); } break; default: PUTCHAR(*p); *q++ = *p; break; } while (*q) q++; } else { PUTCHAR(*p); *q++ = *p; } p++; } Syslog('+', "chat: snd \"%s\"", logs); if (STATUS) { WriteError("$chat: send_str error %d", STATUS); return 1; } else return 0; } static int expired = FALSE; void almhdl(int); void almhdl(int sig) { expired = TRUE; Syslog('c' ,"chat: timeout"); return; } int expect_str(int, char *); int expect_str(int timeout, char *Phone) { int matched = FALSE; int smatch = FALSE; int ematch = FALSE; int ioerror = FALSE; int i, rc; char inbuf[256]; unsigned char ch = '\0'; int eol = FALSE; expired = FALSE; signal(SIGALRM, almhdl); alarm(timeout); while (!matched && !expired && !ioerror && !feof(stdin)) { eol = FALSE; i = 0; memset(&inbuf, 0, sizeof(inbuf)); while (!ioerror && !feof(stdin) && !eol && (i < 255)) { if ((rc = read(0, &ch, 1)) != 1) { ioerror = TRUE; } else { switch(ch) { case '\n': break; case '\r': inbuf[i++] = '\r'; eol = TRUE; break; default: inbuf[i++] = ch; } } if (expired) Syslog('c', "chat: got TIMEOUT"); } inbuf[i] = '\0'; Syslog('c', "chat: rcv \"%s\"", printable(inbuf, 0)); for (i = 0; (i < 10) && !matched; i++) if (strlen(modem.error[i])) if (strncmp(modem.error[i], inbuf, strlen(modem.error[i])) == 0) { matched = TRUE; ematch = TRUE; Syslog('+', "chat: got \"%s\", aborting", printable(inbuf, 0)); } if (Phone != NULL) for (i = 0; (i < 20) && !matched; i++) if (strlen(modem.connect[i])) if (strncmp(modem.connect[i], inbuf, strlen(modem.connect[i])) == 0) { matched = TRUE; smatch = TRUE; Syslog('+', "chat: got \"%s\", continue", printable(inbuf, 0)); } if (!matched) if (strlen(modem.ok)) if (strncmp(modem.ok, inbuf, strlen(modem.ok)) == 0) { matched = TRUE; smatch = TRUE; Syslog('+', "chat: got \"%s\", continue", printable(inbuf, 0)); } if (expired) Syslog('+', "chat: got timeout, aborting"); else if (ferror(stdin)) Syslog('+', "chat: got error, aborting"); if (feof(stdin)) WriteError("$chat: got EOF, aborting"); } alarm(0); signal(SIGALRM, SIG_DFL); rc = !(matched && smatch); return rc; } /* * Chat with modem. If phone is not NULL, then expect also tests the modem * connect strings, else only the error strings and ok string is tested. * The phone number must be full international notation unless the \D * macro is in the dial command. */ int chat(char *Send, int timeout, char *Phone) { int rc; if ((rc = send_str(Send, Phone)) == 0) rc = expect_str(timeout, Phone); return rc; }