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

📄 novnt.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <winsock.h>
#include <wsipx.h>
#include <svcguid.h>
#include <nspapi.h>

#include "watcom.h"
#include "ipxstuff.h"
#include "packet.h"
#include "trperr.h"
#include "trptypes.h"
#include "bool.h"

#ifdef __NT__
#pragma library("wsock32")
#endif

#ifdef SERVER
static HANDLE                   ResponderThreadHandle;
static int                      ResponderSocket;
static int                      ListenSocket = INVALID_SOCKET;
static WORD                     ListenPort = 0;
#endif
static int                      ConnectionSocket = INVALID_SOCKET;
static struct sockaddr_ipx      PartnerAddr;

static char                     ServerName[128];

/* The _SWAPINT is because NT swaps the bytes on us again */
#define DBG_SAP_ID      SVCID_NETWARE( _SWAPINT( DBG_SERVER_TYPE ) );

bool Terminate( void )
{
    // a sideways dive to terminate the link (with failure)
    return( FALSE );
}

unsigned RemoteGet( char *rec, unsigned len )
{
    unsigned    got;
    unsigned    total;

    total = 0;
    for( ;; ) {
        got = recv( ConnectionSocket, rec, len, 0 );
        if( got == SOCKET_ERROR ) return( REQUEST_FAILED );
        total += got;
        if( got != MAX_DATA_SIZE ) break;
        len -= got;
        rec = (unsigned_8 *)rec + got;
    }
    return( total );
}

unsigned RemotePut( char *snd, unsigned len )
{

    while( len >= MAX_DATA_SIZE ) {
        if( send( ConnectionSocket, snd, MAX_DATA_SIZE, 0 ) == SOCKET_ERROR ) {
            return( REQUEST_FAILED );
        }
        snd = (unsigned_8 *)snd + MAX_DATA_SIZE;
        len -= MAX_DATA_SIZE;
    }
    if( send( ConnectionSocket, snd, len, 0 ) == SOCKET_ERROR ) {
        return( REQUEST_FAILED );
    }
    return( len );
}

char RemoteConnect( void )
{
    #ifdef SERVER
        struct sockaddr_ipx     address;
        int                     addr_len;
        struct timeval          timeout;
        struct fd_set           fd;

        if( ListenPort == 0 ) {
            memset( &address, 0, sizeof( address ) );
            address.sa_family = AF_IPX;
            ListenSocket = socket( AF_IPX, SOCK_SEQPACKET, NSPROTO_SPX );
            bind( ListenSocket, (struct sockaddr *)&address, sizeof( address ) );
            addr_len = sizeof( address );
            getsockname( ListenSocket, (struct sockaddr *)&address, &addr_len );
            ListenPort = address.sa_socket;
            listen( ListenSocket, 1 );
        }
        FD_ZERO( &fd );
        FD_SET( ListenSocket, &fd );
        timeout.tv_sec = 0;
        timeout.tv_usec = 10000;
        if( select( FD_SETSIZE, &fd, NULL, NULL, &timeout ) > 0 ) {
            addr_len = sizeof( address );
            ConnectionSocket = accept( ListenSocket, (struct sockaddr *)&address, &addr_len );
            ListenPort = 0;
            closesocket( ListenSocket );
            ListenSocket = INVALID_SOCKET;
            return( 1 );
        }
    #else
        ConnectionSocket = socket( AF_IPX, SOCK_SEQPACKET, NSPROTO_SPX );
        if( connect( ConnectionSocket, (struct sockaddr *)&PartnerAddr, sizeof( PartnerAddr ) ) == 0 ) {
            return( 1 );
        }
    #endif
    return( 0 );
}

void RemoteDisco( void )
{
    Sleep( 500 );       /* make sure last packet gets sent */
    closesocket( ConnectionSocket );
    ConnectionSocket = INVALID_SOCKET;
}

#define _bad_rc(x)              ((x) == SOCKET_ERROR)

