📄 novos2.c
字号:
/*
I don't know what the 0x1001 status is - I can't find it
in any documentation, but if we don't wait for it to clear,
things mess up badly.
*/
if( SendECB.status != SPX_SUCCESSFUL
&& !InUse( SendECB )
&& SendECB.status != 0x1001 ) break;
rc = DosSemWait( &SendSem, 1000 );
if( rc != ERROR_SEM_TIMEOUT ) break;
}
SendECB.hsem = 0;
return( len );
putstring( "Done RemotePut\r\n" );
}
unsigned RemoteGet( char *rec, unsigned len )
{
return( DoRemoteGet( rec, len ) );
}
unsigned RemotePut( char *snd, unsigned len )
{
while( len >= MAX_DATA_SIZE ) {
if( DoRemotePut( snd, MAX_DATA_SIZE ) == REQUEST_FAILED ) {
return( REQUEST_FAILED );
}
snd = (unsigned_8 *)snd + MAX_DATA_SIZE;
len -= MAX_DATA_SIZE;
}
if( DoRemotePut( snd, len ) == REQUEST_FAILED ) {
return( REQUEST_FAILED );
}
return( len );
}
static void PostAListen( int i )
{
WORD rc;
putstring( "Posting RecECB[i]\r\n" );
_INITECB( RecECB[i], RecHead[i], 2, SPX )
RecECB[i].hsem = (HSEM) &RecvSem;
RecECB[i].fragList[1].fragAddress = &Buffer[i];
RecECB[i].fragList[1].fragSize = sizeof( Buffer[i] );
rc = SpxListenForConnectionPacket( Connection, &RecECB[i] );
putrc( "SPXListenForConnectionPacket", rc );
}
static void PostListens()
{
int i;
DosSleep( 0 );
for( i = NUM_REC_BUFFS-1; i >= 0; --i ) {
if( !InUse( RecECB[i] ) ) {
PostAListen( i );
}
}
/* make sure other side get the listens up */
DosSleep( 100 );
}
char RemoteConnect( void )
{
WORD rc;
#ifdef SERVER
if( !Listening ) {
_INITSPXECB( Conn, 1, 0, 0 );
rc = SpxListenForConnection( SPXSocket, &ConnECB, 0, 0, &Connection );
putrc( "SPXListenForConnection", rc );
Listening = 1;
} else if( !InUse( ConnECB ) ) {
PostListens();
return( 1 );
}
IPXRelinquishControl();
#else
putstring( "RemoteConnect\r\n" );
_INITSPXECB( Send, 1, NULL, 0 );
if( ( rc = SpxEstablishConnection( SPXSocket, &SendECB,
0, 0x10, &Connection ) ) == 0 ) {
int i;
for( i = 1; i < 20; ++i ) {
putstring( "RemoteConnect loop\r\n" );
if( !InUse( SendECB ) ) {
PostListens();
putstring( "RemoteConnect loop done\r\n" );
return( 1 );
}
DosSleep( 100 ); /* 20 * 100 is approx 2 seconds */
}
putstring( "RemoteConnect aborting\r\n" );
rc = SpxAbortConnection( Connection );
putrc( "SPXAbortConnection", rc );
} else {
putrc( "SPXEstablishConnection", rc );
}
#endif
return( 0 );
}
void RemoteDisco( void )
{
int i;
DosSleep( 500 ); /* make sure last packet gets sent */
Listening = 0;
_INITSPXECB( Conn, 1, 0, 0 );
if( SpxTerminateConnection( Connection, &ConnECB ) == 0 ) {
while( InUse( ConnECB ) ) IPXRelinquishControl();
}
for( i = NUM_REC_BUFFS-1; i >= 0; --i ) {
if( InUse( RecECB[i] ) ) {
SpxCancelPacket( &RecECB[i] );
}
}
if( InUse( SendECB ) ) {
SpxCancelPacket( &SendECB );
}
for( i = NUM_REC_BUFFS-1; i >= 0; --i ) {
ZeroArray( RecHead[i] );
ZeroArray( RecECB[i] );
}
ZeroArray( ConnHead );
ZeroArray( SendHead );
ZeroArray( ConnECB );
ZeroArray( SendECB );
}
#ifdef SERVER
volatile enum {
DIE_WANT = 0x01,
DIE_RESPOND = 0x02,
DIE_BROADCAST = 0x04
} ServerDie = 0;
#define STACKSIZE 2048
char RespondStack[ STACKSIZE ];
static void far Respond()
{
char dummy;
ServECB.fragCount = 2;
ServECB.fragList[1].fragAddress = &dummy;
ServECB.fragList[1].fragSize = sizeof( dummy );
DosSetPrty( PRTYS_THREAD, PRTYC_NOCHANGE, +1, 0 );
for( ;; ) {
if( IpxReceive( IPXSocket, ~0UL, &ServECB ) == 0 ) {
_IPX_ASSIGNADDR( RespHead.dest, ServHead.source );
AssignArray( RespECB.immediateAddress, ServECB.immediateAddress );
RespECB.fragList[1].fragAddress = &SPXSocket;
IpxSend( IPXSocket, &RespECB );
}
if( ServerDie ) {
ServerDie |= DIE_RESPOND;
DosExit( EXIT_THREAD, 0 );
}
}
}
char BroadcastStack[ STACKSIZE ];
ULONG BroadCastStop = 0;
ULONG BroadCastStart = 0;
static void far Broadcast()
{
_INITIPXECB( SAP );
FillArray( SAPHead.destNode, 0xff );
SAPHead.destSocket = SAP_SOCKET;
SAPHead.infoType = _SWAPINT( 0x2 );
SAPHead.serverType = DBG_SERVER_TYPE;
IpxGetInternetworkAddress( (PUCHAR)&SAPHead.addrNet );
SAPHead.addrSocket = IPXSocket;
SAPHead.intermediateNetworks = _SWAPINT( 0x1 );
AssignArray( SAPECB.immediateAddress, SAPHead.destNode );
for( ;; ) {
IpxSend( IPXSocket, &SAPECB );
DosSemClear( &BroadCastStart );
DosSemWait( &BroadCastStop, 60000 );
if( ServerDie ) {
SAPHead.intermediateNetworks = _SWAPINT( 0x10 );
IpxSend( IPXSocket, &SAPECB );
ServerDie |= DIE_BROADCAST;
DosExit( EXIT_THREAD, 0 );
}
}
}
static char InitServer( void )
{
TID tid;
DosSemSet( &BroadCastStop );
DosSemSet( &BroadCastStart );
DosCreateThread( Broadcast, &tid, BroadcastStack + STACKSIZE );
DosSemWait( &BroadCastStart, -1L );
DosCreateThread( Respond, &tid, RespondStack + STACKSIZE );
return( 1 );
}
#endif
#define ACC_WORD( loc ) (*(unsigned *)&(loc))
static char FindPartner( void )
{
static BYTE segdata[128];
BYTE moresegs;
BYTE flags;
WORD connection;
if( NWGetPrimaryConnectionID( &connection ) != 0 ) return( 0 );
if( NWReadPropertyValue( connection, &SAPHead.name, DBG_SERVER_TYPE,
"NET_ADDRESS", 1, segdata, &moresegs, &flags ) != 0 ) return( 0 );
memcpy( &ServHead.destNet, segdata, 12 );
if( IpxGetLocalTarget( (PUCHAR)&ServHead.destNet,
&ServECB, (PULONG)segdata ) != 0 ) return( 0 );
IpxSend( IPXSocket, &ServECB );
RespECB.fragList[1].fragAddress = &PartnerSPXSocket;
if( IpxReceive( IPXSocket, 55*MAX_PARTNER_WAIT, &RespECB ) != 0 )
return( 0 );
_IPX_ASSIGNADDR( SendHead.dest, RespHead.source );
SendHead.destSocket = PartnerSPXSocket;
AssignArray( SendECB.immediateAddress, RespECB.immediateAddress );
return( 1 );
}
char *RemoteLink( char *name, char server )
{
unsigned i;
putstring( "RemoteLink\r\n" );
server = server;
if( name == NULL || *name == '\0' ) name = "NovLink";
for( i = 0; i < 47 && *name != '\0'; ++name ) {
if( strchr( "/\\:;,*?+-", *name ) == NULL ) {
SAPHead.name[ i++ ] = toupper( *name );
}
}
SAPHead.name[ i ] = '\0';
if( SpxOpenSocket( &SPXSocket ) != 0 || IpxOpenSocket( &IPXSocket ) != 0 ) {
return( TRP_ERR_can_not_obtain_socket );
}
_INITIPXECB( Serv );
_INITIPXECB( Resp );
RespECB.fragCount = 2;
RespECB.fragList[1].fragSize = sizeof( WORD ); /* for SPXSocket */
#ifdef SERVER
if( FindPartner() ) {
RemoteUnLink();
return( TRP_ERR_server_name_already_in_use );
}
if( !InitServer() ) {
RemoteUnLink();
return( TRP_ERR_can_not_initialize_server );
}
#else
if( !FindPartner() ) {
RemoteUnLink();
return( TRP_ERR_no_such_server );
}
#endif
return( NULL );
}
void RemoteUnLink( void )
{
#ifdef SERVER
ServerDie = DIE_WANT;
#endif
IpxCloseSocket( IPXSocket );
#ifdef SERVER
DosSemClear( &BroadCastStop );
if( InUse( ConnECB ) ) {
SpxCancelPacket( &ConnECB );
}
while( ServerDie != (DIE_WANT|DIE_BROADCAST|DIE_RESPOND) ) {
IPXRelinquishControl();
}
#endif
SpxCloseSocket( SPXSocket );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -