home *** CD-ROM | disk | FTP | other *** search
- #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;
- }
-