summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Berla <corey@berla.me>2023-01-23 14:26:52 -0800
committerCorey Berla <corey@berla.me>2023-04-17 11:28:52 -0700
commitfe34628a814a22ff1c07e64a21028d8cb5240771 (patch)
tree74f9b3d9c263534f44cc373d4508ccfa8608a7bf
parent11be0992f408a6b740c72b7a3dfc2ebedbd5c633 (diff)
downloadnautilus-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.c39
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;