Hello.. Since I'm the new mc maintainer in debian and I would like to get rid of many annoying bugs in mc I wrote two patches which will close several issues in the debian bugtracking system and/or several issues in the savannah bugtracking system. The first patch (fish_fix_whitespace.patch) will fix a issue that it was impossible to copy files via the fish vfs if the name of the file contains a space or starts with one. Furthermore it fixes a displaying issue, since such a file was displayed without the leading space. This fix will close this Debian Bug: 461532 The second patch (escaping-issue.patch) will fix several escaping/unescaping issues in the internal cd and in the widgets. Furthermore is this patch needed by the first one, since the internal cp function via fish expects to get the string unescaped but get it in reallity escaped. So the unescape function is needed in order to fix this behaviour. Furthermore now it is possible to use tab completion for external commands on the subshell ( e.g. for a folder called "a /" the completion gave previously for example: "rm -rf a /" ... which is definitly not what was wanted *g*, now it escapes it correct and you'll get "rm -rf a\ /". This patch would close these Savannah Bugs: 16176, 18695, 14976 and these Debian Bugs: 326047, 458403 I'll hope that these patches will make it into the CVS. Thanks in advance. Greetings Winnie ps: In order to se the particular bugreports, please use: http://bugs.debian.org/$bugnumber for the debian bugs. And this for the savannah ones: https://savannah.gnu.org/bugs/?$bugnumber -- .''`. Patrick Winnertz <winnie debian org> : :' : GNU/Linux Debian Developer `. `'` http://www.der-winnie.de http://people.skolelinux.org/~winnie `- Debian - when you have better things to do than fixing systems
Index: util.c =================================================================== RCS file: /cvsroot/mc/mc/src/util.c,v retrieving revision 1.141 diff -u -w -r1.141 util.c --- util.c 25 Sep 2007 15:33:37 -0000 1.141 +++ util.c 27 Feb 2008 15:38:13 -0000 @@ -1525,3 +1525,58 @@ return (sep != NULL) ? sep + 1 : result; } +/* Unescape paths or other strings for e.g the internal cd */ +char * +unescape_string ( const char * in ) { + char * local = NULL; + int i = 0; + int j = 20; + int k = 0; + + local = g_malloc(j); + + for (i=0;i<=strlen(in);i++) { + if (i-k >= j ) { + j = j + 20; + local = g_realloc(local,j); + } + if ( (strchr(" \t*|;<>",in[i])) && ( strchr("\\",in[i-1])) ) { + k++; + local[i-k] = in[i]; + } else { + local[i-k] = in[i]; + } + } + local[i-k] = '\0'; + + return local; +} + +/* To be compatible with the general posix command lines we have to escape * + * strings for the command line */ +char * +escape_string ( const char * in ) { + char * local = NULL; + int i = 0; + int j = 20; + int k = 0; + + local = g_malloc(j); + + for (i=0;i<strlen(in);i++) { + if (i+k >= j ) { //If 20 chars is too low for the path + j = j + 20; + local = g_realloc(local,j); + } + if ( (strchr(" \t*|;<>",in[i])) && (! strchr("\\",in[i-1])) ) { + local[i+k] = 92; // Ascii for "\" + k = k+1; + local[i+k] = in[i]; + } else { + local[i+k] = in[i]; + } + } + local[i+k] = '\0'; + + return local; +} Index: util.h =================================================================== RCS file: /cvsroot/mc/mc/src/util.h,v retrieving revision 1.78 diff -u -w -r1.78 util.h --- util.h 3 Feb 2006 17:04:17 -0000 1.78 +++ util.h 27 Feb 2008 15:38:13 -0000 @@ -14,6 +14,8 @@ extern const char *cstrcasestr (const char *haystack, const char *needle); extern const char *cstrstr (const char *haystack, const char *needle); +char *unescape_string ( const char * in ); +char *escape_string ( const char * in ); void str_replace(char *s, char from, char to); int is_printable (int c); void msglen (const char *text, /* out@*/ int *lines, /* out@*/ int *columns); Index: file.c =================================================================== RCS file: /cvsroot/mc/mc/src/file.c,v retrieving revision 1.151 diff -u -w -r1.151 file.c --- file.c 25 Sep 2007 15:33:36 -0000 1.151 +++ file.c 27 Feb 2008 15:38:14 -0000 @@ -63,6 +63,7 @@ #include "widget.h" #include "wtools.h" #include "background.h" /* we_are_background */ +#include "util.h" /* Needed for current_panel, other_panel and WTree */ #include "dir.h" @@ -456,7 +457,7 @@ }; int -copy_file_file (FileOpContext *ctx, const char *src_path, const char *dst_path, +copy_file_file (FileOpContext *ctx, const char *s, const char *d, int ask_overwrite, off_t *progress_count, double *progress_bytes, int is_toplevel_file) { @@ -464,6 +465,8 @@ gid_t src_gid = (gid_t) - 1; char *buf = NULL; + const char *dst_path = NULL; + const char *dst_path = NULL; int buf_size = BUF_8K; int src_desc, dest_desc = -1; int n_read, n_written; @@ -479,7 +482,8 @@ /* FIXME: We should not be using global variables! */ ctx->do_reget = 0; return_status = FILE_RETRY; - + dst_path = unescape_string(d); + src_path = unescape_string(s); if (file_progress_show_source (ctx, src_path) == FILE_ABORT || file_progress_show_target (ctx, dst_path) == FILE_ABORT) return FILE_ABORT; Index: complete.c =================================================================== RCS file: /cvsroot/mc/mc/src/complete.c,v retrieving revision 1.61 diff -u -w -r1.61 complete.c --- complete.c 25 Sep 2007 15:33:36 -0000 1.61 +++ complete.c 27 Feb 2008 15:38:14 -0000 @@ -40,6 +40,7 @@ #include "wtools.h" #include "complete.h" #include "main.h" +#include "util.h" #include "key.h" /* XCTRL and ALT macros */ typedef char *CompletionFunction (char *, int); @@ -911,6 +912,7 @@ static int complete_engine (WInput *in, int what_to_do) { + char *complete = NULL; if (in->completions && in->point != end) free_completions (in); if (!in->completions){ @@ -924,7 +926,8 @@ } if (in->completions){ if (what_to_do & DO_INSERTION || ((what_to_do & DO_QUERY) && !in->completions[1])) { - if (insert_text (in, in->completions [0], strlen (in->completions [0]))){ + complete = escape_string(in->completions [0]); + if (insert_text (in, complete, strlen (complete))){ if (in->completions [1]) beep (); else @@ -940,9 +943,11 @@ Dlg_head *query_dlg; WListbox *query_list; - for (p=in->completions + 1; *p; count++, p++) + for (p=in->completions + 1; *p; count++, p++) { + *p = escape_string(*p); if ((i = strlen (*p)) > maxlen) maxlen = i; + } start_x = in->widget.x; start_y = in->widget.y; if (start_y - 2 >= count) { Index: command.c =================================================================== RCS file: /cvsroot/mc/mc/src/command.c,v retrieving revision 1.34 diff -u -w -r1.34 command.c --- command.c 26 Sep 2007 10:22:25 -0000 1.34 +++ command.c 27 Feb 2008 15:38:15 -0000 @@ -64,6 +64,7 @@ const char *t; /* Tilde expansion */ + path = unescape_string(path); path_tilde = tilde_expand (path); /* Leave space for further expansion */
Index: fish.c =================================================================== RCS file: /cvsroot/mc/mc/vfs/fish.c,v retrieving revision 1.125 diff -u -w -r1.125 fish.c --- fish.c 2 Nov 2007 14:50:41 -0000 1.125 +++ fish.c 27 Feb 2008 14:57:01 -0000 @@ -366,17 +366,17 @@ dir->timestamp.tv_sec += fish_directory_timeout; quoted_path = name_quote (remote_path, 0); fish_command (me, super, NONE, - "#LIST /%s\n" - "if ls -1 /%s >/dev/null 2>&1 ;\n" + "#LIST \"/%s\"\n" + "if ls -1 \"/%s\" >/dev/null 2>&1 ;\n" "then\n" - "ls -lLan /%s 2>/dev/null | grep '^[^cbt]' | (\n" + "ls -lQLan \"/%s\" 2>/dev/null | grep '^[^cbt]' | (\n" "while read p l u g s m d y n; do\n" - "echo \"P$p $u.$g\nS$s\nd$m $d $y\n:$n\n\"\n" + "echo \"P$p $u.$g\nS$s\nd$m $d $y\n:$n\n\"| sed 's#\\\"##g'\n" "done\n" ")\n" - "ls -lan /%s 2>/dev/null | grep '^[cb]' | (\n" + "ls -Qlan \"/%s\" 2>/dev/null | grep '^[cb]' | (\n" "while read p l u g a i m d y n; do\n" - "echo \"P$p $u.$g\nE$a$i\nd$m $d $y\n:$n\n\"\n" + "echo \"P$p $u.$g\nE$a$i\nd$m $d $y\n:$n\n\" | sed 's#\\\"##g'\n" "done\n" ")\n" "echo '### 200'\n" @@ -534,9 +534,9 @@ /* FIXME: File size is limited to ULONG_MAX */ if (!fh->u.fish.append) n = fish_command (me, super, WAIT_REPLY, - "#STOR %lu /%s\n" + "#STOR %lu \"/%s\"\n" "echo '### 001'\n" - "file=/%s\n" + "file=\"/%s\"\n" "res=`exec 3>&1\n" "(\n" "head -c %lu -q - || echo DD >&3\n" @@ -558,10 +558,10 @@ (unsigned long) s.st_size); else n = fish_command (me, super, WAIT_REPLY, - "#STOR %lu /%s\n" + "#STOR %lu \"/%s\"\n" "echo '### 001'\n" "{\n" - "file=/%s\n" + "file=\"/%s\"\n" "rest=%lu\n" "while [ $rest -gt 0 ]\n" "do\n" @@ -627,7 +627,7 @@ return 0; quoted_name = name_quote (name, 0); g_free (name); - name = quoted_name; + name = unescape_string(quoted_name); fh->u.fish.append = 0; /* @@ -637,15 +637,15 @@ * standard output (i.e. over the network). */ offset = fish_command (me, FH_SUPER, WANT_STRING, - "#RETR /%s\n" - "if dd if=/%s of=/dev/null bs=1 count=1 2>/dev/null ;\n" + "#RETR \"/%s\"\n" + "if dd if=\"/%s\" of=/dev/null bs=1 count=1 2>/dev/null ;\n" "then\n" - "ls -ln /%s 2>/dev/null | (\n" + "ls -ln \"/%s\" 2>/dev/null | (\n" "read p l u g s r\n" "echo \"$s\"\n" ")\n" "echo '### 100'\n" - "cat /%s\n" + "cat \"//%s\"\n" "echo '### 200'\n" "else\n" "echo '### 500'\n" @@ -777,7 +777,7 @@ fish_chmod (struct vfs_class *me, const char *path, int mode) { PREFIX - g_snprintf(buf, sizeof(buf), "#CHMOD %4.4o /%s\n" + g_snprintf(buf, sizeof(buf), "#CHMOD %4.4o \"/%s\"\n" "chmod %4.4o \"/%s\" 2>/dev/null\n" "echo '### 000'\n", mode & 07777, rpath, @@ -811,11 +811,11 @@ return fish_send_command(me, super2, buf, OPT_FLUSH); \ } -FISH_OP(rename, "#RENAME /%s /%s\n" - "mv /%s /%s 2>/dev/null\n" +FISH_OP(rename, "#RENAME \"/%s\" \"/%s\"\n" + "mv \"/%s\" \"/%s\" 2>/dev/null\n" "echo '### 000'" ) -FISH_OP(link, "#LINK /%s /%s\n" - "ln /%s /%s 2>/dev/null\n" +FISH_OP(link, "#LINK \"/%s\" \"/%s\"\n" + "ln \"%s\" \"/%s\" 2>/dev/null\n" "echo '### 000'" ) static int fish_symlink (struct vfs_class *me, const char *setto, const char *path) @@ -824,8 +824,8 @@ PREFIX qsetto = name_quote (setto, 0); g_snprintf(buf, sizeof(buf), - "#SYMLINK %s /%s\n" - "ln -s %s /%s 2>/dev/null\n" + "#SYMLINK \"%s\" \"/%s\"\n" + "ln -s \"%s\" \"/%s\" 2>/dev/null\n" "echo '### 000'\n", qsetto, rpath, qsetto, rpath); g_free (qsetto); @@ -850,16 +850,16 @@ { PREFIX g_snprintf (buf, sizeof(buf), - "#CHOWN /%s /%s\n" - "chown %s /%s 2>/dev/null\n" + "#CHOWN /%s \"/%s\"\n" + "chown %s \"/%s\" 2>/dev/null\n" "echo '### 000'\n", sowner, rpath, sowner, rpath); fish_send_command (me, super, buf, OPT_FLUSH); /* FIXME: what should we report if chgrp succeeds but chown fails? */ g_snprintf (buf, sizeof(buf), - "#CHGRP /%s /%s\n" - "chgrp %s /%s 2>/dev/null\n" + "#CHGRP /%s \"/%s\"\n" + "chgrp %s \"/%s\" 2>/dev/null\n" "echo '### 000'\n", sgroup, rpath, sgroup, rpath); @@ -872,8 +872,8 @@ { PREFIX g_snprintf(buf, sizeof(buf), - "#DELE /%s\n" - "rm -f /%s 2>/dev/null\n" + "#DELE \"/%s\"\n" + "rm -f \"/%s\" 2>/dev/null\n" "echo '### 000'\n", rpath, rpath); POSTFIX(OPT_FLUSH); @@ -886,8 +886,8 @@ (void) mode; g_snprintf(buf, sizeof(buf), - "#MKD /%s\n" - "mkdir /%s 2>/dev/null\n" + "#MKD \"/%s\"\n" + "mkdir \"/%s\" 2>/dev/null\n" "echo '### 000'\n", rpath, rpath); POSTFIX(OPT_FLUSH); @@ -897,8 +897,8 @@ { PREFIX g_snprintf(buf, sizeof(buf), - "#RMD /%s\n" - "rmdir /%s 2>/dev/null\n" + "#RMD \"/%s\"\n" + "rmdir \"/%s\" 2>/dev/null\n" "echo '### 000'\n", rpath, rpath); POSTFIX(OPT_FLUSH);
Attachment:
signature.asc
Description: This is a digitally signed message part.