New API call burn_allow_drive_role_4()

This commit is contained in:
Thomas Schmitt 2011-03-13 13:07:46 +00:00
parent 1b166f484d
commit 402f4c0b04
8 changed files with 154 additions and 35 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.03.12.093520"
#define Cdrskin_timestamP "2011.03.13.130746"

View File

@ -659,6 +659,14 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
"Drive is a virtual placeholder (null-drive)", 0, 0);
return;
}
if (d->drive_role == 4) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020181,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Pseudo-drive is a read-only file. Cannot write.",
0, 0);
return;
}
/* ts A61007 : obsolete Assert in spc_select_write_params() */
if (d->drive_role == 1 && d->mdata->valid <= 0) {

View File

@ -60,6 +60,10 @@ static int drivetop = -1;
/* ts A80410 : in init.c */
extern int burn_support_untested_profiles;
/* ts B10312 : in init.c */
extern int burn_drive_role_4_allowed;
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
*/
int burn_setup_drive(struct burn_drive *d, char *fname)
@ -1386,6 +1390,7 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret,
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
}
}
if (is_rdwr && fd >= 0) {
getfl_ret = fcntl(fd, F_GETFL);
@ -1411,6 +1416,37 @@ fprintf(stderr, "LIBBURN_DEBUG: burn_drive__is_rdwr: getfl_ret = %lX , O_RDWR =
}
static int burn_role_by_access(char *fname, int flag)
{
/* We normally need _LARGEFILE64_SOURCE defined by the build system.
Nevertheless the system might use large address integers by default.
*/
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
int fd;
fd = open(fname, O_RDWR | O_LARGEFILE);
if (fd != -1) {
close(fd);
return 2;
}
fd = open(fname, O_RDONLY | O_LARGEFILE);
if (fd != -1) {
close(fd);
return 4;
}
fd = open(fname, O_WRONLY | O_LARGEFILE);
if (fd != -1) {
close(fd);
return 3;
}
if (flag & 1)
return 0;
return 2;
}
/* ts A70903 : Implements adquiration of pseudo drives */
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
{
@ -1422,8 +1458,6 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
struct burn_drive *d= NULL, *regd_d;
struct stat stbuf;
static int allow_role_3 = 1;
if (fname[0] != 0) {
is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf,
&read_size, 1);
@ -1445,22 +1479,18 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
return 0;
}
if (fname[0] != 0) {
/* >>> as soon as new role 4 is introduced:
if (is_rdwr == 2) role = 4; else
*/
role = 2;
if (is_rdwr == 2 &&
(burn_drive_role_4_allowed & 1))
role = 4;
else
role = 2;
if (stat_ret != -1 && is_rdwr == 1 &&
(burn_drive_role_4_allowed & 3) == 3)
role = burn_role_by_access(fname,
!!(burn_drive_role_4_allowed & 4));
} else
role = 0;
} else {
if(S_ISDIR(stbuf.st_mode) || !allow_role_3) {
libdax_msgs_submit(libdax_messenger, -1,
0x00020149,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Unsuitable filetype for pseudo-drive", 0, 0);
return 0;
}
role = 3;
}
}
@ -1481,22 +1511,28 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
}
free((char *) d); /* all sub pointers have been copied to *regd_d */
d = regd_d;
if (d->drive_role == 2 || d->drive_role == 3) {
d->status = BURN_DISC_BLANK;
d->current_profile = 0xffff; /* MMC for non-compliant drive */
if (d->drive_role == 2 || d->drive_role == 3 || d->drive_role == 4) {
if (d->drive_role == 4) {
d->status = BURN_DISC_FULL;
/* MMC for non-compliant drive */
d->current_profile = 0xffff;
d->block_types[BURN_WRITE_TAO] = 0;
d->block_types[BURN_WRITE_SAO] = 0;
} else {
d->status = BURN_DISC_BLANK;
/* MMC for non-compliant drive */
d->current_profile = 0xffff;
d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1;
d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
}
strcpy(d->current_profile_text,"stdio file");
d->current_is_cd_profile = 0;
d->current_is_supported_profile = 1;
d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1;
d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
if (read_size >= 0)
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
burn_drive_set_media_capacity_remaining(d, size);
/* >>> ? open file for a test ? (>>> beware of "-" = stdin) */;
} else
d->current_profile = 0; /* Drives return this if empty */
@ -1515,6 +1551,10 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
strcpy((*drive_infos)[0].vendor,"YOYODYNE");
strcpy((*drive_infos)[0].product,"BLACKHOLE");
strcpy((*drive_infos)[0].revision,"FX02");
} else if (d->drive_role == 4) {
strcpy((*drive_infos)[0].vendor,"YOYODYNE");
strcpy((*drive_infos)[0].product,"WARP DRIVE");
strcpy((*drive_infos)[0].revision,"FX03");
} else {
strcpy((*drive_infos)[0].vendor,"FERENGI");
strcpy((*drive_infos)[0].product,"VAPORWARE");
@ -2448,7 +2488,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
o->current_is_cd_profile = d->current_is_cd_profile;
o->might_simulate = 0;
if (d->drive_role == 0)
if (d->drive_role == 0 || d->drive_role == 4)
return 0;
if (d->drive_role == 2) {
/* stdio file drive : random access read-write */
@ -2711,12 +2751,9 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
if (fd != -1)
exact_role_matters = 1;
ret = burn_drive__is_rdwr(adr2, NULL, NULL, NULL, 1);
/* >>> as soon as new role 4 is introduced:
if (ret == 2) role2 = 4; else
*/
if (ret == 1)
if (ret == 2 && burn_drive_role_4_allowed)
role2 = 4;
else if (ret > 0)
role2 = 2;
else
role2 = 3;

View File

@ -105,6 +105,14 @@ int burn_support_untested_profiles = 0;
*/
int burn_sg_log_scsi = 0;
/* ts B10312 :
Whether to map random-access readonly files to drive role 4.
Else it is role 2 overwriteable drive
*/
int burn_drive_role_4_allowed = 0;
/* ts A60925 : ticket 74 */
/** Create the messenger object for libburn. */
int burn_msgs_initialize(void)
@ -565,3 +573,10 @@ void burn_set_scsi_logging(int flag)
{
burn_sg_log_scsi = flag & 7;
}
/* ts B10312 API */
void burn_allow_drive_role_4(int allowed)
{
burn_drive_role_4_allowed = (allowed & 7);
}

View File

@ -3004,7 +3004,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
char data[], off_t data_size, off_t *data_count, int flag);
/* A70904 */
/* ts A70904 */
/** Inquire whether the drive object is a real MMC drive or a pseudo-drive
created by a stdio: address.
@param d The drive to inquire
@ -3012,11 +3012,41 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
1= real MMC drive
2= stdio-drive, random access, read-write
3= stdio-drive, sequential, write-only
4= stdio-drive, random access, read-only
(only if enabled by burn_allow_drive_role_4())
@since 0.4.0
*/
int burn_drive_get_drive_role(struct burn_drive *d);
/* ts B10312 */
/** Allow drive role 4 "random access read-only" drive.
By default a random access file assumes drive role 2 "read-write"
regardless whether it is actually readable or writeable.
If enabled, random-access file objects which recognizably allow no
writing will be classified as role 4.
Candidates are drive addresses of the form stdio:/dev/fd/# , where # is
the integer number of an open file descriptor. If this descriptor was
opened read-only, then it gets role 4.
Other paths may get tested by an attempt to open them for read-write
(role 2) resp. read-only (role 4) resp. write-only (role 3). See bit1.
read-only
@param allowed Bitfield for control purposes:
bit0= Enable role 4 for drives which get aquired
after this call
bit1= with bit0:
Test whether the file can be opened for
read-write resp. read-only resp. write-only.
Classify as roles 2 resp. 4 resp. 3.
bit2= with bit0 and bit1:
Classify files which cannot be opened at all
as role 0 : useless dummy.
Else classify as role 2.
@since 1.0.6
*/
void burn_allow_drive_role_4(int allowed);
/* ts A70923 */
/** Find out whether a given address string would lead to the given drive
object. This should be done in advance for track source addresses

View File

@ -2,6 +2,7 @@ LIBBURN4 {
global:
burn_abort;
burn_abort_pacifier;
burn_allow_drive_role_4;
burn_allow_untested_profiles;
burn_disc_add_session;
burn_disc_available_space;

View File

@ -566,6 +566,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002017e (FAILURE,HIGH) = Failed to close track, session, or disc
0x0002017f (FAILURE,HIGH) = Failed to synchronize drive cache
0x00020180 (FAILURE,HIGH) = Premature end of input encountered
0x00020181 (FAILURE,HIGH) = Pseudo-drive is a read-only file. Cannot write.
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -1005,9 +1005,12 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
reason_pt= reasons;
reasons[0] = 0;
if (d->drive_role == 0) {
sprintf(reasons,
"DRIVE: is a virtual placeholder (null-drive)");
if (d->drive_role == 0 || d->drive_role == 4) {
if (d->drive_role == 0)
sprintf(reasons,
"DRIVE: is a virtual placeholder (null-drive)");
else
sprintf(reasons, "DRIVE: read-only pseudo drive");
no_media = 1;
goto ex;
}
@ -2042,6 +2045,14 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
char msg[160];
off_t lseek_res;
if(d->drive_role == 4) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020181,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Pseudo-drive is a read-only file. Cannot write.",
0, 0);
return 0;
}
if (d->devname[0] == 0) /* null drives should not come here */
return -1;
fd = burn_drive__fd_from_special_adr(d->devname);
@ -2421,6 +2432,14 @@ calloc() seems not to have the desired effect. valgrind warns:
d->rlba = -150;
d->toc_temp = 9;
if(d->drive_role == 4) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020181,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Pseudo-drive is a read-only file. Cannot write.",
0, 0);
goto fail_wo_sync;
}
/* ts A70904 */
if (d->drive_role != 1) {
ret = burn_stdio_write_sync(o, disc);
@ -2644,6 +2663,14 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
"Drive is a virtual placeholder (null-drive)", 0, 0);
return 0;
}
if(d->drive_role == 4) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020181,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Pseudo-drive is a read-only file. Cannot write.",
0, 0);
return 0;
}
if(d->drive_role == 2)
alignment = 2 * 1024;