File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / lib / X / XConnDis.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:38:27 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3, HEAD
researchv9-SUN3

#include "copyright.h"
/* $Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/lib/X/XConnDis.c,v 1.1.1.2 2018/04/24 17:38:27 root Exp $ */
/* Copyright    Massachusetts Institute of Technology    1985, 1986	*/
#define NEED_EVENTS
#include <stdio.h>
#include "Xlibint.h"
#include <strings.h>

void bcopy();
/* 
 * Attempts to connect to server, given display name. Returns file descriptor
 * (network socket) or -1 if connection fails. The expanded display name
 * of the form hostname:number.screen ("::" if DECnet) is returned in a result
 * parameter. The screen number to use is also returned.
 */
int _XConnectDisplay (display_name, expanded_name, screen_num)

    char *display_name;
    char *expanded_name;	/* return */
    int *screen_num;		/* return */

{
	struct utsname uts;
	char displaybuf[256];		/* Display string buffer */	
	char ipcstring[256];		/* ipcopen string */	
	register char *display_ptr;	/* Display string buffer pointer */
	register char *numbuf_ptr;	/* Server number buffer pointer */
	char *screen_ptr;		/* Pointer for locating screen num */
	int display_num;		/* Display number */
        int fd;				/* Network socket */
	int port;
	char numberbuf[16];
	char *dot_ptr = NULL;		/* Pointer to . before screen num */

	/* 
	 * Find the ':' seperator and extract the hostname and the
	 * display number.
	 */
	(void) strncpy(displaybuf, display_name, sizeof(displaybuf));
	if ((display_ptr = SearchString(displaybuf,':')) == NULL) return (-1);
	*(display_ptr++) = '\0';
 
	/* displaybuf now contains only a null-terminated host name, and
	 * display_ptr points to the display number.
	 * If the display number is missing there is an error. */

	if (*display_ptr == '\0') return(-1);

	/*
	 * Build a string of the form <display-number>.<screen-number> in
	 * numberbuf, using ".0" as the default.
	 */
	screen_ptr = display_ptr;
	numbuf_ptr = numberbuf;
	while (*screen_ptr != '\0') {
	    if (*screen_ptr == '.') {
		dot_ptr = numbuf_ptr;
		*(screen_ptr++) = '\0';
		*(numbuf_ptr++) = '.';
	    } else {
		*(numbuf_ptr++) = *(screen_ptr++);
	    }
	}

	/*
	 * If the spec doesn't include a screen number, add ".0" (or "0" if
	 * only "." is present.)
	 */
	if (dot_ptr == NULL) {
	    dot_ptr = numbuf_ptr;
	    *(numbuf_ptr++) = '.';
	    *(numbuf_ptr++) = '0';
	} else {
	    if (*(numbuf_ptr - 1) == '.')
		*(numbuf_ptr++) = '0';
	}
	*numbuf_ptr = '\0';

	/*
	 * Return the screen number in the result parameter
	 */
	*screen_num = atoi(dot_ptr + 1);

	/*
	 * Convert the server number string to an integer.
	 */
	display_num = atoi(display_ptr);
        port = display_num + X_TCP_PORT;

	/*
	 * If the display name is missing, use current host.
	 */
	if (displaybuf[0] == '\0') {
		sprintf(ipcstring, "/cs/tcp.%d", port);
		/*
		 * Read in the local system name
		 */
		uname(&uts);
		strcpy(displaybuf, uts.sysname);
	} else
		sprintf(ipcstring, "/cs/tcp!%s!tcp.%d", displaybuf, port);
	if ((fd = ipcopen(ipcstring, "heavy")) == -1) {
		(void) close (fd);
		return(-1);
	}

	/*
	 * set it non-blocking.  This is so we can read data when blocked
	 * for writing in the library.
	 */
	(void) ioctl(fd, FIOWNBLK, 0);
	/*
	 * Return the id if the connection succeeded. Rebuild the expanded
	 * spec and return it in the result parameter.
	 */
	display_ptr = displaybuf;
	while (*(++display_ptr) != '\0')
	    ;
	*(display_ptr++) = ':';
	numbuf_ptr = numberbuf;
	while (*numbuf_ptr != '\0')
	    *(display_ptr++) = *(numbuf_ptr++);
	*display_ptr = '\0';
	(void) strcpy(expanded_name, displaybuf);
	return(fd);

}

