
/*
  Class struct of libisoburn.

  Copyright 2007 Vreixo Formoso Lopes <metalpain2002@yahoo.es>
             and Thomas Schmitt <scdbackup@gmx.net>
*/

#ifndef Isoburn_includeD
#define Isoburn_includeD


/* <<< transition macro */
#define Libisoburn_no_fifO 1


/* for uint8_t */
#include <stdint.h>


struct isoburn {


 /* The libburn drive to which this isoburn object is related
    Most isoburn calls will use a burn_drive as object handle */
 struct burn_drive *drive;

 /* -1= inappropriate media state detected
    0= libburn multi-session media, resp. undecided yet
    1= random access media */
 int emulation_mode;

 /* Although rarely used, libburn can operate on several
    drives simultaneously. */
 struct isoburn *prev;
 struct isoburn *next;


 /* Start address as given by image examination (bytes, not blocks) */
 off_t min_start_byte;

 /* Aligned start address to be used for processing (counted in blocks) */
 int nwa;

 /* Eventual freely fabricated isoburn_disc_get_status().
    BURN_DISC_UNREADY means that normally emulated status is in effect.
 */
 enum burn_disc_status fabricated_disc_status;

#ifndef Libisoburn_no_fifO
 /* The fifo which is installed between track and libisofs burn_source
 */
 struct burn_source *fifo;
#endif /* ! Libisoburn_no_fifO */

 /* Indicator wether the most recent burn run worked :
    -1 = undetermined, ask libburn , 0 = failure , 1 = success
    To be inquired by isoburn_drive_wrote_well()
 */
 int wrote_well;

 
 /* Buffered ISO head from media (should that become part of
    ecma119_read_opts ?) */
 uint8_t target_iso_head[65536];

 /* Libisofs image context */
 IsoImage *image;

#ifdef Libisoburn_no_fifO
 /* The burn source which transfers data from libisofs to libburn.
    It has its own fifo.
 */
 struct burn_source *iso_source;
#endif /* Libisoburn_no_fifO */

 /* For iso_tree_set_report_callback() */
 int (*read_pacifier)(IsoImage*, IsoFileSource*);

 /* For iso_image_attach_data() */
 void *read_pacifier_handle;

};


/* Creation and disposal function */
int isoburn_new(struct isoburn **objpt, int flag);
int isoburn_destroy(struct isoburn **objpt, int flag);

/* Eventual readers for public attributes */
/* ( put into separate .h file then ) */
int isoburn_get_emulation_mode(struct isoburn *o, int *pt, int flag);
int isoburn_get_target_volset(struct isoburn *o, IsoImage **pt, int flag);

/* List management */
int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag);
int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag);
int isoburn_destroy_all(struct isoburn **objpt, int flag);
int isoburn_link(struct isoburn *o, struct isoburn *link, int flag);
int isoburn_count(struct isoburn *o, int flag);
int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag);
int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag);


/* Non API inner interfaces */

/* Submit a libisofs error to the libburn messenger. An application message
   reader shall recognize the error code range and attribute it to the
   libisofs message channel to which one cannot submit via API.
   @param iso_error_code   return value <= 0 from a libisofs API call.
   @param default_msg_text is to be put out if iso_error_code leads to no
                           error message
   @param os_errno         operating system errno, submit 0 if none is known
   @param min_severity     minimum severity, might be be increased if libisofs
                           error severity surpasses min_severity.
   @param flag             Bitfield, submit 0 for now
*/
int isoburn_report_iso_error(int iso_error_code, char default_msg_text[],
                             int os_errno, char min_severity[], int flag);

/* Calls from burn_wrap.c into isofs_wrap.c */ 

int isoburn_start_emulation(struct isoburn *o, int flag);
int isoburn_invalidate_iso(struct isoburn *o, int flag);


/* Calls from isofs_wrap.c into burn_wrap.c */

/** Get an eventual isoburn object which is wrapped around the drive.
    @param pt    Eventually returns a pointer to the found object.
                 It is allowed to become NULL if return value is -1 or 0.
                 In this case, the drive is a genuine libburn drive
                 with no emulation activated by isoburn.
    @param drive The drive to be searched for
    @param flag  unused yet
    @return -1 unsuitable media, 0 generic media, 1 emulated media.
*/
int isoburn_find_emulator(struct isoburn **pt,
                          struct burn_drive *drive, int flag);


/** Set the start address for an emulated add-on session. The value will
    be rounded up to the alignment necessary for the media. The aligned
    value will be divided by 2048 and then put into  o->nwa .
    @param o     The isoburn object to be programmed.
    @param value The start address in bytes
    @param flag  unused yet
    @return <=0 is failure , >0 success
*/
int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag);

/** Get a data source suitable for read from a drive using burn_read_data()
    function.
    @param d drive to read from. Must be grabbed.
    @return the data source, NULL on error. Must be freed with libisofs
            iso_data_source_unref() function. Note: this doesn't release
            the drive.
*/
IsoDataSource *
isoburn_data_source_new(struct burn_drive *d);


/**
 * Options for image reading.
   (Comments here may be outdated. API getter/setter function descriptions
    may override the descriptions here. Any difference is supposed to be a
    minor correction only.)
 */
