📄 afcat.cpp
字号:
/* * afcat.cpp: * * cat the contents of an AFF file... *//* * Copyright (c) 2005, 2006 * 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 * 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"#include <stdio.h>#include <algorithm>#include <vector>using namespace std;vector <int64> pages;char *progname = "afcat";int opt_info = 0;char *opt_segname=0;int64 opt_pagenum = -1;int opt_quiet = 1;int opt_list= 0 ;int opt_list_long = 0;int opt_debug = 0;int64 opt_sector = -1;int opt_badflag = 0;void usage(){ printf("afcat version %s\n",PACKAGE_VERSION); printf("usage: afcat [options] infile [... more infiles]\n"); printf("options:\n"); printf(" -s name --- Just output segment name\n"); printf(" -p ### --- just output data page number ###\n"); printf(" -S ### --- Just output data sector ### (assumes 512-byte sectors). Sector #0 is first\n"); printf(" -q --- quiet; don't print to STDERR if a page is skipped\n"); printf(" -n --- noisy; tell when pages are skipped.\n"); printf(" -l --- List all of the segment names\n"); printf(" -L --- List segment names, lengths, and args\n"); printf(" -d --- debug. Print the page numbers to stderr as data goes to stdout\n"); printf(" -b --- Output BADFALG for bad blocks (default is NULLs)\n"); printf(" -v --- Just print the version number and exit.\n"); exit(0);}int compar(const void *a_,const void *b_){ int64 a = *(int *)a_; int64 b = *(int *)b_; if(a<b) return -1; if(a>b) return 1; return 0;}struct afm_private { AFFILE *aff; // the AFFILE we use for the actual metadata AFFILE *sr; // the AFFILE we use for the splitraw int sr_initialized; // has the split-raw been setup from AFM?};int output_page(AFFILE *af,FILE *outfile,int64 pagenum){ unsigned char *buf = (unsigned char *)malloc(af->image_pagesize); if(buf==0){ err(1,"malloc(%d) failed",(int)af->image_pagesize); } uint64 offset = (uint64)pagenum * af->image_pagesize; // go to that location af_seek(af,offset,SEEK_SET); int bytes = af_read(af,buf,af->image_pagesize); // read what we can if(bytes<0){ if(opt_debug) fprintf(stderr,"afcat: cannot read page %"I64d"\n",pagenum); return -1; } if(opt_debug){ fprintf(stderr,"afcat: page:%"I64d" bytes: %d offset:%"I64d"\n", pagenum, bytes,offset); } /* Check each sector to see if it is badflag or not. * If it is and if opt_badflag is not set, make it all NULs. */ for(unsigned char *cc=buf;cc<buf+bytes;cc+=af->image_sectorsize){ if(af_is_badsector(af,cc) && opt_badflag==0){ memset(cc,0,af->image_sectorsize); } } if(opt_debug) fprintf(stderr," outputing %d bytes\n",bytes); fwrite(buf,1,bytes,outfile); // send to the output free(buf); return bytes;}int afcat(AFFILE *af){ int64 total_bytes_written = 0; /* Read all of the pages from beginning to end and capture * all the segment numbers... */#ifdef WIN32 _setmode(fileno(stdout),_O_BINARY);#endif if(opt_debug) fprintf(stderr,"afcat(%s)\n",af_filename(af)); if(opt_segname){ /* First figure out how big the segment is */ size_t datalen = 0; if(af_get_seg(af,opt_segname,0,0,&datalen)){ fprintf(stderr,"%s: segment '%s' does not exist\n", af_filename(af),opt_segname); return -1; } unsigned char *data = (unsigned char *)malloc(datalen); if(data==0) err(1,"malloc"); if(af_get_seg(af,opt_segname,0,data,&datalen)){ free(data); fprintf(stderr,"%s: could not read segment '%s'\n", af_filename(af),opt_segname); return -1; } fwrite(data,1,datalen,stdout); free(data); return 0; } if(opt_pagenum != -1){ // just write a particular page? int r = output_page(af,stdout,opt_pagenum); return r>=0 ? 0 : -1; } if(opt_sector>=0){ unsigned char *buf = (unsigned char *)malloc(af->image_sectorsize); af_seek(af,(uint64)opt_sector*af->image_sectorsize,SEEK_SET); int r = af_read(af,buf,af->image_sectorsize); if(r>0){ fwrite(buf,1,r,stdout); } free(buf); return 0; } /* Get a list of all the segments. If we are doing a list, just print them. * If we are not doing a list, capture the data pages and put their numbers * into an array. */ if(opt_debug) fprintf(stderr,"af_rewind_seg()\n"); af_rewind_seg(af); // start at the beginning char segname[AF_MAX_NAME_LEN]; unsigned long arg; size_t datalen = 0; memset(segname,0,sizeof(segname)); while(af_get_next_seg(af,segname,sizeof(segname),&arg,0,&datalen)==0){ if(opt_debug) fprintf(stderr,"af_get_next_seg found segment %s\n",segname); if(segname[0]==0) continue; // ignore sector if(opt_list){ printf("%s",segname); if(opt_list_long){ printf("\targ:%lu\tlen:%d",arg,(int)datalen); } putchar('\n'); } else { int64 pagenum = af_segname_page_number(segname); if(pagenum>=0) pages.push_back(pagenum); } datalen = 0; // allow to get the next one } if(opt_list) return 0; // that's all that was wanted. sort(pages.begin(),pages.end()); /* Now I have a list of pages; cat each one */ int next_page = 0; // starting page number int64 imagesize = af_get_imagesize(af); for(vector<int64>::iterator i = pages.begin(); i != pages.end(); i++){ int page = *i; if(page != next_page && opt_quiet==0){ if(page == next_page+1 ){ fprintf(stderr,"afcat: page %d not in file\n",next_page); } else{ fprintf(stderr,"afcat: pages %d through %d not in file\n", next_page,page-1); } } int r = output_page(af,stdout,page); if(r<0) return -1; total_bytes_written += r; next_page = page + 1; // note what should be next //fprintf(stderr,"bytes written=%qd imagesize=%qd\n",total_bytes_written,imagesize); if((total_bytes_written > imagesize) && (imagesize>0)){ err(1,"afcat internal error. bytes written=%"I64d" imagesize=%" I64d, (int64)total_bytes_written, (int64)imagesize); return -1; } } return 0;}int64 atoi64(const char *buf){ int64 r=0; char ch; if(sscanf(buf,"%"I64d"%c",&r,&ch)==1) return r; fprintf(stderr,"Cannot parse '%s'\n",buf); exit(0);}int main(int argc,char **argv){ int bflag, ch; bflag = 0; while ((ch = getopt(argc, argv, "s:S:p:lLh?dqnv")) != -1) { switch (ch) { case 's': opt_segname = optarg; break; case 'S': opt_sector = atoi64(optarg); break; case 'p': opt_pagenum = atoi64(optarg); break; case 'q': opt_quiet = 1; break; case 'n': opt_quiet = 0; break; case 'l': opt_list = 1; break; case 'L': opt_list = 1; opt_list_long = 1; break; case 'b': opt_badflag = 1; break; case 'd': opt_debug++; break; case 'h': case '?': default: usage(); break; case 'v': printf("%s version %s\n",progname,PACKAGE_VERSION); exit(0); } } argc -= optind; argv += optind; if(argc<1){ usage(); } while(*argv){ AFFILE *af = af_open(*argv,O_RDONLY,0); if(!af) err(1,"afcat(%s)",*argv); if(afcat(af)) err(1,"afcat"); af_close(af); argv++; argc--; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -