/*
 * SCM_RIGHTS with unix socket help program for test
 *
 * Copyright IBM, Inc. 2013
 *
 * Authors:
 *  Wenchao Xia    <xiawenc@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 * See the COPYING.LIB file in the top-level directory.
 */

#include "qemu/osdep.h"
#include <sys/socket.h>
#include <sys/un.h>

/* #define SOCKET_SCM_DEBUG */

/*
 * @fd and @fd_to_send will not be checked for validation in this function,
 * a blank will be sent as iov data to notify qemu.
 */
static int send_fd(int fd, int fd_to_send)
{
    struct msghdr msg;
    struct iovec iov[1];
    int ret;
    char control[CMSG_SPACE(sizeof(int))];
    struct cmsghdr *cmsg;

    memset(&msg, 0, sizeof(msg));
    memset(control, 0, sizeof(control));

    /* Send a blank to notify qemu */
    iov[0].iov_base = (void *)" ";
    iov[0].iov_len = 1;

    msg.msg_iov = iov;
    msg.msg_iovlen = 1;

    msg.msg_control = control;
    msg.msg_controllen = sizeof(control);

    cmsg = CMSG_FIRSTHDR(&msg);

    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    memcpy(CMSG_DATA(cmsg), &fd_to_send, sizeof(int));

    do {
        ret = sendmsg(fd, &msg, 0);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0) {
        fprintf(stderr, "Failed to send msg, reason: %s\n", strerror(errno));
    }

    return ret;
}

/* Convert string to fd number. */
static int get_fd_num(const char *fd_str, bool silent)
{
    int sock;
    char *err;

    errno = 0;
    sock = strtol(fd_str, &err, 10);
    if (errno) {
        if (!silent) {
            fprintf(stderr, "Failed in strtol for socket fd, reason: %s\n",
                    strerror(errno));
        }
        return -1;
    }
    if (!*fd_str || *err || sock < 0) {
        if (!silent) {
            fprintf(stderr, "bad numerical value for socket fd '%s'\n", fd_str);
        }
        return -1;
    }

    return sock;
}

/*
 * To make things simple, the caller needs to specify:
 * 1. socket fd.
 * 2. path of the file to be sent.
 */
int main(int argc, char **argv, char **envp)
{
    int sock, fd, ret;

#ifdef SOCKET_SCM_DEBUG
    int i;
    for (i = 0; i < argc; i++) {
        fprintf(stderr, "Parameter %d: %s\n", i, argv[i]);
    }
#endif

    if (argc != 3) {
        fprintf(stderr,
                "Usage: %s < socket-fd > < file-path >\n",
                argv[0]);
        return EXIT_FAILURE;
    }


    sock = get_fd_num(argv[1], false);
    if (sock < 0) {
        return EXIT_FAILURE;
    }

    fd = get_fd_num(argv[2], true);
    if (fd < 0) {
        /* Now only open a file in readonly mode for test purpose. If more
           precise control is needed, use python script in file operation, which
           is supposed to fork and exec this program. */
        fd = open(argv[2], O_RDONLY);
        if (fd < 0) {
            fprintf(stderr, "Failed to open file '%s'\n", argv[2]);
            return EXIT_FAILURE;
        }
    }

    ret = send_fd(sock, fd);
    if (ret < 0) {
        close(fd);
        return EXIT_FAILURE;
    }

    close(fd);
    return EXIT_SUCCESS;
}
