📄 io.c
字号:
/* io.c All the functions that interact with hardware and subprocesses and file IO. 28.3.99 tn*/#include <stdio.h>#include <string.h>#include <strings.h>#include <stdlib.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>#include <time.h>#ifdef linux#include <sys/soundcard.h>#include <sys/ioctl.h>#endif#ifdef sun #include <sys/audioio.h>#endif#ifdef hpux #include <sys/audio.h>#endif#include <gtk/gtk.h>#include <gdk/gdk.h>#include <glib.h>#include "xcdroast.h"#include "main.h"scsi_devices_t **scsidevices;gint scsicount;gint busnr;cd_info_t cdinfo;track_info_t **trackinfo;gint tocstate;gint tocnr;writer_driver_t **drivers;writer_driver_t **blankmodes;writer_driver_t **drv_options;gint drvcount;gint drvoptcount;gint dfrun;gint readcdda_callback;gint readcdda_callback2;gint readcdda_callback3;gint read_done;gint read_output_ctrl;gint read_abort_mark;gint read_tracknr;gchar readtrack_info_string[1024];gfloat pct_so_far, pct_this_track;write_track_param_t writeparams;pid_t readcdda_pid;gint readcd_startsector, readcd_endsector;gint readerr_count;gint matchnr;gint cddb_in;gchar cdinfo_cddb_title_bak[MAXLINE];gint cd_is_still_the_same;gint cdrecord_stdin, cdrecord_reload;gchar xcdroast_version_loaded[MAXLINE];extern gint debug;extern gint ignorescanbus;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 *readtrack_info_label, *readtrack_textview;extern GtkWidget *readtrack_pbar1, *readtrack_pbar2, *readtrack_pbar3;extern GtkWidget *readtrack_small_info, *readtrack_small_info2;extern gchar hostname[MAXLINE];extern gchar username[MAXLINE];extern gchar sharedir[MAXLINE];extern GtkWidget *cddb_info_label;extern GtkCList *cddb_clist;extern master_param_t masterparam;void verify_readcd_err(gpointer pid, gint source, GdkInputCondition cond);/* convert device-type-names back to numeric *//* -1 means unknown */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 */void get_scsi_type_string(gchar *str, gint type, gint removeable) { switch(type) { case 0: if (removeable == 0) { strcpy(str,text(250)); } else { strcpy(str,text(251)); } break; case 1: strcpy(str,text(252)); break; case 2: strcpy(str,text(253)); break; case 3: strcpy(str,text(254)); break; case 4: strcpy(str,text(255)); break; case 5: strcpy(str,text(256)); break; case 6: strcpy(str,text(257)); break; case 7: strcpy(str,text(258)); break; case 8: strcpy(str,text(259)); break; case 9: strcpy(str,text(260)); break; default: strcpy(str,""); break; }}/* get model-str dynamic..some devices dont use all 16 chars */gint get_model_str(gchar *model, gchar *in) {gint i; for (i = 0; i < strlen(in); i++) { if (in[i] == '\'') { strncpy(model, in, i); strncat(model," ",16-i); model[16] = '\0'; return (i+3); } } return 0;}/* interpret output of -scanbus and sort into memory structure */void parse_scan(gchar *line) {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 increment; /* skip header */ if (strncmp(line,"Cdrecord",8) == 0) { return; } 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); if (strncmp(line, tmp, strlen(tmp)) == 0) { return; } /* a line with device-info found (by checking for ")")*/ p1 = index(line,')'); if (p1 != NULL) { strip_string(line); /* get scsi-id */ p1=strtok(line,")"); 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,"'"); 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,""); strcpy(tmp,p1); if (*tmp == '\'') { /* empty device found? ignore */ return; } /* get vendor */ strncpy(s_vendor,tmp,8); s_vendor[8] = '\0'; if (tmp[8] != '\'') { g_error("cdrecord -scanbus output syntax error\n"); } /* get model */ strcpy(tmp2,tmp+11); strcpy(tmp,tmp2); increment = get_model_str(s_model,tmp); if (s_model[16] != '\0') { g_error("cdrecord -scanbus output syntax error\n"); } /* get revision */ strcpy(tmp2,tmp+increment); strcpy(tmp,tmp2); /* empty revision? */ if (strncmp(tmp,"'",1) == 0) { strcpy(s_rev,""); increment = 2; } else { strncpy(s_rev,tmp,4); s_rev[4] = '\0'; if (tmp[4] != '\'') { g_error("cdrecord -scanbus output syntax error\n"); } increment = 6; } /* get type */ strcpy(tmp2,tmp+increment); 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); scsidevices[scsicount]->devnr = busnr*32+s_id; 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) */void print_scsidevices() {gint count; dodebug(2,"------ cdrecord scsidevices-structure -----\n"); count = 0; while(scsidevices[count] != NULL) { dodebug(2,"%d:%d %s %s %s %d,%d\n", scsidevices[count]->bus, scsidevices[count]->id, scsidevices[count]->vendor, scsidevices[count]->model, scsidevices[count]->rev, scsidevices[count]->removable, scsidevices[count]->type); count++; }}/* call cdrecord -scanbus *//* does rely very strict on the output-format... does use fixed length deleminitors to be sure that quotes within an id-string will handled fine - therefore no strtok usage */ void scanbus() {gchar line[MAXLINE];FILE *fpin; /* allocate memory */ scsidevices = g_new0(scsi_devices_t *,MAXDEVICES); scsicount = 0; get_spawn_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); } if (pclose(fpin) == -1) { g_error("pclose error\n"); } if (debug) print_scsidevices(); /* no devices found? */ if (scsicount == 0 && ignorescanbus == 0) { g_warning("Failed to scan the SCSI-bus. Either no permission to access the\ngeneric scsi devices or no SCSI support in the kernel.\n(For ATAPI (IDE) devices you need to install SCSI-Emulation first)\n(You can start X-CD-Roast anyway with the -i option)\n"); gtk_exit(1); }}/* interpret output of driver=help and sort into memory structure */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) */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_spawn_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 driver-options (debug purposes) */void print_drv_options() {gint count; dodebug(2,"------ cdrecord drivers-options-structure -----\n"); if (drv_options == NULL) return; count = 0; while(drv_options[count] != NULL) { dodebug(2, "%s:%s\n", drv_options[count]->driver, drv_options[count]->desc); count++; }}/* allocate memory and sort data into driver-opts-structure */void add_drv_option(gchar *opt, gchar *desc) { strip_string(opt); strip_string(desc); /* no option found? */ if (strcmp(opt,"None") == 0) return; /* first option? allocate memory */ if (drvoptcount == 0) { drv_options = g_new0(writer_driver_t *,MAXDRIVERS); } drv_options[drvoptcount] = g_new(writer_driver_t,1); drv_options[drvoptcount]->driver = g_strdup(opt); drv_options[drvoptcount]->desc = g_strdup(desc); drvoptcount++; if (drvoptcount >= MAXDRIVERS) { g_error("Error: More than %d writer driver-options found\n",MAXDRIVERS); }}/* call cdrecord driveropts=help */void scanoptions(gint write_devnr) {gchar tmp[MAXLINE];gchar tmp2[MAXLINE];gchar line[MAXLINE];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -