コード例 #1
0
ファイル: misc_utils.c プロジェクト: alip2890/Rippix
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;
}
コード例 #2
0
ファイル: misc_utils.c プロジェクト: alip2890/Rippix
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;
}
コード例 #3
0
ファイル: config_rw.c プロジェクト: alip2890/Rippix
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;
    }
}
コード例 #4
0
ファイル: misc_utils.c プロジェクト: alip2890/Rippix
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;
}
コード例 #5
0
ファイル: config_rw.c プロジェクト: alip2890/Rippix
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;
}
コード例 #6
0
ファイル: config_rw.c プロジェクト: alip2890/Rippix
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;
}
コード例 #7
0
ファイル: misc_utils.c プロジェクト: alip2890/Rippix
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;
}
コード例 #8
0
ファイル: job_control.c プロジェクト: sanbeg/ripperx
/* 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);
}
コード例 #9
0
ファイル: job_control.c プロジェクト: sanbeg/ripperx
/* 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);
}
コード例 #10
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

  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;
}
コード例 #11
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;
}
コード例 #12
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;
}