Adapted media evaluation to CD peculiarities
This commit is contained in:
@ -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|",
|
||||
|
Reference in New Issue
Block a user