From ba7985f18aad32187de1612815fe8dc20d1e0c21 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 3 Apr 2009 17:20:33 +0000 Subject: [PATCH] Fixed a potential blind spot of 1 second in -disk_dev_ino comparison --- libisoburn/trunk/xorriso/xorriso.1 | 6 ++-- libisoburn/trunk/xorriso/xorriso.c | 34 +++++++++++++++++- libisoburn/trunk/xorriso/xorriso_private.h | 15 ++++++-- libisoburn/trunk/xorriso/xorriso_timestamp.h | 2 +- libisoburn/trunk/xorriso/xorrisoburn.c | 36 ++++++++++++++++++++ 5 files changed, 86 insertions(+), 7 deletions(-) diff --git a/libisoburn/trunk/xorriso/xorriso.1 b/libisoburn/trunk/xorriso/xorriso.1 index efc74b4a..1ecb3e82 100644 --- a/libisoburn/trunk/xorriso/xorriso.1 +++ b/libisoburn/trunk/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Apr 02, 2009" +.TH XORRISO 1 "Apr 03, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -684,7 +684,9 @@ See also options -getfattr, -setfattr and above paragraph about xattr. \fB\-disk_dev_ino\fR "on"|"ino_only"|"off" Enable or disable processing of recorded file identification numbers (dev_t and ino_t). They are eventually stored as xattr "isofs.di" and allow -to substantially accelerate file comparison. +to substantially accelerate file comparison. The root node gets a global start +timestamp in "isofs.st". If during comparison a file with younger timestamps +is found in the ISO image, then it is suspected to have inconsistent content. .br If device numbers and inode numbers of the disk filesystems are persistent and if no irregular alterations of timestamps or system clock happen, diff --git a/libisoburn/trunk/xorriso/xorriso.c b/libisoburn/trunk/xorriso/xorriso.c index 156da39b..e2f5225f 100644 --- a/libisoburn/trunk/xorriso/xorriso.c +++ b/libisoburn/trunk/xorriso/xorriso.c @@ -1572,6 +1572,7 @@ completed:; 0= ls -l format 1= timestamp format YYYY.MM.DD.hhmmss 2= Wdy Mon Day hh:mm:ss Year + 3= Mon Day hh:mm:ss Year */ char *Ftimetxt(time_t t, char timetext[40], int flag) { @@ -1596,6 +1597,10 @@ char *Ftimetxt(time_t t, char timetext[40], int flag) sprintf(rpt+strlen(rpt), "%s %s %2.2d %2.2d:%2.2d:%2.2d %4.4d", days[tms.tm_wday], months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min, tms.tm_sec, 1900+tms.tm_year); + else if (form==3) + sprintf(rpt+strlen(rpt), "%s %2.2d %2.2d:%2.2d:%2.2d %4.4d", + months[tms.tm_mon], tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec, 1900+tms.tm_year); else if (flag&1) sprintf(rpt+strlen(rpt), "%2d %3s %4.4d %2.2d:%2.2d:%2.2d", tms.tm_mday, months[tms.tm_mon], 1900+tms.tm_year, @@ -4103,6 +4108,8 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->in_drive_handle= NULL; m->in_volset_handle= NULL; m->in_charset= NULL; + m->isofs_st_out= time(0) - 1; + m->isofs_st_in= 0; m->volset_change_pending= 0; m->no_volset_present= 0; m->in_sector_map= NULL; @@ -6772,6 +6779,7 @@ cannot_address:; bit20= xattr differ bit21= mismatch of recorded dev,inode bit22= no recorded dev,inode found in node + bit23= timestamps younger than xorriso->isofs_st_in @param flag bit0= compare atime bit1= compare ctime bit2= check only existence of both file objects @@ -6797,6 +6805,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, char *attrlist1= NULL, *attrlist2= NULL; struct SplitparT *split_parts= NULL; int split_count= 0; + time_t stamp; char part_path[SfileadrL], *part_name; int partno, total_parts= 0; @@ -7016,6 +7025,11 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, (*result)|= 1024; } } + if(xorriso->isofs_st_in > 0 && + (xorriso->isofs_st_in <= s2.st_mtime || + ((flag & 1) && xorriso->isofs_st_in <= s2.st_atime) || + ((flag & 2) && xorriso->isofs_st_in <= s2.st_ctime))) + (*result)|= 1 << 23; if(xorriso->do_aaip & 32) { /* dev,inode comparison. Eventually skip content comparison */ @@ -7026,8 +7040,26 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, } else if(ret == 0) { /* match */ if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){ content_shortcut= 1; - if((*result) & (8 | 128 | 256 | 512 | 1024)) { + if((*result) & (8 | 128 | 256 | 512 | 1024 | (1 << 23))) { (*result)|= (1 << 15); /* content bytes differ */ + if(((*result) & (1 << 23)) && + !((*result) & (8 | 128 | 256 | 512 | 1024))) { + sprintf(respt, + "%s content : node timestamp younger than image timestamp\n", a); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + stamp= s2.st_mtime; + if((flag & 1) && s2.st_atime >= stamp) + stamp= s2.st_atime; + if((flag & 2) && s2.st_ctime >= stamp) + stamp= s2.st_ctime; + sprintf(respt, "%s content : %s > %s diff= %.f s\n", + a, Ftimetxt(stamp, ttx1, 3 << 1), + Ftimetxt(xorriso->isofs_st_in, ttx2, 3 << 1), + ((double) stamp) - (double) xorriso->isofs_st_in); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + } sprintf(respt, "%s content : assuming inequality due to size or timestamps\n", a); if(!(flag&(1<<31))) diff --git a/libisoburn/trunk/xorriso/xorriso_private.h b/libisoburn/trunk/xorriso/xorriso_private.h index ad0502c7..e48612b6 100644 --- a/libisoburn/trunk/xorriso/xorriso_private.h +++ b/libisoburn/trunk/xorriso/xorriso_private.h @@ -101,9 +101,13 @@ struct XorrisO { /* the global context of xorriso */ int do_joliet; - int do_aaip; /* bit0= ACL in , bit1= ACL out , bit2= EA in , bit3= EA out - bit4= record dev,inode , bit5= check dev,inode - bit6= omit content check if dev,inode check is conclusive + int do_aaip; /* bit0= ACL in + bit1= ACL out + bit2= EA in + bit3= EA out + bit4= record dev,inode per node, isofs_st_out in root + bit5= check dev,inode,isofs_st_in + bit6= omit content check if bit5 check is conclusive bit7= omit dev check with bit5 bit8= store output charset in xattr "isofs.cs" bit9= allow to set input charset from xattr "isofs.cs" @@ -174,6 +178,11 @@ struct XorrisO { /* the global context of xorriso */ void *in_drive_handle; /* interpreted only by xorrisoburn.c */ void *in_volset_handle; /* interpreted only by xorrisoburn.c */ char *in_charset; /* The charset to interpret the filename bytes */ + time_t isofs_st_out; /* A time point at least 1 second before image + composition began. To be stored with image as + xattr "isofs.st". */ + time_t isofs_st_in; /* That time point as read from "isofs.st" of the + loaded image. */ int volset_change_pending; /* whether -commit would make sense */ int no_volset_present; /* set to 1 on first failure */ diff --git a/libisoburn/trunk/xorriso/xorriso_timestamp.h b/libisoburn/trunk/xorriso/xorriso_timestamp.h index c1a57d0c..8ae79e73 100644 --- a/libisoburn/trunk/xorriso/xorriso_timestamp.h +++ b/libisoburn/trunk/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.04.02.162530" +#define Xorriso_timestamP "2009.04.03.172034" diff --git a/libisoburn/trunk/xorriso/xorrisoburn.c b/libisoburn/trunk/xorriso/xorrisoburn.c index 4c784fd0..bcd70ac0 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.c +++ b/libisoburn/trunk/xorriso/xorrisoburn.c @@ -527,8 +527,12 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) struct burn_drive *drive, *out_drive, *in_drive; enum burn_disc_status state; IsoImage *volset = NULL; + IsoNode *root_node; struct isoburn_read_opts *ropts= NULL; char libburn_adr[SfileadrL], *boot_fate, *sev; + size_t value_length; + char *value= NULL; + double num; static int no_rr_or_joliet= 0; @@ -541,6 +545,8 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) ret= Xorriso_give_up_drive(xorriso, (flag&3)|8); if(ret<=0) return(ret); + if(flag & 1) + xorriso->isofs_st_out= time(0) - 1; ret= Xorriso_auto_driveadr(xorriso, adr, libburn_adr, 0); if(ret <= 0) @@ -778,6 +784,21 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); Xorriso_record_boot_info(xorriso, 0); } + + if(flag & 1) { + /* Look for isofs.st and put it into xorriso->isofs_st_in */; + root_node= (IsoNode *) iso_image_get_root(volset); + ret= iso_node_lookup_attr(root_node, "isofs.st", &value_length, &value, 0); + if(ret > 0) { + if(value_length > 0) { + sscanf(value, "%lf", &num); + if(num > 0) + xorriso->isofs_st_in= num; + } + free(value); + } + } + if(!(flag&32)) { Xorriso_toc(xorriso, 1 | 8); if(xorriso->loaded_volid[0]!=0) { @@ -845,6 +866,8 @@ int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag) xorriso->in_volset_handle= NULL; Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); xorriso->loaded_volid[0]= 0; + xorriso->isofs_st_out= time(0) - 1; + xorriso->isofs_st_in= 0; xorriso->volset_change_pending= 0; xorriso->no_volset_present= 0; xorriso->loaded_boot_bin_lba= 0; @@ -1314,6 +1337,19 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); } } + + if(xorriso->do_aaip & 16) { + /* Overwrite isofs.st of root node by xorriso->isofs_st_out */ + char *name= "isofs.st"; + char timestamp[16], *value= timestamp; + size_t value_length; + + sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out); + value_length= strlen(timestamp); + Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name, + &value_length, &value, 2 | 8); + } + isoburn_igopt_set_level(sopts, 3); isoburn_igopt_set_extensions(sopts, 1 | ((!!xorriso->do_joliet)<<1) | ((!!(xorriso->do_aaip & (2 | 8 | 16 | 256))) << 5));