h35954
s 00053/00062/01027
d D 1.18 89/08/22 16:55:12 opcode 18 17
c debug comments for gethostname and gethostaddr
e
s 00191/00178/00898
d D 1.17 89/08/21 15:12:29 opcode 17 16
c linted
e
s 00054/00054/01022
d D 1.16 89/08/18 10:25:12 opcode 16 15
c cosmetic changes, registers, etc.
e
s 00092/00036/00984
d D 1.15 89/08/14 15:26:07 opcode 15 14
c updated spawn code to match FCS sun_osi.c
e
s 00092/00058/00928
d D 1.14 89/08/14 10:50:36 chrisb 14 13
c added rs232_debugfile
e
s 00010/00162/00976
d D 1.13 89/08/07 18:21:06 chrisb 13 12
c comments
e
s 00019/00003/01119
d D 1.12 89/08/02 14:00:23 chrisb 12 11
c fixed lseek blocking problem
e
s 00166/00010/00956
d D 1.11 89/07/14 15:34:33 opcode 11 10
c added PIPE rpc, rs232 debugging, changed OPEN packet to match PIPE pkt
e
s 00035/00000/00931
d D 1.10 89/07/12 10:47:56 opcode 10 9
c VERSION rpc
e
s 00021/00005/00910
d D 1.9 89/07/10 14:09:56 opcode 9 8
c host_cache code from sun_osi.c
e
s 00060/00018/00855
d D 1.8 89/07/05 11:01:25 opcode 8 7
c syncing with sun_osi
e
s 00005/00007/00868
d D 1.7 89/03/29 11:31:16 opcode 7 6
c filesize use fstat instead of lseek's
e
s 00094/00092/00781
d D 1.6 89/03/29 10:30:27 opcode 6 5
c debug code cleanup
e
s 00002/00000/00871
d D 1.5 89/03/29 09:56:09 opcode 5 4
c logs out helper when quit from the Nut
e
s 00006/00014/00865
d D 1.4 89/03/13 11:42:26 chrisb 4 3
c chkpt from chrisb
e
s 00096/00038/00783
d D 1.3 89/01/26 14:53:03 chrisb 3 2
c added -i and brought up to 1.1 version
e
s 00004/00000/00817
d D 1.2 88/12/21 11:51:55 chrisb 2 1
c added sccs keyword ids
e
s 00817/00000/00000
d D 1.1 88/12/21 11:28:21 chrisb 1 0
c date and time created 88/12/21 11:28:21 by chrisb
e
u
U
f e 0
t
T
I 2
#ifndef	lint
D 15
static char sccsid[] = "@(#)helper_rcv.c 1.8 88/12/21";
E 15
I 15
static char sccsid[] = "%Z%%M% %I% %E%";
E 15
#endif

I 15
/*
 * Copyright (c) 1989 by Sun Microsystems, Inc. 
 */ 

E 15
E 2
I 1
#include "cbratp.h"
#include <sys/dir.h>
#include <fcntl.h>
#include <ctype.h>
I 8
#include <sys/types.h>
#include <sys/file.h>
E 8
#include <sys/socket.h>
#include <sys/stat.h>
I 8
#ifndef NOUNIXSOCKETS
E 8
#include <sys/un.h>
I 3
#include <strings.h>
I 8
#endif
#include <errno.h>
E 8
E 3
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
I 3
#include <netinet/tcp.h>
E 3
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
I 15
#include <signal.h>
I 17
#include <sys/param.h>
E 17
E 15

I 4
fd_set stopped_fds;
I 12
fd_set lseek_fds;
E 12
I 5
D 15
extern int news_pid;
E 15
I 10
D 17
int firstfd;
int server_version;
E 17
I 17
short firstfd;
short server_version;
E 17
E 10
E 5

I 15
extern int news_pid;
extern char *getenv();

E 15
I 10
static struct  hosts_entry {
    char inet_num[20];
    char name[30];
} hosts_cache[10];
static int next = 0;

I 15
#ifdef	DEBUG
E 15
I 13
extern long bytes_in;
extern long bytes_out;
extern long escapes_in;
extern long escapes_out;
I 15
#endif	/*DEBUG*/
E 15

E 13
E 10
E 4
rcv_control(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
    u_char *b;
    u_char *p;
    int	s;

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
    printf("control\n");
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("control\n");
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "control\n");
E 17
I 17
	(void) fprintf(rs232_debugfile, "control\n");
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 16
    if (chan[c]->len == 0)
    {
E 16
I 16
    if (chan[c]->len == 0) {
E 16
D 17
	free(chan[c]->buf);
E 17
I 17
	free((char *) chan[c]->buf);
E 17
	return 0;
    }
    chan[c]->len = 0;
    p = b = chan[c]->buf;
D 17
    send(c, 0, 0);
E 17
I 17
    enqueue(c, (u_char *) 0, 0);
E 17
    wait_for(c);
I 14
#ifdef	DEBUG
E 14
I 13
    if (rs232_debug) {
D 14
	printf("chars in %d (%d escaped)\n", bytes_in, escapes_in);
	printf("chars out %d (%d escaped)\n", bytes_out, escapes_out);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "in %d (%d escaped)\n", bytes_in, escapes_in);
	fprintf(rs232_debugfile, "out %d (%d escaped)\n",bytes_out,escapes_out);
E 17
I 17
D 18
	(void) fprintf(rs232_debugfile, "in %d (%d escaped)\n", bytes_in, escapes_in);
	(void) fprintf(rs232_debugfile, "out %d (%d escaped)\n",bytes_out,escapes_out);
E 18
I 18
	(void) fprintf(rs232_debugfile, "in %d (%d escaped)\n",
						    bytes_in, escapes_in);
	(void) fprintf(rs232_debugfile, "out %d (%d escaped)\n",
						    bytes_out, escapes_out);
E 18
E 17
E 14
    }
I 14
#endif	DEBUG
E 14
E 13
    drain();

    switch (*b++) {
    case QUIT_CMD:
I 5
D 14
	(void) lseek (0, -16L, 0);	/* will logout */
E 14
I 14
	/*(void) lseek (0, -16L, 0);	/* will logout */
E 14
E 5
	exit(0);
D 16

E 16
    case CRC_CMD:
	crc_mode = *b;
	break;
D 16

E 16
    case SPEED_CMD:
D 17
	s = decode_long(b);
	set_baudrate(s);
E 17
I 17
	s = (int) decode_long(b);
	(void) set_baudrate(s);
E 17
	break;
    }
I 16

E 16
D 17
    free(p);
E 17
I 17
    free((char *) p);
E 17
    return 1;
}

rcv_open(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 11
    char buffer[5];
E 11
I 11
D 17
    char buffer[6];
E 11
    register char *b = buffer;
E 17
I 17
    u_char buffer[6];
    register u_char *b = buffer;
E 17
    int	flags;
    int	mode;
    int fd;

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("open\n");
E 3
I 3
    printf("open(%s)\n",chan[c]->buf);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("open(%s)\n",chan[c]->buf);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "open(%s)\n",chan[c]->buf);
E 17
I 17
	(void) fprintf(rs232_debugfile, "open(%s)\n",chan[c]->buf);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 17
    flags = decode_long(chan[c]->buf + chan[c]->len - 8);
    mode = decode_long(chan[c]->buf + chan[c]->len - 4);
E 17
I 17
    flags = (int) decode_long(chan[c]->buf + chan[c]->len - 8);
    mode = (int) decode_long(chan[c]->buf + chan[c]->len - 4);
E 17

