From 6cfbe6fcd03a3f2dc0cff4e2ba706839b736069e Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 25 Mar 2008 17:07:58 +0000 Subject: [PATCH] Working towards coordination of -compare, -update and -cut_out --- xorriso/xorriso.c | 416 +++++++++++++++++++++++++++++++----- xorriso/xorriso_private.h | 9 +- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 32 ++- xorriso/xorrisoburn.h | 3 +- 5 files changed, 391 insertions(+), 71 deletions(-) diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 9ada6951..d41db90d 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2741,12 +2741,12 @@ int Splitparts_new(struct SplitparT **o, int count, int flag) if((*o)==NULL) return(-1); for(i= 0; iname= NULL; - o[i]->partno= 0; - o[i]->total_parts= 0; - o[i]->offset= 0; - o[i]->bytes= 0; - o[i]->total_bytes= 0; + (*o)[i].name= NULL; + (*o)[i].partno= 0; + (*o)[i].total_parts= 0; + (*o)[i].offset= 0; + (*o)[i].bytes= 0; + (*o)[i].total_bytes= 0; } return(1); } @@ -2759,8 +2759,8 @@ int Splitparts_destroy(struct SplitparT **o, int count, int flag) if((*o)==NULL) return(0); for(i= 0; iname!=NULL) - free(o[i]->name); + if((*o)[i].name!=NULL) + free((*o)[i].name); } free(*o); *o= NULL; @@ -2768,15 +2768,34 @@ int Splitparts_destroy(struct SplitparT **o, int count, int flag) } -int Splitpart_set(struct SplitparT *o, char *name, int partno, int total_parts, - off_t offset, off_t bytes, off_t total_bytes, int flag) +int Splitparts_set(struct SplitparT *o, int idx, + char *name, int partno, int total_parts, + off_t offset, off_t bytes, off_t total_bytes, int flag) { - o->name= name; - o->partno= partno; - o->total_parts= total_parts; - o->offset= offset; - o->bytes= bytes; - o->total_bytes= total_bytes; + if(o[idx].name!=NULL) + free(o[idx].name); + o[idx].name= strdup(name); + if(o[idx].name==NULL) + return(-1); + o[idx].partno= partno; + o[idx].total_parts= total_parts; + o[idx].offset= offset; + o[idx].bytes= bytes; + o[idx].total_bytes= total_bytes; + return(1); +} + + +int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno, + int *total_parts, off_t *offset, off_t *bytes, + off_t *total_bytes, int flag) +{ + *name= o[idx].name; + *partno= o[idx].partno; + *total_parts= o[idx].total_parts; + *offset= o[idx].offset; + *bytes= o[idx].bytes; + *total_bytes= o[idx].total_bytes; return(1); } @@ -2812,25 +2831,25 @@ int Splitpart__parse(char *name, int *partno, int *total_parts, char *cpt, *ept; cpt= name; - ret= Splitpart__read_next_num(name, &ept, &num, 0); + ret= Splitpart__read_next_num(cpt, &ept, &num, 0); if(ret<=0) return(ret); *partno= num; cpt= ept; - ret= Splitpart__read_next_num(name, &ept, &num, 0); + ret= Splitpart__read_next_num(cpt, &ept, &num, 0); if(ret<=0) return(ret); *total_parts= num; cpt= ept; - ret= Splitpart__read_next_num(name, &ept, offset, 0); + ret= Splitpart__read_next_num(cpt, &ept, offset, 0); if(ret<=0) return(ret); cpt= ept; - ret= Splitpart__read_next_num(name, &ept, bytes, 0); + ret= Splitpart__read_next_num(cpt, &ept, bytes, 0); if(ret<=0) return(ret); cpt= ept; - ret= Splitpart__read_next_num(name, &ept, total_bytes, 0); + ret= Splitpart__read_next_num(cpt, &ept, total_bytes, 0); if(ret<=0) return(ret); return(1); @@ -4342,6 +4361,165 @@ much_too_long:; } +#define Xorriso_with_compare_2_contentS yes + +/* + @param result Bitfield indicationg type of mismatch + bit11= cannot open regular disk file + bit12= cannot open iso file + bit13= early eof of disk file + bit14= early eof of iso file + bit15= content bytes differ + @param flag bit0= mtimes of both file objects are equal + bit29= do not issue pacifier messages + bit31= do not issue result messages +*/ +int Xorriso_compare_2_contents(struct XorrisO *xorriso, char *common_adr, + char *disk_adr, off_t disk_size, + off_t offset, off_t bytes, + char *iso_adr, off_t iso_size, + int *result, int flag) +{ + int fd1= -1, ret, r1, r2, done, wanted, i; + void *stream2= NULL; + off_t r1count= 0, r2count= 0, diffcount= 0, first_diff= -1; + char *respt, buf1[32*1024], buf2[32*1024], offset_text[80]; + + respt= xorriso->result_line; + + fd1= open(disk_adr, O_RDONLY); + if(fd1==-1) { + sprintf(respt, "- %s (DISK) : cannot open() : %s\n", + disk_adr, strerror(errno)); +cannot_address:; + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + (*result)|= 2048; + return(0); + } + if(offset>0) + if(lseek(fd1, offset, SEEK_SET)==-1) { + sprintf(respt, "- %s (DISK) : cannot lseek(%.f) : %s\n", + disk_adr, (double) offset, strerror(errno)); + close(fd1); + goto cannot_address; + } + + ret= Xorriso_iso_file_open(xorriso, iso_adr, &stream2, 0); + if(ret<=0) { + sprintf(respt, "- %s (ISO) : cannot open() file in ISO image\n", iso_adr); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + close(fd1); + (*result)|= 4096; + return(0); + } + + done= 0; + while(!done) { + + wanted= sizeof(buf1); + if(r1count+offset+wanted>disk_size) + wanted= disk_size-r1count-offset; + if(r1count+wanted>bytes) + wanted= bytes-r1count; + r1= 0; + while(wanted>0) { + ret= read(fd1, buf1, wanted); + if(ret<=0) + break; + wanted-= ret; + r1+= ret; + } + + wanted= sizeof(buf2); + if(r2count+wanted>iso_size) + wanted= iso_size-r2count; +/* + if(r2count+wanted>bytes) + wanted= bytes-r2count; +*/ + if(wanted>0) + r2= Xorriso_iso_file_read(xorriso, stream2, buf2, wanted, 0); + else + r2= 0; + + if(r1<=0 && r2<=0) + break; + if(r1<=0) { + if(r1<0) + r1= 0; + if(disk_size > r1count + r1 + offset) { + sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n", + disk_adr, (double) r1count); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + (*result)|= 8196; + } + (*result)|= (1<<15); + } + r1count+= r1; + if(r2<=0 || r2 r2count + r2) { + sprintf(respt, "- %s (ISO) : early EOF after %.f bytes\n", + iso_adr, (double) r2count); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + (*result)|= (1<<14); + } + (*result)|= (1<<15); + done= 1; + } + if(r2>r1) { + if(disk_size > r1count + r1 + offset) { + sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n", + disk_adr, (double) r1count); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + (*result)|= 8196; + } + (*result)|= (1<<15); + done= 1; + } + r2count+= r2; + if(r1>r2) + r1= r2; + for(i= 0; ipacifier_count+= r1; + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 0); + } + } + if(diffcount>0 || r1count!=r2count) { + if(first_diff<0) + first_diff= (r1count>r2count ? r2count : r1count); + offset_text[0]= 0; + if(offset>0) + sprintf(offset_text, "%.f+", (double) offset); + sprintf(respt, "%s %s : differs by at least %.f bytes. First at %s%.f\n", + common_adr, (flag&1 ? "CONTENT": "content"), + (double) (diffcount + abs(r1count-r2count)), + offset_text, (double) first_diff); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + (*result)|= (1<<15); + } + if(fd1!=-1) + close(fd1); + Xorriso_iso_file_close(xorriso, &stream2, 0); + return(1); +} + + /* @param result Bitfield indicationg type of mismatch bit0= disk_adr not existing @@ -4361,7 +4539,8 @@ much_too_long:; bit14= early eof of iso file bit15= content bytes differ bit16= symbolic link on disk pointing to dir, dir in iso - >>> bit17= file chunks detected and compared + bit17= file chunks detected and compared + bit18= incomplete chunk collection encountered @param flag bit0= compare atime bit1= compare ctime bit2= check only existence of both file objects @@ -4377,12 +4556,23 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, int *result, int flag) { struct stat s1, s2, stbuf; - int ret, r1, r2, fd1= -1, i, done, wanted, missing= 0, is_split= 0; - void *stream2= NULL; + int ret, missing= 0, is_split= 0, i; char *respt; - char buf1[32*1024], buf2[32*1024], a[5*SfileadrL], sfe[5*SfileadrL]; + char a[5*SfileadrL], sfe[5*SfileadrL]; char ttx1[40], ttx2[40]; + struct SplitparT *split_parts= NULL; + int split_count= 0; + +#ifdef Xorriso_with_compare_2_contentS + char part_path[SfileadrL], *part_name; + int partno, total_parts= 0; + off_t offset, bytes, total_bytes; +#else /* Xorriso_with_compare_2_contentS */ + void *stream2= NULL; + int fd1= -1, wanted, r1, r2, done; off_t r1count= 0, r2count= 0, diffcount= 0, first_diff= -1; + char buf1[32*1024], buf2[32*1024]; +#endif /* Xorriso_with_compare_2_contentS */ *result= 0; respt= xorriso->result_line; @@ -4419,21 +4609,21 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, } if((flag&4)||missing) - return(!missing); + {ret= !missing; goto ex;} + + + /* Splitfile parts */ + if((S_ISREG(s1.st_mode) || S_ISBLK(s1.st_mode)) && S_ISDIR(s2.st_mode)) { + is_split= Xorriso_identify_split(xorriso, iso_adr, &split_parts, + &split_count, &s2, 0); + if(is_split>0) + (*result)|= (1<<17); + else + is_split= 0; + } /* Attributes */ if(s1.st_mode != s2.st_mode) { - - if((S_ISREG(s1.st_mode) || S_ISBLK(s1.st_mode)) && S_ISDIR(s2.st_mode)) { - - /* >>> SPLIT */ - /* >>> check whether there are only part_files in the directory */; - /* >>> is_split= 1; */; - /* >>> count this as content chunk container */; - /* >>> compare access permissions of first chunk */; - - } - if((s1.st_mode&~S_IFMT)!=(s2.st_mode&~S_IFMT)) { sprintf(respt, "%s st_mode : %7.7o <> %7.7o\n", a, s1.st_mode, s2.st_mode); @@ -4519,6 +4709,45 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, } } if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)) { + +#ifdef Xorriso_with_compare_2_contentS + + /* Content */ + if(is_split) { + for(i= 0; i0 && split_count!=total_parts) { + sprintf(xorriso->info_text, + "- %s/* (ISO) : Not all split parts present (%d of %d)\n", + iso_adr, split_count, total_parts); + if(!(flag&(1<<31))) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1); + (*result)|= 1<<18; + } + } else { + ret= Xorriso_compare_2_contents(xorriso, a, disk_adr, s1.st_size, + (off_t) 0, s1.st_size, + iso_adr, s2.st_size, result, + (s1.st_mtime==s2.st_mtime) | (flag&((1<<29)|(1<<31)))); + } + +#else /* Xorriso_with_compare_2_contentS */ + fd1= open(disk_adr, O_RDONLY); if(fd1==-1) { sprintf(respt, "- %s (DISK) : cannot open() : %s\n", @@ -4526,7 +4755,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, if(!(flag&(1<<31))) Xorriso_result(xorriso,0); (*result)|= 2048; - return(0); + {ret= 0; goto ex;} } ret= Xorriso_iso_file_open(xorriso, iso_adr, &stream2, 0); @@ -4535,18 +4764,11 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, if(!(flag&(1<<31))) Xorriso_result(xorriso,0); close(fd1); + fd1= -1; (*result)|= 4096; - return(0); + {ret= 0; goto ex;} } - if(is_split) { - /* >>> SPLIT */ - /* >>> for each chunk file : do content comparison */; - } - - /* Content */ - /* >>> SPLIT */ - /* <<< outsource this as separate content comparison function */ done= 0; while(!done) { /* fd1 is a regular file and should deliver full buffers */ @@ -4635,11 +4857,21 @@ I thought to have seen a libisofs bug here but it seems that it was an illusion Xorriso_result(xorriso,0); (*result)|= (1<<15); } + +#endif /* ! Xorriso_with_compare_2_contentS */ + } + + ret= (((*result)&~((1<<17)|(1<<18)))==0); +ex:; +#ifndef Xorriso_with_compare_2_contentS if(fd1!=-1) close(fd1); Xorriso_iso_file_close(xorriso, &stream2, 0); - return((*result)==0); +#endif /* ! Xorriso_with_compare_2_contentS */ + if(split_parts!=NULL) + Splitparts_destroy(&split_parts, split_count, 0); + return(ret); } @@ -7293,8 +7525,14 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, int compare_result, char *disk_path, char *iso_rr_path, int flag) { - int ret, deleted= 0; + int ret, deleted= 0, is_split= 0, i; char sfe[5*SfileadrL]; + struct stat stbuf; + struct SplitparT *split_parts= NULL; + int split_count= 0; + char part_path[SfileadrL], *part_name; + int partno, total_parts; + off_t offset, bytes, total_bytes; if(compare_result&((1<<11)|(1<<13))) { /* cannot open regular disk file, early eof of disk file */ @@ -7302,14 +7540,23 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, Text_shellsafe(disk_path, sfe, 0)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); xorriso->find_compare_result= -1; - return(1); + ret= 1; goto ex; } xorriso->info_text[0]= 0; + is_split= !!(compare_result & (1<<17)); + + /* <<< */ + if(is_split) { + sprintf(xorriso->info_text, "Split file cannot be updated yet: %s\n", + Text_shellsafe(iso_rr_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 1); + {ret= 1; goto ex;} + } if(compare_result&(8|64)) { /* file type, minor+major with device file */ - /* <<< SPLIT : cannot happen here */ + /* <<< ??? SPLIT : cannot happen here ??? really ? */ ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); /* rm_r */ if(ret>0) { @@ -7323,6 +7570,7 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, /* disk_adr not existing */ /* ??? SPLIT : Shall i recognize a splitfile without disk file ? + Does it make any difference ? */ ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); @@ -7333,20 +7581,68 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, /* iso_adr not existing, size, cannot open iso file, early eof of iso file content bytes differ */ - /* >>> SPLIT : differing content or size */ - /* >>> overwrite all parts in the directory */ + if(is_split) { + /* >>> SPLIT : differing content or size */; + ret= Xorriso_identify_split(xorriso, iso_rr_path, + &split_parts, &split_count, &stbuf, 0); + if(ret<=0) + {ret= -1; goto ex;} /* (should not happen) */ + for(i= 0; i>> ??? if disk file grew over part limit : add part ? */; + + /* >>> copy file attributes to iso_rr_path */; + + } else + ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path, + (off_t) 0, (off_t) 0, 2|(flag&4)); sprintf(xorriso->info_text, "Added/overwrote "); } else if(compare_result&(4|16|32|256|512|1024)) { /* access permissions, user id, group id, mtime, atime, ctime */ - /* >>> SPLIT : differing attributes */ - /* >>> renew attributes of all parts in the directory */ + if(is_split) { + ret= Xorriso_identify_split(xorriso, iso_rr_path, + &split_parts, &split_count, &stbuf, 0); + if(ret<=0) + {ret= -1; goto ex;} /* (should not happen) */ + for(i= 0; i>> copy file attributes to iso_rr_path */; + + } else + ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 0); sprintf(xorriso->info_text, "Adjusted attributes of "); } else @@ -7355,6 +7651,10 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, strcat(xorriso->info_text, Text_shellsafe(iso_rr_path, sfe, 0)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); } + ret= 1; +ex:; + if(split_parts!=NULL) + Splitparts_destroy(&split_parts, split_count, 0); if(ret<=0) return(ret); if(deleted) diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 41c51bcf..3c3e6b9d 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -433,8 +433,13 @@ int Splitparts_new(struct SplitparT **o, int count, int flag); int Splitparts_destroy(struct SplitparT **o, int count, int flag); -int Splitpart_set(struct SplitparT *o, char *name, int partno, int total_parts, - off_t offset, off_t bytes, off_t total_bytes, int flag); +int Splitparts_set(struct SplitparT *o, int idx, + char *name, int partno, int total_parts, + off_t offset, off_t bytes, off_t total_bytes, int flag); + +int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno, + int *total_parts, off_t *offset, off_t *bytes, + off_t *total_bytes, int flag); int Splitpart__parse(char *name, int *partno, int *total_parts, off_t *offset, off_t *bytes, off_t *total_bytes, int flag); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index b29782ff..12a7dc72 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.03.22.130128" +#define Xorriso_timestamP "2008.03.25.170747" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 3361e319..77a45d28 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -1829,7 +1829,7 @@ int Xorriso_copy_implict_properties(struct XorrisO *xorriso, IsoDir *dir, "Copied properties for %s", Text_shellsafe(ni, sfe, 0)); sprintf(xorriso->info_text+strlen(xorriso->info_text), " from %s", Text_shellsafe(nfd, sfe, 0)); - if((flag&1) && d==0) + if(!((flag&1) && d==0)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); return(1); } @@ -4846,11 +4846,12 @@ int Xorriso_iso_file_close(struct XorrisO *xorriso, void **stream, int flag) int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, - struct SplitparT **parts, int *count, int flag) + struct SplitparT **parts, int *count, + struct stat *total_stbuf, int flag) { int ret, i; int partno, total_parts, first_total_parts= -1; - off_t offset, bytes, total_bytes, first_total_bytes= -1; + off_t offset, bytes, total_bytes, first_total_bytes= -1, size; IsoImage *volume; IsoDir *dir_node; IsoDirIter *iter= NULL; @@ -4878,7 +4879,7 @@ cannot_iter:; return(-1); } - for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { + for(i= 0; iso_dir_iter_next(iter, &node) == 1; i++) { name= (char *) iso_node_get_name(node); ret= Splitpart__parse(name, &partno, &total_parts, &offset, &bytes, &total_bytes, 0); @@ -4888,6 +4889,7 @@ cannot_iter:; first_total_parts= total_parts; first_total_bytes= total_bytes; Xorriso_fake_stbuf(xorriso, "", &first_stbuf, &node, 1); + size= first_stbuf.st_size; } else { if(first_total_parts!=total_parts || first_total_bytes!=total_bytes) {ret= 0; goto ex;} @@ -4899,7 +4901,12 @@ cannot_iter:; first_stbuf.st_ctime != stbuf.st_ctime || first_stbuf.st_atime != stbuf.st_atime) {ret= 0; goto ex;} + size= stbuf.st_size; } + /* check for plausible size */ + if(!((partno>> ??? sort list ? */ - /* >>> check for equal frequency */; - /* >>> check for disjointness */ - /* >>> check for plausible size */ + for(i= 0; i<*count; i++) { + /* >>> check for disjointness */; + } + memcpy(total_stbuf, &first_stbuf, sizeof(struct stat)); + total_stbuf->st_size= total_bytes; ret= 1; ex:; if(iter!=NULL) diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 96ba7ae8..2a58a314 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -198,7 +198,8 @@ int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path, struct SplitparT; int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, - struct SplitparT **parts, int *count, int flag); + struct SplitparT **parts, int *count, + struct stat *total_stbuf, int flag); #endif /* Xorrisoburn_includeD */