/*
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 * All rights reserved
 *
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.
 */

#include "shttpd_defs.h"
#include "wsmand-daemon.h"

/*
 * Configuration parameters setters
 */
static void
set_int(struct shttpd_ctx *ctx, void *ptr, const char *string)
{
	ctx = NULL;	/* Unused */
	* (int *) ptr = atoi(string);
}

static void
set_str(struct shttpd_ctx *ctx, void *ptr, const char *string)
{
	ctx = NULL;	/* Unused */
	* (char **) ptr = strdup(string);
}

static void
set_log_file(struct shttpd_ctx *ctx, void *ptr, const char *string)
{
	FILE	**fp = ptr;
	ctx = NULL;

	if ((*fp = fopen(string, "a")) == NULL)
		elog(E_FATAL, NULL, "cannot open log file %s: %s",
		    string, strerror(errno));
}

static int isbyte(int n) { return (n >= 0 && n <= 255); }

static void
set_acl(struct shttpd_ctx *ctx, void *ptr, const char *s)
{
	struct llhead	*head = ptr;
	struct acl	*acl;
	char		flag;
	int		len, a, b, c, d, n, mask;

	ctx = NULL;

	FOR_EACH_WORD_IN_LIST(s, len) {

		mask = 32;

		if (sscanf(s, "%c%d.%d.%d.%d%n",&flag,&a,&b,&c,&d,&n) != 5) {
			elog(E_FATAL, NULL, "[%s]: subnet must be "
			    "[+|-]x.x.x.x[/x]", s);
		} else if (flag != '+' && flag != '-') {
			elog(E_FATAL, NULL, "flag must be + or -: [%s]", s);
		} else if (!isbyte(a)||!isbyte(b)||!isbyte(c)||!isbyte(d)) {
			elog(E_FATAL, NULL, "bad ip address: [%s]", s);
		} else	if ((acl = malloc(sizeof(*acl))) == NULL) {
			elog(E_FATAL, NULL, "%s", "cannot malloc subnet");
		} else if (sscanf(s + n, "/%d", &mask) == 0) {
			/* Do nothing, no mask specified */
		} else if (mask < 0 || mask > 32) {
			elog(E_FATAL, NULL, "bad subnet mask: %d [%s]", n, s);
		}

		acl->ip = (a << 24) | (b << 16) | (c << 8) | d;
		acl->mask = mask ? 0xffffffffU << (32 - mask) : 0;
		acl->flag = flag;
		LL_TAIL(head, &acl->link);
	}
}

#ifndef NO_SSL
/*
 * Dynamically load SSL library. Set up ctx->ssl_ctx pointer.
 */
static void
set_ssl(struct shttpd_ctx *ctx, void *arg, const char *pem)
{
	SSL_CTX		*CTX;
	void		*lib;
	struct ssl_func	*fp;

	arg = NULL;	/* Unused */

	/* Load SSL library dynamically */
	if ((lib = dlopen(SSL_LIB, RTLD_LAZY)) == NULL)
		elog(E_FATAL, NULL, "set_ssl: cannot load %s", SSL_LIB);

	for (fp = ssl_sw; fp->name != NULL; fp++)
		if ((fp->ptr.v_void = dlsym(lib, fp->name)) == NULL)
			elog(E_FATAL, NULL,"set_ssl: cannot find %s", fp->name);

	/* Initialize SSL crap */
	static int ssl_library_initialized = 0;
	if(!ssl_library_initialized) {
		debug("Initialize SSL");
		SSL_library_init();
		ssl_library_initialized = 1;
	}
	if ((CTX = SSL_CTX_new(SSLv23_server_method())) == NULL)
		elog(E_FATAL, NULL, "SSL_CTX_new error");
        else if (wsmand_options_get_ssl_cert_file() && SSL_CTX_use_certificate_file(CTX, wsmand_options_get_ssl_cert_file(),SSL_FILETYPE_PEM) == 0)
		elog(E_FATAL, NULL, "cannot open %s", pem);
	else if (wsmand_options_get_ssl_key_file() && SSL_CTX_use_PrivateKey_file(CTX, wsmand_options_get_ssl_key_file(), SSL_FILETYPE_PEM) == 0)
		elog(E_FATAL, NULL, "cannot open %s", pem);
	ctx->ssl_ctx = CTX;
}
#endif /* NO_SSL */

static void
set_mime(struct shttpd_ctx *ctx, void *arg, const char *string)
{
	arg = NULL;
	set_mime_types(ctx, string);
}

