dbgif_requests.c 4.48 KB
/*
 * ==========================================================================
 * Copyright (c) 1993, Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
 * the contents of this file may not be disclosed to third parties, copied
 * or duplicated in any form, in whole or in part, without the prior written
 * permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
 * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
 * successor clauses in the FAR, DOD or NASA FAR Supplement.  Unpublished
 * rights reserved under the Copyright Laws of the United States.
 * ==========================================================================
 * Module   : request handler and dispatcher
 *
 * Author   : First Last (login)
 * Owner    : First Last (login)
 * Reviewer : First Last (login)
 *
 * $Source: /root/leakn64/depot/rf/sw/n64os20l/debugger/dbgif/dbgif_requests.c,v $
 * $Revision: 1.3 $
 * $Date: 2002/10/29 08:22:51 $
 * ==========================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#ifdef __sgi__
#include <bstring.h>
#endif

#include "rkfsn.h"
#include "dbgproto.h"
#include "dbgif.h"
#include "dbgif_services.h"

#define DEFAULT_PORT 5777 /* debugger connects here */

static char *buf = 0;
static int bufsize = 0;

void stError (const char *str)
{
    perror (str);
    exit (0);
}

KKHeader *stReadRequestPacket (int sock)
{
    int nbytes, size;
    KKHeader *request;
    
    if (buf == 0) {
	buf = (char *) malloc (BUFSIZE);
	bufsize = BUFSIZE;
    }

    nbytes = recv (sock, buf, sizeof(KKHeader), MSG_PEEK);

    if (nbytes == 0) /* close down client */
	return (NULL);
    else if (nbytes != sizeof (KKHeader)) { /* incomplete packet */
	printf("nbytes %d\n", nbytes);
        nbytes = recv (sock, buf, sizeof(KKHeader), MSG_PEEK);
	if (nbytes != sizeof (KKHeader))
	    stError ("packet header read call failed");
    }
    request = (KKHeader *) buf;

    if (request->length > bufsize) {
	bufsize = (request->length % BUFSIZE) * BUFSIZE + BUFSIZE;
	buf = (char *) realloc (buf, bufsize);
    }

    /* read the entire packet */
    nbytes = recv (sock, buf, request->length, 0);
    if (nbytes != request->length)
	stError ("Unable to read request packet");

    if (request->rev != TV_DBGPROTO_REV)
	printf("dbgif readrequest: version mismatch expected %d, got %d\n",
	       TV_DBGPROTO_REV, request->rev);

    return (request);
}

int stDispatchRequest (KKHeader* request)
{
    if (request->code < _KK_REQ_COUNT)
	    (*ClientRequestDispatchTable[request->code])(request);
    else
	    stStray(request);
    return (0);
}

int stOpenTCPconnection (int port)
{
    int sock;
    struct sockaddr_in sockaddr_in;
    struct hostent *hostent;
    char hostname[MAXHOSTNAMELEN + 1];
    int optval = 1;
    int optlen;
    
    /*
     * create a nameless stream socket in internet domain using
     * default TCP protocol
     */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	stError ("Socket call failed");

    if (gethostname (hostname, MAXHOSTNAMELEN) == -1)
	stError ("gethostname call failed");

    if ((hostent = gethostbyname(hostname)) == NULL)
	stError ("gethostbyname call failed");

    setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    setsockopt(sock, SOL_SOCKET, SO_LINGER, &optval, sizeof (optval));

#if 0
    optlen = sizeof(optval);
    getsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &optval, &optlen);
    printf("settop opt reuseaddr %d len %d\n", optval, optlen);
    optlen = sizeof(optval);
    getsockopt (sock, SOL_SOCKET, SO_LINGER, &optval, &optlen);
    printf("settop opt linger %d len %d\n", optval, optlen);
#endif

    bzero ((char *) &sockaddr_in, sizeof(struct sockaddr_in));
    bcopy (hostent->h_addr, (char *)&sockaddr_in.sin_addr, hostent->h_length);
    sockaddr_in.sin_family = AF_INET;
    sockaddr_in.sin_port = port;

    /* bind the name to the socket */
    if (bind (sock, (struct sockaddr *) &sockaddr_in,
	      sizeof(struct sockaddr_in)) == -1)
	stError ("bind call failed");

    /* listen on the socket */
    if (listen (sock, MAX_BACKLOG) == -1)
	stError ("listen call failed");
    
    return (sock);
}