/*  Copyright 1986-1992 Emmet P. Gray.
 *  Copyright 1994,1996-2002,2007-2009,2021 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/>.
 *
 * mcopy.c
 * Copy an MSDOS files to and from Unix
 *
 */


#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()
 */

static void set_mtime(const char *target, time_t mtime)
{
	if (target && strcmp(target, "-") && mtime != 0L) {
#ifdef HAVE_UTIMES
		struct timeval tv[2];
		tv[0].tv_sec = mtime;
		tv[0].tv_usec = 0;
		tv[1].tv_sec = mtime;
		tv[1].tv_usec = 0;
		utimes(target, tv);
#else
#ifdef HAVE_UTIME
		struct utimbuf utbuf;

		utbuf.actime = mtime;
		utbuf.modtime = mtime;
		utime(target, &utbuf);
#endif
#endif
	}
	return;
}

typedef struct Arg_t {
	int recursive;
	int preserveAttributes;
	int preserveTime;
	unsigned char attr;
	char *path;
	int textmode;
	int needfilter;
	int nowarn;
	int verbose;
	int type;
	int convertCharset;
	MainParam_t mp;
	ClashHandling_t ch;
	int noClobber;
} Arg_t;

static int _unix_write(MainParam_t *mp, int needfilter, const char *unixFile);

/* Write the Unix file */
static int unix_write(MainParam_t *mp, int needfilter)
{
	Arg_t *arg=(Arg_t *) mp->arg;

	if(arg->type)
		return _unix_write(mp, needfilter, "-");
	else {
		char *unixFile = mpBuildUnixFilename(mp);
		int ret;
		if(!unixFile) {
			printOom();
			return ERROR_ONE;
		}
		ret = _unix_write(mp, needfilter, unixFile);
		free(unixFile);
		return ret;
	}
}


/* Write the Unix file */
static int _unix_write(MainParam_t *mp, int needfilter, const char *unixFile)
{
	Arg_t *arg=(Arg_t *) mp->arg;
	time_t mtime;
	Stream_t *File=mp->File;
	Stream_t *Target, *Source;
	struct MT_STAT stbuf;
	char errmsg[80];

	File->Class->get_data(File, &mtime, 0, 0, 0);

	if (!arg->preserveTime)
		mtime = 0L;

	/* if we are creating a file, check whether it already exists */
	if(!arg->type) {
		if (!arg->nowarn && !access(unixFile, 0)){
			if(arg->noClobber) {
				fprintf(stderr, "File \"%s\" exists. To overwrite, try again, and explicitly specify target directory\n",unixFile);
				return ERROR_ONE;
			}

			/* sanity checking */
			if (!MT_STAT(unixFile, &stbuf)) {
				struct MT_STAT srcStbuf;
				int sFd; /* Source file descriptor */
				if(!S_ISREG(stbuf.st_mode)) {
					fprintf(stderr,"\"%s\" is not a regular file\n",
						unixFile);

					return ERROR_ONE;
				}
				sFd = get_fd(File);
				if(sFd == -1) {
				} else if((!MT_FSTAT(sFd, &srcStbuf)) &&
					   stbuf.st_dev == srcStbuf.st_dev &&
					   stbuf.st_ino == srcStbuf.st_ino) {
					fprintf(stderr, "Attempt to copy file on itself\n");
					return ERROR_ONE;
				}
			}

			if( ask_confirmation("File \"%s\" exists, overwrite (y/n) ? ",
					     unixFile)) {
				return ERROR_ONE;
			}

		}
	}

	if(!arg->type && arg->verbose) {
		fprintf(stderr,"Copying ");
		mpPrintFilename(stderr,mp);
		fprintf(stderr,"\n");
	}

	if(got_signal) {
		return ERROR_ONE;
	}

	if ((Target = SimpleFileOpen(0, 0, unixFile,
				     O_WRONLY | O_CREAT | O_TRUNC,
				     errmsg, 0, 0, 0))) {
		mt_off_t ret;
		Source = COPY(File);
		if(needfilter && arg->textmode)
			Source = open_dos2unix(Source,arg->convertCharset);

		if (Source)
			ret = copyfile(Source, Target);
		else
			ret = -1;
		FREE(&Source);
		FREE(&Target);
		if(ret < 0){
			if(!arg->type)
				unlink(unixFile);
			return ERROR_ONE;
		}
		if(!arg->type)
			set_mtime(unixFile, mtime);
		return GOT_ONE;
	} else {
		fprintf(stderr,"%s\n", errmsg);
		return ERROR_ONE;
	}
}

