2010-03-08 04:55:21 -06:00
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* NCSA DTM version 2.3
|
|
|
|
* May 1, 1992
|
|
|
|
*
|
|
|
|
* NCSA DTM Version 2.3 source code and documentation are in the public
|
|
|
|
* domain. Specifically, we give to the public domain all rights for future
|
|
|
|
* licensing of the source code, all resale rights, and all publishing rights.
|
|
|
|
*
|
|
|
|
* We ask, but do not require, that the following message be included in all
|
|
|
|
* derived works:
|
|
|
|
*
|
|
|
|
* Portions developed at the National Center for Supercomputing Applications at
|
|
|
|
* the University of Illinois at Urbana-Champaign.
|
|
|
|
*
|
|
|
|
* THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
|
|
|
|
* SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
|
|
|
|
* WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
**
|
|
|
|
** dtminit.c - contains routines to initialize the dtm routines
|
|
|
|
** based on command line options.
|
|
|
|
**
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* $Log: dtminit.c,v $
|
|
|
|
* Revision 1.4 1996/02/18 23:40:12 spowers
|
|
|
|
* PROTO -> DTM_PROTO
|
|
|
|
*
|
|
|
|
* Revision 1.3 1995/10/14 22:07:25 spowers
|
|
|
|
* Bzero and Bcopy removed...memset memcpy used instead.
|
|
|
|
*
|
|
|
|
* Revision 1.2 1995/10/13 06:33:07 spowers
|
|
|
|
* Solaris support added.
|
|
|
|
*
|
|
|
|
* Revision 1.1.1.1 1995/01/11 00:02:59 alanb
|
|
|
|
* New CVS source tree, Mosaic 2.5 beta 4
|
|
|
|
*
|
|
|
|
* Revision 2.5 1994/12/29 23:39:43 alanb
|
|
|
|
* I'm committing with a new symbolic revision number.
|
|
|
|
*
|
|
|
|
* Revision 1.1.1.1 1994/12/28 21:37:31 alanb
|
|
|
|
*
|
|
|
|
* Revision 1.1.1.1 1993/07/04 00:03:16 marca
|
|
|
|
* Mosaic for X version 2 distribution
|
|
|
|
*
|
|
|
|
* Revision 1.3 1993/04/18 05:51:46 marca
|
|
|
|
* Tweaks.
|
|
|
|
*
|
|
|
|
* Revision 1.2 1993/02/26 05:21:53 marca
|
|
|
|
* Unknown change.
|
|
|
|
*
|
|
|
|
* Revision 1.1 1993/01/18 21:50:18 marca
|
|
|
|
* I think I got it now.
|
|
|
|
*
|
|
|
|
* Revision 1.33 92/05/05 22:27:50 jplevyak
|
|
|
|
* Corrected X interface code.
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.32 1992/04/30 20:25:27 jplevyak
|
|
|
|
* Changed Version to 2.3.
|
|
|
|
*
|
|
|
|
* Revision 1.31 1992/04/29 21:57:46 jplevyak
|
|
|
|
* Initialize the new DTMPORT structure elements used for DTMaddInput.
|
|
|
|
*
|
|
|
|
* Revision 1.30 1992/04/06 15:58:25 jplevyak
|
|
|
|
* Fixed minor problems for machines little Endian machines.
|
|
|
|
*
|
|
|
|
* Revision 1.29 92/03/20 21:14:40 jplevyak
|
|
|
|
* Remove comments about DTMgetPortName
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.28 1992/03/16 20:38:36 creiman
|
|
|
|
* Added #include "arch.h"
|
|
|
|
*
|
|
|
|
* Revision 1.27 1992/03/10 22:07:10 jplevyak
|
|
|
|
* Added changed for PC/MAC from Quincey Koziol (koziol@ncsa.uiuc.edu)
|
|
|
|
* with modification.
|
|
|
|
*
|
|
|
|
* Revision 1.26 1992/02/27 23:44:07 jplevyak
|
|
|
|
* New function DTMgetRemotePortAddr.
|
|
|
|
*
|
|
|
|
* Revision 1.25 1992/02/18 14:03:16 jplevyak
|
|
|
|
* Used _ARCH_MACOS instead of macintosh.
|
|
|
|
*
|
|
|
|
* Revision 1.24 1992/01/14 19:37:50 creiman
|
|
|
|
* Removed malloc.h from mac version
|
|
|
|
*
|
|
|
|
* Revision 1.23 1992/01/14 16:31:40 creiman
|
|
|
|
* Removed mac #include
|
|
|
|
*
|
|
|
|
* Revision 1.22 1991/12/09 18:36:18 jplevyak
|
|
|
|
* Added support for Callback ( DTMreadReady ).
|
|
|
|
*
|
|
|
|
* Revision 1.21 1991/12/02 11:14:53 dweber
|
|
|
|
* Deleted DTMgetPortName function
|
|
|
|
*
|
|
|
|
* Revision 1.20 91/11/22 21:31:00 jplevyak
|
|
|
|
* Added initialization for fDiscard (fGotList and fLastWasSuccessfull...)
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.19 1991/10/29 22:05:53 sreedhar
|
|
|
|
* <sys/malloc.h> for CONVEX
|
|
|
|
*
|
|
|
|
* Revision 1.18 1991/10/16 23:24:40 jplevyak
|
|
|
|
* Added new error message.
|
|
|
|
*
|
|
|
|
* Revision 1.17 1991/10/14 16:47:48 jplevyak
|
|
|
|
* Fix bug in physical port addressing.
|
|
|
|
*
|
|
|
|
* Revision 1.16 1991/10/11 20:43:55 jplevyak
|
|
|
|
* Fixed bug in dtm_get_naddr, incorrect error handling.
|
|
|
|
*
|
|
|
|
* Revision 1.15 1991/10/10 14:25:07 jplevyak
|
|
|
|
* Finished fixing naming convensions. Added code to handle multiple
|
|
|
|
* open read sockets on a single DTM socket.
|
|
|
|
*
|
|
|
|
* Revision 1.14 91/09/26 20:14:58 jplevyak
|
|
|
|
* Major reorganization. Dynamically allocate port table. Encode a
|
|
|
|
* key in the external ports to detect stale ports. Rename and
|
|
|
|
* comment functions.
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.13 91/09/18 15:28:11 jplevyak
|
|
|
|
* Added some external definitions for shared functions.
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.12 91/09/16 11:25:37 jplevyak
|
|
|
|
* Fix bug, use of uninitialized register variable in function
|
|
|
|
* DTMdestroyPort
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.11 91/09/13 20:09:31 sreedhar
|
|
|
|
* supporting :9900, absence of env variable
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.10 1991/09/13 18:57:13 sreedhar
|
|
|
|
* removed DTMinit() fn., added qservice in some places
|
|
|
|
*
|
|
|
|
* Revision 1.9 1991/08/15 18:56:19 sreedhar
|
|
|
|
* Changes for logical portname version
|
|
|
|
*
|
|
|
|
* Revision 1.7 1991/06/11 15:34:15 sreedhar
|
|
|
|
* quality of service parameter for future use
|
|
|
|
*
|
|
|
|
* Revision 1.6 1991/06/11 15:18:36 sreedhar
|
|
|
|
* disclaimer added, availwrite/seqstart flags inited.
|
|
|
|
*
|
|
|
|
* Revision 1.5 1991/06/07 16:05:21 sreedhar
|
|
|
|
* *colon = '\0' removed, it writes into user buffer
|
|
|
|
*
|
|
|
|
* Revision 1.4 1991/01/09 16:50:34 jefft
|
|
|
|
* added include sys/include.h
|
|
|
|
*
|
|
|
|
* Revision 1.3 91/01/09 14:10:04 jefft
|
|
|
|
* Now ignoring SIGPIPE signals.
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.2 90/11/21 10:53:08 jefft
|
|
|
|
* Modified DTMgetPortAddr to return IP address instead of hostname.
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
* Revision 1.1 90/11/08 16:21:54 jefft
|
|
|
|
* Initial revision
|
2013-03-09 18:59:42 -06:00
|
|
|
*
|
2010-03-08 04:55:21 -06:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "arch.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#ifndef _ARCH_MACOS
|
|
|
|
# include <sys/signal.h>
|
|
|
|
#endif
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
|
|
|
#ifndef _ARCH_MACOS
|
|
|
|
# if defined(CONVEX) || defined(NEXT)
|
|
|
|
# include <sys/malloc.h>
|
|
|
|
# else
|
|
|
|
# include <malloc.h>
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "dtm.h"
|
|
|
|
#include "dtmint.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
CONTENTS
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
STATIC
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
init_port() - initialize DTM port.
|
|
|
|
grow_ports() - enlarge the DTM port table
|
2013-03-09 18:59:42 -06:00
|
|
|
initialize() - initialize DTM library
|
2010-03-08 04:55:21 -06:00
|
|
|
get_init_port() - find a new port and initialize it
|
|
|
|
set_out_port_address() - set a physical out port adress
|
|
|
|
free_port() - free the internal port structure
|
|
|
|
register_port() - register a logical port with the server
|
|
|
|
|
|
|
|
IN-LIBRARY GLOBAL
|
|
|
|
|
|
|
|
dtm_map_port_internal() - map external port ID to internal port number
|
|
|
|
dtm_map_port_external() - map internal port number to external port ID
|
|
|
|
|
|
|
|
EXTERNALLY GLOBAL
|
|
|
|
|
|
|
|
DTMmakeInPort() - make a DTM input port
|
|
|
|
DTMmakeOutPort() - make a DTM output port
|
|
|
|
DTMdestroyPort() - close and free a DTM port
|
2013-03-09 18:59:42 -06:00
|
|
|
DTMgetPortAddr() - returns the main port address
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
END CONTENTS */
|
|
|
|
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
/*
|
|
|
|
STATIC FUNCTION PROTOTYPES
|
|
|
|
*/
|
|
|
|
static int init_port DTM_PROTO((int ,int ,int ));
|
|
|
|
static int grow_ports DTM_PROTO((VOID ));
|
|
|
|
static int initialize DTM_PROTO((VOID ));
|
|
|
|
static int get_init_port DTM_PROTO((char *,int ,int ));
|
|
|
|
static int set_out_port_address DTM_PROTO((int ,S_ADDR ));
|
|
|
|
static int free_port DTM_PROTO((int ));
|
|
|
|
static int register_port DTM_PROTO((int ));
|
|
|
|
static char *dtm_addr_to_a DTM_PROTO((S_ADDR addr));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
STATIC FUNCTIONS
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
init_port()
|
|
|
|
Allocate and intialize port p.
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
static int init_port(int port,int porttype,int qservice )
|
|
|
|
#else
|
|
|
|
static int init_port( port, porttype, qservice )
|
|
|
|
int port;
|
|
|
|
int porttype ;
|
|
|
|
int qservice ;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
register DTMPORT *pp ;
|
|
|
|
|
|
|
|
DBGFLOW( "init_port called\n" );
|
|
|
|
|
|
|
|
/* allocate port structure */
|
|
|
|
|
|
|
|
if( (pp = DTMpt[port] = (DTMPORT *)malloc(sizeof (DTMPORT))) == NULL ) {
|
|
|
|
DTMerrno = DTMMEM;
|
|
|
|
DBGFLOW("init_port: could not allocate DTMPORT structure.");
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
memset(pp,0,sizeof(DTMPORT));
|
|
|
|
/*
|
|
|
|
#ifdef SOLARIS
|
|
|
|
memset(pp,0,sizeof(DTMPORT));
|
|
|
|
#else
|
|
|
|
bzero( pp, sizeof( DTMPORT ) );
|
|
|
|
#endif
|
|
|
|
*/
|
|
|
|
pp->porttype = porttype ;
|
|
|
|
pp->qservice = qservice ;
|
|
|
|
pp->Xcallback_data = NULL;
|
|
|
|
pp->Xcallback = NULL;
|
|
|
|
pp->XaddInput = NULL;
|
|
|
|
|
|
|
|
/* Input port data init */
|
|
|
|
|
|
|
|
pp->in = NULL;
|
|
|
|
pp->nextToRead = NULL;
|
|
|
|
pp->callback = NULL;
|
|
|
|
|
|
|
|
/* Output port data init */
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
pp->out = NULL ;
|
2010-03-08 04:55:21 -06:00
|
|
|
pp->fLastWasSuccessfulAvailWrite = FALSE;
|
|
|
|
pp->fGotList = FALSE;
|
|
|
|
pp->fDiscard = FALSE;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
grow_ports()
|
|
|
|
Extend the size of the port table by DTM_PORTS_GROW ports.
|
|
|
|
*/
|
|
|
|
static int grow_ports( VOID )
|
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
if ( ( DTMpt = (DTMPORT **) realloc( (void *) DTMpt, (DTMptCount +
|
2010-03-08 04:55:21 -06:00
|
|
|
DTM_PORTS_GROW) * sizeof(DTMPORT))) == NULL ) {
|
|
|
|
DTMerrno = DTMMEM;
|
|
|
|
DTMERR("initialize: insufficient memory for port table.");
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
memset( (char *)&DTMpt[DTMptCount],0,DTM_PORTS_GROW * sizeof(DTMPORT));
|
|
|
|
/*
|
|
|
|
#ifdef SOLARIS
|
|
|
|
memset( (char *)&DTMpt[DTMptCount],0,DTM_PORTS_GROW * sizeof(DTMPORT));
|
|
|
|
#else
|
|
|
|
bzero( (char *)&DTMpt[DTMptCount], DTM_PORTS_GROW * sizeof(DTMPORT));
|
|
|
|
#endif
|
|
|
|
*/
|
|
|
|
DTMptCount += DTM_PORTS_GROW;
|
|
|
|
return DTM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
initialize()
|
|
|
|
Initailized DTM by allocating memory for dtm_discard
|
|
|
|
and DTMpt ( the port table ).
|
|
|
|
*/
|
2013-03-09 18:59:42 -06:00
|
|
|
static int initialize( VOID )
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
/* get the debug option flag */
|
|
|
|
if ( getenv( "DTMDEBUG" ) ) uDTMdbg = -1;
|
|
|
|
|
|
|
|
/* create discard buffer */
|
|
|
|
if ((dtm_discard = (char *)malloc(DISCARDSIZE)) == NULL) {
|
|
|
|
DTMerrno = DTMMEM;
|
|
|
|
DTMERR("initialize: insufficient memory for dicard buffer.");
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((DTMpt = (DTMPORT **)calloc(DTM_PORTS_INITIAL, sizeof(DTMPORT)))
|
|
|
|
== NULL) {
|
|
|
|
DTMerrno = DTMMEM;
|
|
|
|
DTMERR("initialize: insufficient memory for port table.");
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
DTMptCount = DTM_PORTS_INITIAL;
|
|
|
|
|
|
|
|
#if !defined(_ARCH_MACOS) & !defined(_ARCH_MSDOS)
|
|
|
|
/* ignore SIGPIPE signals, handled by dtm_write call */
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
get_init_port()
|
|
|
|
Get and initialize a new port. Setting the porttype, qservice
|
|
|
|
and key fields. Remember to build the external port
|
|
|
|
name before returning it to the user!
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
static int get_init_port(char *portname,int porttype,int qservice )
|
|
|
|
#else
|
|
|
|
static int get_init_port( portname, porttype, qservice )
|
|
|
|
char *portname ;
|
|
|
|
int porttype ;
|
|
|
|
int qservice ;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int tries = 2;
|
|
|
|
int port ;
|
|
|
|
|
|
|
|
DBGFLOW("get_init_port called.\n");
|
|
|
|
|
|
|
|
/* check for library initialization */
|
|
|
|
if( !DTM_INITIALIZED ) CHECK_ERR( initialize());
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* find first open DTM port */
|
|
|
|
while ( tries-- ) {
|
|
|
|
for (port=0; port < DTMptCount; port+=1) {
|
|
|
|
if (DTMpt[port] == NULL) {
|
|
|
|
CHECK_ERR(init_port( port, porttype, qservice ));
|
|
|
|
strncpy( DTMpt[port]->portname, portname, (PNAMELEN - 1) );
|
|
|
|
DTMpt[ port ]->portname[ PNAMELEN - 1 ] = '\0' ;
|
2013-03-09 18:59:42 -06:00
|
|
|
DTMpt[ port ]->key = DTMportSequenceNumber++;
|
2010-03-08 04:55:21 -06:00
|
|
|
return port;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
grow_ports();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we should never get here */
|
|
|
|
DTMerrno = DTMNOPORT;
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
set_out_port_address()
|
|
|
|
Set the single out port address of a DTMPORT with a physical
|
|
|
|
specification.
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
static int set_out_port_address(int port,S_ADDR addr )
|
|
|
|
#else
|
|
|
|
static int set_out_port_address( port, addr )
|
|
|
|
int port;
|
|
|
|
S_ADDR addr;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
Port aPort ;
|
|
|
|
Outport *outp ;
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
DBGINT( "set_out_port_address: Physical TCP portname - %x ",
|
2010-03-08 04:55:21 -06:00
|
|
|
ntohl( addr.sin_addr.s_addr ));
|
|
|
|
DBGINT( "%d\n", ntohs( addr.sin_port ));
|
|
|
|
|
|
|
|
aPort.portid = addr.sin_port ;
|
2013-03-09 18:59:42 -06:00
|
|
|
aPort.nethostid = addr.sin_addr.s_addr ;
|
2010-03-08 04:55:21 -06:00
|
|
|
CHECK_ERR( outp = dtm_new_out_port( &aPort ));
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
DTMpt[port]->out = outp ;
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
return DTM_OK;
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
static int free_port(int port )
|
|
|
|
#else
|
|
|
|
static int free_port( port )
|
|
|
|
int port;
|
|
|
|
#endif
|
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
Outport * outport = DTMpt[ port ]->out;
|
2010-03-08 04:55:21 -06:00
|
|
|
Outport * tempPort;
|
2013-03-09 18:59:42 -06:00
|
|
|
int returnValue = DTM_OK;
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
while ( outport != NULL ) {
|
|
|
|
tempPort = outport->next;
|
|
|
|
#ifdef FREE_RETURNS_INT
|
|
|
|
if ( free( outport ) != 0 ) {
|
2013-03-09 18:59:42 -06:00
|
|
|
DTMerrno = DTMCORPT;
|
2010-03-08 04:55:21 -06:00
|
|
|
returnValue = DTMERROR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
free( outport );
|
|
|
|
#endif
|
|
|
|
outport = tempPort;
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
#ifdef FREE_RETURNS_INT
|
|
|
|
if ( free( DTMpt[ port ] ) != 0 ) {
|
2013-03-09 18:59:42 -06:00
|
|
|
DTMerrno = DTMCORPT;
|
2010-03-08 04:55:21 -06:00
|
|
|
returnValue = DTMERROR;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
free( DTMpt[ port ] );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DTMpt[port] = NULL;
|
|
|
|
return DTM_OK ;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
register_port()
|
|
|
|
Attempt to register the logical port with the name server.
|
|
|
|
On failure, destroy the port.
|
|
|
|
returns: DTM_OK and DTMERROR.
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
static int register_port(int port )
|
|
|
|
#else
|
|
|
|
static int register_port( port )
|
|
|
|
int port;
|
2013-03-09 18:59:42 -06:00
|
|
|
#endif
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
int fd ;
|
|
|
|
S_ADDR addr ;
|
|
|
|
char *naddr ;
|
|
|
|
|
|
|
|
CHECK_ERR( naddr = dtm_get_naddr( &addr, &fd ));
|
2013-03-09 18:59:42 -06:00
|
|
|
if(dtm_nsend_sockaddr(fd, naddr, dtm_get_refname(), DTMpt[port]->portname,
|
2010-03-08 04:55:21 -06:00
|
|
|
&DTMpt[ port ]->sockaddr ) < 0 ) {
|
|
|
|
DTMdestroyPort( DTMpt[port]->sockfd ) ;
|
|
|
|
DTMerrno = DTMTIMEOUT;
|
|
|
|
return DTMERROR ;
|
|
|
|
}
|
|
|
|
return DTM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
IN-LIBRARY GLOBAL FUNCTIONS
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
dtm_map_port_internal()
|
|
|
|
This function takes a pointer to a port and then validates
|
|
|
|
that port. If the validation passes, the port is converted
|
|
|
|
to the internal representation (which is an index into the
|
|
|
|
port table DTMpt).
|
|
|
|
returns: DTMERROR, DTM_OK sets error codes DTMBADPORT
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
int dtm_map_port_internal( int32 port )
|
|
|
|
#else
|
|
|
|
int dtm_map_port_internal( port )
|
|
|
|
int32 port;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int32 thePort = port & DTM_PORT_MASK;
|
|
|
|
|
|
|
|
if ( ( thePort ) >= DTMptCount ) {
|
|
|
|
DTMerrno = DTMBADPORT;
|
2013-03-09 18:59:42 -06:00
|
|
|
return DTMERROR;
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
|
|
|
if ( DTMpt[ thePort ] == NULL ) {
|
|
|
|
DTMerrno = DTMBADPORT;
|
2013-03-09 18:59:42 -06:00
|
|
|
return DTMERROR;
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
|
|
|
if ( ( port >> DTM_PORT_KEY_SHIFT ) != DTMpt[ thePort ]->key ) {
|
|
|
|
DTMerrno = DTMBADPORT;
|
2013-03-09 18:59:42 -06:00
|
|
|
return DTMERROR;
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
|
|
|
return thePort;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
void dtm_map_port_external(int32 *port )
|
|
|
|
#else
|
|
|
|
void dtm_map_port_external( port )
|
|
|
|
int32 *port;
|
|
|
|
#endif
|
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
*port = *port | (DTMpt[ *port ]->key << DTM_PORT_KEY_SHIFT);
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
EXTERNALLY GLOBAL FUNCTIONS
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
DTMmakeInPort()
|
|
|
|
Create and initialize a new port.
|
|
|
|
portname may be a logical or a physical port.
|
|
|
|
qservice is reserved for future use.
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
int DTMmakeInPort(char *portname,int qservice )
|
|
|
|
#else
|
|
|
|
int DTMmakeInPort(portname, qservice )
|
|
|
|
char *portname;
|
|
|
|
int qservice ;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int port;
|
|
|
|
int fLogicalName = FALSE;
|
|
|
|
|
|
|
|
DBGFLOW("DTMmakeInPort called.\n");
|
|
|
|
|
|
|
|
CHECK_ERR(port = get_init_port(portname, INPORTTYPE, qservice ));
|
|
|
|
DBGMSG2("DTMmakeInPort port %d addr %X\n", port, DTMpt[port] );
|
2013-03-09 18:59:42 -06:00
|
|
|
CHECK_ERR(dtm_init_sockaddr( &DTMpt[ port ]->sockaddr,
|
2010-03-08 04:55:21 -06:00
|
|
|
DTMpt[ port ]->portname, &fLogicalName ));
|
|
|
|
DTMpt[port]->fLogical = fLogicalName;
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if ((DTMpt[port]->sockfd = dtm_socket_init( &DTMpt[port]->sockaddr,
|
2010-03-08 04:55:21 -06:00
|
|
|
INPORTTYPE, fLogicalName )) == DTMERROR ) {
|
|
|
|
free_port(port);
|
|
|
|
return DTMERROR ;
|
|
|
|
}
|
|
|
|
|
|
|
|
DBGMSG1( "DTMmakeInPort: sockfd = %d\n", DTMpt[ port ]->sockfd );
|
|
|
|
|
|
|
|
if( fLogicalName ) CHECK_ERR( register_port( port ));
|
|
|
|
|
|
|
|
dtm_map_port_external( &port ) ;
|
|
|
|
return port;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2013-03-09 18:59:42 -06:00
|
|
|
DTMmakeOutPort()
|
2010-03-08 04:55:21 -06:00
|
|
|
Create and initialze a new port.
|
|
|
|
portname may be a logical or a physical port.
|
|
|
|
qservice is reserved for future use.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
int DTMmakeOutPort(char *portname,int qservice )
|
|
|
|
#else
|
|
|
|
int DTMmakeOutPort(portname, qservice )
|
|
|
|
char *portname;
|
|
|
|
int qservice ;
|
2013-03-09 18:59:42 -06:00
|
|
|
#endif
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
int port;
|
|
|
|
int fLogicalName = TRUE;
|
|
|
|
S_ADDR addr;
|
|
|
|
|
|
|
|
DBGFLOW("DTMmakeOutPort called.\n");
|
|
|
|
|
|
|
|
CHECK_ERR( (port = get_init_port( portname, OUTPORTTYPE, qservice)));
|
2013-03-09 18:59:42 -06:00
|
|
|
CHECK_ERR((dtm_init_sockaddr(&addr, DTMpt[port]->portname,&fLogicalName)));
|
2010-03-08 04:55:21 -06:00
|
|
|
DTMpt[port]->fLogical = fLogicalName;
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if( !fLogicalName ) CHECK_ERR( set_out_port_address( port, addr ));
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
if( (DTMpt[port] -> sockfd = dtm_socket_init( &DTMpt[port] -> sockaddr,
|
|
|
|
OUTPORTTYPE, fLogicalName )) == DTMERROR ) {
|
|
|
|
DTMdestroyPort( port );
|
|
|
|
return DTMERROR ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fLogicalName ) CHECK_ERR( register_port( port ));
|
|
|
|
|
|
|
|
dtm_map_port_external( &port ) ;
|
|
|
|
return port;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
DTMdestroyPort()
|
|
|
|
Close all connections attached to this port then free up the memory
|
|
|
|
that it uses.
|
|
|
|
returns: DTMERROR, DTM_OK
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
int DTMdestroyPort(int port)
|
|
|
|
#else
|
|
|
|
int DTMdestroyPort(port)
|
|
|
|
int port;
|
2013-03-09 18:59:42 -06:00
|
|
|
#endif
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
reg DTMPORT *pp ;
|
|
|
|
|
|
|
|
DBGFLOW("DTMdestroyPort called.\n");
|
|
|
|
|
|
|
|
CHECK_ERR( port = dtm_map_port_internal( port ));
|
|
|
|
|
|
|
|
/* close main socket */
|
|
|
|
|
|
|
|
pp = DTMpt[port];
|
|
|
|
if (pp->sockfd != -1) {
|
|
|
|
if ( pp->XinputId ) pp->XremoveInput( pp->XinputId );
|
|
|
|
close(pp->sockfd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* close connections */
|
|
|
|
|
|
|
|
if( pp -> porttype == INPORTTYPE ) {
|
|
|
|
register Inport *pcur ;
|
2013-03-09 18:59:42 -06:00
|
|
|
FOR_EACH_IN_PORT( pcur, pp ) {
|
2010-03-08 04:55:21 -06:00
|
|
|
if( pcur->fd != DTM_NO_CONNECTION ) {
|
|
|
|
if ( pp->Xcallback ) pp->XremoveInput( pcur->XinputId );
|
|
|
|
close( pcur->fd ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
register Outport *pcur ;
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
FOR_EACH_OUT_PORT( pcur, pp ) {
|
2010-03-08 04:55:21 -06:00
|
|
|
if( pcur->connfd != DTM_NO_CONNECTION ) close( pcur->connfd ) ;
|
|
|
|
}
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* free space allocated for port */
|
|
|
|
|
|
|
|
free_port( port );
|
|
|
|
|
|
|
|
return DTM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
DTMgetPortAddr()
|
|
|
|
Copies the physical address of the port into the given
|
|
|
|
buffer up the the length.
|
|
|
|
returns: DTMERROR, DTM_OK.
|
|
|
|
|
|
|
|
BUGS: does not check the length until adding the port.
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
int DTMgetPortAddr(int port,char *addr,int length)
|
|
|
|
#else
|
|
|
|
int DTMgetPortAddr(port, addr, length)
|
|
|
|
int port;
|
|
|
|
int length;
|
|
|
|
char *addr;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
char pnum[10];
|
|
|
|
|
|
|
|
DBGFLOW("DTMgetPortAddr called.\n");
|
|
|
|
|
|
|
|
CHECK_ERR( port = dtm_map_port_internal( port ));
|
|
|
|
|
|
|
|
if (dtm_get_ipaddr(addr) == 0) {
|
|
|
|
DTMerrno = DTMHOST;
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(pnum, ":%d", ntohs( DTMpt[port]->sockaddr.sin_port ) );
|
|
|
|
if ( strlen( pnum ) + strlen( addr ) + 1 > length ) {
|
|
|
|
DTMerrno = DTMBUFOVR;
|
2013-03-09 18:59:42 -06:00
|
|
|
return DTMERROR;
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
|
|
|
strcat(addr, pnum);
|
|
|
|
|
|
|
|
return DTM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
static char * dtm_addr_to_a(S_ADDR addr )
|
|
|
|
#else
|
|
|
|
static char * dtm_addr_to_a( addr )
|
|
|
|
S_ADDR addr;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
static char addr_buf[32];
|
|
|
|
uint32 hnum = addr.sin_addr.s_addr;
|
|
|
|
unsigned char * p_hnum = (unsigned char *) &hnum;
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
sprintf(addr_buf, "%d.%d.%d.%d:%d",
|
2010-03-08 04:55:21 -06:00
|
|
|
p_hnum[0], p_hnum[1], p_hnum[2], p_hnum[3], ntohs( addr.sin_port ));
|
|
|
|
return addr_buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
DTMgetRemotePortAddr
|
|
|
|
Returns:
|
|
|
|
Pointer to a malloc'ed array of pointers to strings.
|
|
|
|
Number of strings in the array.
|
|
|
|
Up to the user to free the list.
|
|
|
|
*/
|
|
|
|
#ifdef DTM_PROTOTYPES
|
|
|
|
int DTMgetRemotePortAddr(int port,char ***addrs,int *n_addrs)
|
|
|
|
#else
|
|
|
|
int DTMgetRemotePortAddr(port, addrs, n_addrs)
|
|
|
|
int port;
|
|
|
|
char *** addrs;
|
|
|
|
int * n_addrs;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int size = 0;
|
|
|
|
int count = 0;
|
|
|
|
reg Outport * pcur;
|
|
|
|
reg DTMPORT * pp;
|
|
|
|
char * strings;
|
|
|
|
|
|
|
|
CHECK_ERR( port = dtm_map_port_internal( port ));
|
|
|
|
pp = DTMpt[port];
|
|
|
|
|
|
|
|
FOR_EACH_OUT_PORT( pcur, pp ) {
|
|
|
|
count++;
|
|
|
|
size += strlen( dtm_addr_to_a( pcur->sockaddr )) + 1 + 4;
|
|
|
|
}
|
|
|
|
*n_addrs = count;
|
|
|
|
*addrs = (char **) malloc( size );
|
|
|
|
if ( !*addrs ) {
|
|
|
|
DTMerrno = DTMMEM;
|
|
|
|
return DTMERROR;
|
|
|
|
}
|
|
|
|
strings = (char *) *addrs;
|
|
|
|
strings += 4 * count;
|
|
|
|
FOR_EACH_OUT_PORT( pcur, pp ) {
|
|
|
|
(*addrs)[--count] = strings;
|
|
|
|
strcpy( strings, dtm_addr_to_a( pcur->sockaddr ));
|
|
|
|
strings += strlen(strings) + 1;
|
|
|
|
}
|
|
|
|
return DTM_OK;
|
|
|
|
}
|