sfakeroot_inline.h (2966B)
1 #include <sys/socket.h> 2 #include <sys/un.h> 3 4 #include "sfakeroot.h" 5 6 static int sfakeroot__session_open_internal(bool session_expected) 7 { 8 struct sockaddr_un sa = {.sun_family = AF_UNIX}; 9 int sockfd; 10 socklen_t socklen; 11 char *sockpath = getenv("SFAKEROOT_SOCKET_PATH"); 12 13 if (sockpath == NULL) { 14 fprintf(stderr, "environment variable SFAKEROOT_SOCKET_PATH not set!\n"); 15 return -1; 16 } 17 18 sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 19 if (sockfd == -1) { 20 fprintf(stderr, "socket: %s\n", strerror(errno)); 21 return -1; 22 } 23 24 strlcpy(sa.sun_path, sockpath, sizeof (sa.sun_path)); 25 socklen = strlen(sa.sun_path) + 1 + sizeof (sa.sun_family); 26 27 if (connect(sockfd, (struct sockaddr *) &sa, socklen) == -1) { 28 if (session_expected) { 29 fprintf(stderr, "connect: %s\n", strerror(errno)); 30 } 31 return -1; 32 } 33 34 return sockfd; 35 } 36 37 int sfakeroot_session_open(void) 38 { 39 return sfakeroot__session_open_internal(true); 40 } 41 42 int sfakeroot_recvmsg(int fd, struct sfakeroot_msg *m) 43 { 44 union { 45 char buf[CMSG_SPACE(253)]; // 253 SCM_MAX_FD 46 struct cmsghdr align; 47 } u; 48 struct iovec io = { 49 .iov_base = m, 50 .iov_len = sizeof (*m) 51 }; 52 struct msghdr msg = { 53 .msg_iov = &io, 54 .msg_iovlen = 1, 55 .msg_control = u.buf, 56 .msg_controllen = sizeof (u.buf) 57 }; 58 if (recvmsg(fd, &msg, 0) == -1) { 59 fprintf(stderr, "sfakeroot_recvmsg: error reading message\n"); 60 return -1; 61 } 62 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); 63 if (cmsg && cmsg->cmsg_type == SCM_RIGHTS) { 64 debug("got an fd!!!\n"); 65 memcpy(&m->fd, CMSG_DATA(cmsg), sizeof (int)); 66 } 67 68 return 0; 69 } 70 71 int sfakeroot_sendmsg(int fd, struct sfakeroot_msg *m, int send_fds[], int send_fds_len) 72 { 73 union { 74 char *buf; 75 struct cmsghdr align; 76 } u; 77 int ret = -1; 78 struct iovec io = { 79 .iov_base = m, 80 .iov_len = sizeof (*m) 81 }; 82 struct msghdr msg = { 83 .msg_iov = &io, 84 .msg_iovlen = 1, 85 }; 86 if (send_fds_len > 0) { 87 size_t buflen = CMSG_SPACE(send_fds_len * sizeof(int)); 88 u.buf = malloc(buflen); 89 if (u.buf == NULL) { 90 fprintf(stderr, "sfakeroot_sendmsg: out of memory: %s\n", strerror(errno)); 91 goto cleanup; 92 } 93 msg.msg_control = u.buf; 94 msg.msg_controllen = buflen; 95 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); 96 cmsg->cmsg_level = SOL_SOCKET; 97 cmsg->cmsg_type = SCM_RIGHTS; 98 cmsg->cmsg_len = CMSG_LEN(send_fds_len * sizeof (int)); 99 memcpy(CMSG_DATA(cmsg), send_fds, send_fds_len * sizeof (int)); 100 } 101 if (sendmsg(fd, &msg, 0) == -1) { 102 fprintf(stderr, "sfakeroot_sendmsg: error writing message: %s\n", strerror(errno)); 103 goto cleanup; 104 } 105 ret = 0; 106 cleanup: 107 if (send_fds_len > 0) { 108 free(u.buf); 109 } 110 return ret; 111 }