/*
 * Copyright 2005 The Android Open Source Project
 *
 * Android "cp" replacement.
 *
 * The GNU/Linux "cp" uses O_LARGEFILE in its open() calls, utimes() instead
 * of utime(), and getxattr()/setxattr() instead of chmod().  These are
 * probably "better", but are non-portable, and not necessary for our
 * purposes.
 */
#include <host/CopyFile.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <dirent.h>
#include <fcntl.h>
#include <utime.h>
#include <limits.h>
#include <errno.h>
#include <assert.h>

#ifdef HAVE_MS_C_RUNTIME
#  define  mkdir(path,mode)   _mkdir(path)
#endif

#ifndef HAVE_SYMLINKS
#  define  lstat              stat
#  ifndef EACCESS   /* seems to be missing from the Mingw headers */
#    define  EACCESS            13
#  endif
#endif

#ifndef O_BINARY
#  define  O_BINARY  0
#endif

/*#define DEBUG_MSGS*/
#ifdef DEBUG_MSGS
# define DBUG(x) printf x
#else
# define DBUG(x) ((void)0)
#endif

#define FSSEP '/'       /* filename separator char */

static int copyFileRecursive(const char* src, const char* dst, bool isCmdLine, unsigned int options);

/*
 * Returns true if the source file is newer than the destination file.
 *
 * The check is based on the modification date, whole seconds only.  This
 * also returns true if the file sizes don't match.
 */
static bool isSourceNewer(const struct stat* pSrcStat, const struct stat* pDstStat)
{
    return (pSrcStat->st_mtime > pDstStat->st_mtime) ||
           (pSrcStat->st_size != pDstStat->st_size);
}

/*
 * Returns true if the source file has high resolution modification
 * date. Cygwin/Mingw doesn't support st_mtim and always returns false.
 */
static bool isHiresMtime(const struct stat* pSrcStat)
{
#if HAVE_STAT_ST_MTIM
#if defined(MACOSX_RSRC)
    return pSrcStat->st_mtimespec.tv_nsec > 0;
#else
    return pSrcStat->st_mtim.tv_nsec > 0;
#endif
#else
    return 0;
#endif
}

/*
 * Returns true if the source and destination files are actually the
 * same thing.  We detect this by checking the inode numbers, which seems
 * to work on Cygwin.
 */
static bool isSameFile(const struct stat* pSrcStat, const struct stat* pDstStat)
{
#ifndef HAVE_VALID_STAT_ST_INO
    /* with MSVCRT.DLL, stat always sets st_ino to 0, and there is no simple way to */
	/* get the equivalent information with Win32 (Cygwin does some weird stuff in   */
	/* its winsup/cygwin/fhandler_disk_file.cc to emulate this, too complex for us) */
	return 0;
#else
    return (pSrcStat->st_ino == pDstStat->st_ino);
#endif
}

static void printCopyMsg(const char* src, const char* dst, unsigned int options)
{
    if ((options & COPY_VERBOSE_MASK) > 0)
        printf("    '%s' --> '%s'\n", src, dst);
}

static void printNotNewerMsg(const char* src, const char* dst, unsigned int options)
{
    if ((options & COPY_VERBOSE_MASK) > 1)
        printf("    '%s' is up-to-date\n", dst);
}

/*
 * Copy the contents of one file to another.
 *
 * The files are assumed to be seeked to the start.
 */
static int copyFileContents(const char* dst, int dstFd, const char* src, int srcFd)
{
    unsigned char buf[8192];
    ssize_t readCount, writeCount;

    /*
     * Read a chunk, write it, and repeat.
     */
    while (1) {
        readCount = read(srcFd, buf, sizeof(buf));
        if (readCount < 0) {
            fprintf(stderr,
                "acp: failed reading '%s': %s\n", src, strerror(errno));
            return -1;
        }

        if (readCount > 0) {
            writeCount = write(dstFd, buf, readCount);
            if (writeCount < 0) {
                fprintf(stderr,
                    "acp: failed writing '%s': %s\n", dst, strerror(errno));
                return -1;
            }
            if (writeCount != readCount) {
                fprintf(stderr, "acp: partial write to '%s' (%d of %d)\n",
                    dst, writeCount, readCount);
                return -1;
            }
        }

        if (readCount < (ssize_t) sizeof(buf))
            break;
    }

    return 0;
}

/*
 * Set the permissions, owner, and timestamps on the destination file
 * equal to those of the source file.
 *
 * Failures here are "soft"; they don't produce warning messages and don't
 * cause the cp command to report a failure.
 */
static int setPermissions(const char* dst, const struct stat* pSrcStat, unsigned int options)
{
    struct utimbuf ut;

    if (options & COPY_TIMESTAMPS) {
        /*
         * Start with timestamps.  The access and mod dates are not affected
         * by the next operations.
         */
        ut.actime = pSrcStat->st_atime;
        ut.modtime = pSrcStat->st_mtime;
        if (isHiresMtime(pSrcStat))
            ut.modtime += 1;
        if (utime(dst, &ut) != 0) {
            DBUG(("---   unable to set timestamps on '%s': %s\n",
                dst, strerror(errno)));
        }
    }

    if (options & COPY_PERMISSIONS) {
        /*
         * Set the permissions.
         */
        if (chmod(dst, pSrcStat->st_mode & ~(S_IFMT)) != 0) {
            DBUG(("---   unable to set perms on '%s' to 0%o: %s\n",
                dst, pSrcStat->st_mode & ~(S_IFMT), strerror(errno)));
        }
#ifndef HAVE_MS_C_RUNTIME
        /*
         * Set the owner.
         */
        if (chown(dst, pSrcStat->st_uid, pSrcStat->st_gid) != 0) {
            DBUG(("---   unable to set owner of '%s' to %d/%d: %s\n",
                dst, pSrcStat->st_uid, pSrcStat->st_gid, strerror(errno)));
        }
#endif
    }

    return 0;
}

/*
 * Copy a regular file.  If the destination file exists and is not a
 * regular file, we fail.  However, we use stat() rather than lstat(),
 * because it's okay to write through a symlink (the noDereference stuff
 * only applies to the source file).
 *
 * If the file doesn't exist, create it.  If it does exist, truncate it.
 */
static int copyRegular(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
{
    struct stat dstStat;
    int srcFd, dstFd, statResult, copyResult;

    DBUG(("--- copying regular '%s' to '%s'\n", src, dst));

    statResult = stat(dst, &dstStat);
    if (statResult == 0 && !S_ISREG(dstStat.st_mode)) {
        fprintf(stderr,
            "acp: destination '%s' exists and is not regular file\n",
            dst);
        return -1;
    } else if (statResult != 0 && errno != ENOENT) {
        fprintf(stderr, "acp: unable to stat destination '%s'\n", dst);
        return -1;
    }

    if (statResult == 0) {
        if (isSameFile(pSrcStat, &dstStat)) {
            fprintf(stderr, "acp: '%s' and '%s' are the same file\n",
                src, dst);
            return -1;
        }
        if (options & COPY_UPDATE_ONLY) {
            if (!isSourceNewer(pSrcStat, &dstStat)) {
                DBUG(("---  source is not newer: '%s'\n", src));
                printNotNewerMsg(src, dst, options);
                return 0;
            }
        }
    }

    /* open src */
    srcFd = open(src, O_RDONLY | O_BINARY, 0);
    if (srcFd < 0) {
        fprintf(stderr, "acp: unable to open '%s': %s\n", src, strerror(errno));
        return -1;
    }

    /* open dest with O_CREAT | O_TRUNC */
    DBUG(("---  opening '%s'\n", dst));
    dstFd = open(dst, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);

    if (dstFd < 0) {
        if (errno == ENOENT) {
            /* this happens if the target directory doesn't exist */
            fprintf(stderr,
                "acp: cannot create '%s': %s\n", dst, strerror(errno));
            (void) close(srcFd);
            return -1;
        }

        /* if "force" is set, try removing the destination file and retry */
        if (options & COPY_FORCE) {
            if (unlink(dst) != 0) {
#ifdef HAVE_MS_C_RUNTIME
				/* MSVCRT.DLL unlink will fail with EACCESS if the file is set read-only */
				/* so try to change its mode, and unlink again                           */
				if (errno == EACCESS) {
					if (chmod(dst, S_IWRITE|S_IREAD) == 0 && unlink(dst) == 0)
						goto Open_File;
				}
#endif		
                fprintf(stderr, "acp: unable to remove '%s': %s\n",
                    dst, strerror(errno));
                (void) close(srcFd);
                return -1;
            }
#ifdef HAVE_MS_C_RUNTIME
        Open_File:
#endif			
            dstFd = open(dst, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
        }
    }
    if (dstFd < 0) {
        fprintf(stderr, "acp: unable to open '%s': %s\n",
            dst, strerror(errno));
        (void) close(srcFd);
        return -1;
    }

    copyResult = copyFileContents(dst, dstFd, src, srcFd);

    (void) close(srcFd);
    (void) close(dstFd);
    if (copyResult != 0)
        return -1;

#ifdef MACOSX_RSRC
    {
        char* srcRsrcName = NULL;
        char* dstRsrcName = NULL;
        struct stat rsrcStat;

        srcRsrcName = malloc(strlen(src) + 5 + 1);
        strcpy(srcRsrcName, src);
        strcat(srcRsrcName, "/rsrc");

        dstRsrcName = malloc(strlen(dst) + 5 + 1);
        strcpy(dstRsrcName, dst);
        strcat(dstRsrcName, "/rsrc");

        if (stat(srcRsrcName, &rsrcStat) == 0 && rsrcStat.st_size > 0) {
            DBUG(("---  RSRC: %s --> %s\n", srcRsrcName, dstRsrcName));

            srcFd = open(srcRsrcName, O_RDONLY);
            dstFd = open(dstRsrcName, O_TRUNC | O_WRONLY, 0);
            copyResult = -1;
            if (srcFd >= 0 && dstFd >= 0) {
                copyResult = copyFileContents(dstRsrcName, dstFd,
                    srcRsrcName, srcFd);
                (void) close(srcFd);
                (void) close(dstFd);
            }

            if (copyResult != 0)
                return -1;
        }

        free(srcRsrcName);
        free(dstRsrcName);
    }
#endif

    setPermissions(dst, pSrcStat, options);

    printCopyMsg(src, dst, options);

    return 0;
}


#ifdef HAVE_SYMLINKS
/*
 * Copy a symlink.  This only happens if we're in "no derefence" mode,
 * in which we copy the links rather than the files that are pointed at.
 *
 * We always discard the destination file.  If it's a symlink already,
 * we want to throw it out and replace it.  If it's not a symlink, we
 * need to trash it so we can create one.
 */
static int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
{
    struct stat dstStat;
    char linkBuf[PATH_MAX+1];
    int statResult, nameLen;

    assert(options & COPY_NO_DEREFERENCE);
    DBUG(("--- copying symlink '%s' to '%s'\n", src, dst));

    /* NOTE: we use lstat() here */
    statResult = lstat(dst, &dstStat);
    if (statResult == 0 && !S_ISREG(dstStat.st_mode)
                         && !S_ISLNK(dstStat.st_mode)
						 )
    {
        fprintf(stderr,
            "acp: destination '%s' exists and is not regular or symlink\n",
            dst);
        return -1;
    }

    if (statResult == 0) {
        if (isSameFile(pSrcStat, &dstStat)) {
            fprintf(stderr, "acp: '%s' and '%s' are the same file\n",
                src, dst);
            return -1;
        }
        if (options & COPY_UPDATE_ONLY) {
            if (!isSourceNewer(pSrcStat, &dstStat)) {
                DBUG(("---  source is not newer: '%s'\n", src));
                printNotNewerMsg(src, dst, options);
                return 0;
            }
        }
    }

    /* extract the symlink contents */
    nameLen = readlink(src, linkBuf, sizeof(linkBuf)-1);
    if (nameLen <= 0) {
        fprintf(stderr, "acp: unable to read symlink '%s': %s\n",
            src, strerror(errno));
        return -1;
    }
    linkBuf[nameLen] = '\0';
    DBUG(("--- creating symlink file '%s' (--> %s)\n", dst, linkBuf));

    if (statResult == 0) {
        DBUG(("---  removing '%s'\n", dst));
        if (unlink(dst) != 0) {
            fprintf(stderr, "acp: unable to remove '%s': %s\n",
                dst, strerror(errno));
            return -1;
        }
    }

    if (symlink(linkBuf, dst) != 0) {
        fprintf(stderr, "acp: unable to create symlink '%s' [%s]: %s\n",
            dst, linkBuf, strerror(errno));
        return -1;
    }

    /*
     * There's no way to set the file date or access permissions, but
     * it is possible to set the owner.
     */
    if (options & COPY_PERMISSIONS) {
        if (lchown(dst, pSrcStat->st_uid, pSrcStat->st_gid) != 0)
            DBUG(("---  lchown failed: %s\n", strerror(errno)));
    }

    printCopyMsg(src, dst, options);

    return 0;
}
#endif /* HAVE_SYMLINKS */

/*
 * Copy the contents of one directory to another.  Both "src" and "dst"
 * must be directories.  We will create "dst" if it does not exist.
 */
int copyDirectory(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
{
    int retVal = 0;
    struct stat dstStat;
    DIR* dir;
    int cc, statResult;

    DBUG(("--- copy dir '%s' to '%s'\n", src, dst));

    statResult = stat(dst, &dstStat);
    if (statResult == 0 && !S_ISDIR(dstStat.st_mode)) {
        fprintf(stderr,
            "acp: destination '%s' exists and is not a directory\n", dst);
        return -1;
    } else if (statResult != 0 && errno != ENOENT) {
        fprintf(stderr, "acp: unable to stat destination '%s'\n", dst);
        return -1;
    }

    if (statResult == 0) {
        if (isSameFile(pSrcStat, &dstStat)) {
            fprintf(stderr,
                "acp: cannot copy directory into itself ('%s' and '%s')\n",
                src, dst);
            return -1;
        }
    } else {
        DBUG(("---  creating dir '%s'\n", dst));
        cc = mkdir(dst, 0755);
        if (cc != 0) {
            fprintf(stderr, "acp: unable to create directory '%s': %s\n",
                dst, strerror(errno));
            return -1;
        }

        /* only print on mkdir */
        printCopyMsg(src, dst, options);
    }

    /*
     * Open the directory, and plow through its contents.
     */
    dir = opendir(src);
    if (dir == NULL) {
        fprintf(stderr, "acp: unable to open directory '%s': %s\n",
            src, strerror(errno));
        return -1;
    }

    while (1) {
        struct dirent* ent;
        char* srcFile;
        char* dstFile;
        int srcLen, dstLen, nameLen;

        ent = readdir(dir);
        if (ent == NULL)
            break;

        if (strcmp(ent->d_name, ".") == 0 ||
            strcmp(ent->d_name, "..") == 0)
        {
            continue;
        }

        nameLen = strlen(ent->d_name);
        srcLen = strlen(src);
        dstLen = strlen(dst);

        srcFile = malloc(srcLen +1 + nameLen +1);
        memcpy(srcFile, src, srcLen);
        srcFile[srcLen] = FSSEP;
        memcpy(srcFile + srcLen+1, ent->d_name, nameLen +1);

        dstFile = malloc(dstLen +1 + nameLen +1);
        memcpy(dstFile, dst, dstLen);
        dstFile[dstLen] = FSSEP;
        memcpy(dstFile + dstLen+1, ent->d_name, nameLen +1);

        if (copyFileRecursive(srcFile, dstFile, false, options) != 0)
            retVal = -1;        /* note failure and keep going */

        free(srcFile);
        free(dstFile);
    }
    closedir(dir);

    setPermissions(dst, pSrcStat, options);

    return retVal;
}

/*
 * Do the actual copy.  This is called recursively from copyDirectory().
 *
 * "dst" should only be a directory if "src" is also a directory.
 *
 * Returns 0 on success.
 */
static int copyFileRecursive(const char* src, const char* dst, bool isCmdLine, unsigned int options)
{
    char* srcExe = NULL;
    char* dstExe = NULL;
    char* dstDir = NULL;
    struct stat srcStat;
    int retVal = 0;
    int statResult, statErrno;

    /*
     * Stat the source file.  If it doesn't exist, fail.
     */
    if (options & COPY_NO_DEREFERENCE)
        statResult = lstat(src, &srcStat);
    else
        statResult = stat(src, &srcStat);
    statErrno = errno;        /* preserve across .exe attempt */

#ifdef WIN32_EXE
    /*
     * Here's the interesting part.  Under Cygwin, if you have a file
     * called "foo.exe", stat("foo", ...) will succeed, but open("foo", ...)
     * will fail.  We need to figure out what its name is supposed to be
     * so we can create the correct destination file.
     *
     * If we don't have the "-e" flag set, we want "acp foo bar" to fail,
     * not automatically find "foo.exe".  That way, if we really were
     * trying to copy "foo", it doesn't grab something we don't want.
     */
    if (isCmdLine && statResult == 0) {
        int tmpFd;
        tmpFd = open(src, O_RDONLY | O_BINARY, 0);
        if (tmpFd < 0) {
            statResult = -1;
            statErrno = ENOENT;
        } else {
            (void) close(tmpFd);
        }
    }

    /*
     * If we didn't find the file, try it again with ".exe".
     */
    if (isCmdLine && statResult < 0 && statErrno == ENOENT && (options & COPY_TRY_EXE)) {
        srcExe = malloc(strlen(src) + 4 +1);
        strcpy(srcExe, src);
        strcat(srcExe, ".exe");

        if (options & COPY_NO_DEREFERENCE)
            statResult = lstat(srcExe, &srcStat);
        else
            statResult = stat(srcExe, &srcStat);

        if (statResult == 0 && !S_ISREG(srcStat.st_mode))
            statResult = -1;        /* fail, use original statErrno below */

        if (statResult == 0) {
            /* found a .exe, copy that instead */
            dstExe = malloc(strlen(dst) + 4 +1);
            strcpy(dstExe, dst);
            strcat(dstExe, ".exe");

            src = srcExe;
            dst = dstExe;
        } else {
            DBUG(("---  couldn't find '%s' either\n", srcExe));
        }
    }
#endif
    if (statResult < 0) {
        if (statErrno == ENOENT)
            fprintf(stderr, "acp: file '%s' does not exist\n", src);
        else
            fprintf(stderr, "acp: unable to stat '%s': %s\n",
                src, strerror(statErrno));
        retVal = -1;
        goto bail;
    }

    /*
     * If "src" is a directory, ignore it if "recursive" isn't set.
     *
     * We want to create "dst" as a directory (or verify that it already
     * exists as a directory), and then copy its contents.
     */
    if (S_ISDIR(srcStat.st_mode)) {
        if (!(options & COPY_RECURSIVE)) {
            fprintf(stderr, "acp: omitting directory '%s'\n", src);
        } else {
            retVal = copyDirectory(src, dst, &srcStat, options);
        }
#ifdef HAVE_SYMLINKS
    } else if (S_ISLNK(srcStat.st_mode)) {
        retVal = copySymlink(src, dst, &srcStat, options);
#endif		
    } else if (S_ISREG(srcStat.st_mode)) {
        retVal = copyRegular(src, dst, &srcStat, options);
    } else {
        fprintf(stderr, "acp: skipping unusual file '%s' (mode=0%o)\n",
            src, srcStat.st_mode);
        retVal = -1;
    }

bail:
    free(srcExe);
    free(dstExe);
    free(dstDir);
    return retVal;
}

int copyFile(const char* src, const char* dst, unsigned int options)
{
    return copyFileRecursive(src, dst, true, options);
}


