#define _GNU_SOURCE
#include "channel.h"
#include "exchange.h"
#include <stdlib.h>
#include <sys/shm.h>

int main(int argc, char **argv)
{
    if (argc != 2) {
        fprintf(stderr, "usage: %s SOCKET\n", argv[0]);
        return EXIT_FAILURE;
    }
    int result = EXIT_FAILURE, id;
    int peer = channel_open(argv[1], 0);
    struct exchange *box = (void *)-1;
    struct shmid_ds info;
    if (peer == -1 || channel_receive(peer, &id, sizeof(id)) == -1)
        goto out;
    if (shmctl(id, IPC_STAT, &info) == -1)
        goto out;
    if (info.shm_segsz != sizeof(*box) || info.shm_perm.uid != geteuid()) {
        errno = EPROTO;
        goto out;
    }
    box = shmat(id, NULL, 0);
    if (box == (void *)-1 || exchange_client(box) == -1)
        goto out;
    result = EXIT_SUCCESS;
out:
    if (result != EXIT_SUCCESS)
        perror("System V client");
    if (box != (void *)-1 && shmdt(box) == -1) {
        perror("shmdt");
        result = EXIT_FAILURE;
    }
    /* Closing the control connection is the final quiescence handshake. */
    if (peer != -1 && close(peer) == -1) {
        perror("peer close");
        result = EXIT_FAILURE;
    }
    return result;
}
