#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

main(argc, argv)
int argc;
char **argv;

{
	int verbose;
	int lfd, sfd;
	struct sockaddr_in myaddr, claddr;
	struct in_addr ia;
	int inane;
	int pid;

	verbose = 0;
	if (argc > 1 && strcmp(argv[1], "-v") == 0) {
		verbose = 1;
		argc--;
		argv++;
	}
	if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}
	myaddr.sin_family = AF_INET;
	myaddr.sin_port = htons(22222);
	myaddr.sin_addr.s_addr = INADDR_ANY;
	if (bind(lfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
		perror("bind");
		exit(1);
	}
	inane = sizeof(myaddr);
	if (getsockname(lfd, (struct sockaddr *)&myaddr, &inane) < 0) {
		perror("getsockname");
		exit(1);
	}
	if (listen(lfd, 5) < 0) {
		perror("listen");
		exit(1);
	}
	fprintf(stderr, "listening on %d\n", ntohs(myaddr.sin_port));
	fflush(stdout);
	while (inane = sizeof(claddr), (sfd = accept(lfd, (struct sockaddr *)&claddr, &inane)) >= 0) {
		if ((pid = fork()) < 0)
			perror("fork");
		else if (pid == 0)
			copydata(sfd, verbose);
		/* else parent */
		close(sfd);
		if (verbose)
			fprintf(stderr, "accept %s:%d, pid %d\n",
				inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port), pid);
	}
	exit(0);
}

copydata(fd, verbose)
int fd;
int verbose;
{
	char buf[200];
	int mypid;
	FILE *fp;

	mypid = getpid();
	if ((fp = fdopen(fd, "r")) == NULL) {
		fprintf(stderr, "%d: can't fdopen\n", mypid);
		exit(1);
	}
	while (fgets(buf, sizeof(buf), fp)) {
		if (verbose)
			printf("%d: ", mypid);
		fputs(buf, stdout);
		fflush(stdout);
	}
	exit(0);
}

