3
* Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
25
#ifdef HAVE_SYS_TYPES_H
26
#include <sys/types.h>
28
#ifdef HAVE_SYS_STAT_H
40
#include <thunar-vfs/thunar-vfs-io-local.h>
41
#include <thunar-vfs/thunar-vfs-io-ops.h>
42
#include <thunar-vfs/thunar-vfs-io-trash.h>
43
#include <thunar-vfs/thunar-vfs-monitor-private.h>
44
#include <thunar-vfs/thunar-vfs-private.h>
45
#include <thunar-vfs/thunar-vfs-thumb-private.h>
46
#include <thunar-vfs/thunar-vfs-alias.h>
48
/* Use g_lstat(), g_mkdir() and g_remove() on win32 */
49
#if defined(G_OS_WIN32)
50
#include <glib/gstdio.h>
52
#define g_lstat(path, statb) (lstat ((path), (statb)))
53
#define g_mkdir(path, mode) (mkdir ((path), (mode)))
54
#define g_remove(path) (remove ((path)))
59
static void tvio_set_g_error_with_paths (GError **error,
61
ThunarVfsPath *source_path,
62
ThunarVfsPath *target_path,
68
tvio_set_g_error_with_paths (GError **error,
70
ThunarVfsPath *source_path,
71
ThunarVfsPath *target_path,
74
gchar *source_display_name;
75
gchar *target_display_name;
78
/* determine a displayable variant of the source_path */
79
s = _thunar_vfs_path_is_local (source_path) ? thunar_vfs_path_dup_string (source_path) : thunar_vfs_path_dup_uri (source_path);
80
source_display_name = g_filename_display_name (s);
83
/* determine a displayable variant of the target_path */
84
s = _thunar_vfs_path_is_local (target_path) ? thunar_vfs_path_dup_string (target_path) : thunar_vfs_path_dup_uri (target_path);
85
target_display_name = g_filename_display_name (s);
88
/* generate a useful error message */
89
s = g_strdup_printf (format, source_display_name, target_display_name);
90
g_set_error (error, err->domain, err->code, "%s: %s", s, err->message);
94
g_free (target_display_name);
95
g_free (source_display_name);
101
* _thunar_vfs_io_ops_get_file_size_and_type:
102
* @path : the #ThunarVfsPath to the file whose size and type
104
* @size_return : return location for the file size or %NULL.
105
* @type_return : return location for the file type or %NULL.
106
* @error : return location for errors or %NULL.
108
* Determines the size and type of the file at @path.
110
* Return value: %TRUE if the size and type was determined successfully,
114
_thunar_vfs_io_ops_get_file_size_and_type (ThunarVfsPath *path,
115
ThunarVfsFileSize *size_return,
116
ThunarVfsFileType *type_return,
120
gboolean succeed = FALSE;
121
gchar *absolute_path;
124
_thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE);
126
/* determine the absolute local path for the path object */
127
absolute_path = _thunar_vfs_path_translate_dup_string (path, THUNAR_VFS_PATH_SCHEME_FILE, error);
128
if (G_LIKELY (absolute_path != NULL))
130
/* determine the file info for the absolute path */
131
succeed = (g_lstat (absolute_path, &statb) == 0);
132
if (G_LIKELY (succeed))
134
/* return size and type if requested */
135
if (G_LIKELY (size_return != NULL))
136
*size_return = statb.st_size;
137
if (G_LIKELY (type_return != NULL))
138
*type_return = (statb.st_mode & S_IFMT) >> 12;
142
/* generate a useful error message */
143
uri = thunar_vfs_path_dup_uri (path);
144
_thunar_vfs_set_g_error_from_errno2 (error, errno, _("Failed to determine file info for \"%s\""), uri);
149
g_free (absolute_path);
158
* _thunar_vfs_io_ops_copy_file:
159
* @source_path : the #ThunarVfsPath to the source file.
160
* @target_path : the #ThunarVfsPath to the target location.
161
* @target_path_return : the final #ThunarVfsPath of the target location, which may be
162
* different than the @target_path.
163
* @callback : the progress callback, invoked whenever a new chunk of data is copied.
164
* @callback_data : additional data to pass to @callback.
165
* @error : return location for errors or %NULL.
167
* Copies the file at the @source_path to the location specified by the
168
* @target_path. The final target location will be returned in @target_path_return.
170
* As a special case, if @callback returns %FALSE, the operation will be cancelled
171
* and an @error with %G_FILE_ERROR and %G_FILE_ERROR_INTR will be returned.
173
* Return value: %TRUE if the file was successfully copied, %FALSE otherwise.
176
_thunar_vfs_io_ops_copy_file (ThunarVfsPath *source_path,
177
ThunarVfsPath *target_path,
178
ThunarVfsPath **target_path_return,
179
ThunarVfsIOOpsProgressCallback callback,
180
gpointer callback_data,
186
_thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE);
187
_thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE);
188
_thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE);
189
_thunar_vfs_return_val_if_fail (callback != NULL, FALSE);
191
/* check if either source or target is trash */
192
if (_thunar_vfs_path_is_trash (source_path) || _thunar_vfs_path_is_trash (target_path))
194
/* copy to or from the trash may result in a new target path */
195
succeed = _thunar_vfs_io_trash_copy_file (source_path, target_path, &target_path, callback, callback_data, &err);
197
else if (_thunar_vfs_path_is_local (source_path) && _thunar_vfs_path_is_local (target_path))
199
/* copying files in the file system */
200
succeed = _thunar_vfs_io_local_copy_file (source_path, target_path, &target_path, callback, callback_data, &err);
204
_thunar_vfs_set_g_error_not_supported (error);
208
/* check if we succeed */
209
if (G_LIKELY (succeed))
211
/* schedule a "created" event for the target path */
212
thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, target_path);
214
/* return the new target path */
215
if (G_LIKELY (target_path_return != NULL))
216
*target_path_return = target_path;
218
thunar_vfs_path_unref (target_path);
222
/* generate a useful error message */
223
tvio_set_g_error_with_paths (error, _("Failed to copy \"%s\" to \"%s\""), source_path, target_path, err);
233
* _thunar_vfs_io_ops_link_file:
234
* @source_path : the #ThunarVfsPath to the source file.
235
* @target_path : the #ThunarVfsPath to the target location.
236
* @target_path_return : return location for the final target path or %NULL.
237
* @error : return location for errors or %NULL.
239
* Creates a symbolic link at @target_path, which points to @source_path. The
240
* real target path may be different than the suggested @target_path, and will
241
* be returned in @target_path_return if not %NULL.
243
* The caller is responsible to free the #ThunarVfsPath object returned in
244
* @target_path_return using thunar_vfs_path_unref() when no longer needed
245
* if %TRUE is returned.
247
* Return value: %TRUE if the link was successfully created, %FALSE otherwise.
250
_thunar_vfs_io_ops_link_file (ThunarVfsPath *source_path,
251
ThunarVfsPath *target_path,
252
ThunarVfsPath **target_path_return,
258
_thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE);
259
_thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE);
260
_thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE);
262
/* check if either source and target are local */
263
if (_thunar_vfs_path_is_local (source_path) && _thunar_vfs_path_is_local (target_path))
265
/* copying files in the file system */
266
succeed = _thunar_vfs_io_local_link_file (source_path, target_path, &target_path, &err);
270
/* impossible to perform the link operation */
271
_thunar_vfs_set_g_error_not_supported (&err);
275
/* check if we succeed */
276
if (G_LIKELY (succeed))
278
/* schedule a "created" event for the target path */
279
thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, target_path);
281
/* return the new target path */
282
if (G_LIKELY (target_path_return != NULL))
283
*target_path_return = target_path;
285
thunar_vfs_path_unref (target_path);
289
/* generate a useful error message */
290
tvio_set_g_error_with_paths (error, _("Failed to link \"%s\" to \"%s\""), source_path, target_path, err);
300
* _thunar_vfs_io_ops_move_file:
301
* @source_path : the #ThunarVfsPath to the source file.
302
* @target_path : the #ThunarVfsPath to the target location.
303
* @target_path_return : the final #ThunarVfsPath of the target location, which
304
* may be different than the @target_path.
305
* @error : return location for errors or %NULL.
307
* Moves the file at the @source_path to the location specified by the
308
* @target_path. The final target location is returned in @target_path_return.
310
* Return value: %TRUE if the file was successfully moved, %FALSE otherwise.
313
_thunar_vfs_io_ops_move_file (ThunarVfsPath *source_path,
314
ThunarVfsPath *target_path,
315
ThunarVfsPath **target_path_return,
321
_thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (source_path), FALSE);
322
_thunar_vfs_return_val_if_fail (!thunar_vfs_path_is_root (target_path), FALSE);
323
_thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE);
325
/* check if either source or target is trash */
326
if (_thunar_vfs_path_is_trash (source_path) || _thunar_vfs_path_is_trash (target_path))
328
/* move to or from the trash may result in a new target path */
329
succeed = _thunar_vfs_io_trash_move_file (source_path, target_path, &target_path, &err);
331
else if (_thunar_vfs_path_is_local (source_path) && _thunar_vfs_path_is_local (target_path))
333
/* moving files in the file system */
334
succeed = _thunar_vfs_io_local_move_file (source_path, target_path, &err);
336
/* local move does not alter the target path */
337
if (G_LIKELY (succeed))
338
thunar_vfs_path_ref (target_path);
342
_thunar_vfs_set_g_error_not_supported (error);
346
/* check if we succeed */
347
if (G_LIKELY (succeed))
349
/* drop the thumbnails for the source path */
350
_thunar_vfs_thumbnail_remove_for_path (source_path);
352
/* schedule a "created" event for the target path */
353
thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, target_path);
355
/* schedule a "deleted" event for the source path */
356
thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_DELETED, source_path);
358
/* return the new target path */
359
if (G_LIKELY (target_path_return != NULL))
360
*target_path_return = target_path;
362
thunar_vfs_path_unref (target_path);
366
/* generate a useful error message */
367
tvio_set_g_error_with_paths (error, _("Failed to move \"%s\" to \"%s\""), source_path, target_path, err);
377
* _thunar_vfs_io_ops_mkdir:
378
* @path : the #ThunarVfsPath to the directory to create.
379
* @mode : the new #ThunarVfsFileMode for the directory.
380
* @flags : see #ThunarVfsIOOpsFlags.
381
* @error : return location for errors or %NULL.
383
* Creates a new directory at the specified @path with the given @mode.
385
* Return value: %TRUE if the directory was created successfully or the
386
* directory exists and %THUNAR_VFS_IO_OPS_IGNORE_EEXIST
387
* was specified in @flags, %FALSE otherwise.
390
_thunar_vfs_io_ops_mkdir (ThunarVfsPath *path,
391
ThunarVfsFileMode mode,
392
ThunarVfsIOOpsFlags flags,
396
gchar *absolute_path;
400
_thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE);
402
/* translate the path object to an absolute path */
403
absolute_path = _thunar_vfs_path_translate_dup_string (path, THUNAR_VFS_PATH_SCHEME_FILE, error);
404
if (G_UNLIKELY (absolute_path == NULL))
407
/* try to create the directory with the given mode */
408
succeed = (g_mkdir (absolute_path, mode) == 0 || (errno == EEXIST && (flags & THUNAR_VFS_IO_OPS_IGNORE_EEXIST) != 0));
409
if (G_UNLIKELY (!succeed))
411
/* save the errno value, may be modified */
414
/* generate a useful error message */
415
display_name = g_filename_display_name (absolute_path);
416
_thunar_vfs_set_g_error_from_errno2 (error, sverrno, _("Failed to create directory \"%s\""), display_name);
417
g_free (display_name);
419
else if (G_LIKELY (errno != EEXIST))
421
/* schedule a "created" event for the directory path */
422
thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_CREATED, path);
426
g_free (absolute_path);
434
* _thunar_vfs_io_ops_remove:
435
* @path : the #ThunarVfsPath to the file to remove.
436
* @flags : see #ThunarVfsIOOpsFlags.
437
* @error : return location for errors or %NULL.
439
* Removes the file or folder at the specified @path.
441
* Return value: %TRUE if the file was successfully
442
* removed, %FALSE otherwise.
445
_thunar_vfs_io_ops_remove (ThunarVfsPath *path,
446
ThunarVfsIOOpsFlags flags,
453
gchar *absolute_path;
455
_thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE);
457
/* remove using the appropriate backend */
458
switch (thunar_vfs_path_get_scheme (path))
460
case THUNAR_VFS_PATH_SCHEME_FILE:
461
absolute_path = thunar_vfs_path_dup_string (path);
462
succeed = (g_remove (absolute_path) == 0);
463
if (G_UNLIKELY (!succeed))
464
_thunar_vfs_set_g_error_from_errno3 (&err);
465
g_free (absolute_path);
468
case THUNAR_VFS_PATH_SCHEME_TRASH:
469
succeed = _thunar_vfs_io_trash_remove (path, &err);
473
_thunar_vfs_set_g_error_not_supported (error);
477
/* drop the thumbnails if the removal succeed */
478
if (G_LIKELY (succeed))
480
/* drop the thumbnails for the removed file */
481
_thunar_vfs_thumbnail_remove_for_path (path);
483
/* tell the monitor about the removed file */
484
thunar_vfs_monitor_feed (_thunar_vfs_monitor, THUNAR_VFS_MONITOR_EVENT_DELETED, path);
486
else if ((flags & THUNAR_VFS_IO_OPS_IGNORE_ENOENT) != 0 && err->domain == G_FILE_ERROR && err->code == G_FILE_ERROR_NOENT)
488
/* we should ignore ENOENT errors */
494
/* generate a useful error message */
495
display_name = _thunar_vfs_path_dup_display_name (path);
496
message = g_strdup_printf (_("Failed to remove \"%s\""), display_name);
497
g_set_error (error, err->domain, err->code, "%s: %s", message, err->message);
498
g_free (display_name);
508
#define __THUNAR_VFS_IO_OPS_C__
509
#include <thunar-vfs/thunar-vfs-aliasdef.c>