📄 aimage.cpp
字号:
/* * aimage.cpp: * * Image a physical drive connected through an IDE, SCSI, USB or * Firewire interface and write the results to either a raw or AFF * file. * * Automatically calculate the MD5 & SHA-1 while image is made. * Handle read errors in an intelligent fashion. * Display the results. *//* * Copyright (c) 2005, 2006 * Simson L. Garfinkel and Basis Technology Corp. * All rights reserved. * * This code is derrived from software contributed by * Simson L. Garfinkel * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Simson L. Garfinkel * and Basis Technology Corp. * 4. Neither the name of Simson Garfinkel, Basis Technology, or other * contributors to this program may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY SIMSON GARFINKEL, BASIS TECHNOLOGY, * AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL SIMSON GARFINKEL, BAIS TECHNOLOGy, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "config.h"#include "afflib.h" #include "afflib_i.h" // grab the internal versions#include "aimage.h"#include "aftimer.h"#include "imager.h"#include "gui.h"#include <algorithm>#include <cstdlib>#include <vector>#include <string>using namespace std;#define xstr(s) str(s)#define str(s) #s/* global variables for imaging calculations *//* For autocompression */double ac_compress_write_time = 0;double ac_nocompress_write_time = 0;char *progname = "aimage";int opt_zap = 0;int opt_append = 0;/* Autocompression features */int opt_compression_level = AF_COMPRESSION_DEFAULT;// default compression levelint opt_compression_alg = AF_COMPRESSION_ALG_ZLIB; // default algorithmint opt_auto_compress = 0;int opt_make_config = 0;aftimer total_time; // total time spend imaging/* size options */int default_pagesize = 16*1024*1024;int opt_pagesize = default_pagesize; // default seg size --- 16MBint opt_readsectors = opt_pagesize / 512; // read in 256K chunksint opt_maxsize = (1<<31) - opt_pagesize; int maxsize_set = 0;/* General options */char *opt_title = "IMAGING";char *command_line = 0; // what is typedint opt_quiet = 0;int opt_silent = 0;int opt_beeps = 1; // beep when doneint opt_recover_scan = 0;int opt_error_mode = 0;int opt_retry_count = 5;int opt_reverse = 0;int opt_fast_quit = 0;int opt_blink = 1;int opt_hexbuf = AF_HEXBUF_SPACE4 | AF_HEXBUF_UPPERCASE;char *opt_logfile_fname = 0;char logfile_fname[MAXPATHLEN];FILE *logfile=0;char *config_filename=AIMAGE_CONFIG_FILENAME;int opt_skip = 0; // what to skip on inputint opt_skip_sectors = 0; // are we skipping sectors?int opt_compress = 1;int opt_preview = 1; // give me a little showint opt_debug = 0;int opt_batch = 0; // output status in XMLint opt_use_timers = 0; // report time spent compressing, reading, writing, etc.int opt_no_ifconfig = 0;int opt_no_dmesg = 0;/* Imagers */imager **imagers;int num_imagers=0;int current_imager=0;vector<string> opt_setseg; // segs that get setvoid add_imager(){ imagers = (imager **)realloc(imagers,sizeof(imager *)*num_imagers+1); imagers[num_imagers] = new imager(); current_imager = num_imagers; num_imagers++;}void bold(const char *str){ tputs(enter_bold_mode,1,putchar); fputs(str,stdout); tputs(exit_attribute_mode,0,putchar);}void usage(){ putchar('\n'); printf("aimage %s\n\n",xstr(PACKAGE_VERSION)); printf("usage: %s [options] INPUT1 [OUTFILE1] [INPUT2 OUTPUT2] ...--- image indev to outfile\n", progname); printf("INPUT may be any of these:\n"); printf(" A device (e.g. /dev/disk1)\n"); printf(" - (or /dev/stdin, for standard input)\n"); printf(" listen:nnnn Listen on TCP port nnnn\n"); printf("OUTFILE may be:\n"); printf(" outfile.aff --- image to the AFF file outfile\n"); bold("\nGeneral Options:\n"); printf(" --quiet, -q -- No interactive statistics.\n"); printf(" --batch, -Y -- Batch output\n"); printf(" --silent, -Q -- No output at all except for errors.\n"); printf(" --readsectors=nn, -R nnnn, -- set number of sectors to read at once (default %d)\n", opt_readsectors); printf(" --version, -v -- Just print the version number and exit.\n"); printf(" --skip=nn[s], -k nn -- Skip nn bytes [or nns for sectors] in input file\n"); printf(" --no_beeps, -B -- Don't beep when imaging is finished.\n"); printf(" --logfile=fn, -l fn -- Where to write a log. By default none is written\n"); printf(" --logAFF, -G -- Log all AFF operations\n"); printf(" --preview, -p -- view some of the data as it goes by.\n"); printf(" --no_preview, -P -- do not show the preview.\n"); bold("\nExisting File Options:\n"); printf(" --append, -a -- Append to existing file\n"); printf(" NOTE: --append is not yet implemented.\n"); printf(" --zap, -z -- Erase outfile(s) before writing\n"); bold("\nRaw Output Options:\n"); printf(" --raw=fname, -r fname -- write block-by-block output to fname.\n"); bold("\nAFF Options:\n"); printf(" --outfile=fname, -ofname -- write an AFF file.\n"); printf(" --image_pagesize=nnn, -S nnnn\n"); printf(" -- set the AFF page size (default %d)\n", opt_pagesize); printf(" (number can be suffixed with b, k, m or g)\n"); printf(" Also sets maxsize to be 2^32 - image_pagesize if not otherwise set.\n"); printf(" --make_config, -m -- Make the config file if it doesn't exist\n"); printf(" Config file is %s by default\n",AIMAGE_CONFIG_FILENAME); printf(" and can be overridden by the %s enviroment variable\n", AIMAGE_CONFIG); printf(" --no_dmesg, -D -- Do not put dmesg into the AFF file\n"); printf(" --no_ifconfig, -I -- Do not put ifconfig output into AFF file\n"); if(getenv(AIMAGE_CONFIG)){ printf(" (Currently set to %s)\n",getenv(AIMAGE_CONFIG)); } else{ printf(" (Currently unset)\n"); } printf(" --no_compress, -x -- Do not compress. Useful on slow machines.\n"); printf(" --compression=n, -Xn -- Set the compression level\n"); printf(" --lzma_compress, -L -- Use LZMA compression (slow but better)\n"); printf(" --auto_compress, -A -- write as fast as possible, with compression if it helps.\n"); printf(" sets compression level 1\n"); printf(" --maxsize=n, -Mn -- sets the maximum size of output file to be n..\n"); printf(" Default units are megabytes; \n"); printf(" suffix with 'g', 'm', 'k' or 'b'\n"); printf(" use 'cd' for a 650MB CD.\n"); printf(" use 'bigcd' for a 700MB CD.\n"); printf(" --setseg name=value, -s name=value\n"); printf(" -- Create segment 'name' and give it 'value'\n"); printf(" This option may be repeated.\n"); printf(" --no_hash, -H -- Do not calculate MD5 and SHA1 of image.\n"); bold("\nError Recovery Options:\n"); printf(" --error_mode=0, -e0 -- Standard error recovery:\n"); printf(" Read disk 256K at a time until there are 5 errors in a row.\n"); printf(" Then go to the end of the disk and read backwards\n"); printf(" until there are 5 erros in a row. Then stop.\n"); printf(" --error=1 -e1 -- Stop reading at first error.\n"); printf(" --retry=nn -tnn -- change retry count from 5 to nn\n"); printf(" --reverse, -V -- Scan in reverse to the beginning.\n"); printf(" --recover-scan, -c -- Starting with an AFF file that has been partially \n"); printf(" acquired, try to read each page, 8 sectors at a time.\n"); printf(" (implies --append)\n"); bold("\nOther:\n"); printf(" --help, -h -- Print this message.\n"); printf(" --fast_quit, -Z -- Make ^c just exit immediately.\n"); printf(" --allow_regular, -E -- allow the imaging of a regular file\n"); printf(" --title=s, -T s -- change title to s (from IMAGING) and disable blink\n"); printf(" --debug=n, -d n -- set debug code n (-d0 for list)\n"); printf(" --use_timers, -y -- Use timers for compressing, reading & writing times\n"); bold("\nExamples:\n"); printf("Create image.aff from /dev/sd0:\n"); printf(" aimage /dev/sd0 image.aff\n"); printf(" aimage -o image.aff /dev/sd0 \n"); printf("\n"); printf("Create image0.aff from /dev/sd0 and image1 from /dev/sd1:\n"); printf(" aimage /dev/sd0 image0.aff /dev/sd1 /image1.aff\n"); printf("\n"); printf("Default values:\n"); printf(" config file: %s (need not be present)\n",AIMAGE_CONFIG_FILENAME); printf(" page size: %d\n",default_pagesize); printf(" default compression: %d\n",AF_COMPRESSION_DEFAULT); printf(" dfault compression algorithm: ZLIB\n"); exit(0);}int debug_list(){ puts("-d99 - Make all reads in imager fail. For testing error routines."); puts("-d2 - Print memcpy\n"); exit(0);}static struct option longopts[] = { { "raw", required_argument, NULL, 'r'}, // can use this for flags, but not for longs { "outfile", required_argument, NULL, 'o'}, { "quiet", no_argument, NULL, 'q'}, { "silent", no_argument, NULL, 'Q'}, { "readsectors", required_argument, NULL, 'R'}, { "image_pagesize",required_argument, NULL, 'S'}, { "zap", no_argument, NULL, 'z'}, { "help", no_argument, NULL, 'h'}, { "retry", required_argument, NULL, 't'}, { "no_compress", no_argument, NULL, 'x'}, { "compression", required_argument, NULL, 'X'}, { "lzma_compress", no_argument, NULL, 'L'}, { "auto_compress", no_argument, NULL, 'A'}, { "no_beeps", no_argument, NULL, 'B'}, { "append", no_argument, NULL, 'a'}, { "make_config", no_argument, NULL, 'm'}, { "logfile", required_argument, NULL, 'l'}, { "logAFF", no_argument, NULL, 'G'}, { "reverse", no_argument, NULL, 'V'}, { "fast_quit", no_argument, NULL, 'Z'}, { "allow_regular", no_argument, NULL, 'E'}, { "title", required_argument, NULL, 'T'}, { "preview", no_argument, NULL, 'p'}, { "no_preview", no_argument, NULL, 'P'}, { "maxsize", required_argument, NULL, 'M'}, { "debug", required_argument, NULL, 'd'}, { "error_mode", required_argument, NULL, 'e'}, { "setseg", required_argument, NULL, 's'}, { "no_hash", no_argument, NULL, 'H'}, { "use_timers", no_argument, NULL, 'y'}, { "version", no_argument, NULL, 'v'}, { "no_dmesg", no_argument, NULL, 'D'}, { "no_ifconfig", no_argument, NULL, 'I'}, { "batch", no_argument, NULL, 'Y'}, { "skip", required_argument, NULL, 'k'}, { "recover-scan", no_argument, NULL, 'c'}, {0,0,0,0}};/**************************************************************** *** Callbacks used for status display ****************************************************************//* * segwrite_callback: * called by AFF before and after each segment is written. */void segwrite_callback(struct affcallback_info *acbi){ imager *im = (imager *)acbi->af->tag; switch(acbi->phase){ case 1: /* Start of compression */ if(opt_use_timers) im->compression_timer.start(); break; case 2: /* End of compression */ if(opt_use_timers) im->compression_timer.stop(); break; case 3: /* Start of writing */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -