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


static const char crap[] =
    "socket-file-crap-crap-crap-crap-crap-crap-crap-crap-crap-crap-crap";

int main(int argc, char *argv[])
{
	int serv, clnt, acpt;
	struct sockaddr_un addr;
	struct sockaddr_un acpt_addr;
	socklen_t acept_addrlen;
	int ret;
	int i;


	serv = socket(AF_UNIX, SOCK_STREAM, 0);
	if (serv == -1)
		err(EXIT_FAILURE, "socket");

	memset(&addr, '\0', sizeof(addr));
	addr.sun_family = AF_UNIX;
	unlink(crap);
	strcpy(addr.sun_path, crap);


	ret = bind(serv, (struct sockaddr *) &addr, sizeof(addr));
	if (ret == -1)
		err(EXIT_FAILURE, "bind");


	ret = listen(serv, SOMAXCONN);
	if (ret == -1)
		err(EXIT_FAILURE, "listen");


	clnt = socket(AF_UNIX, SOCK_STREAM, 0);
	if (clnt == -1)
		err(EXIT_FAILURE, "socket");


	ret = connect(clnt, (struct sockaddr *) &addr, sizeof(addr));
	if (ret == -1)
		err(EXIT_FAILURE, "connect");

#if 1
	ret = close(clnt);
	if (ret == -1)
		err(EXIT_FAILURE, "close");
#endif


	acept_addrlen = sizeof(acpt_addr);
	memset(&acpt_addr, 0, sizeof(acpt_addr));
	acpt = accept(serv, (struct sockaddr *) &acpt_addr,
	    &acept_addrlen);
	if (acpt == -1)
		err(EXIT_FAILURE, "accept");


	printf("client socket length: %d\n", (int) acept_addrlen);
	printf("client family %d\n", acpt_addr.sun_family);
#ifdef __NetBSD__
	printf("client len %d\n", acpt_addr.sun_len);
#endif
	printf("client socket name: ");
	for (i = 0; i < sizeof(acpt_addr.sun_path); i++) {
		int ch = acpt_addr.sun_path[i];
		if (ch < ' ' || '~' < ch)
			printf("\\x%02x", ch);
		else
			printf("%c", ch);
		if (i % 16 == 15)
			printf("\n");
	}
	printf("\n");


	return EXIT_SUCCESS;
}