struct dev_info {
    int type;
    char *vendor;
    char *product;
    char *revision;
};
struct toc {
    int track;
    char type;
    int m, s, f;
    int addr;
    int copy;
    int channels;
};

class msf {
public:
    msf (char a, char b, char c) {m = a; s = b; f = c; next = 0;}
    ~msf () {if (next) delete next;}
    char m, s, f;
    msf *next;
};

class cuesheet {
public:
    cuesheet () { next = 0; index = 0; pregap = new msf (0, 0, 0);}
    ~cuesheet () {delete pregap; if (index) delete index; if (next) delete next;}
    int track;
    int preemp;
    msf *pregap;
    msf *index;
    cuesheet *next;
    void addindex (char, char, char);
};

#include <camlib.h>
#define FD cam_device *
#define CLOSE(a) cam_close_device(a)
#define CFILL(ccb,dir,data,datasize,cmd,tout) \
    cam_fill_csio (&ccb->csio, 1, 0, dir|CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG,\
		   data, datasize, SSD_FULL_SIZE, sizeof(cmd), tout);\
    memcpy(ccb->csio.cdb_io.cdb_bytes, cmd, sizeof(cmd))

struct cd_op {
    int (*set_mode) (FD, int);
    int (*set_speed) (FD, int);
    int (*read_audio_blocks) (FD, char *, int, int);
    int (*read_data_blocks) (FD, char *, int, int);
    int * (*speeds) ();
    int (*default_speed) ();
    int perfect_dae;
};

struct worm_op {
    int (*disk_init) (FD, int, int);
    int (*track_start) (FD, int, int);
    int (*write) (FD, char *, int);
    int (*track_end) (FD);
    int (*disk_end) (FD, int);
    int (*send_cuesheet) (FD, cuesheet *, int *, int *);
    int * (*speeds) ();
    int (*default_speed) ();
    int swap;
};
#define WERR_RECOVERED 0
#define WERR_TRACK     1
#define WERR_UNRECOV   2
    
struct dev_struct {
    char *name;
    int there;
};

#define COPY_ACTIVE  0x01
#define ISO_ACTIVE   0x02
#define WRITE_ACTIVE 0x04
extern int w_active;

#define T_DAO   0x10000
#define T_AUDIO  0x0001
#define T_DATA   0x0002
#define T_PREEMP 0x8000
#define T_PREGAP 0x1000

void write_cd (int, char **), create_iso9660 (int, char **), 
    copy_cd (int, char **);
void Error (char *), start_info (), Info (char *, int = -1), end_info ();
struct dev_info *inquiry (FD);
struct toc *cd_toc (FD);
int rezero_unit (FD), start_unit (FD);
int open_tray (FD), close_tray (FD);
struct cd_op *cd_cap (char *, char *, char *);
void copy_progress_start (int), copy_progress_msg (int);
int test_unit_ready (FD);
void prevent_removable (FD, int);
void check_dev (struct dev_struct*);
struct worm_op *worm_cap (char *, char *, char *);
void set_params (char *, int, int, struct worm_op *, int, int, cuesheet *), 
    add_file (int, char *, char *, int, int);
char *worm ();
void help (int, char **);
char *ADDR (char *);
cuesheet *check_cue_sheet (int *);
void edit_cue_sheet (int *), delete_cue_sheet (), kill_cue ();

