home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
comm
/
cyberpager-1.5.lha
/
CyberPager
/
source
/
spooler
/
doPage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-07
|
10KB
|
460 lines
#include "spooler.h"
#include "/include/memory.h"
UBYTE inputBuffer[1024];
/*
* this next define should __NEVER__ be set to anything higher than 250. as
* a practical limit, it probably shouldn't be set much less than around
* 40-50, either.
*/
#define MAX_BLOCK_SIZE (250)
static const UBYTE transTable[] =
"????????? ?? ??????????????????"
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~?"
"????????????????????????????????"
" !c#??:????<??????23????,1?>????"
"AAAAAA?CEEEEIIIIDNOOOOO*0UUUUY?S"
"aaaaaa?ceeeeiiiidnooooo/0uuuuy?y"
;
static int DumpPage(BPTR fh, PagerAlias_t * als, STRPTR pageText)
{
UBYTE charBuf;
LONG i, j, len, len2;
len = strlen(pageText);
i = 0;
if (FPutC(fh, PAGE_START) == EOF) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
return 10;
}
while (len) {
charBuf = min(len, MAX_BLOCK_SIZE - 1);
/*
* leave room in the first block for the space needed for the
* PIN number
*/
if (i == 0) {
len2 = strlen(als->als_PIN) + 2;
if (len2 + charBuf > MAX_BLOCK_SIZE - 1)
charBuf -= len2;
}
/* try and break blocks on white space if possible */
if (len > charBuf) {
j = i + charBuf;
while (j >= i)
if (isspace(pageText[j]))
break;
else
j--;
if (j >= i)
charBuf = j - i;
}
/* now write the block to the spool file */
if ((FPutC(fh, BLOCK_START) == EOF) || (FPutC(fh, charBuf) == EOF) ||
(FWrite(fh, &pageText[i], 1, charBuf) != charBuf) ||
(FPutC(fh, BLOCK_END) == EOF)) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
return 10;
}
i += charBuf;
len -= charBuf;
}
if (FPutC(fh, PAGE_END) == EOF) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
return 10;
}
return 0;
}
static int WritePage(BPTR fh, PagerService_t * svc, PagerAlias_t * als, STRPTR pageText)
{
ULONG maxPageSize;
ULONG maxMessageLength;
STRPTR messagePtr;
STRPTR bufPtrs[2];
ULONG workBuf;
LONG c, i, j, k;
ULONG len, msgBytes, numPages;
BOOL lastWasWhiteSpace;
int result = 10;
/*
* first we need to determine what the maximum page size is. start
* with the value specified for the individual alias. if that is no
* good then try getting it from the service. if that still results
* in a bad value then choose an arbitrary limt. finally, check if
* the service supports multi-block format and if not limit the page
* size to the maximum size allowed in a single block.
*/
maxPageSize = als->als_MaxPageLen;
if (!maxPageSize || maxPageSize > svc->svc_MaxPageLen)
maxPageSize = svc->svc_MaxPageLen;
if (!maxPageSize)
maxPageSize = 100;
if (maxPageSize < 20)
maxPageSize = 20;
if (svc->svc_MultiBlock == FALSE)
if (maxPageSize > MAX_BLOCK_SIZE - 1)
maxPageSize = MAX_BLOCK_SIZE - strlen(als->als_PIN) - 3;
/*
* now we want to figure out what the maximum message length is. grab
* this from the alias. if it's a bad value then use a fixed value
* so that we don't accidentally get stuck trying to send a monster
* message to a pager
*/
maxMessageLength = als->als_MaxMessageLen;
if (!maxMessageLength)
maxMessageLength = 10 * maxPageSize;
/* now allocate memory to hold the converted message. */
if (messagePtr = MyAllocVec(2 * (maxPageSize + 1))) {
bufPtrs[0] = messagePtr;
bufPtrs[1] = &messagePtr[maxPageSize + 1];
len = strlen(pageText);
lastWasWhiteSpace = TRUE;
i = j = k = 0;
msgBytes = numPages = 0;
workBuf = 0;
result = 0;
while (msgBytes < maxMessageLength && len && !result) {
/* see if we need to remove excess white space */
c = transTable[pageText[i]];
if (isspace(c)) {
if (lastWasWhiteSpace) {
i++;
len--;
continue;
}
else {
c = ' ';
lastWasWhiteSpace = TRUE;
}
}
else
lastWasWhiteSpace = FALSE;
/*
* now see about adding the character to the current
* page. if it won't fit then try doing word wrap
* between pages and inserting a (cont) message
*/
if (j < maxPageSize) {
bufPtrs[workBuf][j] = c;
msgBytes++;
i++;
j++;
len--;
continue;
}
else {
/* grrr. gotta do a page break */
k = j + 1;
/*
* try and find whitespace mark to break on +
* make room for the continued message
*/
while (k + 8 > maxPageSize)
while (k >= 0) {
k--;
if (isspace(bufPtrs[workBuf][k]))
break;
}
if (k == -1)
k = maxPageSize - 8;
k++;
/*
* now copy the tail end of the page into the
* beginning of the next page
*/
if (isspace(bufPtrs[workBuf][k])) {
CopyMem(&bufPtrs[workBuf][k + 1], bufPtrs[1 - workBuf], j - k - 1);
bufPtrs[1 - workBuf][j - k - 1] = '\0';
}
else {
CopyMem(&bufPtrs[workBuf][k], bufPtrs[1 - workBuf], j - k);
bufPtrs[1 - workBuf][j - k] = '\0';
}
/* insert the continued text */
strcpy(&bufPtrs[workBuf][k], " (cont)");
msgBytes += 7;
/*
* now dump the previous page & update the
* necessary pointers
*/
if (result = DumpPage(fh, als, bufPtrs[workBuf])) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
}
numPages++;
workBuf = 1 - workBuf;
j = strlen(bufPtrs[workBuf]);
bufPtrs[workBuf][j] = c;
msgBytes++;
i++;
j++;
len--;
continue;
}
}
if (!result) {
bufPtrs[workBuf][j] = '\0';
if (len) {
/*
* if we still have text waiting then add a
* truncation message to the last page
*/
strcpy(&bufPtrs[workBuf][strlen(bufPtrs[workBuf]) - 8], " (trunc)");
}
/* dump the remaining page out */
if (result = DumpPage(fh, als, bufPtrs[workBuf])) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
}
numPages++;
}
if (!result) {
if (FPutC(fh, END_OF_SPOOL) == EOF) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
result = 10;
}
else {
Printf("spooled %ld byte%s in %ld page%s for %s (%ld byte%s truncated)", msgBytes, (msgBytes == 1 ? "" : "s"), numPages, (numPages == 1 ? "" : "s"), als->als_Name, len, (len == 1 ? "" : "s"));
PutStr("\n");
ULog(ph, -1, "spooled %ld byte%s in %ld page%s for %s (%ld byte%s truncated)", msgBytes, (msgBytes == 1 ? "" : "s"), numPages, (numPages == 1 ? "" : "s"), als->als_Name, len, (len == 1 ? "" : "s"));
}
}
MyFreeVec(messagePtr);
}
else {
ErrorMsg("out of memory!");
}
return result;
}
static int WriteSpoolFile(BPTR fh, PagerService_t * svc, PagerAlias_t * als, STRPTR pageText)
{
ULONG longBuf;
/*
* start by writing out the header information. this includes the
* name of the destination and the pin number
*/
if (FWrite(fh, SPOOLMAGIC, 1, strlen(SPOOLMAGIC) + 1) != strlen(SPOOLMAGIC) + 1) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
return 10;
}
longBuf = strlen(als->als_Name);
if ((FWrite(fh, &longBuf, sizeof(longBuf), 1) != 1) ||
(FWrite(fh, als->als_Name, 1, longBuf) != longBuf)) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
return 10;
}
longBuf = strlen(als->als_PIN);
if ((FWrite(fh, &longBuf, sizeof(longBuf), 1) != 1) ||
(FWrite(fh, als->als_PIN, 1, longBuf) != longBuf)) {
ErrorMsg("error writing to spool file.");
ULog(ph, -1, "error writing to spool file.");
return 10;
}
/*
* now we need to write the page text out.
*/
return WritePage(fh, svc, als, pageText);
}
static BOOL CheckServiceSpoolDir(STRPTR dirName)
{
BPTR lock;
BOOL result = FALSE;
if (lock = Lock(dirName, ACCESS_READ)) {
UnLock(lock);
result = TRUE;
}
else {
if (IoErr() == ERROR_OBJECT_NOT_FOUND) {
if (lock = CreateDir(dirName)) {
UnLock(lock);
result = TRUE;
}
}
}
return result;
}
int DoPage(PagerAlias_t * als, STRPTR pageText)
{
PagerService_t *svc;
STRPTR spoolFileName, dirName;
UBYTE s