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 >
Wrap
C/C++ Source or Header
|
1993-10-03
|
21KB
|
632 lines
/*--------------------------------------------------------------------*/
/* u l i b n m p . c */
/* */
/* OS/2 named pipe support for UUCICO */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Changes Copyright (c) 1989-1993 by Kendra Electronic */
/* Wonderworks. */
/* */
/* All rights reserved except those explicitly granted by the */
/* UUPC/extended license agreement. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/
/*
* $Id: ulibnmp.c 1.7 1993/10/03 22:09:09 ahd Exp $
* $Log: ulibnmp.c $
* Revision 1.7 1993/10/03 22:09:09 ahd
* Use unsigned long to display speed
*
* Revision 1.6 1993/10/03 20:37:34 ahd
* Delete redundant error messages
*
* Revision 1.5 1993/09/29 04:49:20 ahd
* Delete obsolete variable
*
* Revision 1.4 1993/09/27 00:45:20 ahd
* OS/2 16 bit support
*
* Revision 1.3 1993/09/25 03:07:56 ahd
* Various small bug fixes
*
* Revision 1.2 1993/09/24 03:43:27 ahd
* General bug fixes to make work
*
* Revision 1.1 1993/09/23 03:26:51 ahd
* Initial revision
*
*
*/
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
/*--------------------------------------------------------------------*/
/* OS/2 include files */
/*--------------------------------------------------------------------*/
#define INCL_DOSDEVIOCTL
#define INCL_BASE
#include <os2.h>
#include <limits.h>
#ifndef __OS2__
typedef USHORT APIRET ; // Define older API return type
#endif
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "ulibnmp.h"
#include "ssleep.h"
#include "catcher.h"
#include "commlib.h"
#include "pos2err.h"
/*--------------------------------------------------------------------*/
/* Global variables */
/*--------------------------------------------------------------------*/
currentfile();
static boolean carrierDetect = FALSE; /* Modem is not connected */
static boolean hangupNeeded = FALSE;
static BPS currentSpeed = 0;
static boolean passive;
#define FAR_NULL ((PVOID) 0L)
/*--------------------------------------------------------------------*/
/* Definitions of control structures for DOS API */
/*--------------------------------------------------------------------*/
static HPIPE pipeHandle;
static USHORT writeWait = 200;
static USHORT readWait = 50;
static int writes, reads, writeSpins, readSpins;
/*--------------------------------------------------------------------*/
/* p p a s s i v e o p e n l i n e */
/* */
/* Open a server pipe connection */
/*--------------------------------------------------------------------*/
#ifdef __TURBOC__
#pragma argsused
#endif
int ppassiveopenline(char *name, BPS baud, const boolean direct )
{
APIRET rc;
if (portActive) /* Was the port already active? */
closeline(); /* Yes --> Shutdown it before open */
#ifdef UDEBUG
printmsg(15, "ppassiveopenline: %s, %d", name, baud);
#endif
/*--------------------------------------------------------------------*/
/* Perform the open */
/*--------------------------------------------------------------------*/
#ifdef __OS2__
rc = DosCreateNPipe( (PSZ) "\\pipe\\uucp",
&pipeHandle,
NP_ACCESS_DUPLEX | NP_INHERIT | NP_NOWRITEBEHIND,
NP_NOWAIT | 1,
MAXPACK,
MAXPACK,
30000 );
#else
rc = DosMakeNmPipe( (PSZ) "\\pipe\\uucp",
&pipeHandle,
NP_ACCESS_DUPLEX | NP_INHERIT | NP_NOWRITEBEHIND,
NP_NOWAIT | 1,
MAXPACK,
MAXPACK,
30000 );
#endif
/*--------------------------------------------------------------------*/
/* Check the open worked. We translation the common obvious */
/* error of file in use to english, for all other errors are we */
/* report the raw error code. */
/*--------------------------------------------------------------------*/
if ( rc == ERROR_SHARING_VIOLATION)
{
printmsg(0,"Pipe %s already in use", name);
return TRUE;
}
else if ( rc )
{
printOS2error("DosCreateNPipe", rc );
return TRUE;
}
/*--------------------------------------------------------------------*/
/* Set baud rate */
/*--------------------------------------------------------------------*/
SIOSpeed(baud); // Just any old large number.
traceStart( name ); // Enable logging
portActive = TRUE; /* Record status for error handler */
passive = TRUE;
carrierDetect = FALSE; /* Modem is not connected */
return 0;
} /* ppassiveopenline */
/*--------------------------------------------------------------------*/
/* p W a i t F o r N e t C o n n e c t */
/* */
/* Wait for network connection */
/*--------------------------------------------------------------------*/
boolean pWaitForNetConnect(int timeout)
{
time_t stop;
stop = time( NULL ) + timeout;
do {
#ifdef __OS2__
APIRET rc = DosConnectNPipe( pipeHandle );
#else
APIRET rc = DosConnectNmPipe( pipeHandle );
#endif
if ( rc == 0 )
{
hangupNeeded = TRUE; /* Flag that the pipe is now dirty */
return TRUE;
}
else if ( rc == ERROR_PIPE_NOT_CONNECTED )
ssleep(5);
else {
printOS2error("DosConnectNPipe", rc );
return FALSE;
} /* else */
} while( (stop > time( NULL )) && ! terminate_processing );
return FALSE;
} /* pWaitForNetConnect */
/*--------------------------------------------------------------------*/
/* p a c t i v e o p e n l i n e */
/* */
/* Open a client pipe connection */
/*--------------------------------------------------------------------*/
#ifdef __TURBOC__
#pragma argsused
#endif
int pactiveopenline(char *name, BPS baud, const boolean direct )
{
APIRET rc;
#ifdef __OS2__
ULONG action;
#else
USHORT action;
#endif
if (portActive) /* Was the port already active? */
closeline(); /* Yes --> Shutdown it before open */
printmsg(15, "pactiveopenline: %s", name);
/*--------------------------------------------------------------------*/
/* Perform the open */
/*--------------------------------------------------------------------*/
rc = DosOpen( name,
&pipeHandle,
&action,
0L,
0 ,
FILE_OPEN ,
OPEN_FLAGS_FAIL_ON_ERROR |
OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, 0L );
/*--------------------------------------------------------------------*/
/* Check the open worked. */
/*--------------------------------------------------------------------*/
if ( rc )
{
printOS2error("DosOpen", rc );
return TRUE;
}
/*--------------------------------------------------------------------*/
/* Set baud rate */
/*--------------------------------------------------------------------*/
SIOSpeed(57600);
traceStart( name ); // Enable logging
portActive = TRUE; /* Record status for error handler */
passive = FALSE;
carrierDetect = FALSE; /* Modem is not connected */
return 0;
} /* pactiveopenline */
/*--------------------------------------------------------------------*/
/* p s r e a d */
/* */
/* Read from the pipe */
/* */
/* Non-blocking read essential to "g" protocol. See "dcpgpkt.c" */
/* for description. */
/* */
/* This all changes in a multi-tasking system. Requests for I/O */
/* should get queued and an event flag given. Then the */
/* requesting process (e.g. gmachine()) waits for the event flag */
/* to fire processing either a read or a write. Could be */
/* implemented on VAX/VMS or DG but not MS-DOS. */
/* */
/* OS/2 we could multitask, but we just let the system provide */
/* a timeout for us with very little CPU usage. */
/*--------------------------------------------------------------------*/
unsigned int psread(char *output, unsigned int wanted, unsigned int timeout)
{
APIRET rc;
static char save[MAXPACK];
static USHORT bufsize = 0;
time_t stop_time ;
time_t now ;
reads++;
/*--------------------------------------------------------------------*/
/* Determine if our internal buffer has the data */
/*--------------------------------------------------------------------*/
if (bufsize >= wanted)
{
memmove( output, save, wanted );
bufsize -= wanted;
if ( bufsize ) /* Any data left over? */
memmove( save, &save[wanted], bufsize ); /* Yes --> Save it*/
return wanted + bufsize;
} /* if */
/*--------------------------------------------------------------------*/
/* Determine when to stop processing */
/*--------------------------------------------------------------------*/
if ( timeout == 0 )
{
stop_time = 0;
now = 1; /* Any number greater than stop time */
}
else {
time( & now );
stop_time = now + timeout;
}
/*--------------------------------------------------------------------*/
/* Try to read any needed data into the buffer */
/*--------------------------------------------------------------------*/
do {
USHORT needed = (USHORT) wanted - bufsize;
#ifdef __OS2__
ULONG received = 0;
#else
USHORT received = 0;
#endif
/*--------------------------------------------------------------------*/
/* Handle an aborted program */
/*--------------------------------------------------------------------*/
if ( terminate_processing )
{
static boolean recurse = FALSE;
if ( ! recurse )
{
printmsg(2,"sread: User aborted processing");
recurse = TRUE;
}
return 0;
}
readSpins++;
ddelay(readWait);
/*--------------------------------------------------------------------*/
/* Read the data from the named pipe */
/*--------------------------------------------------------------------*/
rc = DosRead( pipeHandle, &save[bufsize], needed, &received );
if ( rc == ERROR_NO_DATA)
{
received = 0;
}
else if ( rc )
{
printmsg(0,"psread: Read from pipe for %d bytes failed.",
needed);
printOS2error("DosRead", rc );
bufsize = 0;
return 0;
}
#ifdef UDEBUG
printmsg(15,"psread: Want %d characters, received %d, total %d in buffer",
(int) wanted, (int) received, (int) bufsize + received);
#endif
/*--------------------------------------------------------------------*/
/* Log the newly received data */
/*--------------------------------------------------------------------*/
traceData( &save[bufsize], received, FALSE );
/*--------------------------------------------------------------------*/
/* If we got the data, return it to the caller */
/*--------------------------------------------------------------------*/
bufsize += received;
if ( bufsize == wanted )
{
memmove( output, save, bufsize);
bufsize = 0;
return wanted;
} /* if */
/*--------------------------------------------------------------------*/
/* Update the clock for the next pass */
/*--------------------------------------------------------------------*/
if (stop_time > 0)
time( &now );
} while (stop_time > now);
/*--------------------------------------------------------------------*/
/* We don't have enough data; report what we do have */
/*--------------------------------------------------------------------*/
return bufsize;
} /* nsread */
/*--------------------------------------------------------------------*/
/* p s w r i t e */
/* */
/* Write to the named pipe */
/*--------------------------------------------------------------------*/
int pswrite(const char *input, unsigned int len)
{
char *data = (char *) input;
unsigned int left = len;
#ifdef __OS2__
ULONG bytes;
#else
size_t bytes;
#endif
APIRET rc;
hangupNeeded = TRUE; /* Flag that the pipe is now dirty */
writes ++;
/*--------------------------------------------------------------------*/
/* Write the data out as the queue becomes available */
/*--------------------------------------------------------------------*/
do {
rc = DosWrite( pipeHandle, data + len - left, left, &bytes);
if (rc)
{
printOS2error("DosWrite", rc );
return bytes;
} /*if */
left -= bytes;
ddelay( writeWait );
writeSpins ++;
} while( left > 0 );
/*--------------------------------------------------------------------*/
/* Log the data written */
/*--------------------------------------------------------------------*/
traceData( data, len, TRUE);
/*--------------------------------------------------------------------*/
/* Return bytes written to the pipe to the caller */
/*--------------------------------------------------------------------*/
return len;
} /* nswrite */
#ifdef __TURBOC__
#pragma argsused
#endif
/*--------------------------------------------------------------------*/
/* p s s e n d b r k */
/* */
/* send a break signal out the pipe */
/*--------------------------------------------------------------------*/
void pssendbrk(unsigned int duration)
{
printmsg(0,"pssendbrk: BREAK not supported with named pipes");
} /* nssendbrk */
/*--------------------------------------------------------------------*/
/* p c l o s e l i n e */
/* */
/* Close the named pipe down */
/*--------------------------------------------------------------------*/
void pcloseline(void)
{
APIRET rc;
if ( ! portActive )
panic();
portActive = FALSE; /* flag pipe closed for error handler */
hangupNeeded = FALSE; /* Don't fiddle with pipe any more */
printmsg(4,
"pcloseline: Read delay %d ms, Write delay %d ms",
(int) readWait,
(int) writeWait );
printmsg(4,
"pcloseline: %d reads (%d waits), %d writes (%d waits)",
(int) reads,
(int) readSpins - reads,
(int) writes,
(int) writeSpins - writes );
/*--------------------------------------------------------------------*/
/* Actually close the pipe */
/*--------------------------------------------------------------------*/
rc = DosClose( pipeHandle );
if ( rc )
printOS2error("DosClose", rc );
/*--------------------------------------------------------------------*/
/* Stop logging the data to disk */
/*--------------------------------------------------------------------*/
traceStop();
} /* pcloseline */
/*--------------------------------------------------------------------*/
/* p h a n g u p */
/* */
/* Hangup the link. No operation on network. */
/*--------------------------------------------------------------------*/
void phangup( void )
{
if ( passive && hangupNeeded)
{
#ifdef __OS2__
DosDisConnectNPipe( pipeHandle );
#else
DosDisConnectNmPipe( pipeHandle );
#endif
hangupNeeded = FALSE;
}
return;
} /* phangup */
/*--------------------------------------------------------------------*/
/* p S I O S p e e d */
/* */
/* Re-specify the speed of an opened pipe; no operation, actually. */
/*--------------------------------------------------------------------*/
#ifdef __TURBOC__
#pragma argsused
#endif
void pSIOSpeed(BPS baud)
{
currentSpeed = baud;
return;
} /* pSIOSpeed */
/*--------------------------------------------------------------------*/
/* p f l o w c o n t r o l */
/* */
/* Enable/Disable in band (XON/XOFF) flow control */
/*--------------------------------------------------------------------*/
#ifdef __TURBOC__
#pragma argsused
#endif
void pflowcontrol( boolean flow )
{
return;
} /* pflowcontrol */
/*--------------------------------------------------------------------*/
/* n G e t S p e e d */
/* */
/* Report current speed of communications connection */
/*--------------------------------------------------------------------*/
BPS pGetSpeed( void )
{
return currentSpeed;
} /* nGetSpeed */
/*--------------------------------------------------------------------*/
/* p C D */
/* */
/* Return status of carrier detect */
/*--------------------------------------------------------------------*/
boolean pCD( void )
{
return carrierDetect;
} /* pCD */