diff --git a/libisofs/errors.c b/libisofs/errors.c deleted file mode 100755 index 860496f..0000000 --- a/libisofs/errors.c +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include "errors.h" -#include - -void iso_warn(enum iso_warnings w) -{ - printf("WARNING: %u\n", w); -} - -void iso_error(enum iso_errors e) -{ - printf("ERROR: %u\n", e); -} diff --git a/libisofs/errors.h b/libisofs/errors.h deleted file mode 100755 index d7a073c..0000000 --- a/libisofs/errors.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __ERRORS -#define __ERRORS - -enum iso_warnings -{ - ISO_WARNING_FOO -}; - -enum iso_errors -{ - ISO_ERROR_FOO -}; - -void iso_warn(enum iso_warnings w); -void iso_error(enum iso_errors e); - -#endif /* __ERRORS */ diff --git a/libisofs/libburn.h b/libisofs/libburn.h deleted file mode 100644 index 7506ed3..0000000 --- a/libisofs/libburn.h +++ /dev/null @@ -1,928 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef LIBBURN_H -#define LIBBURN_H - -/* Needed for off_t which is the (POSIX-ly) appropriate type for - expressing a file or stream size. - - XXX we should enforce 64-bitness for off_t -*/ -#include - -#ifndef DOXYGEN - -#if defined(__cplusplus) -#define BURN_BEGIN_DECLS \ - namespace burn { \ - extern "C" { -#define BURN_END_DECLS \ - } \ - } -#else -#define BURN_BEGIN_DECLS -#define BURN_END_DECLS -#endif - -BURN_BEGIN_DECLS - -#endif - -/** References a physical drive in the system */ -struct burn_drive; - -/** References a whole disc */ -struct burn_disc; - -/** References a single session on a disc */ -struct burn_session; - -/** References a single track on a disc */ -struct burn_track; - -/** Session format for normal audio or data discs */ -#define BURN_CDROM 0 -/** Session format for obsolete CD-I discs */ -#define BURN_CDI 0x10 -/** Session format for CDROM-XA discs */ -#define BURN_CDXA 0x20 - -#define BURN_POS_END 100 - -/** Mask for mode bits */ -#define BURN_MODE_BITS 127 - -/** Track mode - mode 0 data - 0 bytes of user data. it's all 0s. mode 0. get it? HAH -*/ -#define BURN_MODE0 (1 << 0) -/** Track mode - mode "raw" - all 2352 bytes supplied by app - FOR DATA TRACKS ONLY! -*/ -#define BURN_MODE_RAW (1 << 1) -/** Track mode - mode 1 data - 2048 bytes user data, and all the LEC money can buy -*/ -#define BURN_MODE1 (1 << 2) -/** Track mode - mode 2 data - defaults to formless, 2336 bytes of user data, unprotected - | with a data form if required. -*/ -#define BURN_MODE2 (1 << 3) -/** Track mode modifier - Form 1, | with MODE2 for reasonable results - 2048 bytes of user data, 4 bytes of subheader -*/ -#define BURN_FORM1 (1 << 4) -/** Track mode modifier - Form 2, | with MODE2 for reasonable results - lots of user data. not much LEC. -*/ -#define BURN_FORM2 (1 << 5) -/** Track mode - audio - 2352 bytes per sector. may be | with 4ch or preemphasis. - NOT TO BE CONFUSED WITH BURN_MODE_RAW -*/ -#define BURN_AUDIO (1 << 6) -/** Track mode modifier - 4 channel audio. */ -#define BURN_4CH (1 << 7) -/** Track mode modifier - Digital copy permitted, can be set on any track.*/ -#define BURN_COPY (1 << 8) -/** Track mode modifier - 50/15uS pre-emphasis */ -#define BURN_PREEMPHASIS (1 << 9) -/** Input mode modifier - subcodes present packed 16 */ -#define BURN_SUBCODE_P16 (1 << 10) -/** Input mode modifier - subcodes present packed 96 */ -#define BURN_SUBCODE_P96 (1 << 11) -/** Input mode modifier - subcodes present raw 96 */ -#define BURN_SUBCODE_R96 (1 << 12) - -/** Possible disc writing style/modes */ -enum burn_write_types -{ - /** Packet writing. - currently unsupported - */ - BURN_WRITE_PACKET, - /** Track At Once recording. - 2s gaps between tracks, no fonky lead-ins - */ - BURN_WRITE_TAO, - /** Session At Once. - block type MUST be BURN_BLOCK_SAO - */ - BURN_WRITE_SAO, - /** Raw disc at once recording. - all subcodes must be provided by lib or user - only raw block types are supported - */ - BURN_WRITE_RAW -}; - -/** Data format to send to the drive */ -enum burn_block_types -{ - /** sync, headers, edc/ecc provided by lib/user */ - BURN_BLOCK_RAW0 = 1, - /** sync, headers, edc/ecc and p/q subs provided by lib/user */ - BURN_BLOCK_RAW16 = 2, - /** sync, headers, edc/ecc and packed p-w subs provided by lib/user */ - BURN_BLOCK_RAW96P = 4, - /** sync, headers, edc/ecc and raw p-w subs provided by lib/user */ - BURN_BLOCK_RAW96R = 8, - /** only 2048 bytes of user data provided by lib/user */ - BURN_BLOCK_MODE1 = 256, - /** 2336 bytes of user data provided by lib/user */ - BURN_BLOCK_MODE2R = 512, - /** 2048 bytes of user data provided by lib/user - subheader provided in write parameters - are we ever going to support this shit? I vote no. - (supposed to be supported on all drives...) - */ - BURN_BLOCK_MODE2_PATHETIC = 1024, - /** 2048 bytes of data + 8 byte subheader provided by lib/user - hey, this is also dumb - */ - BURN_BLOCK_MODE2_LAME = 2048, - /** 2324 bytes of data provided by lib/user - subheader provided in write parameters - no sir, I don't like it. - */ - BURN_BLOCK_MODE2_OBSCURE = 4096, - /** 2332 bytes of data supplied by lib/user - 8 bytes sub header provided in write parameters - this is the second least suck mode2, and is mandatory for - all drives to support. - */ - BURN_BLOCK_MODE2_OK = 8192, - /** SAO block sizes are based on cue sheet, so use this. */ - BURN_BLOCK_SAO = 16384 -}; - -/** Possible status' of the drive in regard to the disc in it. */ -enum burn_disc_status -{ - /** The current status is not yet known */ - BURN_DISC_UNREADY, - /** The drive holds a blank disc */ - BURN_DISC_BLANK, - /** There is no disc at all in the drive */ - BURN_DISC_EMPTY, - /** There is an incomplete disc in the drive */ - BURN_DISC_APPENDABLE, - /** There is a disc with data on it in the drive */ - BURN_DISC_FULL -}; - -/** Possible types of messages form the library. */ -enum burn_message_type -{ - /** Diagnostic/Process information. For the curious user. */ - BURN_MESSAGE_INFO, - /** A warning regarding a possible problem. The user should probably - be notified, but its not fatal. */ - BURN_MESSAGE_WARNING, - /** An error message. This usually means the current process will be - aborted, and the user should definately see these. */ - BURN_MESSAGE_ERROR -}; - -/** Possible information messages */ -enum burn_message_info -{ - BURN_INFO_FOO -}; - -/** Possible warning messages */ -enum burn_message_warning -{ - BURN_WARNING_FOO -}; - -/** Possible error messages */ -enum burn_message_error -{ - BURN_ERROR_CANCELLED -}; - -/** Possible data source return values */ -enum burn_source_status -{ - /** The source is ok */ - BURN_SOURCE_OK, - /** The source is at end of file */ - BURN_SOURCE_EOF, - /** The source is unusable */ - BURN_SOURCE_FAILED -}; - - -/** Possible busy states for a drive */ -enum burn_drive_status -{ - /** The drive is not in an operation */ - BURN_DRIVE_IDLE, - /** The library is spawning the processes to handle a pending - operation (A read/write/etc is about to start but hasn't quite - yet) */ - BURN_DRIVE_SPAWNING, - /** The drive is reading data from a disc */ - BURN_DRIVE_READING, - /** The drive is writing data to a disc */ - BURN_DRIVE_WRITING, - /** The drive is writing Lead-In */ - BURN_DRIVE_WRITING_LEADIN, - /** The drive is writing Lead-Out */ - BURN_DRIVE_WRITING_LEADOUT, - /** The drive is erasing a disc */ - BURN_DRIVE_ERASING, - /** The drive is being grabbed */ - BURN_DRIVE_GRABBING -}; - -/** Information about a track on a disc - this is from the q sub channel of the - lead-in area of a disc. The documentation here is very terse. - See a document such as mmc3 for proper information. -*/ -struct burn_toc_entry -{ - /** Session the track is in */ - unsigned char session; - /** Type of data. for this struct to be valid, it must be 1 */ - unsigned char adr; - /** Type of data in the track */ - unsigned char control; - /** Zero. Always. Really. */ - unsigned char tno; - /** Track number or special information */ - unsigned char point; - unsigned char min; - unsigned char sec; - unsigned char frame; - unsigned char zero; - /** Track start time minutes for normal tracks */ - unsigned char pmin; - /** Track start time seconds for normal tracks */ - unsigned char psec; - /** Track start time frames for normal tracks */ - unsigned char pframe; -}; - - -/** Data source for tracks */ -struct burn_source { - /** Reference count for the data source. Should be 1 when a new source - is created. Increment it to take a reference for yourself. Use - burn_source_free to destroy your reference to it. */ - int refcount; - - /** Read data from the source */ - int (*read)(struct burn_source *, - unsigned char *buffer, - int size); - - /** Read subchannel data from the source (NULL if lib generated) */ - int (*read_sub)(struct burn_source *, - unsigned char *buffer, - int size); - - /** Get the size of the source's data */ - off_t (*get_size)(struct burn_source *); - - /** Clean up the source specific data */ - void (*free_data)(struct burn_source *); - - /** Next source, for when a source runs dry and padding is disabled - THIS IS AUTOMATICALLY HANDLED, DO NOT TOUCH - */ - struct burn_source *next; - - /** Source specific data */ - void *data; -}; - - -/** Information on a drive in the system */ -struct burn_drive_info -{ - /** Name of the vendor of the drive */ - char vendor[9]; - /** Name of the drive */ - char product[17]; - /** Revision of the drive */ - char revision[5]; - /** Location of the drive in the filesystem. */ - char location[17]; - - /** Can the drive read DVD-RAM discs */ - unsigned int read_dvdram:1; - /** Can the drive read DVD-R discs */ - unsigned int read_dvdr:1; - /** Can the drive read DVD-ROM discs */ - unsigned int read_dvdrom:1; - /** Can the drive read CD-R discs */ - unsigned int read_cdr:1; - /** Can the drive read CD-RW discs */ - unsigned int read_cdrw:1; - - /** Can the drive write DVD-RAM discs */ - unsigned int write_dvdram:1; - /** Can the drive write DVD-R discs */ - unsigned int write_dvdr:1; - /** Can the drive write CD-R discs */ - unsigned int write_cdr:1; - /** Can the drive write CD-RW discs */ - unsigned int write_cdrw:1; - - /** Can the drive simulate a write */ - unsigned int write_simulate:1; - - /** Can the drive report C2 errors */ - unsigned int c2_errors:1; - - /** The size of the drive's buffer (in kilobytes) */ - int buffer_size; - /** - * The supported block types in tao mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int tao_block_types; - /** - * The supported block types in sao mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int sao_block_types; - /** - * The supported block types in raw mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int raw_block_types; - /** - * The supported block types in packet mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int packet_block_types; - - /** The value by which this drive can be indexed when using functions - in the library. This is the value to pass to all libbburn functions - that operate on a drive. */ - struct burn_drive *drive; -}; - -/** Messages from the library */ -struct burn_message -{ - /** The drive associated with the message. NULL if the error is not - related to a specific drive. */ - struct burn_drive *drive; - - /** The type of message this is. See message_type for details. */ - enum burn_message_type type; - - /** The actual message */ - union detail { - struct { - enum burn_message_info message; - } info; - struct { - enum burn_message_warning message; - } warning; - struct { - enum burn_message_error message; - } error; - } detail; -}; - -/** Operation progress report. All values are 0 based indices. - * */ -struct burn_progress { - /** The total number of sessions */ - int sessions; - /** Current session.*/ - int session; - /** The total number of tracks */ - int tracks; - /** Current track. */ - int track; - /** The total number of indices */ - int indices; - /** Curent index. */ - int index; - /** The starting logical block address */ - int start_sector; - /** The number of sector */ - int sectors; - /** The current sector being processed */ - int sector; -}; - -/** Initialize the library. - This must be called before using any other functions in the library. It - may be called more than once with no effect. - If is possible to 'restart' the library by shutting it down and - re-initializing it, though there is no good reason to do that. - @return Nonzero if the library was able to initialize; zero if - initialization failed. -*/ -int burn_initialize(void); - -/** Shutdown the library. - This should be called before exiting your application. Make sure that all - drives you have grabbed are released before calling this. -*/ -void burn_finish(void); - -/** Set the verbosity level of the library. The default value is 0, which means - that nothing is output on stderr. The more you increase this, the more - debug output should be displayed on stderr for you. - @param level The verbosity level desired. 0 for nothing, higher positive - values for more information output. -*/ -void burn_set_verbosity(int level); - -/** Returns a newly allocated burn_message structure. This message should be - freed with burn_message_free() when you are finished with it. - @return A message or NULL when there are no more messages to retrieve. -*/ -struct burn_message* burn_get_message(void); - -/** Frees a burn_message structure */ -void burn_message_free(struct burn_message *msg); - -/** Scans for drives. This function MUST be called until it returns nonzero. - No drives can be in use when this is called or it will assert. - All drive pointers are invalidated by using this function. Do NOT store - drive pointers across calls to this function or death AND pain will ensue. - When the app is done with the burn_drive_info array, it must be freed with - burn_drive_info_free() - @param drives Returns an array of drives (cdroms/burners). The returned - array should be freed when it is no longer needed, and - before calling this function again to rescan. - @param n_drives Returns the number of hardware drives in @c drives. - @return Zero while scanning is not complete; non-zero when it is finished. -*/ -int burn_drive_scan(struct burn_drive_info *drives[], - unsigned int *n_drives); -/** Frees a burn_drive_info array returned by burn_drive_scan - @param info The array to free -*/ -void burn_drive_info_free(struct burn_drive_info *info); - -/** Grab a drive. This must be done before the drive can be used (for reading, - writing, etc). It may be neccesary to call this function more than once - to grab a drive. See burn_grab for details. - @param drive The drive to grab. This is found in a returned - burn_drive_info struct. - @param load Nonzero to make the drive attempt to load a disc (close its - tray door, etc). - @return 1 if the drive has been grabbed, else 0 -*/ -int burn_drive_grab(struct burn_drive *drive, int load); - -/** Release a drive. This should not be done until the drive is no longer - busy (see burn_drive_get_status). - @param drive The drive to release. - @param eject Nonzero to make the drive eject the disc in it. -*/ -void burn_drive_release(struct burn_drive *drive, int eject); - -/** Returns what kind of disc a drive is holding. This function may need to be - called more than once to get a proper status from it. See burn_status - for details. - @param drive The drive to query for a disc. - @return The status of the drive, or what kind of disc is in it. -*/ -enum burn_disc_status burn_disc_get_status(struct burn_drive *drive); - -/** Tells whether a disc can be erased or not - @return Non-zero means erasable -*/ -int burn_disc_erasable(struct burn_drive *d); - -/** Returns the progress and status of a drive. - @param drive The drive to query busy state for. - @param p Returns the progress of the operation, NULL if you don't care - @return the current status of the drive. See also burn_drive_status. -*/ -enum burn_drive_status burn_drive_get_status(struct burn_drive *drive, - struct burn_progress *p); - -/** Creates a write_opts struct for burning to the specified drive - must be freed with burn_write_opts_free - @param drive The drive to write with - @return The write_opts -*/ -struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive); - -/** Frees a write_opts struct created with burn_write_opts_new - @param opts write_opts to free -*/ -void burn_write_opts_free(struct burn_write_opts *opts); - -/** Creates a write_opts struct for reading from the specified drive - must be freed with burn_write_opts_free - @param drive The drive to read from - @return The read_opts -*/ -struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive); - -/** Frees a read_opts struct created with burn_read_opts_new - @param opts write_opts to free -*/ -void burn_read_opts_free(struct burn_read_opts *opts); - -/** Erase a disc in the drive. The drive must be grabbed successfully BEFORE - calling this functions. Always ensure that the drive reports a status of - BURN_DISC_FULL before calling this function. An erase operation is not - cancellable, as control of the operation is passed wholly to the drive and - there is no way to interrupt it safely. - @param drive The drive with which to erase a disc. - @param fast Nonzero to do a fast erase, where only the disc's headers are - erased; zero to erase the entire disc. -*/ -void burn_disc_erase(struct burn_drive *drive, int fast); - -/** Read a disc from the drive and write it to an fd pair. The drive must be - grabbed successfully BEFORE calling this function. Always ensure that the - drive reports a status of BURN_DISC_FULL before calling this function. - @param drive The drive from which to read a disc. - @param o The options for the read operation. -*/ -void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o); - -/** Write a disc in the drive. The drive must be grabbed successfully BEFORE - calling this function. Always ensure that the drive reports a status of - BURN_DISC_BLANK or BURN_STATUS_FULL (to append a new session to the - disc) before calling this function. - @param o The options for the writing operation. - @param disc The struct burn_disc * that described the disc to be created -*/ -void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc); - -/** Cancel an operation on a drive. - This will only work when the drive's busy state is BURN_DRIVE_READING or - BURN_DRIVE_WRITING. - @param drive The drive on which to cancel the current operation. -*/ -void burn_drive_cancel(struct burn_drive *drive); - -/** Convert a minute-second-frame (MSF) value to sector count - @param m Minute component - @param s Second component - @param f Frame component - @return The sector count -*/ -int burn_msf_to_sectors(int m, int s, int f); - -/** Convert a sector count to minute-second-frame (MSF) - @param sectors The sector count - @param m Returns the minute component - @param s Returns the second component - @param f Returns the frame component -*/ -void burn_sectors_to_msf(int sectors, int *m, int *s, int *f); - -/** Convert a minute-second-frame (MSF) value to an lba - @param m Minute component - @param s Second component - @param f Frame component - @return The lba -*/ -int burn_msf_to_lba(int m, int s, int f); - -/** Convert an lba to minute-second-frame (MSF) - @param lba The lba - @param m Returns the minute component - @param s Returns the second component - @param f Returns the frame component -*/ -void burn_lba_to_msf(int lba, int *m, int *s, int *f); - -/** Create a new disc (for DAO recording)*/ -struct burn_disc *burn_disc_create(void); - -/** Delete disc and decrease the reference count on all its sessions - @param d The disc to be freed -*/ -void burn_disc_free(struct burn_disc *d); - -/** Create a new session (For SAO at once recording, or to be added to a - disc for DAO) -*/ -struct burn_session *burn_session_create(void); - -/** Free a session (and decrease reference count on all tracks inside) - @param s Session to be freed -*/ -void burn_session_free(struct burn_session *s); - -/** Add a session to a disc at a specific position, increasing the - sessions's reference count. - @param d Disc to add the session to - @param s Session to add to the disc - @param pos position to add at (BURN_POS_END is "at the end") - @return 0 for failure, 1 for success -*/ -int burn_disc_add_session(struct burn_disc *d, struct burn_session *s, - unsigned int pos); - -/** Remove a session from a disc - @param d Disc to remove session from - @param s Session pointer to find and remove -*/ -int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s); - - -/** Create a track (for TAO recording, or to put in a session) */ -struct burn_track *burn_track_create(void); - -/** Free a track - @param t Track to free -*/ -void burn_track_free(struct burn_track *t); - -/** Add a track to a session at specified position - @param s Session to add to - @param t Track to insert in session - @param pos position to add at (BURN_POS_END is "at the end") - @return 0 for failure, 1 for success -*/ -int burn_session_add_track(struct burn_session *s, struct burn_track *t, - unsigned int pos); - -/** Remove a track from a session - @param s Session to remove track from - @param t Track pointer to find and remove - @return 0 for failure, 1 for success -*/ -int burn_session_remove_track(struct burn_session *s, struct burn_track *t); - - -/** Define the data in a track - @param t the track to define - @param offset The lib will write this many 0s before start of data - @param tail The number of extra 0s to write after data - @param pad 1 means the lib should pad the last sector with 0s if the - track isn't exactly sector sized. (otherwise the lib will - begin reading from the next track) - @param mode data format (bitfield) -*/ -void burn_track_define_data(struct burn_track *t, int offset, int tail, - int pad, int mode); - -/** Set the ISRC details for a track - @param t The track to change - @param country the 2 char country code. Each character must be - only numbers or letters. - @param owner 3 char owner code. Each character must be only numbers - or letters. - @param year 2 digit year. A number in 0-99 (Yep, not Y2K friendly). - @param serial 5 digit serial number. A number in 0-99999. -*/ -void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, - unsigned char year, unsigned int serial); - -/** Disable ISRC parameters for a track - @param t The track to change -*/ -void burn_track_clear_isrc(struct burn_track *t); - -/** Hide the first track in the "pre gap" of the disc - @param s session to change - @param onoff 1 to enable hiding, 0 to disable -*/ -void burn_session_hide_first_track(struct burn_session *s, int onoff); - -/** Get the drive's disc struct - free when done - @param d drive to query - @return the disc struct -*/ -struct burn_disc *burn_drive_get_disc(struct burn_drive *d); - -/** Set the track's data source - @param t The track to set the data source for - @param s The data source to use for the contents of the track - @return An error code stating if the source is ready for use for - writing the track, or if an error occured - -*/ -enum burn_source_status burn_track_set_source(struct burn_track *t, - struct burn_source *s); - -/** Free a burn_source (decrease its refcount and maybe free it) - @param s Source to free -*/ -void burn_source_free(struct burn_source *s); - -/** Creates a data source for an image file (and maybe subcode file) */ -struct burn_source *burn_file_source_new(const char *path, - const char *subpath); - -/** Creates a data source for an image file (resp. a track) from an open - readable filedescriptor, an eventually open readable subcodes file - descriptor and eventually a fixed size in bytes. - @param datafd The source of data. - @param subfd The eventual source for subcodes. Not used if -1. - @param size The eventual fixed size of eventually both fds. - If this value is 0, the size will be determined from datafd. -*/ -struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size); - -/** Tells how long a track will be on disc */ -int burn_track_get_sectors(struct burn_track *); - - -/** Sets drive read and write speed - @param d The drive to set speed for - @param read Read speed in k/s (0 is max) - @param write Write speed in k/s (0 is max) -*/ -void burn_drive_set_speed(struct burn_drive *d, int read, int write); - -/* these are for my debugging, they will disappear */ -void burn_structure_print_disc(struct burn_disc *d); -void burn_structure_print_session(struct burn_session *s); -void burn_structure_print_track(struct burn_track *t); - -/** Sets the write type for the write_opts struct - @param opts The write opts to change - @param write_type The write type to use - @param block_type The block type to use - @return Returns 1 on success and 0 on failure. -*/ -int burn_write_opts_set_write_type(struct burn_write_opts *opts, - enum burn_write_types write_type, - int block_type); - -/** Supplies toc entries for writing - not normally required for cd mastering - @param opts The write opts to change - @param count The number of entries - @param toc_entries -*/ -void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, - int count, - struct burn_toc_entry *toc_entries); - -/** Sets the session format for a disc - @param opts The write opts to change - @param format The session format to set -*/ -void burn_write_opts_set_format(struct burn_write_opts *opts, int format); - -/** Sets the simulate value for the write_opts struct - @param opts The write opts to change - @param sim If non-zero, the drive will perform a simulation instead of a burn - @return Returns 1 on success and 0 on failure. -*/ -int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim); - -/** Controls buffer underrun prevention - @param opts The write opts to change - @param underrun_proof if non-zero, buffer underrun protection is enabled - @return Returns 1 on success and 0 on failure. -*/ -int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts, - int underrun_proof); - -/** Sets whether to use opc or not with the write_opts struct - @param opts The write opts to change - @param opc If non-zero, optical power calibration will be performed at - start of burn - -*/ -void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc); - -void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, int has_mediacatalog); - -void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned char mediacatalog[13]); - -/** Sets whether to read in raw mode or not - @param opts The read opts to change - @param raw_mode If non-zero, reading will be done in raw mode, so that everything in the data tracks on the - disc is read, including headers. -*/ -void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw_mode); - -/** Sets whether to report c2 errors or not - @param opts The read opts to change - @param c2errors If non-zero, report c2 errors. -*/ -void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors); - -/** Sets whether to read subcodes from audio tracks or not - @param opts The read opts to change - @param subcodes_audio If non-zero, read subcodes from audio tracks on the disc. -*/ -void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts, - int subcodes_audio); - -/** Sets whether to read subcodes from data tracks or not - @param opts The read opts to change - @param subcodes_data If non-zero, read subcodes from data tracks on the disc. -*/ -void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts, - int subcodes_data); - -/** Sets whether to recover errors if possible - @param opts The read opts to change - @param hardware_error_recovery If non-zero, attempt to recover errors if possible. -*/ -void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts, - int hardware_error_recovery); - -/** Sets whether to report recovered errors or not - @param opts The read opts to change - @param report_recovered_errors If non-zero, recovered errors will be reported. -*/ -void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts, - int report_recovered_errors); - -/** Sets whether blocks with unrecoverable errors should be read or not - @param opts The read opts to change - @param transfer_damaged_blocks If non-zero, blocks with unrecoverable errors will still be read. -*/ -void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts, - int transfer_damaged_blocks); - -/** Sets the number of retries to attempt when trying to correct an error - @param opts The read opts to change - @param hardware_error_retries The number of retries to attempt when correcting an error. -*/ -void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts, - unsigned char hardware_error_retries); - -/** Gets the maximum write speed for a drive - @param d Drive to query - @return Maximum write speed in K/s -*/ -int burn_drive_get_write_speed(struct burn_drive *d); - -/** Gets the maximum read speed for a drive - @param d Drive to query - @return Maximum read speed in K/s -*/ -int burn_drive_get_read_speed(struct burn_drive *d); - -/** Gets a copy of the toc_entry structure associated with a track - @param t Track to get the entry from - @param entry Struct for the library to fill out -*/ -void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry); - -/** Gets a copy of the toc_entry structure associated with a session's lead out - @param s Session to get the entry from - @param entry Struct for the library to fill out -*/ -void burn_session_get_leadout_entry(struct burn_session *s, - struct burn_toc_entry *entry); - -/** Gets an array of all the sessions for the disc - THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A SESSION - @param d Disc to get session array for - @param num Returns the number of sessions in the array - @return array of sessions -*/ -struct burn_session **burn_disc_get_sessions(struct burn_disc *d, - int *num); - -int burn_disc_get_sectors(struct burn_disc *d); - -/** Gets an array of all the tracks for a session - THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A TRACK - @param s session to get track array for - @param num Returns the number of tracks in the array - @return array of tracks -*/ -struct burn_track **burn_session_get_tracks(struct burn_session *s, - int *num); - -int burn_session_get_sectors(struct burn_session *s); - -/** Gets the mode of a track - @param track the track to query - @return the track's mode -*/ -int burn_track_get_mode(struct burn_track *track); - -/** Returns whether the first track of a session is hidden in the pregap - @param session the session to query - @return non-zero means the first track is hidden -*/ -int burn_session_get_hidefirst(struct burn_session *session); - -/** Returns the library's version in its parts - @param major The major version number - @param minor The minor version number - @param micro The micro version number -*/ -void burn_version(int *major, int *minor, int *micro); - -#ifndef DOXYGEN - -BURN_END_DECLS - -#endif - -#endif /*LIBBURN_H*/ diff --git a/libisofs/struct.c b/libisofs/struct.c deleted file mode 100755 index 1d8e388..0000000 --- a/libisofs/struct.c +++ /dev/null @@ -1,340 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -#include "struct.h" -#include "util.h" -#include -#include -#include -#include -#include - -struct struct_element { - uint8_t ch; - - int bytes; /* The number of bytes in the value to convert - * from/to. */ - uint8_t end; /* The endianness specifier. */ - int mul; /* The number of values to convert. */ - - union { /* Pointer to the value. */ - uint8_t *val8; - uint16_t *val16; - uint32_t *val32; - time_t *time; - } val; -}; - -/* check if a character is a valid endian-ness specifier */ -#define isend(a) ((a) == '=' || (a) == '<' || (a) == '>') - -static int iso_struct_element_make(struct struct_element *elem, - int mul, - char end, - char ch) -{ - if (!end) { -#ifdef WORDS_BIGENDIAN - elem->end = '>'; /* default endianness is native */ -#else - elem->end = '<'; -#endif - } else { - elem->end = end; - } - - elem->ch = ch; - elem->mul = mul; - elem->val.val8 = NULL; - switch(toupper(ch)) { - case 'X': - case 'B': - elem->bytes = 1; - break; - case 'H': - elem->bytes = 2; - break; - case 'L': - elem->bytes = 4; - break; - case 'S': - elem->bytes = 7; - elem->end = '<'; - break; - case 'T': - elem->bytes = 17; - elem->end = '<'; - break; - default: - elem->bytes = -1; - break; - } - return elem->bytes * elem->mul * ((elem->end == '=') ? 2 : 1); -} - -static int iso_struct_element_make_v(struct struct_element *elem, - va_list *ap) -{ - int mul = va_arg(*ap, int); - int end = va_arg(*ap, int); - int ch = va_arg(*ap, int); - return iso_struct_element_make(elem, mul, end, ch); -} - -static int iso_struct_element_parse(const char **ffmt, - struct struct_element *elem) -{ - off_t pos; - const char *fmt = *ffmt; - int mul; - char end = 0; - - mul = 1; - for (pos=0; isdigit(fmt[pos]) || isend(fmt[pos]); pos++) { - if (isdigit(fmt[pos])) { - mul = atoi( fmt + pos ); - while (isdigit(fmt[pos+1])) pos++; - } else { - end = fmt[pos]; - } - } - - (*ffmt) += pos + 1; - - return iso_struct_element_make(elem, mul, end, fmt[pos]); -} - -/* read a single integer from data[i] to elem[i], interpreting the endian-ness - * and offset appropriately. */ -static uint32_t iso_struct_element_read_int(struct struct_element *elem, - const uint8_t *data, - int i) -{ - uint32_t el; - - switch(elem->end) { - case '>': - el = iso_read_msb(data + i*elem->bytes, elem->bytes); - break; - case '<': - el = iso_read_lsb(data + i*elem->bytes, elem->bytes); - break; - case '=': - el = iso_read_bb(data + i*elem->bytes*2, elem->bytes); - } - - switch(elem->bytes) { - case 1: - elem->val.val8[i] = el; - break; - case 2: - elem->val.val16[i] = el; - break; - case 4: - elem->val.val32[i] = el; - break; - } - - return el; -} - -/* write a single integer from elem[i] to data[i]. */ -static uint32_t iso_struct_element_write1(struct struct_element *elem, - uint8_t *data, - int i) -{ - uint32_t el; - - switch(elem->bytes) { - case 1: - el = elem->val.val8[i]; - break; - case 2: - el = elem->val.val16[i]; - break; - case 4: - el = elem->val.val32[i]; - break; - } - - switch(elem->end) { - case '>': - iso_msb(data + i*elem->bytes, el, elem->bytes); - break; - case '<': - iso_lsb(data + i*elem->bytes, el, elem->bytes); - break; - case '=': - iso_bb(data + i*elem->bytes*2, el, elem->bytes); - } - - return el; -} - -static int iso_struct_element_read(struct struct_element *elem, - const uint8_t *data) -{ - int size = elem->bytes * ((elem->end == '=') ? 2 : 1); - int i; - - if (elem->ch == 'x') { - return size * elem->mul; - } - - for (i=0; imul; i++) { - switch(toupper(elem->ch)) { - case 'S': - /* - elem->val.time[i] = iso_datetime_read_7(&data[i*7]); - */ - break; - case 'T': - /* - elem->val.time[i] = iso_datetime_read_17(&data[i*17]); - */ - break; - default: - iso_struct_element_read_int(elem, data, i); - } - } - - return size * elem->mul; -} - -static int iso_struct_element_write(struct struct_element *elem, - uint8_t *data) -{ - int size = elem->bytes * ((elem->end == '=') ? 2 : 1); - int i; - uint32_t ret; - - if (elem->ch == 'x') { - return size*elem->mul; - } - - for (i=0; imul; i++) { - switch(toupper(elem->ch)) { - case 'S': - iso_datetime_7(&data[i*7], elem->val.time[i]); - ret = elem->val.time[i]; - break; - case 'T': - iso_datetime_17(&data[i*17], elem->val.time[i]); - ret = elem->val.time[i]; - break; - default: - ret = iso_struct_element_write1(elem, data, i); - break; - } - - if (islower(elem->ch) && ret == 0) { - memset(data + size*i, 0, size*(elem->mul-i)); - break; - } - } - - return size * elem->mul; -} - -int iso_struct_unpack(const char *fmt, const uint8_t *data, ...) -{ - int num_conv; - int ret; - va_list ap; - struct struct_element elem; - off_t off; - - va_start(ap, data); - num_conv = 0; - off = 0; - while(*fmt) { - ret = iso_struct_element_parse(&fmt, &elem); - if (ret < 0) { - va_end(ap); - return -1; - } - if (elem.ch != 'x') { - elem.val.val8 = va_arg(ap, void*); - } - off += iso_struct_element_read(&elem, data + off); - num_conv++; - } - - va_end(ap); - return num_conv; -} - -int iso_struct_pack(const char *fmt, uint8_t *data, ...) -{ - int num_conv; - int ret; - va_list ap; - struct struct_element elem; - off_t off; - - va_start(ap, data); - num_conv = 0; - off = 0; - while(*fmt) { - ret = iso_struct_element_parse(&fmt, &elem); - if (ret < 0) { - va_end(ap); - return -1; - } - if (elem.ch != 'x') { - elem.val.val8 = va_arg(ap, void*); - } - off += iso_struct_element_write(&elem, data + off); - num_conv++; - } - - va_end(ap); - return num_conv; -} - -int iso_struct_pack_long(uint8_t *data, ...) -{ - int num_conv; - int ret; - int i, j; - va_list ap; - struct struct_element *elem = NULL; - off_t off; - - va_start(ap, data); - num_conv = 0; - off = 0; - - elem = calloc(1, sizeof(struct struct_element)); - i=0; - while ((ret = iso_struct_element_make_v(&elem[i], &ap) > 0)) { - elem = realloc(elem, (++i + 1) * sizeof(struct struct_element)); - } - for (j=0; j big-endian - * = both-endian (ie. according to ecma119 7.2.3 or 7.3.3) - * - * Each conversion specifier may also be preceded by a length specifier. For - * example, "<5L" specifies an array of 5 little-endian 32-bit integers. Note - * that "=L" takes 8 bytes while "L" each take 4. - * - * You can use a lower-case conversion specifier instead of an upper-case one - * to signify that the (multi-element) conversion should stop when a zero is - * reached. This is useful for writing out NULL-terminated strings. Note that - * this has no effect when unpacking data from a struct. - */ - -#ifndef __ISO_STRUCT -#define __ISO_STRUCT - -#include - -/** - * Unpack a struct into its components. The list of components is a list of - * pointers to the variables to write. - * - * For example: - * uint8_t byte1, byte2; - * uint16_t uint; - * iso_struct_unpack("BB=H", data, &byte1, &byte2, &uint); - * - * \return The number of conversions performed, or -1 on error. - */ -int iso_struct_unpack(const char *fmt, const uint8_t *data, ...); - -/** - * Write out a struct from its components. The list of components is a list of - * pointers to the variables to write and the buffer to which to write - * is assumed to be large - * enough to take the data. - * - * \return The number of conversions performed, or -1 on error. - */ -int iso_struct_pack(const char *fmt, uint8_t *data, ...); - -/** - * Achieves the same effect as iso_struct_pack(), but the format is passed as - * a sequence of (int, char, char) triples. This list is terminated by - * (0, 0, 0) and the list of parameters follows. - * - * Example: iso_struct_pack_long(data, 4, '=', 'H', 0, 0, 0, &val) is the same - * as iso_struct_pack("4=H", 0, 0, 0, &val) - */ -int iso_struct_pack_long(uint8_t *data, ...); - -/** - * Calculate the size of a given format string. - * - * \return The sum of the length of all formats in the string, in bytes. Return - * -1 on error. - */ -int iso_struct_calcsize(const char *fmt); - -#endif diff --git a/libisofs/test.c b/libisofs/test.c deleted file mode 100755 index ff74099..0000000 --- a/libisofs/test.c +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set ts=8 sts=8 sw=8 noet : */ - -#define _GNU_SOURCE - -#include "libisofs/libisofs.h" -#include "libburn/libburn.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SECSIZE 2048 - -const char * const optstring = "JRL:h"; -extern char *optarg; -extern int optind; - -void usage() -{ - printf("test [OPTIONS] DIRECTORY OUTPUT\n"); -} - -void help() -{ - printf( -"Options:\n" -" -J Add Joliet support\n" -" -R Add Rock Ridge support\n" -" -L Set the ISO level (1 or 2)\n" -" -h Print this message\n" -); -} - -int main(int argc, char **argv) -{ - struct iso_volset *volset; - struct iso_volume *volume; - struct burn_source *src; - unsigned char buf[2048]; - FILE *fd; - int c; - int level=1, flags=0; - DIR *dir; - struct dirent *ent; - - while ((c = getopt(argc, argv, optstring)) != -1) { - switch(c) { - case 'h': - usage(); - help(); - exit(0); - break; - case 'J': - flags |= ECMA119_JOLIET; - break; - case 'R': - flags |= ECMA119_ROCKRIDGE; - break; - case 'L': - level = atoi(optarg); - break; - case '?': - usage(); - exit(1); - break; - } - } - - if (argc < 2) { - printf ("must pass directory to build iso from\n"); - usage(); - return 1; - } - if (argc < 3) { - printf ("must supply output file\n"); - usage(); - return 1; - } - fd = fopen(argv[optind+1], "w"); - if (!fd) { - perror("error opening output file"); - exit(1); - } - - volume = iso_volume_new( "VOLID", "PUBID", "PREPID" ); - volset = iso_volset_new( volume, "VOLSETID" ); - dir = opendir(argv[optind]); - if (!dir) { - perror("error opening input directory"); - exit(1); - } - - while ( (ent = readdir(dir)) ) { - struct stat st; - char *name; - - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { - continue; - } - - name = malloc(strlen(argv[optind]) + strlen(ent->d_name) + 2); - strcpy(name, argv[optind]); - strcat(name, "/"); - strcat(name, ent->d_name); - if (lstat(name, &st) == -1) { - fprintf(stderr, "error opening file %s: %s\n", - name, strerror(errno)); - exit(1); - } - - if (S_ISDIR(st.st_mode)) { - iso_tree_radd_dir(iso_volume_get_root(volume), name); - } else { - iso_tree_add_file(iso_volume_get_root(volume), name); - } - free(name); - } - - iso_tree_print(iso_volume_get_root(volume), 0); - - src = iso_source_new_ecma119(volset, 0, level, flags); - - while (src->read(src, buf, 2048) == 2048) { - fwrite(buf, 1, 2048, fd); - } - fclose(fd); - - return 0; -} diff --git a/libisofs/writer.c b/libisofs/writer.c deleted file mode 100755 index 2ed2e19..0000000 --- a/libisofs/writer.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include "writer.h" -#include "util.h" -#include "volume.h" -#include -#include -#include -#include -#include - -#define APPLICATION_ID "LIBBURN SUITE (C) 2006 M.DANIC/L.BIDDELL/A.NARAYANAN" - -enum DirType { - DIR_TYPE_SELF, - DIR_TYPE_PARENT, - DIR_TYPE_NORMAL, - DIR_TYPE_ROOT /* the dir record in the volume descriptor */ -}; - -enum SUSPType { - SUSP_TYPE_SP = 1 << 0, - SUSP_TYPE_CE = 1 << 1, - SUSP_TYPE_NM = 1 << 2 -}; - -static int get_path_table_size(struct iso_tree_dir **ddir); -static void iso_next_state(struct iso_write_target *target); -static int iso_source_get_size(struct burn_source *src); -static void iso_source_free(struct burn_source *src); -static void iso_target_layout(struct iso_write_target *target); -static void iso_dir_layout(struct iso_write_target *target, - struct iso_tree_dir **dir); -static void iso_file_layout(struct iso_write_target *target, - struct iso_tree_dir **dir); -static int iso_write_system_area(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err); -static int iso_write_pri_volume(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err); -static int iso_write_volume_terminator(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err); -static int write_path_table_record(unsigned char *buffer, - struct iso_tree_dir **ddir, int *position, - int lsb); -static int write_path_table_records(unsigned char *buffer, - struct iso_tree_dir **ddir, - int level, int *position, int lsb); -static int iso_write_path_table(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err, int lsb); -static int iso_write_dir_record(struct iso_write_target *target, - unsigned char *buffer, - struct iso_tree_dir **dir, enum DirType type); -static int iso_write_file_record(struct iso_write_target *t, - unsigned char *buffer, - struct iso_tree_file **ffile, - enum DirType type); -static void iso_write_file_id(unsigned char *buf, int size, - struct iso_tree_file **f); -static struct iso_tree_dir **find_dir_at_block(struct iso_tree_dir **ddir, - int block); -static struct iso_tree_file **find_file_at_block(struct iso_tree_dir **ddir, - int block); -static void write_child_records(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err, - struct iso_tree_dir *dir); -static int iso_write_dir_records(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err); -static int get_directory_record_length(const char *isoname); -static int iso_write_er_area(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err); -static int copy_file_to_buffer(FILE * fd, unsigned char *buffer, int length); -static int iso_write_files(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err); - -int get_path_table_size(struct iso_tree_dir **ddir) -{ - const char *isoname; - int i, size = 0; - struct iso_tree_dir *dir = *ddir; - - assert(dir); - - isoname = iso_tree_dir_get_name(ddir, ISO_FILE_NAME_ISO); - - if (isoname) { - /* a path table record is 8 bytes + the length of the - directory identifier */ - size += (8 + strlen(isoname)); - } else { - /* if iso_tree_dir_get_name is NULL, this is the root dir and - will have a path record of 10 bytes */ - size += 10; - } - - /* pad the field if the directory identifier is an odd number of - bytes */ - if (size % 2) - ++size; - - for (i = 0; i < dir->nchildren; i++) - size += get_path_table_size(dir->children[i].me); - - return size; -} - -struct burn_source *iso_source_new(struct iso_volumeset *volumeset, int volume) -{ - struct burn_source *src; - struct iso_write_target *t; - - if (!volumeset) - return NULL; - if (volume >= volumeset->volumeset_size) - return NULL; - - t = malloc(sizeof(struct iso_write_target)); - - iso_tree_sort(volumeset->root); - - t->volset = volumeset; - t->volset->refcount++; - t->volume = volume; - t->now = time(NULL); - t->phys_sector_size = 2048; - iso_target_layout(t); - - t->state = ISO_WRITE_BEFORE; - iso_next_state(t); /* prepare for the first state */ - - src = malloc(sizeof(struct burn_source)); - src->refcount = 1; - src->free_data = iso_source_free; - src->read = iso_source_generate; - src->read_sub = NULL; - src->get_size = iso_source_get_size; - src->data = t; - - return src; -} - -void iso_source_free(struct burn_source *src) -{ - struct iso_write_target *target = src->data; - - assert(src->read == iso_source_generate && - src->read_sub == NULL && src->get_size == iso_source_get_size); - - iso_volumeset_free(target->volset); - free(target); - - return; -} - -static int get_susp_length(struct RRInfo *info, enum SUSPType fields) -{ - int len = 0; - - if (fields & SUSP_TYPE_SP) - len += 7; - if (fields & SUSP_TYPE_CE) - len += 28; - if (info->px[0] != 0) - len += info->px[2]; - if (info->tf) - len += info->tf[2]; - if (info->nm && (fields & SUSP_TYPE_NM)) - len += info->nm[2]; - - return len; -} - -int get_directory_record_length(const char *isoname) -{ - int size; - - /* size = the length of the filename + 33 bytes (9.1) */ - size = 33 + strlen(isoname); - /* if size is odd, pad it with a single byte (9.1.12) */ - if (size % 2) - ++size; - - return size; -} - -/* fill in the 'logical_block' and 'size' values for each directory */ -void iso_dir_layout(struct iso_write_target *target, - struct iso_tree_dir **ddir) -{ - int i, length, sectors, rr; - const char *name; - struct iso_tree_dir *dir = *ddir; - - rr = iso_volumeset_get_rr(target->volset); - /* Each directory record starts with a record pointing to itself - and another pointing to its parent; combined, they are 68 bytes. - If RR is in use, calculate the susp length as well. */ - length = 68; - if (rr) { - /* if this is the root dir recored, we need to include the - length of the CE and SP fields */ - if (ddir == target->volset->root) { - length += get_susp_length(&dir->rr, SUSP_TYPE_SP | SUSP_TYPE_CE); - length += get_susp_length(&dir->rr, 0); - } else { - length += get_susp_length(&dir->rr, 0); - length += get_susp_length(&dir->parent->rr, 0); - } - } - - /* calculate the length of this directory */ - name = iso_tree_dir_get_name(ddir, ISO_FILE_NAME_ISO); - if (name) - length += get_directory_record_length(name); - else - length += get_directory_record_length(""); - if (rr) - length += get_susp_length(&dir->rr, SUSP_TYPE_NM); - - for (i = 0; i < dir->nfiles; ++i) { - name = iso_tree_file_get_name(dir->files[i].me, - ISO_FILE_NAME_ISO); - length += get_directory_record_length(name); - if (rr) - length += get_susp_length(&dir->files[i].rr, SUSP_TYPE_NM); - } - - for (i = 0; i < dir->nchildren; ++i) { - name = iso_tree_dir_get_name(dir->children[i].me, - ISO_FILE_NAME_ISO); - length += get_directory_record_length(name); - if (rr) - length += get_susp_length(&dir->children[i].rr, SUSP_TYPE_NM); - } - - /* dir->size is the number of bytes needed to hold the directory - record for each file and subdirectory of 'dir', padded to use up - all of the bytes of a physical sector. */ - sectors = length / target->phys_sector_size; - if (length % target->phys_sector_size) - sectors++; - dir->size = sectors * target->phys_sector_size; - dir->logical_block = target->logical_block; - target->logical_block += sectors; - - /* now calculate the lengths of its children */ - for (i = 0; i < dir->nchildren; ++i) { - iso_dir_layout(target, dir->children[i].me); - } - - return; -} - -/* fill in the 'logical_block' and 'size' values for each file */ -void iso_file_layout(struct iso_write_target *target, - struct iso_tree_dir **ddir) -{ - int i, sectors; - struct iso_tree_dir *dir = *ddir; - - for (i = 0; i < dir->nfiles; ++i) { - dir->files[i].logical_block = target->logical_block; - sectors = dir->files[i].size / target->phys_sector_size; - if (dir->files[i].size % target->phys_sector_size) - sectors++; - /* ensure we move past this logical block if the file was empty */ - else if (!dir->files[i].size) - sectors++; - target->logical_block += sectors; - } - - for (i = 0; i < dir->nchildren; ++i) - iso_file_layout(target, dir->children[i].me); - - return; -} - -void iso_target_layout(struct iso_write_target *target) -{ - /* logical block numbering starts at 1, not 0 */ - target->logical_block = 1; - /* system area */ - target->logical_block += 16; - /* primary volume descriptor */ - target->logical_block++; - /* volume descriptor terminator */ - target->logical_block++; - - target->logical_block_size = 2048; - target->path_table_size = get_path_table_size(target->volset->root); - /* put a 1-block buffer before each path table */ - target->l_path_table_pos = 19; - target->logical_block += 2; - target->total_size += 2 * target->phys_sector_size; - /* put a 1-block buffer before each path table */ - target->m_path_table_pos = 21; - target->logical_block += 2; - - iso_dir_layout(target, target->volset->root); - /* iso_write_dir_records() puts a 1-block buffer after the directory - section, so increment this accordingly */ - target->logical_block++; - - /* the ce area only takes up one block */ - target->susp_er_pos = target->logical_block++; - - iso_file_layout(target, target->volset->root); - - target->volume_space_size = target->logical_block; - target->total_size = target->volume_space_size * target->phys_sector_size; - - return; -} - -int iso_source_get_size(struct burn_source *src) -{ - struct iso_write_target *target = src->data; - - assert(src->read == iso_source_generate && - src->read_sub == NULL && src->get_size == iso_source_get_size); - - return target->total_size; -} - -void iso_next_state(struct iso_write_target *target) -{ - switch (++target->state) { - case ISO_WRITE_BEFORE: - /* this should never occur */ - assert(0); - break; - case ISO_WRITE_SYSTEM_AREA: - target->state_data.system_area.sectors = 0; - break; - case ISO_WRITE_PRI_VOL_DESC: - target->total_size = target->logical_block - 1; - break; - case ISO_WRITE_VOL_DESC_TERMINATOR: - break; - case ISO_WRITE_L_PATH_TABLE: - target->state_data.path_tables.sectors = 0; - break; - case ISO_WRITE_M_PATH_TABLE: - target->state_data.path_tables.sectors = 0; - break; - case ISO_WRITE_DIR_RECORDS: - target->state_data.dir_records.sectors = 0; - break; - case ISO_WRITE_ER_AREA: - break; - case ISO_WRITE_FILES: - target->state_data.dir_records.sectors = 0; - break; - case ISO_WRITE_DONE: - break; - } - - return; -} - -int iso_source_generate(struct burn_source *src, unsigned char *buffer, - int size) -{ - int next = 0; - enum burn_source_status err = BURN_SOURCE_OK; - struct iso_write_target *target = src->data; - - assert(src->read == iso_source_generate && - src->read_sub == NULL && src->get_size == iso_source_get_size); - - /* make sure the app didn't fuck up badly. */ - if (size != target->phys_sector_size) - return BURN_SOURCE_FAILED; /* XXX better code */ - - /* make sure 'buffer' doesn't have anything in it */ - memset(buffer, 0, size); - - switch (target->state) { - case ISO_WRITE_BEFORE: - /* this should never occur */ - assert(0); - case ISO_WRITE_SYSTEM_AREA: - next = iso_write_system_area(target, buffer, &err); - break; - case ISO_WRITE_PRI_VOL_DESC: - /* set target->logical_block to the logical block containing - the root directory record */ - target->logical_block = 23; - next = iso_write_pri_volume(target, buffer, &err); - break; - case ISO_WRITE_VOL_DESC_TERMINATOR: - next = iso_write_volume_terminator(target, buffer, &err); - break; - case ISO_WRITE_L_PATH_TABLE: - next = iso_write_path_table(target, buffer, &err, 1); - break; - case ISO_WRITE_M_PATH_TABLE: - next = iso_write_path_table(target, buffer, &err, 0); - break; - case ISO_WRITE_DIR_RECORDS: - next = iso_write_dir_records(target, buffer, &err); - break; - case ISO_WRITE_ER_AREA: - next = iso_write_er_area(target, buffer, &err); - break; - case ISO_WRITE_FILES: - next = iso_write_files(target, buffer, &err); - break; - case ISO_WRITE_DONE: - err = BURN_SOURCE_EOF; - break; - } - - if (next) - iso_next_state(target); - - return err; -} - -/* writes 16 sectors of '0' */ -int iso_write_system_area(struct iso_write_target *t, - unsigned char *buffer, enum burn_source_status *err) -{ - struct iso_state_system_area *state = &t->state_data.system_area; - - memset(buffer, 0, t->phys_sector_size); - return (++state->sectors == 16); -} - -/* writes the primary volume descriptor */ -int iso_write_pri_volume(struct iso_write_target *t, - unsigned char *buffer, enum burn_source_status *err) -{ - /* volume descriptor type (8.4.1) */ - buffer[0] = 1; - /* standard identifier (8.4.2) */ - memcpy(&buffer[1], "CD001", 5); - /* volume descriptor version (8.4.3) */ - buffer[6] = 1; - /* unused field (8.4.4) */ - buffer[7] = 0; - /* system identifier (8.4.5) */ - /* XXX mkisofs puts "LINUX" here */ - memset(&buffer[8], ' ', 32); - /* volume identifier (8.4.6) */ - iso_d_strcpy(&buffer[40], 32, t->volset->volume_id[t->volume]); - /* unused field (8.4.7) */ - memset(&buffer[72], 0, 8); - /* volume space size (8.4.8) */ - iso_bb(&buffer[80], t->volume_space_size, 4); - /* unused field (8.4.9) */ - memset(&buffer[88], 0, 32); - /* volume set size (8.4.10) */ - iso_bb(&buffer[120], t->volset->volumeset_size, 2); - /* volume sequence number (8.4.11) */ - iso_bb(&buffer[124], t->volume + 1, 2); - /* logical block size (8.4.12) */ - iso_bb(&buffer[128], t->logical_block_size, 2); - /* path table size (8.4.13) */ - iso_bb(&buffer[132], t->path_table_size, 4); - /* location of occurance of type l path table (8.4.14) */ - iso_lsb(&buffer[140], t->l_path_table_pos, 4); - /* location of optional occurance of type l path table (8.4.15) */ - iso_lsb(&buffer[144], 0, 4); - /* location of occurance of type m path table (8.4.16) */ - iso_msb(&buffer[148], t->m_path_table_pos, 4); - /* location of optional occurance of type m path table (8.4.17) */ - iso_msb(&buffer[152], 0, 4); - /* directory record for root directory (8.4.18) */ - iso_write_dir_record(t, &buffer[156], t->volset->root, DIR_TYPE_ROOT); - /* volume set identifier (8.4.19) */ - iso_d_strcpy(&buffer[190], 128, t->volset->volumeset_id); - /* publisher identifier (8.4.20) */ - iso_a_strcpy(&buffer[318], 128, t->volset->publisher_id); - /* data preparer identifier (8.4.21) */ - iso_a_strcpy(&buffer[446], 128, t->volset->data_preparer_id); - /* application identifier (8.4.22) */ - iso_a_strcpy(&buffer[574], 128, APPLICATION_ID); - /* copyright file identifier (8.4.23) */ - iso_write_file_id(&buffer[702], 37, t->volset->copyright_file); - /* abstract file identifier (8.4.24) */ - iso_write_file_id(&buffer[739], 37, t->volset->abstract_file); - /* bibliographic file identifier (8.4.25) */ - iso_write_file_id(&buffer[776], 37, t->volset->bibliographic_file); - /* volume creation date and time (8.4.26) */ - /* XXX is this different for multisession? */ - iso_datetime_17(&buffer[813], t->now); - /* volume modification date and time (8.4.27) */ - iso_datetime_17(&buffer[830], t->now); - /* volume expiration date and time (8.4.28) */ - iso_datetime_17(&buffer[847], t->volset->expiration_time); - /* volume effective date and time (8.4.29) */ - iso_datetime_17(&buffer[864], - t->volset->effective_time == (time_t) - 1 ? - t->now : t->volset->effective_time); - /* file structure version (8.4.30) */ - buffer[881] = 1; - /* reserved for future standardization (8.4.31) */ - buffer[882] = 0; - /* application use (8.4.32) */ - /* XXX put something in here? does mkisofs? */ - memset(&buffer[883], 0, 512); - /* reserved for future standardization (8.4.33) */ - memset(&buffer[1395], 0, 653); - - return 1; -} - -void iso_write_file_id(unsigned char *buf, int size, struct iso_tree_file **f) -{ - if (!f) - memset(buf, ' ', size); - else - iso_filecpy(buf, size, - iso_tree_file_get_name(f, ISO_FILE_NAME_ISO), - (*f)->version); -} - -/* write the contents of the SP System Use Entry */ -/* SUSP-112 5.3 */ -static void fill_sp_sue(unsigned char *sp) -{ - sp[0] = 'S'; - sp[1] = 'P'; - sp[2] = 7; - sp[3] = 1; - sp[4] = 190; - sp[5] = 239; - sp[6] = 0; - - return; -} - -/* write the contents of the CE System Use Entry */ -/* SUSP-112 5.1 */ -static void fill_ce_sue(struct iso_write_target *t, - unsigned char *ce) -{ - ce[0] = 'C'; - ce[1] = 'E'; - ce[2] = 28; - ce[3] = 1; - iso_bb(&ce[4], 0, 4); - iso_bb(&ce[12], t->susp_er_pos, 4); - /* the length of the rock-ridge er area is 185, and that's all we - * store in the ce area right now */ - iso_bb(&ce[20], 185, 4); - - return; -} - -/* return a string containing the System Use Sharing Protocol information - * for 'ddir'. */ -static unsigned char* write_susp_info(struct iso_write_target *t, - struct RRInfo *rr, - enum SUSPType type, - int *len) -{ - unsigned char *buffer = NULL; - - *len = 0; - - /* check to see if susp is even needed (right now, only the rock-ridge - * extensions use it). */ - if (iso_volumeset_get_rr(t->volset)) { - int char_size, size = 0, offset = 0; - int len_sp, len_ce, len_px, len_tf, len_nm; - unsigned char *sp, *ce; - - char_size = sizeof (unsigned char *); - len_sp = len_ce = 0; - - if (type & SUSP_TYPE_SP) { - len_sp = 7; /* 7 bytes for the SP System Use Entry */ - sp = malloc(char_size * len_sp); - fill_sp_sue(sp); - size += len_sp; - } else { - sp = NULL; - } - - if (type & SUSP_TYPE_CE) { - len_ce = 28; /* 28 bytes for the CE System Use Entry */ - ce = malloc(char_size * len_ce); - fill_ce_sue(t, ce); - size += len_ce; - } else { - ce = NULL; - } - - if (rr->px[0] != 0) { - /* the 3rd byte of the PX field holds its length */ - len_px = rr->px[2]; - size += len_px; - } else { - len_px = 0; - } - - if (rr->tf) { - /* the 3rd byte of the TF field holds its length */ - len_tf = rr->tf[2]; - size += len_tf; - } else { - len_tf = 0; - } - - if ((type & SUSP_TYPE_NM) && rr->nm) { - /* the 3rd byte of the NM field holds its length */ - len_nm = rr->nm[2]; - size += len_nm; - } else { - len_nm = 0; - } - - /* fill 'buffer' with the susp info */ - buffer = malloc(char_size * (size + 1)); - if (sp) { - memcpy(buffer + offset, sp, len_sp); - offset += len_sp; - } - if (ce) { - memcpy(buffer + offset, ce, len_ce); - offset += len_ce; - } - if (len_px) { - memcpy(buffer + offset, rr->px, len_px); - offset += len_px; - } - if (len_tf) { - memcpy(buffer + offset, rr->tf, len_tf); - offset += len_tf; - } - if (len_nm) { - memcpy(buffer + offset, rr->nm, len_nm); - offset += len_nm; - } - buffer[offset] = '\0'; - *len = offset; - } - - return buffer; -} - -int iso_write_dir_record(struct iso_write_target *t, - unsigned char *buffer, - struct iso_tree_dir **ddir, enum DirType type) -{ - int len_fi, len_susp, sz; - const char *fi = NULL; - unsigned char *susp; /* the contents, if any, of the "system use sharing protocol" buffer */ - struct iso_tree_dir *dir = *ddir; - - if (type != DIR_TYPE_NORMAL) - len_fi = 1; - else { - assert(dir->parent); - fi = iso_tree_dir_get_name(ddir, ISO_FILE_NAME_ISO); - len_fi = strlen(fi); - } - - /* determine if this is the root directory record */ - if ((*t->volset->root == dir) && (type == DIR_TYPE_SELF)) - susp = write_susp_info(t, &dir->rr, SUSP_TYPE_SP | SUSP_TYPE_CE, &len_susp); - /* determine if this a SELF or PARENT directory record */ - else if (type != DIR_TYPE_NORMAL) - susp = write_susp_info(t, &dir->rr, 0, &len_susp); - /* none of the above == a normal directory record */ - else - susp = write_susp_info(t, &dir->rr, SUSP_TYPE_NM, &len_susp); - - sz = 33 + len_fi + len_susp + !(len_fi % 2); - - /* length of directory record (9.1.1) */ - buffer[0] = sz; - /* extended attribute record length (9.1.2) */ - buffer[1] = 0; /* XXX allow for extended attribute records */ - /* location of extent (9.1.3) */ - iso_bb(&buffer[2], dir->logical_block, 4); - /* data length (9.1.4) */ - iso_bb(&buffer[10], dir->size, 4); - /* recording date and time (9.1.5) */ - iso_datetime_7(&buffer[18], t->now); - /* file flags (9.1.6) */ - buffer[25] = ISO_FILE_FLAG_DIRECTORY; - /* file unit size (9.1.7) */ - buffer[26] = 0; /* XXX support this shit? */ - /* interleave gap size (9.1.8) */ - buffer[27] = 0; /* XXX support this shit? */ - /* volume sequence number (9.1.9) */ - iso_bb(&buffer[28], dir->volume + 1, 2); - /* length of file identifier (9.1.10) */ - buffer[32] = len_fi; - /* file identifier */ - switch (type) { - case DIR_TYPE_ROOT: - case DIR_TYPE_SELF: - buffer[33] = 0; - break; - case DIR_TYPE_PARENT: - buffer[33] = 1; - break; - case DIR_TYPE_NORMAL: - iso_d_strcpy(&buffer[33], len_fi, fi); - break; - } - if (!(len_fi % 2)) - buffer[33 + len_fi] = 0; - /* system use sharing protocol */ - if (susp) - { - int offset; - if (!(len_fi % 2)) - offset = 34; - else - offset = 33; - memcpy(&buffer[offset + len_fi], susp, len_susp); - } - - return sz; -} - -/* write the file record as per (9.1) */ -int iso_write_file_record(struct iso_write_target *t, - unsigned char *buffer, - struct iso_tree_file **ffile, enum DirType type) -{ - int len_fi, len_susp; - const char *fi = NULL; - unsigned char *susp; /* the contents, if any, of the "system use sharing protocol" buffer */ - int sz; - struct iso_tree_file *file = *ffile; - - if (type != DIR_TYPE_NORMAL) - len_fi = 1; - else { - fi = iso_tree_file_get_name(ffile, ISO_FILE_NAME_ISO); - len_fi = strlen(fi); - } - - susp = write_susp_info(t, &file->rr, SUSP_TYPE_NM, &len_susp); - - sz = 33 + len_fi + len_susp + !(len_fi % 2); - - /* length of directory record (9.1.1) */ - buffer[0] = sz; - /* extended attribute record length (9.1.2) */ - buffer[1] = 0; /* XXX allow for extended attribute records */ - /* location of extent (9.1.3) */ - iso_bb(&buffer[2], file->logical_block, 4); - /* data length (9.1.4) */ - iso_bb(&buffer[10], file->size, 4); - /* recording date and time (9.1.5) */ - iso_datetime_7(&buffer[18], t->now); - /* file flags (9.1.6) */ - buffer[25] = ISO_FILE_FLAG_NORMAL; - /* file unit size (9.1.7) */ - buffer[26] = 0; /* XXX support this shit? */ - /* interleave gap size (9.1.8) */ - buffer[27] = 0; /* XXX support this shit? */ - /* volume sequence number (9.1.9) */ - iso_bb(&buffer[28], file->volume + 1, 2); - /* length of file identifier (9.1.10) */ - buffer[32] = len_fi; - /* file identifier */ - switch (type) { - case DIR_TYPE_ROOT: - case DIR_TYPE_SELF: - buffer[33] = 0; - break; - case DIR_TYPE_PARENT: - buffer[33] = 1; - break; - case DIR_TYPE_NORMAL: - memcpy(&buffer[33], fi, len_fi); - break; - } - if (!(len_fi % 2)) - buffer[33 + len_fi] = 0; - /* system use sharing protocol */ - if (susp) - { - int offset; - if (!(len_fi % 2)) - offset = 34; - else - offset = 33; - memcpy(&buffer[offset + len_fi], susp, len_susp); - } - - return sz; -} - -/* writes the volume descriptor set terminator */ -int iso_write_volume_terminator(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err) -{ - /* volume descriptor type (8.3.1) */ - buffer[0] = 255; - /* standard identifier (8.3.2) */ - memcpy(&buffer[1], "CD001", 5); - /* volume descriptor version (8.3.3) */ - buffer[6] = 1; - /* reserved for future standardization (8.3.4) */ - memset(&buffer[7], 0, 2041); - - return 1; -} - -/* write the path record for 'ddir' into 'buffer' */ -int write_path_table_record(unsigned char *buffer, - struct iso_tree_dir **ddir, int *position, int lsb) -{ - int len, bytes_written; - short parent_position; - const char *name; - struct iso_tree_dir *dir = *ddir; - - /* set the position in the path table of this directory */ - dir->position = *position; - /* increment the position for the next path table record */ - *position += 1; - if (dir->parent) - parent_position = dir->parent->position; - else - parent_position = 1; - - name = iso_tree_dir_get_name(ddir, ISO_FILE_NAME_ISO); - if (name) - len = strlen(name); - else - len = 1; - - /* the directory identifier length (9.4.1) */ - buffer[0] = len; - /* the extended attribute record length (9.4.2) */ - buffer[1] = 0; - /* location of extent (9.4.3) */ - if (lsb) - iso_lsb(&buffer[2], dir->logical_block, 4); - else - iso_msb(&buffer[2], dir->logical_block, 4); - /* parent directory record (9.4.4) */ - if (lsb) - iso_lsb(&buffer[6], parent_position, 2); - else - iso_msb(&buffer[6], parent_position, 2); - /* the directory identifier (9.4.5) */ - if (name) - memcpy(&buffer[8], name, len); - else - memset(&buffer[8], 0, len); - /* padding field (9.4.6) */ - if (len % 2) { - bytes_written = 9 + len; - buffer[bytes_written] = 0; - } else - bytes_written = 8 + len; - - return bytes_written; -} - -/* recursive function used to write the path records for each level - * of the file system sequentially, i.e. root, then all children of - * root, then all grandchildren of root, then all great-grandchildren - * of root, etc. */ -int write_path_table_records(unsigned char *buffer, - struct iso_tree_dir **ddir, - int level, int *position, int lsb) -{ - int i, offset; - struct iso_tree_dir *dir = *ddir; - - /* ISO9660 only allows directories to be nested 8-deep */ - if (level >= 8) - return 0; - - if (!level) { - offset = write_path_table_record(buffer, ddir, position, lsb); - } else { - offset = 0; - for (i = 0; i < dir->nchildren; ++i) { - offset += write_path_table_records(buffer + offset, - dir->children[i].me, - level - 1, - position, lsb); - } - } - - return offset; -} - -/* writes set of path table records */ -int iso_write_path_table(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err, int lsb) -{ - int i, offset, position; - struct iso_state_path_tables *state = &t->state_data.path_tables; - - if (state->sectors) { - offset = 0; - position = 1; - - for (i = 0; i < 8; ++i) { - offset += write_path_table_records(buffer + offset, - t->volset->root, - i, &position, lsb); - } - } else { - /* empty buffer sector */ - memset(buffer, 0, t->phys_sector_size); - } - - return (++state->sectors == 2); -} - -struct iso_tree_dir **find_dir_at_block(struct iso_tree_dir **ddir, int block) -{ - int i; - struct iso_tree_dir *dir = *ddir; - struct iso_tree_dir **to_write = NULL; - - if (dir->logical_block == block) - to_write = ddir; - - for (i = 0; (i < dir->nchildren) && !to_write; ++i) { - to_write = find_dir_at_block(dir->children[i].me, block); - } - - return to_write; -} - -struct iso_tree_file **find_file_at_block(struct iso_tree_dir **ddir, int block) -{ - int i; - struct iso_tree_dir *dir = *ddir; - struct iso_tree_file **to_write = NULL; - - for (i = 0; (i < dir->nfiles) && !to_write; ++i) { - if (dir->files[i].logical_block == block) - to_write = dir->files[i].me; - } - - for (i = 0; (i < dir->nchildren) && !to_write; ++i) { - to_write = find_file_at_block(dir->children[i].me, block); - } - - return to_write; -} - -/* write the records for children of 'dir' */ -void write_child_records(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err, struct iso_tree_dir *dir) -{ - int file_counter, dir_counter, order, offset; - - file_counter = dir_counter = offset = 0; - - while ((file_counter < dir->nfiles) || (dir_counter < dir->nchildren)) { - /* if there are files and dirs, compare them to figure out - which comes 1st alphabetically */ - if ((file_counter < dir->nfiles) && - (dir_counter < dir->nchildren)) { - const char *dirname, *filename; - - dirname = iso_tree_dir_get_name - (dir->children[dir_counter].me, - ISO_FILE_NAME_ISO); - filename = iso_tree_file_get_name - (dir->files[file_counter].me, - ISO_FILE_NAME_ISO); - order = strcmp(dirname, filename); - } else { - if (file_counter < dir->nfiles) - /* only files are left */ - order = 1; - else - /* only dirs are left */ - order = -1; - } - - if (order < 0) { - offset += iso_write_dir_record(t, - buffer + offset, - dir-> - children[dir_counter]. - me, DIR_TYPE_NORMAL); - dir_counter++; - } else { - offset += iso_write_file_record(t, - buffer + offset, - dir-> - files[file_counter].me, - DIR_TYPE_NORMAL); - file_counter++; - } - - } - - return; -} - -/* write out the next directory record */ -int iso_write_dir_records(struct iso_write_target *t, - unsigned char *buffer, enum burn_source_status *err) -{ - int finished, offset; - struct iso_tree_dir **ddir, *dir; - struct iso_state_dir_records *state = &t->state_data.dir_records; - - finished = 0; /* set to 1 when all directory records have - been written */ - - if (state->sectors++) { - /* t->logical_block is the next block to write. find the dir - record which belongs there and write it out. if none - exists, we're done writing the directory records. */ - - ddir = find_dir_at_block(t->volset->root, t->logical_block); - - if (ddir) { - /* 1) write the record for this directory 2) write the - record for the parent directory 3) write the - records for all child files and directories */ - dir = *ddir; - offset = iso_write_dir_record(t, - buffer, - ddir, DIR_TYPE_SELF); - if (!dir->parent) { - /* this is the root directory */ - offset += iso_write_dir_record(t, - buffer + offset, - ddir, - DIR_TYPE_PARENT); - } else { - offset += iso_write_dir_record(t, - buffer + offset, - dir->parent->me, - DIR_TYPE_PARENT); - } - - write_child_records(t, buffer + offset, err, dir); - - /* dir->size should always be a multiple of - t->phys_sector_size */ - t->logical_block += (dir->size / t->phys_sector_size); - } else { - /* we just wrote out 2048 0's, so we still need to - increment this */ - t->logical_block++; - finished = 1; - } - } - - return finished; -} - -/* write the 'ER' area of the disc (RRIP-112: 4.3) */ -int iso_write_er_area(struct iso_write_target *t, - unsigned char *buffer, - enum burn_source_status *err) -{ - if (iso_volumeset_get_rr(t->volset)) { - char *text; - int len; - - buffer[0] = 'E'; - buffer[1] = 'R'; - buffer[2] = 237; - buffer[3] = 1; - buffer[4] = 10; - buffer[5] = 84; - buffer[6] = 135; - buffer[7] = 1; - text = strdup("" - "RRIP_1991ATHE ROCK RIDGE INTERCHANGE PROTOCOL " - "PROVIDES SUPPORT FOR POSIX FILE SYSTEM " - "SEMANTICSPLEASE CONTACT DISC PUBLISHER FOR " - "SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN " - "PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION"); - len = strlen (text); - - memcpy (buffer + 8, text, len); - free (text); - - /* next logical block... */ - t->logical_block++; - } - - return 1; -} - -int copy_file_to_buffer(FILE * fd, unsigned char *buffer, int length) -{ - int read; - - read = fread(buffer, 1, length, fd); - - return read; -} - -int iso_write_files(struct iso_write_target *t, - unsigned char *buffer, enum burn_source_status *err) -{ - FILE *fd; - int finished, sectors; - struct iso_tree_file **ffile, *file; - struct iso_state_files *state = &t->state_data.files; - - finished = 0; - - if (state->sectors) { - /* continue writing the file at 't->logical_block' to - 'buffer', then incremenet 't->logical_block' to the next - file section. */ - - fd = t->current_fd; - file = *(t->current_file); - - /* copy one sector of 'ffile' into 'buffer' */ - state->sectors += - copy_file_to_buffer(fd, buffer, t->phys_sector_size); - - if (feof(fd)) { - fclose(fd); - state->sectors = 0; - sectors = file->size / t->phys_sector_size; - if (file->size % t->phys_sector_size) - sectors++; - t->logical_block += sectors; - } - } else { - /* start writing the file at 't->logical_block' to 'buffer'. - if none exists, we are done. */ - ffile = find_file_at_block(t->volset->root, t->logical_block); - if (ffile) { - t->current_file = ffile; - file = *ffile; - fd = fopen(file->path, "r"); - t->current_fd = fd; - - if (fd) { - state->sectors += copy_file_to_buffer(fd, - buffer, - t-> - phys_sector_size); - } - - if (feof(fd)) { - fclose(fd); - fd = NULL; - } - - if (!fd) { - state->sectors = 0; - sectors = file->size / t->phys_sector_size; - if (file->size % t->phys_sector_size) - sectors++; - /* ensure we move past this logical block if the file was empty */ - else if (!file->size) - sectors++; - t->logical_block += sectors; - } - } else - finished = 1; - } - - return finished; -} diff --git a/libisofs/writer.h b/libisofs/writer.h deleted file mode 100755 index 018fd01..0000000 --- a/libisofs/writer.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __WRITER -#define __WRITER - -#include "libisofs.h" - -#include -#include -#include - -enum iso_write_state -{ - ISO_WRITE_BEFORE, - - ISO_WRITE_SYSTEM_AREA, - ISO_WRITE_PRI_VOL_DESC, - ISO_WRITE_VOL_DESC_TERMINATOR, - ISO_WRITE_L_PATH_TABLE, - ISO_WRITE_M_PATH_TABLE, - ISO_WRITE_DIR_RECORDS, - ISO_WRITE_ER_AREA, - ISO_WRITE_FILES, - - ISO_WRITE_DONE -}; - -/** File Flags (9.1.6) */ -enum -{ - ISO_FILE_FLAG_NORMAL = 0, - ISO_FILE_FLAG_HIDDEN = 1 << 0, - ISO_FILE_FLAG_DIRECTORY = 1 << 1, - ISO_FILE_FLAG_ASSOCIATED = 1 << 2, - ISO_FILE_FLAG_RECORD = 1 << 3, - ISO_FILE_FLAG_PROTECTION = 1 << 4, - ISO_FILE_FLAG_MULTIEXTENT = 1 << 7 -}; - -struct iso_write_target -{ - struct iso_volumeset *volset; - int volume; - - /* the time at which the writing began */ - time_t now; - - /* size of a physical sector on the target disc */ - int phys_sector_size; - /* size of the total output */ - int total_size; - - /* when compiling the iso, this is the next available logical block. - when writing the iso, this is the next block to write. */ - int logical_block; - /* The number of Logical Blocks for the Volume Space */ - int volume_space_size; - /* The Logical Block size */ - int logical_block_size; - /* The Path Table size */ - int path_table_size; - /* Locations of Type L Path Table (Logical Block Number) */ - int l_path_table_pos; - /* Locations of Type M Path Table (Logical Block Number) */ - int m_path_table_pos; - /* Location of the SUSP ER area (Logical Block Number) */ - int susp_er_pos; - /* Current file being written in iso_write_files() */ - struct iso_tree_file **current_file; - FILE *current_fd; - - /* what we're doing when the generate function gets called next */ - enum iso_write_state state; - union - { - struct iso_state_system_area - { - /* how many sectors in the system area have been - written */ - int sectors; - } system_area; - struct iso_state_path_tables - { - /* how many sectors in the path table area have been - written */ - int sectors; - } path_tables; - struct iso_state_dir_records - { - /* how many sectors in the directory records area have - been written */ - int sectors; - } dir_records; - struct iso_state_files - { - /* how many sectors in the current file have been - written */ - int sectors; - } files; - } state_data; -}; - -#endif /* __WRITER */