h06995
s 00012/00000/00610
d D 1.2 89/10/19 09:52:05 opcode 2 1
c WIRETAP ifdefs
e
s 00610/00000/00000
d D 1.1 89/10/12 17:03:25 opcode 1 0
c date and time created 89/10/12 17:03:25 by opcode
e
u
U
f e 0
t
T
I 1
#ifndef	lint
static char sccsid[] = "@(#)server_rpc.c 1.9 88/12/21";
#endif	/*lint*/

#include "cbratp.h"
#include "romfs.h"
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/file.h>

extern int vsdev;
extern int errno;

fd_set	non_blocking_fds;
fd_set	stopped_fds;
fd_set	lseek_fds;

I 2
#ifndef	WIRETAP
E 2
rpc_open(path, flags, mode)
    register char *path;
    int flags;
    int mode;
{
    u_char *buffer;
    register u_char *p;

    if (!pkt_mode)
	return -1;

    p = buffer = (u_char *) malloc((unsigned) strlen(path) + 9);
    while (*path)
	*p++ = *path++;
    *p++ = '\0';
    p = encode_long(p, (long) flags);
    p = encode_long(p, (long) mode);
    enqueue(OPEN_CHN, buffer, p - buffer);
    free((char *) buffer);
    wait_for(OPEN_CHN);

    if (flags & O_WRONLY)
	return return_int2;

    return return_int;
}
I 2
#endif	/*WIRETAP*/
E 2

rpc_close(fd)
    int	fd;
{
    u_char buffer[4];
    register u_char *p = buffer;

    if (!pkt_mode)
	return -1;

    *p++ = LOCAL_TO_RPC(fd);
    enqueue(CLOSE_CHN, buffer, p - buffer);
    wait_for(CLOSE_CHN);

    if (return_int == 0) {
	FD_CLR(fd, &read_fds);
	FD_CLR(fd, &non_blocking_fds);
	FD_CLR(fd, &stopped_fds);
	FD_CLR(fd, &lseek_fds);
	if (rd_queue[fd] != NULL) {
	    cq_free(rd_queue[fd]);
	    rd_queue[fd] = NULL;
	}
	if (rd_chan[fd]) {
	    free_channel(rd_chan[fd]);
	    rd_chan[fd] = NULL;
	}
	if (wr_chan[fd]) {
	    free_channel(wr_chan[fd]);
	    wr_chan[fd] = NULL;
	}
    }

    return 0;
}

rpc_read(fd, buf, size)
    int	fd;
    register char *buf;
    register int size;
{
    struct cqueue *r;
    register u_char *p;
    extern u_char bgetc();

    if (!pkt_mode)
	return -1;

    if ((r = rd_queue[fd]) == NULL)
	return -1;

    if (r->size == 0) {
	if (FD_ISSET(fd, &read_fds))
		return 0;
	
	if (FD_ISSET(fd, &non_blocking_fds)) {
	    errno = EWOULDBLOCK;
	    return -1;
	} 
	
	if (FD_ISSET(fd, &lseek_fds)) {
	    u_char buffer[4];

	    p = encode_long(buffer, (long) size);
	    enqueue(rd_chan[fd], buffer, p - buffer);
	}

	wait_for(rd_chan[fd]);
    }

    if (r->size < size)
	size = r->size;

    p = (u_char *) buf;
    while (--size >= 0)
	*p++ = bgetc(r);

    if (r->size == 0) {
	FD_CLR(fd, &read_fds);
    }

    if (r->size < 1024 && FD_ISSET(fd, &stopped_fds)) {
	enqueue(rd_chan[fd], (u_char *) 0, 0);
	FD_CLR(fd, &stopped_fds);
    }

    return((char *) p - buf);
}

I 2
#ifndef	WIRETAP
E 2
rpc_nbwrite(fd, buf, size)
    int fd;
    char *buf;
    int size;
{
    return rpc_write(fd, buf, size);
} /*### all writes are almost non-blocking */
I 2
#endif	/*WIRETAP*/
E 2

rpc_write(fd, buf, size)
    int fd;
    register char *buf;
    register int size;
{
    if (!pkt_mode)
	return size;

    if (wr_chan[fd]) {
	enqueue(wr_chan[fd], (u_char *) buf, size);
	return size;
    }

    return -1;
}

rpc_poll(width, readfds, writefds, exceptfds, timeout)
    register int width;
    register fd_set *readfds;
    register fd_set *writefds;
    fd_set *exceptfds;
    struct timeval *timeout;
{
    register int i;
    register int n = 0;
    register fd_set *rpc_fds = &read_fds;

    if (width > RPC_FDMAX + 1)
	width = RPC_FDMAX + 1;

    if (readfds)
	for (i=RPC_FDBASE; i<width; i++)
	    if (FD_ISSET(i, readfds)) {
	    readagain:
		if (FD_ISSET(i, rpc_fds))
		    n++;
		else {
		    if (timeout)	/* don't wait */
			FD_CLR(i, readfds);
		    else {	/* loop until data is ready for this fd */
			wakeup_io();
			goto readagain;
		    }
		}
	    }

    if (writefds)
	for (i=RPC_FDBASE; i< width; i++)
	    if (FD_ISSET(i, writefds))
		n++;

    if (exceptfds)
	for (i=RPC_FDBASE; i< width; i++)
	    FD_CLR(i, exceptfds);

    return n;
}

rpc_openconnection(name)
    char *name;
{
    if (!pkt_mode)
	return -1;

    enqueue(OPENCON_CHN, (u_char *) name, strlen(name) + 1);
    wait_for(OPENCON_CHN);

    return return_int;
}

rpc_acceptconnection(fd)
    int fd;
{
    u_char buffer[4];
    register u_char *p = buffer;

    if (!pkt_mode)
	return -1;

    *p++ = LOCAL_TO_RPC(fd);
    enqueue(ACCEPTCON_CHN, buffer, p - buffer);
    wait_for(ACCEPTCON_CHN); 
    FD_CLR(fd, &read_fds);

    if (return_int >= 0)
	FD_SET(return_int, &non_blocking_fds);

    return return_int;
}

rpc_spawn(buf)
    register char *buf;
{
    if(!pkt_mode)
	return -1;

    enqueue(SPAWN_CHN, (u_char *) buf, strlen(buf) + 1);
    return 0;
}

rpc_putenv(name, value)
    register char *name;
    register char *value;
{
    int namelen;
    int valuelen;
    char *buffer;

    valuelen = strlen(value);

    if (strcmp(name, "XNEWSHOME") == 0) {
#ifdef	notdef
	if (xnewshome)
	    free(xnewshome);
#endif	/*notdef*/
	if ((xnewshome = malloc((unsigned) (valuelen + 1))) == 0)
	    abort();
	(void) strcpy(xnewshome, value);
    }

    if (pkt_mode) {
	namelen = strlen(name);
	buffer = malloc((unsigned) (namelen + valuelen + 2));
	bcopy(name, buffer, namelen);
	buffer[namelen] = '=';
	bcopy(value, &buffer[namelen + 1], valuelen);
	buffer[namelen + valuelen + 1] = '\0';
	enqueue(PUTENV_CHN, (u_char *) buffer, namelen + valuelen + 2);
	free(buffer);
    }

    (void) setenv(name, value);
    return 0;
}

rpc_serveraddress(fd, adr, len)
    int	fd;
    char *adr;
    int	len;
{
    u_char buffer[4];
    register u_char *p = buffer;

    if (!pkt_mode)
	return -1;

    *p++ = LOCAL_TO_RPC(fd);
    enqueue(SERVERADDR_CHN, buffer, p - buffer);
    wait_for(SERVERADDR_CHN);

    bcopy(return_ptr, adr, len);
    free(return_ptr);

    return 0;
}

