/*
**  Copyright 1998-2003 University of Illinois Board of Trustees
**  Copyright 1998-2003 Mark D. Roth
**  All rights reserved.
**
**  wrapper.c - libtar high-level wrapper code
**
**  Mark D. Roth <roth@uiuc.edu>
**  Campus Information Technologies and Educational Services
**  University of Illinois at Urbana-Champaign
*/

#define DEBUG
#include <internal.h>

#include <stdio.h>
#include <sys/param.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif

int
tar_extract_glob(TAR *t, char *globname, char *prefix)
{
	char *filename;
	char buf[MAXPATHLEN];
	int i;

	while ((i = th_read(t)) == 0)
	{
		filename = th_get_pathname(t);
		if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
		{
			if (TH_ISREG(t) && tar_skip_regfile(t))
				return -1;
			continue;
		}
		if (t->options & TAR_VERBOSE)
			th_print_long_ls(t);
		if (prefix != NULL)
			snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
		else
			strlcpy(buf, filename, sizeof(buf));
		if (tar_extract_file(t, filename, prefix) != 0)
			return -1;
	}

	return (i == 1 ? 0 : -1);
}


int
tar_extract_all(TAR *t, char *prefix)
{
	char *filename;
	char buf[MAXPATHLEN];
	int i;
	printf("prefix: %s\n", prefix);
#ifdef DEBUG
	printf("==> tar_extract_all(TAR *t, \"%s\")\n",
	       (prefix ? prefix : "(null)"));
#endif
	while ((i = th_read(t)) == 0)
	{
#ifdef DEBUG
		puts("    tar_extract_all(): calling th_get_pathname()");
#endif
		filename = th_get_pathname(t);
		if (t->options & TAR_VERBOSE)
			th_print_long_ls(t);
		if (prefix != NULL)
			snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
		else
			strlcpy(buf, filename, sizeof(buf));
#ifdef DEBUG
		printf("    tar_extract_all(): calling tar_extract_file(t, "
		       "\"%s\")\n", buf);
#endif
		printf("item name: '%s'\n", filename);
		/*
		if (strcmp(filename, "/") == 0) {
			printf("skipping /\n");
			continue;
		}
		*/
		if (tar_extract_file(t, buf, prefix) != 0)
			return -1;
	}
	return (i == 1 ? 0 : -1);
}


int
tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude)
{
#ifdef DEBUG
	printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
	       (long unsigned int)t, realdir, (savedir ? savedir : "[NULL]"));
#endif

	char temp[1024];
	int skip = 0, i, n_spaces = 0;
	char ** excluded = NULL;
	char * p = NULL;
	if (exclude) {
		strcpy(temp, exclude);
		p = strtok(exclude, " ");
		if (p == NULL) {
			excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
			excluded[0] = temp;
		} else {
			while (p) {
				excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
				excluded[n_spaces-1] = p;
				p = strtok(NULL, " ");
			}
		}
		excluded = realloc(excluded, sizeof(char*) * (n_spaces+1));
		excluded[n_spaces] = 0;
		for (i = 0; i < (n_spaces+1); i++) {
			if (realdir == excluded[i]) {
				printf("    excluding '%s'\n", excluded[i]);
				skip = 1;
				break;
			}
		}
	}
	if (skip == 0) {
		if (tar_append_file(t, realdir, savedir) != 0)
			return -1;
	}

	char realpath[MAXPATHLEN];
	char savepath[MAXPATHLEN];
	struct dirent *dent;
	DIR *dp;
	struct stat s;

	dp = opendir(realdir);
	if (dp == NULL) {
		if (errno == ENOTDIR)
			return 0;
		return -1;
	}
	while ((dent = readdir(dp)) != NULL) {
		if(strcmp(dent->d_name, ".") == 0
		|| strcmp(dent->d_name, "..") == 0)
			continue;

		if (exclude) {
			int omit = 0;
			for (i = 0; i < (n_spaces+1); i++) {
				if (dent->d_name == excluded[i]) {
					printf("    excluding '%s'\n", excluded[i]);
					omit = 1;
					break;
				}
			}
			if (omit)
				continue;
		}

		snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, dent->d_name);
		if (savedir)
			snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, dent->d_name);

		if (lstat(realpath, &s) != 0)
			return -1;

		if (S_ISDIR(s.st_mode)) {
			if (tar_append_tree(t, realpath, (savedir ? savepath : NULL), (exclude ? exclude : NULL)) != 0)
				return -1;
			continue;
		} else {
			if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0)
				return -1;
			continue;
		}
	}	
	closedir(dp);
	free(excluded);

	return 0;
}


int
tar_find(TAR *t, char *searchstr)
{
	if (!searchstr)
		return 0;

	char *filename;
	int i, entryfound = 0;
#ifdef DEBUG
	printf("==> tar_find(0x%lx, %s)\n", (long unsigned int)t, searchstr);
#endif
	while ((i = th_read(t)) == 0) {
		filename = th_get_pathname(t);
		if (fnmatch(searchstr, filename, FNM_FILE_NAME | FNM_PERIOD) == 0) {
			entryfound++;
#ifdef DEBUG
			printf("Found matching entry: %s\n", filename);
#endif
			break;
		}
	}
#ifdef DEBUG
	if (!entryfound)
		printf("No matching entry found.\n");
#endif

	return entryfound;
}
