/* Copyright (C) 2005 Red Hat, Inc. */

#include <stdio.h>
#include <stdio_ext.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <semanage/handle.h>
#include "parse_utils.h"
#include "debug.h"

int parse_init(semanage_handle_t * handle,
	       const char *filename, void *parse_arg, parse_info_t ** info)
{

	parse_info_t *tmp_info = (parse_info_t *) malloc(sizeof(parse_info_t));

	if (!tmp_info) {
		ERR(handle,
		    "out of memory, could not allocate parse structure");
		return STATUS_ERR;
	}

	tmp_info->filename = filename;
	tmp_info->file_stream = NULL;
	tmp_info->working_copy = NULL;
	tmp_info->orig_line = NULL;
	tmp_info->ptr = NULL;
	tmp_info->lineno = 0;
	tmp_info->parse_arg = parse_arg;

	*info = tmp_info;
	return STATUS_SUCCESS;
}

void parse_release(parse_info_t * info)
{

	parse_close(info);
	parse_dispose_line(info);
	free(info);
}

int parse_open(semanage_handle_t * handle, parse_info_t * info)
{

	info->file_stream = fopen(info->filename, "r");
	if (!info->file_stream && (errno != ENOENT)) {
		ERR(handle, "could not open file %s: %s",
		    info->filename, strerror(errno));
		return STATUS_ERR;
	}
	if (info->file_stream)
		__fsetlocking(info->file_stream, FSETLOCKING_BYCALLER);

	return STATUS_SUCCESS;
}

void parse_close(parse_info_t * info)
{

	if (info->file_stream)
		fclose(info->file_stream);
	info->file_stream = NULL;
}

void parse_dispose_line(parse_info_t * info)
{
	if (info->orig_line) {
		free(info->orig_line);
		info->orig_line = NULL;
	}

	if (info->working_copy) {
		free(info->working_copy);
		info->working_copy = NULL;
	}

	info->ptr = NULL;
}

int parse_skip_space(semanage_handle_t * handle, parse_info_t * info)
{

	size_t buf_len = 0;
	ssize_t len;
	int lineno = info->lineno;
	char *buffer = NULL;
	char *ptr;

	if (info->ptr) {
		while (*(info->ptr) && isspace(*(info->ptr)))
			info->ptr++;

		if (*(info->ptr))
			return STATUS_SUCCESS;
	}

	parse_dispose_line(info);

	while (info->file_stream &&
	       ((len = getline(&buffer, &buf_len, info->file_stream)) > 0)) {

		lineno++;

		/* Eat newline, preceding whitespace */
		if (buffer[len - 1] == '\n')
			buffer[len - 1] = '\0';

		ptr = buffer;
		while (*ptr && isspace(*ptr))
			ptr++;

		/* Skip comments and blank lines */
		if ((*ptr) && *ptr != '#') {
			char *tmp = strdup(buffer);
			if (!tmp)
				goto omem;

			info->lineno = lineno;
			info->working_copy = buffer;
			info->orig_line = tmp;
			info->ptr = ptr;

			return STATUS_SUCCESS;
		}
	}

	free(buffer);
	buffer = NULL;

	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory, could not allocate buffer");
	free(buffer);
	return STATUS_ERR;
}

int parse_assert_noeof(semanage_handle_t * handle, parse_info_t * info)
{

	if (!info->ptr) {
		ERR(handle, "unexpected end of file (%s: %u)",
		    info->filename, info->lineno);
		return STATUS_ERR;
	}

	return STATUS_SUCCESS;
}

int parse_assert_space(semanage_handle_t * handle, parse_info_t * info)
{

	if (parse_assert_noeof(handle, info) < 0)
		return STATUS_ERR;

	if (*(info->ptr) && !isspace(*(info->ptr))) {
		ERR(handle, "missing whitespace (%s: %u):\n%s",
		    info->filename, info->lineno, info->orig_line);
		return STATUS_ERR;
	}

	if (parse_skip_space(handle, info) < 0)
		return STATUS_ERR;

	return STATUS_SUCCESS;
}

int parse_assert_ch(semanage_handle_t * handle,
		    parse_info_t * info, const char ch)
{

	if (parse_assert_noeof(handle, info) < 0)
		return STATUS_ERR;

	if (*(info->ptr) != ch) {
		ERR(handle, "expected character \'%c\', but found \'%c\' "
		    "(%s: %u):\n%s", ch, *(info->ptr), info->filename,
		    info->lineno, info->orig_line);
		return STATUS_ERR;
	}

	info->ptr++;

	return STATUS_SUCCESS;
}

int parse_assert_str(semanage_handle_t * handle,
		     parse_info_t * info, const char *assert_str)
{

	size_t len = strlen(assert_str);

	if (parse_assert_noeof(handle, info) < 0)
		return STATUS_ERR;

	if (strncmp(info->ptr, assert_str, len)) {
		ERR(handle, "experted string \"%s\", but found \"%s\" "
		    "(%s: %u):\n%s", assert_str, info->ptr,
		    info->filename, info->lineno, info->orig_line);

		return STATUS_ERR;
	}

	info->ptr += len;
	return STATUS_SUCCESS;
}

int parse_optional_ch(parse_info_t * info, const char ch)
{

	if (!info->ptr)
		return STATUS_NODATA;
	if (*(info->ptr) != ch)
		return STATUS_NODATA;

	info->ptr++;
	return STATUS_SUCCESS;
}

int parse_optional_str(parse_info_t * info, const char *str)
{
	size_t len = strlen(str);

	if (strncmp(info->ptr, str, len))
		return STATUS_NODATA;

	info->ptr += len;
	return STATUS_SUCCESS;
}

int parse_fetch_int(semanage_handle_t * handle,
		    parse_info_t * info, int *num, char delim)
{

	char *str = NULL;
	char *test = NULL;
	int value = 0;

	if (parse_fetch_string(handle, info, &str, delim) < 0)
		goto err;

	if (!isdigit((int)*str)) {
		ERR(handle, "expected a numeric value: (%s: %u)\n%s",
		    info->filename, info->lineno, info->orig_line);
		goto err;
	}

	value = strtol(str, &test, 10);
	if (*test != '\0') {
		ERR(handle, "could not parse numeric value \"%s\": "
		    "(%s: %u)\n%s", str, info->filename,
		    info->lineno, info->orig_line);
		goto err;
	}

	*num = value;
	free(str);
	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not fetch numeric value");
	free(str);
	return STATUS_ERR;
}

int parse_fetch_string(semanage_handle_t * handle,
		       parse_info_t * info, char **str, char delim)
{

	char *start = info->ptr;
	int len = 0;
	char *tmp_str = NULL;

	if (parse_assert_noeof(handle, info) < 0)
		goto err;

	while (*(info->ptr) && !isspace(*(info->ptr)) &&
	       (*(info->ptr) != delim)) {
		info->ptr++;
		len++;
	}

	if (len == 0) {
		ERR(handle, "expected non-empty string, but did not "
		    "find one (%s: %u):\n%s", info->filename, info->lineno,
		    info->orig_line);
		goto err;
	}

	tmp_str = (char *)malloc(len + 1);
	if (!tmp_str) {
		ERR(handle, "out of memory");
		goto err;
	}

	strncpy(tmp_str, start, len);
	*(tmp_str + len) = '\0';
	*str = tmp_str;
	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not fetch string value");
	return STATUS_ERR;
}
