/*  Copyright 1996-1998,2000-2002,2005,2007-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/>.
 *
 * mmove.c
 * Renames/moves an MSDOS file
 *
 */


#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "vfat.h"
#include "mainloop.h"
#include "plain_io.h"
#include "nameclash.h"
#include "file.h"
#include "fs.h"

/*
 * Preserve the file modification times after the fclose()
 */

typedef struct Arg_t {
	const char *fromname;
	int verbose;
	MainParam_t mp;

	direntry_t *entry;
	ClashHandling_t ch;
} Arg_t;


/*
 * Open the named file for read, create the cluster chain, return the
 * directory structure or NULL on error.
 */
static int renameit(dos_name_t *dosname,
		    char *longname UNUSEDP,
		    void *arg0,
		    direntry_t *targetEntry)
{
	Arg_t *arg = (Arg_t *) arg0;
	uint32_t fat;

	targetEntry->dir = arg->entry->dir;
	dosnameToDirentry(dosname, &targetEntry->dir);

	if(IS_DIR(targetEntry)) {
		direntry_t *movedEntry;

		/* get old direntry. It is important that we do this
		 * on the actual direntry which is stored in the file,
		 * and not on a copy, because we will modify it, and the
		 * modification should be visible at file
		 * de-allocation time */
		movedEntry = getDirentry(arg->mp.File);
		if(movedEntry->Dir != targetEntry->Dir) {
			/* we are indeed moving it to a new directory */
			direntry_t subEntry;
			Stream_t *oldDir;
			/* we have a directory here. Change its parent link */

			initializeDirentry(&subEntry, arg->mp.File);

			switch(vfat_lookup(&subEntry, "..", 2, ACCEPT_DIR,
					   NULL, 0, NULL, 0)) {
			    case -1:
				fprintf(stderr,
					" Directory has no parent entry\n");
				break;
			    case -2:
				return ERROR_ONE;
			    case 0:
				GET_DATA(targetEntry->Dir, 0, 0, 0, &fat);
				if (fat == fat32RootCluster(targetEntry->Dir)) {
				    fat = 0;
				}

				subEntry.dir.start[1] = (fat >> 8) & 0xff;
				subEntry.dir.start[0] = fat & 0xff;
				dir_write(&subEntry);
				if(arg->verbose){
					fprintf(stderr,
						"Easy, isn't it? I wonder why DOS can't do this.\n");
				}
				break;
			}

			wipeEntry(movedEntry);

			/* free the old parent, allocate the new one. */
			oldDir = movedEntry->Dir;
			*movedEntry = *targetEntry;
			COPY(targetEntry->Dir);
			FREE(&oldDir);
			return 0;
		}
	}

	/* wipe out original entry */
	wipeEntry(arg->mp.direntry);
	return 0;
}



static int rename_file(direntry_t *entry, MainParam_t *mp)
/* rename a messy DOS file to another messy DOS file */
{
	int result;
	Stream_t *targetDir;
	char *shortname;
	const char *longname;

	Arg_t * arg = (Arg_t *) (mp->arg);

	arg->entry = entry;
	targetDir = mp->targetDir;

	if (targetDir == entry->Dir){
		arg->ch.ignore_entry = -1;
		arg->ch.source = entry->entry;
		arg->ch.source_entry = entry->entry;
	} else {
		arg->ch.ignore_entry = -1;
		arg->ch.source = -2;
	}

	longname = mpPickTargetName(mp);
	shortname = 0;
	result = mwrite_one(targetDir, longname, shortname,
			    renameit, (void *)arg, &arg->ch);
	if(result == 1)
		return GOT_ONE;
	else
		return ERROR_ONE;
}


static int rename_directory(direntry_t *entry, MainParam_t *mp)
{
	int ret;

	/* moves a DOS dir */
	if(isSubdirOf(mp->targetDir, mp->File)) {
		fprintf(stderr, "Cannot move directory ");
		fprintPwd(stderr, entry,0);
		fprintf(stderr, " into one of its own subdirectories (");
		fprintPwd(stderr, getDirentry(mp->targetDir),0);
		fprintf(stderr, ")\n");
		return ERROR_ONE;
	}

	if(entry->entry == -3) {
		fprintf(stderr, "Cannot move a root directory: ");
		fprintPwd(stderr, entry,0);
		return ERROR_ONE;
	}

	ret = rename_file(entry, mp);
	if(ret & ERROR_ONE)
		return ret;

	return ret;
}