I 2
#ifndef	WIRETAP
E 2
/*
 * Does a getpeername() on peer connected to socket s.
 * Stores the name at adr and returns the actual length.
 */
rpc_clientaddress(fd, adr, len)
    int fd;
    char *adr;
    int len;
{
    u_char buffer[4];
    register u_char *p = buffer;

    if (!pkt_mode)
	return -1;

    *p++ = LOCAL_TO_RPC(fd);
    enqueue(CLIENTADDR_CHN, buffer, p - buffer);
    wait_for(CLIENTADDR_CHN);
    bcopy(return_ptr, adr, len);
    free(return_ptr);

    return 0;
}
I 2
#endif	/*WIRETAP*/
E 2

rpc_servername(adr, len)
    char *adr;
    int len;
{
    if(!pkt_mode)
	return -1;

    enqueue(SERVERNAME_CHN, (u_char *) 0, 0);
    wait_for(SERVERNAME_CHN);
    bcopy(return_ptr, adr, len);
    free(return_ptr);

    return 0;
}

I 2
#ifndef	WIRETAP
E 2
char *
rpc_getenv(name)
    register char *name;
{
    if (pkt_mode) {
	enqueue(GETENV_CHN, (u_char *) name, strlen(name) + 1);
	wait_for(GETENV_CHN);

	if (return_int) {
	    setenv(name, return_ptr);
	    free(return_ptr);
	}
	else {
	    free(return_ptr);
	    return (char *)0;
	}
    }

    return(nut_getenv(name));
}

off_t
rpc_lseek(fd, offset, whence)
    int	fd;
    off_t offset;
    int whence;
{
    u_char buffer[6];
    u_char tmp = whence;
    register u_char *p = buffer;

    if (!pkt_mode)
	return((off_t) -1);

    *p++ = LOCAL_TO_RPC(fd);
    *p++ = tmp;
    p = encode_long(p, offset);
    enqueue(LSEEK_CHN, buffer, p - buffer);
    wait_for(LSEEK_CHN);

    FD_SET(fd, &lseek_fds);
    if (return_long >= 0 && rd_queue[fd] != 0) {
	if (whence == L_INCR && offset == 0) {
	    /* just checking current position, adjust for buffering */
	    return_long -= rd_queue[fd]->size;
	}
	else {
	    /* reset all data pointers, we're seeking some place else */
	    FD_CLR(fd, &read_fds);
	    rd_queue[fd]->size = 0;
	    rd_queue[fd]->tail = rd_queue[fd]->buf;
	    rd_queue[fd]->head = rd_queue[fd]->buf;
	}
    }

    return((off_t) return_long);
}

char *
rpc_gethostname(family, length, pAddr)
    int family;
    int length;
    u_char *pAddr;
{
    u_char buffer[100];
    register u_char *p = buffer;

    if (!pkt_mode)
	return NULL;

    p = encode_long(p, (long) family);
    bcopy((char *) pAddr, (char *) p, length);
    p += length;
    enqueue(GETHOSTNAME_CHN, buffer, p - buffer);
    wait_for(GETHOSTNAME_CHN);

    return return_ptr;
}

rpc_gethostaddr(name, family, length, pAddr)
    char *name;
    int *family;
    int *length;
    char **pAddr;
{
    if (!pkt_mode)
	return 0;

    enqueue(GETHOSTADDR_CHN, (u_char *) name, strlen(name) + 1);
    wait_for(GETHOSTADDR_CHN);

    if (return_int) {
	*length = return_int;
	*family = (int)return_long;
	*pAddr = return_ptr;
	return 1;
    }

    return 0;
}

char *
rpc_homedir(username)
    char *username;
{
    if(!pkt_mode)
	return 0;

    enqueue(HOMEDIR_CHN, (u_char *) username, strlen(username) + 1);
    wait_for(HOMEDIR_CHN);

    return((char *) return_ptr);
}

