📄 communicate.c
字号:
/* rewritten so that it uses no library routines */#if SFS_COMPAT#if defined(__NeXT__)#include <syscall.h>#else#include <sys/syscall.h>#endif#endif#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>/* #include <sys/uio.h> *//* #include <sgtty.h> */#include <signal.h>#if 1#if defined(_IBMR2)#include <sys/select.h>#endif#else#if defined(HAVE_SYS_SELECT_H)#include <sys/select.h>#endif#endif#include "glimpse.h"#include "defs.h"intmystrlen(str, max) char *str; int max;{ int i=0; while ((i<max) && (str[i] != '\0')) i++; return i;}intreadn(fd, ptr, nbytes)int fd;char *ptr;int nbytes;{ int nleft, nread; nleft = nbytes; while (nleft > 0) {#if SFS_COMPAT nread = syscall(SYS_read, fd, ptr, nleft);#else nread = read(fd, ptr, nleft);#endif if (nread < 0) return(nread); else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return (nbytes - nleft);}intwriten(fd, ptr, nbytes)int fd;char *ptr;int nbytes;{ int nleft, nwritten; nleft = nbytes; while (nleft > 0) {#if SFS_COMPAT nwritten = syscall(SYS_write, fd, ptr, nleft);#else nwritten = write(fd, ptr, nleft);#endif if (nwritten <= 0) return nwritten; nleft -= nwritten; ptr += nwritten; } return (nbytes - nleft);}intreadline(sockfd, ptr, maxlen)int sockfd;char *ptr;int maxlen;{ int n, rc; char c; for (n=1; n<maxlen; n++) { if ((rc = readn(sockfd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { if (n==1) return (0); /* EOF */ else break; } else return (-1); } *ptr = 0; return n;}#if USE_MSGHDR/* * This piece of code was causing compilation problems. * It was not being used anyway. So it has been deleted. * -bg, Jan 4th 95 */intsendfile(sockfd, fds, num)int sockfd, fds[], num;{ struct iovec iov[1]; struct msghdr msg; int ret; iov[0].iov_base = (char *) NULL; iov[0].iov_len = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = (caddr_t) NULL; msg.msg_namelen = 0; msg.msg_accrights = (caddr_t) fds; msg.msg_accrightslen = num * sizeof(int); errno = 0;#if SFS_COMPAT if ((ret = syscall(SYS_sendmsg, sockfd, &msg, 0)) < 0) {#else if ((ret = sendmsg(sockfd, &msg, 0)) < 0) {#endif#if 0 printf("sendmsg ret = %x, errno = %d\n", ret, errno);#endif return (-1); }#if 0 printf("sent fds %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);#endif return (0);}intsend_clfds(sockfd, clstdin, clstdout, clstderr)int sockfd, clstdin, clstdout, clstderr;{ int fds[3]; fds[0] = clstdin; fds[1] = clstdout; fds[2] = clstderr; if (sendfile(sockfd, fds, 3) < 0) return -1; return 0;}intgetfile(sockfd, fds, num)int sockfd, fds[], num;{ struct iovec iov[1]; struct msghdr msg; int ret; iov[0].iov_base = (char *) NULL; iov[0].iov_len = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = (caddr_t) NULL; msg.msg_namelen = 0; msg.msg_accrights = (caddr_t)fds; msg.msg_accrightslen = num*sizeof(int); errno = 0;#if SFS_COMPAT if ((ret = syscall(SYS_recvmsg, sockfd, &msg, 0)) < 0) {#else if ((ret = recvmsg(sockfd, &msg, 0)) < 0) {#endif#if 0 printf("bad recvmsg: ret = %x, errno = %d\n", ret, errno);#endif return -1; }#if 0 printf("got fds %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);#endif return 0;}intget_clfds(sockfd, pclstdin, pclstdout, pclstderr)int sockfd, *pclstdin, *pclstdout, *pclstderr;{ int fds[3]; if (getfile(sockfd, fds, 3) < 0) return -1; if (((*pclstdin = fds[0]) < 0) || (*pclstdin >= 20)) return -1; if (((*pclstdout = fds[1]) < 0) || (*pclstdout >= 20)) return -1; if (((*pclstderr = fds[2]) < 0) || (*pclstderr >= 20)) return -1; return 0;}#endif /*USE_MSGHDR*/intlinearize(sockfd, reqbuf, reqlen, argc, argv, pid)int sockfd;int reqlen, argc;char *reqbuf, *argv[];int pid;{ int i; unsigned char array[4]; int ptr = 0; int len; array[0] = (pid & 0xff000000) >> 24; array[1] = (pid & 0xff0000) >> 16; array[2] = (pid & 0xff00) >> 8; array[3] = (pid & 0xff); if (sockfd >= 0) { if (writen(sockfd, array, 4) < 4) return -1; } if (reqbuf != NULL) { if (ptr + 4 >= reqlen) return -1; memcpy(reqbuf+ptr, array, 4); ptr += 4; } array[0] = (argc & 0xff000000) >> 24; array[1] = (argc & 0xff0000) >> 16; array[2] = (argc & 0xff00) >> 8; array[3] = (argc & 0xff); if (sockfd >= 0) { if (writen(sockfd, array, 4) < 4) return -1; } if (reqbuf != NULL) { if (ptr + 4 >= reqlen) return -1; memcpy(reqbuf+ptr, array, 4); ptr += 4; } for (i=0; i<argc; i++) { len = strlen(argv[i]); if (sockfd >= 0) { if (writen(sockfd, argv[i], len + 1) < len + 1) return -1; if (writen(sockfd, "\n", 1) < 1) return -1; /* so that we can do gets */ } if (reqbuf != NULL) { if (ptr + len + 2 >= reqlen) return -1; strcpy(reqbuf+ptr, argv[i]); ptr += len+1; reqbuf[ptr++] = '\0'; /* so that we can do strcpy */ }#if 0 printf("sending %s\n", argv[i]);#endif } return ptr;}intdelinearize(sockfd, reqbuf, reqlen, pargc, pargv, ppid)int sockfd;int reqlen, *pargc;char *reqbuf, **pargv[];int *ppid;{ int i; char line[MAXLINE]; int len; int ptr = 0; unsigned char array[4]; *ppid = 0; *pargc = 0; *pargv = NULL; memset(array, '\0', 4); if (sockfd >= 0) if (readn(sockfd, array, 4) != 4) return -1; if (reqbuf != NULL) { if (ptr+4 >= reqlen) return -1; memcpy(array, reqbuf+ptr, 4); ptr += 4; } *ppid = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3]; memset(array, '\0', 4); if (sockfd >= 0) if (readn(sockfd, array, 4) != 4) return -1; if (reqbuf != NULL) { if (ptr+4 >= reqlen) return -1; memcpy(array, reqbuf+ptr, 4); ptr += 4; } *pargc = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3];#if 0 printf("clargc=%x\n", *pargc);#endif /* VERY important, set hard-coded limit to MAX_ARGS*MAX_NAME_LEN; otherwise can cause the server to allocate TONS of memory */ if (*pargc <= 0 || *pargc >= (MAX_ARGS*MAX_NAME_LEN)) { *pargc = 0; return -1; } if ((*pargv = (char **)malloc(sizeof(char *) * *pargc)) == NULL) { /* no memory, so discard */ *pargc = 0; return - 1; } memset(*pargv, '\0', sizeof(char *) * *pargc); for (i=0; i<*pargc; i++) { if (sockfd >= 0) { if (readline(sockfd, line, MAXLINE) <= 0) return -1; if ((len = mystrlen(line, MAXLINE)) <= 0) { i--; continue; } if (((*pargv)[i] = (char *)malloc(len + 2)) == NULL) return -1; line[len] = '\0'; /* overwrite the '\n' */ strcpy((*pargv)[i], line); } if (reqbuf != NULL) { if ( ((len = mystrlen(reqbuf+ptr, reqlen-ptr)) <= 0) || (len >= MAXLINE) ) return -1; if (((*pargv)[i] = (char *)malloc(len + 2)) == NULL) return -1; strcpy((*pargv)[i], reqbuf+ptr); ptr += len + 2; }#if 0 printf("clargv[%x]=%s\n", i, (*pargv)[i]);#endif } return ptr;}intsendreq(sockfd, reqbuf, clstdin, clstdout, clstderr, clargc, clargv, clpid)int sockfd, clstdin, clstdout, clstderr, clargc, clpid;char reqbuf[MAX_ARGS*MAX_NAME_LEN], *clargv[];{#if USE_MSGHDR struct iovec iov[1]; struct msghdr msg; int ret; int fds[3];#endif /*USE_MSGHDR*/#if USE_MSGHDR if ((ret = linearize(-1, reqbuf, MAX_ARGS*MAX_NAME_LEN, clargc, clargv, clpid)) < 0) return -1; fds[2] = clstdin; fds[1] = clstdout; fds[0] = clstderr; iov[0].iov_base = (char *) reqbuf; iov[0].iov_len = ret; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = (caddr_t) NULL; msg.msg_namelen = 0; msg.msg_accrights = (caddr_t) fds; msg.msg_accrightslen = 2 * sizeof(int); /* don't send clstdin */ errno = 0;#if SFS_COMPAT if ((ret = syscall(SYS_sendmsg, sockfd, &msg, 0)) < 0) {#else if ((ret = sendmsg(sockfd, &msg, 0)) < 0) {#endif#if 0 printf("sendmsg ret = %x, errno = %d\n", ret, errno);#endif return (-1); }#if 0 printf("sendreq %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);#endif#else /*USE_MSGHDR*/ if (linearize(sockfd, (char *)NULL, MAX_ARGS*MAX_NAME_LEN, clargc, clargv, clpid) < 0) return -1;#endif /*USE_MSGHDR*/ return (0);}intgetreq(sockfd, reqbuf, pclstdin, pclstdout, pclstderr, pclargc, pclargv, pclpid)int sockfd, *pclstdin, *pclstdout, *pclstderr, *pclargc, *pclpid;char reqbuf[MAX_ARGS*MAX_NAME_LEN], **pclargv[];{#if USE_MSGHDR struct iovec iov[1]; struct msghdr msg; int ret; int fds[3];#endif /*USE_MSGHDR*/#if USE_MSGHDR iov[0].iov_base = (char *) reqbuf; iov[0].iov_len = MAX_ARGS * MAX_NAME_LEN; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = (caddr_t) NULL; msg.msg_namelen = 0; msg.msg_accrights = (caddr_t)fds; msg.msg_accrightslen = 2*sizeof(int); errno = 0;#if SFS_COMPAT if ((ret = syscall(SYS_recvmsg, sockfd, &msg, 0)) < 0) {#else if ((ret = recvmsg(sockfd, &msg, 0)) < 0) {#endif#if 0 printf("bad recvmsg: ret = %x, errno = %d\n", ret, errno);#endif return -1; } *pclstdin = fds[2]; *pclstdout = fds[1]; *pclstderr = fds[0]; if ((ret == delinearize(-1, reqbuf, MAX_ARGS * MAX_NAME_LEN, pclargc, pclargv, pclpid)) < 0) return -1;#if 0 printf("getreq %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);#endif#else /*USE_MSGHDR*/ if (delinearize(sockfd, (char *)NULL, MAX_ARGS * MAX_NAME_LEN, pclargc, pclargv, pclpid) < 0) return -1; *pclstdin = -1; *pclstdout = sockfd; *pclstderr = sockfd;#endif /*USE_MSGHDR*/ return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -