"Fossies" - the Fresh Open Source Software Archive

Member "ntfs-3g_ntfsprogs-2017.3.23/ntfsprogs/ntfsclone.c" (23 Mar 2017, 71885 Bytes) of package /linux/misc/ntfs-3g_ntfsprogs-2017.3.23.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ntfsclone.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3g_ntfsprogs-2016.2.22_vs_3g_ntfsprogs-2017.3.23.

    1 /**
    2  * ntfsclone - Part of the Linux-NTFS project.
    3  *
    4  * Copyright (c) 2003-2006 Szabolcs Szakacsits
    5  * Copyright (c) 2004-2006 Anton Altaparmakov
    6  * Copyright (c) 2010-2016 Jean-Pierre Andre
    7  * Special image format support copyright (c) 2004 Per Olofsson
    8  *
    9  * Clone NTFS data and/or metadata to a sparse file, image, device or stdout.
   10  *
   11  * This program is free software; you can redistribute it and/or modify
   12  * it under the terms of the GNU General Public License as published by
   13  * the Free Software Foundation; either version 2 of the License, or
   14  * (at your option) any later version.
   15  */
   16 
   17 #include "config.h"
   18 
   19 #ifdef HAVE_UNISTD_H
   20 #include <unistd.h>
   21 #endif
   22 #ifdef HAVE_STDLIB_H
   23 #include <stdlib.h>
   24 #endif
   25 #ifdef HAVE_STDIO_H
   26 #include <stdio.h>
   27 #endif
   28 #ifdef HAVE_SYS_TYPES_H
   29 #include <sys/types.h>
   30 #endif
   31 #ifdef HAVE_SYS_STAT_H
   32 #include <sys/stat.h>
   33 #endif
   34 #ifdef HAVE_TIME_H
   35 #include <time.h>
   36 #endif
   37 #ifdef HAVE_SYS_IOCTL_H
   38 #include <sys/ioctl.h>
   39 #endif
   40 #ifdef HAVE_SYS_VFS_H
   41 #include <sys/vfs.h>
   42 #endif
   43 #ifdef HAVE_SYS_STATVFS_H
   44 #include <sys/statvfs.h>
   45 #endif
   46 #ifdef HAVE_FCNTL_H
   47 #include <fcntl.h>
   48 #endif
   49 #ifdef HAVE_STDARG_H
   50 #include <stdarg.h>
   51 #endif
   52 #ifdef HAVE_STRING_H
   53 #include <string.h>
   54 #endif
   55 #ifdef HAVE_ERRNO_H
   56 #include <errno.h>
   57 #endif
   58 #ifdef HAVE_GETOPT_H
   59 #include <getopt.h>
   60 #endif
   61 #ifdef HAVE_UNISTD_H
   62 #include <unistd.h>
   63 #endif
   64 #ifdef HAVE_SYS_MOUNT_H
   65 #include <sys/mount.h>
   66 #endif
   67 
   68 /*
   69  * FIXME: ntfsclone do bad things about endians handling. Fix it and remove
   70  * this note and define.
   71  */
   72 #define NTFS_DO_NOT_CHECK_ENDIANS
   73 
   74 #include "debug.h"
   75 #include "types.h"
   76 #include "support.h"
   77 #include "endians.h"
   78 #include "bootsect.h"
   79 #include "device.h"
   80 #include "attrib.h"
   81 #include "mst.h"
   82 #include "volume.h"
   83 #include "mft.h"
   84 #include "bitmap.h"
   85 #include "inode.h"
   86 #include "index.h"
   87 #include "dir.h"
   88 #include "runlist.h"
   89 #include "ntfstime.h"
   90 #include "utils.h"
   91 /* #include "version.h" */
   92 #include "misc.h"
   93 
   94 #if defined(linux) && defined(_IO) && !defined(BLKGETSIZE)
   95 #define BLKGETSIZE  _IO(0x12,96)  /* Get device size in 512-byte blocks. */
   96 #endif
   97 #if defined(linux) && defined(_IOR) && !defined(BLKGETSIZE64)
   98 #define BLKGETSIZE64    _IOR(0x12,114,size_t)   /* Get device size in bytes. */
   99 #endif
  100 
  101 #if defined(linux) || defined(__uClinux__) || defined(__sun) \
  102         || defined(__APPLE__) || defined(__DARWIN__)
  103   /* Make sure the presence of <windows.h> means compiling for Windows */
  104 #undef HAVE_WINDOWS_H
  105 #endif
  106 
  107 #if defined(__sun) | defined(HAVE_WINDOWS_H)
  108 #define NO_STATFS 1 /* statfs(2) and f_type are not universal */
  109 #endif
  110 
  111 #ifdef HAVE_WINDOWS_H
  112 /*
  113  *      Replacements for functions which do not exist on Windows
  114  */
  115 int setmode(int, int); /* from msvcrt.dll */
  116 
  117 #define getpid() (0)
  118 #define srandom(seed) srand(seed)
  119 #define random() rand()
  120 #define fsync(fd) (0)
  121 #define ioctl(fd,code,buf) (-1)
  122 #define ftruncate(fd, size) ntfs_device_win32_ftruncate(dev_out, size)
  123 #define BINWMODE "wb"
  124 #else
  125 #define BINWMODE "w"
  126 #endif
  127 
  128 #ifndef O_BINARY
  129 #define O_BINARY 0
  130 #endif
  131 
  132 static const char *EXEC_NAME = "ntfsclone";
  133 
  134 static const char *bad_sectors_warning_msg =
  135 "*************************************************************************\n"
  136 "* WARNING: The disk has one or more bad sectors. This means that damage *\n"
  137 "* has occurred on the disk surface, possibly caused by deterioration of *\n"
  138 "* the physical media, manufacturing faults or other reasons. The        *\n"
  139 "* reliability of the disk may stay stable or degrade fast.              *\n"
  140 "* Use the --rescue option to efficiently save as much data as possible! *\n"
  141 "*************************************************************************\n";
  142 
  143 static const char *dirty_volume_msg =
  144 "Volume '%s' is scheduled for a check or it was shutdown \n"
  145 "uncleanly. Please boot Windows or use the --force option to progress.\n";
  146 
  147 static struct {
  148     int verbose;
  149     int quiet;
  150     int debug;
  151     int force;
  152     int overwrite;
  153     int std_out;
  154     int blkdev_out;     /* output file is block device */
  155     int metadata;       /* metadata only cloning */
  156     int no_action;      /* do not really restore */
  157     int ignore_fs_check;
  158     int rescue;
  159     int save_image;
  160     int new_serial;
  161     int metadata_image;
  162     int preserve_timestamps;
  163     int full_logfile;
  164     int restore_image;
  165     char *output;
  166     char *volume;
  167 #ifndef NO_STATFS
  168     struct statfs stfs;
  169 #endif
  170 } opt;
  171 
  172 struct bitmap {
  173     s64 size;
  174     u8 *bm;
  175 };
  176 
  177 struct progress_bar {
  178     u64 start;
  179     u64 stop;
  180     int resolution;
  181     float unit;
  182 };
  183 
  184 typedef struct {
  185     ntfs_inode *ni;         /* inode being processed */
  186     ntfs_attr_search_ctx *ctx;  /* inode attribute being processed */
  187     s64 inuse;          /* number of clusters in use */
  188     int more_use;           /* possibly allocated clusters */
  189     LCN current_lcn;
  190 } ntfs_walk_clusters_ctx;
  191 
  192 typedef int (ntfs_walk_op)(ntfs_inode *ni, void *data);
  193 
  194 struct ntfs_walk_cluster {
  195     ntfs_walk_op *inode_op;     /* not implemented yet */
  196     ntfs_walk_clusters_ctx *image;
  197 };
  198 
  199 
  200 static ntfs_volume *vol = NULL;
  201 static struct bitmap lcn_bitmap;
  202 
  203 static int fd_in;
  204 static int fd_out;
  205 static FILE *stream_out = (FILE*)NULL;
  206 struct ntfs_device *dev_out = (struct ntfs_device*)NULL;
  207 static FILE *msg_out = NULL;
  208 
  209 static int wipe = 0;
  210 static unsigned int nr_used_mft_records   = 0;
  211 static unsigned int wiped_unused_mft_data = 0;
  212 static unsigned int wiped_unused_mft      = 0;
  213 static unsigned int wiped_resident_data   = 0;
  214 static unsigned int wiped_timestamp_data  = 0;
  215 
  216 static le64 volume_serial_number; /* new random serial number */
  217 static u64 full_device_size; /* full size, including the backup boot sector */
  218 
  219 static BOOL image_is_host_endian = FALSE;
  220 
  221 #define IMAGE_MAGIC "\0ntfsclone-image"
  222 #define IMAGE_MAGIC_SIZE 16
  223 #define IMAGE_OFFSET_OFFSET 46 /* must be the same for all versions ! */
  224 #define IMAGE_HDR_ALIGN 8 /* alignment wanted after header */
  225 
  226 /* This is the first endianness safe format version. */
  227 #define NTFSCLONE_IMG_VER_MAJOR_ENDIANNESS_SAFE 10
  228 #define NTFSCLONE_IMG_VER_MINOR_ENDIANNESS_SAFE 0
  229 
  230 /*
  231  * Set the version to 10.0 to avoid colisions with old ntfsclone which
  232  * stupidly used the volume version as the image version...  )-:  I hope NTFS
  233  * never reaches version 10.0 and if it does one day I hope no-one is using
  234  * such an old ntfsclone by then...
  235  *
  236  * NOTE: Only bump the minor version if the image format and header are still
  237  * backwards compatible.  Otherwise always bump the major version.  If in
  238  * doubt, bump the major version.
  239  *
  240  * Moved to 10.1 : Alternate boot sector now saved. Still compatible.
  241  */
  242 #define NTFSCLONE_IMG_VER_MAJOR 10
  243 #define NTFSCLONE_IMG_VER_MINOR 1
  244 
  245 enum { CMD_GAP, CMD_NEXT } ;
  246 
  247 /* All values are in little endian. */
  248 static struct image_hdr {
  249     char magic[IMAGE_MAGIC_SIZE];
  250     u8 major_ver;
  251     u8 minor_ver;
  252     /* the following is aligned dangerously (too late...) */
  253     le32 cluster_size;
  254     le64 device_size;
  255     sle64 nr_clusters;
  256     le64 inuse;
  257     le32 offset_to_image_data;  /* From start of image_hdr. */
  258 } __attribute__((__packed__)) image_hdr;
  259 
  260 static int compare_bitmaps(struct bitmap *a, BOOL copy);
  261 
  262 #define NTFSCLONE_IMG_HEADER_SIZE_OLD   \
  263         (offsetof(struct image_hdr, offset_to_image_data))
  264 
  265 #define NTFS_MBYTE (1000 * 1000)
  266 
  267 #define ERR_PREFIX   "ERROR"
  268 #define PERR_PREFIX  ERR_PREFIX "(%d): "
  269 #define NERR_PREFIX  ERR_PREFIX ": "
  270 
  271 #define LAST_METADATA_INODE 11
  272 
  273 #define NTFS_MAX_CLUSTER_SIZE   65536
  274 #define NTFS_SECTOR_SIZE      512
  275 
  276 #define rounded_up_division(a, b) (((a) + (b - 1)) / (b))
  277 
  278 #define read_all(f, p, n)  io_all((f), (p), (n), 0)
  279 #define write_all(f, p, n) io_all((f), (p), (n), 1)
  280 
  281 __attribute__((format(printf, 1, 2)))
  282 static void Printf(const char *fmt, ...)
  283 {
  284     va_list ap;
  285 
  286     va_start(ap, fmt);
  287     vfprintf(msg_out, fmt, ap);
  288     va_end(ap);
  289     fflush(msg_out);
  290 }
  291 
  292 __attribute__((format(printf, 1, 2)))
  293 static void perr_printf(const char *fmt, ...)
  294 {
  295     va_list ap;
  296     int eo = errno;
  297 
  298     Printf(PERR_PREFIX, eo);
  299     va_start(ap, fmt);
  300     vfprintf(msg_out, fmt, ap);
  301     va_end(ap);
  302     Printf(": %s\n", strerror(eo));
  303     fflush(msg_out);
  304 }
  305 
  306 __attribute__((format(printf, 1, 2)))
  307 static void err_printf(const char *fmt, ...)
  308 {
  309     va_list ap;
  310 
  311     Printf(NERR_PREFIX);
  312     va_start(ap, fmt);
  313     vfprintf(msg_out, fmt, ap);
  314     va_end(ap);
  315     fflush(msg_out);
  316 }
  317 
  318 __attribute__((noreturn))
  319 __attribute__((format(printf, 1, 2)))
  320 static void err_exit(const char *fmt, ...)
  321 {
  322     va_list ap;
  323 
  324     Printf(NERR_PREFIX);
  325     va_start(ap, fmt);
  326     vfprintf(msg_out, fmt, ap);
  327     va_end(ap);
  328     fflush(msg_out);
  329     if (vol)
  330         ntfs_umount(vol,FALSE);
  331     exit(1);
  332 }
  333 
  334 __attribute__((noreturn))
  335 __attribute__((format(printf, 1, 2)))
  336 static void perr_exit(const char *fmt, ...)
  337 {
  338     va_list ap;
  339     int eo = errno;
  340 
  341     Printf(PERR_PREFIX, eo);
  342     va_start(ap, fmt);
  343     vfprintf(msg_out, fmt, ap);
  344     va_end(ap);
  345     Printf(": %s\n", strerror(eo));
  346     fflush(msg_out);
  347     if (vol)
  348         ntfs_umount(vol,FALSE);
  349     exit(1);
  350 }
  351 
  352 
  353 __attribute__((noreturn))
  354 static void usage(int ret)
  355 {
  356     fprintf(stderr, "\nUsage: %s [OPTIONS] SOURCE\n"
  357         "    Efficiently clone NTFS to a sparse file, image, device or standard output.\n"
  358         "\n"
  359         "    -o, --output FILE      Clone NTFS to the non-existent FILE\n"
  360         "    -O, --overwrite FILE   Clone NTFS to FILE, overwriting if exists\n"
  361         "    -s, --save-image       Save to the special image format\n"
  362         "    -r, --restore-image    Restore from the special image format\n"
  363         "        --rescue           Continue after disk read errors\n"
  364         "    -m, --metadata         Clone *only* metadata (for NTFS experts)\n"
  365         "    -n, --no-action        Test restoring, without outputting anything\n"
  366         "        --ignore-fs-check  Ignore the filesystem check result\n"
  367         "        --new-serial       Set a new serial number\n"
  368         "        --new-half-serial  Set a partial new serial number\n"
  369         "    -t, --preserve-timestamps Do not clear the timestamps\n"
  370         "    -q, --quiet            Do not display any progress bars\n"
  371         "    -f, --force            Force to progress (DANGEROUS)\n"
  372         "        --full-logfile     Include the full logfile in metadata output\n"
  373         "    -h, --help             Display this help\n"
  374 #ifdef DEBUG
  375         "    -d, --debug            Show debug information\n"
  376 #endif
  377         "    -V, --version          Display version information\n"
  378         "\n"
  379         "    If FILE is '-' then send the image to the standard output. If SOURCE is '-'\n"
  380         "    and --restore-image is used then read the image from the standard input.\n"
  381         "\n", EXEC_NAME);
  382     fprintf(stderr, "%s%s", ntfs_bugs, ntfs_home);
  383     exit(ret);
  384 }
  385 
  386 /**
  387  * version
  388  */
  389 __attribute__((noreturn))
  390 static void version(void)
  391 {
  392     fprintf(stderr,
  393            "Efficiently clone, image, restore or rescue an NTFS Volume.\n\n"
  394            "Copyright (c) 2003-2006 Szabolcs Szakacsits\n"
  395            "Copyright (c) 2004-2006 Anton Altaparmakov\n"
  396            "Copyright (c) 2010-2016 Jean-Pierre Andre\n\n");
  397     fprintf(stderr, "%s\n%s%s", ntfs_gpl, ntfs_bugs, ntfs_home);
  398     exit(0);
  399 }
  400 
  401 static void parse_options(int argc, char **argv)
  402 {
  403     static const char *sopt = "-dfhmno:O:qrstV";
  404     static const struct option lopt[] = {
  405 #ifdef DEBUG
  406         { "debug",        no_argument,   NULL, 'd' },
  407 #endif
  408         { "quiet",        no_argument,   NULL, 'q' },
  409         { "force",        no_argument,   NULL, 'f' },
  410         { "help",         no_argument,   NULL, 'h' },
  411         { "metadata",         no_argument,   NULL, 'm' },
  412         { "no-action",        no_argument,   NULL, 'n' },
  413         { "output",       required_argument, NULL, 'o' },
  414         { "overwrite",        required_argument, NULL, 'O' },
  415         { "restore-image",    no_argument,   NULL, 'r' },
  416         { "ignore-fs-check",  no_argument,   NULL, 'C' },
  417         { "rescue",           no_argument,   NULL, 'R' },
  418         { "new-serial",       no_argument,   NULL, 'I' },
  419         { "new-half-serial",  no_argument,   NULL, 'i' },
  420         { "full-logfile",     no_argument,   NULL, 'l' },
  421         { "save-image",       no_argument,   NULL, 's' },
  422         { "preserve-timestamps",   no_argument,  NULL, 't' },
  423         { "version",          no_argument,   NULL, 'V' },
  424         { NULL, 0, NULL, 0 }
  425     };
  426 
  427     int c;
  428 
  429     memset(&opt, 0, sizeof(opt));
  430 
  431     while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
  432         switch (c) {
  433         case 1: /* A non-option argument */
  434             if (opt.volume)
  435                 usage(1);
  436             opt.volume = argv[optind-1];
  437             break;
  438         case 'd':
  439             opt.debug++;
  440             break;
  441         case 'q':
  442             opt.quiet++;
  443             break;
  444         case 'f':
  445             opt.force++;
  446             break;
  447         case 'h':
  448             usage(0);
  449         case '?':
  450             usage(1);
  451         case 'i':   /* not proposed as a short option */
  452             opt.new_serial |= 1;
  453             break;
  454         case 'I':   /* not proposed as a short option */
  455             opt.new_serial |= 2;
  456             break;
  457         case 'l':
  458             opt.full_logfile++;
  459             break;
  460         case 'm':
  461             opt.metadata++;
  462             break;
  463         case 'n':
  464             opt.no_action++;
  465             break;
  466         case 'O':
  467             opt.overwrite++;
  468         case 'o':
  469             if (opt.output)
  470                 usage(1);
  471             opt.output = optarg;
  472             break;
  473         case 'r':
  474             opt.restore_image++;
  475             break;
  476         case 'C':
  477             opt.ignore_fs_check++;
  478             break;
  479         case 'R':
  480             opt.rescue++;
  481             break;
  482         case 's':
  483             opt.save_image++;
  484             break;
  485         case 't':
  486             opt.preserve_timestamps++;
  487             break;
  488         case 'V':
  489             version();
  490             break;
  491         default:
  492             err_printf("Unknown option '%s'.\n", argv[optind-1]);
  493             usage(1);
  494         }
  495     }
  496 
  497     if (!opt.no_action && (opt.output == NULL)) {
  498         err_printf("You must specify an output file.\n");
  499         usage(1);
  500     }
  501 
  502     if (!opt.no_action && (strcmp(opt.output, "-") == 0))
  503         opt.std_out++;
  504 
  505     if (opt.volume == NULL) {
  506         err_printf("You must specify a device file.\n");
  507         usage(1);
  508     }
  509 
  510     if (!opt.restore_image && !strcmp(opt.volume, "-")) {
  511         err_printf("Only special images can be read from standard input\n");
  512         usage(1);
  513     }
  514 
  515     if (opt.metadata && opt.save_image) {
  516         opt.metadata_image++;
  517         opt.save_image = 0;
  518     }
  519 
  520     if (opt.metadata && opt.restore_image)
  521         err_exit("Restoring only metadata from an image is not "
  522              "supported!\n");
  523 
  524     if (opt.metadata && !opt.metadata_image && opt.std_out)
  525         err_exit("Cloning only metadata to stdout isn't supported!\n");
  526 
  527     if (opt.ignore_fs_check && !opt.metadata && !opt.rescue)
  528         err_exit("Filesystem check can be ignored only for metadata "
  529              "cloning or rescue situations!\n");
  530 
  531     if (opt.save_image && opt.restore_image)
  532         err_exit("Saving and restoring an image at the same time "
  533              "is not supported!\n");
  534 
  535     if (opt.no_action && !opt.restore_image)
  536         err_exit("A restoring test requires the restore option!\n");
  537 
  538     if (opt.no_action && opt.output)
  539         err_exit("A restoring test requires not defining any output!\n");
  540 
  541     if (!opt.no_action && !opt.std_out) {
  542         struct stat st;
  543 #ifdef HAVE_WINDOWS_H
  544         BOOL blkdev = opt.output[0] && (opt.output[1] == ':')
  545                     && !opt.output[2];
  546 
  547         if (!blkdev && (stat(opt.output, &st) == -1)) {
  548 #else
  549         if (stat(opt.output, &st) == -1) {
  550 #endif
  551             if (errno != ENOENT)
  552                 perr_exit("Couldn't access '%s'", opt.output);
  553         } else {
  554             if (!opt.overwrite)
  555                 err_exit("Output file '%s' already exists.\n"
  556                      "Use option --overwrite if you want to"
  557                      " replace its content.\n", opt.output);
  558 
  559 #ifdef HAVE_WINDOWS_H
  560             if (blkdev) {
  561 #else
  562             if (S_ISBLK(st.st_mode)) {
  563 #endif
  564                 opt.blkdev_out = 1;
  565                 if (opt.metadata && !opt.force)
  566                     err_exit("Cloning only metadata to a "
  567                          "block device does not usually "
  568                          "make sense, aborting...\n"
  569                          "If you were instructed to do "
  570                          "this by a developer and/or are "
  571                          "sure that this is what you want "
  572                          "to do, run this utility again "
  573                          "but this time add the force "
  574                          "option, i.e. add '--force' to "
  575                          "the command line arguments.");
  576             }
  577         }
  578     }
  579 
  580     /*
  581      * Send messages, debug information and library messages to stdout,
  582      * but, if outputing to stdout send them to stderr
  583      */
  584     if (opt.std_out) {
  585         msg_out = stderr;
  586         ntfs_log_set_handler(ntfs_log_handler_stderr);
  587     } else {
  588         msg_out = stdout;
  589         ntfs_log_set_handler(ntfs_log_handler_outerr);
  590     }
  591 }
  592 
  593 /*
  594  * Initialize the random number generator with the current
  595  * time, and generate a 64-bit random number for the serial
  596  * number
  597  */
  598 static void generate_serial_number(void) {
  599     u64 sn;
  600 
  601         /* different values for parallel processes */
  602     srandom(time((time_t*)NULL) ^ (getpid() << 16));
  603     sn = ((u64)random() << 32) | ((u64)random() & 0xffffffff);
  604     volume_serial_number = cpu_to_le64(sn);
  605 }
  606 
  607 static void progress_init(struct progress_bar *p, u64 start, u64 stop, int res)
  608 {
  609     p->start = start;
  610     p->stop = stop;
  611     p->unit = 100.0 / (stop - start);
  612     p->resolution = res;
  613 }
  614 
  615 
  616 static void progress_update(struct progress_bar *p, u64 current)
  617 {
  618     float percent = p->unit * current;
  619 
  620     if (opt.quiet)
  621         return;
  622 
  623     if (current != p->stop) {
  624         if ((current - p->start) % p->resolution)
  625             return;
  626         Printf("%6.2f percent completed\r", percent);
  627     } else
  628         Printf("100.00 percent completed\n");
  629     fflush(msg_out);
  630 }
  631 
  632 static s64 is_critical_metadata(ntfs_walk_clusters_ctx *image, runlist *rl)
  633 {
  634     s64 inode = image->ni->mft_no;
  635 
  636     if (inode <= LAST_METADATA_INODE) {
  637 
  638         /* Don't save bad sectors (both $Bad and unnamed are ignored */
  639         if (inode == FILE_BadClus && image->ctx->attr->type == AT_DATA)
  640             return 0;
  641 
  642         if ((inode != FILE_LogFile) || opt.full_logfile)
  643             return rl->length;
  644 
  645         if (image->ctx->attr->type == AT_DATA) {
  646 
  647             /* Save at least the first 16 KiB of FILE_LogFile */
  648             s64 s = (s64)16384 - rl->vcn * vol->cluster_size;
  649             if (s > 0) {
  650                 s = rounded_up_division(s, vol->cluster_size);
  651                 if (rl->length < s)
  652                     s = rl->length;
  653                 return s;
  654             }
  655             return 0;
  656         }
  657     }
  658 
  659     if (image->ctx->attr->type != AT_DATA)
  660         return rl->length;
  661 
  662     return 0;
  663 }
  664 
  665 static off_t tellin(int in)
  666 {
  667     return (lseek(in, 0, SEEK_CUR));
  668 }
  669 
  670 static int io_all(void *fd, void *buf, int count, int do_write)
  671 {
  672     int i;
  673     struct ntfs_device *dev = fd;
  674 
  675     while (count > 0) {
  676         if (do_write) {
  677             if (opt.no_action) {
  678                 i = count;
  679             } else {
  680                 if (opt.save_image || opt.metadata_image)
  681                     i = fwrite(buf, 1, count, stream_out);
  682 #ifdef HAVE_WINDOWS_H
  683                 else if (dev_out)
  684                     i = dev_out->d_ops->write(dev_out,
  685                                 buf, count);
  686 #endif
  687                 else
  688                     i = write(*(int *)fd, buf, count);
  689             }
  690         } else if (opt.restore_image)
  691             i = read(*(int *)fd, buf, count);
  692         else
  693             i = dev->d_ops->read(dev, buf, count);
  694         if (i < 0) {
  695             if (errno != EAGAIN && errno != EINTR)
  696                 return -1;
  697         } else if (i == 0 && !do_write && opt.restore_image) {
  698             return -1;
  699         } else {
  700             count -= i;
  701             buf = i + (char *) buf;
  702         }
  703     }
  704     return 0;
  705 }
  706 
  707 
  708 static void rescue_sector(void *fd, u32 bytes_per_sector, off_t pos, void *buff)
  709 {
  710     const char badsector_magic[] = "BadSectoR";
  711     struct ntfs_device *dev = fd;
  712 
  713     if (opt.restore_image) {
  714         if (!opt.no_action
  715             && (lseek(*(int *)fd, pos, SEEK_SET) == (off_t)-1))
  716             perr_exit("lseek");
  717     } else {
  718         if (vol->dev->d_ops->seek(dev, pos, SEEK_SET) == (off_t)-1)
  719             perr_exit("seek input");
  720     }
  721 
  722     if (read_all(fd, buff, bytes_per_sector) == -1) {
  723         Printf("WARNING: Can't read sector at %llu, lost data.\n",
  724             (unsigned long long)pos);
  725         memset(buff, '?', bytes_per_sector);
  726         memmove(buff, badsector_magic, sizeof(badsector_magic));
  727     }
  728 }
  729 
  730 /*
  731  *      Read a cluster, try to rescue if cannot read
  732  */
  733 
  734 static void read_rescue(void *fd, char *buff, u32 csize, u32 bytes_per_sector,
  735                 u64 rescue_lcn)
  736 {
  737     off_t rescue_pos;
  738 
  739     if (read_all(fd, buff, csize) == -1) {
  740 
  741         if (errno != EIO)
  742             perr_exit("read_all");
  743         else if (opt.rescue){
  744             u32 i;
  745 
  746             rescue_pos = (off_t)(rescue_lcn * csize);
  747             for (i = 0; i < csize; i += bytes_per_sector)
  748                 rescue_sector(fd, bytes_per_sector,
  749                         rescue_pos + i, buff + i);
  750         } else {
  751             Printf("%s", bad_sectors_warning_msg);
  752             err_exit("Disk is faulty, can't make full backup!");
  753         }
  754     }
  755 }
  756 
  757 static void copy_cluster(int rescue, u64 rescue_lcn, u64 lcn)
  758 {
  759     char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
  760     /* vol is NULL if opt.restore_image is set */
  761     s32 csize = le32_to_cpu(image_hdr.cluster_size);
  762     BOOL backup_bootsector;
  763     void *fd = (void *)&fd_in;
  764     off_t rescue_pos;
  765     NTFS_BOOT_SECTOR *bs;
  766     le64 mask;
  767     static u16 bytes_per_sector = NTFS_SECTOR_SIZE;
  768 
  769     if (!opt.restore_image) {
  770         csize = vol->cluster_size;
  771         bytes_per_sector = vol->sector_size;
  772         fd = vol->dev;
  773     }
  774 
  775     rescue_pos = (off_t)(rescue_lcn * csize);
  776 
  777         /* possible partial cluster holding the backup boot sector */
  778     backup_bootsector = (lcn + 1)*csize >= full_device_size;
  779     if (backup_bootsector) {
  780         csize = full_device_size - lcn*csize;
  781         if (csize < 0) {
  782             err_exit("Corrupted input, copy aborted");
  783         }
  784     }
  785 
  786 // need reading when not about to write ?
  787     if (read_all(fd, buff, csize) == -1) {
  788 
  789         if (errno != EIO) {
  790             if (!errno && opt.restore_image)
  791                 err_exit("Short image file...\n");
  792             else
  793                 perr_exit("read_all");
  794         }
  795         else if (rescue){
  796             s32 i;
  797             for (i = 0; i < csize; i += bytes_per_sector)
  798                 rescue_sector(fd, bytes_per_sector,
  799                         rescue_pos + i, buff + i);
  800         } else {
  801             Printf("%s", bad_sectors_warning_msg);
  802             err_exit("Disk is faulty, can't make full backup!");
  803         }
  804     }
  805 
  806         /* Set the new serial number if requested */
  807     if (opt.new_serial
  808         && !opt.save_image
  809         && (!lcn || backup_bootsector)) {
  810             /*
  811              * For updating the backup boot sector, we need to
  812              * know the sector size, but this is not recorded
  813              * in the image header, so we collect it on the fly
  814              * while reading the first boot sector.
  815              */
  816         if (!lcn) {
  817             bs = (NTFS_BOOT_SECTOR*)buff;
  818             bytes_per_sector = le16_to_cpu(bs->bpb.bytes_per_sector);
  819             if ((bytes_per_sector > csize)
  820                 || (bytes_per_sector < NTFS_SECTOR_SIZE))
  821                 bytes_per_sector = NTFS_SECTOR_SIZE;
  822         } else
  823             bs = (NTFS_BOOT_SECTOR*)(buff
  824                         + csize - bytes_per_sector);
  825         if (opt.new_serial & 2)
  826             bs->volume_serial_number = volume_serial_number;
  827         else {
  828             mask = const_cpu_to_le64(~0x0ffffffffULL);
  829             bs->volume_serial_number
  830                 = (volume_serial_number & mask)
  831                 | (bs->volume_serial_number & ~mask);
  832         }
  833             /* Show the new full serial after merging */
  834         if (!lcn)
  835             Printf("New serial number      : 0x%llx\n",
  836                 (long long)le64_to_cpu(
  837                         bs->volume_serial_number));
  838     }
  839 
  840     if (opt.save_image || (opt.metadata_image && wipe)) {
  841         char cmd = CMD_NEXT;
  842         if (write_all(&fd_out, &cmd, sizeof(cmd)) == -1)
  843             perr_exit("write_all");
  844     }
  845 
  846     if ((!opt.metadata_image || wipe)
  847         && (write_all(&fd_out, buff, csize) == -1)) {
  848 #ifndef NO_STATFS
  849         int err = errno;
  850         perr_printf("Write failed");
  851         if (err == EIO && opt.stfs.f_type == 0x517b)
  852             Printf("Apparently you tried to clone to a remote "
  853                    "Windows computer but they don't\nhave "
  854                    "efficient sparse file handling by default. "
  855                    "Please try a different method.\n");
  856         exit(1);
  857 #else
  858         perr_printf("Write failed");
  859 #endif
  860     }
  861 }
  862 
  863 static s64 lseek_out(int fd, s64 pos, int mode)
  864 {
  865     s64 ret;
  866 
  867     if (dev_out)
  868         ret = (dev_out->d_ops->seek)(dev_out, pos, mode);
  869     else
  870         ret = lseek(fd, pos, mode);
  871     return (ret);
  872 }
  873 
  874 static void lseek_to_cluster(s64 lcn)
  875 {
  876     off_t pos;
  877 
  878     pos = (off_t)(lcn * vol->cluster_size);
  879 
  880     if (vol->dev->d_ops->seek(vol->dev, pos, SEEK_SET) == (off_t)-1)
  881         perr_exit("lseek input");
  882 
  883     if (opt.std_out || opt.save_image || opt.metadata_image)
  884         return;
  885 
  886     if (lseek_out(fd_out, pos, SEEK_SET) == (off_t)-1)
  887             perr_exit("lseek output");
  888 }
  889 
  890 static void gap_to_cluster(s64 gap)
  891 {
  892     sle64 count;
  893     char buf[1 + sizeof(count)];
  894 
  895     if (gap) {
  896         count = cpu_to_sle64(gap);
  897         buf[0] = CMD_GAP;
  898         memcpy(&buf[1], &count, sizeof(count));
  899         if (write_all(&fd_out, buf, sizeof(buf)) == -1)
  900             perr_exit("write_all");
  901     }
  902 }
  903 
  904 static void image_skip_clusters(s64 count)
  905 {
  906     if (opt.save_image && count > 0) {
  907         sle64 count_buf;
  908         char buff[1 + sizeof(count)];
  909 
  910         buff[0] = CMD_GAP;
  911         count_buf = cpu_to_sle64(count);
  912         memcpy(buff + 1, &count_buf, sizeof(count_buf));
  913 
  914         if (write_all(&fd_out, buff, sizeof(buff)) == -1)
  915             perr_exit("write_all");
  916     }
  917 }
  918 
  919 static void write_image_hdr(void)
  920 {
  921     char alignment[IMAGE_HDR_ALIGN];
  922 
  923     if (opt.save_image || opt.metadata_image) {
  924         int alignsize = le32_to_cpu(image_hdr.offset_to_image_data)
  925                 - sizeof(image_hdr);
  926         memset(alignment,0,IMAGE_HDR_ALIGN);
  927         if ((alignsize < 0)
  928             || write_all(&fd_out, &image_hdr, sizeof(image_hdr))
  929             || write_all(&fd_out, alignment, alignsize))
  930             perr_exit("write_all");
  931     }
  932 }
  933 
  934 static void clone_ntfs(u64 nr_clusters, int more_use)
  935 {
  936     u64 cl, last_cl;  /* current and last used cluster */
  937     void *buf;
  938     u32 csize = vol->cluster_size;
  939     u64 p_counter = 0;
  940     char alignment[IMAGE_HDR_ALIGN];
  941     struct progress_bar progress;
  942 
  943     if (opt.save_image)
  944         Printf("Saving NTFS to image ...\n");
  945     else
  946         Printf("Cloning NTFS ...\n");
  947 
  948     if (opt.new_serial)
  949         generate_serial_number();
  950 
  951     buf = ntfs_calloc(csize);
  952     if (!buf)
  953         perr_exit("clone_ntfs");
  954 
  955     progress_init(&progress, p_counter, nr_clusters, 100);
  956 
  957     if (opt.save_image) {
  958         int alignsize = le32_to_cpu(image_hdr.offset_to_image_data)
  959                 - sizeof(image_hdr);
  960         memset(alignment,0,IMAGE_HDR_ALIGN);
  961         if ((alignsize < 0)
  962             || write_all(&fd_out, &image_hdr, sizeof(image_hdr))
  963             || write_all(&fd_out, alignment, alignsize))
  964             perr_exit("write_all");
  965     }
  966 
  967         /* save suspicious clusters if required */
  968     if (more_use && opt.ignore_fs_check) {
  969         compare_bitmaps(&lcn_bitmap, TRUE);
  970     }
  971         /* Examine up to the alternate boot sector */
  972     for (last_cl = cl = 0; cl <= (u64)vol->nr_clusters; cl++) {
  973 
  974         if (ntfs_bit_get(lcn_bitmap.bm, cl)) {
  975             progress_update(&progress, ++p_counter);
  976             lseek_to_cluster(cl);
  977             image_skip_clusters(cl - last_cl - 1);
  978 
  979             copy_cluster(opt.rescue, cl, cl);
  980             last_cl = cl;
  981             continue;
  982         }
  983 
  984         if (opt.std_out && !opt.save_image) {
  985             progress_update(&progress, ++p_counter);
  986             if (write_all(&fd_out, buf, csize) == -1)
  987                 perr_exit("write_all");
  988         }
  989     }
  990     image_skip_clusters(cl - last_cl - 1);
  991     free(buf);
  992 }
  993 
  994 static void write_empty_clusters(s32 csize, s64 count,
  995                  struct progress_bar *progress, u64 *p_counter)
  996 {
  997     s64 i;
  998     char buff[NTFS_MAX_CLUSTER_SIZE];
  999 
 1000     memset(buff, 0, csize);
 1001 
 1002     for (i = 0; i < count; i++) {
 1003         if (write_all(&fd_out, buff, csize) == -1)
 1004             perr_exit("write_all");
 1005         progress_update(progress, ++(*p_counter));
 1006     }
 1007 }
 1008 
 1009 static void restore_image(void)
 1010 {
 1011     s64 pos = 0, count;
 1012     s32 csize = le32_to_cpu(image_hdr.cluster_size);
 1013     char cmd;
 1014     u64 p_counter = 0;
 1015     struct progress_bar progress;
 1016 
 1017     Printf("Restoring NTFS from image ...\n");
 1018 
 1019     progress_init(&progress, p_counter, opt.std_out ?
 1020               (u64)sle64_to_cpu(image_hdr.nr_clusters) + 1 :
 1021               le64_to_cpu(image_hdr.inuse) + 1,
 1022               100);
 1023 
 1024     if (opt.new_serial)
 1025         generate_serial_number();
 1026 
 1027         /* Restore up to the alternate boot sector */
 1028     while (pos <= sle64_to_cpu(image_hdr.nr_clusters)) {
 1029         if (read_all(&fd_in, &cmd, sizeof(cmd)) == -1) {
 1030             if (pos == sle64_to_cpu(image_hdr.nr_clusters)) {
 1031                 /* alternate boot sector no present in old images */
 1032                 Printf("Warning : no alternate boot"
 1033                         " sector in image\n");
 1034                 break;
 1035             } else
 1036                 perr_exit("read_all");
 1037         }
 1038 
 1039         if (cmd == CMD_GAP) {
 1040             if (!image_is_host_endian) {
 1041                 sle64 lecount;
 1042 
 1043                 /* little endian image, on any computer */
 1044                 if (read_all(&fd_in, &lecount,
 1045                         sizeof(lecount)) == -1)
 1046                     perr_exit("read_all");
 1047                 count = sle64_to_cpu(lecount);
 1048             } else {
 1049                 /* big endian image on big endian computer */
 1050                 if (read_all(&fd_in, &count,
 1051                         sizeof(count)) == -1)
 1052                     perr_exit("read_all");
 1053             }
 1054             if (!count)
 1055                 err_exit("Bad offset at input location 0x%llx\n",
 1056                     (long long)tellin(fd_in) - 9);
 1057             if (opt.std_out) {
 1058                 if ((!p_counter && count) || (count < 0))
 1059                     err_exit("Cannot restore a metadata"
 1060                         " image to stdout\n");
 1061                 else
 1062                     write_empty_clusters(csize, count,
 1063                              &progress, &p_counter);
 1064             } else {
 1065                 if (((pos + count) < 0)
 1066                    || ((pos + count)
 1067                     > sle64_to_cpu(image_hdr.nr_clusters)))
 1068                     err_exit("restore_image: corrupt image "
 1069                         "at input offset %lld\n",
 1070                         (long long)tellin(fd_in) - 9);
 1071                 else {
 1072                     if (!opt.no_action
 1073                         && (lseek_out(fd_out, count * csize,
 1074                             SEEK_CUR) == (off_t)-1))
 1075                         perr_exit("restore_image: lseek");
 1076                 }
 1077             }
 1078             pos += count;
 1079         } else if (cmd == CMD_NEXT) {
 1080             copy_cluster(0, 0, pos);
 1081             pos++;
 1082             progress_update(&progress, ++p_counter);
 1083         } else
 1084             err_exit("Invalid command code %d at input offset 0x%llx\n",
 1085                     cmd, (long long)tellin(fd_in) - 1);
 1086     }
 1087 }
 1088 
 1089 static void wipe_index_entry_timestams(INDEX_ENTRY *e)
 1090 {
 1091     static const struct timespec zero_time = { .tv_sec = 0, .tv_nsec = 0 };
 1092     sle64 timestamp = timespec2ntfs(zero_time);
 1093 
 1094     /* FIXME: can fall into infinite loop if corrupted */
 1095     while (!(e->ie_flags & INDEX_ENTRY_END)) {
 1096 
 1097         e->key.file_name.creation_time = timestamp;
 1098         e->key.file_name.last_data_change_time = timestamp;
 1099         e->key.file_name.last_mft_change_time = timestamp;
 1100         e->key.file_name.last_access_time = timestamp;
 1101 
 1102         wiped_timestamp_data += 32;
 1103 
 1104         e = (INDEX_ENTRY *)((u8 *)e + le16_to_cpu(e->length));
 1105     }
 1106 }
 1107 
 1108 static void wipe_index_allocation_timestamps(ntfs_inode *ni, ATTR_RECORD *attr)
 1109 {
 1110     INDEX_ALLOCATION *indexa, *tmp_indexa;
 1111     INDEX_ENTRY *entry;
 1112     INDEX_ROOT *indexr;
 1113     u8 *bitmap, *byte;
 1114     int bit;
 1115     ntfs_attr *na;
 1116     ntfschar *name;
 1117     u32 name_len;
 1118 
 1119     indexr = ntfs_index_root_get(ni, attr);
 1120     if (!indexr) {
 1121         perr_printf("Failed to read $INDEX_ROOT attribute of inode "
 1122                 "%lld", (long long)ni->mft_no);
 1123         return;
 1124     }
 1125 
 1126     if (indexr->type != AT_FILE_NAME)
 1127         goto out_indexr;
 1128 
 1129     name = (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset));
 1130     name_len = attr->name_length;
 1131 
 1132     byte = bitmap = ntfs_attr_readall(ni, AT_BITMAP, name, name_len,
 1133                         NULL);
 1134     if (!byte) {
 1135         perr_printf("Failed to read $BITMAP attribute");
 1136         goto out_indexr;
 1137     }
 1138 
 1139     na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, name, name_len);
 1140     if (!na) {
 1141         perr_printf("Failed to open $INDEX_ALLOCATION attribute");
 1142         goto out_bitmap;
 1143     }
 1144 
 1145     if (!na->data_size)
 1146         goto out_na;
 1147 
 1148     tmp_indexa = indexa = ntfs_malloc(na->data_size);
 1149     if (!tmp_indexa)
 1150         goto out_na;
 1151 
 1152     if (ntfs_attr_pread(na, 0, na->data_size, indexa) != na->data_size) {
 1153         perr_printf("Failed to read $INDEX_ALLOCATION attribute");
 1154         goto out_indexa;
 1155     }
 1156 
 1157     bit = 0;
 1158     while ((u8 *)tmp_indexa < (u8 *)indexa + na->data_size) {
 1159         if (*byte & (1 << bit)) {
 1160             if (ntfs_mst_post_read_fixup((NTFS_RECORD *)tmp_indexa,
 1161                     le32_to_cpu(
 1162                     indexr->index_block_size))) {
 1163                 perr_printf("Damaged INDX record");
 1164                 goto out_indexa;
 1165             }
 1166             entry = (INDEX_ENTRY *)((u8 *)tmp_indexa + le32_to_cpu(
 1167                 tmp_indexa->index.entries_offset) + 0x18);
 1168 
 1169             wipe_index_entry_timestams(entry);
 1170 
 1171             if (ntfs_mft_usn_dec((MFT_RECORD *)tmp_indexa))
 1172                 perr_exit("ntfs_mft_usn_dec");
 1173 
 1174             if (ntfs_mst_pre_write_fixup((NTFS_RECORD *)tmp_indexa,
 1175                     le32_to_cpu(
 1176                     indexr->index_block_size))) {
 1177                 perr_printf("INDX write fixup failed");
 1178                 goto out_indexa;
 1179             }
 1180         }
 1181         tmp_indexa = (INDEX_ALLOCATION *)((u8 *)tmp_indexa +
 1182                 le32_to_cpu(indexr->index_block_size));
 1183         bit++;
 1184         if (bit > 7) {
 1185             bit = 0;
 1186             byte++;
 1187         }
 1188     }
 1189     if (ntfs_rl_pwrite(vol, na->rl, 0, 0, na->data_size, indexa) != na->data_size)
 1190         perr_printf("ntfs_rl_pwrite failed for inode %lld",
 1191                 (long long)ni->mft_no);
 1192 out_indexa:
 1193     free(indexa);
 1194 out_na:
 1195     ntfs_attr_close(na);
 1196 out_bitmap:
 1197     free(bitmap);
 1198 out_indexr:
 1199     free(indexr);
 1200 }
 1201 
 1202 static void wipe_index_root_timestamps(ATTR_RECORD *attr, sle64 timestamp)
 1203 {
 1204     INDEX_ENTRY *entry;
 1205     INDEX_ROOT *iroot;
 1206 
 1207     iroot = (INDEX_ROOT *)((u8 *)attr + le16_to_cpu(attr->value_offset));
 1208     entry = (INDEX_ENTRY *)((u8 *)iroot +
 1209             le32_to_cpu(iroot->index.entries_offset) + 0x10);
 1210 
 1211     while (!(entry->ie_flags & INDEX_ENTRY_END)) {
 1212 
 1213         if (iroot->type == AT_FILE_NAME) {
 1214 
 1215             entry->key.file_name.creation_time = timestamp;
 1216             entry->key.file_name.last_access_time = timestamp;
 1217             entry->key.file_name.last_data_change_time = timestamp;
 1218             entry->key.file_name.last_mft_change_time = timestamp;
 1219 
 1220             wiped_timestamp_data += 32;
 1221 
 1222         } else if (ntfs_names_are_equal(NTFS_INDEX_Q,
 1223                 sizeof(NTFS_INDEX_Q) / 2 - 1,
 1224                 (ntfschar *)((char *)attr +
 1225                         le16_to_cpu(attr->name_offset)),
 1226                 attr->name_length, CASE_SENSITIVE, NULL, 0)) {
 1227 
 1228             QUOTA_CONTROL_ENTRY *quota_q;
 1229 
 1230             quota_q = (QUOTA_CONTROL_ENTRY *)((u8 *)entry +
 1231                     le16_to_cpu(entry->data_offset));
 1232             /*
 1233              *  FIXME: no guarantee it's indeed /$Extend/$Quota:$Q.
 1234              *  For now, as a minimal safeguard, we check only for
 1235              *  quota version 2 ...
 1236              */
 1237             if (le32_to_cpu(quota_q->version) == 2) {
 1238                 quota_q->change_time = timestamp;
 1239                 wiped_timestamp_data += 4;
 1240             }
 1241         }
 1242 
 1243         entry = (INDEX_ENTRY*)((u8*)entry + le16_to_cpu(entry->length));
 1244     }
 1245 }
 1246 
 1247 #define WIPE_TIMESTAMPS(atype, attr, timestamp)         \
 1248 do {                                \
 1249     atype *ats;                     \
 1250     ats = (atype *)((char *)(attr) + le16_to_cpu((attr)->value_offset)); \
 1251                                 \
 1252     ats->creation_time = (timestamp);               \
 1253     ats->last_data_change_time = (timestamp);       \
 1254     ats->last_mft_change_time= (timestamp);         \
 1255     ats->last_access_time = (timestamp);            \
 1256                                 \
 1257     wiped_timestamp_data += 32;             \
 1258                                 \
 1259 } while (0)
 1260 
 1261 static void wipe_timestamps(ntfs_walk_clusters_ctx *image)
 1262 {
 1263     static const struct timespec zero_time = { .tv_sec = 0, .tv_nsec = 0 };
 1264     ATTR_RECORD *a = image->ctx->attr;
 1265     sle64 timestamp = timespec2ntfs(zero_time);
 1266 
 1267     if (a->type == AT_FILE_NAME)
 1268         WIPE_TIMESTAMPS(FILE_NAME_ATTR, a, timestamp);
 1269 
 1270     else if (a->type == AT_STANDARD_INFORMATION)
 1271         WIPE_TIMESTAMPS(STANDARD_INFORMATION, a, timestamp);
 1272 
 1273     else if (a->type == AT_INDEX_ROOT)
 1274         wipe_index_root_timestamps(a, timestamp);
 1275 }
 1276 
 1277 static void wipe_resident_data(ntfs_walk_clusters_ctx *image)
 1278 {
 1279     ATTR_RECORD *a;
 1280     u32 i;
 1281     int n = 0;
 1282     u8 *p;
 1283 
 1284     a = image->ctx->attr;
 1285     p = (u8*)a + le16_to_cpu(a->value_offset);
 1286 
 1287     if (image->ni->mft_no <= LAST_METADATA_INODE)
 1288         return;
 1289 
 1290     if (a->type != AT_DATA)
 1291         return;
 1292 
 1293     for (i = 0; i < le32_to_cpu(a->value_length); i++) {
 1294         if (p[i]) {
 1295             p[i] = 0;
 1296             n++;
 1297         }
 1298     }
 1299 
 1300     wiped_resident_data += n;
 1301 }
 1302 
 1303 static int wipe_data(char *p, int pos, int len)
 1304 {
 1305     int wiped = 0;
 1306 
 1307     for (p += pos; --len >= 0;) {
 1308         if (p[len]) {
 1309             p[len] = 0;
 1310             wiped++;
 1311         }
 1312     }
 1313 
 1314     return wiped;
 1315 }
 1316 
 1317 static void wipe_unused_mft_data(ntfs_inode *ni)
 1318 {
 1319     int unused;
 1320     MFT_RECORD *m = ni->mrec;
 1321 
 1322     /* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
 1323     if (ni->mft_no <= LAST_METADATA_INODE)
 1324         return;
 1325 
 1326     unused = le32_to_cpu(m->bytes_allocated) - le32_to_cpu(m->bytes_in_use);
 1327     wiped_unused_mft_data += wipe_data((char *)m,
 1328             le32_to_cpu(m->bytes_in_use), unused);
 1329 }
 1330 
 1331 static void wipe_unused_mft(ntfs_inode *ni)
 1332 {
 1333     int unused;
 1334     MFT_RECORD *m = ni->mrec;
 1335 
 1336     /* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
 1337     if (ni->mft_no <= LAST_METADATA_INODE)
 1338         return;
 1339 
 1340     unused = le32_to_cpu(m->bytes_in_use) - sizeof(MFT_RECORD);
 1341     wiped_unused_mft += wipe_data((char *)m, sizeof(MFT_RECORD), unused);
 1342 }
 1343 
 1344 static void clone_logfile_parts(ntfs_walk_clusters_ctx *image, runlist *rl)
 1345 {
 1346     s64 offset = 0, lcn, vcn;
 1347 
 1348     while (1) {
 1349 
 1350         vcn = offset / image->ni->vol->cluster_size;
 1351         lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
 1352         if (lcn < 0)
 1353             break;
 1354 
 1355         lseek_to_cluster(lcn);
 1356 
 1357         if ((lcn + 1) != image->current_lcn) {
 1358             /* do not duplicate a cluster */
 1359             if (opt.metadata_image && wipe)
 1360                 gap_to_cluster(lcn - image->current_lcn);
 1361 
 1362             copy_cluster(opt.rescue, lcn, lcn);
 1363         }
 1364         image->current_lcn = lcn + 1;
 1365         if (opt.metadata_image && !wipe)
 1366             image->inuse++;
 1367 
 1368         if (offset == 0)
 1369             offset = NTFS_BLOCK_SIZE >> 1;
 1370         else
 1371             offset <<= 1;
 1372     }
 1373 }
 1374 
 1375 /*
 1376  *      In-memory wiping of MFT record or MFTMirr record
 1377  *  (only for metadata images)
 1378  *
 1379  *  The resident data and (optionally) the timestamps are wiped.
 1380  */
 1381 
 1382 static void wipe_mft(char *mrec, u32 mrecsz, u64 mft_no)
 1383 {
 1384     ntfs_walk_clusters_ctx image;
 1385     ntfs_attr_search_ctx *ctx;
 1386     ntfs_inode ni;
 1387 
 1388     ni.mft_no = mft_no;
 1389     ni.mrec = (MFT_RECORD*)mrec;
 1390     ni.vol = vol; /* Hmm */
 1391     image.ni = &ni;
 1392     ntfs_mst_post_read_fixup_warn((NTFS_RECORD*)mrec,mrecsz,FALSE);
 1393     wipe_unused_mft_data(&ni);
 1394     if (!(((MFT_RECORD*)mrec)->flags & MFT_RECORD_IN_USE)) {
 1395         wipe_unused_mft(&ni);
 1396     } else {
 1397             /* ctx with no ntfs_inode prevents from searching external attrs */
 1398         if (!(ctx = ntfs_attr_get_search_ctx((ntfs_inode*)NULL, (MFT_RECORD*)mrec)))
 1399             perr_exit("ntfs_get_attr_search_ctx");
 1400 
 1401         while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, CASE_SENSITIVE, 0,
 1402                         NULL, 0, ctx)) {
 1403             if (ctx->attr->type == AT_END)
 1404                 break;
 1405 
 1406             image.ctx = ctx;
 1407             if (!ctx->attr->non_resident
 1408                 && (mft_no > LAST_METADATA_INODE))
 1409                 wipe_resident_data(&image);
 1410             if (!opt.preserve_timestamps)
 1411                 wipe_timestamps(&image);
 1412         }
 1413         ntfs_attr_put_search_ctx(ctx);
 1414     }
 1415     ntfs_mft_usn_dec((MFT_RECORD*)mrec);
 1416     ntfs_mst_pre_write_fixup((NTFS_RECORD*)mrec,mrecsz);
 1417 }
 1418 
 1419 /*
 1420  *      In-memory wiping of a directory record (I30)
 1421  *  (only for metadata images)
 1422  *
 1423  *  The timestamps are (optionally) wiped
 1424  */
 1425 
 1426 static void wipe_indx(char *mrec, u32 mrecsz)
 1427 {
 1428     INDEX_ENTRY *entry;
 1429     INDEX_ALLOCATION *indexa;
 1430 
 1431     if (ntfs_mst_post_read_fixup((NTFS_RECORD *)mrec, mrecsz)) {
 1432         perr_printf("Damaged INDX record");
 1433         goto out_indexa;
 1434     }
 1435     indexa = (INDEX_ALLOCATION*)mrec;
 1436         /*
 1437          * The index bitmap is not checked, obsoleted records are
 1438          * wiped if they pass the safety checks
 1439          */
 1440     if ((indexa->magic == magic_INDX)
 1441         && (le32_to_cpu(indexa->index.entries_offset) >= sizeof(INDEX_HEADER))
 1442         && (le32_to_cpu(indexa->index.allocated_size) <= mrecsz)) {
 1443         entry = (INDEX_ENTRY *)((u8 *)mrec + le32_to_cpu(
 1444                 indexa->index.entries_offset) + 0x18);
 1445         wipe_index_entry_timestams(entry);
 1446     }
 1447 
 1448     if (ntfs_mft_usn_dec((MFT_RECORD *)mrec))
 1449         perr_exit("ntfs_mft_usn_dec");
 1450 
 1451     if (ntfs_mst_pre_write_fixup((NTFS_RECORD *)mrec, mrecsz)) {
 1452         perr_printf("INDX write fixup failed");
 1453         goto out_indexa;
 1454     }
 1455 out_indexa : ;
 1456 }
 1457 
 1458 /*
 1459  *      Output a set of related clusters (MFT record or index block)
 1460  */
 1461 
 1462 static void write_set(char *buff, u32 csize, s64 *current_lcn,
 1463             runlist_element *rl, u32 wi, u32 wj, u32 cnt)
 1464 {
 1465     u32 k;
 1466     s64 target_lcn;
 1467     char cmd = CMD_NEXT;
 1468 
 1469     for (k=0; k<cnt; k++) {
 1470         target_lcn = rl[wi].lcn + wj;
 1471         if (target_lcn != *current_lcn)
 1472             gap_to_cluster(target_lcn - *current_lcn);
 1473         if ((write_all(&fd_out, &cmd, sizeof(cmd)) == -1)
 1474             || (write_all(&fd_out, &buff[k*csize], csize) == -1))
 1475             perr_exit("Failed to write_all");
 1476         *current_lcn = target_lcn + 1;
 1477             
 1478         if (++wj >= rl[wi].length) {
 1479             wj = 0;
 1480             wi++;
 1481         }
 1482     }
 1483 }
 1484 
 1485 /*
 1486  *      Copy and wipe the full MFT or MFTMirr data.
 1487  *  (only for metadata images)
 1488  *
 1489  *  Data are read and written by full clusters, but the wiping is done
 1490  *  per MFT record.
 1491  */
 1492 
 1493 static void copy_wipe_mft(ntfs_walk_clusters_ctx *image, runlist *rl)
 1494 {
 1495     char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
 1496     void *fd;
 1497     s64 mft_no;
 1498     u32 mft_record_size;
 1499     u32 csize;
 1500     u32 bytes_per_sector;
 1501     u32 records_per_set;
 1502     u32 clusters_per_set;
 1503     u32 wi,wj; /* indexes for reading */
 1504     u32 ri,rj; /* indexes for writing */
 1505     u32 k; /* lcn within run */
 1506     u32 r; /* mft_record within set */
 1507     s64 current_lcn;
 1508 
 1509     current_lcn = image->current_lcn;
 1510     mft_record_size = image->ni->vol->mft_record_size;
 1511     csize = image->ni->vol->cluster_size;
 1512     bytes_per_sector = image->ni->vol->sector_size;
 1513     fd = image->ni->vol->dev;
 1514         /*
 1515          * Depending on the sizes, there may be several records
 1516          * per cluster, or several clusters per record.
 1517          */
 1518     if (csize >= mft_record_size) {
 1519         records_per_set = csize/mft_record_size;
 1520         clusters_per_set = 1;
 1521     } else {
 1522         clusters_per_set = mft_record_size/csize;
 1523         records_per_set = 1;
 1524     }
 1525     mft_no = 0;
 1526     ri = rj = 0;
 1527     wi = wj = 0;
 1528     if (rl[ri].length)
 1529         lseek_to_cluster(rl[ri].lcn);
 1530     while (rl[ri].length) {
 1531         for (k=0; (k<clusters_per_set) && rl[ri].length; k++) {
 1532             read_rescue(fd, &buff[k*csize], csize, bytes_per_sector,
 1533                             rl[ri].lcn + rj);
 1534             if (++rj >= rl[ri].length) {
 1535                 rj = 0;
 1536                 if (rl[++ri].length)
 1537                     lseek_to_cluster(rl[ri].lcn);
 1538             }
 1539         }
 1540         if (k == clusters_per_set) {
 1541             for (r=0; r<records_per_set; r++) {
 1542                 if (!strncmp(&buff[r*mft_record_size],"FILE",4))
 1543                     wipe_mft(&buff[r*mft_record_size],
 1544                         mft_record_size, mft_no);
 1545                 mft_no++;
 1546             }
 1547             write_set(buff, csize, &current_lcn,
 1548                     rl, wi, wj, clusters_per_set);
 1549             wj += clusters_per_set;
 1550             while (rl[wi].length && (wj >= rl[wi].length))
 1551                 wj -= rl[wi++].length;
 1552         } else {
 1553             err_exit("Short last MFT record\n");
 1554         }
 1555     }
 1556     image->current_lcn = current_lcn;
 1557 }
 1558 
 1559 /*
 1560  *      Copy and wipe the non-resident part of a directory index
 1561  *  (only for metadata images)
 1562  *
 1563  *  Data are read and written by full clusters, but the wiping is done
 1564  *  per index record.
 1565  */
 1566 
 1567 static void copy_wipe_i30(ntfs_walk_clusters_ctx *image, runlist *rl)
 1568 {
 1569     char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
 1570     void *fd;
 1571     u32 indx_record_size;
 1572     u32 csize;
 1573     u32 bytes_per_sector;
 1574     u32 records_per_set;
 1575     u32 clusters_per_set;
 1576     u32 wi,wj; /* indexes for reading */
 1577     u32 ri,rj; /* indexes for writing */
 1578     u32 k; /* lcn within run */
 1579     u32 r; /* mft_record within set */
 1580     s64 current_lcn;
 1581 
 1582     current_lcn = image->current_lcn;
 1583     csize = image->ni->vol->cluster_size;
 1584     bytes_per_sector = image->ni->vol->sector_size;
 1585     fd = image->ni->vol->dev;
 1586         /*
 1587          * Depending on the sizes, there may be several records
 1588          * per cluster, or several clusters per record.
 1589          */
 1590     indx_record_size = image->ni->vol->indx_record_size;
 1591     if (csize >= indx_record_size) {
 1592         records_per_set = csize/indx_record_size;
 1593         clusters_per_set = 1;
 1594     } else {
 1595         clusters_per_set = indx_record_size/csize;
 1596         records_per_set = 1;
 1597     }
 1598     ri = rj = 0;
 1599     wi = wj = 0;
 1600     if (rl[ri].length)
 1601         lseek_to_cluster(rl[ri].lcn);
 1602     while (rl[ri].length) {
 1603         for (k=0; (k<clusters_per_set) && rl[ri].length; k++) {
 1604             read_rescue(fd, &buff[k*csize], csize, bytes_per_sector,
 1605                             rl[ri].lcn + rj);
 1606             if (++rj >= rl[ri].length) {
 1607                 rj = 0;
 1608                 if (rl[++ri].length)
 1609                     lseek_to_cluster(rl[ri].lcn);
 1610             }
 1611         }
 1612         if (k == clusters_per_set) {
 1613             /* wipe records_per_set records */
 1614             if (!opt.preserve_timestamps)
 1615                 for (r=0; r<records_per_set; r++) {
 1616                     if (!strncmp(&buff[r*indx_record_size],"INDX",4))
 1617                         wipe_indx(&buff[r*indx_record_size],
 1618                             indx_record_size);
 1619                 }
 1620             write_set(buff, csize, &current_lcn,
 1621                     rl, wi, wj, clusters_per_set);
 1622             wj += clusters_per_set;
 1623             while (rl[wi].length && (wj >= rl[wi].length))
 1624                 wj -= rl[wi++].length;
 1625         } else {
 1626             err_exit("Short last directory index record\n");
 1627         }
 1628     }
 1629     image->current_lcn = current_lcn;
 1630 }
 1631 
 1632 static void dump_clusters(ntfs_walk_clusters_ctx *image, runlist *rl)
 1633 {
 1634     s64 i, len; /* number of clusters to copy */
 1635 
 1636     if (opt.restore_image)
 1637         err_exit("Bug : invalid dump_clusters()\n");
 1638 
 1639     if ((opt.std_out && !opt.metadata_image) || !opt.metadata)
 1640         return;
 1641     if (!(len = is_critical_metadata(image, rl)))
 1642         return;
 1643 
 1644     lseek_to_cluster(rl->lcn);
 1645     if (opt.metadata_image ? wipe : !wipe) {
 1646         if (opt.metadata_image)
 1647             gap_to_cluster(rl->lcn - image->current_lcn);
 1648         /* FIXME: this could give pretty suboptimal performance */
 1649         for (i = 0; i < len; i++)
 1650             copy_cluster(opt.rescue, rl->lcn + i, rl->lcn + i);
 1651         if (opt.metadata_image)
 1652             image->current_lcn = rl->lcn + len;
 1653     }
 1654 }
 1655 
 1656 static void walk_runs(struct ntfs_walk_cluster *walk)
 1657 {
 1658     int i, j;
 1659     runlist *rl;
 1660     ATTR_RECORD *a;
 1661     ntfs_attr_search_ctx *ctx;
 1662     BOOL mft_data;
 1663     BOOL index_i30;
 1664 
 1665     ctx = walk->image->ctx;
 1666     a = ctx->attr;
 1667 
 1668     if (!a->non_resident) {
 1669         if (wipe) {
 1670             wipe_resident_data(walk->image);
 1671             if (!opt.preserve_timestamps)
 1672                 wipe_timestamps(walk->image);
 1673         }
 1674         return;
 1675     }
 1676 
 1677     if (wipe
 1678         && !opt.preserve_timestamps
 1679         && walk->image->ctx->attr->type == AT_INDEX_ALLOCATION)
 1680         wipe_index_allocation_timestamps(walk->image->ni, a);
 1681 
 1682     if (!(rl = ntfs_mapping_pairs_decompress(vol, a, NULL)))
 1683         perr_exit("ntfs_decompress_mapping_pairs");
 1684 
 1685         /* special wipings for MFT records and directory indexes */
 1686     mft_data = ((walk->image->ni->mft_no == FILE_MFT)
 1687             || (walk->image->ni->mft_no == FILE_MFTMirr))
 1688             && (a->type == AT_DATA);
 1689     index_i30 = (walk->image->ctx->attr->type == AT_INDEX_ALLOCATION)
 1690             && (a->name_length == 4)
 1691             && !memcmp((char*)a + le16_to_cpu(a->name_offset),
 1692                     NTFS_INDEX_I30,8);
 1693 
 1694     for (i = 0; rl[i].length; i++) {
 1695         s64 lcn = rl[i].lcn;
 1696         s64 lcn_length = rl[i].length;
 1697 
 1698         if (lcn == LCN_HOLE || lcn == LCN_RL_NOT_MAPPED)
 1699             continue;
 1700 
 1701         /* FIXME: ntfs_mapping_pairs_decompress should return error */
 1702         if (lcn < 0 || lcn_length < 0)
 1703             err_exit("Corrupt runlist in inode %lld attr %x LCN "
 1704                  "%llx length %llx\n",
 1705                 (long long)ctx->ntfs_ino->mft_no,
 1706                 (unsigned int)le32_to_cpu(a->type),
 1707                 (long long)lcn, (long long)lcn_length);
 1708 
 1709         if (opt.metadata_image ? wipe && !mft_data && !index_i30 : !wipe)
 1710             dump_clusters(walk->image, rl + i);
 1711 
 1712         for (j = 0; j < lcn_length; j++) {
 1713             u64 k = (u64)lcn + j;
 1714             if (ntfs_bit_get_and_set(lcn_bitmap.bm, k, 1))
 1715                 err_exit("Cluster %llu referenced twice!\n"
 1716                      "You didn't shutdown your Windows "
 1717                      "properly?\n", (unsigned long long)k);
 1718         }
 1719 
 1720         if (!opt.metadata_image)
 1721             walk->image->inuse += lcn_length;
 1722             /*
 1723              * For a metadata image, we have to compute the
 1724              * number of metadata clusters for the percentages
 1725              * to be displayed correctly while restoring.
 1726              */
 1727         if (!wipe && opt.metadata_image) {
 1728             if ((walk->image->ni->mft_no == FILE_LogFile)
 1729                 && (walk->image->ctx->attr->type == AT_DATA)) {
 1730                     /* 16 KiB of FILE_LogFile */
 1731                 walk->image->inuse
 1732                    += is_critical_metadata(walk->image,rl);
 1733             } else {
 1734                 if ((walk->image->ni->mft_no
 1735                         <= LAST_METADATA_INODE)
 1736                    || (walk->image->ctx->attr->type != AT_DATA))
 1737                     walk->image->inuse += lcn_length;
 1738             }
 1739         }
 1740     }
 1741     if (wipe && opt.metadata_image) {
 1742         ntfs_attr *na;
 1743         /*
 1744          * Non-resident metadata has to be wiped globally,
 1745          * because its logical blocks may be larger than
 1746          * a cluster and split over two extents.
 1747          */
 1748         if (mft_data && !a->lowest_vcn) {
 1749             na = ntfs_attr_open(walk->image->ni,
 1750                     AT_DATA, NULL, 0);
 1751             if (na) {
 1752                 na->rl = rl;
 1753                 rl = (runlist_element*)NULL;
 1754                 if (!ntfs_attr_map_whole_runlist(na)) {
 1755                     copy_wipe_mft(walk->image,na->rl);
 1756                 } else
 1757                     perr_exit("Failed to map data of inode %lld",
 1758                         (long long)walk->image->ni->mft_no);
 1759                 ntfs_attr_close(na);
 1760             } else
 1761                 perr_exit("Failed to open data of inode %lld",
 1762                     (long long)walk->image->ni->mft_no);
 1763         }
 1764         if (index_i30 && !a->lowest_vcn) {
 1765             na = ntfs_attr_open(walk->image->ni,
 1766                     AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
 1767             if (na) {
 1768                 na->rl = rl;
 1769                 rl = (runlist_element*)NULL;
 1770                 if (!ntfs_attr_map_whole_runlist(na)) {
 1771                     copy_wipe_i30(walk->image,na->rl);
 1772                 } else
 1773                     perr_exit("Failed to map index of inode %lld",
 1774                         (long long)walk->image->ni->mft_no);
 1775                 ntfs_attr_close(na);
 1776             } else
 1777                 perr_exit("Failed to open index of inode %lld",
 1778                     (long long)walk->image->ni->mft_no);
 1779         }
 1780     }
 1781     if (opt.metadata
 1782         && (opt.metadata_image || !wipe)
 1783         && (walk->image->ni->mft_no == FILE_LogFile)
 1784         && (walk->image->ctx->attr->type == AT_DATA))
 1785         clone_logfile_parts(walk->image, rl);
 1786 
 1787     free(rl);
 1788 }
 1789 
 1790 
 1791 static void walk_attributes(struct ntfs_walk_cluster *walk)
 1792 {
 1793     ntfs_attr_search_ctx *ctx;
 1794 
 1795     if (!(ctx = ntfs_attr_get_search_ctx(walk->image->ni, NULL)))
 1796         perr_exit("ntfs_get_attr_search_ctx");
 1797 
 1798     while (!ntfs_attrs_walk(ctx)) {
 1799         if (ctx->attr->type == AT_END)
 1800             break;
 1801 
 1802         walk->image->ctx = ctx;
 1803         walk_runs(walk);
 1804     }
 1805 
 1806     ntfs_attr_put_search_ctx(ctx);
 1807 }
 1808 
 1809 /*
 1810  *      Compare the actual bitmap to the list of clusters
 1811  *  allocated to identified files.
 1812  *
 1813  *  Clusters found in use, though not marked in the bitmap are copied
 1814  *  if the option --ignore-fs-checks is set.
 1815  */
 1816 
 1817 static int compare_bitmaps(struct bitmap *a, BOOL copy)
 1818 {
 1819     s64 i, pos, count;
 1820     int mismatch = 0;
 1821     int more_use = 0;
 1822     s64 new_cl;
 1823     u8 bm[NTFS_BUF_SIZE];
 1824 
 1825     Printf("Accounting clusters ...\n");
 1826 
 1827     pos = 0;
 1828     new_cl = 0;
 1829     while (1) {
 1830         count = ntfs_attr_pread(vol->lcnbmp_na, pos, NTFS_BUF_SIZE, bm);
 1831         if (count == -1)
 1832             perr_exit("Couldn't get $Bitmap $DATA");
 1833 
 1834         if (count == 0) {
 1835             /* the backup bootsector need not be accounted for */
 1836             if (((vol->nr_clusters + 7) >> 3) > pos)
 1837                 err_exit("$Bitmap size is smaller than expected"
 1838                      " (%lld < %lld)\n",
 1839                     (long long)pos, (long long)a->size);
 1840             break;
 1841         }
 1842 
 1843         for (i = 0; i < count; i++, pos++) {
 1844             s64 cl;  /* current cluster */
 1845 
 1846             if (a->size <= pos)
 1847                 goto done;
 1848 
 1849             if (a->bm[pos] == bm[i])
 1850                 continue;
 1851 
 1852             for (cl = pos * 8; cl < (pos + 1) * 8; cl++) {
 1853                 char bit;
 1854 
 1855                 bit = ntfs_bit_get(a->bm, cl);
 1856                 if (bit == ntfs_bit_get(bm, i * 8 + cl % 8))
 1857                     continue;
 1858 
 1859                 if (!bit)
 1860                     more_use++;
 1861                 if (opt.ignore_fs_check && !bit && copy) {
 1862                     lseek_to_cluster(cl);
 1863                     if (opt.save_image
 1864                        || (opt.metadata
 1865                         && opt.metadata_image)) {
 1866                         gap_to_cluster(cl - new_cl);
 1867                         new_cl = cl + 1;
 1868                     }
 1869                     copy_cluster(opt.rescue, cl, cl);
 1870                 }
 1871 
 1872                 if (++mismatch > 10)
 1873                     continue;
 1874 
 1875                 Printf("Cluster accounting failed at %lld "
 1876                        "(0x%llx): %s cluster in $Bitmap\n",
 1877                        (long long)cl, (unsigned long long)cl,
 1878                        bit ? "missing" : "extra");
 1879             }
 1880         }
 1881     }
 1882 done:
 1883     if (mismatch) {
 1884         Printf("Totally %d cluster accounting mismatches.\n", mismatch);
 1885         if (opt.ignore_fs_check) {
 1886             Printf("WARNING: The NTFS inconsistency was overruled "
 1887                    "by the --ignore-fs-check option.\n");
 1888             if (new_cl) {
 1889                 gap_to_cluster(-new_cl);
 1890             }
 1891             return (more_use);
 1892         }
 1893         err_exit("Filesystem check failed! Windows wasn't shutdown "
 1894              "properly or inconsistent\nfilesystem. Please run "
 1895              "chkdsk /f on Windows then reboot it TWICE.\n");
 1896     }
 1897     return (more_use);
 1898 }
 1899 
 1900 
 1901 static void mft_record_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni)
 1902 {
 1903     if (ntfs_mft_usn_dec(ni->mrec))
 1904         perr_exit("ntfs_mft_usn_dec");
 1905 
 1906     if (ntfs_mft_record_write(volume, ni->mft_no, ni->mrec))
 1907         perr_exit("ntfs_mft_record_write");
 1908 }
 1909 
 1910 static void mft_inode_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni)
 1911 {
 1912     s32 i;
 1913 
 1914     mft_record_write_with_same_usn(volume, ni);
 1915 
 1916     if (ni->nr_extents <= 0)
 1917         return;
 1918 
 1919     for (i = 0; i < ni->nr_extents; ++i) {
 1920         ntfs_inode *eni = ni->extent_nis[i];
 1921         mft_record_write_with_same_usn(volume, eni);
 1922     }
 1923 }
 1924 
 1925 static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
 1926 {
 1927     s64 inode = 0;
 1928     s64 last_mft_rec;
 1929     u64 nr_clusters;
 1930     ntfs_inode *ni;
 1931     struct progress_bar progress;
 1932 
 1933     if (opt.restore_image || (!opt.metadata && wipe))
 1934         err_exit("Bug : invalid walk_clusters()\n");
 1935     Printf("Scanning volume ...\n");
 1936 
 1937     last_mft_rec = (volume->mft_na->initialized_size >>
 1938             volume->mft_record_size_bits) - 1;
 1939     walk->image->current_lcn = 0;
 1940     progress_init(&progress, inode, last_mft_rec, 100);
 1941 
 1942     NVolSetNoFixupWarn(volume);
 1943     for (; inode <= last_mft_rec; inode++) {
 1944 
 1945         int err, deleted_inode;
 1946         MFT_REF mref = (MFT_REF)inode;
 1947 
 1948         progress_update(&progress, inode);
 1949 
 1950         /* FIXME: Terrible kludge for libntfs not being able to return
 1951            a deleted MFT record as inode */
 1952         ni = ntfs_calloc(sizeof(ntfs_inode));
 1953         if (!ni)
 1954             perr_exit("walk_clusters");
 1955 
 1956         ni->vol = volume;
 1957 
 1958         err = ntfs_file_record_read(volume, mref, &ni->mrec, NULL);
 1959         if (err == -1) {
 1960             free(ni);
 1961             continue;
 1962         }
 1963 
 1964         deleted_inode = !(ni->mrec->flags & MFT_RECORD_IN_USE);
 1965 
 1966         if (deleted_inode && !opt.metadata_image) {
 1967 
 1968             ni->mft_no = MREF(mref);
 1969             if (wipe) {
 1970                 wipe_unused_mft(ni);
 1971                 wipe_unused_mft_data(ni);
 1972                 mft_record_write_with_same_usn(volume, ni);
 1973             }
 1974         }
 1975 
 1976         free(ni->mrec);
 1977         free(ni);
 1978 
 1979         if (deleted_inode)
 1980             continue;
 1981 
 1982         if ((ni = ntfs_inode_open(volume, mref)) == NULL) {
 1983             /* FIXME: continue only if it make sense, e.g.
 1984                MFT record not in use based on $MFT bitmap */
 1985             if (errno == EIO || errno == ENOENT)
 1986                 continue;
 1987             perr_exit("Reading inode %lld failed",
 1988                 (long long)inode);
 1989         }
 1990 
 1991         if (wipe)
 1992             nr_used_mft_records++;
 1993 
 1994         if (ni->mrec->base_mft_record)
 1995             goto out;
 1996 
 1997         walk->image->ni = ni;
 1998         walk_attributes(walk);
 1999 out:
 2000         if (wipe && !opt.metadata_image) {
 2001             int i;
 2002 
 2003             wipe_unused_mft_data(ni);
 2004             for (i = 0; i < ni->nr_extents; ++i) {
 2005                 wipe_unused_mft_data(ni->extent_nis[i]);
 2006             }
 2007             mft_inode_write_with_same_usn(volume, ni);
 2008         }
 2009 
 2010         if (ntfs_inode_close(ni))
 2011             perr_exit("ntfs_inode_close for inode %lld",
 2012                 (long long)inode);
 2013     }
 2014     if (opt.metadata) {
 2015         if (opt.metadata_image && wipe && opt.ignore_fs_check) {
 2016             gap_to_cluster(-walk->image->current_lcn);
 2017             compare_bitmaps(&lcn_bitmap, TRUE);
 2018             walk->image->current_lcn = 0;
 2019         }
 2020         if (opt.metadata_image ? wipe : !wipe) {
 2021                 /* also get the backup bootsector */
 2022             nr_clusters = vol->nr_clusters;
 2023             lseek_to_cluster(nr_clusters);
 2024             if (opt.metadata_image && wipe)
 2025                 gap_to_cluster(nr_clusters
 2026                     - walk->image->current_lcn);
 2027             copy_cluster(opt.rescue, nr_clusters, nr_clusters);
 2028             walk->image->current_lcn = nr_clusters;
 2029         }
 2030             /* Not counted, for compatibility with older versions */
 2031         if (!opt.metadata_image)
 2032             walk->image->inuse++;
 2033     }
 2034     return 0;
 2035 }
 2036 
 2037 
 2038 /*
 2039  * $Bitmap can overlap the end of the volume. Any bits in this region
 2040  * must be set. This region also encompasses the backup boot sector.
 2041  */
 2042 static void bitmap_file_data_fixup(s64 cluster, struct bitmap *bm)
 2043 {
 2044     for (; cluster < bm->size << 3; cluster++)
 2045         ntfs_bit_set(bm->bm, (u64)cluster, 1);
 2046 }
 2047 
 2048 
 2049 /*
 2050  * Allocate a block of memory with one bit for each cluster of the disk.
 2051  * All the bits are set to 0, except those representing the region beyond the
 2052  * end of the disk.
 2053  */
 2054 static void setup_lcn_bitmap(void)
 2055 {
 2056     /* Determine lcn bitmap byte size and allocate it. */
 2057     /* include the alternate boot sector in the bitmap count */
 2058     lcn_bitmap.size = rounded_up_division(vol->nr_clusters + 1, 8);
 2059 
 2060     lcn_bitmap.bm = ntfs_calloc(lcn_bitmap.size);
 2061     if (!lcn_bitmap.bm)
 2062         perr_exit("Failed to allocate internal buffer");
 2063 
 2064     bitmap_file_data_fixup(vol->nr_clusters, &lcn_bitmap);
 2065 }
 2066 
 2067 
 2068 static s64 volume_size(ntfs_volume *volume, s64 nr_clusters)
 2069 {
 2070     return nr_clusters * volume->cluster_size;
 2071 }
 2072 
 2073 
 2074 static void print_volume_size(const char *str, s64 bytes)
 2075 {
 2076     Printf("%s: %lld bytes (%lld MB)\n", str, (long long)bytes,
 2077             (long long)rounded_up_division(bytes, NTFS_MBYTE));
 2078 }
 2079 
 2080 
 2081 static void print_disk_usage(const char *spacer, u32 cluster_size,
 2082         s64 nr_clusters, s64 inuse)
 2083 {
 2084     s64 total, used;
 2085 
 2086     total = nr_clusters * cluster_size;
 2087     used = inuse * cluster_size;
 2088 
 2089     Printf("Space in use       %s: %lld MB (%.1f%%)   ", spacer,
 2090             (long long)rounded_up_division(used, NTFS_MBYTE),
 2091             100.0 * ((float)used / total));
 2092 
 2093     Printf("\n");
 2094 }
 2095 
 2096 static void print_image_info(void)
 2097 {
 2098     Printf("Ntfsclone image version: %d.%d\n",
 2099             image_hdr.major_ver, image_hdr.minor_ver);
 2100     Printf("Cluster size           : %u bytes\n",
 2101             (unsigned)le32_to_cpu(image_hdr.cluster_size));
 2102     print_volume_size("Image volume size      ",
 2103             sle64_to_cpu(image_hdr.nr_clusters) *
 2104             le32_to_cpu(image_hdr.cluster_size));
 2105     Printf("Image device size      : %lld bytes\n",
 2106             (long long)le64_to_cpu(image_hdr.device_size));
 2107     print_disk_usage("    ", le32_to_cpu(image_hdr.cluster_size),
 2108             sle64_to_cpu(image_hdr.nr_clusters),
 2109             le64_to_cpu(image_hdr.inuse));
 2110     Printf("Offset to image data   : %u (0x%x) bytes\n",
 2111             (unsigned)le32_to_cpu(image_hdr.offset_to_image_data),
 2112             (unsigned)le32_to_cpu(image_hdr.offset_to_image_data));
 2113 }
 2114 
 2115 static void check_if_mounted(const char *device, unsigned long new_mntflag)
 2116 {
 2117     unsigned long mntflag;
 2118 
 2119     if (ntfs_check_if_mounted(device, &mntflag))
 2120         perr_exit("Failed to check '%s' mount state", device);
 2121 
 2122     if (mntflag & NTFS_MF_MOUNTED) {
 2123         if (!(mntflag & NTFS_MF_READONLY))
 2124             err_exit("Device '%s' is mounted read-write. "
 2125                  "You must 'umount' it first.\n", device);
 2126         if (!new_mntflag)
 2127             err_exit("Device '%s' is mounted. "
 2128                  "You must 'umount' it first.\n", device);
 2129     }
 2130 }
 2131 
 2132 /**
 2133  * mount_volume -
 2134  *
 2135  * First perform some checks to determine if the volume is already mounted, or
 2136  * is dirty (Windows wasn't shutdown properly).  If everything is OK, then mount
 2137  * the volume (load the metadata into memory).
 2138  */
 2139 static void mount_volume(unsigned long new_mntflag)
 2140 {
 2141     check_if_mounted(opt.volume, new_mntflag);
 2142 
 2143     if (!(vol = ntfs_mount(opt.volume, new_mntflag))) {
 2144 
 2145         int err = errno;
 2146 
 2147         perr_printf("Opening '%s' as NTFS failed", opt.volume);
 2148         if (err == EINVAL) {
 2149             Printf("Apparently device '%s' doesn't have a "
 2150                    "valid NTFS. Maybe you selected\nthe whole "
 2151                    "disk instead of a partition (e.g. /dev/hda, "
 2152                    "not /dev/hda1)?\n", opt.volume);
 2153         }
 2154         /*
 2155          * Retry with recovering the log file enabled.
 2156          * Normally avoided in order to get the original log file
 2157          * data, but needed when remounting the metadata of a
 2158          * volume improperly unmounted from Windows.
 2159          * If the full log file was requested, it must be kept
 2160          * as is, so we just remount read-only.
 2161          */
 2162         if (!(new_mntflag & (NTFS_MNT_RDONLY | NTFS_MNT_RECOVER))) {
 2163             if (opt.full_logfile) {
 2164                 Printf("Retrying read-only to ignore"
 2165                             " the log file...\n");
 2166                 vol = ntfs_mount(opt.volume,
 2167                      new_mntflag | NTFS_MNT_RDONLY);
 2168             } else {
 2169                 Printf("Trying to recover...\n");
 2170                 vol = ntfs_mount(opt.volume,
 2171                     new_mntflag | NTFS_MNT_RECOVER);
 2172             }
 2173             Printf("... %s\n",(vol ? "Successful" : "Failed"));
 2174         }
 2175         if (!vol)
 2176             exit(1);
 2177     }
 2178 
 2179     if (vol->flags & VOLUME_IS_DIRTY)
 2180         if (opt.force-- <= 0)
 2181             err_exit(dirty_volume_msg, opt.volume);
 2182 
 2183     if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size)
 2184         err_exit("Cluster size %u is too large!\n",
 2185                 (unsigned int)vol->cluster_size);
 2186 
 2187     Printf("NTFS volume version: %d.%d\n", vol->major_ver, vol->minor_ver);
 2188     if (ntfs_version_is_supported(vol))
 2189         perr_exit("Unknown NTFS version");
 2190 
 2191     Printf("Cluster size       : %u bytes\n",
 2192             (unsigned int)vol->cluster_size);
 2193     print_volume_size("Current volume size",
 2194               volume_size(vol, vol->nr_clusters));
 2195 }
 2196 
 2197 static struct ntfs_walk_cluster backup_clusters = { NULL, NULL };
 2198 
 2199 static int device_offset_valid(int fd, s64 ofs)
 2200 {
 2201     char ch;
 2202 
 2203     if (lseek(fd, ofs, SEEK_SET) >= 0 && read(fd, &ch, 1) == 1)
 2204         return 0;
 2205     return -1;
 2206 }
 2207 
 2208 static s64 device_size_get(int fd)
 2209 {
 2210     s64 high, low;
 2211 #ifdef BLKGETSIZE64
 2212     {   u64 size;
 2213 
 2214         if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
 2215             ntfs_log_debug("BLKGETSIZE64 nr bytes = %llu "
 2216                 "(0x%llx).\n", (unsigned long long)size,
 2217                 (unsigned long long)size);
 2218             return (s64)size;
 2219         }
 2220     }
 2221 #endif
 2222 #ifdef BLKGETSIZE
 2223     {   unsigned long size;
 2224 
 2225         if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
 2226             ntfs_log_debug("BLKGETSIZE nr 512 byte blocks = %lu "
 2227                 "(0x%lx).\n", size, size);
 2228             return (s64)size * 512;
 2229         }
 2230     }
 2231 #endif
 2232 #ifdef FDGETPRM
 2233     {       struct floppy_struct this_floppy;
 2234 
 2235         if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
 2236             ntfs_log_debug("FDGETPRM nr 512 byte blocks = %lu "
 2237                 "(0x%lx).\n", this_floppy.size,
 2238                 this_floppy.size);
 2239             return (s64)this_floppy.size * 512;
 2240         }
 2241     }
 2242 #endif
 2243     /*
 2244      * We couldn't figure it out by using a specialized ioctl,
 2245      * so do binary search to find the size of the device.
 2246      */
 2247     low = 0LL;
 2248     for (high = 1024LL; !device_offset_valid(fd, high); high <<= 1)
 2249         low = high;
 2250     while (low < high - 1LL) {
 2251         const s64 mid = (low + high) / 2;
 2252 
 2253         if (!device_offset_valid(fd, mid))
 2254             low = mid;
 2255         else
 2256             high = mid;
 2257     }
 2258     lseek(fd, 0LL, SEEK_SET);
 2259     return (low + 1LL);
 2260 }
 2261 
 2262 static void fsync_clone(int fd)
 2263 {
 2264     Printf("Syncing ...\n");
 2265     if (opt.save_image && stream_out && fflush(stream_out))
 2266         perr_exit("fflush");
 2267     if (fsync(fd) && errno != EINVAL)
 2268         perr_exit("fsync");
 2269 }
 2270 
 2271 static void set_filesize(s64 filesize)
 2272 {
 2273 #ifndef NO_STATFS
 2274     long fs_type = 0; /* Unknown filesystem type */
 2275 
 2276     if (fstatfs(fd_out, &opt.stfs) == -1)
 2277         Printf("WARNING: Couldn't get filesystem type: "
 2278                "%s\n", strerror(errno));
 2279     else
 2280         fs_type = opt.stfs.f_type;
 2281 
 2282     if (fs_type == 0x52654973)
 2283         Printf("WARNING: You're using ReiserFS, it has very poor "
 2284                "performance creating\nlarge sparse files. The next "
 2285                "operation might take a very long time!\n"
 2286                "Creating sparse output file ...\n");
 2287     else if (fs_type == 0x517b)
 2288         Printf("WARNING: You're using SMBFS and if the remote share "
 2289                "isn't Samba but a Windows\ncomputer then the clone "
 2290                "operation will be very inefficient and may fail!\n");
 2291 #endif
 2292 
 2293     if (!opt.no_action && (ftruncate(fd_out, filesize) == -1)) {
 2294         int err = errno;
 2295         perr_printf("ftruncate failed for file '%s'", opt.output);
 2296 #ifndef NO_STATFS
 2297         if (fs_type)
 2298             Printf("Destination filesystem type is 0x%lx.\n",
 2299                    (unsigned long)fs_type);
 2300 #endif
 2301         if (err == E2BIG) {
 2302             Printf("Your system or the destination filesystem "
 2303                    "doesn't support large files.\n");
 2304 #ifndef NO_STATFS
 2305             if (fs_type == 0x517b) {
 2306                 Printf("SMBFS needs minimum Linux kernel "
 2307                        "version 2.4.25 and\n the 'lfs' option"
 2308                        "\nfor smbmount to have large "
 2309                        "file support.\n");
 2310             }
 2311 #endif
 2312         } else if (err == EPERM) {
 2313             Printf("Apparently the destination filesystem doesn't "
 2314                    "support sparse files.\nYou can overcome this "
 2315                    "by using the more efficient --save-image "
 2316                    "option\nof ntfsclone. Use the --restore-image "
 2317                    "option to restore the image.\n");
 2318         }
 2319         exit(1);
 2320     }
 2321         /*
 2322          * If truncate just created a sparse file, the ability
 2323          * to generically store big files has been checked, but no
 2324          * space has been reserved and available space has probably
 2325          * not been checked. Better reset the file so that we write
 2326          * sequentially to the end.
 2327          */
 2328     if (!opt.no_action) {
 2329 #ifdef HAVE_WINDOWS_H
 2330         if (ftruncate(fd_out, 0))
 2331             Printf("Failed to reset the output file.\n");
 2332 #else
 2333         struct stat st;
 2334         int s;
 2335 
 2336         s = fstat(fd_out, &st);
 2337         if (s || (!st.st_blocks && ftruncate(fd_out, 0)))
 2338             Printf("Failed to reset the output file.\n");
 2339 #endif
 2340             /* Proceed even if ftruncate failed */
 2341     }
 2342 }
 2343 
 2344 static s64 open_image(void)
 2345 {
 2346     if (strcmp(opt.volume, "-") == 0) {
 2347         if ((fd_in = fileno(stdin)) == -1)
 2348             perr_exit("fileno for stdin failed");
 2349 #ifdef HAVE_WINDOWS_H
 2350         if (setmode(fd_in,O_BINARY) == -1)
 2351             perr_exit("setting binary stdin failed");
 2352 #endif
 2353     } else {
 2354         if ((fd_in = open(opt.volume, O_RDONLY | O_BINARY)) == -1)
 2355             perr_exit("failed to open image");
 2356     }
 2357     if (read_all(&fd_in, &image_hdr, NTFSCLONE_IMG_HEADER_SIZE_OLD) == -1)
 2358         perr_exit("read_all");
 2359     if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0)
 2360         err_exit("Input file is not an image! (invalid magic)\n");
 2361     if (image_hdr.major_ver < NTFSCLONE_IMG_VER_MAJOR_ENDIANNESS_SAFE) {
 2362         image_hdr.major_ver = NTFSCLONE_IMG_VER_MAJOR;
 2363         image_hdr.minor_ver = NTFSCLONE_IMG_VER_MINOR;
 2364 #if (__BYTE_ORDER == __BIG_ENDIAN)
 2365         /*
 2366          * old image read on a big endian computer,
 2367          * assuming it was created big endian and read cpu-wise,
 2368          * so we should translate to little endian
 2369          */
 2370         Printf("Old image format detected.  If the image was created "
 2371                 "on a little endian architecture it will not "
 2372                 "work.  Use a more recent version of "
 2373                 "ntfsclone to recreate the image.\n");
 2374         image_hdr.cluster_size = cpu_to_le32(image_hdr.cluster_size);
 2375         image_hdr.device_size = cpu_to_sle64(image_hdr.device_size);
 2376         image_hdr.nr_clusters = cpu_to_sle64(image_hdr.nr_clusters);
 2377         image_hdr.inuse = cpu_to_sle64(image_hdr.inuse);
 2378 #endif
 2379         image_hdr.offset_to_image_data =
 2380                 const_cpu_to_le32((sizeof(image_hdr)
 2381                     + IMAGE_HDR_ALIGN - 1) & -IMAGE_HDR_ALIGN);
 2382         image_is_host_endian = TRUE;
 2383     } else {
 2384             /* safe image : little endian data */
 2385         le32 offset_to_image_data;
 2386         int delta;
 2387 
 2388         if (image_hdr.major_ver > NTFSCLONE_IMG_VER_MAJOR)
 2389             err_exit("Do not know how to handle image format "
 2390                     "version %d.%d.  Please obtain a "
 2391                     "newer version of ntfsclone.\n",
 2392                     image_hdr.major_ver,
 2393                     image_hdr.minor_ver);
 2394         /* Read the image header data offset. */
 2395         if (read_all(&fd_in, &offset_to_image_data,
 2396                 sizeof(offset_to_image_data)) == -1)
 2397             perr_exit("read_all");
 2398             /* do not translate little endian data */
 2399         image_hdr.offset_to_image_data = offset_to_image_data;
 2400         /*
 2401          * Read any fields from the header that we have not read yet so
 2402          * that the input stream is positioned correctly.  This means
 2403          * we can support future minor versions that just extend the
 2404          * header in a backwards compatible way.
 2405          */
 2406         delta = le32_to_cpu(offset_to_image_data)
 2407                 - (NTFSCLONE_IMG_HEADER_SIZE_OLD +
 2408                 sizeof(image_hdr.offset_to_image_data));
 2409         if (delta > 0) {
 2410             char *dummy_buf;
 2411 
 2412             dummy_buf = malloc(delta);
 2413             if (!dummy_buf)
 2414                 perr_exit("malloc dummy_buffer");
 2415             if (read_all(&fd_in, dummy_buf, delta) == -1)
 2416                 perr_exit("read_all");
 2417             free(dummy_buf);
 2418         }
 2419     }
 2420     return le64_to_cpu(image_hdr.device_size);
 2421 }
 2422 
 2423 static s64 open_volume(void)
 2424 {
 2425     s64 device_size;
 2426 
 2427     mount_volume(NTFS_MNT_RDONLY);
 2428 
 2429     device_size = ntfs_device_size_get(vol->dev, 1);
 2430     if (device_size <= 0)
 2431         err_exit("Couldn't get device size (%lld)!\n",
 2432             (long long)device_size);
 2433 
 2434     print_volume_size("Current device size", device_size);
 2435 
 2436     if (device_size < vol->nr_clusters * vol->cluster_size)
 2437         err_exit("Current NTFS volume size is bigger than the device "
 2438              "size (%lld)!\nCorrupt partition table or incorrect "
 2439              "device partitioning?\n", (long long)device_size);
 2440 
 2441     return device_size;
 2442 }
 2443 
 2444 static void initialise_image_hdr(s64 device_size, s64 inuse)
 2445 {
 2446     memcpy(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE);
 2447     image_hdr.major_ver = NTFSCLONE_IMG_VER_MAJOR;
 2448     image_hdr.minor_ver = NTFSCLONE_IMG_VER_MINOR;
 2449     image_hdr.cluster_size = cpu_to_le32(vol->cluster_size);
 2450     image_hdr.device_size = cpu_to_le64(device_size);
 2451     image_hdr.nr_clusters = cpu_to_sle64(vol->nr_clusters);
 2452     image_hdr.inuse = cpu_to_le64(inuse);
 2453     image_hdr.offset_to_image_data = cpu_to_le32((sizeof(image_hdr)
 2454              + IMAGE_HDR_ALIGN - 1) & -IMAGE_HDR_ALIGN);
 2455 }
 2456 
 2457 static void check_output_device(s64 input_size)
 2458 {
 2459     if (opt.blkdev_out) {
 2460         s64 dest_size;
 2461 
 2462         if (dev_out)
 2463             dest_size = ntfs_device_size_get(dev_out, 1);
 2464         else
 2465             dest_size = device_size_get(fd_out);
 2466         if (dest_size < input_size)
 2467             err_exit("Output device is too small (%lld) to fit the "
 2468                  "NTFS image (%lld).\n",
 2469                 (long long)dest_size, (long long)input_size);
 2470 
 2471         check_if_mounted(opt.output, 0);
 2472     } else
 2473         set_filesize(input_size);
 2474 }
 2475 
 2476 static void ignore_bad_clusters(ntfs_walk_clusters_ctx *image)
 2477 {
 2478     ntfs_inode *ni;
 2479     ntfs_attr *na;
 2480     runlist *rl;
 2481     s64 nr_bad_clusters = 0;
 2482     static le16 Bad[4] = {
 2483         const_cpu_to_le16('$'), const_cpu_to_le16('B'),
 2484         const_cpu_to_le16('a'), const_cpu_to_le16('d')
 2485     } ;
 2486 
 2487     if (!(ni = ntfs_inode_open(vol, FILE_BadClus)))
 2488         perr_exit("ntfs_open_inode");
 2489 
 2490     na = ntfs_attr_open(ni, AT_DATA, Bad, 4);
 2491     if (!na)
 2492         perr_exit("ntfs_attr_open");
 2493     if (ntfs_attr_map_whole_runlist(na))
 2494         perr_exit("ntfs_attr_map_whole_runlist");
 2495 
 2496     for (rl = na->rl; rl->length; rl++) {
 2497         s64 lcn = rl->lcn;
 2498 
 2499         if (lcn == LCN_HOLE || lcn < 0)
 2500             continue;
 2501 
 2502         for (; lcn < rl->lcn + rl->length; lcn++, nr_bad_clusters++) {
 2503             if (ntfs_bit_get_and_set(lcn_bitmap.bm, lcn, 0))
 2504                 image->inuse--;
 2505         }
 2506     }
 2507     if (nr_bad_clusters)
 2508         Printf("WARNING: The disk has %lld or more bad sectors"
 2509                " (hardware faults).\n", (long long)nr_bad_clusters);
 2510     ntfs_attr_close(na);
 2511     if (ntfs_inode_close(ni))
 2512         perr_exit("ntfs_inode_close failed for $BadClus");
 2513 }
 2514 
 2515 static void check_dest_free_space(u64 src_bytes)
 2516 {
 2517 #ifndef HAVE_WINDOWS_H
 2518     u64 dest_bytes;
 2519     struct statvfs stvfs;
 2520     struct stat st;
 2521 
 2522     if (opt.metadata || opt.blkdev_out || opt.std_out)
 2523         return;
 2524     /*
 2525      * TODO: save_image needs a bit more space than src_bytes
 2526      * due to the free space encoding overhead.
 2527      */
 2528     if (fstatvfs(fd_out, &stvfs) == -1) {
 2529         Printf("WARNING: Unknown free space on the destination: %s\n",
 2530                strerror(errno));
 2531         return;
 2532     }
 2533     
 2534     /* If file is a FIFO then there is no point in checking the size. */
 2535     if (!fstat(fd_out, &st)) {
 2536         if (S_ISFIFO(st.st_mode))
 2537             return;
 2538     } else
 2539         Printf("WARNING: fstat failed: %s\n", strerror(errno));
 2540 
 2541     dest_bytes = (u64)stvfs.f_frsize * stvfs.f_bfree;
 2542     if (!dest_bytes)
 2543         dest_bytes = (u64)stvfs.f_bsize * stvfs.f_bfree;
 2544 
 2545     if (dest_bytes < src_bytes)
 2546         err_exit("Destination doesn't have enough free space: "
 2547              "%llu MB < %llu MB\n",
 2548              (unsigned long long)rounded_up_division(dest_bytes, NTFS_MBYTE),
 2549              (unsigned long long)rounded_up_division(src_bytes,  NTFS_MBYTE));
 2550 #endif
 2551 }
 2552 
 2553 int main(int argc, char **argv)
 2554 {
 2555     ntfs_walk_clusters_ctx image;
 2556     s64 device_size;        /* input device size in bytes */
 2557     s64 ntfs_size;
 2558     unsigned int wiped_total = 0;
 2559 
 2560     /* make sure the layout of header is not affected by alignments */
 2561     if (offsetof(struct image_hdr, offset_to_image_data)
 2562             != IMAGE_OFFSET_OFFSET) {
 2563         fprintf(stderr,"ntfsclone is not compiled properly. "
 2564                 "Please fix\n");
 2565         exit(1);
 2566     }
 2567     /* print to stderr, stdout can be an NTFS image ... */
 2568     fprintf(stderr, "%s v%s (libntfs-3g)\n", EXEC_NAME, VERSION);
 2569     msg_out = stderr;
 2570 
 2571     parse_options(argc, argv);
 2572 
 2573     utils_set_locale();
 2574 
 2575     if (opt.restore_image) {
 2576         device_size = open_image();
 2577         ntfs_size = sle64_to_cpu(image_hdr.nr_clusters) *
 2578                 le32_to_cpu(image_hdr.cluster_size);
 2579     } else {
 2580         device_size = open_volume();
 2581         ntfs_size = vol->nr_clusters * vol->cluster_size;
 2582     }
 2583     // FIXME: This needs to be the cluster size...
 2584     ntfs_size += 512; /* add backup boot sector */
 2585     full_device_size = device_size;
 2586 
 2587     if (opt.std_out) {
 2588         if ((fd_out = fileno(stdout)) == -1)
 2589             perr_exit("fileno for stdout failed");
 2590         stream_out = stdout;
 2591 #ifdef HAVE_WINDOWS_H
 2592         if (setmode(fileno(stdout),O_BINARY) == -1)
 2593             perr_exit("setting binary stdout failed");
 2594 #endif
 2595     } else {
 2596         /* device_size_get() might need to read() */
 2597         int flags = O_RDWR | O_BINARY;
 2598 
 2599         fd_out = 0;
 2600         if (!opt.blkdev_out) {
 2601             flags |= O_CREAT | O_TRUNC;
 2602             if (!opt.overwrite)
 2603                 flags |= O_EXCL;
 2604         }
 2605 
 2606         if (opt.save_image || opt.metadata_image) {
 2607             stream_out = fopen(opt.output,BINWMODE);
 2608             if (!stream_out)
 2609                 perr_exit("Opening file '%s' failed",
 2610                         opt.output);
 2611             fd_out = fileno(stream_out);
 2612         } else {
 2613 #ifdef HAVE_WINDOWS_H
 2614             if (!opt.no_action) {
 2615                 dev_out = ntfs_device_alloc(opt.output, 0,
 2616                     &ntfs_device_default_io_ops, NULL);
 2617                 if (!dev_out
 2618                     || (dev_out->d_ops->open)(dev_out, flags))
 2619                     perr_exit("Opening volume '%s' failed",
 2620                             opt.output);
 2621             }
 2622 #else
 2623             if (!opt.no_action
 2624                 && ((fd_out = open(opt.output, flags,
 2625                         S_IRUSR | S_IWUSR)) == -1))
 2626                 perr_exit("Opening file '%s' failed",
 2627                         opt.output);
 2628 #endif
 2629         }
 2630 
 2631         if (!opt.save_image && !opt.metadata_image && !opt.no_action)
 2632             check_output_device(ntfs_size);
 2633     }
 2634 
 2635     if (opt.restore_image) {
 2636         print_image_info();
 2637         restore_image();
 2638         if (!opt.no_action)
 2639             fsync_clone(fd_out);
 2640         exit(0);
 2641     }
 2642 
 2643     setup_lcn_bitmap();
 2644     memset(&image, 0, sizeof(image));
 2645     backup_clusters.image = &image;
 2646 
 2647     walk_clusters(vol, &backup_clusters);
 2648     image.more_use = compare_bitmaps(&lcn_bitmap,
 2649                 opt.metadata && !opt.metadata_image);
 2650     print_disk_usage("", vol->cluster_size, vol->nr_clusters, image.inuse);
 2651 
 2652     check_dest_free_space(vol->cluster_size * image.inuse);
 2653 
 2654     ignore_bad_clusters(&image);
 2655 
 2656     if (opt.save_image)
 2657         initialise_image_hdr(device_size, image.inuse);
 2658 
 2659     if ((opt.std_out && !opt.metadata_image) || !opt.metadata) {
 2660         s64 nr_clusters_to_save = image.inuse;
 2661         if (opt.std_out && !opt.save_image)
 2662             nr_clusters_to_save = vol->nr_clusters;
 2663         nr_clusters_to_save++; /* account for the backup boot sector */
 2664 
 2665         clone_ntfs(nr_clusters_to_save, image.more_use);
 2666         fsync_clone(fd_out);
 2667         if (opt.save_image)
 2668             fclose(stream_out);
 2669         ntfs_umount(vol,FALSE);
 2670         free(lcn_bitmap.bm);
 2671         exit(0);
 2672     }
 2673 
 2674     wipe = 1;
 2675     if (opt.metadata_image) {
 2676         initialise_image_hdr(device_size, image.inuse);
 2677         write_image_hdr();
 2678     } else {
 2679         if (dev_out) {
 2680             (dev_out->d_ops->close)(dev_out);
 2681             dev_out = NULL;
 2682         } else
 2683             fsync_clone(fd_out); /* sync copy before mounting */
 2684         opt.volume = opt.output;
 2685     /* 'force' again mount for dirty volumes (e.g. after resize).
 2686        FIXME: use mount flags to avoid potential side-effects in future */
 2687         opt.force++;
 2688         ntfs_umount(vol,FALSE);
 2689         mount_volume(0 /*NTFS_MNT_NOATIME*/);
 2690     }
 2691 
 2692     free(lcn_bitmap.bm);
 2693     setup_lcn_bitmap();
 2694     memset(&image, 0, sizeof(image));
 2695     backup_clusters.image = &image;
 2696 
 2697     walk_clusters(vol, &backup_clusters);
 2698 
 2699     Printf("Num of MFT records       = %10lld\n",
 2700             (long long)vol->mft_na->initialized_size >>
 2701             vol->mft_record_size_bits);
 2702     Printf("Num of used MFT records  = %10u\n", nr_used_mft_records);
 2703 
 2704     Printf("Wiped unused MFT data    = %10u\n", wiped_unused_mft_data);
 2705     Printf("Wiped deleted MFT data   = %10u\n", wiped_unused_mft);
 2706     Printf("Wiped resident user data = %10u\n", wiped_resident_data);
 2707     Printf("Wiped timestamp data     = %10u\n", wiped_timestamp_data);
 2708 
 2709     wiped_total += wiped_unused_mft_data;
 2710     wiped_total += wiped_unused_mft;
 2711     wiped_total += wiped_resident_data;
 2712     wiped_total += wiped_timestamp_data;
 2713     Printf("Wiped totally            = %10u\n", wiped_total);
 2714 
 2715     if (opt.metadata_image)
 2716         fclose(stream_out);
 2717     else
 2718         fsync_clone(fd_out);
 2719     ntfs_umount(vol,FALSE);
 2720     free(lcn_bitmap.bm);
 2721     return (0);
 2722 }