#ifdef SERVER

static void register_bindery( char *name, BOOL do_register )
{
    DWORD               status = 0;
    SERVICE_INFO        info;
    GUID                guid = DBG_SAP_ID;
    SERVICE_ADDRESSES   server_address;
    int                 rv;
    struct sockaddr_ipx address;
    int                 addr_len;


    addr_len = sizeof( address );
    getsockname( ResponderSocket, (struct sockaddr *)&address, &addr_len );
    server_address.dwAddressCount = 1;
    server_address.Addresses[0].dwAddressType   = AF_IPX;
    server_address.Addresses[0].dwAddressFlags  = 0;
    server_address.Addresses[0].dwAddressLength = addr_len;
    server_address.Addresses[0].lpAddress       = (LPBYTE)&address;
    server_address.Addresses[0].dwPrincipalLength = 0;
    server_address.Addresses[0].lpPrincipal     = NULL;

    info.lpServiceType  = &guid;
    info.lpServiceName  = name;
    info.lpComment      = "Watcom Remote Debugger";
    info.lpLocale       = NULL;
    info.dwDisplayHint  = 0;
    info.dwVersion      = 0;
    info.dwTime         = 0;
    info.lpMachineName  = NULL;
    info.lpServiceAddress = &server_address;
    info.ServiceSpecificInfo.cbSize = 0;
    info.ServiceSpecificInfo.pBlobData = NULL;

    rv = SetService(NS_SAP,
                      do_register ? SERVICE_REGISTER : SERVICE_DEREGISTER,
                      SERVICE_FLAG_HARD,
                      &info,
                      NULL,
                      &status);

    if( _bad_rc( rv ) ) {
        return;
    }

    rv = SetService(NS_SAP,
                      SERVICE_FLUSH,
                      SERVICE_FLAG_HARD,
                      &info,
                      NULL,
                      &status);
}

static DWORD WINAPI Responder( LPVOID parm )
{
    int                 from_length;
    struct sockaddr_ipx from;
    char                buffer[ 1 ];

    parm = parm;
    for( ;; ) {
        from_length = sizeof( struct sockaddr_ipx );

        if( from_length == 0 ) break;   //to keep the compiler quiet
        if( recvfrom( ResponderSocket,
                        buffer,
                        sizeof( buffer ),
                        0,
                        (struct sockaddr *)&from,
                        &from_length ) >= 0 ) {
            sendto( ResponderSocket,
                      (char *)&ListenPort,
                      sizeof( ListenPort ),
                      0,
                      (struct sockaddr *)&from,
                      from_length );
        }
    }
    return( 0 );
}


static char *InitServer( void )
{
    DWORD       tid;
    struct sockaddr_ipx address;

    ResponderSocket = socket( AF_IPX, SOCK_DGRAM, NSPROTO_IPX+IPX_PACKET_TYPE );
    if( ResponderSocket == -1 ) return( "No responder socker" );
    memset( &address, 0, sizeof( address ) );
    address.sa_family = AF_IPX;
    bind( ResponderSocket, (struct sockaddr *)&address, sizeof( address ) );
    ResponderThreadHandle = CreateThread( NULL, 0, &Responder, NULL, 0, &tid );
    if( ResponderThreadHandle == NULL ) return( "No responder thread" );
    register_bindery( ServerName, TRUE );
    return( NULL );
}
#endif

static BOOL read_bindery( char * name ) {
/***************************************/
    GUID                guid = DBG_SAP_ID;
    static char         addr_buff[1024];
    DWORD               len;
    DWORD               alias_len;
    int                 protocols[2] = { NSPROTO_IPX, 0 };
    INT                 num;
    LPCSADDR_INFO       address_info;

    len = sizeof( addr_buff );
    alias_len = 0;
    num = GetAddressByName( NS_SAP,
                            &guid,
                            name,
                            protocols,
                            0,
                            NULL,
                            addr_buff,
                            &len,
                            NULL,
                            &alias_len );

    if( _bad_rc( num ) || num < 1 ) {
        return( FALSE );
    }

    address_info = (LPCSADDR_INFO)addr_buff;
    PartnerAddr = *(struct sockaddr_ipx *)(address_info->RemoteAddr.lpSockaddr);
    return( TRUE );
}

