From 75dd14105573f3031db6db4609182e7b0f7d0b94 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 9 Sep 2007 13:31:29 +0000 Subject: [PATCH] Enable os dependend stdio size estimation --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/init.c | 2 ++ libburn/sg-freebsd-port.c | 72 +++++++++++++++++++++++++++++++++++++ libburn/sg-freebsd.c | 70 ++++++++++++++++++++++++++++++++++++ libburn/sg-linux.c | 66 ++++++++++++++++++++++++++++++++++ libburn/sg.h | 2 ++ 6 files changed, 213 insertions(+), 1 deletion(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 49886a1..cfceeb7 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.09.09.093637" +#define Cdrskin_timestamP "2007.09.09.133136" diff --git a/libburn/init.c b/libburn/init.c index d647305..2947651 100644 --- a/libburn/init.c +++ b/libburn/init.c @@ -8,6 +8,8 @@ #include #include #include +#include + #include "init.h" #include "sg.h" diff --git a/libburn/sg-freebsd-port.c b/libburn/sg-freebsd-port.c index 42f8509..e7e8168 100644 --- a/libburn/sg-freebsd-port.c +++ b/libburn/sg-freebsd-port.c @@ -48,6 +48,8 @@ sg_issue_command() sends a SCSI command to the drive, receives reply, sg_obtain_scsi_adr() tries to obtain SCSI address parameters. +burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. + Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . @@ -74,6 +76,10 @@ Send feedback to libburn-hackers@pykix.org . #include /* XXX */ +/* ts A70909 : >>> untestet yet wether this compiles */ +#include + + /** PORTING : ------ libburn portable headers and definitions ----- */ #include "transport.h" @@ -557,3 +563,69 @@ int sg_is_enumerable_adr(char* adr) 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 + exist yet, then the directory will be inquired. + @param bytes This value gets modified if an estimation is possible + @return -2 = cannot perform necessary operations on file object + -1 = neither path nor dirname of path exist + 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) +{ + struct stat stbuf; + struct statvfs vfsbuf; + char testpath[4096], *cpt; + long blocks; + int open_mode = O_RDWR, fd, ret; + off_t add_size = 0; + + testpath[0] = 0; + blocks = *bytes / 512; + if (stat(path, &stbuf) == -1) { + strcpy(testpath, path); + cpt = strrchr(testpath, '/'); + if(cpt == NULL) + strcpy(testpath, "."); + else if(cpt == testpath) + testpath[1] = 0; + else + *cpt = 0; + if (stat(testpath, &stbuf) == -1) + return -1; + +#ifdef Libburn_if_this_was_linuX + + } else if(S_ISBLK(stbuf.st_mode)) { + if(burn_sg_open_o_excl) + open_mode |= O_EXCL; + fd = open(path, open_mode); + if (fd == -1) + return -2; + ret = ioctl(fd, BLKGETSIZE, &blocks); + close(fd); + if (ret == -1) + return -2; + *bytes = ((off_t) blocks) * (off_t) 512; + +#endif /* Libburn_if_this_was_linuX */ + + + } else if(S_ISREG(stbuf.st_mode)) { + add_size = stbuf.st_blocks * (off_t) 512; + strcpy(testpath, path); + } else + return 0; + + if (testpath[0]) { + if (statvfs(testpath, &vfsbuf) == -1) + return -2; + *bytes = add_size + ((off_t) vfsbuf.f_bsize) * + (off_t) vfsbuf.f_bavail; + } + return 1; +} + diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 9fc5448..6be71fe 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -18,6 +18,10 @@ #include /* XXX */ +/* ts A70909 : >>> untestet yet wether this compiles */ +#include + + #include "transport.h" #include "drive.h" #include "sg.h" @@ -598,3 +602,69 @@ int sg_issue_command(struct burn_drive *d, struct command *c) return 1; } + +/* 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 + exist yet, then the directory will be inquired. + @param bytes This value gets modified if an estimation is possible + @return -2 = cannot perform necessary operations on file object + -1 = neither path nor dirname of path exist + 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) +{ + struct stat stbuf; + struct statvfs vfsbuf; + char testpath[4096], *cpt; + long blocks; + int open_mode = O_RDWR, fd, ret; + off_t add_size = 0; + + testpath[0] = 0; + blocks = *bytes / 512; + if (stat(path, &stbuf) == -1) { + strcpy(testpath, path); + cpt = strrchr(testpath, '/'); + if(cpt == NULL) + strcpy(testpath, "."); + else if(cpt == testpath) + testpath[1] = 0; + else + *cpt = 0; + if (stat(testpath, &stbuf) == -1) + return -1; + +#ifdef Libburn_if_this_was_linuX + + } else if(S_ISBLK(stbuf.st_mode)) { + if(burn_sg_open_o_excl) + open_mode |= O_EXCL; + fd = open(path, open_mode); + if (fd == -1) + return -2; + ret = ioctl(fd, BLKGETSIZE, &blocks); + close(fd); + if (ret == -1) + return -2; + *bytes = ((off_t) blocks) * (off_t) 512; + +#endif /* Libburn_if_this_was_linuX */ + + + } else if(S_ISREG(stbuf.st_mode)) { + add_size = stbuf.st_blocks * (off_t) 512; + strcpy(testpath, path); + } else + return 0; + + if (testpath[0]) { + if (statvfs(testpath, &vfsbuf) == -1) + return -2; + *bytes = add_size + ((off_t) vfsbuf.f_bsize) * + (off_t) vfsbuf.f_bavail; + } + return 1; +} + diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index 5a6d653..d19d06a 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -48,6 +48,8 @@ sg_issue_command() sends a SCSI command to the drive, receives reply, sg_obtain_scsi_adr() tries to obtain SCSI address parameters. +burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. + Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . @@ -73,6 +75,11 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and #include #include #include +#include + +/* for ioctl(BLKGETSIZE) */ +#include + #include /* Values within sg_io_hdr_t indicating success after ioctl(SG_IO) : */ @@ -1352,3 +1359,62 @@ int sg_is_enumerable_adr(char *adr) } +/* 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 + exist yet, then the directory will be inquired. + @param bytes The pointed value gets modified, but only if an estimation is + possible. + @return -2 = cannot perform necessary operations on file object + -1 = neither path nor dirname of path exist + 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) +{ + struct stat stbuf; + struct statvfs vfsbuf; + char testpath[4096], *cpt; + long blocks; + int open_mode = O_RDWR, fd, ret; + off_t add_size = 0; + + testpath[0] = 0; + blocks = *bytes / 512; + if (stat(path, &stbuf) == -1) { + strcpy(testpath, path); + cpt = strrchr(testpath, '/'); + if(cpt == NULL) + strcpy(testpath, "."); + else if(cpt == testpath) + testpath[1] = 0; + else + *cpt = 0; + if (stat(testpath, &stbuf) == -1) + return -1; + } else if(S_ISBLK(stbuf.st_mode)) { + if(burn_sg_open_o_excl) + open_mode |= O_EXCL; + fd = open(path, open_mode); + if (fd == -1) + return -2; + ret = ioctl(fd, BLKGETSIZE, &blocks); + close(fd); + if (ret == -1) + return -2; + *bytes = ((off_t) blocks) * (off_t) 512; + } else if(S_ISREG(stbuf.st_mode)) { + add_size = stbuf.st_blocks * (off_t) 512; + strcpy(testpath, path); + } else + return 0; + + if (testpath[0]) { + if (statvfs(testpath, &vfsbuf) == -1) + return -2; + *bytes = add_size + ((off_t) vfsbuf.f_bsize) * + (off_t) vfsbuf.f_bavail; + } + return 1; +} + diff --git a/libburn/sg.h b/libburn/sg.h index abee161..f1de7a2 100644 --- a/libburn/sg.h +++ b/libburn/sg.h @@ -31,4 +31,6 @@ int scsi_enumerate_drives(void); int sg_drive_is_open(struct burn_drive * d); +int burn_os_stdio_capacity(char *path, off_t *bytes); + #endif /* __SG */