struct isoburn_read_opts {
    unsigned int norock:1; /*< Do not read Rock Ridge extensions */
    unsigned int nojoliet:1; /*< Do not read Joliet extensions */
    unsigned int noiso1999:1; /*< Do not read ISO 9660:1999 enhanced tree */
    unsigned int preferjoliet:1; 
                /*< When both Joliet and RR extensions are present, the RR
                 *  tree is used. If you prefer using Joliet, set this to 1. */
    uid_t uid; /**< Default uid when no RR */
    gid_t gid; /**< Default uid when no RR */
    mode_t mode; /**< Default mode when no RR (only permissions) */
    mode_t dirmode; /**< Default mode for directories 
                         when no RR (only permissions) */

    /**
     * Input charset for RR file names. NULL to use default locale charset.
     */
    char *input_charset;

    /* modified by the function isoburn_read_image */
    unsigned int hasRR:1; /*< It will be set to 1 if RR extensions are present,
                             to 0 if not. */
    unsigned int hasJoliet:1; /*< It will be set to 1 if Joliet extensions are 
                                  present, to 0 if not. */

    /**
     * It will be set to 1 if the image is an ISO 9660:1999, i.e. it has
     * a version 2 Enhanced Volume Descriptor.
     */
    unsigned int hasIso1999:1;

    /** It will be set to 1 if El-Torito boot record is present, to 0 if not.*/
    unsigned int hasElTorito:1;

    uint32_t size; /**< Will be filled with the size (in 2048 byte block) of 
                    *   the image, as reported in the PVM. */
    unsigned int pretend_blank:1; /* always create empty image */
};


/**
 * Options for image generation by libisofs and image transport to libburn.
   (Comments here may be outdated. API getter/setter function descriptions
    may override the descriptions here. Any difference is supposed to be a
    minor correction only.)
 */
struct isoburn_imgen_opts {

    /* Options for image generation */

    int level;  /**< ISO level to write at. */
    
    /** Which extensions to support. */
    unsigned int rockridge :1;
    unsigned int joliet :1;
    unsigned int iso1999 :1;

    /* relaxed constraints */

    /*
     * Relaxed constraints. Setting any of these to 1 break the specifications,
     * but it is supposed to work on most moderns systems. Use with caution.
     */

    /**
     * Omit the version number (";1") at the end of the ISO-9660 identifiers.
     * Version numbers are usually not used.
     */
    unsigned int omit_version_numbers :1;

    /**
     * Allow ISO-9660 directory hierarchy to be deeper than 8 levels.
     */
    unsigned int allow_deep_paths :1;

    /**
     * Allow path in the ISO-9660 tree to have more than 255 characters.
     */
    unsigned int allow_longer_paths :1;

    /**
     * Allow a single file or directory hierarchy to have up to 37 characters.
     * This is larger than the 31 characters allowed by ISO level 2, and the
     * extra space is taken from the version number, so this also forces
     * omit_version_numbers.
     */
    unsigned int max_37_char_filenames :1;

    /**
     * ISO-9660 forces filenames to have a ".", that separates file name from
     * extension. libisofs adds it if original filename doesn't has one. Set
     * this to 1 to prevent this behavior
     */
    unsigned int no_force_dots :1;

    /**
     * Allow lowercase characters in ISO-9660 filenames. By default, only
     * uppercase characters, numbers and a few other characters are allowed.
     */
    unsigned int allow_lowercase :1;

    /**
     * Allow all ASCII characters to be appear on an ISO-9660 filename. Note
     * that "/" and "\0" characters are never allowed, even in RR names.
     */
    unsigned int allow_full_ascii :1;

    /**
     * Allow paths in the Joliet tree to have more than 240 characters.
     */
    unsigned int joliet_longer_paths :1;

    unsigned int sort_files:1;
                /**< If files should be sorted based on their weight. */

    /**
     * The following options set the default values for files and directory
     * permissions, gid and uid. All these take one of three values: 0, 1 or 2.
     * If 0, the corresponding attribute will be kept as set in the IsoNode.
     * Unless you have changed it, it corresponds to the value on disc, so it
     * is suitable for backup purposes. If set to 1, the corresponding attrib.
     * will be changed by a default suitable value. Finally, if you set it to
     * 2, the attrib. will be changed with the value specified in the options
     * below. Note that for mode attributes, only the permissions are set, the
     * file type remains unchanged.
     */
    unsigned int replace_dir_mode :2; 
    unsigned int replace_file_mode :2;
    unsigned int replace_uid :2;
    unsigned int replace_gid :2;
    
    mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */
    mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */
    uid_t uid; /** uid to use when replace_uid == 2. */
    gid_t gid; /** gid to use when replace_gid == 2. */

    char *output_charset; /**< NULL to use default charset */


    /* Options for image transport */

    /** The number of bytes to be used for the fifo which decouples libisofs
        and libburn for better throughput and for reducing the risk of
        interrupting signals hitting the libburn thread which operates the
        MMC drive.
        The size will be rounded up to the next full 2048.
        Minimum is 64kiB, maximum is 1 GiB (but that is too much anyway).
    */
    int fifo_size;

};

#endif /* Isoburn_includeD */

