home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
-
- #include "config.h"
- #include <sys/types.h>
- #include <sys/time.h>
- #ifndef NO_UNIXSOCKS
- #include <sys/socket.h>
- #include <sys/un.h>
- #ifndef NO_FDPASSING
- #include <sys/uio.h>
- #endif
- #include <stdio.h>
- #include <strings.h>
- #endif
- #include "sock.h"
- #include "tty.h"
- #include "err.h"
-
- static int bufwrite(fd,buf,num)
- int fd;
- char *buf;
- int num;
- {
- int r;
-
- do
- {
- r = write(fd,buf,num);
- if (r > 0)
- {
- buf += r;
- num -= r;
- }
- }
- while ((num > 0) && ((r != -1) || (errno == EINTR)));
- return (r >= 0) ? 0 : -1;
- }
-
- static int bufread(fd,buf,num)
- int fd;
- char *buf;
- int num;
- {
- int r;
-
- do
- {
- r = read(fd,buf,num);
- if (r > 0)
- {
- buf += r;
- num -= r;
- }
- }
- while ((num > 0) && ((r != -1) || (errno == EINTR)));
- /* Note that we ignore EOF. */
- return (r >= 0) ? 0 : -1;
- }
-
- int pty_readsock(line,path)
- char *line;
- char *path;
- {
- #ifdef NO_UNIXSOCKS
- return -1;
- #else
- int s;
- struct sockaddr_un sa;
-
- if ((s = socket(AF_UNIX,SOCK_STREAM,0)) == -1)
- return -1;
- sa.sun_family = AF_UNIX;
- (void) sprintf(sa.sun_path,"re.%s",line + sizeof(DEVSTY) - 3);
- (void) strcpy(path,sa.sun_path);
- (void) unlink(sa.sun_path);
- if (bind(s,(struct sockaddr *) &sa,strlen(sa.sun_path) + 2) == -1)
- return -1;
- if (listen(s,5) == -1)
- return -1;
- return s;
- #endif
- }
-
- int pty_writesock(line)
- char *line;
- {
- #ifdef NO_UNIXSOCKS
- return -1;
- #else
- int s;
- struct sockaddr_un sa;
-
- if ((s = socket(AF_UNIX,SOCK_STREAM,0)) == -1)
- return -1;
- sa.sun_family = AF_UNIX;
- (void) sprintf(sa.sun_path,"re.%s",line + sizeof(DEVSTY) - 3);
- if (connect(s,(struct sockaddr *) &sa,strlen(sa.sun_path) + 2) == -1)
- return -1;
- (void) unlink(sa.sun_path);
- return s;
- #endif
- }
-
- int pty_acceptsock(fd)
- int fd;
- {
- #ifdef NO_UNIXSOCKS
- return -1;
- #else
- struct sockaddr_un sa;
- int salen = sizeof(sa);
-
- return accept(fd,(struct sockaddr *) &sa,&salen);
- #endif
- }
-
- int pty_putgetonefd(fd,fp)
- int fd;
- int *fp;
- {
- #ifdef NO_FDPASSING
- return -1;
- #else
- struct msghdr msg[2];
- int acc[5];
- struct iovec i[2];
-
- msg[0].msg_name = 0;
- msg[0].msg_namelen = 0;
- msg[0].msg_iov = &i[0]; /* grrrr */
- msg[0].msg_iovlen = 0;
- msg[0].msg_accrights = (caddr_t) acc;
- msg[0].msg_accrightslen = 5 * sizeof(int);
- #ifdef USLEEP
- (void) usleep((unsigned) 100000);
- #else
- (void) sleep(1); /* XXX: work around fd passing bug */
- #endif
- if (recvmsg(fd,msg,0) == -1)
- return -1;
- if (msg[0].msg_accrightslen != sizeof(int))
- return -1;
- if (*fp != -1)
- (void) close(*fp);
- *fp = acc[0]; /* yay! we've passed a file descriptor! */
- return 0;
- #endif
- }
-
- int pty_putgetfd(fd,ch,fp)
- int fd;
- char ch;
- int *fp;
- {
- #ifdef NO_FDPASSING
- return -1;
- #else
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (pty_putgetonefd(fd,fp) < 0)
- return -1;
- if (bufwrite(fd,".",1) < 0)
- return -1;
- return 0;
- #endif
- }
-
- int pty_putgetint(fd,ch,ip)
- int fd;
- char ch;
- int *ip;
- {
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,(char *) ip,sizeof(int)) < 0)
- return -1;
- if (bufwrite(fd,".",1) < 0)
- return -1;
- return 0;
- }
-
- int pty_putgetstr(fd,ch,str)
- int fd;
- char ch;
- char str[TTYNAMELEN];
- {
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,str,TTYNAMELEN) < 0)
- return -1;
- if (bufwrite(fd,".",1) < 0)
- return -1;
- return 0;
- }
-
- int pty_putgettty(fd,ch,tmo)
- int fd;
- char ch;
- struct ttymodes *tmo;
- {
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,(char *) tmo,sizeof(struct ttymodes)) < 0)
- return -1;
- if (bufwrite(fd,".",1) < 0)
- return -1;
- return 0;
- }
-
- int pty_sendonefd(fd,fp)
- int fd;
- int *fp;
- {
- #ifdef NO_FDPASSING
- return -1;
- #else
- struct msghdr msg[2];
- int acc[5]; /* or just 5? or just 1? who cares */
- struct iovec i[2];
-
- msg[0].msg_name = 0;
- msg[0].msg_namelen = 0;
- msg[0].msg_iov = i; /* grrrr */
- msg[0].msg_iovlen = 0;
- msg[0].msg_accrights = (caddr_t) acc;
- msg[0].msg_accrightslen = sizeof(int);
- acc[0] = *fp;
- if (sendmsg(fd,&msg[0],0) == -1)
- return -1;
- /* yay! we've passed a file descriptor! */
- return 0;
- #endif
- }
-
- int pty_sendfd(fd,ch,fp)
- int fd;
- char ch;
- int *fp;
- {
- #ifdef NO_FDPASSING
- return -1;
- #else
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch == ' ')
- return 1;
- if (pty_sendonefd(fd,fp) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch != '.')
- return 1;
- return 0;
- #endif
- }
-
- int pty_sendint(fd,ch,ip)
- int fd;
- char ch;
- int *ip;
- {
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch == ' ')
- return 1;
- if (bufwrite(fd,(char *) ip,sizeof(int)) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch != '.')
- return 1;
- return 0;
- }
-
- int pty_sendstr(fd,ch,str)
- int fd;
- char ch;
- char str[TTYNAMELEN];
- {
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch == ' ')
- return 1;
- if (bufwrite(fd,str,TTYNAMELEN) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch != '.')
- return 1;
- return 0;
- }
-
- int pty_sendtty(fd,ch,tmo)
- int fd;
- char ch;
- struct ttymodes *tmo;
- {
- if (bufwrite(fd,&ch,1) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch == ' ')
- return 1;
- if (bufwrite(fd,(char *) tmo,sizeof(struct ttymodes)) < 0)
- return -1;
- if (bufread(fd,&ch,1) < 0)
- return -1;
- if (ch != '.')
- return 1;
- return 0;
- }
-
- int pty_putch(fd,ch)
- int fd;
- char *ch;
- {
- return bufwrite(fd,ch,1);
- }
-
- int pty_getch(fd,ch)
- int fd;
- char *ch;
- {
- return bufread(fd,ch,1);
- }
-