/*  Copyright 1998-2002,2009 Alain Knaff.
 *  This file is part of mtools.
 *
 *  Mtools is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Mtools 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 Mtools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "sysincludes.h"
#include "msdos.h"
#include "stream.h"
#include "mtools.h"
#include "file.h"
#include "htable.h"
#include "mainloop.h"
#include <dirent.h>

typedef struct Dir_t {
	struct Stream_t head;

	struct MT_STAT statbuf;
	char *pathname;
	DIR *dir;
#ifdef HAVE_FCHDIR
	int fd;
#endif
} Dir_t;

/*#define FCHDIR_MODE*/

static int get_dir_data(Stream_t *Stream, time_t *date, mt_off_t *size,
			int *type, unsigned int *address)
{
	DeclareThis(Dir_t);

	if(date)
		*date = This->statbuf.st_mtime;
	if(size)
		*size = This->statbuf.st_size;
	if(type)
		*type = 1;
	if(address)
		*address = 0;
	return 0;
}

static int dir_free(Stream_t *Stream)
{
	DeclareThis(Dir_t);

	Free(This->pathname);
	closedir(This->dir);
	return 0;
}

static Class_t DirClass = {
	0, /* read */
	0, /* write */
	0, /* pread */
	0, /* pwrite */
	0, /* flush */
	dir_free, /* free */
	0, /* get_geom */
	get_dir_data ,
	0, /* pre-allocate */
	0, /* get_dosConvert */
	0 /* discard */
};

#ifdef HAVE_FCHDIR
#define FCHDIR_MODE
#endif

int unix_dir_loop(Stream_t *Stream, MainParam_t *mp);
int unix_loop(Stream_t *Stream, MainParam_t *mp, char *arg,
	      int follow_dir_link);

int unix_dir_loop(Stream_t *Stream, MainParam_t *mp)
{
	DeclareThis(Dir_t);
	struct dirent *entry;
	char *newName;
	int ret=0;

#ifdef FCHDIR_MODE
	int fd;

	fd = open(".", O_RDONLY);
	if(chdir(This->pathname) < 0) {
		fprintf(stderr, "Could not chdir into %s (%s)\n",
			This->pathname, strerror(errno));
		return -1;
	}
#endif
	while((entry=readdir(This->dir)) != NULL) {
		if(got_signal)
			break;
		if(isSpecial(entry->d_name))
			continue;
#ifndef FCHDIR_MODE
		newName = malloc(strlen(This->pathname) + 1 +
				 strlen(entry->d_name) + 1);
		if(!newName) {
			ret = ERROR_ONE;
			break;
		}
		strcpy(newName, This->pathname);
		strcat(newName, "/");
		strcat(newName, entry->d_name);
#else
		newName = entry->d_name;
#endif
		ret |= unix_loop(Stream, mp, newName, 0);
#ifndef FCHDIR_MODE
		free(newName);
#endif
	}
#ifdef FCHDIR_MODE
	if(fchdir(fd) < 0)
		perror("Could not chdir back to ..");
	close(fd);
#endif
	return ret;
}

Stream_t *OpenDir(const char *filename)
{
	Dir_t *This;

	This = New(Dir_t);
	init_head(&This->head, &DirClass, NULL);
	This->pathname = malloc(strlen(filename)+1);
	if(This->pathname == NULL) {
		Free(This);
		return NULL;
	}
	strcpy(This->pathname, filename);

	if(MT_STAT(filename, &This->statbuf) < 0) {
		Free(This->pathname);
		Free(This);
		return NULL;
	}

	This->dir = opendir(filename);
	if(!This->dir) {
		Free(This->pathname);
		Free(This);
		return NULL;
	}

	return &This->head;
}
