home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / INTERNET / UPC2S1.ZIP / ULIBNMP.C < prev    next >
C/C++ Source or Header  |  1993-10-03  |  21KB  |  632 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    u l i b n m p . c                                               */
  3. /*                                                                    */
  4. /*    OS/2 named pipe support for UUCICO                              */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*    Changes Copyright (c) 1989-1993 by Kendra Electronic            */
  9. /*    Wonderworks.                                                    */
  10. /*                                                                    */
  11. /*    All rights reserved except those explicitly granted by the      */
  12. /*    UUPC/extended license agreement.                                */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. /*--------------------------------------------------------------------*/
  16. /*                          RCS Information                           */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*
  20.  *       $Id: ulibnmp.c 1.7 1993/10/03 22:09:09 ahd Exp $
  21.  *       $Log: ulibnmp.c $
  22.  * Revision 1.7  1993/10/03  22:09:09  ahd
  23.  * Use unsigned long to display speed
  24.  *
  25.  * Revision 1.6  1993/10/03  20:37:34  ahd
  26.  * Delete redundant error messages
  27.  *
  28.  * Revision 1.5  1993/09/29  04:49:20  ahd
  29.  * Delete obsolete variable
  30.  *
  31.  * Revision 1.4  1993/09/27  00:45:20  ahd
  32.  * OS/2 16 bit support
  33.  *
  34.  * Revision 1.3  1993/09/25  03:07:56  ahd
  35.  * Various small bug fixes
  36.  *
  37.  * Revision 1.2  1993/09/24  03:43:27  ahd
  38.  * General bug fixes to make work
  39.  *
  40.  * Revision 1.1  1993/09/23  03:26:51  ahd
  41.  * Initial revision
  42.  *
  43.  *
  44.  */
  45.  
  46. /*--------------------------------------------------------------------*/
  47. /*                        System include files                        */
  48. /*--------------------------------------------------------------------*/
  49.  
  50. #include <stdlib.h>
  51. #include <stdio.h>
  52. #include <string.h>
  53. #include <fcntl.h>
  54. #include <io.h>
  55. #include <time.h>
  56.  
  57. /*--------------------------------------------------------------------*/
  58. /*                         OS/2 include files                         */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. #define INCL_DOSDEVIOCTL
  62. #define INCL_BASE
  63. #include <os2.h>
  64. #include <limits.h>
  65.  
  66. #ifndef __OS2__
  67. typedef USHORT APIRET ;  // Define older API return type
  68. #endif
  69.  
  70. /*--------------------------------------------------------------------*/
  71. /*                    UUPC/extended include files                     */
  72. /*--------------------------------------------------------------------*/
  73.  
  74. #include "lib.h"
  75. #include "ulibnmp.h"
  76. #include "ssleep.h"
  77. #include "catcher.h"
  78.  
  79. #include "commlib.h"
  80. #include "pos2err.h"
  81.  
  82. /*--------------------------------------------------------------------*/
  83. /*                          Global variables                          */
  84. /*--------------------------------------------------------------------*/
  85.  
  86. currentfile();
  87.  
  88. static boolean   carrierDetect = FALSE;  /* Modem is not connected     */
  89.  
  90. static boolean hangupNeeded = FALSE;
  91.  
  92. static BPS currentSpeed = 0;
  93.  
  94. static boolean passive;
  95.  
  96. #define FAR_NULL ((PVOID) 0L)
  97.  
  98. /*--------------------------------------------------------------------*/
  99. /*           Definitions of control structures for DOS API            */
  100. /*--------------------------------------------------------------------*/
  101.  
  102. static HPIPE pipeHandle;
  103.  
  104. static USHORT writeWait = 200;
  105. static USHORT readWait = 50;
  106.  
  107. static int writes, reads, writeSpins, readSpins;
  108.  
  109. /*--------------------------------------------------------------------*/
  110. /*    p p a s s i v e o p e n l i n e                                 */
  111. /*                                                                    */
  112. /*    Open a server pipe connection                                   */
  113. /*--------------------------------------------------------------------*/
  114.  
  115. #ifdef __TURBOC__
  116. #pragma argsused
  117. #endif
  118.  
  119. int ppassiveopenline(char *name, BPS baud, const boolean direct )
  120. {
  121.  
  122.    APIRET rc;
  123.  
  124.    if (portActive)                  /* Was the port already active?    */
  125.       closeline();                  /* Yes --> Shutdown it before open */
  126.  
  127. #ifdef UDEBUG
  128.    printmsg(15, "ppassiveopenline: %s, %d", name, baud);
  129. #endif
  130.  
  131. /*--------------------------------------------------------------------*/
  132. /*                          Perform the open                          */
  133. /*--------------------------------------------------------------------*/
  134.  
  135. #ifdef __OS2__
  136.    rc =  DosCreateNPipe( (PSZ) "\\pipe\\uucp",
  137.                          &pipeHandle,
  138.                          NP_ACCESS_DUPLEX | NP_INHERIT | NP_NOWRITEBEHIND,
  139.                          NP_NOWAIT | 1,
  140.                          MAXPACK,
  141.                          MAXPACK,
  142.                          30000 );
  143. #else
  144.    rc =  DosMakeNmPipe(  (PSZ) "\\pipe\\uucp",
  145.                          &pipeHandle,
  146.                          NP_ACCESS_DUPLEX | NP_INHERIT | NP_NOWRITEBEHIND,
  147.                          NP_NOWAIT | 1,
  148.                          MAXPACK,
  149.                          MAXPACK,
  150.                          30000 );
  151. #endif
  152.  
  153. /*--------------------------------------------------------------------*/
  154. /*    Check the open worked.  We translation the common obvious       */
  155. /*    error of file in use to english, for all other errors are we    */
  156. /*    report the raw error code.                                      */
  157. /*--------------------------------------------------------------------*/
  158.  
  159.    if ( rc == ERROR_SHARING_VIOLATION)
  160.    {
  161.       printmsg(0,"Pipe %s already in use", name);
  162.       return TRUE;
  163.    }
  164.    else if ( rc )
  165.    {
  166.       printOS2error("DosCreateNPipe", rc );
  167.       return TRUE;
  168.    }
  169.  
  170. /*--------------------------------------------------------------------*/
  171. /*                           Set baud rate                            */
  172. /*--------------------------------------------------------------------*/
  173.  
  174.    SIOSpeed(baud);         // Just any old large number.
  175.  
  176.    traceStart( name );     // Enable logging
  177.  
  178.    portActive = TRUE;      /* Record status for error handler        */
  179.    passive    = TRUE;
  180.    carrierDetect = FALSE;  /* Modem is not connected                 */
  181.  
  182.    return 0;
  183.  
  184. } /* ppassiveopenline */
  185.  
  186. /*--------------------------------------------------------------------*/
  187. /*       p W a i t F o r N e t C o n n e c t                          */
  188. /*                                                                    */
  189. /*       Wait for network connection                                  */
  190. /*--------------------------------------------------------------------*/
  191.  
  192. boolean pWaitForNetConnect(int timeout)
  193. {
  194.  
  195.    time_t stop;
  196.  
  197.    stop  = time( NULL ) + timeout;
  198.  
  199.    do {
  200.  
  201. #ifdef __OS2__
  202.       APIRET rc = DosConnectNPipe( pipeHandle );
  203. #else
  204.       APIRET rc = DosConnectNmPipe( pipeHandle );
  205. #endif
  206.  
  207.       if ( rc == 0 )
  208.       {
  209.          hangupNeeded = TRUE;      /* Flag that the pipe is now dirty  */
  210.          return TRUE;
  211.       }
  212.       else if ( rc == ERROR_PIPE_NOT_CONNECTED )
  213.          ssleep(5);
  214.       else {
  215.          printOS2error("DosConnectNPipe", rc );
  216.          return FALSE;
  217.       } /* else */
  218.  
  219.    } while( (stop > time( NULL )) && ! terminate_processing );
  220.  
  221.    return FALSE;
  222.  
  223. }  /* pWaitForNetConnect */
  224.  
  225. /*--------------------------------------------------------------------*/
  226. /*    p a c t i v e o p e n l i n e                                   */
  227. /*                                                                    */
  228. /*    Open a client pipe connection                                   */
  229. /*--------------------------------------------------------------------*/
  230.  
  231. #ifdef __TURBOC__
  232. #pragma argsused
  233. #endif
  234.  
  235. int pactiveopenline(char *name, BPS baud, const boolean direct )
  236. {
  237.  
  238.    APIRET rc;
  239.  
  240. #ifdef __OS2__
  241.    ULONG action;
  242. #else
  243.    USHORT action;
  244. #endif
  245.  
  246.    if (portActive)                  /* Was the port already active?     */
  247.       closeline();                  /* Yes --> Shutdown it before open */
  248.  
  249.    printmsg(15, "pactiveopenline: %s", name);
  250.  
  251. /*--------------------------------------------------------------------*/
  252. /*                          Perform the open                          */
  253. /*--------------------------------------------------------------------*/
  254.  
  255.    rc = DosOpen( name,
  256.                  &pipeHandle,
  257.                  &action,
  258.                  0L,
  259.                  0 ,
  260.                  FILE_OPEN ,
  261.                  OPEN_FLAGS_FAIL_ON_ERROR |
  262.                  OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, 0L );
  263.  
  264. /*--------------------------------------------------------------------*/
  265. /*                       Check the open worked.                       */
  266. /*--------------------------------------------------------------------*/
  267.  
  268.    if ( rc )
  269.    {
  270.       printOS2error("DosOpen", rc );
  271.       return TRUE;
  272.    }
  273.  
  274. /*--------------------------------------------------------------------*/
  275. /*                           Set baud rate                            */
  276. /*--------------------------------------------------------------------*/
  277.  
  278.    SIOSpeed(57600);
  279.  
  280.    traceStart( name );     // Enable logging
  281.  
  282.    portActive = TRUE;      /* Record status for error handler        */
  283.    passive    = FALSE;
  284.    carrierDetect = FALSE;  /* Modem is not connected                 */
  285.  
  286.    return 0;
  287.  
  288. } /* pactiveopenline */
  289.  
  290. /*--------------------------------------------------------------------*/
  291. /*    p s r e a d                                                     */
  292. /*                                                                    */
  293. /*    Read from the pipe                                              */
  294. /*                                                                    */
  295. /*   Non-blocking read essential to "g" protocol.  See "dcpgpkt.c"    */
  296. /*   for description.                                                 */
  297. /*                                                                    */
  298. /*   This all changes in a multi-tasking system.  Requests for I/O    */
  299. /*   should get queued and an event flag given.  Then the             */
  300. /*   requesting process (e.g. gmachine()) waits for the event flag    */
  301. /*   to fire processing either a read or a write.  Could be           */
  302. /*   implemented on VAX/VMS or DG but not MS-DOS.                     */
  303. /*                                                                    */
  304. /*    OS/2 we could multitask, but we just let the system provide     */
  305. /*    a timeout for us with very little CPU usage.                    */
  306. /*--------------------------------------------------------------------*/
  307.  
  308. unsigned int psread(char *output, unsigned int wanted, unsigned int timeout)
  309. {
  310.    APIRET rc;
  311.    static char save[MAXPACK];
  312.    static USHORT bufsize = 0;
  313.    time_t stop_time ;
  314.    time_t now ;
  315.  
  316.    reads++;
  317.  
  318. /*--------------------------------------------------------------------*/
  319. /*           Determine if our internal buffer has the data            */
  320. /*--------------------------------------------------------------------*/
  321.  
  322.    if (bufsize >= wanted)
  323.    {
  324.       memmove( output, save, wanted );
  325.       bufsize -= wanted;
  326.       if ( bufsize )          /* Any data left over?                 */
  327.          memmove( save, &save[wanted], bufsize );  /* Yes --> Save it*/
  328.       return wanted + bufsize;
  329.    } /* if */
  330.  
  331. /*--------------------------------------------------------------------*/
  332. /*                 Determine when to stop processing                  */
  333. /*--------------------------------------------------------------------*/
  334.  
  335.    if ( timeout == 0 )
  336.    {
  337.       stop_time = 0;
  338.       now = 1;                /* Any number greater than stop time   */
  339.    }
  340.    else {
  341.       time( & now );
  342.       stop_time = now + timeout;
  343.    }
  344.  
  345. /*--------------------------------------------------------------------*/
  346. /*            Try to read any needed data into the buffer             */
  347. /*--------------------------------------------------------------------*/
  348.  
  349.    do {
  350.       USHORT needed =  (USHORT) wanted - bufsize;
  351.  
  352. #ifdef __OS2__
  353.       ULONG received = 0;
  354. #else
  355.       USHORT received = 0;
  356. #endif
  357.  
  358. /*--------------------------------------------------------------------*/
  359. /*                     Handle an aborted program                      */
  360. /*--------------------------------------------------------------------*/
  361.  
  362.       if ( terminate_processing )
  363.       {
  364.          static boolean recurse = FALSE;
  365.          if ( ! recurse )
  366.          {
  367.             printmsg(2,"sread: User aborted processing");
  368.             recurse = TRUE;
  369.          }
  370.          return 0;
  371.       }
  372.  
  373.       readSpins++;
  374.  
  375.       ddelay(readWait);
  376.  
  377. /*--------------------------------------------------------------------*/
  378. /*                 Read the data from the named pipe                  */
  379. /*--------------------------------------------------------------------*/
  380.  
  381.       rc = DosRead( pipeHandle, &save[bufsize], needed, &received );
  382.  
  383.       if ( rc == ERROR_NO_DATA)
  384.       {
  385.          received = 0;
  386.       }
  387.       else if ( rc )
  388.       {
  389.          printmsg(0,"psread: Read from pipe for %d bytes failed.",
  390.                   needed);
  391.          printOS2error("DosRead", rc );
  392.          bufsize = 0;
  393.          return 0;
  394.       }
  395.  
  396. #ifdef UDEBUG
  397.       printmsg(15,"psread: Want %d characters, received %d, total %d in buffer",
  398.             (int) wanted, (int) received, (int) bufsize + received);
  399. #endif
  400.  
  401. /*--------------------------------------------------------------------*/
  402. /*                    Log the newly received data                     */
  403. /*--------------------------------------------------------------------*/
  404.  
  405.       traceData( &save[bufsize], received, FALSE );
  406.  
  407. /*--------------------------------------------------------------------*/
  408. /*            If we got the data, return it to the caller             */
  409. /*--------------------------------------------------------------------*/
  410.  
  411.       bufsize += received;
  412.       if ( bufsize == wanted )
  413.       {
  414.          memmove( output, save, bufsize);
  415.          bufsize = 0;
  416.  
  417.          return wanted;
  418.       } /* if */
  419.  
  420. /*--------------------------------------------------------------------*/
  421. /*                 Update the clock for the next pass                 */
  422. /*--------------------------------------------------------------------*/
  423.  
  424.       if (stop_time > 0)
  425.          time( &now );
  426.  
  427.    } while (stop_time > now);
  428.  
  429. /*--------------------------------------------------------------------*/
  430. /*         We don't have enough data; report what we do have          */
  431. /*--------------------------------------------------------------------*/
  432.  
  433.    return bufsize;
  434.  
  435. } /* nsread */
  436.  
  437. /*--------------------------------------------------------------------*/
  438. /*    p s w r i t e                                                   */
  439. /*                                                                    */
  440. /*    Write to the named pipe                                         */
  441. /*--------------------------------------------------------------------*/
  442.  
  443. int pswrite(const char *input, unsigned int len)
  444. {
  445.  
  446.    char *data = (char *) input;
  447.    unsigned int left = len;
  448.  
  449. #ifdef __OS2__
  450.     ULONG bytes;
  451. #else
  452.    size_t bytes;
  453. #endif
  454.  
  455.    APIRET rc;
  456.  
  457.    hangupNeeded = TRUE;      /* Flag that the pipe is now dirty  */
  458.    writes ++;
  459.  
  460. /*--------------------------------------------------------------------*/
  461. /*         Write the data out as the queue becomes available          */
  462. /*--------------------------------------------------------------------*/
  463.  
  464.    do {
  465.  
  466.       rc = DosWrite( pipeHandle, data + len - left, left, &bytes);
  467.  
  468.       if (rc)
  469.       {
  470.          printOS2error("DosWrite", rc );
  471.          return bytes;
  472.       } /*if */
  473.  
  474.       left -= bytes;
  475.  
  476.       ddelay( writeWait );
  477.       writeSpins ++;
  478.  
  479.    } while( left > 0 );
  480.  
  481. /*--------------------------------------------------------------------*/
  482. /*                        Log the data written                        */
  483. /*--------------------------------------------------------------------*/
  484.  
  485.    traceData( data, len, TRUE);
  486.  
  487. /*--------------------------------------------------------------------*/
  488. /*            Return bytes written to the pipe to the caller          */
  489. /*--------------------------------------------------------------------*/
  490.  
  491.    return len;
  492.  
  493. } /* nswrite */
  494.  
  495. #ifdef __TURBOC__
  496. #pragma argsused
  497. #endif
  498.  
  499. /*--------------------------------------------------------------------*/
  500. /*    p s s e n d b r k                                               */
  501. /*                                                                    */
  502. /*    send a break signal out the pipe                                */
  503. /*--------------------------------------------------------------------*/
  504.  
  505. void pssendbrk(unsigned int duration)
  506. {
  507.    printmsg(0,"pssendbrk: BREAK not supported with named pipes");
  508. } /* nssendbrk */
  509.  
  510. /*--------------------------------------------------------------------*/
  511. /*    p c l o s e l i n e                                             */
  512. /*                                                                    */
  513. /*    Close the named pipe down                                       */
  514. /*--------------------------------------------------------------------*/
  515.  
  516. void pcloseline(void)
  517. {
  518.    APIRET rc;
  519.  
  520.    if ( ! portActive )
  521.       panic();
  522.  
  523.    portActive = FALSE; /* flag pipe closed for error handler  */
  524.    hangupNeeded = FALSE;  /* Don't fiddle with pipe any more  */
  525.  
  526.    printmsg(4,
  527.          "pcloseline: Read delay %d ms, Write delay %d ms",
  528.          (int) readWait,
  529.          (int) writeWait );
  530.  
  531.    printmsg(4,
  532.          "pcloseline: %d reads (%d waits), %d writes (%d waits)",
  533.          (int) reads,
  534.          (int) readSpins - reads,
  535.          (int) writes,
  536.          (int) writeSpins - writes );
  537.  
  538. /*--------------------------------------------------------------------*/
  539. /*                      Actually close the pipe                       */
  540. /*--------------------------------------------------------------------*/
  541.  
  542.    rc = DosClose( pipeHandle );
  543.  
  544.    if ( rc )
  545.       printOS2error("DosClose", rc );
  546.  
  547. /*--------------------------------------------------------------------*/
  548. /*                   Stop logging the data to disk                    */
  549. /*--------------------------------------------------------------------*/
  550.  
  551.    traceStop();
  552.  
  553. } /* pcloseline */
  554.  
  555. /*--------------------------------------------------------------------*/
  556. /*    p h a n g u p                                                   */
  557. /*                                                                    */
  558. /*    Hangup the link.  No operation on network.                      */
  559. /*--------------------------------------------------------------------*/
  560.  
  561. void phangup( void )
  562. {
  563.    if ( passive && hangupNeeded)
  564.    {
  565.  
  566. #ifdef __OS2__
  567.       DosDisConnectNPipe( pipeHandle );
  568. #else
  569.       DosDisConnectNmPipe( pipeHandle );
  570. #endif
  571.       hangupNeeded = FALSE;
  572.    }
  573.  
  574.    return;
  575.  
  576. } /* phangup */
  577.  
  578. /*--------------------------------------------------------------------*/
  579. /*    p S I O S p e e d                                               */
  580. /*                                                                    */
  581. /*    Re-specify the speed of an opened pipe; no operation, actually. */
  582. /*--------------------------------------------------------------------*/
  583.  
  584. #ifdef __TURBOC__
  585. #pragma argsused
  586. #endif
  587.  
  588. void pSIOSpeed(BPS baud)
  589. {
  590.    currentSpeed = baud;
  591.    return;
  592.  
  593. } /* pSIOSpeed */
  594.  
  595. /*--------------------------------------------------------------------*/
  596. /*    p f l o w c o n t r o l                                         */
  597. /*                                                                    */
  598. /*    Enable/Disable in band (XON/XOFF) flow control                  */
  599. /*--------------------------------------------------------------------*/
  600.  
  601. #ifdef __TURBOC__
  602. #pragma argsused
  603. #endif
  604.  
  605. void pflowcontrol( boolean flow )
  606. {
  607.    return;
  608. } /* pflowcontrol */
  609.  
  610. /*--------------------------------------------------------------------*/
  611. /*    n G e t S p e e d                                               */
  612. /*                                                                    */
  613. /*    Report current speed of communications connection               */
  614. /*--------------------------------------------------------------------*/
  615.  
  616. BPS pGetSpeed( void )
  617. {
  618.    return currentSpeed;
  619. } /* nGetSpeed */
  620.  
  621. /*--------------------------------------------------------------------*/
  622. /*   p C D                                                            */
  623. /*                                                                    */
  624. /*   Return status of carrier detect                                  */
  625. /*--------------------------------------------------------------------*/
  626.  
  627. boolean pCD( void )
  628. {
  629.    return carrierDetect;
  630.  
  631. } /* pCD */
  632.