Adapted media evaluation to CD peculiarities

This commit is contained in:
2008-08-11 20:17:09 +00:00
parent ff8bfdaf4c
commit d7cea7d8f1
5 changed files with 633 additions and 39 deletions

View File

@ -123,13 +123,13 @@ or
/* The official xorriso options API. "No shortcuts" */
#include "xorriso.h"
/* The inner isofs- and burn-library interface */
#include "xorrisoburn.h"
/* The inner description of XorrisO */
#define Xorriso_is_xorriso_selF 1
#include "xorriso_private.h"
/* The inner isofs- and burn-library interface */
#include "xorrisoburn.h"
/* ------------------------------------------------------------------------ */
@ -2945,6 +2945,12 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
strcpy(name, "good");
else if(quality == Xorriso_read_quality_sloW)
strcpy(name, "slow");
else if(quality == Xorriso_read_quality_partiaL)
strcpy(name, "partial");
else if(quality == Xorriso_read_quality_valiD)
strcpy(name, "valid");
else if(quality == Xorriso_read_quality_invaliD)
strcpy(name, "invalid");
else if(quality == Xorriso_read_quality_off_tracK)
strcpy(name, "off track");
else if(quality == Xorriso_read_quality_untesteD)
@ -2959,6 +2965,266 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
/* ---------------------------- End SpotlisT ------------------------------ */
/* ---------------------------- SectorbitmaP ------------------------------ */
struct SectorbitmaP {
int sectors;
int sector_size;
unsigned char *map;
int map_size;
};
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag);
int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size,
int flag)
{
struct SectorbitmaP *m;
m= TSOB_FELD(struct SectorbitmaP,1);
if(m==NULL)
return(-1);
*o= m;
m->sectors= sectors;
m->sector_size= sector_size;
m->map= NULL;
m->map_size= sectors / 8 + 1;
m->map= calloc(m->map_size, 1);
if(m->map == NULL)
goto failure;
return(1);
failure:;
Sectorbitmap_destroy(o, 0);
return(-1);
}
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag)
{
if((*o) == NULL)
return(0);
if((*o)->map != NULL)
free((char *) (*o)->map);
free((char *) *o);
*o= NULL;
return(1);
}
int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg,
int *os_errno, int flag)
{
int ret, fd= -1, sectors, sector_size, i, todo, map_size;
unsigned char *map;
unsigned char buf[1024];
*os_errno= 0;
if(msg != NULL)
msg[0]= 0;
fd= open(path, O_RDONLY);
if(fd == -1) {
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Cannot open path ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
return(0);
}
ret= read(fd, buf, 32);
if(ret < 32) {
wrong_filetype:;
if(ret == -1)
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Not a sector bitmap file: ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
ret= 0; goto ex;
}
if(strncmp((char *) buf, "xorriso sector bitmap v1 ", 32) != 0)
{ret= 0; goto wrong_filetype;}
ret= read(fd, buf, 8);
if(ret < 4)
goto wrong_filetype;
sectors= (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
sector_size= (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
if(sectors <= 0 || sector_size <= 0)
goto wrong_filetype;
ret= Sectorbitmap_new(o, sectors, sector_size, 0);
if(ret <= 0) {
if(msg != NULL)
sprintf(msg, "Cannot allocate bitmap memory for %d sectors", sectors);
ret= -1; goto ex;
}
map= (*o)->map;
map_size= (*o)->map_size;
for(i= 0; i < map_size; i+= sizeof(buf)) {
todo= sizeof(buf);
if(i + todo > map_size)
todo= map_size - i;
ret= read(fd, buf, todo);
if(ret != todo)
goto wrong_filetype;
memcpy(map + i, buf, todo);
}
ret= 1;
ex:;
if(fd != -1)
close(fd);
if(ret <= 0)
Sectorbitmap_destroy(o, 0);
return(ret);
}
int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *msg,
int *os_errno, int flag)
{
int ret, fd= -1, j;
unsigned char buf[32];
*os_errno= 0;
fd= open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if(fd == -1) {
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Cannot open path ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
return(0);
}
ret= write(fd, "xorriso sector bitmap v1 ", 32);
if(ret != 32) {
cannot_write:;
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Cannot write to ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
ret= 0; goto ex;
}
for(j= 0; j < 4; j++) {
buf[j]= o->sectors >> (24 - j * 8);
buf[j+4]= o->sector_size >> (24 - j * 8);
}
ret= write(fd, buf, 8);
if(ret != 8)
goto cannot_write;
ret= write(fd, o->map, o->map_size);
if(ret != o->map_size)
goto cannot_write;
ret= 1;
ex:;
if(fd != -1)
close(fd);
return(ret);
}
/* @param flag bit0= sector bit value
*/
int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag)
{
if(sector < 0 || sector >= o->sectors)
return(0);
if(flag & 1)
o->map[sector / 8]|= 1 << (sector % 8);
else
o->map[sector / 8]&= ~(1 << (sector % 8));
return(1);
}
/* @param flag bit0= sector bit value
*/
int Sectorbitmap_set_range(struct SectorbitmaP *o,
int start_sector, int sectors, int flag)
{
int start_i, end_i, i;
unsigned char value;
if(start_sector < 0 || start_sector + sectors > o->sectors || sectors < 1)
return(0);
if(flag & 1)
value= ~0;
else
value= 0;
start_i= start_sector / 8;
end_i= (start_sector + sectors - 1) / 8;
for(i= start_sector; i / 8 == start_i && i < start_sector + sectors; i++)
Sectorbitmap_set(o, i, flag & 1);
for(i= start_i + 1; i < end_i; i++)
o->map[i]= value;
if(end_i > start_i)
for(i= end_i * 8; i < start_sector + sectors; i++)
Sectorbitmap_set(o, i, flag & 1);
return(1);
}
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag)
{
if(sector < 0 || sector >= o->sectors)
return(0);
return(!! (o->map[sector / 8] & (1 << (sector % 8))));
}
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag)
{
*sectors= o->sectors;
*sector_size= o->sector_size;
return(1);
}
int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
int flag)
{
int i, run_start, run_value, start_sec, limit_sec, start_aligned;
int end_complete;
if(from->sectors * from->sector_size > to->sectors * to->sector_size)
return(-1);
if(from->sector_size == to->sector_size) {
for(i= 0; i < from->map_size; i++)
to->map[i]= from->map[i];
return(1);
}
run_start= 0;
run_value= Sectorbitmap_is_set(from, 0, 0);
for(i= 1; i <= from->sectors; i++) {
if(i < from->sectors)
if(Sectorbitmap_is_set(from, i, 0) == run_value)
continue;
start_sec= run_start * from->sector_size / to->sector_size;
start_aligned=
(start_sec * to->sector_size == run_start * from->sector_size);
limit_sec= i * from->sector_size / to->sector_size;
end_complete= (limit_sec * to->sector_size == i * from->sector_size);
if(run_value) {
if(!start_aligned)
start_sec++;
} else {
if(!end_complete)
limit_sec++;
}
if(start_sec < limit_sec)
Sectorbitmap_set_range(to, start_sec, limit_sec - 1 - start_sec,
!!run_value);
run_value= !run_value;
run_start= i;
}
return(1);
}
/* -------------------------- End SectorbitmaP ---------------------------- */
/* ---------------------------- CheckmediajoB ----------------------------- */
int Checkmediajob_new(struct CheckmediajoB **o, int flag)
@ -2972,10 +3238,15 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag)
m->min_lba= -1;
m->max_lba= -1;
m->min_block_size= 16;
m->mode= 1;
m->mode= 0;
m->start_time= time(NULL);
m->time_limit= -1;
m->item_limit= -1;
m->data_to_path[0]= 0;
m->data_to_fd= -1;
m->sector_map_path[0]= 0;
m->sector_map= NULL;
m->retry= 0;
return(1);
}
@ -2984,6 +3255,7 @@ int Checkmediajob_destroy(struct CheckmediajoB **o, int flag)
{
if((*o) == NULL)
return(0);
Sectorbitmap_destroy(&((*o)->sector_map), 0);
free((char *) *o);
*o= NULL;
return(1);
@ -8376,7 +8648,70 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
return(1);
}
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SpotlisT *spotlist,
int sector_size,
struct SectorbitmaP **map,
int flag)
{
struct SectorbitmaP *m;
int map_sectors= -1, map_sector_size= -1;
int list_sectors, list_blocks, sector_blocks;
int replace_map= 0, count, i, lba, blocks, quality, ret;
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;
}
/* >>> ??? insist in list_blocks % sector_blocks == 0 */
list_sectors= list_blocks / sector_blocks;
if(list_sectors * sector_blocks < list_blocks)
list_sectors++;
if(*map != NULL && map_sectors * (map_sector_size / 2048) >= list_blocks &&
map_sector_size == sector_size)
m= *map;
else {
ret= Sectorbitmap_new(&m, list_sectors, sector_size, 0);
if(ret <= 0)
return(-1);
replace_map= 1;
if(*map != NULL) {
ret= Sectorbitmap_copy(*map, m, 0);
if(ret <= 0) {
Sectorbitmap_destroy(&m, 0);
return(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;
Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks,
quality >= Xorriso_read_quality_valiD);
}
if(replace_map) {
Sectorbitmap_destroy(map, 0);
*map= m;
}
return(1);
}
/* ---------------------------- Options API ------------------------ */
@ -8896,7 +9231,11 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
goto ex;
for(i= old_idx; i < end_idx; i++) {
if(strncmp(argv[i], "max_lba=", 8) == 0 ||
if(strncmp(argv[i], "data_to=", 8) == 0) {
ret= Sfile_str(job->data_to_path, argv[i] + 8, 0);
if(ret <= 0)
goto ex;
} else if(strncmp(argv[i], "max_lba=", 8) == 0 ||
strncmp(argv[i], "min_lba=", 8) == 0) {
num= -1;
sscanf(argv[i] + 8, "%lf", &num);
@ -8906,6 +9245,19 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
job->max_lba= num;
else
job->min_lba= num;
} else if(strncmp(argv[i], "retry=", 6) == 0) {
if(strcmp(argv[i] + 6, "on") == 0)
job->retry= 1;
else if(strcmp(argv[i] + 6, "off") == 0)
job->retry= -1;
else if(strcmp(argv[i] + 6, "default") == 0)
job->retry= 0;
else
goto unknown_value;
} else if(strncmp(argv[i], "sector_map=", 11) == 0) {
ret= Sfile_str(job->sector_map_path, argv[i] + 11, 0);
if(ret <= 0)
goto ex;
} else if(strncmp(argv[i], "time_limit=", 11) == 0 ||
strncmp(argv[i], "item_limit=", 11) == 0 ) {
num= -1;
@ -8916,8 +9268,20 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
job->time_limit= num;
else
job->item_limit= num;
} else if(strncmp(argv[i], "what=", 5) == 0) {
if(strcmp(argv[i]+5, "tracks") == 0)
job->mode= 0;
else if(strcmp(argv[i]+5, "disc")== 0)
job->mode= 1;
else {
unknown_value:;
sprintf(xorriso->info_text,
"-check_media: Unknown value with option %s", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
sprintf(xorriso->info_text, "-check_media: Unknown option %s", argv[i]);
sprintf(xorriso->info_text, "-check_media: Unknown option '%s'", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
@ -10449,7 +10813,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -check_media [options] --",
" Try to read data blocks from media and report about the",
" outcome. Several options modify the behavior:",
" min_lba= , max_lba= , time_limit= , item_limit=",
" min_lba= , max_lba= , time_limit= , item_limit= ,",
" data_to= ,",
"",
"Compatibility emulation (argument list may be ended by --):",
" -as mkisofs [-help|-version|-o|-R|-J|-V|-P|-f|-m|-exclude-list|-no-pad|",