static int rename_oldsyntax(direntry_t *entry, MainParam_t *mp)
{
	int result;
	Stream_t *targetDir;
	const char *shortname, *longname;

	Arg_t * arg = (Arg_t *) (mp->arg);
	arg->entry = entry;
	targetDir = entry->Dir;

	arg->ch.ignore_entry = -1;
	arg->ch.source = entry->entry;
	arg->ch.source_entry = entry->entry;

#if 0
	if(!strcasecmp(mp->shortname, arg->fromname)){
		longname = mp->longname;
		shortname = mp->targetName;
	} else {
#endif
		longname = mp->targetName;
		shortname = 0;
#if 0
	}
#endif
	result = mwrite_one(targetDir, longname, shortname,
			    renameit, (void *)arg, &arg->ch);
	if(result == 1)
		return GOT_ONE;
	else
		return ERROR_ONE;
}


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 [-vV] [-D clash_option] file targetfile\n", progname);
	fprintf(stderr,
		"       %s [-vV] [-D clash_option] file [files...] target_directory\n",
		progname);
	exit(ret);
}

void mmove(int argc, char **argv, int oldsyntax) NORETURN;
void mmove(int argc, char **argv, int oldsyntax)
{
	Arg_t arg;
	int c;
	char shortname[12*4+1];
	char longname[4*MAX_VNAMELEN+1];
	char def_drive;
	int i;

	/* get command line options */

	init_clash_handling(& arg.ch);

	/* get command line options */
	arg.verbose = 0;
	if(helpFlag(argc, argv))
		usage(0);
	while ((c = getopt(argc, argv, "i:vD:oh")) != EOF) {
		switch (c) {
			case 'i':
				set_cmd_line_image(optarg);
				break;
			case 'v':	/* dummy option for mcopy */
				arg.verbose = 1;
				break;
			case 'o':
				handle_clash_options(&arg.ch, (char)c);
				break;
			case 'D':
				if(handle_clash_options(&arg.ch, *optarg))
					usage(1);
				break;
			case 'h':
				usage(0);
			case '?':
				usage(1);
			default:
				break;
		}
	}

	if (argc - optind < 2)
		usage(1);

	init_mp(&arg.mp);
	arg.mp.arg = (void *) &arg;
	arg.mp.openflags = O_RDWR;

	/* look for a default drive */
	def_drive = '\0';
	for(i=optind; i<argc; i++)
		if(argv[i][0] && argv[i][1] == ':' ){
			if(!def_drive)
				def_drive = ch_toupper(argv[i][0]);
			else if(def_drive != ch_toupper(argv[i][0])){
				fprintf(stderr,
					"Cannot move files across different drives\n");
				exit(1);
			}
		}

	if(def_drive)
		*(arg.mp.mcwd) = def_drive;

	if (oldsyntax && (argc - optind != 2 || strpbrk(":/", argv[argc-1])))
		oldsyntax = 0;

	arg.mp.lookupflags =
	  ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN_DIRS | NO_DOTS | NO_UNIX;

	if (!oldsyntax){
		target_lookup(&arg.mp, argv[argc-1]);
		arg.mp.callback = rename_file;
		arg.mp.dirCallback = rename_directory;
	} else {
		/* do not look up the target; it will be the same dir as the
		 * source */
		arg.fromname = argv[optind];
		if(arg.fromname[0] && arg.fromname[1] == ':')
			arg.fromname += 2;
		arg.fromname = _basename(arg.fromname);
		arg.mp.targetName = strdup(argv[argc-1]);
		arg.mp.callback = rename_oldsyntax;
	}


	arg.mp.longname.data = longname;
	arg.mp.longname.len = sizeof(longname);
	longname[0]='\0';

	arg.mp.shortname.data = shortname;
	arg.mp.shortname.len = sizeof(shortname);
	shortname[0]='\0';

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