D 17
    if ((fd = open(chan[c]->buf, flags, mode)) < 0) {
E 17
I 17
    if ((fd = open((char *) chan[c]->buf, flags, mode)) < 0) {
E 17
I 11
err_ret:
E 11
D 17
	send(c, 0, 0);
	free(chan[c]->buf);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
	free((char *) chan[c]->buf);
E 17
	return 0;
    }
D 11
    
E 11
I 11

E 11
    if (fcntl(fd, F_SETFD, 1) < 0) {
D 3
	perror("open_rcv");
E 3
D 11
	send(c, 0, 0);
	free(chan[c]->buf);
	return 0;
E 11
I 11
	(void) close(fd);
	goto err_ret;
E 11
    }
D 11
    *b++ = fd;
E 11
I 11

E 11
    if ((flags & O_WRONLY) == 0) {
I 11
	*b++ = fd;
E 11
	if (fcntl(fd, F_SETFL, FNDELAY) < 0) {
D 3
	    perror("open_rcv");
E 3
D 11
	    send(c, 0, 0);
	    free(chan[c]->buf);
	    return 0;
E 11
I 11
	    (void) close(fd);
	    goto err_ret;
E 11
	}
D 3

E 3
	*b = new_channel();
	rd_chan[fd] = *b;
D 17
	alloc_channel(*b++, READ_CHN, fd); 
E 17
I 17
	alloc_channel(*b++, READ_CHN, (u_char) fd); 
E 17
	*b++ = READ_CHN;
	if (fd >= maximum_fd)
	    maximum_fd = fd + 1;
	FD_SET(fd, &read_fds); 
I 14
#ifdef	DEBUG
E 14
I 11
D 18
	if (rs232_debug) {
E 18
I 18
	if (rs232_debug)
E 18
D 14
	    (void) fprintf(stderr, "open(%s),fd=%d,chan=%d\n",
E 14
I 14
	    (void) fprintf(rs232_debugfile, "open(%s),fd=%d,chan=%d\n",
E 14
						chan[c]->buf, fd, rd_chan[fd]);
D 14
	    fflush(stderr);
E 14
D 18
	}
E 18
I 14
#endif	DEBUG
E 14
E 11
    }
I 11

E 11
    if ((flags & O_WRONLY) || (flags & O_RDWR)) {
I 11
	*b++ = fd;
E 11
	*b = new_channel();
	wr_chan[fd] = *b;
D 17
	alloc_channel(*b++, WRITE_CHN, fd); 
E 17
I 17
	alloc_channel(*b++, WRITE_CHN, (u_char) fd); 
E 17
	*b++ = WRITE_CHN;
I 14
#ifdef	DEBUG
E 14
I 11
D 18
	if (rs232_debug) {
E 18
I 18
	if (rs232_debug)
E 18
D 14
	    (void) fprintf(stderr, "open(%s),fd=%d,chan=%d\n",
E 14
I 14
	    (void) fprintf(rs232_debugfile, "open(%s),fd=%d,chan=%d\n",
E 14
						chan[c]->buf, fd, wr_chan[fd]);
D 14
	    fflush(stderr);
E 14
D 18
	}
E 18
I 14
#endif	DEBUG
E 14
E 11
    }
I 11

E 11
D 17
    send(c, buffer, b - buffer);
    free(chan[c]->buf);
E 17
I 17
    enqueue(c, buffer, b - buffer);
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_close(c)
D 16
    u_char	c;
E 16
I 16
    u_char c;
E 16
{
D 16
    int fd = *chan[c]->buf;
E 16
I 16
    register int fd = *chan[c]->buf;
E 16

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("close\n");
E 3
I 3
    printf("close(%d)\n",fd);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("close(%d)\n",fd);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "close(%d)\n",fd);
E 17
I 17
	(void) fprintf(rs232_debugfile, "close(%d)\n",fd);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
    if (close(fd) < 0)
D 17
	send(c, &c, 1); /* probably should be errno */
E 17
I 17
	enqueue(c, &c, 1); /* probably should be errno */
E 17
    else {
	FD_CLR(fd, &read_fds); 
I 4
	FD_CLR(fd, &stopped_fds); 
I 12
	FD_CLR(fd, &lseek_fds); 
E 12
E 4
	if (rd_chan[fd]) {
	    free_channel(rd_chan[fd]);
	    rd_chan[fd] = 0;
	}
	if (wr_chan[fd]) {
	    free_channel(wr_chan[fd]);
	    wr_chan[fd] = 0;
	}
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
    }
I 16

E 16
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_lseek(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 17
    char buffer[4];
    char *b = buffer;
    long pos;
E 17
I 17
    u_char buffer[4];
    register u_char *b = buffer;
    off_t pos;
    extern off_t lseek();
E 17

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
    printf("lseek\n");
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("lseek\n");
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "lseek\n");
E 17
I 17
	(void) fprintf(rs232_debugfile, "lseek\n");
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 11
    if ((pos = lseek(chan[c]->buf[0], decode_long(chan[c]->buf + 2),chan[c]->buf[1])) < 0)
E 11
I 11
D 17
    if ((pos = lseek(chan[c]->buf[0], decode_long(chan[c]->buf + 2),
						    chan[c]->buf[1])) < 0)
E 11
	send(c, 0, 0);
E 17
I 17
    if ((pos = lseek((int) chan[c]->buf[0],
	    (off_t) decode_long(chan[c]->buf + 2), (int) chan[c]->buf[1])) < 0)
	enqueue(c, (u_char *) 0, 0);
E 17
    else {
D 17
	b = encode_long(b, pos);
	send(c, buffer, b - buffer);
E 17
I 17
	b = encode_long(b, (long) pos);
	enqueue(c, buffer, b - buffer);
E 17
    }
I 16

E 16
I 11
D 12

E 12
I 12
    FD_SET(chan[c]->buf[0], &lseek_fds);
E 12
E 11
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_filesize(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 3
    int	 fd;
E 3
I 3
D 7
    int	 fd = *chan[c]->buf;
E 3
    long pos;
    long offset;
E 7
I 7
    int fd = *chan[c]->buf;
    struct stat statbuf;
E 7
D 17
    char buffer[4];
    char *b = buffer;
E 17
I 17
    u_char buffer[4];
    register u_char *b = buffer;
E 17

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("filesize\n");
E 3
I 3
    printf("filesize(%d)\n",fd);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("filesize(%d)\n",fd);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "filesize(%d)\n",fd);
E 17
I 17
	(void) fprintf(rs232_debugfile, "filesize(%d)\n",fd);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 3
    offset = lseek(chan[c]->buf[0], 0L, 1);
    pos = lseek(chan[c]->buf[0], 0L, 2);
    if (lseek(chan[c]->buf[0], offset, 0) < 0)
E 3
I 3
D 7
    offset = lseek(fd, 0L, 1);
    pos = lseek(fd, 0L, 2);
    if (lseek(fd, offset, 0) < 0)
E 7
I 7
    if (fstat(fd, &statbuf) < 0)
E 7
E 3
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
    else {
D 7
	b = encode_long(b, pos);
E 7
I 7
	b = encode_long(b, (long) statbuf.st_size);
E 7
D 17
	send(c, buffer, b - buffer);
E 17
I 17
	enqueue(c, buffer, b - buffer);
E 17
    }
I 7

E 7
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

D 13
rcv_gdtsize(c)
    u_char	c;
{
    char buffer[4];
    char *b = buffer;

    b = encode_long(b, getdtablesize());
    send(c, buffer, b - buffer);
    free(chan[c]->buf);
    return 0;
}

E 13
rcv_opencon(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 17
    char buffer[6];
    char *b = buffer;
E 17
I 17
    u_char buffer[6];
    register u_char *b = buffer;
E 17
    register u_char *p = chan[c]->buf;
    int         con = 0;
    int         lis = 0;
    register	fd = -1;

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("opencon\n");
E 3
I 3
    printf("opencon(%s)\n", p);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("opencon(%s)\n", p);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "opencon(%s)\n", p);
E 17
I 17
	(void) fprintf(rs232_debugfile, "opencon(%s)\n", p);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
    if (*p == 'l')
        lis++, p++;
    else if (*p == 'c')
        con++, p++;
D 8
    if (*p == '\0')
	goto bad_socket;
    else if (*p == '/') {
E 8
I 8
#ifndef NOUNIXSOCKETS
    if (*p == '/') {
E 8
        /* This is a Unix domain socket */
        struct sockaddr_un unsock;
        int         oldUmask;
D 17
        int         namelen = strlen(p);
E 17
I 17
        int         namelen = strlen((char *) p);
E 17
 
        unsock.sun_family = AF_UNIX;
        /*
         * Alas,  the length of the pathname for a Unix domain socket is
         * limited by the fact that it must fit into the generic struct
         * sockaddr........
         */
        if (namelen >= sizeof(unsock.sun_path))
            goto bad_socket;
D 17
        (void) strcpy(unsock.sun_path, p);
E 17
I 17
        (void) strcpy(unsock.sun_path, (char *) p);
E 17
        if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
            goto bad_socket;
        }
        if (con) {
            if (connect(fd, (struct sockaddr *) & unsock, namelen + 2))
                goto bad_socket;
            if (fcntl(fd, F_SETFL, FNDELAY) == -1)
                perror("socket fcntl"); /* XXX - this is a BUG! */

	    *b++ = fd;
	    *b = new_channel();
	    rd_chan[fd] = *b;
D 17
	    alloc_channel(*b++, READ_CHN, fd); 
E 17
I 17
	    alloc_channel(*b++, READ_CHN, (u_char) fd); 
E 17
	    if (fd >= maximum_fd)
		maximum_fd = fd + 1;
	    FD_SET(fd, &read_fds); 
	    *b = new_channel();
	    wr_chan[fd] = *b;
D 17
	    alloc_channel(*b++, WRITE_CHN, fd); 
	    send(c, buffer, b - buffer);
E 17
I 17
	    alloc_channel(*b++, WRITE_CHN, (u_char) fd); 
	    enqueue(c, buffer, b - buffer);
E 17
I 14
#ifdef	DEBUG
E 14
I 11
D 18
	    if (rs232_debug) {
D 14
		(void) fprintf(stderr, "opencon(%s),fd=%d,r/wchan=%d/%d\n",
E 14
I 14
		(void) fprintf(rs232_debugfile, "opencon(%s),fd=%d,r/wchan=%d/%d\n",
E 18
I 18
	    if (rs232_debug)
		(void) fprintf(rs232_debugfile,
				"opencon(%s), fd=%d, r/wchan=%d/%d\n",
E 18
E 14
				chan[c]->buf, fd, rd_chan[fd], wr_chan[fd]);
D 14
		fflush(stderr);
E 14
D 18
	    }
E 18
I 14
#endif	DEBUG
E 14
E 11
        }
        else {
            /* Create a Unix domain listener */
D 8
	    extern char *rindex();
E 8
D 17
            register char *q = rindex(p, '/');
E 17
I 17
            register char *q = rindex((char *) p, '/');
E 17
                      
D 8
            /* Unlink any old left-over socket */
            (void) unlink(unsock.sun_path);
E 8
I 8
            /* HACK ALERT */
            /*
             * the following is a hack to get around a bug in bind(2)
             * for AF_UNIX sockets.  since bind(2) returns EADDRINUSE
             * if the rendevous file exists, *not* if its actually
             * in use, we try to find out here whether its really
             * in use or not
             */
D 17
            if (access(p, F_OK) == 0) {
E 17
I 17
            if (access((char *) p, F_OK) == 0) {
E 17
                int     err, sock;
                char    foo[1];
             
                sock = socket(AF_UNIX, SOCK_DGRAM, 0);
D 17
                err = sendto(sock, foo, 1, 0, &unsock,
E 17
I 17
                err = sendto(sock, foo, 1, 0, (struct sockaddr *) &unsock,
E 17
                        sizeof(struct sockaddr_un));
                if (err)        {
                    switch(errno)       {
                    case        ECONNREFUSED:
                        /* Unlink any old left-over socket */
                        (void) unlink(unsock.sun_path);
                        (void) close(sock);
                        break;
                    case        EPROTOTYPE:
                    default:
                        (void) close(sock);
                        /* fake error to look like what we want */
                        errno = EADDRINUSE;
                        goto bad_socket;
                    }
                }
            }

E 8
            if (q) {  
                /* Try to make each directory along the path */
D 8
		extern char *index();
E 8
D 17
                register char *r = index(p + 1, '/');
E 17
I 17
                register char *r = index((char *) p + 1, '/');
E 17
                      
                oldUmask = umask(0);
                while (r && r <= q) {
                    *q = '\0';
                    *r = '\0';
D 17
                    (void) mkdir(p, 0777);
E 17
I 17
                    (void) mkdir((char *) p, 0777);
E 17
                    *r = '/';
                    *q = '/';
                    r = index(r + 1, '/');
                }
                (void) umask(oldUmask);
            }    
            /* Bind the socket into the file system */
            if (bind(fd, (struct sockaddr *) & unsock, namelen + 2))
                goto bad_socket;
D 8
            if (listen(fd, 3))
E 8
I 8
            if (listen(fd, 100))
E 8
                goto bad_socket;
            if (fcntl(fd, F_SETOWN, news_pid) < 0)
                perror("fcntl: open_socket setown");

	    *b++ = fd;
	    *b = new_channel();
	    rd_chan[fd] = *b;
D 17
	    alloc_channel(*b++, READ_CHN, fd); 
E 17
I 17
	    alloc_channel(*b++, READ_CHN, (u_char) fd); 
E 17
	    if (fd >= maximum_fd)
		maximum_fd = fd + 1;
	    FD_SET(fd, &read_fds); 
D 17
	    send(c, buffer, b - buffer);
E 17
I 17
	    enqueue(c, buffer, b - buffer);
E 17
        }
    }
D 8
    else if (*p && (fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0) {
E 8
I 8
    else
#endif
    if (*p && (fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0) {
E 8
	struct sockaddr_in addr;
	char        *hostname;
	long        strtol();

	/* Must be a TCP port */
	bzero((char *)&addr, sizeof(addr));
	addr.sin_family = AF_INET;
D 8
        if ((addr.sin_port = htons((u_short)strtol(p, &hostname, 10))) != 0) {
E 8
I 8
D 17
        if ((addr.sin_port = htons((unsigned short) strtol(p, &hostname, 10))) != 0) {
E 17
I 17
        if ((addr.sin_port = htons((unsigned short) strtol((char *) p,
						    &hostname, 10))) != 0) {
E 17
E 8
            if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)0, 0) < 0)
                perror("setsockopt");
I 8

#ifdef TCPNODELAY             
              if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof(int)))

                perror("setsockopt: NO-DELAY");
#endif
E 8
            if (con) {
                struct  hostent *hp;

                if (*hostname == '\0')
                    hostname = "localhost";
D 8
                if (!isalpha(*hostname))    /* skip separator character */
E 8
I 8
                if (!isalpha(*hostname))    /* skip separator
					     * character */
E 8
                    hostname++;
                hp = gethostbyname(hostname);
                if (hp == NULL)
                    goto bad_socket;
D 8
                bcopy(hp->h_addr, (char *)&addr.sin_addr, hp->h_length);
E 8
I 8
                bcopy((char *) hp->h_addr, (char *) &addr.sin_addr, (int) hp->h_length);
E 8
                if (addr.sin_port == 0 || connect(fd, (struct sockaddr *) &addr, sizeof addr))
                    goto bad_socket;
                if (fcntl(fd, F_SETFL, FNDELAY) == -1)
                    perror("socket fcntl");	/* XXX - this is a BUG! */

		*b++ = fd;
		*b = new_channel();
		rd_chan[fd] = *b;
D 17
		alloc_channel(*b++, READ_CHN, fd); 
E 17
I 17
		alloc_channel(*b++, READ_CHN, (u_char) fd); 
E 17
		if (fd >= maximum_fd)
		    maximum_fd = fd + 1;
		FD_SET(fd, &read_fds); 
		*b = new_channel();
		wr_chan[fd] = *b;
D 17
		alloc_channel(*b++, WRITE_CHN, fd); 
		send(c, buffer, b - buffer);
E 17
I 17
		alloc_channel(*b++, WRITE_CHN, (u_char) fd);
		enqueue(c, buffer, b - buffer);
E 17
I 14
#ifdef	DEBUG
E 14
I 11
D 18
		if (rs232_debug) {
D 14
		    (void) fprintf(stderr, "opencon(%s),fd=%d,r/wchan=%d/%d\n",
E 14
I 14
		    (void) fprintf(rs232_debugfile, "opencon(%s),fd=%d,r/wchan=%d/%d\n",
E 18
I 18
		if (rs232_debug)
		    (void) fprintf(rs232_debugfile,
				    "opencon(%s), fd=%d, r/wchan=%d/%d\n",
E 18
E 14
				    chan[c]->buf, fd, rd_chan[fd], wr_chan[fd]);
D 14
		    fflush(stderr);
E 14
D 18
		}
E 18
I 14
#endif	DEBUG
E 14
E 11
            }
            else {
                addr.sin_addr.s_addr = INADDR_ANY;
                if (bind(fd, (struct sockaddr *) &addr, sizeof addr) < 0
D 8
                            || lis && listen(fd, 3) < 0)
E 8
I 8
                            || lis && listen(fd, 100) < 0)
E 8
                    goto bad_socket;
		if (fcntl(fd, F_SETOWN, news_pid) < 0)
                    perror("fcntl: open_socket setown");

		*b++ = fd;
		*b = new_channel();
		rd_chan[fd] = *b;
D 17
		alloc_channel(*b++, READ_CHN, fd); 
E 17
I 17
		alloc_channel(*b++, READ_CHN, (u_char) fd); 
E 17
		if (fd >= maximum_fd)
		    maximum_fd = fd + 1;
		FD_SET(fd, &read_fds); 
D 17
		send(c, buffer, b - buffer);
E 17
I 17
		enqueue(c, buffer, b - buffer);
E 17
I 14
#ifdef	DEBUG
E 14
I 11
D 18
		if (rs232_debug) {
D 14
		    (void) fprintf(stderr, "opencon(%s),fd=%d,rchan=%d\n",
E 14
I 14
		    (void) fprintf(rs232_debugfile, "opencon(%s),fd=%d,rchan=%d\n",
E 14
						chan[c]->buf, fd, rd_chan[fd]);
D 14
		    fflush(stderr);
E 14
		}
E 18
I 18
		if (rs232_debug)
		    (void) fprintf(rs232_debugfile,
					    "opencon(%s), fd=%d, rchan=%d\n",
					    chan[c]->buf, fd, rd_chan[fd]);
E 18
I 14
#endif	DEBUG
E 14
E 11
            }
        }
	else {
	    goto bad_socket;
	}
    }
    else {
bad_socket:
	if (fd >= 0)
            (void) close(fd);
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
    }
I 11

E 11
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

union genericaddr {
    struct sockaddr     generic;
    struct sockaddr_in  internet;
    struct sockaddr_un  nuxi;
};

rcv_acceptcon(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
    union genericaddr addr;
    int namelen = sizeof(addr);
    int fd;
D 17
    char buffer[6];
    char *b = buffer;
E 17
I 17
    u_char buffer[6];
    register u_char *b = buffer;
E 17

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("acceptcon\n");
E 3
I 3
    printf("acceptcon(%d)\n", *chan[c]->buf);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("acceptcon(%d)\n", *chan[c]->buf);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "acceptcon(%d)\n", *chan[c]->buf);
E 17
I 17
	(void) fprintf(rs232_debugfile, "acceptcon(%d)\n", *chan[c]->buf);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
    bzero((char *) &addr, sizeof addr);
D 17
    if ((fd = accept(*chan[c]->buf, (struct sockaddr *)&addr, &namelen)) < 0) {
E 17
I 17
    if ((fd = accept((int) *chan[c]->buf, (struct sockaddr *)&addr,
							    &namelen)) < 0) {
E 17
D 9
	perror("accept");
E 9
I 9
	perror("X11/NeWS:");
E 9
D 17
	send(c, 0, 0);
	free(chan[c]->buf);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
	free((char *) chan[c]->buf);
E 17
	return 0;
    }
 
    switch (addr.generic.sa_family) {
I 8
#ifndef NOUNIXSOCKETS
E 8
    case AF_UNSPEC:
    case AF_UNIX:
        break;
D 8

E 8
I 8
#endif
E 8
    case AF_INET:
        break;

    default:
        (void) fprintf(stderr,
                "Bad address family %d\n", addr.generic.sa_family);
        break;
    }

    if (fcntl(fd, F_SETFD, 1) < 0 || fcntl(fd, F_SETFL, FNDELAY) < 0
	    || fcntl(fd, F_SETOWN, news_pid) < 0) {
	(void) close(fd);
D 17
	send(c, 0, 0);
	free(chan[c]->buf);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
	free((char *) chan[c]->buf);
E 17
	return 0;
    } 

    *b++ = fd;
    *b = new_channel();
    rd_chan[fd] = *b;
D 17
    alloc_channel(*b++, READ_CHN, fd); 
E 17
I 17
    alloc_channel(*b++, READ_CHN, (u_char) fd); 
E 17
    if (fd >= maximum_fd)
	maximum_fd = fd + 1;
    FD_SET(fd, &read_fds); 
    *b = new_channel();
    wr_chan[fd] = *b;
D 17
    alloc_channel(*b++, WRITE_CHN, fd); 
    send(c, buffer, b - buffer);
E 17
I 17
    alloc_channel(*b++, WRITE_CHN, (u_char) fd); 
    enqueue(c, buffer, b - buffer);
E 17
I 14
#ifdef	DEBUG
E 14
I 11
D 18
    if (rs232_debug) {
D 14
	(void) fprintf(stderr, "acceptcon(%d),fd=%d,r/wchan=%d\n",
E 14
I 14
	(void) fprintf(rs232_debugfile, "acceptcon(%d),fd=%d,r/wchan=%d\n",
E 18
I 18
    if (rs232_debug)
	(void) fprintf(rs232_debugfile, "acceptcon(%d), fd=%d, r/wchan=%d\n",
E 18
E 14
				*chan[c]->buf, fd, rd_chan[fd], wr_chan[fd]);
D 17
	fflush(stderr);
E 17
I 17
D 18
	(void) fflush(stderr);
E 17
    }
E 18
I 14
#endif	DEBUG
E 14

E 11
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

I 3
#define X_UNIX_PATH	"/tmp/.X11-unix/X"

E 3
rcv_serveraddr(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
    register struct hostent *h;
D 3
    struct sockaddr_in addr;
E 3
I 3
    union genericaddr addr;
E 3
    char hname[sizeof addr + 30];
    u_char *p = chan[c]->buf;
    int namelen;

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("serveraddr\n");
E 3
I 3
    printf("serveraddr(%d)\n", *p);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("serveraddr(%d)\n", *p);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "serveraddr(%d)\n", *p);
E 17
I 17
	(void) fprintf(rs232_debugfile, "serveraddr(%d)\n", *p);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
    namelen = sizeof addr;
D 17
    if (getsockname(*p++, (struct sockaddr *) &addr, &namelen) < 0) {
	send(c, 0, 0);
	free(chan[c]->buf);
E 17
I 17
    if (getsockname((int) *p++, (struct sockaddr *) &addr, &namelen) < 0) {
	enqueue(c, (u_char *) 0, 0);
	free((char *) chan[c]->buf);
E 17
	return 0;
    }
D 3
    h = gethostbyname(my_hostname);
    if (h)
        (void) sprintf(hname, "%u.%u;%s", 
		ntohl(*(u_long *) h->h_addr),
		ntohs(addr.sin_port), h->h_name);
    else
        (void) sprintf(hname, "%u.%u;localhost",
                ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port));
    
    send(c, hname, strlen(hname) + 1);
E 3
I 3
    if (addr.generic.sa_family == 0 || addr.generic.sa_family == AF_UNIX) {
D 8
	char bogus_name[128];
E 8
I 8
	char fname[128];
E 8

D 8
	(void)strcpy(bogus_name, X_UNIX_PATH);
	(void)strcat(bogus_name, "0");
	send(c, bogus_name, strlen(bogus_name) + 1);
E 8
I 8
	(void)strcpy(fname, X_UNIX_PATH);
	(void)strcat(fname, "0");
D 17
	send(c, fname, strlen(fname) + 1);
E 17
I 17
	enqueue(c, (u_char *) fname, strlen(fname) + 1);
E 17
E 8
    }
    else {
	h = gethostbyname(my_hostname);
	if (h)
	    (void) sprintf(hname, "%u.%u;%s", 
		    ntohl(*(u_long *) h->h_addr),
		    ntohs(addr.internet.sin_port), h->h_name);
	else
	    (void) sprintf(hname, "%u.%u;localhost",
		    ntohl(addr.internet.sin_addr.s_addr), ntohs(addr.internet.sin_port));
D 17
	send(c, hname, strlen(hname) + 1);
E 17
I 17
	enqueue(c, (u_char *) hname, strlen(hname) + 1);
E 17
    }
I 16

E 16
E 3
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_clientaddr(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
    register struct hostent *h;
D 3
    struct sockaddr_in addr;
E 3
I 3
    union genericaddr addr;
E 3
    u_char *p = chan[c]->buf;
    int         namelen;
I 9
    char  inetaddr[30];
E 9

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("clientaddr\n");
E 3
I 3
    printf("clientaddr(%d)\n", *p);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("clientaddr(%d)\n", *p);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "clientaddr(%d)\n", *p);
E 17
I 17
	(void) fprintf(rs232_debugfile, "clientaddr(%d)\n", *p);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
    namelen = sizeof addr;
D 3
    if (getpeername(*p, (struct sockaddr *) &addr, &namelen) < 0
            || (h = gethostbyaddr((char *) &addr.sin_addr, sizeof addr.sin_addr,
		    addr.sin_family)) == 0) {
E 3
I 3
D 17
    if (getpeername(*p, (struct sockaddr *) &addr, &namelen) < 0)
E 17
I 17
    if (getpeername((int) *p, (struct sockaddr *) &addr, &namelen) < 0)
E 17
	goto bad_access;
    if (addr.generic.sa_family == 0 || addr.generic.sa_family == AF_UNIX) {
D 17
	send(c, my_hostname, strlen(my_hostname) + 1);
E 17
I 17
	enqueue(c, (u_char *) my_hostname, strlen(my_hostname) + 1);
E 17
    }
    else {
D 9
	if ((h = gethostbyaddr((char *) &addr.internet.sin_addr, 
		sizeof addr.internet.sin_addr, addr.internet.sin_family)) == 0)
	    goto bad_access;
	send(c, h->h_name, strlen(h->h_name) + 1);
E 9
I 9
        int i;
        char *h_name = 0;
I 17
	char *inet_ntoa();
E 17

D 17
        strcpy(inetaddr, inet_ntoa(addr.internet.sin_addr));
E 17
I 17
        (void) strcpy(inetaddr, inet_ntoa(addr.internet.sin_addr));
E 17
        for(i=0;(i<next && i<10);i++)
            if (strcmp(hosts_cache[i].inet_num,inetaddr) == 0) {
                h_name = hosts_cache[i].name;
                break;
            }
        if (!h_name) {
            if ( (h = gethostbyaddr((char *) &addr.internet.sin_addr,
                                sizeof addr.internet.sin_addr,
                                addr.internet.sin_family)) == 0 )
                goto bad_access;
D 17
            strcpy(hosts_cache[next].inet_num, inetaddr);
            strcpy(hosts_cache[next++].name, h->h_name);
E 17
I 17
            (void) strcpy(hosts_cache[next].inet_num, inetaddr);
            (void) strcpy(hosts_cache[next++].name, h->h_name);
E 17
            h_name = h->h_name;
        }
D 17
	send(c, h_name, strlen(h_name) + 1);
E 17
I 17
	enqueue(c, (u_char *) h_name, strlen(h_name) + 1);
E 17
E 9
    }
I 16

E 16
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;

bad_access:
D 17
    send(c, 0, 0);
    free(chan[c]->buf);
E 17
I 17
    enqueue(c, (u_char *) 0, 0);
    free((char *) chan[c]->buf);
E 17
    return 0;

}

rcv_gethostname(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 16
    char buffer[100];
    char *p = buffer;
    char *q;
E 16
I 16
    register char *q;
I 17
    extern char *get_hostname();
E 17
E 16

I 18
#ifdef	DEBUG
    if (rs232_debug)
	(void) fprintf(rs232_debugfile, "gethostname(%d)\n",
						decode_long(chan[c]->buf));
#endif	DEBUG

E 18
D 16
    if (chan[c]->len > sizeof(long) 
	&& (q = (char *)get_hostname(decode_long(chan[c]->buf), chan[c]->len 
	    - sizeof(long), chan[c]->buf + sizeof(long))) != NULL)
    {
E 16
I 16
    if (chan[c]->len > sizeof(long) &&
D 17
	    (q = (char *)get_hostname(decode_long(chan[c]->buf), chan[c]->len -
		sizeof(long), chan[c]->buf + sizeof(long))) != NULL)
E 16
	send(c, q, strlen(q) + 1);
E 17
I 17
	    (q = get_hostname((int) decode_long(chan[c]->buf),
				(int) chan[c]->len - sizeof(long),
				chan[c]->buf + sizeof(long))) != NULL)
	enqueue(c, (u_char *) q, strlen(q) + 1);
E 17
D 16
    }
E 16
    else
E 3
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
I 16

E 16
D 3
	free(chan[c]->buf);
	return 0;
E 3
I 3
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_gethostaddr(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
    int family;
    int length;
    u_char *pAddr;
D 17
    char buffer[100];
    char *p = buffer;
E 17
I 17
    u_char buffer[100];
    register u_char *b = buffer;
E 17

I 18
#ifdef	DEBUG
    if (rs232_debug)
	(void) fprintf(rs232_debugfile, "gethostaddr(%s)\n",
						(char *)chan[c]->buf);
#endif	DEBUG

E 18
D 17
    if (get_hostaddress(chan[c]->buf, &family, &length, &pAddr)) {
	p = encode_long(p, family);
	bcopy(pAddr, p, length);
	p += length;
	send(c, buffer, p - buffer);
E 17
I 17
    if (get_hostaddress((char *) chan[c]->buf, &family, &length, &pAddr)) {
	b = encode_long(b, (long) family);
	bcopy((char *) pAddr, (char *) b, length);
	b += length;
	enqueue(c, buffer, b - buffer);
E 17
E 3
    }
D 3
    send(c, h->h_name, strlen(h->h_name) + 1);
E 3
I 3
    else
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
I 16

E 16
E 3
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_servername(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
    printf("servername\n");
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("servername\n");
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "servername\n");
E 17
I 17
	(void) fprintf(rs232_debugfile, "servername\n");
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 17
    gethostname(my_hostname, 40);
E 17
I 17
    (void) gethostname(my_hostname, 40);
E 17
    my_hostname[39] = 0;

D 17
    send(c, my_hostname, strlen(my_hostname) + 1);
    free(chan[c]->buf);
E 17
I 17
    enqueue(c, (u_char *) my_hostname, strlen(my_hostname) + 1);
    free((char *) chan[c]->buf);
E 17
    return 0;
}

D 15
extern char **environ;

E 15
rcv_spawn(c)
D 15
u_char	c;
E 15
I 15
    u_char c;
E 15
{
I 15
    char            combuf[400];
E 15
    char           *args[100];
D 15
    register char  *p = (char *)chan[c]->buf;
E 15
I 15
    register char  *sp = (char *)chan[c]->buf;
    register char  *dp;
    register char **ap;
    register        cnt;
    int             err = 0;
E 15
    register int   len = chan[c]->len;
D 15
    register char **ap = args;
E 15

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("spawn\n");
E 3
I 3
    printf("spawn(%s)\n", p);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("spawn(%s)\n", p);
	fflush(stdout);
E 14
I 14
D 15
	fprintf(rs232_debugfile, "spawn(%s)\n", p);
E 15
I 15
D 17
	fprintf(rs232_debugfile, "spawn(%s)\n", sp);
E 17
I 17
	(void) fprintf(rs232_debugfile, "spawn(%s)\n", sp);
E 17
E 15
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

I 15
    if (len <= 0)    /* Don't fork null process */
      return 1;

    for (dp = sp, cnt = len; --cnt >= 0; dp++)
	switch (*dp) {
	  case '!':
	  case '"':
	  case '$':
	  case '&':
	  case '(':
	  case ')':
	  case '*':
	  case ';':
	  case '<':
	  case '>':
	  case '?':
	  case '[':
	  case '\'':
	  case '\\':
	  case ']':
	  case '`':
	  case '{':
	  case '|':
	  case '}':
	  case '~':
	  cnt = -1;
	}

E 15
E 6
    ap = args;
D 15
    if (strpbrk(p, "!\"$&()*;<>?[\'\\]`{|}~") == NULL) {
        while (len > 0 && ap < &args[sizeof args / sizeof args[0] - 1]) {
            *ap++ = p;
	    while (*p > ' ' && len-- > 0)
		p++;
            *p = 0;
            while (*p <= ' ' && len-- > 0)
                p++;
        }  
E 15
I 15
    if (cnt == -1) {		/* no special characters, don't invoke the
				 * shell */
	dp = combuf;
	while (len > 0 && ap < &args[sizeof args / sizeof args[0] - 1]) {
	    *ap++ = dp;
	    while (dp < combuf + sizeof combuf - 1 && *sp > ' ' && --len >= 0)
		*dp++ = *sp++;
	    *dp++ = 0;
	    while (*sp <= ' ' && --len >= 0)
		sp++;
	}
    } else {
	static char    *shell;

	(void) strncpy(combuf, sp, len);
	combuf[len] = 0;
	if (shell == 0 && (shell = (char *) getenv("SHELL")) == 0)
	    shell = "/bin/sh";
	*ap++ = shell;
	*ap++ = "-c";
	*ap++ = combuf;
E 15
    }
D 15
    else {
        static char    *shell;
	extern char    *getenv();
           
        if (shell == 0 && (shell = getenv("SHELL")) == 0)
            shell = "/bin/sh";
        *ap++ = shell;
        *ap++ = "-c";
        *ap++ = p;
    }      
           
E 15
I 15

E 15
    *ap++ = 0;
    if (vfork() == 0) {
D 15
        (void) setpgrp(0, getpid());
        (void) close(0);
        (void) open("/dev/null", 2);
        (void) dup2(0, 1);
        (void) dup2(0, 2);
        execvp(args[0], args);
        _exit(0252);
E 15
I 15
	if (setpgrp(0, getpid()) < 0)
	    perror("setpgrp"); 
	if (close(0) < 0)
	    perror("close");
	if (open("/dev/null", O_RDWR, 0) < 0)
	    perror("open");
	if (dup2(0, 1) < 0)
	    perror("dup2");
	if (dup2(0, 2) < 0)
	    perror("dup2");
	if ((int) signal(SIGPIPE, SIG_DFL) < 0)
            perror("signal: SIGPIPE");
        if ((int) signal(SIGFPE, SIG_DFL) < 0)
            perror("signal: SIGFPE");
	execvp(args[0], args); 
	/*
	 * Beware: I'm depending on vfork semantics to propagate the error
	 * code.
	 */
	err = 1;
	_exit(0252);
E 15
    }
I 15

E 15
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
D 15
    return 0;
E 15
I 15
    return err;
E 15
}

rcv_homedir(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
    register struct passwd *pw;

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("homedir\n");
E 3
I 3
    printf("homedir(%s)\n", chan[c]->buf);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("homedir(%s)\n", chan[c]->buf);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "homedir(%s)\n", chan[c]->buf);
E 17
I 17
	(void) fprintf(rs232_debugfile, "homedir(%s)\n", chan[c]->buf);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 16
    if ((pw = (struct passwd *)getpwnam(chan[c]->buf)) == NULL) {
E 16
I 16
D 17
    if ((pw = (struct passwd *)getpwnam(chan[c]->buf)) == NULL)
E 16
	send(c, 0, 0);
E 17
I 17
    if ((pw = (struct passwd *) getpwnam((char *) chan[c]->buf)) == NULL)
	enqueue(c, (u_char *) 0, 0);
E 17
D 16
	free(chan[c]->buf);
	return 0;
    }
    send(c, pw->pw_dir, strlen(pw->pw_dir) + 1);
E 16
I 16
    else
D 17
	send(c, pw->pw_dir, strlen(pw->pw_dir) + 1);
E 17
I 17
	enqueue(c, (u_char *) pw->pw_dir, strlen(pw->pw_dir) + 1);
E 17

E 16
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_cwd(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 3
    char cwd[512];
E 3
I 3
D 17
    static char cwd[512];
E 17
I 17
    static char cwd[MAXPATHLEN];
    extern char *getwd();
E 17
E 3

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
    printf("cwd\n");
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("cwd\n");
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "cwd\n");
E 17
I 17
	(void) fprintf(rs232_debugfile, "cwd\n");
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
    if (getwd(cwd) == NULL)
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
    else
D 17
	send(c, cwd, strlen(cwd) + 1);
E 17
I 17
	enqueue(c, (u_char *) cwd, strlen(cwd) + 1);
E 17
I 16

E 16
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_getenv(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 16
    char *buffer;
E 16
I 16
    register char *buffer;
E 16

I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("getenv\n");
E 3
I 3
    printf("getenv(%s)\n", chan[c]->buf);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("getenv(%s)\n", chan[c]->buf);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "getenv(%s)\n", chan[c]->buf);
E 17
I 17
	(void) fprintf(rs232_debugfile, "getenv(%s)\n", chan[c]->buf);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 16
    buffer = getenv(chan[c]->buf); /* error results in null string */

    if (buffer)
E 16
I 16
D 17
    if (buffer = getenv(chan[c]->buf))	/* error results in null string */
E 16
	send(c, buffer, strlen(buffer) + 1);
E 17
I 17
    if (buffer = getenv((char *) chan[c]->buf))	/* null string => error */
	enqueue(c, (u_char *) buffer, strlen(buffer) + 1);
E 17
    else
D 17
	send(c, 0, 0);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
E 17
I 16

E 16
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_putenv(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("putenv\n");
E 3
I 3
    printf("putenv(%s)\n", chan[c]->buf);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("putenv(%s)\n", chan[c]->buf);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "putenv(%s)\n", chan[c]->buf);
E 17
I 17
	(void) fprintf(rs232_debugfile, "putenv(%s)\n", chan[c]->buf);
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

E 6
D 17
    putenv(chan[c]->buf);
    return 0;
E 17
I 17
    return(putenv((char *) chan[c]->buf));
E 17
}

rcv_read(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 4
    int i;
    u_char *buffer;

if (rs232_debug)
{
    printf("read\n");
    fflush(stdout);
}
    i = decode_long(chan[c]->buf);
    buffer = (u_char *)malloc(i);
    if ((i = read(chan[c]->arg, buffer, i)) <= 0)
	send(c, 0, 0);
E 4
I 4
D 12
    if (chan[c]->len > 0)
	FD_SET(chan[c]->arg, &stopped_fds);
E 12
I 12
    if (chan[c]->len > 0) {
	if (FD_ISSET(chan[c]->arg, &lseek_fds)) {
D 16
	    int i = decode_long(chan[c]->buf);
	    char *p;
E 16
I 16
D 17
	    register int i = decode_long(chan[c]->buf);
E 17
I 17
	    register int i = (int) decode_long(chan[c]->buf);
E 17
	    register char *p;
E 16

	    if (i >= 0) {
D 17
		p = malloc(i);
		if ((i = read(chan[c]->arg, p, i)) >= 0)
		    send(c, p, i);
E 17
I 17
		p = malloc((unsigned) i);
		if ((i = read((int) chan[c]->arg, p, i)) >= 0)
		    enqueue(c, (u_char *) p, i);
E 17
		else
D 17
		    send(c, 0, 0);;
E 17
I 17
		    enqueue(c, (u_char *) 0, 0);;
E 17
		free(p);
	    }
	} else
	    FD_SET(chan[c]->arg, &stopped_fds);
    }
E 12
E 4
    else
D 4
	send(c, buffer, i);
    free(buffer);
E 4
I 4
	FD_CLR(chan[c]->arg, &stopped_fds);
I 16

E 16
E 4
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_write(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 16
    u_char buffer[4];
    u_char *b = buffer;
    int i;

E 16
I 14
#ifdef	DEBUG
E 14
D 6
if (rs232_debug)
{
D 3
    printf("write\n");
E 3
I 3
    printf("write(%d)\n", chan[c]->arg);
E 3
    fflush(stdout);
}
E 6
I 6
D 18
    if (rs232_debug) {
D 14
	printf("write(%d)\n", chan[c]->arg);
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "write(%d,%d)\n", chan[c]->arg, chan[c]->len);
E 17
I 17
	(void) fprintf(rs232_debugfile, "write(%d,%d)\n", chan[c]->arg, chan[c]->len);
E 17
E 14
    }
E 18
I 18
    if (rs232_debug)
	(void) fprintf(rs232_debugfile, "write(%d,%d)\n",
					    chan[c]->arg, chan[c]->len);
E 18
I 14
#endif	DEBUG
E 14

E 6
D 16
    if ((i = write(chan[c]->arg, chan[c]->buf, chan[c]->len)) < 0)
E 16
I 16
D 17
    if (write(chan[c]->arg, chan[c]->buf, chan[c]->len) < 0)
E 16
	send(c ,0, 0);
E 17
I 17
D 18
    if (write((int) chan[c]->arg, (char *) chan[c]->buf, (int) chan[c]->len) < 0)
E 18
I 18
    if (write((int)chan[c]->arg, (char *)chan[c]->buf, (int)chan[c]->len) < 0)
E 18
	enqueue(c, (u_char *) 0, 0);
E 17
I 16

E 16
D 17
    free(chan[c]->buf);
E 17
I 17
    free((char *) chan[c]->buf);
E 17
    return 0;
D 13
}

/*
 * The nf_* variables are required to keep the state of the
 * font file search between initfont() and all subsequent
 * nextfont() calls.
 */

static char nf_dirname[128];		/* current search directory name */
static int nf_dirnamelen;		/* strlen(nf_dirname) */
static DIR *nf_dir;			/* current search directory */
static char *nf_p;			/* pointer into fontpath list */
static char nf_pattern[64];		/* filename pattern to match */

rcv_initfont(c)
    u_char	c;
{
    static char nf_fontpath[300];
    register char *sp, *dp;
    register int  fl;

D 6
if (rs232_debug)
{
    printf("initfont\n");
    fflush(stdout);
}
E 6
I 6
    if (rs232_debug) {
	printf("initfont\n");
	fflush(stdout);
    }

E 6
    if (nf_dir) {
	(void) closedir(nf_dir);
	nf_dir = (DIR *) 0;
    }

    fl = strlen(chan[c]->buf);
    strcpy(nf_fontpath, chan[c]->buf);
    strcpy(nf_pattern, chan[c]->buf + fl + 1);
D 6
if (rs232_debug)
    printf("init_font(%s, %s)\n", nf_fontpath, nf_pattern);
E 6
I 6

    if (rs232_debug)
	printf("init_font(%s, %s)\n", nf_fontpath, nf_pattern);

E 6
    sp = nf_fontpath;
    dp = nf_dirname;
    nf_p = sp;
    while (*nf_p != ':' && *nf_p)
	*dp++ = *nf_p++;
    if (dp == nf_dirname)
	*dp++ = '.';
    *dp++ = '\0';
    nf_dir = opendir(nf_dirname);
    nf_dirnamelen = strlen(nf_dirname);

    send(c, 0, 0);
    free(chan[c]->buf);
    return 0;
}

rcv_nextfont(c)
    u_char	c;
{
    static char nextfontname[MAXNAMLEN+1];
    char fname[MAXNAMLEN+1];
    register struct direct *ent;
    register char *sp, *dp;
    register int len;

D 6
if (rs232_debug)
{
    printf("nextfont\n");
    fflush(stdout);
}
E 6
I 6
    if (rs232_debug) {
	printf("nextfont\n");
	fflush(stdout);
    }

E 6
    for (;;) {		/* loop on all colon-separated directories */
	if (nf_dir) {
	    for (;;) {	/* loop on all files in a directory */
		ent = readdir(nf_dir);
		if (ent == 0) {
		    (void) closedir(nf_dir);
		    nf_dir = (DIR *) 0;
		    break;
		}

		/* X/NeWS implementation */
		(void) strncpy(fname, ent->d_name, (int) ent->d_namlen);
		fname[ent->d_namlen] = '\0';
		if (!match(nf_pattern, fname))
		    continue;

		/* compiler bug ??? - this fails without the len = */
		if ((len = (sizeof(nextfontname) - nf_dirnamelen - ent->d_namlen)) <= 0)
		    ent->d_namlen = sizeof(nextfontname) - nf_dirnamelen - 1;
		(void) sprintf(nextfontname, "%s/%.*s",
					nf_dirname, ent->d_namlen, ent->d_name);
		send(c, nextfontname, strlen(nextfontname) + 1);
		free(chan[c]->buf);
		return 0;
	    }
	}

	if (*nf_p == '\0') {
	    if (nf_dir) {
		(void) closedir(nf_dir);
		nf_dir = (DIR *) 0;
	    }
	    send(c, 0, 0);
	    free(chan[c]->buf);
	    return 0;
	}

	sp = nf_p + 1;
	dp = nf_dirname;
	nf_p = sp;
	while (*nf_p != ':' && *nf_p)
	    *dp++ = *nf_p++;
	if (dp == nf_dirname)
	    *dp++ = '.';
	*dp++ = '\0';
	nf_dir = opendir(nf_dirname);
	nf_dirnamelen = strlen(nf_dirname);
    }
}

static
match(pat, string)
    register char *pat;
    register char *string;
{
    register int ip;
    register int matched;

    for (ip=0; pat[ip]!='\0'; ip++) {
        if (pat[ip] == '*') {
            matched = 0;
            while (!matched) {	/* find where pat & string start to match */
                if (string[ip] == '\0') {
                    if (pat[ip+1] == '\0')
                        return(1);
                    break;
                }
                while (!(matched = match( &pat[ip+1], &string[ip]))) {
                    string++;
                    if (string[0] == '\0')
                        return(0);
                }
            }
            if (matched)
                return(1);
        }
        else if (string[ip] == '\0')
            return(0);
        else if (( pat[ip] != '?') && (pat[ip] != string[ip]))
             return(0);
    }
    return(1);
E 13
I 10
}

rcv_version(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 16
    int fd;
E 16
I 16
    register int fd;
E 16
I 14
D 17
    char buffer[sizeof(VERSION)];
D 16
    char *p = buffer;
E 16
I 16
    register char *p = buffer;
E 16
E 14
    extern int server_version;
E 17
I 17
    u_char buffer[sizeof(VERSION)];
    register u_char *b = buffer;
    extern short server_version;
E 17

I 14
#ifdef	DEBUG
E 14
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("version\n");
	fflush(stdout);
E 14
I 14
D 17
	fprintf(rs232_debugfile, "version\n");
E 17
I 17
	(void) fprintf(rs232_debugfile, "version\n");
E 17
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

    if (firstfd == 0) {		/* first time through */
D 14
	server_version = decode_long(chan[c]->buf);
E 14
I 14
	server_version = decode_short(chan[c]->buf);
E 14
	if ((fd = open("/dev/null", 0)) < 0) {
	    (void) fprintf(stderr, "rcv_version: open failed\n");
	    exit(1);
	}
	/* version.version set in main() */
	firstfd = version.firstfd = fd;
	(void) close(fd);
    }
I 16

E 16
D 14

    send(c, (char *)&version, sizeof(VERSION));
E 14
I 14
D 17
    p = encode_short(p, version.version);
    p = encode_short(p, version.firstfd);
    p = encode_long(p, version.res1);
    p = encode_long(p, version.res2);
    p = encode_long(p, version.res3);
E 17
I 17
    b = encode_short(b, version.version);
    b = encode_short(b, version.firstfd);
    b = encode_long(b, (long) version.res1);
    b = encode_long(b, (long) version.res2);
    b = encode_long(b, (long) version.res3);
E 17
I 16

E 16
D 17
    send(c, buffer, p - buffer);
E 14
I 11
    free(chan[c]->buf);
E 17
I 17
    enqueue(c, buffer, b - buffer);
    free((char *) chan[c]->buf);
E 17
    return 0;
}

rcv_pipe(c)
D 16
    u_char	c;
E 16
I 16
    register u_char c;
E 16
{
D 17
    char buffer[512];
    register char *b = buffer;
E 17
I 17
    u_char buffer[512];
    register u_char *b = buffer;
E 17
D 16
    int input, output;
    int pid;
E 16
I 16
    register int input, output;
E 16
    int ipipefd[2], opipefd[2];
I 16
    int pid;
E 16

I 14
#ifdef	DEBUG
E 14
D 18
    if (rs232_debug) {
E 18
I 18
    if (rs232_debug)
E 18
D 14
	printf("pipe(%d,%s)\n", *chan[c]->buf, chan[c]->buf+1);
	fflush(stdout);
E 14
I 14
D 16
	fprintf(rs232_debugfile, "pipe(%d,%s)\n", *chan[c]->buf, chan[c]->buf+1);
E 16
I 16
D 17
	fprintf(rs232_debugfile, "pipe(%d,%s)\n", *chan[c]->buf,
E 17
I 17
	(void) fprintf(rs232_debugfile, "pipe(%d,%s)\n", *chan[c]->buf,
E 17
							    chan[c]->buf+1);
E 16
E 14
D 18
    }
E 18
I 14
#endif	DEBUG
E 14

    input = output = 0;
    switch (*chan[c]->buf) {
    case O_RDONLY:
	input = 1;
	break;
    case O_RDWR:
	input = 1;
	/* fall through */
    case O_WRONLY:
	output = 1;
	break;
    default:
	goto err_ret;
    }

    if (input && pipe(ipipefd) < 0) {
err_ret:
D 17
	send(c, 0, 0);
	free(chan[c]->buf);
E 17
I 17
	enqueue(c, (u_char *) 0, 0);
	free((char *) chan[c]->buf);
E 17
	return 0;
    }

    if (output && pipe(opipefd) < 0) {
icloseret:
D 17
	if (input) close(ipipefd[0]), close(ipipefd[1]);
E 17
I 17
	if (input) {
	    (void) close(ipipefd[0]);
	    (void) close(ipipefd[1]);
	}
E 17
	goto err_ret;
    }

    if ((pid = vfork()) < 0) {
D 17
	if (output) close(opipefd[0]), close(opipefd[1]);
E 17
I 17
	if (output) {
	    (void) close(opipefd[0]);
	    (void) close(opipefd[1]);
	}
E 17
	goto icloseret;
    }

    if (pid == 0) {		/* child */
	if (input) {
D 17
	    dup2(ipipefd[1], 1);
	    close(ipipefd[0]);
	    close(ipipefd[1]);
E 17
I 17
	    (void) dup2(ipipefd[1], 1);
	    (void) close(ipipefd[0]);
	    (void) close(ipipefd[1]);
E 17
	}
	else {
D 17
	    close(1);
	    open("/dev/null", 2);
E 17
I 17
	    (void) close(1);
	    (void) open("/dev/null", 2);
E 17
	}

	if (output) {
D 17
	    dup2(opipefd[0], 0);
	    close(opipefd[0]);
	    close(opipefd[1]);
E 17
I 17
	    (void) dup2(opipefd[0], 0);
	    (void) close(opipefd[0]);
	    (void) close(opipefd[1]);
E 17
	}
	else {
D 17
	    close(0);
	    open("/dev/null", 1);
E 17
I 17
	    (void) close(0);
	    (void) open("/dev/null", 1);
E 17
	}

	execl("/bin/sh", "sh", "-c", chan[c]->buf+1, 0);
D 17
	write(2, "shell missing\n", 14);
E 17
I 17
	(void) write(2, "shell missing\n", 14);
E 17
	exit(1);
    }

    if (input) {
D 17
	close(ipipefd[1]);
E 17
I 17
	(void) close(ipipefd[1]);
E 17
	if (fcntl(ipipefd[0], F_SETFD, 1) < 0 || 
		fcntl(ipipefd[0], F_SETFL, FNDELAY) < 0) {
	    (void) close(ipipefd[0]);
	    goto err_ret;
	}
	*b++ = ipipefd[0];
	*b = new_channel();
	rd_chan[ipipefd[0]] = *b;
D 17
	alloc_channel(*b++, READ_CHN, ipipefd[0]);
E 17
I 17
	alloc_channel(*b++, READ_CHN, (u_char) ipipefd[0]);
E 17
	*b++ = READ_CHN;
	if (ipipefd[0] >= maximum_fd)
	    maximum_fd = ipipefd[0] + 1;
	FD_SET(ipipefd[0], &read_fds);

I 14
#ifdef	DEBUG
E 14
D 18
	if (rs232_debug) {
E 18
I 18
	if (rs232_debug)
E 18
D 14
	    (void) fprintf(stderr, "input pipe(%s),fd=%d,chan=%d\n",
E 14
I 14
	    (void) fprintf(rs232_debugfile, "input pipe(%s),fd=%d,chan=%d\n",
E 14
			    chan[c]->buf+1, ipipefd[0], rd_chan[ipipefd[0]]);
D 14
	    fflush(stderr);
E 14
D 18
	}
E 18
I 14
#endif	DEBUG
E 14
    }

    if (output) {
D 17
	close(opipefd[0]);
E 17
I 17
	(void) close(opipefd[0]);
E 17
	if (fcntl(opipefd[1], F_SETFD, 1) < 0) {
	    (void) close(opipefd[1]);
	    goto err_ret;
	}
	*b++ = opipefd[1];
	*b = new_channel();
	wr_chan[opipefd[1]] = *b;
D 17
	alloc_channel(*b++, WRITE_CHN, opipefd[1]); 
E 17
I 17
	alloc_channel(*b++, WRITE_CHN, (u_char) opipefd[1]); 
E 17
	*b++ = WRITE_CHN;
I 14
#ifdef	DEBUG
E 14
D 18
	if (rs232_debug) {
E 18
I 18
	if (rs232_debug)
E 18
D 14
	    (void) fprintf(stderr, "input pipe(%s),fd=%d,chan=%d\n",
E 14
I 14
	    (void) fprintf(rs232_debugfile, "input pipe(%s),fd=%d,chan=%d\n",
E 14
			    chan[c]->buf+1, opipefd[1], wr_chan[opipefd[1]]);
D 14
	    fflush(stderr);
E 14
D 18
	}
E 18
I 14
#endif	DEBUG
E 14
    }

D 17
    send(c, buffer, b - buffer);
E 11
    free(chan[c]->buf);
E 17
I 17
    enqueue(c, buffer, b - buffer);
    free((char *) chan[c]->buf);
E 17
    return 0;
E 10
}
E 1
