pkg://xcdroast-debuginfo-0.98a15-14.fc7.ppc.rpm:614443/
usr/
src/
debug/
xcdroast-0.98alpha15/
src/io.c
info downloads
/*
io.c
All the functions that interact with hardware and subprocesses
and file IO.
28.3.99 tn
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "largefile.h"
#include "gettext.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#if defined(linux) || defined(__FreeBSD__)
# include <sys/soundcard.h>
# include <sys/ioctl.h>
#endif
#if defined(sun) || defined(__OpenBSD__)
# include <sys/ioctl.h>
# include <sys/audioio.h>
#endif
#ifdef aix
#include <sys/audio.h>
#endif
#ifdef hpux
# ifndef hpux_alib
# include <sys/audio.h>
# endif
#endif
#if defined(__sgi)
#include <dmedia/audio.h>
#endif
#if ENABLE_NLS
# define _(String) gettext (String)
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) (String)
#endif
#define GTK_ENABLE_BROKEN
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib.h>
#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"
writerreader_devices_t **writerreaderdevs;
gchar **alt_scsidevices;
cd_info_t cdinfo;
track_info_t **trackinfo;
writer_driver_t **drivers;
writer_driver_t **blankmodes;
write_track_param_t writeparams;
gchar xcdroast_version_loaded[MAXLINE];
gint read_done;
gint read_abort_mark;
static gint scsicount;
static gint busnr;
static gint tocstate;
static gint tocnr;
static gint drvcount;
static gint dfrun;
static gint readcdda_callback;
static gint readcdda_callback2;
static gint readcdda_callback3;
static gint read_output_ctrl;
static gint read_tracknr;
static gchar readtrack_info_string[1024];
static gfloat pct_so_far, pct_this_track;
static pid_t mkisofs_pid;
static pid_t readcdda_pid, readcdda_pid2;
static gint readcd_startsector, readcd_endsector;
static gint readerr_count;
static gint matchnr;
static gint cddb_in;
static gchar cdinfo_cddb_title_bak[MAXLINE];
static gint cd_is_still_the_same;
static gint cdrecord_stdin, cdrecord_reload;
static gint delete_count, delete_start, delete_all;
static gint msinfo_nr1, msinfo_nr2;
static gint cdrtimer, count_mmaperror, checkmedium_found;
static time_t cdrcmdtimer;
static GtkWidget *getcdtoc_atapi_timeout_dialog;
extern gint debug;
extern gint dialog_done2, dialog_done, dialog_done3;
extern setup_data_t setupdata;
extern track_read_set_t trackreadset;
extern current_set_t curset;
extern gchar *system_platform;
extern GtkWidget *toplevel;
extern GtkWidget *viewmode_dialog;
extern GtkWidget *readtrack_info_label, *readtrack_textview;
extern GtkWidget *readtrack_pbar1, *readtrack_pbar2, *readtrack_pbar3;
extern GtkWidget *readtrack_pbar4, *readtrack_spd;
extern GtkWidget *readtrack_small_info, *readtrack_small_info2;
extern gchar hostname[MAXLINE];
extern gchar username[MAXLINE];
extern gchar sharedir[MAXLINE];
extern gchar configdir[MAXLINE];
extern gchar prefixdir[MAXLINE];
extern GtkWidget *cddb_info_label;
extern GtkCList *cddb_clist;
extern master_param_t masterparam;
extern gchar **charset_types;
extern gchar *master_fname1;
extern gchar *master_fname2;
extern GdkFont *fixedfont;
extern gint support_ontheflyaudio;
static void verify_readcd_err(gpointer pid, gint source, GdkInputCondition cond);
static void read_write_out(gpointer data, gint source, GdkInputCondition cond);
static gint getdevicecap(gchar *dev, gint *readmax, gint *cdrmax, gint *dvdmax, gint *iscdr, gint *isdvdrom, gint *isdvdr);
static gint check_medium_loaded(gint devnr);
static gint get_cdrecord_toc(gint devnr);
static void remove_tmp_writetracks_tocfile(gchar *tocfile);
static void edit_xinf_for_cd_text2(gchar *infname, gchar *title, gchar *artist, gchar *cdtitle, gchar *cdartist);
static pid_t full_dpl_pipe3(gint *out, gint *in, gint *err, gchar *cmd,
gint use_socketpair);
/* convert device-type-names back to numeric */
/* -1 means unknown */
static gint get_scsi_type(gchar *type) {
if (strcmp(type,"Disk") == 0) {
return 0;
}
if (strcmp(type,"Tape") == 0) {
return 1;
}
if (strcmp(type,"Printer") == 0) {
return 2;
}
if (strcmp(type,"Processor") == 0) {
return 3;
}
if (strcmp(type,"WORM") == 0) {
return 4;
}
if (strcmp(type,"CD-ROM") == 0) {
return 5;
}
if (strcmp(type,"Scanner") == 0) {
return 6;
}
if (strcmp(type,"Optical Storage") == 0) {
return 7;
}
if (strcmp(type,"Juke Box") == 0) {
return 8;
}
if (strcmp(type,"Communication") == 0) {
return 9;
}
return -1;
}
/* convert the scsi-type-number back to string */
#if 0
static void get_scsi_type_string(gchar *str, gint type, gint removeable) {
switch(type) {
case 0:
if (removeable == 0) {
strcpy(str,_("Disk"));
} else {
strcpy(str,_("Removable Disk"));
}
break;
case 1:
strcpy(str,_("Tape"));
break;
case 2:
strcpy(str,_("Printer"));
break;
case 3:
strcpy(str,_("Processor/Scanner"));
break;
case 4:
strcpy(str,_("WORM"));
break;
case 5:
strcpy(str,_("CD-ROM"));
break;
case 6:
strcpy(str,_("Scanner"));
break;
case 7:
strcpy(str,_("Optical Storage"));
break;
case 8:
strcpy(str,_("Juke Box"));
break;
case 9:
strcpy(str,_("Communication"));
break;
default:
strcpy(str,"");
break;
}
}
#endif
static gint get_cur_audioread_speed() {
gint i;
i = get_writerreaderdevs_index(curset.reader_devnr);
return (writerreaderdevs[i]->audioread_speed);
}
static gint get_cur_audioread_overlap() {
gint i;
i = get_writerreaderdevs_index(curset.reader_devnr);
return (writerreaderdevs[i]->audioread_overlap);
}
static gint get_cur_audioread_sectorburst() {
gint i;
i = get_writerreaderdevs_index(curset.reader_devnr);
return (writerreaderdevs[i]->audioread_sectorburst);
}
static gint get_cur_audioread_useparanoia() {
gint i;
i = get_writerreaderdevs_index(curset.reader_devnr);
return (writerreaderdevs[i]->audioread_useparanoia);
}
static gint get_cur_audioread_paranoiaretries() {
gint i;
i = get_writerreaderdevs_index(curset.reader_devnr);
return (writerreaderdevs[i]->audioread_paranoiaretries);
}
static gint get_cur_writer_speed() {
gint i;
i = get_writerreaderdevs_index(curset.writer_devnr);
return (writerreaderdevs[i]->writer_speed);
}
static gint get_cur_writer_fifo() {
gint i;
i = get_writerreaderdevs_index(curset.writer_devnr);
return (writerreaderdevs[i]->writer_fifo);
}
static gint get_cur_writemode() {
gint i;
i = get_writerreaderdevs_index(curset.writer_devnr);
return (writerreaderdevs[i]->writer_mode);
}
static gint get_cur_writer_drvmode() {
gint i;
i = get_writerreaderdevs_index(curset.writer_devnr);
return (writerreaderdevs[i]->writer_drvmode);
}
/* look in given string for "' '" and return index to it */
/* return -1 if not found */
static gint look_for_scan_delimitor(gchar *str) {
gint i;
for(i = 0; i < strlen(str)-2; i++) {
if (str[i] == '\'' && str[i+1] == ' ' && str[i+2] == '\'') {
return i;
}
}
return -1;
}
/* look in given string for "' " and return index to it */
/* return -1 if not found */
static gint look_for_scan_delimitor2(gchar *str) {
gint i;
for(i = 0; i < strlen(str)-1; i++) {
if (str[i] == '\'' && str[i+1] == ' ') {
return i;
}
}
return -1;
}
/* interpret output of -scanbus and sort into memory structure */
/* if idx != -1 then we run in manual-device-mode */
static void parse_scan(gchar *line, gint idx, gint transport, scsi_devices_t **scsidevices) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar *p1, *p2;
gint s_id;
gchar s_vendor[9];
gchar s_model[17];
gchar s_rev[5];
gint s_removable;
gint s_type;
gint next;
/* skip header */
if (strncmp(line,"Cdrecord",8) == 0) {
return;
}
#if 0
if (strncmp(line,"devname",7) == 0 ) {
/* set current scsibus nr */
strcpy(tmp,line+7);
p1=strtok(tmp,":");
/* now tmp2 contains the current busnr as string */
devname = strdup(p1);
return;
}
#endif
if (strncmp(line,"scsibus",7) == 0 ) {
/* set current scsibus nr */
strcpy(tmp,line+7);
p1=strtok(tmp,":");
strcpy(tmp2,p1);
/* now tmp2 contains the current busnr as string */
busnr = atoi(tmp2);
return;
}
/* a line with an error message? */
/* get_spawn_path(CDRECORD,tmp); */
strcpy(tmp,"cdrecord: ");
if (strncmp(line, tmp, strlen(tmp)) == 0) {
return;
}
/* a line with device-info found (by checking for ")")*/
p1 = index(line,')');
if (p1 != NULL && !strstr(line,")\"") &&
(strstr(line,"\t") || line[0] == ' ')) {
strip_string(line);
/* get scsi-id */
p1=strtok(line,")");
if (!p1) return;
strcpy(tmp,p1);
strcpy(tmp2,p1);
/* look for last tab or last space in tmp and remove
everything before */
p1=rindex(tmp2,'\t');
p2=rindex(tmp2,' ');
if (p1 > p2) {
/* last interesting char was a tab - cut here */
if (p1 != NULL) {
strcpy(tmp,p1+1);
}
} else {
/* last interesting char was a space - cut here */
if (p2 != NULL) {
strcpy(tmp,p2+1);
}
}
s_id = atoi(tmp);
/* strip host-id from scsi-id-number */
s_id = s_id % 100;
p1=strtok(NULL,"'");
if (p1 == NULL) {
g_warning("cdrecord scanbus error: Try to remove all media from your CD-ROM drives before starting X-CD-Roast.\n");
return;
}
strcpy(tmp,p1);
strip_string(tmp);
if (*tmp == '*') {
/* no device found */
return;
}
if (*tmp == 'H') {
/* HOST ADAPTER found */
/* treat as no device for now */
return;
}
/* get full rest of line */
p1=strtok(NULL,"");
if (!p1) return;
strcpy(tmp,p1);
if (*tmp == '\'') {
/* empty device found? ignore */
return;
}
/* e.g. tmp=YAMAHA ' 'CRW8424S ' '1.0j' */
/* get vendor */
next = look_for_scan_delimitor(tmp);
if (next < 0) {
g_error("cdrecord -scanbus output syntax error\n");
}
strcpy(s_vendor," ");
if (next <= 8) {
strncpy(s_vendor,tmp,next);
} else {
/* strip if to long */
strncpy(s_vendor,tmp,8);
}
s_vendor[8] = '\0';
/* get model */
strcpy(tmp2,tmp+next+3);
strcpy(tmp,tmp2);
next = look_for_scan_delimitor(tmp);
if (next < 0) {
g_error("cdrecord -scanbus output syntax error\n");
}
strcpy(s_model," ");
if (next <= 16) {
strncpy(s_model,tmp,next);
} else {
strncpy(s_model,tmp,16);
}
s_model[16] = '\0';
/* get revision */
strcpy(tmp2,tmp+next+3);
strcpy(tmp,tmp2);
next = look_for_scan_delimitor2(tmp);
if (next < 0) {
g_error("cdrecord -scanbus output syntax error\n");
}
strcpy(s_rev," ");
if (next <= 4) {
strncpy(s_rev,tmp,next);
} else {
strncpy(s_rev,tmp,4);
}
s_rev[4] = '\0';
/* get type */
strcpy(tmp2,tmp+next+2);
strcpy(tmp,tmp2);
strip_string(tmp);
if (strncmp(tmp,"Removable",9) == 0) {
s_removable = 1;
strcpy(tmp2,tmp+10);
strcpy(tmp,tmp2);
} else {
s_removable = 0;
}
s_type = get_scsi_type(tmp);
/* allocate and fill structure */
scsidevices[scsicount]=g_new(scsi_devices_t,1);
if (idx == -1) {
/* autoscan mode */
scsidevices[scsicount]->devnr =
transport*1024+busnr*32+s_id;
scsidevices[scsicount]->alt_dev = -1;
} else {
/* manual mode */
scsidevices[scsicount]->devnr = idx;
scsidevices[scsicount]->alt_dev = idx;
}
scsidevices[scsicount]->sector_size = DATASECTORSIZE;
scsidevices[scsicount]->transport = transport;
scsidevices[scsicount]->bus = busnr;
scsidevices[scsicount]->id = s_id;
strcpy(scsidevices[scsicount]->vendor,s_vendor);
strcpy(scsidevices[scsicount]->model,s_model);
strcpy(scsidevices[scsicount]->rev,s_rev);
scsidevices[scsicount]->removable = s_removable;
scsidevices[scsicount]->type = s_type;
scsicount++;
if (scsicount >= MAXDEVICES) {
g_error("Error: More than %d devices scanned\n",MAXDEVICES);
}
}
}
/* print memory-structure with scsidevices (debug purposes) */
#if 0
static void print_scsidevices(scsi_devices_t **scsidevices) {
gint count;
dodebug(2,"------ cdrecord scsidevices-structure -----\n");
count = 0;
while(scsidevices[count] != NULL) {
dodebug(2,"devnr=%d %d:%d %s %s %s %d,%d (alt: %d) (ssize: %d)\n",
scsidevices[count]->devnr,
scsidevices[count]->bus,
scsidevices[count]->id,
scsidevices[count]->vendor,
scsidevices[count]->model,
scsidevices[count]->rev,
scsidevices[count]->removable,
scsidevices[count]->type,
scsidevices[count]->alt_dev,
scsidevices[count]->sector_size);
count++;
}
}
#endif
static void print_writerreaderdevs() {
gint count;
dodebug(2,"------ cdrecord writerreaderdevs-structure -----\n");
count = 0;
while(writerreaderdevs[count] != NULL) {
dodebug(2, "devnr=%d (%s) [%s %s %s] (ssize: %d)\n",
writerreaderdevs[count]->devnr,
writerreaderdevs[count]->devicestr,
writerreaderdevs[count]->vendor,
writerreaderdevs[count]->model,
writerreaderdevs[count]->rev,
writerreaderdevs[count]->sector_size);
dodebug(2, " readmax: %d, cdrmax: %d, dvdmax: %d, is_cdrwriter: %d, is_dvdreader: %d, is_dvdwriter: %d\n",
writerreaderdevs[count]->writer_readmaxspeed,
writerreaderdevs[count]->writer_cdrmaxspeed,
writerreaderdevs[count]->writer_dvdmaxspeed,
writerreaderdevs[count]->is_cdrwriter,
writerreaderdevs[count]->is_dvdreader,
writerreaderdevs[count]->is_dvdwriter,
writerreaderdevs[count]->sector_size);
dodebug(2, " writer_flags: %s\n",
writerreaderdevs[count]->writer_flags);
dodebug(2, " writer_modes: %s\n",
writerreaderdevs[count]->writer_modes);
count++;
}
}
/* create a new writer/reader entry */
static gint add_writerreader(scsi_devices_t *scsidev, gchar *transport, GtkWidget *txt) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar drvflags[MAXLINE], drvmodes[MAXLINE];
gint readmax, cdrmax, dvdmax, iscdr, isdvdr, isdvdrom;
gint count;
gint mmap_error;
gint i;
static const gchar *writemodes[] = WRITE_MODES;
/* first search last entry of writerreader struct */
count = 0;
while(writerreaderdevs[count] != NULL) {
if (count == MAXDEVICES-1) {
return 0;
}
count++;
}
/* only add type WORM and CD-ROM types */
if (scsidev->type != 4 && scsidev->type != 5) {
return 0;
}
/* build device string */
if (scsidev->alt_dev == -1) {
g_snprintf(tmp,MAXLINE,"%s%d,%d,%d",
transport, scsidev->bus, scsidev->id, 0);
} else {
strncpy(tmp, transport, MAXLINE);
}
/* check if this device already exists */
if (get_writerreaderdevs_index_from_devstr(tmp) != -1) {
if (txt) {
g_snprintf(tmp2,MAXLINE,"([%s] %s %s %s)\n",
tmp, scsidev->vendor,
scsidev->model, scsidev->rev);
convert_for_gtk2_textwidget(tmp2);
gtk_text_insert(GTK_TEXT(txt), NULL, NULL, NULL, tmp2, strlen(tmp2));
wait_and_process_events();
}
return 0;
}
/* create a new entry */
writerreaderdevs[count]=g_new0(writerreader_devices_t,1);
writerreaderdevs[count]->devnr = scsidev->devnr;
writerreaderdevs[count]->devicestr = g_strdup(tmp);
strncpy(writerreaderdevs[count]->vendor, scsidev->vendor,9);
strncpy(writerreaderdevs[count]->model, scsidev->model,17);
strncpy(writerreaderdevs[count]->rev, scsidev->rev,5);
writerreaderdevs[count]->sector_size = scsidev->sector_size;
getmodesflags(tmp, drvflags, drvmodes);
writerreaderdevs[count]->writer_flags = g_strdup(drvflags);
writerreaderdevs[count]->writer_modes = g_strdup(drvmodes);
/* get more detailed information about this device */
mmap_error=getdevicecap(tmp, &readmax, &cdrmax, &dvdmax, &iscdr, &isdvdrom, &isdvdr);
writerreaderdevs[count]->writer_readmaxspeed = readmax;
writerreaderdevs[count]->writer_cdrmaxspeed = cdrmax;
writerreaderdevs[count]->writer_dvdmaxspeed = dvdmax;
writerreaderdevs[count]->is_cdrwriter = iscdr;
writerreaderdevs[count]->is_dvdreader = isdvdrom;
writerreaderdevs[count]->is_dvdwriter = isdvdr;
/* workaround for non-mcc drives */
if (writerreaderdevs[count]->is_cdrwriter == 0) {
/* not detected as writer, but got write modes? */
if (strlen(drvmodes) > 0) {
/* assume its really a writer then */
writerreaderdevs[count]->is_cdrwriter = 1;
}
}
/* set defaults for other fields */
writerreaderdevs[count]->writer_drvmode = -1;
writerreaderdevs[count]->writer_speed = cdrmax;
writerreaderdevs[count]->writer_fifo = 4096;
/* get the first supported mode for that writer */
i = 0;
while (writemodes[i]) {
if (writemode_supported(i, scsidev->devnr)) {
writerreaderdevs[count]->writer_mode = i;
break;
}
i++;
}
writerreaderdevs[count]->audioread_interface = 0;
writerreaderdevs[count]->audioread_speed = readmax;
writerreaderdevs[count]->audioread_overlap = 0;
writerreaderdevs[count]->audioread_sectorburst = 75;
writerreaderdevs[count]->audioread_useparanoia = 0;
writerreaderdevs[count]->audioread_paranoiaretries = 20;
/* add to dialog window */
if (txt) {
g_snprintf(tmp2,MAXLINE,"[%s] %s %s %s\n",
tmp, scsidev->vendor,
scsidev->model, scsidev->rev);
convert_for_gtk2_textwidget(tmp2);
gtk_text_insert(GTK_TEXT(txt), NULL, NULL, NULL, tmp2, strlen(tmp2));
wait_and_process_events();
}
return mmap_error;
}
/* does scan for a single device only */
/* return 1 when new device was found */
static gint scanbus_single(gchar *dev, gint newdevnr, GtkWidget *txt) {
gchar line[MAXLINE];
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
FILE *fpin;
scsi_devices_t **scsidevices;
gint found;
scsidevices = g_new0(scsi_devices_t *, MAXDEVICES);
scsicount = 0;
get_wrap_path_cdrecord(line);
/* make sure we escape any critical chars in input */
strncpy(tmp2,dev,MAXLINE);
convert_escape(tmp2);
g_snprintf(tmp,MAXLINE," -scanbus dev= \"%s\" 2>&1",tmp2);
strcat(line,tmp);
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10,"scanbus: %s",line);
parse_scan(line, newdevnr, 0, scsidevices);
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
found = 0;
if (scsidevices[0]) {
add_writerreader(scsidevices[0], dev, txt);
g_free(scsidevices[0]);
found = 1;
}
g_free(scsidevices);
return found;
}
#if (defined(__MACH__) && defined(__APPLE__))
/* interpret output of -inq and sort into memory structure */
/* if idx != -1 then we run in manual-device-mode */
static void parse_inq(gchar *line, gint idx, scsi_devices_t **scsidevices) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar *p;
gchar s_vendor[9];
gchar s_model[17];
gchar s_rev[5];
gint s_removable;
gint s_type;
if (strncmp("Device type",line,11) == 0) {
p = strtok(line,":");
if (p) {
p = strtok(NULL,"");
if (p) {
strcpy(tmp,p);
strip_string(tmp);
if (strncmp(tmp,"Removable",9) == 0) {
s_removable = 1;
strcpy(tmp2,tmp+10);
strcpy(tmp,tmp2);
} else {
s_removable = 0;
}
s_type = get_scsi_type(tmp);
/* allocate entry now */
scsidevices[scsicount]=g_new(scsi_devices_t,1);
scsidevices[scsicount]->sector_size = DATASECTORSIZE;
scsidevices[scsicount]->devnr = idx;
scsidevices[scsicount]->alt_dev = idx;
scsidevices[scsicount]->transport = 0;
scsidevices[scsicount]->bus = 0;
scsidevices[scsicount]->id = idx;
scsidevices[scsicount]->removable = s_removable;
scsidevices[scsicount]->type = s_type;
}
}
}
if (strncmp("Vendor_info",line,11) == 0) {
p = strtok(line,":");
if (p) {
p = strtok(NULL,"");
if (p) {
strcpy(tmp2,p);
extract_singlequoted(tmp2);
strcpy(s_vendor," ");
if (strlen(tmp2) <= 8) {
strncpy(s_vendor,tmp2,strlen(tmp2));
} else {
/* strip if to long */
strncpy(s_vendor,tmp2,8);
}
s_vendor[8] = '\0';
if (scsidevices[scsicount]) {
strcpy(scsidevices[scsicount]->vendor,s_vendor);
}
}
}
}
if (strncmp("Identifikation",line,14) == 0) {
p = strtok(line,":");
if (p) {
p = strtok(NULL,"");
if (p) {
strcpy(tmp2,p);
extract_singlequoted(tmp2);
strcpy(s_model," ");
if (strlen(tmp2) <= 16) {
strncpy(s_model,tmp2,strlen(tmp2));
} else {
strncpy(s_model,tmp2,16);
}
s_model[16] = '\0';
if (scsidevices[scsicount]) {
strcpy(scsidevices[scsicount]->model,s_model);
}
}
}
}
if (strncmp("Revision",line,8) == 0) {
p = strtok(line,":");
if (p) {
p = strtok(NULL,"");
if (p) {
strcpy(tmp2,p);
extract_singlequoted(tmp2);
strcpy(s_rev," ");
if (strlen(tmp2) <= 4) {
strncpy(s_rev,tmp2,strlen(tmp2));
} else {
strncpy(s_rev,tmp2,4);
}
s_rev[4] = '\0';
if (scsidevices[scsicount]) {
strcpy(scsidevices[scsicount]->rev,s_rev);
scsicount++;
}
}
}
}
if (scsicount >= MAXDEVICES) {
g_error("Error: More than %d devices scanned\n",MAXDEVICES);
}
}
/* does scan for a single device only via inq call (osX) */
static gint scanbus_via_inq(gchar *dev, gint newdevnr, GtkWidget *txt) {
gchar line[MAXLINE];
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
FILE *fpin;
scsi_devices_t **scsidevices;
gint found;
scsidevices = g_new0(scsi_devices_t *, MAXDEVICES);
scsicount = 0;
get_wrap_path_cdrecord(line);
/* make sure we escape any critical chars in input */
strncpy(tmp2,dev,MAXLINE);
convert_escape(tmp2);
g_snprintf(tmp,MAXLINE," -inq dev= \"%s\" 2>&1",tmp2);
strcat(line,tmp);
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10,"scanbus: %s",line);
parse_inq(line, newdevnr, scsidevices);
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
found = 0;
if (scsidevices[0]) {
add_writerreader(scsidevices[0], dev, txt);
g_free(scsidevices[0]);
found = 1;
}
g_free(scsidevices);
return found;
}
#endif
/* scanbus scsi */
static void scan_traditional(GtkWidget *txt) {
gchar line[MAXLINE];
FILE *fpin;
gint count, errcount, ret;
scsi_devices_t **scsidevices;
scsidevices = g_new0(scsi_devices_t *, MAXDEVICES);
scsicount = 0;
/* traditional scanning first */
get_wrap_path_cdrecord(line);
strcat(line," -scanbus 2>&1");
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10,"scanbus: %s",line);
parse_scan(line, -1, 0, scsidevices);
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
/* add the found devices to the writerreader structure */
count = 0;
errcount = 0;
while(scsidevices[count] != NULL) {
errcount+=add_writerreader(scsidevices[count],"", txt);
g_free(scsidevices[count]);
count++;
}
g_free(scsidevices);
/* historic mmap error check */
if (errcount > 0) {
ret = show_dialog(ICO_WARN, _("Warning: The cdrtools binaries you have installed are\nnot compatible with your system. You will NOT be\nable to read or write CDs. Please read the FAQ\non www.xcdroast.org for more information."), T_ANYWAY, _("Exit"), NULL, 1);
if (ret == 1)
gtk_exit(1);
}
}
/* alternative transport method scanning */
/* valid transport choices for now: ATAPI USCSI REMOTE */
static gint scan_other(gchar *transport, gint transid, GtkWidget *txt) {
gchar line[MAXLINE];
gchar tmp[MAXLINE];
FILE *fpin;
gint count;
scsi_devices_t **scsidevices;
scsidevices = g_new0(scsi_devices_t *, MAXDEVICES);
scsicount = 0;
get_wrap_path_cdrecord(line);
g_snprintf(tmp,MAXLINE," dev=%s -scanbus 2>&1", transport);
strcat(line, tmp);
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10,"scanbus (%s): %s", transport, line);
parse_scan(line, -1, transid, scsidevices);
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
/* add the found devices to the writerreader structure */
count = 0;
g_snprintf(tmp,MAXLINE,"%s:", transport);
while(scsidevices[count] != NULL) {
add_writerreader(scsidevices[count], tmp, txt);
g_free(scsidevices[count]);
count++;
}
g_free(scsidevices);
return count;
}
/* new scanbus version */
void scanbus_new(GtkWidget *txt, gint scanparam) {
gchar tmp[MAXLINE];
GdkFont *boldfont;
gint doscanbus;
gint i, devnr;
/* allocate memory */
if (!writerreaderdevs) {
writerreaderdevs = g_new0(writerreader_devices_t *, MAXDEVICES);
}
boldfont = get_some_font(BOLDFONT);
doscanbus = 1;
/* output status texts? */
if (txt) {
strncpy(tmp,_("Starting to scan for devices...\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), boldfont, NULL, NULL, tmp, strlen(tmp));
wait_and_process_events();
}
/* check if we have to do full scanbus, or only partial */
if (alt_scsidevices[0] != NULL) {
i = 0;
while (alt_scsidevices[i] != NULL) {
/* look for a free device number (greater 8192) */
for (devnr = 8192; devnr < 8192 + MAXDEVICES; devnr++) {
if (get_writerreaderdevs_index(devnr) == -1) {
break;
}
}
scanbus_single(alt_scsidevices[i], devnr, txt);
i++;
}
/* trigger not to scan the bus any futher */
doscanbus = 0;
}
#if (defined(__MACH__) && defined(__APPLE__))
/* special handling for osX */
/* try fixed list of devices */
alt_scsidevices[0] = g_strdup("IOCompactDiscServices");
alt_scsidevices[1] = g_strdup("IOCompactDiscServices/2");
alt_scsidevices[2] = g_strdup("IOCompactDiscServices/3");
alt_scsidevices[3] = g_strdup("IODVDServices");
alt_scsidevices[4] = g_strdup("IODVDServices/2");
alt_scsidevices[5] = g_strdup("IODVDServices/3");
i = 0;
while (alt_scsidevices[i] != NULL) {
scanbus_via_inq(alt_scsidevices[i], 4096+i, txt);
i++;
}
/* trigger not to scan the bus any futher */
doscanbus = 0;
#endif
if (doscanbus) {
/* scan for scsi devices */
scan_other("ATA", 1, txt);
scan_traditional(txt);
/* scan for alternatives */
#if defined(linux)
if (scanparam) {
scan_other("ATAPI", 2, txt);
}
#endif
#if defined(sun)
if (scanparam) {
scan_other("USCSI", 3, txt);
}
#endif
}
if (txt) {
strncpy(tmp,_("Scan finished.\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), boldfont, NULL, NULL, tmp, strlen(tmp));
wait_and_process_events();
}
gdk_font_unref(boldfont);
if (debug) print_writerreaderdevs();
}
/* scan for remote scsi devices */
void scanbus_rscsi(gchar *devstr, GtkWidget *txt) {
gchar tmp[MAXLINE];
GdkFont *boldfont;
gint found;
gint i, highest;
/* allocate memory */
if (!writerreaderdevs) {
writerreaderdevs = g_new0(writerreader_devices_t *, MAXDEVICES);
}
boldfont = get_some_font(BOLDFONT);
/* output status texts? */
if (txt) {
strncpy(tmp,_("Starting to scan for remote devices...\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), boldfont, NULL, NULL, tmp, strlen(tmp));
wait_and_process_events();
}
/* look for highest free devnr - but at least a multiple of 16384 */
i = 0;
highest = -1;
while(writerreaderdevs[i] != NULL) {
if (writerreaderdevs[i]->devnr > highest) {
highest = writerreaderdevs[i]->devnr;
}
i++;
}
highest++;
/* when we scan multiple times always arange a new block to play safe */
highest = ((highest/16384)+1)*16384;
found = scan_other(devstr, highest/1024, txt);
if (txt) {
if (found == 0) {
strncpy(tmp,_("No devices found - check your remote scsi setup.\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), NULL, NULL, NULL, tmp, strlen(tmp));
}
strncpy(tmp,_("Scan finished.\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), boldfont, NULL, NULL, tmp, strlen(tmp));
wait_and_process_events();
}
gdk_font_unref(boldfont);
if (debug) print_writerreaderdevs();
}
/* special version where we scan only for a single device */
void scanbus_new_single(gchar *devstr, GtkWidget *txt) {
gchar tmp[MAXLINE];
GdkFont *boldfont;
gint devnr, found;
/* allocate memory */
if (!writerreaderdevs) {
writerreaderdevs = g_new0(writerreader_devices_t *, MAXDEVICES);
}
boldfont = get_some_font(BOLDFONT);
/* output status texts? */
if (txt) {
strncpy(tmp,_("Starting to scan for devices...\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), boldfont, NULL, NULL, tmp, strlen(tmp));
wait_and_process_events();
}
/* look for a free device number (greater 8192) */
for (devnr = 8192; devnr < 8192 + MAXDEVICES; devnr++) {
if (get_writerreaderdevs_index(devnr) == -1) {
break;
}
}
found = scanbus_single(devstr, devnr, txt);
if (txt) {
if (!found) {
strncpy(tmp,_("Device not found.\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), NULL, NULL, NULL, tmp, strlen(tmp));
}
strncpy(tmp,_("Scan finished.\n"), MAXLINE);
convert_for_gtk2_textwidget(tmp);
gtk_text_insert(GTK_TEXT(txt), boldfont, NULL, NULL, tmp, strlen(tmp));
wait_and_process_events();
}
gdk_font_unref(boldfont);
if (debug) print_writerreaderdevs();
}
/* interpret output of driver=help and sort into memory structure */
static void parse_driver(gchar *line) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar drv[MAXLINE];
gchar *p1;
gint n;
if (strncmp(line,"Driver types:",13) != 0 ) {
strcpy(tmp,line);
p1=strtok(tmp," ");
strcpy(drv,p1);
/* now drv contains the driver name */
p1=strtok(NULL,"");
strcpy(tmp2,p1);
strip_string(tmp2);
/* now tmp2 contains the description */
/* cut "driver for" away */
if (strncmp(tmp2,"driver for ",11) == 0 ){
strcpy(tmp,tmp2+11);
strcpy(tmp2,tmp);
}
/* allocate structure */
drivers[drvcount]=g_new(writer_driver_t,1);
n = strlen(drv)+1;
drivers[drvcount]->driver=g_new(gchar,n);
strcpy(drivers[drvcount]->driver,drv);
n = strlen(tmp2)+1;
drivers[drvcount]->desc=g_new(gchar,n);
strcpy(drivers[drvcount]->desc,tmp2);
drvcount++;
if (drvcount >= MAXDRIVERS) {
g_error("Error: More than %d writer devices found\n",MAXDRIVERS);
}
}
}
/* print memory-structure with drivers (debug purposes) */
static void print_drivers() {
gint count;
dodebug(2,"------ cdrecord drivers-structure -----\n");
count = 0;
while(drivers[count] != NULL) {
dodebug(2, "%s:%s\n",
drivers[count]->driver,
drivers[count]->desc);
count++;
}
}
/* call cdrecord driver=help */
void scandrivers() {
gchar line[MAXLINE];
FILE *fpin;
/* allocate memory */
drivers = g_new0(writer_driver_t *,MAXDRIVERS);
drvcount = 0;
get_wrap_path_cdrecord(line);
strcat(line," driver=help 2>&1");
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10, "driverlist: %s",line);
parse_driver(line);
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
if (debug) print_drivers();
}
/* print memory-structure with charsets (debug purposes) */
static void print_charsets() {
gint count;
gchar tmp[MAXLINE];
dodebug(2,"------ mkisofs-charsets-structure -----\n");
count = 0;
strcpy(tmp,"");
while(charset_types[count] != NULL) {
strcat(tmp,charset_types[count]);
if ((count+1) % 6) {
strcat(tmp, ", ");
} else {
dodebug(2, "%s\n", tmp);
strcpy(tmp,"");
}
count++;
}
if (strcmp(tmp,"") != 0)
dodebug(2, "%s\n", tmp);
}
/* call mkisofs -input-charset help */
void scancharsets() {
gchar line[MAXLINE];
FILE *fpin;
gint start,count,backcount;
gchar **tmp_types;
/* allocate memory */
charset_types = g_new0(gchar *,MAXCHARSETS+1);
tmp_types = g_new0(gchar *,MAXCHARSETS+1);
start = 0;
count = 0;
get_wrap_path("MKISOFS",line);
strcat(line," -input-charset help 2>&1");
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
/* wait for Known charsets.... line */
if (strncmp("Known",line,5) == 0) {
start = 1;
continue;
}
if (start) {
dodebug(10, "mkisofs charsets: %s",line);
tmp_types[count] = g_strdup(strip_string(line));
count++;
if (count >= MAXCHARSETS) {
g_error("Error: More than %d input charsets found\n",MAXCHARSETS);
}
}
}
tmp_types[count] = g_strdup("default");
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
/* now the types list is reversed, make it right */
backcount = count;
count = 0;
while(backcount >= 0) {
charset_types[count] = tmp_types[backcount];
count++;
backcount--;
}
g_free(tmp_types);
if (debug) print_charsets();
}
/* call cdrecord -prcap to get some device information */
/* also checks for mmap errors and return 1 if one occured */
static gint getdevicecap(gchar *dev, gint *readmax, gint *cdrmax, gint *dvdmax, gint *iscdr, gint *isdvdrom, gint *isdvdr) {
gchar tmp[MAXLINE];
gchar line[MAXLINE];
gint tmpnr, errcount;
FILE *fpin;
gchar *p;
/* set reasonable defaults */
*readmax = 0;
*cdrmax = 0;
*dvdmax = 0;
*iscdr = 0;
*isdvdr = 0;
*isdvdrom = 0;
if (!dev) return 0;
get_wrap_path_cdrecord(tmp);
g_snprintf(line, MAXLINE, "%s dev= \"%s\" -prcap 2>&1", tmp, dev);
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
errcount = 0;
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10, "prcap: %s",line);
/* line with mmap error? */
if (strstr(line,"annot get mmap for")) {
errcount++;
}
if (strstr(line, "Does write CD-R media")) {
*iscdr = 1;
}
if (strstr(line, "Does read DVD-ROM media")) {
*isdvdrom = 1;
}
if (strstr(line, "Does write DVD-R media")) {
*isdvdr = 1;
}
if (strstr(line, "Maximum read speed:")) {
p = strtok(line,"(");
if (p) {
p = strtok(NULL,")");
if (p) {
strcpy(tmp,p);
sscanf(tmp,"CD %3dx, DVD %3d",
readmax, &tmpnr);
}
}
} else
if (strstr(line, "Maximum write speed:")) {
p = strtok(line,"(");
if (p) {
p = strtok(NULL,")");
if (p) {
strcpy(tmp,p);
sscanf(tmp,"CD %3dx, DVD %3d",
cdrmax, dvdmax);
}
}
}
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
if (errcount > 0) {
return 1;
} else {
return 0;
}
}
/* get driverflags and modes from drive */
void getmodesflags(gchar *dev, gchar *drvflags, gchar *drvmodes) {
gchar tmp[MAXLINE];
gchar line[MAXLINE];
FILE *fpin;
gchar *p;
strcpy(drvflags,"");
strcpy(drvmodes,"");
if (!dev) return;
/* if prodvd available use it to get additional info */
get_wrap_path_cdrecord(tmp);
g_snprintf(line, MAXLINE, "%s dev= \"%s\" -v -checkdrive 2>&1", tmp, dev);
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10, "checkdrive: %s",line);
if (strstr(line, "Driver flags :")) {
p = strtok(line,":");
if (p) {
p = strtok(NULL,"");
if (p) {
strncpy(tmp,p,MAXLINE);
strip_string(tmp);
strncpy(drvflags,tmp,MAXLINE);
}
}
} else
if (strstr(line, "Supported modes:")) {
p = strtok(line,":");
if (p) {
p = strtok(NULL,"");
if (p) {
strncpy(tmp,p,MAXLINE);
strip_string(tmp);
strncpy(drvmodes,tmp,MAXLINE);
}
}
}
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
}
static gint parse_freespace(gchar *line, gchar *fs) {
gchar tmp[MAXLINE];
gchar *p1;
/* skip first line(s) */
if (index(line,'/')) {
strcpy(tmp,line);
#if defined (aix)
/* filesystem label */
p1=strtok(tmp," ");
if (fs != NULL) {
/* get the filesystem */
strcpy(fs,p1);
}
/* size of filesystem */
p1=strtok(NULL," ");
if (p1 == NULL) {
g_error("df -k output syntax error\n");
}
/* available blocks */
p1=strtok(NULL," ");
if (p1 == NULL) {
g_error("df -k output syntax error\n");
}
return (atoi(p1));
#elif defined (hpux)
/* mountpoint */
p1=strtok(tmp,"(");
if (p1 == NULL) {
g_error("df -b output syntax error\n");
}
/* filesystem label */
p1=strtok(NULL,")");
if (fs != NULL) {
/* get the filesystem - avoid "(" at the beginning */
strcpy(fs,p1);
}
/* size in kb */
p1=strtok(NULL,": ");
if (p1 == NULL) {
g_error("df -b output syntax error\n");
}
return (atoi(p1));
#else
/* skip the first 4 fields in output to come to "available" */
/* are we handling the first line of two?*/
p1=strtok(tmp," ");
if (dfrun == 0) {
if (fs != NULL) {
/* get the filesystem */
strcpy(fs,p1);
}
p1=strtok(NULL," ");
if (p1 == NULL) {
/* ok..output splitted on two lines */
dfrun = 1;
return -1;
}
}
p1=strtok(NULL," ");
if (p1 == NULL) {
g_error("df -k output syntax error\n");
}
p1=strtok(NULL," ");
if (p1 == NULL) {
g_error("df -k output syntax error\n");
}
return (atoi(p1));
#endif
}
return -1;
}
/* get free diskspace. return in 1024byte blocks or -1 if not valid */
/* return filesystem if not set to NULL */
/* will handle if output is in two lines...like when the filesystem
output is longer that 20 chars - e.g. on nfs-links */
/* will handle df-output like:
(Solaris)
Filesystem kbytes used avail capacity Mounted on
fileserv:/export/home
17502608 11609120 5718464 67% /export/home
OR
(Linux)
Filesystem 1024-blocks Used Available Capacity Mounted on
/dev/sda3 2494898 1606489 759428 68% /
Système de
fichiers 1K-blocs Utilisé Disponible U.% Monté sur
/dev/hda6 10080488 8043456 1524964 85% /
OR
(AIX)
Filesystem 1024-blocks Free %Used Iused %Iused Mounted on
/dev/hd4 8192 2968 64% 1319 33% /
/dev/hd2 573440 31644 95% 22280 16% /usr
OR
(HP-UXs df -b)
/tmp (/dev/vg00/lvol4 ) : 188158 Kbytes free
/usr (/dev/vg00/lvol5 ) : 286696 Kbytes free
*/
gint get_free_space(gchar *path, gchar *filesystem) {
gchar line[MAXLINE];
FILE *fpin;
gint space;
space = -1;
dfrun = 0;
if (is_directory(path) != 1) {
return -1;
}
if (stat_file(DF)) {
strcpy(line,DF);
strcat(line," \"");
strcat(line,path);
strcat(line,"\"");
} else {
strcpy(line,DF2);
strcat(line," \"");
strcat(line,path);
strcat(line,"\"");
}
dodebug(1, "calling: %s\n", line);
if ((fpin = popen(line,"r")) == NULL) {
g_error("popen error\n");
}
for (;;) {
if (fgets(line,MAXLINE,fpin) == NULL)
break;
dodebug(10,"df: %s",line);
space = parse_freespace(line,filesystem);
}
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
if (filesystem != NULL) {
dodebug(2, "filesystem lookup for %s = %d blocks, fs = %s\n",
path, space, filesystem);
} else {
dodebug(2, "filesystem lookup for %s = %d blocks, fs = %s\n",
path, space, "(NULL)");
}
return space;
}
/* get a list of all audio-devices found on a system. This has to be
done platform dependent */
GList *get_dsp_devices() {
GList *dsp;
GList *loop;
#if !(defined(__MACH__) && defined(__APPLE__))
struct stat buf;
#endif
#if defined(sun) || defined(aix) || defined(__OpenBSD__)
gchar *audiodev;
#endif
dsp = NULL;
#if defined(linux) || defined(__FreeBSD__)
/* for linux check if /dev/dsp or /dev/dsp1 exist */
if (stat("/dev/dsp",&buf) == 0) {
dsp = g_list_append(dsp,"/dev/dsp");
}
if (stat("/dev/dsp1",&buf) == 0) {
dsp = g_list_append(dsp,"/dev/dsp1");
}
#endif
#if defined(sun) || defined(__OpenBSD__)
/* check if the user has any special audio-hardware running,
which set the AUDIODEV-environment-variable */
audiodev = getenv("AUDIODEV");
if (audiodev != NULL) {
if (stat(audiodev,&buf) == 0) {
dsp = g_list_append(dsp,g_strdup(audiodev));
}
} else {
audiodev = "";
}
if (strcmp(audiodev,"/dev/audio") != 0) {
if (stat("/dev/audio",&buf) == 0) {
dsp = g_list_append(dsp,"/dev/audio");
}
}
#endif
#ifdef aix
audiodev = getenv ("AUDIODEV");
if (audiodev != NULL) {
if (stat (audiodev, &buf) == 0) {
dsp = g_list_append (dsp, g_strdup(audiodev));
}
}
/* Try to use the device of a machine with PCI bus */
if (stat ("/dev/paud0/1", &buf) == 0) {
dsp = g_list_append (dsp, "/dev/paud0/1");
}
/* Try to use the device of a machine with MCA bus */
if (stat ("/dev/baud0/1", &buf) == 0) {
dsp = g_list_append (dsp, "/dev/baud0/1");
}
#endif
#ifdef hpux
# ifndef hpux_alib
/* for HP-UX check if /dev/audio exists - I've never seen */
/* other audio devices under HP-UX */
if (stat("/dev/audio",&buf) == 0) {
dsp = g_list_append(dsp,"/dev/audio");
}
# else
/* for HP-UX with the Alib we dont need to check if the */
/* device exists - we actually do not know even the device */
dsp = g_list_append(dsp,"AUDIO ENVIRONMENT");
# endif
#endif
#if (defined(__MACH__) && defined(__APPLE__))
/* on macosX we always should have the build-in-audio device */
dsp = g_list_append(dsp,"Apple CoreAudio");
#endif
#if defined(__sgi)
{
int i, rv;
ALvalue devs [16];
ALpv q [1];
char devLabel [32];
/*
* Fetch the list of available output audio devices.
*/
q[0].param = AL_TYPE;
q[0].value.i = AL_OUTPUT_DEVICE_TYPE;
if ((rv = alQueryValues(AL_SYSTEM, AL_DEVICES, devs, 16, q, 1)) >= 0) {
for (i = 0; i < rv; i++) {
q[0].param = AL_LABEL;
q[0].value.ptr = devLabel;
q[0].sizeIn = 32;
alGetParams(devs[i].i, q, 1);
if (alIsSubtype(AL_DEVICE_TYPE, devs[i].i)) {
dsp = g_list_append(dsp, g_strdup(devLabel));
}
}
}
}
#endif
/* do some debug output */
if (debug) {
loop = g_list_first(dsp);
while(loop) {
if (loop->data != NULL)
dodebug(10, "dspscan: %s\n",
(gchar *) loop->data);
loop = loop->next;
}
}
return g_list_first(dsp);
}
/* take a dsp-device and find the fitting mixer-device */
gchar *gen_mix_from_dspdev(gchar *dsp, gchar *ret) {
#if !(defined(__MACH__) && defined(__APPLE__))
gchar tmp[MAXLINE];
# ifndef aix
struct stat buf;
# endif
#endif
#if defined(linux) || defined(__FreeBSD__)
gchar tmp2[MAXLINE];
#endif
strcpy(ret,"");
#if defined(linux) || defined(__FreeBSD__)
if (strncmp(dsp,"/dev/dsp",8) == 0) {
strcpy(tmp,dsp+8);
g_snprintf(tmp2,MAXLINE,"/dev/mixer%s",tmp);
/* does device exist? */
if (stat(tmp2,&buf) == 0) {
strcpy(ret,tmp2);
}
}
#endif
#if defined(sun) || defined(__OpenBSD__)
g_snprintf(tmp,MAXLINE,"%s%s",dsp,"ctl");
/* does device exist? */
if (stat(tmp,&buf) == 0) {
strcpy(ret,tmp);
}
#endif
#ifdef aix
/* The gain will be set via ioctl and the usual */
/* output device */
g_snprintf(tmp,MAXLINE,"%s",dsp);
strcpy(ret,tmp);
#endif
#ifdef hpux
# ifndef hpux_alib
g_snprintf(tmp,MAXLINE,"%s%s",dsp,"Ctl");
/* does device exist? */
if (stat(tmp,&buf) == 0) {
strcpy(ret,tmp);
}
# else
/* We have no control or mixer device -> all is */
/* done via the Aserver-daemon and its API */
strcpy(ret, "ASERVER");
# endif
#endif
dodebug(10, "mixer: %s\n", ret);
return ret;
}
/* call uname -a to get a nice system-id-string */
gchar *get_uname_info(gchar *str) {
FILE *fpin;
if (stat_file(UNAME)) {
dodebug(1, "calling: %s\n", UNAME);
if ((fpin = popen(UNAME,"r")) == NULL) {
g_error("popen error\n");
}
} else {
dodebug(1, "calling: %s\n", UNAME2);
if ((fpin = popen(UNAME2,"r")) == NULL) {
g_error("popen error\n");
}
}
strcpy(str,"");
fgets(str,MAXLINE,fpin);
if (pclose(fpin) == -1) {
g_error("pclose error\n");
}
dodebug(10, "uname: %s\n", str);
return str;
}
/* Save the setup-configuration to a file - all strings are converted
in a printable form first: return 0 if ok, or 1 on error */
gint save_setup_config(gchar *confdir, gchar *fname) {
FILE *fd;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
GList *loop;
gint count;
/* no confdir? treat path absolute */
if (strcmp(confdir,"") == 0) {
strncpy(tmp,fname,MAXLINE);
} else {
/* now check if the confdir exists */
if (!is_directory(confdir)) {
/* try to create directory */
mkdir(confdir, 0700);
dodebug(2, "trying to mkdir %s\n", confdir);
}
g_snprintf(tmp,MAXLINE,"%s/%s", confdir, fname);
}
dodebug(1, "Opening %s for writing\n", tmp);
dolog(3, "Saving config file %s\n", tmp);
fd = fopen(tmp,"w");
if (fd == NULL) {
/* error opening file */
return 1;
}
/* write the config-file header */
fputs("#\n",fd);
g_snprintf(tmp,MAXLINE,"# X-CD-Roast %s Configuration-File\n",XCDROAST_VERSION);
fputs(tmp,fd);
fputs("#\n",fd);
fputs("# Automatically created by the X-CD-Roast-Setup\n",fd);
fputs("# Don't edit! (Unless you REALLY know what you are doing)\n",fd);
fputs("#\n\n",fd);
/* write data */
g_snprintf(tmp,MAXLINE,"VERSION = \"%s\"\n",XCDROAST_VERSION);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"PLATFORM = \"%s\"\n",system_platform);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITER_DEVNR = %d\n",setupdata.writer_devnr);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"READER_DEVNR = %d\n",setupdata.reader_devnr);
fputs(tmp,fd);
fputs("#\n",fd);
/* write hardware structure */
count = 0;
while(writerreaderdevs[count] != NULL) {
g_snprintf(tmp,MAXLINE,"WRITERREADER_DEVNR = %d\n",writerreaderdevs[count]->devnr);
fputs(tmp,fd);
strcpy(tmp2,writerreaderdevs[count]->devicestr);
g_snprintf(tmp,MAXLINE,"WRITERREADER_DEVICESTR = \"%s\"\n",convert_escape(tmp2));
fputs(tmp,fd);
strcpy(tmp2,writerreaderdevs[count]->vendor);
g_snprintf(tmp,MAXLINE,"WRITERREADER_VENDOR = \"%s\"\n",convert_escape(tmp2));
fputs(tmp,fd);
strcpy(tmp2,writerreaderdevs[count]->model);
g_snprintf(tmp,MAXLINE,"WRITERREADER_MODEL = \"%s\"\n",convert_escape(tmp2));
fputs(tmp,fd);
strcpy(tmp2,writerreaderdevs[count]->rev);
g_snprintf(tmp,MAXLINE,"WRITERREADER_REV = \"%s\"\n",convert_escape(tmp2));
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_READMAXSPEED = %d\n",writerreaderdevs[count]->writer_readmaxspeed);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_CDRMAXSPEED = %d\n",writerreaderdevs[count]->writer_cdrmaxspeed);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_DVDMAXSPEED = %d\n",writerreaderdevs[count]->writer_dvdmaxspeed);
fputs(tmp,fd);
strcpy(tmp2,writerreaderdevs[count]->writer_flags);
g_snprintf(tmp,MAXLINE,"WRITERREADER_WRITER_FLAGS = \"%s\"\n",convert_escape(tmp2));
fputs(tmp,fd);
strcpy(tmp2,writerreaderdevs[count]->writer_modes);
g_snprintf(tmp,MAXLINE,"WRITERREADER_WRITER_MODES = \"%s\"\n",convert_escape(tmp2));
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_IS_CDRWRITER = %d\n",writerreaderdevs[count]->is_cdrwriter);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_IS_DVDWRITER = %d\n",writerreaderdevs[count]->is_dvdwriter);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_IS_DVDREADER = %d\n",writerreaderdevs[count]->is_dvdreader);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_SECTOR_SIZE = %d\n",writerreaderdevs[count]->sector_size);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_DRVMODE = %d\n",writerreaderdevs[count]->writer_drvmode);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_MODE = %d\n",writerreaderdevs[count]->writer_mode);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_SPEED = %d\n",writerreaderdevs[count]->writer_speed);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_FIFO = %d\n",writerreaderdevs[count]->writer_fifo);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_AUDIOREAD_INTERFACE = %d\n",writerreaderdevs[count]->audioread_interface);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_AUDIOREAD_SPEED = %d\n",writerreaderdevs[count]->audioread_speed);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER_AUDIOREAD_OVERLAP = %d\n",writerreaderdevs[count]->audioread_overlap);
fputs(tmp,fd);
g_snprintf(tmp,MAXLINE,"WRITERREADER