static char FindPartner( void )
{
    int                         b_socket;
    int                         rv;
    int                         from_length;
    struct sockaddr_ipx         s_address;
    struct timeval              timer;
    fd_set                      read_set;
    WORD                        port;

    // Look in the NetWare bindery for the requested server name.

    if( !read_bindery( ServerName ) ) {
        return( 0 );
    }

    b_socket = socket( AF_IPX, SOCK_DGRAM, NSPROTO_IPX+IPX_PACKET_TYPE );

    if( b_socket == INVALID_SOCKET ) {
        return( 0 );
    }

    memset( &s_address, 0, sizeof( s_address ) );
    s_address.sa_family = AF_IPX;

    bind( b_socket, (struct sockaddr *)&s_address, sizeof( s_address ) );
    sendto( b_socket, "", 1, 0, (struct sockaddr *)&PartnerAddr, sizeof( PartnerAddr ) );
    WSAGetLastError();
    timer.tv_sec  = MAX_PARTNER_WAIT / TICKS_PER_SEC;
    timer.tv_usec = 0;

    FD_ZERO( &read_set );
    FD_SET( b_socket, &read_set );

    rv = select( b_socket + 1,
                  &read_set,
                  NULL,
                  NULL,
                  &timer );

    if( _bad_rc( rv ) ) {
        closesocket( b_socket );
        return( 0 );
    }

    if( rv == 0 ) {
        // Server not found
        closesocket( b_socket );
        return( 0 );
    }

    // Server found -- get the address.

    from_length = sizeof( PartnerAddr );

    rv = recvfrom( b_socket, (char *)&port, sizeof( port ), 0, (struct sockaddr *)&PartnerAddr, &from_length );

    closesocket( b_socket );

    if( _bad_rc( rv ) ) {
        return( 0 );
    }

    PartnerAddr.sa_socket = port;
    return( 1 );
}

char *RemoteLink( char *name, char server )
{
    unsigned    i;
    WSADATA     data;
#ifdef SERVER
    char        *p;
#endif

    server = server;

    if( name == NULL || *name == '\0' ) name = "NovLink";
    for( i = 0; i < 47 && *name != '\0'; ++name ) {
        if( strchr( "/\\:;,*?+-", *name ) == NULL ) {
            ServerName[ i++ ] = toupper( *name );
        }
    }
    ServerName[ i ] = '\0';
    if( WSAStartup( 0x101, &data ) != 0 ) {
        return( TRP_ERR_can_not_obtain_socket );
    }
    #ifdef SERVER
        if( FindPartner() ) {
            RemoteUnLink();
            return( TRP_ERR_server_name_already_in_use );
        }
        if( ( p = InitServer() ) != NULL ) {
            RemoteUnLink();
            return( p );
        }
    #else
        if( !FindPartner() ) {
            RemoteUnLink();
            return( TRP_ERR_no_such_server );
        }
    #endif
    return( NULL );
}


void RemoteUnLink( void )
{
    #ifdef SERVER
        register_bindery( ServerName, FALSE );
        TerminateThread( ResponderThreadHandle, 0 );
        closesocket( ResponderSocket );
        closesocket( ListenSocket );
        ResponderThreadHandle = 0;
        ResponderSocket = 0;
        ListenSocket = INVALID_SOCKET;
        ListenPort = 0;
    #endif
    closesocket( ConnectionSocket );
    WSACleanup();
    ConnectionSocket = INVALID_SOCKET;
    memset( &PartnerAddr, 0, sizeof( PartnerAddr ) );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -