home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / internet-tools / amitcp / amitcp-sdk-4.3 / src / netlib / pkts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-21  |  4.2 KB  |  207 lines

  1. /*
  2.  * $Id: pkts.c,v 1.1 1996/01/21 01:26:36 jraja Exp $
  3.  *
  4.  * Simplified doublebuffered AmigaDOS IO.
  5.  * 
  6.  * Author: Tomi Ollila <Tomi.Ollila@nsdi.fi>
  7.  *
  8.  *     Copyright (c) 1994 Network Solutions Development Inc. OY
  9.  *                 All rights reserved
  10.  *
  11.  * Created: Thu Sep 15 06:11:55 1994 too
  12.  * Last modified: Thu Sep 15 08:33:18 1994 too
  13.  *
  14.  * HISTORY 
  15.  * $Log: pkts.c,v $
  16.  * Revision 1.1  1996/01/21 01:26:36  jraja
  17.  * Initial revision
  18.  *
  19.  */
  20.  
  21. #include <exec/types.h>
  22. #include <exec/ports.h>
  23. #include <dos/dos.h>
  24. #include <dos/dosextens.h>
  25.  
  26. #include <string.h>        /* memset() */
  27. #include <errno.h>
  28.  
  29. #if __GNUC__
  30. #include <inline/exec.h>
  31. #include <inline/dos.h>
  32. #error ios1 is SAS/C specific
  33. #elif __SASC
  34. #include <proto/exec.h>
  35. #include <proto/dos.h>
  36. #include <ios1.h>        /* SAS/C, chkufb() */
  37. #else
  38. #error :foo
  39. #endif
  40.  
  41. #include "pkts.h"
  42.  
  43. extern int __io2errno(long);
  44.  
  45. int
  46. initPktInfo(struct pktinfo * pkti, int fd, char * buf1, char * buf2, int size)
  47. {
  48.   struct DosPacket * pkt;
  49.   struct MsgPort * port;
  50.   struct UFB * ufb;
  51.   struct FileHandle * fh;
  52.  
  53.   memset(pkti, 0, sizeof(*pkti));
  54.  
  55.   /*
  56.    * get AmigaDOS file handle from SAS/C file handle
  57.    */
  58.   ufb = chkufb(fd);
  59.   if (ufb == NULL || ufb->ufbfh == NULL) {
  60.     errno = EBADF;
  61.     return -1;
  62.   }
  63.   /* convert DOS file handle to struct FileHandle * */
  64.   fh = BADDR((BPTR)ufb->ufbfh);
  65.   pkti->fhType = fh->fh_Type;
  66.  
  67.   port = CreateMsgPort();
  68.   if (port != NULL) {
  69.     pkti->port = port;
  70.  
  71.     pkt = (struct DosPacket *)AllocDosObject(DOS_STDPKT, 0);
  72.     if (pkt != NULL) {
  73.       pkti->pkt = pkt;
  74.  
  75.       pkti->bufs[0] = buf1;
  76.       pkti->bufs[1] = buf2;
  77.       pkti->whichbuf = 0;
  78.  
  79.       pkt->dp_Arg1 = fh->fh_Arg1;
  80.  
  81.       /*
  82.        * Do the initial action. Do nothing if file is NIL:
  83.        */
  84.       if (pkti->fhType == NULL) {
  85.     pkt->dp_Res1 = 0; /* keep everyone happy */
  86.     pkt->dp_Arg3 = 0;
  87.     AddTail(&port->mp_MsgList, (struct Node *)pkt->dp_Link);
  88.       }
  89.       else {
  90.     if (size == 0) {
  91.       pkt->dp_Type = ACTION_WRITE;
  92.       AddTail(&port->mp_MsgList, (struct Node *)pkt->dp_Link);
  93.     }
  94.     else {
  95.       pkt->dp_Arg2 = (LONG)buf1;
  96.       pkt->dp_Arg3 = size;
  97.       pkt->dp_Type = ACTION_READ;
  98.       SendPkt(pkt, pkti->fhType, port);
  99.     }
  100.       }
  101.       return 0;
  102.     }
  103.  
  104.     DeleteMsgPort(port);
  105.   }
  106.  
  107.   errno = ENOMEM;
  108.   return -1;
  109. }
  110.  
  111. int
  112. deInitPktInfo(struct pktinfo * pkti)
  113. {
  114.   int rv;
  115.   /*
  116.    * Take the packet out of the port, save the return code
  117.    */
  118.   WaitPort(pkti->port);
  119.   rv = pkti->pkt->dp_Res1;
  120.   /*
  121.    * Set errno if error
  122.    */
  123.   if (rv < 0 || 
  124.       (pkti->pkt->dp_Type == ACTION_WRITE && rv < pkti->pkt->dp_Arg3)) {
  125.     errno = __io2errno(_OSERR = pkti->pkt->dp_Res2);
  126.     rv = -1;
  127.   }
  128.   
  129.   pkti->fhType = NULL;
  130.   
  131.   FreeDosObject(DOS_STDPKT, pkti->pkt);
  132.   DeleteMsgPort(pkti->port);
  133.  
  134.   memset(pkti, 0, sizeof(*pkti));
  135.  
  136.   return rv;
  137. }
  138.  
  139. #define msgToPkt(msg) ((struct DosPacket *)msg->mn_Node.ln_Name)
  140.  
  141. int
  142. readPkt(struct pktinfo * pkti, char ** buf)
  143. {
  144.   struct DosPacket * pkt;
  145.   int rv;
  146.   
  147.   /*
  148.    * If file is NIL:, return 0 to end the reading
  149.    */
  150.   if (pkti->fhType == NULL)
  151.     return 0;
  152.   
  153.   WaitPort(pkti->port);
  154.   pkt = msgToPkt(GetMsg(pkti->port));
  155.  
  156.   rv = pkt->dp_Res1;
  157.  
  158.   if (rv > 0) {
  159.     *buf = pkti->bufs[pkti->whichbuf];
  160.     pkti->whichbuf ^= 1;
  161.  
  162.     pkt->dp_Arg2 = (LONG)pkti->bufs[pkti->whichbuf];
  163.     SendPkt(pkt, pkti->fhType, pkti->port);
  164.   }
  165.   else {
  166.     if (rv < 0)
  167.       errno = __io2errno(_OSERR = pkt->dp_Res2);
  168.     pkt->dp_Res1 = 0; /* do not receive same error again */
  169.     AddTail(&pkti->port->mp_MsgList, (struct Node *)pkt->dp_Link);
  170.   }
  171.   
  172.   return rv;
  173. }
  174.  
  175. int
  176. writePkt(struct pktinfo * pkti, char ** buf, int len)
  177. {
  178.   struct DosPacket * pkt;
  179.   
  180.   WaitPort(pkti->port);
  181.   pkt = msgToPkt(GetMsg(pkti->port));
  182.  
  183.   if (pkt->dp_Res1 < pkt->dp_Arg3) {
  184.     errno = __io2errno(_OSERR = pkt->dp_Res2);
  185.     pkt->dp_Res1 = pkt->dp_Arg3 = 0; /* do not receive same error again */
  186.     AddTail(&pkti->port->mp_MsgList, (struct Node *)pkt->dp_Link);
  187.     return -1;
  188.   }
  189.  
  190. /* Assert (*buf ==  pkti->whichbuf); */
  191.  
  192.   pkt->dp_Arg2 = (LONG)*buf;
  193.   pkt->dp_Arg3 = len;
  194.  
  195.   if (pkti->fhType != NULL)
  196.     SendPkt(pkt, pkti->fhType, pkti->port);
  197.   else {
  198.     pkt->dp_Res1 = len;        /* writing to NIL: always succeeds */
  199.     AddTail(&pkti->port->mp_MsgList, (struct Node *)pkt->dp_Link);
  200.   }
  201.  
  202.   pkti->whichbuf ^= 1;
  203.   *buf = pkti->bufs[pkti->whichbuf];
  204.  
  205.   return len;
  206. }
  207.