char *
rpc_cwd()
{
    if(!pkt_mode)
	return 0;

    enqueue(CWD_CHN, (u_char *) 0, 0);
    wait_for(CWD_CHN);

    return((char *) return_ptr);
}

off_t 
rpc_filesize(fd)
    int	fd;
{
    u_char	c;

    if(!pkt_mode)
	return 0;

    c = LOCAL_TO_RPC(fd);
    enqueue(FILESIZE_CHN, &c, 1);
    wait_for(FILESIZE_CHN);

    return((off_t) return_long);
}
I 2
#endif	/*WIRETAP*/
E 2

rpc_quit()
{
    u_char buffer[5];
    register u_char *b = buffer;

    if (!pkt_mode)
	return;

    *b++ = QUIT_CMD;
    enqueue(CONTROL_CHN, buffer, b - buffer);
    wait_for(CONTROL_CHN);
    enqueue(CONTROL_CHN, (u_char *) 0, 0);
    drain();
}

I 2
#ifndef	WIRETAP
E 2
rpc_setbaudrate(r)
    int	r;
{
    u_char buffer[5];
    register u_char *p = buffer;

    if(!pkt_mode)
	return 1;

    *p++ = SPEED_CMD;
    p = encode_long(p, (long) r);
    enqueue(CONTROL_CHN, buffer, p - buffer);
    wait_for(CONTROL_CHN);
    enqueue(CONTROL_CHN, (u_char *) 0, 0);
    drain();

    return 0;
}

rpc_crconoff(c)
    int	c;
{
    u_char buffer[4];
    register u_char *b = buffer;

    if(!pkt_mode)
	return;

    *b++ = CRC_CMD;
    *b++ = c;
    enqueue(CONTROL_CHN, buffer, b - buffer);
    wait_for(CONTROL_CHN);
    enqueue(CONTROL_CHN, (u_char *) 0, 0);
    drain();

    crc_mode = c;
}
I 2
#endif	/*WIRETAP*/
E 2


VERSION *
rpc_version(vers)
    int vers;
{
    u_char buffer[4];
    register u_char *p = buffer;
    static VERSION version;

    if(!pkt_mode)
	return 0;

    if (version.version == 0) {
	p = encode_short(p, vers);
	enqueue(VERSION_CHN, buffer, p - buffer);
	wait_for(VERSION_CHN);

	version.version = decode_short((u_char *) return_ptr);
	version.firstfd = decode_short((u_char *) return_ptr + 2);
	version.res1 = decode_long((u_char *) return_ptr + 4);
	version.res2 = decode_long((u_char *) return_ptr + 8);
	version.res3 = decode_long((u_char *) return_ptr + 12);
	free(return_ptr);
    }

    return &version;
}

I 2
#ifndef	WIRETAP
E 2
rpc_pipe(name, ifd, ofd, flags)
    char *name;
    int *ifd;
    int *ofd;
    int flags;
{
    register u_char *buffer;
    register int len;
    register char c = flags;

    if(!pkt_mode)
	return -1;

    len = strlen(name);
    buffer = (u_char *) malloc((unsigned) len + 2);	/* null + 1 byte fd */
    if (buffer == (u_char *) 0)
	return -1;

    *buffer = c;
    bcopy(name, (char *) buffer + 1, len + 1);
    enqueue(PIPE_CHN, buffer, len + 2);
    wait_for(PIPE_CHN);
    free((char *) buffer);

    *ifd = return_int;
    *ofd = return_int2;

    if (flags & O_WRONLY)
	return return_int2;

    return return_int;
}

/*ARGSUSED*/
rpc_ioctl(fd, request, arg)
    int fd;
    int request;
    char *arg;
{
    return 0;
}

/*ARGSUSED*/
rpc_fcntl(fd, cmd, arg)
    int fd;
    int cmd;
    int arg;
{
    return 0;
}
I 2
#endif	/*WIRETAP*/
E 2
E 1
