1
/* GIMP - The GNU Image Manipulation Program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
/* Author: Josh MacDonald. */
27
#include <sys/param.h>
34
#include <libgimp/gimp.h>
35
#include <libgimp/gimpui.h>
37
#include "uri-backend.h"
39
#include "libgimp/stdplugins-intl.h"
47
uri_backend_init (const gchar *plugin_name,
56
uri_backend_shutdown (void)
61
uri_backend_get_load_protocols (void)
63
return "http:,https:,ftp:";
67
uri_backend_get_save_protocols (void)
73
uri_backend_load_image (const gchar *uri,
83
g_set_error (error, 0, 0, "pipe() failed: %s", g_strerror (errno));
87
/* open a process group, so killing the plug-in will kill wget too */
90
if ((pid = fork()) < 0)
92
g_set_error (error, 0, 0, "fork() failed: %s", g_strerror (errno));
97
gchar timeout_str[16];
105
/* produce deterministic output */
106
putenv ("LANGUAGE=C");
111
g_snprintf (timeout_str, sizeof (timeout_str), "%d", TIMEOUT);
114
"wget", "-v", "-e", "server-response=off", "-T", timeout_str,
115
uri, "-O", tmpname, NULL);
116
g_set_error (error, 0, 0, "exec() failed: wget: %s", g_strerror (errno));
123
gboolean seen_resolve = FALSE;
124
gboolean connected = FALSE;
125
gboolean redirect = FALSE;
126
gboolean file_found = FALSE;
132
guint64 kilobytes = 0;
133
gboolean finished = FALSE;
134
gboolean debug = FALSE;
139
#define DEBUG(x) if (debug) g_printerr (x)
143
input = fdopen (p[0], "r");
145
/* hardcoded and not-really-foolproof scanning of wget putput */
148
/* Eat any Location lines */
149
if (redirect && fgets (buf, sizeof (buf), input) == NULL)
151
g_set_error (error, 0, 0,
152
_("wget exited abnormally on URI '%s'"), uri);
158
if (fgets (buf, sizeof (buf), input) == NULL)
160
/* no message here because failing on the first line means
161
* that wget was not found
168
/* The second line is the local copy of the file */
169
if (fgets (buf, sizeof (buf), input) == NULL)
171
g_set_error (error, 0, 0,
172
_("wget exited abnormally on URI '%s'"), uri);
178
/* The third line is "Connecting to..." */
180
timeout_msg = g_strdup_printf (ngettext ("(timeout is %d second)",
181
"(timeout is %d seconds)",
184
gimp_progress_init_printf ("%s %s",
185
_("Connecting to server"), timeout_msg);
188
if (fgets (buf, sizeof (buf), input) == NULL)
190
g_set_error (error, 0, 0,
191
_("wget exited abnormally on URI '%s'"), uri);
194
else if (strstr (buf, "connected"))
198
/* newer wgets have a "Resolving foo" line, so eat it */
199
else if (!seen_resolve && strstr (buf, "Resolving"))
207
/* The fourth line is either the network request or an error */
209
gimp_progress_set_text_printf ("%s %s", _("Opening URI"), timeout_msg);
211
if (fgets (buf, sizeof (buf), input) == NULL)
213
g_set_error (error, 0, 0,
214
_("wget exited abnormally on URI '%s'"), uri);
217
else if (! connected)
219
g_set_error (error, 0, 0,
220
_("A network error occurred: %s"), buf);
226
else if (strstr (buf, "302 Found"))
231
seen_resolve = FALSE;
239
/* The fifth line is either the length of the file or an error */
240
if (fgets (buf, sizeof (buf), input) == NULL)
242
g_set_error (error, 0, 0,
243
_("wget exited abnormally on URI '%s'"), uri);
246
else if (strstr (buf, "Length"))
252
g_set_error (error, 0, 0,
253
_("A network error occurred: %s"), buf);
262
if (sscanf (buf, "Length: %37s", sizestr) != 1)
264
g_set_error (error, 0, 0,
265
"Could not parse wget's file length message");
269
/* strip away commas */
270
for (i = 0, j = 0; i < sizeof (sizestr); i++, j++)
272
if (sizestr[i] == ',')
275
sizestr[j] = sizestr[i];
277
if (sizestr[j] == '\0')
281
if (*sizestr != '\0')
283
size = g_ascii_strtoull (sizestr, &endptr, 10);
285
if (*endptr != '\0' || size == G_MAXUINT64)
289
/* Start the actual download... */
292
memsize = gimp_memsize_to_string (size);
293
message = g_strdup_printf (_("Downloading %s of image data"),
298
message = g_strdup (_("Downloading unknown amount of image data"));
302
gimp_progress_set_text_printf ("%s %s", message, timeout_msg);
307
/* Switch to byte parsing wget's output... */
322
if (dot == '.') /* one kilobyte */
328
gimp_progress_update ((gdouble) (kilobytes * 1024) /
333
memsize = gimp_memsize_to_string (kilobytes * 1024);
335
gimp_progress_set_text_printf
336
(_("Downloaded %s of image data"), memsize);
337
gimp_progress_pulse ();
342
else if (dot == ':') /* the time string contains a ':' */
344
fgets (buf, sizeof (buf), input);
348
if (! strstr (buf, "error"))
351
gimp_progress_update (1.0);
360
g_set_error (error, 0, 0,
361
"wget exited before finishing downloading URI\n'%s'",
371
uri_backend_save_image (const gchar *uri,
372
const gchar *tmpname,
373
GimpRunMode run_mode,
376
g_set_error (error, 0, 0, "EEK");