home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
comm
/
misc
/
cyberpager
/
source
/
dialer
/
send.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-05
|
12KB
|
536 lines
#include "/include/memory.h"
#include "dialer.h"
BOOL online;
static UBYTE packetBuf[1024];
static UBYTE safePacketBuf[8 * sizeof(packetBuf)];
static const UBYTE hexTable[] = "0123456789ABCDEF";
static LONG safeBufIndex = 0;
static BOOL lastSafeSpecial;
static BOOL lastSafeHex;
/*
* add a character to the safe buf. insert an intelligent name for special
* characers and convert unprintable to hex values. calling with a parameter
* of -1 means to close the buffer off.
*/
static WORD AddToSafeBuf(WORD c)
{
STRPTR specialName;
if (safeBufIndex == 0) {
lastSafeSpecial = TRUE;
lastSafeHex = FALSE;
}
if (c == -1) {
if (safeBufIndex == 0 || lastSafeSpecial == FALSE) {
if (safeBufIndex == 0)
safePacketBuf[safeBufIndex++] = '\"';
safePacketBuf[safeBufIndex++] = '\"';
}
safePacketBuf[safeBufIndex] = '\0';
safeBufIndex = 0;
}
else {
switch (c) {
case HSHAKE_STX:
specialName = "STX";
break;
case HSHAKE_ETX:
specialName = "ETX";
break;
case HSHAKE_EOT:
specialName = "EOT";
break;
case HSHAKE_ACK:
specialName = "ACK";
break;
case HSHAKE_NAK:
specialName = "NAK";
break;
case HSHAKE_ETB:
specialName = "ETB";
break;
case HSHAKE_RS:
specialName = "RS";
break;
case HSHAKE_US:
specialName = "US";
break;
case '\r':
specialName = "CR";
break;
case '\x1B':
specialName = "ESC";
break;
default:
specialName = NULL;
break;
}
if (specialName != NULL) {
if (lastSafeSpecial == FALSE) {
safePacketBuf[safeBufIndex++] = '\"';
lastSafeSpecial = TRUE;
}
if (safeBufIndex)
safePacketBuf[safeBufIndex++] = ' ';
while (*specialName)
safePacketBuf[safeBufIndex++] = *specialName++;
lastSafeHex = FALSE;
}
else {
if (lastSafeSpecial) {
if (safeBufIndex)
safePacketBuf[safeBufIndex++] = ' ';
safePacketBuf[safeBufIndex++] = '\"';
lastSafeSpecial = FALSE;
}
if (isprint(c)) {
/*
* check to see if the last character was a
* hex value. if so, see if the current
* characer is a valid hex digit. if so,
* insert " " so that one doesn't get
* confused reading the translated output as
* otherwise it would look like a larger hex
* digit has been specified than really was.
*/
if (lastSafeHex) {
if (isxdigit(c)) {
safePacketBuf[safeBufIndex++] = '\"';
safePacketBuf[safeBufIndex++] = ' ';
safePacketBuf[safeBufIndex++] = '\"';
}
lastSafeHex = FALSE;
}
if (c == '\"')
safePacketBuf[safeBufIndex++] = '\\';
safePacketBuf[safeBufIndex++] = c;
}
else {
safePacketBuf[safeBufIndex++] = '\\';
safePacketBuf[safeBufIndex++] = 'x';
safePacketBuf[safeBufIndex++] = hexTable[(c >> 4) & 0xF];
safePacketBuf[safeBufIndex++] = hexTable[c & 0xF];
lastSafeHex = TRUE;
}
}
}
return c;
}
static LONG GetPacket(STRPTR errorMsg)
{
LONG index;
UWORD c;
safeBufIndex = index = 0;
while (c = SerGetRawChar(20)) {
if (c == TIMEOUT) {
ErrorMsg("%s: timed out trying to read packet from service.", errorMsg);
ULog(ph, -1, "%s: timed out trying to read packet from service.", errorMsg);
return -1;
}
else if (c == '\n')
continue;
else if (c == '\r')
break;
packetBuf[index++] = AddToSafeBuf(c);
if (index == (sizeof(packetBuf) - 2)) {
ErrorMsg("%s: panic attack - packet from service too long.", errorMsg);
ULog(ph, -1, "%s: panic attack - packet from service too long.", errorMsg);
return -2;
}
}
packetBuf[index] = '\0';
AddToSafeBuf(-1);
ULog(ph, 5, "getpacket: got %s", safePacketBuf);
return index;
}
#define MAX_LOGIN_RETRIES (5)
static int DialService(PagerService_t * svc)
{
int retries;
LONG len;
STRPTR ptr;
BOOL doWrite;
Use8N1(svc->svc_Use8N1);
SwitchBaud(svc->svc_BaudRate);
if (!InitModem())
return 2;
SerWrite(svc->svc_Phone, strlen(svc->svc_Phone));
SerPutChar('\r');
ULog(ph, -1, "dialed %s (%s) on modem %ld", svc->svc_Name, svc->svc_Phone, openedModem);
if (SerWaitString("CONNECT", 60)) {
online = TRUE;
/* eat up to the newline after the connect message */
SerWaitString("\r\n", 1);
Delay(TICKS_PER_SECOND);
/* first look for the ID= prompt */
for (retries = 0; retries < MAX_LOGIN_RETRIES; retries++) {
SerPutChar('\r');
if (SerWaitString("ID=", 2))
break;
}
if (retries == MAX_LOGIN_RETRIES) {
ErrorMsg("login failed: no \"ID=\" from the service.");
ULog(ph, -1, "login failed: no \"ID=\" from the service.");
return 4;
}
/* eat any characters trailing the ID= prompt */
while (SerGetRawChar(1) != TIMEOUT) ;
/* now try and log in in automatic mode */
doWrite = TRUE;
for (retries = 0; retries < MAX_LOGIN_RETRIES; retries++) {
if (doWrite) {
SerWrite("\x1B" "PG", 3);
SerWrite(svc->svc_Password, strlen(svc->svc_Password));
SerPutChar('\r');
doWrite = FALSE;
}
if ((len = GetPacket("login failed")) < 0)
return 4;
else {
if (len == 1 && packetBuf[0] == HSHAKE_ACK) {
for (retries = 0; retries < MAX_LOGIN_RETRIES; retries++) {
if ((len = GetPacket("login failed")) < 0)
return 4;
else if (packetBuf[0] == '\x1B' && packetBuf[1] == '[' && packetBuf[2] == 'p') {
ULog(ph, -1, "login successful");
return 0;
}
}
ErrorMsg("login failed: retry limit exceeded");
ULog(ph, -1, "login failed: retry limit exceeded");
return 4;
}
else if (len == 1 && packetBuf[0] == HSHAKE_NAK) {
doWrite = TRUE;
continue;
}
else if (len == 2 && packetBuf[0] == '\x1B' && packetBuf[1] == HSHAKE_EOT) {
ErrorMsg("login failed: service refused connection.");
ULog(ph, -1, "login failed: service refused connection.");
return 4;
}
else if (packetBuf[0]) {
ptr = packetBuf;
while (isspace(*ptr))
ptr++;
if (ptr[0] == 'I' && ptr[1] == 'D' && ptr[2] == '=') {
retries--;
}
else {
ULog(ph, 2, "login: unknown packet received - %s", safePacketBuf);
}
}
}
}
ErrorMsg("login failed: retry limit exceeded");
ULog(ph, -1, "login failed: retry limit exceeded");
return 4;
}
else {
ErrorMsg("login failed: no carrier detected.");
ULog(ph, -1, "login failed: no carrier detected.");
return 4;
}
}
static UBYTE inputBuffer[256];
static const UBYTE checkSumTable[] = "0123456789:;<=>?";
static int SendBlock(void)
{
int sum;
int i, c;
int retries;
LONG len;
BOOL doWrite;
sum = safeBufIndex = i = 0;
while (c = inputBuffer[i++])
sum += AddToSafeBuf(c);
i--;
inputBuffer[i++] = AddToSafeBuf(checkSumTable[(sum >> 8) & 0xF]);
inputBuffer[i++] = AddToSafeBuf(checkSumTable[(sum >> 4) & 0xF]);
inputBuffer[i++] = AddToSafeBuf(checkSumTable[sum & 0xF]);
inputBuffer[i++] = AddToSafeBuf('\r');
AddToSafeBuf(-1);
ULog(ph, 4, "sendblock: sent %s", safePacketBuf);
doWrite = TRUE;
for (retries = 0; retries < 100; retries++) {
if (doWrite) {
SerWrite(inputBuffer, i);
doWrite = FALSE;
}
if ((len = GetPacket("sendblock failed")) < 0)
return 1;
else {
if (len == 1 && packetBuf[0] == HSHAKE_ACK)
return 0;
else if (len == 1 && packetBuf[0] == HSHAKE_NAK) {
ULog(ph, 2, "sendblock: received nak -- retrying");
doWrite = TRUE;
continue;
}
else if (len == 1 && packetBuf[0] == HSHAKE_RS) {
ErrorMsg("sendblock failed: service rejected block");
ULog(ph, -1, "sendblock failed: service rejected block");
return 3;
}
else if (len == 2 && packetBuf[0] == '\x1B' && packetBuf[1] == HSHAKE_EOT) {
ErrorMsg("sendblock failed: service requested hangup");
ULog(ph, -1, "sendblock failed: service requested hangup");
return 1;
}
else if (packetBuf[0]) {
ULog(ph, 2, "sendblock: unknown packet received - %s", safePacketBuf);
}
}
}
ErrorMsg("sendblock failed: retry limit exceeded");
ULog(ph, -1, "sendblock failed: retry limit exceeded");
return 1;
}
static int ProcessSpoolFile(PagerService_t * svc, BPTR fh, STRPTR spoolFileName, STRPTR nameBuffer, STRPTR pinBuffer)
{
LONG tag, blockLen;
int readOffset;
int result;
int pageCount;
/* make sure we are connected to the service. */
if (!online)
if (result = DialService(svc))
return result;
/* loop sending pages in the spoolfile to the service */
for (tag = FGetC(fh), pageCount = result = 0; !result && tag != END_OF_SPOOL; pageCount++) {
if ((tag != PAGE_START) || ((tag = FGetC(fh)) == EOF)) {
ErrorMsg("error reading spool file \"%s\"", spoolFileName);
ULog(ph, -1, "error reading spool file \"%s\"", spoolFileName);
return 3;
}
inputBuffer[0] = HSHAKE_STX;
strcpy(&inputBuffer[1], pinBuffer);
readOffset = strlen(inputBuffer);
inputBuffer[readOffset++] = '\r';
for (; !result && tag != PAGE_END;) {
if ((tag != BLOCK_START) ||
((blockLen = FGetC(fh)) == EOF) || (blockLen + readOffset + 1 > 250) ||
(FRead(fh, &inputBuffer[readOffset], 1, blockLen) != blockLen) ||
((tag = FGetC(fh)) != BLOCK_END) || ((tag = FGetC(fh)) == EOF)) {
ErrorMsg("error reading spool file \"%s\"", spoolFileName);
ULog(ph, -1, "error reading spool file \"%s\"", spoolFileName);
return 3;
}
if (tag == PAGE_END) {
inputBuffer[readOffset + blockLen++] = '\r';
inputBuffer[readOffset + blockLen++] = HSHAKE_ETX;
}
else
inputBuffer[readOffset + blockLen++] = HSHAKE_US;
inputBuffer[readOffset + blockLen] = 0;
result = SendBlock();
readOffset = 1;
}
tag = FGetC(fh);
}
if (!result)
ULog(ph, -1, "delivered message to %s (%s) in %ld page%s", pinBuffer, nameBuffer, pageCount, (pageCount == 1 ? "" : "s"));
return result;
}
static STRPTR ReadLongItem(BPTR fh, STRPTR spoolFileName)
{
LONG longBuf;
STRPTR buffer;
if (FRead(fh, &longBuf, sizeof(longBuf), 1) == 1) {
if (buffer = MyAllocVec(longBuf + 1)) {
if (FRead(fh, buffer, 1, longBuf) == longBuf) {
buffer[longBuf] = '\0';
return buffer;
}
else {
ErrorMsg("error reading spool file \"%s\"", spoolFileName);
ULog(ph, -1, "error reading spool file \"%s\"", spoolFileName);
}
MyFreeVec(buffer);
}
else
ErrorMsg("out of memory!");
}
else {
ErrorMsg("error reading spool file \"%s\"", spoolFileName);
ULog(ph, -1, "error reading spool file \"%s\"", spoolFileName);
}
return buffer;
}
static UBYTE RenameBuf[FILENAME_BUF_SIZE];
int SendSpoolFile(PagerService_t * svc, STRPTR spoolFileName)
{
BPTR fh;
STRPTR nameBuffer, pinBuffer;
int result;
result = 4;
if (LockFile(ph, spoolFileName)) {
if (fh = Open(spoolFileName, MODE_OLDFILE)) {
result = 3;
if (FRead(fh, inputBuffer, 1, strlen(SPOOLMAGIC) + 1) == strlen(SPOOLMAGIC) + 1) {
if (strcmp(inputBuffer, SPOOLMAGIC) == 0) {
if (nameBuffer = ReadLongItem(fh, spoolFileName)) {
if (pinBuffer = ReadLongItem(fh, spoolFileName)) {
result = ProcessSpoolFile(svc, fh, spoolFileName, nameBuffer, pinBuffer);
MyFreeVec(pinBuffer);
}
MyFreeVec(nameBuffer);
}
}
else {
ErrorMsg("\"%s\" is not a valid spool file", spoolFileName);
ULog(ph, -1, "\"%s\" is not a valid spool file", spoolFileName);
}
}
else {
ErrorMsg("error reading spool file \"%s\"", spoolFileName);
ULog(ph, -1, "error reading spool file \"%s\"", spoolFileName);
}
Close(fh);
}
else {
ErrorMsg("couldn't open spool file \"%s\"", spoolFileName);
ULog(ph, -1, "couldn't open spool file \"%s\"", spoolFileName);
}
UnLockFile(ph, spoolFileName);
}
else {
ErrorMsg("couldn't lock spool file \"%s\"", spoolFileName);
ULog(ph, -1, "couldn't lock spool file \"%s\"", spoolFileName);
}
/*
* if the spool file is bad (result = 3) then rename it so we don't
* get hung up on it. in this case we return 0 so that we can
* continue sending other files while on-line
*/
if (result == 3) {
strcpy(RenameBuf, spoolFileName);
strcat(RenameBuf, ".bad");
DeleteFile(RenameBuf); /* sanity check */
if (Rename(spoolFileName, RenameBuf) == DOSTRUE) {
ULog(ph, -1, "renamed \"%s\" to \"%s\".", spoolFileName, RenameBuf);
result = 0;
}
else
ULog(ph, -1, "unable to rename \"%s\" to \"%s\".", spoolFileName, RenameBuf);
}
/*
* if we are all done and sent the spool file without any trouble
* then we need to delete the file
*/
if (!result)
DeleteFile(spoolFileName);
return result;
}