patch for replacing non-printable chars in filenames

Wayne Davison wayned at samba.org
Thu Mar 31 16:13:52 GMT 2005


On Thu, Mar 31, 2005 at 01:17:16PM +0200, Vidar Madsen wrote:
> Alternatively, how about escaping the chars instead of just munging
> them? I.e. output files like "two-line\x0afile name" or "P\xe5ske"
> (norwegian for "easter", for the curious;), or something like that?

I'd be fine with that.  It would mean doubling "\" characters as well,
though.  Anyone else have an opinion on this?

Appended is a patch that does the suggested escaping.

..wayne..
-------------- next part --------------
--- util.c	30 Mar 2005 19:34:20 -0000	1.181
+++ util.c	31 Mar 2005 16:09:16 -0000
@@ -877,11 +877,12 @@ int pop_dir(char *dir)
 	return 1;
 }
 
-/* Return the filename, turning any non-printable characters into '?'s.
- * This ensures that outputting it on a line of its own cannot generate an
- * empty line.  This function can return only MAX_SAFE_NAMES values at a
- * time!  The returned value can be longer than MAXPATHLEN (because we
- * may be trying to output an error about a too-long filename)! */
+/* Return the filename, turning any non-printable characters into escaped
+ * characters (e.g. \n -> \x0d, \ -> \\).  This ensures that outputting it
+ * cannot generate an empty line nor corrupt the screen.  This function can
+ * return only MAX_SAFE_NAMES values at a time!  The returned value can be
+ * longer than MAXPATHLEN (because we may be trying to output an error about
+ * a too-long filename)! */
 char *safe_fname(const char *fname)
 {
 #define MAX_SAFE_NAMES 4
@@ -891,13 +892,21 @@ char *safe_fname(const char *fname)
 	char *t;
 
 	ndx = (ndx + 1) % MAX_SAFE_NAMES;
-	for (t = fbuf[ndx]; *fname; fname++) {
-		if (!isprint(*(uchar*)fname))
-			*t++ = '?';
-		else
+	for (t = fbuf[ndx]; *fname && limit; fname++) {
+		if (*fname == '\\') {
+			if ((limit -= 2) < 0)
+				break;
+			*t++ = '\\';
+			*t++ = '\\';
+		} else if (!isprint(*(uchar*)fname)) {
+			if ((limit -= 3) < 0)
+				break;
+			sprintf(t, "\\%02x", *(uchar*)fname);
+			t += 3;
+		} else {
+			limit--;
 			*t++ = *fname;
-		if (--limit == 0)
-			break;
+		}
 	}
 	*t = '\0';
 


More information about the rsync mailing list