summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ntfsprogs/ntfscp.c
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-08-20 20:04:47 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2014-08-20 20:04:47 +0000
commit5f00496ef2e39b976b062f196ff01a99fd4864a4 (patch)
tree20be9cbc8f4b7ed3e616ce23552728083801e846 /usr/src/cmd/ntfsprogs/ntfscp.c
parentaf59b1a40df03681c1c8129aea7b1f5f52f2bcea (diff)
parent86bb58aec7165f8a0303564575c65e5a2ad58bf1 (diff)
downloadillumos-joyent-release-20140821.tar.gz
[illumos-gate merge]20140821release-20140821
commit 86bb58aec7165f8a0303564575c65e5a2ad58bf1 5095 panic when adding a duplicate dbuf to dn_dbufs commit 60a61f7adabc73a7a0cb70d200ac2a6735f4a6e8 5092 env files don't need to define LOCKNAME by default 5091 illumos.sh env file's LOCKNAME definition is busted commit 5e3f545c431ec4bce3e1b52f3f81bc9befe501f2 4989 removal of ntfsprogs and parted commit ba3594ba9b5dd4c846c472a8d657edcb7c8109ac 5066 remove support for non-ANSI compilation 5068 Remove SCCSID() macro from <macros.h> commit d8ccf998f9c944b8cf27ed840c376f9b79ebce5c 5087 8-bit inline atomic {add,or,and} use wrong reg constraints on x86 Manifests: usr/src/pkg/manifests/SUNWntfsprogs.mf (torch library) usr/src/pkg/manifests/SUNWparted.mf (torch headers) usr/src/pkg/manifests/system-file-system-ntfsprogs.mf usr/src/pkg/manifests/system-storage-parted.mf
Diffstat (limited to 'usr/src/cmd/ntfsprogs/ntfscp.c')
-rw-r--r--usr/src/cmd/ntfsprogs/ntfscp.c584
1 files changed, 0 insertions, 584 deletions
diff --git a/usr/src/cmd/ntfsprogs/ntfscp.c b/usr/src/cmd/ntfsprogs/ntfscp.c
deleted file mode 100644
index 0019667a1e..0000000000
--- a/usr/src/cmd/ntfsprogs/ntfscp.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/**
- * ntfscp - Part of the Linux-NTFS project.
- *
- * Copyright (c) 2004-2007 Yura Pakhuchiy
- * Copyright (c) 2005 Anton Altaparmakov
- * Copyright (c) 2006 Hil Liao
- *
- * This utility will copy file to an 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"
-
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <signal.h>
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_LIBGEN_H
-#include <libgen.h>
-#endif
-
-#include "compat.h"
-#include "types.h"
-#include "attrib.h"
-#include "utils.h"
-#include "volume.h"
-#include "dir.h"
-#include "debug.h"
-#include "version.h"
-#include "logging.h"
-
-struct options {
- char *device; /* Device/File to work with */
- char *src_file; /* Source file */
- char *dest_file; /* Destination file */
- char *attr_name; /* Write to attribute with this name. */
- int force; /* Override common sense */
- int quiet; /* Less output */
- int verbose; /* Extra output */
- int noaction; /* Do not write to disk */
- ATTR_TYPES attribute; /* Write to this attribute. */
- int inode; /* Treat dest_file as inode number. */
-};
-
-static const char *EXEC_NAME = "ntfscp";
-static struct options opts;
-static volatile sig_atomic_t caught_terminate = 0;
-
-/**
- * version - Print version information about the program
- *
- * Print a copyright statement and a brief description of the program.
- *
- * Return: none
- */
-static void version(void)
-{
- ntfs_log_info("\n%s v%s (libntfs %s) - Copy file to an NTFS "
- "volume.\n\n", EXEC_NAME, VERSION, ntfs_libntfs_version());
- ntfs_log_info("Copyright (c) 2004-2007 Yura Pakhuchiy\n");
- ntfs_log_info("Copyright (c) 2005 Anton Altaparmakov\n");
- ntfs_log_info("Copyright (c) 2006 Hil Liao\n");
- ntfs_log_info("\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)
-{
- ntfs_log_info("\nUsage: %s [options] device src_file dest_file\n\n"
- " -a, --attribute NUM Write to this attribute\n"
- " -i, --inode Treat dest_file as inode number\n"
- " -f, --force Use less caution\n"
- " -h, --help Print this help\n"
- " -N, --attr-name NAME Write to attribute with this name\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);
- ntfs_log_info("%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 = "-a:ifh?N:nqVv";
- static const struct option lopt[] = {
- { "attribute", required_argument, NULL, 'a' },
- { "inode", no_argument, NULL, 'i' },
- { "force", no_argument, NULL, 'f' },
- { "help", no_argument, NULL, 'h' },
- { "attr-name", required_argument, NULL, 'N' },
- { "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 *s;
- int c = -1;
- int err = 0;
- int ver = 0;
- int help = 0;
- int levels = 0;
- s64 attr;
-
- opts.device = NULL;
- opts.src_file = NULL;
- opts.dest_file = NULL;
- opts.attr_name = NULL;
- opts.inode = 0;
- opts.attribute = AT_DATA;
-
- opterr = 0; /* We'll handle the errors, thank you. */
-
- while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -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 {
- ntfs_log_error("You must specify exactly two "
- "files.\n");
- err++;
- }
- break;
- case 'a':
- if (opts.attribute != AT_DATA) {
- ntfs_log_error("You can specify only one "
- "attribute.\n");
- err++;
- break;
- }
-
- attr = strtol(optarg, &s, 0);
- if (*s) {
- ntfs_log_error("Couldn't parse attribute.\n");
- err++;
- } else
- opts.attribute = (ATTR_TYPES)cpu_to_le32(attr);
- break;
- case 'i':
- opts.inode++;
- break;
- case 'f':
- opts.force++;
- break;
- case 'h':
- case '?':
- if (strncmp(argv[optind - 1], "--log-", 6) == 0) {
- if (!ntfs_log_parse_option(argv[optind - 1]))
- err++;
- break;
- }
- help++;
- break;
- case 'N':
- if (opts.attr_name) {
- ntfs_log_error("You can specify only one "
- "attribute name.\n");
- err++;
- } else
- opts.attr_name = argv[optind - 1];
- break;
- case 'n':
- opts.noaction++;
- break;
- case 'q':
- opts.quiet++;
- ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET);
- break;
- case 'V':
- ver++;
- break;
- case 'v':
- opts.verbose++;
- ntfs_log_set_levels(NTFS_LOG_LEVEL_VERBOSE);
- break;
- default:
- ntfs_log_error("Unknown option '%s'.\n",
- argv[optind - 1]);
- err++;
- break;
- }
- }
-
- /* Make sure we're in sync with the log levels */
- levels = ntfs_log_get_levels();
- if (levels & NTFS_LOG_LEVEL_VERBOSE)
- opts.verbose++;
- if (!(levels & NTFS_LOG_LEVEL_QUIET))
- opts.quiet++;
-
- if (help || ver) {
- opts.quiet = 0;
- } else {
- if (!opts.device) {
- ntfs_log_error("You must specify a device.\n");
- err++;
- } else if (!opts.src_file) {
- ntfs_log_error("You must specify a source file.\n");
- err++;
- } else if (!opts.dest_file) {
- ntfs_log_error("You must specify a destination "
- "file.\n");
- err++;
- }
-
- if (opts.quiet && opts.verbose) {
- ntfs_log_error("You may not use --quiet and --verbose "
- "at the same time.\n");
- err++;
- }
- }
-
- if (ver)
- version();
- if (help || err)
- usage();
-
- return (!err && !help && !ver);
-}
-
-/**
- * signal_handler - Handle SIGINT and SIGTERM: abort write, sync and exit.
- */
-static void signal_handler(int arg __attribute__((unused)))
-{
- caught_terminate++;
-}
-
-/**
- * Create a regular file under the given directory inode
- *
- * It is a wrapper function to ntfs_create(...)
- *
- * Return: the created file inode
- */
-static ntfs_inode *ntfs_new_file(ntfs_inode *dir_ni,
- const char *filename)
-{
- ntfschar *ufilename;
- /* inode to the file that is being created */
- ntfs_inode *ni;
- int ufilename_len;
-
- /* ntfs_mbstoucs(...) will allocate memory for ufilename if it's NULL */
- ufilename = NULL;
- ufilename_len = ntfs_mbstoucs(filename, &ufilename, 0);
- if (ufilename_len == -1) {
- ntfs_log_perror("ERROR: Failed to convert '%s' to unicode",
- filename);
- return NULL;
- }
- ni = ntfs_create(dir_ni, ufilename, ufilename_len, S_IFREG);
- free(ufilename);
- return ni;
-}
-
-/**
- * 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;
- u64 offset;
- char *buf;
- s64 br, bw;
- ntfschar *attr_name;
- int attr_name_len = 0;
-
- ntfs_log_set_handler(ntfs_log_handler_stderr);
-
- if (!parse_options(argc, argv))
- return 1;
-
- utils_set_locale();
-
- /* Set SIGINT handler. */
- if (signal(SIGINT, signal_handler) == SIG_ERR) {
- ntfs_log_perror("Failed to set SIGINT handler");
- return 1;
- }
- /* Set SIGTERM handler. */
- if (signal(SIGTERM, signal_handler) == SIG_ERR) {
- ntfs_log_perror("Failed to set SIGTERM handler");
- return 1;
- }
-
- if (opts.noaction)
- flags = NTFS_MNT_RDONLY;
- if (opts.force)
- flags |= NTFS_MNT_FORCE;
-
- vol = utils_mount_volume(opts.device, flags);
- if (!vol) {
- ntfs_log_perror("ERROR: couldn't mount volume");
- return 1;
- }
-
- if (NVolWasDirty(vol) && !opts.force)
- goto umount;
-
- {
- struct stat fst;
- if (stat(opts.src_file, &fst) == -1) {
- ntfs_log_perror("ERROR: Couldn't stat source file");
- goto umount;
- }
- new_size = fst.st_size;
- }
- ntfs_log_verbose("New file size: %lld\n", new_size);
-
- in = fopen(opts.src_file, "r");
- if (!in) {
- ntfs_log_perror("ERROR: Couldn't open source file");
- goto umount;
- }
-
- if (opts.inode) {
- s64 inode_num;
- char *s;
-
- inode_num = strtoll(opts.dest_file, &s, 0);
- if (*s) {
- ntfs_log_error("ERROR: Couldn't parse inode number.\n");
- goto close_src;
- }
- out = ntfs_inode_open(vol, inode_num);
- } else
- out = ntfs_pathname_to_inode(vol, NULL, opts.dest_file);
- if (!out) {
- /* Copy the file if the dest_file's parent dir can be opened. */
- char *parent_dirname;
- char *filename;
- ntfs_inode *dir_ni;
- ntfs_inode *ni;
- int dest_path_len;
- char *dirname_last_whack;
-
- filename = basename(opts.dest_file);
- dest_path_len = strlen(opts.dest_file);
- parent_dirname = strdup(opts.dest_file);
- if (!parent_dirname) {
- ntfs_log_perror("strdup() failed");
- goto close_src;
- }
- dirname_last_whack = strrchr(parent_dirname, '/');
- if (dirname_last_whack) {
- dirname_last_whack[1] = 0;
- dir_ni = ntfs_pathname_to_inode(vol, NULL,
- parent_dirname);
- } else {
- ntfs_log_verbose("Target path does not contain '/'. "
- "Using root directory as parent.\n");
- dir_ni = ntfs_inode_open(vol, FILE_root);
- }
- if (dir_ni) {
- if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
- /* Remove the last '/' for estetic reasons. */
- dirname_last_whack[0] = 0;
- ntfs_log_error("The file '%s' already exists "
- "and is not a directory. "
- "Aborting.\n", parent_dirname);
- free(parent_dirname);
- ntfs_inode_close(dir_ni);
- goto close_src;
- }
- ntfs_log_verbose("Creating a new file '%s' under '%s'"
- "\n", filename, parent_dirname);
- ni = ntfs_new_file(dir_ni, filename);
- ntfs_inode_close(dir_ni);
- if (!ni) {
- ntfs_log_perror("Failed to create '%s' under "
- "'%s'", filename,
- parent_dirname);
- free(parent_dirname);
- goto close_src;
- }
- out = ni;
- } else {
- ntfs_log_perror("ERROR: Couldn't open '%s'",
- parent_dirname);
- free(parent_dirname);
- goto close_src;
- }
- free(parent_dirname);
- }
- /* The destination is a directory. */
- if ((out->mrec->flags & MFT_RECORD_IS_DIRECTORY) && !opts.inode) {
- char *filename;
- char *overwrite_filename;
- int overwrite_filename_len;
- ntfs_inode *ni;
- ntfs_inode *dir_ni;
- int filename_len;
- int dest_dirname_len;
-
- filename = basename(opts.src_file);
- dir_ni = out;
- filename_len = strlen(filename);
- dest_dirname_len = strlen(opts.dest_file);
- overwrite_filename_len = filename_len+dest_dirname_len + 2;
- overwrite_filename = malloc(overwrite_filename_len);
- if (!overwrite_filename) {
- ntfs_log_perror("ERROR: Failed to allocate %i bytes "
- "memory for the overwrite filename",
- overwrite_filename_len);
- ntfs_inode_close(out);
- goto close_src;
- }
- strcpy(overwrite_filename, opts.dest_file);
- if (opts.dest_file[dest_dirname_len - 1] != '/') {
- strcat(overwrite_filename, "/");
- }
- strcat(overwrite_filename, filename);
- ni = ntfs_pathname_to_inode(vol, NULL, overwrite_filename);
- /* Does a file with the same name exist in the dest dir? */
- if (ni) {
- ntfs_log_verbose("Destination path has a file with "
- "the same name\nOverwriting the file "
- "'%s'\n", overwrite_filename);
- ntfs_inode_close(out);
- out = ni;
- } else {
- ntfs_log_verbose("Creating a new file '%s' under "
- "'%s'\n", filename, opts.dest_file);
- ni = ntfs_new_file(dir_ni, filename);
- ntfs_inode_close(dir_ni);
- if (!ni) {
- ntfs_log_perror("ERROR: Failed to create the "
- "destination file under '%s'",
- opts.dest_file);
- free(overwrite_filename);
- goto close_src;
- }
- out = ni;
- }
- free(overwrite_filename);
- }
-
- attr_name = ntfs_str2ucs(opts.attr_name, &attr_name_len);
- if (!attr_name) {
- ntfs_log_perror("ERROR: Failed to parse attribute name '%s'",
- opts.attr_name);
- goto close_dst;
- }
-
- na = ntfs_attr_open(out, opts.attribute, attr_name, attr_name_len);
- if (!na) {
- if (errno != ENOENT) {
- ntfs_log_perror("ERROR: Couldn't open attribute");
- goto close_dst;
- }
- /* Requested attribute isn't present, add it. */
- if (ntfs_attr_add(out, opts.attribute, attr_name,
- attr_name_len, NULL, 0)) {
- ntfs_log_perror("ERROR: Couldn't add attribute");
- goto close_dst;
- }
- na = ntfs_attr_open(out, opts.attribute, attr_name,
- attr_name_len);
- if (!na) {
- ntfs_log_perror("ERROR: Couldn't open just added "
- "attribute");
- goto close_dst;
- }
- }
- ntfs_ucsfree(attr_name);
-
- ntfs_log_verbose("Old file size: %lld\n", na->data_size);
- if (na->data_size != new_size) {
- if (__ntfs_attr_truncate(na, new_size, FALSE)) {
- ntfs_log_perror("ERROR: Couldn't resize attribute");
- goto close_attr;
- }
- }
-
- buf = malloc(NTFS_BUF_SIZE);
- if (!buf) {
- ntfs_log_perror("ERROR: malloc failed");
- goto close_attr;
- }
-
- ntfs_log_verbose("Starting write.\n");
- offset = 0;
- while (!feof(in)) {
- if (caught_terminate) {
- ntfs_log_error("SIGTERM or SIGINT received. "
- "Aborting write.\n");
- break;
- }
- br = fread(buf, 1, NTFS_BUF_SIZE, in);
- if (!br) {
- if (!feof(in)) ntfs_log_perror("ERROR: fread failed");
- break;
- }
- bw = ntfs_attr_pwrite(na, offset, br, buf);
- if (bw != br) {
- ntfs_log_perror("ERROR: ntfs_attr_pwrite failed");
- break;
- }
- offset += bw;
- }
- ntfs_log_verbose("Syncing.\n");
- result = 0;
- free(buf);
-close_attr:
- ntfs_attr_close(na);
-close_dst:
- while (ntfs_inode_close(out)) {
- if (errno != EBUSY) {
- ntfs_log_error("Sync failed. Run chkdsk.\n");
- break;
- }
- ntfs_log_error("Device busy. Will retry sync in 3 seconds.\n");
- sleep(3);
- }
-close_src:
- fclose(in);
-umount:
- ntfs_umount(vol, FALSE);
- ntfs_log_verbose("Done.\n");
- return result;
-}