From 3e69dab46959c67c8d14ca03ccaf09863319bb46 Mon Sep 17 00:00:00 2001 From: Sander van der Burg Date: Wed, 16 Sep 2009 17:08:33 +0000 Subject: [PATCH] Applied some fixes to midnight commander so that it no longer displays weird characters svn path=/nixpkgs/trunk/; revision=17207 --- pkgs/development/libraries/slang/default.nix | 15 +- pkgs/tools/misc/mc/default.nix | 46 +- pkgs/tools/misc/mc/mc-4.6.1-bash32-1.patch | 41 + .../misc/mc/mc-4.6.1-debian_fixes-1.patch | 12671 ++++++++++++++++ pkgs/top-level/all-packages.nix | 4 +- 5 files changed, 12766 insertions(+), 11 deletions(-) create mode 100644 pkgs/tools/misc/mc/mc-4.6.1-bash32-1.patch create mode 100644 pkgs/tools/misc/mc/mc-4.6.1-debian_fixes-1.patch diff --git a/pkgs/development/libraries/slang/default.nix b/pkgs/development/libraries/slang/default.nix index 4b221a185832..9208b3001565 100644 --- a/pkgs/development/libraries/slang/default.nix +++ b/pkgs/development/libraries/slang/default.nix @@ -1,10 +1,15 @@ -{stdenv, fetchurl, pcre, libpng}: +{stdenv, fetchurl, ncurses, pcre, libpng, zlib, readline}: stdenv.mkDerivation { - name = "slang-2.0.5"; + name = "slang-2.2.1"; src = fetchurl { - url = ftp://space.mit.edu/pub/davis/slang/v2.0/slang-2.0.5.tar.bz2; - md5 = "8b6afa085f76b1be29825f0c470b6cad"; + url = ftp://ftp.fu-berlin.de/pub/unix/misc/slang/v2.2/slang-2.2.1.tar.bz2; + sha256 = "1qgfg6i5lzmw8j9aqd8pgz3vnhn80giij9bpgm5r3gmna2h0rzfj"; }; - buildInputs = [pcre libpng]; + preConfigure = '' + sed -i -e "s|/usr/lib/terminfo|${ncurses}/lib/terminfo|" configure + sed -i -e "s|/bin/ln|ln|" src/Makefile.in + ''; + configureFlags = "--with-png=${libpng} --with-z=${zlib} --with-pcre=${pcre} --with-readline=${readline}"; + buildInputs = [ncurses pcre libpng zlib readline]; } diff --git a/pkgs/tools/misc/mc/default.nix b/pkgs/tools/misc/mc/default.nix index 8f03756a2d3b..44f042bd4194 100644 --- a/pkgs/tools/misc/mc/default.nix +++ b/pkgs/tools/misc/mc/default.nix @@ -1,4 +1,4 @@ -args: with args; +{stdenv, fetchurl, lib, pkgconfig, glib, ncurses, libX11, shebangfix, perl, zip, unzip, gettext, slang}: stdenv.mkDerivation rec { name = "mc-4.6.1"; @@ -6,8 +6,46 @@ stdenv.mkDerivation rec { url = "http://www.ibiblio.org/pub/Linux/utils/file/managers/mc/${name}.tar.gz"; sha256 = "0zly25mwdn84s0wqx9mzyqi177mm828716nv1n6a4a5cm8yv0sh8"; }; - buildInputs = [pkgconfig glib ncurses libX11 shebangfix perl zip]; - configureFlags = "--with-screen=ncurses"; + buildInputs = [pkgconfig glib ncurses libX11 shebangfix perl zip unzip slang gettext]; + configureFlags = "--enable-charset"; + + # Stole some patches from LFS which fix some nasty bugs + patches = [ ./mc-4.6.1-bash32-1.patch ./mc-4.6.1-debian_fixes-1.patch ]; + + # Required to enable the Debian UTF8 fixes + CPPFLAGS = "-DUTF8"; + + # The Debian UTF8 patch expects that the documentation is in UTF8 format, + # therefore we have to convert them (I stole this also from LFS) + + postBuildPhase = '' + for file in lib/mc.hint{,.es,.it,.nl} doc/{es,it}/mc.hlp.* + do + iconv -f ISO-8859-1 -t UTF-8 $file > $file.utf8 && + mv $file.utf8 $file + done && + for file in lib/mc.hint{.cs,.hu,.pl} doc/{hu,pl}/mc.hlp.* + do + iconv -f ISO-8859-2 -t UTF-8 $file > $file.utf8 && + mv $file.utf8 $file + done && + for file in lib/mc.hint.sr doc/sr/mc.hlp.sr + do + iconv -f ISO-8859-5 -t UTF-8 $file > $file.utf8 && + mv $file.utf8 $file + done && + for file in doc/ru/mc.hlp.ru lib/mc.hint.ru + do + iconv -f KOI8-R -t UTF-8 $file > $file.utf8 && + mv $file.utf8 $file + done && + + iconv -f KOI8-U -t UTF-8 lib/mc.hint.uk > lib/mc.hint.uk.utf8 && + mv lib/mc.hint.uk.utf8 lib/mc.hint.uk && + iconv -f BIG5 -t UTF-8 lib/mc.hint.zh > lib/mc.hint.zh.utf8 && + mv lib/mc.hint.zh.utf8 lib/mc.hint.zh + ''; + makeFlags = "UNZIP=unzip"; postInstall = '' find $out -iname "*.pl" | xargs shebangfix; @@ -15,6 +53,6 @@ stdenv.mkDerivation rec { meta = { description = "File Manager and User Shell for the GNU Project"; homepage = http://www.ibiblio.org/mc; + maintainers = [ lib.maintainers.sander ]; }; } - diff --git a/pkgs/tools/misc/mc/mc-4.6.1-bash32-1.patch b/pkgs/tools/misc/mc/mc-4.6.1-bash32-1.patch new file mode 100644 index 000000000000..d6d55a027074 --- /dev/null +++ b/pkgs/tools/misc/mc/mc-4.6.1-bash32-1.patch @@ -0,0 +1,41 @@ +Submitted By: Alexander E. Patrakov +Date: 2007-01-19 +Initial Package Version: 4.6.1 +Origin: http://bugs.gentoo.org/show_bug.cgi?id=153925 +Upstream Status: aware of the problem +Description: with bash-3.2, unpatched mc-4.6.1 refuses to go into directories +containing underscores or other strange characters. + +--- mc-4.6.1/src/subshell.c.000 2006-05-08 23:11:48.000000000 +0200 ++++ mc-4.6.1/src/subshell.c 2006-10-28 15:40:46.000000000 +0200 +@@ -745,29 +745,13 @@ subshell_name_quote (const char *s) + memcpy (d, cmd_start, len); + d += len; + +- /* +- * Print every character in octal format with the leading backslash. +- * tcsh and zsh may require 4-digit octals, bash < 2.05b doesn't like them. +- */ +- if (subshell_type == BASH) { + for (; *s; s++) { +- /* Must quote numbers, so that they are not glued to octals */ + if (isalpha ((unsigned char) *s)) { + *d++ = (unsigned char) *s; + } else { +- sprintf (d, "\\%03o", (unsigned char) *s); +- d += 4; +- } +- } +- } else { +- for (; *s; s++) { +- if (isalnum ((unsigned char) *s)) { +- *d++ = (unsigned char) *s; +- } else { + sprintf (d, "\\0%03o", (unsigned char) *s); + d += 5; + } +- } + } + + memcpy (d, common_end, sizeof (common_end)); + diff --git a/pkgs/tools/misc/mc/mc-4.6.1-debian_fixes-1.patch b/pkgs/tools/misc/mc/mc-4.6.1-debian_fixes-1.patch new file mode 100644 index 000000000000..931b10b7b651 --- /dev/null +++ b/pkgs/tools/misc/mc/mc-4.6.1-debian_fixes-1.patch @@ -0,0 +1,12671 @@ +Submitted By: Alexander E. Patrakov +Date: 2007-01-19 +Initial Package Version: 4.6.1 +Origin: Debian +Upstream Status: partially applied +Description: This patch adds UTF-8 support to MC, enables recoding +of FTP filenames, fixes 64-bit issues, mcedit segfaults, moves +configuration files to /etc/mc, and contains other changes from the +Debian mc package. + +diff -urN mc-4.6.1.orig/doc/mc.1.in mc-4.6.1/doc/mc.1.in +--- mc-4.6.1.orig/doc/mc.1.in 2005-06-08 18:27:06.000000000 +0600 ++++ mc-4.6.1/doc/mc.1.in 2007-01-19 18:33:58.000000000 +0500 +@@ -1377,7 +1377,7 @@ + but only if it is owned by user or root and is not world-writable. + If no such file found, ~/.mc/menu is tried in the same way, + and otherwise mc uses the default system-wide menu +-@prefix@/share/mc/mc.menu. ++/etc/mc/mc.menu. + .PP + The format of the menu file is very simple. Lines that start with + anything but space or tab are considered entries for the menu (in +@@ -1903,7 +1903,7 @@ + At startup the Midnight Commander will try to load initialization + information from the ~/.mc/ini file. If this file doesn't exist, it will + load the information from the system-wide configuration file, located in +-@prefix@/share/mc/mc.ini. If the system-wide configuration file doesn't ++/etc/mc/mc.ini. If the system-wide configuration file doesn't + exist, MC uses the default settings. + .PP + The +@@ -3235,7 +3235,7 @@ + .IP + The help file for the program. + .PP +-.I @prefix@/share/mc/mc.ext ++.I /etc/mc/mc.ext + .IP + The default system-wide extensions file. + .PP +@@ -3244,12 +3244,12 @@ + User's own extension, view configuration and edit configuration + file. They override the contents of the system wide files if present. + .PP +-.I @prefix@/share/mc/mc.ini ++.I /etc/mc/mc.ini + .IP + The default system-wide setup for the Midnight Commander, used only if + the user doesn't have his own ~/.mc/ini file. + .PP +-.I @prefix@/share/mc/mc.lib ++.I /etc/mc/mc.lib + .IP + Global settings for the Midnight Commander. Settings in this file + affect all users, whether they have ~/.mc/ini or not. Currently, only +@@ -3267,7 +3267,7 @@ + .IP + This file contains the hints displayed by the program. + .PP +-.I @prefix@/share/mc/mc.menu ++.I /etc/mc/mc.menu + .IP + This file contains the default system-wide applications menu. + .PP +diff -urN mc-4.6.1.orig/doc/mcedit.1.in mc-4.6.1/doc/mcedit.1.in +--- mc-4.6.1.orig/doc/mcedit.1.in 2005-06-08 18:27:07.000000000 +0600 ++++ mc-4.6.1/doc/mcedit.1.in 2007-01-19 18:33:58.000000000 +0500 +@@ -464,12 +464,12 @@ + .IP + The help file for the program. + .PP +-.I @prefix@/share/mc/mc.ini ++.I /etc/mc/mc.ini + .IP + The default system-wide setup for GNU Midnight Commander, used only if + the user's own ~/.mc/ini file is missing. + .PP +-.I @prefix@/share/mc/mc.lib ++.I /etc/mc/mc.lib + .IP + Global settings for the Midnight Commander. Settings in this file + affect all users, whether they have ~/.mc/ini or not. +diff -urN mc-4.6.1.orig/doc/mcview.1.in mc-4.6.1/doc/mcview.1.in +--- mc-4.6.1.orig/doc/mcview.1.in 2005-06-08 18:27:07.000000000 +0600 ++++ mc-4.6.1/doc/mcview.1.in 2007-01-19 18:33:58.000000000 +0500 +@@ -65,12 +65,12 @@ + .IP + The help file for the program. + .PP +-.I @prefix@/share/mc/mc.ini ++.I /etc/mc/mc.ini + .IP + The default system-wide setup for GNU Midnight Commander, used only if + the user's own ~/.mc/ini file is missing. + .PP +-.I @prefix@/share/mc/mc.lib ++.I /etc/mc/mc.lib + .IP + Global settings for the Midnight Commander. Settings in this file + affect all users, whether they have ~/.mc/ini or not. +diff -urN mc-4.6.1.orig/edit/edit.c mc-4.6.1/edit/edit.c +--- mc-4.6.1.orig/edit/edit.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/edit.c 2007-01-19 18:33:58.000000000 +0500 +@@ -93,7 +93,7 @@ + + #ifndef NO_INLINE_GETBYTE + +-int edit_get_byte (WEdit * edit, long byte_index) ++mc_wchar_t edit_get_byte (WEdit * edit, long byte_index) + { + unsigned long p; + if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) +@@ -125,7 +125,7 @@ + + edit->curs1 = 0; + edit->curs2 = 0; +- edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } + + /* +@@ -152,7 +152,7 @@ + } + + if (!edit->buffers2[buf2]) +- edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + + mc_read (file, + (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - +@@ -162,7 +162,7 @@ + for (buf = buf2 - 1; buf >= 0; buf--) { + /* edit->buffers2[0] is already allocated */ + if (!edit->buffers2[buf]) +- edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE); + } + +@@ -242,9 +242,44 @@ + { + int c; + long i = 0; +- while ((c = fgetc (f)) >= 0) { ++#ifndef UTF8 ++ while ((c = fgetc (f)) != EOF) { + edit_insert (edit, c); + i++; ++#else /* UTF8 */ ++ unsigned char buf[MB_LEN_MAX]; ++ int charpos = 0; ++ mbstate_t mbs; ++ ++ while ((c = fgetc (f)) != EOF) { ++ mc_wchar_t wc; ++ int size; ++ int j; ++ ++ buf[charpos++] = c; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ size = mbrtowc(&wc, (char *)buf, charpos, &mbs); ++ ++ if (size == -2) ++ continue; /* incomplete */ ++ ++ else if (size >= 0) { ++ edit_insert (edit, wc); ++ i++; ++ charpos = 0; ++ continue; ++ } ++ else { ++ ++ /* invalid */ ++#ifdef __STDC_ISO_10646__ ++ for (j=0; jlast_byte; i++) + if (fputc (edit_get_byte (edit, i), f) < 0) + break; ++#else /* UTF8 */ ++ for (i = 0; i < edit->last_byte; i++) { ++ mc_wchar_t wc = edit_get_byte (edit, i); ++ int res; ++ char tmpbuf[MB_LEN_MAX]; ++ mbstate_t mbs; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++#ifdef __STDC_ISO_10646__ ++ if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) { ++ res = 1; ++ tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET); ++ } else ++#endif ++ res = wcrtomb(tmpbuf, wc, &mbs); ++ if (res > 0) { ++ if (fwrite(tmpbuf, res, 1, f) != 1) ++ break; ++ } ++ } ++#endif /* UTF8 */ + return i; + } + +@@ -294,12 +352,46 @@ + int i, file, blocklen; + long current = edit->curs1; + unsigned char *buf; ++#ifdef UTF8 ++ mbstate_t mbs; ++ int bufstart = 0; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++#endif /* UTF8 */ + if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1) + return 0; + buf = g_malloc (TEMP_BUF_LEN); ++#ifndef UTF8 + while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) { + for (i = 0; i < blocklen; i++) + edit_insert (edit, buf[i]); ++#else /* UTF8 */ ++ while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) { ++ blocklen += bufstart; ++ bufstart = 0; ++ for (i = 0; i < blocklen; ) { ++ mc_wchar_t wc; ++ int j; ++ int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs); ++ if (size == -2) { /*incomplete char*/ ++ bufstart = blocklen - i; ++ memcpy(buf, buf+i, bufstart); ++ i = blocklen; ++ memset (&mbs, 0, sizeof (mbs)); ++ } ++ else if (size <= 0) { ++#ifdef __STDC_ISO_10646__ ++ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]); ++#endif ++ memset (&mbs, 0, sizeof (mbs)); ++ i++; /* skip broken char */ ++ } ++ else { ++ edit_insert (edit, wc); ++ i+=size; ++ } ++ } ++#endif /* UTF8 */ + } + edit_cursor_move (edit, current - edit->curs1); + g_free (buf); +@@ -393,7 +485,11 @@ + static int + edit_load_file (WEdit *edit) + { ++#ifndef UTF8 + int fast_load = 1; ++#else /* UTF8 */ ++ int fast_load = 0; /* can't be used with multibyte characters */ ++#endif /* UTF8 */ + + /* Cannot do fast load if a filter is used */ + if (edit_find_filter (edit->filename) >= 0) +@@ -540,7 +636,7 @@ + edit_set_filename (edit, filename); + edit->stack_size = START_STACK_SIZE; + edit->stack_size_mask = START_STACK_SIZE - 1; +- edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long)); ++ edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action)); + if (edit_load_file (edit)) { + /* edit_load_file already gives an error message */ + if (to_free) +@@ -565,7 +661,9 @@ + edit_move_display (edit, line - 1); + edit_move_to_line (edit, line - 1); + } +- ++#ifdef UTF8 ++ edit->charpoint = 0; ++#endif + return edit; + } + +@@ -693,13 +791,23 @@ + { + unsigned long sp = edit->stack_pointer; + unsigned long spm1; +- long *t; ++ ++ struct action *t; ++ mc_wchar_t ch = 0; ++ ++ if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) { ++ va_list ap; ++ va_start (ap, c); ++ ch = va_arg (ap, mc_wint_t); ++ va_end (ap); ++ } ++ + /* first enlarge the stack if necessary */ + if (sp > edit->stack_size - 10) { /* say */ + if (option_max_undo < 256) + option_max_undo = 256; + if (edit->stack_size < (unsigned long) option_max_undo) { +- t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long)); ++ t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action)); + if (t) { + edit->undo_stack = t; + edit->stack_size <<= 1; +@@ -714,7 +822,7 @@ + #ifdef FAST_MOVE_CURSOR + if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) { + va_list ap; +- edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; ++ edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; + edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; + va_start (ap, c); + c = -(va_arg (ap, int)); +@@ -725,12 +833,14 @@ + && spm1 != edit->stack_bottom + && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) { + int d; +- if (edit->undo_stack[spm1] < 0) { +- d = edit->undo_stack[(sp - 2) & edit->stack_size_mask]; +- if (d == c) { +- if (edit->undo_stack[spm1] > -1000000000) { ++ mc_wchar_t d_ch; ++ if (edit->undo_stack[spm1].flags < 0) { ++ d = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags; ++ d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch; ++ if (d == c && d_ch == ch) { ++ if (edit->undo_stack[spm1].flags > -1000000000) { + if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ +- edit->undo_stack[spm1]--; ++ edit->undo_stack[spm1].flags--; + return; + } + } +@@ -738,19 +848,20 @@ + #ifndef NO_STACK_CURSMOVE_ANIHILATION + else if ((c == CURS_LEFT && d == CURS_RIGHT) + || (c == CURS_RIGHT && d == CURS_LEFT)) { /* a left then a right anihilate each other */ +- if (edit->undo_stack[spm1] == -2) ++ if (edit->undo_stack[spm1].flags == -2) + edit->stack_pointer = spm1; + else +- edit->undo_stack[spm1]++; ++ edit->undo_stack[spm1].flags++; + return; + } + #endif + } else { +- d = edit->undo_stack[spm1]; +- if (d == c) { ++ d = edit->undo_stack[spm1].flags; ++ d_ch = edit->undo_stack[spm1].ch; ++ if (d == c && d_ch == ch) { + if (c >= KEY_PRESS) + return; /* --> no need to push multiple do-nothings */ +- edit->undo_stack[sp] = -2; ++ edit->undo_stack[sp].flags = -2; + goto check_bottom; + } + #ifndef NO_STACK_CURSMOVE_ANIHILATION +@@ -762,7 +873,9 @@ + #endif + } + } +- edit->undo_stack[sp] = c; ++ edit->undo_stack[sp].flags = c; ++ edit->undo_stack[sp].ch = ch; ++ + check_bottom: + + edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; +@@ -775,10 +888,10 @@ + (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom) + do { + edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask; +- } while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); ++ } while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); + + /*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ +- if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS) ++ if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS) + edit->stack_bottom = edit->stack_pointer = 0; + } + +@@ -787,30 +900,30 @@ + then the file should be as it was when he loaded up. Then set edit->modified to 0. + */ + static long +-pop_action (WEdit * edit) ++pop_action (WEdit * edit, struct action *c) + { +- long c; + unsigned long sp = edit->stack_pointer; + if (sp == edit->stack_bottom) { +- return STACK_BOTTOM; ++ c->flags = STACK_BOTTOM; ++ return c->flags; + } + sp = (sp - 1) & edit->stack_size_mask; +- if ((c = edit->undo_stack[sp]) >= 0) { +-/* edit->undo_stack[sp] = '@'; */ ++ *c = edit->undo_stack[sp]; ++ if (edit->undo_stack[sp].flags >= 0) { + edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask; +- return c; ++ return c->flags; + } + if (sp == edit->stack_bottom) { + return STACK_BOTTOM; + } +- c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; +- if (edit->undo_stack[sp] == -2) { +-/* edit->undo_stack[sp] = '@'; */ ++ *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; ++ ++ if (edit->undo_stack[sp].flags == -2) { + edit->stack_pointer = sp; + } else +- edit->undo_stack[sp]++; ++ edit->undo_stack[sp].flags++; + +- return c; ++ return c->flags; + } + + /* is called whenever a modification is made by one of the four routines below */ +@@ -831,7 +944,7 @@ + */ + + void +-edit_insert (WEdit *edit, int c) ++edit_insert (WEdit *edit, mc_wchar_t c) + { + /* check if file has grown to large */ + if (edit->last_byte >= SIZE_LIMIT) +@@ -869,12 +982,11 @@ + /* add a new buffer if we've reached the end of the last one */ + if (!(edit->curs1 & M_EDIT_BUF_SIZE)) + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + + /* perform the insertion */ +- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit-> +- curs1 & M_EDIT_BUF_SIZE] +- = (unsigned char) c; ++ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] ++ [edit->curs1 & M_EDIT_BUF_SIZE] = c; + + /* update file length */ + edit->last_byte++; +@@ -885,7 +997,7 @@ + + + /* same as edit_insert and move left */ +-void edit_insert_ahead (WEdit * edit, int c) ++void edit_insert_ahead (WEdit * edit, mc_wchar_t c) + { + if (edit->last_byte >= SIZE_LIMIT) + return; +@@ -908,7 +1020,7 @@ + edit->last_get_rule += (edit->last_get_rule >= edit->curs1); + + if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) +- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; + + edit->last_byte++; +@@ -918,7 +1030,7 @@ + + int edit_delete (WEdit * edit) + { +- int p; ++ mc_wint_t p; + if (!edit->curs2) + return 0; + +@@ -942,7 +1054,7 @@ + edit->total_lines--; + edit->force |= REDRAW_AFTER_CURSOR; + } +- edit_push_action (edit, p + 256); ++ edit_push_action (edit, CHAR_INSERT_AHEAD, p); + if (edit->curs1 < edit->start_display) { + edit->start_display--; + if (p == '\n') +@@ -956,7 +1068,7 @@ + static int + edit_backspace (WEdit * edit) + { +- int p; ++ mc_wint_t p; + if (!edit->curs1) + return 0; + +@@ -980,7 +1092,7 @@ + edit->total_lines--; + edit->force |= REDRAW_AFTER_CURSOR; + } +- edit_push_action (edit, p); ++ edit_push_action (edit, CHAR_INSERT, p); + + if (edit->curs1 < edit->start_display) { + edit->start_display--; +@@ -993,10 +1105,18 @@ + + #ifdef FAST_MOVE_CURSOR + +-static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) ++static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n) + { + unsigned long next; ++#ifndef UTF8 + while ((next = (unsigned long) memccpy (dest, src, '\n', n))) { ++#else /* UTF8 */ ++ while (n) { ++ next = 0; ++ while (next < n && src[next]!='\n') next++; ++ if (next < n) next++; ++ wmemcpy (dest, src, next) ++#endif /* UTF8 */ + edit->curs_line--; + next -= (unsigned long) dest; + n -= next; +@@ -1009,7 +1129,7 @@ + edit_move_backward_lots (WEdit *edit, long increment) + { + int r, s, t; +- unsigned char *p; ++ mc_wchar_t *p; + + if (increment > edit->curs1) + increment = edit->curs1; +@@ -1049,7 +1169,7 @@ + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; + else + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } else { + g_free (p); + } +@@ -1087,7 +1207,7 @@ + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; + else + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } else { + g_free (p); + } +@@ -1119,7 +1239,7 @@ + + c = edit_get_byte (edit, edit->curs1 - 1); + if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) +- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; + edit->curs2++; + c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE]; +@@ -1144,7 +1264,7 @@ + + c = edit_get_byte (edit, edit->curs1); + if (!(edit->curs1 & M_EDIT_BUF_SIZE)) +- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c; + edit->curs1++; + c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1]; +@@ -1251,7 +1371,7 @@ + q = edit->last_byte + 2; + + for (col = 0, p = current; p < q; p++) { +- int c; ++ mc_wchar_t c; + if (cols != -10) { + if (col == cols) + return p; +@@ -1269,7 +1389,7 @@ + } else if (c < 32 || c == 127) + col += 2; /* Caret notation for control characters */ + else +- col++; ++ col += wcwidth(c); + } + return col; + } +@@ -1402,7 +1522,7 @@ + is_blank (WEdit *edit, long offset) + { + long s, f; +- int c; ++ mc_wchar_t c; + s = edit_bol (edit, offset); + f = edit_eol (edit, offset) - 1; + while (s <= f) { +@@ -1774,13 +1894,13 @@ + static void + edit_do_undo (WEdit * edit) + { +- long ac; ++ struct action ac; + long count = 0; + + edit->stack_disable = 1; /* don't record undo's onto undo stack! */ + +- while ((ac = pop_action (edit)) < KEY_PRESS) { +- switch ((int) ac) { ++ while (pop_action (edit, &ac) < KEY_PRESS) { ++ switch ((int) ac.flags) { + case STACK_BOTTOM: + goto done_undo; + case CURS_RIGHT: +@@ -1801,31 +1921,33 @@ + case COLUMN_OFF: + column_highlighting = 0; + break; ++ case CHAR_INSERT: ++ edit_insert (edit, ac.ch); ++ break; ++ case CHAR_INSERT_AHEAD: ++ edit_insert_ahead (edit, ac.ch); ++ break; + } +- if (ac >= 256 && ac < 512) +- edit_insert_ahead (edit, ac - 256); +- if (ac >= 0 && ac < 256) +- edit_insert (edit, ac); + +- if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) { +- edit->mark1 = ac - MARK_1; ++ if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) { ++ edit->mark1 = ac.flags - MARK_1; + edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); +- } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) { +- edit->mark2 = ac - MARK_2; ++ } else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) { ++ edit->mark2 = ac.flags - MARK_2; + edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); + } + if (count++) + edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ + } + +- if (edit->start_display > ac - KEY_PRESS) { +- edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); ++ if (edit->start_display > ac.flags - KEY_PRESS) { ++ edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display); + edit->force |= REDRAW_PAGE; +- } else if (edit->start_display < ac - KEY_PRESS) { +- edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); ++ } else if (edit->start_display < ac.flags - KEY_PRESS) { ++ edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS); + edit->force |= REDRAW_PAGE; + } +- edit->start_display = ac - KEY_PRESS; /* see push and pop above */ ++ edit->start_display = ac.flags - KEY_PRESS; /* see push and pop above */ + edit_update_curs_row (edit); + + done_undo:; +@@ -2102,7 +2224,7 @@ + * passed as -1. Commands are executed, and char_for_insertion is + * inserted at the cursor. + */ +-void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion) ++void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion) + { + if (command == CK_Begin_Record_Macro) { + edit->macro_i = 0; +@@ -2137,7 +2259,7 @@ + all of them. It also does not check for the Undo command. + */ + void +-edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) ++edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion) + { + edit->force |= REDRAW_LINE; + +@@ -2170,7 +2292,7 @@ + } + + /* An ordinary key press */ +- if (char_for_insertion >= 0) { ++ if (char_for_insertion != (mc_wint_t) -1) { + if (edit->overwrite) { + if (edit_get_byte (edit, edit->curs1) != '\n') + edit_delete (edit); +diff -urN mc-4.6.1.orig/edit/editcmd.c mc-4.6.1/edit/editcmd.c +--- mc-4.6.1.orig/edit/editcmd.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/editcmd.c 2007-01-19 18:33:58.000000000 +0500 +@@ -24,7 +24,6 @@ + /* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */ + + #include +-#include + + #include "edit.h" + #include "editlock.h" +@@ -46,7 +45,7 @@ + #define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f) + + struct selection { +- unsigned char * text; ++ mc_wchar_t *text; + int len; + }; + +@@ -69,12 +68,16 @@ + #define MAX_REPL_LEN 1024 + + static int edit_save_cmd (WEdit *edit); +-static unsigned char *edit_get_block (WEdit *edit, long start, ++static mc_wchar_t *edit_get_block (WEdit *edit, long start, + long finish, int *l); + +-static inline int my_lower_case (int c) ++static inline mc_wchar_t my_lower_case (mc_wchar_t c) + { ++#ifndef UTF8 + return tolower(c & 0xFF); ++#else ++ return towlower(c); ++#endif + } + + static const char *strcasechr (const unsigned char *s, int c) +@@ -108,11 +111,11 @@ + #endif /* !HAVE_MEMMOVE */ + + /* #define itoa MY_itoa <---- this line is now in edit.h */ +-static char * ++static mc_wchar_t * + MY_itoa (int i) + { +- static char t[14]; +- char *s = t + 13; ++ static mc_wchar_t t[14]; ++ mc_wchar_t *s = t + 13; + int j = i; + *s-- = 0; + do { +@@ -196,6 +199,48 @@ + doupdate(); + } + ++#ifdef UTF8 ++ ++static size_t ++wchar_write(int fd, mc_wchar_t *buf, size_t len) ++{ ++ char *tmpbuf = g_malloc(len + MB_LEN_MAX); ++ mbstate_t mbs; ++ size_t i; ++ size_t outlen = 0; ++ size_t res; ++ ++ for (i = 0; i < len; i++) { ++ if (outlen >= len) { ++ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { ++ g_free(tmpbuf); ++ return -1; ++ } ++ outlen = 0; ++ } ++ memset (&mbs, 0, sizeof (mbs)); ++#ifdef __STDC_ISO_10646__ ++ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) { ++ res = 1; ++ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET); ++ ++ } else ++#endif ++ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs); ++ if (res > 0) { ++ outlen += res; ++ } ++ } ++ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { ++ g_free(tmpbuf); ++ return -1; ++ } ++ g_free(tmpbuf); ++ return len; ++} ++ ++#endif /* UTF8 */ ++ + /* If 0 (quick save) then a) create/truncate file, + b) save to ; + if 1 (safe save) then a) save to , +@@ -225,7 +270,7 @@ + } + + if (!vfs_file_is_local (filename) || +- (fd = mc_open (filename, O_WRONLY | O_BINARY)) == -1) { ++ (fd = mc_open (filename, O_RDONLY | O_BINARY)) == -1) { + /* + * The file does not exists yet, so no safe save or + * backup are necessary. +@@ -303,32 +348,48 @@ + buf = 0; + filelen = edit->last_byte; + while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) { ++#ifndef UTF8 + if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE) ++#else /* UTF8 */ ++ if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE) ++#endif /* UTF8 */ + != EDIT_BUF_SIZE) { + mc_close (fd); + goto error_save; + } + buf++; + } ++#ifndef UTF8 + if (mc_write + (fd, (char *) edit->buffers1[buf], ++#else /* UTF8 */ ++ if (wchar_write ++ (fd, edit->buffers1[buf], ++#endif /* UTF8 */ + edit->curs1 & M_EDIT_BUF_SIZE) != + (edit->curs1 & M_EDIT_BUF_SIZE)) { + filelen = -1; + } else if (edit->curs2) { + edit->curs2--; + buf = (edit->curs2 >> S_EDIT_BUF_SIZE); +- if (mc_write +- (fd, +- (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - ++#ifndef UTF8 ++ if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - ++#else /* UTF8 */ ++ if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE - ++#endif /* UTF8 */ + (edit->curs2 & M_EDIT_BUF_SIZE) - 1, + 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) != + 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) { + filelen = -1; + } else { + while (--buf >= 0) { ++#ifndef UTF8 + if (mc_write + (fd, (char *) edit->buffers2[buf], ++#else /* UTF8 */ ++ if (wchar_write ++ (fd, edit->buffers2[buf], ++#endif /* UTF8 */ + EDIT_BUF_SIZE) != EDIT_BUF_SIZE) { + filelen = -1; + break; +@@ -643,13 +704,21 @@ + if (!n || n == EOF) + break; + n = 0; ++#ifndef UTF8 + while (fscanf (f, "%hd %hd, ", ¯o[n].command, ¯o[n].ch)) ++#else /* UTF8 */ ++ while (fscanf (f, "%hd %lu, ", ¯o[n].command, ¯o[n].ch)) ++#endif /* UTF8 */ + n++; + fscanf (f, ";\n"); + if (s != k) { + fprintf (g, ("key '%d 0': "), s); + for (i = 0; i < n; i++) ++#ifndef UTF8 + fprintf (g, "%hd %hd, ", macro[i].command, macro[i].ch); ++#else /* UTF8 */ ++ fprintf (g, "%hd %lu, ", macro[i].command, macro[i].ch); ++#endif /* UTF8 */ + fprintf (g, ";\n"); + } + } +@@ -685,7 +754,11 @@ + if (f) { + fprintf (f, ("key '%d 0': "), s); + for (i = 0; i < n; i++) ++#ifndef UTF8 + fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch); ++#else /* UTF8 */ ++ fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch); ++#endif /* UTF8 */ + fprintf (f, ";\n"); + fclose (f); + if (saved_macros_loaded) { +@@ -734,10 +807,18 @@ + saved_macro[i++] = s; + if (!found) { + *n = 0; ++#ifndef UTF8 + while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", ¯o[*n].command, ¯o[*n].ch)) ++#else /* UTF8 */ ++ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", ¯o[*n].command, ¯o[*n].ch)) ++#endif /* UTF8 */ + (*n)++; + } else { ++#ifndef UTF8 + while (2 == fscanf (f, "%hd %hd, ", &dummy.command, &dummy.ch)); ++#else /* UTF8 */ ++ while (2 == fscanf (f, "%hd %lu, ", &dummy.command, &dummy.ch)); ++#endif /* UTF8 */ + } + fscanf (f, ";\n"); + if (s == k) +@@ -886,7 +967,7 @@ + #define space_width 1 + + static void +-edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width) ++edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width) + { + long cursor; + int i, col; +@@ -934,7 +1015,7 @@ + { + long start_mark, end_mark, current = edit->curs1; + int size, x; +- unsigned char *copy_buf; ++ mc_wchar_t *copy_buf; + + edit_update_curs_col (edit); + x = edit->curs_col; +@@ -979,7 +1060,7 @@ + { + long count; + long current; +- unsigned char *copy_buf; ++ mc_wchar_t *copy_buf; + long start_mark, end_mark; + int deleted = 0; + int x = 0; +@@ -1040,7 +1121,7 @@ + edit_push_action (edit, COLUMN_ON); + column_highlighting = 0; + } else { +- copy_buf = g_malloc (end_mark - start_mark); ++ copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t)); + edit_cursor_move (edit, start_mark - edit->curs1); + edit_scroll_screen_over_cursor (edit); + count = start_mark; +@@ -1371,7 +1452,11 @@ + /* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */ + /* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */ + static int ++#ifndef UTF8 + string_regexp_search (char *pattern, char *string, int len, int match_type, ++#else /* UTF8 */ ++string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type, ++#endif /* UTF8 */ + int match_bol, int icase, int *found_len, void *d) + { + static regex_t r; +@@ -1380,6 +1465,11 @@ + regmatch_t *pmatch; + static regmatch_t s[1]; + ++#ifdef UTF8 ++ char *string; ++ int i; ++#endif /* UTF8 */ ++ + pmatch = (regmatch_t *) d; + if (!pmatch) + pmatch = s; +@@ -1399,13 +1489,51 @@ + old_type = match_type; + old_icase = icase; + } ++ ++#ifdef UTF8 ++ string = wchar_to_mbstr(wstring); ++ if (string == NULL) ++ return -1; ++#endif /* UTF8 */ ++ + if (regexec + (&r, string, d ? NUM_REPL_ARGS : 1, pmatch, + ((match_bol + || match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) { + *found_len = 0; ++ ++#ifdef UTF8 ++ g_free(string); ++#endif /* UTF8 */ ++ + return -1; + } ++ ++#ifdef UTF8 ++ for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) { ++ char tmp; ++ int new_o; ++ ++ if (pmatch[i].rm_so < 0) ++ continue; ++ tmp = string[pmatch[i].rm_so]; ++ string[pmatch[i].rm_so] = 0; ++ new_o = mbstrlen(string); ++ string[pmatch[i].rm_so] = tmp; ++ pmatch[i].rm_so = new_o; ++ ++ if (pmatch[i].rm_eo < 0) ++ continue; ++ tmp = string[pmatch[i].rm_eo]; ++ string[pmatch[i].rm_eo] = 0; ++ new_o = mbstrlen(string); ++ string[pmatch[i].rm_eo] = tmp; ++ pmatch[i].rm_eo = new_o; ++ } ++ ++ g_free(string); ++#endif /* UTF8 */ ++ + *found_len = pmatch[0].rm_eo - pmatch[0].rm_so; + return (pmatch[0].rm_so); + } +@@ -1413,13 +1541,29 @@ + /* thanks to Liviu Daia for getting this + (and the above) routines to work properly - paul */ + ++#ifndef UTF8 + typedef int (*edit_getbyte_fn) (WEdit *, long); ++#else /* UTF8 */ ++typedef mc_wchar_t (*edit_getbyte_fn) (WEdit *, long); ++#endif /* UTF8 */ + + static long ++#ifndef UTF8 + edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) ++#else /* UTF8 */ ++edit_find_string (long start, unsigned char *exp_mb, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) ++#endif /* UTF8 */ + { + long p, q = 0; +- long l = strlen ((char *) exp), f = 0; ++ long f = 0; ++ ++#ifndef UTF8 ++ long l = strlen ((char *) exp); ++#else /* UTF8 */ ++ mc_wchar_t *exp = mbstr_to_wchar((char *)exp_mb); ++ mc_wchar_t *exp_backup = exp; ++ long l = wcslen(exp); ++#endif /* UTF8 */ + int n = 0; + + for (p = 0; p < l; p++) /* count conversions... */ +@@ -1428,19 +1572,22 @@ + n++; + + if (replace_scanf || replace_regexp) { +- int c; +- unsigned char *buf; +- unsigned char mbuf[MAX_REPL_LEN * 2 + 3]; ++ mc_wint_t c; ++ mc_wchar_t *buf; ++ mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3]; + + replace_scanf = (!replace_regexp); /* can't have both */ + + buf = mbuf; + + if (replace_scanf) { +- unsigned char e[MAX_REPL_LEN]; +- if (n >= NUM_REPL_ARGS) +- return -3; +- ++ mc_wchar_t e[MAX_REPL_LEN]; ++ if (n >= NUM_REPL_ARGS) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ ++ return -3; ++ } + if (replace_case) { + for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++) + buf[p - start] = (*get_byte) (data, p); +@@ -1454,20 +1601,36 @@ + } + + buf[(q = p - start)] = 0; ++#ifndef UTF8 + strcpy ((char *) e, (char *) exp); + strcat ((char *) e, "%n"); ++#else /* UTF8 */ ++ wcscpy (e, exp); ++ wcscat (e, L"%n"); ++#endif /* UTF8 */ + exp = e; + + while (q) { + *((int *) sargs[n]) = 0; /* --> here was the problem - now fixed: good */ ++#ifndef UTF8 + if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) { ++#else /* UTF8 */ ++ if (n == swscanf (buf, exp, SCANF_ARGS)) { ++#endif /* UTF8 */ + if (*((int *) sargs[n])) { + *len = *((int *) sargs[n]); ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return start; + } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + if (q + start < last_byte) { + if (replace_case) { + buf[q] = (*get_byte) (data, q + start); +@@ -1481,7 +1644,11 @@ + start++; + buf++; /* move the window along */ + if (buf == mbuf + MAX_REPL_LEN) { /* the window is about to go past the end of array, so... */ ++#ifndef UTF8 + memmove (mbuf, buf, strlen ((char *) buf) + 1); /* reset it */ ++#else /* UTF8 */ ++ wmemmove (mbuf, buf, (wcslen (buf) + 1)); /* reset it */ ++#endif /* UTF8 */ + buf = mbuf; + } + q--; +@@ -1507,10 +1674,17 @@ + + buf = mbuf; + while (q) { ++#ifndef UTF8 + found_start = string_regexp_search ((char *) exp, (char *) buf, q, match_normal, match_bol, !replace_case, len, d); ++#else /* UTF8 */ ++ found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d); ++#endif /* UTF8 */ + + if (found_start <= -2) { /* regcomp/regexec error */ + *len = 0; ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -3; + } + else if (found_start == -1) /* not found: try next line */ +@@ -1521,15 +1695,27 @@ + match_bol = 0; + continue; + } +- else /* found */ ++ else { /* found */ ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return (start + offset - q + found_start); ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + + if (buf[q - 1] != '\n') { /* incomplete line: try to recover */ + buf = mbuf + MAX_REPL_LEN / 2; ++#ifndef UTF8 + q = strlen ((const char *) buf); ++#else /* UTF8 */ ++ q = wcslen (buf); ++#endif /* UTF8 */ + memmove (mbuf, buf, q); + p = start + q; + move_win = 1; +@@ -1539,36 +1725,59 @@ + } + } + } else { ++#ifndef UTF8 + *len = strlen ((const char *) exp); ++#else /* UTF8 */ ++ *len = wcslen (exp); ++#endif /* UTF8 */ + if (replace_case) { + for (p = start; p <= last_byte - l; p++) { +- if ((*get_byte) (data, p) == (unsigned char)exp[0]) { /* check if first char matches */ ++ if ((*get_byte) (data, p) == exp[0]) { /* check if first char matches */ + for (f = 0, q = 0; q < l && f < 1; q++) +- if ((*get_byte) (data, q + p) != (unsigned char)exp[q]) ++ if ((*get_byte) (data, q + p) != exp[q]) + f = 1; +- if (f == 0) ++ if (f == 0) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return p; ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + } + } else { + for (p = 0; exp[p] != 0; p++) + exp[p] = my_lower_case (exp[p]); + + for (p = start; p <= last_byte - l; p++) { +- if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) { ++ if (my_lower_case ((*get_byte) (data, p)) == exp[0]) { + for (f = 0, q = 0; q < l && f < 1; q++) +- if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q]) ++ if (my_lower_case ((*get_byte) (data, q + p)) != exp[q]) + f = 1; +- if (f == 0) ++ if (f == 0) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return p; ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + } + } + } ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -2; + } + +@@ -1582,9 +1791,14 @@ + + while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) { + if (replace_whole) { ++#ifndef UTF8 + /*If the bordering chars are not in option_whole_chars_search then word is whole */ + if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1)) + && !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len))) ++#else /* UTF8 */ ++ if (!iswalnum((*get_byte) (data, p - 1)) ++ && !iswalnum((*get_byte) (data, p + *len))) ++#endif /* UTF8 */ + return p; + if (once_only) + return -2; +@@ -1616,6 +1830,7 @@ + + #define is_digit(x) ((x) >= '0' && (x) <= '9') + ++#ifndef UTF8 + #define snprint(v) { \ + *p1++ = *p++; \ + *p1 = '\0'; \ +@@ -1623,33 +1838,48 @@ + if (n >= (size_t) (e - s)) goto nospc; \ + s += n; \ + } ++#else /* UTF8 */ ++#define snprint(v) { \ ++ *p1++ = *p++; \ ++ *p1 = '\0'; \ ++ n = swprintf(s, e-s, q1,v); \ ++ if (n >= (size_t) (e - s)) goto nospc; \ ++ s += n; \ ++ } ++#endif /* UTF8 */ + + /* this function uses the sprintf command to do a vprintf */ + /* it takes pointers to arguments instead of the arguments themselves */ + /* The return value is the number of bytes written excluding '\0' + if successfull, -1 if the resulting string would be too long and + -2 if the format string is errorneous. */ +-static int snprintf_p (char *str, size_t size, const char *fmt,...) +- __attribute__ ((format (printf, 3, 4))); +- +-static int snprintf_p (char *str, size_t size, const char *fmt,...) ++static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...) + { + va_list ap; + size_t n; +- const char *q, *p; +- char *s = str, *e = str + size; +- char q1[40]; +- char *p1; ++ const mc_wchar_t *q, *p; ++ mc_wchar_t *s = str, *e = str + size; ++ mc_wchar_t q1[40]; ++ ++ mc_wchar_t *p1; + int nargs = 0; + + va_start (ap, fmt); + p = q = fmt; + ++#ifndef UTF8 + while ((p = strchr (p, '%'))) { ++#else /* UTF8 */ ++ while ((p = wcschr (p, L'%'))) { ++#endif /* UTF8 */ + n = p - q; + if (n >= (size_t) (e - s)) + goto nospc; ++#ifndef UTF8 + memcpy (s, q, n); /* copy stuff between format specifiers */ ++#else /* UTF8 */ ++ wmemcpy (s, q, n); /* copy stuff between format specifiers */ ++#endif /* UTF8 */ + s += n; + q = p; + p1 = q1; +@@ -1677,45 +1907,78 @@ + *p1++ = *p++; + if (*p == '*') { + p++; ++#ifndef UTF8 + strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ + p1 += strlen (p1); ++#else /* UTF8 */ ++ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ ++ p1 += wcslen (p1); ++#endif /* UTF8 */ + } else { +- while (is_digit (*p) && p1 < q1 + 20) ++#ifndef UTF8 ++ while (is_digit (*p) ++#else /* UTF8 */ ++ while (iswdigit (*p) ++#endif /* UTF8 */ ++ && p1 < q1 + 20) + *p1++ = *p++; +- if (is_digit (*p)) ++#ifndef UTF8 ++ if (is_digit (*p)) ++#else /* UTF8 */ ++ if (iswdigit (*p)) ++#endif /* UTF8 */ + goto err; + } + if (*p == '.') + *p1++ = *p++; + if (*p == '*') { + p++; ++#ifndef UTF8 + strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ + p1 += strlen (p1); ++#else /* UTF8 */ ++ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ ++ p1 += wcslen (p1); ++#endif /* UTF8 */ + } else { +- while (is_digit (*p) && p1 < q1 + 32) ++#ifndef UTF8 ++ while (is_digit (*p) ++#else /* UTF8 */ ++ while (iswdigit (*p) ++#endif /* UTF8 */ ++ && p1 < q1 + 32) + *p1++ = *p++; +- if (is_digit (*p)) ++#ifndef UTF8 ++ if (is_digit (*p)) ++#else /* UTF8 */ ++ if (iswdigit (*p)) ++#endif /* UTF8 */ + goto err; + } + /* flags done, now get argument */ + if (*p == 's') { ++#ifndef UTF8 + snprint (va_arg (ap, char *)); ++#else /* UTF8 */ ++ *p1++ = 'l'; ++ snprint (va_arg (ap, mc_wchar_t *)); ++#endif /* UTF8 */ + } else if (*p == 'h') { +- if (strchr ("diouxX", *p)) ++ if (*p < 128 && strchr ("diouxX", *p)) + snprint (*va_arg (ap, short *)); + } else if (*p == 'l') { + *p1++ = *p++; +- if (strchr ("diouxX", *p)) ++ if (*p < 128 && strchr ("diouxX", *p)) + snprint (*va_arg (ap, long *)); +- } else if (strchr ("cdiouxX", *p)) { ++ } else if (*p < 128 && strchr ("cdiouxX", *p)) { + snprint (*va_arg (ap, int *)); + } else if (*p == 'L') { + *p1++ = *p++; +- if (strchr ("EefgG", *p)) ++ if (*p < 128 && strchr ("EefgG", *p)) + snprint (*va_arg (ap, double *)); /* should be long double */ +- } else if (strchr ("EefgG", *p)) { ++ } else if (*p < 128 && strchr ("EefgG", *p)) { + snprint (*va_arg (ap, double *)); +- } else if (strchr ("DOU", *p)) { ++ } else if (*p < 128 && strchr ("DOU", *p)) { + snprint (*va_arg (ap, long *)); + } else if (*p == 'p') { + snprint (*va_arg (ap, void **)); +@@ -1724,10 +1987,17 @@ + q = p; + } + va_end (ap); ++#ifndef UTF8 + n = strlen (q); + if (n >= (size_t) (e - s)) + return -1; + memcpy (s, q, n + 1); ++#else /* UTF8 */ ++ n = wcslen (q); ++ if (n >= (size_t) (e - s)) ++ return -1; ++ wmemcpy (s, q, n + 1); ++#endif /* UTF8 */ + return s + n - str; + nospc: + va_end (ap); +@@ -1902,8 +2172,11 @@ + } + } + if (replace_yes) { /* delete then insert new */ ++#ifdef UTF8 ++ mc_wchar_t *winput2 = mbstr_to_wchar(exp2); ++#endif /* UTF8 */ + if (replace_scanf || replace_regexp) { +- char repl_str[MAX_REPL_LEN + 2]; ++ mc_wchar_t repl_str[MAX_REPL_LEN + 2]; + int ret = 0; + + /* we need to fill in sargs just like with scanf */ +@@ -1912,17 +2185,25 @@ + for (k = 1; + k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0; + k++) { ++#ifndef UTF8 + unsigned char *t; ++#else /* UTF8 */ ++ mc_wchar_t *t; ++#endif + + if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) { + ret = -1; + break; + } ++#ifndef UTF8 + t = (unsigned char *) &sargs[k - 1][0]; ++#else /* UTF8 */ ++ t = (mc_wchar_t *) &sargs[k - 1][0]; ++#endif /* UTF8 */ + for (j = 0; + j < pmatch[k].rm_eo - pmatch[k].rm_so + && j < 255; j++, t++) +- *t = (unsigned char) edit_get_byte (edit, ++ *t = edit_get_byte (edit, + edit-> + search_start + - +@@ -1939,13 +2220,22 @@ + sargs[k - 1][0] = 0; + } + if (!ret) ++#ifndef UTF8 + ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, exp2, PRINTF_ARGS); ++#else /* UTF8 */ ++ ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, PRINTF_ARGS); ++#endif /* UTF8 */ + if (ret >= 0) { + times_replaced++; + while (i--) + edit_delete (edit); ++#ifndef UTF8 + while (repl_str[++i]) + edit_insert (edit, repl_str[i]); ++#else /* UTF8 */ ++ while (winput2[++i]) ++ edit_insert (edit, winput2[i]); ++#endif /* UTF8 */ + } else { + edit_error_dialog (_(" Replace "), + ret == -2 +@@ -1957,10 +2247,18 @@ + times_replaced++; + while (i--) + edit_delete (edit); ++#ifndef UTF8 + while (exp2[++i]) + edit_insert (edit, exp2[i]); ++#else /* UTF8 */ ++ while (winput2[++i]) ++ edit_insert (edit, winput2[i]); ++#endif + } + edit->found_len = i; ++#ifdef UTF8 ++ g_free (winput2); ++#endif /* UTF8 */ + } + /* so that we don't find the same string again */ + if (replace_backwards) { +@@ -2132,16 +2430,17 @@ + #define TEMP_BUF_LEN 1024 + + /* Return a null terminated length of text. Result must be g_free'd */ +-static unsigned char * ++static mc_wchar_t * + edit_get_block (WEdit *edit, long start, long finish, int *l) + { +- unsigned char *s, *r; +- r = s = g_malloc (finish - start + 1); ++ mc_wchar_t *s, *r; ++ r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t)); + if (column_highlighting) { + *l = 0; + /* copy from buffer, excluding chars that are out of the column 'margins' */ + while (start < finish) { +- int c, x; ++ mc_wchar_t c; ++ int x; + x = edit_move_forward3 (edit, edit_bol (edit, start), 0, + start); + c = edit_get_byte (edit, start); +@@ -2174,11 +2473,15 @@ + return 0; + + if (column_highlighting) { +- unsigned char *block, *p; ++ mc_wchar_t *block, *p; + int r; + p = block = edit_get_block (edit, start, finish, &len); + while (len) { ++#ifndef UTF8 + r = mc_write (file, p, len); ++#else /* UTF8 */ ++ r = wchar_write (file, p, len); ++#endif /* UTF8 */ + if (r < 0) + break; + p += r; +@@ -2186,15 +2489,19 @@ + } + g_free (block); + } else { +- unsigned char *buf; ++ mc_wchar_t *buf; + int i = start, end; + len = finish - start; +- buf = g_malloc (TEMP_BUF_LEN); ++ buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t)); + while (start != finish) { + end = min (finish, start + TEMP_BUF_LEN); + for (; i < end; i++) + buf[i - start] = edit_get_byte (edit, i); ++#ifndef UTF8 + len -= mc_write (file, (char *) buf, end - start); ++#else /* UTF8 */ ++ len -= wchar_write (file, buf, end - start); ++#endif /* UTF8 */ + start = end; + } + g_free (buf); +@@ -2531,17 +2838,20 @@ + + /* prints at the cursor */ + /* returns the number of chars printed */ ++#ifndef UTF8 + int edit_print_string (WEdit * e, const char *s) ++#else /* UTF8 */ ++int edit_print_wstring (WEdit * e, mc_wchar_t *s) ++#endif /* UTF8 */ + { + int i = 0; + while (s[i]) +- edit_execute_cmd (e, -1, (unsigned char) s[i++]); ++ edit_execute_cmd (e, -1, s[i++]); + e->force |= REDRAW_COMPLETELY; + edit_update_screen (e); + return i; + } + +- + static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc) + { + FILE *p = 0; +@@ -2635,15 +2945,20 @@ + /* find first character of current word */ + static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len) + { +- int i, c, last; ++ int i; ++ mc_wint_t c, last; + + /* return if at begin of file */ + if (edit->curs1 <= 0) + return 0; + +- c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1); ++ c = edit_get_byte (edit, edit->curs1 - 1); + /* return if not at end or in word */ ++#ifndef UTF8 + if (isspace (c) || !(isalnum (c) || c == '_')) ++#else /* UTF8 */ ++ if (iswspace (c) || !(iswalnum (c) || c == '_')) ++#endif /* UTF8 */ + return 0; + + /* search start of word to be completed */ +@@ -2653,11 +2968,19 @@ + return 0; + + last = c; +- c = (unsigned char) edit_get_byte (edit, edit->curs1 - i); ++ c = edit_get_byte (edit, edit->curs1 - i); + ++#ifndef UTF8 + if (!(isalnum (c) || c == '_')) { ++#else /* UTF8 */ ++ if (!(iswalnum (c) || c == '_')) { ++#endif /* UTF8 */ + /* return if word starts with digit */ ++#ifndef UTF8 + if (isdigit (last)) ++#else /* UTF8 */ ++ if (iswdigit (last)) ++#endif /* UTF8 */ + return 0; + + *word_start = edit->curs1 - (i - 1); /* start found */ +@@ -2690,7 +3013,7 @@ + int *num) + { + int len, max_len = 0, i, skip; +- char *bufpos; ++ mc_wchar_t *bufpos; + + /* collect max MAX_WORD_COMPLETIONS completions */ + while (*num < MAX_WORD_COMPLETIONS) { +@@ -2711,9 +3034,16 @@ + buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE]; + skip = 0; + for (i = 0; i < *num; i++) { ++#ifndef UTF8 + if (strncmp + (&compl[i].text[word_len], &bufpos[word_len], +- max (len, compl[i].len) - word_len) == 0) { ++ max (len, ++#else /* UTF8 */ ++ if (wcsncmp ++ ((wchar_t *) &compl[i].text[word_len], ++ (wchar_t *) &bufpos[word_len], max (len, ++#endif /* UTF8 */ ++ compl[i].len) - word_len) == 0) { + skip = 1; + break; /* skip it, already added */ + } +@@ -2721,7 +3051,7 @@ + if (skip) + continue; + +- compl[*num].text = g_malloc (len + 1); ++ compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t)); + compl[*num].len = len; + for (i = 0; i < len; i++) + compl[*num].text[i] = *(bufpos + i); +@@ -2735,6 +3065,18 @@ + return max_len; + } + ++#ifdef UTF8 ++int edit_print_string (WEdit * e, const char *s) ++{ ++ int i; ++ mc_wchar_t *ws = mbstr_to_wchar(s); ++ i = edit_print_wstring (e, ws); ++ g_free(ws); ++ return i; ++} ++ ++#endif /* UTF8 */ ++ + + /* let the user select its preferred completion */ + static void +@@ -2747,6 +3089,10 @@ + WListbox *compl_list; + int compl_dlg_h; /* completion dialog height */ + int compl_dlg_w; /* completion dialog width */ ++#ifdef UTF8 ++ char *mbtext; ++#endif /* UTF8 */ ++ + + /* calculate the dialog metrics */ + compl_dlg_h = num_compl + 2; +@@ -2782,8 +3128,16 @@ + add_widget (compl_dlg, compl_list); + + /* fill the listbox with the completions */ ++#ifndef UTF8 + for (i = 0; i < num_compl; i++) + listbox_add_item (compl_list, 0, 0, compl[i].text, NULL); ++#else /* UTF8 */ ++ for (i = 0; i < num_compl; i++) { ++ mbtext = wchar_to_mbstr(compl[i].text); ++ listbox_add_item (compl_list, 0, 0, mbtext, NULL); ++ g_free(mbtext); ++ } ++#endif /* UTF8 */ + + /* pop up the dialog */ + run_dlg (compl_dlg); +@@ -2791,9 +3145,17 @@ + /* apply the choosen completion */ + if (compl_dlg->ret_value == B_ENTER) { + listbox_get_current (compl_list, &curr, NULL); +- if (curr) ++ if (curr){ ++#ifndef UTF8 + for (curr += word_len; *curr; curr++) + edit_insert (edit, *curr); ++#else /* UTF8 */ ++ mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr); ++ for (wc = wccurr + word_len; *wc; wc++) ++ edit_insert (edit, *wc); ++ g_free(wccurr); ++#endif /* UTF8 */ ++ } + } + + /* destroy dialog before return */ +@@ -2810,8 +3172,9 @@ + { + int word_len = 0, i, num_compl = 0, max_len; + long word_start = 0; +- char *bufpos; +- char *match_expr; ++ mc_wchar_t *bufpos; ++ mc_wchar_t *match_expr; ++ char *mbmatch_expr; + struct selection compl[MAX_WORD_COMPLETIONS]; /* completions */ + + /* don't want to disturb another search */ +@@ -2828,16 +3191,32 @@ + /* prepare match expression */ + bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] + [word_start & M_EDIT_BUF_SIZE]; ++ ++ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t)); ++#ifndef UTF8 + match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); ++#else /* UTF8 */ ++ wcsncpy (match_expr, bufpos, word_len); ++ match_expr[word_len] = '\0'; ++ wcscat (match_expr, L"[a-zA-Z_0-9]+"); ++#endif /* UTF8 */ + + /* init search: backward, regexp, whole word, case sensitive */ + edit_set_search_parameters (0, 1, 1, 1, 1); + + /* collect the possible completions */ + /* start search from curs1 down to begin of file */ ++#ifndef UTF8 + max_len = + edit_collect_completions (edit, word_start, word_len, match_expr, + (struct selection *) &compl, &num_compl); ++#else /* UTF8 */ ++ mbmatch_expr = wchar_to_mbstr(match_expr); ++ max_len = ++ edit_collect_completions (edit, word_start, word_len, mbmatch_expr, ++ (struct selection *) &compl, &num_compl); ++ g_free(mbmatch_expr); ++#endif /* UTF8 */ + + if (num_compl > 0) { + /* insert completed word if there is only one match */ +diff -urN mc-4.6.1.orig/edit/editdraw.c mc-4.6.1/edit/editdraw.c +--- mc-4.6.1.orig/edit/editdraw.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/editdraw.c 2007-01-19 18:33:59.000000000 +0500 +@@ -48,7 +48,7 @@ + + static void status_string (WEdit * edit, char *s, int w) + { +- char byte_str[16]; ++ char byte_str[32]; + + /* + * If we are at the end of file, print , +@@ -56,11 +56,16 @@ + * as decimal and as hex. + */ + if (edit->curs1 < edit->last_byte) { +- unsigned char cur_byte = edit_get_byte (edit, edit->curs1); ++ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1); ++#ifndef UTF8 + g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X", + is_printable (cur_byte) ? cur_byte : '.', +- (int) cur_byte, +- (unsigned) cur_byte); ++#else /* UTF8 */ ++ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X", ++ iswprint(cur_byte) ? cur_byte : '.', ++#endif /* UTF8 */ ++ (int) cur_byte, ++ (unsigned) cur_byte); + } else { + strcpy (byte_str, ""); + } +@@ -183,11 +188,16 @@ + #define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color)) + #endif + ++struct line_s { ++ mc_wchar_t ch; ++ unsigned int style; ++}; ++ + static void + print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, +- long end_col, unsigned int line[]) ++ long end_col, struct line_s line[]) + { +- unsigned int *p; ++ struct line_s *p; + + int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET; + int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET; +@@ -201,9 +211,9 @@ + edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y); + p = line; + +- while (*p) { ++ while (p->ch) { + int style; +- int textchar; ++ mc_wchar_t textchar; + int color; + + if (cols_to_skip) { +@@ -212,9 +222,9 @@ + continue; + } + +- style = *p & 0xFF00; +- textchar = *p & 0xFF; +- color = *p >> 16; ++ style = p->style & 0xFF00; ++ textchar = p->ch; ++ color = p->style >> 16; + + if (style & MOD_ABNORMAL) { + /* Non-printable - use black background */ +@@ -228,8 +238,11 @@ + } else { + lowlevel_set_color (color); + } +- ++#ifdef UTF8 ++ SLsmg_write_nwchars(&textchar, 1); ++#else + addch (textchar); ++#endif + p++; + } + } +@@ -239,11 +252,11 @@ + edit_draw_this_line (WEdit *edit, long b, long row, long start_col, + long end_col) + { +- static unsigned int line[MAX_LINE_LEN]; +- unsigned int *p = line; ++ struct line_s line[MAX_LINE_LEN]; ++ struct line_s *p = line; + long m1 = 0, m2 = 0, q, c1, c2; + int col, start_col_real; +- unsigned int c; ++ mc_wint_t c; + int color; + int i, book_mark = -1; + +@@ -265,66 +278,96 @@ + + if (row <= edit->total_lines - edit->start_line) { + while (col <= end_col - edit->start_col) { +- *p = 0; ++ p->ch = 0; ++ p->style = 0; + if (q == edit->curs1) +- *p |= MOD_CURSOR; ++ p->style |= MOD_CURSOR; + if (q >= m1 && q < m2) { + if (column_highlighting) { + int x; + x = edit_move_forward3 (edit, b, 0, q); + if (x >= c1 && x < c2) +- *p |= MOD_MARKED; ++ p->style |= MOD_MARKED; + } else +- *p |= MOD_MARKED; ++ p->style |= MOD_MARKED; + } + if (q == edit->bracket) +- *p |= MOD_BOLD; ++ p->style |= MOD_BOLD; + if (q >= edit->found_start + && q < edit->found_start + edit->found_len) +- *p |= MOD_BOLD; ++ p->style |= MOD_BOLD; + c = edit_get_byte (edit, q); + /* we don't use bg for mc - fg contains both */ + if (book_mark == -1) { + edit_get_syntax_color (edit, q, &color); +- *p |= color << 16; ++ p->style |= color << 16; + } else { +- *p |= book_mark << 16; ++ p->style |= book_mark << 16; + } + q++; + switch (c) { + case '\n': + col = end_col - edit->start_col + 1; /* quit */ +- *(p++) |= ' '; ++ p->ch = ' '; ++ p++; + break; + case '\t': + i = TAB_SIZE - ((int) col % TAB_SIZE); +- *p |= ' '; +- c = *(p++) & ~MOD_CURSOR; ++ p->ch = ' '; ++ c = p->style & ~MOD_CURSOR; ++ p++; + col += i; +- while (--i) +- *(p++) = c; ++ while (--i) { ++ p->ch = ' '; p->style = c; ++ p++; ++ } + break; + default: + c = convert_to_display_c (c); + + /* Caret notation for control characters */ + if (c < 32) { +- *(p++) = '^' | MOD_ABNORMAL; +- *(p++) = (c + 0x40) | MOD_ABNORMAL; ++ p->ch = '^'; ++ p->style = MOD_ABNORMAL; ++ p++; ++ p->ch = c + 0x40; ++ p->style = MOD_ABNORMAL; + col += 2; + break; + } + if (c == 127) { +- *(p++) = '^' | MOD_ABNORMAL; +- *(p++) = '?' | MOD_ABNORMAL; ++ p->ch = '^'; ++ p->style = MOD_ABNORMAL; ++ p++; ++ p->ch = '?'; ++ p->style = MOD_ABNORMAL; ++ p++; + col += 2; + break; + } + +- if (is_printable (c)) { +- *(p++) |= c; ++#ifndef UTF8 ++ if (is_printable (c) ++#else /* UTF8 */ ++ if (iswprint (c) ++#ifdef __STDC_ISO_10646__ ++ && (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256)) ++#endif ++#endif /* UTF8 */ ++ ) { ++ p->ch = c; ++ p++; ++ ++#ifdef UTF8 ++ i = wcwidth(c); ++ if (i > 1) { ++ col += i - 1; ++ } ++#endif /* UTF8 */ + } else { +- *(p++) = '.' | MOD_ABNORMAL; ++ p->ch = '.'; ++ p->style = MOD_ABNORMAL; ++ p++; + } + col++; + break; +@@ -334,7 +377,7 @@ + } else { + start_col_real = start_col = 0; + } +- *p = 0; ++ p->ch = 0; + + print_to_widget (edit, row, start_col, start_col_real, end_col, line); + } +diff -urN mc-4.6.1.orig/edit/edit.h mc-4.6.1/edit/edit.h +--- mc-4.6.1.orig/edit/edit.h 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/edit.h 2007-01-19 18:33:58.000000000 +0500 +@@ -39,6 +39,27 @@ + + #include "../src/global.h" + ++#include "src/tty.h" ++ ++#ifdef UTF8 ++#include ++#include ++ ++#define mc_wchar_t wchar_t ++#define mc_wint_t wint_t ++ ++#else ++ ++#define mc_wchar_t unsigned char ++#define mc_wint_t int ++ ++#endif ++ ++ ++/* unicode private use area */ ++#define BINARY_CHAR_OFFSET 0xFFE00 ++ ++ + #define N_menus 5 + + #define SEARCH_DIALOG_OPTION_NO_SCANF 1 +@@ -99,6 +120,8 @@ + #define START_STACK_SIZE 32 + + /* Some codes that may be pushed onto or returned from the undo stack */ ++#define CHAR_INSERT 65 ++#define CHAR_INSERT_AHEAD 66 + #define CURS_LEFT 601 + #define CURS_RIGHT 602 + #define DELCHAR 603 +@@ -118,7 +141,7 @@ + + struct macro { + short command; +- short ch; ++ mc_wchar_t ch; + }; + + struct WEdit; +@@ -132,26 +155,8 @@ + void menu_save_mode_cmd (void); + int edit_raw_key_query (const char *heading, const char *query, int cancel); + int edit_file (const char *_file, int line); +-int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch); +- +-#ifndef NO_INLINE_GETBYTE +-int edit_get_byte (WEdit * edit, long byte_index); +-#else +-static inline int edit_get_byte (WEdit * edit, long byte_index) +-{ +- unsigned long p; +- if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) +- return '\n'; +- +- if (byte_index >= edit->curs1) { +- p = edit->curs1 + edit->curs2 - byte_index - 1; +- return edit->buffers2[p >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (p & M_EDIT_BUF_SIZE) - 1]; +- } else { +- return edit->buffers1[byte_index >> S_EDIT_BUF_SIZE][byte_index & M_EDIT_BUF_SIZE]; +- } +-} +-#endif +- ++int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch); ++mc_wchar_t edit_get_byte (WEdit * edit, long byte_index); + int edit_count_lines (WEdit * edit, long current, int upto); + long edit_move_forward (WEdit * edit, long current, int lines, long upto); + long edit_move_forward3 (WEdit * edit, long current, int cols, long upto); +@@ -176,11 +181,11 @@ + void edit_delete_line (WEdit * edit); + + int edit_delete (WEdit * edit); +-void edit_insert (WEdit * edit, int c); ++void edit_insert (WEdit * edit, mc_wchar_t c); + int edit_cursor_move (WEdit * edit, long increment); + void edit_push_action (WEdit * edit, long c, ...); + void edit_push_key_press (WEdit * edit); +-void edit_insert_ahead (WEdit * edit, int c); ++void edit_insert_ahead (WEdit * edit, mc_wchar_t c); + long edit_write_stream (WEdit * edit, FILE * f); + char *edit_get_write_filter (const char *writename, const char *filename); + int edit_save_confirm_cmd (WEdit * edit); +@@ -212,7 +217,7 @@ + int eval_marks (WEdit * edit, long *start_mark, long *end_mark); + void edit_status (WEdit * edit); + void edit_execute_key_command (WEdit *edit, int command, +- int char_for_insertion); ++ mc_wint_t char_for_insertion); + void edit_update_screen (WEdit * edit); + int edit_print_string (WEdit * e, const char *s); + void edit_move_to_line (WEdit * e, long line); +@@ -256,7 +261,7 @@ + void format_paragraph (WEdit *edit, int force); + + /* either command or char_for_insertion must be passed as -1 */ +-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion); ++void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion); + + #define get_sys_error(s) (s) + +diff -urN mc-4.6.1.orig/edit/editkeys.c mc-4.6.1/edit/editkeys.c +--- mc-4.6.1.orig/edit/editkeys.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/editkeys.c 2007-01-19 18:33:59.000000000 +0500 +@@ -162,10 +162,10 @@ + * 'command' is one of the editor commands from editcmddef.h. + */ + int +-edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) ++edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch) + { + int command = CK_Insert_Char; +- int char_for_insertion = -1; ++ mc_wint_t char_for_insertion = -1; + int i = 0; + static const long *key_map; + +@@ -205,7 +205,7 @@ + + #ifdef HAVE_CHARSET + if (x_key == XCTRL ('t')) { +- do_select_codepage (); ++ do_select_codepage (_(" Choose codepage ")); + + edit->force = REDRAW_COMPLETELY; + command = CK_Refresh; +@@ -242,9 +242,30 @@ + /* an ordinary insertable character */ + if (x_key < 256) { + int c = convert_from_input_c (x_key); +- ++#ifdef UTF8 ++ mbstate_t mbs; ++ int res; ++ mc_wchar_t wc; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0; ++ ++ edit->charbuf[edit->charpoint++] = c; ++ ++ res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs); ++ if (res < 0) { ++ if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */ ++ return 0; ++ } ++ edit->charpoint = 0; ++ ++ if (iswprint (wc)) { ++ char_for_insertion = wc; ++#else + if (is_printable (c)) { + char_for_insertion = c; ++#endif /* UTF8 */ + goto fin; + } + } +@@ -285,7 +306,7 @@ + *cmd = command; + *ch = char_for_insertion; + +- if (command == CK_Insert_Char && char_for_insertion == -1) { ++ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) { + /* unchanged, key has no function here */ + return 0; + } +diff -urN mc-4.6.1.orig/edit/editwidget.c mc-4.6.1/edit/editwidget.c +--- mc-4.6.1.orig/edit/editwidget.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/editwidget.c 2007-01-19 18:33:58.000000000 +0500 +@@ -337,7 +337,8 @@ + + case WIDGET_KEY: + { +- int cmd, ch; ++ int cmd; ++ mc_wint_t ch; + + /* first check alt-f, alt-e, alt-s, etc for drop menus */ + if (edit_drop_hotkey_menu (e, parm)) +diff -urN mc-4.6.1.orig/edit/edit-widget.h mc-4.6.1/edit/edit-widget.h +--- mc-4.6.1.orig/edit/edit-widget.h 2003-10-29 13:54:47.000000000 +0500 ++++ mc-4.6.1/edit/edit-widget.h 2007-01-19 18:33:58.000000000 +0500 +@@ -24,6 +24,11 @@ + unsigned char border; + }; + ++struct action { ++ mc_wchar_t ch; ++ long flags; ++}; ++ + struct WEdit { + Widget widget; + +@@ -36,8 +41,17 @@ + /* dynamic buffers and cursor position for editor: */ + long curs1; /* position of the cursor from the beginning of the file. */ + long curs2; /* position from the end of the file */ ++#ifndef UTF8 + unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ + unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++#else /* UTF8 */ ++ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ ++ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++ ++ unsigned char charbuf[MB_LEN_MAX]; ++ int charpoint; ++#endif /* UTF8 */ ++ + + /* search variables */ + long search_start; /* First character to start searching from */ +@@ -81,7 +95,7 @@ + + /* undo stack and pointers */ + unsigned long stack_pointer; +- long *undo_stack; ++ struct action *undo_stack; + unsigned long stack_size; + unsigned long stack_size_mask; + unsigned long stack_bottom; +@@ -92,6 +106,7 @@ + /* syntax higlighting */ + struct _syntax_marker *syntax_marker; + struct context_rule **rules; ++ size_t rules_count; /* number of rules that are defined */ + long last_get_rule; + struct syntax_rule rule; + char *syntax_type; /* description of syntax highlighting type being used */ +diff -urN mc-4.6.1.orig/edit/syntax.c mc-4.6.1/edit/syntax.c +--- mc-4.6.1.orig/edit/syntax.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/syntax.c 2007-01-19 18:33:58.000000000 +0500 +@@ -662,6 +662,7 @@ + strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890"); + + r = edit->rules = g_malloc (alloc_contexts * sizeof (struct context_rule *)); ++ edit->rules_count = 0; + + if (!edit->defines) + edit->defines = g_tree_new ((GCompareFunc) strcmp); +@@ -892,6 +893,7 @@ + if (num_contexts == -1) { + return line; + } ++ edit->rules_count = num_contexts; + + { + char *first_chars, *p; +@@ -916,17 +918,18 @@ + + void edit_free_syntax_rules (WEdit * edit) + { +- int i, j; ++ size_t i, j; + if (!edit) + return; + if (edit->defines) + destroy_defines (&edit->defines); + if (!edit->rules) + return; +- edit_get_rule (edit, -1); ++ if (edit->rules_count > 0) ++ edit_get_rule (edit, -1); + syntax_g_free (edit->syntax_type); + edit->syntax_type = 0; +- for (i = 0; edit->rules[i]; i++) { ++ for (i = 0; i < edit->rules_count; i++) { + if (edit->rules[i]->keyword) { + for (j = 0; edit->rules[i]->keyword[j]; j++) { + syntax_g_free (edit->rules[i]->keyword[j]->keyword); +diff -urN mc-4.6.1.orig/edit/wordproc.c mc-4.6.1/edit/wordproc.c +--- mc-4.6.1.orig/edit/wordproc.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/edit/wordproc.c 2007-01-19 18:33:58.000000000 +0500 +@@ -24,7 +24,12 @@ + + #define tab_width option_tab_spacing + ++#ifndef UTF8 + #define NO_FORMAT_CHARS_START "-+*\\,.;:&>" ++#else /* UTF8 */ ++#define NO_FORMAT_CHARS_START L"-+*\\,.;:&>" ++#endif /* UTF8 */ ++ + #define FONT_MEAN_WIDTH 1 + + static long +@@ -41,14 +46,21 @@ + p = edit_move_forward (edit, p, line - l, 0); + + p = edit_bol (edit, p); ++ ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ ++ + p++; + return p; + } + + static int bad_line_start (WEdit * edit, long p) + { +- int c; ++ mc_wint_t c; ++ + c = edit_get_byte (edit, p); + if (c == '.') { /* `...' is acceptable */ + if (edit_get_byte (edit, p + 1) == '.') +@@ -62,7 +74,13 @@ + return 0; /* `---' is acceptable */ + return 1; + } ++ ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START, c)) ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START, c)) ++#endif /* UTF8 */ ++ + return 1; + return 0; + } +@@ -115,33 +133,37 @@ + i - edit->curs_line, 0)); + } + +-static unsigned char * ++static mc_wchar_t * + get_paragraph (WEdit *edit, long p, long q, int indent, int *size) + { +- unsigned char *s, *t; ++ mc_wchar_t *s, *t; + #if 0 +- t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + +- 10); ++ t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length + ++ 10) * sizeof(mc_wchar_t)); + #else +- t = g_malloc (2 * (q - p) + 100); ++ t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t)); + #endif + if (!t) + return 0; + for (s = t; p < q; p++, s++) { + if (indent) + if (edit_get_byte (edit, p - 1) == '\n') ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + *s = edit_get_byte (edit, p); + } +- *size = (unsigned long) s - (unsigned long) t; ++ *size = s - t; + t[*size] = '\n'; + return t; + } + +-static void strip_newlines (unsigned char *t, int size) ++static void strip_newlines (mc_wchar_t *t, int size) + { +- unsigned char *p = t; ++ mc_wchar_t *p = t; + while (size--) { + *p = *p == '\n' ? ' ' : *p; + p++; +@@ -158,7 +180,7 @@ + { + return x += tab_width - x % tab_width; + } +-static int line_pixel_length (unsigned char *t, long b, int l) ++static int line_pixel_length (mc_wchar_t *t, long b, int l) + { + int x = 0, c, xn = 0; + for (;;) { +@@ -182,7 +204,7 @@ + } + + /* find the start of a word */ +-static int next_word_start (unsigned char *t, int q, int size) ++static int next_word_start (mc_wchar_t *t, int q, int size) + { + int i; + for (i = q;; i++) { +@@ -203,7 +225,7 @@ + } + + /* find the start of a word */ +-static int word_start (unsigned char *t, int q, int size) ++static int word_start (mc_wchar_t *t, int q, int size) + { + int i = q; + if (t[q] == ' ' || t[q] == '\t') +@@ -222,7 +244,7 @@ + } + + /* replaces ' ' with '\n' to properly format a paragraph */ +-static void format_this (unsigned char *t, int size, int indent) ++static void format_this (mc_wchar_t *t, int size, int indent) + { + int q = 0, ww; + strip_newlines (t, size); +@@ -250,7 +272,7 @@ + } + } + +-static void replace_at (WEdit * edit, long q, int c) ++static void replace_at (WEdit * edit, long q, mc_wint_t c) + { + edit_cursor_move (edit, q - edit->curs1); + edit_delete (edit); +@@ -258,18 +280,27 @@ + } + + /* replaces a block of text */ +-static void put_paragraph (WEdit * edit, unsigned char *t, long p, long q, int indent, int size) ++static void put_paragraph (WEdit * edit, mc_wchar_t *t, long p, long q, int indent, int size) + { + long cursor; +- int i, c = 0; ++ int i; ++ mc_wchar_t c = 0; + cursor = edit->curs1; + if (indent) ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + for (i = 0; i < size; i++, p++) { + if (i && indent) { + if (t[i - 1] == '\n' && c == '\n') { ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + } else if (t[i - 1] == '\n') { + long curs; +@@ -281,7 +312,11 @@ + p = edit->curs1; + } else if (c == '\n') { + edit_cursor_move (edit, p - edit->curs1); ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) { ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) { ++#endif /* UTF8 */ + edit_delete (edit); + if (cursor > edit->curs1) + cursor--; +@@ -314,7 +349,7 @@ + { + long p, q; + int size; +- unsigned char *t; ++ mc_wchar_t *t; + int indent = 0; + if (option_word_wrap_line_length < 2) + return; +@@ -324,17 +359,25 @@ + q = end_paragraph (edit, force); + indent = test_indent (edit, p, q); + t = get_paragraph (edit, p, q, indent, &size); +- if (!t) ++ if (!t) + return; + if (!force) { + int i; ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START, *t)) { ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START, *t)) { ++#endif /* UTF8 */ + g_free (t); + return; + } + for (i = 0; i < size - 1; i++) { + if (t[i] == '\n') { ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) { ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) { ++#endif /* UTF8 */ + g_free (t); + return; + } +diff -urN mc-4.6.1.orig/lib/mc.menu mc-4.6.1/lib/mc.menu +--- mc-4.6.1.orig/lib/mc.menu 2004-08-17 14:31:16.000000000 +0600 ++++ mc-4.6.1/lib/mc.menu 2007-01-19 18:33:58.000000000 +0500 +@@ -15,7 +15,7 @@ + + 0 Edit a bug report and send it to root + I=`mktemp ${MC_TMPDIR:-/tmp}/mail.XXXXXX` || exit 1 +- ${EDITOR-vi} $I ++ ${EDITOR-editor} $I + test -r $I && mail root < $I + rm -f $I + +@@ -330,3 +330,7 @@ + o Open next a free console + open -s -- sh + ++=+ f \.dsc$ & t r ++x Extract the contents of a Debian source package ++ dpkg-source -x %f ++ +diff -urN mc-4.6.1.orig/po/de.po mc-4.6.1/po/de.po +--- mc-4.6.1.orig/po/de.po 2005-07-23 22:53:27.000000000 +0600 ++++ mc-4.6.1/po/de.po 2007-01-19 18:33:58.000000000 +0500 +@@ -1412,7 +1412,7 @@ + #: src/cmd.c:988 + #, c-format + msgid " edit symlink: %s " +-msgstr " symbolschen Link barbeiten: %s" ++msgstr " symbolschen Link bearbeiten: %s" + + #: src/cmd.c:999 + #, c-format +@@ -1562,7 +1562,7 @@ + " Cannot create temporary command file \n" + " %s " + msgstr "" +-" Kann temporre Befehlsdaei nicht anlegen \n" ++" Kann temporre Befehlsdatei nicht anlegen \n" + " %s " + + #: src/ext.c:117 src/user.c:606 +@@ -1670,7 +1670,7 @@ + " Cannot stat source file \"%s\" \n" + " %s " + msgstr "" +-" Kann Quelldaei \"%s\" nicht untersuchen \n" ++" Kann Quelldatei \"%s\" nicht untersuchen \n" + " %s " + + #: src/file.c:517 src/file.c:1058 +@@ -2576,7 +2576,7 @@ + #: src/learn.c:115 + #, c-format + msgid " You have entered \"%s\"" +-msgstr " Sie haben \"%s\" einggeben" ++msgstr " Sie haben \"%s\" eingegeben" + + #. TRANSLATORS: This label appears near learned keys. Keep it short. + #: src/learn.c:164 +@@ -2668,7 +2668,7 @@ + + #: src/main.c:811 src/main.c:835 + msgid "S&hell link..." +-msgstr "Shell-Verbindung..." ++msgstr "S&hell-Verbindung..." + + #: src/main.c:813 src/main.c:837 + msgid "SM&B link..." +@@ -4200,7 +4200,7 @@ + #: vfs/ftpfs.c:684 + #, c-format + msgid "ftpfs: connection to server failed: %s" +-msgstr "ftpfs: Verbindung zum Server fehlgeschlgen: %s" ++msgstr "ftpfs: Verbindung zum Server fehlgeschlagen: %s" + + #: vfs/ftpfs.c:725 + #, c-format +diff -urN mc-4.6.1.orig/po/it.po mc-4.6.1/po/it.po +--- mc-4.6.1.orig/po/it.po 2005-07-23 22:53:28.000000000 +0600 ++++ mc-4.6.1/po/it.po 2007-01-19 18:33:58.000000000 +0500 +@@ -2098,7 +2098,7 @@ + + #: src/filegui.c:524 + msgid "A&ppend" +-msgstr "Atta&cca" ++msgstr "atta&Cca" + + #: src/filegui.c:527 + msgid "Overwrite this target?" +diff -urN mc-4.6.1.orig/po/ru.po mc-4.6.1/po/ru.po +--- mc-4.6.1.orig/po/ru.po 2005-07-23 22:53:30.000000000 +0600 ++++ mc-4.6.1/po/ru.po 2007-01-19 18:33:59.000000000 +0500 +@@ -4503,3 +4503,32 @@ + #: vfs/vfs.c:894 + msgid "Changes to file lost" + msgstr " " ++ ++#: messages for recode patch ++msgid "Panel &codepage" ++msgstr " " ++ ++msgid " Choose codepage " ++msgstr " " ++ ++msgid " Choose panel codepage " ++msgstr " " ++ ++msgid " Choose default FTP codepage " ++msgstr " FTP " ++ ++msgid "FTP default codepage:" ++msgstr " FTP :" ++ ++msgid "Recode file names:" ++msgstr " :" ++ ++msgid "Recoding works only with COPY/MOVE operation" ++msgstr " /" ++ ++msgid " Choose \"FROM\" codepage for COPY/MOVE operaion " ++msgstr" / " ++ ++msgid " Choose \"TO\" codepage for COPY/MOVE operaion " ++msgstr" / " ++ +diff -urN mc-4.6.1.orig/po/vi.po mc-4.6.1/po/vi.po +--- mc-4.6.1.orig/po/vi.po 1970-01-01 05:00:00.000000000 +0500 ++++ mc-4.6.1/po/vi.po 2007-01-19 18:33:58.000000000 +0500 +@@ -0,0 +1,4456 @@ ++# Vietnamese translation of Midnight Commander ++# Copyright (C) 1998-2003, 2005 Free Software Foundation, Inc. ++# First translator(s): Phan Vinh Thinh , 2005. ++# ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: mc 4.6.1\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2003-12-24 12:16-0500\n" ++"PO-Revision-Date: 2005-03-29 01:20+0300\n" ++"Last-Translator: Phan Vinh Thinh \n" ++"Language-Team: Vietnamese \n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=UTF-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"X-Generator: KBabel 1.9.1\n" ++ ++#: edit/edit.c:146 edit/edit.c:277 edit/edit.c:285 edit/edit.c:333 ++#: edit/edit.c:348 edit/edit.c:359 edit/edit.c:375 edit/edit.c:2665 ++#: edit/editcmd.c:282 edit/editcmd.c:290 edit/editcmd.c:1719 src/wtools.c:120 ++#: src/wtools.c:275 ++msgid "Error" ++msgstr "Lỗi" ++ ++#: edit/edit.c:149 edit/edit.c:336 ++msgid " Cannot open file for reading: " ++msgstr " Không thể mở tập tin để đọc: " ++ ++#: edit/edit.c:279 ++msgid " Error reading from pipe: " ++msgstr " Lỗi đọc từ đường ống (pipe): " ++ ++#: edit/edit.c:288 ++msgid " Cannot open pipe for reading: " ++msgstr " Không thể mở đường ống để đọc: " ++ ++#: edit/edit.c:351 ++msgid " Cannot get size/permissions info for file: " ++msgstr " Không lấy được thông tin kích thước/quyền hạn của tập tin: " ++ ++#: edit/edit.c:360 ++msgid " Not an ordinary file: " ++msgstr " Tập tin không thông thường: " ++ ++#: edit/edit.c:376 ++msgid " File is too large: " ++msgstr " Tập tin quá lớn: " ++ ++#: edit/edit.c:2665 ++msgid "Macro recursion is too deep" ++msgstr "Đệ qui của macro quá sâu" ++ ++#: edit/edit.h:262 ++msgid "&Dismiss" ++msgstr "Đó&ng" ++ ++#: edit/edit.h:264 edit/editcmd.c:382 edit/editcmd.c:1228 edit/editcmd.c:1310 ++#: edit/editcmd.c:2569 edit/editmenu.c:37 edit/editoptions.c:71 ++#: src/boxes.c:139 src/boxes.c:276 src/boxes.c:372 src/boxes.c:464 ++#: src/boxes.c:590 src/boxes.c:713 src/boxes.c:835 src/boxes.c:945 ++#: src/boxes.c:1013 src/filegui.c:763 src/find.c:184 src/layout.c:348 ++#: src/option.c:113 src/subshell.c:323 src/view.c:2107 src/wtools.c:441 ++msgid "&OK" ++msgstr "Đồng ý &=" ++ ++#: edit/editcmd.c:45 edit/editcmd.c:46 ++msgid " Enter file name: " ++msgstr " Hãy nhập tên tập tin: " ++ ++#: edit/editcmd.c:283 ++msgid " Error writing to pipe: " ++msgstr " Lỗi ghi vào đường ống: " ++ ++#: edit/editcmd.c:293 ++msgid " Cannot open pipe for writing: " ++msgstr " Không thể mở đường ống để ghi: " ++ ++#: edit/editcmd.c:375 ++msgid "Quick save " ++msgstr "&Lưu nhanh" ++ ++#: edit/editcmd.c:376 ++msgid "Safe save " ++msgstr "Lưu &an toàn" ++ ++#: edit/editcmd.c:377 ++msgid "Do backups -->" ++msgstr "&Sao lưu -->" ++ ++#: edit/editcmd.c:380 edit/editcmd.c:1169 edit/editcmd.c:1226 ++#: edit/editcmd.c:1308 edit/editcmd.c:2567 edit/editoptions.c:68 ++#: src/achown.c:68 src/boxes.c:140 src/boxes.c:277 src/boxes.c:370 ++#: src/boxes.c:462 src/boxes.c:588 src/boxes.c:711 src/boxes.c:833 ++#: src/boxes.c:1013 src/chmod.c:96 src/chown.c:72 src/cmd.c:856 ++#: src/filegui.c:745 src/find.c:184 src/hotlist.c:121 src/hotlist.c:523 ++#: src/hotlist.c:830 src/hotlist.c:926 src/layout.c:349 src/learn.c:58 ++#: src/option.c:114 src/panelize.c:66 src/view.c:441 src/view.c:2104 ++#: src/wtools.c:46 src/wtools.c:439 ++msgid "&Cancel" ++msgstr "Đóng hộp thoại &-" ++ ++#: edit/editcmd.c:386 ++msgid "Extension:" ++msgstr "&Mở rộng:" ++ ++#: edit/editcmd.c:392 ++msgid " Edit Save Mode " ++msgstr " Chế độ ghi nhớ " ++ ++#: edit/editcmd.c:465 edit/editcmd.c:524 ++msgid " Save As " ++msgstr " Ghi như " ++ ++#: edit/editcmd.c:482 edit/editcmd.c:804 edit/editcmd.c:841 ++#: edit/editcmd.c:1000 edit/editcmd.c:1113 src/file.c:599 src/help.c:318 ++#: src/main.c:424 src/screen.c:1415 src/selcodepage.c:105 src/subshell.c:319 ++#: src/subshell.c:653 src/utilunix.c:401 src/utilunix.c:405 src/utilunix.c:427 ++#: vfs/mcfs.c:138 ++msgid "Warning" ++msgstr "Cảnh báo" ++ ++#: edit/editcmd.c:483 ++msgid " A file already exists with this name. " ++msgstr " Tập tin có tên như vậy đã tồn tại. " ++ ++#: edit/editcmd.c:484 ++msgid "Overwrite" ++msgstr "Ghi chèn" ++ ++#: edit/editcmd.c:484 edit/editcmd.c:569 edit/editcmd.c:768 edit/editcmd.c:804 ++#: edit/editcmd.c:844 edit/editcmd.c:1003 edit/editcmd.c:1116 ++msgid "Cancel" ++msgstr "Hủy bỏ" ++ ++#: edit/editcmd.c:526 edit/editcmd.c:2293 src/view.c:440 ++msgid " Cannot save file. " ++msgstr " Không thể ghi nhớ tập tin. " ++ ++#: edit/editcmd.c:626 edit/editcmd.c:634 edit/editcmd.c:659 edit/editcmd.c:706 ++msgid " Delete macro " ++msgstr " Xóa macro " ++ ++#: edit/editcmd.c:628 ++msgid " Cannot open temp file " ++msgstr " Không thể mở tập tin tạm thời " ++ ++#: edit/editcmd.c:636 edit/editcmd.c:697 edit/editcmd.c:754 ++msgid " Cannot open macro file " ++msgstr " Không thể mở tập tin chứa các macro " ++ ++#: edit/editcmd.c:660 ++msgid " Cannot overwrite macro file " ++msgstr " Không thể ghi chèn lên tập tin chứa các macro " ++ ++#: edit/editcmd.c:676 edit/editcmd.c:697 ++msgid " Save macro " ++msgstr " Ghi nhớ macro " ++ ++#: edit/editcmd.c:678 ++msgid " Press the macro's new hotkey: " ++msgstr " Hãy nhấn phím tắt mới của macro: " ++ ++#: edit/editcmd.c:707 edit/editkeys.c:195 edit/editkeys.c:225 ++msgid " Press macro hotkey: " ++msgstr " Hãy nhấn phím tắt của macro: " ++ ++#: edit/editcmd.c:753 ++msgid " Load macro " ++msgstr " Nạp macro " ++ ++#: edit/editcmd.c:766 ++msgid " Confirm save file? : " ++msgstr " Phê chuẩn việc ghi nhớ tập tin?: " ++ ++#: edit/editcmd.c:768 src/view.c:439 ++msgid " Save file " ++msgstr " Ghi nhớ tập tin " ++ ++#: edit/editcmd.c:768 edit/editwidget.c:288 src/view.c:2220 ++msgid "Save" ++msgstr "Ghinhớ" ++ ++#: edit/editcmd.c:804 edit/editcmd.c:842 ++msgid "" ++" Current text was modified without a file save. \n" ++" Continue discards these changes. " ++msgstr "" ++" Văn bản hiện thời đã thay đổi và chưa được ghi nhớ. \n" ++" Tiếp tục thao tác sẽ làm mất những thay đổi này. " ++ ++#: edit/editcmd.c:804 edit/editcmd.c:843 edit/editcmd.c:1003 ++#: edit/editcmd.c:1116 ++msgid "Continue" ++msgstr "Tiếp tục" ++ ++#: edit/editcmd.c:850 ++msgid " Load " ++msgstr " Nạp " ++ ++#: edit/editcmd.c:1002 edit/editcmd.c:1115 ++msgid " Block is large, you may not be able to undo this action. " ++msgstr " Khối quá lớn, có thể bạn sẽ không hủy bỏ được bước này. " ++ ++#: edit/editcmd.c:1171 ++msgid "O&ne" ++msgstr "&Một" ++ ++#: edit/editcmd.c:1173 src/file.c:2210 src/filegui.c:521 ++msgid "A&ll" ++msgstr "&Tất cả" ++ ++#: edit/editcmd.c:1175 src/file.c:2147 src/filegui.c:210 ++msgid "&Skip" ++msgstr "&Bỏ qua" ++ ++#: edit/editcmd.c:1177 ++msgid "&Replace" ++msgstr "&Thay thế" ++ ++#: edit/editcmd.c:1184 edit/editcmd.c:1191 ++msgid " Replace with: " ++msgstr " Thay thế bằng: " ++ ++#: edit/editcmd.c:1196 ++msgid " Confirm replace " ++msgstr " Phê chuẩn thay thế " ++ ++#: edit/editcmd.c:1230 edit/editcmd.c:1312 ++msgid "scanf &Expression" ++msgstr "biểu thức &Scanf" ++ ++#: edit/editcmd.c:1232 ++msgid "replace &All" ++msgstr "&Thay thế tất cả" ++ ++#: edit/editcmd.c:1234 ++msgid "pr&Ompt on replace" ++msgstr "&Hỏi trước khi thay" ++ ++#: edit/editcmd.c:1236 edit/editcmd.c:1314 src/view.c:2110 ++msgid "&Backwards" ++msgstr "&Tìm ngược lại" ++ ++#: edit/editcmd.c:1238 edit/editcmd.c:1316 ++msgid "&Regular expression" ++msgstr "&Biểu thức chính quy" ++ ++#: edit/editcmd.c:1240 edit/editcmd.c:1318 ++msgid "&Whole words only" ++msgstr "&Chỉ những từ đầy đủ" ++ ++#: edit/editcmd.c:1242 edit/editcmd.c:1320 src/find.c:176 ++msgid "case &Sensitive" ++msgstr "có tính &Kiểu chữ" ++ ++#: edit/editcmd.c:1246 ++msgid " Enter replacement argument order eg. 3,2,1,4 " ++msgstr " Hãy nhập thứ tự của tham số thay thế, ví dụ 3,2,1,4 " ++ ++#: edit/editcmd.c:1250 ++msgid " Enter replacement string:" ++msgstr " Nhập chuỗi thay thế:" ++ ++#: edit/editcmd.c:1254 edit/editcmd.c:1324 src/view.c:2115 ++msgid " Enter search string:" ++msgstr " Nhập chuỗi tìm kiếm:" ++ ++#: edit/editcmd.c:1273 edit/editcmd.c:1925 edit/editcmd.c:1949 ++msgid " Replace " ++msgstr " Thay thế " ++ ++#: edit/editcmd.c:1338 edit/editcmd.c:2036 edit/editcmd.c:2038 ++#: edit/editcmd.c:2066 edit/editwidget.c:293 src/view.c:1594 src/view.c:1673 ++#: src/view.c:1826 src/view.c:1838 src/view.c:2060 src/view.c:2113 ++#: src/view.c:2120 src/view.c:2236 ++msgid "Search" ++msgstr "Tìm" ++ ++#: edit/editcmd.c:1719 ++msgid " Invalid regular expression, or scanf expression with to many conversions " ++msgstr " Biểu thức chính quy không đúng, hoặc biểu thức scanf có quá nhiều biến đổi " ++ ++#: edit/editcmd.c:1927 ++msgid " Error in replacement format string. " ++msgstr " Lỗi trong định dạng chuỗi thay thế. " ++ ++#: edit/editcmd.c:1957 ++#, c-format ++msgid " %ld replacements made. " ++msgstr " %ld thay thế được thực hiện. " ++ ++#: edit/editcmd.c:1960 edit/editcmd.c:2038 edit/editcmd.c:2066 src/view.c:1673 ++#: src/view.c:1838 ++msgid " Search string not found " ++msgstr " Không tìm thấy chuỗi tìm kiếm " ++ ++#: edit/editcmd.c:2036 ++#, c-format ++msgid " %d finds made, %d bookmarks added " ++msgstr " tìm thấy %d , thêm %d thẻ đánh dấu (bookmark) " ++ ++#: edit/editcmd.c:2088 edit/editwidget.c:296 src/help.c:826 src/main.c:1208 ++#: src/view.c:456 src/view.c:2215 src/view.c:2246 ++msgid "Quit" ++msgstr "Thoát" ++ ++#: edit/editcmd.c:2088 src/view.c:457 ++msgid " File was modified, Save with exit? " ++msgstr "Tập tin đã thay đổi, ghi nhớ khi thoát? " ++ ++#: edit/editcmd.c:2089 src/view.c:458 ++msgid "Cancel quit" ++msgstr "Không thoát" ++ ++#: edit/editcmd.c:2089 src/cmd.c:195 src/file.c:1837 src/file.c:2209 ++#: src/filegui.c:526 src/hotlist.c:1049 src/main.c:471 src/screen.c:1952 ++#: src/subshell.c:654 src/tree.c:708 src/view.c:458 vfs/mcfs.c:143 ++msgid "&Yes" ++msgstr "&Có" ++ ++#: edit/editcmd.c:2089 src/cmd.c:195 src/file.c:1837 src/file.c:2209 ++#: src/filegui.c:525 src/hotlist.c:1049 src/main.c:471 src/screen.c:1953 ++#: src/subshell.c:654 src/tree.c:708 src/view.c:458 vfs/mcfs.c:143 ++msgid "&No" ++msgstr "&Không" ++ ++#: edit/editcmd.c:2202 ++msgid " Copy to clipboard " ++msgstr "Sao chép vào bộ đệm " ++ ++#: edit/editcmd.c:2202 edit/editcmd.c:2215 ++msgid " Unable to save to file. " ++msgstr "Không ghi nhớ được tập tin. " ++ ++#: edit/editcmd.c:2215 ++msgid " Cut to clipboard " ++msgstr "Cắt vào bộ đệm " ++ ++#: edit/editcmd.c:2243 src/view.c:2005 ++msgid " Goto line " ++msgstr "Chuyển tới dòng " ++ ++#: edit/editcmd.c:2243 ++msgid " Enter line: " ++msgstr "Hãy nhập số thứ tự dòng: " ++ ++#: edit/editcmd.c:2278 edit/editcmd.c:2291 ++msgid " Save Block " ++msgstr "Ghi nhớ khối " ++ ++#: edit/editcmd.c:2307 edit/editcmd.c:2320 ++msgid " Insert File " ++msgstr "Chèn tập tin " ++ ++#: edit/editcmd.c:2322 ++msgid " Cannot insert file. " ++msgstr "Không chèn được tập tin. " ++ ++#: edit/editcmd.c:2339 ++msgid " Sort block " ++msgstr "Sắp xếp khối " ++ ++#: edit/editcmd.c:2339 edit/editcmd.c:2465 ++msgid " You must first highlight a block of text. " ++msgstr "Đầu tiên bạn phải chọn một khối văn bản. " ++ ++#: edit/editcmd.c:2346 ++msgid " Run Sort " ++msgstr "Thực hiện sắp xếp " ++ ++#: edit/editcmd.c:2347 ++msgid " Enter sort options (see manpage) separated by whitespace: " ++msgstr "Nhập tùy chọn sắp xếp (xem trang man), phân cách nhau bởi khoảng trắng: " ++ ++#: edit/editcmd.c:2358 edit/editcmd.c:2363 ++msgid " Sort " ++msgstr "Sắp xếp " ++ ++#: edit/editcmd.c:2359 ++msgid " Cannot execute sort command " ++msgstr "Không thể thực hiện câu lệnh sort " ++ ++#: edit/editcmd.c:2364 ++msgid " Sort returned non-zero: " ++msgstr "Sắp xếp trả lại giá trị khác không: " ++ ++#: edit/editcmd.c:2388 ++msgid "Paste output of external command" ++msgstr "Dán kết quả của lệnh ngoại trú" ++ ++#: edit/editcmd.c:2389 ++msgid "Enter shell command(s):" ++msgstr "Nhập (các) câu lệnh shell:" ++ ++#: edit/editcmd.c:2398 ++msgid "External command" ++msgstr "Lệnh ngoại trú" ++ ++#: edit/editcmd.c:2399 ++msgid "Cannot execute command" ++msgstr "Không thực hiện được câu lệnh" ++ ++#: edit/editcmd.c:2433 ++msgid "Error creating script:" ++msgstr "Lỗi tạo script:" ++ ++#: edit/editcmd.c:2441 ++msgid "Error reading script:" ++msgstr "Lỗi đọc script:" ++ ++#: edit/editcmd.c:2450 ++msgid "Error closing script:" ++msgstr "Lỗi đóng script:" ++ ++#: edit/editcmd.c:2456 ++msgid "Script created:" ++msgstr "Đã tạo script:" ++ ++#: edit/editcmd.c:2463 ++msgid "Process block" ++msgstr "Xử lý khối" ++ ++#: edit/editcmd.c:2562 ++msgid " Mail " ++msgstr " Thư " ++ ++#: edit/editcmd.c:2573 ++msgid " Copies to" ++msgstr " Sao chép tới" ++ ++#: edit/editcmd.c:2577 ++msgid " Subject" ++msgstr " Tên thư" ++ ++#: edit/editcmd.c:2581 ++msgid " To" ++msgstr " Người nhận" ++ ++#: edit/editcmd.c:2583 ++msgid " mail -s -c " ++msgstr " mail -s -c " ++ ++#: edit/editkeys.c:180 ++msgid " Emacs key: " ++msgstr "Phím Emacs: " ++ ++#: edit/editkeys.c:194 edit/editkeys.c:225 ++msgid " Execute Macro " ++msgstr "Thực hiện Macro " ++ ++#: edit/editkeys.c:217 ++msgid " Insert Literal " ++msgstr " Chèn văn bản thuần túy " ++ ++#: edit/editkeys.c:218 ++msgid " Press any key: " ++msgstr " Nhấn phím bất kỳ: " ++ ++#: edit/editlock.c:148 ++#, c-format ++msgid "" ++"File \"%s\" is already being edited\n" ++"User: %s\n" ++"Process ID: %d" ++msgstr "" ++"Tập tin \"%s\" đang được soạn thảo\n" ++"Ngưòi dùng: %s\n" ++"ID tiến trình: %d" ++ ++#: edit/editlock.c:153 ++msgid "File locked" ++msgstr "Tập tin bị khóa" ++ ++#: edit/editlock.c:153 ++msgid "&Grab lock" ++msgstr "&Chiếm đoạt khóa" ++ ++#: edit/editlock.c:154 ++msgid "&Ignore lock" ++msgstr "&Lời đi khóa" ++ ++#: edit/editmenu.c:55 ++msgid " About " ++msgstr " Về chương trình " ++ ++#: edit/editmenu.c:56 ++msgid "" ++"\n" ++" Cooledit v3.11.5\n" ++"\n" ++" Copyright (C) 1996 the Free Software Foundation\n" ++"\n" ++" A user friendly text editor written\n" ++" for the Midnight Commander.\n" ++msgstr "" ++"\n" ++" Cooledit v3.11.5\n" ++"\n" ++" Copyright (C) 1996 the Free Software Foundation\n" ++"\n" ++" Trình soạn thảo với giao diện người dùng thân thiện.\n" ++" Được viết cho Midnight Commander.\n" ++ ++#: edit/editmenu.c:283 edit/editmenu.c:301 ++msgid "&Open file..." ++msgstr "&Mở tập tin..." ++ ++#: edit/editmenu.c:284 ++msgid "&New C-n" ++msgstr "&Tập tin mới C-n" ++ ++#: edit/editmenu.c:286 edit/editmenu.c:304 ++msgid "&Save F2" ++msgstr "&Ghi nhớ F2" ++ ++#: edit/editmenu.c:287 edit/editmenu.c:305 ++msgid "Save &as... F12" ++msgstr "Ghi &như... F12" ++ ++#: edit/editmenu.c:289 edit/editmenu.c:307 ++msgid "&Insert file... F15" ++msgstr "&Chèn tập tin... F15" ++ ++#: edit/editmenu.c:290 ++msgid "Copy to &file... C-f" ++msgstr "Ché&p vào tập tin... C-f" ++ ++#: edit/editmenu.c:292 edit/editmenu.c:310 ++msgid "&User menu... F11" ++msgstr "Trình đơn người &dùng... F11" ++ ++#: edit/editmenu.c:294 edit/editmenu.c:312 ++msgid "A&bout... " ++msgstr "&Về chương trình... " ++ ++#: edit/editmenu.c:296 edit/editmenu.c:314 ++msgid "&Quit F10" ++msgstr "T&hoát F10" ++ ++#: edit/editmenu.c:302 ++msgid "&New C-x k" ++msgstr "&Tập tin mới C-x k" ++ ++#: edit/editmenu.c:308 ++msgid "Copy to &file... " ++msgstr "S&ao chép vào tập tin... " ++ ++#: edit/editmenu.c:319 ++msgid "&Toggle Mark F3" ++msgstr "&Bật/tắt bôi đen F3" ++ ++#: edit/editmenu.c:320 ++msgid "&Mark Columns S-F3" ++msgstr "Bôi đen &cột S-F3" ++ ++#: edit/editmenu.c:322 ++msgid "Toggle &ins/overw Ins" ++msgstr "Chế độ chèn/&thay thế Ins" ++ ++#: edit/editmenu.c:324 ++msgid "&Copy F5" ++msgstr "&Sao chép F5" ++ ++#: edit/editmenu.c:325 ++msgid "&Move F6" ++msgstr "&Di chuyển F6" ++ ++#: edit/editmenu.c:326 ++msgid "&Delete F8" ++msgstr "&Xóa F8" ++ ++#: edit/editmenu.c:328 ++msgid "&Undo C-u" ++msgstr "&Hủy bước C-u" ++ ++#: edit/editmenu.c:330 ++msgid "&Beginning C-PgUp" ++msgstr "Đầ&u tập tin C-PgUp" ++ ++#: edit/editmenu.c:331 ++msgid "&End C-PgDn" ++msgstr "Cuố&i tập tin C-PgDn" ++ ++#: edit/editmenu.c:338 ++msgid "&Search... F7" ++msgstr "Tìm &kiếm... F7" ++ ++#: edit/editmenu.c:339 ++msgid "Search &again F17" ++msgstr "&Tìm kiếm lại lần nữa F17" ++ ++#: edit/editmenu.c:340 ++msgid "&Replace... F4" ++msgstr "Th&ay thế... F4" ++ ++#: edit/editmenu.c:347 edit/editmenu.c:371 ++msgid "&Go to line... M-l" ++msgstr "&Chuyển tới dòng... M-l" ++ ++#: edit/editmenu.c:348 edit/editmenu.c:372 ++msgid "Go to matching &bracket M-b" ++msgstr "Chuyển &tới dấu ngoặc tạo cặp M-b" ++ ++#: edit/editmenu.c:350 edit/editmenu.c:374 ++msgid "Insert &literal... C-q" ++msgstr "Chèn &văn bản thuần túy... C-q" ++ ++#: edit/editmenu.c:352 edit/editmenu.c:376 ++msgid "&Refresh screen C-l" ++msgstr "&Làm mới màn hình C-l" ++ ++#: edit/editmenu.c:354 edit/editmenu.c:378 ++msgid "&Start record macro C-r" ++msgstr "&Bắt đầu ghi macro C-r" ++ ++#: edit/editmenu.c:355 edit/editmenu.c:379 ++msgid "&Finish record macro... C-r" ++msgstr "&Kết thúc ghi macro... C-r" ++ ++#: edit/editmenu.c:356 ++msgid "&Execute macro... C-a, KEY" ++msgstr "Chạy ¯o... C-a, KEY" ++ ++#: edit/editmenu.c:357 edit/editmenu.c:381 ++msgid "Delete macr&o... " ++msgstr "&Xóa macro... " ++ ++#: edit/editmenu.c:359 edit/editmenu.c:383 ++msgid "Insert &date/time " ++msgstr "Chèn &ngày/giờ " ++ ++#: edit/editmenu.c:361 edit/editmenu.c:385 ++msgid "Format p&aragraph M-p" ++msgstr "Định &dạng đoạn văn M-p" ++ ++#: edit/editmenu.c:362 ++msgid "'ispell' s&pell check C-p" ++msgstr "Kiểm tra chính tả '&ispell' C-p" ++ ++#: edit/editmenu.c:363 edit/editmenu.c:387 ++msgid "Sor&t... M-t" ++msgstr "&Sắp xếp... M-t" ++ ++#: edit/editmenu.c:364 edit/editmenu.c:388 ++msgid "Paste o&utput of... M-u" ++msgstr "Dán &kết quả của lệnh... M-u" ++ ++#: edit/editmenu.c:365 edit/editmenu.c:389 ++msgid "E&xternal Formatter F19" ++msgstr "T&rình định dạng ngoài F19" ++ ++#: edit/editmenu.c:366 edit/editmenu.c:390 ++msgid "&Mail... " ++msgstr "T&hư điện tử... " ++ ++#: edit/editmenu.c:380 ++msgid "&Execute macro... C-x e, KEY" ++msgstr "Thực hiện ¯o... C-x e, KEY" ++ ++#: edit/editmenu.c:386 ++msgid "'ispell' s&pell check M-$" ++msgstr "Kiểm tra chính tả '&ispell' M-$" ++ ++#: edit/editmenu.c:395 ++msgid "&General... " ++msgstr "Ch&ung... " ++ ++#: edit/editmenu.c:396 ++msgid "&Save mode..." ++msgstr "&Chế độ ghi nhớ..." ++ ++#: edit/editmenu.c:397 src/main.c:909 ++msgid "learn &Keys..." ++msgstr "&Tạo phím tắt... " ++ ++#: edit/editmenu.c:408 edit/editmenu.c:422 src/chmod.c:146 src/chown.c:119 ++msgid " File " ++msgstr " Tập tin " ++ ++#: edit/editmenu.c:410 edit/editmenu.c:424 ++msgid " Edit " ++msgstr " Soạn thảo " ++ ++#: edit/editmenu.c:412 edit/editmenu.c:426 ++msgid " Sear/Repl " ++msgstr " Tìm kiếm/Thay thế " ++ ++#: edit/editmenu.c:414 edit/editmenu.c:428 ++msgid " Command " ++msgstr " Câu lệnh " ++ ++#: edit/editmenu.c:416 edit/editmenu.c:430 ++msgid " Options " ++msgstr " Tùy chọn " ++ ++#: edit/editoptions.c:36 ++msgid "Intuitive" ++msgstr "T&rực giác" ++ ++#: edit/editoptions.c:36 ++msgid "Emacs" ++msgstr "&Emacs" ++ ++#: edit/editoptions.c:39 ++msgid "None" ++msgstr "&Không" ++ ++#: edit/editoptions.c:39 ++msgid "Dynamic paragraphing" ++msgstr "Định &dạng đoạn văn động" ++ ++#: edit/editoptions.c:39 ++msgid "Type writer wrap" ++msgstr "Tự độ&ng chuyển dòng" ++ ++#: edit/editoptions.c:75 ++msgid "Word wrap line length: " ++msgstr "Vị trí chuyển dòng: " ++ ++#: edit/editoptions.c:81 ++msgid "Tab spacing: " ++msgstr "Độ rộng tab: " ++ ++#: edit/editoptions.c:88 ++msgid "Synta&x highlighting" ++msgstr "&Chiếu sáng cú pháp" ++ ++#: edit/editoptions.c:91 ++msgid "Save file &position" ++msgstr "&Ghi nhớ vị trí trong tập tin" ++ ++#: edit/editoptions.c:94 ++msgid "Confir&m before saving" ++msgstr "&Hỏi lại trước khi ghi nhớ" ++ ++#: edit/editoptions.c:97 ++msgid "Fill tabs with &spaces" ++msgstr "&Làm đầy tab bằng khoảng trắng" ++ ++#: edit/editoptions.c:100 ++msgid "&Return does autoindent" ++msgstr "&Enter tự động thụt dòng" ++ ++#: edit/editoptions.c:103 ++msgid "&Backspace through tabs" ++msgstr "&Backpace xóa hết tab" ++ ++#: edit/editoptions.c:106 ++msgid "&Fake half tabs" ++msgstr "&Tạo một nửa tab" ++ ++#: edit/editoptions.c:112 ++msgid "Wrap mode" ++msgstr "Chế độ chuyển dòng" ++ ++#: edit/editoptions.c:119 ++msgid "Key emulation" ++msgstr "Giả tạo phím" ++ ++#: edit/editoptions.c:124 ++msgid " Editor options " ++msgstr " Cấu hình trình soạn thảo " ++ ++#: edit/editwidget.c:287 src/help.c:793 src/help.c:814 src/main.c:1205 ++#: src/screen.c:2184 src/tree.c:970 src/view.c:2213 ++msgid "Help" ++msgstr "Giúpđỡ" ++ ++#: edit/editwidget.c:289 ++msgid "Mark" ++msgstr "Bôiđen" ++ ++#: edit/editwidget.c:290 ++msgid "Replac" ++msgstr "Thayth" ++ ++#: edit/editwidget.c:291 src/file.c:803 src/screen.c:2188 src/tree.c:975 ++msgid "Copy" ++msgstr "Cópi " ++ ++#: edit/editwidget.c:292 ++msgid "Move" ++msgstr "Chuyển" ++ ++#: edit/editwidget.c:294 src/screen.c:2191 ++msgid "Delete" ++msgstr "Xóa " ++ ++#: edit/editwidget.c:295 src/main.c:1207 ++msgid "PullDn" ++msgstr "GọiTĐ " ++ ++#: edit/syntax.c:1100 edit/syntax.c:1107 ++msgid " Load syntax file " ++msgstr " Nạp tập tin cú pháp " ++ ++#: edit/syntax.c:1101 src/help.c:764 src/user.c:711 ++#, c-format ++msgid "" ++" Cannot open file %s \n" ++" %s " ++msgstr "" ++" Không mở được tập tin %s \n" ++" %s " ++ ++#: edit/syntax.c:1108 ++#, c-format ++msgid " Error in file %s on line %d " ++msgstr " Lỗi trong tập tin %s trên dòng %d " ++ ++#: src/achown.c:69 src/chmod.c:97 src/chown.c:73 ++msgid "&Set" ++msgstr "Đồ&ng ý" ++ ++#: src/achown.c:70 ++msgid "S&kip" ++msgstr "&Bỏ qua" ++ ++#: src/achown.c:71 src/chmod.c:101 src/chown.c:76 ++msgid "Set &all" ++msgstr "Đặt &tất cả" ++ ++#: src/achown.c:250 src/achown.c:338 src/achown.c:345 ++msgid "owner" ++msgstr "sở hữu" ++ ++#: src/achown.c:250 src/achown.c:340 src/achown.c:347 ++msgid "group" ++msgstr "nhóm" ++ ++#: src/achown.c:342 ++msgid "other" ++msgstr "khác" ++ ++#: src/achown.c:350 ++msgid "On" ++msgstr "Trên" ++ ++#: src/achown.c:352 ++msgid "Flag" ++msgstr "Cờ" ++ ++#: src/achown.c:354 ++msgid "Mode" ++msgstr "Chếđộ" ++ ++#: src/achown.c:358 ++#, c-format ++msgid "%6d of %d" ++msgstr "%6d của %d" ++ ++#: src/achown.c:549 ++msgid " Chown advanced command " ++msgstr " Câu lệnh chown mở rộng" ++ ++#: src/achown.c:607 src/achown.c:623 src/achown.c:669 src/chmod.c:241 ++#: src/chmod.c:311 ++#, c-format ++msgid "" ++" Cannot chmod \"%s\" \n" ++" %s " ++msgstr "" ++" Không chmod được \"%s\" \n" ++" %s " ++ ++#: src/achown.c:612 src/achown.c:627 src/achown.c:673 src/chown.c:214 ++#: src/chown.c:322 ++#, c-format ++msgid "" ++" Cannot chown \"%s\" \n" ++" %s " ++msgstr "" ++" Không thay thế được chủ sở hữu \"%s\" \n" ++" %s " ++ ++#: src/background.c:205 src/file.c:2145 ++msgid " Background process error " ++msgstr " Lỗi của tiến trình nền sau " ++ ++#: src/background.c:211 ++msgid " Unknown error in child " ++msgstr " Lỗi không rõ trong tiến trình con " ++ ++#: src/background.c:219 ++msgid " Child died unexpectedly " ++msgstr " Tiến trình con bất đắc kỳ tử " ++ ++#: src/background.c:226 ++msgid " Background protocol error " ++msgstr " Lỗi giao thức nền sau " ++ ++#: src/background.c:227 ++msgid "" ++" Background process sent us a request for more arguments \n" ++" than we can handle. \n" ++msgstr "" ++" Tiến trình nền sau yêu cầu nhiều tham số hơn, \n" ++" số chúng ta có thể điều khiển. \n" ++ ++#: src/boxes.c:75 ++msgid "&Full file list" ++msgstr "&Danh sách đầy đủ" ++ ++#: src/boxes.c:76 ++msgid "&Brief file list" ++msgstr "&Thu gọn" ++ ++#: src/boxes.c:77 ++msgid "&Long file list" ++msgstr "&Mở rộng" ++ ++#: src/boxes.c:78 ++msgid "&User defined:" ++msgstr "&Người dùng tự xác định:" ++ ++#: src/boxes.c:136 ++msgid "Listing mode" ++msgstr "Dạng danh sách" ++ ++#: src/boxes.c:138 ++msgid "user &Mini status" ++msgstr "t&Rạng thái mini" ++ ++#: src/boxes.c:278 ++msgid "&Reverse" ++msgstr "&Ngược lại" ++ ++#: src/boxes.c:279 ++msgid "case sensi&tive" ++msgstr "tính đến kiể&U chữ" ++ ++#: src/boxes.c:280 ++msgid "Sort order" ++msgstr "Thứ tự sắp xếp" ++ ++#: src/boxes.c:375 ++msgid " confirm &Exit " ++msgstr " trước khi th&Oát " ++ ++#: src/boxes.c:377 ++msgid " confirm e&Xecute " ++msgstr " trước &Khi thực hiện " ++ ++#: src/boxes.c:379 ++msgid " confirm o&Verwrite " ++msgstr " &Trước khi ghi chèn " ++ ++#: src/boxes.c:381 ++msgid " confirm &Delete " ++msgstr " hỏi lại trước khi &Xóa " ++ ++#: src/boxes.c:387 src/cmd.c:194 ++msgid " Confirmation " ++msgstr " Hỏi xác nhận " ++ ++#: src/boxes.c:459 ++msgid "Full 8 bits output" ++msgstr "Đầu ra 8 bit đầy đủ" ++ ++#: src/boxes.c:459 ++msgid "ISO 8859-1" ++msgstr "ISO.8859-1" ++ ++#: src/boxes.c:459 ++msgid "7 bits" ++msgstr "7 bit" ++ ++#: src/boxes.c:466 src/boxes.c:594 ++msgid "F&ull 8 bits input" ++msgstr "Đầ&u vào 8 bit đầy đủ" ++ ++#: src/boxes.c:474 src/boxes.c:575 ++msgid " Display bits " ++msgstr " Ký tự hiển thị " ++ ++#: src/boxes.c:556 src/boxes.c:581 src/selcodepage.c:70 ++msgid "Other 8 bit" ++msgstr "8 bit khác" ++ ++#: src/boxes.c:578 ++msgid "Input / display codepage:" ++msgstr "Bảng mã đầu vào / hiển thị:" ++ ++#: src/boxes.c:597 ++msgid "&Select" ++msgstr "&Lựa chọn" ++ ++#: src/boxes.c:716 ++msgid "Use &passive mode" ++msgstr "Sử &dụng chế độ thụ động" ++ ++#: src/boxes.c:718 ++msgid "&Use ~/.netrc" ++msgstr "&Sử dụng ~/.netrc" ++ ++#: src/boxes.c:722 ++msgid "&Always use ftp proxy" ++msgstr "&Luôn luôn sử dụng ftp proxy" ++ ++#: src/boxes.c:724 ++msgid "sec" ++msgstr "giây" ++ ++#: src/boxes.c:728 ++msgid "ftpfs directory cache timeout:" ++msgstr "Thời gian chờ của cache thư mục ftp:" ++ ++#: src/boxes.c:732 ++msgid "ftp anonymous password:" ++msgstr "Mật khẩu ftp nặc danh:" ++ ++#: src/boxes.c:739 ++msgid "Timeout for freeing VFSs:" ++msgstr "Thời gian chờ giải phóng VFS:" ++ ++#: src/boxes.c:745 ++msgid " Virtual File System Setting " ++msgstr " Thiết lập hệ thống tập tin ảo " ++ ++#: src/boxes.c:799 ++msgid "Quick cd" ++msgstr "cd nhanh" ++ ++#: src/boxes.c:802 ++msgid "cd" ++msgstr "cd" ++ ++#: src/boxes.c:837 ++msgid "Symbolic link filename:" ++msgstr "Tên của liên kết mềm:" ++ ++#: src/boxes.c:841 ++msgid "Existing filename (filename symlink will point to):" ++msgstr "Tên tập tin đã có (liên kết mềm sẽ chỉ đến):" ++ ++#: src/boxes.c:848 ++msgid "Symbolic link" ++msgstr "Liên kết mềm" ++ ++#: src/boxes.c:881 ++msgid "Running " ++msgstr "Đang chạy " ++ ++#: src/boxes.c:882 src/find.c:721 ++msgid "Stopped" ++msgstr "Đã dừng" ++ ++#: src/boxes.c:942 ++msgid "&Stop" ++msgstr "&Dừng" ++ ++#: src/boxes.c:943 ++msgid "&Resume" ++msgstr "&Phục hồi" ++ ++#: src/boxes.c:944 ++msgid "&Kill" ++msgstr "&Diệt" ++ ++#: src/boxes.c:981 ++msgid "Background Jobs" ++msgstr " Công việc nền sau" ++ ++#: src/boxes.c:1012 ++msgid "Domain:" ++msgstr "Miền (domain):" ++ ++#: src/boxes.c:1012 ++msgid "Username:" ++msgstr "Tên người dùng:" ++ ++#: src/boxes.c:1012 ++msgid "Password:" ++msgstr "Mật khẩu:" ++ ++#: src/boxes.c:1063 ++#, c-format ++msgid "Password for \\\\%s\\%s" ++msgstr "Mật khẩu cho \\\\%s\\%s" ++ ++#: src/charsets.c:51 vfs/extfs.c:1260 vfs/sfs.c:318 ++#, c-format ++msgid "Warning: file %s not found\n" ++msgstr "Cảnh báo: không tìm thấy tập tin %s\n" ++ ++#: src/charsets.c:198 src/charsets.c:212 ++#, c-format ++msgid "Cannot translate from %s to %s" ++msgstr "Không chuyển được bảng mã từ %s thành %s" ++ ++#: src/chmod.c:77 ++msgid "execute/search by others" ++msgstr "người khác có quyền chạy/tìm" ++ ++#: src/chmod.c:78 ++msgid "write by others" ++msgstr "người khác có quyền ghi nhớ" ++ ++#: src/chmod.c:79 ++msgid "read by others" ++msgstr "người khác có quyền đọc" ++ ++#: src/chmod.c:80 ++msgid "execute/search by group" ++msgstr "nhóm có quyền chạy/tìm kiếm" ++ ++#: src/chmod.c:81 ++msgid "write by group" ++msgstr "nhóm có quyền ghi nhớ" ++ ++#: src/chmod.c:82 ++msgid "read by group" ++msgstr "nhóm có quyền đọc" ++ ++#: src/chmod.c:83 ++msgid "execute/search by owner" ++msgstr "chủ sở hữu có quyền chạy/tìm" ++ ++#: src/chmod.c:84 ++msgid "write by owner" ++msgstr "chủ sở hữu có quyền ghi nhớ" ++ ++#: src/chmod.c:85 ++msgid "read by owner" ++msgstr "chủ sở hữu có quyền đọc" ++ ++#: src/chmod.c:86 ++msgid "sticky bit" ++msgstr "bit dính (sticky)" ++ ++#: src/chmod.c:87 ++msgid "set group ID on execution" ++msgstr "đặt ID nhóm khi chạy" ++ ++#: src/chmod.c:88 ++msgid "set user ID on execution" ++msgstr "đặt ID người dùng khi chạy" ++ ++#: src/chmod.c:98 ++msgid "C&lear marked" ++msgstr "&Xóa đánh dấu" ++ ++#: src/chmod.c:99 ++msgid "S&et marked" ++msgstr "Đá&nh dấu" ++ ++#: src/chmod.c:100 ++msgid "&Marked all" ++msgstr "Đánh &dấu tất cả" ++ ++#: src/chmod.c:124 src/screen.c:405 ++msgid "Name" ++msgstr "Tên" ++ ++#: src/chmod.c:126 ++msgid "Permissions (Octal)" ++msgstr "Quyền hạn (Hệ tám)" ++ ++#: src/chmod.c:128 ++msgid "Owner name" ++msgstr "Tên chủ sở hữu" ++ ++#: src/chmod.c:130 ++msgid "Group name" ++msgstr "Tên nhóm" ++ ++#: src/chmod.c:133 ++msgid "Use SPACE to change" ++msgstr "Dùng PHÍM TRẮNG để thay đổi" ++ ++#: src/chmod.c:135 ++msgid "an option, ARROW KEYS" ++msgstr "tùy chọn, PHÍM MŨI TÊN" ++ ++#: src/chmod.c:137 ++msgid "to move between options" ++msgstr "để di chuyển giữa các tùy chọn" ++ ++#: src/chmod.c:139 ++msgid "and T or INS to mark" ++msgstr "và T hoặc INS để đánh dấu" ++ ++#: src/chmod.c:144 src/chown.c:111 ++msgid " Permission " ++msgstr " Quyền truy cập " ++ ++#: src/chmod.c:196 ++msgid "Chmod command" ++msgstr " Câu lệnh chmod " ++ ++#: src/chown.c:74 ++msgid "Set &users" ++msgstr "Đặt &người dùng" ++ ++#: src/chown.c:75 ++msgid "Set &groups" ++msgstr "Đặt &nhóm" ++ ++#: src/chown.c:103 ++msgid " Name " ++msgstr " Tên " ++ ++#: src/chown.c:105 ++msgid " Owner name " ++msgstr " Tên chủ sở hữu " ++ ++#: src/chown.c:107 src/chown.c:117 ++msgid " Group name " ++msgstr " Tên nhóm " ++ ++#: src/chown.c:109 ++msgid " Size " ++msgstr " Kích thước " ++ ++#: src/chown.c:115 ++msgid " User name " ++msgstr " Tên người dùng " ++ ++#: src/chown.c:158 ++msgid " Chown command " ++msgstr " Câu lệnh chown " ++ ++#: src/chown.c:178 ++msgid "" ++msgstr "" ++ ++#: src/chown.c:179 ++msgid "" ++msgstr "" ++ ++#: src/cmd.c:194 ++msgid "Files tagged, want to cd?" ++msgstr "Đã đánh dấu các tập tin, chuyển thư mục?" ++ ++#: src/cmd.c:200 src/cmd.c:670 src/cmd.c:727 src/main.c:681 src/screen.c:1933 ++msgid "Cannot change directory" ++msgstr "Không thay đổi được thư mục" ++ ++#: src/cmd.c:233 ++msgid " View file " ++msgstr " Xem tập tin " ++ ++#: src/cmd.c:233 ++msgid " Filename:" ++msgstr " Tên tập tin:" ++ ++#: src/cmd.c:255 ++msgid " Filtered view " ++msgstr " Lọc rồi xem " ++ ++#: src/cmd.c:256 ++msgid " Filter command and arguments:" ++msgstr " Lệnh lọc và tham số:" ++ ++#: src/cmd.c:355 ++msgid "Create a new Directory" ++msgstr "Tạo thư mục mới" ++ ++#: src/cmd.c:356 ++msgid " Enter directory name:" ++msgstr " Hãy nhập tên thư mục:" ++ ++#: src/cmd.c:428 ++msgid " Filter " ++msgstr " Đầu lọc " ++ ++#: src/cmd.c:429 ++msgid " Set expression for filtering filenames" ++msgstr " Đặt biểu thức để lọc tên tập tin (nhấn F1 để xem trợ giúp)" ++ ++#: src/cmd.c:482 ++msgid " Select " ++msgstr " Chọn " ++ ++#: src/cmd.c:510 src/cmd.c:555 src/find.c:147 ++msgid " Malformed regular expression " ++msgstr " Biểu thức chính quy không đúng " ++ ++#: src/cmd.c:528 ++msgid " Unselect " ++msgstr " Bỏ chọn " ++ ++#: src/cmd.c:596 ++msgid "Extension file edit" ++msgstr "Soạn thảo phần mở rộng tập tin" ++ ++#: src/cmd.c:597 ++msgid " Which extension file you want to edit? " ++msgstr " Soạn thảo phần mở rộng tập tin nào? " ++ ++#: src/cmd.c:598 src/cmd.c:701 ++msgid "&User" ++msgstr "&Người dùng" ++ ++#: src/cmd.c:598 src/cmd.c:627 src/cmd.c:701 ++msgid "&System Wide" ++msgstr "&Hệ thống" ++ ++#: src/cmd.c:624 ++msgid " Menu edit " ++msgstr " Soạn thảo tập tin trình đơn " ++ ++#: src/cmd.c:625 ++msgid " Which menu file do you want to edit? " ++msgstr " Soạn thảo tập tin trình đơn nào? " ++ ++#: src/cmd.c:627 ++msgid "&Local" ++msgstr "&Nội bộ máy" ++ ++#: src/cmd.c:627 ++msgid "&Home" ++msgstr "&Cá nhân" ++ ++#: src/cmd.c:699 ++msgid "Syntax file edit" ++msgstr "Soạn thảo tập tin cú pháp" ++ ++#: src/cmd.c:700 ++msgid " Which syntax file you want to edit? " ++msgstr " Soạn thảo tập tin cú pháp nào? " ++ ++#: src/cmd.c:854 ++msgid " Compare directories " ++msgstr " So sánh thư mục " ++ ++#: src/cmd.c:855 ++msgid " Select compare method: " ++msgstr " Chọn phương pháp so sánh: " ++ ++#: src/cmd.c:855 ++msgid "&Quick" ++msgstr "&Nhanh" ++ ++#: src/cmd.c:856 ++msgid "&Size only" ++msgstr "&Chỉ theo kích thước" ++ ++#: src/cmd.c:856 ++msgid "&Thorough" ++msgstr "&Theo từng byte" ++ ++#: src/cmd.c:869 ++msgid " Both panels should be in the listing mode to use this command " ++msgstr "Để thực hiện câu lệnh này cả hai bảng phải ở trong chế độ danh sách " ++ ++#: src/cmd.c:885 ++msgid " The command history is empty " ++msgstr " Lịch sử dòng lệnh rỗng " ++ ++#: src/cmd.c:889 ++msgid " Command history " ++msgstr " Lịch sử dòng lệnh " ++ ++#: src/cmd.c:925 ++msgid "" ++" Not an xterm or Linux console; \n" ++" the panels cannot be toggled. " ++msgstr "" ++" Đây không phải là xterm hay kênh giao tác Linux; \n" ++" bảng sẽ không thể bị tắt. " ++ ++#: src/cmd.c:939 ++#, c-format ++msgid "Link %s to:" ++msgstr "Tạo liên kết tới %s:" ++ ++#: src/cmd.c:940 ++msgid " Link " ++msgstr " Liên kết " ++ ++#: src/cmd.c:950 ++#, c-format ++msgid " link: %s " ++msgstr " liên kết: %s " ++ ++#: src/cmd.c:978 ++#, c-format ++msgid " symlink: %s " ++msgstr " liên kết mềm: %s " ++ ++#: src/cmd.c:1012 ++#, c-format ++msgid " Symlink `%s' points to: " ++msgstr " Liên kết mềm %s chỉ tới: " ++ ++#: src/cmd.c:1017 ++msgid " Edit symlink " ++msgstr " Sửa liên kết mềm " ++ ++#: src/cmd.c:1022 ++#, c-format ++msgid " edit symlink, unable to remove %s: %s " ++msgstr " sửa liên kết mềm, không thể xóa %s: %s " ++ ++#: src/cmd.c:1026 ++#, c-format ++msgid " edit symlink: %s " ++msgstr " sửa liên kết mềm: %s " ++ ++#: src/cmd.c:1037 ++#, c-format ++msgid "`%s' is not a symbolic link" ++msgstr "`%s' không phải là một liên kết mềm" ++ ++#: src/cmd.c:1155 ++#, c-format ++msgid " Cannot chdir to %s " ++msgstr " Không thể chdir vào %s " ++ ++#: src/cmd.c:1164 ++msgid " Enter machine name (F1 for details): " ++msgstr " Hãy nhập tên máy (nhấn F1 để biết chi tiết): " ++ ++#: src/cmd.c:1169 src/widget.c:1051 ++msgid " Link to a remote machine " ++msgstr " Kiết nối tới máy ở xa " ++ ++#: src/cmd.c:1176 src/widget.c:1052 ++msgid " FTP to machine " ++msgstr " FTP tới máy ở xa " ++ ++#: src/cmd.c:1182 ++msgid " Shell link to machine " ++msgstr " Kết nối shell tới máy ở xa" ++ ++#: src/cmd.c:1189 src/widget.c:1053 ++msgid " SMB link to machine " ++msgstr " Kết nối SMB tới máy ở xa" ++ ++#: src/cmd.c:1198 ++msgid " Undelete files on an ext2 file system " ++msgstr " Phục hồi tập tin trên hệ thống tập tin ext2 sau khi xóa " ++ ++#: src/cmd.c:1199 ++msgid "" ++" Enter device (without /dev/) to undelete\n" ++" files on: (F1 for details)" ++msgstr "" ++" Nhập tên thiết bị (không có /dev/), để\n" ++" phục hồi tập tin của nó: (nhấn F1 để biết chi tiết)" ++ ++#: src/cmd.c:1249 ++msgid " Setup saved to ~/" ++msgstr " Tham số ghi nhớ trong ~/" ++ ++#: src/cmd.c:1251 ++msgid " Setup " ++msgstr " Cấu hình " ++ ++#: src/command.c:177 src/screen.c:2174 src/tree.c:823 ++#, c-format ++msgid "" ++" Cannot chdir to \"%s\" \n" ++" %s " ++msgstr "" ++" Không chdir được tới \"%s\" \n" ++" %s " ++ ++#: src/command.c:210 src/user.c:694 ++msgid " Cannot execute commands on non-local filesystems" ++msgstr " Chỉ có thể thực hiện câu lệnh trên hệ thống tập tin nội bộ" ++ ++#: src/command.c:219 src/execute.c:183 ++msgid " The shell is already running a command " ++msgstr " shell đang chạy một câu lệnh" ++ ++#: src/dir.c:49 ++msgid "&Unsorted" ++msgstr "không &Sắp xếp" ++ ++#: src/dir.c:50 ++msgid "&Name" ++msgstr "th&Eo tên" ++ ++#: src/dir.c:51 ++msgid "&Extension" ++msgstr "&Phần mở rộng" ++ ++#: src/dir.c:52 ++msgid "&Modify time" ++msgstr "&Thời gian sửa đổi" ++ ++#: src/dir.c:53 ++msgid "&Access time" ++msgstr "thời &Gian truy cập" ++ ++#: src/dir.c:54 ++msgid "&Change time" ++msgstr "thời gi&An thay đổi" ++ ++#: src/dir.c:55 ++msgid "&Size" ++msgstr "&Kích thước" ++ ++#: src/dir.c:56 ++msgid "&Inode" ++msgstr "&Chỉ mục inode" ++ ++#: src/dir.c:59 ++msgid "&Type" ++msgstr "&Loại" ++ ++#: src/dir.c:60 ++msgid "&Links" ++msgstr "&Liên kết" ++ ++#: src/dir.c:61 ++msgid "N&GID" ++msgstr "N&GID" ++ ++#: src/dir.c:62 ++msgid "N&UID" ++msgstr "N&UID" ++ ++#: src/dir.c:63 ++msgid "&Owner" ++msgstr "&Chủ sở hữu" ++ ++#: src/dir.c:64 ++msgid "&Group" ++msgstr "&Nhóm" ++ ++#: src/dir.c:475 src/dir.c:577 ++msgid "Cannot read directory contents" ++msgstr "Không đọc được nội dung thư mục" ++ ++#: src/execute.c:133 src/utilunix.c:380 ++msgid "Press any key to continue..." ++msgstr "Để tiếp tục nhấn phím bất kỳ..." ++ ++#: src/execute.c:235 ++msgid "Type `exit' to return to the Midnight Commander" ++msgstr "Hãy gõ \"exit\" để quay trở lại Midnight Commander" ++ ++#: src/execute.c:343 ++#, c-format ++msgid " Cannot fetch a local copy of %s " ++msgstr " Không thể lấy được bản sao nội bộ của %s " ++ ++#: src/ext.c:106 src/user.c:566 ++#, c-format ++msgid "" ++" Cannot create temporary command file \n" ++" %s " ++msgstr "" ++" Không tạo được tập tin câu lệnh tạm thời\n" ++" %s " ++ ++#: src/ext.c:119 src/user.c:589 ++msgid " Parameter " ++msgstr " Tham số " ++ ++#: src/ext.c:462 src/ext.c:481 ++msgid " file error " ++msgstr " lỗi tập tin " ++ ++#: src/ext.c:464 src/ext.c:483 ++msgid "Format of the " ++msgstr "Định dạng của " ++ ++#: src/ext.c:465 ++msgid "" ++"mc.ext file has changed\n" ++"with version 3.0. It seems that installation\n" ++"failed. Please fetch a fresh new copy from the\n" ++"Midnight Commander package." ++msgstr "" ++"Tập tin mc.ext đã thay đổi\n" ++"từ phiên bản 3.0. Rất có thể có sự cố khi cài đặt.\n" ++"Xin hãy lấy bản sao mới nhất từ gói \n" ++"Midnight Commander." ++ ++#: src/ext.c:484 ++msgid "" ++" file has changed\n" ++"with version 3.0. You may want either to\n" ++"copy it from " ++msgstr "" ++" tập tin đã thay đổi\n" ++"trong phiên bản 3.0. Có thể nên sao\n" ++"chép nó từ " ++ ++#: src/ext.c:487 ++msgid "" ++"mc.ext or use that\n" ++"file as an example of how to write it.\n" ++msgstr "" ++"mc.ext, hoặc sử dụng tập tin này làm\n" ++"ví dụ để biết cách viết.\n" ++ ++#: src/ext.c:490 ++msgid "mc.ext will be used for this moment." ++msgstr "mc.ext sẽ được sử dụng trong thời điểm này." ++ ++#: src/file.c:122 src/tree.c:593 ++msgid " Copy " ++msgstr " Sao chép " ++ ++#: src/file.c:123 src/tree.c:634 ++msgid " Move " ++msgstr " Di chuyển " ++ ++#: src/file.c:124 src/tree.c:708 ++msgid " Delete " ++msgstr " Xóa " ++ ++#: src/file.c:217 ++msgid " Invalid target mask " ++msgstr " Dấu hiệu đích đến không đúng " ++ ++#: src/file.c:316 ++msgid " Cannot make the hardlink " ++msgstr " Không thể tạo liên kết cứng " ++ ++#: src/file.c:359 ++#, c-format ++msgid "" ++" Cannot read source link \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể đọc liên kết nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:370 ++msgid "" ++" Cannot make stable symlinks across non-local filesystems: \n" ++"\n" ++" Option Stable Symlinks will be disabled " ++msgstr "" ++" Không tạo được liên kết mềm bền vững giữa các hệ thống tập tin không phải nội bộ:\n" ++"\n" ++" Tùy chọn \"Liên kết mềm Bền vững\" sẽ bị tắt " ++ ++#: src/file.c:419 ++#, c-format ++msgid "" ++" Cannot create target symlink \"%s\" \n" ++" %s " ++msgstr "" ++" Khônt tạo được liên kết mềm đích \"%s\" \n" ++" %s " ++ ++#: src/file.c:493 ++#, c-format ++msgid "" ++" Cannot overwrite directory \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể ghi chèn lên thư mục \"%s\" \n" ++" %s " ++ ++#: src/file.c:504 ++#, c-format ++msgid "" ++" Cannot stat source file \"%s\" \n" ++" %s " ++msgstr "" ++" Không lấy được tính chất (stat) của tập tin nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:514 src/file.c:1115 ++#, c-format ++msgid " `%s' and `%s' are the same file " ++msgstr " `%s' và `%s' là một tập tin " ++ ++#: src/file.c:552 ++#, c-format ++msgid "" ++" Cannot create special file \"%s\" \n" ++" %s " ++msgstr "" ++" Không tạo được tập tin đặc biệt \"%s\" \n" ++" %s " ++ ++#: src/file.c:564 src/file.c:813 ++#, c-format ++msgid "" ++" Cannot chown target file \"%s\" \n" ++" %s " ++msgstr "" ++" Không thay đổi được chủ sở hữu của tập tin đích đến \"%s\" \n" ++" %s " ++ ++#: src/file.c:575 src/file.c:830 ++#, c-format ++msgid "" ++" Cannot chmod target file \"%s\" \n" ++" %s " ++msgstr "" ++" Không thay đổi được quyền hạn (chmod) của tập tin đích đến \"%s\" \n" ++" %s " ++ ++#: src/file.c:589 ++#, c-format ++msgid "" ++" Cannot open source file \"%s\" \n" ++" %s " ++msgstr "" ++" Không mở được tập tin nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:600 ++msgid " Reget failed, about to overwrite file " ++msgstr " Lấy phần còn lại của tập tin không thành công, tập tin sẽ bị ghi đè " ++ ++#: src/file.c:607 ++#, c-format ++msgid "" ++" Cannot fstat source file \"%s\" \n" ++" %s " ++msgstr "" ++" Không lấy được tính chất (fstat) tập tin nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:631 ++#, c-format ++msgid "" ++" Cannot create target file \"%s\" \n" ++" %s " ++msgstr "" ++" Không tạo được tập tin đích \"%s\" \n" ++" %s " ++ ++#: src/file.c:646 ++#, c-format ++msgid "" ++" Cannot fstat target file \"%s\" \n" ++" %s " ++msgstr "" ++" Không lấy được tính chất (fstat) tập tin đích \"%s\" \n" ++" %s " ++ ++#: src/file.c:680 ++#, c-format ++msgid "" ++" Cannot read source file \"%s\" \n" ++" %s " ++msgstr "" ++" Không đọc được tập tin nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:715 ++#, c-format ++msgid "" ++" Cannot write target file \"%s\" \n" ++" %s " ++msgstr "" ++" Không ghi nhớ được tập tin nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:733 ++msgid "(stalled)" ++msgstr "(bị nhốt)" ++ ++#: src/file.c:780 ++#, c-format ++msgid "" ++" Cannot close source file \"%s\" \n" ++" %s " ++msgstr "" ++" Không đóng được tập tin nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:791 ++#, c-format ++msgid "" ++" Cannot close target file \"%s\" \n" ++" %s " ++msgstr "" ++" Không đóng được tập tin đính \"%s\" \n" ++" %s " ++ ++#: src/file.c:804 ++msgid "Incomplete file was retrieved. Keep it?" ++msgstr "Nhận được tập tin không đầy đủ. Giữ tập tin?" ++ ++#: src/file.c:805 ++msgid "&Delete" ++msgstr "&Xóa" ++ ++#: src/file.c:805 ++msgid "&Keep" ++msgstr "&Giữ" ++ ++#: src/file.c:873 ++#, c-format ++msgid "" ++" Cannot stat source directory \"%s\" \n" ++" %s " ++msgstr "" ++" Không lấy được thông tin (stat) thư mục nguồn \"%s\" \n" ++" %s " ++ ++#: src/file.c:900 ++#, c-format ++msgid "" ++" Source directory \"%s\" is not a directory \n" ++" %s " ++msgstr "" ++" Thư mục nguồn \"%s\" không phải là một thư mục \n" ++" %s " ++ ++#: src/file.c:910 ++#, c-format ++msgid "" ++" Cannot copy cyclic symbolic link \n" ++" `%s' " ++msgstr "" ++" Không sao chép được liên kết mềm vòng lặp \n" ++" `%s' " ++ ++#: src/file.c:945 src/file.c:1985 src/tree.c:648 ++#, c-format ++msgid "" ++" Destination \"%s\" must be a directory \n" ++" %s " ++msgstr "" ++" Nơi đến \"%s\" phải là một thư mục \n" ++" %s " ++ ++#: src/file.c:975 ++#, c-format ++msgid "" ++" Cannot create target directory \"%s\" \n" ++" %s " ++msgstr "" ++" Không tạo được thư mục đích đến \"%s\" \n" ++" %s " ++ ++#: src/file.c:994 ++#, c-format ++msgid "" ++" Cannot chown target directory \"%s\" \n" ++" %s " ++msgstr "" ++" Không thay đổi được chủ sở hữu (chown) của thư mục đích đến \"%s\" \n" ++" %s " ++ ++#: src/file.c:1096 ++#, c-format ++msgid "" ++" Cannot stat file \"%s\" \n" ++" %s " ++msgstr "" ++" Không nhận được tính chất (stat) của tập tin \"%s\" \n" ++" %s " ++ ++#: src/file.c:1122 ++#, c-format ++msgid " Cannot overwrite directory `%s' " ++msgstr " Không thể ghi đè lên thư mục `%s' " ++ ++#: src/file.c:1157 ++#, c-format ++msgid "" ++" Cannot move file \"%s\" to \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể di chuyển tập tin \"%s\" vào \"%s\" \n" ++" %s " ++ ++#: src/file.c:1181 ++#, c-format ++msgid "" ++" Cannot remove file \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể xóa tập tin \"%s\" \n" ++" %s " ++ ++#: src/file.c:1233 ++#, c-format ++msgid " `%s' and `%s' are the same directory " ++msgstr " %s và %s - là một thư mục " ++ ++#: src/file.c:1252 ++#, c-format ++msgid " Cannot overwrite directory \"%s\" %s " ++msgstr " Không thể ghi đè lên thư mục \"%s\" %s " ++ ++#: src/file.c:1256 ++#, c-format ++msgid " Cannot overwrite file \"%s\" %s " ++msgstr " Không thể ghi đè tập tin \"%s\" %s " ++ ++#: src/file.c:1282 ++#, c-format ++msgid "" ++" Cannot move directory \"%s\" to \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể di chuyển thư mục \"%s\" vào \"%s\" \n" ++" %s " ++ ++#: src/file.c:1352 ++#, c-format ++msgid "" ++" Cannot delete file \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể xóa tập tin \"%s\" \n" ++" %s " ++ ++#: src/file.c:1412 src/file.c:1481 src/file.c:1509 ++#, c-format ++msgid "" ++" Cannot remove directory \"%s\" \n" ++" %s " ++msgstr "" ++" Không thể xóa thư mục \"%s\" \n" ++" %s " ++ ++#: src/file.c:1657 ++msgid "1Copy" ++msgstr "1Sao chép" ++ ++#: src/file.c:1657 ++msgid "1Move" ++msgstr "1Di chuyển" ++ ++#: src/file.c:1657 ++msgid "1Delete" ++msgstr "1Xóa" ++ ++#: src/file.c:1672 ++#, no-c-format ++msgid "%o %f \"%s\"%m" ++msgstr "%o %f \"%s\"%m" ++ ++# msgfmt warnings/errors must be ignored. mc parse this pattern itself. ++#: src/file.c:1674 ++#, no-c-format ++msgid "%o %d %f%m" ++msgstr "%o (%d cái) %f%m" ++ ++#: src/file.c:1676 vfs/fish.c:561 ++msgid "file" ++msgstr "tập tin" ++ ++#: src/file.c:1676 ++msgid "files" ++msgstr "các tập tin" ++ ++#: src/file.c:1676 ++msgid "directory" ++msgstr "thư mục" ++ ++#: src/file.c:1676 ++msgid "directories" ++msgstr "Các thư mục" ++ ++#: src/file.c:1677 ++msgid "files/directories" ++msgstr "tập tin/thư mục" ++ ++#: src/file.c:1677 ++msgid " with source mask:" ++msgstr " với nhãn ban đầu:" ++ ++#: src/file.c:1677 ++msgid " to:" ++msgstr " vào:" ++ ++#: src/file.c:1821 ++msgid " Cannot operate on \"..\"! " ++msgstr " Không thể thao tác trên \"..\"! " ++ ++#: src/file.c:1877 ++msgid " Sorry, I could not put the job in background " ++msgstr " Xin lỗi, không thể đặt công việc nào vào chế độ nền sau " ++ ++#: src/file.c:2147 src/view.c:441 ++msgid "&Retry" ++msgstr "&Thử lại" ++ ++#: src/file.c:2148 src/file.c:2211 src/filegui.c:207 src/filegui.c:517 ++msgid "&Abort" ++msgstr "&Dừng" ++ ++#: src/file.c:2200 ++msgid "" ++"\n" ++" Directory not empty. \n" ++" Delete it recursively? " ++msgstr "" ++"\n" ++" Thư mục không rỗng. \n" ++" Xóa toàn bộ (đệ quy)? " ++ ++#: src/file.c:2202 ++msgid "" ++"\n" ++" Background process: Directory not empty \n" ++" Delete it recursively? " ++msgstr "" ++"\n" ++" Tiến trình nền sau: Thư mục không rỗng \n" ++" Xóa toàn bộ (đệ quy)? " ++ ++#: src/file.c:2204 ++msgid " Delete: " ++msgstr " Xóa: " ++ ++#: src/file.c:2210 src/filegui.c:519 ++msgid "Non&e" ++msgstr "&Không" ++ ++#: src/filegui.c:324 ++#, c-format ++msgid "ETA %d:%02d.%02d" ++msgstr "Còn lại %d:%02d.%02d" ++ ++#: src/filegui.c:347 ++#, c-format ++msgid "%.2f MB/s" ++msgstr "%.2f МB/giây" ++ ++#: src/filegui.c:350 ++#, c-format ++msgid "%.2f KB/s" ++msgstr "%.2f KB/giây" ++ ++#: src/filegui.c:353 ++#, c-format ++msgid "%ld B/s" ++msgstr "%ld B/giây" ++ ++#: src/filegui.c:376 ++msgid "File" ++msgstr "Tập tin" ++ ++#: src/filegui.c:399 ++msgid "Count" ++msgstr "Đếm" ++ ++#: src/filegui.c:420 ++msgid "Bytes" ++msgstr "Byte" ++ ++#: src/filegui.c:453 ++msgid "Source" ++msgstr "Nguồn" ++ ++#: src/filegui.c:476 ++msgid "Target" ++msgstr "Đích" ++ ++#: src/filegui.c:498 ++msgid "Deleting" ++msgstr "Đang xóa" ++ ++#: src/filegui.c:516 ++#, c-format ++msgid "Target file \"%s\" already exists!" ++msgstr "Tập tin đích \"%s\" đã tồn tại!" ++ ++#: src/filegui.c:518 ++msgid "If &size differs" ++msgstr "&Nếu kích thước khác nhau" ++ ++#: src/filegui.c:520 ++msgid "&Update" ++msgstr "&Cập nhật" ++ ++#: src/filegui.c:522 ++msgid "Overwrite all targets?" ++msgstr "Khi đè lên mọi tập tin đích?" ++ ++#: src/filegui.c:523 ++msgid "&Reget" ++msgstr "&Lấy lại" ++ ++#: src/filegui.c:524 ++msgid "A&ppend" ++msgstr "&Thêm vào cuối" ++ ++#: src/filegui.c:527 ++msgid "Overwrite this target?" ++msgstr "Khi đè lên tập tin này?" ++ ++#: src/filegui.c:528 ++#, c-format ++msgid "Target date: %s, size %d" ++msgstr "Thời gian sửa đổi của tập tin đích: %s, kích thước %d" ++ ++#: src/filegui.c:529 ++#, c-format ++msgid "Source date: %s, size %d" ++msgstr "Thời gian sửa đổi của tập tin nguồn: %s, kích thước %d" ++ ++#: src/filegui.c:604 ++msgid " File exists " ++msgstr " Tập tin tồn tại " ++ ++#: src/filegui.c:606 ++msgid " Background process: File exists " ++msgstr " Tiến trình nền sau: tập tin tồn tại " ++ ++#: src/filegui.c:728 ++msgid "preserve &Attributes" ++msgstr "&Ghi nhớ thuộc tính" ++ ++#: src/filegui.c:730 ++msgid "follow &Links" ++msgstr "đi theo &Liên kết" ++ ++#: src/filegui.c:732 ++msgid "to:" ++msgstr "vào:" ++ ++#: src/filegui.c:733 ++msgid "&Using shell patterns" ++msgstr "&Sử dụng mẫu (pattern) của shell" ++ ++#: src/filegui.c:754 ++msgid "&Background" ++msgstr "&Trong nền sau" ++ ++#: src/filegui.c:764 ++msgid "&Stable Symlinks" ++msgstr "liên kết &Bền vững" ++ ++#: src/filegui.c:766 ++msgid "&Dive into subdir if exists" ++msgstr "&Vào thư mục con, nếu có" ++ ++#: src/filegui.c:938 ++#, c-format ++msgid "" ++"Invalid source pattern `%s' \n" ++" %s " ++msgstr "" ++"Mẫu không đúng `%s' \n" ++" %s " ++ ++#: src/find.c:99 ++msgid "&Suspend" ++msgstr "&Hoãn" ++ ++#: src/find.c:100 ++msgid "Con&tinue" ++msgstr "&Tiếp tục" ++ ++#: src/find.c:101 ++msgid "&Chdir" ++msgstr "&Chuyển thư mục" ++ ++#: src/find.c:102 ++msgid "&Again" ++msgstr "&Lặp lại" ++ ++#: src/find.c:103 src/subshell.c:323 ++msgid "&Quit" ++msgstr "&Thoát" ++ ++#: src/find.c:104 src/panelize.c:69 ++msgid "Pane&lize" ++msgstr "&Bảng" ++ ++#: src/find.c:105 ++msgid "&View - F3" ++msgstr "X&em - F3" ++ ++#: src/find.c:106 ++msgid "&Edit - F4" ++msgstr "&Soạn thảo - F4" ++ ++#: src/find.c:183 ++msgid "Start at:" ++msgstr "Bắt đầu từ:" ++ ++#: src/find.c:183 ++msgid "Filename:" ++msgstr "Tên tập tin:" ++ ++#: src/find.c:183 ++msgid "Content: " ++msgstr "Nội dung: " ++ ++#: src/find.c:184 src/main.c:795 src/main.c:819 ++msgid "&Tree" ++msgstr "&Cây thư mục" ++ ++#: src/find.c:232 src/find.c:792 ++msgid "Find File" ++msgstr "Tìm tập tin" ++ ++#: src/find.c:464 ++#, c-format ++msgid "Grepping in %s" ++msgstr "Tìm trong %s" ++ ++#: src/find.c:538 ++msgid "Finished" ++msgstr "Kết thúc" ++ ++#: src/find.c:565 src/view.c:1594 ++#, c-format ++msgid "Searching %s" ++msgstr "Tìm %s" ++ ++#: src/find.c:721 src/find.c:818 ++msgid "Searching" ++msgstr "Tìm" ++ ++#: src/help.c:279 ++msgid " Help file format error\n" ++msgstr " Lỗi định dạng tập tin trợ giúp\n" ++ ++#: src/help.c:318 ++msgid " Internal bug: Double start of link area " ++msgstr " Lỗi (bug) nội bộ: vùng liên kết có hai đầu " ++ ++#: src/help.c:554 src/help.c:778 ++#, c-format ++msgid " Cannot find node %s in help file " ++msgstr " Không tìm thấy nút %s trong tập tin trợ giúp " ++ ++#: src/help.c:816 ++msgid "Index" ++msgstr "Chỉ mục" ++ ++#: src/help.c:818 ++msgid "Prev" ++msgstr "Quay lại" ++ ++#: src/hotlist.c:115 ++msgid "&Move" ++msgstr "&Di chuyển" ++ ++#: src/hotlist.c:116 src/panelize.c:68 ++msgid "&Remove" ++msgstr "&Xóa" ++ ++#: src/hotlist.c:117 src/hotlist.c:834 src/hotlist.c:930 ++msgid "&Append" ++msgstr "&Thêm vào" ++ ++#: src/hotlist.c:118 src/hotlist.c:832 src/hotlist.c:928 ++msgid "&Insert" ++msgstr "c&Hèn" ++ ++#: src/hotlist.c:119 ++msgid "New &Entry" ++msgstr "tạo &Mục mới" ++ ++#: src/hotlist.c:120 ++msgid "New &Group" ++msgstr "&Nhóm mới" ++ ++#: src/hotlist.c:122 ++msgid "&Up" ++msgstr "&Lên" ++ ++#: src/hotlist.c:123 ++msgid "&Add current" ++msgstr "&Thêm hiện thời" ++ ++#: src/hotlist.c:125 ++msgid "&Refresh" ++msgstr "&Làm mới" ++ ++#: src/hotlist.c:126 ++msgid "Fr&ee VFSs now" ++msgstr "&Giải phóng" ++ ++#: src/hotlist.c:128 ++msgid "Change &To" ++msgstr "&Chuyển tới" ++ ++#: src/hotlist.c:177 ++msgid "Subgroup - press ENTER to see list" ++msgstr "Nhóm con - nhấn ENTER để xem danh sách" ++ ++#: src/hotlist.c:609 ++msgid "Active VFS directories" ++msgstr "Thư mục VFS hoạt động" ++ ++#: src/hotlist.c:612 ++msgid "Directory hotlist" ++msgstr "Danh sách thư mục thường dùng" ++ ++#: src/hotlist.c:640 ++msgid " Directory path " ++msgstr " Đường dẫn tới thư mục " ++ ++#: src/hotlist.c:643 src/hotlist.c:692 ++msgid " Directory label " ++msgstr " Nhãn thư mục" ++ ++#: src/hotlist.c:668 ++#, c-format ++msgid "Moving %s" ++msgstr "Di chuyển %s" ++ ++#: src/hotlist.c:907 ++msgid "New hotlist entry" ++msgstr " Thêm bản ghi vào tra cứu" ++ ++#: src/hotlist.c:907 ++msgid "Directory label" ++msgstr " Tên nhãn thư mục" ++ ++#: src/hotlist.c:907 ++msgid "Directory path" ++msgstr " Đường dẫn tới thư mục" ++ ++#: src/hotlist.c:987 ++msgid " New hotlist group " ++msgstr " Thêm nhóm vào tra cứu " ++ ++#: src/hotlist.c:987 ++msgid "Name of new group" ++msgstr " Tên nhóm mới" ++ ++#: src/hotlist.c:1002 ++#, c-format ++msgid "Label for \"%s\":" ++msgstr " Tên nhãn cho \"%s\":" ++ ++#: src/hotlist.c:1006 ++msgid " Add to hotlist " ++msgstr " Thêm vào tra cứu " ++ ++#: src/hotlist.c:1043 ++msgid " Remove: " ++msgstr " Xóa: " ++ ++#: src/hotlist.c:1047 ++msgid "" ++"\n" ++" Group not empty.\n" ++" Remove it?" ++msgstr "" ++"\n" ++" Nhóm không rỗng.\n" ++" Xóa nó?" ++ ++#: src/hotlist.c:1391 ++msgid " Top level group " ++msgstr "Nhóm cấp độ cao nhất " ++ ++#: src/hotlist.c:1414 ++msgid "MC was unable to write ~/" ++msgstr "MC không thể ghi nhớ ~/" ++ ++#: src/hotlist.c:1415 ++msgid " file, your old hotlist entries were not deleted" ++msgstr " tập tin, tra cứu thư mục cũ chưa bị xóa" ++ ++#: src/hotlist.c:1417 ++msgid " Hotlist Load " ++msgstr " Nạp tra cứu " ++ ++#: src/info.c:74 ++#, c-format ++msgid "Midnight Commander %s" ++msgstr "Midnight Commander %s" ++ ++#: src/info.c:91 ++#, c-format ++msgid "File: %s" ++msgstr "Tập tin: %s" ++ ++#: src/info.c:103 ++#, c-format ++msgid "Free nodes: %d (%d%%) of %d" ++msgstr "Nút tự do: %d (%d%%) trong tổng số %d" ++ ++#: src/info.c:109 ++msgid "No node information" ++msgstr "Không có thông tin về nút (node)" ++ ++#: src/info.c:117 ++#, c-format ++msgid "Free space: %s (%d%%) of %s" ++msgstr "Chỗ trống: %s (%d%%) của %s" ++ ++#: src/info.c:121 ++msgid "No space information" ++msgstr "Không có thông tin về khoảng trống" ++ ++#: src/info.c:125 ++#, c-format ++msgid "Type: %s " ++msgstr "Loại: %s " ++ ++#: src/info.c:125 ++msgid "non-local vfs" ++msgstr "không phải vfs cục bộ" ++ ++#: src/info.c:131 ++#, c-format ++msgid "Device: %s" ++msgstr "Thiết bị: %s" ++ ++#: src/info.c:135 ++#, c-format ++msgid "Filesystem: %s" ++msgstr "Hệ thống tập tin: %s" ++ ++#: src/info.c:140 ++#, c-format ++msgid "Accessed: %s" ++msgstr "Truy cập: %s" ++ ++#: src/info.c:144 ++#, c-format ++msgid "Modified: %s" ++msgstr "Sửa đổi: %s" ++ ++#: src/info.c:148 ++#, c-format ++msgid "Created: %s" ++msgstr "Tạo ra: %s" ++ ++#: src/info.c:163 ++#, c-format ++msgid "Size: %s" ++msgstr "Kích thước: %s" ++ ++#: src/info.c:166 ++#, c-format ++msgid " (%d block)" ++msgstr " (%d khối)" ++ ++#: src/info.c:166 ++#, c-format ++msgid " (%d blocks)" ++msgstr " (%d khối)" ++ ++#: src/info.c:172 ++#, c-format ++msgid "Owner: %s/%s" ++msgstr "Chủ sở hữu: %s/%s" ++ ++#: src/info.c:177 ++#, c-format ++msgid "Links: %d" ++msgstr "Liên kết: %d" ++ ++#: src/info.c:181 ++#, c-format ++msgid "Mode: %s (%04o)" ++msgstr "Quyền hạn: %s (%04o)" ++ ++#: src/info.c:186 ++#, c-format ++msgid "Location: %Xh:%Xh" ++msgstr "Vị trí: %Xh:%Xh" ++ ++#: src/info.c:196 ++msgid "File: None" ++msgstr "Tập tin: Không có" ++ ++#: src/layout.c:151 ++msgid "&Vertical" ++msgstr "&Thẳng đứng" ++ ++#: src/layout.c:152 ++msgid "&Horizontal" ++msgstr "&Nằm ngang" ++ ++#: src/layout.c:162 ++msgid "&Xterm window title" ++msgstr "tiê&U đề cửa sổ xterm" ++ ++#: src/layout.c:163 ++msgid "h&Intbar visible" ++msgstr "dòng &Gợi ý" ++ ++#: src/layout.c:164 ++msgid "&Keybar visible" ++msgstr "&Hiển thị thanh phím tắt" ++ ++#: src/layout.c:165 ++msgid "command &Prompt" ++msgstr "&Dòng lệnh" ++ ++#: src/layout.c:166 ++msgid "show &Mini status" ++msgstr "hiện trạng thái m&Ini" ++ ++#: src/layout.c:167 ++msgid "menu&Bar visible" ++msgstr "thAnh trình đơn" ++ ++#: src/layout.c:168 ++msgid "&Equal split" ++msgstr "&Kích thước bằng nhau" ++ ++#: src/layout.c:169 ++msgid "pe&Rmissions" ++msgstr "&Quyền truy cập" ++ ++#: src/layout.c:170 ++msgid "&File types" ++msgstr "&Loại tập tin" ++ ++#: src/layout.c:350 src/learn.c:59 src/learn.c:174 src/option.c:115 ++msgid "&Save" ++msgstr "Ghi nhớ &+" ++ ++#: src/layout.c:358 ++msgid " Panel split " ++msgstr " Chia bảng " ++ ++#: src/layout.c:359 ++msgid " Highlight... " ++msgstr " Chiếu sáng... " ++ ++#: src/layout.c:360 src/option.c:125 ++msgid " Other options " ++msgstr " Cấu hình khác " ++ ++#: src/layout.c:361 ++msgid "output lines" ++msgstr "dòng kết quả" ++ ++#: src/layout.c:423 ++msgid "Layout" ++msgstr "Vẻ ngoài" ++ ++#: src/learn.c:73 ++msgid "Learn keys" ++msgstr "Tạo phím tắt" ++ ++#: src/learn.c:79 ++msgid " Teach me a key " ++msgstr " Dạy tôi một phím " ++ ++#: src/learn.c:80 ++#, c-format ++msgid "" ++"Please press the %s\n" ++"and then wait until this message disappears.\n" ++"\n" ++"Then, press it again to see if OK appears\n" ++"next to its button.\n" ++"\n" ++"If you want to escape, press a single Escape key\n" ++"and wait as well." ++msgstr "" ++"Xin hãy nhấn lên %s\n" ++"và đợi cho thông báo này biến mất.\n" ++"\n" ++"Sau đó hãy nhấn một lần nữa để chắc chắn là ở bên phải\n" ++"của tên xuất hiện \"OK\".\n" ++"\n" ++"Nếu bạn muốn dừng việc dạy phím, thì hãy nhấn\n" ++"phím Esc và cũng cần đợi một chút." ++ ++#: src/learn.c:114 ++msgid " Cannot accept this key " ++msgstr " Không thể chấp nhận phím này " ++ ++#: src/learn.c:115 ++#, c-format ++msgid " You have entered \"%s\"" ++msgstr " Đã nhập vào \"%s\"" ++ ++#. TRANSLATORS: This label appears near learned keys. Keep it short. ++#: src/learn.c:164 ++msgid "OK" ++msgstr "OK" ++ ++#: src/learn.c:172 ++msgid "" ++"It seems that all your keys already\n" ++"work fine. That's great." ++msgstr "" ++"Có vẻ như tất cả các phím của bạn\n" ++"làm việc tốt. Thật là tuyệt." ++ ++#: src/learn.c:174 ++msgid "&Discard" ++msgstr "&Vứt bỏ" ++ ++#: src/learn.c:179 ++msgid "" ++"Great! You have a complete terminal database!\n" ++"All your keys work well." ++msgstr "" ++"Tuyệt! Chúng ta có một cơ sở dữ liệu mô tả terminal đầy đủ!\n" ++"Tất cả các phím đều làm việc tốt." ++ ++#: src/learn.c:287 ++msgid "Press all the keys mentioned here. After you have done it, check" ++msgstr "Hãy nhấn tất cả những phím liệt kê ở trên. Sau khi nhấn xong, hãy kiểm tra" ++ ++#: src/learn.c:291 ++msgid "which keys are not marked with OK. Press space on the missing" ++msgstr "xem những phím nào không có dấu hiệu \"OK\". Nhấn phím space trên những" ++ ++#: src/learn.c:295 ++msgid "key, or click with the mouse to define it. Move around with Tab." ++msgstr "phím bị thiếu, hoặc nhấn chuột để xác định. Di chuyển bằng Tab." ++ ++#: src/main.c:425 ++msgid "" ++" The Commander can't change to the directory that \n" ++" the subshell claims you are in. Perhaps you have \n" ++" deleted your working directory, or given yourself \n" ++" extra access permissions with the \"su\" command? " ++msgstr "" ++" MC không thể chuyển vào thư mục, mà tiến trình shell \n" ++" con thông báo. Rất có thể, bạn đã xóa thư mục làm việc \n" ++" hoặc thêm cho mình quyền truy cập mở rộng bằng câu \n" ++" lệnh \"su\"? " ++ ++#: src/main.c:469 src/screen.c:1951 ++msgid " The Midnight Commander " ++msgstr " Midnight Commander " ++ ++#: src/main.c:470 ++msgid " Do you really want to quit the Midnight Commander? " ++msgstr " Thực sự muốn thoát Midnight Commander? " ++ ++#: src/main.c:792 src/main.c:816 ++msgid "&Listing mode..." ++msgstr "&Dạng danh sách..." ++ ++#: src/main.c:793 src/main.c:817 ++msgid "&Quick view C-x q" ++msgstr "&Xem nhanh C-x q" ++ ++#: src/main.c:794 src/main.c:818 ++msgid "&Info C-x i" ++msgstr "&Thông tin C-x i" ++ ++#: src/main.c:797 src/main.c:821 ++msgid "&Sort order..." ++msgstr "t&Hứ tự sắp xếp..." ++ ++#: src/main.c:799 src/main.c:823 ++msgid "&Filter..." ++msgstr "&Lọc tập tin..." ++ ++#: src/main.c:803 src/main.c:827 ++msgid "&Network link..." ++msgstr "&Kết nối mạng..." ++ ++#: src/main.c:805 src/main.c:829 ++msgid "FT&P link..." ++msgstr "kết nối &FTP..." ++ ++#: src/main.c:806 src/main.c:830 ++msgid "S&hell link..." ++msgstr "kết nối &Shell..." ++ ++#: src/main.c:808 src/main.c:832 ++msgid "SM&B link..." ++msgstr "kết nối SM&B..." ++ ++#: src/main.c:812 src/main.c:836 ++msgid "&Rescan C-r" ++msgstr "&Quét lại C-r" ++ ++#: src/main.c:840 ++msgid "&User menu F2" ++msgstr "&Trình đơn người dùng F2" ++ ++#: src/main.c:841 ++msgid "&View F3" ++msgstr "&Xem F3" ++ ++#: src/main.c:842 ++msgid "Vie&w file... " ++msgstr "x&Em tập tin... " ++ ++#: src/main.c:843 ++msgid "&Filtered view M-!" ++msgstr "xe&M đã lọc M-!" ++ ++#: src/main.c:844 ++msgid "&Edit F4" ++msgstr "&Soạn thảo F4" ++ ++#: src/main.c:845 ++msgid "&Copy F5" ++msgstr "sao &Chép F5" ++ ++#: src/main.c:846 ++msgid "c&Hmod C-x c" ++msgstr "c&Hmod C-x c" ++ ++#: src/main.c:847 ++msgid "&Link C-x l" ++msgstr "&Liên kết cứng C-x l" ++ ++#: src/main.c:848 ++msgid "&SymLink C-x s" ++msgstr "liên &Kết mềm C-x s" ++ ++#: src/main.c:849 ++msgid "edit s&Ymlink C-x C-s" ++msgstr "sử&A liên kết mềm C-x C-s" ++ ++#: src/main.c:850 ++msgid "ch&Own C-x o" ++msgstr "cho&Wn C-x o" ++ ++#: src/main.c:851 ++msgid "&Advanced chown " ++msgstr "chown &Nâng cao " ++ ++#: src/main.c:852 ++msgid "&Rename/Move F6" ++msgstr "Đổi tên/&Di chuyển F6" ++ ++#: src/main.c:853 ++msgid "&Mkdir F7" ++msgstr "mkdi&R F7" ++ ++#: src/main.c:854 ++msgid "&Delete F8" ++msgstr "xó&A F8" ++ ++#: src/main.c:855 ++msgid "&Quick cd M-c" ++msgstr "cd nhanh &> M-c" ++ ++#: src/main.c:857 ++msgid "select &Group M-+" ++msgstr "Chọn Nhóm &+ M-+" ++ ++#: src/main.c:858 ++msgid "u&Nselect group M-\\" ++msgstr "&Bỏ chọn nhóm M-\\" ++ ++#: src/main.c:859 ++msgid "reverse selec&Tion M-*" ++msgstr "Chọn ngược lạ&I M-*" ++ ++#: src/main.c:861 ++msgid "e&Xit F10" ++msgstr "Th&Oát F10" ++ ++#: src/main.c:869 ++msgid "&Directory tree" ++msgstr "cây thư &Mục" ++ ++#: src/main.c:870 ++msgid "&Find file M-?" ++msgstr "&Tìm tập tin M-?" ++ ++#: src/main.c:871 ++msgid "s&Wap panels C-u" ++msgstr "đổi chỗ h&Ai bảng C-u" ++ ++#: src/main.c:872 ++msgid "switch &Panels on/off C-o" ++msgstr "&Bật/tắt bảng C-o" ++ ++#: src/main.c:873 ++msgid "&Compare directories C-x d" ++msgstr "&So sánh thư mục C-x d" ++ ++#: src/main.c:874 ++msgid "e&Xternal panelize C-x !" ++msgstr "bản&G ngoài C-x !" ++ ++#: src/main.c:875 ++msgid "show directory s&Izes" ++msgstr "&Hiển thị kích thước thư mục" ++ ++#: src/main.c:877 ++msgid "command &History" ++msgstr "&Lịch sử câu lệnh" ++ ++#: src/main.c:878 ++msgid "di&Rectory hotlist C-\\" ++msgstr "Thư mục thường dùng &* C-\\" ++ ++#: src/main.c:880 ++msgid "&Active VFS list C-x a" ++msgstr "&Danh sách VFS hoạt động C-x a" ++ ++#: src/main.c:883 ++msgid "&Background jobs C-x j" ++msgstr "&Công việc nền sau C-x j" ++ ++#: src/main.c:887 ++msgid "&Undelete files (ext2fs only)" ++msgstr "&Phục hồi tập tin đã xóa (chỉ ext2fs)" ++ ++#: src/main.c:890 ++msgid "&Listing format edit" ++msgstr "&Soạn thảo định dạng danh sách" ++ ++#: src/main.c:895 ++msgid "Edit &extension file" ++msgstr "soạn thảo tập tin phần mở &Rộng" ++ ++#: src/main.c:896 ++msgid "Edit &menu file" ++msgstr "soạ&N thảo tập tin trình đơn" ++ ++#: src/main.c:898 ++msgid "Edit edi&tor menu file" ++msgstr "sửa trình đơn của trình s&Oạn thảo" ++ ++#: src/main.c:899 ++msgid "Edit &syntax file" ++msgstr "sửa tập tin cú &Pháp" ++ ++#: src/main.c:905 ++msgid "&Configuration..." ++msgstr "&Cấu hình..." ++ ++#: src/main.c:906 ++msgid "&Layout..." ++msgstr "&Vẻ ngoài..." ++ ++#: src/main.c:907 ++msgid "c&Onfirmation..." ++msgstr "&Xác nhận..." ++ ++#: src/main.c:908 ++msgid "&Display bits..." ++msgstr "bit &Hiển thị..." ++ ++#: src/main.c:911 ++msgid "&Virtual FS..." ++msgstr "&FS ảo..." ++ ++#: src/main.c:914 ++msgid "&Save setup" ++msgstr "&Ghi nhớ cấu hình" ++ ++#: src/main.c:925 ++msgid " &Above " ++msgstr " Ở &trên " ++ ++#: src/main.c:925 ++msgid " &Left " ++msgstr " &Bảng trái " ++ ++#: src/main.c:929 ++msgid " &File " ++msgstr " &Tập tin " ++ ++#: src/main.c:932 ++msgid " &Command " ++msgstr " &Câu lệnh " ++ ++#: src/main.c:935 ++msgid " &Options " ++msgstr " &Cấu hình " ++ ++#: src/main.c:938 ++msgid " &Below " ++msgstr " Ở &dưới " ++ ++#: src/main.c:938 ++msgid " &Right " ++msgstr " Bảng &phải " ++ ++#: src/main.c:981 ++msgid " Information " ++msgstr " Thông tin " ++ ++#: src/main.c:983 ++msgid "" ++" Using the fast reload option may not reflect the exact \n" ++" directory contents. In this case you'll need to do a \n" ++" manual reload of the directory. See the man page for \n" ++" the details. " ++msgstr "" ++" Sử dụng tùy chọn nạp lại nhanh có thể không phản ánh \n" ++" đúng nội dung hiện thời của thư mục. Trong trường hợp \n" ++" này cần nạp lại thư mục một cách thủ công. Hãy xem \n" ++" trang hướng dẫn sử dụng man để biết them chi tiết. " ++ ++#: src/main.c:1206 src/screen.c:2185 ++msgid "Menu" ++msgstr "Trđơn " ++ ++#: src/main.c:1340 ++msgid "The TERM environment variable is unset!\n" ++msgstr "Biến môi trườn TERM chưa được xác định!\n" ++ ++#: src/main.c:1642 src/textconf.c:116 ++#, c-format ++msgid "GNU Midnight Commander %s\n" ++msgstr "GNU Midnight Commander %s\n" ++ ++#: src/main.c:1848 ++msgid "[flags] [this_dir] [other_panel_dir]\n" ++msgstr "[cờ] [thư_mục_này] [thư_mục_bảng_còn_lại]\n" ++ ++#: src/main.c:1852 ++msgid "+number" ++msgstr "+số" ++ ++#: src/main.c:1853 ++msgid "Set initial line number for the internal editor" ++msgstr "Đặt số dòng ban đầu cho trình soạn thảo nội bộ" ++ ++#: src/main.c:1855 ++msgid "" ++"\n" ++"Please send any bug reports (including the output of `mc -V')\n" ++"to mc-devel@gnome.org\n" ++msgstr "" ++"\n" ++"Xin hãy gửi bất kỳ báo cáo lỗi (bug) nào (gồm cả kết quả của lệnh `mc -V')\n" ++"tới mc-devel@gnome.org\n" ++ ++#: src/main.c:1870 ++msgid "" ++"--colors KEYWORD={FORE},{BACK}\n" ++"\n" ++"{FORE} and {BACK} can be omitted, and the default will be used\n" ++"\n" ++"Keywords:\n" ++" Global: errors, reverse, gauge, input\n" ++" File display: normal, selected, marked, markselect\n" ++" Dialog boxes: dnormal, dfocus, dhotnormal, dhotfocus\n" ++" Menus: menu, menuhot, menusel, menuhotsel\n" ++" Help: helpnormal, helpitalic, helplink, helpslink\n" ++" File types: directory, executable, link, stalelink, device, special, " ++"core\n" ++"\n" ++"Colors:\n" ++" black, gray, red, brightred, green, brightgreen, brown,\n" ++" yellow, blue, brightblue, magenta, brightmagenta, cyan,\n" ++" brightcyan, lightgray and white\n" ++"\n" ++msgstr "" ++"--colors TỪ_KHÓA={VĂN BẢN},{NỀN}\n" ++"\n" ++"có thể bỏ qua {VĂN BẢN} và {NỀN}, và sử dụng giá trị theo mặc định\n" ++"\n" ++"Từ khóa:\n" ++" Toàn cầu: errors, reverse, gauge, input\n" ++" Hiển thị tập tin: normal, selected, marked, markselect\n" ++" Hộp thoại: dnormal, dfocus, dhotnormal, dhotfocus\n" ++" Trình đơn: menu, menuhot, menusel, menuhotsel\n" ++" Trợ giúp: helpnormal, helpitalic, helplink, helpslink\n" ++" Dạng tập tin: directory, executable, link, stalelink, device, special, core\n" ++"\n" ++"Màu sắc:\n" ++" black, gray, red, brightred, green, brightgreen, brown,\n" ++" yellow, blue, brightblue, magenta, brightmagenta, cyan,\n" ++" brightcyan, lightgray, white\n" ++"\n" ++ ++#: src/main.c:1945 ++msgid "Displays this help message" ++msgstr "Hiển thị thông báo trợ giúp này" ++ ++#: src/main.c:1947 ++msgid "Displays the current version" ++msgstr "Hiển thị số phiên bản hiện thời" ++ ++#: src/main.c:1951 ++msgid "Forces xterm features" ++msgstr "Bắt buộc dùng tính năng của xterm" ++ ++#: src/main.c:1953 ++msgid "Disable mouse support in text version" ++msgstr "Bỏ hỗ trợ chuột trong phiên bản văn bản (text)" ++ ++#: src/main.c:1956 ++msgid "Tries to use termcap instead of terminfo" ++msgstr "Thử sử dụng termcap thay cho terminfo" ++ ++#: src/main.c:1959 ++msgid "Resets soft keys on HP terminals" ++msgstr "Đặt lại phím phần mềm trên các terminal HP" ++ ++#: src/main.c:1961 ++msgid "To run on slow terminals" ++msgstr "Để chạy trên các terminal chậm" ++ ++#: src/main.c:1963 ++msgid "Use stickchars to draw" ++msgstr "Sử dụng ký tự thẳng đứng để vẽ" ++ ++#: src/main.c:1967 ++msgid "Requests to run in black and white" ++msgstr "Yêu cầu chạy trong chế độ đen trắng" ++ ++#: src/main.c:1969 ++msgid "Request to run in color mode" ++msgstr "Yêu cầu chạy trong chế độ màu" ++ ++#: src/main.c:1971 ++msgid "Specifies a color configuration" ++msgstr "Xác định cấu hình màu sắc" ++ ++#: src/main.c:1973 ++msgid "Displays a help screen on how to change the color scheme" ++msgstr "Hiển thị cửa sổ trợ giúp cách thay đổi bộ phối hợp màu" ++ ++#: src/main.c:1978 ++msgid "Log ftp dialog to specified file" ++msgstr "Ghi hội thoại FTP vào một tập tin" ++ ++#: src/main.c:1981 ++msgid "Set debug level" ++msgstr "Đặt mức độ tìm sửa lỗi (debug)" ++ ++#: src/main.c:1987 ++msgid "Print data directory" ++msgstr "In ra tên thư mục dữ liệu" ++ ++#: src/main.c:1989 ++msgid "Print last working directory to specified file" ++msgstr "Ghi thư mục làm việc cuối cùng vào tập tin chỉ ra" ++ ++#: src/main.c:1994 ++msgid "Enables subshell support (default)" ++msgstr "Bật hỗ trợ shell con (mặc định)" ++ ++#: src/main.c:1996 ++msgid "Disables subshell support" ++msgstr "Tắt hỗ trợ shell con" ++ ++#: src/main.c:2001 ++msgid "Launches the file viewer on a file" ++msgstr "Xem tập tin" ++ ++#: src/main.c:2004 ++msgid "Edits one file" ++msgstr "Soạn thảo tập tin" ++ ++#: src/main.c:2218 ++msgid " Notice " ++msgstr " Cảnh báo " ++ ++#: src/main.c:2219 ++msgid "" ++" The Midnight Commander configuration files \n" ++" are now stored in the ~/.mc directory, the \n" ++" files have been moved now\n" ++msgstr "" ++" Các tập tin cấu hình Midnight Commander \n" ++" bây giờ đặt trong thư mục ~/.mc, các \n" ++" tập tin cũ bây giờ được chuyển tới đó\n" ++ ++#: src/option.c:56 ++msgid "safe de&Lete" ++msgstr "Xóa một cách &An toàn" ++ ++#: src/option.c:57 ++msgid "cd follows lin&Ks" ++msgstr "cd th&Eo liên kết" ++ ++#: src/option.c:58 ++msgid "L&ynx-like motion" ++msgstr "di chuyển giống trong l&Ynx" ++ ++#: src/option.c:59 ++msgid "rotatin&G dash" ++msgstr "cái chỉ &Quay" ++ ++#: src/option.c:60 ++msgid "co&Mplete: show all" ++msgstr "tự động hoàn thành: hiện tất cả" ++ ++#: src/option.c:61 ++msgid "&Use internal view" ++msgstr "trình xem nội &Bộ" ++ ++#: src/option.c:62 ++msgid "use internal ed&It" ++msgstr "sử dụng s&Oạn thảo nội bộ" ++ ++#: src/option.c:63 ++msgid "auto m&Enus" ++msgstr "t&Rình đơn tự động" ++ ++#: src/option.c:64 ++msgid "&Auto save setup" ++msgstr "tự động gh&I nhớ cấu hình" ++ ++#: src/option.c:65 ++msgid "shell &Patterns" ++msgstr "&Mẫu dạng shell" ++ ++#: src/option.c:66 ++msgid "Compute &Totals" ++msgstr "tính tổn&G kích thước" ++ ++#: src/option.c:67 ++msgid "&Verbose operation" ++msgstr "thao tác với thông báo &Dài dòng" ++ ++#: src/option.c:69 ++msgid "&Fast dir reload" ++msgstr "nạ&P nhanh thư mục" ++ ++#: src/option.c:70 ++msgid "mi&X all files" ++msgstr "trộn lẫn tất &Cả tập tin" ++ ++#: src/option.c:71 ++msgid "&Drop down menus" ++msgstr "đẩy &Xuống trình đơn" ++ ++#: src/option.c:72 ++msgid "ma&Rk moves down" ++msgstr "&Nhãn di chuyển xuống" ++ ++#: src/option.c:73 ++msgid "show &Hidden files" ++msgstr "&Hiển thị tập tin ẩn" ++ ++#: src/option.c:74 ++msgid "show &Backup files" ++msgstr "hiển thị tập tin sao &Lưu" ++ ++#: src/option.c:85 ++msgid "&Never" ++msgstr "&Không bao giờ" ++ ++#: src/option.c:86 ++msgid "on dumb &Terminals" ++msgstr "&Trên terminal ngu" ++ ++#: src/option.c:87 ++msgid "Alwa&ys" ++msgstr "&Luôn luôn" ++ ++#: src/option.c:123 ++msgid " Panel options " ++msgstr " Cấu hình bảng " ++ ++#: src/option.c:124 ++msgid " Pause after run... " ++msgstr " Tạm ngừng sau khi chạy... " ++ ++#: src/option.c:170 ++msgid "Configure options" ++msgstr "Tùy chọn cấu hình" ++ ++#: src/panelize.c:67 ++msgid "&Add new" ++msgstr "&Thêm mới" ++ ++#: src/panelize.c:154 src/panelize.c:420 ++msgid "External panelize" ++msgstr "Bảng ngoài" ++ ++#: src/panelize.c:169 ++msgid "Command" ++msgstr "Câu lệnh" ++ ++#: src/panelize.c:185 src/panelize.c:242 src/panelize.c:313 src/panelize.c:334 ++msgid "Other command" ++msgstr "Lệnh khác" ++ ++#: src/panelize.c:226 ++msgid " Add to external panelize " ++msgstr " Thêm vào bảng ngoài " ++ ++#: src/panelize.c:227 ++msgid " Enter command label: " ++msgstr " Nhập tên câu lệnh: " ++ ++#: src/panelize.c:267 ++msgid " Cannot run external panelize in a non-local directory " ++msgstr " Không thể chạy câu lệnh này trên một thư mục không phải nội bộ " ++ ++#: src/panelize.c:316 ++msgid "Find rejects after patching" ++msgstr "Tìm những loại bỏ sau khi vá lỗi (patch)" ++ ++#: src/panelize.c:317 ++msgid "Find *.orig after patching" ++msgstr "Tìm *.orig) sau khi vá lỗi (patch)" ++ ++#: src/panelize.c:318 ++msgid "Find SUID and SGID programs" ++msgstr "Tìm chương trình có các bit SUID/SGID" ++ ++#: src/panelize.c:369 ++msgid "Cannot invoke command." ++msgstr "Không thực hiện được câu lệnh." ++ ++#: src/panelize.c:420 ++msgid "Pipe close failed" ++msgstr "Đóng đường ống không thành công" ++ ++#: src/popt.c:547 ++msgid "missing argument" ++msgstr "thiếu tham số" ++ ++#: src/popt.c:549 ++msgid "unknown option" ++msgstr "tùy chọn không rõ" ++ ++#: src/popt.c:555 ++msgid "invalid numeric value" ++msgstr "giá trị số không thích hợp" ++ ++#: src/popthelp.c:31 ++msgid "Show this help message" ++msgstr "Hiển thị thông báo trợ giúp này" ++ ++#: src/popthelp.c:32 ++msgid "Display brief usage message" ++msgstr "Hiển thị chỉ dẫn ngắn gọn" ++ ++#: src/popthelp.c:60 ++msgid "ARG" ++msgstr "ARG" ++ ++#: src/popthelp.c:179 ++msgid "Usage:" ++msgstr "Sử dụng:" ++ ++#: src/screen.c:201 ++msgid "UP--DIR" ++msgstr "LÊNTRÊN" ++ ++#: src/screen.c:222 ++msgid "SYMLINK" ++msgstr "LIÊNKẾTMỀM" ++ ++#: src/screen.c:226 ++msgid "SUB-DIR" ++msgstr "THƯMỤCCON" ++ ++#: src/screen.c:406 src/screen.c:407 ++msgid "Size" ++msgstr "Kích cỡ" ++ ++#: src/screen.c:409 ++msgid "MTime" ++msgstr "Thời gian sửa" ++ ++#: src/screen.c:410 ++msgid "ATime" ++msgstr "Truy cập cuối cùng" ++ ++#: src/screen.c:411 ++msgid "CTime" ++msgstr "Thời gian thay đổi" ++ ++#: src/screen.c:412 ++msgid "Permission" ++msgstr "Quyền hạn" ++ ++#: src/screen.c:413 ++msgid "Perm" ++msgstr "Quyền" ++ ++#: src/screen.c:414 ++msgid "Nl" ++msgstr "Nl" ++ ++#: src/screen.c:415 ++msgid "Inode" ++msgstr "Nút" ++ ++#: src/screen.c:416 ++msgid "UID" ++msgstr "UID" ++ ++#: src/screen.c:417 ++msgid "GID" ++msgstr "GID" ++ ++#: src/screen.c:418 ++msgid "Owner" ++msgstr "Chủ sở hữu" ++ ++#: src/screen.c:419 ++msgid "Group" ++msgstr "Nhóm" ++ ++#: src/screen.c:655 ++#, c-format ++msgid "%s bytes in %d file" ++msgstr "%s byte trong %d tập tin" ++ ++#: src/screen.c:655 ++#, c-format ++msgid "%s bytes in %d files" ++msgstr "%s byte trong %d tập tin" ++ ++#: src/screen.c:681 ++msgid "" ++msgstr "<đọc liên kết không thành công>" ++ ++#: src/screen.c:1289 ++msgid "Unknown tag on display format: " ++msgstr "Thẻ ghi không rõ trong định dạng hiển thị: " ++ ++#: src/screen.c:1415 ++msgid "User supplied format looks invalid, reverting to default." ++msgstr "Định dạng người dùng đưa ra có vẻ không thích hợp, chuyển lại thành mặc định." ++ ++#: src/screen.c:1952 ++msgid " Do you really want to execute? " ++msgstr " Thực sự muốn thực hiện? " ++ ++#: src/screen.c:2186 ++msgid "View" ++msgstr "Xem " ++ ++#: src/screen.c:2187 src/view.c:2231 ++msgid "Edit" ++msgstr "Soạn " ++ ++#: src/screen.c:2189 src/tree.c:977 ++msgid "RenMov" ++msgstr "Chuyển" ++ ++#: src/screen.c:2190 src/tree.c:981 ++msgid "Mkdir" ++msgstr "Tạotm " ++ ++#: src/selcodepage.c:54 ++msgid " Choose input codepage " ++msgstr " Chọn bảng mã dữ liệu vào " ++ ++#: src/selcodepage.c:58 ++msgid "- < No translation >" ++msgstr "- < Không có dịch >" ++ ++#: src/selcodepage.c:106 ++msgid "" ++"To use this feature select your codepage in\n" ++"Setup / Display Bits dialog!\n" ++"Do not forget to save options." ++msgstr "" ++"Để sử dụng tính năng này, hãy chọn bảng mã trong\n" ++"trình đơn Cấu hình / hộp thoại Bit hiển thị!\n" ++"Đừng quên ghi nhớ lại cấu hình." ++ ++#: src/slint.c:188 ++#, c-format ++msgid "" ++"Screen size %dx%d is not supported.\n" ++"Check the TERM environment variable.\n" ++msgstr "" ++"Kích thước màn hình %dx%d không được hỗ trợ.\n" ++"Hãy kiểm tra biến môi trường TERM.\n" ++ ++#: src/subshell.c:320 ++msgid "" ++"GNU Midnight Commander is already\n" ++"running on this terminal.\n" ++"Subshell support will be disabled." ++msgstr "" ++"Một GNU Midnight Commander đã làm việc\n" ++"trên terminal này. Sẽ không có hỗ trợ\n" ++"shell con." ++ ++#: src/subshell.c:425 ++#, c-format ++msgid "Cannot open named pipe %s\n" ++msgstr "Không mở được đường ống tên (named pipe) %s\n" ++ ++#: src/subshell.c:653 ++msgid " The shell is still active. Quit anyway? " ++msgstr " Shell vẫn còn hoạt động. Vẫn thoát? " ++ ++#: src/subshell.c:790 ++#, c-format ++msgid "Warning: Cannot change to %s.\n" ++msgstr "Cảnh báo: Không chuyển được vào %s.\n" ++ ++#: src/textconf.c:50 ++msgid "With builtin Editor\n" ++msgstr "Với Trình soạn thảo nội trú\n" ++ ++#: src/textconf.c:56 ++msgid "Using system-installed S-Lang library" ++msgstr "Sử dụng thư việc của S-Lang hệ thống" ++ ++#: src/textconf.c:58 ++msgid "Using included S-Lang library" ++msgstr "Sử dụng thư việc S-Lang bao gồm" ++ ++#: src/textconf.c:64 ++msgid "with termcap database" ++msgstr "với cơ sở dữ liệu termcap" ++ ++#: src/textconf.c:66 ++msgid "with terminfo database" ++msgstr "với cơ sở dữ liệu terminfo" ++ ++#: src/textconf.c:70 ++msgid "Using the ncurses library" ++msgstr "Dùng thư viện ncurses" ++ ++#: src/textconf.c:79 ++msgid "With optional subshell support" ++msgstr "Với hỗ trợ shell con không bắt buộc" ++ ++#: src/textconf.c:81 ++msgid "With subshell support as default" ++msgstr "Với hỗ trợ shell con mặc định" ++ ++#: src/textconf.c:87 ++msgid "With support for background operations\n" ++msgstr "Với hỗ trợ thao tác nền sau\n" ++ ++#: src/textconf.c:91 ++msgid "With mouse support on xterm and Linux console\n" ++msgstr "Với hỗ trợ chuột trong xterm và kênh giao tác Linux\n" ++ ++#: src/textconf.c:93 ++msgid "With mouse support on xterm\n" ++msgstr "Với hỗ trợ chuột trong xterm\n" ++ ++#: src/textconf.c:97 ++msgid "With support for X11 events\n" ++msgstr "Với hỗ trợ sự kiện X11\n" ++ ++#: src/textconf.c:101 ++msgid "With internationalization support\n" ++msgstr "Với hỗ trợ các ngôn ngữ khác\n" ++ ++#: src/textconf.c:105 ++msgid "With multiple codepages support\n" ++msgstr "Với hỗ trợ nhiều bảng mã\n" ++ ++#: src/textconf.c:121 ++msgid "Virtual File System:" ++msgstr "Hệ thống tập tin ảo:" ++ ++#: src/tree.c:147 ++#, c-format ++msgid "" ++"Cannot open the %s file for writing:\n" ++"%s\n" ++msgstr "" ++"Không mở được tập tin %s để ghi nhớ:\n" ++"%s\n" ++ ++#: src/tree.c:591 ++#, c-format ++msgid "Copy \"%s\" directory to:" ++msgstr " Sao chép thư mục \"%s\" vào:" ++ ++#: src/tree.c:632 ++#, c-format ++msgid "Move \"%s\" directory to:" ++msgstr " Di chuyển thư mục \"%s\" vào:" ++ ++#: src/tree.c:642 ++#, c-format ++msgid "" ++" Cannot stat the destination \n" ++" %s " ++msgstr "" ++" Không lấy (stat) được thuộc tính của đích đến \n" ++" %s " ++ ++#: src/tree.c:705 ++#, c-format ++msgid " Delete %s? " ++msgstr " Xóa %s? " ++ ++#: src/tree.c:735 ++msgid "Static" ++msgstr "Tĩnh" ++ ++#: src/tree.c:735 ++msgid "Dynamc" ++msgstr "Động" ++ ++#: src/tree.c:971 ++msgid "Rescan" ++msgstr "Quét lại" ++ ++#: src/tree.c:973 ++msgid "Forget" ++msgstr "Quên" ++ ++#: src/tree.c:986 ++msgid "Rmdir" ++msgstr "Xóa thư mục" ++ ++#: src/treestore.c:343 ++#, c-format ++msgid "" ++"Cannot write to the %s file:\n" ++"%s\n" ++msgstr "" ++"Không ghi nhớ được vào tập tin %s:\n" ++"%s\n" ++ ++#: src/user.c:133 ++msgid " Format error on file Extensions File " ++msgstr " Lỗi định dạng tập tin \"Phần mở rộng của tập tin\" " ++ ++#: src/user.c:134 ++#, c-format ++msgid " The %%var macro has no default " ++msgstr " Macro %%var không có giá trị mặc định " ++ ++#: src/user.c:135 ++#, c-format ++msgid " The %%var macro has no variable " ++msgstr " Macro %%var không có giá trị biến " ++ ++#: src/user.c:447 ++msgid " Debug " ++msgstr " Sửa lỗi " ++ ++#: src/user.c:456 ++msgid " ERROR: " ++msgstr " LỖI: " ++ ++#: src/user.c:460 ++msgid " True: " ++msgstr " Đúng: " ++ ++#: src/user.c:462 ++msgid " False: " ++msgstr " Sai: " ++ ++#: src/user.c:669 ++msgid " Warning -- ignoring file " ++msgstr " Cảnh báo - tập tin bị lờ đi " ++ ++#: src/user.c:670 ++#, c-format ++msgid "" ++"File %s is not owned by root or you or is world writable.\n" ++"Using it may compromise your security" ++msgstr "" ++"Tập tin %s không thuộc quyền sở hữu của root, hay của bạn,\n" ++"hoặc ai cũng có thể ghi. Sử dụng tập tin này có thể không an toàn" ++ ++#: src/user.c:792 ++#, c-format ++msgid " No suitable entries found in %s " ++msgstr " Không tìm thấy mục thích hợp trong %s" ++ ++#: src/user.c:798 ++msgid " User menu " ++msgstr " Trình đơn người dùng " ++ ++#: src/util.c:671 src/util.c:697 ++msgid "%b %e %H:%M" ++msgstr "%b %e %H:%M" ++ ++#: src/util.c:672 src/util.c:695 ++msgid "%b %e %Y" ++msgstr "%b %e %Y" ++ ++#: src/utilunix.c:333 ++#, c-format ++msgid "%s is not a directory\n" ++msgstr "%s không phải là một thư mục\n" ++ ++#: src/utilunix.c:335 ++#, c-format ++msgid "Directory %s is not owned by you\n" ++msgstr "Bạn không sở hữu thư mục %s\n" ++ ++#: src/utilunix.c:338 ++#, c-format ++msgid "Cannot set correct permissions for directory %s\n" ++msgstr "Không đặt được quyền hạn đúng cho thư mục %s\n" ++ ++#: src/utilunix.c:343 ++#, c-format ++msgid "Cannot create temporary directory %s: %s\n" ++msgstr "Không tạo được thư mục tạm thời %s: %s\n" ++ ++#: src/utilunix.c:373 ++#, c-format ++msgid "Temporary files will be created in %s\n" ++msgstr "Tập tin tạm thời sẽ được tạo trong thư mục %s\n" ++ ++#: src/utilunix.c:376 ++msgid "Temporary files will not be created\n" ++msgstr "Tập tin tạm thời sẽ không được tạo ra\n" ++ ++#: src/utilunix.c:401 ++msgid " Pipe failed " ++msgstr " Lỗi đường ống " ++ ++#: src/utilunix.c:405 ++msgid " Dup failed " ++msgstr " Lỗi lặp lại " ++ ++#: src/view.c:502 ++msgid " Cannot spawn child program " ++msgstr " Không sinh ra được tiến trình con " ++ ++#: src/view.c:513 ++msgid "Empty output from child filter" ++msgstr "Bộ lọc con trả lại kết quả rỗng" ++ ++#: src/view.c:519 ++msgid " Cannot open file " ++msgstr " Không mở được tập tin " ++ ++#: src/view.c:618 ++#, c-format ++msgid "" ++" Cannot open \"%s\"\n" ++" %s " ++msgstr "" ++" Không mở được \"%s\"\n" ++" %s " ++ ++#: src/view.c:627 ++#, c-format ++msgid "" ++" Cannot stat \"%s\"\n" ++" %s " ++msgstr "" ++" Không lấy (stat) được thuộc tính \"%s\"\n" ++" %s " ++ ++#: src/view.c:636 ++msgid " Cannot view: not a regular file " ++msgstr " Không xem được vì lý do: không\n" ++" phải tập tin thông thường " ++ ++#: src/view.c:775 ++#, c-format ++msgid "File: %s" ++msgstr "Tập tin: %s" ++ ++#: src/view.c:790 ++#, c-format ++msgid "Offset 0x%08lx" ++msgstr "Bộ offset 0x%08lx" ++ ++#: src/view.c:792 ++#, c-format ++msgid "Col %d" ++msgstr "Cột %d" ++ ++#: src/view.c:796 ++#, c-format ++msgid "%s bytes" ++msgstr "%s byte" ++ ++#: src/view.c:801 ++msgid " [grow]" ++msgstr " [lớn lên]" ++ ++#: src/view.c:1826 ++msgid "Invalid hex search expression" ++msgstr "Biểu thức tìm kiếm hex không đúng" ++ ++#: src/view.c:1880 ++msgid " Invalid regular expression " ++msgstr " Biểu thức chính quy không đúng" ++ ++#: src/view.c:2003 ++#, c-format ++msgid "" ++" The current line number is %d.\n" ++" Enter the new line number:" ++msgstr "" ++" Số thứ tự dòng hiện thời %d.\n" ++" Hãy nhập số thứ tự dòng muốn chuyển đến:" ++ ++#: src/view.c:2026 ++#, c-format ++msgid "" ++" The current address is 0x%lx.\n" ++" Enter the new address:" ++msgstr "" ++" Địa chỉ hiện thời - 0x%lx.\n" ++" Hãy nhập địa chỉ mới:" ++ ++#: src/view.c:2028 ++msgid " Goto Address " ++msgstr " Đi tới địa chỉ " ++ ++#: src/view.c:2060 ++msgid " Enter regexp:" ++msgstr " Nhập biểu thức chính quy:" ++ ++#: src/view.c:2216 ++msgid "Ascii" ++msgstr "Ascii" ++ ++#: src/view.c:2216 ++msgid "Hex" ++msgstr "Hex" ++ ++#: src/view.c:2218 ++msgid "Goto" ++msgstr "ĐiTới" ++ ++#: src/view.c:2218 ++msgid "Line" ++msgstr "Dòng" ++ ++#: src/view.c:2220 ++msgid "RxSrch" ++msgstr "TìmRx" ++ ++#: src/view.c:2225 ++msgid "EdHex" ++msgstr "SoạnHex" ++ ++#: src/view.c:2225 ++msgid "EdText" ++msgstr "SoạnVb" ++ ++#: src/view.c:2233 ++msgid "UnWrap" ++msgstr "BỏWrap" ++ ++#: src/view.c:2233 ++msgid "Wrap" ++msgstr "CóWrap" ++ ++#: src/view.c:2236 ++msgid "HxSrch" ++msgstr "TìmHx" ++ ++#: src/view.c:2239 ++msgid "Raw" ++msgstr "Thô" ++ ++#: src/view.c:2239 ++msgid "Parse" ++msgstr "Phtích" ++ ++#: src/view.c:2244 ++msgid "Unform" ++msgstr "K0dạng" ++ ++#: src/view.c:2244 ++msgid "Format" ++msgstr "CóDạng" ++ ++#: src/widget.c:911 ++msgid " History " ++msgstr " Lịch sử" ++ ++#: src/win.c:159 ++msgid "Function key 1" ++msgstr "Phím chức năng 1" ++ ++#: src/win.c:160 ++msgid "Function key 2" ++msgstr "Phím chức năng 2" ++ ++#: src/win.c:161 ++msgid "Function key 3" ++msgstr "Phím chức năng 3" ++ ++#: src/win.c:162 ++msgid "Function key 4" ++msgstr "Phím chức năng 4" ++ ++#: src/win.c:163 ++msgid "Function key 5" ++msgstr "Phím chức năng 5" ++ ++#: src/win.c:164 ++msgid "Function key 6" ++msgstr "Phím chức năng 6" ++ ++#: src/win.c:165 ++msgid "Function key 7" ++msgstr "Phím chức năng 7" ++ ++#: src/win.c:166 ++msgid "Function key 8" ++msgstr "Phím chức năng 8" ++ ++#: src/win.c:167 ++msgid "Function key 9" ++msgstr "Phím chức năng 9" ++ ++#: src/win.c:168 ++msgid "Function key 10" ++msgstr "Phím chức năng 10" ++ ++#: src/win.c:169 ++msgid "Function key 11" ++msgstr "Phím chức năng 11" ++ ++#: src/win.c:170 ++msgid "Function key 12" ++msgstr "Phím chức năng 12" ++ ++#: src/win.c:171 ++msgid "Function key 13" ++msgstr "Phím chức năng 13" ++ ++#: src/win.c:172 ++msgid "Function key 14" ++msgstr "Phím chức năng 14" ++ ++#: src/win.c:173 ++msgid "Function key 15" ++msgstr "Phím chức năng 15" ++ ++#: src/win.c:174 ++msgid "Function key 16" ++msgstr "Phím chức năng 16" ++ ++#: src/win.c:175 ++msgid "Function key 17" ++msgstr "Phím chức năng 17" ++ ++#: src/win.c:176 ++msgid "Function key 18" ++msgstr "Phím chức năng 18" ++ ++#: src/win.c:177 ++msgid "Function key 19" ++msgstr "Phím chức năng 19" ++ ++#: src/win.c:178 ++msgid "Function key 20" ++msgstr "Phím chức năng 20" ++ ++#: src/win.c:179 ++msgid "Backspace key" ++msgstr "Phím Backspace" ++ ++#: src/win.c:180 ++msgid "End key" ++msgstr "Phím End" ++ ++#: src/win.c:181 ++msgid "Up arrow key" ++msgstr "Phím mũi tên lên" ++ ++#: src/win.c:182 ++msgid "Down arrow key" ++msgstr "Phím mũi tên xuống" ++ ++#: src/win.c:183 ++msgid "Left arrow key" ++msgstr "Phím mũi tên sang trái" ++ ++#: src/win.c:184 ++msgid "Right arrow key" ++msgstr "Phím mũi tên sang phải" ++ ++#: src/win.c:185 ++msgid "Home key" ++msgstr "Phím Home" ++ ++#: src/win.c:186 ++msgid "Page Down key" ++msgstr "Phím Page Down" ++ ++#: src/win.c:187 ++msgid "Page Up key" ++msgstr "Phím Page Up" ++ ++#: src/win.c:188 ++msgid "Insert key" ++msgstr "Phím Insert" ++ ++#: src/win.c:189 ++msgid "Delete key" ++msgstr "Phím Delete" ++ ++#: src/win.c:190 ++msgid "Completion/M-tab" ++msgstr "Hoàn thành/M-Tab" ++ ++#: src/win.c:191 ++msgid "+ on keypad" ++msgstr "+ trên phần keypad" ++ ++#: src/win.c:192 ++msgid "- on keypad" ++msgstr "- trên phần keypad" ++ ++#: src/win.c:193 ++msgid "* on keypad" ++msgstr "* trên phần keypad" ++ ++#: src/win.c:195 ++msgid "Left arrow keypad" ++msgstr "Mũi tên sang trái trên phần keypad" ++ ++#: src/win.c:196 ++msgid "Right arrow keypad" ++msgstr "Mũi tên sang phải trên phần keypad" ++ ++#: src/win.c:197 ++msgid "Up arrow keypad" ++msgstr "Mũi tên lên trên của phần keypad" ++ ++#: src/win.c:198 ++msgid "Down arrow keypad" ++msgstr "Mũi tên xuống dưới của phần keypad" ++ ++#: src/win.c:199 ++msgid "Home on keypad" ++msgstr "Home trên keypad" ++ ++#: src/win.c:200 ++msgid "End on keypad" ++msgstr "End trên keypad" ++ ++#: src/win.c:201 ++msgid "Page Down keypad" ++msgstr "Page Down trên keypad" ++ ++#: src/win.c:202 ++msgid "Page Up keypad" ++msgstr "Page Up trên keypad" ++ ++#: src/win.c:203 ++msgid "Insert on keypad" ++msgstr "Insert trên keypad" ++ ++#: src/win.c:204 ++msgid "Delete on keypad" ++msgstr "Delete trên keypad" ++ ++#: src/win.c:205 ++msgid "Enter on keypad" ++msgstr "Enter trên keypad" ++ ++#: src/win.c:206 ++msgid "Slash on keypad" ++msgstr "Slash trên keypad" ++ ++#: src/win.c:207 ++msgid "NumLock on keypad" ++msgstr "NumLock trên keypad" ++ ++#: src/wtools.c:256 ++msgid "Background process:" ++msgstr "Tiến trình nền sau:" ++ ++#: vfs/cpio.c:142 vfs/cpio.c:158 ++#, c-format ++msgid "" ++"Cannot open cpio archive\n" ++"%s" ++msgstr "" ++"Không mở được tập tin nén cpio\n" ++"%s" ++ ++#: vfs/cpio.c:223 ++#, c-format ++msgid "" ++"Premature end of cpio archive\n" ++"%s" ++msgstr "" ++"Phần cuối của tập tin nén cpio bị hỏng\n" ++"%s" ++ ++#: vfs/cpio.c:309 vfs/cpio.c:359 ++#, c-format ++msgid "" ++"Corrupted cpio header encountered in\n" ++"%s" ++msgstr "" ++"Lỗi phần đầu cpio phát hiện trong\n" ++"%s" ++ ++#: vfs/cpio.c:432 ++#, c-format ++msgid "" ++"Inconsistent hardlinks of\n" ++"%s\n" ++"in cpio archive\n" ++"%s" ++msgstr "" ++"Liên kết cứng không thích hợp \n" ++"%s\n" ++"trong tập tin nén cpio\n" ++"%s" ++ ++#: vfs/cpio.c:457 ++#, c-format ++msgid "%s contains duplicate entries! Skipping!" ++msgstr "%s chứa mục lặp lại! Nhảy qua!" ++ ++#: vfs/cpio.c:526 ++#, c-format ++msgid "" ++"Unexpected end of file\n" ++"%s" ++msgstr "" ++"Kết thúc tập tin không mong đợi\n" ++"%s" ++ ++#: vfs/direntry.c:326 ++#, c-format ++msgid "Directory cache expired for %s" ++msgstr "Cache thư mục hết hạn cho %s" ++ ++#: vfs/direntry.c:749 ++msgid "Starting linear transfer..." ++msgstr "Chạy truyền tải theo đường thẳng..." ++ ++#: vfs/direntry.c:886 ++#, c-format ++msgid "%s: %s: %s %3d%% (%lu bytes transferred)" ++msgstr "%s: %s: %s %3d%% (đã truyền tải %lu byte)" ++ ++#: vfs/direntry.c:887 ++#, c-format ++msgid "%s: %s: %s %lu bytes transferred" ++msgstr "%s: %s: %s đã truyền tải %lu byte" ++ ++#: vfs/direntry.c:933 ++msgid "Getting file" ++msgstr "Nhận tập tin" ++ ++#: vfs/extfs.c:303 ++#, c-format ++msgid "" ++"Cannot open %s archive\n" ++"%s" ++msgstr "" ++"Không mở được tập tin nén %s\n" ++"%s" ++ ++#: vfs/extfs.c:343 vfs/extfs.c:365 vfs/extfs.c:415 ++msgid "Inconsistent extfs archive" ++msgstr "Tập tin nén extfs không thích hợp" ++ ++#: vfs/fish.c:157 ++#, c-format ++msgid "fish: Disconnecting from %s" ++msgstr "fish: Ngừng kết nối từ %s" ++ ++#: vfs/fish.c:232 ++msgid "fish: Waiting for initial line..." ++msgstr "fish: Đang chời dòng đầu tiên..." ++ ++#: vfs/fish.c:244 ++msgid "Sorry, we cannot do password authenticated connections for now." ++msgstr "Xin lỗi, bây giờ không thể tạo kết nối xác thực theo mật khẩu." ++ ++#: vfs/fish.c:249 ++msgid " fish: Password required for " ++msgstr "fish: yêu cầu mật khẩu cho " ++ ++#: vfs/fish.c:258 ++msgid "fish: Sending password..." ++msgstr "fish: Đang gửi mật khẩu..." ++ ++#: vfs/fish.c:264 ++msgid "fish: Sending initial line..." ++msgstr "fish: Đang gửi dòng đầu tiên..." ++ ++#: vfs/fish.c:275 ++msgid "fish: Handshaking version..." ++msgstr "fish: Đang xác nhận phiên bản..." ++ ++#: vfs/fish.c:289 ++msgid "fish: Setting up current directory..." ++msgstr "fish: Đang đặt thư mục hiện thời..." ++ ++#: vfs/fish.c:291 ++#, c-format ++msgid "fish: Connected, home %s." ++msgstr "fish: Kết nối thành công, thư mục cá nhân %s." ++ ++#: vfs/fish.c:375 ++#, c-format ++msgid "fish: Reading directory %s..." ++msgstr "fish: Đọc thư mục %s..." ++ ++#: vfs/fish.c:477 vfs/ftpfs.c:1277 vfs/undelfs.c:343 ++#, c-format ++msgid "%s: done." ++msgstr "%s: xong." ++ ++#: vfs/fish.c:482 vfs/ftpfs.c:1247 vfs/undelfs.c:346 ++#, c-format ++msgid "%s: failure" ++msgstr "%s: lỗi" ++ ++#: vfs/fish.c:507 ++#, c-format ++msgid "fish: store %s: sending command..." ++msgstr "fish: bản ghi %s: đang gửi câu lệnh..." ++ ++#: vfs/fish.c:548 ++msgid "fish: Local read failed, sending zeros" ++msgstr "fish: Lỗi đọc nội bộ, đang gửi các số không" ++ ++#: vfs/fish.c:560 ++#, c-format ++msgid "fish: storing %s %d (%lu)" ++msgstr "fish: ghi %s %d (%lu)" ++ ++#: vfs/fish.c:561 ++msgid "zeros" ++msgstr "các số không" ++ ++#: vfs/fish.c:613 ++msgid "Aborting transfer..." ++msgstr "Dừng truyền tải..." ++ ++#: vfs/fish.c:622 ++msgid "Error reported after abort." ++msgstr "Có lỗi báo cáo sau khi dừng." ++ ++#: vfs/fish.c:624 ++msgid "Aborted transfer would be successful." ++msgstr "Dừng truyền tải thành công." ++ ++#: vfs/ftpfs.c:378 ++#, c-format ++msgid "ftpfs: Disconnecting from %s" ++msgstr "ftpfs: Ngắt kết nối từ %s" ++ ++#: vfs/ftpfs.c:433 ++msgid " FTP: Password required for " ++msgstr " FTP: Cần mật khẩu cho " ++ ++#: vfs/ftpfs.c:469 ++msgid "ftpfs: sending login name" ++msgstr "ftpfs: đang gửi tên đăng nhập" ++ ++#: vfs/ftpfs.c:473 ++msgid "ftpfs: sending user password" ++msgstr "ftpfs: đang gửi mật khẩu người dùng" ++ ++#: vfs/ftpfs.c:479 ++#, c-format ++msgid "FTP: Account required for user %s" ++msgstr "FTP: Yêu cầu tài khoản cho người dùng %s" ++ ++#: vfs/ftpfs.c:481 ++msgid "Account:" ++msgstr "Tài khoản:" ++ ++#: vfs/ftpfs.c:485 ++msgid "ftpfs: sending user account" ++msgstr "ftpfs: đang gửi tài khoản người dùng" ++ ++#: vfs/ftpfs.c:495 ++msgid "ftpfs: logged in" ++msgstr "ftpfs: đã đăng nhập" ++ ++#: vfs/ftpfs.c:509 ++#, c-format ++msgid "ftpfs: Login incorrect for user %s " ++msgstr "ftpfs: lỗi đăng nhập cho người dùng %s " ++ ++#: vfs/ftpfs.c:633 ++msgid "ftpfs: Invalid host name." ++msgstr "ftpfs: Tên máy không đúng." ++ ++#: vfs/ftpfs.c:651 ++msgid "ftpfs: Invalid host address." ++msgstr "ftpfs: Địa chỉ không đúng." ++ ++#: vfs/ftpfs.c:673 ++#, c-format ++msgid "ftpfs: making connection to %s" ++msgstr "ftpfs: Thực hiện kết nối với %s" ++ ++#: vfs/ftpfs.c:683 ++msgid "ftpfs: connection interrupted by user" ++msgstr "ftpfs: người dùng dừng kết nối giữa chừng" ++ ++#: vfs/ftpfs.c:685 ++#, c-format ++msgid "ftpfs: connection to server failed: %s" ++msgstr "ftpfs: kết nối tới máy chủ không thành công: %s" ++ ++#: vfs/ftpfs.c:726 ++#, c-format ++msgid "Waiting to retry... %d (Control-C to cancel)" ++msgstr "Chờ thử lại... %d (Control-C để hủy bỏ)" ++ ++#: vfs/ftpfs.c:906 ++msgid "ftpfs: could not setup passive mode" ++msgstr "ftpfs: không đặt được chế độ bị động (passive)" ++ ++#: vfs/ftpfs.c:985 ++msgid "ftpfs: aborting transfer." ++msgstr "ftpfs: dừng truyền tải." ++ ++#: vfs/ftpfs.c:987 ++#, c-format ++msgid "ftpfs: abort error: %s" ++msgstr "ftpfs: lỗi thoát: %s" ++ ++#: vfs/ftpfs.c:995 ++msgid "ftpfs: abort failed" ++msgstr "ftpfs: sự cố thoát" ++ ++#: vfs/ftpfs.c:1099 vfs/ftpfs.c:1203 ++msgid "ftpfs: CWD failed." ++msgstr "ftpfs: CWD (thay đổi thư mục) không thành công." ++ ++#: vfs/ftpfs.c:1109 vfs/ftpfs.c:1116 ++msgid "ftpfs: couldn't resolve symlink" ++msgstr "ftpfs: không tìm được liên kết mềm" ++ ++#: vfs/ftpfs.c:1167 ++msgid "Resolving symlink..." ++msgstr "Đang tìm liên kết mềm..." ++ ++#: vfs/ftpfs.c:1189 ++#, c-format ++msgid "ftpfs: Reading FTP directory %s... %s%s" ++msgstr "ftpfs: Đọc thư mục FTP %s... %s%s" ++ ++#: vfs/ftpfs.c:1192 ++msgid "(strict rfc959)" ++msgstr "(hạn chế rfc959)" ++ ++#: vfs/ftpfs.c:1193 ++msgid "(chdir first)" ++msgstr "(đầu tiên chdir)" ++ ++#: vfs/ftpfs.c:1290 ++msgid "ftpfs: failed; nowhere to fallback to" ++msgstr "ftpfs: lỗi; không có nơi nào để quay lại về" ++ ++#: vfs/ftpfs.c:1355 ++#, c-format ++msgid "ftpfs: storing file %lu (%lu)" ++msgstr "ftpfs: ghi tập tin %lu (%lu)" ++ ++#: vfs/ftpfs.c:1740 ++msgid "" ++"~/.netrc file has incorrect mode.\n" ++"Remove password or correct mode." ++msgstr "" ++"Tập tin ~/.netrc có chế độ truy cập/sở hữu không đúng.\n" ++"Hãy xóa mật khẩu hoặc sửa lại chế độ cho đúng." ++ ++#: vfs/mcfs.c:122 vfs/mcfs.c:167 ++msgid " MCFS " ++msgstr " MCFS " ++ ++#: vfs/mcfs.c:123 ++msgid " The server does not support this version " ++msgstr " Máy chủ không hỗ trợ phiên bản này " ++ ++#: vfs/mcfs.c:140 ++msgid "" ++" The remote server is not running on a system port \n" ++" you need a password to log in, but the information may \n" ++" not be safe on the remote side. Continue? \n" ++msgstr "" ++" Máy chủ ở xa không chạy trên một cổng hệ thống. Cần \n" ++" mật khẩu để đăng nhập vào, nhưng điều này có thể \n" ++" không an toàn cho thông tin phía ở xa. Tiếp tục?\n" ++ ++#: vfs/mcfs.c:153 ++msgid " MCFS Password required " ++msgstr " Yêu cầu mật khẩu MCFS " ++ ++#: vfs/mcfs.c:167 ++msgid " Invalid password " ++msgstr " Mật khẩu không đúng " ++ ++#: vfs/mcfs.c:227 ++#, c-format ++msgid " Cannot locate hostname: %s " ++msgstr " Không xác định được tên máy ở xa: %s" ++ ++#: vfs/mcfs.c:246 ++#, c-format ++msgid " Cannot create socket: %s " ++msgstr " Không tạo được socket: %s " ++ ++#: vfs/mcfs.c:252 ++#, c-format ++msgid " Cannot connect to server: %s " ++msgstr " Không kết nối được tới máy chủ: %s " ++ ++#: vfs/mcfs.c:322 ++msgid " Too many open connections " ++msgstr " Quá nhiều kết nối mở " ++ ++#: vfs/sfs.c:346 ++#, c-format ++msgid "" ++"Warning: Invalid line in %s:\n" ++"%s\n" ++msgstr "" ++"Cảnh báo: dòng không đúng trong %s:\n" ++"%s\n" ++ ++#: vfs/sfs.c:358 ++#, c-format ++msgid "" ++"Warning: Invalid flag %c in %s:\n" ++"%s\n" ++msgstr "" ++"Cảnh báo: Cờ không đúng %c trong %s:\n" ++"%s\n" ++ ++#: vfs/smbfs.c:576 ++#, c-format ++msgid "" ++" smbfs_reconnect to %s failed\n" ++" " ++msgstr "" ++" smbfs_reconnect (kết nối lại) tới %s không thành công\n" ++" " ++ ++#: vfs/smbfs.c:1120 ++msgid " Authentication failed " ++msgstr " Xác thực không thành công " ++ ++#: vfs/smbfs.c:1632 ++#, c-format ++msgid " Error %s creating directory %s " ++msgstr " Lỗi %s khi tạo thư mục %s " ++ ++#: vfs/smbfs.c:1655 ++#, c-format ++msgid " Error %s removing directory %s " ++msgstr " Lỗi %s khi xóa thư mục %s " ++ ++#: vfs/smbfs.c:1744 ++#, c-format ++msgid " %s opening remote file %s " ++msgstr " %s khi mở tập tin ở xa %s " ++ ++#: vfs/smbfs.c:1817 ++#, c-format ++msgid " %s removing remote file %s " ++msgstr " %s khi xoá tập tin ở xa %s " ++ ++#: vfs/smbfs.c:1855 ++#, c-format ++msgid " %s renaming files\n" ++msgstr " %s khi đổi tên các tập tin\n" ++ ++#: vfs/tar.c:212 vfs/tar.c:229 ++#, c-format ++msgid "" ++"Cannot open tar archive\n" ++"%s" ++msgstr "" ++"Không mở được tập tin nén tar\n" ++"%s" ++ ++#: vfs/tar.c:424 ++msgid "Unexpected EOF on archive file" ++msgstr "Kết thúc tập tin EOF nén không mong đợi" ++ ++#: vfs/tar.c:476 vfs/tar.c:483 ++msgid "Inconsistent tar archive" ++msgstr "Tập tin tar không thích hợp" ++ ++#: vfs/tar.c:561 ++#, c-format ++msgid "" ++"Hmm,...\n" ++"%s\n" ++"doesn't look like a tar archive." ++msgstr "" ++"Hừm,...\n" ++"%s\n" ++"không giống tập tin tar." ++ ++#: vfs/undelfs.c:82 ++msgid " undelfs: error " ++msgstr " undelfs: lỗi " ++ ++#: vfs/undelfs.c:189 ++msgid " not enough memory " ++msgstr " không đủ bộ nhớ " ++ ++#: vfs/undelfs.c:194 ++msgid " while allocating block buffer " ++msgstr " khi phân phối bộ đệm khối " ++ ++#: vfs/undelfs.c:198 ++#, c-format ++msgid " open_inode_scan: %d " ++msgstr " open_inode_scan: %d " ++ ++#: vfs/undelfs.c:202 ++#, c-format ++msgid " while starting inode scan %d " ++msgstr " khi bắt đầu quét chỉ mục nút inode %d " ++ ++#: vfs/undelfs.c:211 ++#, c-format ++msgid "undelfs: loading deleted files information %d inodes" ++msgstr "undelfs: nạp thông tin về những tập tin bị xóa %d inode" ++ ++#: vfs/undelfs.c:229 ++#, c-format ++msgid " while calling ext2_block_iterate %d " ++msgstr " khi gọi ext2_block_iterate %d " ++ ++#: vfs/undelfs.c:241 ++msgid " no more memory while reallocating array " ++msgstr " không đủ bộ nhớ khi phân phối lại chuỗi " ++ ++#: vfs/undelfs.c:262 ++#, c-format ++msgid " while doing inode scan %d " ++msgstr " khi quét chỉ mục nút inode %d " ++ ++#: vfs/undelfs.c:297 ++msgid " Ext2lib error " ++msgstr " Lỗi Ext2lib " ++ ++#: vfs/undelfs.c:325 vfs/undelfs.c:644 ++#, c-format ++msgid " Cannot open file %s " ++msgstr " Không mở được tập tin %s " ++ ++#: vfs/undelfs.c:328 ++msgid "undelfs: reading inode bitmap..." ++msgstr "undelfs: đọc sơ đồ bit của nút inode..." ++ ++#: vfs/undelfs.c:331 ++#, c-format ++msgid "" ++" Cannot load inode bitmap from: \n" ++" %s \n" ++msgstr "" ++" Không nạp được sơ đồ bit của nút inode từ:\n" ++" %s \n" ++ ++#: vfs/undelfs.c:334 ++msgid "undelfs: reading block bitmap..." ++msgstr "undelfs: đọc sơ đồ bit của khối..." ++ ++#: vfs/undelfs.c:337 ++#, c-format ++msgid "" ++" Cannot load block bitmap from: \n" ++" %s \n" ++msgstr "" ++" Không nạp được sơ đồ bit của khối từ:\n" ++" %s \n" ++ ++#: vfs/undelfs.c:360 ++msgid " vfs_info is not fs! " ++msgstr " vfs_info không phải là hệ thống tập tin! " ++ ++#: vfs/undelfs.c:416 vfs/undelfs.c:600 ++msgid " You have to chdir to extract files first " ++msgstr " Đầu tiên bạn phải chdir để chuyển tới thư mục chứa tập tin cần giản nén " ++ ++#: vfs/undelfs.c:539 ++msgid " while iterating over blocks " ++msgstr " khi lặp lại khối " ++ ++#: vfs/vfs.c:880 ++msgid "Changes to file lost" ++msgstr "Thay đổi tới tập tin bị mất" ++ +diff -urN mc-4.6.1.orig/src/achown.c mc-4.6.1/src/achown.c +--- mc-4.6.1.orig/src/achown.c 2005-07-23 22:52:02.000000000 +0600 ++++ mc-4.6.1/src/achown.c 2007-01-19 18:33:58.000000000 +0500 +@@ -583,6 +583,12 @@ + b_att[2] = button_new (XTRACT (6)); + b_user = button_new (XTRACT (5)); + b_group = button_new (XTRACT (4)); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1); ++ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1); ++ } ++#endif + + add_widget (ch_dlg, b_group); + add_widget (ch_dlg, b_user); +diff -urN mc-4.6.1.orig/src/boxes.c mc-4.6.1/src/boxes.c +--- mc-4.6.1.orig/src/boxes.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/boxes.c 2007-01-19 18:33:59.000000000 +0500 +@@ -49,6 +49,7 @@ + #ifdef HAVE_CHARSET + #include "charsets.h" + #include "selcodepage.h" ++#include "recode.h" + #endif + + #ifdef USE_NETCODE +@@ -150,23 +151,23 @@ + display_title = _(display_title); + for (i = 0; i < LIST_TYPES; i++) { + displays[i] = _(displays[i]); +- if ((l = strlen (displays[i])) > maxlen) ++ if ((l = mbstrlen (displays[i])) > maxlen) + maxlen = l; + } + +- i = strlen (ok_button) + 5; +- l = strlen (cancel_button) + 3; ++ i = mbstrlen (ok_button) + 5; ++ l = mbstrlen (cancel_button) + 3; + l = max (i, l); + + i = maxlen + l + 16; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (user_mini_status) + 13; ++ i = mbstrlen (user_mini_status) + 13; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (display_title) + 10; ++ i = mbstrlen (display_title) + 10; + if (i > DISPLAY_X) + DISPLAY_X = i; + +@@ -285,20 +286,20 @@ + int maxlen = 0; + for (i = SORT_TYPES - 1; i >= 0; i--) { + sort_orders_names[i] = _(sort_orders[i].sort_name); +- r = strlen (sort_orders_names[i]); ++ r = mbstrlen (sort_orders_names[i]); + if (r > maxlen) + maxlen = r; + } + + check_pos = maxlen + 9; + +- r = strlen (reverse_label) + 4; +- i = strlen (case_label) + 4; ++ r = mbstrlen (reverse_label) + 4; ++ i = mbstrlen (case_label) + 4; + if (i > r) + r = i; + +- l = strlen (ok_button) + 6; +- i = strlen (cancel_button) + 4; ++ l = mbstrlen (ok_button) + 6; ++ i = mbstrlen (cancel_button) + 4; + if (i > l) + l = i; + +@@ -307,7 +308,7 @@ + if (i > SORT_X) + SORT_X = i; + +- i = strlen (sort_title) + 6; ++ i = mbstrlen (sort_title) + 6; + if (i > SORT_X) + SORT_X = i; + +@@ -402,7 +403,7 @@ + while (i--) + { + conf_widgets [i].text = _(conf_widgets [i].text); +- l1 = strlen (conf_widgets [i].text) + 3; ++ l1 = mbstrlen (conf_widgets [i].text) + 3; + if (l1 > maxlen) + maxlen = l1; + } +@@ -417,8 +418,8 @@ + * And this for the case when buttons with some space to the right + * do not fit within 2/6 + */ +- l1 = strlen (conf_widgets [0].text) + 3; +- i = strlen (conf_widgets [1].text) + 5; ++ l1 = mbstrlen (conf_widgets [0].text) + 3; ++ i = mbstrlen (conf_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -446,8 +447,8 @@ + } + } + +-#define DISPY 11 +-#define DISPX 46 ++#define DISPY 13 ++#define DISPX 35 + + + #ifndef HAVE_CHARSET +@@ -489,11 +490,11 @@ + { + display_widgets [i].text = _(display_widgets[i].text); + display_bits_str [i] = _(display_bits_str [i]); +- l1 = strlen (display_bits_str [i]); ++ l1 = mbstrlen (display_bits_str [i]); + if (l1 > maxlen) + maxlen = l1; + } +- l1 = strlen (display_widgets [2].text); ++ l1 = mbstrlen (display_widgets [2].text); + if (l1 > maxlen) + maxlen = l1; + +@@ -501,8 +502,8 @@ + display_bits.xlen = (maxlen + 5) * 6 / 4; + + /* See above confirm_box */ +- l1 = strlen (display_widgets [0].text) + 3; +- i = strlen (display_widgets [1].text) + 5; ++ l1 = mbstrlen (display_widgets [0].text) + 3; ++ i = mbstrlen (display_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -543,26 +544,61 @@ + + + static int new_display_codepage; ++static int new_ftp_codepage; + +-static WLabel *cplabel; + static WCheck *inpcheck; + ++static WButton *cpbutton; ++static WButton *cpbutton_ftp; ++ + static int + sel_charset_button (int action) + { + const char *cpname; + char buf[64]; +- new_display_codepage = select_charset (new_display_codepage, 1); ++ new_display_codepage = select_charset (new_display_codepage, 1, _(" Choose input codepage ")); + cpname = (new_display_codepage < 0) + ? _("Other 8 bit") + : codepages[new_display_codepage].name; + + /* avoid strange bug with label repainting */ +- g_snprintf (buf, sizeof (buf), "%-27s", cpname); +- label_set_text (cplabel, buf); ++ sprintf( buf, "%s", cpname ); ++ button_set_text (cpbutton, buf); ++ ++ if(new_display_codepage<0) new_ftp_codepage=-1; ++ cpname = (new_ftp_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_ftp_codepage ].name; ++ sprintf( buf, "%s", cpname ); ++ button_set_text (cpbutton_ftp, buf); ++ + return 0; + } + ++static int sel_charset_button_ftp(int action) { ++ char *cpname, buf[64]; ++ if(new_display_codepage>0) { ++ new_ftp_codepage = select_charset(new_ftp_codepage, 0, _(" Choose default FTP codepage ")); ++ cpname = (new_display_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_display_codepage ].name; ++ sprintf( buf, "%s", cpname ); ++ button_set_text( cpbutton, buf ); ++ cpname = (new_ftp_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_ftp_codepage ].name; ++ sprintf( buf, "%s", cpname ); ++ button_set_text( cpbutton_ftp, buf ); ++ } ++ else { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ } ++ return 0; ++} ++ + static Dlg_head * + init_disp_bits_box (void) + { +@@ -581,9 +617,6 @@ + cpname = (new_display_codepage < 0) + ? _("Other 8 bit") + : codepages[new_display_codepage].name; +- cplabel = label_new (4, 4, cpname); +- add_widget (dbits_dlg, cplabel); +- + add_widget (dbits_dlg, + button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL, + NORMAL_BUTTON, _("&Cancel"), 0)); +@@ -592,13 +625,30 @@ + 0)); + + inpcheck = +- check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input")); ++ check_new (8, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input")); + add_widget (dbits_dlg, inpcheck); + +- cpname = _("&Select"); +- add_widget (dbits_dlg, +- button_new (4, DISPX - 8 - strlen (cpname), B_USER, +- NORMAL_BUTTON, cpname, sel_charset_button)); ++ ++ add_widget( dbits_dlg, label_new( 5, 4, _("FTP default codepage:"))); ++ if(n_codepages>0) { ++ cpname = (new_display_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_display_codepage ].name; ++ } ++ else cpname= _("Other 8 bit"); ++ cpbutton=button_new(4, 5, B_USER, ++ NORMAL_BUTTON, cpname, sel_charset_button); ++ ++ if(n_codepages>0) { ++ cpname = (new_ftp_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_ftp_codepage ].name; ++ } ++ else cpname= _("Other 8 bit"); ++ cpbutton_ftp=button_new(6, 5, B_USER, ++ NORMAL_BUTTON, cpname, sel_charset_button_ftp); ++ add_widget( dbits_dlg, cpbutton_ftp); ++ add_widget (dbits_dlg, cpbutton); + + return dbits_dlg; + } +@@ -608,6 +658,7 @@ + { + Dlg_head *dbits_dlg; + new_display_codepage = display_codepage; ++ new_ftp_codepage = ftp_codepage; + + application_keypad_mode (); + dbits_dlg = init_disp_bits_box (); +@@ -628,6 +679,17 @@ + && display_codepage != 1) ? 128 : 160; + #endif + use_8th_bit_as_meta = !(inpcheck->state & C_BOOL); ++ ++ ftp_codepage=new_ftp_codepage; ++ if(display_codepage<=0) { ++ panel_reset_codepage(left_panel); ++ paint_dir(left_panel); ++ display_mini_info(left_panel); ++ panel_reset_codepage(right_panel); ++ paint_dir(right_panel); ++ display_mini_info(right_panel); ++ } ++ + } + destroy_dlg (dbits_dlg); + repaint_screen (); +@@ -803,7 +865,7 @@ + quick_widgets [1].y_divisions = + quick_widgets [0].y_divisions = Quick_input.ylen = 5; + +- len = strlen (quick_widgets [1].text); ++ len = mbstrlen (quick_widgets [1].text); + + quick_widgets [0].relative_x = + quick_widgets [1].relative_x + len + 1; +@@ -962,7 +1024,7 @@ + { + job_buttons [i].name = _(job_buttons [i].name); + +- len = strlen (job_buttons [i].name) + 4; ++ len = mbstrlen (job_buttons [i].name) + 4; + JOBS_X = max (JOBS_X, startx + len + 3); + + job_buttons [i].xpos = startx; +@@ -971,7 +1033,7 @@ + + /* Last button - Ok a.k.a. Cancel :) */ + job_buttons [n_buttons - 1].xpos = +- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7; ++ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7; + + i18n_flag = 1; + } +@@ -1029,7 +1091,7 @@ + + while (i--) + { +- l1 = strlen (labs [i] = _(labs [i])); ++ l1 = mbstrlen (labs [i] = _(labs [i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -1039,7 +1101,7 @@ + + for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; ) + { +- l1 += strlen (buts [i] = _(buts [i])); ++ l1 += mbstrlen (buts [i] = _(buts [i])); + } + l1 += 15; + if (l1 > dialog_x) +@@ -1048,7 +1110,7 @@ + ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */ + istart = dialog_x - 3 - ilen; + +- b2 = dialog_x - (strlen(buts[1]) + 6); ++ b2 = dialog_x - (mbstrlen(buts[1]) + 6); + + i18n_flag = 1; + } +diff -urN mc-4.6.1.orig/src/charsets.c mc-4.6.1/src/charsets.c +--- mc-4.6.1.orig/src/charsets.c 2005-07-23 22:52:02.000000000 +0600 ++++ mc-4.6.1/src/charsets.c 2007-01-19 18:33:59.000000000 +0500 +@@ -119,8 +119,6 @@ + } + } + +-#define OTHER_8BIT "Other_8_bit" +- + const char * + get_codepage_id (int n) + { +@@ -139,7 +137,7 @@ + return -1; + } + +-static char ++char + translate_character (iconv_t cd, char c) + { + char outbuf[4], *obuf; +diff -urN mc-4.6.1.orig/src/charsets.h mc-4.6.1/src/charsets.h +--- mc-4.6.1.orig/src/charsets.h 2004-08-30 16:38:00.000000000 +0600 ++++ mc-4.6.1/src/charsets.h 2007-01-19 18:33:59.000000000 +0500 +@@ -6,6 +6,7 @@ + #define UNKNCHAR '\001' + + #define CHARSETS_INDEX "mc.charsets" ++#define OTHER_8BIT "Other_8_bit" + + extern int n_codepages; + +@@ -19,6 +20,10 @@ + + extern struct codepage_desc *codepages; + ++#include ++extern char translate_character(iconv_t cd, char c); ++extern char errbuf[255]; ++ + const char *get_codepage_id (int n); + int get_codepage_index (const char *id); + int load_codepages_list (void); +diff -urN mc-4.6.1.orig/src/cmd.c mc-4.6.1/src/cmd.c +--- mc-4.6.1.orig/src/cmd.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/cmd.c 2007-01-19 18:33:59.000000000 +0500 +@@ -74,6 +74,10 @@ + # include "../edit/edit.h" + #endif + ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif ++ + /* If set and you don't have subshell support,then C-o will give you a shell */ + int output_starts_shell = 0; + +@@ -350,6 +354,9 @@ + { + char *tempdir; + char *dir; ++#ifdef HAVE_CHARSET ++ char *recoded_dir; ++#endif + + dir = + input_expand_dialog (_("Create a new Directory"), +@@ -360,8 +367,17 @@ + + if (dir[0] == '/' || dir[0] == '~') + tempdir = g_strdup (dir); +- else +- tempdir = concat_dir_and_file (current_panel->cwd, dir); ++ else { ++#ifdef HAVE_CHARSET ++ recoded_dir=g_strdup(dir); ++ my_translate_string(dir,strlen(dir), recoded_dir,current_panel->tr_table_input); ++ tempdir = concat_dir_and_file (current_panel->cwd, recoded_dir); ++ g_free(recoded_dir); ++#else ++ tempdir = concat_dir_and_file (current_panel->cwd, dir); ++#endif ++ } ++ + g_free (dir); + + save_cwds_stat (); +diff -urN mc-4.6.1.orig/src/dialog.c mc-4.6.1/src/dialog.c +--- mc-4.6.1.orig/src/dialog.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/dialog.c 2007-01-19 18:33:58.000000000 +0500 +@@ -162,7 +162,7 @@ + + if (h->title) { + attrset (HOT_NORMALC); +- dlg_move (h, space, (h->cols - strlen (h->title)) / 2); ++ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); + addstr (h->title); + } + } +diff -urN mc-4.6.1.orig/src/file.c mc-4.6.1/src/file.c +--- mc-4.6.1.orig/src/file.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/file.c 2007-01-19 18:33:59.000000000 +0500 +@@ -77,6 +77,9 @@ + #include "../vfs/vfs-impl.h" + + /* }}} */ ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif + + int verbose = 1; + +@@ -165,15 +168,20 @@ + do_transform_source (FileOpContext *ctx, const unsigned char *source) + { + size_t j, k, l, len; +- unsigned const char *fnsource = x_basename (source); ++ unsigned const char *fnsource = g_strdup (x_basename (source)); + int next_reg; + enum CaseConvs case_conv = NO_CONV; + static unsigned char fntarget[MC_MAXPATHLEN]; + ++#ifdef UTF8 ++ fix_utf8(fnsource); ++#endif ++ + len = strlen (fnsource); + j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); + if (j != len) { + transform_error = FILE_SKIP; ++ g_free(fnsource); + return NULL; + } + for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { +@@ -217,6 +225,7 @@ + || ctx->regs.start[next_reg] < 0) { + message (1, MSG_ERROR, _(" Invalid target mask ")); + transform_error = FILE_ABORT; ++ g_free(fnsource); + return NULL; + } + for (l = (size_t) ctx->regs.start[next_reg]; +@@ -231,6 +240,7 @@ + } + } + fntarget[k] = 0; ++ g_free(fnsource); + return fntarget; + } + +@@ -380,9 +390,9 @@ + char *p, *q, *s; + + const char *r = strrchr (src_path, PATH_SEP); +- ++ + if (r) { +- p = g_strndup (src_path, r - src_path); ++ p = g_strndup (src_path, r - src_path + 1); + if (*dst_path == PATH_SEP) + q = g_strdup (dst_path); + else +@@ -914,7 +924,11 @@ + } + /* Dive into subdir if exists */ + if (toplevel && ctx->dive_into_subdirs) { +- dest_dir = concat_dir_and_file (d, x_basename (s)); ++#ifdef HAVE_CHARSET ++ dest_dir = concat_dir_and_recoded_fname(d, x_basename (s), ctx); ++#else ++ dest_dir = concat_dir_and_file (d, x_basename (s)); ++#endif + } else { + dest_dir = g_strdup (d); + goto dont_mkdir; +@@ -964,7 +978,11 @@ + + (*ctx->stat_func) (path, &buf); + if (S_ISDIR (buf.st_mode)) { +- mdpath = concat_dir_and_file (dest_dir, next->d_name); ++#ifdef HAVE_CHARSET ++ mdpath = concat_dir_and_recoded_fname(dest_dir, next->d_name, ctx); ++#else ++ mdpath = concat_dir_and_file (dest_dir, next->d_name); ++#endif + /* + * From here, we just intend to recursively copy subdirs, not + * the double functionality of copying different when the target +@@ -975,7 +993,11 @@ + parent_dirs, progress_count, progress_bytes); + g_free (mdpath); + } else { +- dest_file = concat_dir_and_file (dest_dir, x_basename (path)); ++#ifdef HAVE_CHARSET ++ dest_file=concat_dir_and_recoded_fname(dest_dir, x_basename(path),ctx); ++#else ++ dest_file = concat_dir_and_file (dest_dir, x_basename (path)); ++#endif + return_status = copy_file_file (ctx, path, dest_file, 1, + progress_count, progress_bytes, 0); + g_free (dest_file); +@@ -1159,7 +1181,12 @@ + destdir = g_strdup (d); + move_over = 1; + } else +- destdir = concat_dir_and_file (d, x_basename (s)); ++#ifdef HAVE_CHARSET ++ destdir = concat_dir_and_recoded_fname(d, x_basename (s), ctx); ++#else ++ destdir = concat_dir_and_file (d, x_basename (s)); ++#endif ++ + + if (sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino) { + int msize = COLS - 36; +@@ -1875,7 +1902,12 @@ + if (temp == NULL) { + value = transform_error; + } else { +- char *temp2 = concat_dir_and_file (dest, temp); ++#ifdef HAVE_CHARSET ++ char *temp2 = concat_dir_and_recoded_fname (dest, temp, ctx); ++#else ++ char *temp2 = concat_dir_and_file (dest, temp); ++#endif ++ + g_free (dest); + dest = temp2; + temp = NULL; +@@ -1969,7 +2001,12 @@ + if (temp == NULL) + value = transform_error; + else { +- char *temp2 = concat_dir_and_file (dest, temp); ++#ifdef HAVE_CHARSET ++ char *temp2 = concat_dir_and_recoded_fname(dest, temp, ctx); ++#else ++ char *temp2 = concat_dir_and_file (dest, temp); ++#endif ++ + + switch (operation) { + case OP_COPY: +diff -urN mc-4.6.1.orig/src/filegui.c mc-4.6.1/src/filegui.c +--- mc-4.6.1.orig/src/filegui.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/filegui.c 2007-01-19 18:33:59.000000000 +0500 +@@ -69,6 +69,11 @@ + #include "filegui.h" + #include "key.h" /* get_event */ + #include "util.h" /* strip_password() */ ++#include "tty.h" ++ ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif + + /* }}} */ + +@@ -564,8 +569,8 @@ + * longest of "Overwrite..." labels + * (assume "Target date..." are short enough) + */ +- l1 = max (strlen (rd_widgets[6].text), +- strlen (rd_widgets[11].text)); ++ l1 = max (mbstrlen (rd_widgets[6].text), ++ mbstrlen (rd_widgets[11].text)); + + /* longest of button rows */ + i = sizeof (rd_widgets) / sizeof (rd_widgets[0]); +@@ -576,7 +581,7 @@ + l2 = max (l2, l); + l = 0; + } +- l += strlen (rd_widgets[i].text) + 4; ++ l += mbstrlen (rd_widgets[i].text) + 4; + } + } + l2 = max (l2, l); /* last row */ +@@ -594,12 +599,12 @@ + l = l1; + } + rd_widgets[i].xpos = l; +- l += strlen (rd_widgets[i].text) + 4; ++ l += mbstrlen (rd_widgets[i].text) + 4; + } + } + /* Abort button is centered */ + rd_widgets[1].xpos = +- (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2; ++ (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2; + } + #endif /* ENABLE_NLS */ + +@@ -618,7 +623,7 @@ + + ADD_RD_LABEL (ui, 0, + name_trunc (ui->replace_filename, +- rd_trunc - strlen (rd_widgets[0].text)), 0); ++ rd_trunc - mbstrlen (rd_widgets[0].text)), 0); + ADD_RD_BUTTON (1); + + ADD_RD_BUTTON (2); +@@ -721,57 +726,79 @@ + } + } + ++#ifdef HAVE_CHARSET ++#define FMDY 15 ++#else + #define FMDY 13 ++#endif ++ + #define FMD_XLEN 64 + extern int fmd_xlen; + static QuickWidget fmd_widgets[] = { + +-#define FMCB0 FMDC +-#define FMCB12 0 +-#define FMCB11 1 +- /* follow symlinks and preserve Attributes must be the first */ +- {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"), 9, 0, +- 0 /* &op_preserve */ , 0, "preserve"}, +- {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"), 7, 0, +- 0 /* &file_mask_op_follow_links */ , 0, "follow"}, +- {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, "to"}, +- {quick_checkbox, 37, 64, 4, FMDY, N_("&Using shell patterns"), 0, 0, +- 0 /* &source_easy_patterns */ , 0, "using-shell"}, +- {quick_input, 3, 64, 3, FMDY, "", 58, +- 0, 0, 0, "input-def"}, +-#define FMDI1 4 +-#define FMDI2 5 +-#define FMDC 3 +- {quick_input, 3, 64, 6, FMDY, "", 58, 0, +- 0, 0, "input2"}, +-#define FMDI0 6 +- {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, "ql"}, +-#define FMBRGT 7 +- {quick_button, 42, 64, 9, FMDY, N_("&Cancel"), 0, B_CANCEL, 0, 0, +- "cancel"}, +-#undef SKIP ++#ifdef HAVE_CHARSET ++ #define Y_OK 12 ++#else ++ #define Y_OK 9 ++#endif ++ ++#ifdef WITH_BACKGROUND ++ #define ADD 0 ++#else ++ #define ADD -1 ++#endif ++ ++ #define FM_STAB_SYM 0 ++ #define FM_DIVE_INTO_SUBDIR 1 ++ #define FM_PRES_ATTR 2 ++ #define FM_FOLLOW_LINKS 3 ++ #define FM_DST_INPUT 4 ++ #define FM_DST_TITLE 5 ++ #define FM_USING_SHELL_PATT 6 ++ #define FM_SRC_INPUT 7 ++ #define FM_SRC_TITLE 8 ++ #define FM_CANCEL 9 ++#ifdef WITH_BACKGROUND ++ #define FM_BKGND 10 ++#endif ++ #define FM_OK 11+ADD ++#ifdef HAVE_CHARSET ++ #define FM_TO_CODEPAGE 12+ADD ++ #define FM_FROM_CODEPAGE 13+ADD ++ #define FM_RECODE_TITLE 14+ADD ++ #define FM_RECODE_ARROW 15+ADD ++#endif // HAVE_CHARSET ++ ++ ++#ifdef HAVE_CHARSET ++ #define SKIP 10 ++ #define B_FROM B_USER+1 ++ #define B_TO B_USER+2 ++#else ++ #define SKIP 10 ++#endif ++ ++ {quick_checkbox, 42,64, 8, FMDY, N_("&Stable Symlinks"),0,0,0,0,"stab-sym"}, ++ {quick_checkbox, 31,64, 7, FMDY, N_("&Dive into subdir if exists"),0,0,0,0,"dive"}, ++ {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"),9,0,0,0,"preserve"}, ++ {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"),7,0,0,0,"follow"}, ++ {quick_input, 3, 64, 6, FMDY, "", 58, 0, 0, 0, "input2"}, ++ {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, "to"}, ++ {quick_checkbox, 37,64, 4, FMDY, N_("&Using shell patterns"),0,0, 0,0,"us-sh"}, ++ {quick_input, 3, 64, 3, FMDY, "", 58, 0, 0, 0, "input-def"}, ++ {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, "ql"}, ++ {quick_button, 42,64, Y_OK, FMDY, N_("&Cancel"), 0, B_CANCEL, 0,0, "cancel"}, + #ifdef WITH_BACKGROUND +-# define SKIP 5 +-# define FMCB21 11 +-# define FMCB22 10 +-# define FMBLFT 9 +-# define FMBMID 8 +- {quick_button, 25, 64, 9, FMDY, N_("&Background"), 0, B_USER, 0, 0, +- "back"}, +-#else /* WITH_BACKGROUND */ +-# define SKIP 4 +-# define FMCB21 10 +-# define FMCB22 9 +-# define FMBLFT 8 +-# undef FMBMID +-#endif +- {quick_button, 14, 64, 9, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, "ok"}, +- {quick_checkbox, 42, 64, 8, FMDY, N_("&Stable Symlinks"), 0, 0, +- 0 /* &file_mask_stable_symlinks */ , 0, "stab-sym"}, +- {quick_checkbox, 31, 64, 7, FMDY, N_("&Dive into subdir if exists"), 0, +- 0, +- 0 /* &dive_into_subdirs */ , 0, "dive"}, +- NULL_QuickWidget ++ {quick_button, 25,64, Y_OK, FMDY, N_("&Background"), 0, B_USER, 0,0, "back"}, ++#endif ++ {quick_button, 14,64, Y_OK, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, "ok"}, ++#ifdef HAVE_CHARSET ++ {quick_button, 46,64, 10, FMDY,"to codepage", 0, B_TO, 0, 0, "ql"}, ++ {quick_button, 25,64, 10, FMDY, "from codepage", 0, B_FROM, 0, 0, "ql"}, ++ {quick_label, 3, 64, 10, FMDY, N_("Recode file names:"), 0, 0, 0, 0, "ql"}, ++ {quick_label, 42,64, 10, FMDY, "->", 0, 0, 0, 0, "ql"}, ++#endif ++ {0} + }; + + static int +@@ -805,48 +832,48 @@ + if (fmd_widgets[i].text[0] != '\0') + fmd_widgets[i].text = _(fmd_widgets[i].text); + +- len = strlen (fmd_widgets[FMCB11].text) +- + strlen (fmd_widgets[FMCB21].text) + 15; ++ len = mbstrlen (fmd_widgets[FM_FOLLOW_LINKS].text) ++ + mbstrlen (fmd_widgets[FM_DIVE_INTO_SUBDIR].text) + 15; + fmd_xlen = max (fmd_xlen, len); + +- len = strlen (fmd_widgets[FMCB12].text) +- + strlen (fmd_widgets[FMCB22].text) + 15; ++ len = mbstrlen (fmd_widgets[FM_PRES_ATTR].text) ++ + mbstrlen (fmd_widgets[FM_STAB_SYM].text) + 15; + fmd_xlen = max (fmd_xlen, len); + +- len = strlen (fmd_widgets[FMBRGT].text) +- + strlen (fmd_widgets[FMBLFT].text) + 11; ++ len = mbstrlen (fmd_widgets[FM_CANCEL].text) ++ + mbstrlen (fmd_widgets[FM_OK].text) + 11; + +-#ifdef FMBMID +- len += strlen (fmd_widgets[FMBMID].text) + 6; ++#ifdef FM_BKGND ++ len += mbstrlen (fmd_widgets[FM_BKGND].text) + 6; + #endif + + fmd_xlen = max (fmd_xlen, len + 4); + + len = (fmd_xlen - (len + 6)) / 2; +- i = fmd_widgets[FMBLFT].relative_x = len + 3; +- i += strlen (fmd_widgets[FMBLFT].text) + 8; ++ i = fmd_widgets[FM_OK].relative_x = len + 3; ++ i += mbstrlen (fmd_widgets[FM_OK].text) + 8; + +-#ifdef FMBMID +- fmd_widgets[FMBMID].relative_x = i; +- i += strlen (fmd_widgets[FMBMID].text) + 6; ++#ifdef FM_BKGND ++ fmd_widgets[FM_BKGND].relative_x = i; ++ i += mbstrlen (fmd_widgets[FM_BKGND].text) + 6; + #endif + +- fmd_widgets[FMBRGT].relative_x = i; ++ fmd_widgets[FM_CANCEL].relative_x = i; + + #define chkbox_xpos(i) \ +- fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6 ++ fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6 + +- chkbox_xpos (FMCB0); +- chkbox_xpos (FMCB21); +- chkbox_xpos (FMCB22); ++ chkbox_xpos (FM_USING_SHELL_PATT); ++ chkbox_xpos (FM_DIVE_INTO_SUBDIR); ++ chkbox_xpos (FM_STAB_SYM); + + if (fmd_xlen != FMD_XLEN) { + i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]) - 1; + while (i--) + fmd_widgets[i].x_divisions = fmd_xlen; + +- fmd_widgets[FMDI1].hotkey_pos = +- fmd_widgets[FMDI2].hotkey_pos = fmd_xlen - 6; ++ fmd_widgets[FM_SRC_INPUT].hotkey_pos = ++ fmd_widgets[FM_DST_INPUT].hotkey_pos = fmd_xlen - 6; + } + #undef chkbox_xpos + +@@ -856,7 +883,7 @@ + + char * + file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, +- const char *def_text, int only_one, int *do_background) ++ const char *def_text_orig, int only_one, int *do_background) + { + int source_easy_patterns = easy_patterns; + char *source_mask, *orig_mask, *dest_dir, *tmpdest; +@@ -865,20 +892,32 @@ + struct stat buf; + int val; + QuickDialog Quick_input; +- ++ char *def_text; ++#ifdef HAVE_CHARSET ++ char *errmsg; ++#endif + g_return_val_if_fail (ctx != NULL, NULL); ++ ++ def_text = g_strdup(def_text_orig); ++ + #if 0 + message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text, + def_text); + #endif ++ ++#ifdef UTF8 ++ fix_utf8(def_text); ++#endif ++ + fmd_init_i18n (FALSE); + + /* Set up the result pointers */ + +- fmd_widgets[FMCB12].result = &ctx->op_preserve; +- fmd_widgets[FMCB11].result = &ctx->follow_links; +- fmd_widgets[FMCB22].result = &ctx->stable_symlinks; +- fmd_widgets[FMCB21].result = &ctx->dive_into_subdirs; ++ fmd_widgets[FM_PRES_ATTR].result = &ctx->op_preserve; ++ fmd_widgets[FM_FOLLOW_LINKS].result = &ctx->follow_links; ++ fmd_widgets[FM_STAB_SYM].result = &ctx->stable_symlinks; ++ fmd_widgets[FM_DIVE_INTO_SUBDIR].result = &ctx->dive_into_subdirs; ++ + + /* filter out a possible password from def_text */ + def_text_secure = strip_password (g_strdup (def_text), 1); +@@ -886,8 +925,9 @@ + /* Create the dialog */ + + ctx->stable_symlinks = 0; +- fmd_widgets[FMDC].result = &source_easy_patterns; +- fmd_widgets[FMDI1].text = easy_patterns ? "*" : "^\\(.*\\)$"; ++ fmd_widgets[FM_USING_SHELL_PATT].result = &source_easy_patterns; ++ fmd_widgets[FM_SRC_INPUT].text = easy_patterns ? "*" : "^\\(.*\\)$"; ++ + Quick_input.xlen = fmd_xlen; + Quick_input.xpos = -1; + Quick_input.title = op_names[operation]; +@@ -895,19 +935,34 @@ + Quick_input.ylen = FMDY; + Quick_input.i18n = 1; + Quick_input.widgets = fmd_widgets; +- fmd_widgets[FMDI0].text = text; +- fmd_widgets[FMDI2].text = def_text_secure; +- fmd_widgets[FMDI2].str_result = &dest_dir; +- fmd_widgets[FMDI1].str_result = &source_mask; ++ fmd_widgets[FM_SRC_TITLE].text = text; ++ fmd_widgets[FM_DST_INPUT].text = def_text_secure; ++ fmd_widgets[FM_DST_INPUT].str_result = &dest_dir; ++ fmd_widgets[FM_SRC_INPUT].str_result = &source_mask; + + *do_background = 0; ++ ++#ifdef HAVE_CHARSET ++ ctx->from_codepage=current_panel->src_codepage; ++ ctx->to_codepage=left_panel->src_codepage; ++ if(current_panel==left_panel) ctx->to_codepage=right_panel->src_codepage; ++#endif ++ + ask_file_mask: + ++#ifdef HAVE_CHARSET ++ if(operation!=OP_COPY && operation!=OP_MOVE) { ++ ctx->from_codepage=-1; ++ ctx->to_codepage=-1; ++ } ++ fmd_widgets[FM_FROM_CODEPAGE].text=get_codepage_id(ctx->from_codepage); ++ fmd_widgets[FM_TO_CODEPAGE].text=get_codepage_id(ctx->to_codepage); ++#endif ++ + if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) { + g_free (def_text_secure); + return 0; + } +- g_free (def_text_secure); + + if (ctx->follow_links) + ctx->stat_func = (mc_stat_fn) mc_stat; +@@ -929,6 +984,8 @@ + orig_mask = source_mask; + if (!dest_dir || !*dest_dir) { + g_free (source_mask); ++ g_free (def_text_secure); ++ g_free(def_text); + return dest_dir; + } + if (source_easy_patterns) { +@@ -982,5 +1039,48 @@ + } + if (val == B_USER) + *do_background = 1; ++#ifdef HAVE_CHARSET ++ if(val == B_FROM) { ++ if(operation==OP_COPY || operation==OP_MOVE) { ++ if(display_codepage<=0) { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ goto ask_file_mask; ++ } ++ ctx->from_codepage=select_charset(ctx->from_codepage,0, ++ _(" Choose \"FROM\" codepage for COPY/MOVE operaion ")); ++ } ++ else ++ message(1,"Warning",_("Recoding works only with COPY or MOVE operation")); ++ goto ask_file_mask; ++ } ++ if(val == B_TO) { ++ if(operation==OP_COPY || operation==OP_MOVE) { ++ if(display_codepage<=0) { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ goto ask_file_mask; ++ } ++ ctx->to_codepage=select_charset(ctx->to_codepage,0, ++ _(" Choose \"TO\" codepage for COPY/MOVE operaion ")); ++ } ++ else ++ message(1,"Warning",_("Recoding works only with COPY or MOVE operation")); ++ goto ask_file_mask; ++ } ++ ++ errmsg=my_init_tt(ctx->to_codepage,ctx->from_codepage,ctx->tr_table); ++ if(errmsg) { ++ my_reset_tt(ctx->tr_table,256); ++ message( 1, MSG_ERROR, "%s", errmsg); ++ } ++#endif ++ ++ g_free(def_text_secure); ++ g_free(def_text); + return dest_dir; + } +diff -urN mc-4.6.1.orig/src/fileopctx.c mc-4.6.1/src/fileopctx.c +--- mc-4.6.1.orig/src/fileopctx.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/fileopctx.c 2007-01-19 18:33:59.000000000 +0500 +@@ -24,8 +24,12 @@ + #include + + #include "global.h" +-#include "fileopctx.h" + ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif ++ ++#include "fileopctx.h" + + /** + * file_op_context_new: +@@ -52,6 +56,12 @@ + ctx->umask_kill = 0777777; + ctx->erase_at_end = TRUE; + ++#ifdef HAVE_CHARSET ++ ctx->from_codepage=-1; ++ ctx->to_codepage=-1; ++ my_reset_tt(ctx->tr_table,256); ++#endif ++ + return ctx; + } + +diff -urN mc-4.6.1.orig/src/fileopctx.h mc-4.6.1/src/fileopctx.h +--- mc-4.6.1.orig/src/fileopctx.h 2004-10-07 00:06:26.000000000 +0600 ++++ mc-4.6.1/src/fileopctx.h 2007-01-19 18:33:59.000000000 +0500 +@@ -108,6 +108,14 @@ + /* User interface data goes here */ + + void *ui; ++ ++#ifdef HAVE_CHARSET ++ /* Recode data */ ++ int from_codepage, to_codepage; ++ unsigned char tr_table[256]; ++ unsigned char recode_buf[MC_MAXPATHLEN]; ++#endif ++ + } FileOpContext; + + +diff -urN mc-4.6.1.orig/src/find.c mc-4.6.1/src/find.c +--- mc-4.6.1.orig/src/find.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/find.c 2007-01-19 18:33:58.000000000 +0500 +@@ -205,7 +205,7 @@ + int l1, maxlen = 0; + + while (i--) { +- l1 = strlen (labs[i] = _(labs[i])); ++ l1 = mbstrlen (labs[i] = _(labs[i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -214,7 +214,7 @@ + FIND_X = i; + + for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) { +- l1 += strlen (buts[i] = _(buts[i])); ++ l1 += mbstrlen (buts[i] = _(buts[i])); + } + l1 += 21; + if (l1 > FIND_X) +@@ -223,8 +223,8 @@ + ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */ + istart = FIND_X - 3 - ilen; + +- b1 = b0 + strlen (buts[0]) + 7; +- b2 = FIND_X - (strlen (buts[2]) + 6); ++ b1 = b0 + mbstrlen (buts[0]) + 7; ++ b2 = FIND_X - (mbstrlen (buts[2]) + 6); + + i18n_flag = 1; + case_label = _(case_label); +@@ -813,7 +813,7 @@ + if (!i18n_flag) { + register int i = sizeof (fbuts) / sizeof (fbuts[0]); + while (i--) +- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3; ++ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3; + fbuts[2].len += 2; /* DEFPUSH_BUTTON */ + i18n_flag = 1; + } +diff -urN mc-4.6.1.orig/src/global.h mc-4.6.1/src/global.h +--- mc-4.6.1.orig/src/global.h 2004-09-25 19:46:23.000000000 +0600 ++++ mc-4.6.1/src/global.h 2007-01-19 18:33:58.000000000 +0500 +@@ -146,6 +146,13 @@ + # define N_(String) (String) + #endif /* !ENABLE_NLS */ + ++#include ++#if SLANG_VERSION >= 20000 ++#define UTF8 1 ++#define SLsmg_Is_Unicode SLsmg_is_utf8_mode() ++void SLsmg_write_nwchars(wchar_t *s, size_t n); ++#endif ++ + #include "fs.h" + #include "util.h" + +diff -urN mc-4.6.1.orig/src/help.c mc-4.6.1/src/help.c +--- mc-4.6.1.orig/src/help.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/help.c 2007-01-19 18:33:59.000000000 +0500 +@@ -445,10 +445,28 @@ + #ifndef HAVE_SLANG + addch (acs_map [c]); + #else ++#if defined(UTF8) && SLANG_VERSION < 20000 ++ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]); ++#else + SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c); ++#endif /* UTF8 */ + #endif ++ } else { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ int len; ++ mbstate_t mbs; ++ wchar_t wc; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs); ++ if (len <= 0) len = 1; /* skip broken multibyte chars */ ++ ++ SLsmg_write_nwchars(&wc, 1); ++ p += len - 1; + } else ++#endif + addch (c); ++ } + col++; + break; + } +@@ -771,6 +789,12 @@ + message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile, + unix_error_string (errno)); + } ++ else ++ { ++ char *conv = utf8_to_local(data); ++ g_free(data); ++ data = conv; ++ } + + if (!filename) + g_free (hlpfile); +diff -urN mc-4.6.1.orig/src/hotlist.c mc-4.6.1/src/hotlist.c +--- mc-4.6.1.orig/src/hotlist.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/hotlist.c 2007-01-19 18:33:58.000000000 +0500 +@@ -555,7 +555,7 @@ + + row = hotlist_but [i].y; + ++count [row]; +- len [row] += strlen (hotlist_but [i].text) + 5; ++ len [row] += mbstrlen (hotlist_but [i].text) + 5; + if (hotlist_but [i].flags == DEFPUSH_BUTTON) + len [row] += 2; + } +@@ -580,12 +580,12 @@ + /* not first int the row */ + if (!strcmp (hotlist_but [i].text, cancel_but)) + hotlist_but [i].x = +- cols - strlen (hotlist_but [i].text) - 13; ++ cols - mbstrlen (hotlist_but [i].text) - 13; + else + hotlist_but [i].x = cur_x [row]; + } + +- cur_x [row] += strlen (hotlist_but [i].text) + 2 ++ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2 + + (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3); + } + } +@@ -814,7 +814,7 @@ + for (i = 0; i < 3; i++) + { + qw [i].text = _(qw [i].text); +- l[i] = strlen (qw [i].text) + 3; ++ l[i] = mbstrlen (qw [i].text) + 3; + } + space = (len - 4 - l[0] - l[1] - l[2]) / 4; + +@@ -860,7 +860,7 @@ + static int i18n_flag = 0; + #endif /* ENABLE_NLS */ + +- len = max (strlen (header), (size_t) msglen (text1, &lines1)); ++ len = max ((int) mbstrlen (header), (size_t) msglen (text1, &lines1)); + len = max (len, (size_t) msglen (text2, &lines2)) + 4; + len = max (len, 64); + +@@ -955,7 +955,7 @@ + static int i18n_flag = 0; + #endif /* ENABLE_NLS */ + +- len = max (strlen (header), (size_t) msglen (label, &lines)) + 4; ++ len = max ((int) mbstrlen (header), (size_t) msglen (label, &lines)) + 4; + len = max (len, 64); + + #ifdef ENABLE_NLS +@@ -1011,7 +1011,7 @@ + { + char *prompt, *label; + const char *cp = _("Label for \"%s\":"); +- int l = strlen (cp); ++ int l = mbstrlen (cp); + char *label_string = g_strdup (current_panel->cwd); + + strip_password (label_string, 1); +diff -urN mc-4.6.1.orig/src/layout.c mc-4.6.1/src/layout.c +--- mc-4.6.1.orig/src/layout.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/layout.c 2007-01-19 18:33:58.000000000 +0500 +@@ -362,36 +362,36 @@ + + while (i--) { + s_split_direction[i] = _(s_split_direction[i]); +- l1 = strlen (s_split_direction[i]) + 7; ++ l1 = mbstrlen (s_split_direction[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + + for (i = 0; i <= 8; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title1) + 1; ++ l1 = mbstrlen (title1) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + + +- second_width = strlen (title3) + 1; ++ second_width = mbstrlen (title3) + 1; + for (i = 0; i < 6; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > second_width) + second_width = l1; + } + if (console_flag) { +- l1 = strlen (output_lines_label) + 13; ++ l1 = mbstrlen (output_lines_label) + 13; + if (l1 > second_width) + second_width = l1; + } +@@ -405,14 +405,14 @@ + * + * Now the last thing to do - properly space buttons... + */ +- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */ +- +strlen (save_button) /* notice: it is 3 char less because */ +- +strlen (cancel_button); /* of '&' char in button text */ ++ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */ ++ +mbstrlen (save_button) /* notice: it is 3 char less because */ ++ +mbstrlen (cancel_button); /* of '&' char in button text */ + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_layt_flag = 1; + } +@@ -684,7 +684,7 @@ + panel_do_cols (0); + panel_do_cols (1); + +- promptl = strlen (prompt); ++ promptl = mbstrlen (prompt); + + widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); + +diff -urN mc-4.6.1.orig/src/learn.c mc-4.6.1/src/learn.c +--- mc-4.6.1.orig/src/learn.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/learn.c 2007-01-19 18:33:59.000000000 +0500 +@@ -236,7 +236,7 @@ + learn_but[0].x = 78 / 2 + 4; + + learn_but[1].text = _(learn_but[1].text); +- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9); ++ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9); + + learn_title = _(learn_title); + i18n_flag = 1; +diff -urN mc-4.6.1.orig/src/main.c mc-4.6.1/src/main.c +--- mc-4.6.1.orig/src/main.c 2005-07-23 22:52:02.000000000 +0600 ++++ mc-4.6.1/src/main.c 2007-01-19 18:33:59.000000000 +0500 +@@ -86,6 +86,7 @@ + + #ifdef HAVE_CHARSET + #include "charsets.h" ++#include "recode.h" + #endif /* HAVE_CHARSET */ + + #ifdef USE_VFS +@@ -102,6 +103,7 @@ + /* The structures for the panels */ + WPanel *left_panel = NULL; + WPanel *right_panel = NULL; ++WPanel* ret_panel=NULL; + + /* The pointer to the tree */ + WTree *the_tree = NULL; +@@ -274,6 +276,9 @@ + /* The user's shell */ + const char *shell = NULL; + ++/* Is the LANG UTF-8 ? */ ++gboolean is_utf8 = FALSE; ++ + /* mc_home: The home of MC */ + char *mc_home = NULL; + +@@ -585,6 +590,7 @@ + } + directory = *new_dir ? new_dir : home_dir; + ++ ret_panel=panel; + if (mc_chdir (directory) == -1) { + strcpy (panel->cwd, olddir); + g_free (olddir); +@@ -798,6 +804,10 @@ + {' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd}, + {' ', N_("&Info C-x i"), 'I', info_cmd}, + {' ', N_("&Tree"), 'T', tree_cmd}, ++#ifdef HAVE_CHARSET ++ {' ', "", ' ', 0}, ++ {' ', N_("Panel &codepage"), 'C', fnc_l_cmd}, ++#endif + {' ', "", ' ', 0}, + {' ', N_("&Sort order..."), 'S', sort_cmd}, + {' ', "", ' ', 0}, +@@ -822,6 +832,10 @@ + {' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd}, + {' ', N_("&Info C-x i"), 'I', info_cmd}, + {' ', N_("&Tree"), 'T', tree_cmd}, ++#ifdef HAVE_CHARSET ++ {' ', "", ' ', 0}, ++ {' ', N_("Panel &codepage"), 'C', fnc_r_cmd}, ++#endif + {' ', "", ' ', 0}, + {' ', N_("&Sort order..."), 'S', sort_cmd}, + {' ', "", ' ', 0}, +@@ -1600,21 +1614,49 @@ + + #define xtoolkit_panel_setup() + +-/* Show current directory in the xterm title */ ++/* Show hostname and current directory in the xterm title */ + void + update_xterm_title_path (void) + { + unsigned char *p, *s; ++ char *pvp; ++ size_t pvlen; ++ int pvresult; + + if (xterm_flag && xterm_title) { ++ // currrent path + p = s = g_strdup (strip_home_and_password (current_panel->cwd)); ++ // hostname ++ pvlen = strlen(p); ++ pvp = g_malloc (pvlen + 64); //approach - max hostname length ++ pvresult = gethostname(pvp, 63); ++ if (pvresult) { // print just current path ++ g_free (pvp); ++ pvp = p; ++ } else { ++ s = pvp; ++ do { // merge hostname with path ++ if (!is_printable (*s)) ++ *s = '?'; ++ } while (*++s!=0x00); ++ *s++=':'; ++ strcpy (s, p); ++ g_free (p); ++ } ++ + do { ++#ifndef UTF8 + if (!is_printable (*s)) ++#else /* UTF8 */ ++ if (*s < ' ') ++#endif /* UTF8 */ + *s = '?'; + } while (*++s); +- fprintf (stdout, "\33]0;mc - %s\7", p); ++// fprintf (stdout, "\33]0;mc - %s\7", p); ++ fprintf (stdout, "\33]0;mc - %s\7", pvp); + fflush (stdout); +- g_free (p); ++// g_free (p); ++ g_free (pvp); + } + } + +@@ -2136,6 +2178,16 @@ + /* if on, it displays the information that files have been moved to ~/.mc */ + int show_change_notice = 0; + ++ /* Check whether we have UTF-8 locale */ ++ char *lang = getenv("LANG"); ++ size_t len = 0; ++ ++ if ( lang ) ++ len = strlen(lang); ++ ++ if ( len >= 5 && !strcasecmp(&lang[len-5],"UTF-8") ) ++ is_utf8 = TRUE; ++ + /* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */ + setlocale (LC_ALL, ""); + bindtextdomain ("mc", LOCALEDIR); +diff -urN mc-4.6.1.orig/src/main.h mc-4.6.1/src/main.h +--- mc-4.6.1.orig/src/main.h 2005-07-01 21:47:06.000000000 +0600 ++++ mc-4.6.1/src/main.h 2007-01-19 18:33:59.000000000 +0500 +@@ -64,6 +64,7 @@ + extern int only_leading_plus_minus; + extern int output_starts_shell; + extern int midnight_shutdown; ++extern gboolean is_utf8; + extern char cmd_buf [512]; + extern const char *shell; + +diff -urN mc-4.6.1.orig/src/Makefile.am mc-4.6.1/src/Makefile.am +--- mc-4.6.1.orig/src/Makefile.am 2005-06-08 18:27:19.000000000 +0600 ++++ mc-4.6.1/src/Makefile.am 2007-01-19 18:33:59.000000000 +0500 +@@ -40,7 +40,8 @@ + mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \ + $(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV) + +-CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h ++CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h \ ++ recode.c recode.h + + SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \ + chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \ +@@ -55,8 +56,8 @@ + menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h \ + option.c option.h panel.h panelize.c panelize.h poptalloca.h \ + popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c \ +- profile.c profile.h regex.c rxvt.c screen.c setup.c setup.h \ +- slint.c subshell.c subshell.h textconf.c textconf.h \ ++ profile.c profile.h regex.c rxvt.c screen.c screen.h setup.c \ ++ setup.h slint.c subshell.c subshell.h textconf.c textconf.h \ + tree.c tree.h treestore.c treestore.h tty.h user.c user.h \ + util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \ + widget.h win.c win.h wtools.c wtools.h \ +diff -urN mc-4.6.1.orig/src/Makefile.in mc-4.6.1/src/Makefile.in +--- mc-4.6.1.orig/src/Makefile.in 2005-07-23 22:53:15.000000000 +0600 ++++ mc-4.6.1/src/Makefile.in 2007-01-19 18:33:59.000000000 +0500 +@@ -84,12 +84,12 @@ + mouse.c mouse.h myslang.h option.c option.h panel.h panelize.c \ + panelize.h poptalloca.h popt.c poptconfig.c popt.h popthelp.c \ + poptint.h poptparse.c profile.c profile.h regex.c rxvt.c \ +- screen.c setup.c setup.h slint.c subshell.c subshell.h \ ++ screen.c screen.h setup.c setup.h slint.c subshell.c subshell.h \ + textconf.c textconf.h tree.c tree.h treestore.c treestore.h \ + tty.h user.c user.h util.c util.h utilunix.c view.c view.h \ + vfsdummy.h widget.c widget.h win.c win.h wtools.c wtools.h \ + x11conn.h x11conn.c charsets.c charsets.h selcodepage.c \ +- selcodepage.h ++ selcodepage.h recode.c recode.h + am__objects_1 = achown.$(OBJEXT) background.$(OBJEXT) boxes.$(OBJEXT) \ + chmod.$(OBJEXT) chown.$(OBJEXT) cmd.$(OBJEXT) color.$(OBJEXT) \ + command.$(OBJEXT) complete.$(OBJEXT) cons.handler.$(OBJEXT) \ +@@ -109,7 +109,8 @@ + util.$(OBJEXT) utilunix.$(OBJEXT) view.$(OBJEXT) \ + widget.$(OBJEXT) win.$(OBJEXT) wtools.$(OBJEXT) \ + x11conn.$(OBJEXT) +-am__objects_2 = charsets.$(OBJEXT) selcodepage.$(OBJEXT) ++am__objects_2 = charsets.$(OBJEXT) selcodepage.$(OBJEXT) recode.$(OBJEXT) ++ + @CHARSET_FALSE@am_mc_OBJECTS = $(am__objects_1) + @CHARSET_TRUE@am_mc_OBJECTS = $(am__objects_1) $(am__objects_2) + mc_OBJECTS = $(am_mc_OBJECTS) +@@ -342,7 +343,8 @@ + mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \ + $(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV) + +-CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h ++CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h \ ++ recode.c recode.h + SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \ + chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \ + command.c command.h complete.c complete.h cons.handler.c \ +@@ -356,8 +358,8 @@ + menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h \ + option.c option.h panel.h panelize.c panelize.h poptalloca.h \ + popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c \ +- profile.c profile.h regex.c rxvt.c screen.c setup.c setup.h \ +- slint.c subshell.c subshell.h textconf.c textconf.h \ ++ profile.c profile.h regex.c rxvt.c screen.c screen.h setup.c \ ++ setup.h slint.c subshell.c subshell.h textconf.c textconf.h \ + tree.c tree.h treestore.c treestore.h tty.h user.c user.h \ + util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \ + widget.h win.c win.h wtools.c wtools.h \ +diff -urN mc-4.6.1.orig/src/menu.c mc-4.6.1/src/menu.c +--- mc-4.6.1.orig/src/menu.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/menu.c 2007-01-19 18:33:59.000000000 +0500 +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++ + #include "global.h" + #include "tty.h" + #include "menu.h" +@@ -50,33 +52,96 @@ + { + Menu *menu; + const char *cp; ++ int wlen = 0; ++ mbstate_t s; + + menu = (Menu *) g_malloc (sizeof (*menu)); + menu->count = count; + menu->max_entry_len = 20; + menu->entries = entries; ++ menu->name = g_strdup (name); ++ menu_scan_hotkey (menu); ++#ifdef UTF8 ++ menu->wentries = NULL; ++ menu->wname = NULL; ++ if (SLsmg_Is_Unicode) { ++ const char *str = menu->name; ++ memset (&s, 0, sizeof (s)); ++ wlen = mbsrtowcs (NULL, &str, -1, &s); ++ if (wlen > 0) ++ ++wlen; ++ else { ++ wlen = 0; ++ memset (&s, 0, sizeof (s)); ++ } ++ } ++#endif + + if (entries != (menu_entry*) NULL) { + register menu_entry* mp; + for (mp = entries; count--; mp++) { + if (mp->text[0] != '\0') { ++ int len; + #ifdef ENABLE_NLS + mp->text = _(mp->text); + #endif /* ENABLE_NLS */ + cp = strchr (mp->text,'&'); + ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ len = mbstrlen(mp->text) + 1; ++ wlen += len; ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); ++ } else ++#endif ++ len = strlen (mp->text); ++ + if (cp != NULL && *(cp+1) != '\0') { + mp->hot_key = tolower (*(cp+1)); +- menu->max_entry_len = max ((int) (strlen (mp->text) - 1), +- menu->max_entry_len); ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); + } else { +- menu->max_entry_len = max ((int) strlen (mp->text), +- menu->max_entry_len); ++ menu->max_entry_len = max (len, menu->max_entry_len); + } + } + } + } + ++#ifdef UTF8 ++ if (wlen) { ++ wchar_t *wp; ++ const char *str; ++ int len; ++ ++ menu->wentries = (wchar_t **) ++ g_malloc (sizeof (wchar_t *) * menu->count ++ + wlen * sizeof (wchar_t)); ++ wp = (wchar_t *) (menu->wentries + menu->count); ++ str = menu->name; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ menu->wname = wp; ++ wlen -= len + 1; ++ wp += len + 1; ++ } else ++ memset (&s, 0, sizeof (s)); ++ if (menu->entries != NULL) ++ for (count = 0; count < menu->count; ++count) ++ if (menu->entries[count].text[0] != '\0') { ++ str = menu->entries[count].text; ++ menu->wentries[count] = wp; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ wlen -= len + 1; ++ wp += len + 1; ++ } else { ++ memset (&s, 0, sizeof (s)); ++ *wp++ = L'\0'; ++ --wlen; ++ } ++ } ++ } ++#endif ++ + menu->name = g_strdup (name); + menu_scan_hotkey(menu); + menu->start_x = 0; +@@ -109,8 +174,26 @@ + const unsigned char *text; + + addch((unsigned char)menu->entries [idx].first_letter); +- for (text = menu->entries [idx].text; *text; text++) +- { ++#ifdef UTF8 ++ if (menu->wentries) { ++ wchar_t *wtext, *wp; ++ ++ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) { ++ if (*wtext == L'&') { ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ attrset (color == MENU_SELECTED_COLOR ? ++ MENU_HOTSEL_COLOR : MENU_HOT_COLOR); ++ SLsmg_write_nwchars (++wtext, 1); ++ attrset (color); ++ wp = wtext + 1; ++ } ++ } ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ } else ++#endif ++ for (text = menu->entries [idx].text; *text; text++) { + if (*text != '&') + addch(*text); + else { +@@ -119,7 +202,7 @@ + addch(*(++text)); + attrset(color); + } +- } ++ } + } + widget_move (&menubar->widget, y, x + 1); + } +@@ -167,7 +250,13 @@ + if (menubar->active) + attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); + widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); +- printw ("%s", menubar->menu [i]->name); ++#ifdef UTF8 ++ if (menubar->menu [i]->wname) ++ SLsmg_write_nwchars (menubar->menu [i]->wname, ++ wcslen (menubar->menu [i]->wname)); ++ else ++#endif ++ printw ("%s", menubar->menu [i]->name); + } + + if (menubar->dropped) +@@ -489,7 +578,13 @@ + + for (i = 0; i < items; i++) + { +- int len = strlen(menubar->menu[i]->name); ++ int len; ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ len = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ len = strlen(menubar->menu[i]->name); + menubar->menu[i]->start_x = start_x; + start_x += len + gap; + } +@@ -502,7 +597,13 @@ + for (i = 0; i < items; i++) + { + /* preserve length here, to be used below */ +- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name)); ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name); ++ gap -= menubar->menu[i]->start_x; + } + + gap /= (items - 1); +@@ -526,6 +627,9 @@ + void + destroy_menu (Menu *menu) + { ++#ifdef UTF8 ++ g_free (menu->wentries); ++#endif + g_free (menu->name); + g_free (menu->help_node); + g_free (menu); +diff -urN mc-4.6.1.orig/src/menu.h mc-4.6.1/src/menu.h +--- mc-4.6.1.orig/src/menu.h 2004-09-18 20:30:59.000000000 +0600 ++++ mc-4.6.1/src/menu.h 2007-01-19 18:33:59.000000000 +0500 +@@ -21,6 +21,8 @@ + menu_entry *entries; + int start_x; /* position relative to menubar start */ + char *help_node; ++ wchar_t **wentries; ++ wchar_t *wname; + } Menu; + + extern int menubar_visible; +diff -urN mc-4.6.1.orig/src/mountlist.c mc-4.6.1/src/mountlist.c +--- mc-4.6.1.orig/src/mountlist.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/mountlist.c 2007-01-19 18:33:59.000000000 +0500 +@@ -132,11 +132,19 @@ + + struct fs_usage + { ++#ifndef HAVE_SYS_STATVFS_H + long fsu_blocks; /* Total blocks. */ + long fsu_bfree; /* Free blocks available to superuser. */ + long fsu_bavail; /* Free blocks available to non-superuser. */ + long fsu_files; /* Total file nodes. */ + long fsu_ffree; /* Free file nodes. */ ++#else /* We have sys/statvfs.h, use proper data types when _FILE_OFFSET_BITS=64 */ ++ fsblkcnt_t fsu_blocks; ++ fsblkcnt_t fsu_bfree; ++ fsblkcnt_t fsu_bavail; ++ fsblkcnt_t fsu_files; ++ fsblkcnt_t fsu_ffree; ++#endif /* HAVE_SYS_STATVFS_H */ + }; + + static int get_fs_usage (char *path, struct fs_usage *fsp); +@@ -663,6 +671,7 @@ + BLOCKS FROMSIZE-byte blocks, rounding away from zero. + TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */ + ++#if !defined(HAVE_SYS_STATFS_H) || !defined(STAT_STATVFS) + static long + fs_adjust_blocks (long blocks, int fromsize, int tosize) + { +@@ -670,13 +679,21 @@ + abort (); + if (fromsize <= 0) + return -1; +- ++#else ++static fsblkcnt_t ++fs_adjust_blocks (fsblkcnt_t blocks, unsigned long fromsize, unsigned long tosize) ++{ ++ if (!tosize) ++ abort (); ++ if (!fromsize) ++ return -1; ++#endif + if (fromsize == tosize) /* E.g., from 512 to 512. */ + return blocks; + else if (fromsize > tosize) /* E.g., from 2048 to 512. */ + return blocks * (fromsize / tosize); + else /* E.g., from 256 to 512. */ +- return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); ++ return (blocks + 1) / (tosize / fromsize); + } + + #if defined(_AIX) && defined(_I386) +diff -urN mc-4.6.1.orig/src/myslang.h mc-4.6.1/src/myslang.h +--- mc-4.6.1.orig/src/myslang.h 2004-10-12 10:32:04.000000000 +0600 ++++ mc-4.6.1/src/myslang.h 2007-01-19 18:33:59.000000000 +0500 +@@ -11,6 +11,10 @@ + #endif /* HAVE_SLANG_SLANG_H */ + #endif + ++#ifdef UTF8 ++# include ++#endif ++ + enum { + KEY_BACKSPACE = 400, + KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, +diff -urN mc-4.6.1.orig/src/option.c mc-4.6.1/src/option.c +--- mc-4.6.1.orig/src/option.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/option.c 2007-01-19 18:33:59.000000000 +0500 +@@ -124,12 +124,12 @@ + title2 = _(" Pause after run... "); + title3 = _(" Other options "); + +- first_width = strlen (title1) + 1; +- second_width = strlen (title3) + 1; ++ first_width = mbstrlen (title1) + 1; ++ second_width = mbstrlen (title3) + 1; + + for (i = 0; check_options[i].text; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (i >= OTHER_OPTIONS) { + if (l1 > first_width) + first_width = l1; +@@ -142,23 +142,23 @@ + i = PAUSE_OPTIONS; + while (i--) { + pause_options[i] = _(pause_options[i]); +- l1 = strlen (pause_options[i]) + 7; ++ l1 = mbstrlen (pause_options[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = 11 + strlen (ok_button) +- + strlen (save_button) +- + strlen (cancel_button); ++ l1 = 11 + mbstrlen (ok_button) ++ + mbstrlen (save_button) ++ + mbstrlen (cancel_button); + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_config_flag = 1; + } +diff -urN mc-4.6.1.orig/src/panel.h mc-4.6.1/src/panel.h +--- mc-4.6.1.orig/src/panel.h 2004-08-29 22:55:51.000000000 +0600 ++++ mc-4.6.1/src/panel.h 2007-01-19 18:33:59.000000000 +0500 +@@ -71,6 +71,19 @@ + + int searching; + char search_buffer [256]; ++ ++#ifdef HAVE_CHARSET ++ int src_codepage; ++ unsigned char tr_table[256], tr_table_input[256]; ++#endif ++ ++#ifdef USE_VFS ++ #ifdef HAVE_CHARSET ++ int ret_codepage; ++ #endif ++ int is_return; ++ char retdir[MC_MAXPATHLEN]; ++#endif + } WPanel; + + WPanel *panel_new (const char *panel_name); +@@ -96,6 +109,7 @@ + extern WPanel *left_panel; + extern WPanel *right_panel; + extern WPanel *current_panel; ++extern WPanel* ret_panel; + + void try_to_select (WPanel *panel, const char *name); + +diff -urN mc-4.6.1.orig/src/panelize.c mc-4.6.1/src/panelize.c +--- mc-4.6.1.orig/src/panelize.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/panelize.c 2007-01-19 18:33:59.000000000 +0500 +@@ -127,7 +127,7 @@ + i = sizeof (panelize_but) / sizeof (panelize_but[0]); + while (i--) { + panelize_but[i].text = _(panelize_but[i].text); +- maxlen += strlen (panelize_but[i].text) + 5; ++ maxlen += mbstrlen (panelize_but[i].text) + 5; + } + maxlen += 10; + +@@ -136,11 +136,11 @@ + panelize_cols = max (panelize_cols, maxlen); + + panelize_but[2].x = +- panelize_but[3].x + strlen (panelize_but[3].text) + 7; ++ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7; + panelize_but[1].x = +- panelize_but[2].x + strlen (panelize_but[2].text) + 5; ++ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5; + panelize_but[0].x = +- panelize_cols - strlen (panelize_but[0].text) - 8 - BX; ++ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX; + + #endif /* ENABLE_NLS */ + +diff -urN mc-4.6.1.orig/src/recode.c mc-4.6.1/src/recode.c +--- mc-4.6.1.orig/src/recode.c 1970-01-01 05:00:00.000000000 +0500 ++++ mc-4.6.1/src/recode.c 2007-01-19 18:33:59.000000000 +0500 +@@ -0,0 +1,153 @@ ++#include "recode.h" ++#ifdef HAVE_CHARSET ++ ++char *lang; ++char lang_codepage_name[256]; ++int lang_codepage; ++ ++int ftp_codepage=-1; ++ ++// recode buffer for displaying file names ++unsigned char recode_buf[MC_MAXPATHLEN]; ++ ++WPanel* recode_panel; ++ ++//--- get codepage from $LANG ++void get_locale_codepage() { ++ char* a; ++ char* b; ++ int len; ++ ++ lang=getenv("LANG"); ++ if(!lang) { ++ strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); ++ lang_codepage=-1; ++ return; ++ } ++ ++ a=strchr(lang,'.'); ++ if(!a) { ++ strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); ++ lang_codepage=-1; ++ return; ++ } ++ ++a; ++ ++ b=strchr(lang,'@'); ++ if(!b) b=lang+strlen(lang); ++ ++ len=b-a; ++ if(len>=sizeof(lang_codepage_name)) len=sizeof(lang_codepage_name)-1; ++ ++ memcpy(lang_codepage_name,a, len); ++ lang_codepage_name[len]='\0'; ++ lang_codepage=get_codepage_index(lang_codepage_name); ++ if(lang_codepage<0) strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); ++} ++ ++//--- reset translation table ++void my_reset_tt(unsigned char *table,int n) { ++ int i; ++ for(i=0;isrc_codepage=-1; ++ my_reset_tt(p->tr_table,256); ++ my_reset_tt(p->tr_table_input,256); ++} ++ ++//--- Initialize translation table ++// i need this function because init_translation_table from ++// charsets.c fills only fixed translation tables conv_displ and conv_input ++//--- ++char* my_init_tt( int from, int to, unsigned char *table) { ++ int i; ++ iconv_t cd; ++ char *cpfrom, *cpto; ++ ++ if(from < 0 || to < 0 || from == to) { ++ my_reset_tt(table,256); ++ return NULL; ++ } ++ my_reset_tt(table,128); ++ cpfrom=codepages[from ].id; ++ cpto=codepages[to].id; ++ cd=iconv_open(cpfrom, cpto); ++ if(cd==(iconv_t)-1) { ++ snprintf(errbuf, 255, _("Cannot translate from %s to %s"), cpfrom, cpto); ++ return errbuf; ++ } ++ for(i=128; i<=255; ++i) table[i] = translate_character(cd, i); ++ iconv_close(cd); ++ return NULL; ++} ++ ++//--- Translate string from one codepage to another ++void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table) { ++ int i=0; ++ if(!s1) return; ++ while(irecode_buf,ctx->tr_table); ++ if (dir [i-1] == PATH_SEP) ++ return g_strconcat (dir, ctx->recode_buf, NULL); ++ else ++ return g_strconcat (dir, PATH_SEP_STR, ctx->recode_buf, NULL); ++ return 0; ++} ++ ++ ++//--- Internal handler for "Panel codepage" ++static void fnc_cmd(WPanel *p) { ++ char *errmsg; ++ if(display_codepage > 0) { ++ p->src_codepage=select_charset(p->src_codepage, 0, _(" Choose panel codepage ")); ++ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg); ++ } ++ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); ++ if (errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ paint_dir(p); ++ show_dir(p); ++ display_mini_info(p); ++ } ++ else { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ } ++} ++ ++//--- Menu handlers for "Panel codepage" for left and right panel menu ++ ++void fnc_l_cmd() { ++ fnc_cmd(left_panel); ++} ++ ++void fnc_r_cmd() { ++ fnc_cmd(right_panel); ++} ++ ++//--- screen handler for "Panel codepage" ++void fnc_c_cmd(WPanel *panel) { ++ fnc_cmd(current_panel); ++} ++ ++#endif //HAVE_CHARSET +diff -urN mc-4.6.1.orig/src/recode.h mc-4.6.1/src/recode.h +--- mc-4.6.1.orig/src/recode.h 1970-01-01 05:00:00.000000000 +0500 ++++ mc-4.6.1/src/recode.h 2007-01-19 18:33:59.000000000 +0500 +@@ -0,0 +1,48 @@ ++#ifndef __RECODE_H__ ++#define __RECODE_H__ ++#include ++#ifdef HAVE_CHARSET ++ ++#include ++#include ++#include ++ ++#include "global.h" ++#include "wtools.h" ++#include "panel.h" ++#include "charsets.h" ++#include "selcodepage.h" ++#include "screen.h" ++#include "main.h" ++#include "fileopctx.h" ++ ++extern char *lang; ++extern char lang_codepage_name[256]; ++extern int lang_codepage; ++ ++extern int ftp_codepage; ++ ++// recode buffer for displaying file names ++extern unsigned char recode_buf[MC_MAXPATHLEN]; ++extern WPanel* recode_panel; ++ ++//--- get codepage from $LANG ++extern void get_locale_codepage(); ++ ++//--- reset translation table ++extern void my_reset_tt(unsigned char *table,int n); ++//--- reset panel codepage ++extern void panel_reset_codepage(WPanel *p); ++//--- Initialize translation table ++extern char* my_init_tt( int from, int to, unsigned char *table); ++//--- Translate string from one codepage to another ++extern void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table); ++//--- Recode filename and concat in to dir ++extern char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx); ++//--- handlers for "Panel codepage" ++extern void fnc_l_cmd(); ++extern void fnc_r_cmd(); ++extern void fnc_c_cmd(WPanel *panel); ++ ++#endif // HAVE_CHARSET ++#endif //__RECODE_H__ +diff -urN mc-4.6.1.orig/src/screen.c mc-4.6.1/src/screen.c +--- mc-4.6.1.orig/src/screen.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/screen.c 2007-01-19 18:33:59.000000000 +0500 +@@ -48,6 +48,10 @@ + #define WANT_WIDGETS + #include "main.h" /* the_menubar */ + ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif ++ + #define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) ) + + #define J_LEFT 1 +@@ -169,22 +173,67 @@ + static const char * + string_file_name (file_entry *fe, int len) + { +- static char buffer [BUF_SMALL]; + size_t i; ++ char* filename; ++#ifdef UTF8 ++ static char buffer [BUF_SMALL * 4]; ++ mbstate_t s; ++ int mbmax = MB_CUR_MAX; ++ const char *str = fe->fname; + +- for (i = 0; i < sizeof(buffer) - 1; i++) { +- char c; ++ memset (&s, 0, sizeof (s)); ++#else ++ static char buffer [BUF_SMALL]; ++#endif + +- c = fe->fname[i]; ++#ifdef HAVE_CHARSET ++ my_translate_string(fe->fname,fe->fnamelen, recode_buf, recode_panel->tr_table); ++ filename= recode_buf; ++#else ++ filename=fe->fname; ++#endif + +- if (!c) +- break; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ for (i = 0; i < sizeof (buffer) - 1; i++) { ++ wchar_t wc; ++ int len; + +- if (!is_printable(c)) +- c = '?'; ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (!is_printable (wc)) { ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (i >= sizeof (buffer) - len) ++ break; ++ memcpy (buffer + i, str, len); ++ i += len - 1; ++ str += len; ++ } ++ else ++#endif ++ for (i = 0; i < sizeof(buffer) - 1; i++) { ++ char c; + +- buffer[i] = c; +- } ++ c= filename[i]; ++ ++ if (!c) ++ break; ++ ++ if (!is_printable(c)) ++ c = '?'; ++ ++ buffer[i] = c; ++ } + + buffer[i] = 0; + return buffer; +@@ -425,42 +474,6 @@ + { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, + }; + +-static char * +-to_buffer (char *dest, int just_mode, int len, const char *txt) +-{ +- int txtlen = strlen (txt); +- int still, over; +- +- /* Fill buffer with spaces */ +- memset (dest, ' ', len); +- +- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen); +- +- switch (HIDE_FIT(just_mode)){ +- case J_LEFT: +- still = 0; +- break; +- case J_CENTER: +- still /= 2; +- break; +- case J_RIGHT: +- default: +- break; +- } +- +- if (over){ +- if (IS_FIT(just_mode)) +- strcpy (dest, name_trunc(txt, len)); +- else +- strncpy (dest, txt+still, len); +- } else +- strncpy (dest+still, txt, txtlen); +- +- dest[len] = '\0'; +- +- return (dest + len); +-} +- + static int + file_compute_color (int attr, file_entry *fe) + { +@@ -514,14 +527,18 @@ + + /* Formats the file number file_index of panel in the buffer dest */ + static void +-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus) ++format_file (WPanel *panel, int file_index, int width, int attr, int isstatus) + { + int color, length, empty_line; + const char *txt; +- char *old_pos; +- char *cdest = dest; + format_e *format, *home; + file_entry *fe; ++#ifdef UTF8 ++ char buffer[BUF_MEDIUM * sizeof (wchar_t)]; ++#else ++ char buffer[BUF_MEDIUM]; ++#endif ++ int txtwidth; + + length = 0; + empty_line = (file_index >= panel->count); +@@ -539,34 +556,137 @@ + break; + + if (format->string_fn){ +- int len; ++ int len, still, over, perm, txtlen, wide; + + if (empty_line) + txt = " "; + else + txt = (*format->string_fn)(fe, format->field_len); + +- old_pos = cdest; +- + len = format->field_len; + if (len + length > width) + len = width - length; +- if (len + (cdest - dest) > limit) +- len = limit - (cdest - dest); ++ if (len >= BUF_MEDIUM) ++ len = BUF_MEDIUM - 1; + if (len <= 0) + break; +- cdest = to_buffer (cdest, format->just_mode, len, txt); +- length += len; + +- attrset (color); ++ perm = 0; ++ if (permission_mode) { ++ if (!strcmp(format->id, "perm")) ++ perm = 1; ++ else if (!strcmp(format->id, "mode")) ++ perm = 2; ++ } + +- if (permission_mode && !strcmp(format->id, "perm")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 0); +- else if (permission_mode && !strcmp(format->id, "mode")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 1); +- else +- addstr (old_pos); ++ wide = 0; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode && !empty_line && !perm) { ++ mbstate_t s; ++ const char *str = txt; ++ ++ memset (&s, 0, sizeof (s)); ++ txtlen = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), &s); ++ if (txtlen < 0) { ++ txt = " "; ++ txtlen = 1; ++ } else { ++ wide = 1; ++ txtwidth = wcswidth((wchar_t*)buffer, txtlen); ++ } ++ } else ++#endif ++ { ++ txtlen = strlen (txt); ++ txtwidth = txtlen; ++ } ++ ++ over = txtwidth > len; ++ still = over ? txtlen - len : len - txtlen; ++ ++ switch (HIDE_FIT(format->just_mode)) { ++ case J_LEFT: ++ still = 0; ++ break; ++ case J_CENTER: ++ still /= 2; ++ break; ++ case J_RIGHT: ++ default: ++ break; ++ } ++ ++ attrset (color); + ++ if (wide) { ++#ifdef UTF8 ++ if (over) { ++ if (IS_FIT (format->just_mode)) { ++ int n1 = 0; ++ int width1 = 0; ++ int n2 = 0; ++ int width2 = 0; ++ int len1 = len / 2; ++ int len2; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[n1]); ++ if (width1 + w <= len1) { ++ width1 += w; ++ n1++; ++ } ++ else ++ break; ++ } ++ len2 = len - width1 - 1; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); ++ if (width2 + w <= len2) { ++ width2 += w; ++ n2++; ++ } ++ else ++ break; ++ } ++ ++ ++ SLsmg_write_nwchars ((wchar_t *) buffer, n1); ++ SLsmg_write_nwchars (L"~", 1); ++ printw ("%*s", len - width1 - width2 - 1, ""); ++ SLsmg_write_nwchars (((wchar_t *) buffer) ++ + txtlen - n2, n2); ++ } else ++ SLsmg_write_nwchars ((wchar_t *) buffer, len); ++ } else { ++ printw ("%*s", still, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); ++ printw ("%*s", len - txtwidth - still, ""); ++ } ++#endif ++ } else { ++ if (over) { ++ if (IS_FIT (format->just_mode)) ++ strcpy (buffer, name_trunc(txt, len)); ++ else ++ memcpy (buffer, txt + still, len); ++ } else { ++ memset (buffer, ' ', still); ++ memcpy (buffer + still, txt, txtlen); ++ memset (buffer + still + txtlen, ' ', ++ len - txtlen - still); ++ } ++ buffer[len] = '\0'; ++ ++ if (perm) ++ add_permission_string (buffer, format->field_len, fe, ++ attr, color, perm - 1); ++ else ++ addstr (buffer); ++ } ++ ++ length += len; + } else { + if (attr == SELECTED || attr == MARKED_SELECTED) + attrset (SELECTED_COLOR); +@@ -589,7 +709,10 @@ + { + int second_column = 0; + int width, offset; +- char buffer [BUF_MEDIUM]; ++ ++#ifdef HAVE_CHARSET ++ recode_panel=panel; ++#endif + + offset = 0; + if (!isstatus && panel->split){ +@@ -618,7 +741,7 @@ + widget_move (&panel->widget, file_index - panel->top_file + 2, 1); + } + +- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus); ++ format_file (panel, file_index, width, attr, isstatus); + + if (!isstatus && panel->split){ + if (second_column) +@@ -630,7 +753,7 @@ + } + } + +-static void ++void + display_mini_info (WPanel *panel) + { + if (!show_mini_info) +@@ -658,7 +781,7 @@ + g_snprintf (buffer, sizeof (buffer), (panel->marked == 1) ? + _("%s bytes in %d file") : _("%s bytes in %d files"), + size_trunc_sep (panel->total), panel->marked); +- if ((int) strlen (buffer) > cols-2){ ++ if ((int) mbstrlen (buffer) > cols-2){ + buffer [cols] = 0; + p += 2; + } else +@@ -691,7 +814,7 @@ + return; + } + +-static void ++void + paint_dir (WPanel *panel) + { + int i; +@@ -729,7 +852,7 @@ + #endif /* !HAVE_SLANG */ + } + +-static void ++void + show_dir (WPanel *panel) + { + char *tmp; +@@ -749,6 +872,9 @@ + } + #endif /* HAVE_SLANG */ + ++ vscrollbar (panel->widget, panel->widget.lines, panel->widget.cols-1, 2, 2, ++ panel->selected, panel->count, TRUE); ++ + if (panel->active) + attrset (REVERSE_COLOR); + +@@ -757,8 +883,15 @@ + tmp = g_malloc (panel->widget.cols + 1); + tmp[panel->widget.cols] = '\0'; + ++#ifdef HAVE_CHARSET ++ my_translate_string(panel->cwd,strlen(panel->cwd),recode_buf, panel->tr_table); ++ trim (strip_home_and_password (recode_buf), tmp, ++ min (max (panel->widget.cols - 7, 0), panel->widget.cols) ); ++#else + trim (strip_home_and_password (panel->cwd), tmp, + min (max (panel->widget.cols - 7, 0), panel->widget.cols) ); ++#endif ++ + addstr (tmp); + g_free (tmp); + widget_move (&panel->widget, 0, 1); +@@ -970,6 +1103,17 @@ + mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); + strcpy (panel->lwd, "."); + ++#ifdef HAVE_CHARSET ++ panel_reset_codepage(panel); ++#endif ++ ++#ifdef USE_VFS ++ panel->is_return=0; ++ #ifdef HAVE_CHARSET ++ panel->ret_codepage=-1; ++ #endif ++#endif ++ + panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL); + panel->dir_history = history_get (panel->hist_name); + directory_history_add (panel, panel->cwd); +@@ -1068,6 +1212,12 @@ + int side, width; + + const char *txt; ++#ifdef UTF8 ++ char buffer[30 * sizeof (wchar_t)]; ++ mbstate_t s; ++ ++ memset (&s, 0, sizeof (s)); ++#endif + if (!panel->split) + adjust_top_file (panel); + +@@ -1092,16 +1242,37 @@ + if (format->string_fn){ + txt = format->title; + ++ attrset (MARKED_COLOR); ++ width -= format->field_len; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ const char *str = txt; ++ header_len = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), ++ &s); ++ if (header_len < 0) { ++ memset (&s, 0, sizeof (s)); ++ printw ("%*s", format->field_len, ""); ++ continue; ++ } ++ if (header_len > format->field_len) ++ header_len = format->field_len; ++ spaces = (format->field_len - header_len) / 2; ++ extra = (format->field_len - header_len) % 2; ++ printw ("%*s", spaces, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, header_len); ++ printw ("%*s", spaces + extra, ""); ++ continue; ++ } ++#endif + header_len = strlen (txt); + if (header_len > format->field_len) + header_len = format->field_len; + +- attrset (MARKED_COLOR); + spaces = (format->field_len - header_len) / 2; + extra = (format->field_len - header_len) % 2; + printw ("%*s%.*s%*s", spaces, "", + header_len, txt, spaces+extra, ""); +- width -= 2 * spaces + extra + header_len; + } else { + attrset (NORMAL_COLOR); + one_vline (); +@@ -1320,7 +1491,7 @@ + panel->dirty = 1; + + /* Status needn't to be split */ +- usable_columns = ((panel->widget.cols-2)/((isstatus) ++ usable_columns = ((panel->widget.cols-3)/((isstatus) + ? 1 + : (panel->split+1))) - (!isstatus && panel->split); + +@@ -2100,7 +2271,12 @@ + { XCTRL('n'), move_down }, /* C-n like emacs */ + { XCTRL('s'), start_search }, /* C-s like emacs */ + { ALT('s'), start_search }, /* M-s not like emacs */ ++#ifndef HAVE_CHARSET + { XCTRL('t'), mark_file }, ++#endif ++#ifdef HAVE_CHARSET ++ { XCTRL('t'), mark_file }, /* was 'fnc_c_cmd' */ ++#endif + { ALT('o'), chdir_other_panel }, + { ALT('l'), chdir_to_readlink }, + { ALT('H'), directory_history_list }, +diff -urN mc-4.6.1.orig/src/screen.h mc-4.6.1/src/screen.h +--- mc-4.6.1.orig/src/screen.h 1970-01-01 05:00:00.000000000 +0500 ++++ mc-4.6.1/src/screen.h 2007-01-19 18:33:59.000000000 +0500 +@@ -0,0 +1,11 @@ ++#ifndef __SCREEN_H__ ++#define __SCREEN_H__ ++#include ++ ++#include "global.h" ++ ++extern void paint_dir (WPanel *panel); ++extern void display_mini_info (WPanel *panel); ++extern void show_dir(WPanel *panel); ++#endif //__SCREEN_H__ ++ +diff -urN mc-4.6.1.orig/src/selcodepage.c mc-4.6.1/src/selcodepage.c +--- mc-4.6.1.orig/src/selcodepage.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/selcodepage.c 2007-01-19 18:33:59.000000000 +0500 +@@ -44,14 +44,16 @@ + } + + int +-select_charset (int current_charset, int seldisplay) ++select_charset (int current_charset, int seldisplay, const char *title) + { ++ int new_charset; ++ + int i, menu_lines = n_codepages + 1; + char buffer[255]; + + /* Create listbox */ + Listbox *listbox = create_listbox_window (ENTRY_LEN + 2, menu_lines, +- _(" Choose input codepage "), ++ title, + "[Codepages Translation]"); + + if (!seldisplay) +@@ -81,20 +83,26 @@ + + i = run_listbox (listbox); + +- return (seldisplay) ? ((i >= n_codepages) ? -1 : i) +- : (i - 1); ++ if(i==-1) ++ i = (seldisplay) ++ ? ((current_charset < 0) ? n_codepages : current_charset) ++ : (current_charset + 1); ++ ++ new_charset =(seldisplay) ? ( (i >= n_codepages) ? -1 : i ) : ( i-1 ); ++ new_charset = (new_charset==-2) ? current_charset:new_charset; ++ return new_charset; + } + + /* Helper functions for codepages support */ + + + int +-do_select_codepage (void) ++do_select_codepage (const char *title) + { + const char *errmsg; + + if (display_codepage > 0) { +- source_codepage = select_charset (source_codepage, 0); ++ source_codepage = select_charset (source_codepage, 0, title); + errmsg = + init_translation_table (source_codepage, display_codepage); + if (errmsg) { +diff -urN mc-4.6.1.orig/src/selcodepage.h mc-4.6.1/src/selcodepage.h +--- mc-4.6.1.orig/src/selcodepage.h 2002-10-31 04:16:16.000000000 +0500 ++++ mc-4.6.1/src/selcodepage.h 2007-01-19 18:33:59.000000000 +0500 +@@ -2,8 +2,8 @@ + #ifndef __SELCODEPAGE_H__ + #define __SELCODEPAGE_H__ + +-int select_charset (int current_charset, int seldisplay); +-int do_select_codepage (void); ++int select_charset (int current_charset, int seldisplay, const char *title); ++int do_select_codepage (const char *title); + + #endif /* __SELCODEPAGE_H__ */ + #endif /* HAVE_CHARSET */ +diff -urN mc-4.6.1.orig/src/setup.c mc-4.6.1/src/setup.c +--- mc-4.6.1.orig/src/setup.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/setup.c 2007-01-19 18:33:59.000000000 +0500 +@@ -47,6 +47,8 @@ + + #ifdef HAVE_CHARSET + #include "charsets.h" ++#include"recode.h" ++#include "wtools.h" + #endif + + #ifdef USE_NETCODE +@@ -255,6 +257,11 @@ + g_snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status); + save_string (section, "user_mini_status", buffer, + profile_name); ++ ++#ifdef HAVE_CHARSET ++ // save panel codepage ++ save_string(section, "panel_display_codepage", get_codepage_id(panel->src_codepage), profile_name); ++#endif + } + + void +@@ -352,6 +359,7 @@ + #ifdef HAVE_CHARSET + save_string( "Misc", "display_codepage", + get_codepage_id( display_codepage ), profile_name ); ++ save_string( "Misc", "ftp_codepage", get_codepage_id(ftp_codepage), profile_name); + #endif /* HAVE_CHARSET */ + + g_free (profile); +@@ -401,6 +409,31 @@ + panel->user_mini_status = + load_int (section, "user_mini_status", 0); + ++#ifdef HAVE_CHARSET ++//--- Loading panel codepage ++ panel_reset_codepage(panel); ++ if(load_codepages_list()>0) { ++ char cpname[128]; ++ char *errmsg; ++ ++ ++ if(display_codepage>=0) { ++ load_string(section, "panel_display_codepage", "", cpname, sizeof(cpname)); ++ if(cpname[0]!='\0') panel->src_codepage = get_codepage_index(cpname); ++ } ++ ++ errmsg=my_init_tt(display_codepage,panel->src_codepage,panel->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(panel); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ errmsg=my_init_tt(panel->src_codepage,display_codepage,panel->tr_table_input); ++ if(errmsg) { ++ panel_reset_codepage(panel); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ } ++#endif + } + + static void +@@ -543,12 +576,18 @@ + #endif /* USE_VFS && USE_NETCODE */ + + #ifdef HAVE_CHARSET +- if ( load_codepages_list() > 0 ) { +- char cpname[128]; +- load_string( "Misc", "display_codepage", "", +- cpname, sizeof(cpname) ); +- if ( cpname[0] != '\0' ) +- display_codepage = get_codepage_index( cpname ); ++ if(load_codepages_list() > 0) { ++ char cpname[128]; ++ get_locale_codepage(); ++ load_string("Misc", "display_codepage", "", cpname, sizeof(cpname)); ++ if(cpname[0] != '\0') display_codepage=get_codepage_index(cpname); ++ else display_codepage=lang_codepage; ++ ++ ftp_codepage=-1; ++ if(display_codepage >= 0) { ++ load_string( "Misc", "ftp_codepage", "", cpname, sizeof(cpname)); ++ if(cpname[0] != '\0') ftp_codepage=get_codepage_index(cpname); ++ } + } + + init_translation_table( source_codepage, display_codepage ); +diff -urN mc-4.6.1.orig/src/slint.c mc-4.6.1/src/slint.c +--- mc-4.6.1.orig/src/slint.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/slint.c 2007-01-19 18:33:59.000000000 +0500 +@@ -180,6 +180,9 @@ + struct sigaction act, oact; + + SLtt_get_terminfo (); ++#if SLANG_VERSION >= 20000 ++ SLutf8_enable (-1); ++#endif + + /* + * If the terminal in not in terminfo but begins with a well-known +diff -urN mc-4.6.1.orig/src/util.c mc-4.6.1/src/util.c +--- mc-4.6.1.orig/src/util.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/util.c 2007-01-19 18:33:59.000000000 +0500 +@@ -32,7 +32,11 @@ + #include + #include + #include ++#include ++#include ++#include + ++#include "tty.h" + #include "global.h" + #include "profile.h" + #include "main.h" /* mc_home */ +@@ -44,9 +48,40 @@ + #include "charsets.h" + #endif + ++#ifdef UTF8 ++#include ++#include ++#endif ++ + static const char app_text [] = "Midnight-Commander"; + int easy_patterns = 1; + ++#if SLANG_VERSION >= 20000 ++void SLsmg_write_nwchars(wchar_t *s, size_t n) ++{ ++ if (SLsmg_is_utf8_mode()) { /* slang can handle it directly */ ++ while(n-- && *s) ++ SLsmg_write_char(*s++); ++ } ++ else { /* convert wchars back to 8bit encoding */ ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (n-- && *s) { ++ char buf[MB_LEN_MAX + 1]; /* should use 1 char, but to be sure */ ++ if (*s < 0x80) { ++ SLsmg_write_char(*s++); /* ASCII */ ++ } ++ else { ++ if (wcrtomb(buf, *s++, &mbs) == 1) ++ SLsmg_write_char((wchar_t)(buf[0])); ++ else ++ SLsmg_write_char('?'); /* should not happen */ ++ } ++ } ++ } ++} ++#endif ++ + extern void str_replace(char *s, char from, char to) + { + for (; *s != '\0'; s++) { +@@ -77,9 +112,106 @@ + return (c > 31 && c != 127 && c != 155); + } + ++size_t ++mbstrlen (const char *str) ++{ ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ size_t width = 0; ++ ++ for (; *str; str++) { ++ wchar_t c; ++ size_t len; ++ ++ len = mbrtowc (&c, str, MB_CUR_MAX, NULL); ++ ++ if (len == (size_t)(-1) || len == (size_t)(-2)) break; ++ ++ if (len > 0) { ++ int wcsize = wcwidth(c); ++ width += wcsize > 0 ? wcsize : 0; ++ str += len-1; ++ } ++ } ++ ++ return width; ++ } else ++#endif ++ return strlen (str); ++} ++ ++#ifdef UTF8 ++ ++void ++fix_utf8(char *str) ++{ ++ mbstate_t mbs; ++ ++ char *p = str; ++ ++ while (*p) { ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(p, MB_CUR_MAX, &mbs); ++ if (len == -1) { ++ *p = '?'; ++ p++; ++ } else if (len > 0) { ++ p += len; ++ } else { ++ p++; ++ } ++ } ++} ++#endif ++ ++ ++ ++#ifdef UTF8 ++wchar_t * ++mbstr_to_wchar (const char *str) ++{ ++ int len = mbstrlen(str); ++ wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t)); ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ mbsrtowcs (buf, &str, len, &mbs); ++ buf[len] = 0; ++ return buf; ++} ++ ++char * ++wchar_to_mbstr (const wchar_t *wstr) ++{ ++ mbstate_t mbs; ++ const wchar_t *wstr2; ++ char * string; ++ int len; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ wstr2 = wstr; ++ len = wcsrtombs(NULL, &wstr2, 0, &mbs); ++ if (len <= 0) ++ return NULL; ++ ++ string = g_malloc(len + 1); ++ ++ wstr2 = wstr; ++ wcsrtombs(string, &wstr2, len, &mbs); ++ string[len] = 0; ++ return string; ++} ++#endif ++ ++ ++ + int + is_printable (int c) + { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ return iswprint (c); ++#endif + c &= 0xff; + + #ifdef HAVE_CHARSET +@@ -97,7 +229,7 @@ + #endif /* !HAVE_CHARSET */ + } + +-/* Returns the message dimensions (lines and columns) */ ++/* Returns the message dimensions columns */ + int msglen (const char *text, int *lines) + { + int max = 0; +@@ -108,8 +240,18 @@ + line_len = 0; + (*lines)++; + } else { +- line_len++; +- if (line_len > max) ++#ifdef UTF8 ++ size_t len; ++ wchar_t c; ++ ++ len = mbrtowc (&c, text, MB_CUR_MAX, NULL); ++ if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) { ++ int wcsize = wcwidth(c); ++ line_len += wcsize > 0 ? wcsize-1 : -1; ++ text += len-1; ++ } ++#endif ++ if (++line_len > max) + max = line_len; + } + } +@@ -201,7 +343,24 @@ + *d++ = '\\'; + break; + } ++#ifndef UTF8 + *d = *s; ++#else /* UTF8 */ ++ { ++ mbstate_t mbs; ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(s, MB_CUR_MAX, &mbs); ++ if (len > 0) { ++ while (len-- > 1) ++ *d++ = *s++; ++ *d = *s; ++ } else { ++ *d = '?'; ++ } ++ ++ } ++#endif /* UTF8 */ + } + *d = '\0'; + return ret; +@@ -222,25 +381,90 @@ + name_trunc (const char *txt, int trunc_len) + { + static char x[MC_MAXPATHLEN + MC_MAXPATHLEN]; +- int txt_len; ++ int txt_len, first, skip; + char *p; ++ const char *str; + + if ((size_t) trunc_len > sizeof (x) - 1) { + trunc_len = sizeof (x) - 1; + } +- txt_len = strlen (txt); +- if (txt_len <= trunc_len) { +- strcpy (x, txt); +- } else { +- int y = (trunc_len / 2) + (trunc_len % 2); +- strncpy (x, txt, y); +- strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2); +- x[y] = '~'; +- } +- x[trunc_len] = 0; +- for (p = x; *p; p++) +- if (!is_printable (*p)) +- *p = '?'; ++ txt_len = mbstrlen (txt); ++ first = 0; ++ skip = 0; ++ if (txt_len > trunc_len) { ++ first = trunc_len / 2; ++ skip = txt_len - trunc_len + 1; ++ } ++ ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ mbstate_t s; ++ int mbmax; ++ ++ str = txt; ++ memset (&s, 0, sizeof (s)); ++ mbmax = MB_CUR_MAX; ++ p = x; ++ while (p < x + sizeof (x) - 1 && trunc_len) { ++ wchar_t wc; ++ int len; ++ ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ *p = '?'; ++ len = 1; ++ str++; ++ } else if (!is_printable (wc)) { ++ *p = '?'; ++ str += len; ++ len = 1; ++ } else if (p >= x + sizeof (x) - len) ++ break; ++ else { ++ memcpy (p, str, len); ++ str += len; ++ } ++ if (first) { ++ --trunc_len; ++ --first; ++ p += len; ++ if (!first && p < x + sizeof (x) - 1 && trunc_len) { ++ *p++ = '~'; ++ --trunc_len; ++ } ++ } else if (skip) ++ --skip; ++ else { ++ --trunc_len; ++ p += len; ++ } ++ } ++ } else ++#endif ++ { ++ str = txt; ++ p = x; ++ while (p < x + sizeof (x) - 1) { ++ if (*str == '\0') ++ break; ++ else if (!is_printable (*str)) ++ *p++ = '?'; ++ else ++ *p++ = *str; ++ ++str; ++ if (first) { ++ --first; ++ if (!first) { ++ *p++ = '~'; ++ str += skip; ++ } ++ } ++ } ++ } ++ *p = '\0'; + return x; + } + +@@ -650,11 +874,66 @@ + } + + char * ++utf8_to_local(char *str) ++{ ++ iconv_t cd; ++ size_t buflen; ++ char *output; ++ int retry = 1; ++ ++ if (str == NULL) ++ return NULL; ++ else ++ buflen = strlen(str); ++ ++ cd = iconv_open (nl_langinfo(CODESET), "UTF-8"); ++ if (cd == (iconv_t) -1) { ++ return g_strdup(str); ++ } ++ ++ output = g_malloc(buflen + 1); ++ ++ while (retry) ++ { ++ char *wrptr = output; ++ char *inptr = str; ++ size_t insize = buflen; ++ size_t avail = buflen; ++ size_t nconv; ++ ++ nconv = iconv (cd, &inptr, &insize, &wrptr, &avail); ++ if (nconv == (size_t) -1) ++ { ++ if (errno == E2BIG) ++ { ++ buflen *= 2; ++ g_free(output); ++ output = g_malloc(buflen + 1); ++ } ++ else ++ { ++ g_free(output); ++ return g_strdup(str); ++ } ++ } ++ else { ++ retry = 0; ++ *wrptr = 0; ++ } ++ } ++ ++ iconv_close (cd); ++ ++ return output; ++} ++ ++char * + load_mc_home_file (const char *filename, char **allocated_filename) + { + char *hintfile_base, *hintfile; + char *lang; + char *data; ++ char *conv_data; + + hintfile_base = concat_dir_and_file (mc_home, filename); + lang = guess_message_value (); +@@ -687,7 +966,10 @@ + else + g_free (hintfile); + +- return data; ++ conv_data = utf8_to_local(data); ++ g_free(data); ++ ++ return conv_data; + } + + /* Check strftime() results. Some systems (i.e. Solaris) have different +@@ -695,12 +977,14 @@ + size_t i18n_checktimelength (void) + { + size_t length, a, b; +- char buf [MAX_I18NTIMELENGTH + 1]; ++ char buf [4 * MAX_I18NTIMELENGTH + 1]; + time_t testtime = time (NULL); + +- a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); +- b = strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); +- ++ strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); ++ a = mbstrlen (buf); ++ strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); ++ b = mbstrlen (buf); ++ + length = max (a, b); + + /* Don't handle big differences. Use standard value (email bug, please) */ +@@ -712,15 +996,12 @@ + + const char *file_date (time_t when) + { +- static char timebuf [MAX_I18NTIMELENGTH + 1]; ++ static char timebuf [4 * MAX_I18NTIMELENGTH + 1]; + time_t current_time = time ((time_t) 0); +- static size_t i18n_timelength = 0; + static const char *fmtyear, *fmttime; + const char *fmt; + +- if (i18n_timelength == 0){ +- i18n_timelength = i18n_checktimelength() + 1; +- ++ if (fmtyear == NULL) { + /* strftime() format string for old dates */ + fmtyear = _("%b %e %Y"); + /* strftime() format string for recent dates */ +@@ -740,7 +1021,7 @@ + else + fmt = fmttime; + +- strftime (timebuf, i18n_timelength, fmt, localtime(&when)); ++ strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when)); + return timebuf; + } + +@@ -863,10 +1144,27 @@ + r++; + continue; + } +- ++#ifndef UTF8 + if (is_printable(*r)) + *w++ = *r; + ++r; ++#else /* UTF8 */ ++ { ++ mbstate_t mbs; ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(r, MB_CUR_MAX, &mbs); ++ ++ if (len > 0 && (unsigned char)*r >= ' ') ++ while (len--) ++ *w++ = *r++; ++ else { ++ if (len == -1) ++ *w++ = '?'; ++ r++; ++ } ++ } ++#endif /* UTF8 */ + } + *w = 0; + return s; +@@ -1140,21 +1438,23 @@ + * as needed up in first and then goes down using second */ + char *diff_two_paths (const char *first, const char *second) + { +- char *p, *q, *r, *s, *buf = 0; ++ char *p, *q, *r, *s, *buf = NULL; + int i, j, prevlen = -1, currlen; + char *my_first = NULL, *my_second = NULL; + + my_first = resolve_symlinks (first); + if (my_first == NULL) + return NULL; ++ my_second= resolve_symlinks (second); ++ if (my_second == NULL) { ++ g_free (my_first); ++ return NULL; ++ } + for (j = 0; j < 2; j++) { + p = my_first; + if (j) { +- my_second = resolve_symlinks (second); +- if (my_second == NULL) { +- g_free (my_first); ++ if (my_second == NULL) + return buf; +- } + } + q = my_second; + for (;;) { +diff -urN mc-4.6.1.orig/src/util.h mc-4.6.1/src/util.h +--- mc-4.6.1.orig/src/util.h 2005-01-14 00:20:47.000000000 +0500 ++++ mc-4.6.1/src/util.h 2007-01-19 18:33:59.000000000 +0500 +@@ -93,6 +93,13 @@ + char *get_group (int); + char *get_owner (int); + ++void fix_utf8(char *str); ++size_t mbstrlen (const char *); ++wchar_t *mbstr_to_wchar (const char *); ++char *wchar_to_mbstr (const wchar_t *); ++char *utf8_to_local(char *str); ++ ++ + #define MAX_I18NTIMELENGTH 14 + #define MIN_I18NTIMELENGTH 10 + #define STD_I18NTIMELENGTH 12 +@@ -210,7 +217,7 @@ + #define PATH_ENV_SEP ':' + #define TMPDIR_DEFAULT "/tmp" + #define SCRIPT_SUFFIX "" +-#define get_default_editor() "vi" ++#define get_default_editor() "editor" + #define OS_SORT_CASE_SENSITIVE_DEFAULT 1 + #define STRCOMP strcmp + #define STRNCOMP strncmp +diff -urN mc-4.6.1.orig/src/view.c mc-4.6.1/src/view.c +--- mc-4.6.1.orig/src/view.c 2005-05-27 20:19:18.000000000 +0600 ++++ mc-4.6.1/src/view.c 2007-01-19 18:33:59.000000000 +0500 +@@ -36,6 +36,10 @@ + #include + #include + ++#ifdef UTF8 ++#include ++#endif /* UTF8 */ ++ + #include "global.h" + #include "tty.h" + #include "cmd.h" /* For view_other_cmd */ +@@ -793,7 +797,7 @@ + + if (!i18n_adjust) { + file_label = _("File: %s"); +- i18n_adjust = strlen (file_label) - 2; ++ i18n_adjust = mbstrlen (file_label) - 2; + } + + if (w < i18n_adjust + 6) +@@ -849,7 +853,11 @@ + widget_erase ((Widget *) view); + } + ++#ifndef UTF8 + #define view_add_character(view,c) addch (c) ++#else /* UTF8 */ ++#define view_add_character(view,c) {wchar_t tmp=c; SLsmg_write_nwchars(&tmp, 1);} ++#endif /* UTF8 */ + #define view_add_one_vline() one_vline() + #define view_add_string(view,s) addstr (s) + #define view_gotoyx(v,r,c) widget_move (v,r,c) +@@ -1071,6 +1079,12 @@ + if (view->growing_buffer && from == view->last_byte) + get_byte (view, from); + for (; row < height && from < view->last_byte; from++) { ++#ifdef UTF8 ++ mbstate_t mbs; ++ char mbbuf[MB_LEN_MAX]; ++ int mblen; ++ wchar_t wc; ++#endif /* UTF8 */ + c = get_byte (view, from); + if ((c == '\n') || (col >= width && view->wrap_mode)) { + col = frame_shift; +@@ -1084,7 +1098,37 @@ + col = ((col - frame_shift) / 8) * 8 + 8 + frame_shift; + continue; + } ++#ifndef UTF8 + if (view->viewer_nroff_flag && c == '\b') { ++#else /* UTF8 */ ++ mblen = 1; ++ mbbuf[0] = convert_to_display_c (c); ++ ++ while (mblen < MB_LEN_MAX) { ++ int res; ++ memset (&mbs, 0, sizeof (mbs)); ++ res = mbrtowc (&wc, mbbuf, mblen, &mbs); ++ if (res <= 0 && res != -2) { ++ wc = '.'; ++ mblen = 1; ++ break; ++ } ++ if (res == mblen) ++ break; ++ ++ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen)); ++ mblen++; ++ } ++ ++ if (mblen == MB_LEN_MAX) { ++ wc = '.'; ++ mblen = 1; ++ } ++ ++ from += mblen - 1; ++ ++ if (view->viewer_nroff_flag && wc == '\b') { ++#endif /* UTF8 */ + int c_prev; + int c_next; + +@@ -1122,12 +1166,23 @@ + && col < width - view->start_col) { + view_gotoyx (view, row, col + view->start_col); + ++#ifndef UTF8 + c = convert_to_display_c (c); +- + if (!is_printable (c)) + c = '.'; +- + view_add_character (view, c); ++#else /* UTF8 */ ++ if (!iswprint (wc)) ++ wc = '.'; ++ view_add_character (view, wc); ++ ++ { ++ int cw = wcwidth(wc); ++ if (cw > 1) ++ col+= cw - 1; ++ } ++#endif /* UTF8 */ ++ + } + col++; + if (boldflag != MARK_NORMAL) { +@@ -1239,7 +1294,12 @@ + if (lines != -1 && line >= lines) + return p; + +- c = get_byte (view, p); ++ if ((c = get_byte (view, p)) == -1) { ++ if (upto) ++ return line; ++ else ++ return p; ++ } + + if (view->wrap_mode) { + if (c == '\r') +@@ -2534,7 +2594,7 @@ + + #ifdef HAVE_CHARSET + case XCTRL ('t'): +- do_select_codepage (); ++ do_select_codepage (_(" Choose codepage ")); + view->dirty++; + view_update (view, TRUE); + return MSG_HANDLED; +diff -urN mc-4.6.1.orig/src/widget.c mc-4.6.1/src/widget.c +--- mc-4.6.1.orig/src/widget.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/src/widget.c 2007-01-19 18:33:59.000000000 +0500 +@@ -33,6 +33,9 @@ + #include + #include "global.h" + #include "tty.h" ++#ifdef UTF8 ++#include ++#endif /* UTF8 */ + #include "color.h" + #include "mouse.h" + #include "dialog.h" +@@ -148,6 +151,11 @@ + if (b->hotpos >= 0) { + attrset ((b->selected) ? HOT_FOCUSC : HOT_NORMALC); + widget_move (&b->widget, 0, b->hotpos + off); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ SLsmg_write_nwchars (&b->hotwc, 1); ++ else ++#endif + addch ((unsigned char) b->text[b->hotpos]); + } + return MSG_HANDLED; +@@ -179,7 +187,7 @@ + static int + button_len (const char *text, unsigned int flags) + { +- int ret = strlen (text); ++ int ret = mbstrlen (text); + switch (flags){ + case DEFPUSH_BUTTON: + ret += 6; +@@ -202,14 +210,36 @@ + * the button text is g_malloc()ed, we can safely change and shorten it. + */ + static void +-button_scan_hotkey (WButton *b) ++scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp) + { +- char *cp = strchr (b->text, '&'); ++ char *cp = strchr (text, '&'); + + if (cp != NULL && cp[1] != '\0') { +- g_strlcpy (cp, cp + 1, strlen (cp)); +- b->hotkey = tolower (*cp); +- b->hotpos = cp - b->text; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ mbstate_t s; ++ int len; ++ ++ *cp = '\0'; ++ memset (&s, 0, sizeof (s)); ++ len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s); ++ if (len > 0) { ++ *hotposp = mbstrlen (text); ++ if (*hotposp < 0) { ++ *hotposp = -1; ++ } else { ++ /* FIXME */ ++ *hotkeyp = tolower (*hotwcp); ++ } ++ } ++ } else ++#endif ++ { ++ *hotkeyp = tolower (cp[1]); ++ *hotposp = cp - text; ++ } ++ ++ memmove (cp, cp + 1, strlen (cp + 1) + 1); + } + } + +@@ -231,22 +261,23 @@ + widget_want_hotkey (b->widget, 1); + b->hotkey = 0; + b->hotpos = -1; ++ b->hotwc = L'\0'; + +- button_scan_hotkey(b); ++ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); + return b; + } + + void + button_set_text (WButton *b, const char *text) + { +- g_free (b->text); ++ g_free (b->text); + b->text = g_strdup (text); + b->widget.cols = button_len (text, b->flags); +- button_scan_hotkey(b); ++ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); + dlg_redraw (b->widget.parent); + } + +- ++ + /* Radio button widget */ + static int radio_event (Gpm_Event *event, WRadio *r); + +@@ -320,16 +351,37 @@ + widget_move (&r->widget, i, 0); + + printw ("(%c) ", (r->sel == i) ? '*' : ' '); +- for (cp = r->texts[i]; *cp; cp++) { +- if (*cp == '&') { +- attrset ((i == r->pos && msg == WIDGET_FOCUS) +- ? HOT_FOCUSC : HOT_NORMALC); +- addch (*++cp); +- attrset ((i == r->pos +- && msg == WIDGET_FOCUS) ? FOCUSC : NORMALC); ++ cp = strchr (r->texts[i], '&'); ++ if (cp != NULL) { ++#ifdef UTF8 ++ mbstate_t s; ++ wchar_t wc; ++ int len; ++#endif ++ printw ("%.*s", (int) ((char *) cp - r->texts[i]), ++ r->texts[i]); ++ attrset ((i == r->pos && msg == WIDGET_FOCUS) ++ ? HOT_FOCUSC : HOT_NORMALC); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ memset (&s, 0, sizeof (s)); ++ len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s); ++ ++cp; ++ if (len > 0) { ++ printw ("%.*s", len, cp); ++ cp += len; ++ } + } else +- addch (*cp); +- } ++#endif ++ { ++ addch (*++cp); ++ ++cp; ++ } ++ attrset ((i == r->pos && msg == WIDGET_FOCUS) ++ ? FOCUSC : NORMALC); ++ } else ++ cp = r->texts[i]; ++ addstr ((char *) cp); + } + return MSG_HANDLED; + +@@ -365,7 +417,7 @@ + /* Compute the longest string */ + max = 0; + for (i = 0; i < count; i++){ +- m = strlen (texts [i]); ++ m = mbstrlen (texts [i]); + if (m > max) + max = m; + } +@@ -426,6 +478,11 @@ + if (c->hotpos >= 0) { + attrset ((msg == WIDGET_FOCUS) ? HOT_FOCUSC : HOT_NORMALC); + widget_move (&c->widget, 0, +c->hotpos + 4); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ SLsmg_write_nwchars (&c->hotwc, 1); ++ else ++#endif + addch ((unsigned char) c->text[c->hotpos]); + } + return MSG_HANDLED; +@@ -460,32 +517,18 @@ + check_new (int y, int x, int state, const char *text) + { + WCheck *c = g_new (WCheck, 1); +- const char *s; +- char *t; + +- init_widget (&c->widget, y, x, 1, strlen (text), ++ init_widget (&c->widget, y, x, 1, mbstrlen (text), + (callback_fn)check_callback, + (mouse_h) check_event); + c->state = state ? C_BOOL : 0; + c->text = g_strdup (text); + c->hotkey = 0; + c->hotpos = -1; ++ c->hotwc = L'\0'; + widget_want_hotkey (c->widget, 1); + +- /* Scan for the hotkey */ +- for (s = text, t = c->text; *s; s++, t++){ +- if (*s != '&'){ +- *t = *s; +- continue; +- } +- s++; +- if (*s){ +- c->hotkey = tolower (*s); +- c->hotpos = t - c->text; +- } +- *t = *s; +- } +- *t = 0; ++ scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc); + return c; + } + +@@ -527,7 +570,7 @@ + } + widget_move (&l->widget, y, 0); + printw ("%s", p); +- xlen = l->widget.cols - strlen (p); ++ xlen = l->widget.cols - mbstrlen (p); + if (xlen > 0) + printw ("%*s", xlen, " "); + if (!q) +@@ -561,7 +604,7 @@ + if (text){ + label->text = g_strdup (text); + if (label->auto_adjust_cols) { +- newcols = strlen (text); ++ newcols = mbstrlen (text); + if (newcols > label->widget.cols) + label->widget.cols = newcols; + } +@@ -585,7 +628,7 @@ + if (!text || strchr(text, '\n')) + width = 1; + else +- width = strlen (text); ++ width = mbstrlen (text); + + l = g_new (WLabel, 1); + init_widget (&l->widget, y, x, 1, width, +@@ -734,13 +777,69 @@ + /* Pointer to killed data */ + static char *kill_buffer = 0; + ++#ifdef UTF8 ++static int ++charpos(WInput *in, int idx) ++{ ++ int i, pos, l, len; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ i = 0; ++ pos = 0; ++ len = strlen(in->buffer); ++ ++ while (in->buffer[pos]) { ++ if (i == idx) ++ return pos; ++ l = mbrlen(in->buffer + pos, len - pos, &mbs); ++ if (l <= 0) ++ return pos; ++ pos+=l; ++ i++; ++ }; ++ return pos; ++} ++ ++static int ++charcolumn(WInput *in, int idx) ++{ ++ int i, pos, l, width, len; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ i = 0; ++ pos = 0; width = 0; ++ len = strlen(in->buffer); ++ ++ while (in->buffer[pos]) { ++ wchar_t wc; ++ if (i == idx) ++ return width; ++ l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); ++ if (l <= 0) ++ return width; ++ pos += l; width += wcwidth(wc); ++ i++; ++ }; ++ return width; ++} ++#else ++#define charpos(in, idx) (idx) ++#define charcolumn(in, idx) (idx) ++#endif /* UTF8 */ ++ + void + update_input (WInput *in, int clear_first) + { + int has_history = 0; + int i, j; +- unsigned char c; +- int buf_len = strlen (in->buffer); ++ int buf_len = mbstrlen (in->buffer); ++#ifndef UTF8 ++ unsigned char c; ++#else /* UTF8 */ ++ wchar_t c; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++#endif /* UTF8 */ + + if (should_show_history_button (in)) + has_history = HISTORY_BUTTON_WIDTH; +@@ -750,7 +849,7 @@ + + /* Make the point visible */ + if ((in->point < in->first_shown) || +- (in->point >= in->first_shown+in->field_len - has_history)){ ++ (charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){ + in->first_shown = in->point - (in->field_len / 3); + if (in->first_shown < 0) + in->first_shown = 0; +@@ -770,14 +869,29 @@ + addch (' '); + widget_move (&in->widget, 0, 0); + ++#ifndef UTF8 + for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){ + c = in->buffer [j++]; + c = is_printable (c) ? c : '.'; +- if (in->is_password) ++#else /* UTF8 */ ++ for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){ ++ char * chp = in->buffer + charpos(in,j); ++ size_t res = mbrtowc(&c, chp, strlen(chp), &mbs); ++ c = (res && iswprint (c)) ? 0 : '.'; ++#endif /* UTF8 */ ++ if (in->is_password) + c = '*'; ++#ifndef UTF8 + addch (c); ++#else /* UTF8 */ ++ if (c) { ++ addch (c); ++ } ++ else ++ SLsmg_write_nchars (chp, res); ++#endif /* UTF8 */ + } +- widget_move (&in->widget, 0, in->point - in->first_shown); ++ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); + + if (clear_first) + in->first = 0; +@@ -919,7 +1033,7 @@ + show_hist (GList *history, int widget_x, int widget_y) + { + GList *hi, *z; +- size_t maxlen = strlen (i18n_htitle ()), i, count = 0; ++ size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0; + int x, y, w, h; + char *q, *r = 0; + Dlg_head *query_dlg; +@@ -932,7 +1046,7 @@ + z = g_list_first (history); + hi = z; + while (hi) { +- if ((i = strlen ((char *) hi->data)) > maxlen) ++ if ((i = mbstrlen ((char *) hi->data)) > maxlen) + maxlen = i; + count++; + hi = g_list_next (hi); +@@ -1104,35 +1218,83 @@ + in->need_push = 1; + in->buffer [0] = 0; + in->point = 0; ++ in->charpoint = 0; + in->mark = 0; + free_completions (in); + update_input (in, 0); + } + ++static void ++move_buffer_backward (WInput *in, int point) ++{ ++ int i, pos, len; ++ int str_len = mbstrlen (in->buffer); ++ if (point >= str_len) return; ++ ++ pos = charpos(in,point); ++ len = charpos(in,point + 1) - pos; ++ ++ for (i = pos; in->buffer [i + len - 1]; i++) ++ in->buffer [i] = in->buffer [i + len]; ++} ++ + static cb_ret_t + insert_char (WInput *in, int c_code) + { + size_t i; ++#ifdef UTF8 ++ mbstate_t mbs; ++ int res; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++#else ++ in->charpoint = 0; ++#endif /* UTF8 */ + + if (c_code == -1) + return MSG_NOT_HANDLED; + ++#ifdef UTF8 ++ if (in->charpoint >= MB_CUR_MAX) return 1; ++ ++ in->charbuf[in->charpoint++] = c_code; ++ ++ res = mbrlen((char *)in->charbuf, in->charpoint, &mbs); ++ if (res < 0) { ++ if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */ ++ return 1; ++ } ++ ++#endif /* UTF8 */ + in->need_push = 1; +- if (strlen (in->buffer)+1 == (size_t) in->current_max_len){ ++ if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){ + /* Expand the buffer */ +- char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len); ++ char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint); + if (narea){ + in->buffer = narea; +- in->current_max_len += in->field_len; ++ in->current_max_len += in->field_len + in->charpoint; + } + } ++#ifndef UTF8 + if (strlen (in->buffer)+1 < (size_t) in->current_max_len){ + size_t l = strlen (&in->buffer [in->point]); + for (i = l+1; i > 0; i--) + in->buffer [in->point+i] = in->buffer [in->point+i-1]; + in->buffer [in->point] = c_code; ++#else /* UTF8 */ ++ if (strlen (in->buffer) + in->charpoint < in->current_max_len){ ++ size_t ins_point = charpos(in,in->point); /* bytes from begin */ ++ /* move chars */ ++ size_t rest_bytes = strlen (in->buffer + ins_point); ++ ++ for (i = rest_bytes + 1; i > 0; i--) ++ in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1]; ++ ++ memcpy(in->buffer + ins_point, in->charbuf, in->charpoint); ++#endif /* UTF8 */ + in->point++; + } ++ in->charpoint = 0; + return MSG_HANDLED; + } + +@@ -1140,12 +1302,14 @@ + beginning_of_line (WInput *in) + { + in->point = 0; ++ in->charpoint = 0; + } + + static void + end_of_line (WInput *in) + { +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); ++ in->charpoint = 0; + } + + static void +@@ -1153,18 +1317,21 @@ + { + if (in->point) + in->point--; ++ in->charpoint = 0; + } + + static void + forward_char (WInput *in) + { +- if (in->buffer [in->point]) ++ if (in->buffer [charpos(in,in->point)]) + in->point++; ++ in->charpoint = 0; + } + + static void + forward_word (WInput *in) + { ++#ifndef UTF8 + unsigned char *p = in->buffer+in->point; + + while (*p && (isspace (*p) || ispunct (*p))) +@@ -1172,11 +1339,39 @@ + while (*p && isalnum (*p)) + p++; + in->point = p - in->buffer; ++#else /* UTF8 */ ++ mbstate_t mbs; ++ int len = mbstrlen (in->buffer); ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point < len) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (res <= 0 || !(iswspace (c) || iswpunct (c))) ++ break; ++ in->point++; ++ } ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point < len) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (res <= 0 || !iswalnum (c)) ++ break; ++ in->point++; ++ } ++ ++ in->charpoint = 0; ++#endif /* UTF8 */ + } + + static void + backward_word (WInput *in) + { ++#ifndef UTF8 + unsigned char *p = in->buffer+in->point; + + while (p-1 > in->buffer-1 && (isspace (*(p-1)) || ispunct (*(p-1)))) +@@ -1184,6 +1379,32 @@ + while (p-1 > in->buffer-1 && isalnum (*(p-1))) + p--; + in->point = p - in->buffer; ++#else /* UTF8 */ ++ mbstate_t mbs; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ while (in->point > 0) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c)))) ++ break; ++ in->point--; ++ } ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point > 0) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (*p && (res <= 0 || !iswalnum (c))) ++ break; ++ in->point--; ++ } ++ ++ in->charpoint = 0; ++#endif /* UTF8 */ + } + + static void +@@ -1216,8 +1437,9 @@ + + if (!in->point) + return; +- for (i = in->point; in->buffer [i-1]; i++) +- in->buffer [i-1] = in->buffer [i]; ++ ++ move_buffer_backward(in, in->point - 1); ++ in->charpoint = 0; + in->need_push = 1; + in->point--; + } +@@ -1225,10 +1447,8 @@ + static void + delete_char (WInput *in) + { +- int i; +- +- for (i = in->point; in->buffer [i]; i++) +- in->buffer [i] = in->buffer [i+1]; ++ move_buffer_backward(in, in->point); ++ in->charpoint = 0; + in->need_push = 1; + } + +@@ -1243,6 +1463,9 @@ + + g_free (kill_buffer); + ++ first=charpos(in,first); ++ last=charpos(in,last); ++ + kill_buffer = g_strndup(in->buffer+first,last-first); + } + +@@ -1251,11 +1474,13 @@ + { + int first = min (x_first, x_last); + int last = max (x_first, x_last); +- size_t len = strlen (&in->buffer [last]) + 1; ++ size_t len; + + in->point = first; + in->mark = first; +- memmove (&in->buffer [first], &in->buffer [last], len); ++ len = strlen (&in->buffer [charpos(in,last)]) + 1; ++ memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len); ++ in->charpoint = 0; + in->need_push = 1; + } + +@@ -1272,6 +1497,8 @@ + copy_region (in, old_point, new_point); + delete_region (in, old_point, new_point); + in->need_push = 1; ++ in->charpoint = 0; ++ in->charpoint = 0; + } + + static void +@@ -1315,16 +1542,20 @@ + + if (!kill_buffer) + return; ++ in->charpoint = 0; + for (p = kill_buffer; *p; p++) + insert_char (in, *p); ++ in->charpoint = 0; + } + + static void + kill_line (WInput *in) + { ++ int chp = charpos(in,in->point); + g_free (kill_buffer); +- kill_buffer = g_strdup (&in->buffer [in->point]); +- in->buffer [in->point] = 0; ++ kill_buffer = g_strdup (&in->buffer [chp]); ++ in->buffer [chp] = 0; ++ in->charpoint = 0; + } + + void +@@ -1334,9 +1565,10 @@ + g_free (in->buffer); + in->buffer = g_strdup (text); /* was in->buffer->text */ + in->current_max_len = strlen (in->buffer) + 1; +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); + in->mark = 0; + in->need_push = 1; ++ in->charpoint = 0; + } + + static void +@@ -1461,6 +1693,7 @@ + *in->buffer = 0; + in->point = 0; + in->first = 0; ++ in->charpoint = 0; + } + + cb_ret_t +@@ -1489,7 +1722,11 @@ + } + } + if (!input_map [i].fn){ ++#ifndef UTF8 + if (c_code > 255 || !is_printable (c_code)) ++#else /* UTF8 */ ++ if (c_code > 255) ++#endif /* UTF8 */ + return MSG_NOT_HANDLED; + if (in->first){ + port_region_marked_for_delete (in); +@@ -1523,6 +1760,9 @@ + if (pos != in->point) + free_completions (in); + in->point = pos; ++#ifdef UTF8 ++ in->charpoint = 0; ++#endif /* UTF8 */ + update_input (in, 1); + } + +@@ -1562,7 +1802,7 @@ + return MSG_HANDLED; + + case WIDGET_CURSOR: +- widget_move (&in->widget, 0, in->point - in->first_shown); ++ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); + return MSG_HANDLED; + + case WIDGET_DESTROY: +@@ -1584,7 +1824,7 @@ + && should_show_history_button (in)) { + do_show_hist (in); + } else { +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); + if (event->x - in->first_shown - 1 < in->point) + in->point = event->x - in->first_shown - 1; + if (in->point < 0) +@@ -1642,56 +1882,91 @@ + in->is_password = 0; + + strcpy (in->buffer, def_text); +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); ++ in->charpoint = 0; + return in; + } + +- +-/* Listbox widget */ ++/* Vertical scrollbar widget */ + +-/* Should draw the scrollbar, but currently draws only +- * indications that there is more information +- */ +-static int listbox_cdiff (WLEntry *s, WLEntry *e); +- +-static void +-listbox_drawscroll (WListbox *l) ++void ++vscrollbar (Widget widget, int height, int width, int tpad, int bpad, ++ int selected, int count, gboolean color) + { + int line; +- int i, top; +- int max_line = l->height-1; +- ++ int i; ++ + /* Are we at the top? */ +- widget_move (&l->widget, 0, l->width); +- if (l->list == l->top) +- one_vline (); ++ widget_move (&widget, tpad, width); ++#ifndef UTF8 ++ if (!selected) ++ one_vline (); ++ else ++ addch ('^'); ++#else ++ if (color) attrset (MARKED_COLOR); ++ if (is_utf8) ++ SLsmg_write_string("▲"); + else +- addch ('^'); ++ addch ('^'); ++ if (color) attrset (NORMAL_COLOR); ++#endif + + /* Are we at the bottom? */ +- widget_move (&l->widget, max_line, l->width); +- top = listbox_cdiff (l->list, l->top); +- if ((top + l->height == l->count) || l->height >= l->count) +- one_vline (); ++ widget_move (&widget, height-1-bpad, width); ++#ifndef UTF8 ++ if (selected == count-1) ++ one_vline (); ++ else ++ addch ('v'); ++#else ++ if (color) attrset (MARKED_COLOR); ++ if (is_utf8) ++ SLsmg_write_string("▼"); + else +- addch ('v'); ++ addch('v'); ++ if (color) attrset (NORMAL_COLOR); ++#endif + + /* Now draw the nice relative pointer */ +- if (l->count) +- line = 1+ ((l->pos * (l->height-2)) / l->count); ++ if (count > 1) ++ line = tpad + 1 + ((selected * (height-3-tpad-bpad)) / (count-1)); + else +- line = 0; +- +- for (i = 1; i < max_line; i++){ +- widget_move (&l->widget, i, l->width); +- if (i != line) +- one_vline (); +- else +- addch ('*'); ++ line = 0; ++ ++ for (i = tpad + 1; i < height-1-bpad; i++){ ++ widget_move (&widget, i, width); ++ if (i != line) ++#ifndef UTF8 ++ one_vline (); ++ else ++ addch ('*'); ++#else ++ if (is_utf8) ++ SLsmg_write_string("▒"); ++ else ++ one_vline(); ++ else { ++ if (color) attrset (MARKED_COLOR); ++ if (is_utf8) ++ SLsmg_write_string("●"); ++ else ++ addch('*'); ++ if (color) attrset (NORMAL_COLOR); ++ } ++#endif + } + } +- +-static void ++ ++ ++/* Listbox widget */ ++ ++/* Should draw the scrollbar, but currently draws only ++ * indications that there is more information ++ */ ++static int listbox_cdiff (WLEntry *s, WLEntry *e); ++ ++void + listbox_draw (WListbox *l, int focused) + { + WLEntry *e; +@@ -1732,7 +2007,7 @@ + if (!l->scrollbar) + return; + attrset (normalc); +- listbox_drawscroll (l); ++ vscrollbar (l->widget, l->height, l->width, 0, 0, l->pos, l->count, FALSE); + } + + /* Returns the number of items between s and e, +diff -urN mc-4.6.1.orig/src/widget.h mc-4.6.1/src/widget.h +--- mc-4.6.1.orig/src/widget.h 2004-08-30 00:46:16.000000000 +0600 ++++ mc-4.6.1/src/widget.h 2007-01-19 18:33:59.000000000 +0500 +@@ -25,6 +25,7 @@ + char *text; /* text of button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + bcback callback; /* Callback function */ + } WButton; + +@@ -43,6 +44,7 @@ + char *text; /* text of check button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + } WCheck; + + typedef struct WGauge { +@@ -58,16 +60,20 @@ + + typedef struct { + Widget widget; +- int point; /* cursor position in the input line */ +- int mark; /* The mark position */ +- int first_shown; /* Index of the first shown character */ +- int current_max_len; /* Maximum length of input line */ +- int field_len; /* Length of the editing field */ ++ int point; /* cursor position in the input line (mb chars) */ ++ int mark; /* The mark position (mb chars) */ ++ int first_shown; /* Index of the first shown character (mb chars) */ ++ int current_max_len; /* Maximum length of input line (bytes) */ ++ int field_len; /* Length of the editing field (mb chars) */ + int color; /* color used */ + int first; /* Is first keystroke? */ + int disable_update; /* Do we want to skip updates? */ + int is_password; /* Is this a password input line? */ + unsigned char *buffer; /* pointer to editing buffer */ ++#ifdef UTF8 ++ unsigned char charbuf[MB_LEN_MAX]; ++#endif /* UTF8 */ ++ int charpoint; + GList *history; /* The history */ + int need_push; /* need to push the current Input on hist? */ + char **completions; /* Possible completions array */ +@@ -176,6 +182,10 @@ + /* Listbox manager */ + WLEntry *listbox_get_data (WListbox *l, int pos); + ++/* Vertical scrollbar */ ++void vscrollbar (Widget widget, int height, int width, int tpad, int bpad, ++ int selected, int count, gboolean color); ++ + /* search text int listbox entries */ + WLEntry *listbox_search_text (WListbox *l, const char *text); + void listbox_select_entry (WListbox *l, WLEntry *dest); +diff -urN mc-4.6.1.orig/src/wtools.c mc-4.6.1/src/wtools.c +--- mc-4.6.1.orig/src/wtools.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/src/wtools.c 2007-01-19 18:33:59.000000000 +0500 +@@ -48,11 +48,11 @@ + /* Adjust sizes */ + lines = (lines > LINES - 6) ? LINES - 6 : lines; + +- if (title && (cols < (len = strlen (title) + 2))) ++ if (title && (cols < (len = mbstrlen (title) + 2))) + cols = len; + + /* no &, but 4 spaces around button for brackets and such */ +- if (cols < (len = strlen (cancel_string) + 3)) ++ if (cols < (len = mbstrlen (cancel_string) + 3)) + cols = len; + + cols = cols > COLS - 6 ? COLS - 6 : cols; +@@ -123,7 +123,7 @@ + va_start (ap, count); + for (i = 0; i < count; i++) { + char *cp = va_arg (ap, char *); +- win_len += strlen (cp) + 6; ++ win_len += mbstrlen (cp) + 6; + if (strchr (cp, '&') != NULL) + win_len--; + } +@@ -131,7 +131,7 @@ + } + + /* count coordinates */ +- cols = 6 + max (win_len, max ((int) strlen (header), msglen (text, &lines))); ++ cols = 6 + max (win_len, max ((int) mbstrlen (header), msglen (text, &lines))); + lines += 4 + (count > 0 ? 2 : 0); + xpos = COLS / 2 - cols / 2; + ypos = LINES / 3 - (lines - 3) / 2; +@@ -146,7 +146,7 @@ + va_start (ap, count); + for (i = 0; i < count; i++) { + cur_name = va_arg (ap, char *); +- xpos = strlen (cur_name) + 6; ++ xpos = mbstrlen (cur_name) + 6; + if (strchr (cur_name, '&') != NULL) + xpos--; + +@@ -457,7 +457,7 @@ + g_strlcpy (histname + 3, header, 61); + quick_widgets[2].histname = histname; + +- len = max ((int) strlen (header), msglen (text, &lines)) + 4; ++ len = max ((int) mbstrlen (header), msglen (text, &lines)) + 4; + len = max (len, 64); + + /* The special value of def_text is used to identify password boxes +@@ -477,7 +477,7 @@ + */ + quick_widgets[0].relative_x = len / 2 + 4; + quick_widgets[1].relative_x = +- len / 2 - (strlen (_(quick_widgets[1].text)) + 9); ++ len / 2 - (mbstrlen (_(quick_widgets[1].text)) + 9); + quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len; + #endif /* ENABLE_NLS */ + +diff -urN mc-4.6.1.orig/syntax/c.syntax mc-4.6.1/syntax/c.syntax +--- mc-4.6.1.orig/syntax/c.syntax 2005-05-31 12:03:45.000000000 +0600 ++++ mc-4.6.1/syntax/c.syntax 2007-01-19 18:33:58.000000000 +0500 +@@ -32,34 +32,7 @@ + keyword whole volatile yellow + keyword whole while yellow + keyword whole asm yellow +- keyword whole catch yellow +- keyword whole class yellow +- keyword whole friend yellow +- keyword whole delete yellow + keyword whole inline yellow +- keyword whole new yellow +- keyword whole operator yellow +- keyword whole private yellow +- keyword whole protected yellow +- keyword whole public yellow +- keyword whole this yellow +- keyword whole throw yellow +- keyword whole template yellow +- keyword whole try yellow +- keyword whole virtual yellow +- keyword whole bool yellow +- keyword whole const_cast yellow +- keyword whole dynamic_cast yellow +- keyword whole explicit yellow +- keyword whole false yellow +- keyword whole mutable yellow +- keyword whole namespace yellow +- keyword whole reinterpret_cast yellow +- keyword whole static_cast yellow +- keyword whole true yellow +- keyword whole typeid yellow +- keyword whole typename yellow +- keyword whole using yellow + keyword whole wchar_t yellow + keyword whole ... yellow + keyword whole linestart \{\s\t\}\[\s\t\]#*\n brightmagenta +diff -urN mc-4.6.1.orig/syntax/cxx.syntax mc-4.6.1/syntax/cxx.syntax +--- mc-4.6.1.orig/syntax/cxx.syntax 1970-01-01 05:00:00.000000000 +0500 ++++ mc-4.6.1/syntax/cxx.syntax 2007-01-19 18:33:58.000000000 +0500 +@@ -0,0 +1,128 @@ ++context default ++ keyword whole auto yellow ++ keyword whole break yellow ++ keyword whole case yellow ++ keyword whole char yellow ++ keyword whole const yellow ++ keyword whole continue yellow ++ keyword whole default yellow ++ keyword whole do yellow ++ keyword whole double yellow ++ keyword whole else yellow ++ keyword whole enum yellow ++ keyword whole extern yellow ++ keyword whole float yellow ++ keyword whole for yellow ++ keyword whole goto yellow ++ keyword whole if yellow ++ keyword whole int yellow ++ keyword whole long yellow ++ keyword whole register yellow ++ keyword whole return yellow ++ keyword whole short yellow ++ keyword whole signed yellow ++ keyword whole sizeof yellow ++ keyword whole static yellow ++ keyword whole struct yellow ++ keyword whole switch yellow ++ keyword whole typedef yellow ++ keyword whole union yellow ++ keyword whole unsigned yellow ++ keyword whole void yellow ++ keyword whole volatile yellow ++ keyword whole while yellow ++ keyword whole asm yellow ++ keyword whole catch yellow ++ keyword whole class yellow ++ keyword whole friend yellow ++ keyword whole delete yellow ++ keyword whole inline yellow ++ keyword whole new yellow ++ keyword whole operator yellow ++ keyword whole private yellow ++ keyword whole protected yellow ++ keyword whole public yellow ++ keyword whole this yellow ++ keyword whole throw yellow ++ keyword whole template yellow ++ keyword whole try yellow ++ keyword whole virtual yellow ++ keyword whole bool yellow ++ keyword whole const_cast yellow ++ keyword whole dynamic_cast yellow ++ keyword whole explicit yellow ++ keyword whole false yellow ++ keyword whole mutable yellow ++ keyword whole namespace yellow ++ keyword whole reinterpret_cast yellow ++ keyword whole static_cast yellow ++ keyword whole true yellow ++ keyword whole typeid yellow ++ keyword whole typename yellow ++ keyword whole using yellow ++ keyword whole wchar_t yellow ++ keyword whole ... yellow ++ keyword whole linestart \{\s\t\}\[\s\t\]#*\n brightmagenta ++ ++ keyword /\* brown ++ keyword \*/ brown ++ keyword // brown ++ ++ keyword '\\\{"abtnvfr\}' brightgreen ++ keyword '\\\{0123\}\{01234567\}\{01234567\}' brightgreen ++ keyword '\\'' brightgreen ++ keyword '\\\\' brightgreen ++ keyword '\\0' brightgreen ++ keyword '\{\s!"#$%&()\*\+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~\}' brightgreen ++ ++ keyword > yellow ++ keyword < yellow ++ keyword \+ yellow ++ keyword - yellow ++ keyword \* yellow ++ keyword / yellow ++ keyword % yellow ++ keyword = yellow ++ keyword != yellow ++ keyword == yellow ++ keyword { brightcyan ++ keyword } brightcyan ++ keyword ( brightcyan ++ keyword ) brightcyan ++ keyword [ brightcyan ++ keyword ] brightcyan ++ keyword , brightcyan ++ keyword : brightcyan ++ keyword ? brightcyan ++ keyword ; brightmagenta ++ ++context exclusive /\* \*/ brown ++ spellcheck ++ ++context exclusive // \n brown ++ spellcheck ++ ++context linestart # \n brightred ++ keyword \\\n yellow ++ keyword /\**\*/ brown ++ keyword //*\n brown ++ keyword "+" red ++ keyword <+> red ++ ++context " " green ++ spellcheck ++ keyword \\" brightgreen ++ keyword %% brightgreen ++ keyword %\[#0\s-\+,\]\[0123456789\*\]\[.\]\[0123456789\*\]\[L\]\{eEfgGoxX\} brightgreen ++ keyword %\[0\s-\+,\]\[0123456789\*\]\[.\]\[0123456789\*\]\[hl\]\{diuxX\} brightgreen ++ keyword %\[hl\]n brightgreen ++ keyword %\[-\]\[0123456789\*\]\[.\]\[0123456789\*\]s brightgreen ++ keyword %[*] brightgreen ++ keyword %c brightgreen ++ keyword %p brightgreen ++ keyword \\\{0123\}\{01234567\}\{01234567\} brightgreen ++ keyword \\\\ brightgreen ++ keyword \\' brightgreen ++ keyword \\\{abtnvfr\} brightgreen ++ ++ +diff -urN mc-4.6.1.orig/syntax/Makefile.am mc-4.6.1/syntax/Makefile.am +--- mc-4.6.1.orig/syntax/Makefile.am 2005-03-19 22:39:06.000000000 +0500 ++++ mc-4.6.1/syntax/Makefile.am 2007-01-19 18:33:58.000000000 +0500 +@@ -4,6 +4,7 @@ + aspx.syntax \ + assembler.syntax \ + c.syntax \ ++ cxx.syntax \ + cs.syntax \ + changelog.syntax \ + diff.syntax \ +diff -urN mc-4.6.1.orig/syntax/Makefile.in mc-4.6.1/syntax/Makefile.in +--- mc-4.6.1.orig/syntax/Makefile.in 2005-07-23 22:53:15.000000000 +0600 ++++ mc-4.6.1/syntax/Makefile.in 2007-01-19 18:33:58.000000000 +0500 +@@ -218,6 +218,7 @@ + aspx.syntax \ + assembler.syntax \ + c.syntax \ ++ cxx.syntax \ + cs.syntax \ + changelog.syntax \ + diff.syntax \ +diff -urN mc-4.6.1.orig/syntax/sh.syntax mc-4.6.1/syntax/sh.syntax +--- mc-4.6.1.orig/syntax/sh.syntax 2004-12-02 15:47:14.000000000 +0500 ++++ mc-4.6.1/syntax/sh.syntax 2007-01-19 18:33:58.000000000 +0500 +@@ -41,7 +41,9 @@ + keyword whole bg yellow + keyword whole break yellow + keyword whole case yellow ++ keyword whole clear yellow + keyword whole continue yellow ++ keyword whole declare yellow + keyword whole done yellow + keyword whole do yellow + keyword whole elif yellow +@@ -56,11 +58,13 @@ + keyword whole for yellow + keyword whole if yellow + keyword whole in yellow ++ keyword whole let yellow + keyword whole read yellow + keyword whole return yellow + keyword whole select yellow + keyword whole set yellow + keyword whole shift yellow ++ keyword whole source yellow + keyword whole then yellow + keyword whole trap yellow + keyword whole umask yellow +@@ -69,6 +73,8 @@ + keyword whole wait yellow + keyword whole while yellow + ++ keyword whole apt-get cyan ++ keyword whole ar cyan + keyword whole arch cyan + keyword whole ash cyan + keyword whole awk cyan +@@ -77,90 +83,204 @@ + keyword whole bg_backup cyan + keyword whole bg_restore cyan + keyword whole bsh cyan ++ keyword whole bzip cyan ++ keyword whole bzip2 cyan ++ keyword whole cam cyan + keyword whole cat cyan + keyword whole cd cyan ++ keyword whole cdda2wav cyan + keyword whole chgrp cyan + keyword whole chmod cyan + keyword whole chown cyan ++ keyword whole cmp cyan ++ keyword whole col cyan ++ keyword whole compress cyan + keyword whole cp cyan + keyword whole cpio cyan ++ keyword whole cpp cyan + keyword whole csh cyan ++ keyword whole curl cyan ++ keyword whole cut cyan + keyword whole date cyan + keyword whole dd cyan + keyword whole df cyan ++ keyword whole dialog cyan ++ keyword whole diff cyan ++ keyword whole dirname cyan + keyword whole dmesg cyan + keyword whole dnsdomainname cyan + keyword whole doexec cyan + keyword whole domainname cyan ++ keyword whole dpkg cyan ++ keyword whole dpkg-buildpackage cyan ++ keyword whole dpkg-scanpackages cyan ++ keyword whole dpkg-scansources cyan + keyword whole echo cyan + keyword whole ed cyan ++ keyword whole editor cyan + keyword whole egrep cyan + keyword whole ex cyan ++ keyword whole fakeroot cyan + keyword whole false cyan ++ keyword whole fdformat cyan ++ keyword whole fetchmail cyan + keyword whole fgrep cyan + keyword whole find cyan ++ keyword whole formail cyan ++ keyword whole free cyan ++ keyword whole freeze cyan + keyword whole fsconf cyan + keyword whole gawk cyan ++ keyword whole gdb cyan ++ keyword whole gcc cyan + keyword whole grep cyan + keyword whole gunzip cyan + keyword whole gzip cyan ++ keyword whole ha cyan + keyword whole hostname cyan + keyword whole igawk cyan ++ keyword whole insmod cyan + keyword whole ipcalc cyan ++ keyword whole iptables cyan + keyword whole kill cyan + keyword whole ksh cyan ++ keyword whole lame cyan ++ keyword whole less cyan ++ keyword whole lharc cyan ++ keyword whole lilo cyan ++ keyword whole linux_logo cyan + keyword whole linuxconf cyan + keyword whole ln cyan ++ keyword whole locale cyan ++ keyword whole logger cyan + keyword whole login cyan + keyword whole lpdconf cyan + keyword whole ls cyan ++ keyword whole lynx cyan + keyword whole mail cyan ++ keyword whole man cyan ++ keyword whole mc cyan ++ keyword whole mcedit cyan ++ keyword whole mcview cyan ++ keyword whole mimedecode cyan + keyword whole mkdir cyan ++ keyword whole mkdirhier cyan ++ keyword whole mkfs.ext2 cyan ++ keyword whole mkfs.ext3 cyan ++ keyword whole mkfs.minix cyan ++ keyword whole mkfs.msdos cyan ++ keyword whole mke2fs cyan ++ keyword whole mkdosfs cyan ++ keyword whole mkinitrd cyan + keyword whole mknod cyan + keyword whole mktemp cyan ++ keyword whole modprobe cyan + keyword whole more cyan + keyword whole mount cyan ++ keyword whole mozilla cyan ++ keyword whole mp3info cyan ++ keyword whole munpack cyan ++ keyword whole msgfmt cyan + keyword whole mt cyan ++ keyword whole mutt cyan + keyword whole mv cyan + keyword whole netconf cyan + keyword whole netstat cyan + keyword whole nice cyan + keyword whole nisdomainname cyan ++ keyword whole nm cyan ++ keyword whole patch cyan ++ keyword whole pinfo cyan + keyword whole ping cyan ++ keyword whole procmail cyan + keyword whole ps cyan + keyword whole pwd cyan ++ keyword whole rar cyan + keyword whole red cyan + keyword whole remadmin cyan ++ keyword whole rename cyan + keyword whole rm cyan + keyword whole rmdir cyan ++ keyword whole rmmod cyan ++ keyword whole rplay cyan + keyword whole rpm cyan ++ keyword whole rpm2cpio cyan + keyword whole sed cyan + keyword whole set cyan + keyword whole setserial cyan + keyword whole sh cyan + keyword whole sleep cyan + keyword whole sort cyan ++ keyword whole sa-learn cyan ++ keyword whole spamassassin cyan ++ keyword whole spamc cyan ++ keyword whole spamd cyan ++ keyword whole ssmtp cyan ++ keyword whole strace cyan + keyword whole stty cyan + keyword whole su cyan + keyword whole sync cyan + keyword whole taper cyan + keyword whole tar cyan ++ keyword whole tcpdump cyan + keyword whole tcsh cyan + keyword whole test cyan ++ keyword whole tempfile cyan + keyword whole time cyan ++ keyword whole tnef cyan + keyword whole touch cyan ++ keyword whole tr cyan + keyword whole true cyan ++ keyword whole tune2fs cyan + keyword whole umount cyan + keyword whole uname cyan ++ keyword whole unarj cyan ++ keyword whole uniq cyan ++ keyword whole unzip cyan ++ keyword whole uptime cyan + keyword whole userconf cyan + keyword whole usleep cyan + keyword whole vi cyan + keyword whole view cyan + keyword whole vim cyan ++ keyword whole wc cyan ++ keyword whole wget cyan ++ keyword whole whiptail cyan ++ keyword whole wvWare cyan + keyword whole xconf cyan ++ keyword whole xgettext cyan ++ keyword whole xmessage cyan ++ keyword whole xmodmap cyan ++ keyword whole xterm cyan + keyword whole ypdomainname cyan + keyword whole zcat cyan ++ keyword whole zgv cyan ++ keyword whole zip cyan ++ keyword whole zoo cyan + keyword whole zsh cyan ++ keyword whole Xdialog cyan ++ ++ keyword whole gpg red ++ keyword whole md5sum red ++ keyword whole openssl red ++ keyword whole ssh red ++ ++ keyword whole TEXTDOMAINDIR magenta ++ keyword whole TEXTDOMAIN magenta ++ keyword whole VERSION magenta ++ ++ keyword whole jpegtopnm cyan ++ keyword whole pnmscale cyan ++ keyword whole ppmtoxpm cyan ++ ++ keyword whole /dev/audio brightblue ++ keyword whole /dev/dsp brightblue ++ keyword whole /dev/null brightblue ++ keyword whole /dev/mixed brightblue ++ keyword whole /dev/stdin brightblue ++ keyword whole /dev/stdout brightblue ++ keyword whole /dev/stderr brightblue ++ keyword whole /dev/zero brightblue + + wholechars abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ + +@@ -224,7 +344,9 @@ + + keyword whole break yellow + keyword whole case yellow ++ keyword whole clear yellow + keyword whole continue yellow ++ keyword whole declare yellow + keyword whole done yellow + keyword whole do yellow + keyword whole elif yellow +@@ -238,11 +360,15 @@ + keyword whole return yellow + keyword whole select yellow + keyword whole shift yellow ++ keyword whole source yellow + keyword whole then yellow + keyword whole trap yellow + keyword whole until yellow ++ keyword whole wait yellow + keyword whole while yellow + ++ keyword whole apt-get cyan ++ keyword whole ar cyan + keyword whole arch cyan + keyword whole ash cyan + keyword whole awk cyan +@@ -251,89 +377,194 @@ + keyword whole bg_backup cyan + keyword whole bg_restore cyan + keyword whole bsh cyan ++ keyword whole bzip cyan ++ keyword whole bzip2 cyan ++ keyword whole cam cyan + keyword whole cat cyan + keyword whole cd cyan ++ keyword whole cdda2wav cyan + keyword whole chgrp cyan + keyword whole chmod cyan + keyword whole chown cyan ++ keyword whole cmp cyan ++ keyword whole col cyan ++ keyword whole compress cyan + keyword whole cp cyan + keyword whole cpio cyan ++ keyword whole cpp cyan + keyword whole csh cyan ++ keyword whole curl cyan ++ keyword whole cut cyan + keyword whole date cyan + keyword whole dd cyan + keyword whole df cyan ++ keyword whole dialog cyan ++ keyword whole diff cyan ++ keyword whole dirname cyan + keyword whole dmesg cyan + keyword whole dnsdomainname cyan + keyword whole doexec cyan + keyword whole domainname cyan ++ keyword whole dpkg cyan ++ keyword whole dpkg-buildpackage cyan ++ keyword whole dpkg-scanpackages cyan ++ keyword whole dpkg-scansources cyan + keyword whole echo cyan + keyword whole ed cyan ++ keyword whole editor cyan + keyword whole egrep cyan + keyword whole ex cyan ++ keyword whole fakeroot cyan + keyword whole false cyan ++ keyword whole fdformat cyan ++ keyword whole fetchmail cyan + keyword whole fgrep cyan + keyword whole find cyan ++ keyword whole free cyan ++ keyword whole freeze cyan + keyword whole fsconf cyan + keyword whole gawk cyan ++ keyword whole gdb cyan ++ keyword whole gcc cyan + keyword whole grep cyan + keyword whole gunzip cyan + keyword whole gzip cyan ++ keyword whole ha cyan + keyword whole hostname cyan + keyword whole igawk cyan ++ keyword whole insmod cyan ++ keyword whole iptables cyan + keyword whole ipcalc cyan + keyword whole kill cyan + keyword whole ksh cyan ++ keyword whole lame cyan ++ keyword whole less cyan ++ keyword whole lharc cyan ++ keyword whole lilo cyan ++ keyword whole linux_logo cyan + keyword whole linuxconf cyan + keyword whole ln cyan ++ keyword whole locale cyan ++ keyword whole logger cyan + keyword whole login cyan + keyword whole lpdconf cyan + keyword whole ls cyan ++ keyword whole lynx cyan + keyword whole mail cyan ++ keyword whole man cyan ++ keyword whole mc cyan ++ keyword whole mcedit cyan ++ keyword whole mcview cyan ++ keyword whole mimedecode cyan + keyword whole mkdir cyan ++ keyword whole mkdirhier cyan ++ keyword whole mkfs.ext2 cyan ++ keyword whole mkfs.ext3 cyan ++ keyword whole mkfs.minix cyan ++ keyword whole mkfs.msdos cyan ++ keyword whole mke2fs cyan ++ keyword whole mkdosfs cyan ++ keyword whole mkinitrd cyan + keyword whole mknod cyan + keyword whole mktemp cyan ++ keyword whole modprobe cyan + keyword whole more cyan + keyword whole mount cyan ++ keyword whole mozilla cyan ++ keyword whole mp3info cyan ++ keyword whole msgfmt cyan + keyword whole mt cyan ++ keyword whole mutt cyan + keyword whole mv cyan + keyword whole netconf cyan + keyword whole netstat cyan + keyword whole nice cyan + keyword whole nisdomainname cyan ++ keyword whole nm cyan ++ keyword whole patch cyan ++ keyword whole pinfo cyan + keyword whole ping cyan + keyword whole ps cyan + keyword whole pwd cyan ++ keyword whole rar cyan + keyword whole red cyan + keyword whole remadmin cyan ++ keyword whole rename cyan + keyword whole rm cyan + keyword whole rmdir cyan ++ keyword whole rmmod cyan ++ keyword whole rplay cyan + keyword whole rpm cyan ++ keyword whole rpm2cpio cyan + keyword whole sed cyan + keyword whole set cyan + keyword whole setserial cyan + keyword whole sh cyan + keyword whole sleep cyan + keyword whole sort cyan ++ keyword whole sa-learn cyan ++ keyword whole spamassassin cyan ++ keyword whole spamc cyan ++ keyword whole spamd cyan ++ keyword whole ssmtp cyan ++ keyword whole strace cyan + keyword whole stty cyan + keyword whole su cyan + keyword whole sync cyan + keyword whole taper cyan + keyword whole tar cyan ++ keyword whole tcpdump cyan + keyword whole tcsh cyan ++ keyword whole tempfile cyan + keyword whole test cyan + keyword whole time cyan ++ keyword whole tnef cyan + keyword whole touch cyan ++ keyword whole tr cyan + keyword whole true cyan ++ keyword whole tune2fs cyan + keyword whole umount cyan + keyword whole uname cyan ++ keyword whole unarj cyan ++ keyword whole uniq cyan ++ keyword whole unzip cyan ++ keyword whole uptime cyan + keyword whole userconf cyan + keyword whole usleep cyan + keyword whole vi cyan + keyword whole view cyan + keyword whole vim cyan ++ keyword whole wc cyan ++ keyword whole wget cyan ++ keyword whole whiptail cyan ++ keyword whole wvWare cyan + keyword whole xconf cyan ++ keyword whole xgettext cyan ++ keyword whole xmessage cyan ++ keyword whole xmodmap cyan ++ keyword whole xterm cyan + keyword whole ypdomainname cyan + keyword whole zcat cyan ++ keyword whole zgv cyan ++ keyword whole zoo cyan ++ keyword whole zip cyan + keyword whole zsh cyan ++ keyword whole Xdialog cyan + +- ++ keyword whole gpg red ++ keyword whole md5sum red ++ keyword whole openssl red ++ keyword whole ssh red ++ ++ keyword whole TEXTDOMAINDIR magenta ++ keyword whole TEXTDOMAIN magenta ++ keyword whole VERSION magenta ++ ++ keyword whole /dev/audio brightblue ++ keyword whole /dev/dsp brightblue ++ keyword whole /dev/null brightblue ++ keyword whole /dev/mixed brightblue ++ keyword whole /dev/stdin brightblue ++ keyword whole /dev/stdout brightblue ++ keyword whole /dev/stderr brightblue ++ keyword whole /dev/zero brightblue +diff -urN mc-4.6.1.orig/syntax/Syntax mc-4.6.1/syntax/Syntax +--- mc-4.6.1.orig/syntax/Syntax 2005-05-26 13:21:34.000000000 +0600 ++++ mc-4.6.1/syntax/Syntax 2007-01-19 18:33:58.000000000 +0500 +@@ -45,9 +45,10 @@ + file ..\*\\.(rb|RB)$ Ruby\sProgram ^#!.\*([\s/]ruby|@RUBY@) + include ruby.syntax + +-file ..\*\\.(man|[0-9n]|[0-9]x)$ NROFF\sSource ++file ..\*\\.(man|[0-9n]|[0-9](x|ncurses|ssl|p|pm|menu|form|vga|t|td))$ NROFF\sSource + include nroff.syntax + ++ + file ..\*\\.(htm|html|HTM|HTML)$ HTML\sFile + include html.syntax + +@@ -72,9 +73,12 @@ + file ..\*\.(texi|texinfo|TEXI|TEXINFO)$ Texinfo\sDocument + include texinfo.syntax + +-file ..\*\\.([chC]|CC|cxx|cc|cpp|CPP|CXX|hxx|h\.in)$ C/C\+\+\sProgram ++file ..\*\\.c$ C\sProgram + include c.syntax + ++file ..\*\\.([hC]|CC|cxx|cc|cpp|CPP|CXX|hxx|h\.in)$ C/C\+\+\sProgram ++include cxx.syntax ++ + file ..\*\\.[fF]$ Fortran\sProgram + include fortran.syntax + +diff -urN mc-4.6.1.orig/vfs/cpio.c mc-4.6.1/vfs/cpio.c +--- mc-4.6.1.orig/vfs/cpio.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/cpio.c 2007-01-19 18:33:58.000000000 +0500 +@@ -83,7 +83,7 @@ + struct vfs_s_inode *inode; + }; + +-static int cpio_position; ++static off_t cpio_position; + + static int cpio_find_head(struct vfs_class *me, struct vfs_s_super *super); + static int cpio_read_bin_head(struct vfs_class *me, struct vfs_s_super *super); +@@ -107,7 +107,7 @@ + return l; + } + +-static int cpio_skip_padding(struct vfs_s_super *super) ++static off_t cpio_skip_padding(struct vfs_s_super *super) + { + switch(super->u.arch.type) { + case CPIO_BIN: +diff -urN mc-4.6.1.orig/vfs/direntry.c mc-4.6.1/vfs/direntry.c +--- mc-4.6.1.orig/vfs/direntry.c 2004-11-29 23:44:49.000000000 +0500 ++++ mc-4.6.1/vfs/direntry.c 2007-01-19 18:33:58.000000000 +0500 +@@ -243,7 +243,13 @@ + char * const pathref = g_strdup (a_path); + char *path = pathref; + +- canonicalize_pathname (path); ++ if (strncmp(me->name, "ftpfs", 5) != 0) ++ canonicalize_pathname (path); ++ else { ++ char *p = path + strlen (path) - 1; ++ while (p > path && *p == PATH_SEP) ++ *p-- = 0; ++ } + + while (root) { + while (*path == PATH_SEP) /* Strip leading '/' */ +@@ -313,7 +319,13 @@ + if (root->super->root != root) + vfs_die ("We have to use _real_ root. Always. Sorry."); + +- canonicalize_pathname (path); ++ if (strncmp (me->name, "ftpfs", 5) != 0) ++ canonicalize_pathname (path); ++ else { ++ char *p = path + strlen (path) - 1; ++ while (p > path && *p == PATH_SEP) ++ *p-- = 0; ++ } + + if (!(flags & FL_DIR)) { + char *dirname, *name, *save; +@@ -836,13 +848,13 @@ + return 0; + } + +-static int ++static off_t + vfs_s_lseek (void *fh, off_t offset, int whence) + { + off_t size = FH->ino->st.st_size; + + if (FH->handle != -1){ /* If we have local file opened, we want to work with it */ +- int retval = lseek (FH->handle, offset, whence); ++ off_t retval = lseek (FH->handle, offset, whence); + if (retval == -1) + FH->ino->super->me->verrno = errno; + return retval; +diff -urN mc-4.6.1.orig/vfs/extfs/uzip.in mc-4.6.1/vfs/extfs/uzip.in +--- mc-4.6.1.orig/vfs/extfs/uzip.in 2004-09-02 06:16:33.000000000 +0600 ++++ mc-4.6.1/vfs/extfs/uzip.in 2007-01-19 18:33:58.000000000 +0500 +@@ -34,6 +34,14 @@ + # Command used to extract a file to standard out + my $cmd_extract = "$app_unzip -p"; + ++# -rw-r--r-- 2.2 unx 2891 tx 1435 defN 20000330.211927 ./edit.html ++# (perm) (?) (?) (size) (?) (zippedsize) (method) (yyyy)(mm)(dd)(HH)(MM) (fname) ++my $regex_zipinfo_line = qr"^(\S{7,10})\s+(\d+\.\d+)\s+(\S+)\s+(\d+)\s+(\S\S)\s+(\d+)\s+(\S{4})\s+(\d{4})(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)\s(.*)$"; ++ ++# 2891 Defl:N 1435 50% 03-30-00 21:19 50cbaaf8 ./edit.html ++# (size) (method) (zippedsize) (zipratio) (mm)(dd)(yy)(HH)(MM) (cksum) (fname) ++my $regex_nonzipinfo_line = qr"^\s*(\d+)\s+(\S+)\s+(\d+)\s+(-?\d+\%)\s+(\d?\d)-(\d?\d)-(\d\d)\s+(\d?\d):(\d\d)\s+([0-9a-f]+)\s\s(.*)$"; ++ + # + # Main code + # +@@ -50,6 +58,50 @@ + my $cmd_list = ($op_has_zipinfo ? $cmd_list_zi : $cmd_list_nzi); + my ($qarchive, $aqarchive) = map (quotemeta, $archive, $aarchive); + ++# Strip all "." and ".." path components from a pathname. ++sub zipfs_canonicalize_pathname($) { ++ my ($fname) = @_; ++ $fname =~ s,/+,/,g; ++ $fname =~ s,(^|/)(?:\.?\./)+,$1,; ++ return $fname; ++} ++ ++# The Midnight Commander never calls this script with archive pathnames ++# starting with either "./" or "../". Some ZIP files contain such names, ++# so we need to build a translation table for them. ++my $zipfs_realpathname_table = undef; ++sub zipfs_realpathname($) { ++ my ($fname) = @_; ++ ++ if (!defined($zipfs_realpathname_table)) { ++ $zipfs_realpathname_table = {}; ++ if (!open(ZIP, "$cmd_list $qarchive |")) { ++ return $fname; ++ } ++ foreach my $line () { ++ $line =~ s/\r*\n*$//; ++ if ($op_has_zipinfo) { ++ if ($line =~ $regex_zipinfo_line) { ++ my ($fname) = ($14); ++ $zipfs_realpathname_table->{zipfs_canonicalize_pathname($fname)} = $fname; ++ } ++ } else { ++ if ($line =~ $regex_nonzipinfo_line) { ++ my ($fname) = ($11); ++ $zipfs_realpathname_table->{zipfs_canonicalize_pathname($fname)} = $fname; ++ } ++ } ++ } ++ if (!close(ZIP)) { ++ return $fname; ++ } ++ } ++ if (exists($zipfs_realpathname_table->{$fname})) { ++ return $zipfs_realpathname_table->{$fname}; ++ } ++ return $fname; ++} ++ + if ($cmd eq 'list') { &mczipfs_list(@ARGV); } + if ($cmd eq 'rm') { &mczipfs_rm(@ARGV); } + if ($cmd eq 'rmdir') { &mczipfs_rmdir(@ARGV); } +@@ -63,7 +115,12 @@ + + # Remove a file from the archive. + sub mczipfs_rm { +- my ($qfile) = map { &zipquotemeta($_) } @_; ++ my ($qfile) = map { &zipquotemeta(zipfs_realpathname($_)) } @_; ++ ++ # "./" at the beginning of pathnames is stripped by Info-ZIP, ++ # so convert it to "[.]/" to prevent stripping. ++ $qfile =~ s/^\\\./[.]/; ++ + &checkargs(1, 'archive file', @_); + &safesystem("$cmd_delete $qarchive $qfile >/dev/null"); + exit; +@@ -74,7 +131,7 @@ + # additional slash to the directory name to remove. I am not + # sure this is absolutely necessary, but it doesn't hurt. + sub mczipfs_rmdir { +- my ($qfile) = map { &zipquotemeta($_) } @_; ++ my ($qfile) = map { &zipquotemeta(zipfs_realpathname($_)) } @_; + &checkargs(1, 'archive directory', @_); + &safesystem("$cmd_delete $qarchive $qfile/ >/dev/null", 12); + exit; +@@ -84,7 +141,7 @@ + # Note that we don't need to check if the file is a link, + # because mc apparently doesn't call copyout for symbolic links. + sub mczipfs_copyout { +- my ($qafile, $qfsfile) = map { &zipquotemeta($_) } @_; ++ my ($qafile, $qfsfile) = map { &zipquotemeta(zipfs_realpathname($_)) } @_; + &checkargs(1, 'archive file', @_); + &checkargs(2, 'local file', @_); + &safesystem("$cmd_extract $qarchive $qafile > $qfsfile", 11); +@@ -195,14 +252,14 @@ + next if /^Archive:/; + next if /^\d+ file/; + next if /^Empty zipfile\.$/; +- my @match = /^(.{10}) +([\d.]+) +([a-z\d]+) +(\d+) +([^ ]{2}) +(\d+) +([^ ]{4}) +(\d{4})(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d) +(.*)$/; ++ my @match = /$regex_zipinfo_line/; + next if ($#match != 13); + &checked_print_file(@match); + } + } else { + while () { + chomp; +- my @match = /^ *(\d+) +([^ ]+) +(\d+) +(-?\d+\%) +(\d?\d)-(\d?\d)-(\d\d) (\d?\d):(\d\d) +([0-9a-f]+) +(.*)$/; ++ my @match = /$regex_nonzipinfo_line/; + next if ($#match != 10); + my @rmatch = ('', '', 'unknown', $match[0], '', $match[2], $match[1], + $match[6] + ($match[6] < 70 ? 2000 : 1900), $match[4], $match[5], +@@ -230,7 +287,7 @@ + sub mczipfs_run { + my ($afile) = @_; + &checkargs(1, 'archive file', @_); +- my $qafile = &zipquotemeta($afile); ++ my $qafile = &zipquotemeta(zipfs_realpathname($afile)); + my $tmpdir = &mktmpdir(); + my $tmpfile = File::Basename::basename($afile); + +diff -urN mc-4.6.1.orig/vfs/extfs.c mc-4.6.1/vfs/extfs.c +--- mc-4.6.1.orig/vfs/extfs.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/extfs.c 2007-01-19 18:33:58.000000000 +0500 +@@ -1125,7 +1125,7 @@ + return 0; + } + +-static int extfs_lseek (void *data, off_t offset, int whence) ++static off_t extfs_lseek (void *data, off_t offset, int whence) + { + struct pseudofile *file = (struct pseudofile *) data; + +diff -urN mc-4.6.1.orig/vfs/ftpfs.c mc-4.6.1/vfs/ftpfs.c +--- mc-4.6.1.orig/vfs/ftpfs.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/ftpfs.c 2007-01-19 18:33:58.000000000 +0500 +@@ -114,7 +114,7 @@ + int ftpfs_use_unix_list_options = 1; + + /* First "CWD ", then "LIST -la ." */ +-int ftpfs_first_cd_then_ls; ++int ftpfs_first_cd_then_ls = 1; + + /* Use the ~/.netrc */ + int use_netrc = 1; +diff -urN mc-4.6.1.orig/vfs/local.c mc-4.6.1/vfs/local.c +--- mc-4.6.1.orig/vfs/local.c 2004-09-25 05:00:18.000000000 +0600 ++++ mc-4.6.1/vfs/local.c 2007-01-19 18:33:58.000000000 +0500 +@@ -197,7 +197,7 @@ + return chdir (path); + } + +-int ++off_t + local_lseek (void *data, off_t offset, int whence) + { + int fd = * (int *) data; +diff -urN mc-4.6.1.orig/vfs/local.h mc-4.6.1/vfs/local.h +--- mc-4.6.1.orig/vfs/local.h 2004-08-17 15:17:43.000000000 +0600 ++++ mc-4.6.1/vfs/local.h 2007-01-19 18:33:58.000000000 +0500 +@@ -11,7 +11,7 @@ + extern int local_read (void *data, char *buffer, int count); + extern int local_fstat (void *data, struct stat *buf); + extern int local_errno (struct vfs_class *me); +-extern int local_lseek (void *data, off_t offset, int whence); ++extern off_t local_lseek (void *data, off_t offset, int whence); + #ifdef HAVE_MMAP + extern caddr_t local_mmap (struct vfs_class *me, caddr_t addr, size_t len, + int prot, int flags, void *data, off_t offset); +diff -urN mc-4.6.1.orig/vfs/mcfs.c mc-4.6.1/vfs/mcfs.c +--- mc-4.6.1.orig/vfs/mcfs.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/mcfs.c 2007-01-19 18:33:58.000000000 +0500 +@@ -1037,7 +1037,7 @@ + return 0; + } + +-static int ++static off_t + mcfs_lseek (void *data, off_t offset, int whence) + { + mcfs_handle *info = (mcfs_handle *) data; +diff -urN mc-4.6.1.orig/vfs/smbfs.c mc-4.6.1/vfs/smbfs.c +--- mc-4.6.1.orig/vfs/smbfs.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/smbfs.c 2007-01-19 18:33:58.000000000 +0500 +@@ -283,7 +283,7 @@ + static int + smbfs_init (struct vfs_class * me) + { +- const char *servicesf = CONFIGDIR PATH_SEP_STR "smb.conf"; ++ const char *servicesf = CONFIGDIR PATH_SEP_STR "samba/smb.conf"; + + /* DEBUGLEVEL = 4; */ + +@@ -1585,7 +1585,7 @@ + + #define smbfs_lstat smbfs_stat /* no symlinks on smb filesystem? */ + +-static int ++static off_t + smbfs_lseek (void *data, off_t offset, int whence) + { + smbfs_handle *info = (smbfs_handle *) data; +diff -urN mc-4.6.1.orig/vfs/tar.c mc-4.6.1/vfs/tar.c +--- mc-4.6.1.orig/vfs/tar.c 2005-07-23 22:52:04.000000000 +0600 ++++ mc-4.6.1/vfs/tar.c 2007-01-19 18:33:58.000000000 +0500 +@@ -194,7 +194,7 @@ + } + + /* As we open one archive at a time, it is safe to have this static */ +-static int current_tar_position = 0; ++static off_t current_tar_position = 0; + + /* Returns fd of the open tar file */ + static int +@@ -461,7 +461,7 @@ + struct stat st; + struct vfs_s_entry *entry; + struct vfs_s_inode *inode, *parent; +- long data_position; ++ off_t data_position; + char *q; + int len; + char *current_file_name, *current_link_name; +@@ -646,8 +646,9 @@ + int fd = FH_SUPER->u.arch.fd; + struct vfs_class *me = FH_SUPER->me; + +- if (mc_lseek (fd, begin + FH->pos, SEEK_SET) != +- begin + FH->pos) ERRNOR (EIO, -1); ++ ++ off_t o = mc_lseek(fd, begin + FH->pos, SEEK_SET); ++ if ( o != begin + FH->pos) ERRNOR (EIO, -1); + + count = MIN(count, FH->ino->st.st_size - FH->pos); + +diff -urN mc-4.6.1.orig/vfs/undelfs.c mc-4.6.1/vfs/undelfs.c +--- mc-4.6.1.orig/vfs/undelfs.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/undelfs.c 2007-01-19 18:33:58.000000000 +0500 +@@ -645,7 +645,7 @@ + } + + /* this has to stay here for now: vfs layer does not know how to emulate it */ +-static int ++static off_t + undelfs_lseek(void *vfs_info, off_t offset, int whence) + { + return -1; +diff -urN mc-4.6.1.orig/vfs/vfs.c mc-4.6.1/vfs/vfs.c +--- mc-4.6.1.orig/vfs/vfs.c 2005-05-27 20:19:19.000000000 +0600 ++++ mc-4.6.1/vfs/vfs.c 2007-01-19 18:33:59.000000000 +0500 +@@ -49,6 +49,11 @@ + #include "smbfs.h" + #include "local.h" + ++#include "../src/panel.h" ++#ifdef HAVE_CHARSET ++#include "../src/recode.h" ++#endif ++ + /* They keep track of the current directory */ + static struct vfs_class *current_vfs; + static char *current_dir; +@@ -623,14 +628,14 @@ + off_t mc_lseek (int fd, off_t offset, int whence) + { + struct vfs_class *vfs; +- int result; ++ off_t result; + + if (fd == -1) + return -1; + + vfs = vfs_op (fd); + result = vfs->lseek ? (*vfs->lseek)(vfs_info (fd), offset, whence) : -1; +- if (result == -1) ++ if (result == (off_t)-1) + errno = vfs->lseek ? ferrno (vfs) : E_NOTSUPP; + return result; + } +@@ -681,8 +686,66 @@ + vfsid old_vfsid; + int result; + ++#ifdef HAVE_CHARSET ++ char* errmsg; ++#endif ++ WPanel* p=ret_panel; ++ + new_dir = vfs_canon (path); + new_vfs = vfs_get_class (new_dir); ++ old_vfsid = vfs_getid (current_vfs, current_dir); ++ old_vfs = current_vfs; ++ ++ if(p) { ++ ++ // Change from localfs to ftpfs ++ ret_panel=NULL; ++ if( (strcmp(old_vfs->name,"localfs")==0) && ++ (strcmp(new_vfs->name,"ftpfs")==0)){ ++ p->is_return=1; ++ strncpy(p->retdir,current_dir, MC_MAXPATHLEN); ++#ifdef HAVE_CHARSET ++ p->ret_codepage=p->src_codepage; ++ p->src_codepage=ftp_codepage; ++ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++#endif ++ } ++ ++ // Change from ftpfs to localfs ++ if( (strcmp(old_vfs->name,"ftpfs")==0) && ++ (strcmp(new_vfs->name,"localfs")==0) && ++ p->is_return){ ++ p->is_return=0; ++ g_free(new_dir); ++ new_dir = vfs_canon (p->retdir); ++ new_vfs = vfs_get_class (new_dir); ++#ifdef HAVE_CHARSET ++ p->src_codepage=p->ret_codepage; ++ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++#endif ++ } ++ } ++ ++ ++ + if (!new_vfs->chdir) { + g_free (new_dir); + return -1; +@@ -696,9 +759,6 @@ + return -1; + } + +- old_vfsid = vfs_getid (current_vfs, current_dir); +- old_vfs = current_vfs; +- + /* Actually change directory */ + g_free (current_dir); + current_dir = new_dir; +diff -urN mc-4.6.1.orig/vfs/vfs-impl.h mc-4.6.1/vfs/vfs-impl.h +--- mc-4.6.1.orig/vfs/vfs-impl.h 2004-09-02 19:57:59.000000000 +0600 ++++ mc-4.6.1/vfs/vfs-impl.h 2007-01-19 18:33:58.000000000 +0500 +@@ -53,7 +53,7 @@ + int (*rename) (struct vfs_class *me, const char *p1, const char *p2); + int (*chdir) (struct vfs_class *me, const char *path); + int (*ferrno) (struct vfs_class *me); +- int (*lseek) (void *vfs_info, off_t offset, int whence); ++ off_t (*lseek) (void *vfs_info, off_t offset, int whence); + int (*mknod) (struct vfs_class *me, const char *path, int mode, int dev); + + vfsid (*getid) (struct vfs_class *me, const char *path); +diff -urN mc-4.6.1.orig/vfs/xdirentry.h mc-4.6.1/vfs/xdirentry.h +--- mc-4.6.1.orig/vfs/xdirentry.h 2004-10-07 00:04:15.000000000 +0600 ++++ mc-4.6.1/vfs/xdirentry.h 2007-01-19 18:33:58.000000000 +0500 +@@ -90,7 +90,7 @@ + char *linkname; /* Symlink's contents */ + char *localname; /* Filename of local file, if we have one */ + struct timeval timestamp; /* Subclass specific */ +- long data_offset; /* Subclass specific */ ++ off_t data_offset; /* Subclass specific */ + }; + + /* Data associated with an open file */ diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a67b4cc2f180..c93ea90b34c7 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1012,7 +1012,7 @@ let }; mc = import ../tools/misc/mc { - inherit fetchurl stdenv pkgconfig ncurses shebangfix perl zip; + inherit fetchurl stdenv lib pkgconfig ncurses shebangfix perl zip unzip slang gettext; inherit (gtkLibs) glib; inherit (xlibs) libX11; }; @@ -4143,7 +4143,7 @@ let }; slang = import ../development/libraries/slang { - inherit fetchurl stdenv pcre libpng; + inherit fetchurl stdenv ncurses pcre libpng zlib readline; }; snack = import ../development/libraries/snack {