/* 
 * Disconnect from server.
 */

int _XDisconnectDisplay (server)

    int server;

{
    (void) close(server);
}

#undef NULL
#define NULL ((char *) 0)
/*
 * This is an OS dependent routine which:
 * 1) returns as soon as the connection can be written on....
 * 2) if the connection can be read, must enqueue events and handle errors,
 * until the connection is writable.
 */
_XWaitForWritable(dpy)
    Display *dpy;
{
    unsigned long r_mask[MSKCNT];
    unsigned long w_mask[MSKCNT];
    int nfound;

    CLEARBITS(r_mask);
    CLEARBITS(w_mask);

    while (1) {
	BITSET(r_mask, dpy->fd);
        BITSET(w_mask, dpy->fd);

	do {
	    nfound = select (dpy->fd + 1, r_mask, w_mask, 0x6fffffff);
	    if (nfound < 0 && errno != EINTR)
		(*_XIOErrorFunction)(dpy);
	} while (nfound <= 0);

	if (ANYSET(r_mask)) {
	    char buf[BUFSIZE];
	    long pend_not_register;
	    register long pend;
	    register xEvent *ev;

	    /* find out how much data can be read */
	    if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0)
		(*_XIOErrorFunction)(dpy);
	    pend = pend_not_register;

	    /* must read at least one xEvent; if none is pending, then
	       we'll just block waiting for it */
	    if (pend < sizeof(xEvent)) pend = sizeof (xEvent);
		
	    /* but we won't read more than the max buffer size */
	    if (pend > BUFSIZE) pend = BUFSIZE;

	    /* round down to an integral number of XReps */
	    pend = (pend / sizeof (xEvent)) * sizeof (xEvent);

	    _XRead (dpy, buf, pend);
	    for (ev = (xEvent *) buf; pend > 0; ev++, pend -= sizeof(xEvent))
	    {
		if (ev->u.u.type == X_Error)
		    _XError (dpy, (xError *) ev);
		else		/* it's an event packet; enqueue it */
		    _XEnq (dpy, ev);
	    }
	}
	if (ANYSET(w_mask))
	    return;
    }
}


_XWaitForReadable(dpy)
  Display *dpy;
{
    unsigned long r_mask[MSKCNT];
    int result;
	
    CLEARBITS(r_mask);
    do {
	BITSET(r_mask, dpy->fd);
	result = select(dpy->fd + 1, r_mask, NULL, 0x7fffffff);
	if (result == -1 && errno != EINTR) (*_XIOErrorFunction)(dpy);
    } while (result <= 0);
}

static int padlength[4] = {0, 3, 2, 1};

_XSendClientPrefix (dpy, client)
     Display *dpy;
     xConnClientPrefix *client;
{
	/*
	 * Authorization string stuff....  Must always transmit multiple of 4
	 * bytes.
	 */

        char *auth_proto = ""; 
	int auth_length;
	char *auth_string = "";
	int auth_strlen;
	char pad[3];
	char buffer[BUFSIZ], *bptr;

        int bytes=0;

        auth_length = strlen(auth_proto);
        auth_strlen = strlen(auth_string);
        client->nbytesAuthProto = auth_length;
	client->nbytesAuthString = auth_strlen;

	bytes = (sizeof(xConnClientPrefix) + 
                       auth_length + padlength[auth_length & 3] +
                       auth_strlen + padlength[auth_strlen & 3]);

	bcopy(client, buffer, sizeof(xConnClientPrefix));
        bptr = buffer + sizeof(xConnClientPrefix);
        if (auth_length)
	{
	    bcopy(auth_proto, bptr, auth_length);
            bptr += auth_length;
            if (padlength[auth_length & 3])
	    {
		bcopy(pad, bptr, padlength[auth_length & 3]);
	        bptr += padlength[auth_length & 3];
	    }
	}
        if (auth_strlen)
	{
	    bcopy(auth_string, bptr, auth_strlen);
            bptr += auth_strlen;
            if (padlength[auth_strlen & 3])
	    {
		bcopy(pad, bptr, padlength[auth_strlen & 3]);
	        bptr += padlength[auth_strlen & 3];
	    }
	}
	(void) WriteToServer(dpy->fd, buffer, bytes);
	return;
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.