diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 02fc0d2..4c5d547 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2014.05.03.103448" +#define Cdrskin_timestamP "2014.06.09.183251" diff --git a/libburn/drive.c b/libburn/drive.c index c13ffe1..cf8e1f8 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -393,7 +393,7 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret, if (S_ISREG(stbuf.st_mode)) read_size = stbuf.st_size; else if (is_rdwr) - ret = burn_os_stdio_capacity(fname, &read_size); + ret = burn_os_stdio_capacity(fname, 0, &read_size); if (ret <= 0 || read_size / (off_t) 2048 >= (off_t) 0x7ffffff0) read_size = (off_t) 0x7ffffff0 * (off_t) 2048; @@ -450,7 +450,7 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag) d->media_read_capacity = read_size / 2048 - !(read_size % 2048); if ((stat_ret == -1 || is_rdwr) && d->devname[0]) { - ret = burn_os_stdio_capacity(d->devname, &size); + ret = burn_os_stdio_capacity(d->devname, 0, &size); if (ret > 0) burn_drive_set_media_capacity_remaining(d, size); @@ -1722,7 +1722,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf, &read_size, 1 | 2); if (stat_ret == -1 || is_rdwr) { - ret = burn_os_stdio_capacity(fname, &size); + ret = burn_os_stdio_capacity(fname, 0, &size); if (ret == -1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020009, @@ -2637,7 +2637,8 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start) off_t burn_disc_available_space(struct burn_drive *d, struct burn_write_opts *o) { - int lba, nwa; + int lba, nwa, ret; + off_t bytes; if (burn_drive_is_released(d)) return 0; @@ -2646,9 +2647,13 @@ off_t burn_disc_available_space(struct burn_drive *d, if (d->drive_role == 0) return 0; if (d->drive_role != 1) { - if (d->media_capacity_remaining <= 0) - burn_drive_set_media_capacity_remaining(d, - (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); + ret = burn_os_stdio_capacity(d->devname, o->start_byte, &bytes); + if (ret != 1) + bytes = d->media_capacity_remaining; + if (bytes <= 0) + bytes = (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048; + if (bytes != d->media_capacity_remaining) + burn_drive_set_media_capacity_remaining(d, bytes); } else { if (o != NULL) d->send_write_parameters(d, NULL, -1, o); @@ -2897,7 +2902,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, /* stdio file drive : random access read-write */ o->start_adr = 1; size = d->media_capacity_remaining; - burn_os_stdio_capacity(d->devname, &size); + burn_os_stdio_capacity(d->devname, 0, &size); burn_drive_set_media_capacity_remaining(d, size); o->start_range_high = d->media_capacity_remaining; o->start_alignment = 2048; /* imposting a drive, not a file */ @@ -2909,7 +2914,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, /* stdio file drive : random access write-only */ o->start_adr = 1; size = d->media_capacity_remaining; - burn_os_stdio_capacity(d->devname, &size); + burn_os_stdio_capacity(d->devname, 0, &size); burn_drive_set_media_capacity_remaining(d, size); /* >>> start_range_low = file size rounded to 2048 */; diff --git a/libburn/libburn.h b/libburn/libburn.h index 470d88d..caa9fd5 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -1478,7 +1478,7 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba); grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value from the most recent automatic inquiry (e.g. during last drive grabbing). An eventual start address from burn_write_opts_set_start_byte() will be - subtracted from the obtained capacity estimation. Negative results get + taken into respect with the capacity estimation. Negative results get defaulted to 0. If the drive is actually a file in a large filesystem or a large block device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks diff --git a/libburn/sg-dummy.c b/libburn/sg-dummy.c index 2c9b50a..f9b6e40 100644 --- a/libburn/sg-dummy.c +++ b/libburn/sg-dummy.c @@ -244,7 +244,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; @@ -289,7 +289,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) #endif /* Libburn_if_this_was_linuX */ } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg-freebsd-port.c b/libburn/sg-freebsd-port.c index bb89edc..db1c687 100644 --- a/libburn/sg-freebsd-port.c +++ b/libburn/sg-freebsd-port.c @@ -716,7 +716,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; struct statvfs vfsbuf; @@ -769,7 +769,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) {ret = -2; goto ex;} *bytes = add_size; } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 77a3025..6ca26f2 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -1051,7 +1051,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; struct statvfs vfsbuf; @@ -1104,7 +1104,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) {ret = -2; goto ex;} *bytes = add_size; } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg-libcdio.c b/libburn/sg-libcdio.c index 9d8754b..b2a63e2 100644 --- a/libburn/sg-libcdio.c +++ b/libburn/sg-libcdio.c @@ -865,7 +865,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; @@ -944,7 +944,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) #endif /* Libburn_is_on_solariS */ } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index bc95b13..a9ae186 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -2169,6 +2169,24 @@ int sg_issue_command(struct burn_drive *d, struct command *c) c->end_time = burn_get_time(0); +/* + # de fine Libburn_ff_netbsd_mockuP + */ +#ifdef Libburn_ff_netbsd_mockuP + if (c->opcode[0] == 0x5a) { + sprintf(msg, "Libburn_ff_netbsd_mockuP : Emulating zero reply from SCSI command 5A"); + if (burn_sg_log_scsi & 3) + scsi_log_message(d, fp, msg, 0); + libdax_msgs_submit(libdax_messenger, + d->global_index, 0x00000002, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + msg, 0, 0); + memset(c->page->data, 0, c->page->bytes); + c->error = 1; + c->dxfer_len = 0; + } +#endif + /* ts A61010 */ /* a ssert(err != -1); */ if (err == -1) { @@ -2353,7 +2371,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; struct statvfs vfsbuf; @@ -2386,7 +2404,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) {ret = -2; goto ex;} *bytes = ((off_t) blocks) * (off_t) 512; } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg-netbsd.c b/libburn/sg-netbsd.c index 4a9a472..691b3b8 100644 --- a/libburn/sg-netbsd.c +++ b/libburn/sg-netbsd.c @@ -787,7 +787,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; int ret; @@ -830,7 +830,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) } } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg-solaris.c b/libburn/sg-solaris.c index 085507a..7c191ec 100644 --- a/libburn/sg-solaris.c +++ b/libburn/sg-solaris.c @@ -785,7 +785,7 @@ int burn_os_is_2k_seekrw(char *path, int flag) 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ -int burn_os_stdio_capacity(char *path, off_t *bytes) +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; int ret; @@ -826,7 +826,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes) } } else if(S_ISREG(stbuf.st_mode)) { - add_size = stbuf.st_blocks * (off_t) 512; + add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} diff --git a/libburn/sg.h b/libburn/sg.h index 4d69f46..fc05a84 100644 --- a/libburn/sg.h +++ b/libburn/sg.h @@ -36,7 +36,7 @@ int sg_drive_is_open(struct burn_drive * d); int burn_os_is_2k_seekrw(char *path, int flag); -int burn_os_stdio_capacity(char *path, off_t *bytes); +int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes); /* ts A91227 */ /** Returns the id string of the SCSI transport adapter and eventually diff --git a/libburn/util.c b/libburn/util.c index ad7b77a..9dae9b5 100644 --- a/libburn/util.c +++ b/libburn/util.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include @@ -377,4 +379,23 @@ double burn_get_time(int flag) return (double) time(NULL); } +/* ts B40609 */ +off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf) +{ + off_t add_size; + + add_size = stbuf->st_blocks * (off_t) 512; + if (add_size < stbuf->st_size) { + /* Sparse file */ + if (write_start < stbuf->st_size) { + /* Might write into sparse gaps */ + if (write_start > add_size) + add_size = write_start; + } else { + /* Will not write into sparse area */ + add_size = stbuf->st_size; + } + } + return add_size; +} diff --git a/libburn/util.h b/libburn/util.h index 4a37a40..144f8cc 100644 --- a/libburn/util.h +++ b/libburn/util.h @@ -1,6 +1,11 @@ #ifndef __UTIL #define __UTIL +/* for struct stat */ +#include +#include +#include + /* ts A90905 */ int burn_util_make_printable_word(char **text, int flag); @@ -14,4 +19,7 @@ void burn_int_to_lsb(int val, char *target); /* ts B30609 */ double burn_get_time(int flag); +/* ts B40609 */ +off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf); + #endif