/*  Copyright 1999,2001,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/>.
 *
 * Test program for doctoring the fat
 */


#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"
#include "fsP.h"

typedef struct Arg_t {
	char *target;
	MainParam_t mp;
	ClashHandling_t ch;
	Stream_t *sourcefile;
	uint32_t fat;
	int markbad;
	int setsize;
	uint32_t size;
	Fs_t *Fs;
} Arg_t;

static int dos_doctorfat(direntry_t *entry, MainParam_t *mp)
{
	Fs_t *Fs = getFs(mp->File);
	Arg_t *arg=(Arg_t *) mp->arg;

	if(!arg->markbad && entry->entry != -3) {
		/* if not root directory, change it */
		set_word(entry->dir.start, arg->fat & 0xffff);
		set_word(entry->dir.startHi, arg->fat >> 16);
		if(arg->setsize)
			set_dword(entry->dir.size, arg->size);
		dir_write(entry);
	}
	arg->Fs = Fs;
	return GOT_ONE;
}

static int unix_doctorfat(MainParam_t *mp UNUSEDP)
{
	fprintf(stderr,"File does not reside on a Dos fs\n");
	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: [-b] %s file fat\n", progname);
	exit(ret);
}

void mdoctorfat(int argc, char **argv, int mtype UNUSEDP) NORETURN;
void mdoctorfat(int argc, char **argv, int mtype UNUSEDP)
{
	Arg_t arg;
	int c, ret;
	unsigned int address;
	unsigned int begin, end;
	char *number, *eptr;
	int i;
	unsigned int offset;

	/* get command line options */

	init_clash_handling(& arg.ch);

	offset = 0;

	arg.markbad = 0;
	arg.setsize = 0;

	/* get command line options */
	if(helpFlag(argc, argv))
		usage(0);
	while ((c = getopt(argc, argv, "i:bo:s:h")) != EOF) {
		char *endptr = NULL;
		errno=0;
		switch (c) {
			case 'i':
				set_cmd_line_image(optarg);
				break;
			case 'b':
				arg.markbad = 1;
				break;
			case 'o':
				offset = strtoui(optarg,&endptr,0);
				break;
			case 's':
				arg.setsize=1;
				arg.size = strtou32(optarg,&endptr,0);
				break;
			case 'h':
				usage(0);
			case '?':
				usage(1);
		}
		check_number_parse_errno((char)c, optarg, endptr);
	}

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


	/* only 1 file to copy... */
	init_mp(&arg.mp);
	arg.mp.arg = (void *) &arg;

	arg.mp.callback = dos_doctorfat;
	arg.mp.unixcallback = unix_doctorfat;

	arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN;
	arg.mp.openflags = O_RDWR;
	arg.fat = strtoui(argv[optind+1], 0, 0) + offset;
	ret=main_loop(&arg.mp, argv + optind, 1);
	if(ret)
		exit(ret);
	address = 0;
	for(i=optind+1; i < argc; i++) {
		unsigned int j;
		number = argv[i];
		if (*number == '<') {
			number++;
		}
		begin = strtoui(number, &eptr, 0);
		if (eptr && *eptr == '-') {
			number = eptr+1;
			end = strtoui(number, &eptr, 0);
		} else {
			end = begin;
		}
		if (eptr == number) {
			fprintf(stderr, "Not a number: %s\n", number);
			exit(-1);
		}

		if (eptr && *eptr == '>') {
			eptr++;
		}
		if (eptr && *eptr) {
			fprintf(stderr, "Not a number: %s\n", eptr);
			exit(-1);
		}

		for (j=begin; j <= end; j++) {
			if(arg.markbad) {
				arg.Fs->fat_encode(arg.Fs, j+offset, arg.Fs->last_fat ^ 6 ^ 8);
			} else {
				if(address) {
					arg.Fs->fat_encode(arg.Fs, address, j+offset);
				}
				address = j+offset;
			}
		}
	}

	if (address && !arg.markbad) {
		arg.Fs->fat_encode(arg.Fs, address, arg.Fs->end_fat);
	}

	exit(ret);
}
