From 8c56ca131f4fb89295f86dd2c86bf75d0e7a8f8b Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 2 Mar 2009 17:01:21 +0000 Subject: [PATCH] New operating system adapter "dummy" for stdio on POSIX-like systems --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/libdax_msgs.h | 5 + libburn/os-dummy.h | 63 ++++++++++ libburn/os.h | 15 ++- libburn/sg-dummy.c | 227 ++++++++++++++++++++++++++++++++++++ libburn/sg.c | 10 +- 6 files changed, 316 insertions(+), 6 deletions(-) create mode 100644 libburn/os-dummy.h create mode 100644 libburn/sg-dummy.c diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index bb48683..9553b00 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2009.02.27.211707" +#define Cdrskin_timestamP "2009.03.02.170126" diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index b69fce9..cf48717 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -542,8 +542,13 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020167 (SORRY,HIGH) = Drive does not support non-default formatting 0x00020168 (FAILURE,HIGH) = Media not properly formatted. Cannot write. 0x00020169 (WARNING,HIGH) = Last session on media is still open + 0x0002016a (FAILURE,HIGH) = No MMC transport adapter is present + 0x0002016b (WARNING,HIGH) = No MMC transport adapter is present + 0x0002016c (DEBUG,HIGH) = No MMC transport adapter is present + 0x00020170 (NOTE,HIGH) = Closing open session before writing new one 0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session + libdax_audioxtr: 0x00020200 (SORRY,HIGH) = Cannot open audio source file diff --git a/libburn/os-dummy.h b/libburn/os-dummy.h new file mode 100644 index 0000000..b0bfad3 --- /dev/null +++ b/libburn/os-dummy.h @@ -0,0 +1,63 @@ + +/* os-dummy.h + Operating system specific libburn definitions and declarations. Included + by os.h in case of compilation for + Unknown POSIX like systems + with the dummy MMC transport adapter sg-dummy.c + + Copyright (C) 2009 Thomas Schmitt , provided under GPL +*/ + + +/** List of all signals which shall be caught by signal handlers and trigger + a graceful abort of libburn. (See man 7 signal.) +*/ +/* Once as system defined macros */ +#define BURN_OS_SIGNAL_MACRO_LIST \ + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \ + SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \ + SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \ + SIGTTOU + +/* Once as text 1:1 list of strings for messages and interpreters */ +#define BURN_OS_SIGNAL_NAME_LIST \ + "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \ + "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \ + "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \ + "SIGTTOU" + +/* The number of above list items */ +#define BURN_OS_SIGNAL_COUNT 16 + +/** To list all signals which shall surely not be caught */ +#define BURN_OS_NON_SIGNAL_MACRO_LIST \ +SIGKILL, SIGCHLD, SIGSTOP + +/* The number of above list items */ +#define BURN_OS_NON_SIGNAL_COUNT 3 + + +/* The maximum size for a (SCSI) i/o transaction */ +/* Important : MUST be at least 32768 ! */ +#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 + + +/* To hold the position of the most recently delivered address from + device enumeration. +*/ +struct burn_drive_enumerator_struct { + int pos; + int info_count; + char **info_list; +}; + +#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ +typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t; + + +/* The list of operating system dependent elements in struct burn_drive. + Usually they are initialized in sg-*.c:enumerate_common(). +*/ +#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ + int just_a_dummy; + diff --git a/libburn/os.h b/libburn/os.h index 3b7a0f4..9758a30 100644 --- a/libburn/os.h +++ b/libburn/os.h @@ -3,7 +3,7 @@ Operating system specific libburn definitions and declarations. The macros defined here are used by libburn modules in order to avoid own system dependent case distinctions. - Copyright (C) 2006 Thomas Schmitt , provided under GPL + Copyright (C) 2009 Thomas Schmitt , provided under GPL */ #ifndef BURN_OS_H_INCLUDED @@ -20,14 +20,23 @@ #include "os-freebsd.h" -#else /* operating system case distinction */ +#else +#ifdef __linux /* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */ #include "os-linux.h" -#endif /* End of operating system case distinction */ +#else + + +/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */ +#include "os-dummy.h" + + +#endif /* ! __linux */ +#endif /* ! __FreeBSD__ */ #endif /* ! BURN_OS_H_INCLUDED */ diff --git a/libburn/sg-dummy.c b/libburn/sg-dummy.c new file mode 100644 index 0000000..3c19838 --- /dev/null +++ b/libburn/sg-dummy.c @@ -0,0 +1,227 @@ +/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ + +/* + +This is the main operating system dependent SCSI part of libburn. It implements +the transport level aspects of SCSI control and command i/o. + +Present implementation: default dummy which enables libburn only to work + with stdio: pseudo drive addresses. + For real implementations see sg-linux.c or sg-freebsd.c + +*/ + + +#include +#include +#include +#include +#include +#include +#include + +#include "transport.h" +#include "drive.h" +#include "sg.h" +#include "spc.h" +#include "mmc.h" +#include "sbc.h" +#include "debug.h" +#include "toc.h" +#include "util.h" + +#include "libdax_msgs.h" +extern struct libdax_msgs *libdax_messenger; + + + +/** Returns the next index number and the next enumerated drive address. + The enumeration has to cover all available and accessible drives. It is + allowed to return addresses of drives which are not available but under + some (even exotic) circumstances could be available. It is on the other + hand allowed, only to hand out addresses which can really be used right + in the moment of this call. (This implementation chooses the former.) + @param idx An opaque handle. Make no own theories about it. + @param adr Takes the reply + @param adr_size Gives maximum size of reply including final 0 + @param initialize 1 = start new, + 0 = continue, use no other values for now + -1 = finish + @return 1 = reply is a valid address , 0 = no further address available + -1 = severe error (e.g. adr_size too small) +*/ +int sg_give_next_adr(burn_drive_enumerator_t *idx, + char adr[], int adr_size, int initialize) +{ + return 0; +} + + +/** Brings all available, not-whitelist-banned, and accessible drives into + libburn's list of drives. +*/ +/* ts A61115: replacing call to sg-implementation internals from drive.c */ +int scsi_enumerate_drives(void) +{ + libdax_msgs_submit(libdax_messenger, -1, 0x0002016b, + LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, + "No MMC transport adapter is present. Running on sg-dummy.c.", + 0, 0); + return 1; +} + + +/** Tells wether libburn has the given drive in use or exclusively reserved. + If it is "open" then libburn will eventually call sg_release() on it when + it is time to give up usage resp. reservation. +*/ +/** Published as burn_drive.drive_is_open() */ +int sg_drive_is_open(struct burn_drive * d) +{ + return 0; +} + + +/** Opens the drive for SCSI commands and - if burn activities are prone + to external interference on your system - obtains an exclusive access lock + on the drive. (Note: this is not physical tray locking.) + A drive that has been opened with sg_grab() will eventually be handed + over to sg_release() for closing and unreserving. +*/ +int sg_grab(struct burn_drive *d) +{ + libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a, + LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, + "No MMC transport adapter is present. Running on sg-dummy.c.", + 0, 0); + return 0; +} + + +/** Gives up the drive for SCSI commands and releases eventual access locks. + (Note: this is not physical tray locking.) +*/ +int sg_release(struct burn_drive *d) +{ + return 0; +} + + +/** Sends a SCSI command to the drive, receives reply and evaluates wether + the command succeeded or shall be retried or finally failed. + Returned SCSI errors shall not lead to a return value indicating failure. + The callers get notified by c->error. An SCSI failure which leads not to + a retry shall be notified via scsi_notify_error(). + The Libburn_log_sg_commandS facility might be of help when problems with + a drive have to be examined. It shall stay disabled for normal use. + @return: 1 success , <=0 failure +*/ +int sg_issue_command(struct burn_drive *d, struct command *c) +{ + libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a, + LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, + "No MMC transport adapter is present. Running on sg-dummy.c.", + 0, 0); + return -1; +} + + +/** Tries to obtain SCSI address parameters. + @return 1 is success , 0 is failure +*/ +int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, + int *target_no, int *lun_no) +{ + libdax_msgs_submit(libdax_messenger, -1, 0x0002016c, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + "No MMC transport adapter is present. Running on sg-dummy.c.", + 0, 0); + return 0; +} + + +/** Tells wether a text is a persistent address as listed by the enumeration + functions. +*/ +int sg_is_enumerable_adr(char *adr) +{ + 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. + @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; + +#ifdef Libburn_os_has_statvfS + struct statvfs vfsbuf; + int open_mode = O_RDONLY, fd, ret; +#endif + + char testpath[4096], *cpt; + long blocks; + 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)) { + 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]) { + +#ifdef Libburn_os_has_statvfS + + if (statvfs(testpath, &vfsbuf) == -1) + return -2; + *bytes = add_size + ((off_t) vfsbuf.f_bsize) * + (off_t) vfsbuf.f_bavail; + +#else /* Libburn_os_has_statvfS */ + + return 0; + +#endif /* ! Libburn_os_has_stavtfS */ + + } + return 1; +} + diff --git a/libburn/sg.c b/libburn/sg.c index 79b78d9..967cdb2 100644 --- a/libburn/sg.c +++ b/libburn/sg.c @@ -1,7 +1,7 @@ /* sg.c Switcher for operating system dependent transport level modules of libburn. - Copyright (C) 2006 Thomas Schmitt , provided under GPL + Copyright (C) 2009 Thomas Schmitt , provided under GPL */ @@ -10,8 +10,14 @@ #include "sg-freebsd.c" #else +#ifdef __linux #include "sg-linux.c" -#endif +#else + +#include "sg-dummy.c" + +#endif /* ! __linux */ +#endif /* ! __FreeBSD__ */