int main(int argc, char** argv) { FILE* db = fopen(".nitdb", "r"); if(db == NULL) { FILE* temp = fopen(".nitdb", "w"); fclose(temp); } int socket_fd = 0, conn_fd =0; struct sockaddr_in server_addr; socket_fd = socket(PF_INET, SOCK_STREAM, 0); if(socket_fd == -1) err_handler("Failed to get socked file descriptor"); /* Zero the IPV6 compatibility bits */ memset(&server_addr, '0', sizeof(server_addr)); memset(&buf, '\0', sizeof(buf)); memset(&cmd_buf, '\0', sizeof(cmd_buf)); server_addr.sin_family = AF_INET; /* Standardize endian-ness */ server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT_NUM); if(bind(socket_fd, (struct sockaddr*) &server_addr, sizeof(server_addr)) == -1) err_handler("Failed to bind port"); if(listen(socket_fd, 10) == -1) err_handler("Failed to listen on port"); while(1) { conn_fd = accept(socket_fd, (struct sockaddr*) NULL, NULL); printf("ACCEPTED"); /* Recieve opcode */ while(recv(conn_fd, cmd_buf, BUF_SIZE, NO_FLAGS) > 0) { send(conn_fd, ACK, strlen(ACK), NO_FLAGS); memset(buf, '\0', sizeof(buf)); if(recv(conn_fd, buf, BUF_SIZE, NO_FLAGS) <= 0) { close(conn_fd); break; } send(conn_fd, ACK, strlen(ACK), NO_FLAGS); /* Take action */ if(strcmp(cmd_buf, OP_SEND_FILE) == 0) recv_file(conn_fd); if(strcmp(cmd_buf, OP_GET_FILE) == 0) send_file(conn_fd); } close(conn_fd); } return 0; }
void recv_file(int conn_fd) { /* Client sends encoded file path and permissions */ char *perm_ptr, *filepath = buf; if((perm_ptr = strstr(buf, SEPARATOR)) != NULL) { *(perm_ptr) = '\0'; /* Stick in a NULL and advance a pointer, effectively making two * strings. One for file path, one for permissions */ perm_ptr += strlen(SEPARATOR); FILE* f = fopen(filepath, "w"); if(f == NULL) err_handler("Failed to open file"); build_dirs(filepath, 0); memset(buf, '\0', sizeof(buf)); while(recv(conn_fd, buf, BUF_SIZE, NO_FLAGS) > 0) { if(strncmp(buf, OP_EOF, strlen(OP_EOF)) == 0) { fflush(f); break; } fputs(buf, f); send(conn_fd, ACK, strlen(ACK), NO_FLAGS); /* Clear the buffer for accurate comparisons */ memset(buf, '\0', sizeof(buf)); } if(strcmp(buf, OP_EOF) == 0) printf("File transfer successful\n"); fflush(NULL); fclose(f); } }
static void E_handler(lcb_socket_t sock, short which, void *arg) { lcbio_CTX *ctx = arg; lcbio_IOSTATUS status; (void)sock; if (which & LCB_READ_EVENT) { unsigned nb; status = lcbio_E_rdb_slurp(ctx, &ctx->ior); nb = rdb_get_nused(&ctx->ior); if (nb >= ctx->rdwant) { invoke_read_cb(ctx, nb); if (E_free_detached(ctx)) { return; } } if (!LCBIO_IS_OK(status)) { lcb_error_t err = convert_lcberr(ctx, status); lcbio_ctx_senderr(ctx, err); return; } } if (which & LCB_WRITE_EVENT) { if (ctx->wwant) { ctx->wwant = 0; ctx->procs.cb_flush_ready(ctx); if (ctx->err) { return; } } else if (ctx->output) { status = lcbio_E_rb_write(ctx, &ctx->output->rb); if (!LCBIO_IS_OK(status)) { deactivate_watcher(ctx); ctx->err = convert_lcberr(ctx, status); err_handler(ctx); return; } } } lcbio_ctx_schedule(ctx); }
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; }
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; }
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; }
/* * xcalloc(size_tnelem,size_tsize) */ char *xcalloc(size_t nelem, size_t size) { register char *p; /* Do the actual memory allocation */ if((p = calloc(nelem, size)) == NULL) { /* Failure, call the error hook */ if(mestat != NULL) mestat->xerrcals++; p = err_handler(p, nelem, size, errno, "calloc"); } /* Record statistics */ if(mestat != NULL) { mestat->xcallocs++; if(p == NULL) mestat->xfails++; } /* Exit with the pointer */ return(p); }
/* * xrealloc(voidptr,size_tsize) */ char *xrealloc(void *ptr, size_t size) { register void *p; /* Do the actual memory allocation */ if((p = realloc(ptr, size)) == NULL) { /* Failure, call the error hook */ if(mestat != NULL) mestat->xerrcals++; p = err_handler(ptr, (size_t) 1, size, errno, "realloc"); } /* Record statistics */ if(mestat != NULL) { mestat->xreallocs++; if(p == NULL) mestat->xfails++; } /* Exit with the pointer */ return(p); }
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; }
char *dir_window_handler(enum InterfaceCommon ops, const char *cur_dir) { static GtkWidget *filew; static int id; static char buf[ MAX_FILE_PATH_LENGTH ]; static const char *saved_cur_dir; switch(ops) { case WIDGET_CREATE : { struct stat st; char check_dir[ MAX_FILE_PATH_LENGTH + 1]; char *checked_dir; saved_cur_dir = cur_dir; checked_dir = check_dir; strncpy(check_dir, cur_dir, MAX_FILE_PATH_LENGTH); /* Add a final / to input directory string if missing and input string is only a directory (i.e. no filename); but pass through any other strings. This allows GtkFileSelection widget to show proper directory level upon entering. */ if((lstat(checked_dir, &st) >= 0) && (S_ISDIR(st.st_mode))) { if((check_dir[ strlen(checked_dir) - 1 ] != '/') && (strlen(checked_dir) > 0) && (strlen(checked_dir) < MAX_FILE_PATH_LENGTH)) { checked_dir = strcat(check_dir, "/"); } } filew = gtk_file_selection_new(_("Select a directory")); gtk_window_set_position(GTK_WINDOW(filew), GTK_WIN_POS_MOUSE); gtk_file_selection_show_fileop_buttons(GTK_FILE_SELECTION(filew)); id = g_signal_connect(G_OBJECT(filew), "destroy", G_CALLBACK(dw_cancel_clicked), NULL); g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filew) ->ok_button), "clicked", G_CALLBACK(dw_ok_clicked), NULL); g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filew) ->cancel_button), "clicked", G_CALLBACK(dw_cancel_clicked), NULL); gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), checked_dir); gtk_widget_hide(GTK_WIDGET(GTK_FILE_SELECTION(filew) ->fileop_del_file)); gtk_widget_hide(GTK_WIDGET(GTK_FILE_SELECTION(filew) ->fileop_ren_file)); gtk_widget_set_sensitive(GTK_WIDGET(GTK_FILE_SELECTION(filew) ->file_list), FALSE); gtk_widget_show(filew); gtk_main(); g_signal_handler_disconnect(G_OBJECT(filew), id); strncpy(buf, gtk_file_selection_get_filename(GTK_FILE_SELECTION(filew)), sizeof(buf)); gtk_widget_destroy(filew); return buf; } case OP_OK : { struct stat st; //FIXME - should be const, make copy?? gchar *temp = (gchar*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(filew)); if(lstat(temp, &st) < 0) { err_handler(INVALID_FILE_SELECTION_ERR, NULL); return NULL; } if(!S_ISDIR(st.st_mode)) { gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), file_path_without_name(temp)); temp = (gchar*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(filew)); } /* remove final directory ../ from directory string if present */ if(strlen(temp) > 3) { if((temp[ strlen(temp) - 1 ] == '/') && (temp[ strlen(temp) - 2 ] == '.') && (temp[ strlen(temp) - 3 ] == '.') && (temp[ strlen(temp) - 4 ] == '/')) { temp[ strlen(temp) - 3 ] = '\0'; gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), temp); } } /* remove final directory ./ from directory string if present */ if(strlen(temp) > 2) { if((temp[ strlen(temp) - 1 ] == '/') && (temp[ strlen(temp) - 2 ] == '.') && (temp[ strlen(temp) - 3 ] == '/')) { temp[ strlen(temp) - 2 ] = '\0'; gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), temp); } } gtk_main_quit(); return NULL; } case OP_CANCEL : gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), saved_cur_dir); gtk_main_quit(); return NULL; } return NULL; }
int lock_file(char *file_name, int is_temp) { int fd; char *temp; char buf[ MAX_FILE_NAME_LENGTH ]; fd = open(file_name, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH); if(fd >= 0) { close(fd); unlink(file_name); } else { if(errno == EEXIST) if(config.ask_when_file_exists == FALSE || is_temp == TRUE) { if(config.make_mp3_from_existing_wav) { return 1; } /* Prepend config.prepend_char until we succeed open() */ if(strlen(file_name) > MAX_FILE_NAME_LENGTH + MAX_FILE_PATH_LENGTH - 2) { return - 1; } else { temp = file_name_without_path(file_name); strcpy(buf, temp); temp[ 0 ] = config.prepend_char; strcpy(temp + 1, buf); /* now try again */ if(lock_file(file_name, is_temp) < 0) { return - 1; } } } else { if(config.make_mp3_from_existing_wav) { return 1; } if(dialog_handler(WIDGET_CREATE, FALSE, DL_OVERWRITE_CONFIRM, FALSE, file_name_without_path(file_name), NULL, 0) == TRUE) /* Just return. Cdparanoia or 8hz-mp3 will overwrite on it */ { return 0; } /* Let's ask the user what s/he wants */ temp = file_name_without_path(file_name); strcpy(buf, temp); if(dialog_handler(WIDGET_CREATE, TRUE, DL_ENTER_FILE_NAME, TRUE, buf, buf, sizeof(buf) - 1) == FALSE) /* The user does not want to continue. return error */ { return - 1; } strcpy(temp, buf); /* now try again */ if(lock_file(file_name, is_temp) < 0) { return - 1; } } else /* an other error (maybe directory not existent */ { err_handler(CREATING_FILE_ERROR, file_name); return - 1; } } return 0; }
void job_controller(int ops, _main_data *main_data) { static int cur_type = -1; static int wav_cur_track = -1; static int mp3_cur_track = -1; static int mp3_nxt_track = -1; static pid_t wav_pg_pid = -1; static pid_t mp3_pg_pid = -1; static pid_t wav_pi_pid = -1; static pid_t mp3_pi_pid = -1; static int wav_read_fd; static int mp3_read_fd; static _stat stat; static _main_data *saved_main_data; static char *wav_file_path, *enc_file_path; unsigned wav_current = 0; unsigned mp3_current = 0; double wav_progress; double mp3_progress; char msg[ MAX_PLUGIN_OUTPUT_LENGTH ]; char *str; int temp, temp_track; switch(ops) { case JC_START : /* called once when the go button is clicked. */ saved_main_data = main_data; if(wav_cur_track != -1) { err_handler(JOB_IN_PROGRESS_ERR, NULL); job_finisher(main_data); return; } if(find_next_job(main_data, wav_cur_track, WAV, &wav_cur_track, &cur_type) < 0) { /* ok, no more wavs to rip, try looking for mp3s */ if(find_next_job(main_data, mp3_cur_track, MP3, &mp3_cur_track, &cur_type) < 0) { /* nothing at all found */ err_handler(NOTHING_TO_DO_ERR, NULL); job_finisher(main_data); return; } create_file_names_for_track(main_data, mp3_cur_track, &wav_file_path, &enc_file_path); calc_stat(main_data, &stat, mp3_current, mp3_cur_track, MP3, CALC_START_SESSION); calc_stat(main_data, &stat, mp3_current, mp3_cur_track, MP3, CALC_START); /* start encoding */ if(start_ripping_encoding(MP3, main_data->track[ mp3_cur_track ].begin, main_data->track[ mp3_cur_track ].length, mp3_cur_track, wav_file_path, enc_file_path, &mp3_pg_pid, &mp3_pi_pid, &mp3_read_fd) < 0) { job_finisher(main_data); return; } stat.encoding = TRUE; } else { /* found the first wav to rip */ create_file_names_for_track(main_data, wav_cur_track, &wav_file_path, &enc_file_path); calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_START_SESSION); calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_START); /* start ripping */ if(start_ripping_encoding(WAV, main_data->track[ wav_cur_track ].begin, main_data->track[ wav_cur_track ].length, wav_cur_track, wav_file_path, enc_file_path, &wav_pg_pid, &wav_pi_pid, &wav_read_fd) < 0) { job_finisher(main_data); return; } stat.ripping = TRUE; /* Find the next track to encode if any */ if(find_next_job(main_data, mp3_cur_track, MP3, &mp3_nxt_track, &cur_type) < 0 || !main_data->track[ mp3_nxt_track ].make_mp3) { mp3_nxt_track = -1; } } /* Create wav/mp3 status frame */ wm_status_frame_handler(WIDGET_CREATE, cur_type, &stat, NULL); job_controller_timeout_start(); return; case JC_UPDATE : main_data = saved_main_data; /* Part 1: check progress on the rip */ if(stat.ripping == TRUE) { temp = read_and_process_plugin_output(wav_read_fd, &wav_progress, msg); wav_current = main_data->track[ wav_cur_track ].length * wav_progress; switch(temp) { case PLUGIN_MSG_PARSE_ERR : /* Nothing to do. Let's wait more */ break; case PLUGIN_PROGRESS_MSG : /* progress report, update status display */ calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_UPDATE); /* Update status widget */ if(msg[ 0 ] == '\0') { str = NULL; } else { str = msg; } wm_status_frame_handler(WIDGET_UPDATE, WAV, &stat, str); break; case PLUGIN_NO_MSG_AVAILABLE : /* Check if the plugin has exited It only happens when ripperX failed to execute the plugin */ if(wav_pi_pid >= 0) if(waitpid(wav_pi_pid, NULL, WNOHANG) == wav_pi_pid) { err_handler(PLUGIN_NOT_PRESENT_ERR, _("Maybe ripperX has failed to execute the plugin")); wav_pi_pid = -1; job_controller_timeout_stop(); job_controller(JC_ABORT_ALL_DELETE, main_data); return; } /* Check if the job is finished */ if(waitpid(wav_pg_pid, NULL, WNOHANG) == wav_pg_pid) { /* One job finished, go for next one */ /* kill the plugin */ if(waitpid(wav_pi_pid, NULL, WNOHANG) != wav_pi_pid) { kill(-wav_pi_pid, SIGTERM); waitpid(wav_pi_pid, NULL, 0); } /* Close the fd */ close(wav_read_fd); /* stop calculating stats */ calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_STOP); /* Mark that it exists */ main_data->track[ wav_cur_track ].wav_exist = TRUE; /* find next track to rip */ temp_track = wav_cur_track; if(find_next_job(main_data, wav_cur_track, WAV, &wav_cur_track, &cur_type) < 0) { /* All finished - no more rips */ wav_pg_pid = -1; wav_pi_pid = -1; wav_cur_track = -1; cur_type = -1; stat.ripping = FALSE; /* if we are only ripping, finish up for good */ if(!main_data->track[ temp_track ].make_mp3) { calc_stat(main_data, &stat, wav_current, temp_track, WAV, CALC_STOP_SESSION); job_controller_timeout_stop(); job_finisher(main_data); return; } } else { /* if we are only ripping, update the stats */ if(!main_data->track[ temp_track ].make_mp3) { stat.tracks_done++; stat.tracks_remain--; } /* start ripping the next track */ create_file_names_for_track(main_data, wav_cur_track, &wav_file_path, &enc_file_path); calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_START); if(start_ripping_encoding(WAV, main_data->track[ wav_cur_track ].begin, main_data->track[ wav_cur_track ].length, wav_cur_track, wav_file_path, enc_file_path, &wav_pg_pid, &wav_pi_pid, &wav_read_fd) < 0) { calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_STOP_SESSION); job_controller_timeout_stop(); job_finisher(main_data); return; } } } /* end if job is finished section */ break; } /* end rip switch */ } /* end rip progress check */ /* Part 2: check progress on the encode */ if(stat.encoding == TRUE) { temp = read_and_process_plugin_output(mp3_read_fd, &mp3_progress, msg); mp3_current = main_data->track[ mp3_cur_track ].length * mp3_progress; switch(temp) { case PLUGIN_MSG_PARSE_ERR : /* Nothing to do. Let's wait more */ break; case PLUGIN_PROGRESS_MSG : /* progress report, update status display */ calc_stat(main_data, &stat, mp3_current, mp3_cur_track, MP3, CALC_UPDATE); /* Update status widget */ if(msg[ 0 ] == '\0') { str = NULL; } else { str = msg; } wm_status_frame_handler(WIDGET_UPDATE, MP3, &stat, str); break; case PLUGIN_NO_MSG_AVAILABLE : /* Check if the plugin has exited It only happens when ripperX failed to execute the plugin */ if(mp3_pi_pid >= 0) if(waitpid(mp3_pi_pid, NULL, WNOHANG) == mp3_pi_pid) { err_handler(PLUGIN_NOT_PRESENT_ERR, _("Maybe ripperX has failed to execute the plugin")); mp3_pi_pid = -1; job_controller_timeout_stop(); job_controller(JC_ABORT_ALL_DELETE, main_data); return; } /* Check if the job is finished */ if(waitpid(mp3_pg_pid, NULL, WNOHANG) == mp3_pg_pid) { /* One job finished, go for next one */ /* kill the plugin */ if(waitpid(mp3_pi_pid, NULL, WNOHANG) != mp3_pi_pid) { kill(-mp3_pi_pid, SIGTERM); waitpid(mp3_pi_pid, NULL, 0); } /* Close the fd */ close(mp3_read_fd); /* stop calculating stats */ calc_stat(main_data, &stat, mp3_current, mp3_cur_track, MP3, CALC_STOP); main_data->track[ mp3_cur_track ].mp3_exist = TRUE; /* Delete WAV file if he/she doesn't want it */ if(!config.keep_wav) { create_file_names_for_track(main_data, mp3_cur_track, &wav_file_path, &enc_file_path); if(unlink(wav_file_path) < 0) { err_handler(FILE_DELETE_ERR, wav_file_path); } /* Mark that it has been deleted */ main_data->track[ mp3_cur_track ].wav_exist = FALSE; /* Delete WAV work directory if this was the last WAV file, and the mp3 work dir is different */ if(stat.tracks_remain <= 1) if(strcmp(config.wav_path,config.mp3_path) != 0) { rmdir(file_path_without_name(wav_file_path)); } } /* find next track to encode */ temp_track = mp3_cur_track; if(find_next_job(main_data, mp3_cur_track, MP3, &mp3_nxt_track, &cur_type) < 0) { /* All finished - no more encoding - done for good! */ mp3_pg_pid = -1; mp3_pi_pid = -1; mp3_cur_track = mp3_nxt_track = -1; cur_type = -1; calc_stat(main_data, &stat, mp3_current, temp_track, MP3, CALC_STOP_SESSION); job_controller_timeout_stop(); stat.encoding = FALSE; job_finisher(main_data); return; } mp3_cur_track = -1; stat.tracks_done++; stat.tracks_remain--; stat.encoding = FALSE; } /* end if job is finished section */ break; } /* end encode switch */ } /* end encode progress check */ if(!stat.encoding && mp3_nxt_track != -1 && main_data->track[ mp3_nxt_track ].wav_exist) { /* start encoding */ mp3_cur_track = mp3_nxt_track; mp3_nxt_track = -1; create_file_names_for_track(main_data, mp3_cur_track, &wav_file_path, &enc_file_path); calc_stat(main_data, &stat, mp3_current, mp3_cur_track, MP3, CALC_START); if(start_ripping_encoding(MP3, main_data->track[ mp3_cur_track ].begin, main_data->track[ mp3_cur_track ].length, mp3_cur_track, wav_file_path, enc_file_path, &mp3_pg_pid, &mp3_pi_pid, &mp3_read_fd) < 0) { calc_stat(main_data, &stat, mp3_current, mp3_cur_track, MP3, CALC_STOP_SESSION); job_controller_timeout_stop(); job_finisher(main_data); } stat.encoding = TRUE; } /* end of JC_UPDATE */ return; case JC_PAUSE : main_data = saved_main_data; if(wav_pg_pid >= 0) if(waitpid(wav_pg_pid, NULL, WNOHANG) != wav_pg_pid) { kill(wav_pg_pid, SIGTSTP); } if(wav_pi_pid >= 0) if(waitpid(wav_pi_pid, NULL, WNOHANG) != wav_pi_pid) { kill(wav_pi_pid, SIGTSTP); } if(mp3_pg_pid >= 0) if(waitpid(mp3_pg_pid, NULL, WNOHANG) != mp3_pg_pid) { kill(mp3_pg_pid, SIGTSTP); } if(mp3_pi_pid >= 0) if(waitpid(mp3_pi_pid, NULL, WNOHANG) != mp3_pi_pid) { kill(mp3_pi_pid, SIGTSTP); } calc_stat(main_data, &stat, wav_current, wav_cur_track, WAV, CALC_PAUSE); job_controller_timeout_stop(); return; case JC_CONT : main_data = saved_main_data; if(wav_pg_pid >= 0) if(waitpid(wav_pg_pid, NULL, WNOHANG) != wav_pg_pid) { kill(wav_pg_pid, SIGCONT); } if(wav_pi_pid >= 0) if(waitpid(wav_pi_pid, NULL, WNOHANG) != wav_pi_pid) { kill(wav_pi_pid, SIGCONT); } if(mp3_pg_pid >= 0) if(waitpid(mp3_pg_pid, NULL, WNOHANG) != mp3_pg_pid) { kill(mp3_pg_pid, SIGCONT); } if(mp3_pi_pid >= 0) if(waitpid(mp3_pi_pid, NULL, WNOHANG) != mp3_pi_pid) { kill(mp3_pi_pid, SIGCONT); } calc_stat(main_data, &stat, wav_current, wav_cur_track, cur_type, CALC_CONT); job_controller_timeout_start(); return; case JC_ABORT : case JC_ABORT_DELETE : case JC_ABORT_ALL : case JC_ABORT_ALL_DELETE : main_data = saved_main_data; if(wav_pg_pid >= 0) if(waitpid(wav_pg_pid, NULL, WNOHANG) != wav_pg_pid) { job_controller(JC_CONT, NULL); kill(-wav_pg_pid, SIGTERM); waitpid(wav_pg_pid, NULL, 0); } if(wav_pi_pid >= 0) if(waitpid(wav_pi_pid, NULL, WNOHANG) != wav_pi_pid) { kill(-wav_pi_pid, SIGTERM); waitpid(wav_pi_pid, NULL, 0); } if(mp3_pg_pid >= 0) if(waitpid(mp3_pg_pid, NULL, WNOHANG) != mp3_pg_pid) { job_controller(JC_CONT, NULL); kill(-mp3_pg_pid, SIGTERM); waitpid(mp3_pg_pid, NULL, 0); } if(mp3_pi_pid >= 0) if(waitpid(mp3_pi_pid, NULL, WNOHANG) != mp3_pi_pid) { kill(-mp3_pi_pid, SIGTERM); waitpid(mp3_pi_pid, NULL, 0); } /* Close the pipe or pty */ close(wav_read_fd); close(mp3_read_fd); calc_stat(main_data, &stat, wav_current, wav_cur_track, cur_type, CALC_STOP_SESSION); /* Destroy status widget */ wm_status_frame_handler(WIDGET_DESTROY, WAV, &stat, msg); if((ops == JC_ABORT_ALL_DELETE) || (ops == JC_ABORT_DELETE)) { create_file_names_for_track(main_data, wav_cur_track, &wav_file_path, NULL); if(wav_cur_track != -1) { create_file_names_for_track(main_data, wav_cur_track, &wav_file_path, &enc_file_path); if(unlink(wav_file_path) < 0) { err_handler(FILE_DELETE_ERR, wav_file_path); } } if(mp3_cur_track != -1) { create_file_names_for_track(main_data, mp3_cur_track, NULL, &enc_file_path); if(unlink(enc_file_path) < 0) { err_handler(FILE_DELETE_ERR, enc_file_path); } } } else { /* Mark that it exists */ if(wav_cur_track != -1) { main_data->track[ wav_cur_track ].wav_exist = TRUE; } if(mp3_cur_track != -1) { main_data->track[ mp3_cur_track ].mp3_exist = TRUE; } } wav_cur_track = -1; mp3_cur_track = -1; cur_type = -1; calc_stat(main_data, &stat, wav_current, wav_cur_track, cur_type, CALC_STOP_SESSION); job_controller_timeout_stop(); job_finisher(main_data); return; } }
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; /* Open a pty */ if(openpty(&pty_fd, &tty_fd, NULL, NULL, NULL)) { err_handler(PTY_OPEN_ERR, NULL); return - 1; } /* Open /dev/null */ if((null_fd = open("/dev/null", O_WRONLY)) < 0) { err_handler(NULL_OPEN_ERR, NULL); return - 1; } /* Create argvs */ sprintf(tmp, "%s -Q", config.ripper.ripper); if((argv = create_argv_for_execution_using_shell(tmp)) == NULL) { return - 1; } /* Fork */ if((pid = fork()) < 0) { err_handler(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; }
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; }
// // 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; // 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(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(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(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(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 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 /* Reopen the pipe as stream */ if((stream = fdopen(fd, "r")) == NULL) { err_handler(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(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(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(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; }