home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 1 / Mecomp-CD.iso / amiga / librarys / xprascii.library / source / xprascii.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-14  |  22.6 KB  |  1,208 lines

  1. /*
  2. **    Last modified for v2.4 by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  3. **        9-Oct-95
  4. **
  5. **    :ts=3
  6. */
  7.  
  8. /* $Revision Header built by Ueli Kaufmann ********** (please edit) **********
  9. *
  10. *  Copyright by Ueli Kaufmann
  11. *
  12. * File             : xprascii.library
  13. * Created on       : Monday 28-Dec-92 13:21:45
  14. * Created by       : Ueli Kaufmann
  15. * Email via znet   : U.KAUFMANN@LINK-CH1.ZER
  16. * Email via uucp   : Ueli_Kaufmann@augs1.adsp.sub.org
  17. * Created with     : SAS/C 6.1, Cygnus-Ed V2.12, Shell OS2.04
  18. * Current revision : 2.3
  19. *
  20. *
  21. * Purpose
  22. * -------
  23. *   replacement for xprascii.library v0.9  by Willy Langeveld
  24. *
  25. *****************************************************************************/
  26.  
  27.  
  28.  
  29. /************************/
  30.  
  31. #include <dos/dosextens.h>
  32.  
  33. #include <exec/execbase.h>
  34. #include <exec/memory.h>
  35.  
  36. #include <clib/utility_protos.h>
  37. #include <clib/exec_protos.h>
  38. #include <clib/dos_protos.h>
  39.  
  40. #include <pragmas/utility_pragmas.h>
  41. #include <pragmas/exec_pragmas.h>
  42. #include <pragmas/dos_pragmas.h>
  43.  
  44. #include <string.h>
  45. #include <stdarg.h>
  46. #include <ctype.h>
  47. #include <stdio.h>
  48.  
  49. #include "xproto.h"
  50. #include "xprascii.h"
  51.  
  52. STATIC BOOL test(struct XPR_IO *io);
  53. STATIC BOOL setup(struct XPR_IO *io);
  54. STATIC VOID ParseConfigString(struct XPR_IO *io, char *buf);
  55. STATIC UBYTE *FindOption(UBYTE *buf, UBYTE option);
  56. LONG AtoL(STRPTR);
  57. VOID myGetSysTime(ULONG *);
  58. VOID __stdargs upderr(struct XPR_IO *io, UBYTE *err, ...);
  59.  
  60. struct    ExecBase            *SysBase;
  61. struct    DosLibrary        *DOSBase;
  62. struct    Library            *UtilityBase;
  63.  
  64. VOID __saveds __asm __UserLibCleanup(register __a6 struct Library *libBase)
  65. {
  66.     if(UtilityBase)
  67.     {
  68.         CloseLibrary(UtilityBase);
  69.         UtilityBase = NULL;
  70.     }
  71.  
  72.     if(DOSBase)
  73.     {
  74.         CloseLibrary((struct Library *)DOSBase);
  75.         DOSBase = NULL;
  76.     }
  77. }
  78.  
  79.  
  80. int __saveds __asm __UserLibInit(register __a6 struct Library *libBase)
  81. {
  82.     SysBase = *(struct ExecBase **)4;
  83.  
  84.     if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
  85.     {
  86.         if(UtilityBase = OpenLibrary("utility.library", 37))
  87.             return(0);
  88.         else
  89.         {
  90.             CloseLibrary(DOSBase);
  91.             DOSBase = NULL;
  92.         }
  93.     }
  94.  
  95.     return(1);
  96. }
  97.  
  98.  
  99. LONG __saveds __asm XProtocolCleanup(register __a0 struct XPR_IO *io)
  100. {
  101.     struct XProtocolData *xData = (struct XProtocolData *)io->xpr_data;
  102.  
  103.     if(xData != NULL)
  104.     {
  105.         FreeMem(xData, sizeof(struct XProtocolData));
  106.         io->xpr_data = NULL;
  107.     }
  108.  
  109.     return(XPRS_SUCCESS);
  110. }
  111.  
  112.  
  113. STATIC VOID  EncodePromptChar(UBYTE pChar, UBYTE *pBuf);
  114. STATIC UBYTE DecodePromptChar(UBYTE *pBuf);
  115.  
  116. LONG __saveds __asm XProtocolSetup(register __a0 struct XPR_IO *io)
  117. {
  118.     struct XProtocolData *xData;
  119.  
  120.     if(test(io) == FALSE)
  121.         return(XPRS_FAILURE);
  122.  
  123.     if(io->xpr_data == NULL)
  124.     {
  125.         if(setup(io) == FALSE)
  126.             return(XPRS_FAILURE);
  127.     }
  128.  
  129.     xData = (struct XProtocolData *)io->xpr_data;
  130.  
  131.  
  132.     /* If setup string isn't handed to us, ask questions */
  133.  
  134.     if(io->xpr_filename == NULL)
  135.     {
  136.         if(io->xpr_options != NULL)
  137.         {
  138.             enum { OPT_HEADER=0, OPT_CHARDELAY, OPT_LINEDELAY, OPT_LF_CONVERT,
  139.                      OPT_CR_CONVERT, OPT_UUE, OPT_DEL,
  140.                      OPT_PROMPTCHAR, OPT_EXPANDBLANKS,
  141.                      OPT_STRIPHIBIT };
  142.             ULONG numopts;
  143.  
  144.             struct xpr_option *opti[11];
  145.             UBYTE charBuf[LONGLEN], lineBuf[LONGLEN], lfBuf[CHARLEN],
  146.                     crBuf[CHARLEN], stripBuf[STRINGLEN],
  147.                     uueBuf[STRINGLEN], delBuf[STRINGLEN],
  148.                     expandBuf[STRINGLEN], promptBuf[10];
  149.  
  150.             struct xpr_option opt0;
  151.             struct xpr_option opt1;
  152.             struct xpr_option opt2;
  153.             struct xpr_option opt3;
  154.             struct xpr_option opt4;
  155.             struct xpr_option opt5;
  156.             struct xpr_option opt6;
  157.             struct xpr_option opt7;
  158.             struct xpr_option opt8;
  159.             struct xpr_option opt9;
  160.             struct xpr_option opt10;
  161.  
  162.             opti[0]    = &opt0;
  163.             opti[1]    = &opt1;
  164.             opti[2]    = &opt2;
  165.             opti[3]    = &opt3;
  166.             opti[4]    = &opt4;
  167.             opti[5]    = &opt5;
  168.             opti[6]    = &opt6;
  169.             opti[7]    = &opt7;
  170.             opti[8]    = &opt8;
  171.             opti[9]    = &opt9;
  172.             opti[10]    = &opt10;
  173.  
  174.  
  175.             numopts = 0;
  176.  
  177.             opti[OPT_HEADER]->xpro_description    = "ASCII Options:  [s=send / r=receive]";
  178.             opti[OPT_HEADER]->xpro_type    = XPRO_HEADER;
  179.             opti[OPT_HEADER]->xpro_value    = NULL;
  180.             opti[OPT_HEADER]->xpro_length    = NULL;
  181.  
  182. /* */
  183.  
  184.             numopts++;
  185.             opti[OPT_CHARDELAY]->xpro_description    = "Char Delay (ticks) [s]:";
  186.             opti[OPT_CHARDELAY]->xpro_type            = XPRO_LONG;
  187.             sprintf(charBuf, "%ld", xData->CharDelay);
  188.             opti[OPT_CHARDELAY]->xpro_value            = charBuf;
  189.             opti[OPT_CHARDELAY]->xpro_length            = LONGLEN;
  190.  
  191. /* */
  192.  
  193.             numopts++;
  194.             opti[OPT_LINEDELAY]->xpro_description    = "Line Delay (ticks) [s]:";
  195.             opti[OPT_LINEDELAY]->xpro_type            = XPRO_LONG;
  196.             sprintf(lineBuf, "%ld", xData->LineDelay);
  197.             opti[OPT_LINEDELAY]->xpro_value            = lineBuf;
  198.             opti[OPT_LINEDELAY]->xpro_length            = LONGLEN;
  199.  
  200. /* */
  201.  
  202.             numopts++;
  203.             switch(xData->LF_Mode)
  204.             {
  205.                 case STRIP_MODE:
  206.                     lfBuf[0] = 'S';
  207.                 break;
  208.  
  209.                 case ADD_MODE:
  210.                     lfBuf[0] = 'A';
  211.                 break;
  212.  
  213.                 case EXCHANGE_MODE:
  214.                     lfBuf[0] = 'X';
  215.                 break;
  216.  
  217.                 default:
  218.                     lfBuf[0] = 'N';
  219.                 break;
  220.  
  221.             }
  222.             lfBuf[1] = '\0';
  223.  
  224.             opti[OPT_LF_CONVERT]->xpro_description    = "Convert `LF' (N,S,X,A) [s]:";
  225.             opti[OPT_LF_CONVERT]->xpro_type            = XPRO_STRING;
  226.             opti[OPT_LF_CONVERT]->xpro_value            = lfBuf;
  227.             opti[OPT_LF_CONVERT]->xpro_length        = CHARLEN;
  228.  
  229. /* */
  230.  
  231.             numopts++;
  232.             switch(xData->CR_Mode)
  233.             {
  234.                 case STRIP_MODE:
  235.                     crBuf[0] = 'S';
  236.                 break;
  237.  
  238.                 case ADD_MODE:
  239.                     crBuf[0] = 'A';
  240.                 break;
  241.  
  242.                 case EXCHANGE_MODE:
  243.                     crBuf[0] = 'X';
  244.                 break;
  245.  
  246.                 default:
  247.                     crBuf[0] = 'N';
  248.                 break;
  249.  
  250.             }
  251.             crBuf[1] = '\0';
  252.  
  253.             opti[OPT_CR_CONVERT]->xpro_description    = "Convert `CR' (N,S,X,A) [s]:";
  254.             opti[OPT_CR_CONVERT]->xpro_type            = XPRO_STRING;
  255.             opti[OPT_CR_CONVERT]->xpro_value            = crBuf;
  256.             opti[OPT_CR_CONVERT]->xpro_length        = CHARLEN;
  257.  
  258. /* */
  259.  
  260.             numopts++;
  261.             if(xData->BinToASCII != FALSE)
  262.                 strcpy(uueBuf, "on");
  263.             else
  264.                 strcpy(uueBuf, "off");
  265.             opti[OPT_UUE]->xpro_description    = "Use uuencode & decode [s+r]:";
  266.             opti[OPT_UUE]->xpro_type            = XPRO_BOOLEAN;
  267.             opti[OPT_UUE]->xpro_value            = uueBuf;
  268.             opti[OPT_UUE]->xpro_length            = STRINGLEN;
  269.  
  270.  
  271. /* */
  272.  
  273.             numopts++;
  274.             if(xData->DelTmpFile != FALSE)
  275.                 strcpy(delBuf, "on");
  276.             else
  277.                 strcpy(delBuf, "off");
  278.             opti[OPT_DEL]->xpro_description    = "Delete uuencoded file [r]:";
  279.             opti[OPT_DEL]->xpro_type            = XPRO_BOOLEAN;
  280.             opti[OPT_DEL]->xpro_value            = delBuf;
  281.             opti[OPT_DEL]->xpro_length            = STRINGLEN;
  282.  
  283.  
  284. /* */
  285.  
  286.             numopts++;
  287.             opti[OPT_PROMPTCHAR]->xpro_description    = "Prompt Char [s]:";
  288.             opti[OPT_PROMPTCHAR]->xpro_type            = XPRO_STRING;
  289.             EncodePromptChar(xData->PromptChar, promptBuf);
  290.             opti[OPT_PROMPTCHAR]->xpro_value            = promptBuf;
  291.             opti[OPT_PROMPTCHAR]->xpro_length        = 10;
  292.  
  293. /* */
  294.  
  295.             numopts++;
  296.             if(xData->ExpandBlanks != FALSE)
  297.                 strcpy(expandBuf, "on");
  298.             else
  299.                 strcpy(expandBuf, "off");
  300.             opti[OPT_EXPANDBLANKS]->xpro_description    = "Expand Blank Lines [s]:";
  301.             opti[OPT_EXPANDBLANKS]->xpro_type            = XPRO_BOOLEAN;
  302.             opti[OPT_EXPANDBLANKS]->xpro_value            = expandBuf;
  303.             opti[OPT_EXPANDBLANKS]->xpro_length            = STRINGLEN;
  304.  
  305. /* */
  306.  
  307.             numopts++;
  308.             if(xData->StripHiBit != FALSE)
  309.                 strcpy(stripBuf, "on");
  310.             else
  311.                 strcpy(stripBuf, "off");
  312.             opti[OPT_STRIPHIBIT]->xpro_description    = "Strip High Bit [r]:";
  313.             opti[OPT_STRIPHIBIT]->xpro_type            = XPRO_BOOLEAN;
  314.             opti[OPT_STRIPHIBIT]->xpro_value            = stripBuf;
  315.             opti[OPT_STRIPHIBIT]->xpro_length        = STRINGLEN;
  316.  
  317.  
  318.  
  319.  
  320.             io->xpr_options(++numopts, opti);
  321.  
  322.  
  323.             xData->CharDelay = AtoL(charBuf);
  324.             if(xData->CharDelay > 500)
  325.                 xData->CharDelay = 500;
  326.  
  327.  
  328.             xData->LineDelay = AtoL(lineBuf);
  329.             if(xData->LineDelay > 500)
  330.                 xData->LineDelay = 500;
  331.  
  332.             switch(ToUpper(*lfBuf))
  333.             {
  334.                 case 'S':    /* Strip LF */
  335.                     xData->LF_Mode = STRIP_MODE;
  336.                 break;
  337.  
  338.                 case 'A':    /* Add CR */
  339.                     xData->LF_Mode = ADD_MODE;
  340.                 break;
  341.  
  342.                 case 'X':    /* LF -> CR */
  343.                     xData->LF_Mode = EXCHANGE_MODE;
  344.                 break;
  345.  
  346.                 default:        /* None */
  347.                     xData->LF_Mode = NONE_MODE;
  348.                 break;
  349.  
  350.             }
  351.  
  352.             switch(ToUpper(*crBuf))
  353.             {
  354.                 case 'S':    /* Strip CR */
  355.                     xData->CR_Mode = STRIP_MODE;
  356.                 break;
  357.  
  358.                 case 'A':    /* Add LF */
  359.                     xData->CR_Mode = ADD_MODE;
  360.                 break;
  361.  
  362.                 case 'X':    /* CR -> LF */
  363.                     xData->CR_Mode = EXCHANGE_MODE;
  364.                 break;
  365.  
  366.                 default:        /* None */
  367.                     xData->CR_Mode = NONE_MODE;
  368.                 break;
  369.  
  370.             }
  371.  
  372.             xData->ExpandBlanks    = (!stricmp(expandBuf, "yes") ||
  373.                                             !stricmp(expandBuf, "on"));
  374.  
  375.  
  376.             xData->BinToASCII        = (!stricmp(uueBuf, "yes") ||
  377.                                             !stricmp(uueBuf, "on"));
  378.  
  379.             xData->DelTmpFile        = (!stricmp(delBuf, "yes") ||
  380.                                             !stricmp(delBuf, "on"));
  381.  
  382.             xData->StripHiBit        = (!stricmp(stripBuf, "yes") ||
  383.                                             !stricmp(stripBuf, "on"));
  384.  
  385.             xData->PromptChar = DecodePromptChar(promptBuf);
  386.         }
  387.         else
  388.         {
  389.             if(io->xpr_gets != NULL)
  390.             {
  391.                 UWORD expand, strip;
  392.                 UBYTE lf, cr, uue, del, promptBuf[4], buffy[128];
  393.  
  394.                 uue     = (xData->BinToASCII)        ? 1 : 0;
  395.                 del     = (xData->DelTmpFile)        ? 1 : 0;
  396.                 expand = (xData->ExpandBlanks)    ? 1 : 0;
  397.                 strip     = (xData->StripHiBit)        ? 1 : 0;
  398.                 EncodePromptChar(xData->PromptChar, promptBuf);
  399.  
  400.                 switch(xData->LF_Mode)
  401.                 {
  402.                     case STRIP_MODE:
  403.                         lf = 'S';
  404.                     break;
  405.  
  406.                     case ADD_MODE:
  407.                         lf = 'A';
  408.                     break;
  409.  
  410.                     case EXCHANGE_MODE:
  411.                         lf = 'X';
  412.                     break;
  413.  
  414.                     default:
  415.                         lf = 'N';
  416.                     break;
  417.  
  418.                 }
  419.  
  420.                 switch(xData->CR_Mode)
  421.                 {
  422.                     case STRIP_MODE:
  423.                         cr = 'S';
  424.                     break;
  425.  
  426.                     case ADD_MODE:
  427.                         cr = 'A';
  428.                     break;
  429.  
  430.                     case EXCHANGE_MODE:
  431.                         cr = 'X';
  432.                     break;
  433.  
  434.                     default:
  435.                         cr = 'N';
  436.                     break;
  437.  
  438.                 }
  439.  
  440.                 sprintf(buffy, "C%ld,L%ld,F%lc,R%lc,U%lc,D%lc,E%ld,S%ld,P%s", xData->CharDelay, xData->LineDelay, lf, cr, uue, del, expand, strip, promptBuf);
  441.  
  442.                 if(io->xpr_gets("ASCII Options", buffy)  != NULL)
  443.                     ParseConfigString(io, buffy);
  444.             }
  445.         }
  446.     }
  447.     else
  448.         ParseConfigString(io, io->xpr_filename);
  449.  
  450.     return(XPRS_SUCCESS);
  451. }
  452.  
  453.  
  454. STATIC BOOL WaitForPrompt(struct XPR_IO *io)
  455. {
  456.     struct XProtocolData *xData = (struct XProtocolData *)io->xpr_data;
  457.     UWORD data;
  458.  
  459.     if(data = io->xpr_sread(xData->SerBuf, 1, 0) > 0)
  460.     {
  461.         UWORD i;
  462.  
  463.         for(i=0; i<data; i++)
  464.         {
  465.             if(xData->SerBuf[i] == xData->PromptChar)
  466.                 return(0);
  467.         }
  468.     }
  469.  
  470.     for(;;)
  471.     {
  472.         if(io->xpr_sread(xData->SerBuf, 1, 10000000) > 0)
  473.         {
  474.             if(xData->SerBuf[0] == xData->PromptChar)
  475.                 return(0);
  476.         }
  477.         else
  478.             return(1);
  479.     }
  480.  
  481.     return(1);
  482. }
  483.  
  484.  
  485. STATIC LONG SendLine(struct XPR_IO *io, UBYTE *fileBuf, ULONG lineLen)
  486. {
  487.     struct XProtocolData *xData = (struct XProtocolData *)io->xpr_data;
  488.     LONG brkFlag=0;
  489.  
  490.     xData->xpru.xpru_updatemask = XPRU_BYTES | XPRU_BLOCKS | XPRU_BLOCKSIZE;
  491.     xData->xpru.xpru_bytes     += lineLen;
  492.     xData->xpru.xpru_blocksize  = lineLen;
  493.     xData->xpru.xpru_blocks++;
  494.     io->xpr_update(&xData->xpru);
  495.  
  496.  
  497.     if(xData->ExpandBlanks != FALSE  &&
  498.         (xData->SerBuf[0] == '\n'  ||  xData->SerBuf[0] == '\r'))
  499.     {
  500.         io->xpr_swrite(" ", 1);
  501.     }
  502.  
  503.  
  504.     if(xData->CharDelay != 0)    /* writin' in slo'-motion..(-: */
  505.     {
  506.         UWORD i;
  507.         UBYTE *ptr;
  508.  
  509.         ptr = xData->SerBuf;
  510.         for(i=0; i<lineLen; i++, ptr++)
  511.         {
  512.             io->xpr_swrite(ptr, 1);
  513.            Delay(xData->CharDelay);
  514.         }
  515.     }
  516.     else
  517.         io->xpr_swrite(xData->SerBuf, lineLen);    /* BLAST IT..!! */
  518.  
  519.  
  520.  
  521.     if(xData->LineDelay != 0)
  522.           Delay(xData->LineDelay);
  523.  
  524.     if(xData->PromptChar != '\0')
  525.         brkFlag = WaitForPrompt(io);
  526.  
  527.     io->xpr_sflush();
  528.  
  529.  
  530.     brkFlag = (io->xpr_chkabort() != 0  ||  brkFlag != 0);
  531.  
  532.     return(brkFlag);
  533. }
  534.  
  535.  
  536. STATIC LONG SendPacket(struct XPR_IO *io, UBYTE *fileBuf, ULONG dataLen)
  537. {
  538.     struct XProtocolData *xData = (struct XProtocolData *)io->xpr_data;
  539.     LONG retVal;
  540.     WORD i, out;
  541.     UBYTE *ptr;
  542.  
  543.     ptr = fileBuf;
  544.  
  545.     for(i=0, out=0; i<dataLen; i++, ptr++)
  546.     {
  547.         if(isprint(*ptr) == FALSE)
  548.         {
  549.             switch(*ptr)
  550.             {
  551.                 case '\n':
  552.                     switch(xData->LF_Mode)
  553.                     {
  554.                         case STRIP_MODE:
  555.                             ;
  556.                         break;
  557.  
  558.                         case ADD_MODE:
  559.                             xData->SerBuf[out++] = '\r';
  560.                             xData->SerBuf[out++] = '\n';
  561.                         break;
  562.  
  563.                         case EXCHANGE_MODE:
  564.                             xData->SerBuf[out++] = '\r';
  565.                         break;
  566.  
  567.                         default:
  568.                             xData->SerBuf[out++] = '\n';
  569.                         break;
  570.  
  571.                     }
  572.                 break;
  573.  
  574.                 case '\r':
  575.                     switch(xData->CR_Mode)
  576.                     {
  577.                         case STRIP_MODE:
  578.                             ;
  579.                         break;
  580.  
  581.                         case ADD_MODE:
  582.                             xData->SerBuf[out++] = '\r';
  583.                             xData->SerBuf[out++] = '\n';
  584.                         break;
  585.  
  586.                         case EXCHANGE_MODE:
  587.                             xData->SerBuf[out++] = '\n';
  588.                         break;
  589.  
  590.                         default:
  591.                             xData->SerBuf[out++] = '\r';
  592.                         break;
  593.  
  594.                     }
  595.                 break;
  596.  
  597.                 default:
  598.                     xData->SerBuf[out++] = *ptr;
  599.                 break;
  600.  
  601.             }
  602.  
  603.             if(isprint(ptr[1]) != FALSE)
  604.             {
  605.                 if((retVal = SendLine(io, xData->SerBuf, out)) != 0)
  606.                     return(retVal);
  607.  
  608.                 out = 0;
  609.             }
  610.         }
  611.         else
  612.             xData->SerBuf[out++] = *ptr;
  613.     }
  614.  
  615.     if(out > 0)        /* Anything left in the buffer? Flush it! */
  616.     {
  617.         if((retVal = SendLine(io, xData->SerBuf, out)) != 0)
  618.             return(retVal);
  619.     }
  620.  
  621.     return(0);
  622. }
  623.  
  624. VOID    uuencode_header(UBYTE *name, UBYTE *buf);
  625. VOID    uuencode_footer(UBYTE *buf, ULONG size);
  626. VOID    uuencode(UBYTE *in, UBYTE *out, UBYTE *temp, UBYTE len);
  627. BOOL    uudecode(VOID);
  628.  
  629.  
  630. LONG __saveds __asm XProtocolSend(register __a0 struct XPR_IO *io)
  631. {
  632.     struct XProtocolData *xData;
  633.     VOID *fp;
  634.     LONG read, size, brkFlag;
  635.  
  636.     if(test(io) == FALSE)
  637.         return(XPRS_FAILURE);
  638.  
  639.     if(io->xpr_data == NULL)
  640.     {
  641.         if(setup(io) == FALSE)
  642.         {
  643.             upderr(io, "Ran out of memory!");
  644.             return(XPRS_FAILURE);
  645.         }
  646.     }
  647.     xData = (struct XProtocolData *)io->xpr_data;
  648.  
  649.  
  650.     fp = (void *)io->xpr_fopen(io->xpr_filename, "r");
  651.    if(fp == NULL)
  652.     {
  653.         upderr(io, "Failed to open input file \"%s\"", io->xpr_filename);
  654.         return(XPRS_FAILURE);
  655.     }
  656.  
  657.  
  658.     xData->numerrs                    = 0;
  659.     xData->xpru.xpru_bytes        = 0;
  660.     xData->xpru.xpru_blocks        = 0;
  661.     xData->xpru.xpru_blocksize    = 0;
  662.  
  663.  
  664.     if(xData->BinToASCII != FALSE)
  665.     {
  666.         uuencode_header(io->xpr_filename, xData->FileBuf);
  667.         SendPacket(io, xData->FileBuf, strlen(xData->FileBuf));
  668.     }
  669.  
  670.     xData->xpru.xpru_updatemask= XPRU_FILENAME  | XPRU_PACKETDELAY |
  671.                                           XPRU_CHARDELAY | XPRU_PROTOCOL | XPRU_MSG;
  672.     xData->xpru.xpru_filename    = io->xpr_filename;
  673.     xData->xpru.xpru_packetdelay=xData->LineDelay * 20;    /* msec! */
  674.     xData->xpru.xpru_chardelay    = xData->CharDelay * 20;    /* msec! */
  675.  
  676.     xData->xpru.xpru_protocol    = "ascii";
  677.     xData->xpru.xpru_msg = (xData->BinToASCII == FALSE) ? "Starting ASCII Send" :
  678.                                             "Starting ASCII Send  [uuencoded file]";
  679.     io->xpr_update(&xData->xpru);
  680.  
  681.     brkFlag = 0;
  682.     size = 0;
  683.     while(read = io->xpr_fread(xData->FileBuf, 1, FILEBUF, fp))
  684.     {
  685.         WORD inBuf, sentOut;
  686.         UBYTE *fileBuf, *outBuf;
  687.  
  688.         xData->FileBuf[read] = '\0';
  689.  
  690.         size += read;
  691.  
  692.         for(inBuf=read, fileBuf=xData->FileBuf; inBuf>0; fileBuf+=sentOut, inBuf-=sentOut)
  693.         {
  694.             UWORD readyToSend;
  695.  
  696.             if(xData->BinToASCII != FALSE)
  697.             {
  698.                 sentOut = (inBuf > 45) ? 45 : inBuf;
  699.  
  700.                 outBuf = xData->BTA_outbuf;
  701.                 uuencode(fileBuf, outBuf, xData->BTA_tmpbuf, sentOut);
  702.                 readyToSend = strlen(outBuf);
  703.             }
  704.             else
  705.             {
  706.                 outBuf    = fileBuf;
  707.                 sentOut    = strcspn(outBuf, "\n\r");
  708.                 if(outBuf[sentOut] != '\0')
  709.                     sentOut++;
  710.  
  711.                 if(sentOut == 0)
  712.                 {
  713.                     UWORD i;
  714.  
  715.                     sentOut++;
  716.                     for(i=0; i<inBuf; i++)
  717.                     {
  718.                         if(outBuf[i] == '\0')    /* collect null's */
  719.                             sentOut++;
  720.                     }
  721.                 }
  722.  
  723.                 if(sentOut > inBuf)    /* just to be on the wild side..(-; */
  724.                     sentOut = inBuf;
  725.  
  726.                 readyToSend = sentOut;
  727.             }
  728.  
  729.             if((brkFlag = SendPacket(io, outBuf, readyToSend)) != 0)
  730.                 goto bibi;
  731.         }
  732.     }
  733.  
  734.     if(xData->BinToASCII != FALSE)
  735.     {
  736.         UBYTE *tmp;
  737.  
  738.         tmp = xData->BTA_outbuf;
  739.         uuencode("", tmp, xData->BTA_tmpbuf, 0);
  740.         SendPacket(io, tmp, strlen(tmp));
  741.  
  742.         uuencode_footer(tmp, size);
  743.         SendPacket(io, tmp, strlen(tmp));
  744.     }
  745.  
  746.  
  747. bibi:
  748.     io->xpr_fclose(fp);
  749.  
  750.     xData->xpru.xpru_updatemask = XPRU_MSG;
  751.     xData->xpru.xpru_msg = (brkFlag != 0) ? "Aborted" : "Done";
  752.     io->xpr_update(&xData->xpru);
  753.  
  754.     return((brkFlag != 0) ? XPRS_SUCCESS : XPRS_FAILURE);
  755. }
  756.  
  757.  
  758.  
  759. LONG __saveds __asm XProtocolReceive(register __a0 struct XPR_IO *io)
  760. {
  761.     struct XProtocolData *xData;
  762.     VOID *fp;
  763.     LONG bytesRead, fileSize, brkFlag=0;
  764.  
  765.     if(test(io) == FALSE)
  766.         return(XPRS_FAILURE);
  767.  
  768.     if(io->xpr_data == NULL)
  769.     {
  770.         if(setup(io) == FALSE)
  771.         {
  772.             upderr(io, "Ran out of memory!");
  773.             return(XPRS_FAILURE);
  774.         }
  775.     }
  776.     xData = (struct XProtocolData *)io->xpr_data;
  777.  
  778.  
  779.     if(xData->BinToASCII != FALSE)
  780.     {
  781.         if(strstr(io->xpr_filename, ".uue") == NULL)
  782.             strcat(io->xpr_filename, ".uue");
  783.     }
  784.  
  785.     fp = (void *)io->xpr_fopen(io->xpr_filename, "w");
  786.    if(fp == NULL)
  787.     {
  788.         upderr(io, "Failed to open output file \"%s\"", io->xpr_filename);
  789.         return(XPRS_FAILURE);
  790.    }
  791.  
  792.     xData->xpru.xpru_updatemask = XPRU_MSG | XPRU_PROTOCOL | XPRU_FILENAME;
  793.     xData->xpru.xpru_protocol    = "ascii";
  794.     xData->xpru.xpru_filename   = io->xpr_filename;
  795.     xData->xpru.xpru_msg = (xData->BinToASCII == FALSE) ? "Starting ASCII Receive" :
  796.                                             "Starting ASCII Receive [uuencoded file]";
  797.     io->xpr_update(&xData->xpru);
  798.  
  799.  
  800.     fileSize = 0;
  801.  
  802.     xData->numerrs                    = 0;
  803.     xData->xpru.xpru_bytes        = 0;
  804.     xData->xpru.xpru_blocks        = 0;
  805.     xData->xpru.xpru_blocksize    = 0;
  806.     while(bytesRead = io->xpr_sread(xData->SerBuf, 80, 5000000))
  807.     {
  808.         if(bytesRead < 0)
  809.         {
  810.            brkFlag = 1;
  811.            break;
  812.         }
  813.  
  814.         if(xData->StripHiBit != FALSE)
  815.         {
  816.             UWORD i;
  817.  
  818.             for(i=0; i<bytesRead; i++)
  819.                 xData->SerBuf[i] &= 0x7f;
  820.         }
  821.  
  822.         fileSize += bytesRead;
  823.  
  824.       xData->xpru.xpru_updatemask= XPRU_BYTES | XPRU_BLOCKS | XPRU_BLOCKSIZE;
  825.       xData->xpru.xpru_bytes       = fileSize;
  826.       xData->xpru.xpru_blocksize = bytesRead;
  827.       xData->xpru.xpru_blocks++;
  828.       io->xpr_update(&xData->xpru);
  829.  
  830.       io->xpr_fwrite(xData->SerBuf, 1, bytesRead, fp);
  831.  
  832.         if((brkFlag = io->xpr_chkabort()) != 0)
  833.             break;
  834.    }
  835.  
  836.  
  837.     io->xpr_fclose(fp);
  838.  
  839.     if(fileSize > 0)
  840.     {
  841.         if(xData->BinToASCII != FALSE  &&  brkFlag == 0)
  842.         {
  843.             BOOL ProcessUUeFile(struct XPR_IO *io, UBYTE *buf_source, UBYTE *buf_dest, VOID *fp_source);
  844.             BOOL success;
  845.  
  846.             fp = (void *)io->xpr_fopen(io->xpr_filename, "r");
  847.            if(fp == NULL)
  848.             {
  849.                 upderr(io, "Failed to reopen output file \"%s\"", io->xpr_filename);
  850.                 return(XPRS_FAILURE);
  851.            }
  852.  
  853.             success = ProcessUUeFile(io, xData->FileBuf, xData->BTA_outbuf, fp);
  854.  
  855.             io->xpr_fclose(fp);
  856.  
  857.             if(xData->DelTmpFile != FALSE  &&  success != FALSE)
  858.                 io->xpr_unlink(io->xpr_filename);
  859.         }
  860.     }
  861.     else
  862.         io->xpr_unlink(io->xpr_filename);
  863.  
  864.  
  865.     xData->xpru.xpru_updatemask = XPRU_MSG;
  866.     xData->xpru.xpru_msg = (brkFlag != 0) ? "Aborted" : "Done";
  867.     io->xpr_update(&xData->xpru);
  868.  
  869.     return((brkFlag != 0) ? XPRS_SUCCESS : XPRS_FAILURE);
  870. }
  871.  
  872.  
  873. LONG __saveds __asm XProtocolHostMon(register __a0 struct XPR_IO *io, register __a1 UBYTE *serbuff, register __d0 LONG actual, register __d1 LONG maxsize)
  874. {
  875.   return(actual);
  876. }
  877.  
  878.  
  879. LONG __saveds __asm XProtocolUserMon(register __a0 struct XPR_IO *io, register __a1 UBYTE *serbuff, register __d0 LONG actual, register __d1 LONG maxsize)
  880. {
  881.   return(actual);
  882. }
  883.  
  884.  
  885. STATIC BOOL test(struct XPR_IO *io)
  886. {
  887.     UBYTE *func;
  888.  
  889.     /* all we need..(-: */
  890.  
  891.     if(io->xpr_swrite == NULL)
  892.     {
  893.         func = "xpr_swrite";
  894.         goto error;
  895.     }
  896.  
  897.     if(io->xpr_sread == NULL)
  898.     {
  899.         func = "xpr_sread";
  900.         goto error;
  901.     }
  902.  
  903.     if(io->xpr_sflush == NULL)
  904.     {
  905.         func = "xpr_sflush";
  906.         goto error;
  907.     }
  908.  
  909.     if(io->xpr_fopen == NULL)
  910.     {
  911.         func = "xpr_fopen";
  912.         goto error;
  913.     }
  914.  
  915.     if(io->xpr_fwrite == NULL)
  916.     {
  917.         func = "xpr_fwrite";
  918.         goto error;
  919.     }
  920.  
  921.     if(io->xpr_fread == NULL)
  922.     {
  923.         func = "xpr_fread";
  924.         goto error;
  925.     }
  926.  
  927.     if(io->xpr_fclose == NULL)
  928.     {
  929.         func = "xpr_fclose";
  930.         goto error;
  931.     }
  932.  
  933.     if(io->xpr_update == NULL)
  934.     {
  935.         func = "xpr_update";
  936.         goto error;
  937.     }
  938.  
  939.     if(io->xpr_chkabort == NULL)
  940.     {
  941.         func = "xpr_chkabort";
  942.         goto error;
  943.     }
  944.  
  945.     return(TRUE);
  946.  
  947.  
  948. error:
  949.     upderr(io, "Comm prog missing required function \"%s", func);
  950.     return(FALSE);
  951. }
  952.  
  953.  
  954. STATIC BOOL setup(struct XPR_IO *io)
  955. {
  956.     struct XProtocolData *xData;
  957.  
  958.     io->xpr_data = AllocMem(sizeof(struct XProtocolData), MEMF_PUBLIC | MEMF_CLEAR);
  959.  
  960.     if(io->xpr_data == NULL)
  961.         return(FALSE);
  962.  
  963.    xData = (struct XProtocolData *)io->xpr_data;
  964.  
  965. /* some good settings.. */
  966.     xData->CharDelay    = 0;
  967.     xData->LineDelay    = 0;
  968.     xData->PromptChar    = '\0';
  969.  
  970.     xData->ExpandBlanks    = TRUE;
  971.     xData->StripHiBit        = FALSE;
  972.     xData->BinToASCII        = FALSE;
  973.     xData->DelTmpFile        = FALSE;
  974.  
  975.     xData->LF_Mode = NONE_MODE;
  976.     xData->CR_Mode = NONE_MODE;
  977.  
  978.     return(TRUE);
  979. }
  980.  
  981. /* Search for specified option setting in string */
  982. STATIC UBYTE *FindOption(UBYTE *buf, UBYTE option)
  983. {
  984.     while(*buf)
  985.     {
  986.         buf += strspn(buf," ,\t\r\n");
  987.         if(*buf == option)
  988.             return(++buf);
  989.         buf += strcspn(buf," ,\t\r\n");
  990.   }
  991.  
  992.   return(NULL);
  993. }
  994.  
  995.  
  996. STATIC VOID ParseConfigString(struct XPR_IO *io, char *buf)
  997. {
  998.     struct XProtocolData *xData = (struct XProtocolData *)io->xpr_data;
  999.     UBYTE *p;
  1000.  
  1001.     if(p = FindOption(buf, 'P'))
  1002.         xData->PromptChar = DecodePromptChar(p);
  1003.     else
  1004.     {
  1005.         if(p = FindOption(buf, 'p'))
  1006.             xData->PromptChar = DecodePromptChar(p);
  1007.     }
  1008.  
  1009.     strupr(buf);
  1010.  
  1011.     if(p = FindOption(buf, 'C'))
  1012.     {
  1013.         xData->CharDelay = AtoL(p);
  1014.         if(xData->CharDelay > 500)
  1015.             xData->CharDelay = 500;
  1016.     }
  1017.  
  1018.  
  1019.     if(p = FindOption(buf, 'L'))
  1020.     {
  1021.         xData->LineDelay = AtoL(p);
  1022.         if(xData->LineDelay > 500)
  1023.             xData->LineDelay = 500;
  1024.     }
  1025.  
  1026.  
  1027.     if(p = FindOption(buf, 'F'))
  1028.     {
  1029.         switch(*p)
  1030.         {
  1031.             case 'A':
  1032.                 xData->LF_Mode = ADD_MODE;
  1033.             break;
  1034.  
  1035.             case 'S':
  1036.                 xData->LF_Mode = STRIP_MODE;
  1037.             break;
  1038.  
  1039.             case 'X':
  1040.                 xData->LF_Mode = EXCHANGE_MODE;
  1041.             break;
  1042.  
  1043.             default:
  1044.                 xData->LF_Mode = NONE_MODE;
  1045.             break;
  1046.  
  1047.         }
  1048.     }
  1049.  
  1050.  
  1051.     if(p = FindOption(buf, 'R'))
  1052.     {
  1053.         switch(*p)
  1054.         {
  1055.             case 'A':
  1056.                 xData->CR_Mode = ADD_MODE;
  1057.             break;
  1058.  
  1059.             case 'S':
  1060.                 xData->CR_Mode = STRIP_MODE;
  1061.             break;
  1062.  
  1063.             case 'X':    /* LF -> CR */
  1064.                 xData->CR_Mode = EXCHANGE_MODE;
  1065.             break;
  1066.  
  1067.             default:
  1068.                 xData->CR_Mode = NONE_MODE;
  1069.             break;
  1070.  
  1071.         }
  1072.     }
  1073.  
  1074.  
  1075.     if(p = FindOption(buf, 'U'))
  1076.         xData->BinToASCII = (*p == '1');
  1077.  
  1078.  
  1079.     if(p = FindOption(buf, 'D'))
  1080.         xData->DelTmpFile = (*p == '1');
  1081.  
  1082.  
  1083.     if(p = FindOption(buf, 'E'))
  1084.         xData->ExpandBlanks = (*p == '1');
  1085.  
  1086.  
  1087.     if(p = FindOption(buf, 'S'))
  1088.         xData->StripHiBit = (*p == '1');
  1089. }
  1090.  
  1091.  
  1092. LONG AtoL(STRPTR string)
  1093. {
  1094.     LONG value=0;
  1095.  
  1096.     return((StrToLong(string, &value) > 0) ? value : 0);
  1097. }
  1098.  
  1099. VOID __stdargs upderr(struct XPR_IO *io, UBYTE *err, ...)
  1100. {
  1101.     struct XProtocolData *xData = (struct XProtocolData *)io->xpr_data;
  1102.     struct XPR_UPDATE xpru;
  1103.     va_list varargs;
  1104.     UBYTE buff[256];
  1105.  
  1106.     va_start(varargs, err);
  1107.     vsprintf(buff,err,varargs);
  1108.     va_end(varargs);
  1109.  
  1110.     xpru.xpru_updatemask = XPRU_ERRORMSG;
  1111.     xpru.xpru_errormsg = buff;
  1112.  
  1113.     xpru.xpru_updatemask |= XPRU_ERRORS;
  1114.     if(xData != NULL)
  1115.     {
  1116.         xData->numerrs++;
  1117.         xpru.xpru_errors = xData->numerrs;
  1118.     }
  1119.     else
  1120.         xpru.xpru_errors = 1;
  1121.  
  1122.     io->xpr_update(&xpru);
  1123. }
  1124.  
  1125.  
  1126. STATIC VOID EncodePromptChar(UBYTE pChar, UBYTE *pBuf)
  1127. {
  1128.     pChar = ToUpper(pChar);
  1129.  
  1130.     if(isprint(pChar) == 0)
  1131.     {
  1132.         switch(pChar)
  1133.         {
  1134.             case '\0':
  1135.                 pBuf[0] = '\\';
  1136.                 pBuf[1] = '0';
  1137.                 pBuf[2] = '\0';
  1138.             break;
  1139.  
  1140.             case '\n':
  1141.                 pBuf[0] = '\\';
  1142.                 pBuf[1] = 'n';
  1143.                 pBuf[2] = '\0';
  1144.             break;
  1145.  
  1146.             case '\r':
  1147.                 pBuf[0] = '\\';
  1148.                 pBuf[1] = 'r';
  1149.                 pBuf[2] = '\0';
  1150.             break;
  1151.  
  1152.             case '\\':
  1153.                 pBuf[0] = '\\';
  1154.                 pBuf[1] = '\\';
  1155.                 pBuf[2] = '\0';
  1156.             break;
  1157.  
  1158.             default:
  1159.             {
  1160.                 pBuf[0] = '\\';
  1161.                 pBuf[1] = 'd';
  1162.                 sprintf(&pBuf[2], "%ld", pChar);
  1163.             }
  1164.             break;
  1165.  
  1166.         }
  1167.     }
  1168.     else
  1169.     {
  1170.         pBuf[0] = pChar;
  1171.         pBuf[1] = '\0';
  1172.     }
  1173. }
  1174.  
  1175.  
  1176. STATIC UBYTE DecodePromptChar(UBYTE *pBuf)
  1177. {
  1178.     if(pBuf[0] == '\\')
  1179.     {
  1180.         switch(ToUpper(pBuf[1]))
  1181.         {
  1182.             case 'D':
  1183.                 return((UBYTE)AtoL(&pBuf[2]));
  1184.  
  1185.             case 'N':
  1186.                 return('\n');
  1187.  
  1188.             case 'R':
  1189.                 return('\r');
  1190.  
  1191.             case '\\':
  1192.                 return('\\');
  1193.  
  1194.             default:
  1195.                 return('\0');
  1196.  
  1197.         }
  1198.     }
  1199.     else
  1200.         return(*pBuf);
  1201.  
  1202.     return(' ');
  1203. }
  1204.  
  1205.  
  1206.  
  1207. /* end of source-code */
  1208.