#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define DATA "Half a league, half a league . . ."

#define NAME "/tmp/socket"

int main(int argc, char **argv)
{
    int sock;
    socklen_t len;
    struct sockaddr_un server;
    uid_t uid;
    gid_t gid;

    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock == -1)
        err(EXIT_FAILURE, "opening stream socket");

    server.sun_family = AF_UNIX;
    strcpy(server.sun_path, NAME);
    server.sun_len = strlen(NAME);
    if (connect(sock, (struct sockaddr *) &server,
                sizeof(struct sockaddr_un)) == -1)
        err(EXIT_FAILURE, "connecting stream socket");

    len = sizeof(server);
    memset(&server, 0, sizeof(server));
    getsockname(sock, (struct sockaddr *)&server, &len);

    printf("client: From getsockname():\n");
    printf("client: sun_len = %lu\n", (long) server.sun_len);
    printf("client: sun_family = %d\n", (int) server.sun_family);
    printf("client: strlen(sun_path) = %lu\n", (long)strlen(server.sun_path));
    printf("client: sun_path = '%s'\n", server.sun_path);

    len = sizeof(server);
    memset((char *)&server, 0, sizeof(server));
    getpeername(sock, (struct sockaddr *)&server, &len);

    printf("\nclient: From getpeername():\n");
    printf("client: sun_len = %u\n", server.sun_len);
    printf("client: sun_family = %u\n", server.sun_family);
    printf("client: strlen(sun_path) = %zu\n", strlen(server.sun_path));
    printf("client: sun_path = '%s'\n", server.sun_path);

    {
	struct unpcbid cred;
        len = sizeof(cred);
        if (getsockopt(sock, 0, LOCAL_PEEREID, &cred, &len) == -1)
	    warn("getsockopt()");
	else
	    printf("client: Peer uid = %u, gid = %u, pid = %u\n",
		 cred.unp_euid, cred.unp_egid, cred.unp_pid);
    }
#if 0
    if (getpeereid(sock, &uid, &gid) < 0)
	warn("getpeereid()");
    else
        printf("client: Peer uid = %u, gid = %u\n", uid, gid);
#endif

    if (write(sock, DATA, sizeof(DATA)) < 0)
        warn("writing on stream socket");

    close(sock);

    return 0;
}