int add_argv (char **dest, char *content) { size_t i; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); i = 0; while (content[i++] != '\0'); if ((*dest = malloc (i)) == NULL) { err_handler (GTK_WINDOW(main_window), MALLOC_ERR, NULL); return FALSE; } strcpy (*dest, content); return TRUE; }
int create_file_names_for_track (_main_data * main_data, int track, char **wfp, char **efp) { static char *buffer; int rc; char *conv_str = NULL; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); rc = parse_rx_format_string (&buffer, ((char *) config_read (CONF_CDDB_FORMATSTR)), track, main_data->disc_artist, main_data->disc_title, main_data->disc_year, main_data->track[track].title); if (rc < 0) { err_handler (GTK_WINDOW(main_window), RX_PARSING_ERR, _ ("Check if the filename format string contains format characters other than %a %# %v %y or %s.")); return 0; } if (buffer[0] == 0) strcpy (buffer, main_data->track[track].title); conv_str = g_locale_from_utf8 (buffer, -1, NULL, NULL, NULL); remove_non_unix_chars (conv_str); convert_slashes (conv_str, '-'); if ((int) config_read (CONF_GNRL_CONVSPC)) { convert_spaces (conv_str, '_'); } if (wfp) mk_strcat (wfp, wd, conv_str, wfext, NULL); if (efp) mk_strcat (efp, ed, conv_str, ecfext, NULL); g_free (conv_str); return 1; }
void read_an_item (int item_num, char *src) { char *str; char *p_char; float *p_float; int *p_int; int i, len; GtkWindow *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); switch (config_rw_data[item_num].type) { case STRING: str = (char *) config_rw_data[item_num].m_id; strcpy (str, src); /* Strip \n */ len = strlen (str); for (i = 0; i < len && str[i] != '\0'; i++) if (str[i] == '\n') str[i--] = '\0'; break; case CHAR: p_char = (char *) config_rw_data[item_num].m_id; *p_char = src[0]; break; case FLOAT: p_float = (float *) config_rw_data[item_num].m_id; sscanf (src, "%f", p_float); break; case INT: p_int = (int *) config_rw_data[item_num].m_id; sscanf (src, "%d", p_int); break; default: err_handler (GTK_WINDOW(main_window), CONFIG_PARSE_ERR, NULL); break; } }
int process_options (char *options, char **argv, int start, int end) { int current, i, j, flag; char buf[MAX_SINGLE_OPTION_LENGTH]; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); current = start; i = 0; while (options[i] != '\0') { while (isspace (options[i])) i++; j = 0; flag = 0; while (!isspace (options[i]) && options[i] != '\0' && j < MAX_SINGLE_OPTION_LENGTH - 1) { /* It really has something other than spaces */ flag = 1; buf[j++] = options[i++]; } buf[j] = '\0'; /* If it really has something */ if (flag) { if (current < end) { if (add_argv (&argv[current], buf) == FALSE) return -1; } else { err_handler (GTK_WINDOW(main_window), TOO_MANY_ARGS_ERR, NULL); } current++; } } return current - start; }
void read_config (void) { FILE *file; char buf[MAX_CONFIG_LINE_LENGTH + 1]; int i, offset; int flag; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); memset (&config, 0, sizeof (_config)); file = fopen (construct_file_name (getenv ("HOME"), ".ripperXrc"), "r"); if (file == NULL) { config_to_default (-1); if (errno != ENOENT) { err_handler (GTK_WINDOW(main_window), CONFIG_OPEN_ERR, NULL); return; } write_config (); return; } while (fgets (buf, sizeof (buf), file) != NULL) { /* Comments */ if (strncasecmp ("//", buf, 2) == 0) continue; for (i = 0, offset = 0; i < num_entry && offset == 0; i++) { /* Find the match */ if (strncasecmp (config_rw_data[i].f_id, buf, strlen (config_rw_data[i].f_id)) == 0) { /* General::WavRatio = asdf... */ offset += strlen (config_rw_data[i].f_id); while (buf[offset++] != '='); } } i--; /* Mark that this field has been read */ config_rw_data[i].flag = TRUE; /* Skip blank lines */ if (is_str_blank (buf + offset)) continue; /* Skip spaces */ while (isspace (buf[offset++])); offset--; read_an_item (i, buf + offset); } for (i = 0, flag = FALSE; i < num_entry; i++) { if (config_rw_data[i].flag == FALSE) { flag = TRUE; config_to_default (i); } } if (flag) err_handler (GTK_WINDOW(main_window), CONFIG_EMPTY_ITEM_ERR, ""); return; }
void write_config (void) { FILE *file; int fd; int i; char *str; char t_char; float t_float; int t_int; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); fd = open (construct_file_name (getenv ("HOME"), ".ripperXrc"), O_WRONLY | O_TRUNC); if (fd < 0) { if (errno == ENOENT) { if (dialog_handler (WIDGET_CREATE, FALSE, DL_CREATE_CONFIG_CONFIRM, FALSE, NULL, NULL, 0) == FALSE) return; fd = open (construct_file_name (getenv ("HOME"), ".ripperXrc"), O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { err_handler (GTK_WINDOW(main_window), CONFIG_CREATION_ERR, ""); return; } } else err_handler (GTK_WINDOW(main_window), CONFIG_OPEN_ERR, ""); } if ((file = fdopen (fd, "w")) == NULL) { err_handler (GTK_WINDOW(main_window), FDOPEN_ERR, "Cannot re-open config file as a stream"); close (fd); return; } fputs ("//\n", file); fputs ("// ~/.ripperXrc\n", file); fputs ("// This is the resource file for ripperX.\n", file); fputs ("// If you edit this file with an editor, you must leave all\n", file); fputs ("// parameters in the order in which they appear. Also note\n", file); fputs ("// that this file is overwritten each time ripperX is run.\n", file); fputs ("//\n// You can configure everything in the config menu within ripperX.\n", file); fputs ("//\n\n", file); fprintf (file, "//-V %s\n\n", VERSION); for (i = 0; i < num_entry; i++) { switch (config_rw_data[i].type) { case STRING: str = (char *) config_rw_data[i].m_id; fprintf (file, "%s = %s\n", config_rw_data[i].f_id, str); break; case CHAR: t_char = *(char *) config_rw_data[i].m_id; fprintf (file, "%s = %c\n", config_rw_data[i].f_id, t_char); break; case FLOAT: t_float = *(float *) config_rw_data[i].m_id; fprintf (file, "%s = %f\n", config_rw_data[i].f_id, t_float); break; case INT: t_int = *(int *) config_rw_data[i].m_id; fprintf (file, "%s = %d\n", config_rw_data[i].f_id, t_int); break; } } fclose (file); return; }
int create_filenames_from_format (_main_data * main_data) { int i; int rc2; static unsigned char *df; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); char *rip_path = (char *) config_read (CONF_GNRL_RIP_PATH); char *enc_path = (char *) config_read (CONF_GNRL_ENC_PATH); i = strlen (rip_path) - 1; if (i >= 0 && rip_path[i] == '/') rip_path[i] = 0; i = strlen (enc_path) - 1; if (i >= 0 && enc_path[i] == '/') enc_path[i] = 0; char *dirformat = (char *) config_read (CONF_CDDB_DIRFORMATSTR); char *rip_path = (char *) config_read (CONF_GNRL_RIP_PATH); char *enc_path = (char *) config_read (CONF_GNRL_ENC_PATH); if (((char *) config_read (CONF_CDDB_MKDIRS)) && dirformat[0]) { rc2 = parse_rx_format_string (&df, dirformat, -1, main_data->disc_artist, main_data->disc_title, main_data->disc_year, ""); if (rc2 < 0) { err_handler (GTK_WINDOW(main_window), RX_PARSING_ERR, "Check if the directory format string contains format characters other than %a %# %v %y or %s."); return 0; } remove_non_unix_chars (df); if ((int) config_read (CONF_CDDB_CONVSPC)) { convert_spaces (df, '_'); } if (strlen (df) > 0) { mk_strcat (&wd, rip_path, "/", df, "/", NULL); mk_strcat (&ed, enc_path, "/", df, "/", NULL); create_dir (wd); create_dir (ed); } else { mk_strcat (&wd, rip_path, "/", NULL); mk_strcat (&ed, enc_path, "/", NULL); } } else { mk_strcat (&wd, rip_path, "/", NULL); mk_strcat (&ed, enc_path, "/", NULL); } if ((int) config_read (CONF_GNRL_APP_FILE_EXT)) { wfext = ".wav"; char *encoder_type = (char *) config_read (CONF_ENCOD_TYPE); if (encoder_type == OGG) ecfext = ".ogg"; else if (encoder_type == FLAC) ecfext = ".flac"; else if (encoder_type == MP2) ecfext = ".mp2"; else if (encoder_type == MUSE) ecfext = ".mpc"; else ecfext = ".mp3"; } else wfext = ecfext = ""; return 1; }
/* called after all jobs are finshed. Files are cleaned up and renamed */ void job_finisher(_main_data *main_data) { int i; static char status_message[(MAX_FILE_PATH_LENGTH + MAX_FILE_NAME_LENGTH) * MAX_NUM_TRACK ]; static char buffer[(MAX_FILE_PATH_LENGTH + MAX_FILE_NAME_LENGTH) * MAX_NUM_TRACK ]; static char *wav_file, *enc_file; int madewavs = FALSE; int mademp3s = FALSE; int tracksdone = 0; char *s_track_num; char *artist; ID3Tag *myTag; FILE *fp_playlist = NULL; char playlist_filespec[ MAX_FILE_PATH_LENGTH + MAX_FILE_NAME_LENGTH ]; /* Allocate space dynamically. This is overkill, but certainly won't be a problem. */ s_track_num = (char *) malloc((main_data->num_tracks + 2) * sizeof(char)); buffer[0] = 0; /* Clean up */ for(i = 0; i < main_data->num_tracks; i++) { create_file_names_for_track(main_data, i, &wav_file, &enc_file); if(main_data->track[ i ].wav_exist == FALSE) { unlink(wav_file); } else if(main_data->track[ i ].make_wav == TRUE) { madewavs = TRUE; sprintf(&buffer[strlen(buffer)], "%d: %s\n", ++tracksdone, file_name_without_path(wav_file)); } main_data->track[ i ].make_wav = FALSE; if(main_data->track[ i ].mp3_exist == TRUE && main_data->track[ i ].make_mp3 == TRUE) { mademp3s = TRUE; /* add ID3 tag if requested */ if(config.cddb_config.create_id3 == TRUE) { if(!(artist = main_data->track[ i ].artist)) { artist = main_data->disc_artist; } // TODO: fix this to use something like // if (main_data->encoding_type == OGG) { if(!strcmp(config.encoder.encoder, "oggenc")) { /* set VORBIS tags using vorbistag - added DATE tag - R. Turnbull 1-2-2010 */ vorbistag(enc_file, artist, main_data->disc_title, main_data->disc_year, main_data->track[i].title, id3_find_cddb_category(main_data->disc_category), i + 1); } else if(!strcmp(config.encoder.encoder, "flac")) { /* set FLAC tags using metaflac R. Turnbull 1-2-2010 */ flactag(enc_file, artist, main_data->disc_title, main_data->disc_year, main_data->track[i].title, id3_find_cddb_category(main_data->disc_category), i + 1); } else if(!strcmp(config.encoder.encoder, "mppenc")) { /* do nothing for for musepack right now - originally supported id3 now wants apev2 tags */ } else { /* assume MP3 tag is desired */ sprintf(s_track_num,"%d",(i+1)); myTag=ID3Tag_New(); ID3Tag_Link(myTag,enc_file); set_TagField(myTag, main_data->track[ i ].title, ID3FID_TITLE); set_TagField(myTag, artist, ID3FID_LEADARTIST); set_TagField(myTag, main_data->disc_title, ID3FID_ALBUM); set_TagField(myTag, main_data->disc_year, ID3FID_YEAR); set_TagField(myTag, s_track_num, ID3FID_TRACKNUM); set_TagField(myTag, main_data->disc_category, ID3FID_CONTENTTYPE); ID3Tag_UpdateByTagType(myTag, ID3TT_ID3V2); ID3Tag_Delete(myTag); } } //dc: strcat() is for sissies! sprintf(&buffer[strlen(buffer)], "%d: %s\n", ++tracksdone, file_name_without_path(enc_file)); // tm: basic playlist support - thanks to Mark Tyler if(config.cddb_config.create_playlist == TRUE) { if(fp_playlist == NULL) { sprintf(playlist_filespec, "%s/playlist.m3u", file_path_without_name(enc_file)); fp_playlist = fopen(playlist_filespec, "w"); } // if we succeeded above, we can now write to this if(fp_playlist != NULL) { fprintf(fp_playlist, "%s\n", file_name_without_path(enc_file)); } } } main_data->track[ i ].make_mp3 = FALSE; } /* end loop over all tracks */ free(s_track_num); if((config.cddb_config.create_playlist == TRUE) && (fp_playlist != NULL)) { fclose(fp_playlist); } /* Generate status message */ sprintf(status_message, _("Tracks Completed: %2d\n\nArtist: %s\nAlbum: %s\n\n%s"), tracksdone, main_data->disc_artist, main_data->disc_title, buffer); /* show status pop up */ if(madewavs) { status_handler(STAT_FINISH_WAV, status_message); } else if(mademp3s) { status_handler(STAT_FINISH_MP3, status_message); } /* Clear status bar */ main_window_handler(MW_CLEAR_STATUSBAR, NULL, NULL); /* Destroy status widget */ wm_status_frame_handler(WIDGET_DESTROY, WAV, NULL, NULL); /* Create select frame */ select_frame_handler(WIDGET_CREATE, 0, main_data); main_window_handler(MW_MODE_SELECT, NULL, NULL); }
/* this is called when the go button is clicked. The default file names are determined and the files are locked. */ void job_starter(_main_data *main_data) { int i, track, type, is_temp, code; static char *wav_file_path, *enc_file_path; /* Sync main_data structure with the data user has entered */ select_frame_handler(SF_SYNC_MAIN_DATA, 0, main_data); /* Setup directory and filename extension */ if(!create_filenames_from_format(main_data)) { return; } /* Reset exist flags */ for(i = 0; i < main_data->num_tracks; i++) { if(main_data->track[ i ].make_wav) { main_data->track[ i ].wav_exist = FALSE; } if(main_data->track[ i ].make_mp3) { main_data->track[ i ].mp3_exist = FALSE; } } /* Lock target files */ track = -1; type = WAV; while(find_next_job(main_data, track, WAV, &track, &type) >= 0) { is_temp = FALSE; if(!create_file_names_for_track(main_data, track, &wav_file_path, NULL)) { return; } code = lock_file(wav_file_path, is_temp); if(code < 0) { return; } if(code == 1) { main_data->track[ track ].make_wav = FALSE; main_data->track[ track ].wav_exist = TRUE; } } if(main_data->track[ track ].make_mp3) { track = -1; type = MP3; while(find_next_job(main_data, track, MP3, &track, &type) >= 0) { if(!create_file_names_for_track(main_data, track, NULL, &enc_file_path)) { return; } if(lock_file(enc_file_path, FALSE) < 0) { return; } } } /* Destroy select frame & change main window button state */ select_frame_handler(WIDGET_DESTROY, 0, NULL); main_window_handler(MW_MODE_STATUS, NULL, NULL); /* Start Job */ job_controller(JC_START, main_data); }
int process_cd_contents_output (_main_data * main_data, int fd) { FILE *stream; char buf[BUF_LENGTH_FOR_F_SCAN_CD]; char errmsg[1024]; int i, read_offset, track_num; char *temp; int err_code = CD_PARANOIA_MISC_ERR; // err... what should it default to? int cdparanoia_toc = FALSE; // assume failure to get the table of contents GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); /* Reopen the pipe as stream */ if ((stream = fdopen (fd, "r")) == NULL) { err_handler (GTK_WINDOW(main_window), FDOPEN_ERR, _("Cannot reopen pty as stream")); return -1; } temp = fgets (buf, sizeof (buf), stream); /* make sure we get cdparanoia, or else there is a problem */ if (strncmp ("cdparanoia III", buf, 14) != 0) { strcpy (errmsg, buf); err_handler (GTK_WINDOW(main_window), CD_PARANOIA_MISC_ERR, errmsg); return -1; } // read lines until we see "Table of contents" or another error message do { temp = fgets (buf, sizeof (buf), stream); // this is a good response if (strncmp ("Table of contents", temp, 17) == 0) { cdparanoia_toc = TRUE; break; } // there is no disc in the drive if (strncmp ("Unable to open disc.", temp, 20) == 0) { err_code = CD_PARANOIA_NO_DISC; break; } // the user does not have permissions to open the cdrom // (when -sv is not used) if (strncmp ("/dev/cdrom exists but isn\'t accessible.", temp, 39) == 0) { err_code = CD_PARANOIA_NO_PERMS; break; } // the user does not have permissions to open the cdrom // (when -d <device> is used) or the device does not exist if (strncmp ("Unable to open cdrom drive", temp, 26) == 0) { err_code = CD_PARANOIA_MISC_ERR; break; } // the user does not have permissions to open the cdrom // (when -sv is used) // OR // there are no CDROM devices available if (strncmp ("No cdrom drives accessible to", temp, 29) == 0) { err_code = CD_PARANOIA_MISC_ERR; break; } } while (temp != NULL); /* Just to be sure, If we weren't able to read from pty it may * indicate exec failure */ if (temp == NULL) { err_handler (GTK_WINDOW(main_window), PIPE_READ_ERR, NULL); return -1; } // if we didn't get a TOC, display an error message if (cdparanoia_toc != TRUE) { //strncpy( errmsg, buf, BUF_LENGTH_FOR_F_SCAN_CD ); //err_handler( err_code, errmsg ); err_handler (GTK_WINDOW(main_window), err_code, NULL); return -1; } /* Skip two more lines */ for (i = 0; i < 2; i++) fgets (buf, sizeof (buf), stream); /* Process the output from cdparanoia */ track_num = 0; temp = fgets (buf, sizeof (buf), stream); while (temp != NULL && strlen (buf) > 5) { /* fix for cdparanoia 9.7 */ if (strncmp ("TOTAL", buf, 5) != 0) { read_offset = 0; /* Skip unnecessary parts */ while (*(buf + read_offset++) != '.'); /* Read length */ sscanf (buf + read_offset, "%u", &main_data->track[track_num].length); /* Skip */ while (*(buf + read_offset++) != '['); /* Read begin */ while (*(buf + read_offset++) != ']'); sscanf (buf + read_offset, "%u", &main_data->track[track_num].begin); /* Get default track title */ strncpy (main_data->track[track_num].title, get_default_track_title (track_num), MAX_FILE_NAME_LENGTH); track_num++; } temp = fgets (buf, sizeof (buf), stream); } /* Record the number of tracks */ main_data->num_tracks = track_num; /* Record the total length */ main_data->total_length = (int) ((main_data->track[track_num - 1].begin + main_data->track[track_num - 1].length) / 75); /* Close the pipe */ fclose (stream); return 0; }
// // stdout-\ pty/tty stdout -\ pty/tty // ripper/encoder ---------> plugin ---------> ripperX // stderr-/ stderr // // // int execute_ripper_encoder_with_plugin (char *pg_com, char *pi_com, int *program_pid, int *plugin_pid, int *read_fd) { int pty_fd0, tty_fd0, pty_fd1, tty_fd1; char **program_argv, **plugin_argv; pid_t pid; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); // build argvs if ((program_argv = create_argv_for_execution_using_shell (pg_com)) == NULL) return -1; if ((plugin_argv = create_argv_for_execution_using_shell (pi_com)) == NULL) { free_argv (program_argv); return -1; } /* Open two pty/tty pairs */ if (openpty (&pty_fd0, &tty_fd0, NULL, NULL, NULL)) { free_argv (plugin_argv); free_argv (program_argv); err_handler (GTK_WINDOW(main_window), PTY_OPEN_ERR, NULL); return -1; } if (openpty (&pty_fd1, &tty_fd1, NULL, NULL, NULL)) { free_argv (plugin_argv); free_argv (program_argv); close (pty_fd0); close (tty_fd0); err_handler (GTK_WINDOW(main_window), PTY_OPEN_ERR, NULL); return -1; } // fork & exec & link plugin if ((pid = fork ()) < 0) { free_argv (plugin_argv); free_argv (program_argv); close (pty_fd0); close (tty_fd0); close (pty_fd1); close (tty_fd1); err_handler (GTK_WINDOW(main_window), FORK_ERR, NULL); return -1; } *plugin_pid = pid; if (pid == 0) { // We're in the child process // save stderr int stderr_fd; stderr_fd = dup (2); dup2 (pty_fd0, 0); dup2 (tty_fd1, 1); setpgrp (); execvp (plugin_argv[0], plugin_argv); dup2 (stderr_fd, 2); perror (_("Failed to exec plugin")); _exit (127); } // we're in the parent process close (pty_fd0); close (tty_fd1); // fork the real program if ((pid = fork ()) < 0) { free_argv (plugin_argv); free_argv (program_argv); close (tty_fd0); close (pty_fd1); kill (*plugin_pid, SIGTERM); err_handler (GTK_WINDOW(main_window), FORK_ERR, NULL); return -1; } *program_pid = pid; if (pid == 0) { // We're in the child process // save stderr int stderr_fd; stderr_fd = dup (2); dup2 (tty_fd0, 1); dup2 (tty_fd0, 2); setpgrp (); execvp (program_argv[0], program_argv); dup2 (stderr_fd, 2); perror (_("Failed to exec the specified program")); _exit (127); } close (tty_fd0); free_argv (plugin_argv); free_argv (program_argv); *read_fd = pty_fd1; return 0; }
int scan_cd (_main_data * main_data) { pid_t pid; char **argv; char tmp[MAX_COMMAND_LENGTH]; int null_fd, pty_fd, tty_fd; int return_value; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); /* Open a pty */ if (openpty (&pty_fd, &tty_fd, NULL, NULL, NULL)) { err_handler (GTK_WINDOW(main_window), PTY_OPEN_ERR, NULL); return -1; } /* Open /dev/null */ if ((null_fd = open ("/dev/null", O_WRONLY)) < 0) { err_handler (GTK_WINDOW(main_window), NULL_OPEN_ERR, NULL); return -1; } /* Create argvs */ sprintf (tmp, "%s -Q", (char *) config_read (CONF_RPR_RIPPER)); if ((argv = create_argv_for_execution_using_shell (tmp)) == NULL) return -1; /* Fork */ if ((pid = fork ()) < 0) { err_handler (GTK_WINDOW(main_window), FORK_ERR, NULL); return -1; } if (pid == 0) { int stderr_fd; /* This code will be excuted in the child process */ /* Save stderr before attaching to the tty */ stderr_fd = dup (2); dup2 (tty_fd, 2); /* Throw away stdout to the black hole */ dup2 (null_fd, 1); /* Execute cdparanoia */ execvp (argv[0], argv); dup2 (stderr_fd, 2); perror (_("Failed to exec cdparanoia :")); _exit (127); } close (null_fd); return_value = process_cd_contents_output (main_data, pty_fd); /* Kill again the zombie */ waitpid (pid, NULL, 0); return return_value; }