diff options
author | Corey Berla <corey@berla.me> | 2023-01-23 14:26:52 -0800 |
---|---|---|
committer | Corey Berla <corey@berla.me> | 2023-04-17 11:28:52 -0700 |
commit | fe34628a814a22ff1c07e64a21028d8cb5240771 (patch) | |
tree | 74f9b3d9c263534f44cc373d4508ccfa8608a7bf | |
parent | 11be0992f408a6b740c72b7a3dfc2ebedbd5c633 (diff) | |
download | nautilus-wip/corey/4gb.tar.gz |
file-operations: Warn before copying/moving >4GiB file to FATwip/corey/4gb
Nautilus attempts to copy/move >4GiB files to a FAT volume and fail
once it reaches the 4GiB threshold. The verify_destination() function
already scans all of the source files before a copy / move, so we can
add a 4GiB check with almost no overhead. Add attributes to the
SourceInfo to track the largest file. If that file exceeds 4GiB, warn
before initiating the operation. Similar to the existing before of
copying to a volume with insufficient space, allow forcing the copy.
Fixes: https://gitlab.gnome.org/GNOME/nautilus/-/issues/1899
-rw-r--r-- | src/nautilus-file-operations.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c index 09780b35b..78a72a210 100644 --- a/src/nautilus-file-operations.c +++ b/src/nautilus-file-operations.c @@ -269,6 +269,7 @@ G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (SourceInfo, source_info_clear) #define LONG_JOB_THRESHOLD_IN_SECONDS 2 #define MAXIMUM_DISPLAYED_FILE_NAME_LENGTH 50 +#define MAXIMUM_FAT_FILE_SIZE G_MAXUINT32 #define IS_IO_ERROR(__error, KIND) (((__error)->domain == G_IO_ERROR && (__error)->code == G_IO_ERROR_ ## KIND)) @@ -3728,8 +3729,8 @@ scan_sources (GList *files, static void verify_destination (CommonJob *job, GFile *dest, - char **dest_fs_id, - goffset required_size) + GStrv dest_fs_id, + SourceInfo *source_info) { GFileInfo *info, *fsinfo; GError *error; @@ -3740,6 +3741,7 @@ verify_destination (CommonJob *job, int response; GFileType file_type; gboolean dest_is_symlink = FALSE; + goffset required_size = (source_info != NULL) ? source_info->num_bytes : -1; if (dest_fs_id) { @@ -3922,6 +3924,29 @@ retry: } if (!job_aborted (job) && + source_info != NULL && source_info->largest_file_bytes >= G_MAXUINT32 && + (g_strcmp0 (fs_type, "exfat") == 0 || g_strcmp0 (fs_type, "msdos") == 0)) + { + g_autofree gchar *formatted_size = g_format_size (source_info->largest_file_bytes); + + primary = g_strdup (_("File too Large for Destination")); + secondary = g_strdup (_("The FAT filesystem does not allow files over 4GiB.")); + /* Translators: Example string is "file.txt has a size of 5GiB" */ + details = g_strdup_printf (_("%s has a size of %s"), + source_info->largest_file_name, + formatted_size); + response = run_warning (job, + primary, secondary, details, + FALSE, + CANCEL, FORCE_OPERATION, NULL); + + if (response == 0 || response == GTK_RESPONSE_DELETE_EVENT) + { + abort_job (job); + } + } + + if (!job_aborted (job) && g_file_info_get_attribute_boolean (fsinfo, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) { @@ -6101,7 +6126,7 @@ nautilus_file_operations_copy (GTask *task, verify_destination (&job->common, dest, &dest_fs_id, - source_info.num_bytes); + &source_info); g_object_unref (dest); if (job_aborted (common)) { @@ -6799,7 +6824,7 @@ nautilus_file_operations_move (GTask *task, verify_destination (&job->common, job->destination, &dest_fs_id, - -1); + NULL); if (job_aborted (common)) { goto aborted; @@ -6846,7 +6871,7 @@ nautilus_file_operations_move (GTask *task, verify_destination (&job->common, job->destination, NULL, - source_info.num_bytes); + &source_info); if (job_aborted (common)) { goto aborted; @@ -7126,7 +7151,7 @@ link_task_thread_func (GTask *task, verify_destination (&job->common, job->destination, NULL, - -1); + NULL); if (job_aborted (common)) { return; @@ -7650,7 +7675,7 @@ create_task_thread_func (GTask *task, verify_destination (common, job->dest_dir, - NULL, -1); + NULL, NULL); if (job_aborted (common)) { return; |