~ubuntu-branches/ubuntu/vivid/gimp/vivid

« back to all changes in this revision

Viewing changes to plug-ins/file-uri/uri-backend-gnomevfs.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach
  • Date: 2012-05-08 18:50:03 UTC
  • mto: (1.1.26) (0.5.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 71.
  • Revision ID: package-import@ubuntu.com-20120508185003-tltkvbaysf8d2426
ImportĀ upstreamĀ versionĀ 2.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GIMP - The GNU Image Manipulation Program
2
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
 
 *
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.
8
 
 *
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.
13
 
 *
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.
17
 
 */
18
 
 
19
 
#include "config.h"
20
 
 
21
 
#include <libgnomevfs/gnome-vfs.h>
22
 
 
23
 
#ifdef HAVE_GNOMEUI
24
 
#include <libgnomeui/gnome-authentication-manager.h>
25
 
#endif
26
 
#ifdef HAVE_GNOME_KEYRING
27
 
#include <gnome-keyring.h>
28
 
#endif
29
 
 
30
 
#include <libgimp/gimp.h>
31
 
#include <libgimp/gimpui.h>
32
 
 
33
 
#include "uri-backend.h"
34
 
 
35
 
#include "libgimp/stdplugins-intl.h"
36
 
 
37
 
 
38
 
#define BUFSIZE 4096
39
 
 
40
 
 
41
 
/*  local function prototypes  */
42
 
 
43
 
static gchar    * get_protocols (void);
44
 
static gboolean   copy_uri      (const gchar  *src_uri,
45
 
                                 const gchar  *dest_uri,
46
 
                                 const gchar  *copying_format_str,
47
 
                                 const gchar  *copied_format_str,
48
 
                                 GError      **error);
49
 
 
50
 
#ifdef HAVE_GNOME_KEYRING
51
 
static void vfs_async_fill_authentication_callback (gconstpointer in,
52
 
                                                    size_t        in_size,
53
 
                                                    gpointer      out,
54
 
                                                    size_t        out_size,
55
 
                                                    gpointer      user_data,
56
 
                                                    GnomeVFSModuleCallbackResponse response,
57
 
                                                    gpointer      response_data);
58
 
static void vfs_fill_authentication_callback       (gconstpointer in,
59
 
                                                    size_t        in_size,
60
 
                                                    gpointer      out,
61
 
                                                    size_t        out_size,
62
 
                                                    gpointer      user_data);
63
 
#endif /* HAVE_GNOME_KEYRING */
64
 
 
65
 
 
66
 
/*  private variables  */
67
 
 
68
 
static gchar *supported_protocols = NULL;
69
 
 
70
 
 
71
 
/*  public functions  */
72
 
 
73
 
gboolean
74
 
uri_backend_init (const gchar  *plugin_name,
75
 
                  gboolean      run,
76
 
                  GimpRunMode   run_mode,
77
 
                  GError      **error)
78
 
{
79
 
  if (! gnome_vfs_init ())
80
 
    {
81
 
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
82
 
                   "%s", "Could not initialize GnomeVFS");
83
 
      return FALSE;
84
 
    }
85
 
 
86
 
#ifdef HAVE_GNOMEUI
87
 
  if (run)
88
 
    {
89
 
      if (run_mode == GIMP_RUN_INTERACTIVE)
90
 
        {
91
 
          gimp_ui_init (plugin_name, FALSE);
92
 
          gnome_authentication_manager_init ();
93
 
        }
94
 
      else
95
 
        {
96
 
#ifdef HAVE_GNOME_KEYRING
97
 
          gnome_vfs_async_module_callback_set_default
98
 
            (GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION,
99
 
             vfs_async_fill_authentication_callback,
100
 
             GINT_TO_POINTER (0),
101
 
             NULL);
102
 
 
103
 
          gnome_vfs_module_callback_set_default
104
 
            (GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION,
105
 
             vfs_fill_authentication_callback,
106
 
             GINT_TO_POINTER (0),
107
 
             NULL);
108
 
#endif /* HAVE_GNOME_KEYRING */
109
 
        }
110
 
    }
111
 
#endif /* HAVE_GNOMEUI */
112
 
 
113
 
  return TRUE;
114
 
}
115
 
 
116
 
void
117
 
uri_backend_shutdown (void)
118
 
{
119
 
  gnome_vfs_shutdown ();
120
 
}
121
 
 
122
 
const gchar *
123
 
uri_backend_get_load_help (void)
124
 
{
125
 
  return "Loads a file using the GnomeVFS library";
126
 
}
127
 
 
128
 
const gchar *
129
 
uri_backend_get_save_help (void)
130
 
{
131
 
  return "Saves a file using the GnomeVFS library";
132
 
}
133
 
 
134
 
const gchar *
135
 
uri_backend_get_load_protocols (void)
136
 
{
137
 
  if (! supported_protocols)
138
 
    supported_protocols = get_protocols ();
139
 
 
140
 
  return supported_protocols;
141
 
}
142
 
 
143
 
const gchar *
144
 
uri_backend_get_save_protocols (void)
145
 
{
146
 
  if (! supported_protocols)
147
 
    supported_protocols = get_protocols ();
148
 
 
149
 
  return supported_protocols;
150
 
}
151
 
 
152
 
gboolean
153
 
uri_backend_load_image (const gchar  *uri,
154
 
                        const gchar  *tmpname,
155
 
                        GimpRunMode   run_mode,
156
 
                        GError      **error)
157
 
{
158
 
  gchar    *dest_uri;
159
 
  gboolean  success;
160
 
 
161
 
  dest_uri = g_filename_to_uri (tmpname, NULL, NULL);
162
 
  success = copy_uri (uri, dest_uri,
163
 
                      _("Downloading %s of image data"),
164
 
                      _("Downloaded %s of image data"),
165
 
                      error);
166
 
  g_free (dest_uri);
167
 
 
168
 
  return success;
169
 
}
170
 
 
171
 
gboolean
172
 
uri_backend_save_image (const gchar  *uri,
173
 
                        const gchar  *tmpname,
174
 
                        GimpRunMode   run_mode,
175
 
                        GError      **error)
176
 
{
177
 
  gchar    *src_uri;
178
 
  gboolean  success;
179
 
 
180
 
  src_uri = g_filename_to_uri (tmpname, NULL, NULL);
181
 
  success = copy_uri (src_uri, uri,
182
 
                      _("Uploading %s of image data"),
183
 
                      _("Uploaded %s of image data"),
184
 
                      error);
185
 
  g_free (src_uri);
186
 
 
187
 
  return success;
188
 
}
189
 
 
190
 
 
191
 
/*  private functions  */
192
 
 
193
 
static gchar *
194
 
get_protocols (void)
195
 
{
196
 
  static const gchar *protocols[] =
197
 
  {
198
 
    "http:",
199
 
    "https:",
200
 
    "ftp:",
201
 
    "sftp:",
202
 
    "ssh:",
203
 
    "smb:",
204
 
    "dav:",
205
 
    "davs:"
206
 
  };
207
 
 
208
 
  GString *string = g_string_new (NULL);
209
 
  gint     i;
210
 
 
211
 
  for (i = 0; i < G_N_ELEMENTS (protocols); i++)
212
 
    {
213
 
      gchar       *uri;
214
 
      GnomeVFSURI *vfs_uri;
215
 
 
216
 
      uri = g_strdup_printf ("%s//foo/bar.xcf", protocols[i]);
217
 
 
218
 
      vfs_uri = gnome_vfs_uri_new (uri);
219
 
 
220
 
      if (vfs_uri)
221
 
        {
222
 
          if (string->len > 0)
223
 
            g_string_append_c (string, ',');
224
 
 
225
 
          g_string_append (string, protocols[i]);
226
 
 
227
 
          gnome_vfs_uri_unref (vfs_uri);
228
 
        }
229
 
 
230
 
      g_free (uri);
231
 
    }
232
 
 
233
 
  return g_string_free (string, FALSE);
234
 
}
235
 
 
236
 
static gboolean
237
 
copy_uri (const gchar  *src_uri,
238
 
          const gchar  *dest_uri,
239
 
          const gchar  *copying_format_str,
240
 
          const gchar  *copied_format_str,
241
 
          GError      **error)
242
 
{
243
 
  GnomeVFSHandle   *read_handle;
244
 
  GnomeVFSHandle   *write_handle;
245
 
  GnomeVFSFileInfo *src_info;
246
 
  GnomeVFSFileSize  file_size  = 0;
247
 
  GnomeVFSFileSize  bytes_read = 0;
248
 
  guchar            buffer[BUFSIZE];
249
 
  GnomeVFSResult    result;
250
 
  gchar            *memsize;
251
 
  GTimeVal          last_time = { 0, 0 };
252
 
 
253
 
  gimp_progress_init (_("Connecting to server"));
254
 
 
255
 
  src_info = gnome_vfs_file_info_new ();
256
 
  result = gnome_vfs_get_file_info (src_uri, src_info, 0);
257
 
 
258
 
  /*  ignore errors here, they will be noticed below  */
259
 
  if (result == GNOME_VFS_OK &&
260
 
      (src_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE))
261
 
    {
262
 
      file_size = src_info->size;
263
 
    }
264
 
 
265
 
  gnome_vfs_file_info_unref (src_info);
266
 
 
267
 
  result = gnome_vfs_open (&read_handle, src_uri, GNOME_VFS_OPEN_READ);
268
 
 
269
 
  if (result != GNOME_VFS_OK)
270
 
    {
271
 
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
272
 
                   _("Could not open '%s' for reading: %s"),
273
 
                   src_uri, gnome_vfs_result_to_string (result));
274
 
      return FALSE;
275
 
    }
276
 
 
277
 
  result = gnome_vfs_create (&write_handle, dest_uri,
278
 
                             GNOME_VFS_OPEN_WRITE, FALSE, 0644);
279
 
 
280
 
  if (result != GNOME_VFS_OK)
281
 
    {
282
 
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
283
 
                   _("Could not open '%s' for writing: %s"),
284
 
                   dest_uri, gnome_vfs_result_to_string (result));
285
 
      gnome_vfs_close (read_handle);
286
 
      return FALSE;
287
 
    }
288
 
 
289
 
  memsize = g_format_size_for_display (file_size);
290
 
 
291
 
  gimp_progress_init_printf (file_size > 0 ?
292
 
                             copying_format_str : copied_format_str,
293
 
                             memsize);
294
 
 
295
 
  g_free (memsize);
296
 
 
297
 
  while (TRUE)
298
 
    {
299
 
      GnomeVFSFileSize  chunk_read;
300
 
      GnomeVFSFileSize  chunk_written;
301
 
      GTimeVal          now;
302
 
 
303
 
      result = gnome_vfs_read (read_handle, buffer, sizeof (buffer),
304
 
                               &chunk_read);
305
 
 
306
 
      if (chunk_read == 0)
307
 
        {
308
 
          if (result != GNOME_VFS_ERROR_EOF)
309
 
            {
310
 
              memsize = g_format_size_for_display (sizeof (buffer));
311
 
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
312
 
                           _("Failed to read %s from '%s': %s"),
313
 
                           memsize, src_uri,
314
 
                           gnome_vfs_result_to_string (result));
315
 
              g_free (memsize);
316
 
 
317
 
              gnome_vfs_close (read_handle);
318
 
              gnome_vfs_close (write_handle);
319
 
              return FALSE;
320
 
            }
321
 
          else
322
 
            {
323
 
              gimp_progress_update (1.0);
324
 
              break;
325
 
            }
326
 
        }
