home *** CD-ROM | disk | FTP | other *** search
- #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 sequenceName[12];
- BPTR fh;
- int result = 10;
- int seq;
-
- if (svc = FindPagerService(ph, als->als_Service)) {
- SetLogService(ph, svc->svc_Name);
-
- /*
- * make sure the service's directory in the spool directory
- * exists
- */
-
- if (dirName = NameInSpool(ph, svc->svc_Name)) {
- if (CheckServiceSpoolDir(dirName)) {
- if (spoolFileName = MyAllocVec(strlen(dirName) + 12)) {
- seq = GetSequenceNumber(ph, 1);
-
- if (seq >= 0) {
- strcpy(spoolFileName, dirName);
- AddPart(spoolFileName, SequenceToName(sequenceName, seq), strlen(dirName) + 12);
-
- if (LockFile(ph, spoolFileName)) {
- if (fh = Open(spoolFileName, MODE_NEWFILE)) {
- result = WriteSpoolFile(fh, svc, als, pageText);
-
- Close(fh);
-
- /*
- * if an
- * error
- * occured
- * then
- * delete the
- * spool file
- * since it
- * contains
- * bogus info
- * and we
- * don't want
- * to confuse
- * the dialer
- */
-
- if (result)
- DeleteFile(spoolFileName);
- }
- else {
- ErrorMsg("couldn't create spool file.");
- ULog(ph, -1, "couldn't create spool file.");
- }
-
- UnLockFile(ph, spoolFileName);
- }
- else
-
- /*
- * no sense in
- * calling ULock if
- * the LockFile()
- * failed since the
- * lock will fail on
- * the logfile as
- * well and thus
- * nothing will be
- * written to the log
- */
-
- ErrorMsg("couldn't lock spool file.");
- }
- else {
- ErrorMsg("couldn't get next sequence number.");
- ULog(ph, -1, "couldn't get next sequence number.");
- }
-
- MyFreeVec(spoolFileName);
- }
- else
- ErrorMsg("out of memory!");
- }
- else {
- ErrorMsg("couldn't locate spool directory for \"%s\" service.", svc->svc_Name);
- ULog(ph, -1, "couldn't locate spool directory for \"%s\" service.", svc->svc_Name);
- }
-
- FreeNameInSpool(dirName);
- }
- else
- ErrorMsg("out of memory!");
-
- FreePagerService(svc);
- }
- else {
- ErrorMsg("couldn't find \"%s\" service.", als->als_Service);
- ULog(ph, -1, "couldn't find \"%s\" service.", als->als_Service);
- result = 5;
- }
-
- return result;
- }
-