#include "restore.h"
#include <glob.h>

#ifndef GLOB_TILDE
#define GLOB_TILDE 0
#endif

#ifndef GLOB_BRACE
#define GLOB_BRACE 0
#endif

char **exclude_list;
int exclude_count;

void restore_init(struct restore_opts *opts)
{
	int rc;

	struct selinux_opt selinux_opts[] = {
		{ SELABEL_OPT_VALIDATE, opts->selabel_opt_validate },
		{ SELABEL_OPT_PATH, opts->selabel_opt_path },
		{ SELABEL_OPT_DIGEST, opts->selabel_opt_digest }
	};

	opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3);
	if (!opts->hnd) {
		perror(opts->selabel_opt_path);
		exit(1);
	}

	opts->restorecon_flags = 0;
	opts->restorecon_flags = opts->nochange | opts->verbose |
			   opts->progress | opts->set_specctx  |
			   opts->add_assoc | opts->ignore_digest |
			   opts->recurse | opts->userealpath |
			   opts->xdev | opts->abort_on_error |
			   opts->syslog_changes | opts->log_matches |
			   opts->ignore_noent | opts->ignore_mounts;

	/* Use setfiles, restorecon and restorecond own handles */
	selinux_restorecon_set_sehandle(opts->hnd);

	if (opts->rootpath) {
		rc = selinux_restorecon_set_alt_rootpath(opts->rootpath);
		if (rc) {
			fprintf(stderr,
				"selinux_restorecon_set_alt_rootpath error: %s.\n",
				strerror(errno));
			exit(-1);
		}
	}

	if (exclude_list)
		selinux_restorecon_set_exclude_list
						 ((const char **)exclude_list);
}

void restore_finish(void)
{
	int i;

	if (exclude_list) {
		for (i = 0; exclude_list[i]; i++)
			free(exclude_list[i]);
		free(exclude_list);
	}
}

int process_glob(char *name, struct restore_opts *opts)
{
	glob_t globbuf;
	size_t i = 0;
	int len, rc, errors;

	memset(&globbuf, 0, sizeof(globbuf));

	errors = glob(name, GLOB_TILDE | GLOB_PERIOD |
			  GLOB_NOCHECK | GLOB_BRACE, NULL, &globbuf);
	if (errors)
		return errors;

	for (i = 0; i < globbuf.gl_pathc; i++) {
		len = strlen(globbuf.gl_pathv[i]) - 2;
		if (len > 0 && strcmp(&globbuf.gl_pathv[i][len--], "/.") == 0)
			continue;
		if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0)
			continue;
		rc = selinux_restorecon(globbuf.gl_pathv[i],
					opts->restorecon_flags);
		if (rc < 0)
			errors = rc;
	}

	globfree(&globbuf);

	return errors;
}

void add_exclude(const char *directory)
{
	char **tmp_list;

	if (directory == NULL || directory[0] != '/') {
		fprintf(stderr, "Full path required for exclude: %s.\n",
			    directory);
		exit(-1);
	}

	/* Add another two entries, one for directory, and the other to
	 * terminate the list.
	 */
	tmp_list = realloc(exclude_list, sizeof(char *) * (exclude_count + 2));
	if (!tmp_list) {
		fprintf(stderr, "realloc failed while excluding %s.\n",
			    directory);
		exit(-1);
	}
	exclude_list = tmp_list;

	exclude_list[exclude_count] = strdup(directory);
	if (!exclude_list[exclude_count]) {
		fprintf(stderr, "strdup failed while excluding %s.\n",
			    directory);
		exit(-1);
	}
	exclude_count++;
	exclude_list[exclude_count] = NULL;
}