static int makeUnixDir(char *filename)
{
	if(!mkdir(filename
#ifndef OS_mingw32msvc
	          , 0777
#endif
	         ))
		return 0;
	if(errno == EEXIST) {
		struct MT_STAT buf;
		if(MT_STAT(filename, &buf) < 0)
			return -1;
		if(S_ISDIR(buf.st_mode))
			return 0;
		errno = ENOTDIR;
	}
	return -1;
}

/* Copy a directory to Unix */
static int unix_copydir(direntry_t *entry, MainParam_t *mp)
{
	Arg_t *arg=(Arg_t *) mp->arg;
	time_t mtime;
	Stream_t *File=mp->File;
	int ret;
	char *unixFile;

	if (!arg->recursive && mp->basenameHasWildcard)
		return 0;

	File->Class->get_data(File, &mtime, 0, 0, 0);
	if (!arg->preserveTime)
		mtime = 0L;
	if(!arg->type && arg->verbose) {
		fprintf(stderr,"Copying ");
		fprintPwd(stderr, entry,0);
		fprintf(stderr, "\n");
	}
	if(got_signal)
		return ERROR_ONE;
	unixFile = mpBuildUnixFilename(mp);
	if(!unixFile) {
		printOom();
		return ERROR_ONE;
	}
	if(arg->type || !*mpPickTargetName(mp) || !makeUnixDir(unixFile)) {
		Arg_t newArg;

		newArg = *arg;
		newArg.mp.arg = (void *) &newArg;
		newArg.mp.unixTarget = unixFile;
		newArg.mp.targetName = 0;
		newArg.mp.basenameHasWildcard = 1;

		ret = mp->loop(File, &newArg.mp, "*");
		set_mtime(unixFile, mtime);
		free(unixFile);
		return ret | GOT_ONE;
	} else {
		perror("mkdir");
		fprintf(stderr,
			"Failure to make directory %s\n",
			unixFile);
		free(unixFile);
		return ERROR_ONE;
	}
}

static  int dos_to_unix(direntry_t *entry UNUSEDP, MainParam_t *mp)
{
	return unix_write(mp, 1);
}


static  int unix_to_unix(MainParam_t *mp)
{
	return unix_write(mp, 0);
}


static int directory_dos_to_unix(direntry_t *entry, MainParam_t *mp)
{
	return unix_copydir(entry, mp);
}

/*
 * Open the named file for read, create the cluster chain, return the
 * directory structure or NULL on error.
 */
