Commit 4fbff306 authored by Michael Natterer's avatar Michael Natterer 😴

plug-ins: remove the libcurl and wget file-uri backends

and build file-uri unconditionally, always using GIO. Use more GFiles
instead of URIs in the plug-in in preparation of moving its
functionality to the core.
parent c1f7ec52
......@@ -1496,42 +1496,6 @@ if test "x$have_cairo_pdf" = xyes && test "x$have_poppler" = xyes; then
fi
################################
# Check for gio/gvfs and libcurl
################################
uri_plugin=no
AC_ARG_WITH(gvfs, [ --without-gvfs build without GIO/GVfs support])
AM_CONDITIONAL(HAVE_GVFS, test "x$with_gvfs" != xno)
AC_ARG_WITH(libcurl, [ --without-libcurl build without curl support])
have_libcurl="no (disabled)"
if test "x$with_libcurl" != xno; then
PKG_CHECK_MODULES(CURL, libcurl >= libcurl_required_version,
have_libcurl=yes,
have_libcurl="no (libcurl not found)")
fi
AM_CONDITIONAL(HAVE_LIBCURL, test "x$have_libcurl" = xyes)
if test "x$with_gvfs" != xno; then
uri_plugin="yes (using GIO/GVfs)"
elif test "x$have_libcurl" = xyes; then
uri_plugin="yes (using libcurl)"
elif test "x$os_win32" = xno; then
uri_plugin="yes (using wget)"
fi
###################
# Check for libwmf2
###################
......@@ -2367,9 +2331,7 @@ Optional Plug-Ins:
TIFF: $have_libtiff
TWAIN (MacOS X): $mac_twain_ok
TWAIN (Win32): $os_win32
URI: $uri_plugin
Webpage: $have_webkit
Windows ICO: $have_libpng
WMF: $have_libwmf
X11 Mouse Cursor: $have_xmc
XPM: $have_libxpm
......
......@@ -27,11 +27,6 @@ endif
if OS_WIN32
twain = twain
win_snap = win-snap
if HAVE_LIBCURL
file_uri = file-uri
endif
else
file_uri = file-uri
endif
SUBDIRS = \
......@@ -47,7 +42,7 @@ SUBDIRS = \
file-jpeg \
file-psd \
file-sgi \
$(file_uri) \
file-uri \
flame \
fractal-explorer \
gfig \
......
......@@ -23,30 +23,13 @@ libexecdir = $(gimpplugindir)/plug-ins
libexec_PROGRAMS = file-uri
if HAVE_GVFS
backend_sources = uri-backend-gvfs.c
backend_cflags = $(GIO_CFLAGS)
backend_libs = $(GIO_LIBS)
else
if HAVE_LIBCURL
backend_sources = uri-backend-libcurl.c
backend_cflags = $(CURL_CFLAGS)
backend_libs = $(CURL_LIBS)
else
backend_sources = uri-backend-wget.c
backend_cflags =
backend_libs =
endif
endif
file_uri_SOURCES = \
uri.c \
uri-backend.h \
$(backend_sources)
uri-backend-gvfs.c
AM_CPPFLAGS = \
-I$(top_srcdir) \
$(backend_cflags) \
$(GTK_CFLAGS) \
$(GEGL_CFLAGS) \
-I$(includedir)
......@@ -59,7 +42,6 @@ LDADD = \
$(libgimp) \
$(libgimpcolor) \
$(libgimpbase) \
$(backend_libs) \
$(GTK_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
......
......@@ -40,8 +40,8 @@ typedef enum
static gchar * get_protocols (void);
static gboolean copy_uri (const gchar *src_uri,
const gchar *dest_uri,
static gboolean copy_uri (GFile *src_file,
GFile *dest_file,
Mode mode,
GimpRunMode run_mode,
GError **error);
......@@ -101,56 +101,48 @@ uri_backend_get_save_protocols (void)
}
gboolean
uri_backend_load_image (const gchar *uri,
uri_backend_load_image (GFile *file,
const gchar *tmpname,
GimpRunMode run_mode,
GError **error)
{
gchar *dest_uri = g_filename_to_uri (tmpname, NULL, error);
GFile *dest_file;
gboolean success;
if (dest_uri)
{
gboolean success = copy_uri (uri, dest_uri, DOWNLOAD, run_mode, error);
dest_file = g_file_new_for_path (tmpname);
g_free (dest_uri);
success = copy_uri (file, dest_file, DOWNLOAD, run_mode, error);
return success;
}
g_object_unref (dest_file);
return FALSE;
return success;
}
gboolean
uri_backend_save_image (const gchar *uri,
uri_backend_save_image (GFile *file,
const gchar *tmpname,
GimpRunMode run_mode,
GError **error)
{
gchar *src_uri = g_filename_to_uri (tmpname, NULL, error);
GFile *src_file;
gboolean success;
if (src_uri)
{
gboolean success = copy_uri (src_uri, uri, UPLOAD, run_mode, error);
src_file = g_file_new_for_path (tmpname);
g_free (src_uri);
success = copy_uri (src_file, file, UPLOAD, run_mode, error);
return success;
}
g_object_unref (src_file);
return FALSE;
return success;
}
gchar *
uri_backend_map_image (const gchar *uri,
GimpRunMode run_mode)
uri_backend_map_image (GFile *file,
GimpRunMode run_mode)
{
GFile *file = g_file_new_for_uri (uri);
gchar *path = NULL;
gboolean success = TRUE;
if (! file)
return NULL;
if (run_mode == GIMP_RUN_INTERACTIVE)
{
GError *error = NULL;
......@@ -168,8 +160,6 @@ uri_backend_map_image (const gchar *uri,
if (success)
path = g_file_get_path (file);
g_object_unref (file);
return path;
}
......@@ -303,24 +293,19 @@ mount_enclosing_volume (GFile *file,
}
static gboolean
copy_uri (const gchar *src_uri,
const gchar *dest_uri,
copy_uri (GFile *src_file,
GFile *dest_file,
Mode mode,
GimpRunMode run_mode,
GError **error)
{
GFile *src_file;
GFile *dest_file;
UriProgress progress = { 0, };
gboolean success;
UriProgress progress = { 0, };
gboolean success;
gimp_progress_init (_("Connecting to server"));
progress.mode = mode;
src_file = g_file_new_for_uri (src_uri);
dest_file = g_file_new_for_uri (dest_uri);
success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, NULL,
uri_progress_callback, &progress,
error);
......@@ -343,8 +328,5 @@ copy_uri (const gchar *src_uri,
}
}
g_object_unref (src_file);
g_object_unref (dest_file);
return success;
}
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* libcurl backend for the URI plug-in
* Copyright (C) 2006 Mukund Sivaraman <muks@mukund.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <errno.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include <glib/gstdio.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "uri-backend.h"
#include "libgimp/stdplugins-intl.h"
/* private variables */
static gchar *supported_protocols = NULL;
static gchar *user_agent = NULL;
/* public functions */
gboolean
uri_backend_init (const gchar *plugin_name,
gboolean run,
GimpRunMode run_mode,
GError **error)
{
GString *protocols;
curl_version_info_data *vinfo;
if (curl_global_init (CURL_GLOBAL_ALL))
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"%s", _("Could not initialize libcurl"));
return FALSE;
}
vinfo = curl_version_info (CURLVERSION_NOW);
protocols = g_string_new ("http:,ftp:,gopher:");
if (vinfo->features & CURL_VERSION_SSL)
{
g_string_append (protocols, ",https:,ftps:");
}
supported_protocols = g_string_free (protocols, FALSE);
user_agent = g_strconcat ("GIMP/", GIMP_VERSION, NULL);
return TRUE;
}
void
uri_backend_shutdown (void)
{
g_free (user_agent);
g_free (supported_protocols);
curl_global_cleanup ();
}
const gchar *
uri_backend_get_load_help (void)
{
return "Loads a file using the libcurl file transfer library";
}
const gchar *
uri_backend_get_save_help (void)
{
return NULL;
}
const gchar *
uri_backend_get_load_protocols (void)
{
return supported_protocols;
}
const gchar *
uri_backend_get_save_protocols (void)
{
return NULL;
}
static int
progress_callback (void *clientp,
double dltotal,
double dlnow,
double ultotal,
double ulnow)
{
gchar *memsize = NULL;
if (dltotal > 0.0)
{
memsize = g_format_size (dltotal);
gimp_progress_set_text_printf (_("Downloading %s of image data"),
memsize);
gimp_progress_update (dlnow / dltotal);
}
else
{
memsize = g_format_size (dlnow);
gimp_progress_set_text_printf (_("Downloaded %s of image data"),
memsize);
gimp_progress_pulse ();
}
g_free (memsize);
return 0;
}
gboolean
uri_backend_load_image (const gchar *uri,
const gchar *tmpname,
GimpRunMode run_mode,
GError **error)
{
FILE *out_file;
CURL *curl_handle;
CURLcode result;
glong response_code;
gchar *eff_url = NULL;
gchar *proto = NULL;
gboolean is_http = FALSE;
gboolean is_ftp = FALSE;
gboolean is_gopher = FALSE;
gimp_progress_init (_("Connecting to server"));
if ((out_file = g_fopen (tmpname, "wb")) == NULL)
{
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
_("Could not open '%s' for writing: %s"),
gimp_filename_to_utf8 (tmpname), g_strerror (errno));
return FALSE;
}
curl_handle = curl_easy_init ();
curl_easy_setopt (curl_handle, CURLOPT_URL, uri);
curl_easy_setopt (curl_handle, CURLOPT_WRITEDATA, out_file);
curl_easy_setopt (curl_handle, CURLOPT_PROGRESSFUNCTION, progress_callback);
curl_easy_setopt (curl_handle, CURLOPT_NOPROGRESS, FALSE);
curl_easy_setopt (curl_handle, CURLOPT_USERAGENT, user_agent);
curl_easy_setopt (curl_handle, CURLOPT_FOLLOWLOCATION, TRUE);
curl_easy_setopt (curl_handle, CURLOPT_MAXREDIRS, 10);
curl_easy_setopt (curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE);
/* the following empty string causes libcurl to send a list of
* all supported encodings which turns on compression
* if libcurl has support for compression
*/
curl_easy_setopt (curl_handle, CURLOPT_ENCODING, "");
if ((result = curl_easy_perform (curl_handle)) != 0)
{
fclose (out_file);
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Could not open '%s' for reading: %s"),
uri, curl_easy_strerror (result));
curl_easy_cleanup (curl_handle);
return FALSE;
}
curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &response_code);
/* protocol could be not specified in provided uri
get complete url guessed by curl */
curl_easy_getinfo (curl_handle, CURLINFO_EFFECTIVE_URL, &eff_url);
/* detect uri protocol */
if (! g_ascii_strncasecmp (eff_url, "http://", 7))
{
is_http = TRUE;
proto = "HTTP";
}
else
if (! g_ascii_strncasecmp (eff_url, "https://", 8))
{
is_http = TRUE;
proto = "HTTPS";
}
else
if (! g_ascii_strncasecmp (eff_url, "ftp://", 6))
{
is_ftp = TRUE;
proto = "FTP";
}
else
if (! g_ascii_strncasecmp (eff_url, "ftps://", 7))
{
is_ftp = TRUE;
proto = "FTPS";
}
else
if (! g_ascii_strncasecmp (eff_url ,"gopher://", 9))
{
is_gopher = TRUE;
proto = "GOPHER";
}
else
{
proto = "UNKNOWN";
}
if (! ((is_http && response_code == 200) || (is_ftp && response_code == 226) || (is_gopher)))
{
fclose (out_file);
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Opening '%s' for reading resulted in %s "
"response code: %ld"),
uri, proto, response_code);
curl_easy_cleanup (curl_handle);
return FALSE;
}
fclose (out_file);
gimp_progress_update (1.0);
curl_easy_cleanup (curl_handle);
return TRUE;
}
gboolean
uri_backend_save_image (const gchar *uri,
const gchar *tmpname,
GimpRunMode run_mode,
GError **error)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "not implemented");
return FALSE;
}
gchar *
uri_backend_map_image (const gchar *uri,
GimpRunMode run_mode)
{
return NULL;
}
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Author: Josh MacDonald. */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/wait.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "uri-backend.h"
#include "libgimp/stdplugins-intl.h"
#define TIMEOUT 300
#define BUFSIZE 1024
gboolean
uri_backend_init (const gchar *plugin_name,
gboolean run,
GimpRunMode run_mode,
GError **error)
{
return TRUE;
}
void
uri_backend_shutdown (void)
{
}
const gchar *
uri_backend_get_load_help (void)
{
return "Loads a file using GNU Wget";
}
const gchar *
uri_backend_get_save_help (void)
{
return NULL;
}
const gchar *
uri_backend_get_load_protocols (void)
{
return "http:,https:,ftp:";
}
const gchar *
uri_backend_get_save_protocols (void)
{
return NULL;
}
gboolean
uri_backend_load_image (const gchar *uri,
const gchar *tmpname,
GimpRunMode run_mode,
GError **error)
{
gint pid;
gint p[2];
if (pipe (p) != 0)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"pipe() failed: %s", g_strerror (errno));
return FALSE;
}
/* open a process group, so killing the plug-in will kill wget too */
setpgid (0, 0);
if ((pid = fork()) < 0)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"fork() failed: %s", g_strerror (errno));
return FALSE;
}
else if (pid == 0)
{
gchar timeout_str[16];
close (p[0]);
close (2);
dup (p[1]);
close (p[1]);
/* produce deterministic output */
g_setenv ("LANGUAGE", "C", TRUE);
g_setenv ("LC_ALL", "C", TRUE);
g_setenv ("LANG", "C", TRUE);
g_snprintf (timeout_str, sizeof (timeout_str), "%d", TIMEOUT);
execlp ("wget",
"wget", "-v", "-e", "server-response=off", "--progress=dot", "-T", timeout_str,
uri, "-O", tmpname, NULL);
_exit (127);
}
else
{
FILE *input;
gchar buf[BUFSIZE];
gboolean seen_resolve = FALSE;
gboolean seen_ftp = FALSE;
gboolean connected = FALSE;
gboolean redirect = FALSE;
gboolean file_found = FALSE;
gchar sizestr[37];
gchar *endptr;
guint64 size = 0;
gint i, j;
gchar dot;
guint64 kilobytes = 0;
gboolean finished = FALSE;
gboolean debug = FALSE;
gchar *memsize;
gchar *message;
gchar *timeout_msg;
#define DEBUG(x) if (debug) g_printerr ("%s\n", x)
close (p[1]);
input = fdopen (p[0], "r");
/* hardcoded and not-really-foolproof scanning of wget output */
wget_begin:
/* Eat any Location lines */
if (redirect && fgets (buf, sizeof (buf), input) == NULL)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("wget exited abnormally on URI '%s'"), uri);
return FALSE;
}
redirect = FALSE;
if (fgets (buf, sizeof (buf), input) == NULL)
{
/* no message here because failing on the first line means
* that wget was not found
*/
return FALSE;
}
DEBUG (buf);
/* The second line is the local copy of the file */
if (fgets (buf, sizeof (buf), input) == NULL)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("wget exited abnormally on URI '%s'"), uri);
return FALSE;
}
/* with an ftp url wget has a "=> `filename.foo" */
else if ( !seen_ftp && strstr (buf, "=> `"))
{
seen_ftp = TRUE;
}
DEBUG (buf);
/* The third line is "Connecting to..." */
timeout_msg = g_strdup_printf (ngettext ("(timeout is %d second)",
"(timeout is %d seconds)",
TIMEOUT), TIMEOUT);
gimp_progress_init_printf ("%s %s",
_("Connecting to server"), timeout_msg);
read_connect:
if (fgets (buf, sizeof (buf), input) == NULL)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("wget exited abnormally on URI '%s'"), uri);
return FALSE;
}
else if (strstr (buf, "connected"))
{
connected = TRUE;
}
/* newer wgets have a "Resolving foo" line, so eat it */
else if (!seen_resolve && strstr (buf, "Resolving"))
{
seen_resolve = TRUE;
goto read_connect;
}
DEBUG (buf);
/* The fourth line is either the network request or an error */
gimp_progress_set_text_printf ("%s %s", _("Opening URI"), timeout_msg);
if (fgets (buf, sizeof (buf), input) == NULL)