/*  Copyright 1986-1992 Emmet P. Gray.
 *  Copyright 1996-2002,2005,2008,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/>.
 *
 * mdel.c
 * Delete an MSDOS file
 *
 */

#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "stream.h"
#include "mainloop.h"
#include "fs.h"
#include "file.h"
#include "file_name.h"

typedef struct Arg_t {
	int deltype;
	int verbose;
} Arg_t;

/**
 * Wiped the given entry
 */
void wipeEntry(direntry_t *entry)
{
	direntry_t longNameEntry;
	int i;
	initializeDirentry(&longNameEntry, entry->Dir);
	for(i=entry->beginSlot; i< entry->endSlot; i++) {
	    int error;
	    longNameEntry.entry=i;
	    dir_read(&longNameEntry, &error);
	    if(error)
		break;
	    longNameEntry.dir.name[0] = (char) DELMARK;
	    dir_write(&longNameEntry);
	}
	entry->dir.name[0] = (char) DELMARK;
	dir_write(entry);
}

static int del_entry(direntry_t *entry, MainParam_t *mp)
{
	Arg_t *arg=(Arg_t *) mp->arg;

	if(got_signal)
		return ERROR_ONE;

	if(entry->entry == -3) {
		fprintf(stderr, "Cannot remove root directory\n");
		return ERROR_ONE;
	}

	if (arg->verbose) {
		fprintf(stderr,"Removing ");
		fprintPwd(stderr, entry,0);
		fputc('\n', stderr);
	}

	if (entry->dir.attr & (ATTR_READONLY | ATTR_SYSTEM)) {
		char tmp[4*MAX_VNAMELEN+1];
		WCHAR_TO_NATIVE(entry->name,tmp,MAX_VNAMELEN);
		if (ask_confirmation("%s: \"%s\" is read only, erase anyway (y/n) ? ",
				     progname, tmp))
			return ERROR_ONE;
	}
	if (fatFreeWithDirentry(entry))
		return ERROR_ONE;

	wipeEntry(entry);
	return GOT_ONE;
}

static int del_file(direntry_t *entry, MainParam_t *mp)
{
	char shortname[13];
	direntry_t subEntry;
	Stream_t *SubDir;
	Arg_t *arg = (Arg_t *) mp->arg;
	MainParam_t sonmp;
	int ret;
	int r;

	sonmp = *mp;
	sonmp.arg = mp->arg;

	r = 0;
	if (IS_DIR(entry)){
		/* a directory */
		SubDir = OpenFileByDirentry(entry);
		initializeDirentry(&subEntry, SubDir);
		ret = 0;
		while((r=vfat_lookup(&subEntry, "*", 1,
				     ACCEPT_DIR | ACCEPT_PLAIN,
				     shortname, sizeof(shortname),
				     NULL, 0)) == 0 ){
			if(shortname[0] != DELMARK &&
			   shortname[0] &&
			   shortname[0] != '.' ){
				if(arg->deltype != 2){
					fprintf(stderr,
						"Directory ");
					fprintPwd(stderr, entry,0);
					fprintf(stderr," non empty\n");
					ret = ERROR_ONE;
					break;
				}
				if(got_signal) {
					ret = ERROR_ONE;
					break;
				}
				ret = del_file(&subEntry, &sonmp);
				if( ret & ERROR_ONE)
					break;
				ret = 0;
			}
		}
		FREE(&SubDir);
		if (r == -2)
			return ERROR_ONE;
		if(ret)
			return ret;
	}
	return del_entry(entry, mp);
}

static void usage(int ret) NORETURN;
static void usage(int ret)
{
	fprintf(stderr,
		"Mtools version %s, dated %s\n", mversion, mdate);
	fprintf(stderr,
		"Usage: %s [-v] msdosfile [msdosfiles...]\n", progname);
	exit(ret);
}

void mdel(int argc, char **argv, int deltype) NORETURN;
void mdel(int argc, char **argv, int deltype)
{
	Arg_t arg;
	MainParam_t mp;
	int c,i;

	arg.verbose = 0;
	if(helpFlag(argc, argv))
		usage(0);
	while ((c = getopt(argc, argv, "i:vh")) != EOF) {
		switch (c) {
			case 'i':
				set_cmd_line_image(optarg);
				break;
			case 'v':
				arg.verbose = 1;
				break;
			case 'h':
				usage(0);
			default:
				usage(1);
		}
	}

	if(argc == optind)
		usage(1);

	init_mp(&mp);
	mp.callback = del_file;
	mp.arg = (void *) &arg;
	mp.openflags = O_RDWR;
	arg.deltype = deltype;
	switch(deltype){
	case 0:
		mp.lookupflags = ACCEPT_PLAIN; /* mdel */
		break;
	case 1:
		mp.lookupflags = ACCEPT_DIR; /* mrd */
		break;
	case 2:
		mp.lookupflags = ACCEPT_DIR | ACCEPT_PLAIN; /* mdeltree */
		break;
	}
	mp.lookupflags |= NO_DOTS;
	for(i=optind;i<argc;i++) {
		size_t b, l;
		if(argv[i][0] && argv[i][1] == ':')
			b = 2;
		else
			b = 0;
		l = strlen(argv[i]+b);
		if(l > 1 && argv[i][b+l-1] == '/')
			argv[i][b+l-1] = '\0';
	}

	exit(main_loop(&mp, argv + optind, argc - optind));
}