327
 
 
328
 
      bytes_read += chunk_read;
329
 
 
330
 
      /*  update the progress only up to 10 times a second  */
331
 
 
332
 
      g_get_current_time (&now);
333
 
 
334
 
      if (((now.tv_sec - last_time.tv_sec) * 1000 +
335
 
           (now.tv_usec - last_time.tv_usec) / 1000) > 100)
336
 
        {
337
 
          if (file_size > 0)
338
 
            {
339
 
              gimp_progress_update ((gdouble) bytes_read / (gdouble) file_size);
340
 
            }
341
 
          else
342
 
            {
343
 
              memsize = g_format_size_for_display (bytes_read);
344
 
 
345
 
              gimp_progress_set_text_printf (copied_format_str, memsize);
346
 
              gimp_progress_pulse ();
347
 
 
348
 
              g_free (memsize);
349
 
            }
350
 
 
351
 
          last_time = now;
352
 
        }
353
 
 
354
 
      result = gnome_vfs_write (write_handle, buffer, chunk_read,
355
 
                                &chunk_written);
356
 
 
357
 
      if (chunk_written < chunk_read)
358
 
        {
359
 
          memsize = g_format_size_for_display (chunk_read);
360
 
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
361
 
                       _("Failed to write %s to '%s': %s"),
362
 
                       memsize, dest_uri,
363
 
                       gnome_vfs_result_to_string (result));
364
 
          g_free (memsize);
365
 
 
366
 
          gnome_vfs_close (read_handle);
367
 
          gnome_vfs_close (write_handle);
368
 
          return FALSE;
369
 
        }
370
 
    }
371
 
 
372
 
  gnome_vfs_close (read_handle);
373
 
  gnome_vfs_close (write_handle);
374
 
 
375
 
  return TRUE;
376
 
}
377
 
 
378
 
#ifdef HAVE_GNOME_KEYRING
379
 
 
380
 
/* gnome-keyring code copied from
381
 
 * libgnomeui/libgnomeui/gnome-authentication-manager.c CVS version 1.13
382
 
 */
383
 
 
384
 
typedef struct
385
 
{
386
 
  const GnomeVFSModuleCallbackFillAuthenticationIn *in_args;
387
 
  GnomeVFSModuleCallbackFillAuthenticationOut      *out_args;
388
 
 
389
 
  GnomeVFSModuleCallbackResponse                    response;
390
 
  gpointer                                          response_data;
391
 
} FillCallbackInfo;
392
 
 
393
 
static void
394
 
fill_auth_callback (GnomeKeyringResult result,
395
 
                    GList             *list,
396
 
                    gpointer           data)
397
 
{
398
 
  FillCallbackInfo                *info = data;
399
 
  GnomeKeyringNetworkPasswordData *pwd_data;;
400
 
 
401
 
  if (result != GNOME_KEYRING_RESULT_OK || list == NULL)
402
 
    {
403
 
      info->out_args->valid = FALSE;
404
 
    }
405
 
  else
406
 
    {
407
 
      /* We use the first result, which is the least specific match */
408
 
      pwd_data = list->data;
409
 
 
410
 
      info->out_args->valid    = TRUE;
411
 
      info->out_args->username = g_strdup (pwd_data->user);
412
 
      info->out_args->domain   = g_strdup (pwd_data->domain);
413
 
      info->out_args->password = g_strdup (pwd_data->password);
414
 
    }
415
 
 
416
 
  info->response (info->response_data);
417
 
}
418
 
 
419
 
static void /* GnomeVFSAsyncModuleCallback */
420
 
vfs_async_fill_authentication_callback (gconstpointer in,
421
 
                                        size_t in_size,
422
 
                                        gpointer out,
423
 
                                        size_t out_size,
424
 
                                        gpointer user_data,
425
 
                                        GnomeVFSModuleCallbackResponse response,
426
 
                                        gpointer response_data)
427
 
