⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 novos2.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        /*
            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 + -