#define	OFS(x)	offsetof(struct shttpd_ctx, x)
#define BOOL_OPT	"0|1"
const struct opt options[] = {
	{'d', "document_root", "Web root directory", set_str,
		OFS(document_root), "directory", NULL, OPT_DIR},
	{'i', "index_files", "Index files", set_str, OFS(index_files),
		"file_list", INDEX_FILES, OPT_ADVANCED},
	{'p', "listen_ports", "Listening ports", set_str,
		OFS(ports), "ports", LISTENING_PORTS, OPT_ADVANCED},
	{'D', "list_directories", "Directory listing", set_int,
		OFS(dirlist), BOOL_OPT, "1", OPT_BOOL | OPT_ADVANCED},
#ifndef NO_CGI
	{'c', "cgi_extensions", "CGI extensions", set_str,
		OFS(cgi_extensions), "ext_list", CGI_EXT, OPT_ADVANCED},
	{'C', "cgi_interpreter", "CGI interpreter", set_str,
		OFS(cgi_interpreter), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'V', "cgi_envvar", "CGI envir variables", set_str,
		OFS(cgi_vars), "X=Y,....", NULL, OPT_ADVANCED},
#endif /* NO_CGI */
#if !defined(NO_SSI)
	{'S', "ssi_extensions", "SSI extensions", set_str,
		OFS(ssi_extensions), "ext_list", SSI_EXT, OPT_ADVANCED},
#endif /* NO_SSI */
	{'N', "auth_realm", "Authentication realm", set_str,
		OFS(auth_realm), "auth_realm", REALM, OPT_ADVANCED},
	{'l', "access_log", "Access log file", set_log_file,
		OFS(access_log), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'e', "error_log", "Error log file", set_log_file,
		OFS(error_log), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'m', "mime_types", "Mime types file", set_mime,
		OFS(mime_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'P', "global_htpasswd", "Global passwords file", set_str,
		OFS(global_passwd_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
#ifndef NO_SSL
	{'s', "ssl_certificate", "SSL certificate file", set_ssl,
		OFS(ssl_ctx), "pem_file", NULL, OPT_FILE | OPT_ADVANCED},
#endif /* NO_SSL */
	{'U', "put_auth", "PUT,DELETE auth file",set_str,
		OFS(put_auth_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'a', "aliases", "Aliases", set_str,
		OFS(aliases), "X=Y,...", NULL, OPT_ADVANCED},
	{'b', "io_buf_size", "IO buffer size", set_int, OFS(io_buf_size),
		"bytes", DFLT_IO_SIZ, OPT_INT | OPT_ADVANCED},
	{'x', "acl", "Allow/deny IP addresses/subnets", set_acl,
		OFS(acl), "acl_list", NULL, OPT_ADVANCED},
#ifdef _WIN32
	{'B', "auto_start", "Autostart with Windows", set_int,
		OFS(auto_start), BOOL_OPT, "1", OPT_BOOL},
#else
	{'I', "inetd_mode", "Inetd mode", set_int,
		OFS(inetd_mode), BOOL_OPT, NULL, OPT_BOOL	},
	{'u', "runtime_uid", "Run as user", set_str,
		OFS(uid), "user_name", NULL, 0		},
#endif /* _WIN32 */
	{0,   NULL, NULL, NULL, 0, NULL, NULL, 0	}
};

static const struct opt *
find_option(int sw, const char *name)
{
	const struct opt	*opt;

	for (opt = options; opt->sw != 0; opt++)
		if (sw == opt->sw || (name && strcmp(opt->name, name) == 0))
			return (opt);

	return (NULL);
}

static void
set_option(const struct opt *opt, const char *val, char **tmpvars)
{
	tmpvars += opt - options;

	if (*tmpvars != NULL)
		free(*tmpvars);

	*tmpvars = strdup(val);
}

/*
 * Initialize shttpd context
 */
static void
initialize_context(struct shttpd_ctx *ctx, const char *config_file,
		int argc, char *argv[], char **tmpvars)
{
	char			line[FILENAME_MAX], root[FILENAME_MAX],
					var[sizeof(line)], val[sizeof(line)];
	const char		*arg;
	size_t			i;
	const struct opt	*opt;
	FILE 			*fp;
	struct tm		*tm;

	current_time = time(NULL);
	tm = localtime(&current_time);
	tz_offset = 0;
#if 0
	tm->tm_gmtoff - 3600 * (tm->tm_isdst > 0 ? 1 : 0);
#endif

	(void) memset(ctx, 0, sizeof(*ctx));

	ctx->start_time = current_time;
	InitializeCriticalSection(&ctx->mutex);

	LL_INIT(&ctx->connections);
	LL_INIT(&ctx->mime_types);
	LL_INIT(&ctx->registered_uris);
	LL_INIT(&ctx->uri_auths);
	LL_INIT(&ctx->error_handlers);
	LL_INIT(&ctx->acl);

#if !defined(NO_SSI)
	LL_INIT(&ctx->ssi_funcs);
#endif /* NO_SSI */

	/* First pass: set the defaults */
	for (opt = options; opt->sw != 0; opt++)
		if (tmpvars[opt - options] == NULL && opt->def != NULL)
			tmpvars[opt - options] = strdup(opt->def);

	/* Second pass: load config file  */
	if (config_file != NULL && (fp = fopen(config_file, "r")) != NULL) {
		DBG(("init_ctx: config file %s", config_file));

		/* Loop through the lines in config file */
		while (fgets(line, sizeof(line), fp) != NULL) {

			/* Skip comments and empty lines */
			if (line[0] == '#' || line[0] == '\n')
				continue;

			/* Trim trailing newline character */
			line[strlen(line) - 1] = '\0';

			if (sscanf(line, "%s %[^#\n]", var, val) != 2)
				elog(E_FATAL,0,"init_ctx: bad line: [%s]",line);

			if ((opt = find_option(0, var)) == NULL)
				elog(E_FATAL, NULL,
				    "set_option: unknown variable [%s]", var);
			set_option(opt, val, tmpvars);
		}
		(void) fclose(fp);
	}

	/* Third pass: process command line args */
	for (i = 1; i < (size_t) argc && argv[i][0] == '-'; i++)
		if ((opt = find_option(argv[i][1], NULL)) != NULL) {
			arg = argv[i][2] ? &argv[i][2] : argv[++i];

			if (arg == NULL)
				usage(argv[0]);

			set_option(opt, arg, tmpvars);
		} else {
			usage(argv[0]);
		}

	/* Call setters functions now */
	for (i = 0; i < NELEMS(options); i++)
		if (tmpvars[i] != NULL) {
			options[i].setter(ctx,
			    ((char *) ctx) + options[i].ofs, tmpvars[i]);
			free(tmpvars[i]);
		}

	/* If document_root is not set, set it to current directory */
	if (ctx->document_root == NULL) {
		(void) my_getcwd(root, sizeof(root));
		ctx->document_root = strdup(root);
	}

#ifdef _WIN32
	{WSADATA data;	WSAStartup(MAKEWORD(2,2), &data);}
#endif /* _WIN32 */

	DBG(("init_ctx: initialized context %p", (void *) ctx));
}

/*
 * Show usage string and exit.
 */
void
usage(const char *prog)
{
	const struct opt	*opt;

	(void) fprintf(stderr,
	    "SHTTPD version %s (c) Sergey Lyubka\n"
	    "usage: %s [OPTIONS] [config_file]\n"
	    "Note: config line keyword for every option is in the "
	    "round brackets\n", VERSION, prog);

#if !defined(NO_AUTH)
	(void) fprintf(stderr, "-A <htpasswd_file> <realm> <user> <passwd>\n");
#endif /* NO_AUTH */

	for (opt = options; opt->name != NULL; opt++)
		(void) fprintf(stderr, "-%c <%s>\t\t%s (%s)\n",
		    opt->sw, opt->arg, opt->desc, opt->name);

	exit(EXIT_FAILURE);
}

struct shttpd_ctx *
init_from_argc_argv(const char *config_file, int argc, char *argv[])
{
	struct shttpd_ctx	*ctx;
	char			*tmpvars[NELEMS(options)];
	size_t			i;

	/* Initialize all temporary holders to NULL */
	for (i = 0; i < NELEMS(tmpvars); i++)
		tmpvars[i] = NULL;

	if ((ctx = malloc(sizeof(*ctx))) != NULL)
		initialize_context(ctx, config_file, argc, argv, tmpvars);

	return (ctx);
}

struct shttpd_ctx *
shttpd_init(const char *config_file, ...)
{
	struct shttpd_ctx	*ctx;
	va_list			ap;
	const char		*opt_name, *opt_value;
	char			*tmpvars[NELEMS(options)];
	const struct opt	*opt;
	size_t			i;

	elog(E_LOG, NULL, "Initializing http server");
	/* Initialize all temporary holders to NULL */
	for (i = 0; i < NELEMS(tmpvars); i++)
		tmpvars[i] = NULL;

	if ((ctx = malloc(sizeof(*ctx))) != NULL) {

		va_start(ap, config_file);
		while ((opt_name = va_arg(ap, const char *)) != NULL) {
			opt_value = va_arg(ap, const char *);

			if ((opt = find_option(0, opt_name)) == NULL)
				elog(E_FATAL, NULL, "shttpd_init: "
				    "unknown variable [%s]", opt_name);
			set_option(opt, opt_value, tmpvars);
		}
		va_end(ap);

		initialize_context(ctx, config_file, 0, NULL, tmpvars);
	}

	return (ctx);
}
