Sindbad~EG File Manager
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#include <signal.h>
#include <sys/socket.h>
#if !defined CMSG_SPACE || !defined CMSG_LEN
#ifndef ALIGN
#define ALIGN(len) len
#endif
#ifndef CMSG_SPACE
#define CMSG_SPACE(len) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(len))
#endif
#ifndef CMSG_LEN
#define CMSG_LEN(len) (ALIGN(sizeof(struct cmsghdr)) + len)
#endif
#endif
#define TEST "test"
static int send_fd(int s, int fd)
{
struct msghdr msg;
struct cmsghdr *cmsg;
unsigned char fdbuf[CMSG_SPACE(sizeof(int))];
struct iovec iov[1];
char dummy[] = "";
iov[0].iov_base = dummy;
iov[0].iov_len = 1;
memset(&msg, 0, sizeof(msg));
msg.msg_control = fdbuf;
/* must send/receive at least one byte */
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_controllen = CMSG_LEN(sizeof(int));
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(cmsg) = fd;
if (sendmsg(s, &msg, 0) == -1) {
perror("sendmsg");
close(s);
return -1;
}
return 0;
}
static int testfd(int desc)
{
char buf[256];
if (read(desc, buf, sizeof(buf)) != sizeof(TEST)) {
fprintf(stderr, "test data not received correctly!");
return 1;
}
return memcmp(buf, TEST, sizeof(TEST));
}
static int recv_fd(int desc)
{
unsigned char buf[CMSG_SPACE(sizeof(int))];
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov[1];
char dummy;
int ret = 2;
memset(&msg, 0, sizeof(msg));
iov[0].iov_base = &dummy;
iov[0].iov_len = 1;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
if (recvmsg(desc, &msg, 0) == -1) {
perror("recvmsg failed!");
return -1;
}
if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC)) {
fprintf(stderr, "control message truncated");
return -1;
}
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int fd = *(int *)CMSG_DATA(cmsg);
ret = testfd(fd);
close(fd);
}
}
return ret;
}
int main(void)
{
int fd[2];
int pip[2];
pid_t pid;
int status;
if (pipe(pip)) {
perror("pipe");
return 1;
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
perror("socketpair");
return 1;
}
if ((pid = fork()) < 0) {
perror("fork");
} else if (!pid) {
exit(recv_fd(fd[1]));
} else {
/* parent */
if (send_fd(fd[0], pip[0]) == -1) {
kill(pid, 9);
waitpid(pid, NULL, 0);
return 2;
}
if (write(pip[1], TEST, sizeof(TEST)) != sizeof(TEST)) {
close(pip[1]);
return -1;
}
close(pip[1]);
waitpid(pid, &status, 0);
}
return status;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists