diff --git a/ntfsprogs/ntfscp.c b/ntfsprogs/ntfscp.c index d2e2eb2c..e69de29b 100644 --- a/ntfsprogs/ntfscp.c +++ b/ntfsprogs/ntfscp.c @@ -1,308 +0,0 @@ -/** - * ntfscp - Part of the Linux-NTFS project. - * - * Copyright (c) 2004 Yura Pakhuchiy - * - * This utility will overwrite files on ntfs volume - * - * This program 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 2 of the License, or - * (at your option) any later version. - * - * This program 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 this program (in the main directory of the Linux-NTFS - * distribution in the file COPYING); if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "types.h" -#include "attrib.h" -#include "utils.h" -#include "volume.h" -#include "debug.h" - -struct options { - char *device; /* Device/File to work with */ - char *src_file; /* Source file */ - char *dest_file; /* Destination file */ - int force; /* Override common sense */ - int quiet; /* Less output */ - int verbose; /* Extra output */ - int noaction; /* Do not write to disk */ -}; - -static const char *EXEC_NAME = "ntfscp"; -static struct options opts; - -GEN_PRINTF (Eprintf, stderr, NULL, FALSE) -GEN_PRINTF (Vprintf, stderr, &opts.verbose, TRUE) -GEN_PRINTF (Qprintf, stderr, &opts.quiet, FALSE) -static GEN_PRINTF (Printf, stderr, NULL, FALSE) - -/** - * version - Print version information about the program - * - * Print a copyright statement and a brief description of the program. - * - * Return: none - */ -static void version (void) -{ - Printf ("\n%s v%s - Overwrite files on NTFS volume.\n\n", - EXEC_NAME, VERSION); - Printf ("Copyright (c) 2004 Yura Pakhuchiy\n"); - Printf ("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home); -} - -/** - * usage - Print a list of the parameters to the program - * - * Print a list of the parameters and options for the program. - * - * Return: none - */ -static void usage (void) -{ - Printf ("\nUsage: %s [options] device src_file dest_file\n\n" - " -f --force Use less caution\n" - " -h --help Print this help\n" - " -n --no-action Do not write to disk\n" - " -q --quiet Less output\n" - " -V --version Version information\n" - " -v --verbose More output\n\n", - EXEC_NAME); - Printf ("%s%s\n", ntfs_bugs, ntfs_home); -} - -/** - * parse_options - Read and validate the programs command line - * - * Read the command line, verify the syntax and parse the options. - * This function is very long, but quite simple. - * - * Return: 1 Success - * 0 Error, one or more problems - */ -static int parse_options (int argc, char **argv) -{ - static const char *sopt = "-fh?nqVv"; - static const struct option lopt[] = { - { "force", no_argument, NULL, 'f' }, - { "help", no_argument, NULL, 'h' }, - { "no-action", no_argument, NULL, 'n' }, - { "quiet", no_argument, NULL, 'q' }, - { "version", no_argument, NULL, 'V' }, - { "verbose", no_argument, NULL, 'v' }, - { NULL, 0, NULL, 0 } - }; - - char c = -1; - int err = 0; - int ver = 0; - int help = 0; - - opts.device = 0; - opts.src_file = 0; - opts.dest_file = 0; - - opterr = 0; /* We'll handle the errors, thank you. */ - - while ((c = getopt_long (argc, argv, sopt, lopt, NULL)) != (char)-1) { - switch (c) { - case 1: /* A non-option argument */ - if (!opts.device) { - opts.device = argv[optind-1]; - } else if (!opts.src_file) { - opts.src_file = argv[optind-1]; - } else if (!opts.dest_file) { - opts.dest_file = argv[optind-1]; - } else { - Eprintf("You must specify exactly two files.\n"); - err++; - } - break; - case 'f': - opts.force++; - break; - case 'h': - case '?': - help++; - break; - case 'n': - opts.noaction++; - break; - case 'q': - opts.quiet++; - break; - case 'V': - ver++; - break; - case 'v': - opts.verbose++; - break; - default: - Eprintf ("Unknown option '%s'.\n", argv[optind-1]); - err++; - break; - } - } - - if (help || ver) { - opts.quiet = 0; - } else { - if (!opts.device) { - Eprintf ("You must specify a device.\n"); - err++; - } else if (!opts.src_file) { - Eprintf ("You must specify a source file.\n"); - err++; - } else if (!opts.dest_file) { - Eprintf ("You must specify a destination file.\n"); - err++; - } - - if (opts.quiet && opts.verbose) { - Eprintf("You may not use --quiet and --verbose at the " - "same time.\n"); - err++; - } - } - - if (ver) - version(); - if (help || err) - usage(); - - return (!err && !help && !ver); -} - -/** - * main - Begin here - * - * Start from here. - * - * Return: 0 Success, the program worked - * 1 Error, something went wrong - */ -int main (int argc, char *argv[]) -{ - FILE *in; - ntfs_volume *vol; - ntfs_inode *out; - ntfs_attr *na; - int flags = 0; - int result = 1; - s64 new_size; - int need_logfile_reset = 0; - u64 offset; - char *buf; - s64 br, bw; - - if (!parse_options (argc, argv)) - return 1; - - utils_set_locale(); - - if (opts.noaction) - flags = MS_RDONLY; - - vol = utils_mount_volume (opts.device, flags, opts.force); - if (!vol) { - perror("ERROR: couldn't mount volume"); - return 1; - } - - if ((vol->flags & VOLUME_IS_DIRTY) && (!opts.force)) - goto umount; - - { - struct stat fst; - if (stat (opts.src_file, &fst) == -1) { - perror ("ERROR: Couldn't star source file\n"); - goto umount; - } - new_size = fst.st_size; - } - Vprintf ("New file size: %lld\n", new_size); - - in = fopen (opts.src_file, "r"); - if (!in) { - perror ("ERROR: Couldn't open source file"); - goto umount; - } - - out = utils_pathname_to_inode (vol, NULL, opts.dest_file); - if (!out) { - perror ("ERROR: Couldn't open destination file"); - goto close_src; - } - - na = ntfs_attr_open (out, AT_DATA, 0, 0); - if (!na) { - perror ("ERROR: Couldn't open $DATA attribute"); - goto close_dst; - } - - Vprintf ("Old file size: %lld\n", na->data_size); - if (na->data_size != new_size) { - if (ntfs_attr_truncate (na, new_size)) { - perror ("ERROR: Couldn't resize $DATA attribute"); - goto close_attr; - } - need_logfile_reset = 1; - } - - buf = malloc (NTFS_BUF_SIZE); - if (!buf) { - perror ("ERROR: malloc failed"); - goto close_attr; - } - - offset = 0; - while (!feof (in)) { - br = fread (buf, 1, NTFS_BUF_SIZE, in); - if (!br) { - if (!feof (in)) perror ("ERROR: fread failed"); - break; - } - - bw = ntfs_attr_pwrite (na, offset, br, buf); - if (bw != br) { - perror ("ERROR: ntfs_attr_pwrite failed"); - break; - } - offset += bw; - } - need_logfile_reset = 1; - - free (buf); -close_attr: - ntfs_attr_close (na); -close_dst: - ntfs_inode_close (out); - - if (need_logfile_reset) { - printf ("Resetting logfile.\n"); - ntfs_logfile_reset (vol); - } - -close_src: - fclose (in); -umount: - ntfs_umount (vol, FALSE); - - return result; -}