static int writeit(struct dos_name_t *dosname,
		   char *longname,
		   void *arg0,
		   direntry_t *entry)
{
	Stream_t *Target;
	time_t now;
	int type;
	mt_off_t ret;
	uint32_t fat;
	time_t date;
	mt_off_t filesize;
	Arg_t *arg = (Arg_t *) arg0;
	Stream_t *Source = COPY(arg->mp.File);

	if (Source->Class->get_data(Source, &date, &filesize,
				    &type, 0) < 0 ){
		fprintf(stderr, "Can't stat source file\n");
		return -1;
	}

	if(fileTooBig(filesize)) {
		fprintf(stderr, "File \"%s\" too big\n", longname);
		return 1;
	}

	if (type){
		if (arg->verbose)
			fprintf(stderr, "\"%s\" is a directory\n", longname);
		return -1;
	}

	/*if (!arg->single || arg->recursive)*/
	if(arg->verbose)
		fprintf(stderr,"Copying %s\n", longname);
	if(got_signal)
		return -1;

	/* will it fit? */
	if (!getfreeMinBytes(arg->mp.targetDir, filesize))
		return -1;

	/* preserve mod time? */
	if (arg->preserveTime)
		now = date;
	else
		getTimeNow(&now);

	mk_entry(dosname, arg->attr, 1, 0, now, &entry->dir);

	Target = OpenFileByDirentry(entry);
	if(!Target){
		fprintf(stderr,"Could not open Target\n");
		exit(1);
	}
	if (arg->needfilter & arg->textmode) {
		Source = open_unix2dos(Source,arg->convertCharset);
	}
		
	ret = copyfile(Source, Target);
	GET_DATA(Target, 0, 0, 0, &fat);
	FREE(&Source);
	FREE(&Target);
	if(ret < 0 ){
		fat_free(arg->mp.targetDir, fat);
		return -1;
	} else {
		mk_entry(dosname, arg->attr, fat, (uint32_t)ret,
				 now, &entry->dir);
		return 0;
	}
}



static int dos_write(direntry_t *entry, MainParam_t *mp, int needfilter)
/* write a messy dos file to another messy dos file */
{
	int result;
	Arg_t * arg = (Arg_t *) (mp->arg);
	const char *targetName = mpPickTargetName(mp);

	if(entry && arg->preserveAttributes)
		arg->attr = entry->dir.attr;
	else
		arg->attr = ATTR_ARCHIVE;

	arg->needfilter = needfilter;
	if (entry && mp->targetDir == entry->Dir){
		arg->ch.ignore_entry = -1;
		arg->ch.source = entry->entry;
	} else {
		arg->ch.ignore_entry = -1;
		arg->ch.source = -2;
	}
	result = mwrite_one(mp->targetDir, targetName, 0,
			    writeit, (void *)arg, &arg->ch);
	if(result == 1)
		return GOT_ONE;
	else
		return ERROR_ONE;
}

static Stream_t *subDir(Stream_t *parent, const char *filename)
{
	direntry_t entry;
	initializeDirentry(&entry, parent);

	switch(vfat_lookup_zt(&entry, filename, ACCEPT_DIR, 0, 0, 0, 0)) {
	    case 0:
		return OpenFileByDirentry(&entry);
	    case -1:
		return NULL;
	    default: /* IO Error */
		return NULL;
	}
}

static int dos_copydir(direntry_t *entry, MainParam_t *mp)
/* copyes a directory to Dos */
{
	Arg_t * arg = (Arg_t *) (mp->arg);
	Arg_t newArg;
	time_t now;
	time_t date;
	int ret;
	const char *targetName = mpPickTargetName(mp);

	if (!arg->recursive && mp->basenameHasWildcard)
		return 0;

	if(entry && isSubdirOf(mp->targetDir, mp->File)) {
		fprintf(stderr, "Cannot recursively copy 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 (arg->mp.File->Class->get_data(arg->mp.File,
					  & date, 0, 0, 0) < 0 ){
		fprintf(stderr, "Can't stat source file\n");
		return ERROR_ONE;
	}

	if(!arg->type && arg->verbose)
		fprintf(stderr,"Copying %s\n", mpGetBasename(mp));

	if(entry && arg->preserveAttributes)
		arg->attr = entry->dir.attr;
	else
		arg->attr = 0;

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

	/* preserve mod time? */
	if (arg->preserveTime)
		now = date;
	else
		getTimeNow(&now);

	newArg = *arg;
	newArg.mp.arg = &newArg;
	newArg.mp.targetName = 0;
	newArg.mp.basenameHasWildcard = 1;
	if(*targetName) {
		/* maybe the directory already exist. Use it */
		newArg.mp.targetDir = subDir(mp->targetDir, targetName);
		if(!newArg.mp.targetDir)
			newArg.mp.targetDir = createDir(mp->targetDir,
							targetName,
							&arg->ch, arg->attr,
							now);
	} else
		newArg.mp.targetDir = mp->targetDir;

	if(!newArg.mp.targetDir)
		return ERROR_ONE;

	ret = mp->loop(mp->File, &newArg.mp, "*");
	if(*targetName)
		FREE(&newArg.mp.targetDir);
	return ret | GOT_ONE;
}


static int dos_to_dos(direntry_t *entry, MainParam_t *mp)
{
	return dos_write(entry, mp, 0);
}

static int unix_to_dos(MainParam_t *mp)
{
	return dos_write(0, mp, 1);
}

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 [-spatnmQVBT] [-D clash_option] sourcefile targetfile\n", progname);
	fprintf(stderr,
		"       %s [-spatnmQVBT] [-D clash_option] sourcefile [sourcefiles...] targetdirectory\n",
		progname);
	exit(ret);
}

void mcopy(int argc, char **argv, int mtype) NORETURN;
void mcopy(int argc, char **argv, int mtype)
{
	Arg_t arg;
	int c, fastquit;


	/* get command line options */

	init_clash_handling(& arg.ch);

	/* get command line options */
	arg.recursive = 0;
	arg.preserveTime = 0;
	arg.preserveAttributes = 0;
	arg.nowarn = 0;
	arg.textmode = 0;
	arg.verbose = 0;
	arg.convertCharset = 0;
	arg.type = mtype;
	fastquit = 0;
	if(helpFlag(argc, argv))
		usage(0);
	while ((c = getopt(argc, argv, "i:abB/sptTnmvQD:oh")) != EOF) {
		switch (c) {
			case 'i':
				set_cmd_line_image(optarg);
				break;
			case 's':
			case '/':
				arg.recursive = 1;
				break;
			case 'p':
				arg.preserveAttributes = 1;
				break;
			case 'T':
				arg.convertCharset = 1;
				 /*-fallthrough*/
			case 'a':
			case 't':
				arg.textmode = 1;
				break;
			case 'n':
				arg.nowarn = 1;
				break;
			case 'm':
				arg.preserveTime = 1;
				break;
			case 'v':
				arg.verbose = 1;
				break;
			case 'Q':
				fastquit = 1;
				break;
			case 'B':
			case 'b':
				batchmode = 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 < 1)
		usage(1);

	init_mp(&arg.mp);
	arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN | NO_DOTS;
	arg.mp.fast_quit = fastquit;
	arg.mp.arg = (void *) &arg;
	arg.mp.openflags = O_RDONLY;
	arg.noClobber = 0;

	/* last parameter is "-", use mtype mode */
	if(!mtype && !strcmp(argv[argc-1], "-")) {
		arg.type = mtype = 1;
		argc--;
	}

	if(mtype){
		/* Mtype = copying to stdout */
		arg.mp.targetName = strdup("-");
		arg.mp.unixTarget = strdup("");
		arg.mp.callback = dos_to_unix;
		arg.mp.dirCallback = unix_copydir;
		arg.mp.unixcallback = unix_to_unix;
	} else {
		const char *target;
		if (argc - optind == 1) {
			/* copying to the current directory */
			target = ".";
			arg.noClobber = 1;
		} else {
			/* target is the last item mentioned */
			argc--;
			target = argv[argc];
		}

		target_lookup(&arg.mp, target);
		if(!arg.mp.targetDir && !arg.mp.unixTarget) {
			fprintf(stderr,"Bad target %s\n", target);
			exit(1);
		}

		/* callback functions */
		if(arg.mp.unixTarget) {
			arg.mp.callback = dos_to_unix;
			arg.mp.dirCallback = directory_dos_to_unix;
			arg.mp.unixcallback = unix_to_unix;
		} else {
			arg.mp.dirCallback = dos_copydir;
			arg.mp.callback = dos_to_dos;
			arg.mp.unixcallback = unix_to_dos;
		}
	}

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