home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / comm / tcp / amitcp / src / l / inet-handler / handler / applmsg.c next >
Encoding:
Text File  |  1994-04-20  |  5.7 KB  |  215 lines

  1. /* Created: Wed Nov 10 13:25:17 1993 too
  2.  * Last modified: Wed Apr 20 18:50:10 1994 too
  3.  */
  4.  
  5.   while (applcbcur != applcbpos) {
  6.     struct Message * msg;
  7.     struct ApplPort * applport;
  8.     
  9.     applport = directIndex(struct ApplPort *, applcbbuf, applcbcur);
  10.  
  11. /*    DP("posp %ld, curp %ld, applp %ld\n", applcbpos, applcbcur, applport); */
  12.  
  13.     applcbcur += sizeof (struct ApplPort *);
  14.     applcbcur &= 0x3f * sizeof (struct ApplPort *);
  15.     /*
  16.      * packets have arrived to application msgport
  17.      * (signalled by interrupt)
  18.      */
  19.     if ((msg = GetMsg(&applport->ap_AMP.amp_Msgport)) != NULL) {
  20.       struct DosPacket * packet = msgToPkt(msg);
  21.       
  22.       DP("sd: %ld packet: %lx type: %ld, size: %ld, firstc: %ld",
  23.      applport->ap_Sd, packet, packet->dp_Type,
  24.      packet->dp_Arg3, ((char *)packet->dp_Arg2)[0]);
  25.       
  26.       switch (packet->dp_Type) {
  27.       case ACTION_WRITE:
  28.     if (applport->ap_Pw)
  29.       ReplyPkt(packet, DOSFALSE, ERROR_OBJECT_IN_USE);
  30.     else {
  31.       int sent;
  32.       int len = packet->dp_Arg3; /*Side Note: no less code generated
  33.                        without len declared */
  34.       /*
  35.        * Send message to socket.
  36.        */
  37.       if ((sent = send(applport->ap_Sd, (char *)packet->dp_Arg2,
  38.                len , 0)) == len)
  39.         ReplyPkt(packet, sent, 0);
  40.       else {
  41.         /*
  42.          * The whole message could not be sent. Keep rest and set
  43.          * write flag to select.
  44.          */
  45.         struct PendingWrites * pw;
  46.  
  47.         if (sent == -1)
  48.           if (Errno() != EWOULDBLOCK) {
  49.         ReplyPkt(packet, -1, 0); /* -1 == EOF in Write() */
  50.         break;
  51.           }
  52.           else
  53.         sent = 0;
  54.         
  55.         if ((pw = getBuffer((struct List *)&freewritelist,
  56.                 sizeof (struct PendingWrites))) == NULL)
  57.           ReplyPkt(packet, sent, 0);
  58.         else {
  59.           /*
  60.            */
  61.           pw->pw_Applport = applport;
  62.           applport->ap_Pw = pw;
  63.           FD_SET(applport->ap_Sd, &writefds);
  64.           writespending++;
  65.           /*
  66.            */
  67.           pw->pw_Start = (char *)packet->dp_Arg2 + sent;
  68.           pw->pw_Left = len - sent;
  69.           pw->pw_Len = len;
  70.           pw->pw_Packet = packet;
  71.           AddTail((struct List *)&writelist, &pw->pw_Link);
  72.         }
  73.       }
  74.     }
  75.     break;
  76.       case ACTION_READ:
  77.     /*
  78.      * Check that there is no ACTION_READ or ACTION_WAIT_CHAR
  79.      * packets already received.
  80.      */
  81.     if (applport->ap_Packet != NULL)
  82.       ReplyPkt(packet, DOSFALSE, ERROR_OBJECT_IN_USE);
  83.     
  84.     else if (applport->ap_Disb == TRUE) {
  85.       /*
  86.        * Data already in socket buffer. Reply it and enable
  87.        * notification of arriving data to this socket 
  88.        * (unless EOF)
  89.        */
  90.       int len;
  91.       len = recv(applport->ap_Sd, (char *)packet->dp_Arg2,
  92.              packet->dp_Arg3, 0);
  93.  
  94.       DP("sd: len %ld\n", len);
  95.       /*
  96.        * len == 0? -> EOF. *Don't* reset operation...
  97.        */
  98.       if (len > 0) {
  99.         FD_SET(applport->ap_Sd, &readfds);
  100.         applport->ap_Disb = FALSE;
  101.       }
  102.       ReplyPkt(packet, len, 0);
  103.     }
  104.     else
  105.       applport->ap_Packet = packet;
  106.     
  107.     break;
  108.       case ACTION_WAIT_CHAR:
  109.     /*
  110.      * WaitForChar. same check as in ACTION_READ.
  111.      */
  112.     if (applport->ap_Packet != NULL)
  113.       ReplyPkt(packet, DOSFALSE, ERROR_OBJECT_IN_USE);
  114.     else if (applport->ap_Disb == TRUE) {
  115.       /*
  116.        * Data already in socket buffer... it it not read here.
  117.        */
  118.       LONG size;
  119.       
  120.       IoctlSocket(applport->ap_Sd, FIONREAD, (char *)&size);
  121.       ReplyPkt(packet, size, 0);
  122.     }
  123.     else if (packet->dp_Arg1 == 0)
  124.       /*
  125.        * No timeout. Reply there is 0 characters available
  126.        */
  127.       ReplyPkt(packet, 0, 0);
  128.     else {
  129.       /*
  130.        * No data and timeout: send timerequest and leave packet
  131.        * waiting for data to arrive or timeout expire.
  132.        */
  133.       applport->ap_Packet = packet;
  134.       Send_Timeout(&applport->ap_Tr, packet->dp_Arg1);
  135.     }
  136.     break;
  137.       case ACTION_STACK: /* Currently fast hack to support packet aborting */
  138.     if (applport->ap_Packet == NULL) {
  139.       ReplyPkt(packet, packet->dp_Arg3, 0); /* actually dropped
  140.                            the stuff */
  141.       break;
  142.     }
  143.     { int i, len = packet->dp_Arg3 > applport->ap_Packet->dp_Arg3 ?
  144.         applport->ap_Packet->dp_Arg3: packet->dp_Arg3;
  145.  
  146.       for(i = 0; i < len; i++)
  147.         ((char *)applport->ap_Packet->dp_Arg2)[i] =
  148.           ((char *)packet->dp_Arg2)[i];
  149.  
  150.       ReplyPkt(packet, len, 0);
  151.       ReplyPkt(applport->ap_Packet, len, 0);
  152.       applport->ap_Packet = NULL;
  153.     }
  154.     break;
  155.       case ACTION_END:  /* should we do this if packets in ? */
  156.     if (--applport->ap_OpenCnt == 0) {
  157.       int sd = applport->ap_Sd;
  158.  
  159.       if (sd == lastsd)
  160.         lastmask = 0;    /* lastappl won't exist anymore */
  161.  
  162.       nfds--;
  163.       if (sd < nfds) {
  164.         Dup2Socket(nfds, sd);
  165.         applarray[sd] = applarray[nfds];
  166.         applarray[sd]->ap_Sd = sd;
  167.         if (FD_ISSET(nfds, &readfds))
  168.           FD_SET(sd, &readfds);
  169.         else
  170.           FD_CLR(sd, &readfds);
  171.         DP("socket %ld now %ld", nfds, sd);
  172.       }
  173.       CloseSocket(nfds);
  174.       FD_CLR(nfds, &readfds);
  175.       
  176.       if (applport->ap_Packet) {
  177.         if (applport->ap_Packet->dp_Type == ACTION_WAIT_CHAR)
  178.           Abort_Timeout(&applport->ap_Tr);
  179.         ReplyPkt(applport->ap_Packet, 0, 0);
  180.       }
  181.       
  182.       if (applport->ap_Pw) {
  183.         ReplyPkt(applport->ap_Pw->pw_Packet, applport->ap_Pw->pw_Len, 0);
  184.         writespending--;  /* identical code 2 times */
  185.         FD_CLR(sd, &writefds);
  186.         AddTail((struct List *)&freewritelist, &applport->ap_Pw->pw_Link);
  187.       }
  188.       AddTail((struct List *)&freeappllist,
  189.           &applport->ap_AMP.amp_Msgport.mp_Node);
  190.     }
  191.     ReplyPkt(packet, DOSTRUE, 0);
  192.     break;
  193.       case ACTION_FINDINPUT:
  194.       case ACTION_FINDOUTPUT:
  195.       case ACTION_FINDUPDATE:
  196.     {
  197.       struct FileHandle * fh =
  198.         (struct FileHandle *)BADDR(packet->dp_Arg1);
  199.       /*
  200.        * Same FileHandle information as in open packet.
  201.        */
  202.       fh->fh_Arg1 = (LONG)applport >> 2;
  203.       fh->fh_Port = (struct MsgPort *)DOSTRUE;  /* IsInteractive() */
  204.       fh->fh_Type = &applport->ap_AMP.amp_Msgport;
  205.     }
  206.     applport->ap_OpenCnt++;
  207.     ReplyPkt(packet, DOSTRUE, packet->dp_Res2);
  208.     break;
  209.       default:
  210.     ReplyPkt(packet, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
  211.     break;
  212.       }
  213.     }
  214.   }
  215.