Пример #1
0
/**
 * Download URL to local file using the external 'curl' command.
 */
static int
curl_download (const char *url, const char *local_file)
{
  char curl_config_file[] = "/tmp/curl.XXXXXX";
  char error_file[] = "/tmp/curlerr.XXXXXX";
  CLEANUP_FREE char *error_message = NULL;
  int fd, r;
  size_t i, len;
  FILE *fp;
  CLEANUP_FREE char *curl_cmd = NULL;

  fd = mkstemp (error_file);
  if (fd == -1)
    error (EXIT_FAILURE, errno, "mkstemp: %s", error_file);
  close (fd);

  /* Use a secure curl config file because escaping is easier. */
  fd = mkstemp (curl_config_file);
  if (fd == -1)
    error (EXIT_FAILURE, errno, "mkstemp: %s", curl_config_file);
  fp = fdopen (fd, "w");
  if (fp == NULL)
    error (EXIT_FAILURE, errno, "fdopen: %s", curl_config_file);
  fprintf (fp, "url = \"");
  len = strlen (url);
  for (i = 0; i < len; ++i) {
    switch (url[i]) {
    case '\\': fprintf (fp, "\\\\"); break;
    case '"':  fprintf (fp, "\\\""); break;
    case '\t': fprintf (fp, "\\t");  break;
    case '\n': fprintf (fp, "\\n");  break;
    case '\r': fprintf (fp, "\\r");  break;
    case '\v': fprintf (fp, "\\v");  break;
    default:   fputc (url[i], fp);
    }
  }
  fprintf (fp, "\"\n");
  fclose (fp);

  /* Run curl to download the URL to a file. */
  if (asprintf (&curl_cmd, "curl -f -s -S -o %s -K %s 2>%s",
                local_file, curl_config_file, error_file) == -1)
    error (EXIT_FAILURE, errno, "asprintf");

  r = system (curl_cmd);
  /* unlink (curl_config_file); - useful for debugging */
  if (r == -1)
    error (EXIT_FAILURE, errno, "system: %s", curl_cmd);

  /* Did curl subprocess fail? */
  if (WIFEXITED (r) && WEXITSTATUS (r) != 0) {
    if (read_whole_file (error_file, &error_message, NULL) == 0)
      set_ssh_error ("%s: %s", url, error_message);
    else
      set_ssh_error ("%s: curl error %d", url, WEXITSTATUS (r));
    unlink (error_file);
    return -1;
  }
  else if (!WIFEXITED (r)) {
    set_ssh_error ("curl subprocess got a signal (%d)", r);
    unlink (error_file);
    return -1;
  }

  unlink (error_file);
  return 0;
}
Пример #2
0
/* Download URL to local file using the external 'curl' command. */
static int
curl_download (const char *url, const char *local_file)
{
  char curl_config_file[] = "/tmp/curl.XXXXXX";
  int fd, r;
  size_t i, len;
  FILE *fp;
  CLEANUP_FREE char *curl_cmd = NULL;

  /* Use a secure curl config file because escaping is easier. */
  fd = mkstemp (curl_config_file);
  if (fd == -1) {
    perror ("mkstemp");
    exit (EXIT_FAILURE);
  }
  fp = fdopen (fd, "w");
  if (fp == NULL) {
    perror ("fdopen");
    exit (EXIT_FAILURE);
  }
  fprintf (fp, "url = \"");
  len = strlen (url);
  for (i = 0; i < len; ++i) {
    switch (url[i]) {
    case '\\': fprintf (fp, "\\\\"); break;
    case '"':  fprintf (fp, "\\\""); break;
    case '\t': fprintf (fp, "\\t");  break;
    case '\n': fprintf (fp, "\\n");  break;
    case '\r': fprintf (fp, "\\r");  break;
    case '\v': fprintf (fp, "\\v");  break;
    default:   fputc (url[i], fp);
    }
  }
  fprintf (fp, "\"\n");
  fclose (fp);

  /* Run curl to download the URL to a file. */
  if (asprintf (&curl_cmd, "curl -f -o %s -K %s",
                local_file, curl_config_file) == -1) {
    perror ("asprintf");
    exit (EXIT_FAILURE);
  }

  r = system (curl_cmd);
  /* unlink (curl_config_file); - useful for debugging */
  if (r == -1) {
    perror ("system");
    exit (EXIT_FAILURE);
  }

  /* Did curl subprocess fail? */
  if (WIFEXITED (r) && WEXITSTATUS (r) != 0) {
    /* XXX Better error handling.  The codes can be looked up in
     * the curl(1) man page.
     */
    set_ssh_error ("%s: curl error %d", url, WEXITSTATUS (r));
    return -1;
  }
  else if (!WIFEXITED (r)) {
    set_ssh_error ("curl subprocess got a signal (%d)", r);
    return -1;
  }

  return 0;
}