From 294a55d552bc39929f1925d7e9bfcb96a93c3736 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 17 Aug 2008 22:05:48 +0000 Subject: [PATCH] -find tests -damaged and -lba_range, new -find action report_damage --- libisoburn/trunk/xorriso/xorriso.1 | 55 +++- libisoburn/trunk/xorriso/xorriso.c | 194 +++++++++--- libisoburn/trunk/xorriso/xorriso_private.h | 17 +- libisoburn/trunk/xorriso/xorriso_timestamp.h | 2 +- libisoburn/trunk/xorriso/xorrisoburn.c | 306 +++++++++++++++++-- libisoburn/trunk/xorriso/xorrisoburn.h | 4 + 6 files changed, 511 insertions(+), 67 deletions(-) diff --git a/libisoburn/trunk/xorriso/xorriso.1 b/libisoburn/trunk/xorriso/xorriso.1 index 01862877..0f569238 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 "Aug 15, 2008" +.TH XORRISO 1 "Aug 17, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -832,21 +832,44 @@ where "A0" is year 2000, "B0" is 2010, etc. \fB\-alter_date_r\fR type timestring iso_rr_path [***] Like -alter_date but affecting all files below eventual directories. .TP -\fB\-find\fR iso_rr_path [-name pattern] [-type t] [-exec action [params]] -- +\fB\-find\fR iso_rr_path [test [test ...]] [-exec action [params]] -- A very restricted substitute for shell command find in the ISO image. It performs an action on matching file objects at or below iso_rr_path. .br -Optional -name pattern is not expanded but used for comparison with -the particular file names of the eventual directory tree underneath -iso_rr_path. If no -name pattern is given, then any file name matches. +Tests are optional. If they are omitted then action is applied to all file +objects. If tests are given then action is applied only if all of them +match the file object. Available tests are: .br -The optional -type test restricts matching to files of the given type: +-name pattern +.br +Pattern is not expanded but used for comparison with +the particular file names of the eventual directory tree underneath +iso_rr_path. +.br +-type type_letter +.br +matches only files files of the given type: "block", "char", "dir", "pipe", "file", "link", "socket", "Xotic" which eventually matches what is not matched by the other types. .br Only the first letter is interpreted. E.g.: -find / -type d .br -If a file matches then the action is performed. Default action is "echo", +-damaged +.br +matches only files which use data blocks marked as damaged by a previous +run of -check_media. The damage info vanishes when a new ISO image gets +loaded. +.br +-undamaged +.br +matches only files which use data blocks outside the areas marked as damaged. +.br +-lba_range start_lba block_count +.br +matches only files which use data blocks within the range of start_lba +and start_lba+block_count-1. +.br +Default action is "echo", i.e. to print the address of the found file. Other actions are certain xorriso commands which get performed on the found files. These commands may have specific parameters. See also their particular descriptions. @@ -904,6 +927,15 @@ E.g.: .br -find /uh/oh -name *private* -exec rm_r -- .br +"report_damage" classifies files whether they hit a data block that is +marked as damaged. The result is printed together with the eventual address +of the first damaged byte, the maximum span of damages, file size, and the +path of the file. +.br +E.g.: +.br + -find / -damaged -exec report_damage +.br "find" performs another run of -find on the matching file address. It accepts the same params as -find, except iso_rr_path. E.g.: @@ -1671,7 +1703,7 @@ time_limit=28800 item_limit=100000 .br abort_file=/var/opt/xorriso/do_abort_check_media .br -data_to= sector_map= map_with_volid=off +data_to='' sector_map='' map_with_volid=off report=blocks .br Non-default settings: .br @@ -1684,7 +1716,7 @@ avoids loading the ISO image tree from media. .br "max_lba=" switches to what=disc and omits all blocks above its option value. .br -"retry=on" forces read retries with single blocks when the normal block +"retry=on" forces read retries with single blocks when the normal read chunk produces a read error. By default, retries are only enabled with CD media. "retry=off" forbits retries for all media types. .br @@ -1722,6 +1754,11 @@ sector_map= and processes this virtual outcome. The result list tells intervals of 2 KiB blocks with start address, number of blocks and quality. Qualities which begin with "+" are supposed to be valid readable data. Qualities with "-" are no valid data. +.br +"report=files" lists the files which use damaged blocks (not with use=outdev). +The format is like with find -exec report_damage. +.br +"report=blocks_files" first lists damaged blocks and then affected files. .TP .B osirrox restore options: .PP diff --git a/libisoburn/trunk/xorriso/xorriso.c b/libisoburn/trunk/xorriso/xorriso.c index 85feb876..72fffd26 100644 --- a/libisoburn/trunk/xorriso/xorriso.c +++ b/libisoburn/trunk/xorriso/xorriso.c @@ -1874,6 +1874,9 @@ struct FindjoB { */ char file_type; + int start_lba; + int end_lba; + int damage_filter; /* -1=only undamaged , 0=all , 1=only damaged */ /* 0= echo 1= rm (also rmdir) @@ -1896,6 +1899,8 @@ struct FindjoB { 18= add_missing iso_rr_equiv 19= empty_iso_dir iso_rr_equiv 20= is_full_in_iso iso_rr_equiv + 21= report_damage +>>>22= report_lba */ int action; char *target; @@ -1905,7 +1910,6 @@ struct FindjoB { int type; /* see Xorriso_set_time flag */ time_t date; struct FindjoB *subjob; - }; int Findjob_destroy(struct FindjoB **job, int flag); @@ -1921,6 +1925,9 @@ int Findjob_new(struct FindjoB **o, char *start_path, int flag) m->start_path= NULL; m->name_expr= NULL; m->file_type= 0; + m->start_lba= -1; + m->end_lba= -1; + m->damage_filter= 0; m->action= 0; /* print */ m->target= NULL; /* a mere pointer, not managed memory */ m->user= 0; @@ -2012,6 +2019,39 @@ int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) } +int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, + int flag) +{ + o->start_lba= start_lba; + o->end_lba= start_lba + count - 1; + return(1); +} + + +/* @param value -1= only undamaged files, 0= all files, 1= only damaged files +*/ +int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag) +{ + if(value < 0) + o->damage_filter= -1; + else if(value > 0) + o->damage_filter= 1; + else + o->damage_filter= 0; + return(1); +} + + +int Findjob_get_lba_damage_filter(struct FindjoB *o, int *start_lba, + int *end_lba, int *damage_filter, int flag) +{ + *start_lba= o->start_lba; + *end_lba= o->end_lba; + *damage_filter= o->damage_filter; + return(1); +} + + /* @return 0=no match , 1=match , <0 = error */ int Findjob_test(struct FindjoB *o, char *name, @@ -2763,6 +2803,35 @@ int Spotlist_count(struct SpotlisT *o, int flag) } +int Spotlist_block_count(struct SpotlisT *o, int flag) +{ + int list_blocks= 0; + struct SpotlistiteM *li; + + for(li= o->list_start; li != NULL; li= li->next) { + if(li->start_lba + li->blocks > list_blocks) + list_blocks= li->start_lba + li->blocks; + } + return(list_blocks); +} + + +int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag) +{ + int sector_size; + struct SpotlistiteM *li; + + sector_size= read_chunk * 2048; + for(li= o->list_start; li != NULL; li= li->next) { + if((li->start_lba % read_chunk) || (li->blocks % read_chunk)) { + sector_size= 2048; + break; + } + } + return(sector_size); +} + + int Spotlist_get_item(struct SpotlisT *o, int idx, int *start_lba, int *blocks, int *quality, int flag) { @@ -3133,6 +3202,7 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag) m->sector_map= NULL; m->map_with_volid= 0; m->retry= 0; + m->report_mode= 0; return(1); } @@ -3221,6 +3291,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->in_volset_handle= NULL; m->volset_change_pending= 0; m->no_volset_present= 0; + m->in_sector_map= NULL; m->outdev[0]= 0; m->out_drive_handle= NULL; m->dev_fd_1= -1; @@ -8753,31 +8824,27 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag) } +/* @param flag bit0= mark untested areas as valid +*/ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso, struct SpotlisT *spotlist, - int sector_size, + int read_chunk, struct SectorbitmaP **map, int flag) { struct SectorbitmaP *m; int map_sectors= -1, map_sector_size= -1; - int list_sectors, list_blocks, sector_blocks; + int list_sectors, list_blocks, sector_size, sector_blocks; int replace_map= 0, count, i, lba, blocks, quality, ret; + sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); sector_blocks= sector_size / 2048; if(*map != NULL) Sectorbitmap_get_layout(*map, &map_sectors, &map_sector_size, 0); count= Spotlist_count(spotlist, 0); - list_blocks= 0; - for(i= 0; i < count; i++) { - ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); - if(ret <= 0) - continue; - if(lba + blocks > list_blocks) - list_blocks= lba + blocks; - } - + list_blocks= Spotlist_block_count(spotlist, 0); + /* >>> ??? insist in list_blocks % sector_blocks == 0 */ list_sectors= list_blocks / sector_blocks; @@ -8805,10 +8872,10 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso, ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); if(ret <= 0) continue; - if(quality == Xorriso_read_quality_untesteD) + if(quality == Xorriso_read_quality_untesteD && !(flag & 1)) continue; Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks, - quality >= Xorriso_read_quality_valiD); + quality >= Xorriso_read_quality_untesteD); } if(replace_map) { Sectorbitmap_destroy(map, 0); @@ -9471,6 +9538,8 @@ int Xorriso_option_check_media(struct XorrisO *xorriso, double num; struct SpotlisT *spotlist= NULL; struct CheckmediajoB *job= NULL; + struct FindjoB *findjob= NULL; + struct stat dir_stbuf; old_idx= *idx; end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); @@ -9506,6 +9575,15 @@ int Xorriso_option_check_media(struct XorrisO *xorriso, job->max_lba= num; else job->min_lba= num; + } else if(strncmp(argv[i], "report=", 7) == 0) { + if(strcmp(argv[i] + 7, "blocks") == 0) + job->report_mode= 0; + else if(strcmp(argv[i] + 7, "files") == 0) + job->report_mode= 1; + else if(strcmp(argv[i] + 7, "blocks_files") == 0) + job->report_mode= 2; + else + goto unknown_value; } else if(strncmp(argv[i], "retry=", 6) == 0) { if(strcmp(argv[i] + 6, "on") == 0) job->retry= 1; @@ -9557,6 +9635,12 @@ unknown_value:; } } + if((job->report_mode == 1 || job->report_mode == 2) && job->use_dev == 1) { + + /* >>> this combination makes no sense */; + + } + if(job->use_dev == 2) { if(job->sector_map_path[0] == 0) { sprintf(xorriso->info_text, @@ -9575,25 +9659,43 @@ unknown_value:; ret= Xorriso_sectormap_to_spotlist(xorriso, job, &spotlist, 0); if(ret <= 0) goto ex; + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); + xorriso->in_sector_map= job->sector_map; + job->sector_map= NULL; } else { ret= Xorriso_check_media(xorriso, &spotlist, job, 0); if(ret <= 0) goto ex; } - sprintf(xorriso->result_line, - "MCL layout : lba , size , quality\n"); - Xorriso_result(xorriso,0); - count= Spotlist_count(spotlist, 0); - for(i= 0; i < count; i++) { - ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); - if(ret <= 0) - continue; - sprintf(xorriso->result_line, "MCL item : %10d , %10d , %s\n", - lba, blocks, Spotlist__quality_name(quality, quality_name, 0)); + if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */ + sprintf(xorriso->result_line, + "MCL layout : lba , size , quality\n"); Xorriso_result(xorriso,0); + count= Spotlist_count(spotlist, 0); + for(i= 0; i < count; i++) { + ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); + if(ret <= 0) + continue; + sprintf(xorriso->result_line, "MCL item : %10d , %10d , %s\n", + lba, blocks, Spotlist__quality_name(quality, quality_name, 0)); + Xorriso_result(xorriso,0); + } + } + if(job->report_mode == 1 || job->report_mode == 2) { /* report files */ + ret= Findjob_new(&findjob, "/", 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-check_media report=files", 0); + {ret= -1; goto ex;} + } + Findjob_set_damage_filter(findjob, 1, 0); + Findjob_set_action_target(findjob, 21, NULL, 0); + ret= Xorriso_findi(xorriso, findjob, NULL, (off_t) 0, + NULL, "/", &dir_stbuf, 0, 0); + Findjob_destroy(&findjob, 0); + if(ret <= 0) + goto ex; } - ret= 1; ex:; Spotlist_destroy(&spotlist, 0); @@ -10558,7 +10660,7 @@ sorry_ex: int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { - int ret, i, end_idx, type= 0, action, deleter= 0; + int ret, i, end_idx, type= 0, action, deleter= 0, start_lba, count; struct FindjoB *job, *first_job= NULL, *new_job; char *start_path, sfe[5*SfileadrL], *cpt, other_path_start[SfileadrL]; struct stat dir_stbuf; @@ -10596,6 +10698,26 @@ not_enough_arguments:; Text_shellsafe(argv[i], sfe, 0)); goto sorry_ex; } + } else if(strcmp(argv[i], "-type")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Findjob_set_file_type(job, argv[i][0], 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-find[ix]: unknown -type '%c'",argv[i][0]); + goto sorry_ex; + } + } else if(strcmp(argv[i], "-damaged")==0) { + Findjob_set_damage_filter(job, 1, 0); + } else if(strcmp(argv[i], "-undamaged")==0) { + Findjob_set_damage_filter(job, -1, 0); + } else if(strcmp(argv[i], "-lba_range")==0) { + if(i+2>=end_idx) + goto not_enough_arguments; + i+= 2; + sscanf(argv[i-1], "%d", &start_lba); + sscanf(argv[i], "%d", &count); + Findjob_set_lba_range(job, start_lba, count, 0); } else if(strcmp(argv[i], "-exec")==0) { if(i+1>=end_idx) goto not_enough_arguments; @@ -10732,20 +10854,15 @@ not_enough_arguments:; goto ex; Findjob_set_start_path(job, sfe, 0); + } else if(strcmp(cpt, "report_damage")==0) { + Findjob_set_action_target(job, 21, NULL, 0); + } else if(strcmp(cpt, "report_lba")==0) { + Findjob_set_action_target(job, 22, NULL, 0); } else { sprintf(xorriso->info_text, "-find -exec: unknown action %s", Text_shellsafe(argv[i], sfe, 0)); goto sorry_ex; } - } else if(strcmp(argv[i], "-type")==0) { - if(i+1>=end_idx) - goto not_enough_arguments; - i++; - ret= Findjob_set_file_type(job, argv[i][0], 0); - if(ret<=0) { - sprintf(xorriso->info_text, "-find[ix]: unknown -type '%c'",argv[i][0]); - goto sorry_ex; - } } else { sprintf(xorriso->info_text, "-find[ix]: unknown option %s", Text_shellsafe(argv[i], sfe, 0)); @@ -10955,17 +11072,18 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " access time, modification time, both times.", " -alter_date_r type timestring iso_rr_path [***]", " Like -alter_date but affecting all files below directories.", -" -find iso_rr_path [-name pattern] [-type t] [-exec action [params]]", +" -find iso_rr_path [test [test ...]] [-exec action [params]]", " performs an action on files below the current working", " directory in the ISO image. If -name pattern is given", " then only files with matching leaf names are processed.", " If -type is given then only files with matching type are", " processed. Types: block,char,dir,pipe,file,link,socket.", +" Further tests: -damaged, -undamaged, -lba_range start count", " action may be one of: echo, chown, chown_r, chgrp, chgrp_r", " chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", -" rm, rm_r, compare, update, find.", +" rm, rm_r, compare, update, report_damage, find.", " params are their arguments except iso_rr_path.", -" I.e. echo, lsdl, rm, rm_r have no params at all.", +" echo, lsdl, rm, rm_r, report_damage have no params at all.", " -mkdir iso_rr_path [...]", " Create empty directories if they do not exist yet.", " -rmdir iso_rr_path [***]", diff --git a/libisoburn/trunk/xorriso/xorriso_private.h b/libisoburn/trunk/xorriso/xorriso_private.h index 38fa4670..dcb8e82f 100644 --- a/libisoburn/trunk/xorriso/xorriso_private.h +++ b/libisoburn/trunk/xorriso/xorriso_private.h @@ -151,6 +151,9 @@ struct XorrisO { /* the global context of xorriso */ int volset_change_pending; /* whether -commit would make sense */ int no_volset_present; /* set to 1 on first failure */ + struct SectorbitmaP *in_sector_map; /* eventual sector validity bitmap */ + + char outdev[SfileadrL]; void *out_drive_handle; /* interpreted only by xorrisoburn.c */ int dev_fd_1; /* The fd which substitutes for /dev/fd/1 and is @@ -464,9 +467,12 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag); int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag); + +/* @param flag bit0= mark untested areas as valid +*/ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso, struct SpotlisT *spotlist, - int sector_size, + int read_chunk, struct SectorbitmaP **map, int flag); @@ -630,6 +636,9 @@ int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag); int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag); +int Findjob_get_lba_damage_filter(struct FindjoB *o, int *start_lba, + int *end_lba, int *damage_filter, int flag); + struct SplitparT; @@ -670,6 +679,10 @@ int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks, int Spotlist_count(struct SpotlisT *o, int flag); +int Spotlist_block_count(struct SpotlisT *o, int flag); + +int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag); + int Spotlist_get_item(struct SpotlisT *o, int idx, int *start_lba, int *blocks, int *quality, int flag); @@ -707,6 +720,8 @@ int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag); int Sectorbitmap_get_layout(struct SectorbitmaP *o, int *sectors, int *sector_size, int flag); +int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to, + int flag); #endif /* Xorriso_private_includeD */ diff --git a/libisoburn/trunk/xorriso/xorriso_timestamp.h b/libisoburn/trunk/xorriso/xorriso_timestamp.h index c47a2599..bede3d89 100644 --- a/libisoburn/trunk/xorriso/xorriso_timestamp.h +++ b/libisoburn/trunk/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.08.15.155421" +#define Xorriso_timestamP "2008.08.17.220043" diff --git a/libisoburn/trunk/xorriso/xorrisoburn.c b/libisoburn/trunk/xorriso/xorrisoburn.c index f36eaaa1..cd84ec45 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.c +++ b/libisoburn/trunk/xorriso/xorrisoburn.c @@ -219,6 +219,7 @@ int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag) if(xorriso->in_volset_handle!=NULL) { /* standalone image */ iso_image_unref((IsoImage *) xorriso->in_volset_handle); xorriso->in_volset_handle= NULL; + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); } if(flag&1) { if(xorriso->libs_are_started==0) @@ -375,6 +376,7 @@ int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag) if(xorriso->in_volset_handle!=NULL) { iso_image_unref((IsoImage *) xorriso->in_volset_handle); xorriso->in_volset_handle= NULL; + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); xorriso->loaded_volid[0]= 0; xorriso->volset_change_pending= 0; xorriso->no_volset_present= 0; @@ -397,6 +399,7 @@ int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag) return(-1); } xorriso->in_volset_handle= (void *) volset; + xorriso->in_sector_map= NULL; Xorriso_update_volid(xorriso, 0); xorriso->volset_change_pending= 0; xorriso->no_volset_present= 0; @@ -544,6 +547,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) if(xorriso->in_volset_handle!=NULL) iso_image_unref((IsoImage *) xorriso->in_volset_handle); xorriso->in_volset_handle= NULL; + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); /* check for invalid state */ if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE && @@ -595,6 +599,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0, "", 1); /* report end count */ xorriso->in_volset_handle= (void *) volset; + xorriso->in_sector_map= NULL; Xorriso_set_image_severities(xorriso, 0); Xorriso_update_volid(xorriso, 0); @@ -686,6 +691,7 @@ int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag) if(xorriso->in_volset_handle!=NULL) iso_image_unref((IsoImage *) xorriso->in_volset_handle); xorriso->in_volset_handle= NULL; + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); xorriso->loaded_volid[0]= 0; xorriso->volset_change_pending= 0; xorriso->no_volset_present= 0; @@ -3538,8 +3544,12 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag) return(1); disc= isoburn_toc_drive_get_disc(drive); - sprintf(respt, "TOC layout : %3s , %9s , %10s , %s\n", - "Idx", "sbsector", "Size", "Volume Id"); + if(flag & 4) + sprintf(respt, "TOC layout : %3s , %9s , %10s\n", + "Idx", "sbsector", "Size"); + else + sprintf(respt, "TOC layout : %3s , %9s , %10s , %s\n", + "Idx", "sbsector", "Size", "Volume Id"); if(!(flag&1)) Xorriso_result(xorriso,0); @@ -5524,6 +5534,168 @@ int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, } +int Xorriso_start_end_lba(struct XorrisO *xorriso, IsoNode *node, + int *start_lba, int *end_lba, off_t *size, int flag) +{ + uint32_t iso_start_lba; + int ret; + + *size= 0; + *start_lba= *end_lba= -1; + ret= iso_node_get_old_image_lba(node, &iso_start_lba, 0); + if(ret < 0) + return(-1); + if(ret != 1) + return(0); + *start_lba= iso_start_lba; + if(LIBISO_ISREG(node)) + *size= iso_file_get_size((IsoFile *) node); + *end_lba= *start_lba + *size / 2048; + if((*size % 2048) == 0 && *end_lba > *start_lba) + (*end_lba)--; + return(1); +} + + +/* @param damage_start Returns first damaged byte address + @param damage_end Returns first byte address after last damaged byte + @return <0 error, 0=undamaged , 1=damaged +*/ +int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node, + off_t *damage_start, off_t *damage_end, + int flag) +{ + int start_lba, end_lba, i, sectors, sector_size, damaged= 0, ret; + int next_good_lba, first_bad_lba= -1; + off_t size= 0; + struct SectorbitmaP *map; + + *damage_start= *damage_end= -1; + map= xorriso->in_sector_map; + if(map == NULL) + return(0); + + ret= Xorriso_start_end_lba(xorriso, node, &start_lba, &end_lba, &size, 0); + if(ret <= 0) + return(ret); + Sectorbitmap_get_layout(map, §ors, §or_size, 0); + sector_size/= 2048; + for(i= start_lba; i <= end_lba; i+= sector_size) + if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) { + damaged= 1; + if(first_bad_lba < 0) + first_bad_lba= i; + next_good_lba= (i / sector_size + 1) * sector_size; + } + + if(damaged) { + *damage_start= (first_bad_lba - start_lba) * 2048; + *damage_end= (next_good_lba - start_lba) * 2048; + if(*damage_end > size) + *damage_end= size; + return(1); + } + return(0); +} + + +int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path, + IsoNode *node, int flag) +{ + int ret; + off_t size= 0, damage_start, damage_end; + char sfe[5*SfileadrL]; + + ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0); + if(ret < 0) + return(0); + + if(LIBISO_ISREG(node)) + size= iso_file_get_size((IsoFile *) node); + if(ret > 0) { + sprintf(xorriso->result_line, "File damaged : %8.f , %8.f , %8.f , %s\n", + (double) damage_start, (double) (damage_end - damage_start) , + (double) size, Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } else { + sprintf(xorriso->result_line, "File seems ok: %8.f , %8.f , %8.f , %s\n", + -1.0, -1.0, (double) size, Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + return(1); +} + + +/* <<< shall be replaced by tests and -exec report_damage +#define Xorriso_check_find_as_exeC 1 +*/ + +#ifdef Xorriso_check_find_as_exeC + +/* @param flag bit0= report about undamaged files +*/ +int Xorriso_file_vs_bitmap(struct XorrisO *xorriso, char *show_path, + IsoNode *node, int flag) +{ + uint32_t start_lba; + int end_lba, i, sectors, sector_size, damaged= 0, ret; + int next_good_lba, first_bad_lba= -1; + off_t size= 0, damage_start, damage_count; + struct SectorbitmaP *map; + char sfe[5*SfileadrL]; + + ret= iso_node_get_old_image_lba(node, &start_lba, 0); + if(ret < 0) + return(0); + if(ret == 0) { + if(flag & 1) + goto undamaged; + return(2); + } + map= xorriso->in_sector_map; + if(map == NULL) { + if(flag & 1) + goto undamaged; + return(2); + } + if(LIBISO_ISREG(node)) + size= iso_file_get_size((IsoFile *) node); + end_lba= start_lba + size / 2048; + if(size % 2048) + end_lba++; + + Sectorbitmap_get_layout(map, §ors, §or_size, 0); + sector_size/= 2048; + for(i= start_lba; i < end_lba; i+= sector_size) + if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) { + damaged= 1; + if(first_bad_lba < 0) + first_bad_lba= i; + next_good_lba= (i / sector_size + 1) * sector_size; + } + + if(damaged && !(flag & 1)) { + damage_start= (first_bad_lba - start_lba) * 2048; + damage_count= (next_good_lba - start_lba) * 2048; + if(damage_count > size) + damage_count= size; + damage_count-= damage_start; + sprintf(xorriso->result_line, "File damage : %13.f , %13.f , %13.f , %s\n", + (double) damage_start, (double) damage_count, (double) size, + Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } else if((flag & 1) && !damaged) { +undamaged:; + sprintf(xorriso->result_line, "File seems ok: %s\n", + Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + return(1); +} + +#endif /* Xorriso_check_find_as_exeC */ + + /* @param flag bit0= not a command parameter (directory iteration or recursion) bit1= do not count deleted files with rm and rm_r @return <=0 error, @@ -5592,6 +5764,24 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, ret= 1; } else if(action==16 || action==18) { /* not_in_iso , add_missing */ ; + +#ifdef Xorriso_check_find_as_exeC + + } else if(action == 21) { /* is_damaged */ + ret= Xorriso_file_vs_bitmap(xorriso, show_path, node, 0); + } else if(action == 22) { /* is_undamaged */ + ret= Xorriso_file_vs_bitmap(xorriso, show_path, node, 1); + +#else + + } else if(action == 21) { /* report_damage */ + ret= Xorriso_report_damage(xorriso, show_path, node, 0); + } else if(action == 22) { + /* >>> report_lba */; + +#endif /* ! Xorriso_check_find_as_exeC */ + + } else { /* includes : 15 in_iso */ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -5607,6 +5797,39 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } +int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, + IsoNode *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, + int depth, int flag) +{ + int ret, start_lba, end_lba, damage_filter, file_end_lba, file_start_lba; + off_t damage_start, damage_end, size; + + ret= Findjob_test(job, name, boss_stbuf, stbuf, depth, 0); + if(ret<=0) + return(ret); + + Findjob_get_lba_damage_filter(job, &start_lba, &end_lba, &damage_filter, 0); + if(damage_filter != 0) { + ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0); + if(ret < 0) + return(ret); + if((damage_filter > 0) != (ret > 0)) + return(0); + } + + if(start_lba >= 0 && end_lba >= 0) { + ret= Xorriso_start_end_lba(xorriso, node, &file_start_lba, &file_end_lba, + &size, 0); + if(ret <= 0) + return(ret); + if(file_end_lba < start_lba || file_start_lba > end_lba) + return(0); + } + return(1); +} + + /* @param flag bit0= recursion bit1= do not count deleted files with rm and rm_r @return <=0 error, 1= ok , 2= dir node and path has been deleted @@ -5642,6 +5865,11 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, action= Findjob_get_action(job, 0); if(action<0) action= 0; + if(action == 21 && !(flag & 1)) { + sprintf(xorriso->result_line, "Report layout: %8s , %8s , %8s , %s\n", + "at byte", "range", "filesize", "ISO image path"); + Xorriso_result(xorriso, 0); + } dir_node= (IsoDir *) dir_node_generic; if(dir_node==NULL) { @@ -5664,7 +5892,18 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, name= dir_path; else name++; + +#ifdef Xorriso_check_find_as_exeC + ret= Findjob_test(job, name, NULL, dir_stbuf, depth, 0); + +#else + + ret= Xorriso_findi_test(xorriso, job, iso_node, name, NULL, dir_stbuf, + depth, 0); + +#endif /* ! Xorriso_check_find_as_exeC */ + if(ret<0) goto ex; if(ret>0) { @@ -5731,7 +5970,18 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, --- Seems that the current configuration represents the special handling of the find start path with mount points. Dangerous to change. */ + +#ifdef Xorriso_check_find_as_exeC + ret= Findjob_test(job, name, dir_stbuf, &stbuf, depth, 0); + +#else + + ret= Xorriso_findi_test(xorriso, job, node, name, dir_stbuf, &stbuf, + depth, 0); + +#endif /* ! Xorriso_check_find_as_exeC */ + if(ret<0) goto ex; if(ret>0) { @@ -6792,13 +7042,41 @@ ex: } +int Xorriso_update_in_sector_map(struct XorrisO *xorriso, + struct SpotlisT *spotlist, int read_chunk, + struct CheckmediajoB *job, int flag) +{ + int sectors, sector_size, sector_blocks, ret; + struct SectorbitmaP *map; + + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); + if(job->use_dev == 1) + return(1); + map= job->sector_map; + sectors= Spotlist_block_count(spotlist, 0); + if(sectors <= 0) + return(0); + sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); + sector_blocks= sector_size / 2048; + if(sector_blocks > 1) + sectors= sectors / sector_blocks + !!(sectors % sector_blocks); + ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0); + if(ret <= 0) + return(ret); + if(map != NULL) + Sectorbitmap_copy(map, xorriso->in_sector_map, 0); + ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk, + &(xorriso->in_sector_map), 1); + return(ret); +} + + int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, struct CheckmediajoB *job, int flag) { int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0; int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba; - int num_sessions, num_tracks, declare_untested= 0, sector_size, count; - int lba, quality; + int num_sessions, num_tracks, declare_untested= 0; char sfe[5*SfileadrL], *toc_info= NULL; struct burn_drive *drive; struct burn_drive_info *dinfo; @@ -6815,10 +7093,9 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, !!job->use_dev); if(ret<=0) goto ex; - /* >>> determine media type dependent blocking factor: - 32 kB for CD (with 2kB retry) iand DVD, 64 kB for BD + 32 kB for CD (with 2kB retry) and DVD, 64 kB for BD eventually adjust read_chunk */; @@ -6948,19 +7225,12 @@ no_content_visible:; ex:; if(job->data_to_fd != -1) close(job->data_to_fd); + + if(ret > 0) + ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0); + if(ret > 0 && job->sector_map_path[0]) { - sector_size= read_chunk * 2048; - count= Spotlist_count(*spotlist, 0); - for(i= 0; i < count; i++) { - ret= Spotlist_get_item(*spotlist, i, &lba, &blocks, &quality, 0); - if(ret <= 0) - continue; - if(lba % read_chunk) { - sector_size= 2048; - break; - } - } - ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, sector_size, + ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, read_chunk, &(job->sector_map), 0); if(ret > 0) { ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path, toc_info, diff --git a/libisoburn/trunk/xorriso/xorrisoburn.h b/libisoburn/trunk/xorriso/xorrisoburn.h index dc56ea41..fbdc8d6e 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.h +++ b/libisoburn/trunk/xorriso/xorrisoburn.h @@ -311,6 +311,10 @@ struct CheckmediajoB { 0= retry with CD, full chunk else */ + int report_mode; /* 0= print MCL items + 1= print damaged files + */ + }; int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,