/** * 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; }
/* 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; }