[patch] Replace illegal characters in filenames for FAT (switch)

Jonas Häggqvist rasher at rasher.dk
Sat Jan 24 22:59:14 GMT 2009


This patch adds a switch --fat-filenames which replaces all characters
that aren't legal on FAT filesystems with an underscore. This is the first
time I touch the rsync code, so I may not be going about it the right way,
but it seems to be working.

Naturally there's some potential for collisions, but it's probably better
than what happens currently (such files are simply not copied).
Alternatives could be to use a different character for each illegal character.

Not sure if this list allows attachments, or if this is the right place,
but here goes. It's a tiny patch at any rate.

-- 
Jonas Häggqvist
rasher(at)rasher(dot)dk
-------------- next part --------------
diff --git a/options.c b/options.c
index 8b67275..bfcb3e6 100644
--- a/options.c
+++ b/options.c
@@ -197,6 +197,7 @@ int need_unsorted_flist = 0;
 #ifdef ICONV_OPTION
 char *iconv_opt = ICONV_OPTION;
 #endif
+int fat_filenames = 0;
 
 struct chmod_mode_struct *chmod_modes = NULL;
 
@@ -779,6 +780,7 @@ void usage(enum logcode F)
 #ifdef ICONV_OPTION
   rprintf(F,"     --iconv=CONVERT_SPEC    request charset conversion of filenames\n");
 #endif
+  rprintf(F,"     --fat-filenames         ensure filenames are legal on fat filesystems\n");
   rprintf(F," -4, --ipv4                  prefer IPv4\n");
   rprintf(F," -6, --ipv6                  prefer IPv6\n");
   rprintf(F,"     --version               print version number\n");
@@ -990,6 +992,7 @@ static struct poptOption long_options[] = {
   {"iconv",            0,  POPT_ARG_STRING, &iconv_opt, 0, 0, 0 },
   {"no-iconv",         0,  POPT_ARG_NONE,   0, OPT_NO_ICONV, 0, 0 },
 #endif
+  {"fat-filenames",    0,  POPT_ARG_NONE,   &fat_filenames, 0, 0, 0 },
   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
   {"8-bit-output",    '8', POPT_ARG_VAL,    &allow_8bit_chars, 1, 0, 0 },
diff --git a/receiver.c b/receiver.c
index 4325e30..bc9dc90 100644
--- a/receiver.c
+++ b/receiver.c
@@ -38,6 +38,7 @@ extern int relative_paths;
 extern int preserve_hard_links;
 extern int preserve_perms;
 extern int preserve_xattrs;
+extern int fat_filenames;
 extern int basis_dir_cnt;
 extern int make_backups;
 extern int cleanup_got_literal;
@@ -441,6 +442,8 @@ int recv_files(int f_in, char *local_name)
 	const char *parent_dirname = "";
 #endif
 	int ndx, recv_ok;
+    int i;
+    static const char fat_invalid_chars[] = "*/:<>?\\|\"";
 
 	if (DEBUG_GTE(RECV, 1))
 		rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used);
@@ -487,6 +490,14 @@ int recv_files(int f_in, char *local_name)
 			file = dir_flist->files[cur_flist->parent_ndx];
 		fname = local_name ? local_name : f_name(file, fbuf);
 
+        if (fat_filenames) {
+            for (i = 0; *fname != 0; i++, fname++) {
+               if (strchr(fat_invalid_chars, *fname))
+                    *fname = '_';
+            }            
+            fname -= i; /* Reset pointer */
+        }
+
 		if (DEBUG_GTE(RECV, 1))
 			rprintf(FINFO, "recv_files(%s)\n", fname);
 


More information about the rsync mailing list