Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7712944
affix.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
7 KB
Referenced Files
None
Subscribers
None
affix.cpp
View Options
/**
* affix.cpp
*
* Fix an aff file that is corrupt.
* Current methodologies:
* - If file does not have a GUID, create one.
*/
/*
* 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
* 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 "affconfig.h"
#include "afflib.h"
#include "afflib_i.h"
#include "vnode_aff.h" // so we can use magical af_open_with...
#include <ctype.h>
#include <zlib.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <assert.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_TERM_H
#include <term.h>
#endif
#ifdef HAVE_NCURSES_TERM_H
#include <ncurses/term.h>
#endif
#ifdef WIN32
#include "unix4win32.h"
#include <malloc.h>
#endif
const char *progname = "affix";
int opt_fix = 0;
void usage()
{
printf("usage: %s [options] file1 [...]\n",progname);
printf(" -y = Actually modify the files; normally just reports the problems\n");
printf(" -v = Just print the version number and exit.\n");
exit(0);
}
/* Returns 0 if this is a valid AFF file, code if it isn't. */
int af_is_valid_afffile(const char *file)
{
return 0; // I should write this
}
int fix(const char *infile)
{
char buf[1024];
int flags = (opt_fix ? O_RDWR : O_RDONLY) | O_BINARY;
switch(af_identify_file_type(infile,1)){
case AF_IDENTIFY_ERR:
perror(infile);
return 0;
default:
fprintf(stderr,"%s is not an AFF file\n",infile);
return 0;
case AF_IDENTIFY_AFF:
break;
}
printf("%s ",infile);
int r=0;
/* First see if the if the file begins with an AFF flag */
int fd = open(infile,flags,0666);
if(fd<0) err(1,"fopen(%s)",infile);
if(read(fd,buf,strlen(AF_HEADER)+1)!=strlen(AF_HEADER)+1)
err(1,"can't read AFF file header. Stop.");
if(strcmp(buf,AF_HEADER)!=0)
err(1,"%s does not begin with an AF_HEADER. Stop.",infile);
if(read(fd,buf,strlen(AF_SEGHEAD)+1)!=strlen(AF_SEGHEAD)+1)
err(1,"Can't read AF_SEGHEAD after AF_HEADER. Stop.");
if(strcmp(buf,AF_SEGHEAD)!=0)
err(1,"%s does not have an AF_SEGHEAD after AF_SEGEADER. Stop.",infile);
/* Figure out length */
off_t len = lseek(fd,0,SEEK_END);
if(len<0) err(1,"Can't seek to end of %s. Stop.",infile);
close(fd);
AFFILE *af = af_open_with(infile,AF_HALF_OPEN|flags,0,&vnode_aff);
printf("Scanning AFF file...\n");
r = (*af->v->open)(af);
/* See if we can build a TOC */
if(r<0){
printf("AFF file corrupt at %"I64d" out of %"I64d" (%"I64d" bytes from end)\n",
ftello(af->aseg),(int64_t)len,len-ftello(af->aseg));
if(opt_fix){
printf("Truncating... %d \n",fileno(af->aseg));
if(ftruncate(fileno(af->aseg),ftello(af->aseg))){
err(1,"ftruncate");
}
}
}
/* See if it has a GID or an encrypted GID */
if(af_get_seg(af,AF_IMAGE_GID,0,0,0)!=0 &&
af_get_seg(af,AF_IMAGE_GID AF_AES256_SUFFIX,0,0,0)!=0){
printf("AFF file is missing a GID. ");
if(opt_fix){
printf("Making one...");
if(af_make_gid(af)<0) af_err(1,"af_make_gid");
}
putchar('\n');
}
af_close(af);
return 0;
}
#if 0
/* See if it ends properly */
off_t len;
printf("File is %"I64d" bytes long\n",len);
if(lseek(fd,len-4,SEEK_SET)<0)
err(1,"Can't backup %d bytes. Stop.",-4);
r = read(fd,buf,4);
if(r!=4)
err(1,"Can't read last %d bytes of file. Read %d. Stop. ", strlen(AF_SEGTAIL)+1,r);
if(strcmp(buf,AF_SEGTAIL)!=0){
printf("Does not end with an AF_SEGTAIL. Scanning backwards to find last complete AF_SEGTAIL.\n");
for(off_t end=len-4;end>4;end--){
if(lseek(fd,end,SEEK_SET)<0) err(1,"lseek bad=%"I64d,end);
r = read(fd,buf,4);
if(r!=4) err(1,"Can't read 4 bytes at %"I64d);
if(strcmp(buf,AF_SEGTAIL)==0){
printf("Valid AF_SEGTAIL found at %"I64d" (%"I64d" bytes in)\n",end,len-end);
if(!opt_fix) errx(0,"Rerun with -y flag to fix");
printf("Truncating at %"I64d"\n",end);
if(ftruncate(fd,end+4)) err(0,"ftruncate");
break;
}
}
}
close(fd);
exit(0);
AFFILE *af = af_open(infile,O_RDONLY,0);
if(!af) af_err(1,infile);
int fix = 0;
bool fix_add_gid = false;
if(af_get_seg(af,AF_IMAGE_GID,0,0,0)){
printf("no GID (%s)",AF_IMAGE_GID);
fix++;
fix_add_gid = true;
}
af_close(af);
if(opt_fix==0 || fix==0) return 0;
if(fix){
af = af_open(infile,O_RDWR,0);
if(!af){
warn(infile);
return -1;
}
if(fix_add_gid) {
printf(" ... adding GID ",infile);
unsigned char bit128[16];
RAND_pseudo_bytes(bit128,sizeof(bit128));
if(af_update_seg(af,AF_IMAGE_GID,0,bit128,sizeof(bit128))){
warn("Cannot write %s: ",AF_IMAGE_GID);
}
}
if(af_close(af)){
warn("Cannot close %s",infile);
}
}
putchar('\n');
return 0;
}
#endif
int main(int argc,char **argv)
{
int bflag, ch;
setvbuf(stdout,0,_IONBF,0); // turn off buffering
/* Figure out how many cols the screen has... */
bflag = 0;
while ((ch = getopt(argc, argv, "yh?v")) != -1) {
switch (ch) {
case 'y':
opt_fix = 1;
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();
}
/* Loop through all of the files */
while(*argv){
fix(*argv++); // get the file
argc--; // decrement argument counter
}
exit(0);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Nov 21, 12:05 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1361240
Default Alt Text
affix.cpp (7 KB)
Attached To
Mode
rXMOUNT xmount
Attached
Detach File
Event Timeline
Log In to Comment