/*
testlib.c - DSBL tester shared library
Copyright (C) 2002 Ian Gulliver

This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#define TESTLIB_C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <firedns.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <firestring.h>
#include "testlib.h"

struct firestring_conf_t *config;

#define COOKIE_PORT 200

void readconf() {
	char *homedir;

	homedir = getenv("HOME");
	if (homedir != NULL) {
		config = firestring_conf_parse(firestring_concat(homedir,"/.dsblrc",NULL));
		if (config != NULL)
			return;
	}
	
	config = firestring_conf_parse(CONFDIR "/dsbl.conf");
	if (config == NULL) {
		fprintf(stderr,"Cannot open ~/.dsblrc or " CONFDIR "/dsbl.conf\n");
		exit(100);
	}
}

char *getcookiefromserver() {
	int fd;
	struct in_addr *in;
	struct sockaddr_in cookie_addr;
	static char cookie[COOKIE_LENGTH + 1];
	char *cookie_login;
	int i;
	const char *cookie_host,
		*cookie_user,
		*cookie_pass;

	cookie_host = firestring_conf_find(config,"cookie_host");
	if (cookie_host == NULL) {
		fprintf(stderr,"cookie_host not set in config.\n");
		exit(100);
	}

	cookie_user = firestring_conf_find(config,"cookie_user");
	if (cookie_user == NULL) {
		fprintf(stderr,"cookie_user not set in config.\n");
		exit(100);
	}

	cookie_pass = firestring_conf_find(config,"cookie_pass");
	if (cookie_pass == NULL) {
		fprintf(stderr,"cookie_pass not set in config.\n");
		exit(100);
	}

	in = firedns_resolveip4(cookie_host);
	if (in == NULL) {
		fprintf(stderr,"Unable to resolve cookie server.\n");
		exit(100);
	}

	memcpy(&cookie_addr.sin_addr,in,sizeof(struct in_addr));
	cookie_addr.sin_family = AF_INET;
	cookie_addr.sin_port = htons(COOKIE_PORT);

	fd = socket(PF_INET, SOCK_STREAM, 0);
	if (fd == -1) {
		perror("cookie server socket()");
		exit(100);
	}

	if (connect(fd,(struct sockaddr *)&cookie_addr,sizeof(struct sockaddr_in)) != 0) {
		perror("cookie server connect()");
		exit(100);
	}

	cookie_login = firestring_concat(cookie_user,"\n",cookie_pass,"\n",NULL);
	i = strlen(cookie_login);
	if (send(fd,cookie_login,i,0) != i) {
		perror("cookie server send()");
		exit(100);
	}

	if (recv(fd,cookie,COOKIE_LENGTH,0) != COOKIE_LENGTH) {
		perror("cookie server recv()");
		exit(100);
	}

	cookie[COOKIE_LENGTH] = '\0';
	return cookie;
}

char *getcookie() {
	static char *cookie;
	if ((cookie = getenv("DSBL_COOKIE")) == NULL)
		return getcookiefromserver();
	if (strlen(cookie) != COOKIE_LENGTH) {
		perror("DSBL_COOKIE invalid");
		exit(100);
	}
	return cookie;
}

static void alarmhandler(int sig) {
	exit(3);
}

void setalarm() {
	signal(SIGALRM,alarmhandler);
	alarm(120);
}
