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 >
C/C++ Source or Header  |  1994-02-07  |  10KB  |  460 lines

  1. #include "spooler.h"
  2. #include "/include/memory.h"
  3.  
  4. UBYTE inputBuffer[1024];
  5.  
  6.  /*
  7.   * this next define should __NEVER__ be set to anything higher than 250.  as
  8.   * a practical limit, it probably shouldn't be set much less than around
  9.   * 40-50, either.
  10.   */
  11.  
  12. #define MAX_BLOCK_SIZE (250)
  13.  
  14. static const UBYTE transTable[] =
  15. "?????????  ?? ??????????????????"
  16. " !\"#$%&'()*+,-./0123456789:;<=>?"
  17. "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
  18. "`abcdefghijklmnopqrstuvwxyz{|}~?"
  19. "????????????????????????????????"
  20. " !c#??:????<??????23????,1?>????"
  21. "AAAAAA?CEEEEIIIIDNOOOOO*0UUUUY?S"
  22. "aaaaaa?ceeeeiiiidnooooo/0uuuuy?y"
  23. ;
  24.  
  25. static int DumpPage(BPTR fh, PagerAlias_t * als, STRPTR pageText)
  26. {
  27.     UBYTE charBuf;
  28.     LONG i, j, len, len2;
  29.  
  30.     len = strlen(pageText);
  31.     i = 0;
  32.  
  33.     if (FPutC(fh, PAGE_START) == EOF) {
  34.         ErrorMsg("error writing to spool file.");
  35.         ULog(ph, -1, "error writing to spool file.");
  36.         return 10;
  37.     }
  38.  
  39.     while (len) {
  40.         charBuf = min(len, MAX_BLOCK_SIZE - 1);
  41.  
  42.         /*
  43.          * leave room in the first block for the space needed for the
  44.          * PIN number
  45.          */
  46.  
  47.         if (i == 0) {
  48.             len2 = strlen(als->als_PIN) + 2;
  49.  
  50.             if (len2 + charBuf > MAX_BLOCK_SIZE - 1)
  51.                 charBuf -= len2;
  52.         }
  53.  
  54.         /* try and break blocks on white space if possible */
  55.  
  56.         if (len > charBuf) {
  57.             j = i + charBuf;
  58.  
  59.             while (j >= i)
  60.                 if (isspace(pageText[j]))
  61.                     break;
  62.                 else
  63.                     j--;
  64.  
  65.             if (j >= i)
  66.                 charBuf = j - i;
  67.         }
  68.  
  69.         /* now write the block to the spool file */
  70.  
  71.         if ((FPutC(fh, BLOCK_START) == EOF) || (FPutC(fh, charBuf) == EOF) ||
  72.             (FWrite(fh, &pageText[i], 1, charBuf) != charBuf) ||
  73.             (FPutC(fh, BLOCK_END) == EOF)) {
  74.             ErrorMsg("error writing to spool file.");
  75.             ULog(ph, -1, "error writing to spool file.");
  76.             return 10;
  77.         }
  78.  
  79.         i += charBuf;
  80.         len -= charBuf;
  81.     }
  82.  
  83.     if (FPutC(fh, PAGE_END) == EOF) {
  84.         ErrorMsg("error writing to spool file.");
  85.         ULog(ph, -1, "error writing to spool file.");
  86.         return 10;
  87.     }
  88.  
  89.     return 0;
  90. }
  91.  
  92. static int WritePage(BPTR fh, PagerService_t * svc, PagerAlias_t * als, STRPTR pageText)
  93. {
  94.     ULONG maxPageSize;
  95.     ULONG maxMessageLength;
  96.     STRPTR messagePtr;
  97.     STRPTR bufPtrs[2];
  98.     ULONG workBuf;
  99.     LONG c, i, j, k;
  100.     ULONG len, msgBytes, numPages;
  101.     BOOL lastWasWhiteSpace;
  102.     int result = 10;
  103.  
  104.     /*
  105.      * first we need to determine what the maximum page size is.  start
  106.      * with the value specified for the individual alias.  if that is no
  107.      * good then try getting it from the service.  if that still results
  108.      * in a bad value then choose an arbitrary limt.  finally, check if
  109.      * the service supports multi-block format and if not limit the page
  110.      * size to the maximum size allowed in a single block.
  111.      */
  112.  
  113.     maxPageSize = als->als_MaxPageLen;
  114.     if (!maxPageSize || maxPageSize > svc->svc_MaxPageLen)
  115.         maxPageSize = svc->svc_MaxPageLen;
  116.     if (!maxPageSize)
  117.         maxPageSize = 100;
  118.     if (maxPageSize < 20)
  119.         maxPageSize = 20;
  120.  
  121.     if (svc->svc_MultiBlock == FALSE)
  122.         if (maxPageSize > MAX_BLOCK_SIZE - 1)
  123.             maxPageSize = MAX_BLOCK_SIZE - strlen(als->als_PIN) - 3;
  124.  
  125.     /*
  126.      * now we want to figure out what the maximum message length is. grab
  127.      * this from the alias.  if it's a bad value then use a fixed value
  128.      * so that we don't accidentally get stuck trying to send a monster
  129.      * message to a pager
  130.      */
  131.  
  132.     maxMessageLength = als->als_MaxMessageLen;
  133.     if (!maxMessageLength)
  134.         maxMessageLength = 10 * maxPageSize;
  135.  
  136.     /* now allocate memory to hold the converted message. */
  137.  
  138.     if (messagePtr = MyAllocVec(2 * (maxPageSize + 1))) {
  139.         bufPtrs[0] = messagePtr;
  140.         bufPtrs[1] = &messagePtr[maxPageSize + 1];
  141.  
  142.         len = strlen(pageText);
  143.         lastWasWhiteSpace = TRUE;
  144.  
  145.         i = j = k = 0;
  146.         msgBytes = numPages = 0;
  147.  
  148.         workBuf = 0;
  149.  
  150.         result = 0;
  151.  
  152.         while (msgBytes < maxMessageLength && len && !result) {
  153.             /* see if we need to remove excess white space */
  154.             c = transTable[pageText[i]];
  155.  
  156.             if (isspace(c)) {
  157.                 if (lastWasWhiteSpace) {
  158.                     i++;
  159.                     len--;
  160.                     continue;
  161.                 }
  162.                 else {
  163.                     c = ' ';
  164.                     lastWasWhiteSpace = TRUE;
  165.                 }
  166.             }
  167.             else
  168.                 lastWasWhiteSpace = FALSE;
  169.  
  170.             /*
  171.              * now see about adding the character to the current
  172.              * page.  if it won't fit then try doing word wrap
  173.              * between pages and inserting a (cont) message
  174.              */
  175.  
  176.             if (j < maxPageSize) {
  177.                 bufPtrs[workBuf][j] = c;
  178.                 msgBytes++;
  179.                 i++;
  180.                 j++;
  181.                 len--;
  182.                 continue;
  183.             }
  184.             else {
  185.                 /* grrr.  gotta do a page break */
  186.                 k = j + 1;
  187.  
  188.                 /*
  189.                  * try and find whitespace mark to break on +
  190.                  * make room for the continued message
  191.                  */
  192.  
  193.                 while (k + 8 > maxPageSize)
  194.                     while (k >= 0) {
  195.                         k--;
  196.  
  197.                         if (isspace(bufPtrs[workBuf][k]))
  198.                             break;
  199.                     }
  200.  
  201.                 if (k == -1)
  202.                     k = maxPageSize - 8;
  203.  
  204.                 k++;
  205.  
  206.                 /*
  207.                  * now copy the tail end of the page into the
  208.                  * beginning of the next page
  209.                  */
  210.  
  211.                 if (isspace(bufPtrs[workBuf][k])) {
  212.                     CopyMem(&bufPtrs[workBuf][k + 1], bufPtrs[1 - workBuf], j - k - 1);
  213.                     bufPtrs[1 - workBuf][j - k - 1] = '\0';
  214.                 }
  215.                 else {
  216.                     CopyMem(&bufPtrs[workBuf][k], bufPtrs[1 - workBuf], j - k);
  217.                     bufPtrs[1 - workBuf][j - k] = '\0';
  218.                 }
  219.  
  220.                 /* insert the continued text */
  221.  
  222.                 strcpy(&bufPtrs[workBuf][k], " (cont)");
  223.                 msgBytes += 7;
  224.  
  225.                 /*
  226.                  * now dump the previous page & update the
  227.                  * necessary pointers
  228.                  */
  229.  
  230.                 if (result = DumpPage(fh, als, bufPtrs[workBuf])) {
  231.                     ErrorMsg("error writing to spool file.");
  232.                     ULog(ph, -1, "error writing to spool file.");
  233.                 }
  234.  
  235.                 numPages++;
  236.  
  237.                 workBuf = 1 - workBuf;
  238.                 j = strlen(bufPtrs[workBuf]);
  239.  
  240.                 bufPtrs[workBuf][j] = c;
  241.                 msgBytes++;
  242.  
  243.                 i++;
  244.                 j++;
  245.                 len--;
  246.                 continue;
  247.             }
  248.         }
  249.  
  250.         if (!result) {
  251.             bufPtrs[workBuf][j] = '\0';
  252.  
  253.             if (len) {
  254.  
  255.                 /*
  256.                  * if we still have text waiting then add a
  257.                  * truncation message to the last page
  258.                  */
  259.  
  260.                 strcpy(&bufPtrs[workBuf][strlen(bufPtrs[workBuf]) - 8], " (trunc)");
  261.             }
  262.  
  263.             /* dump the remaining page out */
  264.  
  265.             if (result = DumpPage(fh, als, bufPtrs[workBuf])) {
  266.                 ErrorMsg("error writing to spool file.");
  267.                 ULog(ph, -1, "error writing to spool file.");
  268.             }
  269.  
  270.             numPages++;
  271.         }
  272.  
  273.         if (!result) {
  274.             if (FPutC(fh, END_OF_SPOOL) == EOF) {
  275.                 ErrorMsg("error writing to spool file.");
  276.                 ULog(ph, -1, "error writing to spool file.");
  277.                 result = 10;
  278.             }
  279.             else {
  280.                 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"));
  281.                 PutStr("\n");
  282.                 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"));
  283.             }
  284.         }
  285.  
  286.         MyFreeVec(messagePtr);
  287.     }
  288.     else {
  289.         ErrorMsg("out of memory!");
  290.     }
  291.  
  292.     return result;
  293. }
  294.  
  295. static int WriteSpoolFile(BPTR fh, PagerService_t * svc, PagerAlias_t * als, STRPTR pageText)
  296. {
  297.     ULONG longBuf;
  298.  
  299.     /*
  300.      * start by writing out the header information.  this includes the
  301.      * name of the destination and the pin number
  302.      */
  303.  
  304.     if (FWrite(fh, SPOOLMAGIC, 1, strlen(SPOOLMAGIC) + 1) != strlen(SPOOLMAGIC) + 1) {
  305.         ErrorMsg("error writing to spool file.");
  306.         ULog(ph, -1, "error writing to spool file.");
  307.         return 10;
  308.     }
  309.  
  310.     longBuf = strlen(als->als_Name);
  311.  
  312.     if ((FWrite(fh, &longBuf, sizeof(longBuf), 1) != 1) ||
  313.         (FWrite(fh, als->als_Name, 1, longBuf) != longBuf)) {
  314.         ErrorMsg("error writing to spool file.");
  315.         ULog(ph, -1, "error writing to spool file.");
  316.         return 10;
  317.     }
  318.  
  319.     longBuf = strlen(als->als_PIN);
  320.  
  321.     if ((FWrite(fh, &longBuf, sizeof(longBuf), 1) != 1) ||
  322.         (FWrite(fh, als->als_PIN, 1, longBuf) != longBuf)) {
  323.         ErrorMsg("error writing to spool file.");
  324.         ULog(ph, -1, "error writing to spool file.");
  325.         return 10;
  326.     }
  327.  
  328.     /*
  329.      * now we need to write the page text out.
  330.      */
  331.  
  332.     return WritePage(fh, svc, als, pageText);
  333. }
  334.  
  335. static BOOL CheckServiceSpoolDir(STRPTR dirName)
  336. {
  337.     BPTR lock;
  338.     BOOL result = FALSE;
  339.  
  340.     if (lock = Lock(dirName, ACCESS_READ)) {
  341.         UnLock(lock);
  342.         result = TRUE;
  343.     }
  344.     else {
  345.         if (IoErr() == ERROR_OBJECT_NOT_FOUND) {
  346.             if (lock = CreateDir(dirName)) {
  347.                 UnLock(lock);
  348.                 result = TRUE;
  349.             }
  350.         }
  351.     }
  352.  
  353.     return result;
  354. }
  355.  
  356. int DoPage(PagerAlias_t * als, STRPTR pageText)
  357. {
  358.     PagerService_t *svc;
  359.     STRPTR spoolFileName, dirName;
  360.     UBYTE s