/*
 * Copyright (c) 2002, 2004, 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-sr-fd.c,v 1.9 2005/04/14 17:14:02 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/test.h"
#include "sm/io.h"
#include "sm/ctype.h"
#include "smi-net.h"

#include <stdio.h>

extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;

static int Verbose;

#define SM_BUFSIZE	8192

static void
usage(const char *prg)
{
	fprintf(stderr, "usage: %s options\n", prg);
	fprintf(stderr, "-b n: set buffer size to n\n");
	fprintf(stderr, "-c n: write n bytes\n");
	fprintf(stderr, "-d n: sleep n seconds before close()\n");
	fprintf(stderr, "-p port: port to use\n");
	fprintf(stderr, "-s n: read n bytes\n");
	exit(0);
}

#if LIB44_FD || LIBSUN_FD || LIBSYSV_FD

/*
**  CLIENT -- send fd to localhost:port
**
**	Parameters:
**		port -- port
**		wr -- number of chars to send
**		delay -- sleep time before close
**		bsize -- buffer size to use
**		timeout -- timeout
**
**	Returns:
**		none
*/

static void
client(int port)
{
	int fd;
	int res;

	if (Verbose > 1)
		fprintf(stderr, "clt: connect\n");
	(void) net_client_connect("127.0.0.1", port, &fd);
	if (Verbose > 1)
		fprintf(stderr, "clt: connected=%d\n", fd);
	SM_TEST(fd >= 0);
	if (fd < 0)
		return;

	/* XXX send */
	res = send_fd(fd, STDIN_FILENO);
	SM_TEST(res >= 0);
	if (sm_is_err(res))
		fprintf(stderr, "clt: send_fd failed=%x\n", res);
}

/*
**  SERVER -- receive rd characters on localhost:port
**
**	Parameters:
**		port -- port
**
**	Returns:
**		none
*/

static void
server(int port)
{
	int fd, lfd, servfd;
	ssize_t i;
	struct sockaddr addr;
	sockaddr_len_T addrlen;
	char buf[256];

	lfd = fd = -1;
	lfd = netserverlisten(NULL, port, 10);
	SM_TEST(lfd >= 0);
	if (lfd < 0)
		return;
	addrlen = sizeof(addr);
	if (Verbose > 1)
		fprintf(stderr, "srv: accept\n");
	fd = net_server_accept(lfd, &addr, &addrlen);
	SM_TEST(fd >= 0);
	if (fd < 0)
		goto err;

	/* XXX receive */
	servfd = recv_fd(fd);
	SM_TEST(servfd >= 0);
	if (servfd >= 0)
	{
		/* read from it... */
		while ((i = read(servfd, buf, sizeof(buf))) >= 0)
		{
			write(STDOUT_FILENO, buf, i);
		}
	}
	else
		fprintf(stderr, "srv: recv_fd failed=%x\n", servfd);

	fd = -1;

  err:
	if (fd >= 0)
		close(fd);
	if (lfd >= 0)
		close(lfd);
}
#endif /* LIB44_FD || LIBSUN_FD || LIBSYSV_FD */

int
main(int argc, char *argv[])
{
	bool clt, any;
	int c, port;
#if LIB44_FD || LIBSUN_FD || LIBSYSV_FD
	sm_ret_T res;
#endif /* LIB44_FD || LIBSUN_FD || LIBSYSV_FD */

	opterr = 0;
	clt = true;
	any = false;
	port = 2525;
	Verbose = 0;
	while ((c = getopt(argc, argv, "csp:V")) != -1)
	{
		any = true;
		switch (c)
		{
		  case 'c':
			clt = true;
			break;
		  case 'p':
			port = atoi(optarg);
			break;
		  case 's':
			clt = false;
			break;
		  case 'V':
			++Verbose;
			break;
		  default:
			usage(argv[0]);
			return(1);
		}
	}
	sm_test_begin(argc, argv, "test send/receive fd");
#if LIB44_FD || LIBSUN_FD || LIBSYSV_FD
	res = net_startup();
	SM_TEST(sm_is_success(res));
	if (!sm_is_success(res))
		return sm_test_end();
	if (!any)
		goto end;

	if (clt)
		client(port);
	else
		server(port);
  end:
#endif /* LIB44_FD || LIBSUN_FD || LIBSYSV_FD */
	net_shutdown();
	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1