/*
 * Copyright 2001, 2002, 2003, 2013 Adam Sampson <ats@offog.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "iolib.h"
#include "freedt.h"
#include "config.h"
const char *progname = "anonidentd";
const char *proghelp =
	"Usage: anonidentd [OPTIONS]\n"
	"A simple anonymous identd server.\n\n"
	"-n        Return a HIDDEN-USER response\n"
	"-c ID     Return a USERID:UNIX ID response\n";

char *response = NULL;

int main(int argc, char **argv) {
	int my_pid = getpid();
	char *remoteip, *remoteport;
	buffer overflow = BUFFER;

	while (1) {
		int c = getopt(argc, argv, "V?nc:");
		if (c == -1)
			break;
		switch (c) {
		case 'n':
			response = NULL;
			break;
		case 'c':
			response = strdup(optarg);
			break;
		case 'V':
			version();
		default:
			help();
		}
	}

	if (argc != optind)
		help();

	setuidgidroot();

	remoteip = getenv("TCPREMOTEIP");
	if (remoteip == NULL)
		die("no TCPREMOTEIP set");
	remoteport = getenv("TCPREMOTEPORT");
	if (remoteport == NULL)
		die("no TCPREMOTEPORT set");

	format(fd_err, "@i: connect from @c port @c\n",
		my_pid, remoteip, remoteport);	

	while (1) {
		ssize_t pos;
		int c;
		const char *s;
		int my_port, their_port;
		buffer request = BUFFER, reply = BUFFER;

		c = readlineb(fd_in, &request, 1000, &overflow);
		if (c == 0)
			break;
		if (c < 0) {
			format(fd_err, "@i: read from client failed\n", my_pid);
			break;
		}

		pos = bindex(&request, ',');
		if (pos == -1) {
			format(fd_err, "@i: request without comma\n", my_pid);
			break;
		}

		s = bstr(&request);
		my_port = atoi(s);
		their_port = atoi(s + pos + 1);

		if (my_port < 1 || my_port > 65535
			|| their_port < 1 || their_port > 65535) {
			format(fd_err, "@i: port out of range in request\n",
				my_pid);
			break;
		}

		format(fd_err, "@i: request @i,@i\n",
			my_pid, my_port, their_port);

		bformat(&reply, " @i , @i : ", my_port, their_port);
		if (response == NULL) {
			bformat(&reply, "ERROR : HIDDEN-USER\r\n");
		} else {
			bformat(&reply, "USERID : UNIX : @c\r\n", response);
		}

		if (writeba(fd_out, &reply) < 0) {
			format(fd_err, "@i: write to client failed\n", my_pid);
			break;
		}

		bfree(&request);
		bfree(&reply);
	}

	format(fd_err, "@i: closed\n", my_pid);

	return 0;
}