{
428
 
  GnomeVFSModuleCallbackFillAuthenticationIn  *in_real;
429
 
  GnomeVFSModuleCallbackFillAuthenticationOut *out_real;
430
 
  gpointer                                     request;
431
 
  FillCallbackInfo                            *info;
432
 
 
433
 
  g_return_if_fail
434
 
    (sizeof (GnomeVFSModuleCallbackFillAuthenticationIn) == in_size &&
435
 
     sizeof (GnomeVFSModuleCallbackFillAuthenticationOut) == out_size);
436
 
 
437
 
  g_return_if_fail (in != NULL);
438
 
  g_return_if_fail (out != NULL);
439
 
 
440
 
  in_real  = (GnomeVFSModuleCallbackFillAuthenticationIn *)in;
441
 
  out_real = (GnomeVFSModuleCallbackFillAuthenticationOut *)out;
442
 
 
443
 
  info = g_new (FillCallbackInfo, 1);
444
 
 
445
 
  info->in_args       = in_real;
446
 
  info->out_args      = out_real;
447
 
  info->response      = response;
448
 
  info->response_data = response_data;
449
 
 
450
 
  request = gnome_keyring_find_network_password (in_real->username,
451
 
                                                 in_real->domain,
452
 
                                                 in_real->server,
453
 
                                                 in_real->object,
454
 
                                                 in_real->protocol,
455
 
                                                 in_real->authtype,
456
 
                                                 in_real->port,
457
 
                                                 fill_auth_callback,
458
 
                                                 info, g_free);
459
 
}
460
 
 
461
 
static void /* GnomeVFSModuleCallback */
462
 
vfs_fill_authentication_callback (gconstpointer in,
463
 
                                  size_t        in_size,
464
 
                                  gpointer      out,
465
 
                                  size_t        out_size,
466
 
                                  gpointer      user_data)
467
 
{
468
 
  GnomeVFSModuleCallbackFillAuthenticationIn  *in_real;
469
 
  GnomeVFSModuleCallbackFillAuthenticationOut *out_real;
470
 
  GnomeKeyringNetworkPasswordData             *pwd_data;
471
 
  GList                                       *list;
472
 
  GnomeKeyringResult                           result;
473
 
 
474
 
  g_return_if_fail
475
 
    (sizeof (GnomeVFSModuleCallbackFillAuthenticationIn) == in_size &&
476
 
     sizeof (GnomeVFSModuleCallbackFillAuthenticationOut) == out_size);
477
 
 
478
 
  g_return_if_fail (in != NULL);
479
 
  g_return_if_fail (out != NULL);
480
 
 
481
 
  in_real  = (GnomeVFSModuleCallbackFillAuthenticationIn *)in;
482
 
  out_real = (GnomeVFSModuleCallbackFillAuthenticationOut *)out;
483
 
 
484
 
  result = gnome_keyring_find_network_password_sync (in_real->username,
485
 
                                                     in_real->domain,
486
 
                                                     in_real->server,
487
 
                                                     in_real->object,
488
 
                                                     in_real->protocol,
489
 
                                                     in_real->authtype,
490
 
                                                     in_real->port,
491
 
                                                     &list);
492
 
 
493
 
  if (result != GNOME_KEYRING_RESULT_OK || list == NULL)
494
 
    {
495
 
      out_real->valid = FALSE;
496
 
    }
497
 
  else
498
 
    {
499
 
      /* We use the first result, which is the least specific match */
500
 
      pwd_data = list->data;
501
 
 
502
 
      out_real->valid    = TRUE;
503
 
      out_real->username = g_strdup (pwd_data->user);
504
 
      out_real->domain   = g_strdup (pwd_data->domain);
505
 
      out_real->password = g_strdup (pwd_data->password);
506
 
 
507
 
      gnome_keyring_network_password_list_free (list);
508
 
    }
509
 
}
510
 
 
511
 
#endif /* HAVE_GNOME_KEYRING */