📄 afconvert.cpp
字号:
/* * afconvert.cpp: * * Convert raw -> aff * aff -> raw * aff -> aff (recompressing/uncompressing) */#include "config.h"#include "afflib.h"#include "afflib_i.h" // we do enough mucking, we need the internal version#include <openssl/md5.h>#include <openssl/sha.h>#ifdef HAVE_CURSES_H#include <curses.h>#endif#ifdef HAVE_TERM_H#include <term.h>#endif#ifdef HAVE_NCURSES_TERM_H#include <ncurses/term.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef linux#include <sys/time.h>#endif#ifdef HAVE_GETOPT_H#include <getopt.h>#endif/* * Copyright (c) 2005 * Simson L. Garfinkel and Basis Technology, Inc. * 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, * Basis Technology, and its contributors. * 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. */char *progname = "afconvert";int image_pagesize = 16*1024*1024; // default seg size --- 16MBint opt_compression_alg = AF_COMPRESSION_ALG_ZLIB;int opt_compress_level = AF_COMPRESSION_DEFAULT;int64 bytes_to_convert = 0;int opt_batch = 1;int opt_zap = 0;int opt_quiet = 0;int opt_nozprobe = 0;int opt_write_raw = 0; // outputchar *opt_write_raw_ext = "raw";char *opt_outdir = 0;char *opt_aff_ext = "aff";int64 opt_maxsize = 0;int opt_yes = 0;int opt_debug = 0;char *command_line = 0; // what is typedchar *append(char *base,char *str){ base = (char *)realloc(base,strlen(base)+strlen(str)+1); strcat(base,str); // can't fail return base;}void usage(){ printf("%s version %s\n",progname,PACKAGE_VERSION); printf("\n"); printf("usage: %s [options] file1 [... files] \n",progname); printf("\n"); printf("examples:\n"); printf(" %s file1.iso --- convert file1.iso to file1.aff\n",progname); printf(" %s file1.iso file2.iso file3.iso... --- batch convert files\n",progname); printf(" %s -r -e iso image.aff --- convert image.aff to image.iso\n",progname); //printf(" %s -p image.aff --- recompress image.aff to maximum compression\n",progname); printf("\n"); printf("\nGeneral options:\n"); printf(" -q -- Quiet mode. Don't ask questions, don't print status.\n"); printf("\nAFF output options:\n"); printf(" -a ext -- use 'ext' for aff files (default is %s)\n",opt_aff_ext); printf(" (use .afd for AFD files)\n"); printf(" -M nnn -- set maximum size of output file. Suffix with g, m or k.\n"); printf(" -s nnnn -- set the image_pagesize (default %d)\n",image_pagesize); printf(" -x -- don't compress AFF file.\n"); printf(" -O dir -- use 'dir' as the output directory\n"); printf(" -o file -- output to 'file' (can only convert one at a time)\n"); printf(" File is AFF is file ends .aff; otherwise assumes raw.\n"); printf(" -Xn -- Set compression to n; default is 7\n"); printf(" -L -- Use the LZMA compression algorithm (better but slower)\n"); printf("\nRaw output options:\n"); printf(" -r -- force raw output. \n"); printf(" -e ext -- use 'ext' for the raw files (default %s)\n",opt_write_raw_ext); printf(" (implies -r)\n"); printf("\nDangerous input options:\n"); printf(" -z -- zap; delete the output file if it already exists.\n"); printf(" -Z -- Do not automatically probe for gzip/bzip2 compression.\n"); printf(" -y -- Always answer yes/no questions 'yes.'\n"); printf(" -V = Just print the version number and exit.\n"); printf("\n"); exit(0);}/* probe_gzip(): * Is this a gzip file? * Right now it just looks at the file extension. */int probe_gzip(const char *infile){ int len = strlen(infile); if(len>3 && strcmp(infile+len-3,".gz")==0){ return 1; } return 0;}int probe_bzip2(const char *infile){ int len = strlen(infile); if(len>4 && strcmp(infile+len-4,".bz2")==0){ return 1; } return 0;}/* yesno(): * As a yes/no question. Return 1 if yes, 0 if no. */int yesno(char *statement,char *question,char *affirmative){ if(opt_yes){ if(!opt_quiet) printf("%s. %s.\n",statement,affirmative); return 1; } printf("%s. ",statement); char buf[256]; do { printf("%s [y/n]: ",question); memset(buf,0,sizeof(buf)); fgets(buf,sizeof(buf)-1,stdin); if(buf[0]=='y' || buf[0]=='Y'){ printf("%s.\n",affirmative); return 1; } } while(buf[0]!='n' && buf[0]!='N'); return 0;}/* * Basic conversion: * We have an input, which may be raw or aff, * and we have an output, which may be raw or aff. * We are going to want to read a segment at a time. */#include <algorithm>#include <cstdlib>#include <vector>#include <string>using namespace std;int convert(const char *infile,char *outfile){ if(opt_debug) fprintf(stderr,"convert(%s,%s)\n",infile,outfile); if(access(infile,F_OK)!=0){ err(1,"%s",infile); // file does not exist? } if(infile && outfile && strcmp(infile,outfile)==0){ errx(1,"Can't convert a file to itself\n"); } if(!opt_quiet) printf("convert %s --> %s\n",infile,outfile); /**************************************************************** *** Open Input ****************************************************************/ AFFILE *a_in = 0; // input file, if aff /* Check to see if it is a gzip file... */ if(probe_gzip(infile) && yesno("infile looks like a gzip file","Uncompress it","Uncompressing")){ /* Open with a subprocess. We will need to use zlib when we move to Windows. */ if(af_hasmeta(infile)) return -1; // don't covert with shell metacharacters char buf[256]; snprintf(buf,sizeof(buf),"gzcat %s",infile); a_in = af_popen(buf,"r"); } /* Check to see if it is a bzip2 file... */ if(!a_in && probe_bzip2(infile) && yesno("infile looks like a bzip2 file","Uncompress it","Uncompressing")){ /* Open with a subprocess. We will need to use bzip2zlib when we move to Windows. */ if(af_hasmeta(infile)) return -1; // don't covert with shell metacharacters char buf[256]; snprintf(buf,sizeof(buf),"bzcat %s",infile); a_in = af_popen(buf,"r"); } /* If the file isn't open, try to open it... */ if(!a_in){ a_in = af_open(infile,O_RDONLY,0); if(!a_in) err(1,"%s",infile); // give up if(af_identify(a_in)==AF_IDENTIFY_RAW){ af_set_pagesize(a_in,image_pagesize); // match the page size we want to use } else { image_pagesize = a_in->image_pagesize; // that's what we are using } } /**************************************************************** *** Open Ouptut ****************************************************************/ if(opt_zap) unlink(outfile); // we were told to zap it AFFILE *a_out = 0; // output file, if aff or raw... if(access(outfile,F_OK)==0){ /* If outfile is a device, ask user... */ struct stat sb; if(stat(outfile,&sb)){ err(1,"%s exists but can't be stat?",outfile); } if((sb.st_mode & S_IFMT)==S_IFCHR || (sb.st_mode & S_IFMT)==S_IFBLK){ char buf[1024]; snprintf(buf,sizeof(buf),"%s is a raw device.\n",outfile); if(yesno(buf,"Overwrite raw device?","yes")){ goto doit; } } fprintf(stderr,"%s: file exists. Delete it before converting.\n",outfile); return -1; } /* Check for splitraw names */ if(af_ext_is(outfile,"afm")){ char file000[MAXPATHLEN+1]; strlcpy(file000,outfile,sizeof(file000)); char *cc = rindex(file000,'.'); if(!cc) err(1,"Cannot file '.' in %s\n",file000); for(int i=0;i<2;i++){ sprintf(cc,".%03d",i); if(access(file000,F_OK)==0){ fprintf(stderr,"%s: file exists. Delete it before converting.\n",file000); fprintf(stderr,"NOTE: -z option will not delete %s\n",file000); return -1; } } } doit:; if(opt_write_raw){ /* Easy way to make a raw output is to reopen an existing output file... */ FILE *f = fopen(outfile,"w+b"); if(!f){ err(1,"%s",outfile); } a_out = af_freopen(f); } else { a_out = af_open(outfile,O_RDWR|O_CREAT|O_BINARY,0777); if(opt_maxsize){ af_set_maxsize(a_out,opt_maxsize); } } if(a_out == 0) err(1,"af_open: %s",outfile); af_enable_writing(a_out,1); // we will be writing af_update_seg(a_out,AF_ACQUISITION_COMMAND_LINE,0,command_line,strlen(command_line)); /**************************************************************** *** Set up the AFF file (assuming it's an aff file) *** stuff that we keep at the beginning of the file... ****************************************************************/ unsigned char md5_buf[16]; unsigned char sha1_buf[20]; memset(md5_buf,0,sizeof(md5_buf)); memset(sha1_buf,0,sizeof(sha1_buf)); MD5_CTX md5; MD5_Init(&md5); SHA_CTX sha; SHA1_Init(&sha); /* Setup writing */ if(a_in->image_pagesize){ image_pagesize = a_in->image_pagesize; } af_set_pagesize(a_out,image_pagesize); af_set_sectorsize(a_out,a_in->image_sectorsize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -