From 39fd8b922dd7cbd2838e5acd9a591eae1caef603 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 16 Jan 2010 12:51:24 +0000 Subject: [PATCH] New OS adapter burn_os_is_2k_seekrw() replaces S_ISBLK() with pseudo-drives --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 35 +--------------- libburn/sg-dummy.c | 17 ++++++++ libburn/sg-freebsd-port.c | 60 +++++++++++++++++++++++++++- libburn/sg-freebsd.c | 41 +++++++++++++++++++ libburn/sg-libcdio.c | 79 +++++++++++++++++++++++++++++++++++++ libburn/sg-linux.c | 23 +++++++++++ libburn/sg.h | 2 + 8 files changed, 224 insertions(+), 35 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index cc20d63..82bd187 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2010.01.15.182615" +#define Cdrskin_timestamP "2010.01.16.125258" diff --git a/libburn/drive.c b/libburn/drive.c index 2c97550..698f1ef 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -1322,7 +1322,7 @@ int burn_drive__fd_from_special_adr(char *adr) int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) { int ret = -1, fd = -1, role = 0; - int is_fabricated_block_dev, is_block_dev = 0; + int is_block_dev = 0; /* divided by 512 it needs to fit into a signed long integer */ off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); off_t read_size = -1; @@ -1331,36 +1331,6 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) static int allow_role_3 = 1; -/* ts B00112 : - >>> this is just a test hack to work with an USB stick on FreeBSD -*/ -#ifdef __FreeBSD__ -#define Libburn_guess_block_devicE 1 -#endif -#ifdef __FreeBSD_kernel__ -#define Libburn_guess_block_devicE 1 -#endif - - is_fabricated_block_dev = 0; - -#ifdef Libburn_guess_block_devicE - { - char *spt; - spt = strrchr(fname, '/'); - if (spt == NULL) - spt = fname; - else - spt++; - if (spt[0] == 'd' && spt[1] == 'a' && - (spt[2] >= '0' || spt[2] <= '9') && spt[3] == 0) - is_fabricated_block_dev = 1; - if (spt[0] == 'c' && spt[1] == 'd' && - (spt[2] >= '0' || spt[2] <= '9') && spt[3] == 0) - is_fabricated_block_dev = 1; - - } -#endif /* Libburn_guess_block_devicE */ - if (fname[0] != 0) { memset(&stbuf, 0, sizeof(stbuf)); fd = burn_drive__fd_from_special_adr(fname); @@ -1369,8 +1339,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) else ret = stat(fname, &stbuf); if (ret != -1) { - is_block_dev = S_ISBLK(stbuf.st_mode) || - is_fabricated_block_dev; + is_block_dev = burn_os_is_2k_seekrw(fname, 0); if (S_ISREG(stbuf.st_mode)) read_size = stbuf.st_size; else if (is_block_dev) { diff --git a/libburn/sg-dummy.c b/libburn/sg-dummy.c index 47c82a2..be9abbc 100644 --- a/libburn/sg-dummy.c +++ b/libburn/sg-dummy.c @@ -206,6 +206,23 @@ int sg_is_enumerable_adr(char *adr) } +/* Return 1 if the given path leads to a regular file or a device that can be + seeked, read, and possibly written with 2 kB granularity. +*/ +int burn_os_is_2k_seekrw(char *path, int flag) +{ + struct stat stbuf; + + if (stat(path, &stbuf) == -1) + return 0; + if (S_ISREG(stbuf.st_mode)) + return 1; + if (S_ISBLK(stbuf.st_mode)) + return 1; + return 0; +} + + /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. diff --git a/libburn/sg-freebsd-port.c b/libburn/sg-freebsd-port.c index 363ccd9..cbb2e35 100644 --- a/libburn/sg-freebsd-port.c +++ b/libburn/sg-freebsd-port.c @@ -64,8 +64,25 @@ sg_issue_command() sends a SCSI command to the drive, receives reply, sg_obtain_scsi_adr() tries to obtain SCSI address parameters. + +burn_os_is_2k_seekrw() tells whether the given path leads to a file object + that can be used in 2 kB granularity by lseek(2), + read(2), and possibly write(2) if not read-only. + E.g. a USB stick or a hard disk. + burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. +burn_os_open_track_src() opens a disk file in a way that allows best + throughput with file reading and/or SCSI write command + transmission. + +burn_os_alloc_buffer() allocates a memory area that is suitable for file + descriptors issued by burn_os_open_track_src(). + The buffer size may be rounded up for alignment + reasons. + +burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer(). + Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . @@ -370,7 +387,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */ break; snprintf(buf, sizeof (buf), "/dev/%s%d", result->periph_name, result->unit_number); - if(adr_size <= strlen(buf) + if(adr_size <= strlen(buf)) return -1; strcpy(adr, buf); @@ -637,6 +654,47 @@ int sg_is_enumerable_adr(char* adr) } +/* ts B00115 */ +/* Return 1 if the given path leads to a regular file or a device that can be + seeked, written, and read with 2 kB granularity. +*/ +int burn_os_is_2k_seekrw(char *path, int flag) +{ + struct stat stbuf; + char *spt; + int i, e; + + if (stat(path, &stbuf) == -1) + return 0; + if (S_ISREG(stbuf.st_mode)) + return 1; + if (!S_ISCHR(stbuf.st_mode)) + return 0; + spt = strrchr(path, '/'); + if (spt == NULL) + spt = path; + else + spt++; + e = strlen(spt); + for (i = strlen(spt) - 1; i > 0; i--) + if (spt[i] >= '0' && spt[i] <= '9') + e = i; + if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */ + return 1; + if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */ + return 1; + if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */ + return 1; + if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */ + return 1; + if (strncmp(spt, "fd", e) == 0) /* Floppy disk */ + return 1; + if (strncmp(spt, "fla", e) == 0) /* Flash drive */ + return 1; + return 0; +} + + /* ts A70909 */ /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 0598cf6..712d241 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -852,6 +852,47 @@ ex:; } +/* ts B00115 */ +/* Return 1 if the given path leads to a regular file or a device that can be + seeked, read and eventually written with 2 kB granularity. +*/ +int burn_os_is_2k_seekrw(char *path, int flag) +{ + struct stat stbuf; + char *spt; + int i, e; + + if (stat(path, &stbuf) == -1) + return 0; + if (S_ISREG(stbuf.st_mode)) + return 1; + if (!S_ISCHR(stbuf.st_mode)) + return 0; + spt = strrchr(path, '/'); + if (spt == NULL) + spt = path; + else + spt++; + e = strlen(spt); + for (i = strlen(spt) - 1; i > 0; i--) + if (spt[i] >= '0' && spt[i] <= '9') + e = i; + if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */ + return 1; + if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */ + return 1; + if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */ + return 1; + if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */ + return 1; + if (strncmp(spt, "fd", e) == 0) /* Floppy disk */ + return 1; + if (strncmp(spt, "fla", e) == 0) /* Flash drive */ + return 1; + return 0; +} + + /* ts A70909 */ /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not diff --git a/libburn/sg-libcdio.c b/libburn/sg-libcdio.c index dc1676d..2b536bc 100644 --- a/libburn/sg-libcdio.c +++ b/libburn/sg-libcdio.c @@ -64,6 +64,12 @@ sg_issue_command() sends a SCSI command to the drive, receives reply, sg_obtain_scsi_adr() tries to obtain SCSI address parameters. + +burn_os_is_2k_seekrw() tells whether the given path leads to a file object + that can be used in 2 kB granularity by lseek(2), + read(2), and possibly write(2) if not read-only.. + E.g. a USB stick or a hard disk. + burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. burn_os_open_track_src() opens a disk file in a way that allows best @@ -709,6 +715,79 @@ int sg_is_enumerable_adr(char* adr) } +#ifdef __FreeBSD__ +#define Libburn_guess_block_devicE 1 +#endif +#ifdef __FreeBSD_kernel__ +#define Libburn_guess_block_devicE 1 +#endif + +#ifdef Libburn_guess_block_devicE + +/* ts B00115 */ +/* The FreeBSD implementation of burn_os_is_2k_seekrw(). + On FreeBSD there are no block devices. +*/ +static int freebsd_is_2k_seekrw(char *path, int flag) +{ + struct stat stbuf; + char *spt; + int i, e; + + if (stat(path, &stbuf) == -1) + return 0; + if (S_ISREG(stbuf.st_mode)) + return 1; + if (!S_ISCHR(stbuf.st_mode)) + return 0; + spt = strrchr(path, '/'); + if (spt == NULL) + spt = path; + else + spt++; + e = strlen(spt); + for (i = strlen(spt) - 1; i > 0; i--) + if (spt[i] >= '0' && spt[i] <= '9') + e = i; + if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */ + return 1; + if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */ + return 1; + if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */ + return 1; + if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */ + return 1; + if (strncmp(spt, "fd", e) == 0) /* Floppy disk */ + return 1; + if (strncmp(spt, "fla", e) == 0) /* Flash drive */ + return 1; + return 0; +} + +#endif /* Libburn_guess_block_devicE */ + + +/* Return 1 if the given path leads to a regular file or a device that can be + seeked, read, and possibly written with 2 kB granularity. +*/ +int burn_os_is_2k_seekrw(char *path, int flag) +{ +#ifdef Libburn_guess_block_devicE + return freebsd_is_2k_seekrw(path, flag); +#else + struct stat stbuf; + + if (stat(path, &stbuf) == -1) + return 0; + if (S_ISREG(stbuf.st_mode)) + return 1; + if (S_ISBLK(stbuf.st_mode)) + return 1; + return 0; +#endif /* ! Libburn_guess_block_devicE */ +} + + /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index c624a1b..3b6d2aa 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -71,6 +71,11 @@ sg_issue_command() sends a SCSI command to the drive, receives reply, sg_obtain_scsi_adr() tries to obtain SCSI address parameters. +burn_os_is_2k_seekrw() tells whether the given path leads to a file object + that can be used in 2 kB granularity by lseek(2), + read(2), and possibly write(2). + E.g. a USB stick or a hard disk. + burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. burn_os_open_track_src() opens a disk file in a way that allows best @@ -2050,6 +2055,24 @@ int sg_is_enumerable_adr(char *adr) } +/* ts B00115 */ +/* Return 1 if the given path leads to a regular file or a device that can be + seeked, read, and possibly written with 2 kB granularity. +*/ +int burn_os_is_2k_seekrw(char *path, int flag) +{ + struct stat stbuf; + + if (stat(path, &stbuf) == -1) + return 0; + if (S_ISREG(stbuf.st_mode)) + return 1; + if (S_ISBLK(stbuf.st_mode)) + return 1; + return 0; +} + + /* ts A70909 */ /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not diff --git a/libburn/sg.h b/libburn/sg.h index 31f1dd9..a4e9c8a 100644 --- a/libburn/sg.h +++ b/libburn/sg.h @@ -31,6 +31,8 @@ int scsi_enumerate_drives(void); 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); /* ts A91227 */