home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff226.lzh / Vlt / xprlib / library / xprascii.c < prev    next >
C/C++ Source or Header  |  1989-06-25  |  8KB  |  292 lines

  1. /** xprascii.c
  2. *
  3. *   These are the protocol transfer routines for a simple ASCII upload.
  4. *
  5. **/
  6. #include <exec/exec.h>
  7. #include <functions.h>
  8. #include <stdio.h>
  9. /*
  10. *   xproto.h is the include file given in Appendix B.
  11. */
  12. #include "xproto.h"
  13. /*
  14. *   The following two strings must exist.
  15. */
  16. char  XPRname[]   = "xprascii.library";
  17. char  XPRid[]     = "xprascii 0.9 (May 89)\r\n";
  18. UWORD XPRrevision = 9;
  19.  
  20. long atol();
  21. /*
  22. *   The callxx...() routines are described later. They provide the 
  23. *   assembler interface from the XPR library to the call-back routines.
  24. */
  25. long calla(), callaa(), callad(), calladd(), calladda();
  26.  
  27. char *malloc();
  28.  
  29.  
  30. /**
  31. *
  32. *   Send a file
  33. *
  34. **/
  35. long XProtocolSend(IO)
  36. struct XPR_IO *IO;
  37. {
  38.    long fp, r, i;
  39.    long brkflag = 0, fl = 0L, sd = 0L;
  40.    long (*xupdate)(), (*xswrite)(), (*xfopen)(), (*xfclose)(), (*xfread)(),
  41.         (*xsread)(),  (*xchkabort)();
  42.    unsigned char *buff = NULL, *serbuff = NULL;
  43.    struct XPR_UPDATE xpru;
  44.  
  45. /*
  46. *   These are the call-backs we need. If any of them isn't provided, quit.
  47. *   Could do some error reporting if at least xupdate is there.
  48. */
  49.    if ((xupdate    = IO->xpr_update)   == NULL) return(0L);
  50.    if ((xswrite    = IO->xpr_swrite)   == NULL) return(0L);
  51.    if ((xfopen     = IO->xpr_fopen)    == NULL) return(0L);
  52.    if ((xfclose    = IO->xpr_fclose)   == NULL) return(0L);
  53.    if ((xfread     = IO->xpr_fread)    == NULL) return(0L);
  54.    if ((xsread     = IO->xpr_sread)    == NULL) return(0L);
  55.    if ((xchkabort  = IO->xpr_chkabort) == NULL) return(0L);
  56. /*
  57. *   Allocate a few buffers.
  58. */
  59.    buff    = (unsigned char *) malloc(80);
  60.    serbuff = (unsigned char *) malloc(80);
  61. /*
  62. *   If we ran out of memory, print a message.
  63. *   The argument needs to go in A0: calla does this for us. 
  64. */
  65.    if (buff == NULL || serbuff == NULL) {
  66.       xpru.xpru_updatemask = XPRU_ERRORMSG;
  67.       xpru.xpru_errormsg   = "Ran out of memory!";
  68.       calla(xupdate, &xpru);
  69.       return(0L);
  70.    }
  71. /*
  72. *   Read the send delay, if a XProtocolSetup() was done before.
  73. *   If send delay is too large, cut it off at 10 seconds.
  74. *   In this example, the xpr_data field contains a null terminated string
  75. *   containing the number of ticks to delay each 80 characters.
  76. */
  77.    if (IO->xpr_data) {
  78.       sd = atol(IO->xpr_data);
  79.       if (sd > 500L) sd == 500L;
  80.    }
  81. /*
  82. *   Open the file. One could do wild card detection here.
  83. *   xfopen requires two arguments, in a0 and a1 respectively.
  84. *   Again, this must be done in assembler, and callaa does it.
  85. */
  86.    fp = callaa(xfopen, IO->xpr_filename, "r");
  87.    if (fp == NULL) {
  88.       free(buff);
  89.       free(serbuff);
  90.       xpru.xpru_updatemask = XPRU_ERRORMSG | XPRU_FILENAME;
  91.       xpru.xpru_errormsg   = "Failed to open input file";
  92.       xpru.xpru_filename   = IO->xpr_filename;
  93.       calla(xupdate, &xpru);
  94.       return(0L);
  95.    }
  96. /*
  97. *   Start the transfer. See 3.8 for a discussion on how to implement
  98. *   xupdate. 
  99. */
  100.    xpru.xpru_updatemask = XPRU_MSG | XPRU_FILENAME;
  101.    xpru.xpru_msg        = "Starting ASCII Send";
  102.    xpru.xpru_filename   = IO->xpr_filename;
  103.    calla(xupdate, &xpru);
  104. /*
  105. *   Now read 80 byte chunks from the file using xfread.
  106. *   xfread requires four arguments, a0, d0, d1 and a1.
  107. */
  108.    xpru.xpru_blocks = 0L;
  109.    while (r = calladda(xfread, buff, 1L, 80L, fp)) {
  110. /*
  111. *   Convert line feeds to carriage returns before sending to host.
  112. *   fl counts the characters. Display how many characters are sent.
  113. */
  114.       for (i = 0L; i < r; i++) if (buff[i] == '\n') buff[i] = '\r';
  115.       fl += r;
  116.       xpru.xpru_updatemask = XPRU_BYTES | XPRU_BLOCKS | XPRU_BLOCKSIZE;
  117.       xpru.xpru_bytes      = fl;
  118.       xpru.xpru_blocks++;
  119.       xpru.xpru_blocksize  = r;
  120.       calla(xupdate, &xpru);
  121.       callad(xswrite, buff, r);
  122. /*
  123. *   Every 80 bytes, put out a message and delay if requested.
  124. */
  125.       xpru.xpru_updatemask  = XPRU_PACKETDELAY;
  126.       xpru.xpru_packetdelay = sd * 20L;  /* msec! */
  127.       calla(xupdate, &xpru);
  128. /*
  129. *   Can't use Delay() here, because Delay() is in dos.library!
  130. *   However writing an equivalent function using the timer.device is
  131. *   trivial.
  132. */
  133.       TimeOut(sd);
  134. /*
  135. *   Eat any characters that might arrive from the serial port.
  136. *   calladd stores arg1 in a0, arg2 in d0, arg3 in d1.
  137. *   We're not really waiting for any characters: use a timeout of 0L.
  138. */
  139.       while (calladd(xsread, serbuff, 80L, 0L) > 0L) ;
  140. /*
  141. *   Check for "abort" here. Perhaps should call chkmisc() as well.
  142. */
  143.       if (brkflag = xchkabort()) break;
  144.    }
  145. /*
  146. *   Close the file
  147. */
  148.    calla(xfclose, fp);
  149.    free(buff);
  150.    free(serbuff);
  151. /*
  152. *   If we got here through chkabort() say Aborted.
  153. */
  154.    xpru.xpru_updatemask       = XPRU_MSG;
  155.    if (brkflag) xpru.xpru_msg = "Aborted";
  156.    else         xpru.xpru_msg = "Done"; 
  157.    calla(xupdate, &xpru);
  158.    if (brkflag) return(0L);
  159.    else        return(1L);
  160. }
  161.  
  162.  
  163. /**
  164. *
  165. *   Receive a file.
  166. *
  167. **/
  168. long XProtocolReceive(IO)
  169. struct XPR_IO *IO;
  170. {
  171.    long (*xupdate)();
  172.    struct XPR_UPDATE xpru;
  173.  
  174.    if (xupdate = IO->xpr_update) {
  175.       xpru.xpru_updatemask = XPRU_MSG;
  176.       xpru.xpru_msg        = "ASCII receive is not implemented. Use capture?";
  177.       calla(xupdate, &xpru);
  178.    }
  179.    return(0L);
  180. }
  181.  
  182.  
  183. /**
  184. *
  185. *   Setup
  186. *
  187. **/
  188. long XProtocolSetup(IO)
  189. struct XPR_IO *IO;
  190. {
  191.    long (*xupdate)(), (*xgets)();
  192.    struct XPR_UPDATE xpru;
  193.  
  194.    if ((xupdate = IO->xpr_update) == NULL) return(0L);
  195.    if ((xgets   = IO->xpr_gets)   == NULL) return(0L);
  196. /*
  197. *   Allocate a bit of memory for a data buffer
  198. */
  199.    if (IO->xpr_data == NULL) {
  200.       if ((IO->xpr_data = (long *) malloc(256)) == NULL) {
  201.          xpru.xpru_updatemask = XPRU_ERRORMSG;
  202.          xpru.xpru_errormsg   = "ASCII - Out of memory!";
  203.          calla(xupdate, &xpru);
  204.          return(0L);
  205.       }
  206.    }
  207. /*
  208. *   If setup string isn't handed to us, ask questions
  209. */
  210.    if (IO->xpr_filename == NULL) {
  211. /*
  212. *   Get the value for the send dealy
  213. */
  214.       callaa(xgets, "Enter ASCII send delay (ticks, 1 tick = 20 msec)",
  215.                   IO->xpr_data);
  216.    }
  217.    else {
  218.       strcpy(IO->xpr_data, IO->xpr_filename);
  219.    }
  220.    
  221.    return(1L);
  222. }
  223.  
  224. /**
  225. *
  226. *   Cleanup
  227. *
  228. **/
  229. long XProtocolCleanup(IO)
  230. struct XPR_IO *IO;
  231. {
  232.    if (IO->xpr_data) free(IO->xpr_data);
  233.    IO->xpr_data = NULL;
  234.  
  235.    return(1L);
  236. }
  237.  
  238. /**
  239. *
  240. *   The following functions setup the proper registers for the call-back 
  241. *   functions.
  242. *
  243. **/
  244. #asm
  245.         public _callad
  246. _callad:
  247.         movea.l 4(sp),a2                ; First  argument is function
  248.         movea.l 8(sp),a0                ; Second argument goes in a0
  249.         move.l  12(sp),d0               ; Third  argument goes in d0
  250.         jsr     (a2)
  251.         rts
  252.  
  253.         public  _calladda
  254. _calladda:
  255.         movea.l 4(sp),a2                ; First  argument is function
  256.         movea.l 8(sp),a0                ; Second argument goes in a0
  257.         move.l  12(sp),d0               ; Third  argument goes in d0
  258.         move.l  16(sp),d1               ; Fourth argument goes in d1
  259.         movea.l 20(sp),a1               ; Fifth  argument goes in a1
  260.         jsr     (a2)
  261.         rts
  262.  
  263.         public  _calla
  264. _calla:
  265.         movea.l 4(sp),a2                ; First  argument is function
  266.         movea.l 8(sp),a0                ; Second argument goes in a0
  267.         jsr     (a2)
  268.         rts
  269.  
  270.         public  _callaa
  271. _callaa:
  272.         movea.l 4(sp),a2                ; First  argument is function
  273.         movea.l 8(sp),a0                ; Second argument goes in a0
  274.         movea.l 12(sp),a1               ; Third  argument goes in a1
  275.         jsr     (a2)
  276.         rts
  277.  
  278.         public  _calladd
  279. _calladd:
  280.         movea.l 4(sp),a2                ; First  argument is function
  281.         move.l  8(sp),a0                ; Second argument goes in a0
  282.         move.l  12(sp),d0               ; Third  argument goes in d0
  283.         move.l  16(sp),d1               ; Fourth argument goes in d1
  284.         jsr     (a2)
  285.         rts
  286.  
  287. #endasm
  288. /*
  289. *   Could have added any other functions needed for other call-backs.
  290. *   Could have written a fancier single one... Could've...
  291. */
  292.