diff --git a/doc/packages-list.txt b/doc/packages-list.txt
index 378df3846..186a6b994 100644
--- a/doc/packages-list.txt
+++ b/doc/packages-list.txt
@@ -1,4 +1,4 @@
-== List of softwares used to build IPFire Version: 2.3 ==
+== List of softwares used to build IPFire Version: 2.3-beta1 ==
* Archive-Tar-1.29
* Archive-Zip-1.16
* BerkeleyDB-0.27
diff --git a/lfs/dm9601 b/lfs/dm9601
deleted file mode 100644
index 1af9a2f19..000000000
--- a/lfs/dm9601
+++ /dev/null
@@ -1,92 +0,0 @@
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see . #
-# #
-###############################################################################
-
-###############################################################################
-# Definitions
-###############################################################################
-
-include Config
-
-VER = 2.6
-
-THISAPP = dm9601-$(VER)
-DL_FILE = $(THISAPP).tgz
-DL_FROM = $(URL_IPFIRE)
-DIR_APP = $(DIR_SRC)/$(THISAPP)
-ifeq "$(SMP)" "1"
- TARGET = $(DIR_INFO)/$(THISAPP)-smp
-else
- TARGET = $(DIR_INFO)/$(THISAPP)
-endif
-
-
-###############################################################################
-# Top-level Rules
-###############################################################################
-
-objects = $(DL_FILE)
-
-$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-
-$(DL_FILE)_MD5 = e041c02477d8e19d79ae07d168ab3f73
-
-install : $(TARGET)
-
-check : $(patsubst %,$(DIR_CHK)/%,$(objects))
-
-download :$(patsubst %,$(DIR_DL)/%,$(objects))
-
-md5 : $(subst %,%_MD5,$(objects))
-
-dist:
- $(PAK)
-
-###############################################################################
-# Downloading, checking, md5sum
-###############################################################################
-
-$(patsubst %,$(DIR_CHK)/%,$(objects)) :
- @$(CHECK)
-
-$(patsubst %,$(DIR_DL)/%,$(objects)) :
- @$(LOAD)
-
-$(subst %,%_MD5,$(objects)) :
- @$(MD5)
-
-###############################################################################
-# Installation Details
-###############################################################################
-
-$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
- @$(PREBUILD)
- @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
- cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dm9601-make+ids.patch
-ifeq "$(SMP)" "1"
- cd $(DIR_APP) && make clean
- cd $(DIR_APP) && make -C /lib/modules/$(KVER)-ipfire-smp/build/ SUBDIRS=$(DIR_APP) modules
- cd $(DIR_APP) && install -m 644 dm9601.ko /lib/modules/$(KVER)-ipfire-smp/kernel/drivers/usb/net
-else
- cd $(DIR_APP) && make clean
- cd $(DIR_APP) && make -C /lib/modules/$(KVER)-ipfire/build/ SUBDIRS=$(DIR_APP) modules
- cd $(DIR_APP) && install -m 644 dm9601.ko /lib/modules/$(KVER)-ipfire/kernel/drivers/usb/net
-endif
- @rm -rf $(DIR_APP)
- @$(POSTBUILD)
diff --git a/lfs/mcs7830 b/lfs/mcs7830
deleted file mode 100644
index e5eb43bf8..000000000
--- a/lfs/mcs7830
+++ /dev/null
@@ -1,92 +0,0 @@
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see . #
-# #
-###############################################################################
-
-###############################################################################
-# Definitions
-###############################################################################
-
-include Config
-
-VER = 060926
-
-THISAPP = mcs7830-$(VER)
-DL_FILE = $(THISAPP).tar.bz2
-DL_FROM = $(URL_IPFIRE)
-DIR_APP = $(DIR_SRC)/$(THISAPP)
-ifeq "$(SMP)" "1"
- TARGET = $(DIR_INFO)/$(THISAPP)-smp
-else
- TARGET = $(DIR_INFO)/$(THISAPP)
-endif
-
-
-###############################################################################
-# Top-level Rules
-###############################################################################
-
-objects = $(DL_FILE)
-
-$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-
-$(DL_FILE)_MD5 = 234b18d71a55ee70b06c87fc4e7516a1
-
-install : $(TARGET)
-
-check : $(patsubst %,$(DIR_CHK)/%,$(objects))
-
-download :$(patsubst %,$(DIR_DL)/%,$(objects))
-
-md5 : $(subst %,%_MD5,$(objects))
-
-dist:
- $(PAK)
-
-###############################################################################
-# Downloading, checking, md5sum
-###############################################################################
-
-$(patsubst %,$(DIR_CHK)/%,$(objects)) :
- @$(CHECK)
-
-$(patsubst %,$(DIR_DL)/%,$(objects)) :
- @$(LOAD)
-
-$(subst %,%_MD5,$(objects)) :
- @$(MD5)
-
-###############################################################################
-# Installation Details
-###############################################################################
-
-$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
- @$(PREBUILD)
- @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar jxf $(DIR_DL)/$(DL_FILE)
-
-ifeq "$(SMP)" "1"
- cd $(DIR_APP) && make clean
- cd $(DIR_APP) && make -C /lib/modules/$(KVER)-ipfire-smp/build/ SUBDIRS=$(DIR_APP) modules
- cd $(DIR_APP) && install -m 644 mcs7830.ko /lib/modules/$(KVER)-ipfire-smp/kernel/drivers/usb/net
-else
- cd $(DIR_APP) && make clean
- cd $(DIR_APP) && make -C /lib/modules/$(KVER)-ipfire/build/ SUBDIRS=$(DIR_APP) modules
- cd $(DIR_APP) && install -m 644 mcs7830.ko /lib/modules/$(KVER)-ipfire/kernel/drivers/usb/net
-endif
- @rm -rf $(DIR_APP)
- @$(POSTBUILD)
diff --git a/src/patches/cyrus-sasl-2.1.21-openldap23-1.patch b/src/patches/cyrus-sasl-2.1.21-openldap23-1.patch
deleted file mode 100644
index 81949d944..000000000
--- a/src/patches/cyrus-sasl-2.1.21-openldap23-1.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-Submitted By: Dan Nicholson
-Date: 2006-04-25
-Initial Package Version: 2.1.21
-Upstream Status: Applied
-Origin: Upstream CVS
- $ cvs log cmulocal/openldap.m4
- ...
- RCS file: /cvs/src/cmulocal/openldap.m4,v
- Working file: cmulocal/openldap.m4
- ...
- ----------------------------
- revision 1.2
- date: 2006/03/13 19:16:11; author: mel; state: Exp; lines: +3 -1
- Allow for OpenLDAP 2.3+
-Description: Allow OpenLDAP => 2.3
-
-diff -pur cyrus-sasl-2.1.21.orig/configure cyrus-sasl-2.1.21/configure
---- cyrus-sasl-2.1.21.orig/configure 2006-03-30 14:24:55.000000000 +0000
-+++ cyrus-sasl-2.1.21/configure 2006-03-30 21:00:35.388580365 +0000
-@@ -12253,6 +12253,8 @@ cat >>conftest.$ac_ext <<_ACEOF
- char *__openldap_compat = "2.1.27 or better okay";
- #elif LDAP_VENDOR_VERSION_MAJOR == 2 && LDAP_VENDOR_VERSION_MINOR == 2 && LDAP_VENDOR_VERSION_PATCH > 5
- char *__openldap_compat = "2.2.6 or better okay";
-+#elif LDAP_VENDOR_VERSION_MAJOR == 2 && LDAP_VENDOR_VERSION_MINOR > 2
-+char *__openldap_compat = "2.3 or better okay"
- #endif
-
- _ACEOF
diff --git a/src/patches/cyrus-sasl-2.1.21-openssl98-1.patch b/src/patches/cyrus-sasl-2.1.21-openssl98-1.patch
deleted file mode 100644
index a3ec2d4c0..000000000
--- a/src/patches/cyrus-sasl-2.1.21-openssl98-1.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-Submitted By: Dan Nicholson
-Date: 2006-04-25
-Initial Package Version: 2.1.21
-Upstream Status: Applied
-Origin: Upstream CVS
- http://asg.web.cmu.edu/archive/message.php?mailbox=org.acs.asg.project.sasl.commits&msg=1519
- http://asg.web.cmu.edu/archive/message.php?mailbox=org.acs.asg.project.sasl.commits&msg=1578
-Description: Adds needed headers for plugins when compiled with OpenSSL-0.9.8
-
-diff -pNur cyrus-sasl-2.1.21.orig/plugins/ntlm.c cyrus-sasl-2.1.21/plugins/ntlm.c
---- cyrus-sasl-2.1.21.orig/plugins/ntlm.c 2004-12-24 16:06:14.000000000 +0000
-+++ cyrus-sasl-2.1.21/plugins/ntlm.c 2006-04-25 18:46:24.433487794 +0000
-@@ -74,6 +74,7 @@
- #endif /* WIN32 */
-
- #include
-+#include
- #include
- #include
- #include
-diff -pNur cyrus-sasl-2.1.21.orig/plugins/passdss.c cyrus-sasl-2.1.21/plugins/passdss.c
---- cyrus-sasl-2.1.21.orig/plugins/passdss.c 2004-11-27 16:17:43.000000000 +0000
-+++ cyrus-sasl-2.1.21/plugins/passdss.c 2006-04-25 18:46:36.131787252 +0000
-@@ -67,6 +67,9 @@
- /* for digest and cipher support */
- #include
- #include
-+#include
-+#include
-+#include
-
- #include
- #define MD5_H /* suppress internal MD5 */
-diff -pNur cyrus-sasl-2.1.21.orig/plugins/srp.c cyrus-sasl-2.1.21/plugins/srp.c
---- cyrus-sasl-2.1.21.orig/plugins/srp.c 2004-06-23 18:43:37.000000000 +0000
-+++ cyrus-sasl-2.1.21/plugins/srp.c 2006-04-25 18:46:36.135785645 +0000
-@@ -87,6 +87,7 @@ typedef unsigned short uint32;
- /* for digest and cipher support */
- #include
- #include
-+#include
-
- #include
- #define MD5_H /* suppress internal MD5 */
diff --git a/src/patches/dm9601-make+ids.patch b/src/patches/dm9601-make+ids.patch
deleted file mode 100644
index 9d27d6dcc..000000000
--- a/src/patches/dm9601-make+ids.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-diff -Naur dm9601-2.6.org/dm9601.h dm9601-2.6/dm9601.h
---- dm9601-2.6.org/dm9601.h 2006-11-24 10:06:02.000000000 +0100
-+++ dm9601-2.6/dm9601.h 2008-04-04 09:54:06.000000000 +0200
-@@ -162,6 +162,8 @@
- DEFAULT_GPIO_RESET )
- DM9601_DEV( "Davicom USB-100", 0x3334, 0x1701,
- DEFAULT_GPIO_RESET )
-+DM9601_DEV( "ShanTou ST268 USB", 0x0a46, 0x0268,
-+ DEFAULT_GPIO_RESET )
- DM9601_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
- DEFAULT_GPIO_RESET )
- DM9601_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
-diff -Naur dm9601-2.6.org/Makefile dm9601-2.6/Makefile
---- dm9601-2.6.org/Makefile 2006-11-24 10:06:04.000000000 +0100
-+++ dm9601-2.6/Makefile 2008-04-03 22:34:04.000000000 +0200
-@@ -1,51 +1,17 @@
--##================================================================
--## Davicom Semiconductor Inc. For DM9601 V0.00
--## --------------------------------------------------------
--## Description:
--## Compile driver dm9601.c to dm9601.o
--##
--## Modification List:
--## 09/05/2000 Fixed SMPFALGS wrong on smp & smp_mod
--## 08/02/2000 Changed some description string & include file path
--## 07/25/2000 Append smp_mod and changed some descriptions
--## 01/25/2000 by Sten Wang
--##================================================================
--# Comment/uncomment the following line to disable/enable debugging
--#DEBUG = y
-+obj-m := dm9601.o
-
--# Add your debugging flag (or not) to CFLAGS
--ifeq ($(DEBUG),y)
-- DEBFLAGS = -O -g # "-O" is needed to expand inlines
--else
-- DEBFLAGS = -O2
--endif
--
--CFLAGS += $(DEBFLAGS) -I$(LDDINCDIR)
--
--ifneq ($(KERNELRELEASE),)
--# call from kernel build system
--
--obj-m := dm9601.o
--
--else
--
--KERNELDIR ?= /lib/modules/$(shell uname -r)/build
--PWD := $(shell pwd)
-+KDIR := /lib/modules/$(shell uname -r)/build
-+PWD := $(shell pwd)
-
- default:
-- $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINCDIR=$(PWD)/../include modules
--
--endif
--
--
-+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules;
-+install:
-+ insmod dm9601.ko
-+remove:
-+ rmmod dm9601
-
- clean:
-- rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
--
--depend .depend dep:
-- $(CC) $(CFLAGS) -M *.c > .depend
-+ rm -rf .tmp_versions Modules.symvers *.mod.c *.o *.ko .*.cmd
-
-+
-
--ifeq (.depend,$(wildcard .depend))
--include .depend
--endif
diff --git a/src/patches/epia_dma.patch b/src/patches/epia_dma.patch
deleted file mode 100644
index 203c04207..000000000
--- a/src/patches/epia_dma.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-*** orgdriver/ide/pci/via82cxxx.c Thu May 3 21:49:52 2007
---- drivers/ide/pci/via82cxxx.c Thu May 10 11:51:49 2007
-***************
-*** 67,72 ****
---- 67,76 ----
- #define VIA_NO_UNMASK 0x080 /* Doesn't work with IRQ unmasking on */
- #define VIA_BAD_ID 0x100 /* Has wrong vendor ID (0x1107) */
- #define VIA_BAD_AST 0x200 /* Don't touch Address Setup Timing */
-+ #define PCI_DEVICE_ID_VIA_VT8251 0x3287
-+ #define PCI_DEVICE_ID_VIA_VT8237A 0x3337
-+ #define PCI_DEVICE_ID_VIA_CX700 0x8324
-+ #define PCI_DEVICE_ID_VIA_CX700_IDE 0x5324
-
- /*
- * VIA SouthBridge chips.
-***************
-*** 79,84 ****
---- 83,91 ----
- u8 rev_max;
- u16 flags;
- } via_isa_bridges[] = {
-+ { "vt8251", PCI_DEVICE_ID_VIA_VT8251 , 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-+ { "vt8237a", PCI_DEVICE_ID_VIA_VT8237A , 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-+ { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
- { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
- { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
- { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-***************
-*** 498,503 ****
---- 505,511 ----
- static struct pci_device_id via_pci_tbl[] = {
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0,0},
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { 0, },
- };
diff --git a/src/patches/ffmpeg-0.4.9-pre1-amr_fixes-1.patch b/src/patches/ffmpeg-0.4.9-pre1-amr_fixes-1.patch
deleted file mode 100644
index 3435fbc8a..000000000
--- a/src/patches/ffmpeg-0.4.9-pre1-amr_fixes-1.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-Submitted By: Randy McMurchy
-Date: 2006-01-12
-Initial Package Version: 0.4.9-pre1
-Upstream Status: Applied in upstream CVS
-Origin: MPlayer-1.0pre7try2 version of FFmpeg (upstream CVS)
-Description: Fixes building with AMR code
-
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/Makefile ffmpeg-0.4.9-pre1/libavcodec/Makefile
---- ffmpeg-0.4.9-pre1-orig/libavcodec/Makefile 2004-06-18 13:11:15.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/Makefile 2006-01-12 18:27:33.000000000 +0000
-@@ -7,7 +7,7 @@
- VPATH=$(SRC_PATH)/libavcodec
-
- # NOTE: -I.. is needed to include config.h
--CFLAGS=$(OPTFLAGS) -DHAVE_AV_CONFIG_H -I.. -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE
-+CFLAGS=$(OPTFLAGS) -DHAVE_AV_CONFIG_H -I.. -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE $(AMR_CFLAGS)
-
- OBJS= common.o utils.o mem.o allcodecs.o \
- mpegvideo.o jrevdct.o jfdctfst.o jfdctint.o\
-@@ -22,14 +22,16 @@
- smc.o parser.o flicvideo.o truemotion1.o vmdav.o lcl.o qtrle.o g726.o \
- flac.o vp3dsp.o integer.o
-
-+AMROBJS=
- ifeq ($(AMR_NB),yes)
- ifeq ($(AMR_NB_FIXED),yes)
--OBJS+= amr.o
-+AMROBJS= amr.o
- AMREXTRALIBS+= amr/*.o
- AMRLIBS=amrlibs
- CLEANAMR=cleanamr
- else
--OBJS+= amr.o amr_float/sp_dec.o amr_float/sp_enc.o amr_float/interf_dec.o amr_float/interf_enc.o
-+AMROBJS= amr.o
-+OBJS+= amr_float/sp_dec.o amr_float/sp_enc.o amr_float/interf_dec.o amr_float/interf_enc.o
- CLEANAMR=cleanamrfloat
- endif
- endif
-@@ -43,13 +45,15 @@
- endif
-
- ifeq ($(AMR_WB),yes)
--OBJS+= amr.o amrwb_float/dec_acelp.o amrwb_float/dec_dtx.o amrwb_float/dec_gain.o \
-+AMROBJS= amr.o
-+OBJS+= amrwb_float/dec_acelp.o amrwb_float/dec_dtx.o amrwb_float/dec_gain.o \
- amrwb_float/dec_if.o amrwb_float/dec_lpc.o amrwb_float/dec_main.o \
- amrwb_float/dec_rom.o amrwb_float/dec_util.o amrwb_float/enc_acelp.o \
- amrwb_float/enc_dtx.o amrwb_float/enc_gain.o amrwb_float/enc_if.o \
- amrwb_float/enc_lpc.o amrwb_float/enc_main.o amrwb_float/enc_rom.o \
- amrwb_float/enc_util.o amrwb_float/if_rom.o
- endif
-+OBJS+= $(AMROBJS)
- CLEANAMRWB=cleanamrwbfloat
- ASM_OBJS=
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/amr.c ffmpeg-0.4.9-pre1/libavcodec/amr.c
---- ffmpeg-0.4.9-pre1-orig/libavcodec/amr.c 2004-05-21 14:37:16.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/amr.c 2006-01-12 18:27:33.000000000 +0000
-@@ -411,27 +411,32 @@
- AMRContext *s = (AMRContext*)avctx->priv_data;
-
- uint8_t*amrData=buf;
-- int offset=0;
- static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
- enum Mode dec_mode;
- int packet_size;
-
-- //printf("amr_decode_frame data_size=%i buf=0x%X buf_size=%d frameCount=%d!!\n",*data_size,buf,buf_size,s->frameCount);
-+ /* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */
-+
-+ if(buf_size==0) {
-+ /* nothing to do */
-+ return 0;
-+ }
-
-- while(offset> 3) & 0x000F;
-- packet_size = block_size[dec_mode];
-+ dec_mode = (buf[0] >> 3) & 0x000F;
-+ packet_size = block_size[dec_mode]+1;
-+
-+ if(packet_size > buf_size) {
-+ av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size);
-+ return -1;
-+ }
-
-- s->frameCount++;
-- //printf("offset=%d, packet_size=%d amrData= 0x%X %X %X %X\n",offset,packet_size,amrData[offset],amrData[offset+1],amrData[offset+2],amrData[offset+3]);
-- /* call decoder */
-- Decoder_Interface_Decode(s->decState, &amrData[offset], data+*data_size, 0);
-- *data_size+=160*2;
-+ s->frameCount++;
-+ /* av_log(NULL,AV_LOG_DEBUG,"packet_size=%d amrData= 0x%X %X %X %X\n",packet_size,amrData[0],amrData[1],amrData[2],amrData[3]); */
-+ /* call decoder */
-+ Decoder_Interface_Decode(s->decState, amrData, data, 0);
-+ *data_size=160*2;
-
-- offset+=packet_size+1;
-- }
-- return buf_size;
-+ return packet_size;
- }
-
- static int amr_nb_encode_frame(AVCodecContext *avctx,
-@@ -445,6 +450,7 @@
- data,
- frame,
- 0);
-+ /* av_log(NULL,AV_LOG_DEBUG,"amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",written, s->enc_bitrate, frame[0] ); */
-
- return written;
- }
-@@ -598,20 +604,26 @@
- AMRWBContext *s = (AMRWBContext*)avctx->priv_data;
-
- uint8_t*amrData=buf;
-- int offset=0;
- int mode;
- int packet_size;
-
-- while(offsetframeCount++;
-- mode = (Word16)((amrData[offset] >> 3) & 0x0F);
-- packet_size = block_size[mode];
-- D_IF_decode( s->state, &amrData[offset], data+*data_size, _good_frame);
-- *data_size+=320*2;
-- offset+=packet_size;
-+ if(buf_size==0) {
-+ /* nothing to do */
-+ return 0;
- }
-- return buf_size;
-+
-+ mode = (amrData[0] >> 3) & 0x000F;
-+ packet_size = block_size[mode];
-+
-+ if(packet_size > buf_size) {
-+ av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size+1);
-+ return -1;
-+ }
-+
-+ s->frameCount++;
-+ D_IF_decode( s->state, amrData, data, _good_frame);
-+ *data_size=320*2;
-+ return packet_size;
- }
-
- static int amr_wb_decode_close(AVCodecContext * avctx)
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/avcodec.h ffmpeg-0.4.9-pre1/libavcodec/avcodec.h
---- ffmpeg-0.4.9-pre1-orig/libavcodec/avcodec.h 2004-07-09 12:49:55.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/avcodec.h 2006-01-12 18:27:33.000000000 +0000
-@@ -124,7 +124,7 @@
- CODEC_ID_ADPCM_G726,
-
- /* AMR */
-- CODEC_ID_AMR_NB,
-+ CODEC_ID_AMR_NB= 0x12000,
- CODEC_ID_AMR_WB,
-
- /* RealAudio codecs*/
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavformat/Makefile ffmpeg-0.4.9-pre1/libavformat/Makefile
---- ffmpeg-0.4.9-pre1-orig/libavformat/Makefile 2004-04-24 15:16:23.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavformat/Makefile 2006-01-12 18:27:33.000000000 +0000
-@@ -23,15 +23,17 @@
- OBJS+= asf-enc.o
- endif
-
-+AMROBJS=
- ifeq ($(AMR_NB),yes)
--OBJS+= amr.o
-+AMROBJS= amr.o
- endif
- ifeq ($(AMR_NB_FIXED),yes)
--OBJS+= amr.o
-+AMROBJS= amr.o
- endif
- ifeq ($(AMR_WB),yes)
--OBJS+= amr.o
-+AMROBJS= amr.o
- endif
-+OBJS+= $(AMROBJS)
-
- # image formats
- OBJS+= pnm.o yuv.o png.o jpeg.o gifdec.o sgi.o
-
diff --git a/src/patches/ffmpeg-0.4.9-pre1-gcc4-1.patch b/src/patches/ffmpeg-0.4.9-pre1-gcc4-1.patch
deleted file mode 100644
index 07e3a87a5..000000000
--- a/src/patches/ffmpeg-0.4.9-pre1-gcc4-1.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-Submitted By: Randy McMurchy
-Date: 2005-09-07
-Initial Package Version: 0.4.9-pre1
-Upstream Status: Some fixes unknown, the MMX fix is from upstream CVS
-Origin: Frugalware Linux (frugalware.org)
- http://frugalware.org/pipermail/frugalware-darcs/2005-August/003296.html
- Also the MMX fix is from upstream CVS
- http://www1.mplayerhq.hu/cgi-bin/cvsweb.cgi/ffmpeg/libavcodec/i386/dsputil_mmx.c.diff?r1=1.88&r2=1.89&cvsroot=FFMpeg
-Description: Fixes GCC-4.0.1 build problems
-
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/ac3.h ffmpeg-0.4.9-pre1/libavcodec/ac3.h
---- ffmpeg-0.4.9-pre1-orig/libavcodec/ac3.h 2003-03-06 11:32:04.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/ac3.h 2005-09-07 18:50:35.000000000 +0000
-@@ -43,6 +43,7 @@
- int cplfleak, cplsleak;
- } AC3BitAllocParameters;
-
-+#if 0
- extern const uint16_t ac3_freqs[3];
- extern const uint16_t ac3_bitratetab[19];
- extern const int16_t ac3_window[256];
-@@ -52,6 +53,7 @@
- extern const uint16_t dbkneetab[4];
- extern const uint16_t floortab[8];
- extern const uint16_t fgaintab[8];
-+#endif
-
- void ac3_common_init(void);
- void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/avcodec.h ffmpeg-0.4.9-pre1/libavcodec/avcodec.h
---- ffmpeg-0.4.9-pre1-orig/libavcodec/avcodec.h 2004-07-09 12:49:55.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/avcodec.h 2005-09-07 18:49:40.000000000 +0000
-@@ -1657,6 +1657,14 @@
- #define FF_OPT_MAX_DEPTH 10
- } AVOption;
-
-+struct AVOption;
-+#ifdef HAVE_MMX
-+extern const struct AVOption avoptions_common[3 + 5];
-+#else
-+extern const struct AVOption avoptions_common[3];
-+#endif
-+extern const struct AVOption avoptions_workaround_bug[11];
-+
- /**
- * Parse option(s) and sets fields in passed structure
- * @param strct structure where the parsed results will be written
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/common.h ffmpeg-0.4.9-pre1/libavcodec/common.h
---- ffmpeg-0.4.9-pre1-orig/libavcodec/common.h 2004-07-01 12:33:07.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/common.h 2005-09-07 18:49:40.000000000 +0000
-@@ -62,14 +62,6 @@
- #define AVOPTION_SUB(ptr) { .name = NULL, .help = (const char*)ptr }
- #define AVOPTION_END() AVOPTION_SUB(NULL)
-
--struct AVOption;
--#ifdef HAVE_MMX
--extern const struct AVOption avoptions_common[3 + 5];
--#else
--extern const struct AVOption avoptions_common[3];
--#endif
--extern const struct AVOption avoptions_workaround_bug[11];
--
- #endif /* HAVE_AV_CONFIG_H */
-
- /* Suppress restrict if it was not defined in config.h. */
-
-diff -Naur ffmpeg-0.4.9-pre1-orig/libavcodec/i386/dsputil_mmx.c ffmpeg-0.4.9-pre1/libavcodec/i386/dsputil_mmx.c
---- ffmpeg-0.4.9-pre1-orig/libavcodec/i386/dsputil_mmx.c 2004-06-08 02:13:44.000000000 +0000
-+++ ffmpeg-0.4.9-pre1/libavcodec/i386/dsputil_mmx.c 2005-09-07 18:54:04.000000000 +0000
-@@ -644,26 +644,22 @@
- "punpcklwd %%mm0, %%mm1 \n\t"
- "punpckhwd %%mm4, %%mm3 \n\t"
- "punpckhwd %%mm0, %%mm6 \n\t"
-- "movd %%mm5, %0 \n\t"
-- "punpckhdq %%mm5, %%mm5 \n\t"
-- "movd %%mm5, %1 \n\t"
-- "movd %%mm3, %2 \n\t"
-- "punpckhdq %%mm3, %%mm3 \n\t"
-- "movd %%mm3, %3 \n\t"
-- "movd %%mm1, %4 \n\t"
-- "punpckhdq %%mm1, %%mm1 \n\t"
-- "movd %%mm1, %5 \n\t"
-- "movd %%mm6, %6 \n\t"
-- "punpckhdq %%mm6, %%mm6 \n\t"
-- "movd %%mm6, %7 \n\t"
-- : "=m" (*(uint32_t*)(src + 0*stride)),
-- "=m" (*(uint32_t*)(src + 1*stride)),
-- "=m" (*(uint32_t*)(src + 2*stride)),
-- "=m" (*(uint32_t*)(src + 3*stride)),
-- "=m" (*(uint32_t*)(src + 4*stride)),
-- "=m" (*(uint32_t*)(src + 5*stride)),
-- "=m" (*(uint32_t*)(src + 6*stride)),
-- "=m" (*(uint32_t*)(src + 7*stride))
-+ "movd %%mm5, (%0) \n\t"
-+ "punpckhdq %%mm5, %%mm5 \n\t"
-+ "movd %%mm5, (%0,%2) \n\t"
-+ "movd %%mm3, (%0,%2,2) \n\t"
-+ "punpckhdq %%mm3, %%mm3 \n\t"
-+ "movd %%mm3, (%0,%3) \n\t"
-+ "movd %%mm1, (%1) \n\t"
-+ "punpckhdq %%mm1, %%mm1 \n\t"
-+ "movd %%mm1, (%1,%2) \n\t"
-+ "movd %%mm6, (%1,%2,2) \n\t"
-+ "punpckhdq %%mm6, %%mm6 \n\t"
-+ "movd %%mm6, (%1,%3) \n\t"
-+ :: "r" (src),
-+ "r" (src + 4*stride),
-+ "r" ((long) stride ),
-+ "r" ((long)(3*stride))
- );
- }
-
diff --git a/src/patches/ffmpeg-0.4.9-pre1-gcc4-2.patch b/src/patches/ffmpeg-0.4.9-pre1-gcc4-2.patch
deleted file mode 100644
index f2ba15078..000000000
--- a/src/patches/ffmpeg-0.4.9-pre1-gcc4-2.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- libavcodec/libpostproc/postprocess_template.orig.c 2005-05-04 00:13:55.809595776 -0400
-+++ libavcodec/libpostproc/postprocess_template.c 2005-05-04 00:17:44.090891744 -0400
-@@ -2646,7 +2646,7 @@
- * accurate deblock filter
- */
- static always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int stride, PPContext *c){
-- int64_t dc_mask, eq_mask;
-+ int64_t dc_mask, eq_mask, both_masks;
- int64_t sums[10*8*2];
- src+= step*3; // src points to begin of the 8x8 Block
- //START_TIMER
-@@ -2755,7 +2755,9 @@
- : "%eax"
- );
-
-- if(dc_mask & eq_mask){
-+ both_masks = dc_mask & eq_mask;
-+
-+ if (both_masks){
- int offset= -8*step;
- int64_t *temp_sums= sums;
-
-@@ -2930,7 +2932,7 @@
- " js 1b \n\t"
-
- : "+r"(offset), "+r"(temp_sums)
-- : "r" (step), "r"(src - offset), "m"(dc_mask & eq_mask)
-+ : "r" (step), "r"(src - offset), "m"(both_masks)
- );
- }else
- src+= step; // src points to begin of the 8x8 Block
diff --git a/src/patches/ipac-ng-1.31-fetchcounter.patch b/src/patches/ipac-ng-1.31-fetchcounter.patch
deleted file mode 100644
index eb6c0738a..000000000
--- a/src/patches/ipac-ng-1.31-fetchcounter.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -ruw ipac-ng-1.31_iptables-1.3.1/agents/iptables/iptables.c ipac-ng-1.31/agents/iptables/iptables.c
---- ipac-ng-1.31_iptables-1.3.1/agents/iptables/iptables.c 2005-05-02 12:00:48.000000000 +0200
-+++ ipac-ng-1.31/agents/iptables/iptables.c 2005-05-11 22:15:59.558139120 +0200
-@@ -1144,6 +1144,7 @@
- rule = new_rule();
-
- chain = new_rule();
-+ chain->pkts = 1;
-
- strncpy(rule->name, cp+1, MAX_RULE_NAME_LENGTH);
- strncpy(chain->name, nextline->line, cp-nextline->line);
diff --git a/src/patches/ipac-ng-1.31-iptables-1.3.1.patch b/src/patches/ipac-ng-1.31-iptables-1.3.1.patch
deleted file mode 100644
index a0225dd63..000000000
--- a/src/patches/ipac-ng-1.31-iptables-1.3.1.patch
+++ /dev/null
@@ -1,4826 +0,0 @@
-diff -Nur ipac-ng-1.31.orig/agents/iptables/iptables.c ipac-ng-1.31/agents/iptables/iptables.c
---- ipac-ng-1.31.orig/agents/iptables/iptables.c 2004-06-27 22:08:54.000000000 +0000
-+++ ipac-ng-1.31/agents/iptables/iptables.c 2006-01-11 21:49:40.000000000 +0000
-@@ -62,10 +62,6 @@
- #define FALSE 0
- #endif
-
--#ifndef IPT_LIB_DIR
--#define IPT_LIB_DIR "/lib/iptables"
--#endif
--
- #define FMT_NUMERIC 0x0001
- #define FMT_NOCOUNTS 0x0002
- #define FMT_KILOMEGAGIGA 0x0004
-@@ -91,7 +87,6 @@
- static struct option *opts = original_opts;
- static unsigned int global_option_offset = 0;
-
--extern char *authhost;
-
- /* - T.Mohan 5/7/2001
- * interface structure to pass to append rule
-@@ -106,6 +101,14 @@
- typedef struct iface_struct s_iface;
-
-
-+struct iptables_rule_match
-+{
-+ struct iptables_rule_match *next;
-+
-+ struct iptables_match *match;
-+};
-+
-+
- /* Include file for additions: new matches and targets. */
- struct iptables_match
- {
-@@ -113,6 +116,9 @@
-
- ipt_chainlabel name;
-
-+ /* Revision of match (0 by default). */
-+ u_int8_t revision;
-+
- const char *version;
-
- /* Size of match data. */
-@@ -152,7 +158,6 @@
- unsigned int option_offset;
- struct ipt_entry_match *m;
- unsigned int mflags;
-- unsigned int used;
- };
-
- struct iptables_target
-@@ -161,6 +166,9 @@
-
- ipt_chainlabel name;
-
-+ /* Revision of target (0 by default). */
-+ u_int8_t revision;
-+
- const char *version;
-
- /* Size of target data. */
-@@ -202,6 +210,7 @@
- unsigned int used;
- };
-
-+
- enum ipt_tryload {
- DONT_LOAD,
- TRY_LOAD,
-@@ -246,6 +255,9 @@
- * compiler warning.
- */
-
-+char *lib_dir = "/lib/iptables";
-+
-+
- void
- exit_error(enum exittype status, char *msg, ...)
- {
-@@ -367,7 +379,7 @@
- * iptables-1.2.2 file:iptables.c
- */
-
--void
-+static void
- parse_interface(const char *arg, char *vianame, unsigned char *mask)
- {
- int vialen = strlen(arg);
-@@ -382,23 +394,25 @@
- " (%i)", arg, IFNAMSIZ-1);
-
- strcpy(vianame, arg);
-- if (vialen == 0)
-+ if ((vialen == 0) || (vialen == 1 && vianame[0] == '+'))
- memset(mask, 0, IFNAMSIZ);
- else if (vianame[vialen - 1] == '+') {
- memset(mask, 0xFF, vialen - 1);
- memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1);
-+ /* Don't remove `+' here! -HW */
- } else {
- /* Include nul-terminator in match */
- memset(mask, 0xFF, vialen + 1);
- memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1);
-- }
- for (i = 0; vianame[i]; i++) {
- if (!isalnum(vianame[i])
- && vianame[i] != '_'
-- && vianame[i] != '+'
- && vianame[i] != '.') {
-- exit_error(PARAMETER_PROBLEM, "Warning: weird character in interface"
-- " `%s' (No aliases, :, ! or *).\n", vianame);
-+ printf("Warning: wierd character in interface"
-+ " `%s' (No aliases, :, ! or *).\n",
-+ vianame);
-+ break;
-+ }
- }
- }
- }
-@@ -429,20 +443,27 @@
- }
-
- int
--check_inverse(const char option[], int *invert)
-+check_inverse(const char option[], int *invert, int *optind, int argc)
- {
- if (option && strcmp(option, "!") == 0) {
- if (*invert)
- exit_error(PARAMETER_PROBLEM,
- "Multiple `!' flags not allowed");
--
- *invert = TRUE;
-+ if (optind) {
-+ *optind = *optind+1;
-+ if (argc && *optind > argc)
-+ exit_error(PARAMETER_PROBLEM,
-+ "no argument following `!'");
-+ }
-+
- return TRUE;
- }
- return FALSE;
- }
-
- // ---------------------------------------------------------------------
-+/* code copied from iptables 1.3.1 */
- // ---------------------------------------------------------------------
-
- static char *
-@@ -509,7 +530,7 @@
- return addr_to_dotted(addr);
- }
-
--static char *
-+char *
- mask_to_dotted(const struct in_addr *mask)
- {
- int i;
-@@ -535,22 +556,19 @@
- return buf;
- }
-
-+
- static struct ipt_entry *
- generate_entry(const struct ipt_entry *fw,
-- struct iptables_match *matches,
-+ struct iptables_rule_match *matches,
- struct ipt_entry_target *target)
- {
- unsigned int size;
-- struct iptables_match *m;
-+ struct iptables_rule_match *matchp;
- struct ipt_entry *e;
-
- size = sizeof(struct ipt_entry);
-- for (m = matches; m; m = m->next) {
-- if (!m->used)
-- continue;
--
-- size += m->m->u.match_size;
-- }
-+ for (matchp = matches; matchp; matchp = matchp->next)
-+ size += matchp->match->m->u.match_size;
-
- e = xmalloc(size + target->u.target_size);
- *e = *fw;
-@@ -558,12 +576,9 @@
- e->next_offset = size + target->u.target_size;
-
- size = 0;
-- for (m = matches; m; m = m->next) {
-- if (!m->used)
-- continue;
--
-- memcpy(e->elems + size, m->m, m->m->u.match_size);
-- size += m->m->u.match_size;
-+ for (matchp = matches; matchp; matchp = matchp->next) {
-+ memcpy(e->elems + size, matchp->match->m, matchp->match->m->u.match_size);
-+ size += matchp->match->m->u.match_size;
- }
- memcpy(e->elems + size, target, target->u.target_size);
-
-@@ -575,15 +590,17 @@
- int procfile;
- char *ret;
-
-+#define PROCFILE_BUFSIZ 1024
- procfile = open(PROC_SYS_MODPROBE, O_RDONLY);
- if (procfile < 0)
- return NULL;
-
-- ret = malloc(1024);
-+ ret = (char *) malloc(PROCFILE_BUFSIZ);
- if (ret) {
-- switch (read(procfile, ret, 1024)) {
-+ memset(ret, 0, PROCFILE_BUFSIZ);
-+ switch (read(procfile, ret, PROCFILE_BUFSIZ)) {
- case -1: goto fail;
-- case 1024: goto fail; /* Partial read. Wierd */
-+ case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */
- }
- if (ret[strlen(ret)-1]=='\n')
- ret[strlen(ret)-1]=0;
-@@ -618,22 +635,22 @@
- }
-
- if (!ptr && tryload != DONT_LOAD) {
-- char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so")
-+ char path[strlen(lib_dir) + sizeof("/libipt_.so")
- + strlen(name)];
-- sprintf(path, IPT_LIB_DIR "/libipt_%s.so", name);
-+ sprintf(path, "%s/libipt_%s.so", lib_dir, name);
- if (dlopen(path, RTLD_NOW)) {
- /* Found library. If it didn't register itself,
- maybe they specified match as a target. */
- ptr = find_target(name, DONT_LOAD);
- if (!ptr) {
-- fprintf(stderr, "Couldn't load target `%s'\n",
-+ exit_error(PARAMETER_PROBLEM,
-+ "Couldn't load target `%s'\n",
- name);
-- exit(1);
- }
- } else if (tryload == LOAD_MUST_SUCCEED) {
-- fprintf(stderr, "Couldn't load target `%s':%s\n",
-+ exit_error(PARAMETER_PROBLEM,
-+ "Couldn't load target `%s':%s\n",
- name, dlerror());
-- exit(1);
- }
- }
-
-@@ -647,8 +664,9 @@
- {
- char *buf = NULL;
- char *argv[3];
-+ int status;
-
--// If they don't explicitly set it, read out of kernel
-+ /* If they don't explicitly set it, read out of kernel */
- if (!modprobe) {
- buf = get_modprobe();
- if (!buf)
-@@ -664,16 +682,18 @@
- execv(argv[0], argv);
-
- // not usually reached
-- exit(0);
-+ exit(1);
- case -1:
- return -1;
-
- default: // parent
-- wait(NULL);
-+ wait(&status);
- }
-
- free(buf);
-+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
- return 0;
-+ return -1;
- }
-
- void
-@@ -687,7 +707,7 @@
-
- if (me->size != IPT_ALIGN(me->size)) {
- fprintf(stderr, "%s: target `%s' has invalid size %u.\n",
-- "fddfgdsse", me->name, me->size);
-+ "fddfgdsse", me->name, (unsigned int)me->size);
- exit(1);
- }
-
-@@ -698,20 +718,17 @@
- me->tflags = 0;
- }
-
--unsigned char * make_delete_mask(struct ipt_entry *fw)
-+static unsigned char *
-+make_delete_mask(struct ipt_entry *fw, struct iptables_rule_match *matches)
- {
- /* Establish mask for comparison */
- unsigned int size;
-- struct iptables_match *m;
-+ struct iptables_rule_match *matchp;
- unsigned char *mask, *mptr;
-
- size = sizeof(struct ipt_entry);
-- for (m = iptables_matches; m; m = m->next) {
-- if (!m->used)
-- continue;
--
-- size += IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
-- }
-+ for (matchp = matches; matchp; matchp = matchp->next)
-+ size += IPT_ALIGN(sizeof(struct ipt_entry_match)) + matchp->match->size;
-
- mask = xcalloc(1, size
- + IPT_ALIGN(sizeof(struct ipt_entry_target))
-@@ -720,14 +737,11 @@
- memset(mask, 0xFF, sizeof(struct ipt_entry));
- mptr = mask + sizeof(struct ipt_entry);
-
-- for (m = iptables_matches; m; m = m->next) {
-- if (!m->used)
-- continue;
--
-+ for (matchp = matches; matchp; matchp = matchp->next) {
- memset(mptr, 0xFF,
- IPT_ALIGN(sizeof(struct ipt_entry_match))
-- + m->userspacesize);
-- mptr += IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
-+ + matchp->match->userspacesize);
-+ mptr += IPT_ALIGN(sizeof(struct ipt_entry_match)) + matchp->match->size;
- }
-
- memset(mptr, 0xFF,
-@@ -738,7 +752,7 @@
- }
-
- struct iptables_match *
--find_match(const char *name, enum ipt_tryload tryload)
-+find_match(const char *name, enum ipt_tryload tryload, struct iptables_rule_match **matches)
- {
- struct iptables_match *ptr;
-
-@@ -748,28 +762,37 @@
- }
-
- if (!ptr && tryload != DONT_LOAD) {
-- char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so")
-+ char path[strlen(lib_dir) + sizeof("/libipt_.so")
- + strlen(name)];
-- sprintf(path, IPT_LIB_DIR "/libipt_%s.so", name);
-+ sprintf(path, "%s/libipt_%s.so", lib_dir, name);
- if (dlopen(path, RTLD_NOW)) {
- /* Found library. If it didn't register itself,
- maybe they specified target as match. */
-- ptr = find_match(name, DONT_LOAD);
-+ ptr = find_match(name, DONT_LOAD, NULL);
-
- if (!ptr) {
-- fprintf(stderr, "Couldn't load match `%s'\n",
-+ exit_error(PARAMETER_PROBLEM,
-+ "Couldn't load match `%s'\n",
- name);
-- exit(1);
- }
- } else if (tryload == LOAD_MUST_SUCCEED) {
-- fprintf(stderr, "Couldn't load match `%s':%s\n",
-+ exit_error(PARAMETER_PROBLEM,
-+ "Couldn't load match `%s':%s\n",
- name, dlerror());
-- exit(1);
- }
- }
-
-- if (ptr)
-- ptr->used = 1;
-+ if (ptr && matches) {
-+ struct iptables_rule_match **i;
-+ struct iptables_rule_match *newentry;
-+
-+ newentry = xmalloc(sizeof(struct iptables_rule_match));
-+
-+ for (i = matches; *i; i = &(*i)->next);
-+ newentry->match = ptr;
-+ newentry->next = NULL;
-+ *i = newentry;
-+ }
-
- return ptr;
- }
-@@ -779,7 +802,7 @@
- {
- struct iptables_match **i;
-
-- if (find_match(me->name, DONT_LOAD)) {
-+ if (find_match(me->name, DONT_LOAD, NULL)) {
- fprintf(stderr, "%s: match `%s' already registered.\n",
- "fetchipac??", me->name);
- exit(1);
-@@ -787,7 +810,7 @@
-
- if (me->size != IPT_ALIGN(me->size)) {
- fprintf(stderr, "%s: match `%s' has invalid size %u.\n",
-- "fetchipac??", me->name, me->size);
-+ "fetchipac??", me->name, (unsigned int)me->size);
- exit(1);
- }
-
-@@ -801,16 +824,21 @@
- }
-
-
-+/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
- static struct iptables_match *
--find_proto(const char *pname, enum ipt_tryload tryload, int nolookup)
-+find_proto(const char *pname, enum ipt_tryload tryload, int nolookup, struct iptables_rule_match **matches)
- {
-- int proto;
-+ unsigned int proto;
-
-- proto = string_to_number(pname, 0, 255);
-- if (proto != -1)
-- return find_match(proto_to_name(proto, nolookup), tryload);
-+ if ((proto = string_to_number(pname, 0, 255)) != -1) {
-+ char *protoname = proto_to_name(proto, nolookup);
-
-- return find_match(pname, tryload);
-+ if (protoname)
-+ return find_match(protoname, tryload, matches);
-+ } else
-+ return find_match(pname, tryload, matches);
-+
-+ return NULL;
- }
-
- static void
-@@ -823,15 +851,19 @@
- number = (number + 500) / 1000;
- if (number > 9999) {
- number = (number + 500) / 1000;
-- printf(FMT("%4lluG ","%lluG "),number);
-+ if (number > 9999) {
-+ number = (number + 500) / 1000;
-+ printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
- }
-- else printf(FMT("%4lluM ","%lluM "), number);
-+ else printf(FMT("%4lluG ","%lluG "), (unsigned long long)number);
-+ }
-+ else printf(FMT("%4lluM ","%lluM "), (unsigned long long)number);
- } else
-- printf(FMT("%4lluK ","%lluK "), number);
-+ printf(FMT("%4lluK ","%lluK "), (unsigned long long)number);
- } else
-- printf(FMT("%5llu ","%llu "), number);
-+ printf(FMT("%5llu ","%llu "), (unsigned long long)number);
- } else
-- printf(FMT("%8llu ","%llu "), number);
-+ printf(FMT("%8llu ","%llu "), (unsigned long long)number);
- }
-
- static int
-@@ -839,7 +871,7 @@
- const struct ipt_ip *ip,
- int numeric)
- {
-- struct iptables_match *match = find_match(m->u.user.name, TRY_LOAD);
-+ struct iptables_match *match = find_match(m->u.user.name, TRY_LOAD, NULL);
-
- if (match) {
- if (match->print)
-@@ -867,9 +899,6 @@
- u_int8_t flags;
- char buf[BUFSIZ];
-
-- /* User creates a chain called "REJECT": this overrides the
-- `REJECT' target module. Keep feeding them rope until the
-- revolution... Bwahahahahah */
- if (!iptc_is_chain(targname, handle))
- target = find_target(targname, TRY_LOAD);
- else
-@@ -917,10 +946,6 @@
-
- if (fw->ip.iniface[0] != '\0') {
- strcat(iface, fw->ip.iniface);
-- /* If it doesn't compare the nul-term, it's a
-- wildcard. */
-- if (fw->ip.iniface_mask[strlen(fw->ip.iniface)] == 0)
-- strcat(iface, "+");
- }
- else if (format & FMT_NUMERIC) strcat(iface, "*");
- else strcat(iface, "any");
-@@ -934,10 +959,6 @@
-
- if (fw->ip.outiface[0] != '\0') {
- strcat(iface, fw->ip.outiface);
-- /* If it doesn't compare the nul-term, it's a
-- wildcard. */
-- if (fw->ip.outiface_mask[strlen(fw->ip.outiface)] == 0)
-- strcat(iface, "+");
- }
- else if (format & FMT_NUMERIC) strcat(iface, "*");
- else strcat(iface, "any");
-@@ -979,7 +1000,7 @@
- target->print(&fw->ip, t, format & FMT_NUMERIC);
- } else if (t->u.target_size != sizeof(*t))
- printf("[%u bytes of unknown target data] ",
-- t->u.target_size - sizeof(*t));
-+ (unsigned int)(t->u.target_size - sizeof(*t)));
-
- if (!(format & FMT_NONEWLINE))
- fputc('\n', stdout);
-@@ -996,6 +1017,15 @@
- }
-
-
-+static void set_revision(char *name, u_int8_t revision)
-+{
-+ /* Old kernel sources don't have ".revision" field,
-+ but we stole a byte from name. */
-+ name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0';
-+ name[IPT_FUNCTION_MAXNAMELEN - 1] = revision;
-+}
-+
-+
- // ---------------------------------------------------------------------
-
-
-@@ -1129,8 +1159,7 @@
- chain->pkts++;
- continue;
- }
--
-- counters = iptc_read_counter(chain->name, chain->pkts, &handle);
-+ counters = iptc_read_counter(chain->name, chain->pkts, &handle); // ???? why chain->pkts
- if (counters) {
- iptc_zero_counter(chain->name, chain->pkts, &handle);
- chain->pkts++;
-@@ -1192,7 +1221,7 @@
- *
- */
- static int
--prepare_entry (raw_rule_type *d, struct ipt_entry **e)
-+prepare_entry (raw_rule_type *d, struct ipt_entry **e, struct iptables_rule_match **matches)
- {
- struct ipt_entry fw;
- unsigned int naddrs = 0;
-@@ -1200,10 +1229,14 @@
- struct iptables_match *m;
- struct iptables_target *target = NULL;
- struct iptables_target *t;
-+
-+ struct iptables_rule_match *matchp;
-+
- size_t size;
- int inverse;
- int c,argc;
- int invert = 0;
-+ int proto_used = 0;
-
- bzero(&fw, sizeof(fw));
-
-@@ -1233,7 +1266,6 @@
-
- for (m = iptables_matches; m; m = m->next) {
- m->mflags = 0;
-- m->used = 0;
- }
-
- for (t = iptables_targets; t; t = t->next) {
-@@ -1279,6 +1311,8 @@
- target->t = xcalloc(1, size);
- target->t->u.target_size = size;
- strcpy(target->t->u.user.name, d->target);
-+ set_revision(target->t->u.user.name, target->revision);
-+ if (target->init != NULL)
- target->init(target->t, &fw.nfcache);
-
- if(check_inverse_type(d->protocol))
-@@ -1290,7 +1324,7 @@
- }
-
- if (d->protocol[0] != '\0' && d->protocol[0] != 'i') {
-- m = find_proto(d->protocol, LOAD_MUST_SUCCEED, 0);
-+ m = find_proto(d->protocol, LOAD_MUST_SUCCEED, 0, matches);
- size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
- m->m = xcalloc(size, 1);
- m->m->u.match_size = size;
-@@ -1338,7 +1372,7 @@
- while ((c = getopt_long(argc, d->extension,"-m:", opts, NULL))!= -1) {
- switch (c) {
- case 'm':
-- m = find_match(optarg, LOAD_MUST_SUCCEED);
-+ m = find_match(optarg, LOAD_MUST_SUCCEED, matches);
- size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
- m->m = xcalloc(1, size);
- m->m->u.match_size = size;
-@@ -1361,32 +1395,80 @@
- exit(1);
-
- default:
-- for (m = iptables_matches; m; m = m->next) {
-- if (!m->used)
-- continue;
-- if (m->parse(c - m->option_offset,
-+
-+ /* FIXME: This scheme doesn't allow two of the same
-+ matches --RR */
-+ if (!target
-+ || !(target->parse(c - target->option_offset,
-+ d->extension, invert,
-+ &target->tflags,
-+ &fw, &target->t))) {
-+ for (matchp = *matches; matchp; matchp = matchp->next) {
-+ if (matchp->match->parse(c - matchp->match->option_offset,
- d->extension, invert,
-- &m->mflags,
-- &fw, &fw.nfcache, &m->m))
-+ &matchp->match->mflags,
-+ &fw,
-+ &fw.nfcache,
-+ &matchp->match->m))
- break;
- }
-- break;
-+
-+ if (m == NULL
-+ && d->protocol
-+ && (!find_proto(d->protocol, DONT_LOAD,
-+ 0, NULL)
-+ || (find_proto(d->protocol, DONT_LOAD,
-+ 0, NULL)
-+ && (proto_used == 0))
-+ )
-+ && (m = find_proto(d->protocol, TRY_LOAD,
-+ 0, matches))) {
-+ /* Try loading protocol */
-+ size_t size;
-+
-+ proto_used = 1;
-+
-+ size = IPT_ALIGN(sizeof(struct ipt_entry_match))
-+ + m->size;
-+
-+ m->m = xcalloc(1, size);
-+ m->m->u.match_size = size;
-+ strcpy(m->m->u.user.name, m->name);
-+ set_revision(m->m->u.user.name,
-+ m->revision);
-+ if (m->init != NULL)
-+ m->init(m->m, &fw.nfcache);
-+
-+ opts = merge_options(opts,
-+ m->extra_opts, &m->option_offset);
-+
-+ optind--;
-+ continue;
-+ }
-+
-+ m = matchp ? matchp->match : NULL;
-+ if (!m)
-+ exit_error(PARAMETER_PROBLEM,
-+ "Unknown arg `%s'",
-+ d->extension);
- }
- }
- }
-- for (m = iptables_matches; m; m = m->next) {
-- if (!m->used)
-- continue;
-- m->final_check(m->mflags);
- }
-
-+ for (matchp = *matches; matchp; matchp = matchp->next)
-+ matchp->match->final_check(matchp->match->mflags);
-+
-+ if (target)
- target->final_check(target->tflags);
-- *e = generate_entry(&fw, iptables_matches, target->t);
-+
-+ *e = generate_entry(&fw, *matches, target->t);
-+ free(target->t);
-+
-
- if (!handle) if (!(handle = iptc_init("filter")))
- exit_error(PARAMETER_PROBLEM,
- "iptables: %s\n", iptc_strerror(errno));
--
- return 0;
- }
-
-@@ -1399,9 +1481,11 @@
- insert_rule(raw_rule_type *d, int rule_num)
- {
- struct ipt_entry *e = NULL;
-+ struct iptables_rule_match *matches = NULL;
-+
- int ret=1;
-
-- if (prepare_entry(d, &e)!=0)
-+ if (prepare_entry(d, &e, &matches)!=0)
- return (1);
- if (verbose>1) {
- printf("Inserting rule\n");
-@@ -1412,28 +1496,6 @@
- return ret;
- }
-
--/*
-- * Try to atomically replace rule in kernel return 0 in case all right, 1 otherwice
-- */
--static int
--//replace_rule (char *chain, char *saddr, char *sport, char *daddr, char *dport,
--// char *proto, char *targ, int rule_num, char *iface)
--replace_rule (raw_rule_type *d, int rule_num)
--{
-- struct ipt_entry *e = NULL;
-- int ret=1;
--
-- if (prepare_entry(d, &e)!=0)
-- return (1);
--
-- if (verbose>1) {
-- printf("Replacing rule %d in '%s'\n", rule_num, d->dest);
-- print_firewall_line(e, handle);
-- }
-- ret &= iptc_replace_entry(d->dest, e, rule_num, &handle);
-- free(e);
-- return ret;
--}
-
- /*
- * Try to append rule into kernel return 0 in case all right, 1 otherwice
-@@ -1449,8 +1511,9 @@
- append_rule (raw_rule_type *d)
- {
- struct ipt_entry *e = NULL;
-+ struct iptables_rule_match *matches = NULL;
-
-- if (prepare_entry(d, &e)!=0)
-+ if (prepare_entry(d, &e, &matches)!=0)
- return (1);
-
- if (verbose>1) {
-@@ -1472,9 +1535,11 @@
- {
- struct ipt_entry *e = NULL;
- unsigned char *mask = NULL;
-+ struct iptables_rule_match *matches = NULL;
-+
- int ret=1;
-
-- if (prepare_entry(d, &e)!=0)
-+ if (prepare_entry(d, &e, &matches)!=0)
- return (1);
-
- if (verbose>1) {
-@@ -1482,26 +1547,12 @@
- print_firewall_line(e, handle);
- }
-
-- mask = make_delete_mask(e);
-+ mask = make_delete_mask(e, matches);
- ret &= iptc_delete_entry(d->dest, e, mask, &handle);
- free(e);
- return ret;
- }
-
--static int
--delete_num_rule (char *chain, int num)
--{
-- struct ipt_entry *e = NULL;
-- unsigned char *mask = NULL;
-- int ret = 1;
--
-- mask = make_delete_mask(e);
-- ret &= iptc_delete_num_entry(chain, num, &handle);
-- free(e);
-- return ret;
--}
--
--
-
- /** Setup chains if they doesn't exist
- *
-@@ -1588,11 +1639,9 @@
- if (!handle)
- handle = iptc_init("filter");
-
-- if (!handle) {
--// try to insmod the module if iptc_init failed
-- iptables_insmod("ip_tables", modprobe);
-+ /* try to insmod the module if iptc_init failed */
-+ if (!handle && iptables_insmod("ip_tables", modprobe) != -1)
- handle = iptc_init("filter");
-- }
-
- if (!handle) {
- fprintf(stderr, "ipac-ng: can't initialize iptables table `filter'\n"
-@@ -1617,7 +1666,6 @@
- setup_rules(void)
- {
- raw_rule_type *d, *d1;
-- char targ[MAX_RULE_NAME_LENGTH+2];
- char chain[MAX_RULE_NAME_LENGTH+2];
- FILE *frunfile;
-
-diff -Nur ipac-ng-1.31.orig/agents/iptables/libip4tc.c ipac-ng-1.31/agents/iptables/libip4tc.c
---- ipac-ng-1.31.orig/agents/iptables/libip4tc.c 2003-07-06 10:33:23.000000000 +0000
-+++ ipac-ng-1.31/agents/iptables/libip4tc.c 2006-01-11 21:51:46.000000000 +0000
-@@ -16,6 +16,7 @@
- #include
- #include
- #include
-+#include
-
- #ifdef DEBUG_CONNTRACK
- #define inline
-@@ -90,6 +91,7 @@
- #define TC_SET_POLICY iptc_set_policy
- #define TC_GET_RAW_SOCKET iptc_get_raw_socket
- #define TC_INIT iptc_init
-+#define TC_FREE iptc_free
- #define TC_COMMIT iptc_commit
- #define TC_STRERROR iptc_strerror
-
-@@ -121,121 +123,49 @@
-
- #define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n))
-
--int
--dump_entry(STRUCT_ENTRY *e, const TC_HANDLE_T handle)
--{
-- size_t i;
-- STRUCT_ENTRY_TARGET *t;
--
-- printf("Entry %u (%lu):\n", entry2index(handle, e),
-- entry2offset(handle, e));
-- printf("SRC IP: %u.%u.%u.%u/%u.%u.%u.%u\n",
-- IP_PARTS(e->ip.src.s_addr),IP_PARTS(e->ip.smsk.s_addr));
-- printf("DST IP: %u.%u.%u.%u/%u.%u.%u.%u\n",
-- IP_PARTS(e->ip.dst.s_addr),IP_PARTS(e->ip.dmsk.s_addr));
-- printf("Interface: `%s'/", e->ip.iniface);
-- for (i = 0; i < IFNAMSIZ; i++)
-- printf("%c", e->ip.iniface_mask[i] ? 'X' : '.');
-- printf("to `%s'/", e->ip.outiface);
-- for (i = 0; i < IFNAMSIZ; i++)
-- printf("%c", e->ip.outiface_mask[i] ? 'X' : '.');
-- printf("\nProtocol: %u\n", e->ip.proto);
-- printf("Flags: %02X\n", e->ip.flags);
-- printf("Invflags: %02X\n", e->ip.invflags);
-- printf("Counters: %llu packets, %llu bytes\n",
-- e->counters.pcnt, e->counters.bcnt);
-- printf("Cache: %08X ", e->nfcache);
-- if (e->nfcache & NFC_ALTERED) printf("ALTERED ");
-- if (e->nfcache & NFC_UNKNOWN) printf("UNKNOWN ");
-- if (e->nfcache & NFC_IP_SRC) printf("IP_SRC ");
-- if (e->nfcache & NFC_IP_DST) printf("IP_DST ");
-- if (e->nfcache & NFC_IP_IF_IN) printf("IP_IF_IN ");
-- if (e->nfcache & NFC_IP_IF_OUT) printf("IP_IF_OUT ");
-- if (e->nfcache & NFC_IP_TOS) printf("IP_TOS ");
-- if (e->nfcache & NFC_IP_PROTO) printf("IP_PROTO ");
-- if (e->nfcache & NFC_IP_OPTIONS) printf("IP_OPTIONS ");
-- if (e->nfcache & NFC_IP_TCPFLAGS) printf("IP_TCPFLAGS ");
-- if (e->nfcache & NFC_IP_SRC_PT) printf("IP_SRC_PT ");
-- if (e->nfcache & NFC_IP_DST_PT) printf("IP_DST_PT ");
-- if (e->nfcache & NFC_IP_PROTO_UNKNOWN) printf("IP_PROTO_UNKNOWN ");
-- printf("\n");
--
-- IPT_MATCH_ITERATE(e, print_match);
--
-- t = GET_TARGET(e);
-- printf("Target name: `%s' [%u]\n", t->u.user.name, t->u.target_size);
-- if (strcmp(t->u.user.name, STANDARD_TARGET) == 0) {
-- int pos = *(int *)t->data;
-- if (pos < 0)
-- printf("verdict=%s\n",
-- pos == -NF_ACCEPT-1 ? "NF_ACCEPT"
-- : pos == -NF_DROP-1 ? "NF_DROP"
-- : pos == -NF_QUEUE-1 ? "NF_QUEUE"
-- : pos == RETURN ? "RETURN"
-- : "UNKNOWN");
-- else
-- printf("verdict=%u\n", pos);
-- } else if (strcmp(t->u.user.name, IPT_ERROR_TARGET) == 0)
-- printf("error=`%s'\n", t->data);
--
-- printf("\n");
-- return 0;
--}
-
--static int
-+static unsigned char *
- is_same(const STRUCT_ENTRY *a, const STRUCT_ENTRY *b, unsigned char *matchmask)
- {
- unsigned int i;
-- STRUCT_ENTRY_TARGET *ta, *tb;
- unsigned char *mptr;
-
- /* Always compare head structures: ignore mask here. */
- if (a->ip.src.s_addr != b->ip.src.s_addr
- || a->ip.dst.s_addr != b->ip.dst.s_addr
- || a->ip.smsk.s_addr != b->ip.smsk.s_addr
-- || a->ip.smsk.s_addr != b->ip.smsk.s_addr
-+ || a->ip.dmsk.s_addr != b->ip.dmsk.s_addr
- || a->ip.proto != b->ip.proto
- || a->ip.flags != b->ip.flags
- || a->ip.invflags != b->ip.invflags)
-- return 0;
-+ return NULL;
-
- for (i = 0; i < IFNAMSIZ; i++) {
- if (a->ip.iniface_mask[i] != b->ip.iniface_mask[i])
-- return 0;
-+ return NULL;
- if ((a->ip.iniface[i] & a->ip.iniface_mask[i])
- != (b->ip.iniface[i] & b->ip.iniface_mask[i]))
-- return 0;
-+ return NULL;
- if (a->ip.outiface_mask[i] != b->ip.outiface_mask[i])
-- return 0;
-+ return NULL;
- if ((a->ip.outiface[i] & a->ip.outiface_mask[i])
- != (b->ip.outiface[i] & b->ip.outiface_mask[i]))
-- return 0;
-+ return NULL;
- }
-
- if (a->nfcache != b->nfcache
- || a->target_offset != b->target_offset
- || a->next_offset != b->next_offset)
-- return 0;
-+ return NULL;
-
- mptr = matchmask + sizeof(STRUCT_ENTRY);
- if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems, &mptr))
-- return 0;
-+ return NULL;
-
-- ta = GET_TARGET((STRUCT_ENTRY *)a);
-- tb = GET_TARGET((STRUCT_ENTRY *)b);
-- if (ta->u.target_size != tb->u.target_size)
-- return 0;
-- if (strcmp(ta->u.user.name, tb->u.user.name) != 0)
-- return 0;
--
-- mptr += sizeof(*ta);
-- if (target_different(ta->data, tb->data,
-- ta->u.target_size - sizeof(*ta), mptr))
-- return 0;
--
-- return 1;
-+ return mptr;
- }
-
-+#if 0
- /***************************** DEBUGGING ********************************/
- static inline int
- unconditional(const struct ipt_ip *ip)
-@@ -290,20 +220,20 @@
- assert(t->verdict == -NF_DROP-1
- || t->verdict == -NF_ACCEPT-1
- || t->verdict == RETURN
-- || t->verdict < (int)h->entries.size);
-+ || t->verdict < (int)h->entries->size);
-
- if (t->verdict >= 0) {
- STRUCT_ENTRY *te = get_entry(h, t->verdict);
- int idx;
-
-- idx = entry2index(h, te);
-+ idx = iptcb_entry2index(h, te);
- assert(strcmp(GET_TARGET(te)->u.user.name,
- IPT_ERROR_TARGET)
- != 0);
- assert(te != e);
-
- /* Prior node must be error node, or this node. */
-- assert(t->verdict == entry2offset(h, e)+e->next_offset
-+ assert(t->verdict == iptcb_entry2offset(h, e)+e->next_offset
- || strcmp(GET_TARGET(index2entry(h, idx-1))
- ->u.user.name, IPT_ERROR_TARGET)
- == 0);
-@@ -335,7 +265,7 @@
- return 0;
- }
-
--#ifndef NDEBUG
-+#ifdef IPTC_DEBUG
- /* Do every conceivable sanity check on the handle */
- static void
- do_check(TC_HANDLE_T h, unsigned int line)
-@@ -364,35 +294,90 @@
-
- user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
- } else if (strcmp(h->info.name, "nat") == 0) {
-- assert(h->info.valid_hooks
-+ assert((h->info.valid_hooks
- == (1 << NF_IP_PRE_ROUTING
- | 1 << NF_IP_POST_ROUTING
-- | 1 << NF_IP_LOCAL_OUT));
-+ | 1 << NF_IP_LOCAL_OUT)) ||
-+ (h->info.valid_hooks
-+ == (1 << NF_IP_PRE_ROUTING
-+ | 1 << NF_IP_LOCAL_IN
-+ | 1 << NF_IP_POST_ROUTING
-+ | 1 << NF_IP_LOCAL_OUT)));
-
- assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
-
- n = get_chain_end(h, 0);
-+
- n += get_entry(h, n)->next_offset;
- assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);
--
- n = get_chain_end(h, n);
-+
- n += get_entry(h, n)->next_offset;
- assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
--
- user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
-+
-+ if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) {
-+ n = get_chain_end(h, n);
-+ n += get_entry(h, n)->next_offset;
-+ assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n);
-+ user_offset = h->info.hook_entry[NF_IP_LOCAL_IN];
-+ }
-+
- } else if (strcmp(h->info.name, "mangle") == 0) {
-+ /* This code is getting ugly because linux < 2.4.18-pre6 had
-+ * two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks
-+ * */
-+ assert((h->info.valid_hooks
-+ == (1 << NF_IP_PRE_ROUTING
-+ | 1 << NF_IP_LOCAL_OUT)) ||
-+ (h->info.valid_hooks
-+ == (1 << NF_IP_PRE_ROUTING
-+ | 1 << NF_IP_LOCAL_IN
-+ | 1 << NF_IP_FORWARD
-+ | 1 << NF_IP_LOCAL_OUT
-+ | 1 << NF_IP_POST_ROUTING)));
-+
-+ /* Hooks should be first five */
-+ assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
-+
-+ n = get_chain_end(h, 0);
-+
-+ if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) {
-+ n += get_entry(h, n)->next_offset;
-+ assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n);
-+ n = get_chain_end(h, n);
-+ }
-+
-+ if (h->info.valid_hooks & (1 << NF_IP_FORWARD)) {
-+ n += get_entry(h, n)->next_offset;
-+ assert(h->info.hook_entry[NF_IP_FORWARD] == n);
-+ n = get_chain_end(h, n);
-+ }
-+
-+ n += get_entry(h, n)->next_offset;
-+ assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
-+ user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
-+
-+ if (h->info.valid_hooks & (1 << NF_IP_POST_ROUTING)) {
-+ n = get_chain_end(h, n);
-+ n += get_entry(h, n)->next_offset;
-+ assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);
-+ user_offset = h->info.hook_entry[NF_IP_POST_ROUTING];
-+ }
-+ } else if (strcmp(h->info.name, "raw") == 0) {
- assert(h->info.valid_hooks
- == (1 << NF_IP_PRE_ROUTING
- | 1 << NF_IP_LOCAL_OUT));
-
-- /* Hooks should be first two */
-+ /* Hooks should be first three */
- assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
-
-- n = get_chain_end(h, 0);
-+ n = get_chain_end(h, n);
- n += get_entry(h, n)->next_offset;
- assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
-
- user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
-+
- #ifdef NF_IP_DROPPING
- } else if (strcmp(h->info.name, "drop") == 0) {
- assert(h->info.valid_hooks == (1 << NF_IP_DROPPING));
-@@ -425,8 +410,8 @@
- assert(unconditional(&e->ip));
- assert(e->target_offset == sizeof(*e));
- t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
-- assert(t->target.u.target_size == IPT_ALIGN(sizeof(*t)));
-- assert(e->next_offset == sizeof(*e) + IPT_ALIGN(sizeof(*t)));
-+ assert(t->target.u.target_size == ALIGN(sizeof(*t)));
-+ assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t)));
-
- assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0);
- assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1);
-@@ -458,6 +443,8 @@
- /* Final entry must be error node */
- assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1))
- ->u.user.name,
-- IPT_ERROR_TARGET) == 0);
-+ ERROR_TARGET) == 0);
- }
--#endif /*NDEBUG*/
-+#endif /*IPTC_DEBUG*/
-+
-+#endif
-diff -Nur ipac-ng-1.31.orig/agents/iptables/libiptc.c ipac-ng-1.31/agents/iptables/libiptc.c
---- ipac-ng-1.31.orig/agents/iptables/libiptc.c 2003-07-06 11:34:52.000000000 +0000
-+++ ipac-ng-1.31/agents/iptables/libiptc.c 2006-01-10 21:01:39.000000000 +0000
-@@ -9,21 +9,43 @@
- */
-
- /* (C)1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
-- COPYING for details). */
-+ * COPYING for details).
-+ * (C) 2000-2004 by the Netfilter Core Team
-+ *
-+ * 2003-Jun-20: Harald Welte :
-+ * - Reimplementation of chain cache to use offsets instead of entries
-+ * 2003-Jun-23: Harald Welte :
-+ * - performance optimization, sponsored by Astaro AG (http://www.astaro.com/)
-+ * don't rebuild the chain cache after every operation, instead fix it
-+ * up after a ruleset change.
-+ * 2004-Aug-18: Harald Welte :
-+ * - futher performance work: total reimplementation of libiptc.
-+ * - libiptc now has a real internal (linked-list) represntation of the
-+ * ruleset and a parser/compiler from/to this internal representation
-+ * - again sponsored by Astaro AG (http://www.astaro.com/)
-+ */
-+#include
-+#include
-
--#ifndef IPT_LIB_DIR
--#define IPT_LIB_DIR "/lib/iptables"
-+#include "linux_list.h"
-+
-+//#define IPTC_DEBUG2 1
-+
-+#ifdef IPTC_DEBUG2
-+#include
-+#define DEBUGP(x, args...) fprintf(stderr, "%s: " x, __FUNCTION__, ## args)
-+#define DEBUGP_C(x, args...) fprintf(stderr, x, ## args)
-+#else
-+#define DEBUGP(x, args...)
-+#define DEBUGP_C(x, args...)
- #endif
-
--#ifndef __OPTIMIZE__
--STRUCT_ENTRY_TARGET *
--GET_TARGET(STRUCT_ENTRY *e)
--{
-- return (void *)e + e->target_offset;
--}
-+#ifndef IPT_LIB_DIR
-+#define IPT_LIB_DIR "/usr/local/lib/iptables"
- #endif
-
- static int sockfd = -1;
-+static int sockfd_use = 0;
- static void *iptc_fn = NULL;
-
- static const char *hooknames[]
-@@ -37,6 +59,16 @@
- #endif
- };
-
-+/* Convenience structures */
-+struct ipt_error_target
-+{
-+ STRUCT_ENTRY_TARGET t;
-+ char error[TABLE_MAXNAMELEN];
-+};
-+
-+struct chain_head;
-+struct rule_head;
-+
- struct counter_map
- {
- enum {
-@@ -48,59 +80,95 @@
- unsigned int mappos;
- };
-
--/* Convenience structures */
--struct ipt_error_target
-+enum iptcc_rule_type {
-+ IPTCC_R_STANDARD, /* standard target (ACCEPT, ...) */
-+ IPTCC_R_MODULE, /* extension module (SNAT, ...) */
-+ IPTCC_R_FALLTHROUGH, /* fallthrough rule */
-+ IPTCC_R_JUMP, /* jump to other chain */
-+};
-+
-+struct rule_head
- {
-- STRUCT_ENTRY_TARGET t;
-- char error[TABLE_MAXNAMELEN];
-+ struct list_head list;
-+ struct chain_head *chain;
-+ struct counter_map counter_map;
-+
-+ unsigned int index; /* index (needed for counter_map) */
-+ unsigned int offset; /* offset in rule blob */
-+
-+ enum iptcc_rule_type type;
-+ struct chain_head *jump; /* jump target, if IPTCC_R_JUMP */
-+
-+ unsigned int size; /* size of entry data */
-+ STRUCT_ENTRY entry[0];
- };
-
--struct chain_cache
-+struct chain_head
- {
-+ struct list_head list;
- char name[TABLE_MAXNAMELEN];
-- /* This is the first rule in chain. */
-- STRUCT_ENTRY *start;
-- /* Last rule in chain */
-- STRUCT_ENTRY *end;
-+ unsigned int hooknum; /* hook number+1 if builtin */
-+ unsigned int references; /* how many jumps reference us */
-+ int verdict; /* verdict if builtin */
-+
-+ STRUCT_COUNTERS counters; /* per-chain counters */
-+ struct counter_map counter_map;
-+
-+ unsigned int num_rules; /* number of rules in list */
-+ struct list_head rules; /* list of rules */
-+
-+ unsigned int index; /* index (needed for jump resolval) */
-+ unsigned int head_offset; /* offset in rule blob */
-+ unsigned int foot_index; /* index (needed for counter_map) */
-+ unsigned int foot_offset; /* offset in rule blob */
- };
-
- STRUCT_TC_HANDLE
- {
-- /* Have changes been made? */
-- int changed;
-- /* Size in here reflects original state. */
-- STRUCT_GETINFO info;
-+ int changed; /* Have changes been made? */
-+
-+ struct list_head chains;
-+
-+ struct chain_head *chain_iterator_cur;
-+ struct rule_head *rule_iterator_cur;
-
-- struct counter_map *counter_map;
-- /* Array of hook names */
-- const char **hooknames;
--
-- /* Cached position of chain heads (NULL = no cache). */
-- unsigned int cache_num_chains;
-- unsigned int cache_num_builtins;
-- struct chain_cache *cache_chain_heads;
--
-- /* Chain iterator: current chain cache entry. */
-- struct chain_cache *cache_chain_iteration;
--
-- /* Rule iterator: terminal rule */
-- STRUCT_ENTRY *cache_rule_end;
--
-- /* Number in here reflects current state. */
-- unsigned int new_number;
-- STRUCT_GET_ENTRIES entries;
-+ STRUCT_GETINFO info;
-+ STRUCT_GET_ENTRIES *entries;
- };
-
-+/* allocate a new chain head for the cache */
-+static struct chain_head *iptcc_alloc_chain_head(const char *name, int hooknum)
-+{
-+ struct chain_head *c = malloc(sizeof(*c));
-+ if (!c)
-+ return NULL;
-+ memset(c, 0, sizeof(*c));
-+
-+ strncpy(c->name, name, TABLE_MAXNAMELEN);
-+ c->hooknum = hooknum;
-+ INIT_LIST_HEAD(&c->rules);
-+
-+ return c;
-+}
-+
-+/* allocate and initialize a new rule for the cache */
-+static struct rule_head *iptcc_alloc_rule(struct chain_head *c, unsigned int size)
-+{
-+ struct rule_head *r = malloc(sizeof(*r)+size);
-+ if (!r)
-+ return NULL;
-+ memset(r, 0, sizeof(*r));
-+
-+ r->chain = c;
-+ r->size = size;
-+
-+ return r;
-+}
-+
-+/* notify us that the ruleset has been modified by the user */
- static void
- set_changed(TC_HANDLE_T h)
- {
-- if (h->cache_chain_heads) {
-- free(h->cache_chain_heads);
-- h->cache_chain_heads = NULL;
-- h->cache_num_chains = 0;
-- h->cache_chain_iteration = NULL;
-- h->cache_rule_end = NULL;
-- }
- h->changed = 1;
- }
-
-@@ -111,8 +179,13 @@
- #define CHECK(h)
- #endif
-
-+
-+/**********************************************************************
-+ * iptc blob utility functions (iptcb_*)
-+ **********************************************************************/
-+
- static inline int
--get_number(const STRUCT_ENTRY *i,
-+iptcb_get_number(const STRUCT_ENTRY *i,
- const STRUCT_ENTRY *seek,
- unsigned int *pos)
- {
-@@ -122,22 +195,8 @@
- return 0;
- }
-
--static unsigned int
--entry2index(const TC_HANDLE_T h, const STRUCT_ENTRY *seek)
--{
-- unsigned int pos = 0;
--
-- if (ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
-- get_number, seek, &pos) == 0) {
-- fprintf(stderr, "ERROR: offset %i not an entry!\n",
-- (char *)seek - (char *)h->entries.entrytable);
-- abort();
-- }
-- return pos;
--}
--
- static inline int
--get_entry_n(STRUCT_ENTRY *i,
-+iptcb_get_entry_n(STRUCT_ENTRY *i,
- unsigned int number,
- unsigned int *pos,
- STRUCT_ENTRY **pe)
-@@ -150,51 +209,556 @@
- return 0;
- }
-
--static STRUCT_ENTRY *
--index2entry(TC_HANDLE_T h, unsigned int index)
-+static inline STRUCT_ENTRY *
-+iptcb_get_entry(TC_HANDLE_T h, unsigned int offset)
- {
-- unsigned int pos = 0;
-- STRUCT_ENTRY *ret = NULL;
-+ return (STRUCT_ENTRY *)((char *)h->entries->entrytable + offset);
-+}
-
-- ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
-- get_entry_n, index, &pos, &ret);
-+static unsigned int
-+iptcb_entry2index(const TC_HANDLE_T h, const STRUCT_ENTRY *seek)
-+{
-+ unsigned int pos = 0;
-
-- return ret;
-+ if (ENTRY_ITERATE(h->entries->entrytable, h->entries->size,
-+ iptcb_get_number, seek, &pos) == 0) {
-+ fprintf(stderr, "ERROR: offset %u not an entry!\n",
-+ (unsigned int)((char *)seek - (char *)h->entries->entrytable));
-+ abort();
-+ }
-+ return pos;
- }
-
- static inline STRUCT_ENTRY *
--get_entry(TC_HANDLE_T h, unsigned int offset)
-+iptcb_offset2entry(TC_HANDLE_T h, unsigned int offset)
- {
-- return (STRUCT_ENTRY *)((char *)h->entries.entrytable + offset);
-+ return (STRUCT_ENTRY *) ((void *)h->entries->entrytable+offset);
- }
-
-+
- static inline unsigned long
--entry2offset(const TC_HANDLE_T h, const STRUCT_ENTRY *e)
-+iptcb_entry2offset(const TC_HANDLE_T h, const STRUCT_ENTRY *e)
- {
-- return (char *)e - (char *)h->entries.entrytable;
-+ return (void *)e - (void *)h->entries->entrytable;
- }
-
--static unsigned long
--index2offset(TC_HANDLE_T h, unsigned int index)
-+static inline unsigned int
-+iptcb_offset2index(const TC_HANDLE_T h, unsigned int offset)
- {
-- return entry2offset(h, index2entry(h, index));
-+ return iptcb_entry2index(h, iptcb_offset2entry(h, offset));
- }
-
--static const char *
--get_errorlabel(TC_HANDLE_T h, unsigned int offset)
-+/* Returns 0 if not hook entry, else hooknumber + 1 */
-+static inline unsigned int
-+iptcb_ent_is_hook_entry(STRUCT_ENTRY *e, TC_HANDLE_T h)
- {
-- STRUCT_ENTRY *e;
-+ unsigned int i;
-
-- e = get_entry(h, offset);
-- if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) != 0) {
-- fprintf(stderr, "ERROR: offset %u not an error node!\n",
-- offset);
-- abort();
-+ for (i = 0; i < NUMHOOKS; i++) {
-+ if ((h->info.valid_hooks & (1 << i))
-+ && iptcb_get_entry(h, h->info.hook_entry[i]) == e)
-+ return i+1;
-+ }
-+ return 0;
-+}
-+
-+
-+/**********************************************************************
-+ * iptc cache utility functions (iptcc_*)
-+ **********************************************************************/
-+
-+/* Is the given chain builtin (1) or user-defined (0) */
-+static unsigned int iptcc_is_builtin(struct chain_head *c)
-+{
-+ return (c->hooknum ? 1 : 0);
-+}
-+
-+/* Get a specific rule within a chain */
-+static struct rule_head *iptcc_get_rule_num(struct chain_head *c,
-+ unsigned int rulenum)
-+{
-+ struct rule_head *r;
-+ unsigned int num = 0;
-+
-+ list_for_each_entry(r, &c->rules, list) {
-+ num++;
-+ if (num == rulenum)
-+ return r;
-+ }
-+ return NULL;
-+}
-+
-+/* Get a specific rule within a chain backwards */
-+static struct rule_head *iptcc_get_rule_num_reverse(struct chain_head *c,
-+ unsigned int rulenum)
-+{
-+ struct rule_head *r;
-+ unsigned int num = 0;
-+
-+ list_for_each_entry_reverse(r, &c->rules, list) {
-+ num++;
-+ if (num == rulenum)
-+ return r;
-+ }
-+ return NULL;
-+}
-+
-+/* Returns chain head if found, otherwise NULL. */
-+static struct chain_head *
-+iptcc_find_chain_by_offset(TC_HANDLE_T handle, unsigned int offset)
-+{
-+ struct list_head *pos;
-+
-+ if (list_empty(&handle->chains))
-+ return NULL;
-+
-+ list_for_each(pos, &handle->chains) {
-+ struct chain_head *c = list_entry(pos, struct chain_head, list);
-+ if (offset >= c->head_offset && offset <= c->foot_offset)
-+ return c;
-+ }
-+
-+ return NULL;
-+}
-+/* Returns chain head if found, otherwise NULL. */
-+static struct chain_head *
-+iptcc_find_label(const char *name, TC_HANDLE_T handle)
-+{
-+ struct list_head *pos;
-+
-+ if (list_empty(&handle->chains))
-+ return NULL;
-+
-+ list_for_each(pos, &handle->chains) {
-+ struct chain_head *c = list_entry(pos, struct chain_head, list);
-+ if (!strcmp(c->name, name))
-+ return c;
-+ }
-+
-+ return NULL;
-+}
-+
-+/* called when rule is to be removed from cache */
-+static void iptcc_delete_rule(struct rule_head *r)
-+{
-+ DEBUGP("deleting rule %p (offset %u)\n", r, r->offset);
-+ /* clean up reference count of called chain */
-+ if (r->type == IPTCC_R_JUMP
-+ && r->jump)
-+ r->jump->references--;
-+
-+ list_del(&r->list);
-+ free(r);
-+}
-+
-+
-+/**********************************************************************
-+ * RULESET PARSER (blob -> cache)
-+ **********************************************************************/
-+
-+/* Delete policy rule of previous chain, since cache doesn't contain
-+ * chain policy rules.
-+ * WARNING: This function has ugly design and relies on a lot of context, only
-+ * to be called from specific places within the parser */
-+static int __iptcc_p_del_policy(TC_HANDLE_T h, unsigned int num)
-+{
-+ if (h->chain_iterator_cur) {
-+ /* policy rule is last rule */
-+ struct rule_head *pr = (struct rule_head *)
-+ h->chain_iterator_cur->rules.prev;
-+
-+ /* save verdict */
-+ h->chain_iterator_cur->verdict =
-+ *(int *)GET_TARGET(pr->entry)->data;
-+
-+ /* save counter and counter_map information */
-+ h->chain_iterator_cur->counter_map.maptype =
-+ COUNTER_MAP_NORMAL_MAP;
-+ h->chain_iterator_cur->counter_map.mappos = num-1;
-+ memcpy(&h->chain_iterator_cur->counters, &pr->entry->counters,
-+ sizeof(h->chain_iterator_cur->counters));
-+
-+ /* foot_offset points to verdict rule */
-+ h->chain_iterator_cur->foot_index = num;
-+ h->chain_iterator_cur->foot_offset = pr->offset;
-+
-+ /* delete rule from cache */
-+ iptcc_delete_rule(pr);
-+ h->chain_iterator_cur->num_rules--;
-+
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/* alphabetically insert a chain into the list */
-+static inline void iptc_insert_chain(TC_HANDLE_T h, struct chain_head *c)
-+{
-+ struct chain_head *tmp;
-+
-+ /* sort only user defined chains */
-+ if (!c->hooknum) {
-+ list_for_each_entry(tmp, &h->chains, list) {
-+ if (strcmp(c->name, tmp->name) <= 0) {
-+ list_add(&c->list, tmp->list.prev);
-+ return;
-+ }
-+ }
-+ }
-+
-+ /* survived till end of list: add at tail */
-+ list_add_tail(&c->list, &h->chains);
-+}
-+
-+/* Another ugly helper function split out of cache_add_entry to make it less
-+ * spaghetti code */
-+static void __iptcc_p_add_chain(TC_HANDLE_T h, struct chain_head *c,
-+ unsigned int offset, unsigned int *num)
-+{
-+ __iptcc_p_del_policy(h, *num);
-+
-+ c->head_offset = offset;
-+ c->index = *num;
-+
-+ iptc_insert_chain(h, c);
-+
-+ h->chain_iterator_cur = c;
-+}
-+
-+/* main parser function: add an entry from the blob to the cache */
-+static int cache_add_entry(STRUCT_ENTRY *e,
-+ TC_HANDLE_T h,
-+ STRUCT_ENTRY **prev,
-+ unsigned int *num)
-+{
-+ unsigned int builtin;
-+ unsigned int offset = (char *)e - (char *)h->entries->entrytable;
-+
-+ DEBUGP("entering...");
-+
-+ /* Last entry ("policy rule"). End it.*/
-+ if (iptcb_entry2offset(h,e) + e->next_offset == h->entries->size) {
-+ /* This is the ERROR node at the end of the chain */
-+ DEBUGP_C("%u:%u: end of table:\n", *num, offset);
-+
-+ __iptcc_p_del_policy(h, *num);
-+
-+ h->chain_iterator_cur = NULL;
-+ goto out_inc;
-+ }
-+
-+ /* We know this is the start of a new chain if it's an ERROR
-+ * target, or a hook entry point */
-+
-+ if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) == 0) {
-+ struct chain_head *c =
-+ iptcc_alloc_chain_head((const char *)GET_TARGET(e)->data, 0);
-+ DEBUGP_C("%u:%u:new userdefined chain %s: %p\n", *num, offset,
-+ (char *)c->name, c);
-+ if (!c) {
-+ errno = -ENOMEM;
-+ return -1;
-+ }
-+
-+ __iptcc_p_add_chain(h, c, offset, num);
-+
-+ } else if ((builtin = iptcb_ent_is_hook_entry(e, h)) != 0) {
-+ struct chain_head *c =
-+ iptcc_alloc_chain_head((char *)hooknames[builtin-1],
-+ builtin);
-+ DEBUGP_C("%u:%u new builtin chain: %p (rules=%p)\n",
-+ *num, offset, c, &c->rules);
-+ if (!c) {
-+ errno = -ENOMEM;
-+ return -1;
-+ }
-+
-+ c->hooknum = builtin;
-+
-+ __iptcc_p_add_chain(h, c, offset, num);
-+
-+ /* FIXME: this is ugly. */
-+ goto new_rule;
-+ } else {
-+ /* has to be normal rule */
-+ struct rule_head *r;
-+new_rule:
-+
-+ if (!(r = iptcc_alloc_rule(h->chain_iterator_cur,
-+ e->next_offset))) {
-+ errno = ENOMEM;
-+ return -1;
-+ }
-+ DEBUGP_C("%u:%u normal rule: %p: ", *num, offset, r);
-+
-+ r->index = *num;
-+ r->offset = offset;
-+ memcpy(r->entry, e, e->next_offset);
-+ r->counter_map.maptype = COUNTER_MAP_NORMAL_MAP;
-+ r->counter_map.mappos = r->index;
-+
-+ /* handling of jumps, etc. */
-+ if (!strcmp(GET_TARGET(e)->u.user.name, STANDARD_TARGET)) {
-+ STRUCT_STANDARD_TARGET *t;
-+
-+ t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
-+ if (t->target.u.target_size
-+ != ALIGN(sizeof(STRUCT_STANDARD_TARGET))) {
-+ errno = EINVAL;
-+ return -1;
-+ }
-+
-+ if (t->verdict < 0) {
-+ DEBUGP_C("standard, verdict=%d\n", t->verdict);
-+ r->type = IPTCC_R_STANDARD;
-+ } else if (t->verdict == r->offset+e->next_offset) {
-+ DEBUGP_C("fallthrough\n");
-+ r->type = IPTCC_R_FALLTHROUGH;
-+ } else {
-+ DEBUGP_C("jump, target=%u\n", t->verdict);
-+ r->type = IPTCC_R_JUMP;
-+ /* Jump target fixup has to be deferred
-+ * until second pass, since we migh not
-+ * yet have parsed the target */
-+ }
-+ } else {
-+ DEBUGP_C("module, target=%s\n", GET_TARGET(e)->u.user.name);
-+ r->type = IPTCC_R_MODULE;
-+ }
-+
-+ list_add_tail(&r->list, &h->chain_iterator_cur->rules);
-+ h->chain_iterator_cur->num_rules++;
-+ }
-+out_inc:
-+ (*num)++;
-+ return 0;
-+}
-+
-+
-+/* parse an iptables blob into it's pieces */
-+static int parse_table(TC_HANDLE_T h)
-+{
-+ STRUCT_ENTRY *prev;
-+ unsigned int num = 0;
-+ struct chain_head *c;
-+
-+ /* First pass: over ruleset blob */
-+ ENTRY_ITERATE(h->entries->entrytable, h->entries->size,
-+ cache_add_entry, h, &prev, &num);
-+
-+ /* Second pass: fixup parsed data from first pass */
-+ list_for_each_entry(c, &h->chains, list) {
-+ struct rule_head *r;
-+ list_for_each_entry(r, &c->rules, list) {
-+ struct chain_head *c;
-+ STRUCT_STANDARD_TARGET *t;
-+
-+ if (r->type != IPTCC_R_JUMP)
-+ continue;
-+
-+ t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
-+ c = iptcc_find_chain_by_offset(h, t->verdict);
-+ if (!c)
-+ return -1;
-+ r->jump = c;
-+ c->references++;
-+ }
-+ }
-+
-+ /* FIXME: sort chains */
-+
-+ return 1;
-+}
-+
-+
-+/**********************************************************************
-+ * RULESET COMPILATION (cache -> blob)
-+ **********************************************************************/
-+
-+/* Convenience structures */
-+struct iptcb_chain_start{
-+ STRUCT_ENTRY e;
-+ struct ipt_error_target name;
-+};
-+#define IPTCB_CHAIN_START_SIZE (sizeof(STRUCT_ENTRY) + \
-+ ALIGN(sizeof(struct ipt_error_target)))
-+
-+struct iptcb_chain_foot {
-+ STRUCT_ENTRY e;
-+ STRUCT_STANDARD_TARGET target;
-+};
-+#define IPTCB_CHAIN_FOOT_SIZE (sizeof(STRUCT_ENTRY) + \
-+ ALIGN(sizeof(STRUCT_STANDARD_TARGET)))
-+
-+struct iptcb_chain_error {
-+ STRUCT_ENTRY entry;
-+ struct ipt_error_target target;
-+};
-+#define IPTCB_CHAIN_ERROR_SIZE (sizeof(STRUCT_ENTRY) + \
-+ ALIGN(sizeof(struct ipt_error_target)))
-+
-+
-+
-+/* compile rule from cache into blob */
-+static inline int iptcc_compile_rule (TC_HANDLE_T h, STRUCT_REPLACE *repl, struct rule_head *r)
-+{
-+ /* handle jumps */
-+ if (r->type == IPTCC_R_JUMP) {
-+ STRUCT_STANDARD_TARGET *t;
-+ t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
-+ /* memset for memcmp convenience on delete/replace */
-+ memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
-+ strcpy(t->target.u.user.name, STANDARD_TARGET);
-+ /* Jumps can only happen to builtin chains, so we
-+ * can safely assume that they always have a header */
-+ t->verdict = r->jump->head_offset + IPTCB_CHAIN_START_SIZE;
-+ } else if (r->type == IPTCC_R_FALLTHROUGH) {
-+ STRUCT_STANDARD_TARGET *t;
-+ t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
-+ t->verdict = r->offset + r->size;
-+ }
-+
-+ /* copy entry from cache to blob */
-+ memcpy((char *)repl->entries+r->offset, r->entry, r->size);
-+
-+ return 1;
-+}
-+
-+/* compile chain from cache into blob */
-+static int iptcc_compile_chain(TC_HANDLE_T h, STRUCT_REPLACE *repl, struct chain_head *c)
-+{
-+ int ret;
-+ struct rule_head *r;
-+ struct iptcb_chain_start *head;
-+ struct iptcb_chain_foot *foot;
-+
-+ /* only user-defined chains have heaer */
-+ if (!iptcc_is_builtin(c)) {
-+ /* put chain header in place */
-+ head = (void *)repl->entries + c->head_offset;
-+ head->e.target_offset = sizeof(STRUCT_ENTRY);
-+ head->e.next_offset = IPTCB_CHAIN_START_SIZE;
-+ strcpy(head->name.t.u.user.name, ERROR_TARGET);
-+ head->name.t.u.target_size =
-+ ALIGN(sizeof(struct ipt_error_target));
-+ strcpy(head->name.error, c->name);
-+ } else {
-+ repl->hook_entry[c->hooknum-1] = c->head_offset;
-+ repl->underflow[c->hooknum-1] = c->foot_offset;
-+ }
-+
-+ /* iterate over rules */
-+ list_for_each_entry(r, &c->rules, list) {
-+ ret = iptcc_compile_rule(h, repl, r);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ /* put chain footer in place */
-+ foot = (void *)repl->entries + c->foot_offset;
-+ foot->e.target_offset = sizeof(STRUCT_ENTRY);
-+ foot->e.next_offset = IPTCB_CHAIN_FOOT_SIZE;
-+ strcpy(foot->target.target.u.user.name, STANDARD_TARGET);
-+ foot->target.target.u.target_size =
-+ ALIGN(sizeof(STRUCT_STANDARD_TARGET));
-+ /* builtin targets have verdict, others return */
-+ if (iptcc_is_builtin(c))
-+ foot->target.verdict = c->verdict;
-+ else
-+ foot->target.verdict = RETURN;
-+ /* set policy-counters */
-+ memcpy(&foot->e.counters, &c->counters, sizeof(STRUCT_COUNTERS));
-+
-+ return 0;
-+}
-+
-+/* calculate offset and number for every rule in the cache */
-+static int iptcc_compile_chain_offsets(TC_HANDLE_T h, struct chain_head *c,
-+ int *offset, int *num)
-+{
-+ struct rule_head *r;
-+
-+ c->head_offset = *offset;
-+ DEBUGP("%s: chain_head %u, offset=%u\n", c->name, *num, *offset);
-+
-+ if (!iptcc_is_builtin(c)) {
-+ /* Chain has header */
-+ *offset += sizeof(STRUCT_ENTRY)
-+ + ALIGN(sizeof(struct ipt_error_target));
-+ (*num)++;
-+ }
-+
-+ list_for_each_entry(r, &c->rules, list) {
-+ DEBUGP("rule %u, offset=%u, index=%u\n", *num, *offset, *num);
-+ r->offset = *offset;
-+ r->index = *num;
-+ *offset += r->size;
-+ (*num)++;
-+ }
-+
-+ DEBUGP("%s; chain_foot %u, offset=%u, index=%u\n", c->name, *num,
-+ *offset, *num);
-+ c->foot_offset = *offset;
-+ c->foot_index = *num;
-+ *offset += sizeof(STRUCT_ENTRY)
-+ + ALIGN(sizeof(STRUCT_STANDARD_TARGET));
-+ (*num)++;
-+
-+ return 1;
-+}
-+
-+/* put the pieces back together again */
-+static int iptcc_compile_table_prep(TC_HANDLE_T h, unsigned int *size)
-+{
-+ struct chain_head *c;
-+ unsigned int offset = 0, num = 0;
-+ int ret = 0;
-+
-+ /* First pass: calculate offset for every rule */
-+ list_for_each_entry(c, &h->chains, list) {
-+ ret = iptcc_compile_chain_offsets(h, c, &offset, &num);
-+ if (ret < 0)
-+ return ret;
- }
-
-- return (const char *)GET_TARGET(e)->data;
-+ /* Append one error rule at end of chain */
-+ num++;
-+ offset += sizeof(STRUCT_ENTRY)
-+ + ALIGN(sizeof(struct ipt_error_target));
-+
-+ /* ruleset size is now in offset */
-+ *size = offset;
-+ return num;
- }
-
-+static int iptcc_compile_table(TC_HANDLE_T h, STRUCT_REPLACE *repl)
-+{
-+ struct chain_head *c;
-+ struct iptcb_chain_error *error;
-+
-+ /* Second pass: copy from cache to offsets, fill in jumps */
-+ list_for_each_entry(c, &h->chains, list) {
-+ int ret = iptcc_compile_chain(h, repl, c);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ /* Append error rule at end of chain */
-+ error = (void *)repl->entries + repl->size - IPTCB_CHAIN_ERROR_SIZE;
-+ error->entry.target_offset = sizeof(STRUCT_ENTRY);
-+ error->entry.next_offset = IPTCB_CHAIN_ERROR_SIZE;
-+ error->target.t.u.user.target_size =
-+ ALIGN(sizeof(struct ipt_error_target));
-+ strcpy((char *)&error->target.t.u.user.name, ERROR_TARGET);
-+ strcpy((char *)&error->target.error, "ERROR");
-+
-+ return 1;
-+}
-+
-+/**********************************************************************
-+ * EXTERNAL API (operates on cache only)
-+ **********************************************************************/
-+
- /* Allocate handle of given size */
- static TC_HANDLE_T
- alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
-@@ -202,94 +766,139 @@
- size_t len;
- TC_HANDLE_T h;
-
-- len = sizeof(STRUCT_TC_HANDLE)
-- + size
-- + num_rules * sizeof(struct counter_map);
-+ len = sizeof(STRUCT_TC_HANDLE) + size;
-
-- if ((h = malloc(len)) == NULL) {
-+ h = malloc(sizeof(STRUCT_TC_HANDLE));
-+ if (!h) {
- errno = ENOMEM;
- return NULL;
- }
--
-- h->changed = 0;
-- h->cache_num_chains = 0;
-- h->cache_chain_heads = NULL;
-- h->counter_map = (void *)h
-- + sizeof(STRUCT_TC_HANDLE)
-- + size;
-+ memset(h, 0, sizeof(*h));
-+ INIT_LIST_HEAD(&h->chains);
- strcpy(h->info.name, tablename);
-- strcpy(h->entries.name, tablename);
-+
-+ h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + size);
-+ if (!h->entries)
-+ goto out_free_handle;
-+
-+ strcpy(h->entries->name, tablename);
-+ h->entries->size = size;
-
- return h;
-+
-+out_free_handle:
-+ free(h);
-+
-+ return NULL;
- }
-
-+
- TC_HANDLE_T
- TC_INIT(const char *tablename)
- {
- TC_HANDLE_T h;
- STRUCT_GETINFO info;
-- unsigned int i;
- int tmp;
- socklen_t s;
-
- iptc_fn = TC_INIT;
-
-- if (sockfd != -1)
-- close(sockfd);
-+ if (strlen(tablename) >= TABLE_MAXNAMELEN) {
-+ errno = EINVAL;
-+ return NULL;
-+ }
-
-+ if (sockfd_use == 0) {
- sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
- if (sockfd < 0)
- return NULL;
-+ }
-+ sockfd_use++;
-
- s = sizeof(info);
-- if (strlen(tablename) >= TABLE_MAXNAMELEN) {
-- errno = EINVAL;
-- return NULL;
-- }
-+
- strcpy(info.name, tablename);
-- if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0)
-+ if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) {
-+ if (--sockfd_use == 0) {
-+ close(sockfd);
-+ sockfd = -1;
-+ }
- return NULL;
-+ }
-
-- if ((h = alloc_handle(info.name, info.size, info.num_entries))
-- == NULL)
-- return NULL;
-+ DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
-+ info.valid_hooks, info.num_entries, info.size);
-
--/* Too hard --RR */
--#if 0
-- sprintf(pathname, "%s/%s", IPT_LIB_DIR, info.name);
-- dynlib = dlopen(pathname, RTLD_NOW);
-- if (!dynlib) {
-- errno = ENOENT;
-- return NULL;
-+ if ((h = alloc_handle(info.name, info.size, info.num_entries))
-+ == NULL) {
-+ if (--sockfd_use == 0) {
-+ close(sockfd);
-+ sockfd = -1;
- }
-- h->hooknames = dlsym(dynlib, "hooknames");
-- if (!h->hooknames) {
-- errno = ENOENT;
- return NULL;
- }
--#else
-- h->hooknames = hooknames;
--#endif
-
- /* Initialize current state */
- h->info = info;
-- h->new_number = h->info.num_entries;
-- for (i = 0; i < h->info.num_entries; i++)
-- h->counter_map[i]
-- = ((struct counter_map){COUNTER_MAP_NORMAL_MAP, i});
-
-- h->entries.size = h->info.size;
-+ h->entries->size = h->info.size;
-
- tmp = sizeof(STRUCT_GET_ENTRIES) + h->info.size;
-
-- if (getsockopt(sockfd, TC_IPPROTO, SO_GET_ENTRIES, &h->entries,
-- &tmp) < 0) {
-- free(h);
-- return NULL;
-+ if (getsockopt(sockfd, TC_IPPROTO, SO_GET_ENTRIES, h->entries,
-+ &tmp) < 0)
-+ goto error;
-+
-+#ifdef IPTC_DEBUG2
-+ {
-+ int fd = open("/tmp/libiptc-so_get_entries.blob",
-+ O_CREAT|O_WRONLY);
-+ if (fd >= 0) {
-+ write(fd, h->entries, tmp);
-+ close(fd);
-+ }
- }
-+#endif
-+
-+ if (parse_table(h) < 0)
-+ goto error;
-
- CHECK(h);
- return h;
-+error:
-+ if (--sockfd_use == 0) {
-+ close(sockfd);
-+ sockfd = -1;
-+ }
-+ TC_FREE(&h);
-+ return NULL;
-+}
-+
-+void
-+TC_FREE(TC_HANDLE_T *h)
-+{
-+ struct chain_head *c, *tmp;
-+
-+ iptc_fn = TC_FREE;
-+ if (--sockfd_use == 0) {
-+ close(sockfd);
-+ sockfd = -1;
-+ }
-+
-+ list_for_each_entry_safe(c, tmp, &(*h)->chains, list) {
-+ struct rule_head *r, *rtmp;
-+
-+ list_for_each_entry_safe(r, rtmp, &c->rules, list) {
-+ free(r);
-+ }
-+
-+ free(c);
-+ }
-+
-+ free((*h)->entries);
-+ free(*h);
-+
-+ *h = NULL;
- }
-
- static inline int
-@@ -304,11 +913,11 @@
- void
- TC_DUMP_ENTRIES(const TC_HANDLE_T handle)
- {
-+ iptc_fn = TC_DUMP_ENTRIES;
- CHECK(handle);
--
-- printf("libiptc v%s. %u entries, %u bytes.\n",
-- NETFILTER_VERSION,
-- handle->new_number, handle->entries.size);
-+#if 0
-+ printf("libiptc v%s. %u bytes.\n",
-+ IPTABLES_VERSION, handle->entries->size);
- printf("Table `%s'\n", handle->info.name);
- printf("Hooks: pre/in/fwd/out/post = %u/%u/%u/%u/%u\n",
- handle->info.hook_entry[HOOK_PRE_ROUTING],
-@@ -323,516 +932,277 @@
- handle->info.underflow[HOOK_LOCAL_OUT],
- handle->info.underflow[HOOK_POST_ROUTING]);
-
-- ENTRY_ITERATE(handle->entries.entrytable, handle->entries.size,
-+ ENTRY_ITERATE(handle->entries->entrytable, handle->entries->size,
- dump_entry, handle);
--}
--
--/* Returns 0 if not hook entry, else hooknumber + 1 */
--static inline unsigned int
--is_hook_entry(STRUCT_ENTRY *e, TC_HANDLE_T h)
--{
-- unsigned int i;
--
-- for (i = 0; i < NUMHOOKS; i++) {
-- if ((h->info.valid_hooks & (1 << i))
-- && get_entry(h, h->info.hook_entry[i]) == e)
-- return i+1;
-- }
-- return 0;
--}
--
--static inline int
--add_chain(STRUCT_ENTRY *e, TC_HANDLE_T h, STRUCT_ENTRY **prev)
--{
-- unsigned int builtin;
--
-- /* Last entry. End it. */
-- if (entry2offset(h, e) + e->next_offset == h->entries.size) {
-- /* This is the ERROR node at end of the table */
-- h->cache_chain_heads[h->cache_num_chains-1].end = *prev;
-- return 0;
-- }
--
-- /* We know this is the start of a new chain if it's an ERROR
-- target, or a hook entry point */
-- if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) == 0) {
-- /* prev was last entry in previous chain */
-- h->cache_chain_heads[h->cache_num_chains-1].end
-- = *prev;
--
-- strcpy(h->cache_chain_heads[h->cache_num_chains].name,
-- (const char *)GET_TARGET(e)->data);
-- h->cache_chain_heads[h->cache_num_chains].start
-- = (void *)e + e->next_offset;
-- h->cache_num_chains++;
-- } else if ((builtin = is_hook_entry(e, h)) != 0) {
-- if (h->cache_num_chains > 0)
-- /* prev was last entry in previous chain */
-- h->cache_chain_heads[h->cache_num_chains-1].end
-- = *prev;
--
-- strcpy(h->cache_chain_heads[h->cache_num_chains].name,
-- h->hooknames[builtin-1]);
-- h->cache_chain_heads[h->cache_num_chains].start
-- = (void *)e;
-- h->cache_num_chains++;
-- }
--
-- *prev = e;
-- return 0;
--}
--
--static int alphasort(const void *a, const void *b)
--{
-- return strcmp(((struct chain_cache *)a)->name,
-- ((struct chain_cache *)b)->name);
--}
--
--static int populate_cache(TC_HANDLE_T h)
--{
-- unsigned int i;
-- STRUCT_ENTRY *prev;
--
-- /* # chains < # rules / 2 + num builtins - 1 */
-- h->cache_chain_heads = malloc((h->new_number / 2 + 4)
-- * sizeof(struct chain_cache));
-- if (!h->cache_chain_heads) {
-- errno = ENOMEM;
-- return 0;
-- }
--
-- h->cache_num_chains = 0;
-- h->cache_num_builtins = 0;
--
-- /* Count builtins */
-- for (i = 0; i < NUMHOOKS; i++) {
-- if (h->info.valid_hooks & (1 << i))
-- h->cache_num_builtins++;
-- }
--
-- prev = NULL;
-- ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
-- add_chain, h, &prev);
--
-- qsort(h->cache_chain_heads + h->cache_num_builtins,
-- h->cache_num_chains - h->cache_num_builtins,
-- sizeof(struct chain_cache), alphasort);
--
-- return 1;
--}
--
--/* Returns cache ptr if found, otherwise NULL. */
--static struct chain_cache *
--find_label(const char *name, TC_HANDLE_T handle)
--{
-- unsigned int i;
--
-- if (handle->cache_chain_heads == NULL
-- && !populate_cache(handle))
-- return NULL;
--
-- /* FIXME: Linear search through builtins, then binary --RR */
-- for (i = 0; i < handle->cache_num_chains; i++) {
-- if (strcmp(handle->cache_chain_heads[i].name, name) == 0)
-- return &handle->cache_chain_heads[i];
-- }
--
-- return NULL;
-+#endif
- }
-
- /* Does this chain exist? */
- int TC_IS_CHAIN(const char *chain, const TC_HANDLE_T handle)
- {
-- return find_label(chain, handle) != NULL;
-+ iptc_fn = TC_IS_CHAIN;
-+ return iptcc_find_label(chain, handle) != NULL;
- }
-
--/* Returns the position of the final (ie. unconditional) element. */
--static unsigned int
--get_chain_end(const TC_HANDLE_T handle, unsigned int start)
-+static void iptcc_chain_iterator_advance(TC_HANDLE_T handle)
- {
-- unsigned int last_off, off;
-- STRUCT_ENTRY *e;
--
-- last_off = start;
-- e = get_entry(handle, start);
--
-- /* Terminate when we meet a error label or a hook entry. */
-- for (off = start + e->next_offset;
-- off < handle->entries.size;
-- last_off = off, off += e->next_offset) {
-- STRUCT_ENTRY_TARGET *t;
-- unsigned int i;
--
-- e = get_entry(handle, off);
--
-- /* We hit an entry point. */
-- for (i = 0; i < NUMHOOKS; i++) {
-- if ((handle->info.valid_hooks & (1 << i))
-- && off == handle->info.hook_entry[i])
-- return last_off;
-- }
-+ struct chain_head *c = handle->chain_iterator_cur;
-
-- /* We hit a user chain label */
-- t = GET_TARGET(e);
-- if (strcmp(t->u.user.name, ERROR_TARGET) == 0)
-- return last_off;
-- }
-- /* SHOULD NEVER HAPPEN */
-- fprintf(stderr, "ERROR: Off end (%u) of chain from %u!\n",
-- handle->entries.size, off);
-- abort();
-+ if (c->list.next == &handle->chains)
-+ handle->chain_iterator_cur = NULL;
-+ else
-+ handle->chain_iterator_cur =
-+ list_entry(c->list.next, struct chain_head, list);
- }
-
- /* Iterator functions to run through the chains. */
- const char *
- TC_FIRST_CHAIN(TC_HANDLE_T *handle)
- {
-- if ((*handle)->cache_chain_heads == NULL
-- && !populate_cache(*handle))
-+ struct chain_head *c = list_entry((*handle)->chains.next,
-+ struct chain_head, list);
-+
-+ iptc_fn = TC_FIRST_CHAIN;
-+
-+
-+ if (list_empty(&(*handle)->chains)) {
-+ DEBUGP(": no chains\n");
- return NULL;
-+ }
-
-- (*handle)->cache_chain_iteration
-- = &(*handle)->cache_chain_heads[0];
-+ (*handle)->chain_iterator_cur = c;
-+ iptcc_chain_iterator_advance(*handle);
-
-- return (*handle)->cache_chain_iteration->name;
-+ DEBUGP(": returning `%s'\n", c->name);
-+ return c->name;
- }
-
- /* Iterator functions to run through the chains. Returns NULL at end. */
- const char *
- TC_NEXT_CHAIN(TC_HANDLE_T *handle)
- {
-- (*handle)->cache_chain_iteration++;
-+ struct chain_head *c = (*handle)->chain_iterator_cur;
-
-- if ((*handle)->cache_chain_iteration - (*handle)->cache_chain_heads
-- == (*handle)->cache_num_chains)
-+ iptc_fn = TC_NEXT_CHAIN;
-+
-+ if (!c) {
-+ DEBUGP(": no more chains\n");
- return NULL;
-+ }
-
-- return (*handle)->cache_chain_iteration->name;
-+ iptcc_chain_iterator_advance(*handle);
-+
-+ DEBUGP(": returning `%s'\n", c->name);
-+ return c->name;
- }
-
- /* Get first rule in the given chain: NULL for empty chain. */
- const STRUCT_ENTRY *
- TC_FIRST_RULE(const char *chain, TC_HANDLE_T *handle)
- {
-- struct chain_cache *c;
-+ struct chain_head *c;
-+ struct rule_head *r;
-+
-+ iptc_fn = TC_FIRST_RULE;
-+
-+ DEBUGP("first rule(%s): ", chain);
-
-- c = find_label(chain, *handle);
-+ c = iptcc_find_label(chain, *handle);
- if (!c) {
- errno = ENOENT;
- return NULL;
- }
-
- /* Empty chain: single return/policy rule */
-- if (c->start == c->end)
-+ if (list_empty(&c->rules)) {
-+ DEBUGP_C("no rules, returning NULL\n");
- return NULL;
-+ }
-+
-+ r = list_entry(c->rules.next, struct rule_head, list);
-+ (*handle)->rule_iterator_cur = r;
-+ DEBUGP_C("%p\n", r);
-
-- (*handle)->cache_rule_end = c->end;
-- return c->start;
-+ return r->entry;
- }
-
- /* Returns NULL when rules run out. */
- const STRUCT_ENTRY *
- TC_NEXT_RULE(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
- {
-- if ((void *)prev + prev->next_offset
-- == (void *)(*handle)->cache_rule_end)
-+ struct rule_head *r;
-+
-+ iptc_fn = TC_NEXT_RULE;
-+ DEBUGP("rule_iterator_cur=%p...", (*handle)->rule_iterator_cur);
-+
-+ if (!(*handle)->rule_iterator_cur) {
-+ DEBUGP_C("returning NULL\n");
-+ return NULL;
-+ }
-+
-+ r = list_entry((*handle)->rule_iterator_cur->list.next,
-+ struct rule_head, list);
-+
-+ iptc_fn = TC_NEXT_RULE;
-+
-+ DEBUGP_C("next=%p, head=%p...", &r->list,
-+ &(*handle)->rule_iterator_cur->chain->rules);
-+
-+ if (&r->list == &(*handle)->rule_iterator_cur->chain->rules) {
-+ (*handle)->rule_iterator_cur = NULL;
-+ DEBUGP_C("finished, returning NULL\n");
- return NULL;
-+ }
-+
-+ (*handle)->rule_iterator_cur = r;
-
-- return (void *)prev + prev->next_offset;
-+ /* NOTE: prev is without any influence ! */
-+ DEBUGP_C("returning rule %p\n", r);
-+ return r->entry;
- }
-
--#if 0
- /* How many rules in this chain? */
- unsigned int
- TC_NUM_RULES(const char *chain, TC_HANDLE_T *handle)
- {
-- unsigned int off = 0;
-- STRUCT_ENTRY *start, *end;
--
-+ struct chain_head *c;
-+ iptc_fn = TC_NUM_RULES;
- CHECK(*handle);
-- if (!find_label(&off, chain, *handle)) {
-+
-+ c = iptcc_find_label(chain, *handle);
-+ if (!c) {
- errno = ENOENT;
- return (unsigned int)-1;
- }
-
-- start = get_entry(*handle, off);
-- end = get_entry(*handle, get_chain_end(*handle, off));
--
-- return entry2index(*handle, end) - entry2index(*handle, start);
-+ return c->num_rules;
- }
-
--/* Get n'th rule in this chain. */
- const STRUCT_ENTRY *TC_GET_RULE(const char *chain,
- unsigned int n,
- TC_HANDLE_T *handle)
- {
-- unsigned int pos = 0, chainindex;
-+ struct chain_head *c;
-+ struct rule_head *r;
-+
-+ iptc_fn = TC_GET_RULE;
-
- CHECK(*handle);
-- if (!find_label(&pos, chain, *handle)) {
-+
-+ c = iptcc_find_label(chain, *handle);
-+ if (!c) {
- errno = ENOENT;
- return NULL;
- }
-
-- chainindex = entry2index(*handle, get_entry(*handle, pos));
--
-- return index2entry(*handle, chainindex + n);
-+ r = iptcc_get_rule_num(c, n);
-+ if (!r)
-+ return NULL;
-+ return r->entry;
- }
--#endif
-
--static const char *
--target_name(TC_HANDLE_T handle, const STRUCT_ENTRY *ce)
-+/* Returns a pointer to the target name of this position. */
-+const char *standard_target_map(int verdict)
- {
-- int spos;
-- unsigned int labelidx;
-- STRUCT_ENTRY *jumpto;
--
-- /* To avoid const warnings */
-- STRUCT_ENTRY *e = (STRUCT_ENTRY *)ce;
--
-- if (strcmp(GET_TARGET(e)->u.user.name, STANDARD_TARGET) != 0)
-- return GET_TARGET(e)->u.user.name;
--
-- /* Standard target: evaluate */
-- spos = *(int *)GET_TARGET(e)->data;
-- if (spos < 0) {
-- if (spos == RETURN)
-+ switch (verdict) {
-+ case RETURN:
- return LABEL_RETURN;
-- else if (spos == -NF_ACCEPT-1)
-+ break;
-+ case -NF_ACCEPT-1:
- return LABEL_ACCEPT;
-- else if (spos == -NF_DROP-1)
-+ break;
-+ case -NF_DROP-1:
- return LABEL_DROP;
-- else if (spos == -NF_QUEUE-1)
-+ break;
-+ case -NF_QUEUE-1:
- return LABEL_QUEUE;
--
-- fprintf(stderr, "ERROR: off %lu/%u not a valid target (%i)\n",
-- entry2offset(handle, e), handle->entries.size,
-- spos);
-+ break;
-+ default:
-+ fprintf(stderr, "ERROR: %d not a valid target)\n",
-+ verdict);
- abort();
-+ break;
- }
--
-- jumpto = get_entry(handle, spos);
--
-- /* Fall through rule */
-- if (jumpto == (void *)e + e->next_offset)
-- return "";
--
-- /* Must point to head of a chain: ie. after error rule */
-- labelidx = entry2index(handle, jumpto) - 1;
-- return get_errorlabel(handle, index2offset(handle, labelidx));
-+ /* not reached */
-+ return NULL;
- }
-
- /* Returns a pointer to the target name of this position. */
--const char *TC_GET_TARGET(const STRUCT_ENTRY *e,
-+const char *TC_GET_TARGET(const STRUCT_ENTRY *ce,
- TC_HANDLE_T *handle)
- {
-- return target_name(*handle, e);
-+ STRUCT_ENTRY *e = (STRUCT_ENTRY *)ce;
-+ struct rule_head *r = container_of(e, struct rule_head, entry[0]);
-+
-+ iptc_fn = TC_GET_TARGET;
-+
-+ switch(r->type) {
-+ int spos;
-+ case IPTCC_R_FALLTHROUGH:
-+ return "";
-+ break;
-+ case IPTCC_R_JUMP:
-+ DEBUGP("r=%p, jump=%p, name=`%s'\n", r, r->jump, r->jump->name);
-+ return r->jump->name;
-+ break;
-+ case IPTCC_R_STANDARD:
-+ spos = *(int *)GET_TARGET(e)->data;
-+ DEBUGP("r=%p, spos=%d'\n", r, spos);
-+ return standard_target_map(spos);
-+ break;
-+ case IPTCC_R_MODULE:
-+ return GET_TARGET(e)->u.user.name;
-+ break;
-+}
-+ return NULL;
- }
--
- /* Is this a built-in chain? Actually returns hook + 1. */
- int
- TC_BUILTIN(const char *chain, const TC_HANDLE_T handle)
- {
-- unsigned int i;
-+ struct chain_head *c;
-
-- for (i = 0; i < NUMHOOKS; i++) {
-- if ((handle->info.valid_hooks & (1 << i))
-- && handle->hooknames[i]
-- && strcmp(handle->hooknames[i], chain) == 0)
-- return i+1;
-- }
-+ iptc_fn = TC_BUILTIN;
-+
-+ c = iptcc_find_label(chain, handle);
-+ if (!c) {
-+ errno = ENOENT;
- return 0;
- }
-
-+ return iptcc_is_builtin(c);
-+}
-+
- /* Get the policy of a given built-in chain */
- const char *
- TC_GET_POLICY(const char *chain,
- STRUCT_COUNTERS *counters,
-- TC_HANDLE_T *handle)
--{
-- unsigned int start;
-- STRUCT_ENTRY *e;
-- int hook;
--
-- hook = TC_BUILTIN(chain, *handle);
-- if (hook != 0)
-- start = (*handle)->info.hook_entry[hook-1];
-- else
-- return NULL;
--
-- e = get_entry(*handle, get_chain_end(*handle, start));
-- *counters = e->counters;
--
-- return target_name(*handle, e);
--}
--
--static int
--correct_verdict(STRUCT_ENTRY *e,
-- char *base,
-- unsigned int offset, int delta_offset)
--{
-- STRUCT_STANDARD_TARGET *t = (void *)GET_TARGET(e);
-- unsigned int curr = (char *)e - base;
--
-- /* Trap: insert of fall-through rule. Don't change fall-through
-- verdict to jump-over-next-rule. */
-- if (strcmp(t->target.u.user.name, STANDARD_TARGET) == 0
-- && t->verdict > (int)offset
-- && !(curr == offset &&
-- t->verdict == curr + e->next_offset)) {
-- t->verdict += delta_offset;
-- }
--
-- return 0;
--}
--
--/* Adjusts standard verdict jump positions after an insertion/deletion. */
--static int
--set_verdict(unsigned int offset, int delta_offset, TC_HANDLE_T *handle)
--{
-- ENTRY_ITERATE((*handle)->entries.entrytable,
-- (*handle)->entries.size,
-- correct_verdict, (char *)(*handle)->entries.entrytable,
-- offset, delta_offset);
--
-- set_changed(*handle);
-- return 1;
--}
--
--/* If prepend is set, then we are prepending to a chain: if the
-- * insertion position is an entry point, keep the entry point. */
--static int
--insert_rules(unsigned int num_rules, unsigned int rules_size,
-- const STRUCT_ENTRY *insert,
-- unsigned int offset, unsigned int num_rules_offset,
-- int prepend,
- TC_HANDLE_T *handle)
- {
-- TC_HANDLE_T newh;
-- STRUCT_GETINFO newinfo;
-- unsigned int i;
--
-- if (offset >= (*handle)->entries.size) {
-- errno = EINVAL;
-- return 0;
-- }
-+ struct chain_head *c;
-
-- newinfo = (*handle)->info;
--
-- /* Fix up entry points. */
-- for (i = 0; i < NUMHOOKS; i++) {
-- /* Entry points to START of chain, so keep same if
-- inserting on at that point. */
-- if ((*handle)->info.hook_entry[i] > offset)
-- newinfo.hook_entry[i] += rules_size;
--
-- /* Underflow always points to END of chain (policy),
-- so if something is inserted at same point, it
-- should be advanced. */
-- if ((*handle)->info.underflow[i] >= offset)
-- newinfo.underflow[i] += rules_size;
-- }
--
-- newh = alloc_handle((*handle)->info.name,
-- (*handle)->entries.size + rules_size,
-- (*handle)->new_number + num_rules);
-- if (!newh)
-- return 0;
-- newh->info = newinfo;
--
-- /* Copy pre... */
-- memcpy(newh->entries.entrytable, (*handle)->entries.entrytable,offset);
-- /* ... Insert new ... */
-- memcpy((char *)newh->entries.entrytable + offset, insert, rules_size);
-- /* ... copy post */
-- memcpy((char *)newh->entries.entrytable + offset + rules_size,
-- (char *)(*handle)->entries.entrytable + offset,
-- (*handle)->entries.size - offset);
--
-- /* Move counter map. */
-- /* Copy pre... */
-- memcpy(newh->counter_map, (*handle)->counter_map,
-- sizeof(struct counter_map) * num_rules_offset);
-- /* ... copy post */
-- memcpy(newh->counter_map + num_rules_offset + num_rules,
-- (*handle)->counter_map + num_rules_offset,
-- sizeof(struct counter_map) * ((*handle)->new_number
-- - num_rules_offset));
-- /* Set intermediates to no counter copy */
-- for (i = 0; i < num_rules; i++)
-- newh->counter_map[num_rules_offset+i]
-- = ((struct counter_map){ COUNTER_MAP_SET, 0 });
--
-- newh->new_number = (*handle)->new_number + num_rules;
-- newh->entries.size = (*handle)->entries.size + rules_size;
-- newh->hooknames = (*handle)->hooknames;
--
-- if ((*handle)->cache_chain_heads)
-- free((*handle)->cache_chain_heads);
-- free(*handle);
-- *handle = newh;
--
-- return set_verdict(offset, rules_size, handle);
--}
--
--static int
--delete_rules(unsigned int num_rules, unsigned int rules_size,
-- unsigned int offset, unsigned int num_rules_offset,
-- TC_HANDLE_T *handle)
--{
-- unsigned int i;
-+ iptc_fn = TC_GET_POLICY;
-
-- if (offset + rules_size > (*handle)->entries.size) {
-- errno = EINVAL;
-- return 0;
-- }
-+ DEBUGP("called for chain %s\n", chain);
-
-- /* Fix up entry points. */
-- for (i = 0; i < NUMHOOKS; i++) {
-- /* In practice, we never delete up to a hook entry,
-- since the built-in chains are always first,
-- so these two are never equal */
-- if ((*handle)->info.hook_entry[i] >= offset + rules_size)
-- (*handle)->info.hook_entry[i] -= rules_size;
-- else if ((*handle)->info.hook_entry[i] > offset) {
-- fprintf(stderr, "ERROR: Deleting entry %u %u %u\n",
-- i, (*handle)->info.hook_entry[i], offset);
-- abort();
-+ c = iptcc_find_label(chain, *handle);
-+ if (!c) {
-+ errno = ENOENT;
-+ return NULL;
- }
-
-- /* Underflow points to policy (terminal) rule in
-- built-in, so sequality is valid here (when deleting
-- the last rule). */
-- if ((*handle)->info.underflow[i] >= offset + rules_size)
-- (*handle)->info.underflow[i] -= rules_size;
-- else if ((*handle)->info.underflow[i] > offset) {
-- fprintf(stderr, "ERROR: Deleting uflow %u %u %u\n",
-- i, (*handle)->info.underflow[i], offset);
-- abort();
-- }
-- }
-+ if (!iptcc_is_builtin(c))
-+ return NULL;
-
-- /* Move the rules down. */
-- memmove((char *)(*handle)->entries.entrytable + offset,
-- (char *)(*handle)->entries.entrytable + offset + rules_size,
-- (*handle)->entries.size - (offset + rules_size));
--
-- /* Move the counter map down. */
-- memmove(&(*handle)->counter_map[num_rules_offset],
-- &(*handle)->counter_map[num_rules_offset + num_rules],
-- sizeof(struct counter_map)
-- * ((*handle)->new_number - (num_rules + num_rules_offset)));
--
-- /* Fix numbers */
-- (*handle)->new_number -= num_rules;
-- (*handle)->entries.size -= rules_size;
-+ *counters = c->counters;
-
-- return set_verdict(offset, -(int)rules_size, handle);
-+ return standard_target_map(c->verdict);
- }
-
- static int
--standard_map(STRUCT_ENTRY *e, int verdict)
-+iptcc_standard_map(struct rule_head *r, int verdict)
- {
-+ STRUCT_ENTRY *e = r->entry;
- STRUCT_STANDARD_TARGET *t;
-
- t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
-@@ -847,64 +1217,62 @@
- strcpy(t->target.u.user.name, STANDARD_TARGET);
- t->verdict = verdict;
-
-+ r->type = IPTCC_R_STANDARD;
-+
- return 1;
- }
-
- static int
--map_target(const TC_HANDLE_T handle,
-- STRUCT_ENTRY *e,
-- unsigned int offset,
-- STRUCT_ENTRY_TARGET *old)
-+iptcc_map_target(const TC_HANDLE_T handle,
-+ struct rule_head *r)
- {
-+ STRUCT_ENTRY *e = r->entry;
- STRUCT_ENTRY_TARGET *t = GET_TARGET(e);
-
-- /* Save old target (except data, which we don't change, except for
-- standard case, where we don't care). */
-- *old = *t;
--
- /* Maybe it's empty (=> fall through) */
-- if (strcmp(t->u.user.name, "") == 0)
-- return standard_map(e, offset + e->next_offset);
-+ if (strcmp(t->u.user.name, "") == 0) {
-+ r->type = IPTCC_R_FALLTHROUGH;
-+ return 1;
-+ }
- /* Maybe it's a standard target name... */
- else if (strcmp(t->u.user.name, LABEL_ACCEPT) == 0)
-- return standard_map(e, -NF_ACCEPT - 1);
-+ return iptcc_standard_map(r, -NF_ACCEPT - 1);
- else if (strcmp(t->u.user.name, LABEL_DROP) == 0)
-- return standard_map(e, -NF_DROP - 1);
-+ return iptcc_standard_map(r, -NF_DROP - 1);
- else if (strcmp(t->u.user.name, LABEL_QUEUE) == 0)
-- return standard_map(e, -NF_QUEUE - 1);
-+ return iptcc_standard_map(r, -NF_QUEUE - 1);
- else if (strcmp(t->u.user.name, LABEL_RETURN) == 0)
-- return standard_map(e, RETURN);
-+ return iptcc_standard_map(r, RETURN);
- else if (TC_BUILTIN(t->u.user.name, handle)) {
- /* Can't jump to builtins. */
- errno = EINVAL;
- return 0;
- } else {
- /* Maybe it's an existing chain name. */
-- struct chain_cache *c;
-+ struct chain_head *c;
-+ DEBUGP("trying to find chain `%s': ", t->u.user.name);
-
-- c = find_label(t->u.user.name, handle);
-- if (c)
-- return standard_map(e, entry2offset(handle, c->start));
-+ c = iptcc_find_label(t->u.user.name, handle);
-+ if (c) {
-+ DEBUGP_C("found!\n");
-+ r->type = IPTCC_R_JUMP;
-+ r->jump = c;
-+ c->references++;
-+ return 1;
-+}
-+ DEBUGP_C("not found :(\n");
- }
-
- /* Must be a module? If not, kernel will reject... */
-- /* memset to all 0 for your memcmp convenience. */
-+ /* memset to all 0 for your memcmp convenience: don't clear version */
- memset(t->u.user.name + strlen(t->u.user.name),
- 0,
-- FUNCTION_MAXNAMELEN - strlen(t->u.user.name));
-+ FUNCTION_MAXNAMELEN - 1 - strlen(t->u.user.name));
-+ r->type = IPTCC_R_MODULE;
-+ set_changed(handle);
- return 1;
- }
-
--static void
--unmap_target(STRUCT_ENTRY *e, STRUCT_ENTRY_TARGET *old)
--{
-- STRUCT_ENTRY_TARGET *t = GET_TARGET(e);
--
-- /* Save old target (except data, which we don't change, except for
-- standard case, where we don't care). */
-- *t = *old;
--}
--
- /* Insert the entry `fw' in chain `chain' into position `rulenum'. */
- int
- TC_INSERT_ENTRY(const IPT_CHAINLABEL chain,
-@@ -912,36 +1280,56 @@
- unsigned int rulenum,
- TC_HANDLE_T *handle)
- {
-- unsigned int chainindex, offset;
-- STRUCT_ENTRY_TARGET old;
-- struct chain_cache *c;
-- STRUCT_ENTRY *tmp;
-- int ret;
-+ struct chain_head *c;
-+ struct rule_head *r;
-+ struct list_head *prev;
-
- iptc_fn = TC_INSERT_ENTRY;
-- if (!(c = find_label(chain, *handle))) {
-+
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- chainindex = entry2index(*handle, c->start);
--
-- tmp = index2entry(*handle, chainindex + rulenum);
-- if (!tmp || tmp > c->end) {
-+ /* first rulenum index = 0
-+ first c->num_rules index = 1 */
-+ if (rulenum > c->num_rules) {
- errno = E2BIG;
- return 0;
- }
-- offset = index2offset(*handle, chainindex + rulenum);
-
-- /* Mapping target actually alters entry, but that's
-- transparent to the caller. */
-- if (!map_target(*handle, (STRUCT_ENTRY *)e, offset, &old))
-+ /* If we are inserting at the end just take advantage of the
-+ double linked list, insert will happen before the entry
-+ prev points to. */
-+ if (rulenum == c->num_rules) {
-+ prev = &c->rules;
-+ } else if (rulenum + 1 <= c->num_rules/2) {
-+ r = iptcc_get_rule_num(c, rulenum + 1);
-+ prev = &r->list;
-+ } else {
-+ r = iptcc_get_rule_num_reverse(c, c->num_rules - rulenum);
-+ prev = &r->list;
-+ }
-+
-+ if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
-+ errno = ENOMEM;
-+ return 0;
-+ }
-+
-+ memcpy(r->entry, e, e->next_offset);
-+ r->counter_map.maptype = COUNTER_MAP_SET;
-+
-+ if (!iptcc_map_target(*handle, r)) {
-+ free(r);
- return 0;
-+ }
-+
-+ list_add_tail(&r->list, prev);
-+ c->num_rules++;
-+
-+ set_changed(*handle);
-
-- ret = insert_rules(1, e->next_offset, e, offset,
-- chainindex + rulenum, rulenum == 0, handle);
-- unmap_target((STRUCT_ENTRY *)e, &old);
-- return ret;
-+ return 1;
- }
-
- /* Atomically replace rule `rulenum' in `chain' with `fw'. */
-@@ -951,40 +1339,47 @@
- unsigned int rulenum,
- TC_HANDLE_T *handle)
- {
-- unsigned int chainindex, offset;
-- STRUCT_ENTRY_TARGET old;
-- struct chain_cache *c;
-- STRUCT_ENTRY *tmp;
-- int ret;
-+ struct chain_head *c;
-+ struct rule_head *r, *old;
-
- iptc_fn = TC_REPLACE_ENTRY;
-
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- chainindex = entry2index(*handle, c->start);
--
-- tmp = index2entry(*handle, chainindex + rulenum);
-- if (!tmp || tmp >= c->end) {
-+ if (rulenum >= c->num_rules) {
- errno = E2BIG;
- return 0;
- }
-
-- offset = index2offset(*handle, chainindex + rulenum);
-- /* Replace = delete and insert. */
-- if (!delete_rules(1, get_entry(*handle, offset)->next_offset,
-- offset, chainindex + rulenum, handle))
-+ /* Take advantage of the double linked list if possible. */
-+ if (rulenum + 1 <= c->num_rules/2) {
-+ old = iptcc_get_rule_num(c, rulenum + 1);
-+ } else {
-+ old = iptcc_get_rule_num_reverse(c, c->num_rules - rulenum);
-+ }
-+
-+ if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
-+ errno = ENOMEM;
- return 0;
-+ }
-
-- if (!map_target(*handle, (STRUCT_ENTRY *)e, offset, &old))
-+ memcpy(r->entry, e, e->next_offset);
-+ r->counter_map.maptype = COUNTER_MAP_SET;
-+
-+ if (!iptcc_map_target(*handle, r)) {
-+ free(r);
- return 0;
-+ }
-+
-+ list_add(&r->list, &old->list);
-+ iptcc_delete_rule(old);
-+
-+ set_changed(*handle);
-
-- ret = insert_rules(1, e->next_offset, e, offset,
-- chainindex + rulenum, 1, handle);
-- unmap_target((STRUCT_ENTRY *)e, &old);
-- return ret;
-+ return 1;
- }
-
- /* Append entry `fw' to chain `chain'. Equivalent to insert with
-@@ -994,26 +1389,37 @@
- const STRUCT_ENTRY *e,
- TC_HANDLE_T *handle)
- {
-- struct chain_cache *c;
-- STRUCT_ENTRY_TARGET old;
-- int ret;
-+ struct chain_head *c;
-+ struct rule_head *r;
-
- iptc_fn = TC_APPEND_ENTRY;
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
-+ DEBUGP("unable to find chain `%s'\n", chain);
- errno = ENOENT;
- return 0;
- }
-
-- if (!map_target(*handle, (STRUCT_ENTRY *)e,
-- entry2offset(*handle, c->end), &old))
-+ if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
-+ DEBUGP("unable to allocate rule for chain `%s'\n", chain);
-+ errno = ENOMEM;
-+ return 0;
-+ }
-+
-+ memcpy(r->entry, e, e->next_offset);
-+ r->counter_map.maptype = COUNTER_MAP_SET;
-+
-+ if (!iptcc_map_target(*handle, r)) {
-+ DEBUGP("unable to map target of rule for chain `%s'\n", chain);
-+ free(r);
- return 0;
-+ }
-+
-+ list_add_tail(&r->list, &c->rules);
-+ c->num_rules++;
-+
-+ set_changed(*handle);
-
-- ret = insert_rules(1, e->next_offset, e,
-- entry2offset(*handle, c->end),
-- entry2index(*handle, c->end),
-- 0, handle);
-- unmap_target((STRUCT_ENTRY *)e, &old);
-- return ret;
-+ return 1;
- }
-
- static inline int
-@@ -1044,20 +1450,42 @@
- }
-
- static inline int
--target_different(const unsigned char *a_targdata,
-- const unsigned char *b_targdata,
-- unsigned int tdatasize,
-- const unsigned char *mask)
-+target_same(struct rule_head *a, struct rule_head *b,const unsigned char *mask)
- {
- unsigned int i;
-- for (i = 0; i < tdatasize; i++)
-- if (((a_targdata[i] ^ b_targdata[i]) & mask[i]) != 0)
-+ STRUCT_ENTRY_TARGET *ta, *tb;
-+
-+ if (a->type != b->type)
-+ return 0;
-+
-+ ta = GET_TARGET(a->entry);
-+ tb = GET_TARGET(b->entry);
-+
-+ switch (a->type) {
-+ case IPTCC_R_FALLTHROUGH:
- return 1;
-+ case IPTCC_R_JUMP:
-+ return a->jump == b->jump;
-+ case IPTCC_R_STANDARD:
-+ return ((STRUCT_STANDARD_TARGET *)ta)->verdict
-+ == ((STRUCT_STANDARD_TARGET *)tb)->verdict;
-+ case IPTCC_R_MODULE:
-+ if (ta->u.target_size != tb->u.target_size)
-+ return 0;
-+ if (strcmp(ta->u.user.name, tb->u.user.name) != 0)
-+ return 0;
-
-+ for (i = 0; i < ta->u.target_size - sizeof(*ta); i++)
-+ if (((ta->data[i] ^ tb->data[i]) & mask[i]) != 0)
- return 0;
-+ return 1;
-+ default:
-+ fprintf(stderr, "ERROR: bad type %i\n", a->type);
-+ abort();
-+ }
- }
-
--static int
-+static unsigned char *
- is_same(const STRUCT_ENTRY *a,
- const STRUCT_ENTRY *b,
- unsigned char *matchmask);
-@@ -1069,88 +1497,106 @@
- unsigned char *matchmask,
- TC_HANDLE_T *handle)
- {
-- unsigned int offset;
-- struct chain_cache *c;
-- STRUCT_ENTRY *e, *fw;
-+ struct chain_head *c;
-+ struct rule_head *r, *i;
-
- iptc_fn = TC_DELETE_ENTRY;
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- fw = malloc(origfw->next_offset);
-- if (fw == NULL) {
-+ /* Create a rule_head from origfw. */
-+ r = iptcc_alloc_rule(c, origfw->next_offset);
-+ if (!r) {
- errno = ENOMEM;
- return 0;
- }
-
-- for (offset = entry2offset(*handle, c->start);
-- offset < entry2offset(*handle, c->end);
-- offset += e->next_offset) {
-- STRUCT_ENTRY_TARGET discard;
--
-- memcpy(fw, origfw, origfw->next_offset);
--
-- /* FIXME: handle this in is_same --RR */
-- if (!map_target(*handle, fw, offset, &discard)) {
-- free(fw);
-+ memcpy(r->entry, origfw, origfw->next_offset);
-+ r->counter_map.maptype = COUNTER_MAP_NOMAP;
-+ if (!iptcc_map_target(*handle, r)) {
-+ DEBUGP("unable to map target of rule for chain `%s'\n", chain);
-+ free(r);
- return 0;
- }
-- e = get_entry(*handle, offset);
-
--#if 0
-- printf("Deleting:\n");
-- dump_entry(newe);
--#endif
-- if (is_same(e, fw, matchmask)) {
-- int ret;
-- ret = delete_rules(1, e->next_offset,
-- offset, entry2index(*handle, e),
-- handle);
-- free(fw);
-- return ret;
-+ list_for_each_entry(i, &c->rules, list) {
-+ unsigned char *mask;
-+
-+ mask = is_same(r->entry, i->entry, matchmask);
-+ if (!mask)
-+ continue;
-+
-+ if (!target_same(r, i, mask))
-+ continue;
-+
-+ /* If we are about to delete the rule that is the
-+ * current iterator, move rule iterator back. next
-+ * pointer will then point to real next node */
-+ if (i == (*handle)->rule_iterator_cur) {
-+ (*handle)->rule_iterator_cur =
-+ list_entry((*handle)->rule_iterator_cur->list.prev,
-+ struct rule_head, list);
- }
-+
-+ c->num_rules--;
-+ iptcc_delete_rule(i);
-+
-+ set_changed(*handle);
-+ free(r);
-+ return 1;
- }
-
-- free(fw);
-+ free(r);
- errno = ENOENT;
- return 0;
- }
-
-+
- /* Delete the rule in position `rulenum' in `chain'. */
- int
- TC_DELETE_NUM_ENTRY(const IPT_CHAINLABEL chain,
- unsigned int rulenum,
- TC_HANDLE_T *handle)
- {
-- unsigned int index;
-- int ret;
-- STRUCT_ENTRY *e;
-- struct chain_cache *c;
-+ struct chain_head *c;
-+ struct rule_head *r;
-
- iptc_fn = TC_DELETE_NUM_ENTRY;
-- if (!(c = find_label(chain, *handle))) {
-+
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- index = entry2index(*handle, c->start) + rulenum;
--
-- if (index >= entry2index(*handle, c->end)) {
-+ if (rulenum >= c->num_rules) {
- errno = E2BIG;
- return 0;
- }
-
-- e = index2entry(*handle, index);
-- if (e == NULL) {
-- errno = EINVAL;
-- return 0;
-+ /* Take advantage of the double linked list if possible. */
-+ if (rulenum + 1 <= c->num_rules/2) {
-+ r = iptcc_get_rule_num(c, rulenum + 1);
-+ } else {
-+ r = iptcc_get_rule_num_reverse(c, c->num_rules - rulenum);
-+ }
-+
-+ /* If we are about to delete the rule that is the current
-+ * iterator, move rule iterator back. next pointer will then
-+ * point to real next node */
-+ if (r == (*handle)->rule_iterator_cur) {
-+ (*handle)->rule_iterator_cur =
-+ list_entry((*handle)->rule_iterator_cur->list.prev,
-+ struct rule_head, list);
- }
-
-- ret = delete_rules(1, e->next_offset, entry2offset(*handle, e),
-- index, handle);
-- return ret;
-+ c->num_rules--;
-+ iptcc_delete_rule(r);
-+
-+ set_changed(*handle);
-+
-+ return 1;
- }
-
- /* Check the packet `fw' on chain `chain'. Returns the verdict, or
-@@ -1160,6 +1606,7 @@
- STRUCT_ENTRY *entry,
- TC_HANDLE_T *handle)
- {
-+ iptc_fn = TC_CHECK_PACKET;
- errno = ENOSYS;
- return NULL;
- }
-@@ -1168,44 +1615,44 @@
- int
- TC_FLUSH_ENTRIES(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
- {
-- unsigned int startindex, endindex;
-- struct chain_cache *c;
-- int ret;
-+ struct chain_head *c;
-+ struct rule_head *r, *tmp;
-
- iptc_fn = TC_FLUSH_ENTRIES;
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-- startindex = entry2index(*handle, c->start);
-- endindex = entry2index(*handle, c->end);
-
-- ret = delete_rules(endindex - startindex,
-- (char *)c->end - (char *)c->start,
-- entry2offset(*handle, c->start), startindex,
-- handle);
-- return ret;
-+ list_for_each_entry_safe(r, tmp, &c->rules, list) {
-+ iptcc_delete_rule(r);
-+ }
-+
-+ c->num_rules = 0;
-+
-+ set_changed(*handle);
-+
-+ return 1;
- }
-
- /* Zeroes the counters in a chain. */
- int
- TC_ZERO_ENTRIES(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
- {
-- unsigned int i, end;
-- struct chain_cache *c;
-+ struct chain_head *c;
-+ struct rule_head *r;
-
-- if (!(c = find_label(chain, *handle))) {
-+ iptc_fn = TC_ZERO_ENTRIES;
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- i = entry2index(*handle, c->start);
-- end = entry2index(*handle, c->end);
--
-- for (; i <= end; i++) {
-- if ((*handle)->counter_map[i].maptype ==COUNTER_MAP_NORMAL_MAP)
-- (*handle)->counter_map[i].maptype = COUNTER_MAP_ZEROED;
-+ list_for_each_entry(r, &c->rules, list) {
-+ if (r->counter_map.maptype == COUNTER_MAP_NORMAL_MAP)
-+ r->counter_map.maptype = COUNTER_MAP_ZEROED;
- }
-+
- set_changed(*handle);
-
- return 1;
-@@ -1216,29 +1663,23 @@
- unsigned int rulenum,
- TC_HANDLE_T *handle)
- {
-- STRUCT_ENTRY *e;
-- struct chain_cache *c;
-- unsigned int chainindex, end;
-+ struct chain_head *c;
-+ struct rule_head *r;
-
- iptc_fn = TC_READ_COUNTER;
- CHECK(*handle);
-
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return NULL;
- }
-
-- chainindex = entry2index(*handle, c->start);
-- end = entry2index(*handle, c->end);
--
-- if (chainindex + rulenum > end) {
-+ if (!(r = iptcc_get_rule_num(c, rulenum))) {
- errno = E2BIG;
- return NULL;
- }
-
-- e = index2entry(*handle, chainindex + rulenum);
--
-- return &e->counters;
-+ return &r->entry[0].counters;
- }
-
- int
-@@ -1246,33 +1687,24 @@
- unsigned int rulenum,
- TC_HANDLE_T *handle)
- {
-- STRUCT_ENTRY *e;
-- struct chain_cache *c;
-- unsigned int chainindex, end;
-+ struct chain_head *c;
-+ struct rule_head *r;
-
- iptc_fn = TC_ZERO_COUNTER;
- CHECK(*handle);
-
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- chainindex = entry2index(*handle, c->start);
-- end = entry2index(*handle, c->end);
--
-- if (chainindex + rulenum > end) {
-+ if (!(r = iptcc_get_rule_num(c, rulenum))) {
- errno = E2BIG;
- return 0;
- }
-
-- e = index2entry(*handle, chainindex + rulenum);
--
--// if ((*handle)->counter_map[chainindex + rulenum].maptype
--// == COUNTER_MAP_NORMAL_MAP) {
-- (*handle)->counter_map[chainindex + rulenum].maptype
-- = COUNTER_MAP_ZEROED;
--// }
-+ if (r->counter_map.maptype == COUNTER_MAP_NORMAL_MAP)
-+ r->counter_map.maptype = COUNTER_MAP_ZEROED;
-
- set_changed(*handle);
-
-@@ -1285,30 +1717,25 @@
- STRUCT_COUNTERS *counters,
- TC_HANDLE_T *handle)
- {
-+ struct chain_head *c;
-+ struct rule_head *r;
- STRUCT_ENTRY *e;
-- struct chain_cache *c;
-- unsigned int chainindex, end;
-
- iptc_fn = TC_SET_COUNTER;
- CHECK(*handle);
-
-- if (!(c = find_label(chain, *handle))) {
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- chainindex = entry2index(*handle, c->start);
-- end = entry2index(*handle, c->end);
--
-- if (chainindex + rulenum > end) {
-+ if (!(r = iptcc_get_rule_num(c, rulenum))) {
- errno = E2BIG;
- return 0;
- }
-
-- e = index2entry(*handle, chainindex + rulenum);
--
-- (*handle)->counter_map[chainindex + rulenum].maptype
-- = COUNTER_MAP_SET;
-+ e = r->entry;
-+ r->counter_map.maptype = COUNTER_MAP_SET;
-
- memcpy(&e->counters, counters, sizeof(STRUCT_COUNTERS));
-
-@@ -1323,71 +1750,42 @@
- int
- TC_CREATE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
- {
-- int ret;
-- struct {
-- STRUCT_ENTRY head;
-- struct ipt_error_target name;
-- STRUCT_ENTRY ret;
-- STRUCT_STANDARD_TARGET target;
-- } newc;
-+ static struct chain_head *c;
-
- iptc_fn = TC_CREATE_CHAIN;
-
- /* find_label doesn't cover built-in targets: DROP, ACCEPT,
- QUEUE, RETURN. */
-- if (find_label(chain, *handle)
-+ if (iptcc_find_label(chain, *handle)
- || strcmp(chain, LABEL_DROP) == 0
- || strcmp(chain, LABEL_ACCEPT) == 0
- || strcmp(chain, LABEL_QUEUE) == 0
- || strcmp(chain, LABEL_RETURN) == 0) {
-+ DEBUGP("Chain `%s' already exists\n", chain);
- errno = EEXIST;
- return 0;
- }
-
- if (strlen(chain)+1 > sizeof(IPT_CHAINLABEL)) {
-+ DEBUGP("Chain name `%s' too long\n", chain);
- errno = EINVAL;
- return 0;
- }
-
-- memset(&newc, 0, sizeof(newc));
-- newc.head.target_offset = sizeof(STRUCT_ENTRY);
-- newc.head.next_offset
-- = sizeof(STRUCT_ENTRY)
-- + ALIGN(sizeof(struct ipt_error_target));
-- strcpy(newc.name.t.u.user.name, ERROR_TARGET);
-- newc.name.t.u.target_size = ALIGN(sizeof(struct ipt_error_target));
-- strcpy(newc.name.error, chain);
--
-- newc.ret.target_offset = sizeof(STRUCT_ENTRY);
-- newc.ret.next_offset
-- = sizeof(STRUCT_ENTRY)
-- + ALIGN(sizeof(STRUCT_STANDARD_TARGET));
-- strcpy(newc.target.target.u.user.name, STANDARD_TARGET);
-- newc.target.target.u.target_size
-- = ALIGN(sizeof(STRUCT_STANDARD_TARGET));
-- newc.target.verdict = RETURN;
--
-- /* Add just before terminal entry */
-- ret = insert_rules(2, sizeof(newc), &newc.head,
-- index2offset(*handle, (*handle)->new_number - 1),
-- (*handle)->new_number - 1,
-- 0, handle);
-- return ret;
--}
-+ c = iptcc_alloc_chain_head(chain, 0);
-+ if (!c) {
-+ DEBUGP("Cannot allocate memory for chain `%s'\n", chain);
-+ errno = ENOMEM;
-+ return 0;
-
--static int
--count_ref(STRUCT_ENTRY *e, unsigned int offset, unsigned int *ref)
--{
-- STRUCT_STANDARD_TARGET *t;
-+ }
-
-- if (strcmp(GET_TARGET(e)->u.user.name, STANDARD_TARGET) == 0) {
-- t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
-+ DEBUGP("Creating chain `%s'\n", chain);
-+ list_add_tail(&c->list, &(*handle)->chains);
-
-- if (t->verdict == offset)
-- (*ref)++;
-- }
-+ set_changed(*handle);
-
-- return 0;
-+ return 1;
- }
-
- /* Get the number of references to this chain. */
-@@ -1395,17 +1793,16 @@
- TC_GET_REFERENCES(unsigned int *ref, const IPT_CHAINLABEL chain,
- TC_HANDLE_T *handle)
- {
-- struct chain_cache *c;
-+ struct chain_head *c;
-
-- if (!(c = find_label(chain, *handle))) {
-+ iptc_fn = TC_GET_REFERENCES;
-+ if (!(c = iptcc_find_label(chain, *handle))) {
- errno = ENOENT;
- return 0;
- }
-
-- *ref = 0;
-- ENTRY_ITERATE((*handle)->entries.entrytable,
-- (*handle)->entries.size,
-- count_ref, entry2offset(*handle, c->start), ref);
-+ *ref = c->references;
-+
- return 1;
- }
-
-@@ -1413,45 +1810,53 @@
- int
- TC_DELETE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
- {
-- unsigned int labelidx, labeloff;
- unsigned int references;
-- struct chain_cache *c;
-- int ret;
--
-- if (!TC_GET_REFERENCES(&references, chain, handle))
-- return 0;
-+ struct chain_head *c;
-
- iptc_fn = TC_DELETE_CHAIN;
-
-+ if (!(c = iptcc_find_label(chain, *handle))) {
-+ DEBUGP("cannot find chain `%s'\n", chain);
-+ errno = ENOENT;
-+ return 0;
-+ }
-+
- if (TC_BUILTIN(chain, *handle)) {
-+ DEBUGP("cannot remove builtin chain `%s'\n", chain);
- errno = EINVAL;
- return 0;
- }
-
-- if (references > 0) {
-- errno = EMLINK;
-+ if (!TC_GET_REFERENCES(&references, chain, handle)) {
-+ DEBUGP("cannot get references on chain `%s'\n", chain);
- return 0;
- }
-
-- if (!(c = find_label(chain, *handle))) {
-- errno = ENOENT;
-+ if (references > 0) {
-+ DEBUGP("chain `%s' still has references\n", chain);
-+ errno = EMLINK;
- return 0;
- }
-
-- if ((void *)c->start != c->end) {
-+ if (c->num_rules) {
-+ DEBUGP("chain `%s' is not empty\n", chain);
- errno = ENOTEMPTY;
- return 0;
- }
-
-- /* Need label index: preceeds chain start */
-- labelidx = entry2index(*handle, c->start) - 1;
-- labeloff = index2offset(*handle, labelidx);
--
-- ret = delete_rules(2,
-- get_entry(*handle, labeloff)->next_offset
-- + c->start->next_offset,
-- labeloff, labelidx, handle);
-- return ret;
-+ /* If we are about to delete the chain that is the current
-+ * iterator, move chain iterator firward. */
-+ if (c == (*handle)->chain_iterator_cur)
-+ iptcc_chain_iterator_advance(*handle);
-+
-+ list_del(&c->list);
-+ free(c);
-+
-+ DEBUGP("chain `%s' deleted\n", chain);
-+
-+ set_changed(*handle);
-+
-+ return 1;
- }
-
- /* Renames a chain. */
-@@ -1459,15 +1864,12 @@
- const IPT_CHAINLABEL newname,
- TC_HANDLE_T *handle)
- {
-- unsigned int labeloff, labelidx;
-- struct chain_cache *c;
-- struct ipt_error_target *t;
--
-+ struct chain_head *c;
- iptc_fn = TC_RENAME_CHAIN;
-
- /* find_label doesn't cover built-in targets: DROP, ACCEPT,
- QUEUE, RETURN. */
-- if (find_label(newname, *handle)
-+ if (iptcc_find_label(newname, *handle)
- || strcmp(newname, LABEL_DROP) == 0
- || strcmp(newname, LABEL_ACCEPT) == 0
- || strcmp(newname, LABEL_QUEUE) == 0
-@@ -1476,7 +1878,7 @@
- return 0;
- }
-
-- if (!(c = find_label(oldname, *handle))
-+ if (!(c = iptcc_find_label(oldname, *handle))
- || TC_BUILTIN(oldname, *handle)) {
- errno = ENOENT;
- return 0;
-@@ -1487,15 +1889,8 @@
- return 0;
- }
-
-- /* Need label index: preceeds chain start */
-- labelidx = entry2index(*handle, c->start) - 1;
-- labeloff = index2offset(*handle, labelidx);
-+ strncpy(c->name, newname, sizeof(IPT_CHAINLABEL));
-
-- t = (struct ipt_error_target *)
-- GET_TARGET(get_entry(*handle, labeloff));
--
-- memset(t->error, 0, sizeof(t->error));
-- strcpy(t->error, newname);
- set_changed(*handle);
-
- return 1;
-@@ -1508,51 +1903,37 @@
- STRUCT_COUNTERS *counters,
- TC_HANDLE_T *handle)
- {
-- unsigned int hook;
-- unsigned int policyoff, ctrindex;
-- STRUCT_ENTRY *e;
-- STRUCT_STANDARD_TARGET *t;
-+ struct chain_head *c;
-
- iptc_fn = TC_SET_POLICY;
-- /* Figure out which chain. */
-- hook = TC_BUILTIN(chain, *handle);
-- if (hook == 0) {
-+
-+ if (!(c = iptcc_find_label(chain, *handle))) {
-+ DEBUGP("cannot find chain `%s'\n", chain);
- errno = ENOENT;
- return 0;
-- } else
-- hook--;
-+ }
-
-- policyoff = get_chain_end(*handle, (*handle)->info.hook_entry[hook]);
-- if (policyoff != (*handle)->info.underflow[hook]) {
-- printf("ERROR: Policy for `%s' offset %u != underflow %u\n",
-- chain, policyoff, (*handle)->info.underflow[hook]);
-+ if (!iptcc_is_builtin(c)) {
-+ DEBUGP("cannot set policy of userdefinedchain `%s'\n", chain);
-+ errno = ENOENT;
- return 0;
- }
-
-- e = get_entry(*handle, policyoff);
-- t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
--
- if (strcmp(policy, LABEL_ACCEPT) == 0)
-- t->verdict = -NF_ACCEPT - 1;
-+ c->verdict = -NF_ACCEPT - 1;
- else if (strcmp(policy, LABEL_DROP) == 0)
-- t->verdict = -NF_DROP - 1;
-+ c->verdict = -NF_DROP - 1;
- else {
- errno = EINVAL;
- return 0;
- }
-
-- ctrindex = entry2index(*handle, e);
--
- if (counters) {
- /* set byte and packet counters */
-- memcpy(&e->counters, counters, sizeof(STRUCT_COUNTERS));
--
-- (*handle)->counter_map[ctrindex].maptype
-- = COUNTER_MAP_SET;
--
-+ memcpy(&c->counters, counters, sizeof(STRUCT_COUNTERS));
-+ c->counter_map.maptype = COUNTER_MAP_SET;
- } else {
-- (*handle)->counter_map[ctrindex]
-- = ((struct counter_map){ COUNTER_MAP_NOMAP, 0 });
-+ c->counter_map.maptype = COUNTER_MAP_NOMAP;
- }
-
- set_changed(*handle);
-@@ -1575,31 +1956,100 @@
- answer->bcnt = a->bcnt - b->bcnt;
- }
-
-+
-+static void counters_nomap(STRUCT_COUNTERS_INFO *newcounters,
-+ unsigned int index)
-+{
-+ newcounters->counters[index] = ((STRUCT_COUNTERS) { 0, 0});
-+ DEBUGP_C("NOMAP => zero\n");
-+}
-+
-+static void counters_normal_map(STRUCT_COUNTERS_INFO *newcounters,
-+ STRUCT_REPLACE *repl,
-+ unsigned int index,
-+ unsigned int mappos)
-+{
-+ /* Original read: X.
-+ * Atomic read on replacement: X + Y.
-+ * Currently in kernel: Z.
-+ * Want in kernel: X + Y + Z.
-+ * => Add in X + Y
-+ * => Add in replacement read.
-+ */
-+ newcounters->counters[index] = repl->counters[mappos];
-+ DEBUGP_C("NORMAL_MAP => mappos %u \n", mappos);
-+}
-+
-+static void counters_map_zeroed(STRUCT_COUNTERS_INFO *newcounters,
-+ STRUCT_REPLACE *repl,
-+ unsigned int index,
-+ unsigned int mappos,
-+ STRUCT_COUNTERS *counters)
-+{
-+ /* Original read: X.
-+ * Atomic read on replacement: X + Y.
-+ * Currently in kernel: Z.
-+ * Want in kernel: Y + Z.
-+ * => Add in Y.
-+ * => Add in (replacement read - original read).
-+ */
-+ subtract_counters(&newcounters->counters[index],
-+ &repl->counters[mappos],
-+ counters);
-+ DEBUGP_C("ZEROED => mappos %u\n", mappos);
-+}
-+
-+static void counters_map_set(STRUCT_COUNTERS_INFO *newcounters,
-+ unsigned int index,
-+ STRUCT_COUNTERS *counters)
-+{
-+ /* Want to set counter (iptables-restore) */
-+
-+ memcpy(&newcounters->counters[index], counters,
-+ sizeof(STRUCT_COUNTERS));
-+
-+ DEBUGP_C("SET\n");
-+}
-+
-+
- int
- TC_COMMIT(TC_HANDLE_T *handle)
- {
- /* Replace, then map back the counters. */
- STRUCT_REPLACE *repl;
- STRUCT_COUNTERS_INFO *newcounters;
-- unsigned int i;
-- size_t counterlen
-- = sizeof(STRUCT_COUNTERS_INFO)
-- + sizeof(STRUCT_COUNTERS) * (*handle)->new_number;
-+ struct chain_head *c;
-+ int ret;
-+ size_t counterlen;
-+ int new_number;
-+ unsigned int new_size;
-
-+ iptc_fn = TC_COMMIT;
- CHECK(*handle);
--#if 0
-- TC_DUMP_ENTRIES(*handle);
--#endif
-
- /* Don't commit if nothing changed. */
- if (!(*handle)->changed)
- goto finished;
-
-- repl = malloc(sizeof(*repl) + (*handle)->entries.size);
-+ new_number = iptcc_compile_table_prep(*handle, &new_size);
-+ if (new_number < 0) {
-+ errno = ENOMEM;
-+ return 0;
-+ }
-+
-+ repl = malloc(sizeof(*repl) + new_size);
- if (!repl) {
- errno = ENOMEM;
- return 0;
- }
-+ memset(repl, 0, sizeof(*repl) + new_size);
-+
-+#if 0
-+ TC_DUMP_ENTRIES(*handle);
-+#endif
-+
-+ counterlen = sizeof(STRUCT_COUNTERS_INFO)
-+ + sizeof(STRUCT_COUNTERS) * new_number;
-
- /* These are the old counters we will get from kernel */
- repl->counters = malloc(sizeof(STRUCT_COUNTERS)
-@@ -1609,7 +2059,6 @@
- errno = ENOMEM;
- return 0;
- }
--
- /* These are the counters we're going to put back, later. */
- newcounters = malloc(counterlen);
- if (!newcounters) {
-@@ -1618,21 +2067,40 @@
- errno = ENOMEM;
- return 0;
- }
-+ memset(newcounters, 0, counterlen);
-
- strcpy(repl->name, (*handle)->info.name);
-- repl->num_entries = (*handle)->new_number;
-- repl->size = (*handle)->entries.size;
-- memcpy(repl->hook_entry, (*handle)->info.hook_entry,
-- sizeof(repl->hook_entry));
-- memcpy(repl->underflow, (*handle)->info.underflow,
-- sizeof(repl->underflow));
-+ repl->num_entries = new_number;
-+ repl->size = new_size;
-+
- repl->num_counters = (*handle)->info.num_entries;
- repl->valid_hooks = (*handle)->info.valid_hooks;
-- memcpy(repl->entries, (*handle)->entries.entrytable,
-- (*handle)->entries.size);
-+
-+ DEBUGP("num_entries=%u, size=%u, num_counters=%u\n",
-+ repl->num_entries, repl->size, repl->num_counters);
-+
-+ ret = iptcc_compile_table(*handle, repl);
-+ if (ret < 0) {
-+ errno = ret;
-+ free(repl->counters);
-+ free(repl);
-+ return 0;
-+ }
-+
-+
-+#ifdef IPTC_DEBUG2
-+ {
-+ int fd = open("/tmp/libiptc-so_set_replace.blob",
-+ O_CREAT|O_WRONLY);
-+ if (fd >= 0) {
-+ write(fd, repl, sizeof(*repl) + repl->size);
-+ close(fd);
-+ }
-+ }
-+#endif
-
- if (setsockopt(sockfd, TC_IPPROTO, SO_SET_REPLACE, repl,
-- sizeof(*repl) + (*handle)->entries.size) < 0) {
-+ sizeof(*repl) + repl->size) < 0) {
- free(repl->counters);
- free(repl);
- free(newcounters);
-@@ -1641,49 +2109,64 @@
-
- /* Put counters back. */
- strcpy(newcounters->name, (*handle)->info.name);
-- newcounters->num_counters = (*handle)->new_number;
-- for (i = 0; i < (*handle)->new_number; i++) {
-- unsigned int mappos = (*handle)->counter_map[i].mappos;
-- switch ((*handle)->counter_map[i].maptype) {
-+ newcounters->num_counters = new_number;
-+
-+ list_for_each_entry(c, &(*handle)->chains, list) {
-+ struct rule_head *r;
-+
-+ /* Builtin chains have their own counters */
-+ if (iptcc_is_builtin(c)) {
-+ DEBUGP("counter for chain-index %u: ", c->foot_index);
-+ switch(c->counter_map.maptype) {
-+ case COUNTER_MAP_NOMAP:
-+ counters_nomap(newcounters, c->foot_index);
-+ break;
-+ case COUNTER_MAP_NORMAL_MAP:
-+ counters_normal_map(newcounters, repl,
-+ c->foot_index,
-+ c->counter_map.mappos);
-+ break;
-+ case COUNTER_MAP_ZEROED:
-+ counters_map_zeroed(newcounters, repl,
-+ c->foot_index,
-+ c->counter_map.mappos,
-+ &c->counters);
-+ break;
-+ case COUNTER_MAP_SET:
-+ counters_map_set(newcounters, c->foot_index,
-+ &c->counters);
-+ break;
-+ }
-+ }
-+
-+ list_for_each_entry(r, &c->rules, list) {
-+ DEBUGP("counter for index %u: ", r->index);
-+ switch (r->counter_map.maptype) {
- case COUNTER_MAP_NOMAP:
-- newcounters->counters[i]
-- = ((STRUCT_COUNTERS){ 0, 0 });
-+ counters_nomap(newcounters, r->index);
- break;
-
- case COUNTER_MAP_NORMAL_MAP:
-- /* Original read: X.
-- * Atomic read on replacement: X + Y.
-- * Currently in kernel: Z.
-- * Want in kernel: X + Y + Z.
-- * => Add in X + Y
-- * => Add in replacement read.
-- */
-- newcounters->counters[i] = repl->counters[mappos];
-+ counters_normal_map(newcounters, repl,
-+ r->index,
-+ r->counter_map.mappos);
- break;
-
- case COUNTER_MAP_ZEROED:
-- /* Original read: X.
-- * Atomic read on replacement: X + Y.
-- * Currently in kernel: Z.
-- * Want in kernel: Y + Z.
-- * => Add in Y.
-- * => Add in (replacement read - original read).
-- */
-- subtract_counters(&newcounters->counters[i],
-- &repl->counters[mappos],
-- &index2entry(*handle, i)->counters);
-+ counters_map_zeroed(newcounters, repl,
-+ r->index,
-+ r->counter_map.mappos,
-+ &r->entry->counters);
- break;
-
- case COUNTER_MAP_SET:
-- /* Want to set counter (iptables-restore) */
--
-- memcpy(&newcounters->counters[i],
-- &index2entry(*handle, i)->counters,
-- sizeof(STRUCT_COUNTERS));
--
-+ counters_map_set(newcounters, r->index,
-+ &r->entry->counters);
- break;
- }
- }
-+ }
-+
-
- #ifdef KERNEL_64_USERSPACE_32
- {
-@@ -1696,10 +2179,21 @@
- "counters alignment incorrect! Mail rusty!\n");
- abort();
- }
-- *kernptr = &newcounters->counters;
-+ *kernptr = newcounters->counters;
- }
- #endif /* KERNEL_64_USERSPACE_32 */
-
-+#ifdef IPTC_DEBUG2
-+ {
-+ int fd = open("/tmp/libiptc-so_set_add_counters.blob",
-+ O_CREAT|O_WRONLY);
-+ if (fd >= 0) {
-+ write(fd, newcounters, counterlen);
-+ close(fd);
-+ }
-+ }
-+#endif
-+
- if (setsockopt(sockfd, TC_IPPROTO, SO_SET_ADD_COUNTERS,
- newcounters, counterlen) < 0) {
- free(repl->counters);
-@@ -1713,10 +2207,7 @@
- free(newcounters);
-
- finished:
-- if ((*handle)->cache_chain_heads)
-- free((*handle)->cache_chain_heads);
-- free(*handle);
-- *handle = NULL;
-+ TC_FREE(handle);
- return 1;
- }
-
-diff -Nur ipac-ng-1.31.orig/agents/iptables/libiptc.h ipac-ng-1.31/agents/iptables/libiptc.h
---- ipac-ng-1.31.orig/agents/iptables/libiptc.h 2003-07-06 10:33:17.000000000 +0000
-+++ ipac-ng-1.31/agents/iptables/libiptc.h 2006-01-10 21:01:39.000000000 +0000
-@@ -1,7 +1,3 @@
--#ifndef NETFILTER_VERSION
--#define NETFILTER_VERSION "1.2.5"
--#endif
--
- #ifndef _LIBIPTC_H
- #define _LIBIPTC_H
- /* Library which manipulates filtering rules. */
-@@ -38,6 +34,9 @@
- /* Take a snapshot of the rules. Returns NULL on error. */
- iptc_handle_t iptc_init(const char *tablename);
-
-+/* Cleanup after iptc_init(). */
-+void iptc_free(iptc_handle_t *h);
-+
- /* Iterator functions to run through the chains. Returns NULL at end. */
- const char *iptc_first_chain(iptc_handle_t *handle);
- const char *iptc_next_chain(iptc_handle_t *handle);
-diff -Nur ipac-ng-1.31.orig/agents/iptables/linux_list.h ipac-ng-1.31/agents/iptables/linux_list.h
---- ipac-ng-1.31.orig/agents/iptables/linux_list.h 1970-01-01 00:00:00.000000000 +0000
-+++ ipac-ng-1.31/agents/iptables/linux_list.h 2006-01-10 21:01:39.000000000 +0000
-@@ -0,0 +1,723 @@
-+#ifndef _LINUX_LIST_H
-+#define _LINUX_LIST_H
-+
-+#undef offsetof
-+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-+
-+/**
-+ * container_of - cast a member of a structure out to the containing structure
-+ *
-+ * @ptr: the pointer to the member.
-+ * @type: the type of the container struct this is embedded in.
-+ * @member: the name of the member within the struct.
-+ *
-+ */
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+
-+/*
-+ * Check at compile time that something is of a particular type.
-+ * Always evaluates to 1 so you may use it easily in comparisons.
-+ */
-+#define typecheck(type,x) \
-+({ type __dummy; \
-+ typeof(x) __dummy2; \
-+ (void)(&__dummy == &__dummy2); \
-+ 1; \
-+})
-+
-+#define prefetch(x) 1
-+
-+/* empty define to make this work in userspace -HW */
-+#define smp_wmb()
-+
-+/*
-+ * These are non-NULL pointers that will result in page faults
-+ * under normal circumstances, used to verify that nobody uses
-+ * non-initialized list entries.
-+ */
-+#define LIST_POISON1 ((void *) 0x00100100)
-+#define LIST_POISON2 ((void *) 0x00200200)
-+
-+/*
-+ * Simple doubly linked list implementation.
-+ *
-+ * Some of the internal functions ("__xxx") are useful when
-+ * manipulating whole lists rather than single entries, as
-+ * sometimes we already know the next/prev entries and we can
-+ * generate better code by using them directly rather than
-+ * using the generic single-entry routines.
-+ */
-+
-+struct list_head {
-+ struct list_head *next, *prev;
-+};
-+
-+#define LIST_HEAD_INIT(name) { &(name), &(name) }
-+
-+#define LIST_HEAD(name) \
-+ struct list_head name = LIST_HEAD_INIT(name)
-+
-+#define INIT_LIST_HEAD(ptr) do { \
-+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-+} while (0)
-+
-+/*
-+ * Insert a new entry between two known consecutive entries.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static inline void __list_add(struct list_head *new,
-+ struct list_head *prev,
-+ struct list_head *next)
-+{
-+ next->prev = new;
-+ new->next = next;
-+ new->prev = prev;
-+ prev->next = new;
-+}
-+
-+/**
-+ * list_add - add a new entry
-+ * @new: new entry to be added
-+ * @head: list head to add it after
-+ *
-+ * Insert a new entry after the specified head.
-+ * This is good for implementing stacks.
-+ */
-+static inline void list_add(struct list_head *new, struct list_head *head)
-+{
-+ __list_add(new, head, head->next);
-+}
-+
-+/**
-+ * list_add_tail - add a new entry
-+ * @new: new entry to be added
-+ * @head: list head to add it before
-+ *
-+ * Insert a new entry before the specified head.
-+ * This is useful for implementing queues.
-+ */
-+static inline void list_add_tail(struct list_head *new, struct list_head *head)
-+{
-+ __list_add(new, head->prev, head);
-+}
-+
-+/*
-+ * Insert a new entry between two known consecutive entries.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static inline void __list_add_rcu(struct list_head * new,
-+ struct list_head * prev, struct list_head * next)
-+{
-+ new->next = next;
-+ new->prev = prev;
-+ smp_wmb();
-+ next->prev = new;
-+ prev->next = new;
-+}
-+
-+/**
-+ * list_add_rcu - add a new entry to rcu-protected list
-+ * @new: new entry to be added
-+ * @head: list head to add it after
-+ *
-+ * Insert a new entry after the specified head.
-+ * This is good for implementing stacks.
-+ *
-+ * The caller must take whatever precautions are necessary
-+ * (such as holding appropriate locks) to avoid racing
-+ * with another list-mutation primitive, such as list_add_rcu()
-+ * or list_del_rcu(), running on this same list.
-+ * However, it is perfectly legal to run concurrently with
-+ * the _rcu list-traversal primitives, such as
-+ * list_for_each_entry_rcu().
-+ */
-+static inline void list_add_rcu(struct list_head *new, struct list_head *head)
-+{
-+ __list_add_rcu(new, head, head->next);
-+}
-+
-+/**
-+ * list_add_tail_rcu - add a new entry to rcu-protected list
-+ * @new: new entry to be added
-+ * @head: list head to add it before
-+ *
-+ * Insert a new entry before the specified head.
-+ * This is useful for implementing queues.
-+ *
-+ * The caller must take whatever precautions are necessary
-+ * (such as holding appropriate locks) to avoid racing
-+ * with another list-mutation primitive, such as list_add_tail_rcu()
-+ * or list_del_rcu(), running on this same list.
-+ * However, it is perfectly legal to run concurrently with
-+ * the _rcu list-traversal primitives, such as
-+ * list_for_each_entry_rcu().
-+ */
-+static inline void list_add_tail_rcu(struct list_head *new,
-+ struct list_head *head)
-+{
-+ __list_add_rcu(new, head->prev, head);
-+}
-+
-+/*
-+ * Delete a list entry by making the prev/next entries
-+ * point to each other.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static inline void __list_del(struct list_head * prev, struct list_head * next)
-+{
-+ next->prev = prev;
-+ prev->next = next;
-+}
-+
-+/**
-+ * list_del - deletes entry from list.
-+ * @entry: the element to delete from the list.
-+ * Note: list_empty on entry does not return true after this, the entry is
-+ * in an undefined state.
-+ */
-+static inline void list_del(struct list_head *entry)
-+{
-+ __list_del(entry->prev, entry->next);
-+ entry->next = LIST_POISON1;
-+ entry->prev = LIST_POISON2;
-+}
-+
-+/**
-+ * list_del_rcu - deletes entry from list without re-initialization
-+ * @entry: the element to delete from the list.
-+ *
-+ * Note: list_empty on entry does not return true after this,
-+ * the entry is in an undefined state. It is useful for RCU based
-+ * lockfree traversal.
-+ *
-+ * In particular, it means that we can not poison the forward
-+ * pointers that may still be used for walking the list.
-+ *
-+ * The caller must take whatever precautions are necessary
-+ * (such as holding appropriate locks) to avoid racing
-+ * with another list-mutation primitive, such as list_del_rcu()
-+ * or list_add_rcu(), running on this same list.
-+ * However, it is perfectly legal to run concurrently with
-+ * the _rcu list-traversal primitives, such as
-+ * list_for_each_entry_rcu().
-+ *
-+ * Note that the caller is not permitted to immediately free
-+ * the newly deleted entry. Instead, either synchronize_kernel()
-+ * or call_rcu() must be used to defer freeing until an RCU
-+ * grace period has elapsed.
-+ */
-+static inline void list_del_rcu(struct list_head *entry)
-+{
-+ __list_del(entry->prev, entry->next);
-+ entry->prev = LIST_POISON2;
-+}
-+
-+/**
-+ * list_del_init - deletes entry from list and reinitialize it.
-+ * @entry: the element to delete from the list.
-+ */
-+static inline void list_del_init(struct list_head *entry)
-+{
-+ __list_del(entry->prev, entry->next);
-+ INIT_LIST_HEAD(entry);
-+}
-+
-+/**
-+ * list_move - delete from one list and add as another's head
-+ * @list: the entry to move
-+ * @head: the head that will precede our entry
-+ */
-+static inline void list_move(struct list_head *list, struct list_head *head)
-+{
-+ __list_del(list->prev, list->next);
-+ list_add(list, head);
-+}
-+
-+/**
-+ * list_move_tail - delete from one list and add as another's tail
-+ * @list: the entry to move
-+ * @head: the head that will follow our entry
-+ */
-+static inline void list_move_tail(struct list_head *list,
-+ struct list_head *head)
-+{
-+ __list_del(list->prev, list->next);
-+ list_add_tail(list, head);
-+}
-+
-+/**
-+ * list_empty - tests whether a list is empty
-+ * @head: the list to test.
-+ */
-+static inline int list_empty(const struct list_head *head)
-+{
-+ return head->next == head;
-+}
-+
-+/**
-+ * list_empty_careful - tests whether a list is
-+ * empty _and_ checks that no other CPU might be
-+ * in the process of still modifying either member
-+ *
-+ * NOTE: using list_empty_careful() without synchronization
-+ * can only be safe if the only activity that can happen
-+ * to the list entry is list_del_init(). Eg. it cannot be used
-+ * if another CPU could re-list_add() it.
-+ *
-+ * @head: the list to test.
-+ */
-+static inline int list_empty_careful(const struct list_head *head)
-+{
-+ struct list_head *next = head->next;
-+ return (next == head) && (next == head->prev);
-+}
-+
-+static inline void __list_splice(struct list_head *list,
-+ struct list_head *head)
-+{
-+ struct list_head *first = list->next;
-+ struct list_head *last = list->prev;
-+ struct list_head *at = head->next;
-+
-+ first->prev = head;
-+ head->next = first;
-+
-+ last->next = at;
-+ at->prev = last;
-+}
-+
-+/**
-+ * list_splice - join two lists
-+ * @list: the new list to add.
-+ * @head: the place to add it in the first list.
-+ */
-+static inline void list_splice(struct list_head *list, struct list_head *head)
-+{
-+ if (!list_empty(list))
-+ __list_splice(list, head);
-+}
-+
-+/**
-+ * list_splice_init - join two lists and reinitialise the emptied list.
-+ * @list: the new list to add.
-+ * @head: the place to add it in the first list.
-+ *
-+ * The list at @list is reinitialised
-+ */
-+static inline void list_splice_init(struct list_head *list,
-+ struct list_head *head)
-+{
-+ if (!list_empty(list)) {
-+ __list_splice(list, head);
-+ INIT_LIST_HEAD(list);
-+ }
-+}
-+
-+/**
-+ * list_entry - get the struct for this entry
-+ * @ptr: the &struct list_head pointer.
-+ * @type: the type of the struct this is embedded in.
-+ * @member: the name of the list_struct within the struct.
-+ */
-+#define list_entry(ptr, type, member) \
-+ container_of(ptr, type, member)
-+
-+/**
-+ * list_for_each - iterate over a list
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @head: the head for your list.
-+ */
-+#define list_for_each(pos, head) \
-+ for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-+ pos = pos->next, prefetch(pos->next))
-+
-+/**
-+ * __list_for_each - iterate over a list
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @head: the head for your list.
-+ *
-+ * This variant differs from list_for_each() in that it's the
-+ * simplest possible list iteration code, no prefetching is done.
-+ * Use this for code that knows the list to be very short (empty
-+ * or 1 entry) most of the time.
-+ */
-+#define __list_for_each(pos, head) \
-+ for (pos = (head)->next; pos != (head); pos = pos->next)
-+
-+/**
-+ * list_for_each_prev - iterate over a list backwards
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @head: the head for your list.
-+ */
-+#define list_for_each_prev(pos, head) \
-+ for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
-+ pos = pos->prev, prefetch(pos->prev))
-+
-+/**
-+ * list_for_each_safe - iterate over a list safe against removal of list entry
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @n: another &struct list_head to use as temporary storage
-+ * @head: the head for your list.
-+ */
-+#define list_for_each_safe(pos, n, head) \
-+ for (pos = (head)->next, n = pos->next; pos != (head); \
-+ pos = n, n = pos->next)
-+
-+/**
-+ * list_for_each_entry - iterate over list of given type
-+ * @pos: the type * to use as a loop counter.
-+ * @head: the head for your list.
-+ * @member: the name of the list_struct within the struct.
-+ */
-+#define list_for_each_entry(pos, head, member) \
-+ for (pos = list_entry((head)->next, typeof(*pos), member), \
-+ prefetch(pos->member.next); \
-+ &pos->member != (head); \
-+ pos = list_entry(pos->member.next, typeof(*pos), member), \
-+ prefetch(pos->member.next))
-+
-+/**
-+ * list_for_each_entry_reverse - iterate backwards over list of given type.
-+ * @pos: the type * to use as a loop counter.
-+ * @head: the head for your list.
-+ * @member: the name of the list_struct within the struct.
-+ */
-+#define list_for_each_entry_reverse(pos, head, member) \
-+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
-+ prefetch(pos->member.prev); \
-+ &pos->member != (head); \
-+ pos = list_entry(pos->member.prev, typeof(*pos), member), \
-+ prefetch(pos->member.prev))
-+
-+/**
-+ * list_prepare_entry - prepare a pos entry for use as a start point in
-+ * list_for_each_entry_continue
-+ * @pos: the type * to use as a start point
-+ * @head: the head of the list
-+ * @member: the name of the list_struct within the struct.
-+ */
-+#define list_prepare_entry(pos, head, member) \
-+ ((pos) ? : list_entry(head, typeof(*pos), member))
-+
-+/**
-+ * list_for_each_entry_continue - iterate over list of given type
-+ * continuing after existing point
-+ * @pos: the type * to use as a loop counter.
-+ * @head: the head for your list.
-+ * @member: the name of the list_struct within the struct.
-+ */
-+#define list_for_each_entry_continue(pos, head, member) \
-+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
-+ prefetch(pos->member.next); \
-+ &pos->member != (head); \
-+ pos = list_entry(pos->member.next, typeof(*pos), member), \
-+ prefetch(pos->member.next))
-+
-+/**
-+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
-+ * @pos: the type * to use as a loop counter.
-+ * @n: another type * to use as temporary storage
-+ * @head: the head for your list.
-+ * @member: the name of the list_struct within the struct.
-+ */
-+#define list_for_each_entry_safe(pos, n, head, member) \
-+ for (pos = list_entry((head)->next, typeof(*pos), member), \
-+ n = list_entry(pos->member.next, typeof(*pos), member); \
-+ &pos->member != (head); \
-+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
-+
-+/**
-+ * list_for_each_rcu - iterate over an rcu-protected list
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @head: the head for your list.
-+ *
-+ * This list-traversal primitive may safely run concurrently with
-+ * the _rcu list-mutation primitives such as list_add_rcu()
-+ * as long as the traversal is guarded by rcu_read_lock().
-+ */
-+#define list_for_each_rcu(pos, head) \
-+ for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-+ pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
-+
-+#define __list_for_each_rcu(pos, head) \
-+ for (pos = (head)->next; pos != (head); \
-+ pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
-+
-+/**
-+ * list_for_each_safe_rcu - iterate over an rcu-protected list safe
-+ * against removal of list entry
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @n: another &struct list_head to use as temporary storage
-+ * @head: the head for your list.
-+ *
-+ * This list-traversal primitive may safely run concurrently with
-+ * the _rcu list-mutation primitives such as list_add_rcu()
-+ * as long as the traversal is guarded by rcu_read_lock().
-+ */
-+#define list_for_each_safe_rcu(pos, n, head) \
-+ for (pos = (head)->next, n = pos->next; pos != (head); \
-+ pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
-+
-+/**
-+ * list_for_each_entry_rcu - iterate over rcu list of given type
-+ * @pos: the type * to use as a loop counter.
-+ * @head: the head for your list.
-+ * @member: the name of the list_struct within the struct.
-+ *
-+ * This list-traversal primitive may safely run concurrently with
-+ * the _rcu list-mutation primitives such as list_add_rcu()
-+ * as long as the traversal is guarded by rcu_read_lock().
-+ */
-+#define list_for_each_entry_rcu(pos, head, member) \
-+ for (pos = list_entry((head)->next, typeof(*pos), member), \
-+ prefetch(pos->member.next); \
-+ &pos->member != (head); \
-+ pos = list_entry(pos->member.next, typeof(*pos), member), \
-+ ({ smp_read_barrier_depends(); 0;}), \
-+ prefetch(pos->member.next))
-+
-+
-+/**
-+ * list_for_each_continue_rcu - iterate over an rcu-protected list
-+ * continuing after existing point.
-+ * @pos: the &struct list_head to use as a loop counter.
-+ * @head: the head for your list.
-+ *
-+ * This list-traversal primitive may safely run concurrently with
-+ * the _rcu list-mutation primitives such as list_add_rcu()
-+ * as long as the traversal is guarded by rcu_read_lock().
-+ */
-+#define list_for_each_continue_rcu(pos, head) \
-+ for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
-+ (pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
-+
-+/*
-+ * Double linked lists with a single pointer list head.
-+ * Mostly useful for hash tables where the two pointer list head is
-+ * too wasteful.
-+ * You lose the ability to access the tail in O(1).
-+ */
-+
-+struct hlist_head {
-+ struct hlist_node *first;
-+};
-+
-+struct hlist_node {
-+ struct hlist_node *next, **pprev;
-+};
-+
-+#define HLIST_HEAD_INIT { .first = NULL }
-+#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
-+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-+#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
-+
-+static inline int hlist_unhashed(const struct hlist_node *h)
-+{
-+ return !h->pprev;
-+}
-+
-+static inline int hlist_empty(const struct hlist_head *h)
-+{
-+ return !h->first;
-+}
-+
-+static inline void __hlist_del(struct hlist_node *n)
-+{
-+ struct hlist_node *next = n->next;
-+ struct hlist_node **pprev = n->pprev;
-+ *pprev = next;
-+ if (next)
-+ next->pprev = pprev;
-+}
-+
-+static inline void hlist_del(struct hlist_node *n)
-+{
-+ __hlist_del(n);
-+ n->next = LIST_POISON1;
-+ n->pprev = LIST_POISON2;
-+}
-+
-+/**
-+ * hlist_del_rcu - deletes entry from hash list without re-initialization
-+ * @n: the element to delete from the hash list.
-+ *
-+ * Note: list_unhashed() on entry does not return true after this,
-+ * the entry is in an undefined state. It is useful for RCU based
-+ * lockfree traversal.
-+ *
-+ * In particular, it means that we can not poison the forward
-+ * pointers that may still be used for walking the hash list.
-+ *
-+ * The caller must take whatever precautions are necessary
-+ * (such as holding appropriate locks) to avoid racing
-+ * with another list-mutation primitive, such as hlist_add_head_rcu()
-+ * or hlist_del_rcu(), running on this same list.
-+ * However, it is perfectly legal to run concurrently with
-+ * the _rcu list-traversal primitives, such as
-+ * hlist_for_each_entry().
-+ */
-+static inline void hlist_del_rcu(struct hlist_node *n)
-+{
-+ __hlist_del(n);
-+ n->pprev = LIST_POISON2;
-+}
-+
-+static inline void hlist_del_init(struct hlist_node *n)
-+{
-+ if (n->pprev) {
-+ __hlist_del(n);
-+ INIT_HLIST_NODE(n);
-+ }
-+}
-+
-+#define hlist_del_rcu_init hlist_del_init
-+
-+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
-+{
-+ struct hlist_node *first = h->first;
-+ n->next = first;
-+ if (first)
-+ first->pprev = &n->next;
-+ h->first = n;
-+ n->pprev = &h->first;
-+}
-+
-+
-+/**
-+ * hlist_add_head_rcu - adds the specified element to the specified hlist,
-+ * while permitting racing traversals.
-+ * @n: the element to add to the hash list.
-+ * @h: the list to add to.
-+ *
-+ * The caller must take whatever precautions are necessary
-+ * (such as holding appropriate locks) to avoid racing
-+ * with another list-mutation primitive, such as hlist_add_head_rcu()
-+ * or hlist_del_rcu(), running on this same list.
-+ * However, it is perfectly legal to run concurrently with
-+ * the _rcu list-traversal primitives, such as
-+ * hlist_for_each_entry(), but only if smp_read_barrier_depends()
-+ * is used to prevent memory-consistency problems on Alpha CPUs.
-+ * Regardless of the type of CPU, the list-traversal primitive
-+ * must be guarded by rcu_read_lock().
-+ *
-+ * OK, so why don't we have an hlist_for_each_entry_rcu()???
-+ */
-+static inline void hlist_add_head_rcu(struct hlist_node *n,
-+ struct hlist_head *h)
-+{
-+ struct hlist_node *first = h->first;
-+ n->next = first;
-+ n->pprev = &h->first;
-+ smp_wmb();
-+ if (first)
-+ first->pprev = &n->next;
-+ h->first = n;
-+}
-+
-+/* next must be != NULL */
-+static inline void hlist_add_before(struct hlist_node *n,
-+ struct hlist_node *next)
-+{
-+ n->pprev = next->pprev;
-+ n->next = next;
-+ next->pprev = &n->next;
-+ *(n->pprev) = n;
-+}
-+
-+static inline void hlist_add_after(struct hlist_node *n,
-+ struct hlist_node *next)
-+{
-+ next->next = n->next;
-+ n->next = next;
-+ next->pprev = &n->next;
-+
-+ if(next->next)
-+ next->next->pprev = &next->next;
-+}
-+
-+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
-+
-+#define hlist_for_each(pos, head) \
-+ for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
-+ pos = pos->next)
-+
-+#define hlist_for_each_safe(pos, n, head) \
-+ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
-+ pos = n)
-+
-+/**
-+ * hlist_for_each_entry - iterate over list of given type
-+ * @tpos: the type * to use as a loop counter.
-+ * @pos: the &struct hlist_node to use as a loop counter.
-+ * @head: the head for your list.
-+ * @member: the name of the hlist_node within the struct.
-+ */
-+#define hlist_for_each_entry(tpos, pos, head, member) \
-+ for (pos = (head)->first; \
-+ pos && ({ prefetch(pos->next); 1;}) && \
-+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-+ pos = pos->next)
-+
-+/**
-+ * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
-+ * @tpos: the type * to use as a loop counter.
-+ * @pos: the &struct hlist_node to use as a loop counter.
-+ * @member: the name of the hlist_node within the struct.
-+ */
-+#define hlist_for_each_entry_continue(tpos, pos, member) \
-+ for (pos = (pos)->next; \
-+ pos && ({ prefetch(pos->next); 1;}) && \
-+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-+ pos = pos->next)
-+
-+/**
-+ * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
-+ * @tpos: the type * to use as a loop counter.
-+ * @pos: the &struct hlist_node to use as a loop counter.
-+ * @member: the name of the hlist_node within the struct.
-+ */
-+#define hlist_for_each_entry_from(tpos, pos, member) \
-+ for (; pos && ({ prefetch(pos->next); 1;}) && \
-+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-+ pos = pos->next)
-+
-+/**
-+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
-+ * @tpos: the type * to use as a loop counter.
-+ * @pos: the &struct hlist_node to use as a loop counter.
-+ * @n: another &struct hlist_node to use as temporary storage
-+ * @head: the head for your list.
-+ * @member: the name of the hlist_node within the struct.
-+ */
-+#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
-+ for (pos = (head)->first; \
-+ pos && ({ n = pos->next; 1; }) && \
-+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-+ pos = n)
-+
-+/**
-+ * hlist_for_each_entry_rcu - iterate over rcu list of given type
-+ * @pos: the type * to use as a loop counter.
-+ * @pos: the &struct hlist_node to use as a loop counter.
-+ * @head: the head for your list.
-+ * @member: the name of the hlist_node within the struct.
-+ *
-+ * This list-traversal primitive may safely run concurrently with
-+ * the _rcu list-mutation primitives such as hlist_add_rcu()
-+ * as long as the traversal is guarded by rcu_read_lock().
-+ */
-+#define hlist_for_each_entry_rcu(tpos, pos, head, member) \
-+ for (pos = (head)->first; \
-+ pos && ({ prefetch(pos->next); 1;}) && \
-+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-+ pos = pos->next, ({ smp_read_barrier_depends(); 0; }) )
-+
-+#endif
diff --git a/src/patches/linux-2.6.16-imq2.diff b/src/patches/linux-2.6.16-imq2.diff
deleted file mode 100644
index bb224d0ad..000000000
--- a/src/patches/linux-2.6.16-imq2.diff
+++ /dev/null
@@ -1,885 +0,0 @@
-diff -Nru linux-2.6.16/drivers/net/Kconfig linux-2.6.16-imq/drivers/net/Kconfig
---- linux-2.6.16/drivers/net/Kconfig 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/drivers/net/Kconfig 2006-03-25 20:57:14.000000000 +0000
-@@ -93,6 +93,129 @@
- To compile this driver as a module, choose M here: the module
- will be called eql. If unsure, say N.
-
-+config IMQ
-+ tristate "IMQ (intermediate queueing device) support"
-+ depends on NETDEVICES && NETFILTER
-+ ---help---
-+ The IMQ device(s) is used as placeholder for QoS queueing disciplines.
-+ Every packet entering/leaving the IP stack can be directed through
-+ the IMQ device where it's enqueued/dequeued to the attached qdisc.
-+ This allows you to treat network devices as classes and distribute
-+ bandwidth among them. Iptables is used to specify through which IMQ
-+ device, if any, packets travel.
-+
-+ More information at: http://www.linuximq.net/
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called imq. If unsure, say N.
-+
-+choice
-+ prompt "IMQ behavior (PRE/POSTROUTING)"
-+ depends on IMQ
-+ default IMQ_BEHAVIOR_BA
-+ help
-+
-+ This settings defines how IMQ behaves in respect to its
-+ hooking in PREROUTING and POSTROUTING.
-+
-+ IMQ can work in any of the following ways:
-+
-+ PREROUTING | POSTROUTING
-+ -----------------|-------------------
-+ #1 After NAT | After NAT
-+ #2 After NAT | Before NAT
-+ #3 Before NAT | After NAT
-+ #4 Before NAT | Before NAT
-+
-+ The default behavior is to hook before NAT on PREROUTING
-+ and after NAT on POSTROUTING (#3).
-+
-+ This settings are specially usefull when trying to use IMQ
-+ to shape NATed clients.
-+
-+ More information can be found at: www.linuximq.net
-+
-+ If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_AA
-+ bool "IMQ AA"
-+ help
-+ This settings defines how IMQ behaves in respect to its
-+ hooking in PREROUTING and POSTROUTING.
-+
-+ Choosing this option will make IMQ hook like this:
-+
-+ PREROUTING: After NAT
-+ POSTROUTING: After NAT
-+
-+ More information can be found at: www.linuximq.net
-+
-+ If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_AB
-+ bool "IMQ AB"
-+ help
-+ This settings defines how IMQ behaves in respect to its
-+ hooking in PREROUTING and POSTROUTING.
-+
-+ Choosing this option will make IMQ hook like this:
-+
-+ PREROUTING: After NAT
-+ POSTROUTING: Before NAT
-+
-+ More information can be found at: www.linuximq.net
-+
-+ If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_BA
-+ bool "IMQ BA"
-+ help
-+ This settings defines how IMQ behaves in respect to its
-+ hooking in PREROUTING and POSTROUTING.
-+
-+ Choosing this option will make IMQ hook like this:
-+
-+ PREROUTING: Before NAT
-+ POSTROUTING: After NAT
-+
-+ More information can be found at: www.linuximq.net
-+
-+ If not sure leave the default settings alone.
-+
-+config IMQ_BEHAVIOR_BB
-+ bool "IMQ BB"
-+ help
-+ This settings defines how IMQ behaves in respect to its
-+ hooking in PREROUTING and POSTROUTING.
-+
-+ Choosing this option will make IMQ hook like this:
-+
-+ PREROUTING: Before NAT
-+ POSTROUTING: Before NAT
-+
-+ More information can be found at: www.linuximq.net
-+
-+ If not sure leave the default settings alone.
-+
-+endchoice
-+
-+config IMQ_NUM_DEVS
-+
-+ int "Number of IMQ devices"
-+ range 2 8
-+ depends on IMQ
-+ default "2"
-+ help
-+
-+ This settings defines how many IMQ devices will be
-+ created.
-+
-+ The default value is 2.
-+
-+ More information can be found at: www.linuximq.net
-+
-+ If not sure leave the default settings alone.
-+
- config TUN
- tristate "Universal TUN/TAP device driver support"
- select CRC32
-diff -Nru linux-2.6.16/drivers/net/Makefile linux-2.6.16-imq/drivers/net/Makefile
---- linux-2.6.16/drivers/net/Makefile 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/drivers/net/Makefile 2006-03-25 21:04:53.000000000 +0000
-@@ -125,6 +125,7 @@
- endif
-
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_DE600) += de600.o
- obj-$(CONFIG_DE620) += de620.o
-diff -Nru linux-2.6.16/drivers/net/imq.c linux-2.6.16-imq/drivers/net/imq.c
---- linux-2.6.16/drivers/net/imq.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16-imq/drivers/net/imq.c 2006-03-25 20:57:14.000000000 +0000
-@@ -0,0 +1,403 @@
-+/*
-+ * Pseudo-driver for the intermediate queue device.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ * Authors: Patrick McHardy,
-+ *
-+ * The first version was written by Martin Devera,
-+ *
-+ * Credits: Jan Rafaj
-+ * - Update patch to 2.4.21
-+ * Sebastian Strollo
-+ * - Fix "Dead-loop on netdevice imq"-issue
-+ * Marcel Sebek
-+ * - Update to 2.6.2-rc1
-+ *
-+ * After some time of inactivity there is a group taking care
-+ * of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ * 2004/06/30 - New version of IMQ patch to kernels <=2.6.7 including
-+ * the following changes:
-+ *
-+ * - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ * - Correction of imq_init_devs() issue that resulted in
-+ * kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ * - Addition of functionality to choose number of IMQ devices
-+ * during kernel config (Andre Correa)
-+ * - Addition of functionality to choose how IMQ hooks on
-+ * PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ * - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ * 2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ * released with almost no problems. 2.6.14-x was released
-+ * with some important changes: nfcache was removed; After
-+ * some weeks of trouble we figured out that some IMQ fields
-+ * in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ * These functions are correctly patched by this new patch version.
-+ *
-+ * Thanks for all who helped to figure out all the problems with
-+ * 2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ * Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ * I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ * More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+ #include
-+#endif
-+#include
-+#include
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+ .hook = imq_nf_hook,
-+ .owner = THIS_MODULE,
-+ .pf = PF_INET,
-+ .hooknum = NF_IP_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+ .priority = NF_IP_PRI_MANGLE + 1
-+#else
-+ .priority = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+ .hook = imq_nf_hook,
-+ .owner = THIS_MODULE,
-+ .pf = PF_INET,
-+ .hooknum = NF_IP_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+ .priority = NF_IP_PRI_LAST
-+#else
-+ .priority = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+ .hook = imq_nf_hook,
-+ .owner = THIS_MODULE,
-+ .pf = PF_INET6,
-+ .hooknum = NF_IP6_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+ .priority = NF_IP6_PRI_MANGLE + 1
-+#else
-+ .priority = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+ .hook = imq_nf_hook,
-+ .owner = THIS_MODULE,
-+ .pf = PF_INET6,
-+ .hooknum = NF_IP6_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+ .priority = NF_IP6_PRI_LAST
-+#else
-+ .priority = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = 2;
-+#endif
-+
-+static struct net_device *imq_devs;
-+
-+static struct net_device_stats *imq_get_stats(struct net_device *dev)
-+{
-+ return (struct net_device_stats *)dev->priv;
-+}
-+
-+/* called for packets kfree'd in qdiscs at places other than enqueue */
-+static void imq_skb_destructor(struct sk_buff *skb)
-+{
-+ struct nf_info *info = skb->nf_info;
-+
-+ if (info) {
-+ if (info->indev)
-+ dev_put(info->indev);
-+ if (info->outdev)
-+ dev_put(info->outdev);
-+ kfree(info);
-+ }
-+}
-+
-+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
-+
-+ stats->tx_bytes += skb->len;
-+ stats->tx_packets++;
-+
-+ skb->imq_flags = 0;
-+ skb->destructor = NULL;
-+
-+ dev->trans_start = jiffies;
-+ nf_reinject(skb, skb->nf_info, NF_ACCEPT);
-+ return 0;
-+}
-+
-+static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, unsigned queue_num, void *data)
-+{
-+ struct net_device *dev;
-+ struct net_device_stats *stats;
-+ struct sk_buff *skb2 = NULL;
-+ struct Qdisc *q;
-+ unsigned int index = skb->imq_flags&IMQ_F_IFMASK;
-+ int ret = -1;
-+
-+ if (index > numdevs)
-+ return -1;
-+
-+ dev = imq_devs + index;
-+ if (!(dev->flags & IFF_UP)) {
-+ skb->imq_flags = 0;
-+ nf_reinject(skb, info, NF_ACCEPT);
-+ return 0;
-+ }
-+ dev->last_rx = jiffies;
-+
-+ if (skb->destructor) {
-+ skb2 = skb;
-+ skb = skb_clone(skb, GFP_ATOMIC);
-+ if (!skb)
-+ return -1;
-+ }
-+ skb->nf_info = info;
-+
-+ stats = (struct net_device_stats *)dev->priv;
-+ stats->rx_bytes+= skb->len;
-+ stats->rx_packets++;
-+
-+ spin_lock_bh(&dev->queue_lock);
-+ q = dev->qdisc;
-+ if (q->enqueue) {
-+ q->enqueue(skb_get(skb), q);
-+ if (skb_shared(skb)) {
-+ skb->destructor = imq_skb_destructor;
-+ kfree_skb(skb);
-+ ret = 0;
-+ }
-+ }
-+ if (spin_is_locked(&dev->xmit_lock))
-+ netif_schedule(dev);
-+ else
-+
-+ while (!netif_queue_stopped(dev) &&
-+ qdisc_restart(dev)<0)
-+ /* NOTHING */;
-+
-+ spin_unlock_bh(&dev->queue_lock);
-+
-+ if (skb2)
-+ kfree_skb(ret ? skb : skb2);
-+
-+ return ret;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+ .name = "imq",
-+ .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb,
-+ const struct net_device *indev,
-+ const struct net_device *outdev,
-+ int (*okfn)(struct sk_buff *))
-+{
-+ if ((*pskb)->imq_flags & IMQ_F_ENQUEUE)
-+ return NF_QUEUE;
-+
-+ return NF_ACCEPT;
-+}
-+
-+
-+static int __init imq_init_hooks(void)
-+{
-+ int err;
-+
-+ err = nf_register_queue_handler(PF_INET, &nfqh);
-+ if (err > 0)
-+ goto err1;
-+ if ((err = nf_register_hook(&imq_ingress_ipv4)))
-+ goto err2;
-+ if ((err = nf_register_hook(&imq_egress_ipv4)))
-+ goto err3;
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+ if ((err = nf_register_queue_handler(PF_INET6, &nfqh)))
-+ goto err4;
-+ if ((err = nf_register_hook(&imq_ingress_ipv6)))
-+ goto err5;
-+ if ((err = nf_register_hook(&imq_egress_ipv6)))
-+ goto err6;
-+#endif
-+
-+ return 0;
-+
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+err6:
-+ nf_unregister_hook(&imq_ingress_ipv6);
-+err5:
-+ nf_unregister_queue_handler(PF_INET6);
-+err4:
-+ nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+err3:
-+ nf_unregister_hook(&imq_ingress_ipv4);
-+err2:
-+ nf_unregister_queue_handler(PF_INET);
-+err1:
-+ return err;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+ nf_unregister_hook(&imq_ingress_ipv4);
-+ nf_unregister_hook(&imq_egress_ipv4);
-+ nf_unregister_queue_handler(PF_INET);
-+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-+ nf_unregister_hook(&imq_ingress_ipv6);
-+ nf_unregister_hook(&imq_egress_ipv6);
-+ nf_unregister_queue_handler(PF_INET6);
-+#endif
-+}
-+
-+static int __init imq_dev_init(struct net_device *dev)
-+{
-+ dev->hard_start_xmit = imq_dev_xmit;
-+ dev->type = ARPHRD_VOID;
-+ dev->mtu = 1500;
-+ dev->tx_queue_len = 30;
-+ dev->flags = IFF_NOARP;
-+ dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
-+ if (dev->priv == NULL)
-+ return -ENOMEM;
-+ memset(dev->priv, 0, sizeof(struct net_device_stats));
-+ dev->get_stats = imq_get_stats;
-+
-+ return 0;
-+}
-+
-+static void imq_dev_uninit(struct net_device *dev)
-+{
-+ kfree(dev->priv);
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+ struct net_device *dev;
-+ int i,j;
-+ j = numdevs;
-+
-+ if (!numdevs || numdevs > IMQ_MAX_DEVS) {
-+ printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+ IMQ_MAX_DEVS);
-+ return -EINVAL;
-+ }
-+
-+ imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL);
-+ if (!imq_devs)
-+ return -ENOMEM;
-+ memset(imq_devs, 0, sizeof(struct net_device) * numdevs);
-+
-+ /* we start counting at zero */
-+ numdevs--;
-+
-+ for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) {
-+ SET_MODULE_OWNER(dev);
-+ strcpy(dev->name, "imq%d");
-+ dev->init = imq_dev_init;
-+ dev->uninit = imq_dev_uninit;
-+
-+ if (register_netdev(dev) < 0)
-+ goto err_register;
-+ }
-+ printk(KERN_INFO "IMQ starting with %u devices...\n", j);
-+ return 0;
-+
-+err_register:
-+ for (; i; i--)
-+ unregister_netdev(--dev);
-+ kfree(imq_devs);
-+ return -EIO;
-+}
-+
-+static void imq_cleanup_devs(void)
-+{
-+ int i;
-+ struct net_device *dev = imq_devs;
-+
-+ for (i = 0; i <= numdevs; i++)
-+ unregister_netdev(dev++);
-+
-+ kfree(imq_devs);
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+ int err;
-+
-+ if ((err = imq_init_devs())) {
-+ printk(KERN_ERR "IMQ: Error trying imq_init_devs()\n");
-+ return err;
-+ }
-+ if ((err = imq_init_hooks())) {
-+ printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+ imq_cleanup_devs();
-+ return err;
-+ }
-+
-+ printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+ printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+ printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+ printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+ printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+ return 0;
-+}
-+
-+static void __exit imq_cleanup_module(void)
-+{
-+ imq_unhook();
-+ imq_cleanup_devs();
-+ printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+
-+module_init(imq_init_module);
-+module_exit(imq_cleanup_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-diff -Nru linux-2.6.16/include/linux/imq.h linux-2.6.16-imq/include/linux/imq.h
---- linux-2.6.16/include/linux/imq.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16-imq/include/linux/imq.h 2006-03-25 20:57:14.000000000 +0000
-@@ -0,0 +1,9 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+#define IMQ_MAX_DEVS 16
-+
-+#define IMQ_F_IFMASK 0x7f
-+#define IMQ_F_ENQUEUE 0x80
-+
-+#endif /* _IMQ_H */
-diff -Nru linux-2.6.16/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.6.16-imq/include/linux/netfilter_ipv4/ipt_IMQ.h
---- linux-2.6.16/include/linux/netfilter_ipv4/ipt_IMQ.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16-imq/include/linux/netfilter_ipv4/ipt_IMQ.h 2006-03-25 20:57:14.000000000 +0000
-@@ -0,0 +1,8 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+struct ipt_imq_info {
-+ unsigned int todev; /* target imq device */
-+};
-+
-+#endif /* _IPT_IMQ_H */
-diff -Nru linux-2.6.16/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.6.16-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h
---- linux-2.6.16/include/linux/netfilter_ipv6/ip6t_IMQ.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h 2006-03-25 20:57:14.000000000 +0000
-@@ -0,0 +1,8 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+struct ip6t_imq_info {
-+ unsigned int todev; /* target imq device */
-+};
-+
-+#endif /* _IP6T_IMQ_H */
-diff -Nru linux-2.6.16/include/linux/skbuff.h linux-2.6.16-imq/include/linux/skbuff.h
---- linux-2.6.16/include/linux/skbuff.h 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/include/linux/skbuff.h 2006-03-25 20:57:14.000000000 +0000
-@@ -275,6 +275,10 @@
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- struct sk_buff *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+ unsigned char imq_flags;
-+ struct nf_info *nf_info;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- struct nf_bridge_info *nf_bridge;
- #endif
-diff -Nru linux-2.6.16/net/core/skbuff.c linux-2.6.16-imq/net/core/skbuff.c
---- linux-2.6.16/net/core/skbuff.c 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/net/core/skbuff.c 2006-03-25 20:57:14.000000000 +0000
-@@ -425,6 +425,10 @@
- C(nfct_reasm);
- nf_conntrack_get_reasm(skb->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+ C(imq_flags);
-+ C(nf_info);
-+#endif /*CONFIG_IMQ*/
- #ifdef CONFIG_BRIDGE_NETFILTER
- C(nf_bridge);
- nf_bridge_get(skb->nf_bridge);
-@@ -489,6 +493,10 @@
- #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
- new->ipvs_property = old->ipvs_property;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+ new->imq_flags = old->imq_flags;
-+ new->nf_info = old->nf_info;
-+#endif /*CONFIG_IMQ*/
- #ifdef CONFIG_BRIDGE_NETFILTER
- new->nf_bridge = old->nf_bridge;
- nf_bridge_get(old->nf_bridge);
-diff -Nru linux-2.6.16/net/ipv4/netfilter/Kconfig linux-2.6.16-imq/net/ipv4/netfilter/Kconfig
---- linux-2.6.16/net/ipv4/netfilter/Kconfig 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/net/ipv4/netfilter/Kconfig 2006-03-25 21:54:10.000000000 +0000
-@@ -505,6 +505,17 @@
-
- To compile it as a module, choose M here. If unsure, say N.
-
-+config IP_NF_TARGET_IMQ
-+ tristate "IMQ target support"
-+ depends on IP_NF_MANGLE
-+ help
-+ This option adds a `IMQ' target which is used to specify if and
-+ to which IMQ device packets should get enqueued/dequeued.
-+
-+ For more information visit: http://www.linuximq.net/
-+
-+ To compile it as a module, choose M here. If unsure, say N.
-+
- config IP_NF_TARGET_TOS
- tristate "TOS target support"
- depends on IP_NF_MANGLE
-diff -Nru linux-2.6.16/net/ipv4/netfilter/Makefile linux-2.6.16-imq/net/ipv4/netfilter/Makefile
---- linux-2.6.16/net/ipv4/netfilter/Makefile 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/net/ipv4/netfilter/Makefile 2006-03-25 21:06:00.000000000 +0000
-@@ -64,6 +64,7 @@
- obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
- obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
- obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
-+obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
- obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
- obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
- obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
-diff -Nru linux-2.6.16/net/ipv4/netfilter/ipt_IMQ.c linux-2.6.16-imq/net/ipv4/netfilter/ipt_IMQ.c
---- linux-2.6.16/net/ipv4/netfilter/ipt_IMQ.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16-imq/net/ipv4/netfilter/ipt_IMQ.c 2006-03-25 20:57:14.000000000 +0000
-@@ -0,0 +1,80 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+static unsigned int imq_target(struct sk_buff **pskb,
-+ const struct net_device *in,
-+ const struct net_device *out,
-+ unsigned int hooknum,
-+ const void *targinfo,
-+ void *userdata)
-+{
-+ struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo;
-+
-+ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
-+
-+ return IPT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const char *tablename,
-+ const struct ipt_entry *e,
-+ void *targinfo,
-+ unsigned int targinfosize,
-+ unsigned int hook_mask)
-+{
-+ struct ipt_imq_info *mr;
-+
-+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_imq_info))) {
-+ printk(KERN_WARNING "IMQ: invalid targinfosize\n");
-+ return 0;
-+ }
-+ mr = (struct ipt_imq_info*)targinfo;
-+
-+ if (strcmp(tablename, "mangle") != 0) {
-+ printk(KERN_WARNING
-+ "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n",
-+ tablename);
-+ return 0;
-+ }
-+
-+ if (mr->todev > IMQ_MAX_DEVS) {
-+ printk(KERN_WARNING
-+ "IMQ: invalid device specified, highest is %u\n",
-+ IMQ_MAX_DEVS);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static struct ipt_target ipt_imq_reg = {
-+ .name = "IMQ",
-+ .target = imq_target,
-+ .checkentry = imq_checkentry,
-+ .me = THIS_MODULE
-+};
-+
-+static int __init init(void)
-+{
-+ if (ipt_register_target(&ipt_imq_reg))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static void __exit fini(void)
-+{
-+ ipt_unregister_target(&ipt_imq_reg);
-+}
-+
-+module_init(init);
-+module_exit(fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-diff -Nru linux-2.6.16/net/ipv6/netfilter/Kconfig linux-2.6.16-imq/net/ipv6/netfilter/Kconfig
---- linux-2.6.16/net/ipv6/netfilter/Kconfig 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/net/ipv6/netfilter/Kconfig 2006-03-25 21:54:48.000000000 +0000
-@@ -183,6 +183,15 @@
-
- To compile it as a module, choose M here. If unsure, say N.
-
-+config IP6_NF_TARGET_IMQ
-+ tristate "IMQ target support"
-+ depends on IP6_NF_MANGLE
-+ help
-+ This option adds a `IMQ' target which is used to specify if and
-+ to which imq device packets should get enqueued/dequeued.
-+
-+ To compile it as a module, choose M here. If unsure, say N.
-+
- config IP6_NF_TARGET_HL
- tristate 'HL (hoplimit) target support'
- depends on IP6_NF_MANGLE
-diff -Nru linux-2.6.16/net/ipv6/netfilter/Makefile linux-2.6.16-imq/net/ipv6/netfilter/Makefile
---- linux-2.6.16/net/ipv6/netfilter/Makefile 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/net/ipv6/netfilter/Makefile 2006-03-25 21:07:08.000000000 +0000
-@@ -15,6 +15,7 @@
- obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
- obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
- obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
-+obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o
- obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
- obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
- obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
-diff -Nru linux-2.6.16/net/ipv6/netfilter/ip6t_IMQ.c linux-2.6.16-imq/net/ipv6/netfilter/ip6t_IMQ.c
---- linux-2.6.16/net/ipv6/netfilter/ip6t_IMQ.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16-imq/net/ipv6/netfilter/ip6t_IMQ.c 2006-03-25 20:57:14.000000000 +0000
-@@ -0,0 +1,80 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+static unsigned int imq_target(struct sk_buff **pskb,
-+ unsigned int hooknum,
-+ const struct net_device *in,
-+ const struct net_device *out,
-+ const void *targinfo,
-+ void *userdata)
-+{
-+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo;
-+
-+ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
-+
-+ return IP6T_CONTINUE;
-+}
-+
-+static int imq_checkentry(const char *tablename,
-+ const struct ip6t_entry *e,
-+ void *targinfo,
-+ unsigned int targinfosize,
-+ unsigned int hook_mask)
-+{
-+ struct ip6t_imq_info *mr;
-+
-+ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_imq_info))) {
-+ printk(KERN_WARNING "IMQ: invalid targinfosize\n");
-+ return 0;
-+ }
-+ mr = (struct ip6t_imq_info*)targinfo;
-+
-+ if (strcmp(tablename, "mangle") != 0) {
-+ printk(KERN_WARNING
-+ "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n",
-+ tablename);
-+ return 0;
-+ }
-+
-+ if (mr->todev > IMQ_MAX_DEVS) {
-+ printk(KERN_WARNING
-+ "IMQ: invalid device specified, highest is %u\n",
-+ IMQ_MAX_DEVS);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static struct ip6t_target ip6t_imq_reg = {
-+ .name = "IMQ",
-+ .target = imq_target,
-+ .checkentry = imq_checkentry,
-+ .me = THIS_MODULE
-+};
-+
-+static int __init init(void)
-+{
-+ if (ip6t_register_target(&ip6t_imq_reg))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static void __exit fini(void)
-+{
-+ ip6t_unregister_target(&ip6t_imq_reg);
-+}
-+
-+module_init(init);
-+module_exit(fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-diff -Nru linux-2.6.16/net/sched/sch_generic.c linux-2.6.16-imq/net/sched/sch_generic.c
---- linux-2.6.16/net/sched/sch_generic.c 2006-03-20 05:53:29.000000000 +0000
-+++ linux-2.6.16-imq/net/sched/sch_generic.c 2006-03-25 20:57:14.000000000 +0000
-@@ -29,6 +29,9 @@
- #include
- #include
- #include
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include
-+#endif
- #include
- #include
- #include
-@@ -136,7 +139,13 @@
-
- if (!netif_queue_stopped(dev)) {
- int ret;
-- if (netdev_nit)
-+
-+ if (netdev_nit
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+ && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+ )
-+
- dev_queue_xmit_nit(skb, dev);
-
- ret = dev->hard_start_xmit(skb, dev);
diff --git a/src/patches/linux-2.6.16.27-utf8_input-1.patch b/src/patches/linux-2.6.16.27-utf8_input-1.patch
deleted file mode 100644
index fe94285b5..000000000
--- a/src/patches/linux-2.6.16.27-utf8_input-1.patch
+++ /dev/null
@@ -1,380 +0,0 @@
-Submitted by: Alexander E. Patrakov
-Signed-off-by: Alexander E. Patrakov
-Date: 2005-10-18
-Initial Package Version: 2.6.15
-Upstream Status: Rejected: they say it modifies the meaning of an existing ioctl
-Origin: http://chris.heathens.co.nz/linux/downloads/patches-2.6.4-cdh1.tar.gz
- Porting to linux-2.6.16 by Alexander E. Patrakov
-Description: This patch fixes dead keys and copy/paste of non-ASCII characters
- in UTF-8 mode on Linux console.
- See more details about the original patch at:
- http://chris.heathens.co.nz/linux/utf8.html
-
-diff -ur linux-2.6.15-rc6.orig/drivers/char/consolemap.c linux-2.6.15-rc6.my/drivers/char/consolemap.c
---- linux-2.6.15-rc6.orig/drivers/char/consolemap.c 2005-12-25 10:00:12.000000000 +0500
-+++ linux-2.6.15-rc6.my/drivers/char/consolemap.c 2005-12-25 10:01:22.000000000 +0500
-@@ -178,6 +178,7 @@
- unsigned long refcount;
- unsigned long sum;
- unsigned char *inverse_translations[4];
-+ u16 *inverse_trans_unicode;
- int readonly;
- };
-
-@@ -208,6 +209,41 @@
- }
- }
-
-+static void set_inverse_trans_unicode(struct vc_data *conp,
-+ struct uni_pagedir *p)
-+{
-+ int i, j, k, glyph;
-+ u16 **p1, *p2;
-+ u16 *q;
-+
-+ if (!p) return;
-+ q = p->inverse_trans_unicode;
-+ if (!q) {
-+ q = p->inverse_trans_unicode =
-+ kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
-+ if (!q)
-+ return;
-+ }
-+ memset(q, 0, MAX_GLYPH * sizeof(u16));
-+
-+ for (i = 0; i < 32; i++) {
-+ p1 = p->uni_pgdir[i];
-+ if (!p1)
-+ continue;
-+ for (j = 0; j < 32; j++) {
-+ p2 = p1[j];
-+ if (!p2)
-+ continue;
-+ for (k = 0; k < 64; k++) {
-+ glyph = p2[k];
-+ if (glyph >= 0 && glyph < MAX_GLYPH
-+ && q[glyph] < 32)
-+ q[glyph] = (i << 11) + (j << 6) + k;
-+ }
-+ }
-+ }
-+}
-+
- unsigned short *set_translate(int m, struct vc_data *vc)
- {
- inv_translate[vc->vc_num] = m;
-@@ -218,19 +254,29 @@
- * Inverse translation is impossible for several reasons:
- * 1. The font<->character maps are not 1-1.
- * 2. The text may have been written while a different translation map
-- * was active, or using Unicode.
-+ * was active.
- * Still, it is now possible to a certain extent to cut and paste non-ASCII.
- */
--unsigned char inverse_translate(struct vc_data *conp, int glyph)
-+u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
- {
- struct uni_pagedir *p;
-+ int m;
- if (glyph < 0 || glyph >= MAX_GLYPH)
- return 0;
-- else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc) ||
-- !p->inverse_translations[inv_translate[conp->vc_num]])
-+ else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc))
- return glyph;
-- else
-- return p->inverse_translations[inv_translate[conp->vc_num]][glyph];
-+ else if (use_unicode) {
-+ if (!p->inverse_trans_unicode)
-+ return glyph;
-+ else
-+ return p->inverse_trans_unicode[glyph];
-+ } else {
-+ m = inv_translate[conp->vc_num];
-+ if (!p->inverse_translations[m])
-+ return glyph;
-+ else
-+ return p->inverse_translations[m][glyph];
-+ }
- }
-
- static void update_user_maps(void)
-@@ -244,6 +290,7 @@
- p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
- if (p && p != q) {
- set_inverse_transl(vc_cons[i].d, p, USER_MAP);
-+ set_inverse_trans_unicode(vc_cons[i].d, p);
- q = p;
- }
- }
-@@ -354,6 +401,10 @@
- kfree(p->inverse_translations[i]);
- p->inverse_translations[i] = NULL;
- }
-+ if (p->inverse_trans_unicode) {
-+ kfree(p->inverse_trans_unicode);
-+ p->inverse_trans_unicode = NULL;
-+ }
- }
-
- void con_free_unimap(struct vc_data *vc)
-@@ -512,6 +563,7 @@
-
- for (i = 0; i <= 3; i++)
- set_inverse_transl(vc, p, i); /* Update all inverse translations */
-+ set_inverse_trans_unicode(vc, p);
-
- return err;
- }
-@@ -562,6 +614,7 @@
-
- for (i = 0; i <= 3; i++)
- set_inverse_transl(vc, p, i); /* Update all inverse translations */
-+ set_inverse_trans_unicode(vc, p);
- dflt = p;
- return err;
- }
-@@ -618,6 +671,19 @@
- p->readonly = rdonly;
- }
-
-+/* may be called during an interrupt */
-+u32 conv_8bit_to_uni(unsigned char c)
-+{
-+ /*
-+ * Always use USER_MAP. This function is used by the keyboard,
-+ * which shouldn't be affected by G0/G1 switching, etc.
-+ * If the user map still contains default values, i.e. the
-+ * direct-to-font mapping, then assume user is using Latin1.
-+ */
-+ unsigned short uni = translations[USER_MAP][c];
-+ return uni == (0xf000 | c) ? c : uni;
-+}
-+
- int
- conv_uni_to_pc(struct vc_data *conp, long ucs)
- {
-diff -ur linux-2.6.15-rc6.orig/drivers/char/keyboard.c linux-2.6.15-rc6.my/drivers/char/keyboard.c
---- linux-2.6.15-rc6.orig/drivers/char/keyboard.c 2005-12-25 10:00:12.000000000 +0500
-+++ linux-2.6.15-rc6.my/drivers/char/keyboard.c 2005-12-25 10:01:22.000000000 +0500
-@@ -34,6 +34,7 @@
- #include
- #include
-
-+#include
- #include
- #include
- #include
-@@ -329,10 +330,9 @@
- * Many other routines do put_queue, but I think either
- * they produce ASCII, or they produce some user-assigned
- * string, and in both cases we might assume that it is
-- * in utf-8 already. UTF-8 is defined for words of up to 31 bits,
-- * but we need only 16 bits here
-+ * in utf-8 already.
- */
--static void to_utf8(struct vc_data *vc, ushort c)
-+static void to_utf8(struct vc_data *vc, uint c)
- {
- if (c < 0x80)
- /* 0******* */
-@@ -341,14 +341,33 @@
- /* 110***** 10****** */
- put_queue(vc, 0xc0 | (c >> 6));
- put_queue(vc, 0x80 | (c & 0x3f));
-- } else {
-+ } else if (c < 0x10000) {
-+ if (c >= 0xD800 && c < 0xE000)
-+ return;
-+ if (c == 0xFFFF)
-+ return;
- /* 1110**** 10****** 10****** */
- put_queue(vc, 0xe0 | (c >> 12));
- put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
- put_queue(vc, 0x80 | (c & 0x3f));
-+ } else if (c < 0x110000) {
-+ /* 11110*** 10****** 10****** 10****** */
-+ put_queue(vc, 0xf0 | (c >> 18));
-+ put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
-+ put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
-+ put_queue(vc, 0x80 | (c & 0x3f));
- }
- }
-
-+static void put_8bit(struct vc_data *vc, u8 c)
-+{
-+ if (kbd->kbdmode != VC_UNICODE || c < 32 || c == 127)
-+ /* Don't translate control chars */
-+ put_queue(vc, c);
-+ else
-+ to_utf8(vc, conv_8bit_to_uni(c));
-+}
-+
- /*
- * Called after returning from RAW mode or when changing consoles - recompute
- * shift_down[] and shift_state from key_down[] maybe called when keymap is
-@@ -409,7 +428,7 @@
- if (ch == ' ' || ch == d)
- return d;
-
-- put_queue(vc, d);
-+ put_8bit(vc, d);
- return ch;
- }
-
-@@ -419,7 +438,7 @@
- static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
- {
- if (diacr) {
-- put_queue(vc, diacr);
-+ put_8bit(vc, diacr);
- diacr = 0;
- }
- put_queue(vc, 13);
-@@ -628,7 +647,7 @@
- diacr = value;
- return;
- }
-- put_queue(vc, value);
-+ put_8bit(vc, value);
- }
-
- /*
-@@ -774,7 +793,7 @@
- /* kludge */
- if (up_flag && shift_state != old_state && npadch != -1) {
- if (kbd->kbdmode == VC_UNICODE)
-- to_utf8(vc, npadch & 0xffff);
-+ to_utf8(vc, npadch);
- else
- put_queue(vc, npadch & 0xff);
- npadch = -1;
-diff -ur linux-2.6.15-rc6.orig/drivers/char/selection.c linux-2.6.15-rc6.my/drivers/char/selection.c
---- linux-2.6.15-rc6.orig/drivers/char/selection.c 2005-12-25 10:00:12.000000000 +0500
-+++ linux-2.6.15-rc6.my/drivers/char/selection.c 2005-12-25 10:01:22.000000000 +0500
-@@ -20,6 +20,7 @@
-
- #include
-
-+#include
- #include
- #include
- #include
-@@ -34,6 +35,7 @@
- /* Variables for selection control. */
- /* Use a dynamic buffer, instead of static (Dec 1994) */
- struct vc_data *sel_cons; /* must not be disallocated */
-+static int use_unicode;
- static volatile int sel_start = -1; /* cleared by clear_selection */
- static int sel_end;
- static int sel_buffer_lth;
-@@ -54,10 +56,11 @@
- complement_pos(sel_cons, where);
- }
-
--static unsigned char
-+static u16
- sel_pos(int n)
- {
-- return inverse_translate(sel_cons, screen_glyph(sel_cons, n));
-+ return inverse_translate(sel_cons, screen_glyph(sel_cons, n),
-+ use_unicode);
- }
-
- /* remove the current selection highlight, if any,
-@@ -86,8 +89,8 @@
- 0xFF7FFFFF /* latin-1 accented letters, not division sign */
- };
-
--static inline int inword(const unsigned char c) {
-- return ( inwordLut[c>>5] >> (c & 0x1F) ) & 1;
-+static inline int inword(const u16 c) {
-+ return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
- }
-
- /* set inwordLut contents. Invoked by ioctl(). */
-@@ -108,13 +111,36 @@
- return (v > u) ? u : v;
- }
-
-+/* stores the char in UTF8 and returns the number of bytes used (1-3) */
-+int store_utf8(u16 c, char *p)
-+{
-+ if (c < 0x80) {
-+ /* 0******* */
-+ p[0] = c;
-+ return 1;
-+ } else if (c < 0x800) {
-+ /* 110***** 10****** */
-+ p[0] = 0xc0 | (c >> 6);
-+ p[1] = 0x80 | (c & 0x3f);
-+ return 2;
-+ } else {
-+ /* 1110**** 10****** 10****** */
-+ p[0] = 0xe0 | (c >> 12);
-+ p[1] = 0x80 | ((c >> 6) & 0x3f);
-+ p[2] = 0x80 | (c & 0x3f);
-+ return 3;
-+ }
-+}
-+
- /* set the current selection. Invoked by ioctl() or by kernel code. */
- int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
- {
- struct vc_data *vc = vc_cons[fg_console].d;
- int sel_mode, new_sel_start, new_sel_end, spc;
- char *bp, *obp;
-- int i, ps, pe;
-+ int i, ps, pe, multiplier;
-+ u16 c;
-+ struct kbd_struct *kbd = kbd_table + fg_console;
-
- poke_blanked_console();
-
-@@ -158,7 +184,8 @@
- clear_selection();
- sel_cons = vc_cons[fg_console].d;
- }
--
-+ use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
-+
- switch (sel_mode)
- {
- case TIOCL_SELCHAR: /* character-by-character selection */
-@@ -240,7 +267,8 @@
- sel_end = new_sel_end;
-
- /* Allocate a new buffer before freeing the old one ... */
-- bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
-+ multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */
-+ bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL);
- if (!bp) {
- printk(KERN_WARNING "selection: kmalloc() failed\n");
- clear_selection();
-@@ -251,8 +279,12 @@
-
- obp = bp;
- for (i = sel_start; i <= sel_end; i += 2) {
-- *bp = sel_pos(i);
-- if (!isspace(*bp++))
-+ c = sel_pos(i);
-+ if (use_unicode)
-+ bp += store_utf8(c, bp);
-+ else
-+ *bp++ = c;
-+ if (!isspace(c))
- obp = bp;
- if (! ((i + 2) % vc->vc_size_row)) {
- /* strip trailing blanks from line and add newline,
-diff -ur linux-2.6.15-rc6.orig/include/linux/consolemap.h linux-2.6.15-rc6.my/include/linux/consolemap.h
---- linux-2.6.15-rc6.orig/include/linux/consolemap.h 2005-12-25 10:00:13.000000000 +0500
-+++ linux-2.6.15-rc6.my/include/linux/consolemap.h 2005-12-25 10:01:22.000000000 +0500
-@@ -10,6 +10,7 @@
-
- struct vc_data;
-
--extern unsigned char inverse_translate(struct vc_data *conp, int glyph);
-+extern u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode);
- extern unsigned short *set_translate(int m, struct vc_data *vc);
- extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
-+extern u32 conv_8bit_to_uni(unsigned char c);
diff --git a/src/patches/mc-4.6.1-debian_fixes-1.patch b/src/patches/mc-4.6.1-debian_fixes-1.patch
deleted file mode 100644
index b79a7010d..000000000
--- a/src/patches/mc-4.6.1-debian_fixes-1.patch
+++ /dev/null
@@ -1,15425 +0,0 @@
---- mc-4.6.1.orig/debian/dirs
-+++ mc-4.6.1/debian/dirs
-@@ -0,0 +1,2 @@
-+/etc/mc
-+/usr/share/pixmaps
---- mc-4.6.1.orig/debian/docs
-+++ mc-4.6.1/debian/docs
-@@ -0,0 +1,8 @@
-+FAQ
-+NEWS
-+README
-+AUTHORS
-+TODO
-+AUTHORS
-+ABOUT-NLS
-+HACKING
---- mc-4.6.1.orig/debian/menu
-+++ mc-4.6.1/debian/menu
-@@ -0,0 +1,8 @@
-+?package(mc):\
-+ needs="text"\
-+ section="Apps/Tools"\
-+ title="mc"\
-+ longtitle="Midnight Commander"\
-+ hints="File managers"\
-+ command="/usr/bin/mc"\
-+ icon="/usr/share/pixmaps/mc.xpm"
---- mc-4.6.1.orig/debian/control
-+++ mc-4.6.1/debian/control
-@@ -0,0 +1,21 @@
-+Source: mc
-+Section: utils
-+Priority: optional
-+Maintainer: Stefano Melchior
-+Uploaders: Ludovic Drolez
-+Build-Depends: debhelper (>> 4.0.0), libglib2.0-dev, libgpmg1-dev |not+linux-gnu, gettext, libslang2-dev
-+Standards-Version: 3.7.2
-+
-+Package: mc
-+Architecture: any
-+Depends: ${shlibs:Depends}
-+Suggests: perl, mime-support, zip, unzip, bzip2, links | w3m | lynx, arj
-+Conflicts: mc-common, suidmanager (<< 0.52)
-+Replaces: mc-common, manpages-pl (<= 20030210)
-+Description: midnight commander - a powerful file manager
-+ GNU Midnight Commander is a text-mode full-screen file manager. It
-+ uses a two panel interface and a subshell for command execution. It
-+ includes an internal editor with syntax highlighting and an internal
-+ viewer with support for binary files. Also included is Virtual
-+ Filesystem (VFS), that allows files on remote systems (e.g. FTP, SSH,
-+ SMB servers) and files inside archives to be manipulated like real files.
---- mc-4.6.1.orig/debian/extra/icon.xpm
-+++ mc-4.6.1/debian/extra/icon.xpm
-@@ -0,0 +1,45 @@
-+/* XPM */
-+static char *icon[] = {
-+/* columns rows colors chars-per-pixel */
-+"32 32 7 1",
-+" c black",
-+". c gray20",
-+"X c blue",
-+"o c cyan",
-+"O c yellow",
-+"+ c gray80",
-+"@ c gray90",
-+/* pixels */
-+"+@+@+@++@++@+@+@+@+@++@@++@++@+@",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XXOOOOOXXoXOOXXoXXXOOOOXXoXOOX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XoooooooXoXooXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XoooooooXoXooXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XoooooooXoXooXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XoooooooXoXooXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XoooooooXoXooXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"+XoooooooXoXooXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XXXXXXXXXoXXXXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@XXXXXXXXXoXXXXXoXoooooooXoXooX.",
-+"+XXXXXXXXXoXXXXXoXXXXXXXXXoXXXX.",
-+"@oooooooooooooooooooooooooooooo ",
-+"+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.",
-+"@XooooooXoXoooXXXXooooooXooXooX.",
-+"+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.",
-+"+oooooooooooooooooooooooooooooo.",
-+"@ .",
-+"+ .",
-+"+.+ .",
-+"@ .",
-+"++O++ ++++ O++O +O++O +O++ ++O+.",
-+"+..............................."
-+};
---- mc-4.6.1.orig/debian/extra/mcview-debian.1
-+++ mc-4.6.1/debian/extra/mcview-debian.1
-@@ -0,0 +1,19 @@
-+.TH MCVIEW-DEBIAN 1
-+.SH NAME
-+mcview-debian \- mcview wrapper
-+.br
-+.SH DESCRIPTION
-+This script is just a wrapper for
-+.B mcview,
-+(the Midnight Commander internal viewer) to use with Debian
-+alternatives system.
-+.SH OPTIONS
-+Full list of supported options could be found on the
-+.BR mcview (1)
-+manpage.
-+.SH SEE ALSO
-+.BR mcview (1),
-+.BR mc (1)
-+.SH AUTHOR
-+This manual page was written by Adam Byrtek , for
-+the Debian GNU/Linux system.
---- mc-4.6.1.orig/debian/extra/mcedit-debian
-+++ mc-4.6.1/debian/extra/mcedit-debian
-@@ -0,0 +1,5 @@
-+#!/bin/sh
-+
-+# mcedit wrapper for Debian alternatives system
-+
-+mcedit $@
---- mc-4.6.1.orig/debian/extra/mcmfmt.1
-+++ mc-4.6.1/debian/extra/mcmfmt.1
-@@ -0,0 +1,14 @@
-+.TH MCMFMT 1
-+.SH NAME
-+mcmfmt \- sets bold and underline for mail files
-+.br
-+.SH "DESCRIPTION"
-+.B mcmfmt
-+is a program for internal use by the Midnight Commander only. It sets bold and underline for mail files.
-+.SH OPTIONS
-+There are no options for this program.
-+.SH "SEE ALSO"
-+mc(1)
-+.SH AUTHOR
-+This manual page was written by Paul Seelig ,
-+for the Debian GNU/Linux system (but may be used by others).
---- mc-4.6.1.orig/debian/extra/mcview-debian
-+++ mc-4.6.1/debian/extra/mcview-debian
-@@ -0,0 +1,5 @@
-+#!/bin/sh
-+
-+# mcview wrapper for Debian alternatives system
-+
-+mcview $@
---- mc-4.6.1.orig/debian/extra/mcedit-debian.1
-+++ mc-4.6.1/debian/extra/mcedit-debian.1
-@@ -0,0 +1,19 @@
-+.TH MCEDIT-DEBIAN 1
-+.SH NAME
-+mcedit-debian \- mcedit wrapper
-+.br
-+.SH DESCRIPTION
-+This script is just a wrapper for
-+.B mcedit,
-+(the Midnight Commander internal editor) to use with Debian
-+alternatives system.
-+.SH OPTIONS
-+Full list of supported options could be found on the
-+.BR mcedit (1)
-+manpage.
-+.SH SEE ALSO
-+.BR mcedit (1),
-+.BR mc (1)
-+.SH AUTHOR
-+This manual page was written by Adam Byrtek , for
-+the Debian GNU/Linux system.
---- mc-4.6.1.orig/debian/links
-+++ mc-4.6.1/debian/links
-@@ -0,0 +1,3 @@
-+/etc/mc/mc.ext /usr/share/mc/mc.ext
-+/etc/mc/mc.menu /usr/share/mc/mc.menu
-+/etc/mc/mc.lib /usr/share/mc/mc.lib
---- mc-4.6.1.orig/debian/rocks
-+++ mc-4.6.1/debian/rocks
-@@ -0,0 +1,45 @@
-+# custom tweaks to cbs' debian/rules
-+
-+DEB_CONFIGURE_EXTRA_FLAGS := --with-glib2 --without-ext2undel \
-+ --enable-charset --with-samba --with-screen=slang
-+
-+deb-extra-clean::
-+ rm -f config.sub config.guess
-+ rm -f po/ru.gmo
-+
-+deb-binary-hook-mc:
-+ cp debian/extra/icon.xpm debian/mc/usr/share/pixmaps/mc.xpm
-+
-+ cp debian/extra/mcview-debian debian/mc/usr/bin/
-+ cp debian/extra/mcedit-debian debian/mc/usr/bin/
-+
-+ chmod a+x debian/mc/usr/share/mc/edit.spell.rc
-+ chmod a+x debian/mc/usr/share/mc/edit.indent.rc
-+ chmod a-x debian/mc/usr/share/mc/bin/*
-+
-+ -mv debian/mc/usr/share/mc/mc.ext debian/mc/etc/mc/mc.ext
-+ -mv debian/mc/usr/share/mc/mc.menu debian/mc/etc/mc/mc.menu
-+ -mv debian/mc/usr/share/mc/mc.lib debian/mc/etc/mc/mc.lib
-+
-+ # convert docs to UTF8
-+ cd debian/mc/usr/share/mc && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hint > tmp && mv tmp mc.hint && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hlp > tmp && mv tmp mc.hlp && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hint.es > tmp && mv tmp mc.hint.es && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hlp.es > tmp && mv tmp mc.hlp.es && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hint.it > tmp && mv tmp mc.hint.it && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hlp.it > tmp && mv tmp mc.hlp.it && \
-+ iconv -f ISO-8859-1 -t UTF-8 mc.hint.nl > tmp && mv tmp mc.hint.nl && \
-+ iconv -f ISO-8859-2 -t UTF-8 mc.hint.cs > tmp && mv tmp mc.hint.cs && \
-+ iconv -f ISO-8859-2 -t UTF-8 mc.hint.hu > tmp && mv tmp mc.hint.hu && \
-+ iconv -f ISO-8859-2 -t UTF-8 mc.hlp.hu > tmp && mv tmp mc.hlp.hu && \
-+ iconv -f ISO-8859-2 -t UTF-8 mc.hint.pl > tmp && mv tmp mc.hint.pl && \
-+ iconv -f ISO-8859-2 -t UTF-8 mc.hlp.pl > tmp && mv tmp mc.hlp.pl && \
-+ iconv -f ISO-8859-5 -t UTF-8 mc.hint.sr > tmp && mv tmp mc.hint.sr && \
-+ iconv -f ISO-8859-5 -t UTF-8 mc.hlp.sr > tmp && mv tmp mc.hlp.sr && \
-+ iconv -f ISO-8859-5 -t UTF-8 mc.menu.sr > tmp && mv tmp mc.menu.sr && \
-+ iconv -f koi8-r -t UTF-8 mc.hint.ru > tmp && mv tmp mc.hint.ru && \
-+ iconv -f koi8-r -t UTF-8 mc.hlp.ru > tmp && mv tmp mc.hlp.ru && \
-+ iconv -f koi8-u -t UTF-8 mc.hint.uk > tmp && mv tmp mc.hint.uk && \
-+ iconv -f big5 -t UTF-8 mc.hint.zh > tmp && mv tmp mc.hint.zh
-+
---- mc-4.6.1.orig/debian/rules
-+++ mc-4.6.1/debian/rules
-@@ -0,0 +1,551 @@
-+#!/usr/bin/make -f
-+# -*- mode: makefile; coding: utf-8 -*-
-+# Colin's Build System
-+# Copyright © 2002 Colin Walters
-+# $Id: rules,v 1.3 2005/10/16 15:03:43 ldrolez Exp $
-+
-+####################################
-+# DO NOT MODIFY THIS FILE DIRECTLY #
-+####################################
-+
-+### Introduction to Colin's Build System #############################
-+# This file is shared between all the packages which use Colin's Build
-+# System. The idea is that this file contains sane defaults, and
-+# stuff specific to a package should go into the debian/rocks Makefile
-+# fragment. There generic hooks where you can override and add
-+# functionality for a specific package.
-+
-+# The big motivating factor for CBS was originally that more and more
-+# programs today are created using GNU configure scripts and GNU
-+# automake, and as such they are all very similar to configure and
-+# build. CBS takes advantage of this by doing stuff like looking for
-+# an executable file named "configure"; if it exists, CBS tries
-+# treating it like a GNU configure script, and passes it sane
-+# arguments (like --prefix=/usr). This will work for like 90% of the
-+# cases out there (including at least all my packages). But if it
-+# doesn't work, no problem; you can customize or just completely
-+# override it the debian/rocks file. For example, suppose that you
-+# need to pass "--enable-foo" to the configure script. In that case,
-+# all you need to do is create a file named debian/rocks, which
-+# contains:
-+
-+# DEB_CONFIGURE_EXTRA_FLAGS := --enable-foo
-+
-+# And that's it! Everything else happens automagically. However,
-+# suppose that your "configure" script isn't made by autoconf, and
-+# instead expects the user to interactively configure the program
-+# (e.g. Perl). In that case, you can just override the
-+# "deb-common-configure" rule, by putting something like the following
-+# in your debian/rocks:
-+
-+# deb-common-configure:
-+# ./configure --blah --blargh < debian/answers
-+
-+# All of the rules which are overridable are listed below, up to the
-+# line "-include debian/rocks". There are also a large group of
-+# variables you may customize to affect a default rule, instead of of
-+# just overriding the rule completely.
-+
-+# CBS also helps you keep up-to-date with the latest policy; when
-+# there is a new DEB_BUILD_OPTIONS entry, or they change semantics (as
-+# in the latest "debug" => "noopt" change), you shouldn't have to
-+# change anything in your packages (besides rebuilding them with the
-+# latest CBS version); CBS will just handle it.
-+
-+### CBS and Debhelper ################################################
-+# Colin's Build System currently relies heavily on debhelper version
-+# 4, so you must have a Build-Depends: debhelper (>= 4.0.0).
-+
-+### Single vs. Multi Binary packages #################################
-+# If you have a single binary package, CBS tries to use the upstream
-+# Makefile to install everything into debian/packagename, so it will
-+# all appear in the binary package. To remove files, move them
-+# around, just override the deb-binary-hook- target in
-+# the debian/rocks file, like:
-+
-+# deb-binary-hook-mypackage:
-+# mv debian/mypackage/usr/sbin/myprogram debian/mypackage/usr/bin/myprogram
-+# rm debian/mypackage/usr/share/doc/mypackage/INSTALL
-+
-+# If you have a multi-binary package, CBS (by default) uses the
-+# upstream Makefile to install everything in debian/tmp. After this,
-+# the recommended method is to use dh_install to copy these files into
-+# the appropriate package. To do this, just create
-+# "packagename.install" files; see the dh_install man page.
-+
-+### Common Problems ##################################################
-+
-+# Are you having problems with your package not building with the
-+# default deb-common-build rule? This could be because of CFLAGS
-+# issues. If it doesn't work, then your upstream's build system is
-+# broken. You should be able to set CFLAGS to contain the
-+# optimization and debugging settings you want, and this shouldn't
-+# frob any -I or other internal arguments the upstream build system
-+# needs. One way to fix this is to have upstream fix their Makefile
-+# to do something like:
-+
-+# # This is the default set of optimization and debugging flags, which
-+# # can be overridden with a CFLAGS passed to the make invocation.
-+# CFLAGS = -g -O2
-+# # Now add specific stuff we need.
-+# override CFLAGS += -I. -I.. -ffrob-stuff
-+
-+# On a related note, if you want to have a nice, easy-to-maintain,
-+# working build system, try to convince your upstream to switch to
-+# automake, autoconf, and libtool.
-+
-+### The latest version of CBS ########################################
-+# The canonical source for Colin's Build System is:
-+# http://cvs.verbum.org/debian/rules
-+
-+# Note that you can easily update your current version by running:
-+# debian/rules update
-+
-+# Are you keeping your Debian packages in CVS? In that case, it would
-+# probably be a good idea to disable keyword expansion for this file,
-+# so debian/rules update won't get confused. Run:
-+# cvs admin -ko debian/rules
-+
-+### Hooks which are overridable ######################################
-+
-+## This target is called before almost anything else; in particular,
-+## it is called even before patches are applied. This is a good place
-+## to do stuff like generate a debian/control from debian/control.xml,
-+## etc.
-+deb-pre-build:
-+ if [ -x $(CURDIR)/autogen.sh ]; then \
-+ $(CURDIR)/autogen.sh || echo -n "Failed to run autogen.sh script"; \
-+ fi
-+
-+## This target is called after patches are applied, but before
-+## configure scripts or anything else are run. This is a good place
-+## to do wacky stuff like:
-+## 'find . -name 'Makefile.in' -exec touch {} \;'.
-+deb-post-patches:
-+ # Nothing to do by default.
-+
-+## This target is called after patches are applied (i.e. after
-+## deb-post-patches). It is, as its name implies, a good place to run
-+## GNU configure scripts or the like.
-+deb-common-configure:
-+ if [ -x ./configure ]; then $(DEB_CONFIGURE_INVOKE) --prefix=$(DEB_CONFIGURE_PREFIX) --mandir=$(DEB_CONFIGURE_MANDIR) --infodir=$(DEB_CONFIGURE_INFODIR) --sysconfdir=$(DEB_CONFIGURE_SYSCONFDIR) --localstatedir=$(DEB_CONFIGURE_LOCALSTATEDIR) --libexecdir=$(DEB_CONFIGURE_LIBEXECDIR) --disable-maintainer-mode $(DEB_CONFIGURE_EXTRA_FLAGS) $(DEB_USER_CONFIGURE_FLAGS); fi
-+
-+## This target is for configuring a specific package. It is called
-+## once for each package.
-+deb-configure-%:
-+ # Nothing to do by default.
-+
-+## This is an "extra" rule, where you may prefix arbitrary commands to
-+## the general build, but not override the default. It is called
-+## before deb-common-build.
-+deb-extra-pre-common-build::
-+ # Nothing to do by default.
-+
-+## This target is called after common configuration (but not
-+## necessarily after package-specific configuration). Generally, this
-+## is a good place to invoke make and the like. Note that if you do
-+## package-specific configuration, you should likely override this
-+## rule to do nothing, and then do package-specific building in
-+## deb-build-.
-+deb-common-build:
-+ if [ -f Makefile ]; then \
-+ $(DEB_MAKE_ENVVARS) $(MAKE) CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" $(DEB_BUILD_MAKE_TARGET); \
-+ fi
-+
-+## This is an "extra" rule, where you may add arbitrary commands to
-+## the general build, but not override the default. It is called
-+## after deb-common-build.
-+deb-extra-common-build:: deb-common-build
-+ # Nothing to do by default.
-+
-+## This target is called once for each package, after package-specific
-+## configuration; it is for doing any building to a specific package.
-+deb-build-%:
-+ # Nothing to do by default.
-+
-+## This is an "extra" rule, where you may add arbitrary commands to
-+## the package-specific build, but not override the default. It is
-+## called after deb-build-.
-+deb-extra-build-%: deb-build-%
-+ # Nothing to do by default.
-+
-+## This target is called after pre-build, and before any configuration
-+## takes place. It is designed to automatically update
-+## config.{sub,guess} files which are used by packages which use GNU
-+## autoconf. You should not generally need to override this target.
-+## You may need to set DEB_AC_AUX_DIR if upstream used the autoconf
-+## macro AC_CONFIG_AUX_DIR.
-+deb-autotools-setup:
-+ if [ -r /usr/share/misc/config.sub ]; then \
-+ if [ -r $(DEB_AC_AUX_DIR)/config.sub -a ! -f $(DEB_AC_AUX_DIR)/config.sub.orig-cbs ]; then \
-+ mv $(DEB_AC_AUX_DIR)/config.sub $(DEB_AC_AUX_DIR)/config.sub.orig-cbs; \
-+ cp -f /usr/share/misc/config.sub $(DEB_AC_AUX_DIR)/config.sub; \
-+ fi; \
-+ fi
-+ if [ -r /usr/share/misc/config.guess ]; then \
-+ if [ -r $(DEB_AC_AUX_DIR)/config.guess -a ! -f $(DEB_AC_AUX_DIR)/config.guess.orig-cbs ]; then \
-+ mv $(DEB_AC_AUX_DIR)/config.guess $(DEB_AC_AUX_DIR)/config.guess.orig-cbs; \
-+ cp -f /usr/share/misc/config.guess $(DEB_AC_AUX_DIR)/config.guess; \
-+ fi; \
-+ fi
-+
-+## This target is called during the clean process; it is designed to
-+## undo the effects of deb-autotools-setup, so that you won't get
-+## spurious bits in your Debian diff. You should not generally need
-+## to override this target.
-+deb-autotools-clean:
-+ if [ -r $(DEB_AC_AUX_DIR)/config.sub.orig-cbs ]; then \
-+ mv $(DEB_AC_AUX_DIR)/config.sub.orig-cbs $(DEB_AC_AUX_DIR)/config.sub; \
-+ fi
-+ if [ -r $(DEB_AC_AUX_DIR)/config.guess.orig-cbs ]; then \
-+ mv $(DEB_AC_AUX_DIR)/config.guess.orig-cbs $(DEB_AC_AUX_DIR)/config.guess; \
-+ fi
-+
-+## This target is called during the cleaning process.
-+deb-clean:
-+ if [ -f Makefile ]; then $(MAKE) distclean || $(MAKE) clean || true; fi
-+ if test -f config.log; then \
-+ if grep -i -q 'generated by GNU Autoconf' config.log || grep -i -q 'to aid debugging if configure ' config.log; then \
-+ rm -f config.log; \
-+ fi; \
-+ fi
-+ if test -f config.status && grep -i -q 'Generated.*by configure.' config.status; then rm -f config.status; fi
-+ if test -f config.cache && grep -i -q 'shell.*script.*caches.*results.*configure' config.cache; then rm -f config.cache; fi
-+ rm -f po/it.gmo po/de.gmo
-+
-+## This is an "extra" rule, where you may add arbitrary commands to
-+## the cleaning process, but not override the default.
-+deb-extra-clean:: deb-clean
-+ # Nothing to do by default.
-+
-+## This target is called after the common installation step. It
-+## should install your package into its destination, e.g. debian/tmp
-+## (for single-binary packages, into debian/).
-+deb-common-install:
-+ if [ -f Makefile ]; then \
-+ if grep -q DESTDIR Makefile || grep -q -i 'generated.*by.*automake' Makefile; then \
-+ $(DEB_MAKE_ENVVARS) $(MAKE) install DESTDIR=$(DEB_DESTDIR); \
-+ else \
-+ echo "This Makefile doesn't appear to support DESTDIR; you must override $@ in debian/rocks"; \
-+ exit 1; \
-+ fi; \
-+ else \
-+ echo "No default install action, you must override $@ in debian/rocks"; \
-+ exit 1; \
-+ fi
-+
-+## This is an "extra" rule, where you may add arbitrary commands to
-+## the common installation process, but not override the default.
-+deb-extra-common-install:: deb-common-install
-+ # Nothing to do by default.
-+
-+## This target is called once for each package, after that package's
-+## specific build step.
-+deb-install-%:
-+ # Nothing to do by default.
-+
-+## This is an "extra" rule, where you may add arbitrary commands to
-+## the installation process for a specific package, but not override
-+## the default.
-+deb-extra-install-%: deb-install-%
-+ # Nothing to do by default.
-+
-+## This is a sort of "catchall" rule to do post-installation cleanup.
-+## It is called by deb-binary- after everything should be
-+## installed in debian/tmp or debian/. This is a good
-+## place to do things like move binaries from debian/tmp/usr/bin to
-+## debian/tmp/usr/sbin, convert HTML documentation into plain text,
-+## etc.
-+deb-binary-hook-%:
-+ # Nothing to do by default.
-+
-+## This rule is called after the installation for a package. It does
-+## all the work of installing things like changelogs, README.Debian
-+## files, etc., and also actually builds the .deb files. It relies
-+## heavily on Debhelper, so please see the docs for those commands to
-+## understand how it works and to customize things more. You may
-+## override this target if you have special needs, but it is not
-+## recommended. It is better instead to use one of the provided
-+## hooks, or add a hook where necessary and send in a patch for CBS.
-+deb-binary-%:
-+ dh_installdocs $(DEB_ALL_DOCS) $(DEB_INSTALL_DOCS_$(DEB_CURPACKAGE)) -p$(DEB_CURPACKAGE)
-+ dh_installexamples $(DEB_INSTALL_EXAMPLES_$(DEB_CURPACKAGE)) -p$(DEB_CURPACKAGE)
-+ dh_installman $(DEB_INSTALL_MANPAGES_$(DEB_CURPACKAGE)) -p$(DEB_CURPACKAGE)
-+ dh_installinfo $(DEB_INSTALL_INFO_$(DEB_CURPACKAGE)) -p$(DEB_CURPACKAGE)
-+ dh_installmenu -p$(DEB_CURPACKAGE)
-+ dh_installcron -p$(DEB_CURPACKAGE)
-+ dh_installdebconf -p$(DEB_CURPACKAGE)
-+ dh_installpam -p$(DEB_CURPACKAGE)
-+ dh_installchangelogs -p$(DEB_CURPACKAGE)
-+ dh_install -p$(DEB_CURPACKAGE)
-+ $(internal_invoke) deb-binary-hook-$(DEB_CURPACKAGE)
-+ $(internal_invoke) deb-strip-$(DEB_CURPACKAGE)
-+ dh_link -p$(DEB_CURPACKAGE)
-+ dh_compress -p$(DEB_CURPACKAGE) $(foreach entry,$(DEB_COMPRESS_EXCLUDE),$(patsubst %,-X %,$(entry))) \
-+ $(foreach entry,$(DEB_COMPRESS_EXCLUDE_$(DEB_CURPACKAGE)),$(patsubst %,-X %,$(entry)))
-+ dh_fixperms -p$(DEB_CURPACKAGE) $(foreach entry,$(DEB_FIXPERMS_EXCLUDE),$(patsubst %,-X %,$(entry))) \
-+ $(foreach entry,$(DEB_FIXPERMS_EXCLUDE_$(DEB_CURPACKAGE)),$(patsubst %,-X %,$(entry)))
-+ $(internal_invoke) deb-makeshlibs-$(DEB_CURPACKAGE)
-+ $(internal_invoke) deb-post-fixperms-binary-$(DEB_CURPACKAGE)
-+ dh_installdeb -p$(DEB_CURPACKAGE)
-+ $(internal_invoke) deb-shlibdeps-$(DEB_CURPACKAGE)
-+ dh_gencontrol -p$(DEB_CURPACKAGE)
-+ dh_md5sums -p$(DEB_CURPACKAGE)
-+ dh_builddeb -p$(DEB_CURPACKAGE)
-+
-+## This rule is called by the default deb-binary-
-+## implementation, after all package data has been installed, and
-+## after the deb-binary-hook- has been called. As its
-+## name implies, it is where you should strip binaries.
-+deb-strip-%:
-+ dh_strip -p$(DEB_CURPACKAGE)
-+
-+## This rule is called by the default deb-binary-
-+## implementation, *after* permissions have been sanitized. This is
-+## an excellent place to make binaries setuid where necessary, for
-+## example.
-+deb-post-fixperms-binary-%:
-+ # Nothing to do by default.
-+
-+## This rule is called by the default deb-binary-
-+## implementation, right before the final Debian package building
-+## process. This is where you should generate a "shlibs" file for
-+## your package, if necessary.
-+deb-makeshlibs-%:
-+ dh_makeshlibs -p$(DEB_CURPACKAGE)
-+
-+## This rule is called by the default deb-binary-
-+## implementation, during the final Debian package building
-+## process. This is where you should determine
-+deb-shlibdeps-%:
-+ dh_shlibdeps -p$(DEB_CURPACKAGE) $(if $(DEB_SHLIBDEPS_LIBRARY_$(DEB_CURPACKAGE)),-L $(DEB_SHLIBDEPS_LIBRARY_$(DEB_CURPACKAGE))) $(if $(DEB_SHLIBDEPS_INCLUDE_$(DEB_CURPACKAGE))$(DEB_SHLIBDEPS_INCLUDE),-l $(DEB_SHLIBDEPS_INCLUDE_$(DEB_CURPACKAGE)):$(DEB_SHLIBDEPS_INCLUDE))
-+
-+-include debian/rocks
-+
-+### Overridable variables #######################################
-+
-+# Some common variables; usually you shouldn't have to set these.
-+DEB_ARCH_PACKAGES ?= $(shell dh_listpackages -a 2>/dev/null || true)
-+DEB_INDEP_PACKAGES ?= $(shell dh_listpackages -i 2>/dev/null || true)
-+DEB_ALL_PACKAGES ?= $(DEB_ARCH_PACKAGES) $(DEB_INDEP_PACKAGES)
-+DEB_SOURCE_PACKAGE ?= $(strip $(shell egrep '^Source: ' debian/control | cut -f 2 -d ':'))
-+
-+export DH_COMPAT=4
-+
-+DEB_VERSION ?= $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ')
-+
-+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-+DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
-+DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
-+
-+DEB_C_DEFAULT_OPT ?= -O2
-+DEB_CXX_DEFAULT_OPT ?= $(DEB_C_DEFAULT_OPT)
-+CFLAGS ?= -Wall -g
-+CXXFLAGS ?= -Wall -g
-+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-+ CFLAGS += -O0
-+ CXXFLAGS += -O0
-+else
-+ CFLAGS += $(DEB_C_DEFAULT_OPT)
-+ CXXFLAGS += $(DEB_CXX_DEFAULT_OPT)
-+endif
-+
-+DEB_PATCHDIRS ?= debian/patches
-+DEB_PATCHES ?= $(foreach dir,$(DEB_PATCHDIRS),$(shell echo $(wildcard $(dir)/*.patch) $(wildcard $(dir)/*.diff)))
-+
-+DEB_CONFIGURE_INVOKE ?= ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE)
-+DEB_CONFIGURE_PREFIX ?=/usr
-+DEB_CONFIGURE_MANDIR ?="\$${prefix}/share/man"
-+DEB_CONFIGURE_INFODIR ?="\$${prefix}/share/info"
-+DEB_CONFIGURE_SYSCONFDIR ?=/etc
-+DEB_CONFIGURE_LOCALSTATEDIR ?=/var
-+DEB_CONFIGURE_LIBEXECDIR ?="\$${prefix}/lib/$(DEB_SOURCE_PACKAGE)"
-+DEB_CONFIGURE_EXTRA_FLAGS ?=
-+DEB_MAKE_ENVVARS ?=
-+DEB_BUILD_MAKE_TARGET ?=
-+DEB_DIRS ?=
-+DEB_CLEAN ?=
-+DEB_CLEAN_EXCLUDE ?=
-+DEB_ALL_DOCS ?=
-+DEB_KEEP_CHANGELOG_NAME ?=
-+DEB_ALL_CHANGELOG ?= $(if $(DEB_ISNATIVE),,$(shell if test -r ChangeLog; then echo ChangeLog; fi))
-+DEB_FIXPERMS_EXCLUDE ?=
-+DEB_COMPRESS_EXCLUDE ?=
-+# This variable should be a colon-separated list of paths
-+DEB_SHLIBDEPS_INCLUDE ?=
-+DEB_EXAMPLES ?=
-+DEB_CHANGELOGS ?=
-+DEB_AC_AUX_DIR ?=.
-+
-+DEB_PHONY_RULES ?=
-+
-+ifeq ($(strip $(shell echo $(DEB_ALL_PACKAGES) | wc -w)),1)
-+ DEB_DESTDIR ?= `pwd`/debian/$(strip $(DEB_ALL_PACKAGES))
-+else
-+ DEB_DESTDIR ?= `pwd`/debian/tmp
-+endif
-+
-+### Other variables ##################################################
-+
-+DEB_ISNATIVE := $(shell dpkg-parsechangelog | egrep '^Version:' | perl -ne 'print if not /^Version:\s*.*-/;')
-+
-+### Internal implementation ##########################################
-+update:
-+ @if [ -f debian/rules ]; then \
-+ curversion=`head debian/rules | perl -lne 'if (/Id: rules,v (.*?) /) { print $$1; }'`; \
-+ echo "Installed version: " $$curversion; \
-+ rm -rf debian/cbs-update ; mkdir -p debian/cbs-update && cd debian/cbs-update; \
-+ echo -n "Downloading latest version from :pserver:anoncvs@cvs.verbum.org:/cvs..."; \
-+ cvs -Q -d :pserver:anoncvs@cvs.verbum.org:/cvs co debian/rules; \
-+ echo "done."; \
-+ newversion=`head debian/rules | perl -lne 'if (/Id: rules,v (.*?) /) { print $$1; }'`; \
-+ if [ "$$newversion" != "$$curversion" ]; then \
-+ echo "Retrieving log for revisions $$curversion to $$newversion..."; \
-+ cvs -q -d :pserver:anoncvs@cvs.verbum.org:/cvs log "-r$$curversion:$$newversion" debian/rules; \
-+ else \
-+ echo "No changes."; \
-+ fi; \
-+ mv debian/rules .. ; cd .. ; rm -rf cbs-update ; chmod a+x rules; \
-+ else \
-+ echo "Couldn't find debian/rules; you must execute this target as debian/rules update"; \
-+ fi
-+
-+internal_invoke := debian/rules "DEB_ARCH_PACKAGES=$(DEB_ARCH_PACKAGES)" "DEB_INDEP_PACKAGES=$(DEB_INDEP_PACKAGES)" "DEB_ALL_PACKAGES=$(DEB_ALL_PACKAGES)" "DEB_VERSION=$(DEB_VERSION)" "DEB_HOST_GNU_TYPE=$(DEB_HOST_GNU_TYPE)" "DEB_BUILD_GNU_TYPE=$(DEB_BUILD_GNU_TYPE)" "DEB_DESTDIR=$(DEB_DESTDIR)" "DEB_PATCHES=$(DEB_PATCHES)"
-+
-+pre-build: debian/stamp-pre-build
-+debian/stamp-pre-build:
-+ $(internal_invoke) deb-pre-build
-+ touch $@
-+
-+# The patch subsystem
-+apply-patches: pre-build debian/stamp-patched
-+debian/stamp-patched: $(DEB_PATCHES)
-+debian/stamp-patched reverse-patches:
-+ @echo "patches: $(DEB_PATCHES)"
-+ @set -e ; \
-+ DPATCHES="$(DEB_PATCHES)"; \
-+ [ "$@" = "reverse-patches" ] && DPATCHES="`ls -r $(DEB_PATCHES)`"; \
-+ for patch in $$DPATCHES; do \
-+ level=$(head $$patch | egrep '^#DPATCHLEVEL=' | cut -f 2 -d '='); \
-+ reverse=""; \
-+ if [ "$@" = "reverse-patches" ]; then reverse="-R"; fi; \
-+ success=""; \
-+ if [ -z "$$level" ]; then \
-+ echo -n "Trying "; if test -n "$$reverse"; then echo -n "reversed "; fi; echo -n "patch $$patch at level "; \
-+ for level in 0 1 2; do \
-+ if test -z "$$success"; then \
-+ echo -n "$$level..."; \
-+ if cat $$patch | patch $$reverse --dry-run -p$$level --verbose 1>$$patch.level-$$level.log 2>&1; then \
-+ if cat $$patch | patch $$reverse --no-backup-if-mismatch -V never -p$$level 1>$$patch.level-$$level.log 2>&1; then \
-+ success=yes; \
-+ touch debian/stamp-patch-$$(basename $$patch); \
-+ echo "success."; \
-+ fi; \
-+ fi; \
-+ fi; \
-+ done; \
-+ if test -z "$$success"; then \
-+ if test -z "$$reverse"; then \
-+ echo "failure."; \
-+ exit 1; \
-+ else \
-+ echo "failure (ignored)."; \
-+ fi \
-+ fi; \
-+ else \
-+ echo -n "Trying patch $$patch at level $$level..."; \
-+ if cat $$patch | patch $$reverse --no-backup-if-mismatch -V never -p$$level 1>$$patch.log 2>&1; then \
-+ touch debian/stamp-patch-$$(basename $$patch); \
-+ echo "success."; \
-+ else \
-+ echo "failure:"; \
-+ cat $$patch.log; \
-+ if test -z "$$reverse"; then exit 1; fi; \
-+ fi; \
-+ fi; \
-+ done
-+ if [ "$@" = "debian/stamp-patched" ]; then touch debian/stamp-patched; fi
-+
-+post-patches: debian/stamp-post-patches
-+debian/stamp-post-patches: apply-patches
-+ $(internal_invoke) deb-post-patches
-+ touch $@
-+
-+# The general targets
-+common-configure: post-patches debian/stamp-common-configure
-+debian/stamp-common-configure:
-+ dh_testdir
-+ $(internal_invoke) deb-autotools-setup
-+ $(internal_invoke) deb-common-configure
-+ touch $@
-+$(patsubst %,configure-%,$(DEB_ALL_PACKAGES)) : configure-% : common-configure debian/stamp-configure-%
-+$(patsubst %,debian/stamp-configure-%,$(DEB_ALL_PACKAGES)) : debian/stamp-configure-%: debian/stamp-patched
-+ dh_testdir
-+ $(internal_invoke) deb-configure-package-$(patsubst debian/stamp-configure-%,%,$@) DEB_CURPACKAGE=$(patsubst debian/stamp-configure-%,%,$@)
-+ touch $@
-+
-+# Required Debian target
-+build: build-arch build-indep
-+
-+common-build: debian/stamp-common-build
-+debian/stamp-common-build: $(patsubst %,configure-%,$(DEB_ALL_PACKAGES))
-+ dh_testdir
-+ $(internal_invoke) deb-extra-pre-common-build
-+ $(internal_invoke) deb-extra-common-build
-+ touch $@
-+$(patsubst %,build-%,$(DEB_ALL_PACKAGES)) :: build-% : debian/stamp-build-%
-+$(patsubst %,debian/stamp-build-%,$(DEB_ALL_PACKAGES)) : debian/stamp-build-% : common-build configure-%
-+ dh_testdir
-+ $(internal_invoke) deb-extra-build-$(patsubst debian/stamp-build-%,%,$@) DEB_CURPACKAGE=$(patsubst debian/stamp-build-%,%,$@)
-+ touch $@
-+
-+build-arch: $(patsubst %,build-%,$(DEB_ARCH_PACKAGES))
-+build-indep: $(patsubst %,build-%,$(DEB_INDEP_PACKAGES))
-+
-+# Required Debian target
-+clean: clean-dh-tests reverse-patches clean-impl
-+clean-dh-tests:
-+ dh_testdir
-+ dh_testroot
-+clean-impl:
-+ $(internal_invoke) deb-autotools-clean
-+ $(internal_invoke) deb-extra-clean
-+ for dir in $(DEB_PATCHDIRS); do rm -f $$dir/*.log; done
-+ rm -f debian/stamp-*
-+ dh_clean $(DEB_CLEAN) $(foreach entry,$(DEB_CLEAN_EXCLUDE),$(patsubst %,-X %,$(entry)))
-+
-+common-install: debian/stamp-common-install
-+debian/stamp-common-install: $(patsubst %,build-%,$(DEB_ALL_PACKAGES))
-+ dh_testdir
-+ dh_clean -k
-+ dh_installdirs -A $(DEB_DIRS)
-+ $(internal_invoke) deb-extra-common-install DEB_CURPACKAGE=
-+ touch $@
-+install-arch: $(patsubst %,install-%,$(DEB_ARCH_PACKAGES))
-+install-indep: $(patsubst %,install-%,$(DEB_INDEP_PACKAGES))
-+$(patsubst %,install-%,$(DEB_ALL_PACKAGES)) :: install-% : common-install build-%
-+ dh_testdir
-+ dh_testroot
-+ $(internal_invoke) deb-extra-install-$(patsubst install-%,%,$@) DEB_CURPACKAGE=$(patsubst install-%,%,$@)
-+
-+common-binary: debian/stamp-common-binary
-+debian/stamp-common-binary: $(patsubst %,install-%,$(DEB_ALL_PACKAGES)) common-install
-+ dh_testdir
-+ dh_testroot
-+ dh_installchangelogs $(if $(DEB_KEEP_CHANGELOG_NAME),-k) $(DEB_ALL_CHANGELOG)
-+ touch $@
-+
-+# Required Debian targets
-+binary-indep: common-binary $(patsubst %,binary-%,$(DEB_INDEP_PACKAGES))
-+binary-arch: common-binary $(patsubst %,binary-%,$(DEB_ARCH_PACKAGES))
-+
-+binary-% :: common-binary install-%
-+ dh_testdir
-+ dh_testroot
-+ $(internal_invoke) deb-binary-$(patsubst binary-%,%,$@) DEB_CURPACKAGE=$(patsubst binary-%,%,$@)
-+
-+# Required Debian target
-+binary: binary-indep binary-arch
-+
-+.PHONY: pre-build apply-patches reverse-patches post-patches common-configure build common-build build-% build-arch build-indep clean clean-dh-tests clean-impl common-install install-arch install-indep install-% common-binary binary-% binary-indep binary-arch binary deb-common-configure deb-common-build deb-clean deb-common-install deb-strip deb-makeshlibs $(DEB_PHONY_RULES)
---- mc-4.6.1.orig/debian/watch
-+++ mc-4.6.1/debian/watch
-@@ -0,0 +1,2 @@
-+version=2
-+http://pavelsh.pp.ru/mc/ mc-([0-9\-\.pre]+).tar.gz debian uupdate
---- mc-4.6.1.orig/debian/changelog
-+++ mc-4.6.1/debian/changelog
-@@ -0,0 +1,985 @@
-+mc (1:4.6.1-7) unstable; urgency=medium
-+
-+ * Fixed Anton Pak's recode patch which can cause a segfault.
-+ Closes: #382206, #382857, #400927
-+ * Mode display bug fixed. Patch added to 50_utf8-more.patch. Closes: #415097
-+ * Shift-Enter bug fixed. The line editing widget went crazy when seeing a litteral newline
-+ (Shift+enter or Ctrl-q+enter). Patch added to 50_utf8-more.patch
-+ Downloaded from https://svn.uhulinux.hu/packages/dev/mc/patches/
-+
-+ -- Ludovic Drolez Mon, 2 Apr 2007 8:44:35 +0200
-+
-+mc (1:4.6.1-6) unstable; urgency=medium
-+
-+ * debian/rules modified to fix a FTBFS during the 2nd build. Closes: #384302
-+ * added 05_symcrash.patch to fix a segfault (should be in mc's CVS). Closes: #383341
-+ * mpg123 title view fixed. Closes: #391644
-+
-+ -- Ludovic Drolez Thu, 24 Aug 2006 22:19:03 +0200
-+
-+mc (1:4.6.1-5) unstable; urgency=low
-+
-+ * Removed the Ctrl-t accelerator from 60_recode.patch. Closes: #380417
-+ * Modified 47_mc.menu.patch to use 'editor' instead of the hardcoded 'vi'
-+ so that mc makes use of /etc/alternatives. Closes: #373144
-+ * .tar view fixed in 01_mc.ext.in.mime.patch. Closes: #381353
-+ * still 68 bugs in the BTS...
-+
-+ -- Ludovic Drolez Mon, 31 Jul 2006 22:25:47 +0200
-+
-+mc (1:4.6.1-4) unstable; urgency=medium
-+
-+ * added 52_utf8-8bits-slang2.patch. Closes: #359016, #378786
-+ * added 55_mc-utf8-look-and-feel.patch : nicer look and feel
-+ * added 60_recode.patch : a patch to choose the charset from mc
-+ * 77 bugs should still remain after this upload... If you have some time please join
-+ the Debian MC team.
-+
-+ -- Ludovic Drolez Thu, 12 Jul 2006 20:00:00 +0200
-+
-+mc (1:4.6.1-3) unstable; urgency=low
-+
-+ * Changelog removed. Closes: #317707
-+ * Lowered the alternative priority on 'view' and 'edit'. Closes: #367991
-+ * Patched the UTF8 patch to allow compiling mc without UTF8. Closes: #367187
-+ * html files can be opened with links, w3m or lynx. Closes: #332910
-+ * added 04_off64t.patch to fix problems with tar archives
-+ larger than 2GB. Already added in mc's CVS. Closes: #324755
-+ * in 50_utf8-more.patch added a small patch for a problem in the status
-+ line with UTF-8 locales. Closes: #360427
-+ * 78 bugs should still remain after this upload...
-+
-+ -- Ludovic Drolez Thu, 22 Jun 2006 16:55:12 +0200
-+
-+mc (1:4.6.1-2) unstable; urgency=medium
-+
-+ * mc with UTF-8 support upload. Closes: #354691, #309398, #126077, #242194
-+ * added Ubuntu UTF-8 patches: 48_utf8-slang2.patch
-+ Many thanks to Leonard den Ottolander and Sebastian Droge
-+ * removed 27_menu-generation.patch because of UTF-8 problems
-+ * convert help and hint files to UTF-8 in the Debian makefile
-+ * 49_64bit.patch: patch to solve some 64bit problems from Gentoo
-+ * use arj instead of unarj. Closes: #340089
-+
-+ -- Ludovic Drolez Mon, 20 Mar 2006 23:41:40 +0200
-+
-+mc (1:4.6.1-1) unstable; urgency=low
-+
-+ * New upstream release. Closes: #321805, #298345
-+ getgrouplist() is not used anymore. Closes: #313401
-+ * View jpegs with /usr/bin/exif. Closes: #207655
-+ * Handle .ipk like .tgz. Closes: #323927
-+ * Filter for .mo files. Closes: #318077
-+ * Obsolete patches: 07_mc-tar-name-length-fix.patch,
-+ 24_mc-complete-show-all-fix.patch, 33_mc-iconv-error.patch.
-+ * 79 bugs should still remain after this upload...
-+
-+ -- Ludovic Drolez Mon, 5 Sep 2005 22:02:24 +0200
-+
-+mc (1:4.6.0-4.6.1-pre4-2) unstable; urgency=low
-+
-+ * Build against libslang2-dev. Closes: #315241
-+ * Added 07_mc-tar-name-length-fix.patch. Closes: #315597
-+ * Modified 35_mc.ext.in.patch to improve to deb vfs view. Closes: #198691
-+ * Added 09_de.po.patch to fix some typos in mc's de.po. Closes: #313796, #309957
-+ * Combined 35_mc.ext.in.patch, 04_dpkg_and_apt_vfs.patch, 01_mime.patch,
-+ 41_antiword_mc.ext.patch
-+ to 01_mc.ext.in.mime.patch to fix build problems.
-+
-+ -- Ludovic Drolez Tue, 21 Jun 2005 20:01:31 +0200
-+
-+mc (1:4.6.0-4.6.1-pre4-1) unstable; urgency=low
-+
-+ * New upstream release. Closes: #309630
-+ 20_german_translation.patch, 23_php.singlequote_fix.patch,
-+ 30_mc-spaceprompt1.patch, 43_AUTHORS.patch, 32_lang-with-env.patch removed
-+ * Build with debian slang1-dev
-+ * Do not remove /etc/mc/mc.ini. Closes: #198954
-+
-+ -- Ludovic Drolez Wed, 18 May 2005 23:15:05 +0200
-+
-+mc (1:4.6.0-4.6.1-pre3-3) unstable; urgency=medium
-+
-+ * urgency=medium because of 3 important bugs introduced by the last upload.
-+ * removed 46_dotdotdir.patch to fix the tar bug. Closes: #308546
-+ * replaced the iconv patch, 33_mc-iconv-error.patch, with a new
-+ one provided by Roland Illig. Closes: #308296
-+ * added cxx.syntax by copying the old c.syntax to it. Closes: #308794
-+ * removed the useless 44_str_unconst.patch.
-+
-+ -- Ludovic Drolez Wed, 11 May 2005 22:57:44 +0200
-+
-+mc (1:4.6.0-4.6.1-pre3-2) unstable; urgency=medium
-+
-+ * Urgency set to medium because of LOTS of annoying bugs fixed and
-+ the segfault in mcedit.
-+ * Fixed German po translation with upstream, 20_german_translation.patch.
-+ Closes: #253869
-+ * Added Antiword to view .doc files, 41_antiword_mc.ext.patch
-+ Closes: #305649
-+ * Added menu entry for Debian source packages, 47_mc.menu.diff
-+ Closes: #307344
-+ * Fixed Samba enabling. Closes: #264890
-+ * Fixed Build-Depend on libgpm for GNU/non-Linux. Closes: #226987
-+ * Added colored syntax for man pages by Michelle Konzack,
-+ 13_syntax.patch. Closes: #298322
-+ * Improved shell syntax highlighting by Michelle Konzack: 18_sh_syntax.patch.
-+ Closes: #299210
-+ * Improved php syntax HL with 23_php.singlequote_fix.patch
-+ * Fixed colored syntax highlighting and hostname in the title bar,
-+ 22_main.c.patch
-+ * Fixed tar file system glitch for "tar -cvzlf file.tgz / /home/"
-+ Closes: #89350
-+ * Fixed problems with View and Edit when used with LANG=hu_HU. Closes: #103242
-+ * Fixed unprintable control sequences in PS1 cause broken prompt
-+ Closes: #83447
-+ * Fixed: mcedit: subshell changes directory. Closes: #208867
-+ * Fixed the #utar archive content viewer missing files. Closes: #228934
-+ * Enabled charset conversion feature. Closes: #109956, #167986
-+ * Added new keybinding by Vitja Makarov with 42_keybindings-0.2.2.patch
-+ * Added const_cast to be replaced by str_unconst, 44_str_unconst.patch
-+ by Roland Illig.
-+ * Improved symlink handling in ftpfs (45_ftpfs_symlink*.patch) by P.Tsekov.
-+ * Parent directory's patch by Leonard den Ottolander with 46_dotdotdir.patch
-+ * Fixed user@hostname in the term emulation title bar.
-+ * Added new menu generation patch by Roland Illig
-+ with 27_menu-generation.patch
-+ * Fixed: possible data loss when quota exedeed by Jindrich Novy.
-+ * Fixed uarj bug from Savannah with 29_uarj_bug.patch (Savannah #12406).
-+ * Added patch to view inside udebs by Mantas Kriauciunas, 35_mc.ext.in.patch
-+ (Sannavah #3899)
-+ * Added "space on prompt bugfix" by Jindrich Novy with
-+ 30_mc-spaceprompt1.patch. Closes: #305859
-+ * Added Bad error checking after iconv() call patch by Jindrich Novy with
-+ 33_mc-iconv-error.patch
-+ * Added syntax patches for c vs. cxx with 32_c-vs-cxx.patch
-+ * Added syntax patches for scripts starting with /usr/bin/env with
-+ 32_lang-with-env.patch
-+ * Added a substitute for --enable-maintainer-mode with 36_developer_mode.patch
-+ by Roland Illig.
-+ * Fixed mc core dumps when not find "context default" section in syntax section
-+ with 37_mcedit-segv.patch by Ian Zagorskih.
-+ * Added the ext2 quote fixing hunks by Leonard den Ottolander.
-+ * Added AUTHORS patch, 43_AUTHORS.patch, by Leonard den Ottolander.
-+ * Added mcedit position remember bugfix by Christian Hamar with
-+ 31_mc_filepos_bugfix_461pre4a.patch
-+ * Added fix for End key in viewer by Jindrich Makovicka with 40_view.c.patch
-+ * Added Vietnamese translation with 26_vietnamese_po.patch
-+ * Fixed 11_extfs_missing.patch because of problems with .jar files.
-+ Closes: #299932.
-+ * added zip, unzip, bzip2 to 'Suggests'.
-+
-+ -- Ludovic Drolez Sun, 6 Mar 2005 12:06:32 +0100
-+
-+mc (1:4.6.0-4.6.1-pre3-1) unstable; urgency=high
-+
-+ * New maintainers: Stefano Melchior and Ludovic Drolez (closes: #282301).
-+ * Urgency set to high because of security bug fixes.
-+ * Missing quoting in ext2 and i18n fix.
-+ * Samba lib warning (netmask.c) fixed by 12_netmask_c.patch.
-+ * Security upload to handle DSA 639 (references: CAN-2004-1004,
-+ CAN-2004-1005, CAN-2004-1009, CAN-2004-1090, CAN-2004-1091, CAN-2004-1092,
-+ CAN-2004-1093, CAN-2004-1174, CAN-2004-1175, CAN-2004-1176),
-+ Fixed upstream in the pre3 release (Closes: #295261).
-+ * Pre3 release includes fix for CAN-2004-0226 (closes: #286395).
-+ * Fixed ftp filesystem impossibility to list dirs when password contains #
-+ (closes: #92121).
-+ * Fixed subshell impossibility to be started (closes: #241891).
-+ * Fixed CAN-2004-0494 (closes: #267596).
-+ * Fixed buffer overflow and format string vulnerabilities (closes: #295259).
-+ * Italian hotkey translation changed (closes: #231071).
-+ * New upstream pre-release.
-+
-+ -- Ludovic Drolez Mon, 17 Feb 2005 22:45:32 +0100
-+
-+mc (1:4.6.0-4.6.1-pre1-3) unstable; urgency=low
-+
-+ * Polish documentation fix no longer needed.
-+
-+ -- Adam Byrtek Wed, 5 May 2004 00:08:26 +0200
-+
-+mc (1:4.6.0-4.6.1-pre1-2) unstable; urgency=high
-+
-+ * Security upload to handle DSA-497-1 (references: CAN-2004-0226,
-+ CAN-2004-0231, CAN-2004-0232). Patch by Jakub Jelinek ported to
-+ 4.6.1-pre1 by Adam Byrtek.
-+
-+ -- Adam Byrtek Tue, 4 May 2004 09:28:26 +0200
-+
-+mc (1:4.6.0-4.6.1-pre1-1) unstable; urgency=high
-+
-+ * Security upload to fix buffer overflow, 4.6.1 final will be there
-+ soon (closes: #226737).
-+ * --without-x configure flag removed as mc now libX11 is loaded
-+ dynamically using gmodule, if possible.
-+
-+ -- Adam Byrtek Thu, 15 Jan 2004 15:55:52 +0100
-+
-+mc (1:4.6.0-5) unstable; urgency=low
-+
-+ * Fix segfault when TERM is unset (closes: #191867).
-+ * Removed conflict with gmc, which works with 4.6.0. Note that gmc
-+ installation still requires some --force (closes: #192493).
-+ * Files in /var/log are no longer treated as manpages
-+ (closes: #179350).
-+
-+ -- Adam Byrtek Tue, 17 Jun 2003 15:37:05 +0200
-+
-+mc (1:4.6.0-4) unstable; urgency=low
-+
-+ * Standard `awk' detected first by configure, not the specific
-+ implmentation (closes: #181972).
-+ * Polish translation breakage fixed (closes: #183275).
-+
-+ -- Adam Byrtek Wed, 19 Mar 2003 22:17:16 +0100
-+
-+mc (1:4.6.0-3) unstable; urgency=low
-+
-+ * `mcview' and `mcedit' added as alternatives for `editor' and `view'
-+ (closes: #116518).
-+
-+ -- Adam Byrtek Tue, 11 Feb 2003 22:05:00 +0100
-+
-+mc (1:4.6.0-2) unstable; urgency=low
-+
-+ * Control field 'Replaces: manpages-pl' added to replace Polish
-+ manual from this package with official one (closes: #180442).
-+ * 'Replaces: mc-common' added to make upgrade smoother.
-+ * 'Conflicts: suidmanager' because mc used to use it, but it is now
-+ deprecated (closes: #180431).
-+ * Doesn't depend on libgpm when compiling on HURD.
-+
-+ * README.Debian now mentions -P syntax changes (close: #180551).
-+
-+ -- Adam Byrtek Tue, 11 Feb 2003 13:55:47 +0100
-+
-+mc (1:4.6.0-1) unstable; urgency=low
-+
-+ * New upstream release.
-+ * First 4.6.0 official upload, and package takeover.
-+
-+ -- Adam Byrtek Wed, 5 Feb 2003 20:34:46 +0100
-+
-+mc (4.6.0-pre3-1) unstable; urgency=low
-+
-+ * New upstream prerelease.
-+
-+ -- Adam Byrtek Wed, 22 Jan 2003 09:54:58 +0100
-+
-+mc (4.6.0-pre2-2) unstable; urgency=low
-+
-+ * Patches checked, unneccesary removed, others reviewed.
-+
-+ -- Adam Byrtek Wed, 15 Jan 2003 00:35:20 +0100
-+
-+mc (4.6.0-pre2-1) unstable; urgency=low
-+
-+ * New upstream release (gmc, mc-common packages removed).
-+ * New maintainer, some cleanups.
-+ * Menu icon added (credits for the icon go to BigVax, bigvax@mail.ru).
-+ * New description (taken from freshmeat.net).
-+
-+ -- Adam Byrtek Sun, 29 Dec 2002 16:18:18 +0100
-+
-+mc (4.5.55-1.2) unstable; urgency=low
-+
-+ * Non-maintainer upload.
-+ * Make /etc/CORBA/servers/gmc.gnorba a conffile (closes: #132831).
-+ * Correct spelling mistakes in descriptions (closes: #124680, #125121).
-+ * Update convert-metadata.db to deal with libgnome32 linking against db3
-+ rather than db2, and add a new debconf question prompting the admin to
-+ run it. I've left the db1->db2 question there temporarily for historical
-+ and translation interest (closes: #103102).
-+ * Upgrades from slink need both libdb2-util and libdb3-util. Fortunately,
-+ they can coexist. I'll leave it up to the maintainers what to do about
-+ this after the woody release.
-+
-+ -- Colin Watson Sat, 16 Feb 2002 23:09:34 +0000
-+
-+mc (4.5.55-1.1) unstable; urgency=low
-+
-+ * Non-maintainer upload, with Martin's permission.
-+ * Build-depend on docbook-utils, not cygnus-stylesheets (closes: #123161).
-+ * Remove bashism in debian/rules (closes: #126733).
-+ * Depend on perl rather than on dummy packages (closes: #113208).
-+
-+ -- Colin Watson Tue, 15 Jan 2002 01:20:08 +0000
-+
-+mc (4.5.55-1) unstable; urgency=low
-+
-+ * New upstream release
-+ * Enable mouse for Eterm TERM value
-+ * mc.ext stabilized again upstream, so make it more Debian compliant
-+ again, closes: #105935, #98827
-+ * gmc documentation is fixed, closes: #107936
-+ * Fix german locale, closes: #108302
-+
-+ -- Martin Bialasinski Sun, 2 Sep 2001 17:07:56 +0200
-+
-+mc (4.5.54-2) unstable; urgency=low
-+
-+ * Use new config.guess and config.sub to allow compilation on hppa
-+
-+ -- Martin Bialasinski Fri, 13 Jul 2001 23:47:18 +0200
-+
-+mc (4.5.54-1) unstable; urgency=low
-+
-+ * New upstream release, closes: #99127
-+ * make gzip, compress, bzip, bzip2 entries in mc.ext more specific
-+ closes: #97242, #103800, #102512, #97896, #96649, #104111
-+ (Oskar Liljeblad)
-+ * Updated syntax highlighting for debian files, closes: #93228
-+ (Lenart Janos)
-+ * Fix regexp for rexx files in mc.ext, closes: #98432 (Michel Casabona)
-+ * Build fixes for the hurd, closes: #101542, #101543 (Marcus Brinkmann)
-+ * Danish translation for the debconf template, closes: #100335
-+ (Jesper R. Meyer)
-+ * Dutch translation for the debconf template, closes: #95738
-+ (Thomas J. Zeeman)
-+ * Spanish translation for the debconf template, closes: #102903
-+ (Carlos Valdivia Yague)
-+
-+ -- Martin Bialasinski Sun, 8 Jul 2001 12:19:24 +0200
-+
-+mc (4.5.51-16) unstable; urgency=low
-+
-+ * Update zu the uzip extfs
-+
-+ -- Martin Bialasinski Sun, 4 Mar 2001 20:57:25 +0100
-+
-+mc (4.5.51-15) unstable; urgency=low
-+
-+ * Update uzip extfs, closes: #86913
-+ * Fix compilation, closes: #87414
-+
-+ -- Martin Bialasinski Wed, 28 Feb 2001 19:32:44 +0100
-+
-+mc (4.5.51-14) unstable; urgency=low
-+
-+ * Translations for the gmc debconf template, thanks to
-+ fr by Thomas Morin, closes: #83765
-+ sv by Andre Dahlqvist, closes: #83677
-+
-+ -- Martin Bialasinski Sat, 3 Feb 2001 21:55:27 +0100
-+
-+mc (4.5.51-13) unstable; urgency=high
-+
-+ * Added libgnorba-dev to the build-depends. It is not pulled in by
-+ libgnome-dev on the m68k autobuilder, closes: #81200
-+ * Fixed dependancy on perl (lintian)
-+ * Fix for devfs in cons.saver, closes: #57557
-+ * Patch for proxy support in ftpfs from Mandrake
-+ * [gmc] Disabled checking of owner on file rename as a dirty fix
-+ closes: #80544
-+ * [gmc] Don't let the use confirm twice that he wants to exit,
-+ closes: #48523
-+ * Updated FAQ to reflect rename of mc mailinglists
-+ * Fix security bug using quick patch by Andrew V. Samoilov
-+ see http://www.securityfocus.com/vdb/?id=2016
-+ * Statoverride adaption
-+
-+ -- Martin Bialasinski Thu, 11 Jan 2001 20:07:02 +0100
-+
-+mc (4.5.51-12) unstable; urgency=high
-+
-+ * Added build-depends
-+ * Recompiled with latest glibc, closes: #74905, #74906, #75134, #77172
-+ * Added menu hints, closes: #80014, #80038
-+ * Fix problems with file selection code, closes: #79639
-+ Thanks to Alexander Viro
-+
-+ -- Martin Bialasinski Thu, 21 Dec 2000 14:48:35 +0100
-+
-+mc (4.5.51-11) unstable; urgency=high
-+
-+ * Security fix for cons.saver, bugtraq id 1945
-+ serious local DoS possibility
-+
-+ -- Martin Bialasinski Wed, 15 Nov 2000 20:05:20 +0100
-+
-+mc (4.5.51-10) unstable; urgency=low
-+
-+ * Fix for ftpfs, closes: #61239
-+
-+ -- Martin Bialasinski Sun, 12 Nov 2000 20:37:50 +0100
-+
-+mc (4.5.51-9) unstable; urgency=low
-+
-+ * Upstream patch to fix storing on root directory on a ftp server
-+
-+ -- Martin Bialasinski Wed, 8 Nov 2000 01:01:40 +0100
-+
-+mc (4.5.51-8) unstable; urgency=low
-+
-+ * Small fix to the .deb entry in mc.ext to make it work with new
-+ and old tar
-+ * New uzip extfs by Oskar Liljeblad, closes: #75353
-+
-+ -- Martin Bialasinski Sat, 4 Nov 2000 00:05:08 +0100
-+
-+mc (4.5.51-7) unstable; urgency=low
-+
-+ * Quote pathname on C-x p and C-x P, closes: #72632
-+ Thanks to Lois Lefort (sorry, missed the report somehow)
-+
-+ -- Martin Bialasinski Sat, 21 Oct 2000 14:50:12 +0200
-+
-+mc (4.5.51-6) unstable; urgency=low
-+
-+ * Changed F3 view of .deb and .rpm files like done on advanced mc,
-+ changed dependancies a bit to suit this
-+ * Correcting small spelling error (#21825 in the GNOME BTS)
-+ * Make mouse work in rxvt, closes: #74400
-+
-+ -- Martin Bialasinski Wed, 18 Oct 2000 20:22:45 +0200
-+
-+mc (4.5.51-5) unstable; urgency=low
-+
-+ * Upstream patch to fix %e behaviour on opening files for edit in gmc
-+
-+ -- Martin Bialasinski Wed, 4 Oct 2000 22:27:04 +0200
-+
-+mc (4.5.51-4) unstable; urgency=low
-+
-+ * Fix typo in mc.ext and mc-gnome.ext, thanks to Robert Luberda
-+ Closes: #71788
-+
-+ -- Martin Bialasinski Sat, 16 Sep 2000 09:33:57 +0200
-+
-+mc (4.5.51-3) unstable; urgency=low
-+
-+ * Fix to the patchfs by Loic Lefort, Closes: #71430
-+ * Fix filelocations in the manpages
-+ * Add the patchfs to mc.ext, so you can enter a (compressed)
-+ patch with
-+
-+ -- Martin Bialasinski Fri, 15 Sep 2000 00:16:50 +0200
-+
-+mc (4.5.51-2) unstable; urgency=low
-+
-+ * Fixed some strange problems with the patches, Closes: #69516
-+
-+ -- Martin Bialasinski Mon, 21 Aug 2000 01:13:21 +0200
-+
-+mc (4.5.51-1) unstable; urgency=low
-+
-+ * New upstream release, closes: #62261, #64975
-+ * Fixed description, closes: #62260
-+ * Moved locales data into mc-common, closes: #67577
-+ * Move documentation to /usr/share/doc and make a symlink in
-+ /usr/share/gnome/help
-+ * Fix gmc doc-base description, closes: #68671
-+ * Don't install a wrong manpage
-+
-+ -- Martin Bialasinski Mon, 14 Aug 2000 23:39:48 +0200
-+
-+mc (4.5.42-16) unstable; urgency=low
-+
-+ * Fix path in doc-base and create a missing symlink
-+
-+ -- Martin Bialasinski Sun, 26 Mar 2000 22:52:15 +0200
-+
-+mc (4.5.42-15) unstable; urgency=low
-+
-+ * Fix usage of debconf. Don't issue the warning on new installs
-+ * Move convert.metadata.db from /usr/lib/mc to /usr/bin
-+
-+ -- Martin Bialasinski Sun, 26 Mar 2000 14:37:36 +0200
-+
-+mc (4.5.42-14) unstable; urgency=low
-+
-+ * make convert-metadata.db executable in the postinst
-+
-+ -- Martin Bialasinski Sun, 19 Mar 2000 23:43:44 +0100
-+
-+mc (4.5.42-13) unstable; urgency=low
-+
-+ * Changed the undelfs example in mc.sgml and mc.1.in as well
-+ * Fix build from source bug, closes: #60289
-+
-+ -- Martin Bialasinski Mon, 13 Mar 2000 18:19:34 +0100
-+
-+mc (4.5.42-12) unstable; urgency=low
-+
-+ * Fix problem with hex view, roll-over on first position.
-+ Patch by Loic Lefort
-+
-+ -- Martin Bialasinski Mon, 13 Mar 2000 12:17:16 +0100
-+
-+mc (4.5.42-11) frozen unstable; urgency=low
-+
-+ * [gmc] Let the admin know that he must run convert-metadata.db
-+ via debconf. Closes: #58707
-+
-+ -- Martin Bialasinski Sun, 12 Mar 2000 20:27:56 +0100
-+
-+mc (4.5.42-10) frozen unstable; urgency=low
-+
-+ * Fixed documentation bug, closes: #60045
-+ * Fixed terminfo searchpath in internal slang, closes: #56272
-+ * [gmc] added dependancy on eject and made some comments in README.Debian,
-+ closes: #59214
-+
-+ -- Martin Bialasinski Sun, 12 Mar 2000 01:16:41 +0100
-+
-+mc (4.5.42-9) frozen unstable; urgency=low
-+
-+ * convert-metadata.db : set gid and egid before setting uid and euid. Doh!
-+ * Helpfile mentioned non-existing file. Closes: #56053
-+ * Fix small typo in mc.ext.in, part of #55897
-+ * Upload with full sources due to the change in the packaging method
-+
-+ -- Martin Bialasinski Mon, 6 Mar 2000 16:06:37 +0100
-+
-+mc (4.5.42-8) frozen unstable; urgency=low
-+
-+ * Switched to the Multipatch System the X packages use.
-+ * Patch from Andrew V. Samoilov, so the display is correct
-+ when selecting more than 2GB of files, closes: #53980, #58920
-+ * Added "or" and "and" keywords to perl sytnax file - patch by
-+ Tomasz Wegrzanowski, closes: #58437
-+ * Fix german translation, closes: #55401
-+ partly closes #56117
-+ * compile with --with-netrc
-+
-+ -- Martin Bialasinski Wed, 1 Mar 2000 01:50:05 +0100
-+
-+mc (4.5.42-7) unstable; urgency=low
-+
-+ * Fixes missing esac in mc.menu, thanks to Michel Casabona
-+ Closes: #54108
-+
-+ -- Martin Bialasinski Wed, 12 Jan 2000 21:22:47 +0100
-+
-+mc (4.5.42-6) unstable; urgency=low
-+
-+ * Fixes a y2k bug in the apt and dpkg vfs, closes: #54037
-+
-+ -- Martin Bialasinski Wed, 5 Jan 2000 17:39:43 +0100
-+
-+mc (4.5.42-5) unstable; urgency=low
-+
-+ * [gmc] Added dependancy on libdb-util* for convert-metadata.db
-+
-+ -- Martin Bialasinski Tue, 4 Jan 2000 14:20:05 +0100
-+
-+mc (4.5.42-4) unstable; urgency=low
-+
-+ * [gmc] Revised patch for the icon handling, closes: #53814
-+
-+ -- Martin Bialasinski Sat, 1 Jan 2000 17:53:13 +0100
-+
-+mc (4.5.42-3) unstable; urgency=low
-+
-+ * [gmc] Applied patch for icon misplacement, closes: #51571
-+ * SEP, closes #52250
-+ * Fixed lintian warnings about copyright file location
-+
-+ -- Martin Bialasinski Mon, 27 Dec 1999 18:43:18 +0100
-+
-+mc (4.5.42-2) unstable; urgency=low
-+
-+ * New version of the apt/dpkg vfs
-+
-+ -- Martin Bialasinski Mon, 20 Dec 1999 11:18:26 +0100
-+
-+mc (4.5.42-1) unstable; urgency=low
-+
-+ * New upstream release
-+ * [gmc] Remove notice how to fix broken desktop icons from postinst
-+ * enable NLS
-+
-+ -- Martin Bialasinski Wed, 8 Dec 1999 12:22:13 +0100
-+
-+mc (4.5.40-8) unstable; urgency=low
-+
-+ * Small fix to the apt and dpkg vfs.
-+
-+ -- Martin Bialasinski Fri, 3 Dec 1999 18:16:41 +0100
-+
-+mc (4.5.40-7) unstable; urgency=low
-+
-+ * Really fixes all zip,jar archive problems,
-+ thanks again to Oskar Liljeblad. Closes: #50528, #51779
-+ * Amazing new vfs by Piotr Roszatycki , a
-+ dpkg and apt frontend! See README.Debian for info.
-+ Closes: #46694
-+
-+ -- Martin Bialasinski Fri, 3 Dec 1999 00:11:07 +0100
-+
-+mc (4.5.40-6) unstable; urgency=low
-+
-+ * Fixed problem with ~/.gnome/metadata.db
-+ libc switch from DB 1.85 to DB 2, so the file has to be recreated.
-+ Shipping a conversion script as /usr/lib/mc/convert-metadata.db
-+ Closes: #47115, #46491
-+ * Don't wait for upstream to include the new Debian logo, Closes: #46502
-+
-+ -- Martin Bialasinski Tue, 30 Nov 1999 21:24:35 +0100
-+
-+mc (4.5.40-5) unstable; urgency=low
-+
-+ * Patch for mc.ext by Tomasz Wegrzanowski
-+ to use sensible-* Closes: #50210
-+ * Patch for mc.ext by Oskar Liljeblad
-+ to use run-mailcap Closes: #50732
-+ * Missing closing bracket in uzip.in (thanks to Andreas Wappel),
-+ fixed the other repored problems. Closes: #48003
-+ (Also #50528, #50452, but has to be checked)
-+ * Using a better fix for the tar problem in the deb vfs
-+
-+ -- Martin Bialasinski Thu, 25 Nov 1999 23:45:20 +0100
-+
-+mc (4.5.40-4) unstable; urgency=low
-+
-+ * Use mc's own slang, which has some modifications.
-+ Closes: #47487
-+ * mc doesn't have a mtools vfs for some time now, closes: #26821
-+ * Included syntax highlighting definitions for debian/changelog,
-+ debian/rules, debian/control and sources.list, closes: #47403
-+ Thanks to Radovan Garabik
-+
-+ -- Martin Bialasinski Sat, 31 Oct 1999 13:59:54 +0200
-+
-+mc (4.5.40-3) unstable; urgency=low
-+
-+ * Recompiled with slang 1.3 - Fixes the dreadful
-+ "right border is not cleaned" and other display bugs.
-+ Closes: #34315, #40496, #41166, #47328 and part of #47197
-+
-+ -- Martin Bialasinski Thu, 14 Oct 1999 19:03:32 +0200
-+
-+mc (4.5.40-2) unstable; urgency=low
-+
-+ * Added conflicts to the versions before mc-common was introduced
-+
-+ -- Martin Bialasinski Sat, 2 Oct 1999 12:34:06 +0200
-+
-+mc (4.5.40-1) unstable; urgency=low
-+
-+ * New upstream release
-+
-+ -- Martin Bialasinski Thu, 30 Sep 1999 00:51:33 +0200
-+
-+mc (4.5.39-1) unstable; urgency=low
-+
-+ * New upstream version
-+ * Uploading as a co-maintainer
-+ * New package setup
-+ - mc-common, mc and gmc
-+ - mc and gmc don't conflict anymore
-+ Closes: #43761
-+ * Using debhelper, no more fhs problems, closes: #45962
-+ * Applied fixes for new tar format (without leading ./)
-+ Closes: #45473, #45432, #45145, #45131, #44965, #45340
-+ * Suidregister only in the mc package, closes: #45014
-+ * smbfs was removed before, closes: #45481, #45267, #45339
-+ * Added xterm-color to the list of color capable TERMs in mc.ini
-+ * Added note in README about fixing ~/.mc/ini to enable colored mc
-+ Closes: #26820
-+ * Added TODO and upstream changelogs to the packages
-+
-+ -- Martin Bialasinski Tue, 28 Sep 1999 03:09:32 +0200
-+
-+mc (4.5.38-4) unstable; urgency=low
-+
-+ * add -f to the rm's in debian/rules (Close: #45650)
-+
-+ -- Michael Bramer Fri, 24 Sep 1999 07:58:57 +0200
-+
-+mc (4.5.38-3) unstable; urgency=low
-+
-+ * remove mc.real to mc and remove the --with-samba option. I must
-+ work with the sources.
-+ Sorry, for the last problems.
-+
-+ -- Michael Bramer Sun, 19 Sep 1999 14:25:57 +0200
-+
-+mc (4.5.38-2) unstable; urgency=low
-+
-+ * add .real to mc in /usr/bin/mc
-+
-+ -- Michael Bramer Wed, 15 Sep 1999 13:23:44 +0200
-+
-+mc (4.5.38-1) unstable; urgency=low
-+
-+ * add patch from viro@math.psu.edu (Close:#29176)
-+ * add --with-samba to configure
-+ * move /usr/bin/mc to /usr/bin/mc.real and add the
-+ script /usr/bin/mc (Close:#43168)
-+ * recompiled with slang1-dev 1.2.2-3 (Close:#44359)
-+ * add link from /usr/bin/mcedit to /usr/bin/mc (Close:#40943)
-+ * new upstream version
-+
-+ -- Michael Bramer Tue, 7 Sep 1999 22:34:18 +0200
-+
-+mc (4.5.37-2) unstable; urgency=low
-+
-+ * rebuild with newer gpm. (now should use /var/run/gpmctl and not
-+ /dev/gpmctl)
-+
-+ -- Michael Bramer Wed, 4 Aug 1999 11:41:32 +0200
-+
-+mc (4.5.37-1) unstable; urgency=low
-+
-+ * new upstream version
-+
-+ -- Michael Bramer Tue, 3 Aug 1999 22:29:21 +0200
-+
-+mc (4.5.33-6) unstable; urgency=low
-+
-+ * set auto_save_setup to no in mc.ini
-+
-+ -- Michael Bramer Sat, 3 Jul 1999 11:32:50 +0200
-+
-+mc (4.5.33-5) unstable; urgency=low
-+
-+ * add link from /usr/lib/mc/mc.ini to /etc/mc/
-+
-+ -- Michael Bramer Sat, 3 Jul 1999 09:02:00 +0200
-+
-+mc (4.5.33-4) unstable; urgency=low
-+
-+ * add 'AWK="awk"' in debian/rules
-+ * remove /usr/etc/mc (change rules and Makefiles.in's) (close: 37070)
-+ * remove changelog_intl.gz (close: 36683)
-+ * remove README.debian (close: 36682)
-+ * add 'color_terminals=linux,xterm-debian,screen' in debian/addons/mc.ini
-+ (close: 26820)
-+ * move /usr/lib/mc/term/ to /urs/doc/mc/ (close: 26022)
-+
-+ -- Michael Bramer Fri, 2 Jul 1999 14:54:14 +0200
-+
-+mc (4.5.33-3) unstable; urgency=low
-+
-+ * Add 'Provides: mc' in gmc-package controlfile (close: #35005)
-+
-+ -- Michael Bramer Tue, 29 Jun 1999 23:52:56 +0200
-+
-+mc (4.5.33-2) unstable; urgency=low
-+
-+ * now compiled with the installed package e2fslibs-dev (close: 40335)
-+
-+ -- Michael Bramer Tue, 29 Jun 1999 00:44:50 +0200
-+
-+mc (4.5.33-1) unstable; urgency=low
-+
-+ * new upstream version
-+
-+ -- Michael Bramer Wed, 9 Jun 1999 05:02:23 +0200
-+
-+mc (4.5.30-2) unstable; urgency=low
-+
-+ * Patch from Martin Bialasinski close:#36246
-+
-+ -- Michael Bramer Mon, 19 Apr 1999 12:19:25 +0200
-+
-+mc (4.5.30-1) unstable; urgency=low
-+
-+ * new upstream version
-+
-+ -- Michael Bramer Wed, 14 Apr 1999 17:41:15 +0200
-+
-+mc (4.5.25-1) unstable; urgency=low
-+
-+ * change the download source to:
-+ ftp://ftp.sunsite.org.uk/packages/gnome/sources/mc
-+ * add --sysconfdir=/etc in the rule file
-+ * new upstream version (with my patches :-)
-+
-+ -- Michael Bramer Tue, 16 Mar 1999 13:38:32 +0100
-+
-+mc (4.5.22-1) unstable; urgency=low
-+
-+ * change ee to eeyes in lib/mc-gnome.ext.in
-+ * new upstream version
-+
-+ -- Michael Bramer Thu, 4 Mar 1999 23:47:37 +0100
-+
-+mc (4.5.21-1) unstable; urgency=low
-+
-+ * remove usr/share/pixmaps/ from mc
-+ (from the 'first' 4.5.21-1 upload in gnome-staging)
-+ * remove usr/bin/plain-gmc from mc
-+ (from the 'first' 4.5.21-1 upload in gnome-staging)
-+ * add patch from viro@math.psu.edu close:29176
-+ * new config files: mc.global and mc-gnome.ext
-+ * add link from /usr/lib/etc/mc.global to /etc/mc/mc.global
-+ * add links from /usr/lib/mc/* to /etc/mc/
-+ * new upstream version
-+ * add a '-f' to -rm gnome/gmc in debian/rule
-+ * change 'ee' in 'eeyes' in lib/mc-gnome.ext
-+ * add the conffiles in the gmc-package
-+
-+ -- Michael Bramer Sat, 27 Feb 1999 00:11:28 +0100
-+
-+mc (4.5.1-1.1) frozen; urgency=medium
-+
-+ * NMU in behalf of Michael Bramer as he has not got a pure slink system
-+ * Fixes Bug#33341, priority important (buffer overrun) for slink
-+
-+ -- Martin Bialasinski Wed, 17 Feb 1999 00:26:48 +0100
-+
-+mc (4.5.1-1) unstable; urgency=low
-+
-+ * new (beta) version
-+
-+ -- Michael Bramer Thu, 22 Oct 1998 19:48:42 +0200
-+
-+mc (4.1.36-1) unstable; urgency=low
-+
-+ * change from +Z to -Z for zsh (close:#26428)
-+ * add Suggests:rpm (close:#26137)
-+ * remove /usr/doc/mc/README.edit (close:#26047)
-+ * add patch from Patrik Rak in deb.in (close:#25838)
-+ * add link from /usr/lib/mc/mc.ext to /etc/mc/mc.ext (close#25719)
-+ * New upsteam release
-+
-+ -- Michael Bramer Thu, 15 Oct 1998 11:41:11 +0200
-+
-+mc (4.1.35-6) unstable; urgency=low
-+
-+ * don't print debug-code in gnome/*.c (#25587)
-+ * move usr/doc/mc/changelog_src.gz to usr/doc/mc/changelog.gz
-+ * Change menue from Apps/Misc to Apps/Tools
-+
-+ -- Michael Bramer Wed, 26 Aug 1998 10:23:43 +0200
-+
-+mc (4.1.35-5) unstable; urgency=low
-+
-+ * make the menufiles in the new format
-+ * change from ee to eeyes for *.jpeg etc. in mc.ext
-+
-+ -- Michael Bramer Tue, 25 Aug 1998 18:35:11 +0200
-+
-+mc (4.1.35-4) unstable; urgency=low
-+
-+ * add to debstd the -u option
-+ * make a new build with gonme0.27 and co.
-+
-+ -- Michael Bramer Mon, 17 Aug 1998 13:07:11 +0200
-+
-+mc (4.1.35-3) unstable; urgency=low
-+
-+ * add all changelog-files in /usr/doc/[g]mc
-+ * make for gmc a /usr/doc/gmc/
-+ * add a '!' in the first line from mcfn_install.in, now: #!/bin/sh
-+ * typo in the Description (thanks to joey)
-+ * don't print debug-code in gdesktop.c (#25587)
-+
-+ -- Michael Bramer Mon, 10 Aug 1998 23:29:33 +0200
-+
-+mc (4.1.35-2) unstable; urgency=low
-+
-+ * the multi-package is not nice, but it should work
-+ * add gmc support in a multi-binary-package
-+ * new maintainer
-+
-+ -- Michael Bramer Fri, 31 Jul 1998 13:04:28 +0200
-+
-+mc (4.1.35-1) frozen unstable; urgency=low
-+
-+ * New upsteam release fixes a bug introduced by last version,
-+ which made the history input lines stop working. Since this
-+ is one of the essential useability features of MC which will
-+ most certainly provoke bug reports this here should still go
-+ into frozen.
-+
-+ -- Paul Seelig Tue, 26 May 1998 05:00:05 +0100
-+
-+mc (4.1.34-1) frozen unstable; urgency=low
-+
-+ * New upsteam release really fixes Bug#20727 and some bugs no one
-+ has even bothered to report until now. :-)
-+ * Added "--without-gnome" and "--disable-nls" flags to debian/rules.
-+ The internationalized Gnome version of MC is becoming pretty mature,
-+ but will not go into frozen, sorry.
-+
-+ -- Paul Seelig Fri, 15 May 1998 21:36:56 +0100
-+
-+mc (4.1.28-3) frozen unstable; urgency=low
-+
-+ * Rebuild using ss-dev, comerr-dev and e2fslibs-dev closing Bug#21749
-+
-+ -- Paul Seelig Tue, 28 Apr 1998 22:32:15 +0100
-+
-+mc (4.1.28-2) frozen unstable; urgency=low
-+
-+ * Changed debian/postinst to address and close Bug#20871. I wonder why
-+ this didn't show up earlier?
-+
-+ -- Paul Seelig Wed, 08 Apr 1998 21:29:51 +0100
-+
-+mc (4.1.28-1) frozen unstable; urgency=low
-+
-+ * New upstream release.
-+ * Compiled with ext2undel feature closing Bug#20752.
-+ * Fixes an upstream bug which made MC crash when trying to copy an
-+ unreadable file via FTP.
-+
-+ -- Paul Seelig Mon, 06 Apr 1998 17:23:15 +0100
-+
-+mc (4.1.27-1) unstable; urgency=low
-+
-+ * New upstream release.
-+
-+ -- Paul Seelig Fri, 27 Feb 1998 07:44:29 +0100
-+
-+mc (4.1.26-1) unstable; urgency=low
-+
-+ * New upstream release.
-+ * Updated to standards version 2.4.0.0
-+ * Updated postal address of FSF in copyright file
-+ * Added manual page for 'mcmfmt'.
-+ * Adapted control file to place package in section "utils"
-+ with priority "optional".
-+
-+ -- Paul Seelig Fri, 20 Feb 1998 03:41:38 +0100
-+
-+mc (4.1.24-1) unstable; urgency=low
-+
-+ * New upstream release version
-+ * Binary package now smaller because upstream maintainer truncated
-+ the src/Changelog file which has grown far too large over time. ;-)
-+ * Changed "Architecture: i386" to "Architecture: any" in control file.
-+ This addresses and closes bug #17226 as reported by James Troup.
-+
-+ -- Paul Seelig Thu, 22 Jan 1998 18:32:55 +0100
-+
-+mc (4.1.22-2) unstable; urgency=low
-+
-+ * Adapted debian/changelog to reflect official Debian release history
-+ * Added debian/menu file from former maintainer
-+ * Closing supposedly outdated bugs #9868, #14744, #14768, #16050
-+ and #11968 due to increase of upstream version number.
-+
-+ -- Paul Seelig Fri, 16 Jan 1998 23:41:32 +0100
-+
-+mc (4.1.22-1) unstable; urgency=low
-+
-+ * New maintainer
-+ * New upstream version
-+
-+ -- Paul Seelig Fri, 16 Jan 1998 17:41:32 +0100
-+
-+mc (4.1.9-1) unstable; urgency=low
-+
-+ * Upgraded to latest upstream release (Bugs #13145, #14012).
-+ * Use pristine source.
-+ * Wrote patch to build with libc6.
-+ * Orphaned the package (Unfixed since 6 months).
-+ * Recommends file (Bug #7338).
-+ * #11864 sould be fixed (libgpmg problem).
-+ * Depend on login-970616-1 and don't install cons.saver suid root
-+ (Bug #13440).
-+ * Corrected debian/rules (make clean shouldn't fail).
-+
-+ -- Vincent Renardias Mon, 10 Nov 1997 00:05:02 +0100
-+
-+mc (3.5.17-1) unstable; urgency=low
-+
-+ * Upgraded to latest upstream release
-+ * Sources converted to new format
-+
-+ -- Fernando Alegre Mon, 24 Feb 1997 12:56:43 +0100
-+
---- mc-4.6.1.orig/debian/slang.c
-+++ mc-4.6.1/debian/slang.c
-@@ -0,0 +1,19 @@
-+#include
-+#include
-+
-+void main(void)
-+{
-+ SLtt_get_terminfo ();
-+ SLang_init_tty (-1, 0, 0);
-+ SLsmg_init_smg ();
-+
-+ /* do stuff .... */
-+ SLsmg_write_nchars("éàç", 3);
-+ SLsmg_printf (" éàç ");
-+ SLsmg_write_char ('à');
-+ SLsmg_refresh();
-+ sleep(5);
-+
-+ SLsmg_reset_smg ();
-+ SLang_reset_tty ();
-+}
---- mc-4.6.1.orig/debian/mc.postinst
-+++ mc-4.6.1/debian/mc.postinst
-@@ -0,0 +1,14 @@
-+#! /bin/sh
-+
-+set -e
-+
-+case "$1" in
-+ configure|abort-upgrade)
-+ update-alternatives --install /usr/bin/view view /usr/bin/mcview-debian 25 \
-+ --slave /usr/share/man/man1/view.1.gz view.1.gz /usr/share/man/man1/mcview.1.gz
-+ update-alternatives --install /usr/bin/editor editor /usr/bin/mcedit-debian 25 \
-+ --slave /usr/share/man/man1/editor.1.gz editor.1.gz /usr/share/man/man1/mcedit.1.gz
-+ ;;
-+esac
-+
-+#DEBHELPER#
---- mc-4.6.1.orig/debian/manpages
-+++ mc-4.6.1/debian/manpages
-@@ -0,0 +1,3 @@
-+debian/extra/mcmfmt.1
-+debian/extra/mcedit-debian.1
-+debian/extra/mcview-debian.1
---- mc-4.6.1.orig/debian/mc.postrm
-+++ mc-4.6.1/debian/mc.postrm
-@@ -0,0 +1,12 @@
-+#! /bin/sh
-+
-+set -e
-+
-+case "$1" in
-+ purge)
-+ rm -f /etc/mc/mc.lib /etc/mc/mc.ext /etc/mc/mc.menu
-+ rmdir /etc/mc 2>/dev/null || true
-+ ;;
-+esac
-+
-+#DEBHELPER#
---- mc-4.6.1.orig/debian/README.Debian
-+++ mc-4.6.1/debian/README.Debian
-@@ -0,0 +1,34 @@
-+mc for Debian
-+-------------
-+
-+ Debian mc package patches: http://alioth.debian.org/projects/pkg-mc/
-+
-+
-+ The 4.6.1-pre3 introduces the charset and samba enabling in the mc package
-+ compilation.
-+
-+ The current is a pre-release for 4.6.1 where the aim is to include as
-+ many bug fixes as possible. In particular DSA 639-1 vulnerabilities.
-+
-+ -- Stefano Melchior Mon, 31 Jan 2005 23:50:45 +0100
-+
-+ Starting with version 4.6.0 Midnight Commander doesn't include any
-+ GUI interface. The GNOME interface has been removed so that the
-+ developers could concentrate on the text edition of the program. If
-+ you need a GUI file manager, there are many of them available in the
-+ Debian archive - pick one and use it.
-+
-+ Because of some issues a method to stay in the last working directory
-+ after exit has changed with 4.6.0. See the description of the -P
-+ option in the Options section of the manual and new wrapper scripts
-+ in /usr/share/mc/bin/.
-+
-+ If you want to learn some interesting usage tips, you should read the
-+ Midnight Commander FAQ (/usr/share/doc/mc/FAQ, also available through
-+ the Debian doc-base interface).
-+
-+ Midnight Commander supports apt and dpkg archive managment through
-+ it's ExtFS feature. Just "cd #apt" or "cd #dpkg" at the mc command
-+ line and try it.
-+
-+ -- Adam Byrtek Wed, 5 Feb 2003 20:34:46 +0100
---- mc-4.6.1.orig/debian/patches/13_syntax.patch
-+++ mc-4.6.1/debian/patches/13_syntax.patch
-@@ -0,0 +1,13 @@
-+--- syntax/Syntax Sun Mar 6 14:11:31 2005
-++++ syntax/Syntax Sun Mar 6 19:00:44 2005
-+@@ -41,8 +41,9 @@
-+ file ..\*\\.(rb|RB)$ Ruby\sProgram ^#!\s\*/.\*/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
---- mc-4.6.1.orig/debian/patches/48_utf8-slang2.patch
-+++ mc-4.6.1/debian/patches/48_utf8-slang2.patch
-@@ -0,0 +1,5119 @@
-+diff -Naur mc-4.6.1-old/edit/edit.c mc-4.6.1/edit/edit.c
-+--- mc-4.6.1-old/edit/edit.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/edit.c 2005-10-28 10:08:07.736247264 +0200
-+@@ -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 +789,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 +820,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 +831,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 +846,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 +871,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 +886,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 +898,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 +942,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 +980,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 +995,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 +1018,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 +1028,7 @@
-+
-+ int edit_delete (WEdit * edit)
-+ {
-+- int p;
-++ mc_wint_t p;
-+ if (!edit->curs2)
-+ return 0;
-+
-+@@ -942,7 +1052,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 +1066,7 @@
-+ static int
-+ edit_backspace (WEdit * edit)
-+ {
-+- int p;
-++ mc_wint_t p;
-+ if (!edit->curs1)
-+ return 0;
-+
-+@@ -980,7 +1090,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 +1103,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 +1127,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 +1167,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 +1205,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 +1237,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 +1262,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 +1369,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 +1387,7 @@
-+ } else if (c < 32 || c == 127)
-+ col += 2; /* Caret notation for control characters */
-+ else
-+- col++;
-++ col += wcwidth(c);
-+ }
-+ return col;
-+ }
-+@@ -1402,7 +1520,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 +1892,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 +1919,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 +2222,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 +2257,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 +2290,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 -Naur mc-4.6.1-old/edit/editcmd.c mc-4.6.1/edit/editcmd.c
-+--- mc-4.6.1-old/edit/editcmd.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/editcmd.c 2005-10-28 10:08:07.687254712 +0200
-+@@ -46,7 +46,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 +69,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 +112,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 +200,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 ,
-+@@ -303,32 +349,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 +705,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 +755,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 +808,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 +968,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 +1016,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 +1061,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 +1122,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 +1453,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 +1466,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 +1490,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 +1542,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 +1573,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 +1602,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 +1645,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 +1675,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 +1696,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 +1726,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 +1792,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 +1831,7 @@
-+
-+ #define is_digit(x) ((x) >= '0' && (x) <= '9')
-+
-++#ifndef UTF8
-+ #define snprint(v) { \
-+ *p1++ = *p++; \
-+ *p1 = '\0'; \
-+@@ -1623,33 +1839,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 +1908,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 +1988,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 +2173,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 +2186,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 +2221,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 +2248,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 +2431,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 +2474,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 +2490,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 +2839,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 +2946,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 +2969,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 +3014,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 +3035,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 +3052,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 +3066,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 +3090,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 +3129,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 +3146,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 +3173,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 +3192,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 -Naur mc-4.6.1-old/edit/editdraw.c mc-4.6.1/edit/editdraw.c
-+--- mc-4.6.1-old/edit/editdraw.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/editdraw.c 2005-10-28 10:08:07.657259272 +0200
-+@@ -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_char(textchar);
-++#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 -Naur mc-4.6.1-old/edit/edit.h mc-4.6.1/edit/edit.h
-+--- mc-4.6.1-old/edit/edit.h 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/edit.h 2005-10-28 10:08:07.768242400 +0200
-+@@ -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 -Naur mc-4.6.1-old/edit/editkeys.c mc-4.6.1/edit/editkeys.c
-+--- mc-4.6.1-old/edit/editkeys.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/editkeys.c 2005-10-28 10:08:07.659258968 +0200
-+@@ -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;
-+
-+@@ -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 -Naur mc-4.6.1-old/edit/editwidget.c mc-4.6.1/edit/editwidget.c
-+--- mc-4.6.1-old/edit/editwidget.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/editwidget.c 2005-10-28 10:08:07.664258208 +0200
-+@@ -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 -Naur mc-4.6.1-old/edit/edit-widget.h mc-4.6.1/edit/edit-widget.h
-+--- mc-4.6.1-old/edit/edit-widget.h 2003-10-29 09:54:47.000000000 +0100
-++++ mc-4.6.1/edit/edit-widget.h 2005-10-28 10:08:07.750245136 +0200
-+@@ -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;
-+diff -Naur mc-4.6.1-old/edit/wordproc.c mc-4.6.1/edit/wordproc.c
-+--- mc-4.6.1-old/edit/wordproc.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/edit/wordproc.c 2005-10-28 10:08:07.668257600 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/achown.c mc-4.6.1/src/achown.c
-+--- mc-4.6.1-old/src/achown.c 2005-07-23 18:52:02.000000000 +0200
-++++ mc-4.6.1/src/achown.c 2005-10-28 10:08:08.094192848 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/boxes.c mc-4.6.1/src/boxes.c
-+--- mc-4.6.1-old/src/boxes.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/boxes.c 2005-10-28 10:08:08.079195128 +0200
-+@@ -150,23 +150,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 +285,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 +307,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 +402,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 +417,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;
-+
-+@@ -489,11 +489,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 +501,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;
-+
-+@@ -597,7 +597,7 @@
-+
-+ cpname = _("&Select");
-+ add_widget (dbits_dlg,
-+- button_new (4, DISPX - 8 - strlen (cpname), B_USER,
-++ button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER,
-+ NORMAL_BUTTON, cpname, sel_charset_button));
-+
-+ return dbits_dlg;
-+@@ -803,7 +803,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 +962,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 +971,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 +1029,7 @@
-+
-+ while (i--)
-+ {
-+- l1 = strlen (labs [i] = _(labs [i]));
-++ l1 = mbstrlen (labs [i] = _(labs [i]));
-+ if (l1 > maxlen)
-+ maxlen = l1;
-+ }
-+@@ -1039,7 +1039,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 +1048,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 -Naur mc-4.6.1-old/src/dialog.c mc-4.6.1/src/dialog.c
-+--- mc-4.6.1-old/src/dialog.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/dialog.c 2005-10-28 10:08:07.891223704 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/file.c mc-4.6.1/src/file.c
-+--- mc-4.6.1-old/src/file.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/file.c 2005-10-28 10:08:08.002206832 +0200
-+@@ -165,15 +165,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 +222,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 +237,7 @@
-+ }
-+ }
-+ fntarget[k] = 0;
-++ g_free(fnsource);
-+ return fntarget;
-+ }
-+
-+diff -Naur mc-4.6.1-old/src/filegui.c mc-4.6.1/src/filegui.c
-+--- mc-4.6.1-old/src/filegui.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/filegui.c 2005-10-28 10:08:08.140185856 +0200
-+@@ -69,6 +69,7 @@
-+ #include "filegui.h"
-+ #include "key.h" /* get_event */
-+ #include "util.h" /* strip_password() */
-++#include "tty.h"
-+
-+ /* }}} */
-+
-+@@ -564,8 +565,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 +577,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 +595,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 +619,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);
-+@@ -805,36 +806,36 @@
-+ 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[FMCB11].text)
-++ + mbstrlen (fmd_widgets[FMCB21].text) + 15;
-+ fmd_xlen = max (fmd_xlen, len);
-+
-+- len = strlen (fmd_widgets[FMCB12].text)
-+- + strlen (fmd_widgets[FMCB22].text) + 15;
-++ len = mbstrlen (fmd_widgets[FMCB12].text)
-++ + mbstrlen (fmd_widgets[FMCB22].text) + 15;
-+ fmd_xlen = max (fmd_xlen, len);
-+
-+- len = strlen (fmd_widgets[FMBRGT].text)
-+- + strlen (fmd_widgets[FMBLFT].text) + 11;
-++ len = mbstrlen (fmd_widgets[FMBRGT].text)
-++ + mbstrlen (fmd_widgets[FMBLFT].text) + 11;
-+
-+ #ifdef FMBMID
-+- len += strlen (fmd_widgets[FMBMID].text) + 6;
-++ len += mbstrlen (fmd_widgets[FMBMID].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 += mbstrlen (fmd_widgets[FMBLFT].text) + 8;
-+
-+ #ifdef FMBMID
-+ fmd_widgets[FMBMID].relative_x = i;
-+- i += strlen (fmd_widgets[FMBMID].text) + 6;
-++ i += mbstrlen (fmd_widgets[FMBMID].text) + 6;
-+ #endif
-+
-+ fmd_widgets[FMBRGT].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);
-+@@ -856,7 +857,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,12 +866,20 @@
-+ struct stat buf;
-+ int val;
-+ QuickDialog Quick_input;
-+-
-++ char *def_text;
-+ 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 */
-+@@ -929,6 +938,7 @@
-+ orig_mask = source_mask;
-+ if (!dest_dir || !*dest_dir) {
-+ g_free (source_mask);
-++ g_free(def_text);
-+ return dest_dir;
-+ }
-+ if (source_easy_patterns) {
-+@@ -982,5 +992,6 @@
-+ }
-+ if (val == B_USER)
-+ *do_background = 1;
-++ g_free(def_text);
-+ return dest_dir;
-+ }
-+diff -Naur mc-4.6.1-old/src/find.c mc-4.6.1/src/find.c
-+--- mc-4.6.1-old/src/find.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/find.c 2005-10-28 10:08:08.049199688 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/global.h mc-4.6.1/src/global.h
-+--- mc-4.6.1-old/src/global.h 2004-09-25 15:46:23.000000000 +0200
-++++ mc-4.6.1/src/global.h 2005-10-28 10:11:08.071832088 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/help.c mc-4.6.1/src/help.c
-+--- mc-4.6.1-old/src/help.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/help.c 2005-10-28 10:09:53.961098632 +0200
-+@@ -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_char(wc);
-++ 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 -Naur mc-4.6.1-old/src/hotlist.c mc-4.6.1/src/hotlist.c
-+--- mc-4.6.1-old/src/hotlist.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/hotlist.c 2005-10-28 10:08:07.918219600 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/layout.c mc-4.6.1/src/layout.c
-+--- mc-4.6.1-old/src/layout.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/layout.c 2005-10-28 10:08:07.947215192 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/learn.c mc-4.6.1/src/learn.c
-+--- mc-4.6.1-old/src/learn.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/learn.c 2005-10-28 10:08:07.787239512 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/main.c mc-4.6.1/src/main.c
-+--- mc-4.6.1-old/src/main.c 2005-07-23 18:52:02.000000000 +0200
-++++ mc-4.6.1/src/main.c 2005-10-28 10:08:07.816235104 +0200
-+@@ -1609,7 +1609,11 @@
-+ if (xterm_flag && xterm_title) {
-+ p = s = g_strdup (strip_home_and_password (current_panel->cwd));
-+ do {
-++#ifndef UTF8
-+ if (!is_printable (*s))
-++#else /* UTF8 */
-++ if (*s < ' ')
-++#endif /* UTF8 */
-+ *s = '?';
-+ } while (*++s);
-+ fprintf (stdout, "\33]0;mc - %s\7", p);
-+diff -Naur mc-4.6.1-old/src/menu.c mc-4.6.1/src/menu.c
-+--- mc-4.6.1-old/src/menu.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/menu.c 2005-10-28 10:08:08.110190416 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/menu.h mc-4.6.1/src/menu.h
-+--- mc-4.6.1-old/src/menu.h 2004-09-18 16:30:59.000000000 +0200
-++++ mc-4.6.1/src/menu.h 2005-10-28 10:08:07.949214888 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/myslang.h mc-4.6.1/src/myslang.h
-+--- mc-4.6.1-old/src/myslang.h 2004-10-12 06:32:04.000000000 +0200
-++++ mc-4.6.1/src/myslang.h 2005-10-28 10:08:07.831232824 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/option.c mc-4.6.1/src/option.c
-+--- mc-4.6.1-old/src/option.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/option.c 2005-10-28 10:08:08.121188744 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/panelize.c mc-4.6.1/src/panelize.c
-+--- mc-4.6.1-old/src/panelize.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/panelize.c 2005-10-28 10:08:07.933217320 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/screen.c mc-4.6.1/src/screen.c
-+--- mc-4.6.1-old/src/screen.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/screen.c 2005-10-28 10:08:07.987209112 +0200
-+@@ -169,22 +169,59 @@
-+ static const char *
-+ string_file_name (file_entry *fe, int len)
-+ {
-+- static char buffer [BUF_SMALL];
-+ size_t i;
-++#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 UTF8
-++ if (SLsmg_Is_Unicode)
-++ for (i = 0; i < sizeof (buffer) - 1; i++) {
-++ wchar_t wc;
-++ int len;
-+
-+- if (!c)
-+- break;
-++ 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;
-+
-+- if (!is_printable(c))
-+- c = '?';
-++ c = fe->fname[i];
-+
-+- buffer[i] = c;
-+- }
-++ if (!c)
-++ break;
-++
-++ if (!is_printable(c))
-++ c = '?';
-++
-++ buffer[i] = c;
-++ }
-+
-+ buffer[i] = 0;
-+ return buffer;
-+@@ -425,42 +462,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 +515,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 +544,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;
-++ }
-++
-++ 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;
-+
-+- 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);
-++ 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 +697,6 @@
-+ {
-+ int second_column = 0;
-+ int width, offset;
-+- char buffer [BUF_MEDIUM];
-+
-+ offset = 0;
-+ if (!isstatus && panel->split){
-+@@ -618,7 +725,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)
-+@@ -1068,6 +1175,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 +1205,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 ();
-+diff -Naur mc-4.6.1-old/src/slint.c mc-4.6.1/src/slint.c
-+--- mc-4.6.1-old/src/slint.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/slint.c 2005-10-28 10:08:35.422038384 +0200
-+@@ -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 -Naur mc-4.6.1-old/src/util.c mc-4.6.1/src/util.c
-+--- mc-4.6.1-old/src/util.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/util.c 2005-10-28 10:19:11.683311968 +0200
-+@@ -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,22 @@
-+ #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)
-++{
-++ while(n--)
-++ SLsmg_write_char(*s++);
-++}
-++#endif
-++
-+ extern void str_replace(char *s, char from, char to)
-+ {
-+ for (; *s != '\0'; s++) {
-+@@ -77,9 +94,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 +211,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 +222,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 +325,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 +363,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 +856,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 +948,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 +959,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 +978,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 +1003,7 @@
-+ else
-+ fmt = fmttime;
-+
-+- strftime (timebuf, i18n_timelength, fmt, localtime(&when));
-++ strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when));
-+ return timebuf;
-+ }
-+
-+@@ -863,10 +1126,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;
-+diff -Naur mc-4.6.1-old/src/util.h mc-4.6.1/src/util.h
-+--- mc-4.6.1-old/src/util.h 2005-01-13 20:20:47.000000000 +0100
-++++ mc-4.6.1/src/util.h 2005-10-28 10:08:07.852229632 +0200
-+@@ -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
-+diff -Naur mc-4.6.1-old/src/view.c mc-4.6.1/src/view.c
-+--- mc-4.6.1-old/src/view.c 2005-05-27 16:19:18.000000000 +0200
-++++ mc-4.6.1/src/view.c 2005-10-28 10:08:08.023203640 +0200
-+@@ -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) SLsmg_write_char(c)
-++#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) {
-+diff -Naur mc-4.6.1-old/src/widget.c mc-4.6.1/src/widget.c
-+--- mc-4.6.1-old/src/widget.c 2005-05-27 16:19:19.000000000 +0200
-++++ mc-4.6.1/src/widget.c 2005-10-28 10:08:07.888224160 +0200
-+@@ -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,7 +1882,8 @@
-+ in->is_password = 0;
-+
-+ strcpy (in->buffer, def_text);
-+- in->point = strlen (in->buffer);
-++ in->point = mbstrlen (in->buffer);
-++ in->charpoint = 0;
-+ return in;
-+ }
-+
-+diff -Naur mc-4.6.1-old/src/widget.h mc-4.6.1/src/widget.h
-+--- mc-4.6.1-old/src/widget.h 2004-08-29 20:46:16.000000000 +0200
-++++ mc-4.6.1/src/widget.h 2005-10-28 10:08:08.064197408 +0200
-+@@ -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 */
-+diff -Naur mc-4.6.1-old/src/wtools.c mc-4.6.1/src/wtools.c
-+--- mc-4.6.1-old/src/wtools.c 2005-05-27 16:19:19.000000000 +0200
-++++ mc-4.6.1/src/wtools.c 2005-10-28 10:08:08.036201664 +0200
-+@@ -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 */
-+
---- mc-4.6.1.orig/debian/patches/03_conffiles_in_mans.patch
-+++ mc-4.6.1/debian/patches/03_conffiles_in_mans.patch
-@@ -0,0 +1,90 @@
-+diff -urN mc-4.6.0-pre3.orig/doc/mc.1.in mc-4.6.0-pre3/doc/mc.1.in
-+--- mc-4.6.0-pre3.orig/doc/mc.1.in 2003-01-14 21:01:34.000000000 +0100
-++++ mc-4.6.0-pre3/doc/mc.1.in 2003-01-14 21:59:38.000000000 +0100
-+@@ -1337,7 +1337,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
-+@@ -1855,7 +1855,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
-+@@ -3045,7 +3045,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
-+@@ -3054,12 +3054,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
-+@@ -3077,7 +3077,7 @@
-+ .IP
-+ This file contains the hints (cookies) 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.0-pre3.orig/doc/mcedit.1.in mc-4.6.0-pre3/doc/mcedit.1.in
-+--- mc-4.6.0-pre3.orig/doc/mcedit.1.in 2003-01-20 15:18:36.000000000 +0100
-++++ mc-4.6.0-pre3/doc/mcedit.1.in 2003-01-23 18:57:57.000000000 +0100
-+@@ -436,12 +436,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.0-pre3.orig/doc/mcview.1.in mc-4.6.0-pre3/doc/mcview.1.in
-+--- mc-4.6.0-pre3.orig/doc/mcview.1.in 2003-01-20 15:18:36.000000000 +0100
-++++ mc-4.6.0-pre3/doc/mcview.1.in 2003-01-23 18:58:24.000000000 +0100
-+@@ -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.
---- mc-4.6.1.orig/debian/patches/55_mc-utf8-look-and-feel.patch
-+++ mc-4.6.1/debian/patches/55_mc-utf8-look-and-feel.patch
-@@ -0,0 +1,204 @@
-+--- mc-4.6.1/src/main.c.laf 2005-11-24 16:55:06.000000000 +0100
-++++ mc-4.6.1/src/main.c 2005-11-24 16:56:27.000000000 +0100
-+@@ -274,6 +274,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;
-+
-+@@ -2167,6 +2170,16 @@ main (int argc, char *argv[])
-+ /* 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);
-+--- mc-4.6.1a/src/main.h.laf 2005-11-24 16:55:06.000000000 +0100
-++++ mc-4.6.1a/src/main.h 2005-11-24 16:55:06.000000000 +0100
-+@@ -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;
-+
-+--- mc-4.6.1a/src/widget.c.laf 2005-11-24 16:55:06.000000000 +0100
-++++ mc-4.6.1a/src/widget.c 2005-11-24 16:55:06.000000000 +0100
-+@@ -1948,52 +1948,86 @@ input_new (int y, int x, int color, int
-+ return in;
-+ }
-+
-+-
-+-/* Listbox widget */
-+-
-+-/* Should draw the scrollbar, but currently draws only
-+- * indications that there is more information
-+- */
-+-static int listbox_cdiff (WLEntry *s, WLEntry *e);
-++/* Vertical scrollbar widget */
-+
-+-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 ('^');
-++ addch ('^');
-++#else
-++ if (color) attrset (MARKED_COLOR);
-++ if (is_utf8)
-++ SLsmg_write_string("â–²");
-++ else
-++ 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;
-+@@ -2034,7 +2068,7 @@ listbox_draw (WListbox *l, int focused)
-+ 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,
-+--- mc-4.6.1a/src/screen.c.laf 2005-11-24 16:55:06.000000000 +0100
-++++ mc-4.6.1a/src/screen.c 2005-11-24 16:55:06.000000000 +0100
-+@@ -888,6 +888,9 @@ show_dir (WPanel *panel)
-+ }
-+ #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);
-+
-+@@ -1504,7 +1507,7 @@ use_display_format (WPanel *panel, const
-+ 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);
-+
-+--- mc-4.6.1a/src/widget.h.laf 2005-11-24 16:55:06.000000000 +0100
-++++ mc-4.6.1a/src/widget.h 2005-11-24 16:55:06.000000000 +0100
-+@@ -170,6 +170,10 @@ void button_set_text (WButton *b, const
-+ /* 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);
---- mc-4.6.1.orig/debian/patches/26_vietnamese_po.patch
-+++ mc-4.6.1/debian/patches/26_vietnamese_po.patch
-@@ -0,0 +1,4459 @@
-+--- /dev/null 2005-03-28 19:01:57.000000000 +0200
-++++ po/vi.po 2005-04-03 00:46:14.000000000 +0200
-+@@ -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 "