aboutsummaryrefslogtreecommitdiff
path: root/chinese/pine4
diff options
context:
space:
mode:
authorVanilla I. Shu <vanilla@FreeBSD.org>1998-07-21 14:11:48 +0000
committerVanilla I. Shu <vanilla@FreeBSD.org>1998-07-21 14:11:48 +0000
commite1440990540ff9d3ccec2d75b9fa2b57e750e7e0 (patch)
tree685a05d7146ae079bf8d8ad46ce0b6fd3561dd76 /chinese/pine4
parent5ffa69c61fc1f17cfd9412b296c466d60239f0d3 (diff)
downloadports-e1440990540ff9d3ccec2d75b9fa2b57e750e7e0.tar.gz
ports-e1440990540ff9d3ccec2d75b9fa2b57e750e7e0.zip
Notes
Diffstat (limited to 'chinese/pine4')
-rw-r--r--chinese/pine4/Makefile40
-rw-r--r--chinese/pine4/distinfo2
-rw-r--r--chinese/pine4/files/dot.pinerc.sample333
-rw-r--r--chinese/pine4/files/patch-aa151
-rw-r--r--chinese/pine4/files/patch-ab30
-rw-r--r--chinese/pine4/files/patch-ac426
-rw-r--r--chinese/pine4/files/patch-ad157
-rw-r--r--chinese/pine4/files/patch-af57
-rw-r--r--chinese/pine4/files/patch-ag39
-rw-r--r--chinese/pine4/files/patch-ah607
-rw-r--r--chinese/pine4/files/patch-ai417
-rw-r--r--chinese/pine4/files/patch-aj201
-rw-r--r--chinese/pine4/files/patch-ak61
-rw-r--r--chinese/pine4/files/patch-al172
-rw-r--r--chinese/pine4/files/patch-am156
-rw-r--r--chinese/pine4/files/patch-an5448
-rw-r--r--chinese/pine4/files/patch-ao31
-rw-r--r--chinese/pine4/files/patch-ap1351
-rw-r--r--chinese/pine4/files/patch-aq750
-rw-r--r--chinese/pine4/files/patch-ar1268
-rw-r--r--chinese/pine4/files/patch-as173
-rw-r--r--chinese/pine4/files/patch-au372
-rw-r--r--chinese/pine4/files/patch-av411
-rw-r--r--chinese/pine4/files/patch-aw497
-rw-r--r--chinese/pine4/files/patch-ax79
-rw-r--r--chinese/pine4/files/patch-ay2198
-rw-r--r--chinese/pine4/files/patch-az421
-rw-r--r--chinese/pine4/files/patch-ba297
-rw-r--r--chinese/pine4/files/patch-bb197
-rw-r--r--chinese/pine4/files/patch-bc166
-rw-r--r--chinese/pine4/files/patch-bd843
-rw-r--r--chinese/pine4/files/patch-be425
-rw-r--r--chinese/pine4/files/patch-bf178
-rw-r--r--chinese/pine4/files/patch-bg63
-rw-r--r--chinese/pine4/files/patch-bh68
-rw-r--r--chinese/pine4/files/patch-bi31
-rw-r--r--chinese/pine4/files/patch-bj13
-rw-r--r--chinese/pine4/files/pine.conf43
-rw-r--r--chinese/pine4/pkg-comment2
-rw-r--r--chinese/pine4/pkg-descr18
-rw-r--r--chinese/pine4/pkg-plist12
41 files changed, 14735 insertions, 3469 deletions
diff --git a/chinese/pine4/Makefile b/chinese/pine4/Makefile
index 5ef0b1ed618e..769eb036cdcf 100644
--- a/chinese/pine4/Makefile
+++ b/chinese/pine4/Makefile
@@ -1,24 +1,46 @@
# New ports collection makefile for: pine
-# Version required: 3.96
+# Version required: 4.00
# Date created: 19 Nov1997
# Whom: Wu Ching-hong <woju@FreeBSD.ee.Ntu.edu.TW>
#
-# $Id: Makefile,v 1.1.1.1 1997/12/01 19:47:20 vanilla Exp $
+# $Id: Makefile,v 1.2 1997/12/02 04:23:43 asami Exp $
#
-DISTNAME= pine3.96
-PKGNAME= zh-pine-3.96
+DISTNAME= pine4.00
+PKGNAME= zh-pine-4.00
CATEGORIES= chinese mail news
MASTER_SITES= ftp://ftp.cac.washington.edu/pine/
-MAINTAINER= woju@FreeBSD.ee.Ntu.edu.TW
+MAINTAINER= avatar@www.mmlab.cse.yzu.edu.tw
MAN1= pine.1 pico.1 pilot.1
+do-build:
+ @(cd ${WRKSRC}; ${SETENV} ${MAKE_ENV} ./build bsf)
+
+do-install:
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ ${WRKSRC}/bin/libpico.so.1.3 ${PREFIX}/lib/libpico.so.1.3
+ ${INSTALL_PROGRAM} ${WRKSRC}/bin/pico ${PREFIX}/bin/pico
+ ${INSTALL_PROGRAM} ${WRKSRC}/bin/pilot ${PREFIX}/bin/pilot
+ ${INSTALL_PROGRAM} ${WRKSRC}/bin/pine ${PREFIX}/bin/pine
+ ${INSTALL_SCRIPT} ${FILESDIR}/pgpencrypt ${PREFIX}/bin/pgpencrypt
+ ${INSTALL_SCRIPT} ${FILESDIR}/pgpdecode ${PREFIX}/bin/pgpdecode
+ ${INSTALL_SCRIPT} ${FILESDIR}/pgpsign ${PREFIX}/bin/pgpsign
+ ${INSTALL_DATA} ${FILESDIR}/dot.pinerc.pgp.sample \
+ ${PREFIX}/etc/dot.pinerc.pgp.sample
+ ${INSTALL_DATA} ${FILESDIR}/dot.pinerc.sample \
+ ${PREFIX}/etc/dot.pinerc.sample
+ ${INSTALL_DATA} ${FILESDIR}/pine.conf ${PREFIX}/etc/pine.conf
+ ${INSTALL_MAN} ${WRKSRC}/doc/pico.1 ${PREFIX}/man/man1/pico.1
+ ${INSTALL_MAN} ${WRKSRC}/doc/pilot.1 ${PREFIX}/man/man1/pilot.1
+ ${INSTALL_MAN} ${WRKSRC}/doc/pine.1 ${PREFIX}/man/man1/pine.1
+.if !defined(NOPORTDOCS)
+ ${INSTALL_DATA} -d ${PREFIX}/share/doc/pine
+ ${INSTALL_DATA} ${WRKSRC}/doc/tech-notes.txt ${PREFIX}/share/doc/pine
+.endif
+
post-install:
- ${INSTALL} -d -o ${SHAREOWN} -g ${SHAREGRP} -m 755 \
- ${PREFIX}/share/doc/pine
- cd ${WRKSRC} && \
- ${INSTALL_DATA} doc/tech-notes.txt ${PREFIX}/share/doc/pine
+ ${LDCONFIG} -m ${PREFIX}/lib/
.include <bsd.port.mk>
diff --git a/chinese/pine4/distinfo b/chinese/pine4/distinfo
index 383150f45632..4539b8cda85b 100644
--- a/chinese/pine4/distinfo
+++ b/chinese/pine4/distinfo
@@ -1 +1 @@
-MD5 (pine3.96.tar.gz) = bf32b0bf1296ff2151e1bc7f546d43ab
+MD5 (pine4.00.tar.gz) = 4aa00d67b4060299e9edff744cab6f23
diff --git a/chinese/pine4/files/dot.pinerc.sample b/chinese/pine4/files/dot.pinerc.sample
new file mode 100644
index 000000000000..9b9ef28749cc
--- /dev/null
+++ b/chinese/pine4/files/dot.pinerc.sample
@@ -0,0 +1,333 @@
+# Updated by Pine(tm) 4.00, copyright 1989-1998 University of Washington.
+#
+# Pine configuration file -- customize as needed.
+#
+# This file sets the configuration options used by Pine and PC-Pine. If you
+# are using Pine on a Unix system, there may be a system-wide configuration
+# file which sets the defaults for these variables. There are comments in
+# this file to explain each variable, but if you have questions about
+# specific settings see the section on configuration options in the Pine
+# notes. On Unix, run pine -conf to see how system defaults have been set.
+# For variables that accept multiple values, list elements are separated
+# by commas. A line beginning with a space or tab is considered to be a
+# continuation of the previous line. For a variable to be unset its value
+# must be blank. To set a variable to the empty string its value should
+# be "". You can override system defaults by setting a variable to the
+# empty string. Switch variables are set to either "yes" or "no", and
+# default to "no".
+# Lines beginning with "#" are comments, and ignored by Pine.
+
+########################### Essential Parameters ###########################
+
+# Over-rides your full name from Unix password file. Required for PC-Pine.
+personal-name=
+
+# Sets domain part of From: and local addresses in outgoing mail.
+user-domain=brahms.mmlab.cse.yzu.edu.tw
+
+# List of SMTP servers for sending mail. If blank: Unix Pine uses sendmail.
+smtp-server=brahms.mmlab.cse.yzu.edu.tw
+
+# NNTP server for posting news. Also sets news-collections for news reading.
+nntp-server=news.yzu.edu.tw
+
+# Path of (local or remote) INBOX, e.g. ={mail.somewhere.edu}inbox
+# Normal Unix default is the local INBOX (usually /usr/spool/mail/$USER).
+inbox-path=$MAIL
+
+###################### Collections, Folders, and Files #####################
+
+# List of incoming msg folders besides INBOX, e.g. ={host2}inbox, {host3}inbox
+# Syntax: optnl-label {optnl-imap-host-name}folder-path
+incoming-folders=
+
+# List of directories where saved-message folders may be. First one is
+# the default for Saves. Example: Main {host1}mail/[], Desktop mail\[]
+# Syntax: optnl-label {optnl-imap-hostname}optnl-directory-path[]
+folder-collections=
+
+# List, only needed if nntp-server not set, or news is on a different host
+# than used for NNTP posting. Examples: News *[] or News *{host3/nntp}[]
+# Syntax: optnl-label *{news-host/protocol}[]
+news-collections=
+
+# Over-rides default path for sent-mail folder, e.g. =old-mail (using first
+# folder collection dir) or ={host2}sent-mail or ="" (to suppress saving).
+# Default: sent-mail (Unix) or SENTMAIL.MTX (PC) in default folder collection.
+default-fcc=
+
+# Over-rides default path for postponed messages folder, e.g. =pm (which uses
+# first folder collection dir) or ={host4}pm (using home dir on host4).
+# Default: postponed-mail (Unix) or POSTPONE.MTX (PC) in default fldr coltn.
+postponed-folder=
+
+# If set, specifies where already-read messages will be moved upon quitting.
+read-message-folder=
+
+# Over-rides default path for signature file. Default is ~/.signature
+signature-file=mail/.signature
+
+# List of file or path names for global/shared addressbook(s).
+# Default: none
+# Syntax: optnl-label path-name
+global-address-book=
+
+# List of file or path names for personal addressbook(s).
+# Default: ~/.addressbook (Unix) or \PINE\ADDRBOOK (PC)
+# Syntax: optnl-label path-name
+address-book=
+
+############################### Preferences ################################
+
+# List of features; see Pine's Setup/options menu for the current set.
+# e.g. feature-list= select-without-confirm, signature-at-bottom
+# Default condition for all of the features is no-.
+feature-list=use-8bit-encoding,
+ use-8bit-encoding-confirm,
+ enable-full-header-cmd,
+ signature-at-bottom,
+ pass-control-characters-as-is,
+ enable-mail-check-cue,
+ enable-8bit-esmtp-negotiation,
+ enable-8bit-nntp-posting,
+ quell-dead-letter-on-cancel,
+ compose-send-offers-first-filter,
+ enable-arrow-navigation,
+ enable-msg-view-urls,
+ enable-msg-view-web-hostnames
+
+# Pine executes these keys upon startup (e.g. to view msg 13: i,j,1,3,CR,v)
+initial-keystroke-list=
+
+# Only show these headers (by default) when composing messages
+default-composer-hdrs=
+
+# Add these customized headers (and possible default values) when composing
+customized-hdrs=
+
+# Determines default folder name for Saves...
+# Choices: default-folder, by-sender, by-from, by-recipient, last-folder-used.
+# Default: "default-folder", i.e. "saved-messages" (Unix) or "SAVEMAIL" (PC).
+saved-msg-name-rule=
+
+# Determines default name for Fcc...
+# Choices: default-fcc, by-recipient, last-fcc-used.
+# Default: "default-fcc" (see also "default-fcc=" variable.)
+fcc-name-rule=
+
+# Sets presentation order of messages in Index. Choices:
+# subject, from, arrival, date, size. Default: "arrival".
+sort-key=subject
+
+# Sets presentation order of address book entries. Choices: dont-sort,
+# fullname-with-lists-last, fullname, nickname-with-lists-last, nickname
+# Default: "fullname-with-lists-last".
+addrbook-sort-rule=
+
+# Reflects capabilities of the display you have. Default: US-ASCII.
+# Typical alternatives include ISO-8859-x, (x is a number between 1 and 9).
+character-set=
+
+# Specifies the program invoked by ^_ in the Composer,
+# or the "enable-alternate-editor-implicitly" feature.
+editor=/usr/local/bin/joe
+
+# Program to view images (e.g. GIF or TIFF attachments).
+image-viewer=/usr/X11R6/bin/xli
+
+# If "user-domain" not set, strips hostname in FROM address. (Unix only)
+use-only-domain-name=
+
+########## Set within or by Pine: No need to edit below this line ##########
+
+# Your printer selection
+printer=attached-to-ansi
+
+# Special print command if it isn't one of the standard printers
+personal-print-command=
+
+# Set by Pine; controls beginning-of-month sent-mail pruning.
+last-time-prune-questioned=98.7
+
+# Set by Pine; controls display of "new version" message.
+last-version-used=4.00
+
+# List of folder pairs; the first indicates a folder to archive, and the
+# second indicates the folder read messages in the first should
+# be moved to.
+incoming-archive-folders=
+
+# List of context and folder pairs, delimited by a space, to be offered for
+# pruning each month. For example: {host1}mail/[] mumble
+pruned-folders=
+
+# Over-rides default path for saved-msg folder, e.g. =saved-messages (using first
+# folder collection dir) or ={host2}saved-mail or ="" (to suppress saving).
+# Default: saved-messages (Unix) or SAVEMAIL.MTX (PC) in default folder collection.
+default-saved-msg-folder=
+
+# When viewing messages, include this list of headers
+viewer-hdrs=
+
+# Sets the default folder and collectionoffered at the Goto Command's prompt.
+goto-default-rule=inbox-or-folder-in-first-collection
+
+# Specifies the program invoked by ^T in the Composer.
+speller=
+
+# Specifies the column of the screen where the composer should wrap.
+composer-wrap-column=
+
+# Specifies the string to insert when replying to message.
+reply-indent-string=
+
+# Specifies the string to use when sending a message with no to or cc.
+empty-header-message=
+
+# Which category default print command is in
+personal-print-category=-1
+
+# This names the path to an alternative program, and any necessary arguments,
+# to be used in posting mail messages. Example:
+# /usr/lib/sendmail -oem -t -oi
+# or,
+# /usr/local/bin/sendit.sh
+# The latter a script found in Pine distribution's contrib/util directory.
+# NOTE: The program MUST read the message to be posted on standard input,
+# AND operate in the style of sendmail's "-t" option.
+sendmail-path=/usr/sbin/sendmail -oem -oi -t
+
+# This names the root of the tree to which the user is restricted when reading
+# and writing folders and files. For example, on Unix ~/work confines the
+# user to the subtree beginning with their work subdirectory.
+# (Note: this alone is not sufficient for preventing access. You will also
+# need to restrict shell access and so on, see Pine Technical Notes.)
+# Default: not set (so no restriction)
+operating-dir=
+
+# This variable takes a list of programs that message text is piped into
+# after MIME decoding, prior to display.
+display-filters="-----BEGIN PGP" /usr/local/bin/pgpdecode
+
+# This defines a program that message text is piped into before MIME
+# encoding, prior to sending
+sending-filters=/usr/local/bin/pgpsign,
+ /usr/local/bin/pgpencrypt _RECIPIENTS_
+
+# A list of alternate addresses the user is known by
+alt-addresses=
+
+# This is a list of formats for address books. Each entry in the list is made
+# up of space-delimited tokens telling which fields are displayed and in
+# which order. See help text
+addressbook-formats=
+
+# This gives a format for displaying the index. It is made
+# up of space-delimited tokens telling which fields are displayed and in
+# which order. See help text
+index-format=
+
+# The number of lines of overlap when scrolling through message text
+viewer-overlap=
+
+# Number of lines from top and bottom of screen where single
+# line scrolling occurs.
+scroll-margin=
+
+# The number of seconds to sleep after writing a status message
+status-message-delay=
+
+# The approximate number of seconds between checks for new mail
+mail-check-interval=
+
+# Full path and name of NEWSRC file
+newsrc-path=
+
+# Path and filename of news configation's active file.
+# The default is typically "/usr/lib/news/active".
+news-active-file-path=
+
+# Directory containing system's news data.
+# The default is typically "/usr/spool/news"
+news-spool-directory=
+
+# Path and filename of the program used to upload text from your terminal
+# emulator's into Pine's composer.
+upload-command=
+
+# Text sent to terminal emulator prior to invoking the program defined by
+# the upload-command variable.
+# Note: _FILE_ will be replaced with the temporary file used in the upload.
+upload-command-prefix=
+
+# Path and filename of the program used to download text via your terminal
+# emulator from Pine's export and save commands.
+download-command=
+
+# Text sent to terminal emulator prior to invoking the program defined by
+# the download-command variable.
+# Note: _FILE_ will be replaced with the temporary file used in the downlaod.
+download-command-prefix=
+
+# Sets the search path for the mailcap cofiguration file.
+# NOTE: colon delimited under UNIX, semi-colon delimited under DOS/Windows/OS2.
+mailcap-search-path=
+
+# Sets the search path for the mimetypes cofiguration file.
+# NOTE: colon delimited under UNIX, semi-colon delimited under DOS/Windows/OS2.
+mimetype-search-path=
+
+# Sets the time in seconds that Pine will attempt to open a network
+# connection. The default is 30, the minimum is 5, and the maximum is
+# system defined (typically 75).
+tcp-open-timeout=
+
+# Sets the time in seconds that Pine will attempt to open a UNIX remote
+# shell connection. The default is 15, min is 5, and max is unlimited.
+# Zero disables rsh altogether.
+rsh-open-timeout=
+
+# Sets the version number Pine will use as a threshold for offering
+# its new version message on startup.
+new-version-threshold=
+
+# If set, specifies where form letters should be stored.
+form-letter-folder=
+
+# Sets presentation order of folder list entries. Choices: ,
+#
+# Default: "alpha-with-directories-last".
+folder-sort-rule=
+
+# Sets message which cursor begins on. Choices: first-unseen, first-recent,
+# first, last. Default: "first-unseen".
+incoming-startup-rule=
+
+# If no user input for this many hours, Pine will exit if in an idle loop
+# waiting for a new command. If set to zero (the default), then there will
+# be no timeout.
+user-input-timeout=
+
+# Sets the name of the command used to open a UNIX remote shell connection.
+# The default is tyically /usr/ucb/rsh.
+rsh-path=/usr/local/bin/ssh
+
+# Sets the format of the command used to open a UNIX remote
+# shell connection. The default is "%s %s -l %s exec /etc/r%sd"
+# NOTE: the 4 (four) "%s" entries MUST exist in the provided command
+# where the first is for the command's path, the second is for the
+# host to connnect to, the third is for the user to connect as, and the
+# fourth is for the connection method (typically "imap")
+rsh-command=
+
+# List of programs to open Internet URLs (e.g. http or ftp references).
+url-viewers=/usr/local/bin/lynx
+
+# List of mail drivers to disable. See technical notes.
+disable-these-drivers=
+
+# Set by Pine; contains data for caching remote address books.
+remote-abook-metafile=
+
+# How many extra copies of remote address book should be kept. Default: 3
+remote-abook-history=
diff --git a/chinese/pine4/files/patch-aa b/chinese/pine4/files/patch-aa
index ae7d1c175683..6d30bc5ae927 100644
--- a/chinese/pine4/files/patch-aa
+++ b/chinese/pine4/files/patch-aa
@@ -1,100 +1,51 @@
-*** pico/makefile.bsf.orig Fri Jun 14 00:15:20 1996
---- pico/makefile.bsf Fri Jun 14 00:15:20 1996
-***************
-*** 0 ****
---- 1,95 ----
-+ #
-+ # Michael Seibel
-+ # Networks and Distributed Computing
-+ # Computing and Communications
-+ # University of Washington
-+ # Administration Builiding, AG-44
-+ # Seattle, Washington, 98195, USA
-+ # Internet: mikes@cac.washington.edu
-+ #
-+ # Please address all bugs and comments to "pine-bugs@cac.washington.edu"
-+ #
-+ #
-+ # Pine and Pico are registered trademarks of the University of Washington.
-+ # No commercial use of these trademarks may be made without prior written
-+ # permission of the University of Washington.
-+ #
-+ # Pine, Pico, and Pilot software and its included text are Copyright
-+ # 1989-1996 by the University of Washington.
-+ #
-+ # The full text of our legal notices is contained in the file called
-+ # CPYRIGHT, included with this distribution.
-+ #
-+
-+ #
-+ # Makefile for the FreeBSD shared-lib version of the PINE composer library and
-+ # stand-alone editor pico.
-+ #
-+
-+ #includes symbol info for debugging
-+ DASHO= # -g
-+ #for normal build
-+ #DASHO= -O
-+
-+ STDCFLAGS= -DBSDI -DBSDI2 -DPOSIX -DJOB_CONTROL -DANSI -DMOUSE
-+ CFLAGS+= $(EXTRACFLAGS) $(DASHO) $(STDCFLAGS)
-+
-+ # switches for library building
-+ LIBCMD= ar
-+ LIBARGS= ru
-+ RANLIB= ranlib
-+
-+ LIBS= $(EXTRALIBES) -ltermcap
-+
-+ OFILES= attach.o ansi.o basic.o bind.o browse.o buffer.o \
-+ composer.o display.o file.o fileio.o line.o osdep.o \
-+ pico.o random.o region.o search.o spell.o tcap.o window.o word.o
-+
-+ # Lets be elite and not retype in the above
-+ SOFILES= ${OFILES:.o=.so}
-+
-+ CFILES= attach.c ansi.c basic.c bind.c browse.c buffer.c \
-+ composer.c display.c file.c fileio.c line.c osdep.c \
-+ pico.c random.c region.c search.c spell.c tcap.c window.c word.c
-+
-+ HFILES= estruct.h edef.h efunc.h ebind.h pico.h osdep.h
-+
-+ # Need this for the shared library rule to work correctly
-+ .SUFFIXES: .o .so
-+
-+ #
-+ # dependencies for the Unix versions of pico and libpico.a
-+ #
-+ all: pico pilot
-+
-+ osdep.c: os_unix.c
-+ rm -f osdep.c
-+ cp os_unix.c osdep.c
-+
-+ osdep.h: os_unix.h
-+ rm -f osdep.h
-+ cp os_unix.h osdep.h
-+
-+ libpico.a: osdep.c osdep.h $(OFILES)
-+ $(LIBCMD) $(LIBARGS) libpico.a $(OFILES)
-+ $(RANLIB) libpico.a
-+
-+ libpico.so.1.3: osdep.c osdep.h $(SOFILES)
-+ ld -Bshareable -x -o libpico.so.1.3 $(SOFILES)
-+
-+ pico: main.c libpico.so.1.3
-+ $(CC) $(CFLAGS) main.c -L. -lpico $(LIBS) -o pico
-+
-+ pilot: pilot.c libpico.so.1.3
-+ $(CC) $(CFLAGS) pilot.c -L. -lpico $(LIBS) -o pilot
-+
-+ .c.so: ; $(CC) -fpic -DPIC -c $(CFLAGS) ${@:.so=.c} -o $@
-+
-+ .c.o: ; $(CC) -c $(CFLAGS) $*.c
-+
-+ $(OFILES): $(HFILES)
-+
-+ $(SOFILES): $(HFILES)
-+
-+ clean:
-+ rm -f *.a *.so.1.3 *.o *.so *~ osdep.c osdep.h pico pilot
+--- imap/src/osdep/unix/Makefile.orig Thu Jul 9 05:49:11 1998
++++ imap/src/osdep/unix/Makefile Tue Jul 21 21:09:14 1998
+@@ -75,7 +75,7 @@
+ # Commands possibly overriden by the individual port
+
+ ARRC=ar rc
+-CC=cc
++#CC=cc
+ LN=ln -s
+ RANLIB=ranlib
+
+@@ -93,7 +93,7 @@
+ dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
+ rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
+ unix.o mbox.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o
+-CFLAGS=$(BASECFLAGS) $(EXTRACFLAGS)
++#CFLAGS=$(BASECFLAGS) $(EXTRACFLAGS)
+ MAKE=make
+ MV=mv
+ RM=rm -rf
+@@ -183,7 +183,7 @@
+ SPOOLDIR=/var \
+ ACTIVEFILE=/usr/local/news/lib/active \
+ RSHPATH=/usr/bin/rsh \
+- BASECFLAGS="-g -O -pipe -DNFSKLUDGE" \
++ CFLAGS="${CFLAGS} -DNFSKLUDGE $(EXTRACFLAGS)" \
+ BASELDFLAGS="-lcrypt"
+
+ bsi: # BSD/i386
+--- pico/makefile.bsf.orig Tue Jul 21 21:17:35 1998
++++ pico/makefile.bsf Tue Jul 21 21:17:53 1998
+@@ -37,7 +37,7 @@
+ DEBUG= -DDEBUG # -g
+
+ STDCFLAGS= -DBSDI -DBSDI2 -DPOSIX -DJOB_CONTROL -DMOUSE
+-CFLAGS+= $(OPTIMIZE) $(PROFILE) $(DEBUG) $(EXTRACFLAGS) $(STDCFLAGS)
++CFLAGS+= $(OPTIMIZE) $(PROFILE) $(EXTRACFLAGS) $(STDCFLAGS)
+
+ # switches for library building
+ LIBCMD= ar
+--- pine/makefile.bsf.orig Tue Jul 21 21:21:11 1998
++++ pine/makefile.bsf Tue Jul 21 21:21:55 1998
+@@ -69,7 +69,7 @@
+ `cat $(CCLIENTDIR)/LDFLAGS`
+
+ STDCFLAGS= -DBSDI -DSYSTYPE=\"BSF\" -DMOUSE
+-CFLAGS+= $(OPTIMIZE) $(PROFILE) $(DEBUG) $(EXTRACFLAGS) $(LDAPCFLAGS) \
++CFLAGS+= $(OPTIMIZE) $(PROFILE) $(EXTRACFLAGS) $(LDAPCFLAGS) \
+ $(STDCFLAGS)
+
+ OFILES= addrbook.o adrbkcmd.o adrbklib.o args.o bldaddr.o context.o filter.o \
diff --git a/chinese/pine4/files/patch-ab b/chinese/pine4/files/patch-ab
index ea73b2fddef4..b92d69d2aa96 100644
--- a/chinese/pine4/files/patch-ab
+++ b/chinese/pine4/files/patch-ab
@@ -1,15 +1,15 @@
-*** pico/os_unix.c.orig Wed Jun 12 15:47:21 1996
---- pico/os_unix.c Fri Jun 14 00:15:30 1996
-***************
-*** 1343,1347 ****
- extern int sys_nerr;
-
-! return((err >= 0 && err < sys_nerr) ? sys_errlist[err] : NULL);
- }
-
---- 1343,1347 ----
- extern int sys_nerr;
-
-! return(((err >= 0) && (err < sys_nerr)) ? (char*)sys_errlist[err] : NULL);
- }
-
+--- imap/src/osdep/unix/os_bsi.h.orig Thu Feb 13 13:25:33 1997
++++ imap/src/osdep/unix/os_bsi.h Wed Jul 15 17:02:29 1998
+@@ -37,7 +37,12 @@
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/types.h>
++#ifdef __FreeBSD__
++#include <dirent.h>
++#define direct dirent
++#else
+ #include <sys/dir.h>
++#endif
+ #include <fcntl.h>
+ #include <syslog.h>
+ #include <sys/file.h>
diff --git a/chinese/pine4/files/patch-ac b/chinese/pine4/files/patch-ac
index 40842ed0c9b0..019b2b798002 100644
--- a/chinese/pine4/files/patch-ac
+++ b/chinese/pine4/files/patch-ac
@@ -1,411 +1,15 @@
-*** pine/osdep/os-bsf.h.orig Tue Dec 3 16:36:18 1996
---- pine/osdep/os-bsf.h Tue Dec 3 17:46:48 1996
-***************
-*** 0 ****
---- 1,406 ----
-+ /*----------------------------------------------------------------------
-+
-+ T H E P I N E M A I L S Y S T E M
-+
-+ Laurence Lundblade and Mike Seibel
-+ Networks and Distributed Computing
-+ Computing and Communications
-+ University of Washington
-+ Administration Builiding, AG-44
-+ Seattle, Washington, 98195, USA
-+ Internet: lgl@CAC.Washington.EDU
-+ mikes@CAC.Washington.EDU
-+
-+ Please address all bugs and comments to "pine-bugs@cac.washington.edu"
-+
-+
-+ Pine and Pico are registered trademarks of the University of Washington.
-+ No commercial use of these trademarks may be made without prior written
-+ permission of the University of Washington.
-+
-+ Pine, Pico, and Pilot software and its included text are Copyright
-+ 1989-1996 by the University of Washington.
-+
-+ The full text of our legal notices is contained in the file called
-+ CPYRIGHT, included with this distribution.
-+
-+
-+ Pine is in part based on The Elm Mail System:
-+ ***********************************************************************
-+ * The Elm Mail System - Revision: 2.13 *
-+ * *
-+ * Copyright (c) 1986, 1987 Dave Taylor *
-+ * Copyright (c) 1988, 1989 USENET Community Trust *
-+ ***********************************************************************
-+
-+
-+ ----------------------------------------------------------------------*/
-+
-+ #ifndef _OS_INCLUDED
-+ #define _OS_INCLUDED
-+
-+
-+ /*----------------------------------------------------------------------
-+
-+ This first section has some constants that you may want to change
-+ for your configuration. This is the BSD/386 Gamma 4.1 version of the
-+ os.h file.
-+ Further down in the file are os-dependent things that need to be set up
-+ correctly for each os. They aren't interesting, they just have to be
-+ right. There are also a few constants down there that may be of
-+ interest to some.
-+
-+ ----*/
-+
-+ /*----------------------------------------------------------------------
-+ Define this if you want the disk quota to be checked on startup.
-+ Of course, this only makes sense if your system has quotas. If it doesn't,
-+ there should be a dummy disk_quota() routine in os-xxx.c so that defining
-+ this won't be harmful anyway.
-+ ----*/
-+ /* #define USE_QUOTAS /* comment out if you never want quotas checked */
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Define this if you want to allow the users to change their From header
-+ line when they send out mail. The users will still have to configure
-+ either default-composer-hdrs or customized-hdrs to get at the From
-+ header, even if this is set.
-+ ----*/
-+ #define ALLOW_CHANGING_FROM /* comment out to not allow changing From */
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Define this if you want to allow users to turn on the feature that
-+ enables sending to take place in a fork()'d child. This may reduce
-+ the time on the user's wall clock it takes to post mail.
-+ NOTE: You'll also have to make sure the appropriate osdep/postreap.*
-+ file is included in the os-*.ic file for your system.
-+ ----*/
-+ #define BACKGROUND_POST /* comment out to disable posting from child */
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Turn this on if you want to disable the keyboard lock function.
-+ ----*/
-+ /* #define NO_KEYBOARD_LOCK */
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Turn this on to trigger QP encoding of sent message text if it contains
-+ "From " at the beginning of a line or "." on a line by itself.
-+ ----*/
-+ /* #define ENCODE_FROMS */
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Timeouts (seconds)
-+ ----*/
-+ #define DF_MAILCHECK "150" /* How often to check for new mail, by
-+ default. There's some expense in doing
-+ this so it shouldn't be done too
-+ frequently. (Can be set in config
-+ file now.) */
-+
-+ /*----------------------------------------------------------------------
-+ Check pointing (seconds)
-+ ----*/
-+ #define CHECK_POINT_TIME (7*60) /* Check point the mail file (write changes
-+ to disk) if more than CHECK_POINT_TIME
-+ seconds have passed since the first
-+ change was made. Depending on what is
-+ happening, we may wait up to three times
-+ this long, since we don't want to do the
-+ slow check pointing and irritate the user. */
-+
-+ #define CHECK_POINT_FREQ (12) /* Check point the mail file if there have been
-+ at least this many (status) changes to the
-+ current mail file. We may wait longer if
-+ it isn't a good time to do the checkpoint. */
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ In scrolling through text, the number of lines from the previous
-+ screen to overlap when showing the next screen. Usually set to two.
-+ ----*/
-+ #define DF_OVERLAP "2"
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ When scrolling screens, the number of lines from top and bottom of
-+ the screen to initiate single-line scrolling.
-+ ----*/
-+ #define DF_MARGIN "0"
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Default fill column for pine composer and maximum fill column. The max
-+ is used to stop people from setting their custom fill column higher than
-+ that number. Note that DF_FILLCOL is a string but MAX_FILLCOL is an integer.
-+ ----*/
-+ #define DF_FILLCOL "74"
-+ #define MAX_FILLCOL 80
-+
-+
-+
-+ /*----- System-wide config file ----------------------------------------*/
-+ #define SYSTEM_PINERC "/usr/local/etc/pine.conf"
-+ #define SYSTEM_PINERC_FIXED "/usr/local/etc/pine.conf.fixed"
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ The default folder names and folder directories (some for backwards
-+ compatibility). Think hard before changing any of these.
-+ ----*/
-+ #define DF_DEFAULT_FCC "sent-mail"
-+ #define DEFAULT_SAVE "saved-messages"
-+ #define POSTPONED_MAIL "postponed-mail"
-+ #define POSTPONED_MSGS "postponed-msgs"
-+ #define INTERRUPTED_MAIL ".pine-interrupted-mail"
-+ #define DEADLETTER "dead.letter"
-+ #define DF_MAIL_DIRECTORY "mail"
-+ #define INBOX_NAME "INBOX"
-+ #define DF_SIGNATURE_FILE ".signature"
-+ #define DF_ELM_STYLE_SAVE "no"
-+ #define DF_HEADER_IN_REPLY "no"
-+ #define DF_OLD_STYLE_REPLY "no"
-+ #define DF_USE_ONLY_DOMAIN_NAME "no"
-+ #define DF_FEATURE_LEVEL "sapling"
-+ #define DF_SAVE_BY_SENDER "no"
-+ #define DF_SORT_KEY "arrival"
-+ #define DF_AB_SORT_RULE "fullname-with-lists-last"
-+ #define DF_SAVED_MSG_NAME_RULE "default-folder"
-+ #define DF_FCC_RULE "default-fcc"
-+ #define DF_STANDARD_PRINTER "lpr"
-+ #define ANSI_PRINTER "attached-to-ansi"
-+ #define DF_ADDRESSBOOK ".addressbook"
-+ #define DF_BUGS_FULLNAME "Pine Developers"
-+ #define DF_BUGS_ADDRESS "pine-bugs@cac.washington.edu"
-+ #define DF_SUGGEST_FULLNAME "Pine Developers"
-+ #define DF_SUGGEST_ADDRESS "pine-suggestions@cac.washington.edu"
-+ #define DF_PINEINFO_FULLNAME "Pine-Info News Group"
-+ #define DF_PINEINFO_ADDRESS "pine-info@cac.washington.edu"
-+ #define DF_LOCAL_FULLNAME "Local Support"
-+ #define DF_LOCAL_ADDRESS "postmaster"
-+ #define DF_KBLOCK_PASSWD_COUNT "1"
-+
-+ /*----------------------------------------------------------------------
-+ The default printer when pine starts up for the first time with no printer
-+ ----*/
-+ #define DF_DEFAULT_PRINTER ANSI_PRINTER
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+
-+ OS dependencies, BSD/386 Gamma 4.1 version. See also the os-bsi.c files.
-+ The following stuff may need to be changed for a new port, but once
-+ the port is done, it won't change. At the bottom of the file are a few
-+ constants that you may want to configure differently than they
-+ are configured, but probably not.
-+
-+ ----*/
-+
-+
-+
-+ /*----------------- Are we ANSI? ---------------------------------------*/
-+ #define ANSI /* this is an ANSI compiler */
-+
-+ /*------ If our compiler doesn't understand type void ------------------*/
-+ /* #define void char /* no void in compiler */
-+
-+
-+
-+ /*------- Some more includes that should usually be correct ------------*/
-+ #include <pwd.h>
-+ #include <sys/wait.h>
-+ #include <sys/stat.h>
-+ #include <fcntl.h>
-+ #include <netdb.h>
-+
-+
-+
-+ /*----------------- locale.h -------------------------------------------*/
-+ #include <locale.h> /* To make matching and sorting work right */
-+
-+
-+
-+ /*----------------- time.h ---------------------------------------------*/
-+ #include <time.h>
-+ /* plain time.h isn't enough on some systems */
-+ /* #include <sys/time.h> /* For struct timeval usually in time.h */
-+
-+
-+
-+ /*--------------- signal.h ---------------------------------------------*/
-+ #include <signal.h> /* sometimes both required, sometimes */
-+ /* #include <sys/signal.h> /* only one or the other */
-+
-+ #define SigType void /* value returned by sig handlers is void */
-+ /* #define SigType int /* value returned by sig handlers is int */
-+
-+ #define POSIX_SIGNALS /* use POSIX signal semantics (ttyin.c) */
-+ /* #define SYSV_SIGNALS /* use System-V signal semantics (ttyin.c) */
-+
-+
-+
-+
-+ /*-------------- A couple typedef's for integer sizes ------------------*/
-+ typedef unsigned int usign32_t;
-+ typedef unsigned short usign16_t;
-+
-+
-+
-+ /*-------------- qsort argument type -----------------------------------*/
-+ #define QSType void /* qsort arg is of type void * */
-+ /* #define QSType char /* qsort arg is of type char * */
-+
-+
-+
-+ /*-------------- fcntl flag to set non-blocking IO ---------------------*/
-+ #define NON_BLOCKING_IO O_NONBLOCK /* POSIX style */
-+ /* #define NON_BLOCKING_IO FNDELAY /* good ol' bsd style */
-+
-+
-+
-+ /*------ how help text is referenced (always char ** on Unix) ----------*/
-+ #define HelpType char **
-+ #define NO_HELP (char **)NULL
-+
-+
-+
-+ /*
-+ * Choose one of the following three terminal drivers
-+ */
-+
-+ /*--------- Good 'ol BSD -----------------------------------------------*/
-+ /* #include <sgtty.h> /* BSD-based systems */
-+
-+ /*--------- System V terminal driver -----------------------------------*/
-+ /* #define HAVE_TERMIO /* this is for pure System V */
-+ /* #include <termio.h> /* Sys V */
-+
-+ /*--------- POSIX terminal driver --------------------------------------*/
-+ #define HAVE_TERMIOS /* this is an alternative */
-+ #include <termios.h> /* POSIX */
-+
-+
-+
-+ /*-------- Use poll system call instead of select ----------------------*/
-+ /* #define USE_POLL /* use the poll() system call instead of select() */
-+
-+
-+
-+ /*-------- Use terminfo database instead of termcap --------------------*/
-+ /* #define USE_TERMINFO /* use terminfo instead of termcap */
-+
-+
-+
-+ /*-- What argument does wait(2) take? Define this if it is a union -----*/
-+ /* #define HAVE_WAIT_UNION /* the arg to wait is a union wait * */
-+
-+
-+
-+ /*-------- Is window resizing available? -------------------------------*/
-+ #if defined(TIOCGWINSZ) && defined(SIGWINCH)
-+ #define RESIZING /* SIGWINCH and friends */
-+ #endif
-+
-+
-+
-+ /*-------- If no vfork, use regular fork -------------------------------*/
-+ /* #define vfork fork /* vfork is just a lightweight fork, so can use fork */
-+
-+
-+
-+ /*----- The usual sendmail configuration for sending mail on Unix ------*/
-+ #define SENDMAIL "/usr/sbin/sendmail"
-+ #define SENDMAILFLAGS "-bs -odb -oem" /* send via smtp with backgroud
-+ delivery and mail back errors */
-+
-+
-+ /*----------------------------------------------------------------------
-+ If no nntp-servers are defined, this program will be used to post news.
-+ ----*/
-+ #define SENDNEWS "/usr/local/news/lib/inews -h" /* news posting cmd */
-+
-+
-+ /*--------- Program employed by users to change their password ---------*/
-+ #define PASSWD_PROG "/usr/bin/passwd"
-+
-+
-+ /*-------------- A couple constants used to size arrays ----------------*/
-+ #include <sys/param.h> /* Get it from param.h if available */
-+ #undef MAXPATH /* Sometimes defined in param.h differently */
-+ #define MAXPATH MAXPATHLEN /* Longest pathname we ever expect */
-+ /* #define MAXPATH (512) /* Longest pathname we ever expect */
-+ #define MAXFOLDER (64) /* Longest foldername we ever expect */
-+
-+
-+ /*-- Max screen pine will display on. Used to define some array sizes --*/
-+ #define MAX_SCREEN_COLS (170)
-+ #define MAX_SCREEN_ROWS (200)
-+
-+
-+ /*---- When no screen size can be discovered this is the size used -----*/
-+ #define DEFAULT_LINES_ON_TERMINAL (24)
-+ #define DEFAULT_COLUMNS_ON_TERMINAL (80)
-+
-+
-+ /*----------------------------------------------------------------------
-+ Where to put the output of pine in debug mode. Files are created
-+ in the user's home directory and have a number appended to them when
-+ there is more than one.
-+ ----*/
-+ #define DEBUGFILE ".pine-debug"
-+
-+ /*----------------------------------------------------------------------
-+ The number of debug files to save in the user's home diretory. The files
-+ are useful for figuring out what a user did when he complains that something
-+ went wrong. It's important to keep a bunch around, usually 4, so that the
-+ debug file in question will still be around when the problem gets
-+ investigated. Users tend to go in and out of Pine a few times and there
-+ is one file for each pine invocation
-+ ----*/
-+ #define NUMDEBUGFILES 4
-+
-+ /*----------------------------------------------------------------------
-+ The default debug level to set (approximate meanings):
-+ 1 logs only highest level events and errors
-+ 2 logs events like file writes
-+ 3
-+ 4 logs each command
-+ 5
-+ 6
-+ 7 logs details of command execution (7 is highest to run any production)
-+ 8
-+ 9 logs gross details of command execution
-+ ----*/
-+ #define DEFAULT_DEBUG 0
-+
-+
-+
-+ /*----------------------------------------------------------------------
-+ Various maximum field lengths, probably shouldn't be changed.
-+ ----*/
-+ #define MAX_FULLNAME (100)
-+ #define MAX_NICKNAME (40)
-+ #define MAX_ADDRESS (200)
-+ #define MAX_NEW_LIST (500) /* Max addrs to be added when creating list */
-+ #define MAX_SEARCH (100) /* Longest string to search for */
-+ #define MAX_ADDR_EXPN (1000) /* Longest expanded addr */
-+ #define MAX_ADDR_FIELD (10000) /* Longest fully-expanded addr field */
-+
-+
-+ #endif /* _OS_INCLUDED */
-+
-+
+--- imap/src/osdep/unix/unix.c.orig Tue Jun 23 08:25:52 1998
++++ imap/src/osdep/unix/unix.c Wed Jul 15 17:02:29 1998
+@@ -1006,7 +1006,11 @@
+ /* try again if file exists(?) */
+ if (!stat (hitch,&sb)) break;
+ /* punt silently if paranoid site */
+- if (mail_parameters (NIL,GET_LOCKEACCESERROR,NIL))
++ if (
++#ifdef __FreeBSD__
++ strncmp(lock,"/var/mail/",10) && /* /var/mail/... isn't lockable */
++#endif
++ mail_parameters (NIL,GET_LOCKEACCESERROR,NIL))
+ default: /* some other error */
+ mm_log (tmp,WARN); /* this is probably not good */
+ *lock = '\0'; /* give up on lock file */
diff --git a/chinese/pine4/files/patch-ad b/chinese/pine4/files/patch-ad
index 4db92fa563ed..90b84b4c3253 100644
--- a/chinese/pine4/files/patch-ad
+++ b/chinese/pine4/files/patch-ad
@@ -1,138 +1,19 @@
-*** pine/osdep/os-bsf.ic.orig Fri Jun 14 00:15:47 1996
---- pine/osdep/os-bsf.ic Fri Jun 14 00:57:02 1996
-***************
-*** 0 ****
---- 1,133 ----
-+ ;
-+ ; FreeBSD os-fbs.ic file for building os-fbs.c.
-+ ;
-+ ; Boilerplate header.
-+ include(header)
-+
-+ ; Can_access function. Just calls access. Only one version available.
-+ include(canacces)
-+
-+ ; File_size function. Only one version available.
-+ include(filesize)
-+
-+ ; Is_writable_dir function. Only one version available.
-+ include(writ_dir)
-+
-+ ; Create_mail_dir function. All Unixes use creatdir and DOS
-+ ; uses creatdir.dos.
-+ include(creatdir)
-+
-+ ; Rename_file function. All Unixes use rename and DOS uses
-+ ; rename.dos. There is also one called rename.hom which
-+ ; is currently unused. Hom stands for homemade.
-+ include(rename)
-+
-+ ; Build_path function. All Unixes use bld_path and DOS
-+ ; uses bld_path.dos.
-+ include(bld_path)
-+
-+ ; Last_cmpnt function. All Unixes use lstcmpnt and DOS
-+ ; uses lstcmpnt.dos.
-+ include(lstcmpnt)
-+
-+ ; Expand_foldername function. All Unixes use expnfldr and DOS
-+ ; uses expnfldr.dos.
-+ include(expnfldr)
-+
-+ ; Fnexpand function. All Unixes use fnexpand and DOS
-+ ; uses fnexpand.dos.
-+ include(fnexpand)
-+
-+ ; Filter_filename function. All Unixes use fltrname and DOS
-+ ; uses fltrname.dos.
-+ include(fltrname)
-+
-+ ; There are several versions of disk quotas. Standard BSD-style quotas
-+ ; (Australian) include diskquot. Systems which don't have quotas use
-+ ; diskquot.non. Systems which use Sun-style quotas are slightly more
-+ ; complicated. They usually require different include files. They are
-+ ; set up to include the file sunquota and prepend include file info to
-+ ; that. See diskquot.*.
-+ include(diskquot.non)
-+
-+ ; Read_file function. All Unixes use readfile and DOS
-+ ; uses readfile.dos.
-+ include(readfile)
-+
-+ ; Create_tmpfile function. This usually just calls the ANSI standard
-+ ; tmpfile function if there is one. That is the version in the file tempfile.
-+ ; There is also a tempfile.non for Unix systems which don't have a tmpfile
-+ ; function already.
-+ include(tempfile)
-+
-+ ; Temp_nam function. This usually just calls the "standard"
-+ ; tmpnam function if there is one. That is the version in the file tempnam.
-+ include(tempnam)
-+
-+ ; Coredump function. Version called coredump just calls abort, coredump.fpe
-+ ; uses a floating point exception to cause the coredump on some systems.
-+ include(coredump)
-+
-+ ; This is usually a call to gethostname. That version is in the file hostname.
-+ ; There is also a version called hostname.una which uses the uname system
-+ ; call commonly found in SysV systems. An unused version called
-+ ; hostname.hom also exists.
-+ include(hostname)
-+
-+ ; Getdomainnames function. All Unixes use domnames and DOS
-+ ; uses domnames.dos.
-+ include(domnames)
-+
-+ ; Canonical_name function. All Unixes use canonicl and DOS
-+ ; uses canonicl.dos.
-+ include(canonicl)
-+
-+ ; This file includes two functions, have_job_control and stop_process.
-+ ; The Unix version is called jobcntrl and the slightly-different DOS
-+ ; version is jobcntrl.dos.
-+ include(jobcntrl)
-+
-+ ; Error_desciption function. All Unixes use err_desc. The version
-+ ; called err_desc.dos is the same except that it doesn't declare the
-+ ; variable sys_errlist[], which is already declared. There
-+ ; is also a version called err_desc.hom which is unused.
-+ include(err_desc.dos)
-+
-+ ; There are six functions in this include. They are get_system_login,
-+ ; get_system_fullname, get_system_homedir, get_system_passwd, gcos_name,
-+ ; and local_name_lookup. The Unix version is pw_stuff and the dos version
-+ ; is pw_stuff.dos. There is also a pw_stuff.fun. Fun stands for funny
-+ ; GCOS field. It's currently unused.
-+ include(pw_stuff)
-+
-+ ; Change_passwd function. Unixes use chnge_pw.
-+ ; There is also a DOS version.
-+ include(chnge_pw)
-+
-+ ; Mime_can_display function. Only a single version of this now.
-+ include(mimedisp)
-+
-+ ; Most systems have the ANSI fgetpos and fsetpos functions. For those,
-+ ; use fgetpos. If a system doesn't have it use fgetpos.non.
-+ include(fgetpos)
-+
-+ ; These functions are similar to popen(), but allow both an input stream
-+ ; and an output buffer.
-+ include(pipe)
-+
-+ ; These functions are used to wait on a fork'd child doing our posting
-+ include(postreap.wtp)
-+
-+ ; These functions are used to hand messages off to local mail transport
-+ ; and posting agents (typically, "sendmail").
-+ include(sendmail)
-+
-+ ; This function is used to actually spawn the given command (usually dredged
-+ ; from mailcap) on the given data file (usually on /tmp).
-+ include(execview)
-+
-+ ; This includes the various routines to support printing
-+ include(print)
-+
-+ ; Debug file maintenance.
-+ include(debuging)
+--- imap/Makefile.orig Wed Apr 29 07:38:46 1998
++++ imap/Makefile Wed Jul 15 17:02:29 1998
+@@ -250,12 +250,12 @@
+ $(TOOLS)/$@ "$(LN)" src/charset c-client
+ $(LN) `pwd`/src/kerberos/* c-client
+ $(TOOLS)/$@ "$(LN)" src/osdep/$(SYSTEM) c-client
+- $(TOOLS)/$@ "$(LN)" src/mtest mtest
+- $(TOOLS)/$@ "$(LN)" src/ipopd ipopd
+- $(TOOLS)/$@ "$(LN)" src/imapd imapd
++# $(TOOLS)/$@ "$(LN)" src/mtest mtest
++# $(TOOLS)/$@ "$(LN)" src/ipopd ipopd
++# $(TOOLS)/$@ "$(LN)" src/imapd imapd
+ $(LN) $(TOOLS)/$@ .
+
+-build: OSTYPE rebuild rebuildclean bundled
++build: OSTYPE rebuild rebuildclean # bundled
+
+ OSTYPE:
+ @echo Building c-client for $(OS)...
diff --git a/chinese/pine4/files/patch-af b/chinese/pine4/files/patch-af
index 7fbd6dc999e0..5b02a1835d24 100644
--- a/chinese/pine4/files/patch-af
+++ b/chinese/pine4/files/patch-af
@@ -1,37 +1,20 @@
-*** imap/ANSI/c-client/Makefile.orig Sat Jun 22 01:25:45 1996
---- imap/ANSI/c-client/Makefile Sun Jan 12 19:41:38 1997
-***************
-*** 36,43 ****
- BINARIES=mail.o bezerk.o mtx.o tenex2.o mbox.o mh.o mmdf.o imap2.o pop3.o \
- news.o nntpcunx.o phile.o dummy.o smtp.o nntp.o rfc822.o misc.o \
- osdep.o sm_unix.o newsrc.o
-! CC=cc
-! CFLAGS=$(EXTRACFLAGS)
- DEFAULTDRIVERS=imap nntp pop3 mh tenex mtx mmdf bezerk news phile dummy
- LN=ln -s
- MAKE=make
---- 36,43 ----
- BINARIES=mail.o bezerk.o mtx.o tenex2.o mbox.o mh.o mmdf.o imap2.o pop3.o \
- news.o nntpcunx.o phile.o dummy.o smtp.o nntp.o rfc822.o misc.o \
- osdep.o sm_unix.o newsrc.o
-! #CC=cc
-! #CFLAGS=$(EXTRACFLAGS)
- DEFAULTDRIVERS=imap nntp pop3 mh tenex mtx mmdf bezerk news phile dummy
- LN=ln -s
- MAKE=make
-***************
-*** 118,123 ****
---- 118,130 ----
- STDPROTO=bezerkproto MAILSPOOL=/var/mail \
- ACTIVEFILE=/usr/lib/news/active NEWSSPOOL=/usr/spool/news \
- RSHPATH=/usr/bin/rsh CFLAGS="-g -O -pipe -DNFSKLUDGE $(EXTRACFLAGS)"
-+
-+ bsf: # FreeBSD
-+ $(MAKE) $(ARCHIVE) OS=bsi EXTRADRIVERS="$(EXTRADRIVERS)" \
-+ STDPROTO=bezerkproto MAILSPOOL=/var/mail \
-+ ACTIVEFILE=/usr/local/news/lib/active NEWSSPOOL=/var/news \
-+ RSHPATH=/usr/bin/rsh CFLAGS="${CFLAGS} -DNFSKLUDGE $(EXTRACFLAGS)" \
-+ LDFLAGS="-lcrypt"
-
- cvx: # Convex
- $(MAKE) mtest OS=$@ EXTRADRIVERS="$(EXTRADRIVERS)" \
+--- pico/osdep/os-bsf.h.orig Thu Jul 9 00:37:28 1998
++++ pico/osdep/os-bsf.h Wed Jul 15 17:02:31 1998
+@@ -23,7 +23,7 @@
+
+ #define USE_DIRENT
+ #include <sys/types.h>
+-#include <sys/dir.h>
++#include <dirent.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+@@ -152,7 +152,7 @@
+ /*
+ * Place where mail gets delivered (for pico's new mail checking)
+ */
+-#define MAILDIR "/usr/spool/mail"
++#define MAILDIR "/var/mail"
+
+ /*
+ * What and where the tool that checks spelling is located. If this is
diff --git a/chinese/pine4/files/patch-ag b/chinese/pine4/files/patch-ag
index a9742708f79d..b1e3da93a6a2 100644
--- a/chinese/pine4/files/patch-ag
+++ b/chinese/pine4/files/patch-ag
@@ -1,28 +1,11 @@
-*** imap/ANSI/c-client/mh.c.orig Wed May 15 13:49:54 1996
---- imap/ANSI/c-client/mh.c Fri Jun 14 00:12:23 1996
-***************
-*** 808,812 ****
- if (sbuf.st_ctime != LOCAL->scantime) {
- struct direct **names = NIL;
-! long nfiles = scandir (LOCAL->dir,&names,mh_select,mh_numsort);
- old = nmsgs ? mail_elt (stream,nmsgs)->data1 : 0;
- /* note scanned now */
---- 808,812 ----
- if (sbuf.st_ctime != LOCAL->scantime) {
- struct direct **names = NIL;
-! long nfiles = scandir (LOCAL->dir,&names,mh_select,(void*)mh_numsort);
- old = nmsgs ? mail_elt (stream,nmsgs)->data1 : 0;
- /* note scanned now */
-***************
-*** 1050,1054 ****
- }
- mh_file (tmp,mailbox); /* build file name we will use */
-! if (nfiles = scandir (tmp,&names,mh_select,mh_numsort)) {
- /* largest number */
- last = atoi (names[nfiles-1]->d_name);
---- 1050,1054 ----
- }
- mh_file (tmp,mailbox); /* build file name we will use */
-! if (nfiles = scandir (tmp,&names,mh_select,(void*)mh_numsort)) {
- /* largest number */
- last = atoi (names[nfiles-1]->d_name);
+--- pico/osdep/unix.orig Thu Jul 9 00:20:10 1998
++++ pico/osdep/unix Wed Jul 15 17:02:31 1998
+@@ -1952,7 +1952,7 @@
+
+ errno = 0; /* make sure previous error are cleared */
+
+- switch(fexist(fn, "w", &filesize)){
++ switch(fexist(fn, "w", (long *)&filesize)){
+ case FIOFNF :
+ vapor = TRUE;
+
diff --git a/chinese/pine4/files/patch-ah b/chinese/pine4/files/patch-ah
index d91c27e83135..32d85be0d037 100644
--- a/chinese/pine4/files/patch-ah
+++ b/chinese/pine4/files/patch-ah
@@ -1,15 +1,592 @@
-*** imap/ANSI/c-client/news.c.orig Wed May 15 13:50:02 1996
---- imap/ANSI/c-client/news.c Fri Jun 14 00:12:49 1996
-***************
-*** 310,314 ****
- while (s = strchr (s,'.')) *s = '/';
- /* scan directory */
-! if ((nmsgs = scandir (tmp,&names,news_select,news_numsort)) >= 0) {
- stream->local = fs_get (sizeof (NEWSLOCAL));
- LOCAL->dirty = NIL; /* no update to .newsrc needed yet */
---- 310,314 ----
- while (s = strchr (s,'.')) *s = '/';
- /* scan directory */
-! if ((nmsgs = scandir (tmp,&names,news_select,(void*)news_numsort)) >= 0) {
- stream->local = fs_get (sizeof (NEWSLOCAL));
- LOCAL->dirty = NIL; /* no update to .newsrc needed yet */
+--- pico/browse.c.orig Fri May 29 06:39:05 1998
++++ pico/browse.c Wed Jul 15 17:02:30 1998
+@@ -126,12 +126,12 @@
+
+
+ static KEYMENU menu_browse[] = {
+- {"?", "Get Help", KS_SCREENHELP}, {NULL, NULL, KS_NONE},
+- {NULL, NULL, KS_NONE}, {"-", "Prev Pg", KS_PREVPAGE},
+- {"D", "Delete", KS_NONE}, {"C","Copy", KS_NONE},
++ {"?", "輔助說明", KS_SCREENHELP}, {NULL, NULL, KS_NONE},
++ {NULL, NULL, KS_NONE}, {"-", "上一頁", KS_PREVPAGE},
++ {"D", "刪除", KS_NONE}, {"C","複製", KS_NONE},
+ {NULL, NULL, KS_NONE}, {NULL, NULL, KS_NONE},
+- {"W", "Where is", KS_NONE}, {"Spc", "Next Pg", KS_NEXTPAGE},
+- {"R", "Rename", KS_NONE}, {NULL, NULL, KS_NONE}
++ {"W", "搜尋", KS_NONE}, {"Spc", "下一頁", KS_NEXTPAGE},
++ {"R", "更名", KS_NONE}, {NULL, NULL, KS_NONE}
+ };
+ #define QUIT_KEY 1
+ #define EXEC_KEY 2
+@@ -331,7 +331,7 @@
+ child[0] = '\0';
+
+ if((gmode&MDTREE) && !in_oper_tree(dir)){
+- emlwrite("\007Can't read outside of %s in restricted mode", opertree);
++ emlwrite("\007無法在限制模式中讀取 %s 以外的東西", opertree);
+ sleep(2);
+ return(0);
+ }
+@@ -419,7 +419,7 @@
+ else{
+ if(timeo && (c == NODATA || time_to_check()))
+ if(pico_new_mail())
+- emlwrite("You may possibly have new mail.", NULL);
++ emlwrite("您可能有新信件。", NULL);
+ }
+
+ if(km_popped)
+@@ -695,7 +695,7 @@
+ gmp->current->fname);
+ /* make sure selected isn't a directory or executable */
+ if(!LikelyASCII(child)){
+- emlwrite("Can't edit non-text file. Try Launch.", NULL);
++ emlwrite("無法讀取非文字檔。試試 \"啟動\"。", NULL);
+ break;
+ }
+
+@@ -725,13 +725,13 @@
+ return(0);
+ }
+
+- emlwrite("\007Unknown command '%c'", (void *)c);
++ emlwrite("\007未知的命令 '%c'", (void *)c);
+ break;
+
+ case 'l': /* run Command */
+ case 'L':
+ if(!(gmode&MDBRONLY)){
+- emlwrite("\007Unknown command '%c'", (void *)c);
++ emlwrite("\007未知的命令 '%c'", (void *)c);
+ break;
+ }
+
+@@ -748,11 +748,11 @@
+ {NULL, NULL, 0, KS_NONE},
+ };
+
+- status = mlreply("Command to execute: ",
++ status = mlreply("欲執行的命令:",
+ tmp, NLINE, QNORML, opts);
+ switch(status){
+ case HELPCH:
+- emlwrite("\007No help yet!", NULL);
++ emlwrite("\007尚無輔助說明!", NULL);
+ /* remove break and sleep after help text is installed */
+ sleep(3);
+ break;
+@@ -763,7 +763,7 @@
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ break;
+ case ABORT:
+- emlwrite("Command cancelled", NULL);
++ emlwrite("命令已取消", NULL);
+ i++;
+ break;
+ case FALSE:
+@@ -771,7 +771,7 @@
+ i++;
+
+ if(tmp[0] == '\0'){
+- emlwrite("No command specified", NULL);
++ emlwrite("尚未下達命令", NULL);
+ break;
+ }
+
+@@ -790,12 +790,12 @@
+ case 'D':
+ if(gmp->current->mode == FIODIR){
+ /* BUG: if dir is empty it should be deleted */
+- emlwrite("\007Can't delete a directory", NULL);
++ emlwrite("\007無法刪除該目錄", NULL);
+ break;
+ }
+
+ if(gmode&MDSCUR){ /* not allowed! */
+- emlwrite("Delete not allowed in restricted mode",NULL);
++ emlwrite("無法在限制模式中使用刪除指令",NULL);
+ break;
+ }
+
+@@ -806,17 +806,17 @@
+ while(i++ < 2){ /* verify twice!! */
+ if(i == 1){
+ if(fexist(child, "w", (long *)NULL) != FIOSUC)
+- strcpy(tmp, "File is write protected! OVERRIDE");
++ strcpy(tmp, "檔案為防寫! 要跳過防寫保護");
+ else
+- sprintf(tmp, "Delete file \"%.*s\"", NLINE - 20, child);
++ sprintf(tmp, "刪除檔案 \"%.*s\"", NLINE - 20, child);
+ }
+ else
+- strcpy(tmp, "File CANNOT be UNdeleted! Really delete");
++ strcpy(tmp, "檔案將無法被反刪除! 確定刪除");
+
+ if((status = mlyesno(tmp, FALSE)) != TRUE){
+ emlwrite((status == ABORT)
+- ? "Delete Cancelled"
+- : "File Not Deleted",
++ ? "取消刪除"
++ : "檔案沒有被刪除",
+ NULL);
+ break;
+ }
+@@ -824,7 +824,7 @@
+
+ if(status == TRUE){
+ if(unlink(child) < 0){
+- emlwrite("Delete Failed: %s", errstr(errno));
++ emlwrite("刪除失敗:%s", errstr(errno));
+ }
+ else{ /* fix up pointers and redraw */
+ tp = gmp->current;
+@@ -893,12 +893,12 @@
+
+ while(!i){
+
+- status = mlreply("Directory to go to: ", child, NLINE, QNORML,
++ status = mlreply("切換至哪一個目錄:", child, NLINE, QNORML,
+ NULL);
+
+ switch(status){
+ case HELPCH:
+- emlwrite("\007No help yet!", NULL);
++ emlwrite("\007尚無輔助說明!", NULL);
+ /* remove break and sleep after help text is installed */
+ sleep(3);
+ break;
+@@ -906,7 +906,7 @@
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ break;
+ case ABORT:
+- emlwrite("Goto cancelled", NULL);
++ emlwrite("取消切換目錄", NULL);
+ i++;
+ break;
+ case FALSE:
+@@ -917,17 +917,17 @@
+ strcpy(child, gethomedir(NULL));
+
+ if(!compresspath(gmp->dname, child, NLINE)){
+- emlwrite("Invalid Directory: %s", child);
++ emlwrite("無效的目錄:%s", child);
+ break;
+ }
+
+ if((gmode&MDSCUR) && homeless(child)){
+- emlwrite("Restricted mode browsing limited to home directory",NULL);
++ emlwrite("限制模式中僅能瀏覽 home directory",NULL);
+ break;
+ }
+
+ if((gmode&MDTREE) && !in_oper_tree(child)){
+- emlwrite("Attempt to Goto directory denied", NULL);
++ emlwrite("已拒絕使用者切換目錄的請求", NULL);
+ break;
+ }
+
+@@ -943,7 +943,7 @@
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ }
+ else
+- emlwrite("\007Not a directory: \"%s\"", child);
++ emlwrite("\007\"%s\"不是一個目錄", child);
+
+ break;
+ default:
+@@ -956,7 +956,7 @@
+ case 'a': /* Add */
+ case 'A':
+ if(gmode&MDSCUR){ /* not allowed! */
+- emlwrite("Copy not allowed in restricted mode",NULL);
++ emlwrite("無法在限制模式中新增檔案",NULL);
+ break;
+ }
+
+@@ -965,10 +965,10 @@
+
+ while(!i){
+
+- switch(status=mlreply("Name of file to add: ", child, NLINE,
++ switch(status=mlreply("欲新增的檔名:", child, NLINE,
+ QFFILE, NULL)){
+ case HELPCH:
+- emlwrite("\007No help yet!", NULL);
++ emlwrite("\007尚無輔助說明!", NULL);
+ /* remove break and sleep after help text is installed */
+ sleep(3);
+ break;
+@@ -976,7 +976,7 @@
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ break;
+ case ABORT:
+- emlwrite("Add File Cancelled", NULL);
++ emlwrite("取消新增檔案", NULL);
+ i++;
+ break;
+ case FALSE:
+@@ -987,7 +987,7 @@
+ i++;
+
+ if(child[0] == '\0'){
+- emlwrite("No file named. Add Cancelled.", NULL);
++ emlwrite("未指定檔名,取消新增檔案。", NULL);
+ break;
+ }
+
+@@ -995,7 +995,7 @@
+ sprintf(child, "%s%c%s", gmp->dname, C_FILESEP, tmp);
+
+ if((status = fexist(child, "w", (long *)NULL)) == FIOSUC){
+- sprintf(tmp,"File \"%.*s\" already exists!",
++ sprintf(tmp,"檔案 \"%.*s\" 已存在!",
+ NLINE - 20, child);
+ emlwrite(tmp, NULL);
+ break;
+@@ -1011,7 +1011,7 @@
+ }
+ else{ /* highlight new file */
+ ffclose();
+- emlwrite("Added File \"%s\"", child);
++ emlwrite("新增檔案 \"%s\"", child);
+
+ if((p = strrchr(child, C_FILESEP)) == NULL){
+ emlwrite("Problems refiguring browser", NULL);
+@@ -1059,12 +1059,12 @@
+ case 'c': /* copy */
+ case 'C':
+ if(gmp->current->mode == FIODIR){
+- emlwrite("\007Can't copy a directory", NULL);
++ emlwrite("\007無法複製目錄", NULL);
+ break;
+ }
+
+ if(gmode&MDSCUR){ /* not allowed! */
+- emlwrite("Copy not allowed in restricted mode",NULL);
++ emlwrite("無法在限制模式中複製檔案",NULL);
+ break;
+ }
+
+@@ -1073,10 +1073,10 @@
+
+ while(!i){
+
+- switch(status=mlreply("Name of new copy: ", child, NLINE,
++ switch(status=mlreply("新複製檔名:", child, NLINE,
+ QFFILE, NULL)){
+ case HELPCH:
+- emlwrite("\007No help yet!", NULL);
++ emlwrite("\007尚無輔助說明!", NULL);
+ /* remove break and sleep after help text is installed */
+ sleep(3);
+ break;
+@@ -1084,7 +1084,7 @@
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ break;
+ case ABORT:
+- emlwrite("Make Copy Cancelled", NULL);
++ emlwrite("取消複製檔案", NULL);
+ i++;
+ break;
+ case FALSE:
+@@ -1095,12 +1095,12 @@
+ i++;
+
+ if(child[0] == '\0'){
+- emlwrite("No destination, file not copied", NULL);
++ emlwrite("未指定目地檔名,檔案沒有被複製。", NULL);
+ break;
+ }
+
+ if(!strcmp(gmp->current->fname, child)){
+- emlwrite("\007Can't copy file on to itself!", NULL);
++ emlwrite("\007無法將檔案複製至它自己!", NULL);
+ break;
+ }
+
+@@ -1108,12 +1108,12 @@
+ sprintf(child, "%s%c%s", gmp->dname, C_FILESEP, tmp);
+
+ if((status = fexist(child, "w", (long *)NULL)) == FIOSUC){
+- sprintf(tmp,"File \"%.*s\" exists! OVERWRITE",
++ sprintf(tmp,"檔案 \"%.*s\" 已存在! 要覆蓋\嗎",
+ NLINE - 20, child);
+ if((status = mlyesno(tmp, 0)) != TRUE){
+ emlwrite((status == ABORT)
+- ? "Make copy cancelled"
+- : "File Not Renamed",
++ ? "取消複製"
++ : "檔案沒有被複製",
+ NULL);
+ break;
+ }
+@@ -1131,7 +1131,7 @@
+ break;
+ }
+ else{ /* highlight new file */
+- emlwrite("File copied to %s", child);
++ emlwrite("複製檔案到 %s", child);
+
+ if((p = strrchr(child, C_FILESEP)) == NULL){
+ emlwrite("Problems refiguring browser", NULL);
+@@ -1174,12 +1174,12 @@
+ i = 0;
+
+ if(!strcmp(gmp->current->fname, "..")){
+- emlwrite("\007Can't rename \"..\"", NULL);
++ emlwrite("\007無法更改 \"..\" 的名稱", NULL);
+ break;
+ }
+
+ if(gmode&MDSCUR){ /* not allowed! */
+- emlwrite("Rename not allowed in restricted mode",NULL);
++ emlwrite("無法在限制模式中更改檔案名",NULL);
+ break;
+ }
+
+@@ -1187,10 +1187,10 @@
+
+ while(!i){
+
+- switch(status=mlreply("Rename file to: ", child, NLINE, QFFILE,
++ switch(status=mlreply("檔案名稱更改為:", child, NLINE, QFFILE,
+ NULL)){
+ case HELPCH:
+- emlwrite("\007No help yet!", NULL);
++ emlwrite("\007尚無輔助說明!", NULL);
+ /* remove break and sleep after help text is installed */
+ sleep(3);
+ break;
+@@ -1198,7 +1198,7 @@
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ break;
+ case ABORT:
+- emlwrite("Rename cancelled", NULL);
++ emlwrite("取消更改檔案名稱", NULL);
+ i++;
+ break;
+ case FALSE:
+@@ -1216,13 +1216,13 @@
+ status = fexist(child, "w", (long *)NULL);
+ if(status == FIOSUC || status == FIOFNF){
+ if(status == FIOSUC){
+- sprintf(tmp,"File \"%.*s\" exists! OVERWRITE",
++ sprintf(tmp,"檔案 \"%.*s\" 已存在! 要覆蓋\嗎",
+ NLINE - 20, child);
+
+ if((status = mlyesno(tmp, FALSE)) != TRUE){
+ emlwrite((status == ABORT)
+- ? "Rename cancelled"
+- : "Not Renamed",
++ ? "取消更名"
++ : "檔案沒有被更名",
+ NULL);
+ break;
+ }
+@@ -1232,7 +1232,7 @@
+ gmp->current->fname);
+
+ if(rename(tmp, child) < 0){
+- emlwrite("Rename Failed: %s", errstr(errno));
++ emlwrite("更名失敗:%s", errstr(errno));
+ }
+ else{
+ if((p = strrchr(child, C_FILESEP)) == NULL){
+@@ -1291,7 +1291,7 @@
+
+ if((gmode&MDTREE) && !in_oper_tree(tmp)){
+ emlwrite(
+- "\007Can't visit parent in restricted mode",
++ "\007無法在限制模式中檢視上層目錄",
+ NULL);
+ break;
+ }
+@@ -1312,7 +1312,7 @@
+ strcpy(tmp, S_FILESEP);
+ #endif
+ else{
+- emlwrite("\007Can't move up a directory",
++ emlwrite("\007無法切換至上一層目錄",
+ NULL);
+ break;
+ }
+@@ -1339,12 +1339,12 @@
+ PlaceCell(gmp, gmp->current, &row, &col);
+ }
+ else
+- emlwrite("\007Problem finding dir \"%s\"",child);
++ emlwrite("\007搜尋目錄 \"%s\" 時出了問題",child);
+ }
+
+ PaintBrowser(gmp, 0, &crow, &ccol);
+ if(!*child)
+- emlwrite("Select/View \".. parent dir\" to return to previous directory.",
++ emlwrite("以 [選擇]/[檢視] \".. parent dir\" 回到前一個目錄。",
+ NULL);
+
+ break;
+@@ -1383,7 +1383,7 @@
+
+ switch(readpattern("File name to find")){
+ case HELPCH:
+- emlwrite("\007No help yet!", NULL);
++ emlwrite("\007尚無輔助說明!", NULL);
+ /* remove break and sleep after help text is installed */
+ sleep(3);
+ break;
+@@ -1414,10 +1414,10 @@
+ }
+ while(tp->next);
+
+- emlwrite("Searched to end of directory", NULL);
++ emlwrite("搜尋至目錄結尾", NULL);
+ }
+ else
+- emlwrite("Searched to start of directory", NULL);
++ emlwrite("搜尋至目錄起始", NULL);
+
+ if(tp){
+ PlaceCell(gmp, gmp->current, &row, &col);
+@@ -1436,7 +1436,7 @@
+ i++; /* make sure we jump out */
+ break;
+ case ABORT:
+- emlwrite("Whereis cancelled", NULL);
++ emlwrite("取消搜尋", NULL);
+ i++;
+ break;
+ case FALSE:
+@@ -1460,7 +1460,7 @@
+ mlerase();
+ }
+ else
+- emlwrite("\"%s\" not found", pat);
++ emlwrite("找不到 \"%s\"", pat);
+
+ i++;
+ break;
+@@ -1482,11 +1482,11 @@
+ default: /* what? */
+ Default:
+ if(c < 0xff)
+- emlwrite("\007Unknown command: '%c'", (void *) c);
++ emlwrite("\007未知的命令:'%c'", (void *) c);
+ else if(c & CTRL)
+- emlwrite("\007Unknown command: ^%c", (void *)(c&0xff));
++ emlwrite("\007未知的命令:^%c", (void *)(c&0xff));
+ else
+- emlwrite("\007Unknown command", NULL);
++ emlwrite("\007未知的命令", NULL);
+ case NODATA: /* no op */
+ break;
+ }
+@@ -1516,7 +1516,7 @@
+
+ errbuf[0] = '\0';
+ if((mp=(struct bmaster *)malloc(sizeof(struct bmaster))) == NULL){
+- emlwrite("\007Can't malloc space for master filename cell", NULL);
++ emlwrite("\007無法配置記憶體空間給 master filename cell", NULL);
+ return(NULL);
+ }
+
+@@ -1540,7 +1540,7 @@
+ mp->cpf = mp->fpl = 0;
+ mp->longest = 5; /* .. must be labeled! */
+
+- emlwrite("Building file list of %s...", mp->dname);
++ emlwrite("正在建立 %s 的檔案列表...", mp->dname);
+
+ if((mp->names = getfnames(mp->dname, NULL, &nentries, errbuf)) == NULL){
+ free((char *) mp);
+@@ -1559,7 +1559,7 @@
+ * easily be made a user option later on...
+ */
+ if((filtnames=(char **)malloc((nentries+1) * sizeof(char *))) == NULL){
+- emlwrite("\007Can't malloc space for name array", NULL);
++ emlwrite("\007無法配置記憶體空間給 name array", NULL);
+ zotmaster(&mp);
+ return(NULL);
+ }
+@@ -1608,7 +1608,7 @@
+ while(nentries--){ /* stat filtered files */
+ /* get a new cell */
+ if((ncp=(struct fcell *)malloc(sizeof(struct fcell))) == NULL){
+- emlwrite("\007Can't malloc cells for browser!", NULL);
++ emlwrite("\007無法配置記憶體空間給 browser!", NULL);
+ zotfcells(mp->head); /* clean up cells */
+ free((char *) filtnames);
+ free((char *) mp);
+@@ -1778,22 +1778,22 @@
+ BrowserKeys()
+ {
+ menu_browse[QUIT_KEY].name = (gmode&MDBRONLY) ? "Q" : "E";
+- menu_browse[QUIT_KEY].label = (gmode&MDBRONLY) ? "Quit" : "Exit Brwsr";
++ menu_browse[QUIT_KEY].label = (gmode&MDBRONLY) ? "離開" : "離開瀏覽器";
+ menu_browse[GOTO_KEY].name = (gmode&MDGOTO) ? "G" : NULL;
+- menu_browse[GOTO_KEY].label = (gmode&MDGOTO) ? "Goto" : NULL;
++ menu_browse[GOTO_KEY].label = (gmode&MDGOTO) ? "切換" : NULL;
+ if(gmode & MDBRONLY){
+ menu_browse[EXEC_KEY].name = "L";
+- menu_browse[EXEC_KEY].label = "Launch";
++ menu_browse[EXEC_KEY].label = "啟動";
+ menu_browse[SELECT_KEY].name = "V";
+- menu_browse[SELECT_KEY].label = "[View]";
++ menu_browse[SELECT_KEY].label = "[檢視]";
+ menu_browse[PICO_KEY].name = "E";
+- menu_browse[PICO_KEY].label = "Edit";
++ menu_browse[PICO_KEY].label = "編輯";
+ }
+ else{
+ menu_browse[SELECT_KEY].name = "S";
+- menu_browse[SELECT_KEY].label = "[Select]";
++ menu_browse[SELECT_KEY].label = "[選擇]";
+ menu_browse[PICO_KEY].name = "A";
+- menu_browse[PICO_KEY].label = "Add";
++ menu_browse[PICO_KEY].label = "新增";
+ }
+
+ wkeyhelp(menu_browse);
+@@ -1896,7 +1896,7 @@
+
+ if((tp = tp->next) == NULL){ /* above top? */
+ if(secondtry++){
+- emlwrite("\007Internal error: can't find fname cell", NULL);
++ emlwrite("\007內部錯誤: 找不到 fname cell", NULL);
+ return(-1);
+ }
+ else{
+@@ -2062,10 +2062,10 @@
+ if(!p) /* no suitable length! */
+ p = &dir[l-(term.t_ncol-i-19)];
+
+- sprintf(buf, "%s Dir ...%s", (gmode&MDBRONLY) ? "" : " BROWSER ", p);
++ sprintf(buf, "%s 目錄 ...%s", (gmode&MDBRONLY) ? "" : " BROWSER ", p);
+ }
+ else
+- sprintf(buf,"%s Dir: %s", (gmode&MDBRONLY) ? "" : " BROWSER ", dir);
++ sprintf(buf,"%s 目錄: %s", (gmode&MDBRONLY) ? "" : " BROWSER ", dir);
+
+ if(i < j) /* keep it centered */
+ j = j - i; /* as long as we can */
+@@ -2194,18 +2194,18 @@
+ if((line = (buf[i] == '\n') ? 0 : line + 1) >= LA_LINE_LIMIT
+ || !buf[i]){
+ rv = FALSE;
+- emlwrite("Can't display non-text file. Try \"Launch\".",
++ emlwrite("無法顯示非文字檔。試試 \"啟動\"。",
+ NULL);
+ break;
+ }
+ }
+ else
+- emlwrite("Can't read file: %s", file);
++ emlwrite("無法讀取檔案:%s", file);
+
+ fclose(fp);
+ }
+ else
+- emlwrite("Can't open file: %s", file);
++ emlwrite("無法開啟檔案:%s", file);
+
+ return(rv);
+ }
diff --git a/chinese/pine4/files/patch-ai b/chinese/pine4/files/patch-ai
index bd1b5bf4346c..de248a4d94ec 100644
--- a/chinese/pine4/files/patch-ai
+++ b/chinese/pine4/files/patch-ai
@@ -1,69 +1,348 @@
-*** pine/send.c.orig Tue Feb 25 00:57:38 1997
---- pine/send.c Sun Jul 20 02:50:31 1997
-***************
-*** 5352,5364 ****
- body->subtype = cpystr("octet-stream");
- }
-
- /*
- * Apply maximal encoding regardless of previous
- * setting. This segment's either not text, or is
- * unlikely to be readable with > 30% of the
- * text encoded anyway, so we might as well save space...
- */
-! new_encoding = ENCBINARY; /* > 30% 8 bit chars */
- }
- }
-
---- 5352,5367 ----
- body->subtype = cpystr("octet-stream");
- }
-
-+ if(body->type == TYPETEXT)
-+ new_encoding = ENC8BIT;
-+ else
- /*
- * Apply maximal encoding regardless of previous
- * setting. This segment's either not text, or is
- * unlikely to be readable with > 30% of the
- * text encoded anyway, so we might as well save space...
- */
-! new_encoding = ENCBINARY; /* > 30% 8 bit chars */
- }
- }
-
-***************
-*** 6113,6119 ****
-
- switch (body->encoding) { /* all else needs filtering */
- case ENC8BIT: /* encode 8BIT into QUOTED-PRINTABLE */
-! gf_link_filter(gf_8bit_qp);
- break;
-
- case ENCBINARY: /* encode binary into BASE64 */
---- 6116,6123 ----
-
- switch (body->encoding) { /* all else needs filtering */
- case ENC8BIT: /* encode 8BIT into QUOTED-PRINTABLE */
-! if(F_OFF(F_ENABLE_8BIT, ps_global))
-! gf_link_filter(gf_8bit_qp);
- break;
-
- case ENCBINARY: /* encode binary into BASE64 */
-***************
-*** 6172,6178 ****
- sprintf (*dst += strlen (*dst), "Content-Transfer-Encoding: %s\015\012",
- body_encodings[(body->encoding == ENCBINARY)
- ? ENCBASE64
-! : (body->encoding == ENC8BIT)
- ? ENCQUOTEDPRINTABLE
- : (body->encoding <= ENCMAX)
- ? body->encoding : ENCOTHER]);
---- 6176,6182 ----
- sprintf (*dst += strlen (*dst), "Content-Transfer-Encoding: %s\015\012",
- body_encodings[(body->encoding == ENCBINARY)
- ? ENCBASE64
-! : (body->encoding == ENC8BIT && F_OFF(F_ENABLE_8BIT, ps_global))
- ? ENCQUOTEDPRINTABLE
- : (body->encoding <= ENCMAX)
- ? body->encoding : ENCOTHER]);
+--- pico/composer.c.orig Fri Jul 3 07:00:40 1998
++++ pico/composer.c Wed Jul 15 17:02:30 1998
+@@ -136,12 +136,12 @@
+
+
+ static KEYMENU menu_header[] = {
+- {"^G", "Get Help", KS_SCREENHELP}, {"^X", "Send", KS_SEND},
+- {"^R", "Rich Hdr", KS_RICHHDR}, {"^Y", "PrvPg/Top", KS_PREVPAGE},
+- {"^K", "Cut Line", KS_CURPOSITION}, {"^O", "Postpone", KS_POSTPONE},
+- {"^C", "Cancel", KS_CANCEL}, {"^D", "Del Char", KS_NONE},
+- {"^J", "Attach", KS_ATTACH}, {"^V", "NxtPg/End", KS_NEXTPAGE},
+- {"^U", "UnDel Line", KS_NONE}, {NULL, NULL}
++ {"^G", "輔助說明", KS_SCREENHELP}, {"^X", "送出", KS_SEND},
++ {"^R", "完整標頭", KS_RICHHDR}, {"^Y", "上一頁", KS_PREVPAGE},
++ {"^K", "剪下一行", KS_CURPOSITION}, {"^O", "暫緩寫信", KS_POSTPONE},
++ {"^C", "取消", KS_CANCEL}, {"^D", "刪除字元", KS_NONE},
++ {"^J", "夾附件", KS_ATTACH}, {"^V", "下一頁", KS_NEXTPAGE},
++ {"^U", "復原刪除行", KS_NONE}, {NULL, NULL}
+ };
+ #define SEND_KEY 1
+ #define RICH_KEY 2
+@@ -231,7 +231,7 @@
+ if(strlen(addrbuf) + strlen(buf) >= addrbuflen){
+ addrbuflen += NLINE * 4;
+ if(!(addrbuf = (char *)realloc(addrbuf, addrbuflen))){
+- emlwrite("\007Can't realloc addrbuf to %d bytes",
++ emlwrite("\007無法更改 addrbuf 的記憶體配置至 %d bytes",
+ (void *) addrbuflen);
+ return(ABORT);
+ }
+@@ -298,7 +298,7 @@
+ * get first chunk of memory, and tie it to structure...
+ */
+ if((curline = HALLOC()) == NULL){
+- emlwrite("Unable to make room for full Header.", NULL);
++ emlwrite("無法配置空間給完整標頭。", NULL);
+ return(FALSE);
+ }
+ longest = term.t_ncol - e->prlen - 1;
+@@ -680,7 +680,7 @@
+ }
+ else{
+ (*term.t_beep)();
+- emlwrite("Unknown Command: ^Z", NULL);
++ emlwrite("未知的命令:^Z", NULL);
+ }
+ break;
+
+@@ -693,12 +693,12 @@
+ err = NULL;
+ if(headents[ods.cur_e].is_attach){
+ if(SyncAttach() < 0){
+- if(mlyesno("Problem with attachments. Postpone anyway?",
++ if(mlyesno("附件有問題。無論如何都要暫緩該信嗎?",
+ FALSE) != TRUE){
+ if(FormatLines(headents[ods.cur_e].hd_text, "",
+ term.t_ncol - headents[ods.cur_e].prlen,
+ headents[ods.cur_e].break_on_comma, 0) == -1)
+- emlwrite("\007Format lines failed!", NULL);
++ emlwrite("\007版面整理失敗!", NULL);
+ UpdateHeader();
+ PaintHeader(COMPOSER_TOP_LINE, FALSE);
+ PaintBody(1);
+@@ -952,7 +952,7 @@
+ if(FormatLines(headents[ods.cur_e].hd_text, buf,
+ term.t_ncol - headents[ods.cur_e].prlen,
+ headents[ods.cur_e].break_on_comma,0)==-1){
+- emlwrite("\007Format lines failed!", NULL);
++ emlwrite("\007版面整理失敗!", NULL);
+ }
+
+ UpdateHeader();
+@@ -1011,7 +1011,7 @@
+ if(FormatLines(ods.cur_l, bufp,
+ (term.t_ncol-headents[ods.cur_e].prlen),
+ headents[ods.cur_e].break_on_comma, 0) == -1){
+- emlwrite("Problem adding address to header !",
++ emlwrite("在標頭加入地址時出了問題!",
+ NULL);
+ (*term.t_beep)();
+ break;
+@@ -1092,10 +1092,10 @@
+ default : /* huh? */
+ bleep:
+ if(ch&CTRL)
+- emlwrite("\007Unknown command: ^%c", (void *)(ch&0xff));
++ emlwrite("\007未知的命令:^%c", (void *)(ch&0xff));
+ else
+ case BADESC:
+- emlwrite("\007Unknown command", NULL);
++ emlwrite("\007未知的命令", NULL);
+
+ case NODATA:
+ break;
+@@ -1135,14 +1135,14 @@
+ if(gripe){
+ char xx[81];
+
+- strcpy(xx, "Can't move down. Use ^X to ");
++ strcpy(xx, "無法再往下移了。請用 ^X ");
+ strcat(xx, (Pmaster && Pmaster->exit_label)
+ ? Pmaster->exit_label
+ : (gmode & MDHDRONLY)
+- ? "eXit/Save"
++ ? "離開/送出"
+ : (gmode & MDVIEW)
+- ? "eXit"
+- : "Send");
++ ? "離開"
++ : "送出");
+ strcat(xx, ".");
+ emlwrite(xx, NULL);
+ }
+@@ -1177,7 +1177,7 @@
+ if(FormatLines(headents[ods.cur_e].hd_text, "",
+ term.t_ncol-headents[new_e].prlen,
+ headents[ods.cur_e].break_on_comma, 0) == -1)
+- emlwrite("\007Format lines failed!", NULL);
++ emlwrite("\007版面整理失敗!", NULL);
+ }
+ } else if(headents[ods.cur_e].builder) { /* expand addresses */
+ int mangled = 0;
+@@ -1248,8 +1248,8 @@
+ if(!(new_l = prev_sel_hline(&new_e, ods.cur_l))){ /* all the way up! */
+ ods.p_line = COMPOSER_TOP_LINE;
+ if(gripe)
+- emlwrite("Can't move beyond top of %s",
+- (Pmaster->pine_flags & MDHDRONLY) ? "entry" : "header");
++ emlwrite("無法移到超出%s的頂端",
++ (Pmaster->pine_flags & MDHDRONLY) ? "項目" : "標頭");
+
+ return(0);
+ }
+@@ -1278,7 +1278,7 @@
+ if(FormatLines(headents[ods.cur_e].hd_text, "",
+ term.t_ncol - headents[ods.cur_e].prlen,
+ headents[ods.cur_e].break_on_comma,0) == -1)
+- emlwrite("\007Format lines failed!", NULL);
++ emlwrite("\007版面整理失敗!", NULL);
+ }
+ }
+ else if(headents[ods.cur_e].builder){
+@@ -1357,7 +1357,7 @@
+ lp = lp->next;
+ }
+ else{
+- emlwrite("\007Can't allocate line for new attachment!", NULL);
++ emlwrite("\007無法為新的附件配置空間!", NULL);
+ return(0);
+ }
+ }
+@@ -1371,12 +1371,12 @@
+ /* validate the new attachment, and reformat if needed */
+ if(status = SyncAttach()){
+ if(status < 0)
+- emlwrite("\007Problem attaching: %s", fn);
++ emlwrite("\007有問題的附件:%s", fn);
+
+ if(FormatLines(headents[a_e].hd_text, "",
+ term.t_ncol - headents[a_e].prlen,
+ headents[a_e].break_on_comma, 0) == -1){
+- emlwrite("\007Format lines failed!", NULL);
++ emlwrite("\007版面整理失敗!", NULL);
+ return(0);
+ }
+ }
+@@ -1452,7 +1452,7 @@
+
+ if (term.t_nrow < 6 && ch != NODATA){
+ (*term.t_beep)();
+- emlwrite("Please make the screen bigger.", NULL);
++ emlwrite("請將畫面調大一些。", NULL);
+ continue;
+ }
+
+@@ -1523,13 +1523,13 @@
+ if(headents[ods.cur_e].only_file_chars
+ && !fallowc((unsigned char) ch)){
+ /* no garbage in filenames */
+- emlwrite("\007Can't have a '%c' in folder name",
++ emlwrite("\007資料匣中不能有 '%c' 這個字元",
+ (void *) ch);
+ continue;
+ }
+ else if(headents[ods.cur_e].is_attach
+ && intag(strng,ods.p_off)){
+- emlwrite("\007Can't edit attachment number!", NULL);
++ emlwrite("\007無法編輯附件的代碼!", NULL);
+ continue;
+ }
+
+@@ -1675,7 +1675,7 @@
+ headents[ods.cur_e].dirty = 1;
+ }
+ else
+- emlwrite("Problem Unkilling text", NULL);
++ emlwrite("有問題的反刪除文字", NULL);
+ continue;
+
+ case (CTRL|'F') :
+@@ -1726,7 +1726,7 @@
+ continue;
+
+ if(headents[ods.cur_e].is_attach && intag(strng, ods.p_off)){
+- emlwrite("\007Can't edit attachment number!", NULL);
++ emlwrite("\007無法編輯附件的代碼!", NULL);
+ continue;
+ }
+
+@@ -1740,7 +1740,7 @@
+ }
+
+ if(headents[ods.cur_e].is_attach && intag(strng, ods.p_off-1)){
+- emlwrite("\007Can't edit attachment number!", NULL);
++ emlwrite("\007無法編輯附件的代碼!", NULL);
+ continue;
+ }
+
+@@ -1951,7 +1951,7 @@
+
+ if(nlp == NULL){ /* no place to add below? */
+ if((lp = HALLOC()) == NULL){
+- emlwrite("Can't allocate any more lines for header!", NULL);
++ emlwrite("無法再配置更多的空間給標頭!", NULL);
+ free(buf);
+ return(-1);
+ }
+@@ -1986,7 +1986,7 @@
+
+ if(strlen(buf) && !nlp){
+ if((lp = HALLOC()) == NULL){
+- emlwrite("Can't allocate any more lines for header!",NULL);
++ emlwrite("無法再配置更多的空間給標頭!",NULL);
+ free(buf);
+ return(-1);
+ }
+@@ -2272,14 +2272,14 @@
+
+ if(level < 0 || !headents[level].name){
+ (*term.t_beep)();
+- emlwrite("Sorry, I can't help you with that.", NULL);
++ emlwrite("很抱歉,關於那個我無法幫忙。", NULL);
+ sleep(2);
+ return(FALSE);
+ }
+
+- sprintf(buf, "Help for %s %.40s Field",
+- (Pmaster->pine_flags & MDHDRONLY) ? "Address Book"
+- : "Composer",
++ sprintf(buf, "%s欄位%.40s的輔助說明",
++ (Pmaster->pine_flags & MDHDRONLY) ? "地址簿"
++ : "編輯器",
+ headents[level].name);
+ (*Pmaster->helper)(headents[level].help, buf, 1);
+ ttresize();
+@@ -2909,7 +2909,7 @@
+ }
+
+ if((sbuf=(char *)malloc((unsigned) i)) == NULL){
+- emlwrite("Can't malloc space to expand address", NULL);
++ emlwrite("無法配置記憶體空間以展開地址", NULL);
+ return(-1);
+ }
+
+@@ -2966,7 +2966,7 @@
+ if(!arg){
+ headarg = arg = (BUILDER_ARG *)malloc(sizeof(BUILDER_ARG));
+ if(!arg){
+- emlwrite("Can't malloc space for fcc", NULL);
++ emlwrite("無法配置記憶體空間給 fcc", NULL);
+ return(-1);
+ }
+ else{
+@@ -2979,7 +2979,7 @@
+ else{
+ nextarg = (BUILDER_ARG *)malloc(sizeof(BUILDER_ARG));
+ if(!nextarg){
+- emlwrite("Can't malloc space for fcc", NULL);
++ emlwrite("無法配置記憶體空間給 fcc", NULL);
+ return(-1);
+ }
+ else{
+@@ -2995,7 +2995,7 @@
+ if(!e->sticky){
+ line = e->hd_text;
+ if(!(arg->tptr=(char *)malloc(strlen(line->text) + 1))){
+- emlwrite("Can't malloc space for fcc", NULL);
++ emlwrite("無法配置記憶體空間給 fcc", NULL);
+ return(-1);
+ }
+ else
+@@ -3012,7 +3012,7 @@
+ if(!headarg){
+ headarg = (BUILDER_ARG *)malloc(sizeof(BUILDER_ARG));
+ if(!headarg){
+- emlwrite("Can't malloc space", NULL);
++ emlwrite("無法配置記憶體空間", NULL);
+ return(-1);
+ }
+ else{
+@@ -3321,7 +3321,7 @@
+
+ if(ksize()){
+ if((bp = buf = (char *)malloc(ksize()+5)) == NULL){
+- emlwrite("Can't malloc space for saved text", NULL);
++ emlwrite("無法配置保存文字的記憶體空間", NULL);
+ return(FALSE);
+ }
+ }
+@@ -3355,7 +3355,7 @@
+ work_buf_len = strlen(ods.cur_l->text) + buf_len;
+ work_buf = (char *) malloc((work_buf_len + 1) * sizeof(char));
+ if (work_buf == NULL) {
+- emlwrite("Can't malloc space for saved text", NULL);
++ emlwrite("無法配置保存文字的記憶體空間", NULL);
+ return(FALSE);
+ }
+
+@@ -3564,9 +3564,9 @@
+ if(Pmaster && Pmaster->exit_label)
+ menu_header[SEND_KEY].label = Pmaster->exit_label;
+ else if(gmode & (MDVIEW | MDHDRONLY))
+- menu_header[SEND_KEY].label = (gmode & MDHDRONLY) ? "eXit/Save" : "eXit";
++ menu_header[SEND_KEY].label = (gmode & MDHDRONLY) ? "離開/儲存" : "離開";
+ else
+- menu_header[SEND_KEY].label = "Send";
++ menu_header[SEND_KEY].label = "送出";
+
+ if(gmode & MDVIEW){
+ menu_header[CUT_KEY].name = NULL;
+@@ -3587,7 +3587,7 @@
+ menu_header[RICH_KEY].name = NULL;
+ }
+ else{
+- menu_header[RICH_KEY].label = "Rich Hdr";
++ menu_header[RICH_KEY].label = "完整標頭";
+ menu_header[RICH_KEY].name = "^R";
+ }
+
+@@ -3666,7 +3666,7 @@
+ *headents[i].realaddr = bufp;
+ }
+ else{
+- emlwrite("Can't make room to pack header field.", NULL);
++ emlwrite("無法配置包裝表頭欄位的記憶體空間。", NULL);
+ retval = FALSE;
+ }
+ }
diff --git a/chinese/pine4/files/patch-aj b/chinese/pine4/files/patch-aj
index 9a9d853c0b35..223012340858 100644
--- a/chinese/pine4/files/patch-aj
+++ b/chinese/pine4/files/patch-aj
@@ -1,17 +1,184 @@
-*** imap/ANSI/c-client/os_bsi.h.bak Wed Feb 7 12:01:07 1996
---- imap/ANSI/c-client/os_bsi.h Sun Jul 20 01:47:23 1997
-***************
-*** 36,42 ****
---- 36,47 ----
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
-+ #ifdef __FreeBSD__
-+ #include <dirent.h>
-+ #define direct dirent
-+ #else
- #include <sys/dir.h>
-+ #endif
- #include <sys/uio.h> /* needed for writev() prototypes */
- #include <fcntl.h>
- #include <syslog.h>
+--- pico/display.c.orig Sat Jun 20 01:19:53 1998
++++ pico/display.c Wed Jul 15 17:02:30 1998
+@@ -71,32 +71,32 @@
+ * Standard pico keymenus...
+ */
+ static KEYMENU menu_pico[] = {
+- {"^G", "Get Help", KS_SCREENHELP}, {"^O", "WriteOut", KS_SAVEFILE},
+- {"^R", "Read File", KS_READFILE}, {"^Y", "Prev Pg", KS_PREVPAGE},
+- {"^K", "Cut Text", KS_NONE}, {"^C", "Cur Pos", KS_CURPOSITION},
+- {"^X", "Exit", KS_EXIT}, {"^J", "Justify", KS_JUSTIFY},
+- {"^W", "Where is", KS_WHEREIS}, {"^V", "Next Pg", KS_NEXTPAGE},
++ {"^G", "輔助說明", KS_SCREENHELP}, {"^O", "寫入檔案", KS_SAVEFILE},
++ {"^R", "讀取檔案", KS_READFILE}, {"^Y", "上一頁", KS_PREVPAGE},
++ {"^K", "剪下一行", KS_NONE}, {"^C", "目前位置", KS_CURPOSITION},
++ {"^X", "離開", KS_EXIT}, {"^J", "重整段落", KS_JUSTIFY},
++ {"^W", "搜尋", KS_WHEREIS}, {"^V", "下一頁", KS_NEXTPAGE},
+ {"^U", NULL, KS_NONE},
+ #ifdef SPELLER
+- {"^T", "To Spell", KS_SPELLCHK}
++ {"^T", "拼字檢查", KS_SPELLCHK}
+ #else
+- {"^D", "Del Char", KS_NONE}
++ {"^D", "刪除字元", KS_NONE}
+ #endif
+ };
+ #define UNCUT_KEY 10
+
+
+ static KEYMENU menu_compose[] = {
+- {"^G", "Get Help", KS_SCREENHELP}, {"^X", NULL, KS_SEND},
+- {"^R", "Read File", KS_READFILE}, {"^Y", "Prev Pg", KS_PREVPAGE},
+- {"^K", "Cut Text", KS_NONE}, {"^O", "Postpone", KS_POSTPONE},
+- {"^C", "Cancel", KS_CANCEL}, {"^J", "Justify", KS_JUSTIFY},
+- {NULL, NULL, KS_NONE}, {"^V", "Next Pg", KS_NEXTPAGE},
++ {"^G", "輔助說明", KS_SCREENHELP}, {"^X", NULL, KS_SEND},
++ {"^R", "讀取檔案", KS_READFILE}, {"^Y", "上一頁", KS_PREVPAGE},
++ {"^K", "剪下一行", KS_NONE}, {"^O", "暫緩寫信", KS_POSTPONE},
++ {"^C", "取消", KS_CANCEL}, {"^J", "重整段落", KS_JUSTIFY},
++ {NULL, NULL, KS_NONE}, {"^V", "下一頁", KS_NEXTPAGE},
+ {"^U", NULL, KS_NONE},
+ #ifdef SPELLER
+- {"^T", "To Spell", KS_SPELLCHK}
++ {"^T", "拼字檢查", KS_SPELLCHK}
+ #else
+- {"^D", "Del Char", KS_NONE}
++ {"^D", "刪除字元", KS_NONE}
+ #endif
+ };
+ #define EXIT_KEY 1
+@@ -152,7 +152,7 @@
+ (*term.t_rev)(FALSE);
+ vscreen = (VIDEO **) malloc((term.t_nrow+1)*sizeof(VIDEO *));
+ if (vscreen == NULL){
+- emlwrite("Allocating memory for virtual display failed.", NULL);
++ emlwrite("配置記憶體給虛擬顯示器失敗。", NULL);
+ return(FALSE);
+ }
+
+@@ -160,7 +160,7 @@
+ pscreen = (VIDEO **) malloc((term.t_nrow+1)*sizeof(VIDEO *));
+ if (pscreen == NULL){
+ free((void *)vscreen);
+- emlwrite("Allocating memory for physical display failed.", NULL);
++ emlwrite("配置記憶體給實體顯示器失敗。", NULL);
+ return(FALSE);
+ }
+
+@@ -171,7 +171,7 @@
+ if (vp == NULL){
+ free((void *)vscreen);
+ free((void *)pscreen);
+- emlwrite("Allocating memory for virtual display lines failed.",
++ emlwrite("配置記憶體給虛擬顯示行失敗。",
+ NULL);
+ return(FALSE);
+ }
+@@ -191,7 +191,7 @@
+
+ free((void *)vscreen);
+ free((void *)pscreen);
+- emlwrite("Allocating memory for physical display lines failed.",
++ emlwrite("配置記憶體給實體顯示行失敗。",
+ NULL);
+ return(FALSE);
+ }
+@@ -749,12 +749,12 @@
+ }
+
+ if(lastflag&CFFILL){
+- menu_pico[UNCUT_KEY].label = "UnJustify";
+- emlwrite("Can now UnJustify!", NULL);
++ menu_pico[UNCUT_KEY].label = "取消重整";
++ emlwrite("現在可以取消重整!", NULL);
+ mpresf = FARAWAY; /* remove this after next keystroke! */
+ }
+ else
+- menu_pico[UNCUT_KEY].label = "UnCut Text";
++ menu_pico[UNCUT_KEY].label = "復原刪字";
+
+ wkeyhelp(menu_pico);
+ sgarbk = FALSE;
+@@ -944,18 +944,18 @@
+ ShowPrompt();
+ else{
+ menu_compose[EXIT_KEY].label = (Pmaster->headents)
+- ? "Send" :"Exit";
++ ? "送出" :"離開";
+ menu_compose[PSTPN_KEY].name = (Pmaster->headents)
+ ? "^O" : NULL;
+ menu_compose[PSTPN_KEY].label = (Pmaster->headents)
+- ? "Postpone" : NULL;
++ ? "暫緩寫信" : NULL;
+ menu_compose[WHERE_KEY].name = (Pmaster->alt_ed) ? "^_" : "^W";
+ menu_compose[WHERE_KEY].label = (Pmaster->alt_ed) ? "Alt Edit"
+- : "Where is";
++ : "搜尋";
+ KS_OSDATASET(&menu_compose[WHERE_KEY],
+ (Pmaster->alt_ed) ? KS_ALTEDITOR : KS_WHEREIS);
+- menu_compose[UNCUT_KEY].label = (thisflag&CFFILL) ? "UnJustify"
+- : "UnCut Text";
++ menu_compose[UNCUT_KEY].label = (thisflag&CFFILL) ? "取消重整"
++ : "復原刪字";
+ wkeyhelp(menu_compose);
+ #ifdef _WINDOWS
+ /* When alt editor is available "Where is" is not on the menu
+@@ -1150,11 +1150,11 @@
+ }
+
+ menu_yesno[1].name = "Y";
+- menu_yesno[1].label = (dflt == TRUE) ? "[Yes]" : "Yes";
++ menu_yesno[1].label = (dflt == TRUE) ? "[是]" : "是";
+ menu_yesno[6].name = "^C";
+- menu_yesno[6].label = "Cancel";
++ menu_yesno[6].label = "取消";
+ menu_yesno[7].name = "N";
+- menu_yesno[7].label = (dflt == FALSE) ? "[No]" : "No";
++ menu_yesno[7].label = (dflt == FALSE) ? "[否]" : "否";
+ wkeyhelp(menu_yesno); /* paint generic menu */
+ sgarbk = TRUE; /* mark menu dirty */
+ if(Pmaster && curwp)
+@@ -1168,7 +1168,7 @@
+ switch(GetKey()){
+ case (CTRL|'M') : /* default */
+ if(dflt >= 0){
+- pputs((dflt) ? "Yes" : "No", 1);
++ pputs((dflt) ? "是" : "否", 1);
+ rv = dflt;
+ }
+ else
+@@ -1185,14 +1185,14 @@
+ case 'y' :
+ case 'Y' :
+ case F3 :
+- pputs("Yes", 1);
++ pputs("是", 1);
+ rv = TRUE;
+ break;
+
+ case 'n' :
+ case 'N' :
+ case F4 :
+- pputs("No", 1);
++ pputs("否", 1);
+ rv = FALSE;
+ break;
+
+@@ -1320,7 +1320,7 @@
+ #endif
+
+ menu_mlreply[0].name = "^G";
+- menu_mlreply[0].label = "Get Help";
++ menu_mlreply[0].label = "輔助說明";
+ KS_OSDATASET(&menu_mlreply[0], KS_SCREENHELP);
+ for(j = 0, i = 1; i < 6; i++){ /* insert odd extras */
+ menu_mlreply[i].name = NULL;
+@@ -1340,7 +1340,7 @@
+ }
+
+ menu_mlreply[6].name = "^C";
+- menu_mlreply[6].label = "Cancel";
++ menu_mlreply[6].label = "取消";
+ KS_OSDATASET(&menu_mlreply[6], KS_NONE);
+ for(j = 0, i = 7; i < 12; i++){ /* insert even extras */
+ menu_mlreply[i].name = NULL;
diff --git a/chinese/pine4/files/patch-ak b/chinese/pine4/files/patch-ak
index 6ca5d41436cc..dc35ee22e609 100644
--- a/chinese/pine4/files/patch-ak
+++ b/chinese/pine4/files/patch-ak
@@ -1,50 +1,11 @@
-*** imap/Makefile.orig Thu May 30 07:33:10 1996
---- imap/Makefile Sun Jan 12 17:05:17 1997
-***************
-*** 47,53 ****
-
- # ANSI compiler ports. Note for SCO you may have to set LN to "copy -rom"
-
-! a32 a41 aix bsi d-g drs lnx lyn mct mnt neb nxt osf sc5 sco sgi slx sos:
- $(MAKE) build SYSTYPE=ANSI OS=$@
-
- # Non-ANSI compiler ports.
---- 47,53 ----
-
- # ANSI compiler ports. Note for SCO you may have to set LN to "copy -rom"
-
-! a32 a41 aix bsi bsf d-g drs lnx lyn mct mnt neb nxt osf sc5 sco sgi slx sos:
- $(MAKE) build SYSTYPE=ANSI OS=$@
-
- # Non-ANSI compiler ports.
-***************
-*** 82,87 ****
---- 82,90 ----
- bs2:
- $(MAKE) build SYSTYPE=ANSI OS=bsi
-
-+ bsf:
-+ $(MAKE) build OS=bsf PROCESS=an
-+
- pt1:
- $(MAKE) build SYSTYPE=non-ANSI OS=ptx
-
-***************
-*** 92,99 ****
- $(LN) $(SYSTYPE) systype
- cd $(SYSTYPE)/c-client; $(MAKE) $(OS)
- cd $(SYSTYPE)/ms;$(MAKE)
-! cd $(SYSTYPE)/ipopd;$(MAKE)
-! cd $(SYSTYPE)/imapd;$(MAKE)
-
- clean:
- $(RM) systype
---- 95,102 ----
- $(LN) $(SYSTYPE) systype
- cd $(SYSTYPE)/c-client; $(MAKE) $(OS)
- cd $(SYSTYPE)/ms;$(MAKE)
-! # cd $(SYSTYPE)/ipopd;$(MAKE)
-! # cd $(SYSTYPE)/imapd;$(MAKE)
-
- clean:
- $(RM) systype
+--- pico/estruct.h.orig Fri May 29 06:56:52 1998
++++ pico/estruct.h Wed Jul 15 17:02:30 1998
+@@ -125,7 +125,7 @@
+ #define LOBIT_CHAR(C) ((C) > 0x1f && (C) < 0x7f)
+ #define HIBIT_CHAR(C) ((C) > 0x7f && (C) <= 0xff)
+ #define HIBIT_OK(C) (!(gmode & MDHBTIGN))
+-#define VALID_KEY(C) (LOBIT_CHAR(C) || (HIBIT_OK(C) && HIBIT_CHAR(C)))
++#define VALID_KEY(C) (((C) & 0x80) ? 1 : LOBIT_CHAR(C))
+ #define ctrl(c) ((c) & 0x1f) /* control character mapping */
+
+ #define STDIN_FD 0
diff --git a/chinese/pine4/files/patch-al b/chinese/pine4/files/patch-al
index 2c6d35ba6a4d..4d0a775a03f6 100644
--- a/chinese/pine4/files/patch-al
+++ b/chinese/pine4/files/patch-al
@@ -1,55 +1,117 @@
-*** build.orig Tue May 14 23:22:47 1996
---- build Sun Jan 12 20:18:50 1997
-***************
-*** 167,180 ****
- cd $PHOME/bin
- rm -f pine mtest imapd pico pilot
- if [ -s ../pine/pine ] ; then ln ../pine/pine pine ; fi
-- if [ -s ../c-client/mtest ] ; then ln ../c-client/mtest mtest ; fi
-- if [ -s ../imapd/imapd ] ; then ln ../imapd/imapd imapd ; fi
- if [ -s ../pico/pico ] ; then ln ../pico/pico pico ; fi
- if [ -s ../pico/pilot ] ; then ln ../pico/pilot pilot ; fi
- cd $PHOME
- echo ''
- echo "Links to executables are in bin directory:"
-- size bin/pine bin/mtest bin/imapd bin/pico bin/pilot
- echo "Done"
- ;;
-
---- 167,179 ----
- cd $PHOME/bin
- rm -f pine mtest imapd pico pilot
- if [ -s ../pine/pine ] ; then ln ../pine/pine pine ; fi
- if [ -s ../pico/pico ] ; then ln ../pico/pico pico ; fi
- if [ -s ../pico/pilot ] ; then ln ../pico/pilot pilot ; fi
-+ if [ -s ../pico/libpico.so.1.3 ] ;
-+ then ln ../pico/libpico.so.1.3 libpico.so.1.3 ; fi
- cd $PHOME
- echo ''
- echo "Links to executables are in bin directory:"
- echo "Done"
- ;;
-
-***************
-*** 185,194 ****
- make clean
- echo "Cleaning Pine"
- cd $PHOME/pine
-! make -f makefile.ult clean
- echo "Cleaning pico"
- cd $PHOME/pico
-! make $makeargs -f makefile.ult clean
- echo "Done"
- cd $PHOME
- ;;
---- 184,193 ----
- make clean
- echo "Cleaning Pine"
- cd $PHOME/pine
-! make -f makefile.bsf clean
- echo "Cleaning pico"
- cd $PHOME/pico
-! make $makeargs -f makefile.bsf clean
- echo "Done"
- cd $PHOME
- ;;
+--- pico/pico.c.orig Tue Jul 7 05:41:45 1998
++++ pico/pico.c Wed Jul 15 17:02:31 1998
+@@ -318,7 +318,7 @@
+ c = GetKey();
+ if (term.t_nrow < 6 && c != NODATA){
+ (*term.t_beep)();
+- emlwrite("Please make the screen bigger.", NULL);
++ emlwrite("請將畫面調大一些。", NULL);
+ continue;
+ }
+
+@@ -560,9 +560,9 @@
+ }
+
+ if(c&CTRL)
+- emlwrite("\007Unknown Command: ^%c", (void *)(c&0xff));
++ emlwrite("\007未知的命令:^%c", (void *)(c&0xff));
+ else
+- emlwrite("\007Unknown Command", NULL);
++ emlwrite("\007未知的命令", NULL);
+
+ lastflag = 0; /* Fake last flags. */
+ return (FALSE);
+@@ -615,7 +615,7 @@
+ return(TRUE);
+ }
+ else{
+- emlwrite("Cancel Cancelled", NULL);
++ emlwrite("取消", NULL);
+ curwp->w_flag |= WFMODE; /* and modeline so we */
+ sgarbk = TRUE; /* redraw the keymenu */
+ pclear(term.t_nrow - 1, term.t_nrow + 1);
+@@ -624,17 +624,17 @@
+ }
+ }
+ else switch(mlyesno(Pmaster->headents
+- ? "Cancel message (answering \"Yes\" will abandon your mail message)"
++ ? "\"取消\"這個動作將會放棄你目前的信件。確定取消嗎"
+ : (anycb() == FALSE)
+- ? "Cancel Edit (and abandon changes)"
+- : "Cancel Edit",
++ ? "取消編輯(並放棄所有的改變)"
++ : "取消編輯",
+ FALSE)){
+ case TRUE:
+ pico_all_done = COMP_CANCEL;
+ return(TRUE);
+
+ case ABORT:
+- emlwrite("\007Cancel Cancelled", NULL);
++ emlwrite("\007取消", NULL);
+ break;
+
+ default:
+@@ -672,7 +672,7 @@
+
+ /* First, make sure there are no outstanding problems */
+ if(AttachError()){
+- emlwrite("\007Problem with attachments! Fix errors or delete attachments.", NULL);
++ emlwrite("\007有問題的附件! 請修復或刪除該附件。", NULL);
+ return(FALSE);
+ }
+
+@@ -706,7 +706,7 @@
+ if (f != FALSE /* Argument forces it. */
+ || anycb() == FALSE /* All buffers clean. */
+ /* User says it's OK. */
+- || (s=mlyesno("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES)", -1)) == FALSE) {
++ || (s=mlyesno("存入更改過的緩衝區 (回答 \"No\" 將清除所有已做過的修改)", -1)) == FALSE) {
+ vttidy();
+ #if defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS)
+ kbdestroy(kbesc);
+@@ -719,7 +719,7 @@
+ wquit(1, 0);
+ }
+ else if(s == ABORT){
+- emlwrite("Exit cancelled", NULL);
++ emlwrite("取消離開", NULL);
+ if(term.t_mrow == 0)
+ curwp->w_flag |= WFHARD; /* cause bottom 3 lines to paint */
+ }
+@@ -753,7 +753,7 @@
+ ctrlg(f, n)
+ int f, n;
+ {
+- emlwrite("Cancelled", NULL);
++ emlwrite("取消", NULL);
+ return (ABORT);
+ }
+
+@@ -764,7 +764,7 @@
+ rdonly()
+ {
+ (*term.t_beep)();
+- emlwrite("Key illegal in VIEW mode", NULL);
++ emlwrite("這不是一個在 VIEW 模式中合法的命令", NULL);
+ return(FALSE);
+ }
+
+@@ -1289,7 +1289,7 @@
+ wp->doto = 0;
+ }
+ else
+- emlwrite("Can't allocate space for text", NULL);
++ emlwrite("無法配置文字的記憶體空間", NULL);
+
+ return((void *)wp);
+ }
+@@ -1377,7 +1377,7 @@
+ register LINE *lp;
+
+ if((lp = lalloc(0)) == NULL){
+- emlwrite("Can't allocate space for more characters",NULL);
++ emlwrite("無法配置記憶體空間給更多的字元",NULL);
+ return(0);
+ }
+
diff --git a/chinese/pine4/files/patch-am b/chinese/pine4/files/patch-am
index 77328d9843ae..be59a33310c6 100644
--- a/chinese/pine4/files/patch-am
+++ b/chinese/pine4/files/patch-am
@@ -1,19 +1,137 @@
-*** pine/pine.h.bak Thu Jul 11 22:15:44 1996
---- pine/pine.h Tue Dec 3 20:52:56 1996
-***************
-*** 2085,2091 ****
- } ATABLE_S;
-
-
-! #define TAG_EMBED '\377' /* Announces embedded data in text string */
- #define TAG_INVON '\001' /* Supported character attributes */
- #define TAG_INVOFF '\002'
- #define TAG_BOLDON '\003'
---- 2085,2091 ----
- } ATABLE_S;
-
-
-! #define TAG_EMBED '\001' /* Announces embedded data in text string */
- #define TAG_INVON '\001' /* Supported character attributes */
- #define TAG_INVOFF '\002'
- #define TAG_BOLDON '\003'
+--- pico/search.c.orig Fri Jun 26 05:48:14 1998
++++ pico/search.c Wed Jul 15 17:02:31 1998
+@@ -165,7 +165,7 @@
+ break;
+ default:
+ if(status == ABORT)
+- emlwrite("Search Cancelled", NULL);
++ emlwrite("取消搜尋", NULL);
+ else
+ mlerase();
+ curwp->w_flag |= WFMODE;
+@@ -212,16 +212,16 @@
+
+ /* and complain if not there */
+ if (status == FALSE){
+- emlwrite("\"%s\" not found", defpat);
++ emlwrite("找不到 \"%s\"", defpat);
+ }
+ else if((gmode & MDREPLACE) && repl_mode == TRUE){
+ status = replace_pat(defpat, &wrapt2); /* replace pattern */
+ if (wrapt == TRUE || wrapt2 == TRUE)
+- emlwrite("Replacement %srapped",
+- (status == ABORT) ? "cancelled but w" : "W");
++ emlwrite("取代%s由檔案起始從頭搜尋",
++ (status == ABORT) ? "已取消,但" : "");
+ }
+ else if(wrapt == TRUE){
+- emlwrite("Search Wrapped", NULL);
++ emlwrite("從頭搜尋", NULL);
+ }
+ else if(status == TRUE){
+ emlwrite("", NULL);
+@@ -251,7 +251,7 @@
+ /* additional 'replace all' menu option */
+ menu_pat[0].name = "^X";
+ menu_pat[0].key = (CTRL|'X');
+- menu_pat[0].label = "Repl All";
++ menu_pat[0].label = "取代所有";
+ KS_OSDATASET(&menu_pat[0], KS_NONE);
+ menu_pat[1].name = NULL;
+
+@@ -298,10 +298,10 @@
+ case (CTRL|'X'): /* toggle replace all option */
+ if (repl_all){
+ repl_all = FALSE;
+- menu_pat[0].label = "Repl All";
++ menu_pat[0].label = "取代所有";
+ }else{
+ repl_all = TRUE;
+- menu_pat[0].label = "Repl One";
++ menu_pat[0].label = "取代一個";
+ }
+ break;
+
+@@ -342,7 +342,7 @@
+ else
+ {
+ if(status == ABORT)
+- emlwrite("Replacement Cancelled", NULL);
++ emlwrite("取消取代", NULL);
+ else
+ mlerase();
+ chword(defpat, defpat);
+@@ -352,7 +352,7 @@
+
+ default:
+ if(status == ABORT)
+- emlwrite("Replacement Cancelled", NULL);
++ emlwrite("取消取代", NULL);
+ else
+ mlerase();
+ chword(defpat, defpat);
+@@ -384,9 +384,9 @@
+ (*term.t_rev)(0);
+ fflush(stdout);
+
+- strcpy(prompt, "Replace \"");
++ strcpy(prompt, "取代 \"");
+ expandp(&orig[0], &prompt[strlen(prompt)], NPAT/2);
+- strcat(prompt, "\" with \"");
++ strcat(prompt, "\" 為 \"");
+ expandp(&repl[0], &prompt[strlen(prompt)], NPAT/2);
+ strcat(prompt, "\"");
+
+@@ -400,13 +400,13 @@
+ chword(orig, orig); /* replace word by itself */
+ update();
+ if(status == ABORT){ /* if cancelled return */
+- emlwrite("Replace All cancelled after %d changes", (char *) n);
++ emlwrite("在取消「取代所有」之前,已做過 %d 個改變", (char *) n);
+ return (ABORT); /* ... else keep looking */
+ }
+ }
+ }
+ else{
+- emlwrite("No more matches for \"%s\"", orig);
++ emlwrite("沒有符合 \"%s\" 的字串了", orig);
+ return (FALSE);
+ }
+ }
+@@ -423,18 +423,18 @@
+ EXTRAKEYS menu_pat[4];
+
+ menu_pat[0].name = "^Y";
+- menu_pat[0].label = "FirstLine";
++ menu_pat[0].label = "第一行";
+ menu_pat[0].key = (CTRL|'Y');
+ KS_OSDATASET(&menu_pat[0], KS_NONE);
+ menu_pat[1].name = "^V";
+- menu_pat[1].label = "LastLine";
++ menu_pat[1].label = "最後一行";
+ menu_pat[1].key = (CTRL|'V');
+ KS_OSDATASET(&menu_pat[1], KS_NONE);
+ menu_pat[2].name = "^R";
+ if (repl_mode)
+- menu_pat[2].label = "Don't Replace";
++ menu_pat[2].label = "不取代";
+ else
+- menu_pat[2].label = "Replace";
++ menu_pat[2].label = "取代";
+ menu_pat[2].key = (CTRL|'R');
+ KS_OSDATASET(&menu_pat[2], KS_NONE);
+ menu_pat[3].name = NULL;
+@@ -485,11 +485,11 @@
+ EXTRAKEYS menu_pat[3];
+
+ menu_pat[0].name = "^Y";
+- menu_pat[0].label = "FirstLine";
++ menu_pat[0].label = "第一行";
+ menu_pat[0].key = (CTRL|'Y');
+ KS_OSDATASET(&menu_pat[0], KS_NONE);
+ menu_pat[1].name = "^V";
+- menu_pat[1].label = "LastLine";
++ menu_pat[1].label = "最後一行";
+ menu_pat[1].key = (CTRL|'V');
+ KS_OSDATASET(&menu_pat[1], KS_NONE);
+ menu_pat[2].name = NULL;
diff --git a/chinese/pine4/files/patch-an b/chinese/pine4/files/patch-an
index c0b69d687620..b617d04de358 100644
--- a/chinese/pine4/files/patch-an
+++ b/chinese/pine4/files/patch-an
@@ -1,32 +1,5416 @@
-*** pico/os_unix.h.orig Thu Jun 13 00:47:23 1996
---- pico/os_unix.h Thu Jan 29 21:29:51 1998
-***************
-*** 122,133 ****
- /*
- * Place where mail gets delivered (for pico's new mail checking)
- */
- #if defined(sv3) || defined(ct) || defined(isc) || defined(AUX) || defined(sgi)
- #define MAILDIR "/usr/mail"
- #else
- #define MAILDIR "/usr/spool/mail"
- #endif
-!
-
- /*
- * What and where the tool that checks spelling is located. If this is
---- 122,136 ----
- /*
- * Place where mail gets delivered (for pico's new mail checking)
- */
-+ #ifdef __FreeBSD__
-+ #define MAILDIR "/var/mail"
-+ #else
- #if defined(sv3) || defined(ct) || defined(isc) || defined(AUX) || defined(sgi)
- #define MAILDIR "/usr/mail"
- #else
- #define MAILDIR "/usr/spool/mail"
- #endif
-! #endif
-
- /*
- * What and where the tool that checks spelling is located. If this is
+--- pine/osdep/os-bsf.c.orig Wed Jul 15 17:02:35 1998
++++ pine/osdep/os-bsf.c Wed Jul 15 17:02:35 1998
+@@ -0,0 +1,5413 @@
++/*----------------------------------------------------------------------
++
++ T H E P I N E M A I L S Y S T E M
++
++ Laurence Lundblade and Mike Seibel
++ Networks and Distributed Computing
++ Computing and Communications
++ University of Washington
++ Administration Builiding, AG-44
++ Seattle, Washington, 98195, USA
++ Internet: lgl@CAC.Washington.EDU
++ mikes@CAC.Washington.EDU
++
++ Please address all bugs and comments to "pine-bugs@cac.washington.edu"
++
++
++ Pine and Pico are registered trademarks of the University of Washington.
++ No commercial use of these trademarks may be made without prior written
++ permission of the University of Washington.
++
++ Pine, Pico, and Pilot software and its included text are Copyright
++ 1989-1998 by the University of Washington.
++
++ The full text of our legal notices is contained in the file called
++ CPYRIGHT, included with this distribution.
++
++
++ Pine is in part based on The Elm Mail System:
++ ***********************************************************************
++ * The Elm Mail System - Revision: 2.13 *
++ * *
++ * Copyright (c) 1986, 1987 Dave Taylor *
++ * Copyright (c) 1988, 1989 USENET Community Trust *
++ ***********************************************************************
++
++
++ ----------------------------------------------------------------------*/
++
++/*======================================================================
++
++ This contains most of Pine's interface to the local operating system
++and hardware. Hopefully this file, os-xxx.h and makefile.xxx are the
++only ones that have to be modified for most ports. Signals.c, ttyin.c,
++and ttyout.c also have some dependencies. See the doc/tech-notes for
++notes on porting Pine to other platforms. Here is a list of the functions
++required for an implementation:
++
++
++ File System Access
++ can_access -- See if a file can be accessed
++ name_file_size -- Return the number of bytes in the file (by name)
++ fp_file_size -- Return the number of bytes in the file (by FILE *)
++ name_file_mtime -- Return the mtime of a file (by name)
++ fp_file_mtime -- Return the mtime of a file (by FILE *)
++ file_attrib_copy -- Copy attributes of one file to another.
++ is_writable_dir -- Check to see if directory exists and is writable
++ create_mail_dir -- Make a directory
++ rename_file -- change name of a file
++ build_path -- Put together a file system path
++ last_cmpnt -- Returns pointer to last component of path
++ expand_foldername -- Expand a folder name to full path
++ fnexpand -- Do filename exansion for csh style "~"
++ filter_filename -- Make sure file name hasn't got weird chars
++ cntxt_allowed -- Check whether a pathname is allowed for read/write
++ disk_quota -- Check the user's disk quota
++ read_file -- Read whole file into memory (for small files)
++ create_tmpfile -- Just like ANSI C tmpfile function
++ temp_nam -- Almost like common tempnam function
++ fget_pos,fset_pos -- Just like ANSI C fgetpos, fsetpos functions
++
++ Abort
++ coredump -- Abort running Pine dumping core if possible
++
++ System Name and Domain
++ hostname -- Figure out the system's host name, only
++ used internally in this file.
++ getdomainnames -- Figure out the system's domain name
++ canonical_name -- Returns canonical form of host name
++
++ Job Control
++ have_job_control -- Returns 1 if job control exists
++ stop_process -- What to do to stop process when it's time to stop
++ (only used if have_job_control returns 1)
++
++ System Error Messages (in case given one is a problem)
++ error_description -- Returns string describing error
++
++ System Password and Accounts
++ gcos_name -- Parses full name from system, only used
++ locally in this file so if you don't use it you
++ don't need it
++ get_user_info -- Finds in login name, full name, and homedir
++ local_name_lookup -- Get full name of user on system
++ change_passwd -- Calls system password changer
++
++ MIME utilities
++ mime_can_display -- Can we display this type/subtype?
++ exec_mailcap_cmd -- Run the mailcap command to view a type/subtype.
++ exec_mailcap_test_cmd -- Run mailcap test= test command.
++
++ Other stuff
++ srandom -- Dummy srandom if you don't have this function
++ init_debug
++ do_debug
++ save_debug_on_crash
++
++ ====*/
++
++
++#include "headers.h"
++
++
++
++/*----------------------------------------------------------------------
++ Check if we can access a file in a given way
++
++ Args: file -- The file to check
++ mode -- The mode ala the access() system call, see ACCESS_EXISTS
++ and friends in pine.h.
++
++ Result: returns 0 if the user can access the file according to the mode,
++ -1 if he can't (and errno is set).
++ ----*/
++int
++can_access(file, mode)
++ char *file;
++ int mode;
++{
++ return(access(file, mode));
++}
++
++
++/*----------------------------------------------------------------------
++ Check if we can access a file in a given way in the given path
++
++ Args: path -- The path to look for "file" in
++ file -- The file to check
++ mode -- The mode ala the access() system call, see ACCESS_EXISTS
++ and friends in pine.h.
++
++ Result: returns 0 if the user can access the file according to the mode,
++ -1 if he can't (and errno is set).
++ ----*/
++can_access_in_path(path, file, mode)
++ char *path, *file;
++ int mode;
++{
++ char tmp[MAXPATH], *path_copy, *p, *t;
++ int rv = -1;
++
++ if(!path || !*path || *file == '/'){
++ rv = access(file, mode);
++ }
++ else if(*file == '~'){
++ strcpy(tmp, file);
++ rv = fnexpand(tmp, sizeof(tmp)) ? access(tmp, mode) : -1;
++ }
++ else{
++ for(p = path_copy = cpystr(path); p && *p; p = t){
++ if(t = strindex(p, ':'))
++ *t++ = '\0';
++
++ sprintf(tmp, "%s/%s", p, file);
++ if((rv = access(tmp, mode)) == 0)
++ break;
++ }
++
++ fs_give((void **)&path_copy);
++ }
++
++ return(rv);
++}
++
++/*----------------------------------------------------------------------
++ Return the number of bytes in given file
++
++ Args: file -- file name
++
++ Result: the number of bytes in the file is returned or
++ -1 on error, in which case errno is valid
++ ----*/
++long
++name_file_size(file)
++ char *file;
++{
++ struct stat buffer;
++
++ if(stat(file, &buffer) != 0)
++ return(-1L);
++
++ return((long)buffer.st_size);
++}
++
++
++/*----------------------------------------------------------------------
++ Return the number of bytes in given file
++
++ Args: fp -- FILE * for open file
++
++ Result: the number of bytes in the file is returned or
++ -1 on error, in which case errno is valid
++ ----*/
++long
++fp_file_size(fp)
++ FILE *fp;
++{
++ struct stat buffer;
++
++ if(fstat(fileno(fp), &buffer) != 0)
++ return(-1L);
++
++ return((long)buffer.st_size);
++}
++
++
++/*----------------------------------------------------------------------
++ Return the modification time of given file
++
++ Args: file -- file name
++
++ Result: the time of last modification (mtime) of the file is returned or
++ -1 on error, in which case errno is valid
++ ----*/
++time_t
++name_file_mtime(file)
++ char *file;
++{
++ struct stat buffer;
++
++ if(stat(file, &buffer) != 0)
++ return((time_t)(-1));
++
++ return(buffer.st_mtime);
++}
++
++
++/*----------------------------------------------------------------------
++ Return the modification time of given file
++
++ Args: fp -- FILE * for open file
++
++ Result: the time of last modification (mtime) of the file is returned or
++ -1 on error, in which case errno is valid
++ ----*/
++time_t
++fp_file_mtime(fp)
++ FILE *fp;
++{
++ struct stat buffer;
++
++ if(fstat(fileno(fp), &buffer) != 0)
++ return((time_t)(-1));
++
++ return(buffer.st_mtime);
++}
++
++
++/*----------------------------------------------------------------------
++ Copy the mode, owner, and group of sourcefile to targetfile.
++
++ Args: targetfile --
++ sourcefile --
++
++ We don't bother keeping track of success or failure because we don't care.
++ ----*/
++void
++file_attrib_copy(targetfile, sourcefile)
++ char *targetfile;
++ char *sourcefile;
++{
++ struct stat buffer;
++
++ if(stat(sourcefile, &buffer) == 0){
++ chmod(targetfile, buffer.st_mode);
++#if !defined(DOS) && !defined(OS2)
++ chown(targetfile, buffer.st_uid, buffer.st_gid);
++#endif
++ }
++}
++
++
++
++/*----------------------------------------------------------------------
++ Check to see if a directory exists and is writable by us
++
++ Args: dir -- directory name
++
++ Result: returns 0 if it exists and is writable
++ 1 if it is a directory, but is not writable
++ 2 if it is not a directory
++ 3 it doesn't exist.
++ ----*/
++is_writable_dir(dir)
++ char *dir;
++{
++ struct stat sb;
++
++ if(stat(dir, &sb) < 0)
++ /*--- It doesn't exist ---*/
++ return(3);
++
++ if(!(sb.st_mode & S_IFDIR))
++ /*---- it's not a directory ---*/
++ return(2);
++
++ if(can_access(dir, 07))
++ return(1);
++ else
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Create the mail subdirectory.
++
++ Args: dir -- Name of the directory to create
++
++ Result: Directory is created. Returns 0 on success, else -1 on error
++ and errno is valid.
++ ----*/
++create_mail_dir(dir)
++ char *dir;
++{
++ if(mkdir(dir, 0700) < 0)
++ return(-1);
++
++ (void)chmod(dir, 0700);
++ /* Some systems need this, on others we don't care if it fails */
++ (void)chown(dir, getuid(), getgid());
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Rename a file
++
++ Args: tmpfname -- Old name of file
++ fname -- New name of file
++
++ Result: File is renamed. Returns 0 on success, else -1 on error
++ and errno is valid.
++ ----*/
++rename_file(tmpfname, fname)
++ char *tmpfname, *fname;
++{
++ return(rename(tmpfname, fname));
++}
++
++
++
++/*----------------------------------------------------------------------
++ Paste together two pieces of a file name path
++
++ Args: pathbuf -- Put the result here
++ first_part -- of path name
++ second_part -- of path name
++
++ Result: New path is in pathbuf. No check is made for overflow. Note that
++ we don't have to check for /'s at end of first_part and beginning
++ of second_part since multiple slashes are ok.
++
++BUGS: This is a first stab at dealing with fs naming dependencies, and others
++still exist.
++ ----*/
++void
++build_path(pathbuf, first_part, second_part)
++ char *pathbuf, *first_part, *second_part;
++{
++ if(!first_part)
++ strcpy(pathbuf, second_part);
++ else
++ sprintf(pathbuf, "%s%s%s", first_part,
++ (*first_part && first_part[strlen(first_part)-1] != '/')
++ ? "/" : "",
++ second_part);
++}
++
++
++/*----------------------------------------------------------------------
++ Test to see if the given file path is absolute
++
++ Args: file -- file path to test
++
++ Result: TRUE if absolute, FALSE otw
++
++ ----*/
++int
++is_absolute_path(path)
++ char *path;
++{
++ return(path && (*path == '/' || *path == '~'));
++}
++
++
++
++/*----------------------------------------------------------------------
++ Return pointer to last component of pathname.
++
++ Args: filename -- The pathname.
++
++ Result: Returned pointer points to last component in the input argument.
++ ----*/
++char *
++last_cmpnt(filename)
++ char *filename;
++{
++ register char *p = NULL, *q = filename;
++
++ while(q = strchr(q, '/'))
++ if(*++q)
++ p = q;
++
++ return(p);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Expand a folder name, taking account of the folders_dir and `~'.
++
++ Args: filename -- The name of the file that is the folder
++
++ Result: The folder name is expanded in place.
++ Returns 0 and queues status message if unsuccessful.
++ Input string is overwritten with expanded name.
++ Returns 1 if successful.
++
++BUG should limit length to MAXPATH
++ ----*/
++int
++expand_foldername(filename)
++ char *filename;
++{
++ char temp_filename[MAXPATH+1];
++
++ dprint(5, (debugfile, "=== expand_foldername called (%s) ===\n",filename));
++
++ /*
++ * We used to check for valid filename chars here if "filename"
++ * didn't refer to a remote mailbox. This has been rethought
++ */
++
++ strcpy(temp_filename, filename);
++ if(strucmp(temp_filename, "inbox") == 0) {
++ strcpy(filename, ps_global->VAR_INBOX_PATH == NULL ? "inbox" :
++ ps_global->VAR_INBOX_PATH);
++ } else if(temp_filename[0] == '{') {
++ strcpy(filename, temp_filename);
++ } else if(ps_global->restricted
++ && (strindex("./~", temp_filename[0]) != NULL
++ || srchstr(temp_filename,"/../"))){
++ q_status_message(SM_ORDER, 0, 3, "僅能開啟本地的檔案匣");
++ return(0);
++ } else if(temp_filename[0] == '*') {
++ strcpy(filename, temp_filename);
++ } else if(ps_global->VAR_OPER_DIR && srchstr(temp_filename,"..")){
++ q_status_message(SM_ORDER, 0, 3,
++ "檔案匣名稱中不允許\有 \"..\"");
++ return(0);
++ } else if (temp_filename[0] == '~'){
++ if(fnexpand(temp_filename, sizeof(temp_filename)) == NULL) {
++ char *p = strindex(temp_filename, '/');
++ if(p != NULL)
++ *p = '\0';
++ q_status_message1(SM_ORDER, 3, 3,
++ "檔案匣展開錯誤:\"%s\" 未知的使用者",
++ temp_filename);
++ return(0);
++ }
++ strcpy(filename, temp_filename);
++ } else if(temp_filename[0] == '/') {
++ strcpy(filename, temp_filename);
++ } else if(F_ON(F_USE_CURRENT_DIR, ps_global)){
++ strcpy(filename, temp_filename);
++ } else if(ps_global->VAR_OPER_DIR){
++ build_path(filename, ps_global->VAR_OPER_DIR, temp_filename);
++ } else {
++ build_path(filename, ps_global->home_dir, temp_filename);
++ }
++ dprint(5, (debugfile, "returning \"%s\"\n", filename));
++ return(1);
++}
++
++
++
++struct passwd *getpwnam();
++
++/*----------------------------------------------------------------------
++ Expand the ~ in a file ala the csh (as home directory)
++
++ Args: buf -- The filename to expand (nothing happens unless begins with ~)
++ len -- The length of the buffer passed in (expansion is in place)
++
++ Result: Expanded string is returned using same storage as passed in.
++ If expansion fails, NULL is returned
++ ----*/
++char *
++fnexpand(buf, len)
++ char *buf;
++ int len;
++{
++ struct passwd *pw;
++ register char *x,*y;
++ char name[20];
++
++ if(*buf == '~') {
++ for(x = buf+1, y = name; *x != '/' && *x != '\0'; *y++ = *x++);
++ *y = '\0';
++ if(x == buf + 1)
++ pw = getpwuid(getuid());
++ else
++ pw = getpwnam(name);
++ if(pw == NULL)
++ return((char *)NULL);
++ if(strlen(pw->pw_dir) + strlen(buf) > len) {
++ return((char *)NULL);
++ }
++ rplstr(buf, x - buf, pw->pw_dir);
++ }
++ return(len ? buf : (char *)NULL);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Filter file names for strange characters
++
++ Args: file -- the file name to check
++
++ Result: Returns NULL if file name is OK
++ Returns formatted error message if it is not
++ ----*/
++char *
++filter_filename(file)
++ char *file;
++{
++#ifdef ALLOW_WEIRD
++ static char illegal[] = {'\177', '\0'};
++#else
++ static char illegal[] = {'"', '#', '$', '%', '&', '\'','(', ')','*',
++ ',', ':', ';', '<', '=', '>', '?', '[', ']',
++ '\\', '^', '|', '\177', '\0'};
++#endif
++ static char error[100];
++ char ill_file[MAXPATH+1], *ill_char, *ptr, e2[10];
++ int i;
++
++ for(ptr = file; *ptr == ' '; ptr++) ; /* leading spaces gone */
++
++ while(*ptr && (unsigned char)(*ptr) > ' ' && strindex(illegal, *ptr) == 0)
++ ptr++;
++
++ if(*ptr != '\0') {
++ if(*ptr == ' ') {
++ ill_char = "<space>";
++ } else if(*ptr == '\n') {
++ ill_char = "<newline>";
++ } else if(*ptr == '\r') {
++ ill_char = "<carriage return>";
++ } else if(*ptr == '\t') {
++ ill_char = "<tab>";
++ } else if(*ptr < ' ') {
++ sprintf(e2, "control-%c", *ptr + '@');
++ ill_char = e2;
++ } else if (*ptr == '\177') {
++ ill_char = "<del>";
++ } else {
++ e2[0] = *ptr;
++ e2[1] = '\0';
++ ill_char = e2;
++ }
++ if(ptr != file) {
++ strncpy(ill_file, file, ptr - file);
++ ill_file[ptr - file] = '\0';
++ sprintf(error,
++ "Character \"%s\" after \"%s\" not allowed in file name",
++ ill_char, ill_file);
++ } else {
++ sprintf(error,
++ "First character, \"%s\", not allowed in file name",
++ ill_char);
++ }
++
++ return(error);
++ }
++
++ if((i=is_writable_dir(file)) == 0 || i == 1){
++ sprintf(error, "\"%s\" is a directory", file);
++ return(error);
++ }
++
++ if(ps_global->restricted || ps_global->VAR_OPER_DIR){
++ for(ptr = file; *ptr == ' '; ptr++) ; /* leading spaces gone */
++
++ if((ptr[0] == '.' && ptr[1] == '.') || srchstr(ptr, "/../")){
++ sprintf(error, "\"..\" not allowed in filename");
++ return(error);
++ }
++ }
++
++ return((char *)NULL);
++}
++
++
++/*----------------------------------------------------------------------
++ Check to see if user is allowed to read or write this folder.
++
++ Args: s -- the name to check
++
++ Result: Returns 1 if OK
++ Returns 0 and posts an error message if access is denied
++ ----*/
++int
++cntxt_allowed(s)
++ char *s;
++{
++ struct variable *vars = ps_global->vars;
++ int retval = 1;
++ MAILSTREAM stream; /* fake stream for error message in mm_notify */
++
++ if(ps_global->restricted
++ && (strindex("./~", s[0]) || srchstr(s, "/../"))){
++ stream.mailbox = s;
++ mm_notify(&stream, "Restricted mode doesn't allow operation", WARN);
++ retval = 0;
++ }
++ else if(VAR_OPER_DIR
++ && s[0] != '{' && !(s[0] == '*' && s[1] == '{')
++ && strucmp(s,ps_global->inbox_name) != 0
++ && strcmp(s, ps_global->VAR_INBOX_PATH) != 0){
++ char *p, *free_this = NULL;
++
++ p = s;
++ if(strindex(s, '~')){
++ p = strindex(s, '~');
++ free_this = (char *)fs_get(strlen(p) + 200);
++ strcpy(free_this, p);
++ fnexpand(free_this, strlen(p)+200);
++ p = free_this;
++ }
++ else if(p[0] != '/'){ /* add home dir to relative paths */
++ free_this = p = (char *)fs_get(strlen(s)
++ + strlen(ps_global->home_dir) + 2);
++ build_path(p, ps_global->home_dir, s);
++ }
++
++ if(!in_dir(VAR_OPER_DIR, p)){
++ char err[200];
++
++ sprintf(err, "Not allowed outside of %s", VAR_OPER_DIR);
++ stream.mailbox = p;
++ mm_notify(&stream, err, WARN);
++ retval = 0;
++ }
++ else if(srchstr(p, "/../")){ /* check for .. in path */
++ stream.mailbox = p;
++ mm_notify(&stream, "\"..\" not allowed in name", WARN);
++ retval = 0;
++ }
++
++ if(free_this)
++ fs_give((void **)&free_this);
++ }
++
++ return retval;
++}
++
++
++
++#if defined(USE_QUOTAS)
++
++/*----------------------------------------------------------------------
++ This system doesn't have disk quotas.
++ Return space left in disk quota on file system which given path is in.
++
++ Args: path - Path name of file or directory on file system of concern
++ over - pointer to flag that is set if the user is over quota
++
++ Returns: If *over = 0, the number of bytes free in disk quota as per
++ the soft limit.
++ If *over = 1, the number of bytes *over* quota.
++ -1 is returned on an error looking up quota
++ 0 is returned if there is no quota
++
++BUG: If there's more than 2.1Gb free this function will break
++ ----*/
++long
++disk_quota(path, over)
++ char *path;
++ int *over;
++{
++ return(0L);
++}
++#endif /* USE_QUOTAS */
++
++
++
++/*----------------------------------------------------------------------
++ Read whole file into memory
++
++ Args: filename -- path name of file to read
++
++ Result: Returns pointer to malloced memory with the contents of the file
++ or NULL
++
++This won't work very well if the file has NULLs in it and is mostly
++intended for fairly small text files.
++ ----*/
++char *
++read_file(filename)
++ char *filename;
++{
++ int fd;
++ struct stat statbuf;
++ char *buf;
++ int nb;
++
++ fd = open(filename, O_RDONLY);
++ if(fd < 0)
++ return((char *)NULL);
++
++ fstat(fd, &statbuf);
++
++ buf = fs_get((size_t)statbuf.st_size + 1);
++
++ /*
++ * On some systems might have to loop here, if one read isn't guaranteed
++ * to get the whole thing.
++ */
++ if((nb = read(fd, buf, (int)statbuf.st_size)) < 0)
++ fs_give((void **)&buf); /* NULL's buf */
++ else
++ buf[nb] = '\0';
++
++ close(fd);
++ return(buf);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Create a temporary file, the name of which we don't care about
++and that goes away when it is closed. Just like ANSI C tmpfile.
++ ----*/
++FILE *
++create_tmpfile()
++{
++ return(tmpfile());
++}
++
++
++
++/*----------------------------------------------------------------------
++ Abort with a core dump
++ ----*/
++void
++coredump()
++{
++ abort();
++}
++
++
++
++/*----------------------------------------------------------------------
++ Call system gethostname
++
++ Args: hostname -- buffer to return host name in
++ size -- Size of buffer hostname is to be returned in
++
++ Result: returns 0 if the hostname is correctly set,
++ -1 if not (and errno is set).
++ ----*/
++hostname(hostname,size)
++ char *hostname;
++ int size;
++{
++ return(gethostname(hostname, size));
++}
++
++
++
++/*----------------------------------------------------------------------
++ Get the current host and domain names
++
++ Args: hostname -- buffer to return the hostname in
++ hsize -- size of buffer above
++ domainname -- buffer to return domain name in
++ dsize -- size of buffer above
++
++ Result: The system host and domain names are returned. If the full host
++ name is akbar.cac.washington.edu then the domainname is
++ cac.washington.edu.
++
++On Internet connected hosts this look up uses /etc/hosts and DNS to
++figure all this out. On other less well connected machines some other
++file may be read. If there is no notion of a domain name the domain
++name may be left blank. On a PC where there really isn't a host name
++this should return blank strings. The .pinerc will take care of
++configuring the domain names. That is, this should only return the
++native system's idea of what the names are if the system has such
++a concept.
++ ----*/
++void
++getdomainnames(hostname, hsize, domainname, dsize)
++ char *hostname, *domainname;
++ int hsize, dsize;
++{
++ char *dn, hname[MAX_ADDRESS+1];
++ struct hostent *he;
++ char **alias;
++ char *maybe = NULL;
++
++ gethostname(hname, MAX_ADDRESS);
++ he = gethostbyname(hname);
++ hostname[0] = '\0';
++
++ if(he == NULL)
++ strncpy(hostname, hname, hsize-1);
++ else{
++ /*
++ * If no dot in hostname it may be the case that there
++ * is an alias which is really the fully-qualified
++ * hostname. This could happen if the administrator has
++ * (incorrectly) put the unqualified name first in the
++ * hosts file, for example. The problem with looking for
++ * an alias with a dot is that now we're guessing, since
++ * the aliases aren't supposed to be the official hostname.
++ * We'll compromise and only use an alias if the primary
++ * name has no dot and exactly one of the aliases has a
++ * dot.
++ */
++ strncpy(hostname, he->h_name, hsize-1);
++ if(strindex(hostname, '.') == NULL){ /* no dot in hostname */
++ for(alias = he->h_aliases; *alias; alias++){
++ if(strindex(*alias, '.') != NULL){ /* found one */
++ if(maybe){ /* oops, this is the second one */
++ maybe = NULL;
++ break;
++ }
++ else
++ maybe = *alias;
++ }
++ }
++
++ if(maybe)
++ strncpy(hostname, maybe, hsize-1);
++ }
++ }
++
++ hostname[hsize-1] = '\0';
++
++
++ if((dn = strindex(hostname, '.')) != NULL)
++ strncpy(domainname, dn+1, dsize-1);
++ else
++ strncpy(domainname, hostname, dsize-1);
++
++ domainname[dsize-1] = '\0';
++}
++
++
++
++/*----------------------------------------------------------------------
++ Return canonical form of host name ala c-client (UNIX version).
++
++ Args: host -- The host name
++
++ Result: Canonical form, or input argument (worst case)
++ ----*/
++char *
++canonical_name(host)
++ char *host;
++{
++ struct hostent *hent;
++ char hostname[MAILTMPLEN];
++ char tmp[MAILTMPLEN];
++ extern char *lcase();
++ /* domain literal is easy */
++ if (host[0] == '[' && host[(strlen (host))-1] == ']')
++ return host;
++
++ strcpy (hostname,host); /* UNIX requires lowercase */
++ /* lookup name, return canonical form */
++ return (hent = gethostbyname (lcase (strcpy (tmp,host)))) ?
++ hent->h_name : host;
++}
++
++
++
++/*----------------------------------------------------------------------
++ This routine returns 1 if job control is available. Note, thiis
++ could be some type of fake job control. It doesn't have to be
++ real BSD-style job control.
++ ----*/
++have_job_control()
++{
++ return 1;
++}
++
++
++/*----------------------------------------------------------------------
++ If we don't have job control, this routine is never called.
++ ----*/
++stop_process()
++{
++ SigType (*save_usr2) SIG_PROTO((int));
++
++ /*
++ * Since we can't respond to KOD while stopped, the process that sent
++ * the KOD is going to go read-only. Therefore, we can safely ignore
++ * any KODs that come in before we are ready to respond...
++ */
++ save_usr2 = signal(SIGUSR2, SIG_IGN);
++ kill(0, SIGSTOP);
++ (void)signal(SIGUSR2, save_usr2);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Return string describing the error
++
++ Args: errnumber -- The system error number (errno)
++
++ Result: long string describing the error is returned
++ ----*/
++char *
++error_description(errnumber)
++ int errnumber;
++{
++ static char buffer[50+1];
++
++ if(errnumber >= 0 && errnumber < sys_nerr)
++ sprintf(buffer, "%.*s", 50, sys_errlist[errnumber]);
++ else
++ sprintf(buffer, "Unknown error #%d", errnumber);
++
++ return ( (char *) buffer);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Pull the name out of the gcos field if we have that sort of /etc/passwd
++
++ Args: gcos_field -- The long name or GCOS field to be parsed
++ logname -- Replaces occurances of & with logname string
++
++ Result: returns pointer to buffer with name
++ ----*/
++static char *
++gcos_name(gcos_field, logname)
++ char *logname, *gcos_field;
++{
++ static char fullname[MAX_FULLNAME+1];
++ register char *fncp, *gcoscp, *lncp, *end;
++
++ /* full name is all chars up to first ',' (or whole gcos, if no ',') */
++ /* replace any & with logname in upper case */
++
++ for(fncp = fullname, gcoscp= gcos_field, end = fullname + MAX_FULLNAME - 1;
++ (*gcoscp != ',' && *gcoscp != '\0' && fncp != end);
++ gcoscp++) {
++
++ if(*gcoscp == '&') {
++ for(lncp = logname; *lncp; fncp++, lncp++)
++ *fncp = toupper((unsigned char)(*lncp));
++ } else {
++ *fncp++ = *gcoscp;
++ }
++ }
++
++ *fncp = '\0';
++ return(fullname);
++}
++
++
++/*----------------------------------------------------------------------
++ Fill in homedir, login, and fullname for the logged in user.
++ These are all pointers to static storage so need to be copied
++ in the caller.
++
++ Args: ui -- struct pointer to pass back answers
++
++ Result: fills in the fields
++ ----*/
++void
++get_user_info(ui)
++ struct user_info *ui;
++{
++ struct passwd *unix_pwd;
++
++ unix_pwd = getpwuid(getuid());
++ if(unix_pwd == NULL) {
++ ui->homedir = cpystr("");
++ ui->login = cpystr("");
++ ui->fullname = cpystr("");
++ }else {
++ ui->homedir = cpystr(unix_pwd->pw_dir);
++ ui->login = cpystr(unix_pwd->pw_name);
++ ui->fullname = cpystr(gcos_name(unix_pwd->pw_gecos, unix_pwd->pw_name));
++ }
++}
++
++
++/*----------------------------------------------------------------------
++ Look up a userid on the local system and return rfc822 address
++
++ Args: name -- possible login name on local system
++
++ Result: returns NULL or pointer to alloc'd string rfc822 address.
++ ----*/
++char *
++local_name_lookup(name)
++ char *name;
++{
++ struct passwd *pw = getpwnam(name);
++
++ if(pw == NULL)
++ return((char *)NULL);
++
++ return(cpystr(gcos_name(pw->pw_gecos, name)));
++}
++
++
++
++/*----------------------------------------------------------------------
++ Call the system to change the passwd
++
++It would be nice to talk to the passwd program via a pipe or ptty so the
++user interface could be consistent, but we can't count on the the prompts
++and responses from the passwd program to be regular so we just let the user
++type at the passwd program with some screen space, hope he doesn't scroll
++off the top and repaint when he's done.
++ ----*/
++change_passwd()
++{
++ char cmd_buf[100];
++
++ ClearLines(1, ps_global->ttyo->screen_rows - 1);
++
++ MoveCursor(5, 0);
++ fflush(stdout);
++
++ PineRaw(0);
++ strcpy(cmd_buf, PASSWD_PROG);
++ system(cmd_buf);
++ sleep(3);
++ PineRaw(1);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Can we display this type/subtype?
++
++ Args: type -- the MIME type to check
++ subtype -- the MIME subtype
++ params -- parameters
++ use_viewer -- tell caller he should run external viewer cmd to view
++
++ Result: Returns:
++
++ MCD_NONE if we can't display this type at all
++ MCD_INTERNAL if we can display it internally
++ MCD_EXTERNAL if it can be displayed via an external viewer
++
++ ----*/
++mime_can_display(type, subtype, params)
++ int type;
++ char *subtype;
++ PARAMETER *params;
++{
++ return((mailcap_can_display(type, subtype, params)
++ ? MCD_EXTERNAL : MCD_NONE)
++ | ((type == TYPETEXT || type == TYPEMESSAGE
++ || MIME_VCARD(type,subtype))
++ ? MCD_INTERNAL : MCD_NONE));
++}
++
++
++
++/*----------------------------------------------------------------------
++ This is just a call to the ANSI C fgetpos function.
++ ----*/
++fget_pos(stream, ptr)
++FILE *stream;
++fpos_t *ptr;
++{
++ return(fgetpos(stream, ptr));
++}
++
++
++/*----------------------------------------------------------------------
++ This is just a call to the ANSI C fsetpos function.
++ ----*/
++fset_pos(stream, ptr)
++FILE *stream;
++fpos_t *ptr;
++{
++ return(fsetpos(stream, ptr));
++}
++
++
++
++/*======================================================================
++ pipe
++
++ Initiate I/O to and from a process. These functions are similar to
++ popen and pclose, but both an incoming stream and an output file are
++ provided.
++
++ ====*/
++
++#ifndef STDIN_FILENO
++#define STDIN_FILENO 0
++#endif
++#ifndef STDOUT_FILENO
++#define STDOUT_FILENO 1
++#endif
++#ifndef STDERR_FILENO
++#define STDERR_FILENO 2
++#endif
++
++
++/*
++ * Defs to help fish child's exit status out of wait(2)
++ */
++#ifdef HAVE_WAIT_UNION
++#define WaitType union wait
++#ifndef WIFEXITED
++#define WIFEXITED(X) (!(X).w_termsig) /* child exit by choice */
++#endif
++#ifndef WEXITSTATUS
++#define WEXITSTATUS(X) (X).w_retcode /* childs chosen exit value */
++#endif
++#else
++#define WaitType int
++#ifndef WIFEXITED
++#define WIFEXITED(X) (!((X) & 0xff)) /* low bits tell how it died */
++#endif
++#ifndef WEXITSTATUS
++#define WEXITSTATUS(X) (((X) >> 8) & 0xff) /* high bits tell exit value */
++#endif
++#endif
++
++
++/*
++ * Global's to helpsignal handler tell us child's status has changed...
++ */
++short child_signalled;
++short child_jump = 0;
++jmp_buf child_state;
++
++
++/*
++ * Internal Protos
++ */
++void pipe_error_cleanup PROTO((PIPE_S **, char *, char *, char *));
++void zot_pipe PROTO((PIPE_S **));
++
++
++
++
++/*----------------------------------------------------------------------
++ Spawn a child process and optionally connect read/write pipes to it
++
++ Args: command -- string to hand the shell
++ outfile -- address of pointer containing file to receive output
++ errfile -- address of pointer containing file to receive error output
++ mode -- mode for type of shell, signal protection etc...
++ Returns: pointer to alloc'd PIPE_S on success, NULL otherwise
++
++ The outfile is either NULL, a pointer to a NULL value, or a pointer
++ to the requested name for the output file. In the pointer-to-NULL case
++ the caller doesn't care about the name, but wants to see the pipe's
++ results so we make one up. It's up to the caller to make sure the
++ free storage containing the name is cleaned up.
++
++ Mode bits serve several purposes.
++ PIPE_WRITE tells us we need to open a pipe to write the child's
++ stdin.
++ PIPE_READ tells us we need to open a pipe to read from the child's
++ stdout/stderr. *NOTE* Having neither of the above set means
++ we're not setting up any pipes, just forking the child and exec'ing
++ the command. Also, this takes precedence over any named outfile.
++ PIPE_STDERR means we're to tie the childs stderr to the same place
++ stdout is going. *NOTE* This only makes sense then if PIPE_READ
++ or an outfile is provided. Also, this takes precedence over any
++ named errfile.
++ PIPE_PROT means to protect the child from the usual nasty signals
++ that might cause premature death. Otherwise, the default signals are
++ set so the child can deal with the nasty signals in its own way.
++ PIPE_NOSHELL means we're to exec the command without the aid of
++ a system shell. *NOTE* This negates the affect of PIPE_USER.
++ PIPE_USER means we're to try executing the command in the user's
++ shell. Right now we only look in the environment, but that may get
++ more sophisticated later.
++ PIPE_RESET means we reset the terminal mode to what it was before
++ we started pine and then exec the command.
++ ----*/
++PIPE_S *
++open_system_pipe(command, outfile, errfile, mode)
++ char *command;
++ char **outfile, **errfile;
++ int mode;
++{
++ PIPE_S *syspipe = NULL;
++ char shellpath[32], *shell;
++ int p[2], oparentd = -1, ochildd = -1, iparentd = -1, ichildd = -1;
++
++ dprint(5, (debugfile, "Opening pipe: \"%s\" (%s%s%s%s%s%s)\n", command,
++ (mode & PIPE_WRITE) ? "W":"", (mode & PIPE_READ) ? "R":"",
++ (mode & PIPE_NOSHELL) ? "N":"", (mode & PIPE_PROT) ? "P":"",
++ (mode & PIPE_USER) ? "U":"", (mode & PIPE_RESET) ? "T":""));
++
++ syspipe = (PIPE_S *)fs_get(sizeof(PIPE_S));
++ memset(syspipe, 0, sizeof(PIPE_S));
++
++ /*
++ * If we're not using the shell's command parsing smarts, build
++ * argv by hand...
++ */
++ if(mode & PIPE_NOSHELL){
++ char **ap, *p;
++ size_t n;
++
++ /* parse the arguments into argv */
++ for(p = command; *p && isspace((unsigned char)(*p)); p++)
++ ; /* swallow leading ws */
++
++ if(*p){
++ syspipe->args = cpystr(p);
++ }
++ else{
++ pipe_error_cleanup(&syspipe, "<null>", "execute",
++ "No command name found");
++ return(NULL);
++ }
++
++ for(p = syspipe->args, n = 2; *p; p++) /* count the args */
++ if(isspace((unsigned char)(*p))
++ && *(p+1) && !isspace((unsigned char)(*(p+1))))
++ n++;
++
++ syspipe->argv = ap = (char **)fs_get(n * sizeof(char *));
++ memset(syspipe->argv, 0, n * sizeof(char *));
++
++ for(p = syspipe->args; *p; ){ /* collect args */
++ while(*p && isspace((unsigned char)(*p)))
++ *p++ = '\0';
++
++ *ap++ = (*p) ? p : NULL;
++ while(*p && !isspace((unsigned char)(*p)))
++ p++;
++ }
++
++ /* make sure argv[0] exists in $PATH */
++ if(can_access_in_path(getenv("PATH"), syspipe->argv[0],
++ EXECUTE_ACCESS) < 0){
++ pipe_error_cleanup(&syspipe, syspipe->argv[0], "access",
++ error_description(errno));
++ return(NULL);
++ }
++ }
++
++ /* fill in any output filenames */
++ if(!(mode & PIPE_READ)){
++ if(outfile && !*outfile)
++ *outfile = temp_nam(NULL, "pine_p"); /* asked for, but not named? */
++
++ if(errfile && !*errfile)
++ *errfile = temp_nam(NULL, "pine_p"); /* ditto */
++ }
++
++ /* create pipes */
++ if(mode & (PIPE_WRITE | PIPE_READ)){
++ if(mode & PIPE_WRITE){
++ pipe(p); /* alloc pipe to write child */
++ oparentd = p[STDOUT_FILENO];
++ ichildd = p[STDIN_FILENO];
++ }
++
++ if(mode & PIPE_READ){
++ pipe(p); /* alloc pipe to read child */
++ iparentd = p[STDIN_FILENO];
++ ochildd = p[STDOUT_FILENO];
++ }
++ }
++ else if(!(mode & PIPE_SILENT)){
++ flush_status_messages(0); /* just clean up display */
++ ClearScreen();
++ fflush(stdout);
++ }
++
++ if((syspipe->mode = mode) & PIPE_RESET)
++ PineRaw(0);
++
++#ifdef SIGCHLD
++ /*
++ * Prepare for demise of child. Use SIGCHLD if it's available so
++ * we can do useful things, like keep the IMAP stream alive, while
++ * we're waiting on the child.
++ */
++ child_signalled = child_jump = 0;
++#endif
++
++ if((syspipe->pid = vfork()) == 0){
++ /* reset child's handlers in requested fashion... */
++ (void)signal(SIGINT, (mode & PIPE_PROT) ? SIG_IGN : SIG_DFL);
++ (void)signal(SIGQUIT, (mode & PIPE_PROT) ? SIG_IGN : SIG_DFL);
++ (void)signal(SIGHUP, (mode & PIPE_PROT) ? SIG_IGN : SIG_DFL);
++#ifdef SIGCHLD
++ (void) signal(SIGCHLD, SIG_DFL);
++#endif
++
++ /* if parent isn't reading, and we have a filename to write */
++ if(!(mode & PIPE_READ) && outfile){ /* connect output to file */
++ int output = creat(*outfile, 0600);
++ dup2(output, STDOUT_FILENO);
++ if(mode & PIPE_STDERR)
++ dup2(output, STDERR_FILENO);
++ else if(errfile)
++ dup2(creat(*errfile, 0600), STDERR_FILENO);
++ }
++
++ if(mode & PIPE_WRITE){ /* connect process input */
++ close(oparentd);
++ dup2(ichildd, STDIN_FILENO); /* tie stdin to pipe */
++ close(ichildd);
++ }
++
++ if(mode & PIPE_READ){ /* connect process output */
++ close(iparentd);
++ dup2(ochildd, STDOUT_FILENO); /* tie std{out,err} to pipe */
++ if(mode & PIPE_STDERR)
++ dup2(ochildd, STDERR_FILENO);
++ else if(errfile)
++ dup2(creat(*errfile, 0600), STDERR_FILENO);
++
++ close(ochildd);
++ }
++
++ if(mode & PIPE_NOSHELL){
++ execvp(syspipe->argv[0], syspipe->argv);
++ }
++ else{
++ if(mode & PIPE_USER){
++ char *env, *sh;
++ if((env = getenv("SHELL")) && (sh = strrchr(env, '/'))){
++ shell = sh + 1;
++ strcpy(shellpath, env);
++ }
++ else{
++ shell = "csh";
++ strcpy(shellpath, "/bin/csh");
++ }
++ }
++ else{
++ shell = "sh";
++ strcpy(shellpath, "/bin/sh");
++ }
++
++ execl(shellpath, shell, command ? "-c" : 0, command, 0);
++ }
++
++ fprintf(stderr, "Can't exec %s\nReason: %s",
++ command, error_description(errno));
++ _exit(-1);
++ }
++
++ if(syspipe->pid > 0){
++ syspipe->isig = signal(SIGINT, SIG_IGN); /* Reset handlers to make */
++ syspipe->qsig = signal(SIGQUIT, SIG_IGN); /* sure we don't come to */
++ syspipe->hsig = signal(SIGHUP, SIG_IGN); /* a premature end... */
++
++ if(mode & PIPE_WRITE){
++ close(ichildd);
++ if(mode & PIPE_DESC)
++ syspipe->out.d = oparentd;
++ else
++ syspipe->out.f = fdopen(oparentd, "w");
++ }
++
++ if(mode & PIPE_READ){
++ close(ochildd);
++ if(mode & PIPE_DESC)
++ syspipe->in.d = iparentd;
++ else
++ syspipe->in.f = fdopen(iparentd, "r");
++ }
++
++ dprint(5, (debugfile, "PID: %d, COMMAND: %s\n",syspipe->pid,command));
++ }
++ else{
++ if(mode & (PIPE_WRITE | PIPE_READ)){
++ if(mode & PIPE_WRITE){
++ close(oparentd);
++ close(ichildd);
++ }
++
++ if(mode & PIPE_READ){
++ close(iparentd);
++ close(ochildd);
++ }
++ }
++ else if(!(mode & PIPE_SILENT)){
++ ClearScreen();
++ ps_global->mangled_screen = 1;
++ }
++
++ if(mode & PIPE_RESET)
++ PineRaw(1);
++
++#ifdef SIGCHLD
++ (void) signal(SIGCHLD, SIG_DFL);
++#endif
++ if(outfile)
++ fs_give((void **) outfile);
++
++ pipe_error_cleanup(&syspipe, command, "fork",error_description(errno));
++ }
++
++ return(syspipe);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Write appropriate error messages and cleanup after pipe error
++
++ Args: syspipe -- address of pointer to struct to clean up
++ cmd -- command we were trying to exec
++ op -- operation leading up to the exec
++ res -- result of that operation
++
++ ----*/
++void
++pipe_error_cleanup(syspipe, cmd, op, res)
++ PIPE_S **syspipe;
++ char *cmd, *op, *res;
++{
++ q_status_message3(SM_ORDER, 3, 3, "Pipe can't %s \"%.20s\": %s",
++ op, cmd, res);
++ dprint(1, (debugfile, "* * PIPE CAN'T %s(%s): %s\n", op, cmd, res));
++ zot_pipe(syspipe);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Free resources associated with the given pipe struct
++
++ Args: syspipe -- address of pointer to struct to clean up
++
++ ----*/
++void
++zot_pipe(syspipe)
++ PIPE_S **syspipe;
++{
++ if((*syspipe)->args)
++ fs_give((void **) &(*syspipe)->args);
++
++ if((*syspipe)->argv)
++ fs_give((void **) &(*syspipe)->argv);
++
++ if((*syspipe)->tmp)
++ fs_give((void **) &(*syspipe)->tmp);
++
++ fs_give((void **)syspipe);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Close pipe previously allocated and wait for child's death
++
++ Args: syspipe -- address of pointer to struct returned by open_system_pipe
++ Returns: returns exit status of child or -1 if invalid syspipe
++ ----*/
++int
++close_system_pipe(syspipe)
++ PIPE_S **syspipe;
++{
++ WaitType stat;
++ int status;
++
++ if(!(syspipe && *syspipe))
++ return(-1);
++
++ if(((*syspipe)->mode) & PIPE_WRITE){
++ if(((*syspipe)->mode) & PIPE_DESC){
++ if((*syspipe)->out.d >= 0)
++ close((*syspipe)->out.d);
++ }
++ else if((*syspipe)->out.f)
++ fclose((*syspipe)->out.f);
++ }
++
++ if(((*syspipe)->mode) & PIPE_READ){
++ if(((*syspipe)->mode) & PIPE_DESC){
++ if((*syspipe)->in.d >= 0)
++ close((*syspipe)->in.d);
++ }
++ else if((*syspipe)->in.f)
++ fclose((*syspipe)->in.f);
++ }
++
++#ifdef SIGCHLD
++ {
++ SigType (*alarm_sig)();
++ int old_cue = F_ON(F_SHOW_DELAY_CUE, ps_global);
++
++ /*
++ * remember the current SIGALRM handler, and make sure it's
++ * installed when we're finished just in case the longjmp
++ * out of the SIGCHLD handler caused sleep() to lose it.
++ * Don't pay any attention to that man behind the curtain.
++ */
++ alarm_sig = signal(SIGALRM, SIG_IGN);
++ (void) signal(SIGALRM, alarm_sig);
++ F_SET(F_SHOW_DELAY_CUE, ps_global, 0);
++ ps_global->noshow_timeout = 1;
++ while(!child_signalled){
++ /* wake up and prod server */
++ new_mail(0, 2, ((*syspipe)->mode & PIPE_RESET)
++ ? NM_NONE : NM_DEFER_SORT);
++
++ if(!child_signalled){
++ if(setjmp(child_state) == 0){
++ child_jump = 1; /* prepare to wake up */
++ sleep(600); /* give it 5mins to happend */
++ }
++ else
++ our_sigunblock(SIGCHLD);
++ }
++
++ child_jump = 0;
++ }
++
++ ps_global->noshow_timeout = 0;
++ F_SET(F_SHOW_DELAY_CUE, ps_global, old_cue);
++ (void) signal(SIGALRM, alarm_sig);
++ }
++#endif
++
++ /*
++ * Call c-client's pid reaper to wait() on the demise of our child,
++ * then fish out its exit status...
++ */
++ grim_pid_reap_status((*syspipe)->pid, 0, &stat);
++ status = WIFEXITED(stat) ? WEXITSTATUS(stat) : -1;
++
++ /*
++ * restore original handlers...
++ */
++ (void)signal(SIGINT, (*syspipe)->isig);
++ (void)signal(SIGHUP, (*syspipe)->hsig);
++ (void)signal(SIGQUIT, (*syspipe)->qsig);
++
++ if((*syspipe)->mode & PIPE_RESET) /* restore our tty modes */
++ PineRaw(1);
++
++ if(!((*syspipe)->mode & (PIPE_WRITE | PIPE_READ | PIPE_SILENT))){
++ ClearScreen(); /* No I/O to forked child */
++ ps_global->mangled_screen = 1;
++ }
++
++ zot_pipe(syspipe);
++
++ return(status);
++}
++
++/*======================================================================
++ post_reap
++
++ Manage exit status collection of a child spawned to handle posting
++ ====*/
++
++
++
++#if defined(BACKGROUND_POST) && defined(SIGCHLD)
++/*----------------------------------------------------------------------
++ Check to see if we have any posting processes to clean up after
++
++ Args: none
++ Returns: any finished posting process reaped
++ ----*/
++post_reap()
++{
++ WaitType stat;
++ int r;
++
++ if(ps_global->post && ps_global->post->pid){
++ r = waitpid(ps_global->post->pid, &stat, WNOHANG);
++ if(r == ps_global->post->pid){
++ ps_global->post->status = WIFEXITED(stat) ? WEXITSTATUS(stat) : -1;
++ ps_global->post->pid = 0;
++ return(1);
++ }
++ else if(r < 0 && errno != EINTR){ /* pid's become bogus?? */
++ fs_give((void **) &ps_global->post);
++ }
++ }
++
++ return(0);
++}
++#endif
++
++/*----------------------------------------------------------------------
++ Routines used to hand off messages to local agents for sending/posting
++
++ The two exported routines are:
++
++ 1) smtp_command() -- used to get local transport agent to invoke
++ 2) post_handoff() -- used to pass messages to local posting agent
++
++ ----*/
++
++
++
++/*
++ * Protos for "sendmail" internal functions
++ */
++static char *mta_parse_post PROTO((METAENV *, BODY *, char *, char *));
++static long pine_pipe_soutr_nl PROTO((void *, char *));
++
++
++
++/* ----------------------------------------------------------------------
++ Figure out command to start local SMTP agent
++
++ Args: errbuf -- buffer for reporting errors (assumed non-NULL)
++
++ Returns an alloc'd copy of the local SMTP agent invocation or NULL
++
++ ----*/
++char *
++smtp_command(errbuf)
++ char *errbuf;
++{
++#if defined(SENDMAIL) && defined(SENDMAILFLAGS)
++ char tmp[256];
++
++ sprintf(tmp, "%s %s", SENDMAIL, SENDMAILFLAGS);
++ return(cpystr(tmp));
++#else
++ strcpy(errbuf, "No default posting command.");
++ return(NULL);
++#endif
++}
++
++
++
++/*----------------------------------------------------------------------
++ Hand off given message to local posting agent
++
++ Args: envelope -- The envelope for the BCC and debugging
++ header -- The text of the message header
++ errbuf -- buffer for reporting errors (assumed non-NULL)
++
++ ----*/
++int
++mta_handoff(header, body, errbuf)
++ METAENV *header;
++ BODY *body;
++ char *errbuf;
++{
++ char cmd_buf[256], *cmd = NULL;
++
++ /*
++ * A bit of complicated policy implemented here.
++ * There are two posting variables sendmail-path and smtp-server.
++ * Precedence is in that order.
++ * They can be set one of 4 ways: fixed, command-line, user, or globally.
++ * Precedence is in that order.
++ * Said differently, the order goes something like what's below.
++ *
++ * NOTE: the fixed/command-line/user precendence handling is also
++ * indicated by what's pointed to by ps_global->VAR_*, but since
++ * that also includes the global defaults, it's not sufficient.
++ */
++
++ if(ps_global->FIX_SENDMAIL_PATH
++ && ps_global->FIX_SENDMAIL_PATH[0]){
++ cmd = ps_global->FIX_SENDMAIL_PATH;
++ }
++ else if(!(ps_global->FIX_SMTP_SERVER
++ && ps_global->FIX_SMTP_SERVER[0])){
++ if(ps_global->COM_SENDMAIL_PATH
++ && ps_global->COM_SENDMAIL_PATH[0]){
++ cmd = ps_global->COM_SENDMAIL_PATH;
++ }
++ else if(!(ps_global->COM_SMTP_SERVER
++ && ps_global->COM_SMTP_SERVER[0])){
++ if(ps_global->USR_SENDMAIL_PATH
++ && ps_global->USR_SENDMAIL_PATH[0]){
++ cmd = ps_global->USR_SENDMAIL_PATH;
++ }
++ else if(!(ps_global->USR_SMTP_SERVER
++ && ps_global->USR_SMTP_SERVER[0])){
++ if(ps_global->GLO_SENDMAIL_PATH
++ && ps_global->GLO_SENDMAIL_PATH[0]){
++ cmd = ps_global->GLO_SENDMAIL_PATH;
++ }
++#ifdef DF_SENDMAIL_PATH
++ /*
++ * This defines the default method of posting. So,
++ * unless we're told otherwise use it...
++ */
++ else if(!(ps_global->GLO_SMTP_SERVER
++ && ps_global->GLO_SMTP_SERVER[0])){
++ strcpy(cmd = cmd_buf, DF_SENDMAIL_PATH);
++ }
++#endif
++ }
++ }
++ }
++
++ *errbuf = '\0';
++ if(cmd){
++ dprint(4, (debugfile, "call_mailer via cmd: %s\n", cmd));
++
++ (void) mta_parse_post(header, body, cmd, errbuf);
++ return(1);
++ }
++ else
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Hand off given message to local posting agent
++
++ Args: envelope -- The envelope for the BCC and debugging
++ header -- The text of the message header
++ errbuf -- buffer for reporting errors (assumed non-NULL)
++
++ Fork off mailer process and pipe the message into it
++ Called to post news via Inews when NNTP is unavailable
++
++ ----*/
++char *
++post_handoff(header, body, errbuf)
++ METAENV *header;
++ BODY *body;
++ char *errbuf;
++{
++ char *err = NULL;
++#ifdef SENDNEWS
++ char *s;
++
++ if(s = strstr(header->env->date," (")) /* fix the date format for news */
++ *s = '\0';
++
++ if(err = mta_parse_post(header, body, SENDNEWS, errbuf))
++ sprintf(err = errbuf, "News not posted: \"%s\": %s", SENDNEWS, err);
++
++ if(s)
++ *s = ' '; /* restore the date */
++
++#else /* !SENDNEWS */ /* this is the default case */
++ sprintf(err = errbuf, "Can't post, NNTP-server must be defined!");
++#endif /* !SENDNEWS */
++ return(err);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Hand off message to local MTA; it parses recipients from 822 header
++
++ Args: header -- struct containing header data
++ body -- struct containing message body data
++ cmd -- command to use for handoff (%s says where file should go)
++ errs -- pointer to buf to hold errors
++
++ ----*/
++static char *
++mta_parse_post(header, body, cmd, errs)
++ METAENV *header;
++ BODY *body;
++ char *cmd;
++ char *errs;
++{
++ char *result = NULL;
++ PIPE_S *pipe;
++
++ dprint(1, (debugfile, "=== mta_parse_post(%s) ===\n", cmd));
++
++ if(pipe = open_system_pipe(cmd, &result, NULL,
++ PIPE_STDERR|PIPE_WRITE|PIPE_PROT|PIPE_NOSHELL|PIPE_DESC)){
++ if(!pine_rfc822_output(header, body, pine_pipe_soutr_nl,
++ (TCPSTREAM *) pipe))
++ strcpy(errs, "Error posting.");
++
++ if(close_system_pipe(&pipe) && !*errs){
++ sprintf(errs, "Posting program %s returned error", cmd);
++ if(result)
++ display_output_file(result, "POSTING ERRORS", errs, 1);
++ }
++ }
++ else
++ sprintf(errs, "Error running \"%s\"", cmd);
++
++ if(result){
++ unlink(result);
++ fs_give((void **)&result);
++ }
++
++ return(*errs ? errs : NULL);
++}
++
++
++/*
++ * pine_pipe_soutr - Replacement for tcp_soutr that writes one of our
++ * pipes rather than a tcp stream
++ */
++static long
++pine_pipe_soutr_nl (stream,s)
++ void *stream;
++ char *s;
++{
++ long rv = T;
++ char *p;
++ size_t n;
++
++ while(*s && rv){
++ if(n = (p = strstr(s, "\015\012")) ? p - s : strlen(s))
++ while((rv = write(((PIPE_S *)stream)->out.d, s, n)) != n)
++ if(rv < 0){
++ if(errno != EINTR){
++ rv = 0;
++ break;
++ }
++ }
++ else{
++ s += rv;
++ n -= rv;
++ }
++
++ if(p && rv){
++ s = p + 2; /* write UNIX EOL */
++ while((rv = write(((PIPE_S *)stream)->out.d,"\n",1)) != 1)
++ if(rv < 0 && errno != EINTR){
++ rv = 0;
++ break;
++ }
++ }
++ else
++ break;
++ }
++
++ return(rv);
++}
++
++/* ----------------------------------------------------------------------
++ Execute the given mailcap command
++
++ Args: cmd -- the command to execute
++ image_file -- the file the data is in
++ needsterminal -- does this command want to take over the terminal?
++ ----*/
++void
++exec_mailcap_cmd(cmd, image_file, needsterminal)
++char *cmd;
++char *image_file;
++int needsterminal;
++{
++ char *command = NULL,
++ *result_file = NULL,
++ *p;
++ char **r_file_h;
++ PIPE_S *syspipe;
++ int mode;
++
++ p = command = (char *)fs_get((32 + strlen(cmd) + (2*strlen(image_file)))
++ * sizeof(char));
++ if(!needsterminal) /* put in background if it doesn't need terminal */
++ *p++ = '(';
++ sprintf(p, "%s ; rm -f %s", cmd, image_file);
++ p += strlen(p);
++ if(!needsterminal){
++ *p++ = ')';
++ *p++ = ' ';
++ *p++ = '&';
++ }
++ *p++ = '\n';
++ *p = '\0';
++ dprint(9, (debugfile, "exec_mailcap_cmd: command=%s\n", command));
++
++ mode = PIPE_RESET;
++ if(needsterminal == 1)
++ r_file_h = NULL;
++ else{
++ mode |= PIPE_WRITE | PIPE_STDERR;
++ result_file = temp_nam(NULL, "pine_cmd");
++ r_file_h = &result_file;
++ }
++
++ if(syspipe = open_system_pipe(command, r_file_h, NULL, mode)){
++ close_system_pipe(&syspipe);
++ if(needsterminal == 1)
++ q_status_message(SM_ORDER, 0, 4, "VIEWER 命令完成");
++ else if(needsterminal == 2)
++ display_output_file(result_file, "VIEWER", " command result", 1);
++ else
++ display_output_file(result_file, "VIEWER", " command launched", 1);
++ }
++ else
++ q_status_message1(SM_ORDER, 3, 4, "無法起始命令:%s", cmd);
++
++ fs_give((void **)&command);
++ if(result_file)
++ fs_give((void **)&result_file);
++}
++
++
++/* ----------------------------------------------------------------------
++ Execute the given mailcap test= cmd
++
++ Args: cmd -- command to execute
++ Returns exit status
++
++ ----*/
++int
++exec_mailcap_test_cmd(cmd)
++ char *cmd;
++{
++ PIPE_S *syspipe;
++
++ return((syspipe = open_system_pipe(cmd, NULL, NULL, PIPE_SILENT))
++ ? close_system_pipe(&syspipe) : -1);
++}
++
++
++
++/*======================================================================
++ print routines
++
++ Functions having to do with printing on paper and forking of spoolers
++
++ In general one calls open_printer() to start printing. One of
++ the little print functions to send a line or string, and then
++ call print_end() when complete. This takes care of forking off a spooler
++ and piping the stuff down it. No handles or anything here because there's
++ only one printer open at a time.
++
++ ====*/
++
++
++
++static char *trailer; /* so both open and close_printer can see it */
++
++/*----------------------------------------------------------------------
++ Open the printer
++
++ Args: desc -- Description of item to print. Should have one trailing blank.
++
++ Return value: < 0 is a failure.
++ 0 a success.
++
++This does most of the work of popen so we can save the standard output of the
++command we execute and send it back to the user.
++ ----*/
++int
++open_printer(desc)
++ char *desc;
++{
++ char command[201], prompt[200];
++ int cmd, rc, just_one;
++ char *p, *init, *nick;
++ char aname[100];
++ char *printer;
++ int done = 0, i, lastprinter, cur_printer = 0;
++ HelpType help;
++ char **list;
++ static ESCKEY_S ekey[] = {
++ {'y', 'y', "Y", "是"},
++ {'n', 'n', "N", "否"},
++ {ctrl('P'), 10, "^P", "前一印表機"},
++ {ctrl('N'), 11, "^N", "下一印表機"},
++ {-2, 0, NULL, NULL},
++ {'c', 'c', "C", "自定印表機"},
++ {KEY_UP, 10, "", ""},
++ {KEY_DOWN, 11, "", ""},
++ {-1, 0, NULL, NULL}};
++#define PREV_KEY 2
++#define NEXT_KEY 3
++#define CUSTOM_KEY 5
++#define UP_KEY 6
++#define DOWN_KEY 7
++
++ trailer = NULL;
++ init = NULL;
++ nick = NULL;
++ command[200] = '\0';
++
++ if(ps_global->VAR_PRINTER == NULL){
++ q_status_message(SM_ORDER | SM_DING, 3, 5,
++ "尚未選擇印表機。請用主選單中的設定來選擇。");
++ return(-1);
++ }
++
++ /* Is there just one print command available? */
++ just_one = (ps_global->printer_category!=3&&ps_global->printer_category!=2)
++ || (ps_global->printer_category == 2
++ && !(ps_global->VAR_STANDARD_PRINTER
++ && ps_global->VAR_STANDARD_PRINTER[0]
++ && ps_global->VAR_STANDARD_PRINTER[1]))
++ || (ps_global->printer_category == 3
++ && !(ps_global->VAR_PERSONAL_PRINT_COMMAND
++ && ps_global->VAR_PERSONAL_PRINT_COMMAND[0]
++ && ps_global->VAR_PERSONAL_PRINT_COMMAND[1]));
++
++ if(F_ON(F_CUSTOM_PRINT, ps_global))
++ ekey[CUSTOM_KEY].ch = 'c'; /* turn this key on */
++ else
++ ekey[CUSTOM_KEY].ch = -2; /* turn this key off */
++
++ if(just_one){
++ ekey[PREV_KEY].ch = -2; /* turn these keys off */
++ ekey[NEXT_KEY].ch = -2;
++ ekey[UP_KEY].ch = -2;
++ ekey[DOWN_KEY].ch = -2;
++ }
++ else{
++ ekey[PREV_KEY].ch = ctrl('P'); /* turn these keys on */
++ ekey[NEXT_KEY].ch = ctrl('N');
++ ekey[UP_KEY].ch = KEY_UP;
++ ekey[DOWN_KEY].ch = KEY_DOWN;
++ /*
++ * count how many printers in list and find the default in the list
++ */
++ if(ps_global->printer_category == 2)
++ list = ps_global->VAR_STANDARD_PRINTER;
++ else
++ list = ps_global->VAR_PERSONAL_PRINT_COMMAND;
++
++ for(i = 0; list[i]; i++)
++ if(strcmp(ps_global->VAR_PRINTER, list[i]) == 0)
++ cur_printer = i;
++
++ lastprinter = i - 1;
++ }
++
++ help = NO_HELP;
++ ps_global->mangled_footer = 1;
++
++ while(!done){
++ if(init)
++ fs_give((void **)&init);
++
++ if(trailer)
++ fs_give((void **)&trailer);
++
++ if(just_one)
++ printer = ps_global->VAR_PRINTER;
++ else
++ printer = list[cur_printer];
++
++ parse_printer(printer, &nick, &p, &init, &trailer, NULL, NULL);
++ strncpy(command, p, 200);
++ fs_give((void **)&p);
++ sprintf(prompt, "Print %susing \"%s\" ? ", desc ? desc : "",
++ *nick ? nick : command);
++
++ fs_give((void **)&nick);
++
++ cmd = radio_buttons(prompt, -FOOTER_ROWS(ps_global),
++ ekey, 'y', 'x', help, RB_NORM);
++
++ switch(cmd){
++ case 'y':
++ q_status_message1(SM_ORDER, 0, 9,
++ "正以 \"%s\" 命令列印中", command);
++ done++;
++ break;
++
++ case 10:
++ cur_printer = (cur_printer>0)
++ ? (cur_printer-1)
++ : lastprinter;
++ break;
++
++ case 11:
++ cur_printer = (cur_printer<lastprinter)
++ ? (cur_printer+1)
++ : 0;
++ break;
++
++ case 'n':
++ case 'x':
++ done++;
++ break;
++
++ case 'c':
++ done++;
++ break;
++
++ default:
++ break;
++ }
++ }
++
++ if(cmd == 'c'){
++ if(init)
++ fs_give((void **)&init);
++
++ if(trailer)
++ fs_give((void **)&trailer);
++
++ sprintf(prompt, "輸入命令:");
++ command[0] = '\0';
++ rc = 1;
++ help = NO_HELP;
++ while(rc){
++ int flags = OE_APPEND_CURRENT;
++
++ rc = optionally_enter(command, -FOOTER_ROWS(ps_global), 0,
++ 200, prompt, NULL, help, &flags);
++
++ if(rc == 1){
++ cmd = 'x';
++ rc = 0;
++ }
++ else if(rc == 3)
++ help = (help == NO_HELP) ? h_custom_print : NO_HELP;
++ else if(rc == 0){
++ removing_trailing_white_space(command);
++ removing_leading_white_space(command);
++ q_status_message1(SM_ORDER, 0, 9,
++ "正以 \"%s\" 命令列印中", command);
++ }
++ }
++ }
++
++ if(cmd == 'x' || cmd == 'n'){
++ q_status_message(SM_ORDER, 0, 2, "取消列印");
++ if(init)
++ fs_give((void **)&init);
++
++ if(trailer)
++ fs_give((void **)&trailer);
++
++ return(-1);
++ }
++
++ display_message('x');
++
++ ps_global->print = (PRINT_S *)fs_get(sizeof(PRINT_S));
++ memset(ps_global->print, 0, sizeof(PRINT_S));
++
++ strcat(strcpy(aname, ANSI_PRINTER), "-no-formfeed");
++ if(strucmp(command, ANSI_PRINTER) == 0
++ || strucmp(command, aname) == 0){
++ /*----------- Printer attached to ansi device ---------*/
++ q_status_message(SM_ORDER, 0, 9,
++ "正列印至桌上印表機...");
++ display_message('x');
++ xonxoff_proc(1); /* make sure XON/XOFF used */
++ crlf_proc(1); /* AND LF->CR xlation */
++ fputs("\033[5i", stdout);
++ ps_global->print->fp = stdout;
++ if(strucmp(command, ANSI_PRINTER) == 0){
++ /* put formfeed at the end of the trailer string */
++ if(trailer){
++ int len = strlen(trailer);
++
++ fs_resize((void **)&trailer, len+2);
++ trailer[len] = '\f';
++ trailer[len+1] = '\0';
++ }
++ else
++ trailer = cpystr("\f");
++ }
++ }
++ else{
++ /*----------- Print by forking off a UNIX command ------------*/
++ dprint(4, (debugfile, "Printing using command \"%s\"\n", command));
++ ps_global->print->result = temp_nam(NULL, "pine_prt");
++ if(ps_global->print->pipe = open_system_pipe(command,
++ &ps_global->print->result, NULL,
++ PIPE_WRITE | PIPE_STDERR)){
++ ps_global->print->fp = ps_global->print->pipe->out.f;
++ }
++ else{
++ fs_give((void **)&ps_global->print->result);
++ q_status_message1(SM_ORDER | SM_DING, 3, 4,
++ "印表機開啟錯誤:%s",
++ error_description(errno));
++ dprint(2, (debugfile, "Error popening printer \"%s\"\n",
++ error_description(errno)));
++ if(init)
++ fs_give((void **)&init);
++
++ if(trailer)
++ fs_give((void **)&trailer);
++
++ return(-1);
++ }
++ }
++
++ ps_global->print->err = 0;
++ if(init){
++ if(*init)
++ fputs(init, ps_global->print->fp);
++
++ fs_give((void **)&init);
++ }
++
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Close printer
++
++ If we're piping to a spooler close down the pipe and wait for the process
++to finish. If we're sending to an attached printer send the escape sequence.
++Also let the user know the result of the print
++ ----*/
++void
++close_printer()
++{
++ if(trailer){
++ if(*trailer)
++ fputs(trailer, ps_global->print->fp);
++
++ fs_give((void **)&trailer);
++ }
++
++ if(ps_global->print->fp == stdout) {
++ fputs("\033[4i", stdout);
++ fflush(stdout);
++ if(F_OFF(F_PRESERVE_START_STOP, ps_global))
++ xonxoff_proc(0); /* turn off XON/XOFF */
++
++ crlf_proc(0); /* turn off CF->LF xlantion */
++ } else {
++ (void) close_system_pipe(&ps_global->print->pipe);
++ display_output_file(ps_global->print->result, "PRINT", NULL, 1);
++ fs_give((void **)&ps_global->print->result);
++ }
++
++ fs_give((void **)&ps_global->print);
++
++ q_status_message(SM_ASYNC, 0, 3, "列印指令完成");
++ display_message('x');
++}
++
++
++
++/*----------------------------------------------------------------------
++ Print a single character
++
++ Args: c -- char to print
++ Returns: 1 on success, 0 on ps_global->print->err
++ ----*/
++int
++print_char(c)
++ int c;
++{
++ if(!ps_global->print->err && putc(c, ps_global->print->fp) == EOF)
++ ps_global->print->err = 1;
++
++ return(!ps_global->print->err);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Send a line of text to the printer
++
++ Args: line -- Text to print
++
++ ----*/
++
++void
++print_text(line)
++ char *line;
++{
++ if(!ps_global->print->err && fputs(line, ps_global->print->fp) == EOF)
++ ps_global->print->err = 1;
++}
++
++
++
++/*----------------------------------------------------------------------
++ printf style formatting with one arg for printer
++
++ Args: line -- The printf control string
++ a1 -- The 1st argument for printf
++ ----*/
++void
++print_text1(line, a1)
++ char *line, *a1;
++{
++ if(!ps_global->print->err
++ && fprintf(ps_global->print->fp, line, a1) < 0)
++ ps_global->print->err = 1;
++}
++
++
++
++/*----------------------------------------------------------------------
++ printf style formatting with one arg for printer
++
++ Args: line -- The printf control string
++ a1 -- The 1st argument for printf
++ a2 -- The 2nd argument for printf
++ ----*/
++void
++print_text2(line, a1, a2)
++ char *line, *a1, *a2;
++{
++ if(!ps_global->print->err
++ && fprintf(ps_global->print->fp, line, a1, a2) < 0)
++ ps_global->print->err = 1;
++}
++
++
++
++/*----------------------------------------------------------------------
++ printf style formatting with one arg for printer
++
++ Args: line -- The printf control string
++ a1 -- The 1st argument for printf
++ a2 -- The 2nd argument for printf
++ a3 -- The 3rd argument for printf
++ ----*/
++void
++print_text3(line, a1, a2, a3)
++ char *line, *a1, *a2, *a3;
++{
++ if(!ps_global->print->err
++ && fprintf(ps_global->print->fp, line, a1, a2, a3) < 0)
++ ps_global->print->err = 1;
++}
++
++#ifdef DEBUG
++/*----------------------------------------------------------------------
++ Initialize debugging - open the debug log file
++
++ Args: none
++
++ Result: opens the debug logfile for dprints
++
++ Opens the file "~/.pine-debug1. Also maintains .pine-debug[2-4]
++ by renaming them each time so the last 4 sessions are saved.
++ ----*/
++void
++init_debug()
++{
++ char nbuf[5];
++ char newfname[MAXPATH+1], filename[MAXPATH+1];
++ int i, fd;
++
++ if(!(debug || ps_global->debug_imap))
++ return;
++
++ for(i = ps_global->debug_nfiles - 1; i > 0; i--){
++ build_path(filename, ps_global->home_dir, DEBUGFILE);
++ strcpy(newfname, filename);
++ sprintf(nbuf, "%d", i);
++ strcat(filename, nbuf);
++ sprintf(nbuf, "%d", i+1);
++ strcat(newfname, nbuf);
++ (void)rename_file(filename, newfname);
++ }
++
++ build_path(filename, ps_global->home_dir, DEBUGFILE);
++ strcat(filename, "1");
++
++ debugfile = NULL;
++ if((fd = open(filename, O_TRUNC|O_RDWR|O_CREAT, 0600)) >= 0)
++ debugfile = fdopen(fd, "w+");
++
++ if(debugfile != NULL){
++ time_t now = time((time_t *)0);
++ if(ps_global->debug_flush)
++ setbuf(debugfile, NULL);
++
++ if(ps_global->debug_nfiles == 0){
++ /*
++ * If no debug files are asked for, make filename a tempfile
++ * to be used for a record should pine later crash...
++ */
++ if(debug < 9 && !ps_global->debug_flush && ps_global->debug_imap<4)
++ unlink(filename);
++ }
++
++ dprint(0, (debugfile,
++ "Debug output of the Pine program (debug=%d debug_imap=%d). Version %s\n%s\n",
++ debug, ps_global->debug_imap, pine_version, ctime(&now)));
++ }
++}
++
++
++/*----------------------------------------------------------------------
++ Try to save the debug file if we crash in a controlled way
++
++ Args: dfile: pointer to open debug file
++
++ Result: tries to move the appropriate .pine-debugx file to .pine-crash
++
++ Looks through the four .pine-debug files hunting for the one that is
++ associated with this pine, and then renames it.
++ ----*/
++void
++save_debug_on_crash(dfile)
++FILE *dfile;
++{
++ char nbuf[5], crashfile[MAXPATH+1], filename[MAXPATH+1];
++ int i;
++ struct stat dbuf, tbuf;
++ time_t now = time((time_t *)0);
++
++ if(!(dfile && fstat(fileno(dfile), &dbuf) != 0))
++ return;
++
++ fprintf(dfile, "\nsave_debug_on_crash: Version %s: debug level %d\n",
++ pine_version, debug);
++ fprintf(dfile, "\n : %s\n", ctime(&now));
++
++ build_path(crashfile, ps_global->home_dir, ".pine-crash");
++
++ fprintf(dfile, "\nAttempting to save debug file to %s\n", crashfile);
++ fprintf(stderr,
++ "\n\n Attempting to save debug file to %s\n\n", crashfile);
++
++ /* Blat out last n keystrokes */
++ fputs("========== Latest keystrokes ==========\n", dfile);
++ while((i = key_playback(0)) != -1)
++ fprintf(dfile, "\t%s\t(0x%04.4x)\n", pretty_command(i), i);
++
++ /* look for existing debug file */
++ for(i = 1; i <= ps_global->debug_nfiles; i++){
++ build_path(filename, ps_global->home_dir, DEBUGFILE);
++ sprintf(nbuf, "%d", i);
++ strcat(filename, nbuf);
++ if(stat(filename, &tbuf) != 0)
++ continue;
++
++ /* This must be the current debug file */
++ if(tbuf.st_dev == dbuf.st_dev && tbuf.st_ino == dbuf.st_ino){
++ rename_file(filename, crashfile);
++ break;
++ }
++ }
++
++ /* if current debug file name not found, write it by hand */
++ if(i > ps_global->debug_nfiles){
++ FILE *cfp;
++ char buf[1025];
++
++ /*
++ * Copy the debug temp file into the
++ */
++ if(cfp = fopen(crashfile, "w")){
++ buf[1024] = '\0';
++ fseek(dfile, 0L, 0);
++ while(fgets(buf, 1025, dfile) && fputs(buf, cfp) != EOF)
++ ;
++
++ fclose(cfp);
++ }
++ }
++
++ fclose(dfile);
++}
++
++
++#define CHECK_EVERY_N_TIMES 100
++#define MAX_DEBUG_FILE_SIZE 200000L
++/*
++ * This is just to catch runaway Pines that are looping spewing out
++ * debugging (and filling up a file system). The stop doesn't have to be
++ * at all precise, just soon enough to hopefully prevent filling the
++ * file system. If the debugging level is high (9 for now), then we're
++ * presumably looking for some problem, so don't truncate.
++ */
++int
++do_debug(debug_fp)
++FILE *debug_fp;
++{
++ static int counter = CHECK_EVERY_N_TIMES;
++ static int ok = 1;
++ long filesize;
++
++ if(debug == DEFAULT_DEBUG
++ && !ps_global->debug_flush
++ && !ps_global->debug_timestamp
++ && ps_global->debug_imap < 2
++ && ok
++ && --counter <= 0){
++ if((filesize = fp_file_size(debug_fp)) != -1L)
++ ok = (unsigned long)filesize < (unsigned long)MAX_DEBUG_FILE_SIZE;
++
++ counter = CHECK_EVERY_N_TIMES;
++ if(!ok){
++ fprintf(debug_fp, "\n\n --- No more debugging ---\n");
++ fprintf(debug_fp,
++ " (debug file growing too large - over %ld bytes)\n\n",
++ MAX_DEBUG_FILE_SIZE);
++ fflush(debug_fp);
++ }
++ }
++
++ if(ok && ps_global->debug_timestamp)
++ fprintf(debug_fp, "\n%s\n", debug_time(0));
++
++ return(ok);
++}
++
++
++/*
++ * Returns a pointer to static string for a timestamp.
++ *
++ * If timestamp is set .subseconds are added if available.
++ * If include_date is set the date is appended.
++ */
++char *
++debug_time(include_date)
++ int include_date;
++{
++ time_t t;
++ struct tm *tm_now;
++ struct timeval tp;
++ struct timezone tzp;
++ static char timestring[23];
++ char subsecond[8];
++ char datestr[7];
++
++ if(gettimeofday(&tp, &tzp) == 0){
++ t = (time_t)tp.tv_sec;
++ if(include_date){
++ tm_now = localtime(&t);
++ sprintf(datestr, " %d/%d", tm_now->tm_mon+1, tm_now->tm_mday);
++ }
++ else
++ datestr[0] = '\0';
++
++ if(ps_global->debug_timestamp)
++ sprintf(subsecond, ".%06ld", tp.tv_usec);
++ else
++ subsecond[0] = '\0';
++
++ sprintf(timestring, "%.8s%s%s", ctime(&t)+11, subsecond, datestr);
++ }
++ else
++ timestring[0] = '\0';
++
++ return(timestring);
++}
++#endif /* DEBUG */
++
++
++/*
++ * Fills in the passed in structure with the current time.
++ *
++ * Returns 0 if ok
++ * -1 if can't do it
++ */
++int
++get_time(our_time_val)
++ TIMEVAL_S *our_time_val;
++{
++ struct timeval tp;
++ struct timezone tzp;
++
++ if(gettimeofday(&tp, &tzp) == 0){
++ our_time_val->sec = tp.tv_sec;
++ our_time_val->usec = tp.tv_usec;
++ return 0;
++ }
++ else
++ return -1;
++}
++
++
++/*
++ * Returns the difference between the two values, in microseconds.
++ * Value returned is first - second.
++ */
++long
++time_diff(first, second)
++ TIMEVAL_S *first,
++ *second;
++{
++ return(1000000L*(first->sec - second->sec) + (first->usec - second->usec));
++}
++
++
++
++/*======================================================================
++ Things having to do with reading from the tty driver and keyboard
++ - initialize tty driver and reset tty driver
++ - read a character from terminal with keyboard escape seqence mapping
++ - initialize keyboard (keypad or such) and reset keyboard
++ - prompt user for a line of input
++ - read a command from keyboard with timeouts.
++
++ ====*/
++
++
++/*
++ * Helpful definitions
++ */
++#define RETURN_CH(X) return(key_recorder((X)))
++/*
++ * Should really be using pico's TERM's t_getchar to read a character but
++ * we're just calling ttgetc directly for now. Ttgetc is the same as
++ * t_getchar whenever we use it so we're avoiding the trouble of initializing
++ * the TERM struct and calling ttgetc directly.
++ */
++#define READ_A_CHAR() ttgetc(NO_OP_COMMAND, key_recorder, read_bail)
++
++
++/*
++ * Internal prototypes
++ */
++void line_paint PROTO((int, int *));
++int process_config_input PROTO((int *));
++int check_for_timeout PROTO((int));
++void read_bail PROTO((void));
++
++
++/*----------------------------------------------------------------------
++ Initialize the tty driver to do single char I/O and whatever else (UNIX)
++
++ Args: struct pine
++
++ Result: tty driver is put in raw mode so characters can be read one
++ at a time. Returns -1 if unsuccessful, 0 if successful.
++
++Some file descriptor voodoo to allow for pipes across vforks. See
++open_mailer for details.
++ ----------------------------------------------------------------------*/
++init_tty_driver(ps)
++ struct pine *ps;
++{
++#ifdef MOUSE
++ if(F_ON(F_ENABLE_MOUSE, ps_global))
++ init_mouse();
++#endif /* MOUSE */
++
++ /* turn off talk permission by default */
++
++ if(F_ON(F_ALLOW_TALK, ps))
++ allow_talk(ps);
++ else
++ disallow_talk(ps);
++
++ return(PineRaw(1));
++}
++
++
++
++/*----------------------------------------------------------------------
++ Set or clear the specified tty mode
++
++ Args: ps -- struct pine
++ mode -- mode bits to modify
++ clear -- whether or not to clear or set
++
++ Result: tty driver mode change.
++ ----------------------------------------------------------------------*/
++void
++tty_chmod(ps, mode, func)
++ struct pine *ps;
++ int mode;
++ int func;
++{
++ char *tty_name;
++ int new_mode;
++ struct stat sbuf;
++ static int saved_mode = -1;
++
++ /* if no problem figuring out tty's name & mode? */
++ if((((tty_name = (char *) ttyname(STDIN_FD)) != NULL
++ && fstat(STDIN_FD, &sbuf) == 0)
++ || ((tty_name = (char *) ttyname(STDOUT_FD)) != NULL
++ && fstat(STDOUT_FD, &sbuf) == 0))
++ && !(func == TMD_RESET && saved_mode < 0)){
++ new_mode = (func == TMD_RESET)
++ ? saved_mode
++ : (func == TMD_CLEAR)
++ ? (sbuf.st_mode & ~mode)
++ : (sbuf.st_mode | mode);
++ /* assign tty new mode */
++ if(chmod(tty_name, new_mode) == 0){
++ if(func == TMD_RESET) /* forget we knew */
++ saved_mode = -1;
++ else if(saved_mode < 0)
++ saved_mode = sbuf.st_mode; /* remember original */
++ }
++ }
++}
++
++
++
++/*----------------------------------------------------------------------
++ End use of the tty, put it back into it's normal mode (UNIX)
++
++ Args: ps -- struct pine
++
++ Result: tty driver mode change.
++ ----------------------------------------------------------------------*/
++void
++end_tty_driver(ps)
++ struct pine *ps;
++{
++ ps = ps; /* get rid of unused parameter warning */
++
++#ifdef MOUSE
++ end_mouse();
++#endif /* MOUSE */
++ fflush(stdout);
++ dprint(2, (debugfile, "about to end_tty_driver\n"));
++
++ tty_chmod(ps, 0, TMD_RESET);
++ PineRaw(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Actually set up the tty driver (UNIX)
++
++ Args: state -- which state to put it in. 1 means go into raw, 0 out of
++
++ Result: returns 0 if successful and < 0 if not.
++ ----*/
++
++PineRaw(state)
++int state;
++{
++ int result;
++
++ result = Raw(state);
++
++ if(result == 0 && state == 1){
++ /*
++ * Only go into 8 bit mode if we are doing something other
++ * than plain ASCII. This will save the folks that have
++ * their parity on their serial lines wrong thr trouble of
++ * getting it right
++ */
++ if(ps_global->VAR_CHAR_SET && ps_global->VAR_CHAR_SET[0] &&
++ strucmp(ps_global->VAR_CHAR_SET, "us-ascii"))
++ bit_strip_off();
++
++#ifdef DEBUG
++ if(debug < 9) /* only on if full debugging set */
++#endif
++ quit_char_off();
++ ps_global->low_speed = ttisslow();
++ crlf_proc(0);
++ xonxoff_proc(F_ON(F_PRESERVE_START_STOP, ps_global));
++ }
++
++ return(result);
++}
++
++
++#ifdef RESIZING
++jmp_buf winch_state;
++int winch_occured = 0;
++int ready_for_winch = 0;
++#endif
++
++/*----------------------------------------------------------------------
++ This checks whether or not a character (UNIX)
++ is ready to be read, or it times out.
++
++ Args: time_out -- number of seconds before it will timeout
++
++ Result: Returns a NO_OP_IDLE or a NO_OP_COMMAND if the timeout expires
++ before input is available, or a KEY_RESIZE if a resize event
++ occurs, or READY_TO_READ if input is available before the timeout.
++ ----*/
++int
++check_for_timeout(time_out)
++ int time_out;
++{
++ int res;
++
++ fflush(stdout);
++
++#ifdef RESIZING
++ if(winch_occured || setjmp(winch_state) != 0){
++ ready_for_winch = 0;
++ fix_windsize(ps_global);
++
++ /*
++ * May need to unblock signal after longjmp from handler, because
++ * signal is normally unblocked upon routine exit from the handler.
++ */
++ if(!winch_occured)
++ our_sigunblock(SIGWINCH);
++
++ winch_occured = 0;
++ return(KEY_RESIZE);
++ }
++ else
++ ready_for_winch = 1;
++#endif /* RESIZING */
++
++ switch(res=input_ready(time_out)){
++ case BAIL_OUT:
++ read_bail(); /* non-tragic exit */
++ /* NO RETURN */
++
++ case PANIC_NOW:
++ panic1("Select error: %s\n", error_description(errno));
++ /* NO RETURN */
++
++ case READ_INTR:
++ res = NO_OP_COMMAND;
++ /* fall through */
++
++ case NO_OP_IDLE:
++ case NO_OP_COMMAND:
++ case READY_TO_READ:
++#ifdef RESIZING
++ ready_for_winch = 0;
++#endif
++ return(res);
++ }
++}
++
++
++
++/*----------------------------------------------------------------------
++ Read input characters with lots of processing for arrow keys and such (UNIX)
++
++ Args: time_out -- The timeout to for the reads
++
++ Result: returns the character read. Possible special chars.
++
++ This deals with function and arrow keys as well.
++
++ The idea is that this routine handles all escape codes so it done in
++ only one place. Especially so the back arrow key can work when entering
++ things on a line. Also so all function keys can be disabled and not
++ cause weird things to happen.
++ ---*/
++int
++read_char(time_out)
++ int time_out;
++{
++ int ch, status, cc;
++
++ /* Get input from initial-keystrokes */
++ if(process_config_input(&ch))
++ return(ch);
++
++ /*
++ * We only check for timeouts at the start of read_char, not in the
++ * middle of escape sequences.
++ */
++ if((ch = check_for_timeout(time_out)) != READY_TO_READ)
++ goto done;
++
++ ps_global->time_of_last_input = time((time_t *)0);
++
++ switch(status = kbseq(simple_ttgetc, key_recorder, read_bail, &ch)){
++ case KEY_DOUBLE_ESC:
++ /*
++ * Special hack to get around comm devices eating control characters.
++ */
++ if(check_for_timeout(5) != READY_TO_READ){
++ ch = KEY_JUNK; /* user typed ESC ESC, then stopped */
++ goto done;
++ }
++ else
++ ch = READ_A_CHAR();
++
++ ch &= 0x7f;
++ if(isdigit((unsigned char)ch)){
++ int n = 0, i = ch - '0';
++
++ if(i < 0 || i > 2){
++ ch = KEY_JUNK;
++ goto done; /* bogus literal char value */
++ }
++
++ while(n++ < 2){
++ if(check_for_timeout(5) != READY_TO_READ
++ || (!isdigit((unsigned char) (ch = READ_A_CHAR()))
++ || (n == 1 && i == 2 && ch > '5')
++ || (n == 2 && i == 25 && ch > '5'))){
++ ch = KEY_JUNK; /* user typed ESC ESC #, stopped */
++ goto done;
++ }
++
++ i = (i * 10) + (ch - '0');
++ }
++
++ ch = i;
++ }
++ else{
++ if(islower((unsigned char)ch)) /* canonicalize if alpha */
++ ch = toupper((unsigned char)ch);
++
++ ch = (isalpha((unsigned char)ch) || ch == '@'
++ || (ch >= '[' && ch <= '_'))
++ ? ctrl(ch) : ((ch == SPACE) ? ctrl('@'): ch);
++ }
++
++ goto done;
++
++#ifdef MOUSE
++ case KEY_XTERM_MOUSE:
++ if(mouseexist()){
++ /*
++ * Special hack to get mouse events from an xterm.
++ * Get the details, then pass it past the keymenu event
++ * handler, and then to the installed handler if there
++ * is one...
++ */
++ static int down = 0;
++ int x, y, button;
++ unsigned cmd;
++
++ clear_cursor_pos();
++ button = READ_A_CHAR() & 0x03;
++
++ x = READ_A_CHAR() - '!';
++ y = READ_A_CHAR() - '!';
++
++ ch = NO_OP_COMMAND;
++ if(button == 0){ /* xterm button 1 down */
++ down = 1;
++ if(checkmouse(&cmd, 1, x, y))
++ ch = (int)cmd;
++ }
++ else if (down && button == 3){
++ down = 0;
++ if(checkmouse(&cmd, 0, x, y))
++ ch = (int)cmd;
++ }
++
++ goto done;
++ }
++
++ break;
++#endif /* MOUSE */
++
++ case KEY_UP :
++ case KEY_DOWN :
++ case KEY_RIGHT :
++ case KEY_LEFT :
++ case KEY_PGUP :
++ case KEY_PGDN :
++ case KEY_HOME :
++ case KEY_END :
++ case KEY_DEL :
++ case PF1 :
++ case PF2 :
++ case PF3 :
++ case PF4 :
++ case PF5 :
++ case PF6 :
++ case PF7 :
++ case PF8 :
++ case PF9 :
++ case PF10 :
++ case PF11 :
++ case PF12 :
++ dprint(9, (debugfile, "Read char returning: %d %s\n",
++ status, pretty_command(status)));
++ return(status);
++
++ case KEY_SWALLOW_Z:
++ status = KEY_JUNK;
++ case KEY_SWAL_UP:
++ case KEY_SWAL_DOWN:
++ case KEY_SWAL_LEFT:
++ case KEY_SWAL_RIGHT:
++ do
++ if(check_for_timeout(2) != READY_TO_READ){
++ status = KEY_JUNK;
++ break;
++ }
++ while(!strchr("~qz", READ_A_CHAR()));
++ ch = (status == KEY_JUNK) ? status : status - (KEY_SWAL_UP - KEY_UP);
++ goto done;
++
++ case KEY_KERMIT:
++ do{
++ cc = ch;
++ if(check_for_timeout(2) != READY_TO_READ){
++ status = KEY_JUNK;
++ break;
++ }
++ else
++ ch = READ_A_CHAR();
++ }while(cc != '\033' && ch != '\\');
++
++ ch = KEY_JUNK;
++ goto done;
++
++ case BADESC:
++ ch = KEY_JUNK;
++ goto done;
++
++ case 0: /* regular character */
++ default:
++ /*
++ * we used to strip (ch &= 0x7f;), but this seems much cleaner
++ * in the face of line noise and has the benefit of making it
++ * tougher to emit mistakenly labeled MIME...
++ */
++ if((ch & 0x80) && (!ps_global->VAR_CHAR_SET
++ || !strucmp(ps_global->VAR_CHAR_SET, "US-ASCII"))){
++ dprint(9, (debugfile, "Read char returning: %d %s\n",
++ status, pretty_command(status)));
++ return(KEY_JUNK);
++ }
++ else if(ch == ctrl('Z')){
++ dprint(9, (debugfile, "Read char calling do_suspend\n"));
++ return(do_suspend());
++ }
++
++
++ done:
++ dprint(9, (debugfile, "Read char returning: %d %s\n",
++ ch, pretty_command(ch)));
++ return(ch);
++ }
++}
++
++
++/*----------------------------------------------------------------------
++ Reading input somehow failed and we need to shutdown now
++
++ Args: none
++
++ Result: pine exits
++
++ ---*/
++void
++read_bail()
++{
++ end_signals(1);
++ if(ps_global->inbox_stream){
++ if(ps_global->inbox_stream == ps_global->mail_stream)
++ ps_global->mail_stream = NULL;
++
++ if(!ps_global->inbox_stream->lock) /* shouldn't be... */
++ pine_close_stream(ps_global->inbox_stream);
++ }
++
++ if(ps_global->mail_stream && !ps_global->mail_stream->lock)
++ pine_close_stream(ps_global->mail_stream);
++
++ end_keyboard(F_ON(F_USE_FK,ps_global));
++ end_tty_driver(ps_global);
++ if(filter_data_file(0))
++ unlink(filter_data_file(0));
++
++ exit(0);
++}
++
++
++extern char term_name[];
++/* -------------------------------------------------------------------
++ Set up the keyboard -- usually enable some function keys (UNIX)
++
++ Args: struct pine
++
++So far all we do here is turn on keypad mode for certain terminals
++
++Hack for NCSA telnet on an IBM PC to put the keypad in the right mode.
++This is the same for a vtXXX terminal or [zh][12]9's which we have
++a lot of at UW
++ ----*/
++void
++init_keyboard(use_fkeys)
++ int use_fkeys;
++{
++ if(use_fkeys && (!strucmp(term_name,"vt102")
++ || !strucmp(term_name,"vt100")))
++ printf("\033\133\071\071\150");
++}
++
++
++
++/*----------------------------------------------------------------------
++ Clear keyboard, usually disable some function keys (UNIX)
++
++ Args: pine state (terminal type)
++
++ Result: keyboard state reset
++ ----*/
++void
++end_keyboard(use_fkeys)
++ int use_fkeys;
++{
++ if(use_fkeys && (!strcmp(term_name, "vt102")
++ || !strcmp(term_name, "vt100"))){
++ printf("\033\133\071\071\154");
++ fflush(stdout);
++ }
++}
++
++
++#ifdef _WINDOWS
++#line 3 "osdep/termin.gen"
++#endif
++/*
++ * Generic tty input routines
++ */
++
++
++/*----------------------------------------------------------------------
++ Read a character from keyboard with timeout
++ Input: none
++
++ Result: Returns command read via read_char
++ Times out and returns a null command every so often
++
++ Calculates the timeout for the read, and does a few other house keeping
++things. The duration of the timeout is set in pine.c.
++ ----------------------------------------------------------------------*/
++int
++read_command()
++{
++ int ch, tm = 0;
++ long dtime;
++
++ cancel_busy_alarm(-1);
++ tm = (messages_queued(&dtime) > 1) ? (int)dtime : timeo;
++
++ /*
++ * Before we sniff at the input queue, make sure no external event's
++ * changed our picture of the message sequence mapping. If so,
++ * recalculate the dang thing and run thru whatever processing loop
++ * we're in again...
++ */
++ if(ps_global->expunge_count){
++ q_status_message2(SM_ORDER, 3, 3,
++ "自資料匣 \"%s\" 中刪除 %s 封信件",
++ pretty_fn(ps_global->cur_folder),
++ long2string(ps_global->expunge_count));
++ ps_global->expunge_count = 0L;
++ display_message('x');
++ }
++
++ if(ps_global->inbox_expunge_count){
++ q_status_message2(SM_ORDER, 3, 3,
++ "自資料匣 \"%s\" 中刪除 %s 封信件",
++ pretty_fn(ps_global->inbox_name),
++ long2string(ps_global->inbox_expunge_count));
++ ps_global->inbox_expunge_count = 0L;
++ display_message('x');
++ }
++
++ if(ps_global->mail_box_changed && ps_global->new_mail_count){
++ dprint(2, (debugfile, "Noticed %ld new msgs! \n",
++ ps_global->new_mail_count));
++ return(NO_OP_COMMAND); /* cycle thru so caller can update */
++ }
++
++ ch = read_char(tm);
++ dprint(9, (debugfile, "Read command returning: %d %s\n", ch,
++ pretty_command(ch)));
++ if(ch != NO_OP_COMMAND && ch != NO_OP_IDLE && ch != KEY_RESIZE)
++ zero_new_mail_count();
++
++#ifdef BACKGROUND_POST
++ /*
++ * Any expired children to report on?
++ */
++ if(ps_global->post && ps_global->post->pid == 0){
++ int winner = 0;
++
++ if(ps_global->post->status < 0){
++ q_status_message(SM_ORDER | SM_DING, 3, 3, "徹底失敗!");
++ }
++ else{
++ (void) pine_send_status(ps_global->post->status,
++ ps_global->post->fcc, tmp_20k_buf,
++ &winner);
++ q_status_message(SM_ORDER | (winner ? 0 : SM_DING), 3, 3,
++ tmp_20k_buf);
++
++ }
++
++ if(!winner)
++ q_status_message(SM_ORDER, 0, 3,
++ "由 \"編修\" 再回答 \"是\" 來繼續重送 \"上次中斷的信件?\"");
++/*
++ "Re-send via \"Compose\" then \"Yes\" to \"Continue INTERRUPTED?\"");
++*/
++ if(ps_global->post->fcc)
++ fs_give((void **) &ps_global->post->fcc);
++
++ fs_give((void **) &ps_global->post);
++ }
++#endif
++
++ return(ch);
++}
++
++
++
++
++/*
++ *
++ */
++static struct display_line {
++ int row, col; /* where display starts */
++ int dlen; /* length of display line */
++ char *dl; /* line on display */
++ char *vl; /* virtual line */
++ int vlen; /* length of virtual line */
++ int vused; /* length of virtual line in use */
++ int vbase; /* first virtual char on display */
++} dline;
++
++
++
++static struct key oe_keys[] =
++ {{"^G","輔助說明",KS_SCREENHELP}, {"^C","取消",KS_NONE},
++ {"^T","xxx",KS_NONE}, {"Ret","同意",KS_NONE},
++ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
++ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
++ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
++ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE}};
++INST_KEY_MENU(oe_keymenu, oe_keys);
++#define OE_HELP_KEY 0
++#define OE_CANCEL_KEY 1
++#define OE_CTRL_T_KEY 2
++#define OE_ENTER_KEY 3
++
++
++/*----------------------------------------------------------------------
++ Prompt user for a string in status line with various options
++
++ Args: string -- the buffer result is returned in, and original string (if
++ any) is passed in.
++ y_base -- y position on screen to start on. 0,0 is upper left
++ negative numbers start from bottom
++ x_base -- column position on screen to start on. 0,0 is upper left
++ field_len -- Maximum length of string to accept
++ prompt -- The string to prompt with
++ escape_list -- pointer to array of ESCKEY_S's. input chars matching
++ those in list return value from list.
++ help -- Arrary of strings for help text in bottom screen lines
++ flags -- pointer (because some are return values) to flags
++ OE_USER_MODIFIED - Set on return if user modified buffer
++ OE_DISALLOW_CANCEL - No cancel in menu.
++ OE_DISALLOW_HELP - No help in menu.
++ OE_KEEP_TRAILING_SPACE - Allow trailing space.
++ OE_SEQ_SENSITIVE - Caller is sensitive to sequence
++ number changes.
++ OE_APPEND_CURRENT - String should not be truncated
++ before accepting user input.
++ OE_PASSWD - Don't echo on screen.
++
++ Result: editing input string
++ returns -1 unexpected errors
++ returns 0 normal entry typed (editing and return or PF2)
++ returns 1 typed ^C or PF2 (cancel)
++ returns 3 typed ^G or PF1 (help)
++ returns 4 typed ^L for a screen redraw
++
++ WARNING: Care is required with regard to the escape_list processing.
++ The passed array is terminated with an entry that has ch = -1.
++ Function key labels and key strokes need to be setup externally!
++ Traditionally, a return value of 2 is used for ^T escapes.
++
++ Unless in escape_list, tabs are trapped by isprint().
++This allows near full weemacs style editing in the line
++ ^A beginning of line
++ ^E End of line
++ ^R Redraw line
++ ^G Help
++ ^F forward
++ ^B backward
++ ^D delete
++----------------------------------------------------------------------*/
++
++optionally_enter(string, y_base, x_base, field_len,
++ prompt, escape_list, help, flags)
++ char *string, *prompt;
++ ESCKEY_S *escape_list;
++ HelpType help;
++ int x_base, y_base, field_len;
++ int *flags;
++{
++ register char *s2;
++ register int field_pos;
++ int i, j, return_v, cols, ch, prompt_len, too_thin,
++ real_y_base, km_popped, passwd;
++ char *saved_original = NULL, *k, *kb;
++ char *kill_buffer = NULL;
++ char **help_text;
++ int fkey_table[12];
++ struct key_menu *km;
++ bitmap_t bitmap;
++#ifdef _WINDOWS
++ int cursor_shown;
++#endif
++
++ dprint(5, (debugfile, "=== optionally_enter called ===\n"));
++ dprint(9, (debugfile, "string:\"%s\" y:%d x:%d length: %d append: %d\n",
++ string, x_base, y_base, field_len,
++ (flags && *flags & OE_APPEND_CURRENT)));
++ dprint(9, (debugfile, "passwd:%d prompt:\"%s\" label:\"%s\"\n",
++ (flags && *flags & OE_PASSWD),
++ prompt, (escape_list && escape_list[0].ch != -1)
++ ? escape_list[0].label: ""));
++
++#ifdef _WINDOWS
++ if (mswin_usedialog ()) {
++ MDlgButton button_list[12];
++ int b;
++ int i;
++
++ memset (&button_list, 0, sizeof (MDlgButton) * 12);
++ b = 0;
++ for (i = 0; escape_list && escape_list[i].ch != -1 && i < 11; ++i) {
++ if (escape_list[i].name != NULL
++ && escape_list[i].ch > 0 && escape_list[i].ch < 256) {
++ button_list[b].ch = escape_list[i].ch;
++ button_list[b].rval = escape_list[i].rval;
++ button_list[b].name = escape_list[i].name;
++ button_list[b].label = escape_list[i].label;
++ ++b;
++ }
++ }
++ button_list[b].ch = -1;
++
++
++ help_text = get_help_text (help);
++ return_v = mswin_dialog (prompt, string, field_len,
++ (flags && *flags & OE_APPEND_CURRENT),
++ (flags && *flags & OE_PASSWD),
++ button_list,
++ help_text, flags ? *flags : OE_NONE);
++ free_list_array (&help_text);
++ return (return_v);
++ }
++#endif
++
++ suspend_busy_alarm();
++ cols = ps_global->ttyo->screen_cols;
++ prompt_len = strlen(prompt);
++ too_thin = 0;
++ km_popped = 0;
++ if(y_base > 0) {
++ real_y_base = y_base;
++ } else {
++ real_y_base= y_base + ps_global->ttyo->screen_rows;
++ if(real_y_base < 2)
++ real_y_base = ps_global->ttyo->screen_rows;
++ }
++
++ flush_ordered_messages();
++ mark_status_dirty();
++ if(flags && *flags & OE_APPEND_CURRENT) /* save a copy in case of cancel */
++ saved_original = cpystr(string);
++
++ /*
++ * build the function key mapping table, skipping predefined keys...
++ */
++ memset(fkey_table, NO_OP_COMMAND, 12 * sizeof(int));
++ for(i = 0, j = 0; escape_list && escape_list[i].ch != -1 && i+j < 12; i++){
++ if(i+j == OE_HELP_KEY)
++ j++;
++
++ if(i+j == OE_CANCEL_KEY)
++ j++;
++
++ if(i+j == OE_ENTER_KEY)
++ j++;
++
++ fkey_table[i+j] = escape_list[i].ch;
++ }
++
++#if defined(HELPFILE)
++ help_text = (help != NO_HELP) ? get_help_text(help) : (char **)NULL;
++#else
++ help_text = help;
++#endif
++ if(help_text){ /*---- Show help text -----*/
++ int width = ps_global->ttyo->screen_cols - x_base;
++
++ if(FOOTER_ROWS(ps_global) == 1){
++ km_popped++;
++ FOOTER_ROWS(ps_global) = 3;
++ clearfooter(ps_global);
++
++ y_base = -3;
++ real_y_base = y_base + ps_global->ttyo->screen_rows;
++ }
++
++ for(j = 0; j < 2 && help_text[j]; j++){
++ MoveCursor(real_y_base + 1 + j, x_base);
++ CleartoEOLN();
++
++ if(width < strlen(help_text[j])){
++ char *tmp = fs_get((width + 1) * sizeof(char));
++ strncpy(tmp, help_text[j], width);
++ tmp[width] = '\0';
++ PutLine0(real_y_base + 1 + j, x_base, tmp);
++ fs_give((void **)&tmp);
++ }
++ else
++ PutLine0(real_y_base + 1 + j, x_base, help_text[j]);
++ }
++
++#if defined(HELPFILE)
++ free_list_array(&help_text);
++#endif
++
++ } else {
++ clrbitmap(bitmap);
++ clrbitmap((km = &oe_keymenu)->bitmap); /* force formatting */
++ if(!(flags && (*flags) & OE_DISALLOW_HELP))
++ setbitn(OE_HELP_KEY, bitmap);
++
++ setbitn(OE_ENTER_KEY, bitmap);
++ if(!(flags && (*flags) & OE_DISALLOW_CANCEL))
++ setbitn(OE_CANCEL_KEY, bitmap);
++
++ setbitn(OE_CTRL_T_KEY, bitmap);
++
++ /*---- Show the usual possible keys ----*/
++ for(i=0,j=0; escape_list && escape_list[i].ch != -1 && i+j < 12; i++){
++ if(i+j == OE_HELP_KEY)
++ j++;
++
++ if(i+j == OE_CANCEL_KEY)
++ j++;
++
++ if(i+j == OE_ENTER_KEY)
++ j++;
++
++ oe_keymenu.keys[i+j].label = escape_list[i].label;
++ oe_keymenu.keys[i+j].name = escape_list[i].name;
++ setbitn(i+j, bitmap);
++ }
++
++ for(i = i+j; i < 12; i++)
++ if(!(i == OE_HELP_KEY || i == OE_ENTER_KEY || i == OE_CANCEL_KEY))
++ oe_keymenu.keys[i].name = NULL;
++
++ draw_keymenu(km, bitmap, cols, 1-FOOTER_ROWS(ps_global), 0, FirstMenu);
++ }
++
++ StartInverse(); /* Always in inverse */
++
++ /*
++ * if display length isn't wide enough to support input,
++ * shorten up the prompt...
++ */
++ if((dline.dlen = cols - (x_base + prompt_len + 1)) < 5){
++ prompt_len += (dline.dlen - 5); /* adding negative numbers */
++ prompt -= (dline.dlen - 5); /* subtracting negative numbers */
++ dline.dlen = 5;
++ }
++
++ dline.dl = fs_get((size_t)dline.dlen + 1);
++ memset((void *)dline.dl, 0, (size_t)(dline.dlen + 1) * sizeof(char));
++ dline.row = real_y_base;
++ dline.col = x_base + prompt_len;
++ dline.vl = string;
++ dline.vlen = --field_len; /* -1 for terminating NULL */
++ dline.vbase = field_pos = 0;
++
++#ifdef _WINDOWS
++ cursor_shown = mswin_showcursor(1);
++#endif
++
++ PutLine0(real_y_base, x_base, prompt);
++ /* make sure passed in string is shorter than field_len */
++ /* and adjust field_pos.. */
++
++ while((flags && *flags & OE_APPEND_CURRENT) &&
++ field_pos < field_len && string[field_pos] != '\0')
++ field_pos++;
++
++ string[field_pos] = '\0';
++ dline.vused = (int)(&string[field_pos] - string);
++ passwd = (flags && *flags & OE_PASSWD) ? 1 : 0;
++ line_paint(field_pos, &passwd);
++
++ /*----------------------------------------------------------------------
++ The main loop
++
++ here field_pos is the position in the string.
++ s always points to where we are in the string.
++ loops until someone sets the return_v.
++ ----------------------------------------------------------------------*/
++ return_v = -10;
++
++#ifdef _WINDOWS
++ mswin_allowpaste(MSWIN_PASTE_LINE);
++#endif
++
++ while(return_v == -10) {
++ /* Timeout 10 min to keep imap mail stream alive */
++ ch = read_char(600);
++
++ /*
++ * Don't want to intercept all characters if typing in passwd.
++ * We select an ad hoc set that we will catch and let the rest
++ * through. We would have caught the set below in the big switch
++ * but we skip the switch instead. Still catch things like ^K,
++ * DELETE, ^C, RETURN.
++ */
++ if(passwd)
++ switch(ch) {
++ case ctrl('F'):
++ case KEY_RIGHT:
++ case ctrl('B'):
++ case KEY_LEFT:
++ case ctrl('U'):
++ case ctrl('A'):
++ case KEY_HOME:
++ case ctrl('E'):
++ case KEY_END:
++ case TAB:
++ goto ok_for_passwd;
++ }
++
++ if(too_thin && ch != KEY_RESIZE && ch != ctrl('Z') && ch != ctrl('C'))
++ goto bleep;
++
++ switch(ch) {
++
++ /*--------------- KEY RIGHT ---------------*/
++ case ctrl('F'):
++ case KEY_RIGHT:
++ if(field_pos >= field_len || string[field_pos] == '\0')
++ goto bleep;
++
++ line_paint(++field_pos, &passwd);
++ break;
++
++ /*--------------- KEY LEFT ---------------*/
++ case ctrl('B'):
++ case KEY_LEFT:
++ if(field_pos <= 0)
++ goto bleep;
++
++ line_paint(--field_pos, &passwd);
++ break;
++
++ /*-------------------- WORD SKIP --------------------*/
++ case ctrl('@'):
++ /*
++ * Note: read_char *can* return NO_OP_COMMAND which is
++ * the def'd with the same value as ^@ (NULL), BUT since
++ * read_char has a big timeout (>25 secs) it won't.
++ */
++
++ /* skip thru current word */
++ while(string[field_pos]
++ && isalnum((unsigned char) string[field_pos]))
++ field_pos++;
++
++ /* skip thru current white space to next word */
++ while(string[field_pos]
++ && !isalnum((unsigned char) string[field_pos]))
++ field_pos++;
++
++ line_paint(field_pos, &passwd);
++ break;
++
++ /*-------------------- RETURN --------------------*/
++ case PF4:
++ if(F_OFF(F_USE_FK,ps_global)) goto bleep;
++ case ctrl('J'):
++ case ctrl('M'):
++ return_v = 0;
++ break;
++
++ /*-------------------- Destructive backspace --------------------*/
++ case '\177': /* DEL */
++ case ctrl('H'):
++ /* Try and do this with by telling the terminal to delete a
++ a character. If that fails, then repaint the rest of the
++ line, acheiving the same much less efficiently
++ */
++ if(field_pos <= 0)
++ goto bleep;
++
++ field_pos--;
++ /* drop thru to pull line back ... */
++
++ /*-------------------- Delete char --------------------*/
++ case ctrl('D'):
++ case KEY_DEL:
++ if(field_pos >= field_len || !string[field_pos])
++ goto bleep;
++
++ dline.vused--;
++ for(s2 = &string[field_pos]; *s2 != '\0'; s2++)
++ *s2 = s2[1];
++
++ *s2 = '\0'; /* Copy last NULL */
++ line_paint(field_pos, &passwd);
++ if(flags) /* record change if requested */
++ *flags |= OE_USER_MODIFIED;
++
++ break;
++
++
++ /*--------------- Kill line -----------------*/
++ case ctrl('K'):
++ if(kill_buffer != NULL)
++ fs_give((void **)&kill_buffer);
++
++ if(field_pos != 0 || string[0]){
++ if(!passwd && F_ON(F_DEL_FROM_DOT, ps_global))
++ dline.vused -= strlen(&string[i = field_pos]);
++ else
++ dline.vused = i = 0;
++
++ kill_buffer = cpystr(&string[field_pos = i]);
++ string[field_pos] = '\0';
++ line_paint(field_pos, &passwd);
++ if(flags) /* record change if requested */
++ *flags |= OE_USER_MODIFIED;
++
++ }
++
++ break;
++
++ /*------------------- Undelete line --------------------*/
++ case ctrl('U'):
++ if(kill_buffer == NULL)
++ goto bleep;
++
++ /* Make string so it will fit */
++ kb = cpystr(kill_buffer);
++ dprint(2, (debugfile,
++ "Undelete: %d %d\n", strlen(string), field_len));
++ if(strlen(kb) + strlen(string) > field_len)
++ kb[field_len - strlen(string)] = '\0';
++ dprint(2, (debugfile,
++ "Undelete: %d %d\n", field_len - strlen(string),
++ strlen(kb)));
++
++ if(string[field_pos] == '\0') {
++ /*--- adding to the end of the string ----*/
++ for(k = kb; *k; k++)
++ string[field_pos++] = *k;
++
++ string[field_pos] = '\0';
++ } else {
++ goto bleep;
++ /* To lazy to do insert in middle of string now */
++ }
++
++ if(*kb && flags) /* record change if requested */
++ *flags |= OE_USER_MODIFIED;
++
++ dline.vused = strlen(string);
++ fs_give((void **)&kb);
++ line_paint(field_pos, &passwd);
++ break;
++
++
++ /*-------------------- Interrupt --------------------*/
++ case ctrl('C'): /* ^C */
++ if(F_ON(F_USE_FK,ps_global)
++ || (flags && ((*flags) & OE_DISALLOW_CANCEL)))
++ goto bleep;
++
++ goto cancel;
++
++ case PF2:
++ if(F_OFF(F_USE_FK,ps_global)
++ || (flags && ((*flags) & OE_DISALLOW_CANCEL)))
++ goto bleep;
++
++ cancel:
++ return_v = 1;
++ if(saved_original)
++ strcpy(string, saved_original);
++
++ break;
++
++
++ case ctrl('A'):
++ case KEY_HOME:
++ /*-------------------- Start of line -------------*/
++ line_paint(field_pos = 0, &passwd);
++ break;
++
++
++ case ctrl('E'):
++ case KEY_END:
++ /*-------------------- End of line ---------------*/
++ line_paint(field_pos = dline.vused, &passwd);
++ break;
++
++
++ /*-------------------- Help --------------------*/
++ case ctrl('G') :
++ case PF1:
++ if(flags && ((*flags) & OE_DISALLOW_HELP))
++ goto bleep;
++ else if(FOOTER_ROWS(ps_global) == 1 && km_popped == 0){
++ km_popped++;
++ FOOTER_ROWS(ps_global) = 3;
++ clearfooter(ps_global);
++ EndInverse();
++ draw_keymenu(km, bitmap, cols, 1-FOOTER_ROWS(ps_global),
++ 0, FirstMenu);
++ StartInverse();
++ mark_keymenu_dirty();
++ y_base = -3;
++ dline.row = real_y_base = y_base + ps_global->ttyo->screen_rows;
++ PutLine0(real_y_base, x_base, prompt);
++ fs_resize((void **)&dline.dl, (size_t)dline.dlen + 1);
++ memset((void *)dline.dl, 0, (size_t)(dline.dlen + 1));
++ line_paint(field_pos, &passwd);
++ break;
++ }
++
++ if(FOOTER_ROWS(ps_global) > 1){
++ mark_keymenu_dirty();
++ return_v = 3;
++ }
++ else
++ goto bleep;
++
++ break;
++
++ case NO_OP_IDLE:
++ /* Keep mail stream alive */
++ i = new_mail(0, 2, NM_DEFER_SORT);
++ if(ps_global->expunge_count &&
++ flags && ((*flags) & OE_SEQ_SENSITIVE))
++ goto cancel;
++
++ if(i < 0)
++ break; /* no changes, get on with life */
++ /* Else fall into redraw */
++
++ /*-------------------- Redraw --------------------*/
++ case ctrl('L'):
++ /*---------------- re size ----------------*/
++ case KEY_RESIZE:
++
++ dline.row = real_y_base = y_base > 0 ? y_base :
++ y_base + ps_global->ttyo->screen_rows;
++ EndInverse();
++ ClearScreen();
++ redraw_titlebar();
++ if(ps_global->redrawer != (void (*)())NULL)
++ (*ps_global->redrawer)();
++
++ redraw_keymenu();
++ StartInverse();
++
++ PutLine0(real_y_base, x_base, prompt);
++ cols = ps_global->ttyo->screen_cols;
++ too_thin = 0;
++ if(cols < x_base + prompt_len + 4) {
++ Writechar(BELL, 0);
++ PutLine0(real_y_base, 0, "Screen's too thin. Ouch!");
++ too_thin = 1;
++ } else {
++ dline.col = x_base + prompt_len;
++ dline.dlen = cols - (x_base + prompt_len + 1);
++ fs_resize((void **)&dline.dl, (size_t)dline.dlen + 1);
++ memset((void *)dline.dl, 0, (size_t)(dline.dlen + 1));
++ line_paint(field_pos, &passwd);
++ }
++ fflush(stdout);
++
++ dprint(9, (debugfile,
++ "optionally_enter RESIZE new_cols:%d too_thin: %d\n",
++ cols, too_thin));
++ break;
++
++ case PF3 : /* input to potentially remap */
++ case PF5 :
++ case PF6 :
++ case PF7 :
++ case PF8 :
++ case PF9 :
++ case PF10 :
++ case PF11 :
++ case PF12 :
++ if(F_ON(F_USE_FK,ps_global)
++ && fkey_table[ch - PF1] != NO_OP_COMMAND)
++ ch = fkey_table[ch - PF1]; /* remap function key input */
++
++ default:
++ if(escape_list){ /* in the escape key list? */
++ for(j=0; escape_list[j].ch != -1; j++){
++ if(escape_list[j].ch == ch){
++ return_v = escape_list[j].rval;
++ break;
++ }
++ }
++
++ if(return_v != -10)
++ break;
++ }
++
++ if(iscntrl(ch & 0x7f)){
++ bleep:
++ putc(BELL, stdout);
++ continue;
++ }
++
++ ok_for_passwd:
++ /*--- Insert a character -----*/
++ if(dline.vused >= field_len)
++ goto bleep;
++
++ /*---- extending the length of the string ---*/
++ for(s2 = &string[++dline.vused]; s2 - string > field_pos; s2--)
++ *s2 = *(s2-1);
++
++ string[field_pos++] = ch;
++ line_paint(field_pos, &passwd);
++ if(flags) /* record change if requested */
++ *flags |= OE_USER_MODIFIED;
++
++ } /*---- End of switch on char ----*/
++ }
++
++#ifdef _WINDOWS
++ if(!cursor_shown)
++ mswin_showcursor(0);
++
++ mswin_allowpaste(MSWIN_PASTE_DISABLE);
++#endif
++ fs_give((void **)&dline.dl);
++ if(saved_original)
++ fs_give((void **)&saved_original);
++
++ if(kill_buffer)
++ fs_give((void **)&kill_buffer);
++
++ if (!(flags && (*flags) & OE_KEEP_TRAILING_SPACE))
++ removing_trailing_white_space(string);
++ EndInverse();
++ MoveCursor(real_y_base, x_base); /* Move the cursor to show we're done */
++ fflush(stdout);
++ resume_busy_alarm(0);
++ if(km_popped){
++ FOOTER_ROWS(ps_global) = 1;
++ clearfooter(ps_global);
++ ps_global->mangled_body = 1;
++ }
++
++ return(return_v);
++}
++
++
++/*
++ * line_paint - where the real work of managing what is displayed gets done.
++ * The passwd variable is overloaded: if non-zero, don't
++ * output anything, else only blat blank chars across line
++ * once and use this var to tell us we've already written the
++ * line.
++ */
++void
++line_paint(offset, passwd)
++ int offset; /* current dot offset into line */
++ int *passwd; /* flag to hide display of chars */
++{
++ register char *pfp, *pbp;
++ register char *vfp, *vbp;
++ int extra = 0;
++#define DLEN (dline.vbase + dline.dlen)
++
++ /*
++ * for now just leave line blank, but maybe do '*' for each char later
++ */
++ if(*passwd){
++ if(*passwd > 1)
++ return;
++ else
++ *passwd == 2; /* only blat once */
++
++ extra = 0;
++ MoveCursor(dline.row, dline.col);
++ while(extra++ < dline.dlen)
++ Writechar(' ', 0);
++
++ MoveCursor(dline.row, dline.col);
++ return;
++ }
++
++ /* adjust right margin */
++ while(offset >= DLEN + ((dline.vused > DLEN) ? -1 : 1))
++ dline.vbase += dline.dlen/2;
++
++ /* adjust left margin */
++ while(offset < dline.vbase + ((dline.vbase) ? 2 : 0))
++ dline.vbase = max(dline.vbase - (dline.dlen/2), 0);
++
++ if(dline.vbase){ /* off screen cue left */
++ vfp = &dline.vl[dline.vbase+1];
++ pfp = &dline.dl[1];
++ if(dline.dl[0] != '<'){
++ MoveCursor(dline.row, dline.col);
++ Writechar(dline.dl[0] = '<', 0);
++ }
++ }
++ else{
++ vfp = dline.vl;
++ pfp = dline.dl;
++ if(dline.dl[0] == '<'){
++ MoveCursor(dline.row, dline.col);
++ Writechar(dline.dl[0] = ' ', 0);
++ }
++ }
++
++ if(dline.vused > DLEN){ /* off screen right... */
++ vbp = vfp + (long)(dline.dlen-(dline.vbase ? 2 : 1));
++ pbp = pfp + (long)(dline.dlen-(dline.vbase ? 2 : 1));
++ if(pbp[1] != '>'){
++ MoveCursor(dline.row, dline.col+dline.dlen);
++ Writechar(pbp[1] = '>', 0);
++ }
++ }
++ else{
++ extra = dline.dlen - (dline.vused - dline.vbase);
++ vbp = &dline.vl[max(0, dline.vused-1)];
++ pbp = &dline.dl[dline.dlen];
++ if(pbp[0] == '>'){
++ MoveCursor(dline.row, dline.col+dline.dlen);
++ Writechar(pbp[0] = ' ', 0);
++ }
++ }
++
++ while(*pfp == *vfp && vfp < vbp) /* skip like chars */
++ pfp++, vfp++;
++
++ if(pfp == pbp && *pfp == *vfp){ /* nothing to paint! */
++ MoveCursor(dline.row, dline.col + (offset - dline.vbase));
++ return;
++ }
++
++ /* move backward thru like characters */
++ if(extra){
++ while(extra >= 0 && *pbp == ' ') /* back over spaces */
++ extra--, pbp--;
++
++ while(extra >= 0) /* paint new ones */
++ pbp[-(extra--)] = ' ';
++ }
++
++ if((vbp - vfp) == (pbp - pfp)){ /* space there? */
++ while((*pbp == *vbp) && pbp != pfp) /* skip like chars */
++ pbp--, vbp--;
++ }
++
++ if(pfp != pbp || *pfp != *vfp){ /* anything to paint?*/
++ MoveCursor(dline.row, dline.col + (int)(pfp - dline.dl));
++
++ do
++ Writechar((unsigned char)((vfp <= vbp && *vfp)
++ ? ((*pfp = *vfp++) == TAB) ? ' ' : *pfp
++ : (*pfp = ' ')), 0);
++ while(++pfp <= pbp);
++ }
++
++ MoveCursor(dline.row, dline.col + (offset - dline.vbase));
++}
++
++
++
++/*----------------------------------------------------------------------
++ Check to see if the given command is reasonably valid
++
++ Args: ch -- the character to check
++
++ Result: A valid command is returned, or a well know bad command is returned.
++
++ ---*/
++validatekeys(ch)
++ int ch;
++{
++#ifndef _WINDOWS
++ if(F_ON(F_USE_FK,ps_global)) {
++ if(ch >= 'a' && ch <= 'z')
++ return(KEY_JUNK);
++ } else {
++ if(ch >= PF1 && ch <= PF12)
++ return(KEY_JUNK);
++ }
++#else
++ /*
++ * In windows menu items are bound to a single key command which
++ * gets inserted into the input stream as if the user had typed
++ * that key. But all the menues are bonund to alphakey commands,
++ * not PFkeys. to distinguish between a keyboard command and a
++ * menu command we insert a flag (KEY_MENU_FLAG) into the
++ * command value when setting up the bindings in
++ * configure_menu_items(). Here we strip that flag.
++ */
++ if(F_ON(F_USE_FK,ps_global)) {
++ if(ch >= 'a' && ch <= 'z' && !(ch & KEY_MENU_FLAG))
++ return(KEY_JUNK);
++ ch &= ~ KEY_MENU_FLAG;
++ } else {
++ ch &= ~ KEY_MENU_FLAG;
++ if(ch >= PF1 && ch <= PF12)
++ return(KEY_JUNK);
++ }
++#endif
++
++ return(ch);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Prepend config'd commands to keyboard input
++
++ Args: ch -- pointer to storage for returned command
++
++ Returns: TRUE if we're passing back a useful command, FALSE otherwise
++
++ ---*/
++int
++process_config_input(ch)
++ int *ch;
++{
++ static char firsttime = (char) 1;
++
++ /* commands in config file */
++ if(ps_global->initial_cmds && *ps_global->initial_cmds) {
++ /*
++ * There are a few commands that may require keyboard input before
++ * we enter the main command loop. That input should be interactive,
++ * not from our list of initial keystrokes.
++ */
++ if(ps_global->dont_use_init_cmds)
++ return(0);
++
++ *ch = *ps_global->initial_cmds++;
++ if(!*ps_global->initial_cmds && ps_global->free_initial_cmds){
++ fs_give((void **)&(ps_global->free_initial_cmds));
++ ps_global->initial_cmds = 0;
++ }
++
++ return(1);
++ }
++
++ if(firsttime) {
++ firsttime = 0;
++ if(ps_global->in_init_seq) {
++ ps_global->in_init_seq = 0;
++ ps_global->save_in_init_seq = 0;
++ clear_cursor_pos();
++ F_SET(F_USE_FK,ps_global,ps_global->orig_use_fkeys);
++ /* draw screen */
++ *ch = ctrl('L');
++ return(1);
++ }
++ }
++
++ return(0);
++}
++
++
++#define TAPELEN 256
++static int tape[TAPELEN];
++static long recorded = 0L;
++static short length = 0;
++
++
++/*
++ * record user keystrokes
++ *
++ * Args: ch -- the character to record
++ *
++ * Returns: character recorded
++ */
++int
++key_recorder(ch)
++ int ch;
++{
++ tape[recorded++ % TAPELEN] = ch;
++ if(length < TAPELEN)
++ length++;
++
++ return(ch);
++}
++
++
++/*
++ * playback user keystrokes
++ *
++ * Args: ch -- ignored
++ *
++ * Returns: character played back or -1 to indicate end of tape
++ */
++int
++key_playback(ch)
++ int ch;
++{
++ ch = length ? tape[(recorded + TAPELEN - length--) % TAPELEN] : -1;
++ return(ch);
++}
++
++
++
++/*======================================================================
++ Routines for painting the screen
++ - figure out what the terminal type is
++ - deal with screen size changes
++ - save special output sequences
++ - the usual screen clearing, cursor addressing and scrolling
++
++
++ This library gives programs the ability to easily access the
++ termcap information and write screen oriented and raw input
++ programs. The routines can be called as needed, except that
++ to use the cursor / screen routines there must be a call to
++ InitScreen() first. The 'Raw' input routine can be used
++ independently, however. (Elm comment)
++
++ Not sure what the original source of this code was. It got to be
++ here as part of ELM. It has been changed significantly from the
++ ELM version to be more robust in the face of inconsistent terminal
++ autowrap behaviour. Also, the unused functions were removed, it was
++ made to pay attention to the window size, and some code was made nicer
++ (in my opinion anyways). It also outputs the terminal initialization
++ strings and provides for minimal scrolling and detects terminals
++ with out enough capabilities. (Pine comment, 1990)
++
++
++This code used to pay attention to the "am" auto margin and "xn"
++new line glitch fields, but they were so often incorrect because many
++terminals can be configured to do either that we've taken it out. It
++now assumes it dosn't know where the cursor is after outputing in the
++80th column.
++*/
++
++#define PUTLINE_BUFLEN 256
++
++static int _lines, _columns;
++static int _line = FARAWAY;
++static int _col = FARAWAY;
++static int _in_inverse;
++
++
++/*
++ * Internal prototypes
++ */
++static void moveabsolute PROTO((int, int));
++static void CursorUp PROTO((int));
++static void CursorDown PROTO((int));
++static void CursorLeft PROTO((int));
++static void CursorRight PROTO((int));
++
++
++extern char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
++ *_setinverse, *_clearinverse,
++ *_setunderline, *_clearunderline,
++ *_setbold, *_clearbold,
++ *_cleartoeoln, *_cleartoeos,
++ *_startinsert, *_endinsert, *_insertchar, *_deletechar,
++ *_deleteline, *_insertline,
++ *_scrollregion, *_scrollup, *_scrolldown,
++ *_termcap_init, *_termcap_end;
++extern char term_name[];
++extern int _tlines, _tcolumns;
++
++static enum {NoScroll,UseScrollRegion,InsertDelete} _scrollmode;
++
++char *tgoto(); /* and the goto stuff */
++
++
++
++/*----------------------------------------------------------------------
++ Initialize the screen for output, set terminal type, etc
++
++ Args: tt -- Pointer to variable to store the tty output structure.
++
++ Result: terminal size is discovered and set in pine state
++ termcap entry is fetched and stored
++ make sure terminal has adequate capabilites
++ evaluate scrolling situation
++ returns status of indicating the state of the screen/termcap entry
++
++ Returns:
++ -1 indicating no terminal name associated with this shell,
++ -2..-n No termcap for this terminal type known
++ -3 Can't open termcap file
++ -4 Terminal not powerful enough - missing clear to eoln or screen
++ or cursor motion
++ ----*/
++int
++config_screen(tt)
++ struct ttyo **tt;
++{
++ struct ttyo *ttyo;
++ int err;
++
++ ttyo = (struct ttyo *)fs_get(sizeof (struct ttyo));
++
++ _line = 0; /* where are we right now?? */
++ _col = 0; /* assume zero, zero... */
++
++ /*
++ * This is an ugly hack to let vtterminalinfo know it's being called
++ * from pine.
++ */
++ Pmaster = (PICO *)1;
++ if(err = vtterminalinfo(F_ON(F_TCAP_WINS, ps_global)))
++ return(err);
++
++ Pmaster = NULL;
++
++ if(_tlines <= 0)
++ _lines = DEFAULT_LINES_ON_TERMINAL;
++ else
++ _lines = _tlines;
++
++ if(_tcolumns <= 0)
++ _columns = DEFAULT_COLUMNS_ON_TERMINAL;
++ else
++ _columns = _tcolumns;
++
++ get_windsize(ttyo);
++
++ ttyo->header_rows = 2;
++ ttyo->footer_rows = 3;
++
++ /*---- Make sure this terminal has the capability.
++ All we need is cursor address, clear line, and
++ reverse video.
++ ---*/
++ if(_moveto == NULL || _cleartoeoln == NULL ||
++ _setinverse == NULL || _clearinverse == NULL) {
++ return(-4);
++ }
++
++ dprint(1, (debugfile, "Terminal type: %s\n", term_name));
++
++ /*------ Figure out scrolling mode -----*/
++ if(_scrollregion != NULL && _scrollregion[0] != '\0' &&
++ _scrollup != NULL && _scrollup[0] != '\0'){
++ _scrollmode = UseScrollRegion;
++ } else if(_insertline != NULL && _insertline[0] != '\0' &&
++ _deleteline != NULL && _deleteline[0] != '\0') {
++ _scrollmode = InsertDelete;
++ } else {
++ _scrollmode = NoScroll;
++ }
++ dprint(7, (debugfile, "Scroll mode: %s\n",
++ _scrollmode==NoScroll ? "No Scroll" :
++ _scrollmode==InsertDelete ? "InsertDelete" : "Scroll Regions"));
++
++ if (!_left) {
++ _left = "\b";
++ }
++
++ *tt = ttyo;
++
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Initialize the screen with the termcap string
++ ----*/
++void
++init_screen()
++{
++ if(_termcap_init) /* init using termcap's rule */
++ tputs(_termcap_init, 1, outchar);
++
++ /* and make sure there are no scrolling surprises! */
++ BeginScroll(0, ps_global->ttyo->screen_rows - 1);
++ /* and make sure icon text starts out consistent */
++ icon_text(NULL);
++ fflush(stdout);
++}
++
++
++
++
++/*----------------------------------------------------------------------
++ Get the current window size
++
++ Args: ttyo -- pointer to structure to store window size in
++
++ NOTE: we don't override the given values unless we know better
++ ----*/
++int
++get_windsize(ttyo)
++struct ttyo *ttyo;
++{
++#ifdef RESIZING
++ struct winsize win;
++
++ /*
++ * Get the window size from the tty driver. If we can't fish it from
++ * stdout (pine's output is directed someplace else), try stdin (which
++ * *must* be associated with the terminal; see init_tty_driver)...
++ */
++ if(ioctl(1, TIOCGWINSZ, &win) >= 0 /* 1 is stdout */
++ || ioctl(0, TIOCGWINSZ, &win) >= 0){ /* 0 is stdin */
++ if(win.ws_row)
++ _lines = min(win.ws_row, MAX_SCREEN_ROWS);
++
++ if(win.ws_col)
++ _columns = min(win.ws_col, MAX_SCREEN_COLS);
++
++ dprint(2, (debugfile, "new win size -----<%d %d>------\n",
++ _lines, _columns));
++ }
++ else
++ /* Depending on the OS, the ioctl() may have failed because
++ of a 0 rows, 0 columns setting. That happens on DYNIX/ptx 1.3
++ (with a kernel patch that happens to involve the negotiation
++ of window size in the telnet streams module.) In this case
++ the error is EINVARG. Leave the default settings. */
++ dprint(1, (debugfile, "ioctl(TIOCWINSZ) failed :%s\n",
++ error_description(errno)));
++#endif
++
++ ttyo->screen_cols = min(_columns, MAX_SCREEN_COLS);
++ ttyo->screen_rows = min(_lines, MAX_SCREEN_ROWS);
++ return(0);
++}
++
++
++/*----------------------------------------------------------------------
++ End use of the screen.
++ Print status message, if any.
++ Flush status messages.
++ ----*/
++void
++end_screen(message)
++ char *message;
++{
++ int footer_rows_was_one = 0;
++
++ dprint(9, (debugfile, "end_screen called\n"));
++
++ if(FOOTER_ROWS(ps_global) == 1){
++ footer_rows_was_one++;
++ FOOTER_ROWS(ps_global) = 3;
++ mark_status_unknown();
++ }
++
++ flush_status_messages(1);
++ blank_keymenu(_lines - 2, 0);
++ MoveCursor(_lines - 2, 0);
++ if(_termcap_end != NULL)
++ tputs(_termcap_end, 1, outchar);
++
++ if(message){
++ printf("%s\r\n", message);
++ }
++
++ if(F_ON(F_ENABLE_XTERM_NEWMAIL, ps_global) && getenv("DISPLAY"))
++ icon_text("xterm");
++
++ fflush(stdout);
++
++ if(footer_rows_was_one){
++ FOOTER_ROWS(ps_global) = 1;
++ mark_status_unknown();
++ }
++}
++
++
++
++/*----------------------------------------------------------------------
++ Clear the terminal screen
++
++ Result: The screen is cleared
++ internal cursor position set to 0,0
++ ----*/
++void
++ClearScreen()
++{
++ _line = 0; /* clear leaves us at top... */
++ _col = 0;
++
++ if(ps_global->in_init_seq)
++ return;
++
++ mark_status_unknown();
++ mark_keymenu_dirty();
++ mark_titlebar_dirty();
++
++ if(!_clearscreen){
++ ClearLines(0, _lines-1);
++ MoveCursor(0, 0);
++ }
++ else{
++ tputs(_clearscreen, 1, outchar);
++ moveabsolute(0, 0); /* some clearscreens don't move correctly */
++ }
++}
++
++
++/*----------------------------------------------------------------------
++ Internal move cursor to absolute position
++
++ Args: col -- column to move cursor to
++ row -- row to move cursor to
++
++ Result: cursor is moved (variables, not updates)
++ ----*/
++
++static void
++moveabsolute(col, row)
++{
++
++ char *stuff, *tgoto();
++
++ stuff = tgoto(_moveto, col, row);
++ tputs(stuff, 1, outchar);
++}
++
++
++/*----------------------------------------------------------------------
++ Move the cursor to the row and column number
++ Args: row number
++ column number
++
++ Result: Cursor moves
++ internal position updated
++ ----*/
++void
++MoveCursor(row, col)
++ int row, col;
++{
++ /** move cursor to the specified row column on the screen.
++ 0,0 is the top left! **/
++
++ int scrollafter = 0;
++
++ /* we don't want to change "rows" or we'll mangle scrolling... */
++
++ if(ps_global->in_init_seq)
++ return;
++
++ if (col < 0)
++ col = 0;
++ if (col >= ps_global->ttyo->screen_cols)
++ col = ps_global->ttyo->screen_cols - 1;
++ if (row < 0)
++ row = 0;
++ if (row > ps_global->ttyo->screen_rows) {
++ if (col == 0)
++ scrollafter = row - ps_global->ttyo->screen_rows;
++ row = ps_global->ttyo->screen_rows;
++ }
++
++ if (!_moveto)
++ return;
++
++ if (row == _line) {
++ if (col == _col)
++ return; /* already there! */
++
++ else if (abs(col - _col) < 5) { /* within 5 spaces... */
++ if (col > _col && _right)
++ CursorRight(col - _col);
++ else if (col < _col && _left)
++ CursorLeft(_col - col);
++ else
++ moveabsolute(col, row);
++ }
++ else /* move along to the new x,y loc */
++ moveabsolute(col, row);
++ }
++ else if (col == _col && abs(row - _line) < 5) {
++ if (row < _line && _up)
++ CursorUp(_line - row);
++ else if (_line > row && _down)
++ CursorDown(row - _line);
++ else
++ moveabsolute(col, row);
++ }
++ else if (_line == row-1 && col == 0) {
++ putchar('\n'); /* that's */
++ putchar('\r'); /* easy! */
++ }
++ else
++ moveabsolute(col, row);
++
++ _line = row; /* to ensure we're really there... */
++ _col = col;
++
++ if (scrollafter) {
++ while (scrollafter--) {
++ putchar('\n');
++ putchar('\r');
++
++ }
++ }
++
++ return;
++}
++
++
++
++/*----------------------------------------------------------------------
++ Newline, move the cursor to the start of next line
++
++ Result: Cursor moves
++ ----*/
++void
++NewLine()
++{
++ /** move the cursor to the beginning of the next line **/
++
++ Writechar('\n', 0);
++ Writechar('\r', 0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Move cursor up n lines with terminal escape sequence
++
++ Args: n -- number of lines to go up
++
++ Result: cursor moves,
++ internal position updated
++
++ Only for ttyout use; not outside callers
++ ----*/
++static void
++CursorUp(n)
++int n;
++{
++ /** move the cursor up 'n' lines **/
++ /** Calling function must check that _up is not null before calling **/
++
++ _line = (_line-n > 0? _line - n: 0); /* up 'n' lines... */
++
++ while (n-- > 0)
++ tputs(_up, 1, outchar);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Move cursor down n lines with terminal escape sequence
++
++ Arg: n -- number of lines to go down
++
++ Result: cursor moves,
++ internal position updated
++
++ Only for ttyout use; not outside callers
++ ----*/
++static void
++CursorDown(n)
++ int n;
++{
++ /** move the cursor down 'n' lines **/
++ /** Caller must check that _down is not null before calling **/
++
++ _line = (_line+n < ps_global->ttyo->screen_rows ? _line + n
++ : ps_global->ttyo->screen_rows);
++ /* down 'n' lines... */
++
++ while (n-- > 0)
++ tputs(_down, 1, outchar);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Move cursor left n lines with terminal escape sequence
++
++ Args: n -- number of lines to go left
++
++ Result: cursor moves,
++ internal position updated
++
++ Only for ttyout use; not outside callers
++ ----*/
++static void
++CursorLeft(n)
++int n;
++{
++ /** move the cursor 'n' characters to the left **/
++ /** Caller must check that _left is not null before calling **/
++
++ _col = (_col - n> 0? _col - n: 0); /* left 'n' chars... */
++
++ while (n-- > 0)
++ tputs(_left, 1, outchar);
++}
++
++
++/*----------------------------------------------------------------------
++ Move cursor right n lines with terminal escape sequence
++
++ Args: number of lines to go right
++
++ Result: cursor moves,
++ internal position updated
++
++ Only for ttyout use; not outside callers
++ ----*/
++static void
++CursorRight(n)
++int n;
++{
++ /** move the cursor 'n' characters to the right (nondestructive) **/
++ /** Caller must check that _right is not null before calling **/
++
++ _col = (_col+n < ps_global->ttyo->screen_cols? _col + n :
++ ps_global->ttyo->screen_cols); /* right 'n' chars... */
++
++ while (n-- > 0)
++ tputs(_right, 1, outchar);
++
++}
++
++
++
++/*----------------------------------------------------------------------
++ Start painting inverse on the screen
++
++ Result: escape sequence to go into inverse is output
++ returns 1 if it was done, 0 if not.
++ ----*/
++int
++StartInverse()
++{
++ /** set inverse video mode **/
++
++ if (!_setinverse)
++ return(0);
++
++ if(_in_inverse)
++ return(1);
++
++ _in_inverse = 1;
++ tputs(_setinverse, 1, outchar);
++ return(1);
++}
++
++
++
++/*----------------------------------------------------------------------
++ End painting inverse on the screen
++
++ Result: escape sequence to go out of inverse is output
++ returns 1 if it was done, 0 if not.
++ ----------------------------------------------------------------------*/
++void
++EndInverse()
++{
++ /** compliment of startinverse **/
++
++ if (!_clearinverse)
++ return;
++
++ if(_in_inverse){
++ _in_inverse = 0;
++ tputs(_clearinverse, 1, outchar);
++ }
++}
++
++
++int
++StartUnderline()
++{
++ if (!_setunderline)
++ return(0);
++
++ tputs(_setunderline, 1, outchar);
++ return(1);
++}
++
++
++void
++EndUnderline()
++{
++ if (!_clearunderline)
++ return;
++
++ tputs(_clearunderline, 1, outchar);
++}
++
++int
++StartBold()
++{
++ if (!_setbold)
++ return(0);
++
++ tputs(_setbold, 1, outchar);
++ return(1);
++}
++
++void
++EndBold()
++{
++ if (!_clearbold)
++ return;
++
++ tputs(_clearbold, 1, outchar);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Insert character on screen pushing others right
++
++ Args: c -- character to insert
++
++ Result: charcter is inserted if possible
++ return -1 if it can't be done
++ ----------------------------------------------------------------------*/
++InsertChar(c)
++ int c;
++{
++ if(_insertchar != NULL && *_insertchar != '\0') {
++ tputs(_insertchar, 1, outchar);
++ Writechar(c, 0);
++ } else if(_startinsert != NULL && *_startinsert != '\0') {
++ tputs(_startinsert, 1, outchar);
++ Writechar(c, 0);
++ tputs(_endinsert, 1, outchar);
++ } else {
++ return(-1);
++ }
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Delete n characters from line, sliding rest of line left
++
++ Args: n -- number of characters to delete
++
++
++ Result: characters deleted on screen
++ returns -1 if it wasn't done
++ ----------------------------------------------------------------------*/
++DeleteChar(n)
++ int n;
++{
++ if(_deletechar == NULL || *_deletechar == '\0')
++ return(-1);
++
++ while(n) {
++ tputs(_deletechar, 1, outchar);
++ n--;
++ }
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Go into scrolling mode, that is set scrolling region if applicable
++
++ Args: top -- top line of region to scroll
++ bottom -- bottom line of region to scroll
++ (These are zero-origin numbers)
++
++ Result: either set scrolling region or
++ save values for later scrolling
++ returns -1 if we can't scroll
++
++ Unfortunately this seems to leave the cursor in an unpredictable place
++ at least the manuals don't say where, so we force it here.
++-----*/
++static int __t, __b;
++
++BeginScroll(top, bottom)
++ int top, bottom;
++{
++ char *stuff;
++
++ if(_scrollmode == NoScroll)
++ return(-1);
++
++ __t = top;
++ __b = bottom;
++ if(_scrollmode == UseScrollRegion){
++ stuff = tgoto(_scrollregion, bottom, top);
++ tputs(stuff, 1, outchar);
++ /*-- a location very far away to force a cursor address --*/
++ _line = FARAWAY;
++ _col = FARAWAY;
++ }
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ End scrolling -- clear scrolling regions if necessary
++
++ Result: Clear scrolling region on terminal
++ -----*/
++void
++EndScroll()
++{
++ if(_scrollmode == UseScrollRegion && _scrollregion != NULL){
++ /* Use tgoto even though we're not cursor addressing because
++ the format of the capability is the same.
++ */
++ char *stuff = tgoto(_scrollregion, ps_global->ttyo->screen_rows -1, 0);
++ tputs(stuff, 1, outchar);
++ /*-- a location very far away to force a cursor address --*/
++ _line = FARAWAY;
++ _col = FARAWAY;
++ }
++}
++
++
++/* ----------------------------------------------------------------------
++ Scroll the screen using insert/delete or scrolling regions
++
++ Args: lines -- number of lines to scroll, positive forward
++
++ Result: Screen scrolls
++ returns 0 if scroll succesful, -1 if not
++
++ positive lines goes foward (new lines come in at bottom
++ Leaves cursor at the place to insert put new text
++
++ 0,0 is the upper left
++ -----*/
++ScrollRegion(lines)
++ int lines;
++{
++ int l;
++
++ if(lines == 0)
++ return(0);
++
++ if(_scrollmode == UseScrollRegion) {
++ if(lines > 0) {
++ MoveCursor(__b, 0);
++ for(l = lines ; l > 0 ; l--)
++ tputs((_scrolldown == NULL || _scrolldown[0] =='\0') ? "\n" :
++ _scrolldown, 1, outchar);
++ } else {
++ MoveCursor(__t, 0);
++ for(l = -lines; l > 0; l--)
++ tputs(_scrollup, 1, outchar);
++ }
++ } else if(_scrollmode == InsertDelete) {
++ if(lines > 0) {
++ MoveCursor(__t, 0);
++ for(l = lines; l > 0; l--)
++ tputs(_deleteline, 1, outchar);
++ MoveCursor(__b, 0);
++ for(l = lines; l > 0; l--)
++ tputs(_insertline, 1, outchar);
++ } else {
++ for(l = -lines; l > 0; l--) {
++ MoveCursor(__b, 0);
++ tputs(_deleteline, 1, outchar);
++ MoveCursor(__t, 0);
++ tputs(_insertline, 1, outchar);
++ }
++ }
++ } else {
++ return(-1);
++ }
++ fflush(stdout);
++ return(0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Write a character to the screen, keeping track of cursor position
++
++ Args: ch -- character to output
++
++ Result: character output
++ cursor position variables updated
++ ----*/
++void
++Writechar(ch, new_esc_len)
++ register unsigned int ch;
++ int new_esc_len;
++{
++ static int esc_len = 0;
++
++ if(ps_global->in_init_seq /* silent */
++ || (F_ON(F_BLANK_KEYMENU, ps_global) /* or bottom, */
++ && !esc_len /* right cell */
++ && _line + 1 == ps_global->ttyo->screen_rows
++ && _col + 1 == ps_global->ttyo->screen_cols))
++ return;
++
++ if(!iscntrl(ch & 0x7f)){
++ putchar(ch);
++ if(esc_len > 0)
++ esc_len--;
++ else
++ _col++;
++ }
++ else{
++ switch(ch){
++ case LINE_FEED:
++ /*-- Don't have to watch out for auto wrap or newline glitch
++ because we never let it happen. See below
++ ---*/
++ putchar('\n');
++ _line = min(_line+1,ps_global->ttyo->screen_rows);
++ esc_len = 0;
++ break;
++
++ case RETURN : /* move to column 0 */
++ putchar('\r');
++ _col = 0;
++ esc_len = 0;
++ break;
++
++ case BACKSPACE : /* move back a space if not in column 0 */
++ if(_col != 0) {
++ putchar('\b');
++ _col--;
++ } /* else BACKSPACE does nothing */
++
++ break;
++
++ case BELL : /* ring the bell but don't advance _col */
++ putchar(ch);
++ break;
++
++ case TAB : /* if a tab, output it */
++ do /* BUG? ignores tty driver's spacing */
++ putchar(' ');
++ while(_col < ps_global->ttyo->screen_cols - 1
++ && ((++_col)&0x07) != 0);
++ break;
++
++ case ESCAPE :
++ /* If we're outputting an escape here, it may be part of an iso2022
++ escape sequence in which case take up no space on the screen.
++ Unfortunately such sequences are variable in length.
++ */
++ esc_len = new_esc_len - 1;
++ putchar(ch);
++ break;
++
++ default : /* Change remaining control characters to ? */
++ if(F_ON(F_PASS_CONTROL_CHARS, ps_global))
++ putchar(ch);
++ else
++ putchar('?');
++
++ if(esc_len > 0)
++ esc_len--;
++ else
++ _col++;
++
++ break;
++ }
++ }
++
++
++ /* Here we are at the end of the line. We've decided to make no
++ assumptions about how the terminal behaves at this point.
++ What can happen now are the following
++ 1. Cursor is at start of next line, and next character will
++ apear there. (autowrap, !newline glitch)
++ 2. Cursor is at start of next line, and if a newline is output
++ it'll be ignored. (autowrap, newline glitch)
++ 3. Cursor is still at end of line and next char will apear
++ there over the top of what is there now (no autowrap).
++ We ignore all this and force the cursor to the next line, just
++ like case 1. A little expensive but worth it to avoid problems
++ with terminals configured so they don't match termcap
++ */
++ if(_col == ps_global->ttyo->screen_cols) {
++ _col = 0;
++ if(_line + 1 < ps_global->ttyo->screen_rows)
++ _line++;
++
++ moveabsolute(_col, _line);
++ }
++}
++
++
++
++/*----------------------------------------------------------------------
++ Write string to screen at current cursor position
++
++ Args: string -- strings to be output
++
++ Result: Line written to the screen
++ ----*/
++void
++Write_to_screen(string) /* UNIX */
++ register char *string;
++{
++ while(*string)
++ Writechar((unsigned char) *string++, 0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Clear screen to end of line on current line
++
++ Result: Line is cleared
++ ----*/
++void
++CleartoEOLN()
++{
++ if(!_cleartoeoln)
++ return;
++
++ tputs(_cleartoeoln, 1, outchar);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Clear screen to end of screen from current point
++
++ Result: screen is cleared
++ ----*/
++CleartoEOS()
++{
++ if(!_cleartoeos){
++ CleartoEOLN();
++ ClearLines(_line, _lines-1);
++ }
++ else
++ tputs(_cleartoeos, 1, outchar);
++}
++
++
++
++/*----------------------------------------------------------------------
++ function to output character used by termcap
++
++ Args: c -- character to output
++
++ Result: character output to screen via stdio
++ ----*/
++void
++outchar(c)
++int c;
++{
++ /** output the given character. From tputs... **/
++ /** Note: this CANNOT be a macro! **/
++
++ putc((unsigned char)c, stdout);
++}
++
++
++
++/*----------------------------------------------------------------------
++ function to output string such that it becomes icon text
++
++ Args: s -- string to write
++
++ Result: string indicated become our "icon" text
++ ----*/
++void
++icon_text(s)
++ char *s;
++{
++ static char *old_s;
++ static enum {ukn, yes, no} xterm;
++
++ if(xterm == ukn)
++ xterm = (getenv("DISPLAY") != NULL) ? yes : no;
++
++ if(F_ON(F_ENABLE_XTERM_NEWMAIL,ps_global) && xterm == yes && (s || old_s)){
++ fputs("\033]1;", stdout);
++ fputs((old_s = s) ? s : ps_global->pine_name, stdout);
++ fputs("\007", stdout);
++ fflush(stdout);
++ }
++}
++
++
++#ifdef _WINDOWS
++#line 3 "osdep/termout.gen"
++#endif
++
++/*
++ * Generic tty output routines...
++ */
++
++/*----------------------------------------------------------------------
++ Printf style output line to the screen at given position, 0 args
++
++ Args: x -- column position on the screen
++ y -- row position on the screen
++ line -- line of text to output
++
++ Result: text is output
++ cursor position is update
++ ----*/
++void
++PutLine0(x, y, line)
++ int x,y;
++ register char *line;
++{
++ MoveCursor(x,y);
++ Write_to_screen(line);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Output line of length len to the display observing embedded attributes
++
++ Args: x -- column position on the screen
++ y -- column position on the screen
++ line -- text to be output
++ length -- length of text to be output
++
++ Result: text is output
++ cursor position is updated
++ ----------------------------------------------------------------------*/
++void
++PutLine0n8b(x, y, line, length, handles)
++ int x, y, length;
++ register char *line;
++ HANDLE_S *handles;
++{
++ unsigned char c;
++
++ MoveCursor(x,y);
++ while(length-- && (c = (unsigned char)*line++)){
++ if(c == (unsigned char)TAG_EMBED && length){
++ length--;
++ switch(*line++){
++ case TAG_INVON :
++ StartInverse();
++ break;
++ case TAG_INVOFF :
++ EndInverse();
++ break;
++ case TAG_BOLDON :
++ StartBold();
++ break;
++ case TAG_BOLDOFF :
++ EndBold();
++ break;
++ case TAG_ULINEON :
++ StartUnderline();
++ break;
++ case TAG_ULINEOFF :
++ EndUnderline();
++ break;
++ case TAG_HANDLE :
++ length -= *line + 1; /* key length plus length tag */
++ if(handles){
++ int key, n;
++
++ for(key = 0, n = *line++; n; n--) /* forget Horner? */
++ key = (key * 10) + (*line++ - '0');
++
++ if(key == handles->key){
++ EndBold();
++ StartInverse();
++ }
++ }
++ else{
++ /* BUG: complain? */
++ line += *line + 1;
++ }
++
++ break;
++ default : /* literal "embed" char? */
++ Writechar(TAG_EMBED, 0);
++ Writechar(*(line-1), 0);
++ break;
++ } /* tag with handle, skip it */
++ }
++ else if(c == '\033') /* check for iso-2022 escape */
++ Writechar(c, match_escapes(line));
++ else
++ Writechar(c, 0);
++ }
++}
++
++
++/*----------------------------------------------------------------------
++ Printf style output line to the screen at given position, 1 arg
++
++ Input: position on the screen
++ line of text to output
++
++ Result: text is output
++ cursor position is update
++ ----------------------------------------------------------------------*/
++void
++/*VARARGS2*/
++PutLine1(x, y, line, arg1)
++ int x, y;
++ char *line;
++ void *arg1;
++{
++ char buffer[PUTLINE_BUFLEN];
++
++ sprintf(buffer, line, arg1);
++ PutLine0(x, y, buffer);
++}
++
++
++/*----------------------------------------------------------------------
++ Printf style output line to the screen at given position, 2 args
++
++ Input: position on the screen
++ line of text to output
++
++ Result: text is output
++ cursor position is update
++ ----------------------------------------------------------------------*/
++void
++/*VARARGS3*/
++PutLine2(x, y, line, arg1, arg2)
++ int x, y;
++ char *line;
++ void *arg1, *arg2;
++{
++ char buffer[PUTLINE_BUFLEN];
++
++ sprintf(buffer, line, arg1, arg2);
++ PutLine0(x, y, buffer);
++}
++
++
++/*----------------------------------------------------------------------
++ Printf style output line to the screen at given position, 3 args
++
++ Input: position on the screen
++ line of text to output
++
++ Result: text is output
++ cursor position is update
++ ----------------------------------------------------------------------*/
++void
++/*VARARGS4*/
++PutLine3(x, y, line, arg1, arg2, arg3)
++ int x, y;
++ char *line;
++ void *arg1, *arg2, *arg3;
++{
++ char buffer[PUTLINE_BUFLEN];
++
++ sprintf(buffer, line, arg1, arg2, arg3);
++ PutLine0(x, y, buffer);
++}
++
++
++/*----------------------------------------------------------------------
++ Printf style output line to the screen at given position, 4 args
++
++ Args: x -- column position on the screen
++ y -- column position on the screen
++ line -- printf style line of text to output
++
++ Result: text is output
++ cursor position is update
++ ----------------------------------------------------------------------*/
++void
++/*VARARGS5*/
++PutLine4(x, y, line, arg1, arg2, arg3, arg4)
++ int x, y;
++ char *line;
++ void *arg1, *arg2, *arg3, *arg4;
++{
++ char buffer[PUTLINE_BUFLEN];
++
++ sprintf(buffer, line, arg1, arg2, arg3, arg4);
++ PutLine0(x, y, buffer);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Printf style output line to the screen at given position, 5 args
++
++ Args: x -- column position on the screen
++ y -- column position on the screen
++ line -- printf style line of text to output
++
++ Result: text is output
++ cursor position is update
++ ----------------------------------------------------------------------*/
++void
++/*VARARGS6*/
++PutLine5(x, y, line, arg1, arg2, arg3, arg4, arg5)
++ int x, y;
++ char *line;
++ void *arg1, *arg2, *arg3, *arg4, *arg5;
++{
++ char buffer[PUTLINE_BUFLEN];
++
++ sprintf(buffer, line, arg1, arg2, arg3, arg4, arg5);
++ PutLine0(x, y, buffer);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Output a line to the screen, centered
++
++ Input: Line number to print on, string to output
++
++ Result: String is output to screen
++ Returns column number line is output on
++ ----------------------------------------------------------------------*/
++int
++Centerline(line, string)
++ int line;
++ char *string;
++{
++ register int length, col;
++
++ length = strlen(string);
++
++ if (length > ps_global->ttyo->screen_cols)
++ col = 0;
++ else
++ col = (ps_global->ttyo->screen_cols - length) / 2;
++
++ PutLine0(line, col, string);
++ return(col);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Clear specified line on the screen
++
++ Result: The line is blanked and the cursor is left at column 0.
++
++ ----*/
++void
++ClearLine(n)
++ int n;
++{
++ if(ps_global->in_init_seq)
++ return;
++
++ MoveCursor(n, 0);
++ CleartoEOLN();
++}
++
++
++
++/*----------------------------------------------------------------------
++ Clear specified lines on the screen
++
++ Result: The lines starting at 'x' and ending at 'y' are blanked
++ and the cursor is left at row 'x', column 0
++
++ ----*/
++void
++ClearLines(x, y)
++ int x, y;
++{
++ int i;
++
++ for(i = x; i <= y; i++)
++ ClearLine(i);
++
++ MoveCursor(x, 0);
++}
++
++
++
++/*----------------------------------------------------------------------
++ Indicate to the screen painting here that the position of the cursor
++ has been disturbed and isn't where these functions might think.
++ ----*/
++void
++clear_cursor_pos()
++{
++ _line = FARAWAY;
++ _col = FARAWAY;
++}
++
++
++/*----------------------------------------------------------------------
++ Return current inverse state
++
++ Result: returns 1 if in inverse state, 0 if not.
++ ----------------------------------------------------------------------*/
++int
++InverseState()
++{
++ return(_in_inverse);
++}
++
++
diff --git a/chinese/pine4/files/patch-ao b/chinese/pine4/files/patch-ao
index ae0d6d6574cb..aa19f2338c1d 100644
--- a/chinese/pine4/files/patch-ao
+++ b/chinese/pine4/files/patch-ao
@@ -1,20 +1,11 @@
-*** pico/tcap.c.bak Fri Mar 15 10:42:31 1996
---- pico/tcap.c Thu Jan 29 22:04:28 1998
-***************
-*** 322,328 ****
- KPPU = tgetstr("kP", &p);
- KPPD = tgetstr("kN", &p);
- KPHOME = tgetstr("kh", &p);
-! KPEND = tgetstr("kE", &p);
- KPDEL = tgetstr("kD", &p);
- KU = tgetstr("ku", &p);
- KD = tgetstr("kd", &p);
---- 322,329 ----
- KPPU = tgetstr("kP", &p);
- KPPD = tgetstr("kN", &p);
- KPHOME = tgetstr("kh", &p);
-! if((KPEND = tgetstr("@7", &p)) == NULL)
-! KPEND = tgetstr("kE", &p);
- KPDEL = tgetstr("kD", &p);
- KU = tgetstr("ku", &p);
- KD = tgetstr("kd", &p);
+--- pine/osdep/os-bsf.h.orig Fri Jun 26 14:19:54 1998
++++ pine/osdep/os-bsf.h Wed Jul 15 17:02:35 1998
+@@ -268,7 +268,7 @@
+ 8
+ 9 logs gross details of command execution
+ ----*/
+-#define DEFAULT_DEBUG 2
++#define DEFAULT_DEBUG 0
+
+
+
diff --git a/chinese/pine4/files/patch-ap b/chinese/pine4/files/patch-ap
index 4a7155a3732d..ce5e2d6eb0dd 100644
--- a/chinese/pine4/files/patch-ap
+++ b/chinese/pine4/files/patch-ap
@@ -1,20 +1,1331 @@
-*** pine/ttyout.c.bak Thu Jul 11 05:45:56 1996
---- pine/ttyout.c Thu Jan 29 22:17:48 1998
-***************
-*** 289,295 ****
- _kppu = tgetstr("kP", &ptr);
- _kppd = tgetstr("kN", &ptr);
- _kphome = tgetstr("kh", &ptr);
-! _kpend = tgetstr("kE", &ptr);
- _kpdel = tgetstr("kD", &ptr);
- _kf1 = tgetstr("k1", &ptr);
- _kf2 = tgetstr("k2", &ptr);
---- 289,296 ----
- _kppu = tgetstr("kP", &ptr);
- _kppd = tgetstr("kN", &ptr);
- _kphome = tgetstr("kh", &ptr);
-! if((_kpend = tgetstr("@7", &ptr)) == NULL)
-! _kpend = tgetstr("kE", &ptr);
- _kpdel = tgetstr("kD", &ptr);
- _kf1 = tgetstr("k1", &ptr);
- _kf2 = tgetstr("k2", &ptr);
+--- pine/addrbook.c.orig Thu Jul 9 05:35:32 1998
++++ pine/addrbook.c Wed Jul 15 17:02:31 1998
+@@ -126,13 +126,13 @@
+ int addr_scroll_callback PROTO((int, long));
+ #endif
+
+-#define CLICKHERE "[ Address List ]"
+-#define EMPTY "[ Empty ]"
+-#define ZOOM_EMPTY "[ No Selected Entries in this Address Book ]"
+-#define ADD_PERSONAL " [ Move here to add a Personal Address Book ]"
+-#define ADD_GLOBAL " [ Move here to add a Global Address Book ]"
+-#define DISTLIST "DISTRIBUTION LIST:"
+-#define NOABOOKS "[ No Address Book Configured ]"
++#define CLICKHERE "[ 地址列表 ]"
++#define EMPTY "[ 沒有任何項目 ]"
++#define ZOOM_EMPTY "[ 本列表中沒有任何已被選取的項目 ]"
++#define ADD_PERSONAL " [ 移到這裡加入一個個人的地址簿 ]"
++#define ADD_GLOBAL " [ 移到這裡加入一個整體的地址簿 ]"
++#define DISTLIST "分類列表:"
++#define NOABOOKS "[ 沒有已經設定好的地址簿 ]"
+
+
+ /*
+@@ -283,7 +283,7 @@
+
+ dprint(2, (debugfile, "parse_format: ignoring unrecognized word \"%s\" in address-book-formats\n", p));
+ q_status_message1(SM_ORDER, warnings++==0 ? 1 : 0, 4,
+- "Ignoring unrecognized word \"%s\" in address-book-formats", p);
++ "忽略地址簿格式中無法辨識的字 \"%s\"", p);
+ /* put back space */
+ if(r)
+ *r = SPACE;
+@@ -353,7 +353,7 @@
+
+ if(column == 0){
+ q_status_message(SM_ORDER, 0, 4,
+- "address-book-formats has no recognizable words, using default format");
++ "由於在地址簿格式中找不到足以辨識的字, 因此使用預設模式");
+ goto assign_default;
+ }
+
+@@ -575,7 +575,7 @@
+ }
+ else{
+ q_status_message(SM_ORDER | SM_DING, 5, 10,
+- "Bug in addrbook, not supposed to happen, re-syncing...");
++ "地址簿功\能中出現未預期的錯誤,重新同步中...");
+ dprint(1,
+ (debugfile,
+ "Bug in addrbook (null dlc in dlist(%ld), not supposed to happen\n",
+@@ -1676,14 +1676,14 @@
+ mailcap_free(); /* free resources we won't be using for a while */
+
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1, (debugfile, "RESETTING address book... addr_book_screen!\n"));
+ addrbook_reset();
+ }
+
+ ab_nesting_level = 1; /* come here only from main menu */
+
+- (void)addr_book(AddrBookScreen, "ADDRESS BOOK", NULL);
++ (void)addr_book(AddrBookScreen, "地址簿", NULL);
+ end_adrbks();
+
+ ab_nesting_level = 0;
+@@ -1701,14 +1701,14 @@
+ mailcap_free(); /* free resources we won't be using for a while */
+
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1, (debugfile, "RESETTING address book... addr_book_config!\n"));
+ addrbook_reset();
+ }
+
+ ab_nesting_level = 1;
+
+- (void)addr_book(AddrBookConfig, "SETUP ADDRESS BOOKS", NULL);
++ (void)addr_book(AddrBookConfig, "設定地址簿", NULL);
+ end_adrbks();
+
+ ab_nesting_level = 0;
+@@ -1737,7 +1737,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book... addr_book_compose!\n"));
+ addrbook_reset();
+@@ -1746,7 +1746,7 @@
+
+ ab_nesting_level++;
+
+- p = addr_book(SelectNicksCom, "COMPOSER: SELECT ADDRESS", error);
++ p = addr_book(SelectNicksCom, "編輯器:選擇地址", error);
+
+ if(ab_nesting_level <= 1)
+ end_adrbks();
+@@ -1781,7 +1781,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book... addr_book_compose_lcc!\n"));
+ addrbook_reset();
+@@ -1794,7 +1794,7 @@
+ * We used to use SelectAddrLccCom here but decided it wasn't necessary
+ * to restrict the selection to a list.
+ */
+- p = addr_book(SelectNicksCom, "COMPOSER: SELECT LIST", error);
++ p = addr_book(SelectNicksCom, "編輯器:選擇列表", error);
+
+ if(ab_nesting_level <= 1)
+ end_adrbks();
+@@ -1829,7 +1829,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book... addr_book_change_list!\n"));
+ addrbook_reset();
+@@ -1838,7 +1838,7 @@
+
+ ab_nesting_level++;
+
+- p = addr_book(SelectNicksCom, "ADDRESS BOOK (Update): SELECT ADDRESSES",
++ p = addr_book(SelectNicksCom, "地址簿 (更新):選擇地址",
+ error);
+
+ if(ab_nesting_level <= 1)
+@@ -1871,7 +1871,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book...addr_book_bounce!\n"));
+ addrbook_reset();
+@@ -1912,7 +1912,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book...addr_book_takeaddr!\n"));
+ addrbook_reset();
+@@ -1957,7 +1957,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book...addr_book_nick_for_edit!\n"));
+ addrbook_reset();
+@@ -2005,7 +2005,7 @@
+ save_nesting_level = cpyint(ab_nesting_level);
+ memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
+ if(setjmp(addrbook_changed_unexpectedly)){
+- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
++ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
+ dprint(1,
+ (debugfile, "RESETTING address book...addr_book_selnick!\n"));
+ addrbook_reset();
+@@ -2037,8 +2037,8 @@
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+- {"P", "PrevEntry", {MC_PREVITEM,1,{'p'}}, KS_NONE},
+- {"N", "NextEntry", {MC_NEXTITEM,1,{'n'}}, KS_NONE},
++ {"P", "前一個項目", {MC_PREVITEM,1,{'p'}}, KS_NONE},
++ {"N", "下一個項目", {MC_NEXTITEM,1,{'n'}}, KS_NONE},
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ NULL_MENU,
+@@ -2061,10 +2061,10 @@
+
+ HELP_MENU,
+ OTHER_MENU,
+- {";","Select",{MC_SELECT,1,{';'}},KS_NONE},
+- {"A","Apply",{MC_APPLY,1,{'a'}},KS_APPLY},
+- {":","SelectCur",{MC_SELCUR,1,{':'}},KS_SELECTCUR},
+- {"Z","ZoomMode",{MC_ZOOM,1,{'z'}},KS_NONE},
++ {";","選擇",{MC_SELECT,1,{';'}},KS_NONE},
++ {"A","套用",{MC_APPLY,1,{'a'}},KS_APPLY},
++ {":","選擇目前的",{MC_SELCUR,1,{':'}},KS_SELECTCUR},
++ {"Z","縮放模式",{MC_ZOOM,1,{'z'}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -2193,7 +2193,7 @@
+ if(!init_addrbooks(HalfOpen, 1, !as.config, !are_selecting)){
+ if(are_selecting){
+ q_status_message(SM_ORDER | SM_DING, 0, 4,
+- "No Address Book Configured");
++ "沒有已設定完成的地址簿");
+ display_message(c);
+ sleep(2);
+ return NULL;
+@@ -2201,7 +2201,7 @@
+ else if(!as.config){
+ ps->next_screen = main_menu_screen;
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "No Address Book Configured, Use SETUP Addressbook screen");
++ "沒有已設定完成的地址簿,請用 SETUP Addressbook 功\能畫面");
+ ps->mangled_screen = 1;
+ return NULL;
+ }
+@@ -2211,7 +2211,7 @@
+ readonly_warning(NO_DING, NULL);
+ else if(as.adrbks[0].access == NoAccess)
+ q_status_message(SM_ORDER, 0, 4,
+- "AddressBook not accessible, permission denied");
++ "地址簿禁止被存取");
+ }
+
+ erase_checks();
+@@ -2342,8 +2342,8 @@
+ char buf[80], *bp;
+
+ if(style == AddrBookScreen){
+- sprintf(buf, "ADDRESS BOOK%s%s%s",
+- (!as.opened) ? " LIST" :
++ sprintf(buf, "地址簿%s%s%s",
++ (!as.opened) ? "列表" :
+ (as.n_addrbk > 1) ? " <" : "",
+ (as.opened && as.n_addrbk > 1 && pab->nickname)
+ ? pab->nickname : "",
+@@ -2418,7 +2418,7 @@
+ km->how_many = 1;
+
+ clrbitn(OTHER_KEY, bitmap);
+- menu_init_binding(km, 'E', MC_EXIT, "E", "Exit Setup", TWO_KEY);
++ menu_init_binding(km, 'E', MC_EXIT, "E", "離開", TWO_KEY);
+ KS_OSDATASET(&km->keys[TWO_KEY], KS_EXITMODE);
+
+ /*
+@@ -2431,22 +2431,22 @@
+ clrbitn(THREE_KEY, bitmap);
+ menu_init_binding(km, 'A', MC_ADDABOOK, "A",
+ add_is_global(as.top_ent+as.cur_row)
+- ? "[Add Glob Abook]"
+- : "[Add Pers Abook]",
++ ? "[新增整體地址簿]"
++ : "[新增個人地址簿]",
+ ADD_KEY);
+ def_key = ADD_KEY;
+ }
+ else{
+- menu_init_binding(km, 'D', MC_DELABOOK, "D", "Del Abook",
++ menu_init_binding(km, 'D', MC_DELABOOK, "D", "刪除地址簿",
+ DELETE_KEY);
+- menu_init_binding(km, '$', MC_SHUFFLE, "$", "Shuffle",
++ menu_init_binding(km, '$', MC_SHUFFLE, "$", "重整",
+ SENDTO_KEY);
+- menu_init_binding(km, 'C', MC_EDITABOOK, "C", "[Change]",
++ menu_init_binding(km, 'C', MC_EDITABOOK, "C", "[修改]",
+ THREE_KEY);
+ menu_init_binding(km, 'A', MC_ADDABOOK, "A",
+ add_is_global(as.top_ent+as.cur_row)
+- ? "Add Glob Abook"
+- : "Add Pers Abook",
++ ? "新增整體地址簿"
++ : "新增個人地址簿",
+ ADD_KEY);
+ }
+ }
+@@ -2459,7 +2459,7 @@
+ * The OTHER_KEY is used as the Exit key in selection mode.
+ * This is because the TWO_KEY is being used for < actions.
+ */
+- menu_init_binding(km, 'E', MC_EXIT, "E", "ExitSelect",
++ menu_init_binding(km, 'E', MC_EXIT, "E", "離開",
+ OTHER_KEY);
+ KS_OSDATASET(&km->keys[OTHER_KEY], KS_EXITMODE);
+
+@@ -2474,7 +2474,7 @@
+ cmd = MC_POPUP;
+
+ menu_init_binding(km, '<', cmd, "<",
+- cmd == MC_POPUP ? "AddbkList" : "Unexpand",
++ cmd == MC_POPUP ? "地址簿列表" : "復原展開",
+ TWO_KEY);
+ menu_add_binding(km, ',', cmd);
+ if(F_ON(F_ARROW_NAV,ps))
+@@ -2489,7 +2489,7 @@
+ * key becomes the ViewAbook key.
+ */
+ if(entry_is_askserver(as.top_ent+as.cur_row)){
+- menu_init_binding(km, '>', MC_QUERY_SERV, ">", "[Search]",
++ menu_init_binding(km, '>', MC_QUERY_SERV, ">", "[搜尋]",
+ THREE_KEY);
+ menu_add_binding(km, 's', MC_QUERY_SERV);
+ menu_add_binding(km, '.', MC_QUERY_SERV);
+@@ -2497,7 +2497,7 @@
+ menu_add_binding(km, KEY_RIGHT, MC_QUERY_SERV);
+ }
+ else if(entry_is_clickable_title(as.top_ent+as.cur_row)){
+- menu_init_binding(km, '>', MC_OPENABOOK, ">", "[ViewAbook]",
++ menu_init_binding(km, '>', MC_OPENABOOK, ">", "[檢視地址簿]",
+ THREE_KEY);
+ menu_add_binding(km, 'v', MC_OPENABOOK);
+ menu_add_binding(km, '.', MC_OPENABOOK);
+@@ -2505,7 +2505,7 @@
+ menu_add_binding(km, KEY_RIGHT, MC_OPENABOOK);
+ }
+ else if(as.opened){
+- menu_init_binding(km, 'S', MC_CHOICE, "S", "[Select]",
++ menu_init_binding(km, 'S', MC_CHOICE, "S", "[選取]",
+ THREE_KEY);
+ }
+ else
+@@ -2518,7 +2518,7 @@
+ */
+ if(entry_is_clickable(as.top_ent+as.cur_row) &&
+ !entry_is_clickable_title(as.top_ent+as.cur_row)){
+- menu_init_binding(km, '>', MC_EXPAND, ">", "Expand",
++ menu_init_binding(km, '>', MC_EXPAND, ">", "展開",
+ SENDTO_KEY);
+ menu_add_binding(km, '.', MC_EXPAND);
+ if(F_ON(F_ARROW_NAV,ps))
+@@ -2528,12 +2528,12 @@
+ clrbitn(SENDTO_KEY, bitmap);
+
+ if(as.opened && as.checkboxes){
+- menu_init_binding(km, 'X', MC_TOGGLE, "X", "Set/Unset",
++ menu_init_binding(km, 'X', MC_TOGGLE, "X", "設定/解除設定",
+ DELETE_KEY);
+
+ }
+ else if(as.opened && listmode_ok){
+- menu_init_binding(km, 'L', MC_LISTMODE, "L", "ListMode",
++ menu_init_binding(km, 'L', MC_LISTMODE, "L", "列表模式",
+ DELETE_KEY);
+ }
+ else
+@@ -2550,7 +2550,7 @@
+ * reasonable function call.
+ */
+ km->keys[OTHER_KEY].name = "O";
+- km->keys[OTHER_KEY].label = "OTHER CMDS";
++ km->keys[OTHER_KEY].label = "其他命令";
+ km->keys[OTHER_KEY].bind.cmd = MC_OTHER;
+ km->keys[OTHER_KEY].bind.ch[0] = 'O';
+ km->keys[OTHER_KEY].bind.nch = 1;
+@@ -2569,18 +2569,18 @@
+ if(F_OFF(F_EXPANDED_DISTLISTS,ps) &&
+ entry_is_listent(as.top_ent+as.cur_row)){
+ cmd = MC_UNEXPAND;
+- menu_init_binding(km, '<', cmd, "<", "Unexpand",
++ menu_init_binding(km, '<', cmd, "<", "復原展開",
+ TWO_KEY);
+ }
+ else{
+ if(as.n_addrbk > 1 || as.n_serv){
+ cmd = MC_POPUP;
+- menu_init_binding(km, '<', cmd, "<", "AddbkList",
++ menu_init_binding(km, '<', cmd, "<", "地址簿列表",
+ TWO_KEY);
+ }
+ else{
+ cmd = MC_MAIN;
+- menu_init_binding(km, 'M', cmd, "<", "Main Menu",
++ menu_init_binding(km, 'M', cmd, "<", "主選單",
+ TWO_KEY);
+ KS_OSDATASET(&km->keys[TWO_KEY], KS_MAINMENU);
+ }
+@@ -2592,9 +2592,9 @@
+ /*
+ * Add or delete entries from this address book.
+ */
+- menu_init_binding(km, '@', MC_ADD, "@", "AddNew",
++ menu_init_binding(km, '@', MC_ADD, "@", "新增",
+ ADD_KEY);
+- menu_init_binding(km, 'D', MC_DELETE, "D", "Delete",
++ menu_init_binding(km, 'D', MC_DELETE, "D", "刪除",
+ DELETE_KEY);
+ }
+ else{
+@@ -2604,14 +2604,14 @@
+
+ /* Find someplace to put Main Menu command */
+ if(cmd == MC_POPUP){
+- menu_init_binding(km, 'M', MC_MAIN, "M", "Main Menu",
++ menu_init_binding(km, 'M', MC_MAIN, "M", "主選單",
+ SECONDARY_MAIN_KEY);
+ KS_OSDATASET(&km->keys[SECONDARY_MAIN_KEY],KS_MAINMENU);
+ }
+ else
+ clrbitn(SECONDARY_MAIN_KEY, bitmap);
+
+- menu_init_binding(km, 'C', MC_COMPOSE, "C", "ComposeTo",
++ menu_init_binding(km, 'C', MC_COMPOSE, "C", "編修",
+ SENDTO_KEY);
+ KS_OSDATASET(&km->keys[SENDTO_KEY], KS_COMPOSER);
+ }
+@@ -2621,7 +2621,7 @@
+ * non-selection mode.
+ */
+ cmd = MC_MAIN;
+- menu_init_binding(km, 'M', cmd, "<", "Main Menu",
++ menu_init_binding(km, 'M', cmd, "<", "主選單",
+ TWO_KEY);
+ KS_OSDATASET(&km->keys[TWO_KEY], KS_MAINMENU);
+
+@@ -2661,10 +2661,10 @@
+ cmd = MC_VIEW_ENTRY;
+
+ menu_init_binding(km, '>', cmd, ">",
+- cmd == MC_EXPAND ? "[Expand]" :
+- cmd == MC_QUERY_SERV ? "[Search]" :
+- as.opened ? "[View/Update]"
+- : "[ViewAbook]",
++ cmd == MC_EXPAND ? "[展開]" :
++ cmd == MC_QUERY_SERV ? "[搜尋]" :
++ as.opened ? "[檢視/更新]"
++ : "[檢視地址簿]",
+ THREE_KEY);
+
+ if(cmd == MC_QUERY_SERV)
+@@ -2777,34 +2777,34 @@
+ }
+
+ if(as.config){
+- helper(h_abook_config, "HELP ON CONFIGURING ADDRESS BOOKS",
++ helper(h_abook_config, "設定地址簿的輔助說明",
+ HLPD_NONE);
+ }
+ else if(are_selecting){
+ if(as.opened){
+ /* single nick select from TakeAddr */
+ if(style == SelectNickTake)
+- helper(h_abook_select_nicks_take, "HELP ON ADDRESS BOOK",
++ helper(h_abook_select_nicks_take, "地址簿的輔助說明",
+ HLPD_SIMPLE | HLPD_NEWWIN);
+ /* single nick select from addrbook */
+ else if(selecting_one_nick)
+- helper(h_abook_select_nick, "HELP ON ADDRESS BOOK",
++ helper(h_abook_select_nick, "地址簿的輔助說明",
+ HLPD_SIMPLE | HLPD_NEWWIN);
+ /* can use X checkbox command now */
+ else if(as.checkboxes)
+- helper(h_abook_select_checks, "HELP ON ADDRESS BOOK",
++ helper(h_abook_select_checks, "地址簿的輔助說明",
+ HLPD_SIMPLE | HLPD_NEWWIN);
+ /* ListMode command available */
+ else if(listmode_ok)
+- helper(h_abook_select_listmode, "HELP ON ADDRESS BOOK",
++ helper(h_abook_select_listmode, "地址簿的輔助說明",
+ HLPD_SIMPLE | HLPD_NEWWIN);
+ /* no ListMode command available */
+ else
+- helper(h_abook_select_addr, "HELP ON ADDRESS BOOK",
++ helper(h_abook_select_addr, "地址簿的輔助說明",
+ HLPD_SIMPLE | HLPD_NEWWIN);
+ }
+ else{
+- helper(h_abook_select_top, "HELP ON ADDRESS BOOK",
++ helper(h_abook_select_top, "地址簿的輔助說明",
+ HLPD_SIMPLE | HLPD_NEWWIN);
+ }
+ }
+@@ -2812,9 +2812,9 @@
+ else{
+ ps->next_screen = SCREEN_FUN_NULL;
+ if(as.opened)
+- helper(h_abook_opened, "HELP ON ADDRESS BOOK", HLPD_NONE);
++ helper(h_abook_opened, "地址簿的輔助說明", HLPD_NONE);
+ else
+- helper(h_abook_top, "HELP ON ADDRESS BOOK", HLPD_NONE);
++ helper(h_abook_top, "地址簿的輔助說明", HLPD_NONE);
+ }
+
+ /*
+@@ -2887,7 +2887,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't happen in MC_UNEXPAND");
++ "無法在 MC_UNEXPAND 時發生");
+
+ break;
+
+@@ -2923,7 +2923,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't happen in MC_POPUP");
++ "無法在 MC_POPUP 時發生");
+
+ break;
+
+@@ -2984,11 +2984,11 @@
+ }
+ else if(dlc_to_flush->type == DlcTitleNoPerm)
+ q_status_message(SM_ORDER, 0, 4,
+- "Cannot access address book.");
++ "無法存取地址簿。");
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't happen in MC_OPENABOOK");
++ "無法在 MC_OPENABOOK 時發生");
+
+ break;
+
+@@ -3034,7 +3034,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't happen in MC_EXPAND");
++ "無法在 MC_EXPAND 時發生");
+
+ break;
+
+@@ -3046,7 +3046,7 @@
+ /* Select an entry to mail to or a nickname to add to */
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+ q_status_message(SM_ORDER | SM_DING, 0, 4,
+- "No entries in address book. Use ExitSelect to leave address books");
++ "地址簿中找不到任何項目. 請以 離開選擇(E) 離開");
+ break;
+ }
+
+@@ -3068,7 +3068,7 @@
+ }
+ else if(as.checkboxes && checkedn <= 0){
+ q_status_message(SM_ORDER, 0, 1,
+- "Use \"X\" to mark addresses or lists");
++ "使用 \"X\" 標記地址或列表");
+ break;
+ }
+ else if(as.checkboxes){
+@@ -3152,7 +3152,7 @@
+ if(selecting_mult_nicks){
+ if(dl->type != ListHead && style == SelectAddrLccCom){
+ q_status_message(SM_ORDER, 0, 4,
+- "You may only select lists for lcc, use bcc for other addresses");
++ "僅能選擇 lcc 列表, 其他的地址請用 bcc");
+ break;
+ }
+ else{
+@@ -3214,16 +3214,16 @@
+ if(entry_is_clickable(as.top_ent+as.cur_row))
+ clickable_warning(as.top_ent+as.cur_row);
+ else if(entry_is_askserver(as.top_ent+as.cur_row))
+- q_status_message(SM_ORDER, 3, 4, "Use select to select an address or addresses from address books");
++ q_status_message(SM_ORDER, 3, 4, "使用「選擇」來選擇地址簿中的地址");
+ else
+- q_status_message(SM_ORDER, 3, 4, "No address selected");
++ q_status_message(SM_ORDER, 3, 4, "尚未選擇任何地址");
+
+ break;
+ }
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't happen in MC_CHOICE");
++ "無法在 MC_CHOICE 時發生");
+
+ break;
+
+@@ -3247,7 +3247,7 @@
+ if(adrbk_check_all_validity_now()){
+ if(resync_screen(pab, style, checkedn)){
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Address book changed. AddNew cancelled. Try again.");
++ "地址簿被改變了;取消新增。請重試一遍。");
+ ps->mangled_screen = 1;
+ break;
+ }
+@@ -3262,7 +3262,7 @@
+ dprint(9, (debugfile,
+ "Calling edit_entry to add entry manually\n"));
+ edit_entry(pab->address_book, (AdrBk_Entry *)NULL, NO_NEXT,
+- NotSet, 0, &warped, "add");
++ NotSet, 0, &warped, "新增");
+
+ /*
+ * Warped means we got plopped down somewhere in the display
+@@ -3406,7 +3406,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER|SM_DING, 0, 4,
+- "Missing \"}\" in config: %s", q);
++ "設定檔中缺乏 \"}\":%s", q);
+ if(nick)
+ fs_give((void **)&nick);
+ if(file)
+@@ -3442,7 +3442,7 @@
+ ps->mangled_screen = 1;
+ }
+ else
+- q_status_message(SM_ORDER, 0, 4, "Not a changeable line");
++ q_status_message(SM_ORDER, 0, 4, "不為可被更改的一行");
+
+ break;
+
+@@ -3450,7 +3450,7 @@
+ /*---------- Delete an address book -------------------*/
+ case MC_DELABOOK:
+ if(as.n_addrbk == 0){
+- q_status_message(SM_ORDER, 0, 4, "Nothing to delete");
++ q_status_message(SM_ORDER, 0, 4, "沒有可被刪除的項目");
+ break;
+ }
+
+@@ -3505,7 +3505,7 @@
+ start_disp = 0;
+ ps->mangled_body = 1;
+ ps->mangled_footer = 1;
+- q_status_message(SM_ORDER, 0, 3, "Address book deleted");
++ q_status_message(SM_ORDER, 0, 3, "地址簿已被刪除");
+ }
+ else{
+ if(err){
+@@ -3523,7 +3523,7 @@
+ case MC_SHUFFLE:
+ if(entry_is_addkey(as.top_ent+as.cur_row)){
+ q_status_message(SM_ORDER, 0, 4,
+- "Highlight entry you wish to shuffle");
++ "標示想要重整的項目");
+ break;
+ }
+
+@@ -3596,8 +3596,8 @@
+
+ q_status_message(SM_ORDER, 0, 3,
+ msg ? msg :
+- (ret < 0) ? "Shuffle failed" :
+- "Address books shuffled");
++ (ret < 0) ? "重整失敗" :
++ "地址簿已重整");
+ if(ret < 0)
+ dprint(5, (debugfile, "addrbook shuffle failed: %s\n",
+ msg ? msg : "?"));
+@@ -3615,7 +3615,7 @@
+ case MC_PREVITEM:
+ r = prev_selectable_line(as.cur_row+as.top_ent, &new_line);
+ if(r == 0){
+- q_status_message(SM_INFO, 0, 1, "Already on first line.");
++ q_status_message(SM_INFO, 0, 1, "已經在第一行了。");
+ break;
+ }
+
+@@ -3654,7 +3654,7 @@
+ case MC_NEXTITEM:
+ r = next_selectable_line(as.cur_row+as.top_ent, &new_line);
+ if(r == 0){
+- q_status_message(SM_INFO, 0, 1, "Already on last line.");
++ q_status_message(SM_INFO, 0, 1, "已經在最後一行了。");
+ break;
+ }
+
+@@ -3733,7 +3733,7 @@
+ #endif
+ default:
+ q_status_message(SM_INFO, 0, 1,
+- "Can't happen in MC_MOUSE");
++ "無法在 MC_MOUSE 時發生");
+ break;
+ }
+ }
+@@ -3786,7 +3786,7 @@
+ break;
+
+ if(as.top_ent == new_top_ent && as.cur_row == (fl-as.top_ent)){
+- q_status_message(SM_INFO, 0, 1, "Already on first page.");
++ q_status_message(SM_INFO, 0, 1, "已經在第一頁了。");
+ break;
+ }
+
+@@ -3809,7 +3809,7 @@
+ else{
+ new_top_ent = as.top_ent;
+ if(as.cur_row == (fl - as.top_ent)){ /* no change */
+- q_status_message(SM_INFO,0,1,"Already on last page.");
++ q_status_message(SM_INFO,0,1,"已經在最後一頁了。");
+ break;
+ }
+ }
+@@ -3848,14 +3848,14 @@
+ if(adrbk_check_all_validity_now()){
+ if(resync_screen(pab, style, checkedn)){
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Address book changed. Delete cancelled. Try again.");
++ "地址簿被改變了;取消刪除。請重試一遍。");
+ ps->mangled_screen = 1;
+ break;
+ }
+ }
+
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to delete");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供刪除的項目");
+ break;
+ }
+
+@@ -3917,7 +3917,7 @@
+ case MC_TOGGLE:
+ togglex:
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to select");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供選擇的項目");
+ break;
+ }
+
+@@ -3936,10 +3936,10 @@
+
+ if(style == SelectAddrLccCom && dl->type == ListEnt)
+ q_status_message(SM_ORDER, 0, 4,
+- "You may only select whole lists for lcc");
++ "僅能選擇整個列表給 lcc");
+ else if(style == SelectAddrLccCom && dl->type != ListHead)
+ q_status_message(SM_ORDER, 0, 4,
+- "You may only select lists for lcc, use bcc for personal entries");
++ "僅能選擇列表給 lcc,個人項目請用 bcc");
+ else if(dl->type == ListHead || dl->type == Simple){
+ current_changed_flag++;
+ if(entry_is_checked(pab->address_book->checks,
+@@ -3956,11 +3956,11 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 4,
+- "You may not select list members, only whole lists or personal entries");
++ "無法選擇列表成員,僅能選擇整個列表或個人項目");
+ }
+ else
+ q_status_message(SM_ORDER, 0, 4,
+- "You may only select addresses or lists");
++ "僅能選擇地址或列表");
+
+ break;
+
+@@ -3968,7 +3968,7 @@
+ /*------ Turn all checkboxes on ---------*/
+ case MC_SELALL:
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to select");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供選擇的項目");
+ break;
+ }
+
+@@ -4018,7 +4018,7 @@
+ ps->mangled_body = 1;
+ start_disp = 0;
+ q_status_message(SM_ORDER, 0, 4,
+- "Use \"X\" to select addresses or lists");
++ "使用 \"X\" 標記地址或列表");
+ break;
+
+
+@@ -4038,13 +4038,13 @@
+ if(!directory_ok){
+ q_status_message(SM_ORDER, 0, 4,
+ (style == SelectAddrLccCom)
+- ? "Can't search server for Lcc"
+- : "Can't search server from here");
++ ? "無法由伺服器搜尋 Lcc"
++ : "無法由此搜尋伺服器");
+ break;
+ }
+ else if(as.checkboxes){
+ q_status_message(SM_ORDER, 0, 4,
+- "Can't search server when using ListMode");
++ "使用 ListMode 時無法搜尋伺服器");
+ break;
+ }
+
+@@ -4099,7 +4099,7 @@
+ /*----- Select entries to work on --*/
+ case MC_SELECT:
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to select");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供選擇的項目");
+ break;
+ }
+
+@@ -4134,7 +4134,7 @@
+ /*----------- Select current entry ----------*/
+ case MC_SELCUR:
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to select");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供選擇的項目");
+ break;
+ }
+
+@@ -4195,7 +4195,7 @@
+ dlc_restart = *dlc;
+ as.zoomed = 0;
+ q_status_message(SM_ORDER, 0, 2,
+- "Zoom Mode is now off, no entries selected");
++ "縮放模式目前為關閉狀態,沒有任何被選擇的項目");
+
+ warp_to_dlc(&dlc_restart, 0L);
+ /* put current entry in middle of screen */
+@@ -4262,11 +4262,11 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 4,
+- "You may not select list members, only whole lists or personal entries");
++ "無法選擇列表成員,僅能選擇整個列表或個人項目");
+ }
+ else
+ q_status_message(SM_ORDER, 0, 4,
+- "You may only select addresses or lists");
++ "僅能選擇地址或列表");
+
+ break;
+
+@@ -4279,7 +4279,7 @@
+ : NULL,
+ &start_disp);
+ else{
+- q_status_message(SM_ORDER, 0, 2, "Zoom Mode is now off");
++ q_status_message(SM_ORDER, 0, 2, "現在關閉縮放模式");
+ ab_unzoom(&start_disp);
+ }
+
+@@ -4321,7 +4321,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 2,
+- "No selected entries to apply command to");
++ "沒有已選擇的項目可供套用命令");
+
+ break;
+
+@@ -4377,7 +4377,7 @@
+ /*------ Copy entries into an abook ----*/
+ case MC_SAVE:
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to save");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供存入的項目");
+ break;
+ }
+
+@@ -4399,7 +4399,7 @@
+ /*------ Forward an entry in mail -----------*/
+ case MC_FORWARD:
+ if(!any_addrs_avail(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "No entries to forward");
++ q_status_message(SM_ORDER, 0, 4, "沒有可供轉寄的項目");
+ break;
+ }
+
+@@ -4414,14 +4414,14 @@
+ }
+
+ if(!is_addr(as.top_ent+as.cur_row)){
+- q_status_message(SM_ORDER, 0, 4, "Nothing to forward");
++ q_status_message(SM_ORDER, 0, 4, "沒有東西可以轉寄");
+ break;
+ }
+
+ dl = dlist(as.top_ent+as.cur_row);
+ if(dl->type != ListHead && dl->type != Simple){
+ q_status_message(SM_ORDER, 0, 4,
+- "Can only forward whole entries");
++ "僅能轉寄整個列表");
+ break;
+ }
+
+@@ -4453,18 +4453,18 @@
+ case MC_UNKNOWN:
+ if(c == 'e' && !are_selecting){
+ q_status_message(SM_ORDER | SM_DING, 0, 2,
+- "Command \"E\" not defined. Use \"View/Update\" to edit an entry");
++ "\"E\" 這個命令尚未被定義. 請使用 \"檢視/編輯\" 編輯選項");
+ break;
+ }
+ else if(c == 's'
+ && !(are_selecting || entry_is_clickable(as.top_ent+as.cur_row))){
+ q_status_message(SM_ORDER | SM_DING, 0, 2,
+- "Command \"S\" not defined. Use \"AddNew\" to create a list");
++ "\"S\" 這個命令尚未被定義. 請使用 \"新增\" 建立列表");
+ break;
+ }
+ else if(c == 'z' && !are_selecting){
+ q_status_message(SM_ORDER | SM_DING, 0, 2,
+- "Command \"Z\" not defined. Use \"View/Update\" to add to a list");
++ "\"Z\" 這個命令尚未被定義. 請使用 \"檢視/更新\" 新增至列表");
+ break;
+ }
+ /* else, fall through */
+@@ -4499,7 +4499,7 @@
+ as.zoomed = 1;
+
+ if(as.selections){
+- q_status_message(SM_ORDER, 0, 2, "Zoom Mode is now on");
++ q_status_message(SM_ORDER, 0, 2, "現在開啟縮放模式");
+ if(as.opened){
+ dl = dlist(as.top_ent+as.cur_row);
+ if((dl->type == ListHead ||
+@@ -4540,7 +4540,7 @@
+ }
+ else{
+ as.zoomed = 0;
+- q_status_message(SM_ORDER, 0, 2, "No selected entries to zoom on");
++ q_status_message(SM_ORDER, 0, 2, "沒有已選擇的項目可供縮放");
+ }
+ }
+
+@@ -4601,7 +4601,7 @@
+ char *name;
+ {
+ q_status_message2(SM_ORDER | (bell ? SM_DING : 0), 0, 4,
+- "AddressBook%s%s is Read Only",
++ "地址簿%s%s 是唯讀的",
+ name ? " " : "",
+ name ? name : "");
+ }
+@@ -4622,11 +4622,11 @@
+ dl = dlist(cur_line);
+ if(dl->type == NoAbooks)
+ q_status_message(SM_ORDER, 0, 4,
+- "No address books configured, use Setup");
++ "沒有已設定好的地址簿,請用 Setup");
+ else if(dl->type == Empty)
+- q_status_message(SM_ORDER, 0, 4, "Address Book is Empty");
++ q_status_message(SM_ORDER, 0, 4, "地址簿是空的");
+ else
+- q_status_message(SM_ORDER, 0, 4, "Distribution List is Empty");
++ q_status_message(SM_ORDER, 0, 4, "分類列表是空的");
+ }
+
+
+@@ -4643,9 +4643,9 @@
+ register AddrScrn_Disp *dl;
+
+ dl = dlist(cur_line);
+- q_status_message1(SM_ORDER, 0, 4, "%s not expanded, use \">\" to expand",
+- dl->type == Title ? "Address Book"
+- : "Distribution List");
++ q_status_message1(SM_ORDER, 0, 4, "%s 未被展開,使用 \">\" 來展開",
++ dl->type == Title ? "地址簿"
++ : "分類列表");
+ }
+
+
+@@ -4661,7 +4661,7 @@
+ char *what;
+ {
+ q_status_message1(SM_INFO | (bell ? SM_DING : 0), 0, 2,
+- "Address book %s cancelled", what);
++ "地址簿%s已取消", what);
+ }
+
+
+@@ -4671,7 +4671,7 @@
+ void
+ no_tabs_warning()
+ {
+- q_status_message(SM_ORDER, 0, 4, "Tabs not allowed in address book");
++ q_status_message(SM_ORDER, 0, 4, "地址簿中不允許\有 Tab 存在");
+ }
+
+
+@@ -4690,11 +4690,11 @@
+ {
+ int ret = 0;
+ static ESCKEY_S opts[] = {
+- {'c', 'c', "C", "ComposeTo"},
+- {'d', 'd', "D", "Delete"},
+- {'%', '%', "%", "Print"},
+- {'f', 'f', "F", "Forward"},
+- {'s', 's', "S", "Save"},
++ {'c', 'c', "C", "編排"},
++ {'d', 'd', "D", "刪除"},
++ {'%', '%', "%", "列印"},
++ {'f', 'f', "F", "轉寄"},
++ {'s', 's', "S", "存檔"},
+ { 0, '%', "", ""},
+ {-1, 0, NULL, NULL}};
+
+@@ -4726,7 +4726,7 @@
+ break;
+
+ case 'z':
+- cmd_cancelled("Apply command");
++ cmd_cancelled("套用命令");
+ break;
+ }
+
+@@ -4748,22 +4748,22 @@
+ int *start_disp;
+ {
+ static ESCKEY_S sel_opts1[] = {
+- {'a', 'a', "A", "unselect All"},
++ {'a', 'a', "A", "取消所有選擇"},
+ { 0 , 'c', "C", NULL},
+- {'b', 'b', "B", "Broaden selctn"},
+- {'n', 'n', "N", "Narrow selctn"},
+- {'f', 'f', "F", "Flip selected"},
++ {'b', 'b', "B", "擴大選擇"},
++ {'n', 'n', "N", "縮小選擇"},
++ {'f', 'f', "F", "切換選擇"},
+ {-1, 0, NULL, NULL}
+ };
+- static char *sel_pmt1 = "ALTER message selection : ";
++ static char *sel_pmt1 = "更改訊息選擇:";
+ static ESCKEY_S sel_opts2[] = {
+- {'a', 'a', "A", "select All"},
+- {'c', 'c', "C", "select Cur"},
+- {'t', 't', "T", "Text"},
+- {'s', 's', "S", "Status"},
++ {'a', 'a', "A", "選擇全部"},
++ {'c', 'c', "C", "選擇目前的"},
++ {'t', 't', "T", "文字"},
++ {'s', 's', "S", "狀態"},
+ {-1, 0, NULL, NULL}
+ };
+- static char *sel_pmt2 = "SELECT criteria : ";
++ static char *sel_pmt2 = "選擇標準:";
+ ESCKEY_S *sel_opts;
+ HelpType help = NO_HELP;
+ adrbk_cntr_t num, ab_count;
+@@ -4791,8 +4791,8 @@
+ if(dl && (dl->type == ListHead || dl->type == Simple)){
+ sel_opts1[1].label = entry_is_selected(abook->selects,
+ (a_c_arg_t)dl->elnum)
+- ? "unselect Cur"
+- : "select Cur";
++ ? "取消目前的選擇"
++ : "選擇目前的";
+ sel_opts1[1].ch = 'c';
+ }
+ else
+@@ -4814,7 +4814,7 @@
+
+ default:
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Unsupported Select option");
++ "尚未支援的選項");
+ return;
+ }
+ }
+@@ -4823,8 +4823,8 @@
+ (dl->type == ListHead || dl->type == Simple)){
+ sel_opts1[1].label = entry_is_selected(abook->selects,
+ (a_c_arg_t)dl->elnum)
+- ? "unselect Cur"
+- : "select Cur";
++ ? "取消目前的選擇"
++ : "選擇目前的";
+ sel_opts1[1].ch = 'c';
+ }
+ else
+@@ -4841,7 +4841,7 @@
+
+ switch(q){
+ case 'x': /* cancel */
+- cmd_cancelled("Select command");
++ cmd_cancelled("選擇命令");
+ break;
+
+ case 'c': /* select/unselect current */
+@@ -4853,7 +4853,7 @@
+ if(as.selections == 0 && as.zoomed){
+ as.zoomed = 0;
+ q_status_message(SM_ORDER, 0, 2,
+- "Zoom Mode is now off, no entries selected");
++ "縮放模式目前為關閉狀態,沒有任何被選擇的項目");
+ do_warp++;
+ }
+ else if(as.zoomed){
+@@ -4892,7 +4892,7 @@
+ if(as.selections == 0 && as.zoomed){
+ as.zoomed = 0;
+ q_status_message(SM_ORDER, 0, 2,
+- "Zoom Mode is now off, all entries UNselected");
++ "縮放模式目前為關閉狀態,取消所有已選擇的項目");
+ do_warp++;
+ }
+ else{
+@@ -4918,7 +4918,7 @@
+ }
+ }
+
+- q_status_message1(SM_ORDER, 0, 2, "All %s entries selected",
++ q_status_message1(SM_ORDER, 0, 2, "已選擇所有 %s 的項目",
+ comatose(ab_count));
+ if(prevsel == 0 && as.selections > 0 &&
+ !as.zoomed && F_ON(F_AUTO_ZOOM, ps)){
+@@ -4955,14 +4955,14 @@
+ do_beginning++;
+ else{
+ as.zoomed = 0;
+- q_status_message(SM_ORDER, 0, 2, "Zoom Mode is now off");
++ q_status_message(SM_ORDER, 0, 2, "現在關閉縮放模式");
+ do_warp++;
+ }
+ }
+ else
+ do_warp++;
+
+- q_status_message1(SM_ORDER, 0, 2, "%s entries now selected",
++ q_status_message1(SM_ORDER, 0, 2, "項目 %s 現在已被選擇",
+ comatose(as.selections));
+
+ break;
+@@ -4988,7 +4988,7 @@
+ if(as.selections == 0){
+ as.zoomed = 0;
+ q_status_message(SM_ORDER, 0, 2,
+- "Zoom Mode is now off");
++ "現在關閉縮放模式");
+ do_warp++;
+ }
+ else
+@@ -5007,63 +5007,63 @@
+ if(prevsel == as.selections && prevsel > 0){
+ if(as.selections == 1)
+ q_status_message(SM_ORDER, 0, 2,
+- "No change resulted, 1 entry remains selected");
++ "沒有導致任何改變,仍有一個項目被選擇");
+ else
+ q_status_message1(SM_ORDER, 0, 2,
+- "No change resulted, %s entries remain selected",
++ "沒有導致任何改變,仍有 %s 個項目被選擇",
+ comatose(as.selections));
+ }
+ else if(prevsel == 0){
+ if(as.selections == 1)
+ q_status_message(SM_ORDER, 0, 2,
+- "Select matched 1 entry");
++ "選擇符合的一個項目");
+ else if(as.selections > 1)
+ q_status_message1(SM_ORDER, 0, 2,
+- "Select matched %s entries",
++ "選擇符合的 %s 個項目",
+ comatose(as.selections));
+ else
+ q_status_message(SM_ORDER, 0, 2,
+- "Select failed! No entries selected");
++ "選擇失敗! 沒有任何項目被選擇");
+ }
+ else if(as.selections == 0){
+ if(prevsel == 1)
+ q_status_message(SM_ORDER, 0, 2,
+- "The single selected entry is UNselected");
++ "取消已被選擇的單一項目");
+ else
+ q_status_message1(SM_ORDER, 0, 2,
+- "All %s entries UNselected",
++ "所有 %s 個項目都被取消選擇",
+ comatose(prevsel));
+ }
+ else if(narrow){
+ if(as.selections == 1 && (prevsel-as.selections) == 1)
+ q_status_message(SM_ORDER, 0, 2,
+- "1 entry now selected, 1 entry was UNselected");
++ "一項目被選擇,一項目被取消選擇");
+ else if(as.selections == 1)
+ q_status_message1(SM_ORDER, 0, 2,
+- "1 entry now selected, %s entries were UNselected",
++ "一項目被選擇,%s 個項目被取消選擇",
+ comatose(prevsel-as.selections));
+ else if((prevsel-as.selections) == 1)
+ q_status_message1(SM_ORDER, 0, 2,
+- "%s entries now selected, 1 entry was UNselected",
++ "%s 個項目被選擇,一項目被取消選擇",
+ comatose(as.selections));
+ else
+ q_status_message2(SM_ORDER, 0, 2,
+- "%s entries now selected, %s entries were UNselected",
++ "%s 個項目被選擇,%s 個項目被取消選擇",
+ comatose(as.selections),
+ comatose(prevsel-as.selections));
+ }
+ else{
+ if((as.selections-prevsel) == 1)
+ q_status_message1(SM_ORDER, 0, 2,
+- "1 new entry selected, %s entries now selected",
++ "一個新項目被選擇,目前有 %s 個項目已被選擇",
+ comatose(as.selections));
+ else if(as.selections == 1)
+ q_status_message1(SM_ORDER, 0, 2,
+- "%s new entries selected, 1 entry now selected",
++ "%s 個新項目被選擇,一個項目已被選擇",
+ comatose(as.selections-prevsel));
+ else
+ q_status_message2(SM_ORDER, 0, 2,
+- "%s new entries selected, %s entries now selected",
++ "%s 個新項目被選擇,目前有 %s 個項目已被選擇",
+ comatose(as.selections-prevsel),
+ comatose(as.selections));
+ }
+@@ -5073,13 +5073,13 @@
+
+ default :
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Unsupported Select option");
++ "尚未支援的選項");
+ break;
+ }
+ }
+ else{
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Select is not supported from the top-level view");
++ "尚未支援自頂層視角選擇");
+ return;
+ }
+
+@@ -5137,11 +5137,11 @@
+ int narrow;
+ {
+ static ESCKEY_S ab_sel_type_opt[] = {
+- {'s', 's', "S", "Simple"},
+- {'l', 'l', "L", "List"},
++ {'s', 's', "S", "簡單"},
++ {'l', 'l', "L", "列表"},
+ {-1, 0, NULL, NULL}
+ };
+- static char *ab_sel_type = "Select Lists or Simples (non Lists) ? ";
++ static char *ab_sel_type = "選擇列表或簡單(無列表)?";
+ int type;
+ adrbk_cntr_t num, ab_count;
+
+@@ -5159,7 +5159,7 @@
+ break;
+
+ case 'x':
+- cmd_cancelled("Select");
++ cmd_cancelled("選擇");
+ return -1;
+
+ default:
+@@ -5279,7 +5279,7 @@
+ }
+
+ if(type == 'x' || r == 'x'){
+- cmd_cancelled("Select");
++ cmd_cancelled("選擇");
+ return -1;
+ }
+
+@@ -5362,7 +5362,7 @@
+ break;
+
+ default:
+- q_status_message(SM_ORDER | SM_DING, 3, 3, "Unknown type");
++ q_status_message(SM_ORDER | SM_DING, 3, 3, "未知的型態");
+ return(err);
+ }
+
+@@ -5481,18 +5481,18 @@
+ new_top_ent = NO_LINE;
+
+ if(rc == -2)
+- cancel_warning(NO_DING, "search");
++ cancel_warning(NO_DING, "搜尋");
+
+ else if(rc == -1)
+- q_status_message(SM_ORDER, 0, 4, "Word not found");
++ q_status_message(SM_ORDER, 0, 4, "找不到該字");
+
+ else if(rc == 0){ /* search succeeded */
+
+ if(wrapped == 1)
+- q_status_message(SM_INFO, 0, 2, "Search wrapped to beginning");
++ q_status_message(SM_INFO, 0, 2, "從頭搜尋");
+ else if(wrapped == 2)
+ q_status_message(SM_INFO, 0, 2,
+- "Current line contains the only match");
++ "目前這行僅包含唯一符合的目標");
+
+ /* know match is on the same page */
+ if(!*warped &&
+@@ -6115,7 +6115,7 @@
+
+ dprint(7, (debugfile, "- search_book -\n"));
+
+- sprintf(prompt, "Word to search for [%s]: ", search_string);
++ sprintf(prompt, "欲搜尋的字串 [%s]:", search_string);
+ help = NO_HELP;
+ nsearch_string[0] = '\0';
+
+@@ -6127,12 +6127,12 @@
+ ekey[1].ch = ctrl('Y');
+ ekey[1].rval = 10;
+ ekey[1].name = "^Y";
+- ekey[1].label = "First Adr";
++ ekey[1].label = "第一個地址";
+
+ ekey[2].ch = ctrl('V');
+ ekey[2].rval = 11;
+ ekey[2].name = "^V";
+- ekey[2].label = "Last Adr";
++ ekey[2].label = "最後一個地址";
+
+ ekey[3].ch = -1;
+
+@@ -6149,11 +6149,11 @@
+ warp_to_beginning(); /* go to top of addrbooks */
+ if((nl=first_selectable_line(0L)) != NO_LINE){
+ *new_line = nl;
+- q_status_message(SM_INFO, 0, 2, "Searched to first entry");
++ q_status_message(SM_INFO, 0, 2, "搜尋至第一個項目");
+ return 0;
+ }
+ else{
+- q_status_message(SM_INFO, 0, 2, "No entries");
++ q_status_message(SM_INFO, 0, 2, "沒有任何項目");
+ return -1;
+ }
+ }
+@@ -6162,11 +6162,11 @@
+ warp_to_end(); /* go to bottom */
+ if((nl=first_selectable_line(0L)) != NO_LINE){
+ *new_line = nl;
+- q_status_message(SM_INFO, 0, 2, "Searched to last entry");
++ q_status_message(SM_INFO, 0, 2, "搜尋至最終項");
+ return 0;
+ }
+ else{
+- q_status_message(SM_INFO, 0, 2, "No entries");
++ q_status_message(SM_INFO, 0, 2, "沒有任何項目");
+ return -1;
+ }
+ }
diff --git a/chinese/pine4/files/patch-aq b/chinese/pine4/files/patch-aq
index d90d3d3f065c..a014d6f16518 100644
--- a/chinese/pine4/files/patch-aq
+++ b/chinese/pine4/files/patch-aq
@@ -1,57 +1,693 @@
-*** pico/display.c.bak Wed Jul 10 20:59:09 1996
---- pico/display.c Thu Jan 29 23:06:07 1998
-***************
-*** 82,88 ****
- {"^X", "Exit", KS_EXIT}, {"^J", "Justify", KS_JUSTIFY},
- {"^W", "Where is", KS_WHEREIS}, {"^V", "Next Pg", KS_NEXTPAGE},
- {"^U", NULL, KS_NONE},
-! #ifdef SPELLER
- {"^T", "To Spell", KS_SPELLCHK}
- #else
- {"^D", "Del Char", KS_NONE}
---- 82,88 ----
- {"^X", "Exit", KS_EXIT}, {"^J", "Justify", KS_JUSTIFY},
- {"^W", "Where is", KS_WHEREIS}, {"^V", "Next Pg", KS_NEXTPAGE},
- {"^U", NULL, KS_NONE},
-! #if defined(SPELLER) && !defined(__FreeBSD__)
- {"^T", "To Spell", KS_SPELLCHK}
- #else
- {"^D", "Del Char", KS_NONE}
-*** pico/ebind.h.bak Fri Mar 15 10:41:58 1996
---- pico/ebind.h Thu Jan 29 23:04:30 1998
-***************
-*** 145,151 ****
- {CTRL|'O', filewrite},
- {CTRL|'P', backline},
- {CTRL|'R', insfile},
-! #ifdef SPELLER
- {CTRL|'T', spell},
- #endif /* SPELLER */
- {CTRL|'U', yank},
---- 145,151 ----
- {CTRL|'O', filewrite},
- {CTRL|'P', backline},
- {CTRL|'R', insfile},
-! #if defined(SPELLER) && !defined(__FreeBSD__)
- {CTRL|'T', spell},
- #endif /* SPELLER */
- {CTRL|'U', yank},
-*** pico/main.c.bak Wed May 29 04:05:27 1996
---- pico/main.c Thu Jan 29 23:04:30 1998
-***************
-*** 72,78 ****
- { F9, (CTRL|'K')},
- { F10, (CTRL|'U')},
- { F11, (CTRL|'C')},
-! #ifdef SPELLER
- { F12, (CTRL|'T')}
- #else
- { F12, (CTRL|'D')}
---- 72,78 ----
- { F9, (CTRL|'K')},
- { F10, (CTRL|'U')},
- { F11, (CTRL|'C')},
-! #if defined(SPELLER) && !defined(__FreeBSD__)
- { F12, (CTRL|'T')}
- #else
- { F12, (CTRL|'D')}
+--- pine/adrbkcmd.c.orig Tue Jul 7 03:24:34 1998
++++ pine/adrbkcmd.c Wed Jul 15 17:02:32 1998
+@@ -112,23 +112,23 @@
+ static struct key abook_view_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"<","Abook",{MC_EXIT,2,{'<',','}},KS_NONE},
+- {"U","Update",{MC_EDIT,1,{'u'}},KS_NONE},
++ {"<","地址簿",{MC_EXIT,2,{'<',','}},KS_NONE},
++ {"U","更新",{MC_EDIT,1,{'u'}},KS_NONE},
+ NULL_MENU,
+- {"C","ComposeTo",{MC_COMPOSE,1,{'c'}},KS_COMPOSER},
++ {"C","編修",{MC_COMPOSE,1,{'c'}},KS_COMPOSER},
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ PRYNTTXT_MENU,
+ WHEREIS_MENU,
+- {"F", "Fwd Email", {MC_FORWARD, 1, {'f'}}, KS_FORWARD},
++ {"F", "信件轉寄", {MC_FORWARD, 1, {'f'}}, KS_FORWARD},
+ SAVE_MENU,
+
+ HELP_MENU,
+ OTHER_MENU,
+- {"V","ViewLink",{MC_VIEW_HANDLE,3,{'v',ctrl('m'),ctrl('j')}},KS_NONE},
++ {"V","檢視連結",{MC_VIEW_HANDLE,3,{'v',ctrl('m'),ctrl('j')}},KS_NONE},
+ NULL_MENU,
+- {"^B","PrevLink",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
+- {"^F","NextLink",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
++ {"^B","前一連結",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
++ {"^F","下一連結",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -144,7 +144,7 @@
+ static struct key abook_text_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"E","Exit Viewer",{MC_EXIT,1,{'e'}},KS_NONE},
++ {"E","離開",{MC_EXIT,1,{'e'}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -153,7 +153,7 @@
+ PRYNTTXT_MENU,
+ WHEREIS_MENU,
+ FWDEMAIL_MENU,
+- {"S", "Save", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
++ {"S", "存檔", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
+ INST_KEY_MENU(abook_text_km, abook_text_keys);
+
+ #define VIEW_ABOOK_NONE 0
+@@ -301,15 +301,15 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(out_store);
+ sargs.text.src = CharStar;
+- sargs.text.desc = "expanded entry";
++ sargs.text.desc = "已展開的項目";
+ sargs.text.handles = handles;
+- sargs.bar.title = "ADDRESS BOOK (View)";
++ sargs.bar.title = "地址簿 (檢視)";
+ sargs.bar.style = TextPercent;
+ sargs.proc.tool = process_abook_view_cmd;
+ sargs.proc.data.i = VIEW_ABOOK_NONE;
+ sargs.resize_exit = 1;
+ sargs.help.text = h_abook_view;
+- sargs.help.title = "HELP FOR ADDRESS BOOK VIEW";
++ sargs.help.title = "檢視地址簿的輔助說明";
+ sargs.keys.menu = &abook_view_keymenu;
+ setbitmap(sargs.keys.bitmap);
+
+@@ -405,7 +405,7 @@
+ if(adrbk_check_all_validity_now()){
+ if(resync_screen(pab, AddrBookScreen, 0)){
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Address book changed. Update cancelled. Try again.");
++ "地址簿已被更動。取消更新。請重試一遍。");
+ ps_global->mangled_screen = 1;
+ break;
+ }
+@@ -433,7 +433,7 @@
+ abe_copy = copy_ae(abe);
+ dprint(9, (debugfile,"Calling edit_entry to edit from view\n"));
+ edit_entry(pab->address_book, abe_copy, entry,
+- abe->tag, 0, &warped, "update");
++ abe->tag, 0, &warped, "更新");
+ /*
+ * The ABOOK_EDITED case doesn't mean that we necessarily
+ * changed something, just that we might have but we know
+@@ -478,7 +478,7 @@
+ h_ab_text_or_vcard, RB_NORM);
+ switch(i){
+ case 'x':
+- cancel_warning(NO_DING, "forward");
++ cancel_warning(NO_DING, "轉寄");
+ break;
+
+ case 't':
+@@ -704,8 +704,8 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = CharStar;
+- sargs.text.desc = "expanded entry";
+- sargs.bar.title = "ADDRESS BOOK (Rich View)";
++ sargs.text.desc = "已展開的項目";
++ sargs.bar.title = "地址簿 (完整檢視)";
+ sargs.bar.style = TextPercent;
+ sargs.keys.menu = &abook_text_km;
+ setbitmap(sargs.keys.bitmap);
+@@ -772,8 +772,8 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = src;
+- sargs.text.desc = "expanded entry";
+- sargs.bar.title = "MESSAGE TEXT";
++ sargs.text.desc = "已展開的項目";
++ sargs.bar.title = "訊息文字";
+ sargs.bar.style = TextPercent;
+ sargs.keys.menu = &abook_text_km;
+ setbitmap(sargs.keys.bitmap);
+@@ -796,19 +796,19 @@
+ */
+ static struct headerentry headents_for_edit[]={
+ {"Nickname : ", "Nickname", h_composer_abook_nick, 12, 0, NULL,
+- verify_nick, NULL, NULL, addr_book_nick_for_edit, "To AddrBk",
++ verify_nick, NULL, NULL, addr_book_nick_for_edit, "地址簿",
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, KS_NONE},
+ {"Fullname : ", "Fullname", h_composer_abook_full, 12, 0, NULL,
+- NULL, NULL, NULL, view_message_for_pico, "To Message",
++ NULL, NULL, NULL, view_message_for_pico, "資料匣",
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
+ {"Fcc : ", "FileCopy", h_composer_abook_fcc, 12, 0, NULL,
+- NULL, NULL, NULL, folders_for_fcc, "To Fldrs",
++ NULL, NULL, NULL, folders_for_fcc, "資料匣",
+ 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, KS_NONE},
+ {"Comment : ", "Comment", h_composer_abook_comment, 12, 0, NULL,
+- NULL, NULL, NULL, view_message_for_pico, "To Message",
++ NULL, NULL, NULL, view_message_for_pico, "資料匣",
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
+ {"Addresses : ", "Addresses", h_composer_abook_addrs, 12, 0, NULL,
+- verify_addr, NULL, NULL, addr_book_change_list, "To AddrBk",
++ verify_addr, NULL, NULL, addr_book_change_list, "地址簿",
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
+ {NULL, NULL, NO_HELP, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE}
+@@ -923,7 +923,7 @@
+ pbuf.canceltest = warped ? pico_cancel_for_adrbk_edit
+ : pico_cancel_for_adrbk_take;
+ pbuf.expander = expand_addrs_for_pico;
+- pbuf.ctrlr_label = "RichView";
++ pbuf.ctrlr_label = "完整表頭";//"RichView";
+ pbuf.resize = resize_for_pico;
+ pbuf.winch_cleanup = winch_cleanup;
+ pbuf.suspend = do_suspend;
+@@ -938,7 +938,7 @@
+ pbuf.browse_help = h_composer_browse;
+ pbuf.attach_help = h_composer_ctrl_j;
+ pbuf.composer_help = h_composer;
+- sprintf(titlebar, "ADDRESS BOOK (%c%s)",
++ sprintf(titlebar, "地址簿 (%c%s)",
+ readonly ? 'V' : islower((unsigned char)(*cmd))
+ ? toupper((unsigned char)*cmd)
+ : *cmd,
+@@ -1523,12 +1523,12 @@
+ ps_global->redrawer = redraw_pico;
+ fix_windsize(ps_global);
+
+- switch(want_to("Exit and save changes ", 'y', 0, NO_HELP, WT_NORM)){
++ switch(want_to("存檔並離開 ", 'y', 0, NO_HELP, WT_NORM)){
+ case 'y':
+ break;
+
+ case 'n':
+- rstr = "Use ^C to abandon changes you've made";
++ rstr = "以 ^C 放棄曾做過的改變";
+ break;
+ }
+
+@@ -1552,8 +1552,8 @@
+ char *rstr = NULL;
+ void (*redraw)() = ps_global->redrawer;
+
+- strcat(strcat(strcpy(prompt, "Cancel "), word),
+- " (answering \"Yes\" will abandon any changes made) ");
++ strcat(strcat(strcpy(prompt, "取消"), word),
++ " (回答 \"是\" 將放棄曾作過的改變) ");
+ ps_global->redrawer = redraw_pico;
+ fix_windsize(ps_global);
+
+@@ -1576,7 +1576,7 @@
+ pico_cancel_for_adrbk_take(redraw_pico)
+ void (*redraw_pico)();
+ {
+- return(pico_cancelexit_for_adrbk("take", redraw_pico));
++ return(pico_cancelexit_for_adrbk("擷取", redraw_pico));
+ }
+
+
+@@ -1584,7 +1584,7 @@
+ pico_cancel_for_adrbk_edit(redraw_pico)
+ void (*redraw_pico)();
+ {
+- return(pico_cancelexit_for_adrbk("changes", redraw_pico));
++ return(pico_cancelexit_for_adrbk("修改", redraw_pico));
+ }
+
+
+@@ -1701,16 +1701,16 @@
+
+ if(ps_global->readonly_pinerc){
+ q_status_message1(SM_ORDER, 0, 3,
+- "%s cancelled: config file not changeable",
+- edit ? "Change" : "Add");
++ "取消%s:設定檔無法被修改",
++ edit ? "修改" : "新增");
+ return -1;
+ }
+
+ if(global && vars[V_GLOB_ADDRBOOK].is_fixed ||
+ !global && vars[V_ADDRESSBOOK].is_fixed){
+ q_status_message1(SM_ORDER, 0, 3,
+- "Cancelled: Sys. Mgmt. does not allow changing %saddress books",
+- global ? "global " : "");
++ "動作取消:系統管理員不允許\改變%s地址簿",
++ global ? "整體的" : "");
+
+ return -1;
+ }
+@@ -1759,7 +1759,7 @@
+ pbuf.browse_help = h_composer_browse;
+ pbuf.attach_help = h_composer_ctrl_j;
+ pbuf.composer_help = h_composer;
+- sprintf(titlebar, "%s ADDRESS BOOK", edit ? "CHANGE" : "ADD");
++ sprintf(titlebar, "%s地址簿", edit ? "修改" : "新增");
+ pbuf.pine_anchor = set_titlebar(titlebar,
+ ps_global->mail_stream,
+ ps_global->context_current,
+@@ -1828,8 +1828,8 @@
+ if(editor_result & COMP_CANCEL){
+ ret = -1;
+ q_status_message1(SM_ORDER, 0, 3,
+- "Address book %s is cancelled",
+- edit ? "change" : "add");
++ "取消地址簿的%s",
++ edit ? "修改" : "新增");
+ }
+ else if(editor_result & COMP_EXIT){
+ if(!strcmp(server, def_serv ? def_serv : "") &&
+@@ -1837,8 +1837,8 @@
+ !strcmp(nickname, def_nick ? def_nick : "")){
+ ret = -1;
+ q_status_message1(SM_ORDER, 0, 3,
+- "No change: Address book %s is cancelled",
+- edit ? "change" : "add");
++ "沒有改變:取消地址簿的%s",
++ edit ? "修改" : "新增");
+ }
+ else{
+
+@@ -1898,8 +1898,8 @@
+
+ if(*tmp == '\0'){
+ q_status_message1(SM_ORDER, 0, 3,
+- "Address book %s is cancelled",
+- edit ? "change" : "add");
++ "取消地址簿的%s",
++ edit ? "修改" : "新增");
+ ret = -1;
+ goto get_out;
+ }
+@@ -1924,8 +1924,8 @@
+ if(set_variable_list(global ? V_GLOB_ADDRBOOK : V_ADDRESSBOOK,
+ new_list, TRUE)){
+ q_status_message1(SM_ORDER, 0, 3,
+- "%s cancelled: couldn't save pine configuration file",
+- edit ? "Change" : "Add");
++ "取消%s:無法存入 pine 的設定檔",
++ edit ? "修改" : "新增");
+
+ set_current_val(&vars[global ? V_GLOB_ADDRBOOK : V_ADDRESSBOOK],
+ TRUE, FALSE);
+@@ -2099,7 +2099,7 @@
+
+ if(ps_global->readonly_pinerc){
+ if(err)
+- *err = "Delete cancelled: config file not changeable";
++ *err = "取消刪除:設定檔無法被改變";
+
+ return -1;
+ }
+@@ -2116,10 +2116,10 @@
+ if(err){
+ if(pab->type & GLOBAL)
+ *err =
+- "Cancelled: Sys. Mgmt. does not allow changing global address book config";
++ "動作取消:系統管理員不允許\改變整體的地址簿設定";
+ else
+ *err =
+- "Cancelled: Sys. Mgmt. does not allow changing address book config";
++ "動作取消:系統管理員不允許\改變地址簿設定";
+ }
+
+ return -1;
+@@ -2172,8 +2172,8 @@
+
+ if(cnt > 1){
+ static ESCKEY_S opts[] = {
+- {'i', 'i', "I", "Ignore All"},
+- {'r', 'r', "R", "Remove One"},
++ {'i', 'i', "I", "忽略全部"},
++ {'r', 'r', "R", "移除一個"},
+ {-1, 0, NULL, NULL}};
+
+ sprintf(tmp,
+@@ -2191,7 +2191,7 @@
+
+ case 'x':
+ if(err)
+- *err = "Delete cancelled";
++ *err = "取消刪除";
+
+ return -1;
+ }
+@@ -2202,7 +2202,7 @@
+ case 'n':
+ case 'x':
+ if(err)
+- *err = "Delete cancelled";
++ *err = "取消刪除";
+
+ return -1;
+
+@@ -2247,7 +2247,7 @@
+ case 'x': /* Cancel */
+ default:
+ if(err)
+- *err = "Delete cancelled";
++ *err = "取消刪除";
+
+ return -1;
+ }
+@@ -2267,7 +2267,7 @@
+ case 'x':
+ default:
+ if(err)
+- *err = "Delete cancelled";
++ *err = "取消刪除";
+
+ return -1;
+
+@@ -2328,7 +2328,7 @@
+ case 'n':
+ default:
+ if(err)
+- *err = "Delete cancelled";
++ *err = "取消刪除";
+
+ return -1;
+ }
+@@ -2467,7 +2467,7 @@
+ /* this also frees old variable contents for us */
+ if(set_variable_list(varnum, new_list, TRUE)){
+ if(err)
+- *err = "Delete cancelled: couldn't save pine configuration file";
++ *err = "取消刪除:無法存入 pine 的設定檔";
+
+ set_current_val(&vars[varnum], TRUE, FALSE);
+ free_list_array(&new_list);
+@@ -2534,7 +2534,7 @@
+
+ if(ps_global->readonly_pinerc){
+ if(msg)
+- *msg = cpystr("Shuffle cancelled: config file not changeable");
++ *msg = cpystr("取消重整:設定檔無法被改變");
+
+ return -1;
+ }
+@@ -2544,12 +2544,12 @@
+ opts[i].ch = 'u';
+ opts[i].rval = 'u';
+ opts[i].name = "U";
+- opts[i++].label = "Up";
++ opts[i++].label = "上移";
+
+ opts[i].ch = 'd';
+ opts[i].rval = 'd';
+ opts[i].name = "D";
+- opts[i++].label = "Down";
++ opts[i++].label = "下移";
+
+ opts[i].ch = -1;
+ deefault = 'u';
+@@ -2557,7 +2557,7 @@
+ if(pab->type & GLOBAL){
+ if(vars[V_GLOB_ADDRBOOK].is_fixed){
+ if(msg)
+- *msg = cpystr("Cancelled: Sys. Mgmt. does not allow changing global address book config");
++ *msg = cpystr("動作取消:系統管理員不允許\改變整體的地址簿設定");
+
+ return -1;
+ }
+@@ -2577,7 +2577,7 @@
+ else{
+ if(vars[V_ADDRESSBOOK].is_fixed){
+ if(msg)
+- *msg = cpystr("Cancelled: Sys. Mgmt. does not allow changing address book config");
++ *msg = cpystr("動作取消:系統管理員不允許\改變地址簿設定");
+
+ return -1;
+ }
+@@ -2616,7 +2616,7 @@
+
+ if(rv == 'x'){
+ if(msg)
+- *msg = cpystr("Shuffle cancelled");
++ *msg = cpystr("取消重整");
+
+ return -1;
+ }
+@@ -2659,7 +2659,7 @@
+ enum {NotSet, Pers, Glob, Empty} type1, type2;
+ int i, j;
+ struct variable *vars = ps_global->vars;
+- char *cancel_msg = "Shuffle cancelled: couldn't save configuration file";
++ char *cancel_msg = "取消重整:無法存入設定檔";
+
+ dprint(5, (debugfile, "- do_the_shuffle(%d, %d) -\n", anum1, anum2));
+
+@@ -2673,7 +2673,7 @@
+ if(type1 == Empty){
+ if(msg)
+ *msg =
+- cpystr("Shuffle cancelled: highlight entry you wish to shuffle");
++ cpystr("取消重整:請先標示欲重整的項目");
+
+ return -1;
+ }
+@@ -2690,14 +2690,14 @@
+
+ if((type1 == Pers || type2 == Pers) && vars[V_ADDRESSBOOK].is_fixed){
+ if(msg)
+- *msg = cpystr("Cancelled: Sys. Mgmt. does not allow changing address book configuration");
++ *msg = cpystr("動作取消:系統管理員不允許\改變地址簿設定");
+
+ return -1;
+ }
+
+ if((type1 == Glob || type2 == Glob) && vars[V_GLOB_ADDRBOOK].is_fixed){
+ if(msg)
+- *msg = cpystr("Cancelled: Sys. Mgmt. does not allow changing global address book config");
++ *msg = cpystr("動作取消:系統管理員不允許\改變整體的地址簿設定");
+
+ return -1;
+ }
+@@ -3167,7 +3167,7 @@
+ AdrBk_Entry *abe;
+ VCARD_INFO_S *vinfo;
+ static ESCKEY_S ab_export_opts[] = {
+- {ctrl('T'), 10, "^T", "To Files"},
++ {ctrl('T'), 10, "^T", "檔案列表"},
+ {-1, 0, NULL, NULL},
+ {-1, 0, NULL, NULL}};
+ static ESCKEY_S vcard_or_addresses[] = {
+@@ -3190,7 +3190,7 @@
+
+ switch(i){
+ case 'x':
+- cancel_warning(NO_DING, "export");
++ cancel_warning(NO_DING, "匯出");
+ return(ret);
+
+ case 'a':
+@@ -3219,7 +3219,7 @@
+ ab_export_opts[++r].ch = ctrl('I');
+ ab_export_opts[r].rval = 11;
+ ab_export_opts[r].name = "TAB";
+- ab_export_opts[r].label = "Complete";
++ ab_export_opts[r].label = "完成";
+ }
+
+ ab_export_opts[++r].ch = -1;
+@@ -3232,7 +3232,7 @@
+ if(r < 0){
+ switch(r){
+ case -1:
+- cancel_warning(NO_DING, "export");
++ cancel_warning(NO_DING, "匯出");
+ break;
+
+ case -2:
+@@ -3616,7 +3616,7 @@
+ switch(want_to("Expand nicknames", 'y', 'x', h_ab_forward,WT_NORM)){
+ case 'x':
+ gf_clear_so_writec((STORE_S *) pb->contents.text.data);
+- cancel_warning(NO_DING, "forward");
++ cancel_warning(NO_DING, "轉寄");
+ goto bomb;
+
+ case 'y':
+@@ -3700,7 +3700,7 @@
+
+ gf_clear_so_writec((STORE_S *) pb->contents.text.data);
+
+- pine_send(outgoing, &body, "FORWARDING ADDRESS BOOK ENTRY", NULL,
++ pine_send(outgoing, &body, "轉寄地址簿項目", NULL,
+ NULL, NULL, NULL, NULL, 0);
+
+ ps->mangled_screen = 1;
+@@ -4165,8 +4165,8 @@
+ char tmp[200];
+ ACTION_LIST_S *action_list = NULL, *al;
+ static ESCKEY_S save_or_export[] = {
+- {'s', 's', "S", "Save"},
+- {'e', 'e', "E", "Export"},
++ {'s', 's', "S", "存檔"},
++ {'e', 'e', "E", "匯出"},
+ {-1, 0, NULL, NULL}};
+
+ sprintf(tmp, "Save%s to address book or Export to filesystem ? ",
+@@ -4177,7 +4177,7 @@
+ h_ab_save_exp, RB_NORM);
+ switch(i){
+ case 'x':
+- cancel_warning(NO_DING, "save");
++ cancel_warning(NO_DING, "存檔");
+ return(0);
+
+ case 'e':
+@@ -4356,7 +4356,7 @@
+ if(action_list)
+ fs_give((void **)&action_list);
+
+- cancel_warning(NO_DING, "save");
++ cancel_warning(NO_DING, "存檔");
+ return(ret);
+ }
+
+@@ -4545,7 +4545,7 @@
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+ "Save only partially completed");
+ else
+- cancel_warning(NO_DING, "save");
++ cancel_warning(NO_DING, "存檔");
+ }
+ else if (how_many_to_copy + how_many_no_action -
+ (skip_dups ? how_many_dups : 0) > 0){
+@@ -4621,15 +4621,15 @@
+
+ if(!agg && as.opened){
+ static ESCKEY_S prt[] = {
+- {'a', 'a', "A", "AddressBook"},
+- {'e', 'e', "E", "Entry"},
++ {'a', 'a', "A", "地址簿"},
++ {'e', 'e', "E", "項目"},
+ {-1, 0, NULL, NULL}};
+
+ prompt = "Print Address Book or just this Entry? ";
+ switch(radio_buttons(prompt, -FOOTER_ROWS(ps_global), prt, 'a', 'x',
+ NO_HELP, RB_NORM)){
+ case 'x' :
+- cancel_warning(NO_DING, "print");
++ cancel_warning(NO_DING, "列印");
+ ps_global->mangled_footer = 1;
+ return 0;
+
+@@ -4700,7 +4700,7 @@
+ switch(want_to("Expand nicknames", 'y', 'x', h_ab_forward,
+ WT_NORM)){
+ case 'x':
+- cancel_warning(NO_DING, "print");
++ cancel_warning(NO_DING, "列印");
+ ps_global->mangled_footer = 1;
+ return 0;
+
+@@ -4924,7 +4924,7 @@
+ lineno = 0L;
+
+ if(as.opened)
+- print_text1(" ADDRESS BOOK %s\n\n",
++ print_text1(" 地址簿 %s\n\n",
+ as.adrbks[as.cur].nickname);
+
+
+@@ -4979,7 +4979,7 @@
+ dprint(2, (debugfile, "- ab_delete -\n"));
+
+ if(agg){
+- sprintf(prompt, "Really delete %d selected entries", as.selections);
++ sprintf(prompt, "確定刪除 %d 選取的項目", as.selections);
+ ch = want_to(prompt, 'n', 'n', NO_HELP, WT_NORM);
+ if(ch == 'y'){
+ adrbk_cntr_t newelnum, flushelnum = NO_NEXT;
+@@ -5144,7 +5144,7 @@
+ }
+ }
+ else
+- cmd_cancelled("Apply command");
++ cmd_cancelled("套用命令");
+ }
+
+ return(ret);
+@@ -5192,7 +5192,7 @@
+ ? (char *)rfc1522_decode((unsigned char *)tmp_20k_buf,
+ abe->fullname, NULL)
+ : abe->nickname ? abe->nickname : "";
+- cmd = "Really delete \"%.50s\"";
++ cmd = "確定刪除 \"%.50s\"";
+ break;
+
+ case ListHead:
+@@ -5200,13 +5200,13 @@
+ ? (char *)rfc1522_decode((unsigned char *)tmp_20k_buf,
+ abe->fullname, NULL)
+ : abe->nickname ? abe->nickname : "";
+- cmd = "Really delete ENTIRE list \"%.50s\"";
++ cmd = "確定刪除「整個」列表 \"%.50s\"";
+ break;
+
+ case ListEnt:
+ dname = (char *)rfc1522_decode((unsigned char *)tmp_20k_buf,
+ listmem_from_dl(abook, dl), NULL);
+- cmd = "Really delete \"%.100s\" from list";
++ cmd = "確定自列表中刪除 \"%.100s\"";
+ break;
+ }
+
+@@ -5305,7 +5305,7 @@
+ return 0;
+ }
+ else{
+- q_status_message(SM_INFO, 0, 2, "Entry not deleted");
++ q_status_message(SM_INFO, 0, 2, "該項目未被刪除");
+ return 0;
+ }
+ }
+@@ -5441,7 +5441,7 @@
+ if(r == 1 || r != 10 && fbuf[0] == '\0'){
+ ps->mangled_footer = 1;
+ if(error)
+- *error = cpystr("Cancelled");
++ *error = cpystr("取消");
+
+ return(ret);
+ }
+@@ -5480,7 +5480,7 @@
+ pbuf.browse_help = h_composer_browse;
+ pbuf.attach_help = h_composer_ctrl_j;
+ pbuf.composer_help = h_composer;
+- pbuf.pine_anchor = set_titlebar("SEARCH DIRECTORY SERVER",
++ pbuf.pine_anchor = set_titlebar("搜尋地址伺服器",
+ ps_global->mail_stream,
+ ps_global->context_current,
+ ps_global->cur_folder,
+@@ -5728,13 +5728,13 @@
+ static struct key ldap_view_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"<","Results Index",{MC_EXIT,2,{'<',','}},KS_NONE},
++ {"<","結果索引",{MC_EXIT,2,{'<',','}},KS_NONE},
+ PRYNTTXT_MENU,
+ NULL_MENU,
+ NULL_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"C", "ComposeTo", {MC_COMPOSE,1,{'c'}}, KS_COMPOSER},
++ {"C", "編修", {MC_COMPOSE,1,{'c'}}, KS_COMPOSER},
+ FWDEMAIL_MENU,
+ SAVE_MENU,
+ WHEREIS_MENU};
+@@ -5763,12 +5763,12 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(srcstore);
+ sargs.text.src = srctype;
+- sargs.text.desc = "expanded entry";
+- sargs.bar.title = "DIRECTORY ENTRY";
++ sargs.text.desc = "已展開的項目";
++ sargs.bar.title = "地址項目";
+ sargs.proc.tool = process_ldap_cmd;
+ sargs.proc.data.p = (void *) winning_e;
+ sargs.help.text = h_ldap_view;
+- sargs.help.title = "HELP FOR DIRECTORY VIEW";
++ sargs.help.title = "地址項目的輔助說明";
+ sargs.keys.menu = &ldap_view_keymenu;
+ setbitmap(sargs.keys.bitmap);
+
+@@ -6117,7 +6117,7 @@
+ struct headerentry *he;
+ void (*redraw_pico)();
+ {
+- return("Cancelled");
++ return("取消");
+ }
+
+
diff --git a/chinese/pine4/files/patch-ar b/chinese/pine4/files/patch-ar
index b3babb7c1407..d70d02915af1 100644
--- a/chinese/pine4/files/patch-ar
+++ b/chinese/pine4/files/patch-ar
@@ -1,8 +1,1260 @@
---- pico/estruct.h.orig Sat Dec 28 02:40:35 1996
-+++ pico/estruct.h Sat Dec 28 02:41:45 1996
-@@ -114,6 +114,6 @@
- #define LOBIT_CHAR(C) ((C) > 0x1f && (C) < 0x7f)
- #define HIBIT_CHAR(C) ((C) > 0x7f && (C) <= 0xff)
- #define HIBIT_OK(C) (!(gmode & MDHBTIGN))
--#define VALID_KEY(C) (LOBIT_CHAR(C) || (HIBIT_OK(C) && HIBIT_CHAR(C)))
-+#define VALID_KEY(ch) (((ch) & 0x80) ? 1 : LOBIT_CHAR(ch))
+--- pine/folder.c.orig Tue Jul 7 07:13:25 1998
++++ pine/folder.c Wed Jul 15 17:02:32 1998
+@@ -63,13 +63,13 @@
+ ((X)->dir->status&CNTXT_PARTFIND) == 0)
+ #define FLDR_NAME(X) ((X) ? ((X)->nickname ? (X)->nickname : (X)->name) :"")
+ #define SUBSCRIBE_PMT \
+- "Enter newsgroup name (or partial name to get a list): "
+-#define LISTMODE_GRIPE "Use \"X\" to mark selections in list mode"
+-#define SEL_ALTER_PMT "ALTER folder selection : "
+-#define SEL_TEXT_PMT "Select by folder Name or Contents ? "
+-#define SEL_PROP_PMT "Select by which folder property ? "
++ "輸入新聞組群名稱(或部份名稱以取得列表):"
++#define LISTMODE_GRIPE "以 \"X\" 來在列表模式中標示選擇"
++#define SEL_ALTER_PMT "更改資料匣的選擇:"
++#define SEL_TEXT_PMT "根據資料匣名稱或內容選擇?"
++#define SEL_PROP_PMT "根據哪一個資料匣性質?"
+ #define DIR_FOLD_PMT \
+- "Folder by the same name *MAY* get deleted as well. Continue"
++ "同名稱的資料匣 *可能* 被刪除。繼續"
+
+ #define mail_list(S, R, N) mail_list_internal(S, R, N)
+
+@@ -270,18 +270,18 @@
+ /*
+ * Various screen keymenu/command binding s.
+ */
+-#define PREVC_MENU {"P", "PrevCltn", {MC_PREVITEM, 1, {'p'}}, KS_NONE}
+-#define NEXTC_MENU {"N", "NextCltn", {MC_NEXTITEM, 2, {'n',TAB}}, KS_NONE}
+-#define DELC_MENU {"D", "Del Cltn", {MC_DELETE,2,{'d',KEY_DEL}}, KS_NONE}
+-#define PREVF_MENU {"P", "PrevFldr", {MC_PREVITEM, 1, {'p'}}, KS_NONE}
+-#define NEXTF_MENU {"N", "NextFldr", {MC_NEXTITEM, 2, {'n',TAB}}, KS_NONE}
+-#define CIND_MENU {"I", "CurIndex", {MC_INDEX,1,{'i'}}, KS_FLDRINDEX}
++#define PREVC_MENU {"P", "前一總集", {MC_PREVITEM, 1, {'p'}}, KS_NONE}
++#define NEXTC_MENU {"N", "次一總集", {MC_NEXTITEM, 2, {'n',TAB}}, KS_NONE}
++#define DELC_MENU {"D", "刪除總集", {MC_DELETE,2,{'d',KEY_DEL}}, KS_NONE}
++#define PREVF_MENU {"P", "前一資料匣", {MC_PREVITEM, 1, {'p'}}, KS_NONE}
++#define NEXTF_MENU {"N", "次一資料匣", {MC_NEXTITEM, 2, {'n',TAB}}, KS_NONE}
++#define CIND_MENU {"I", "索引", {MC_INDEX,1,{'i'}}, KS_FLDRINDEX}
+
+ static struct key context_mgr_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"<", "Main Menu", {MC_MAIN,3,{'m','<',','}}, KS_EXITMODE},
+- {">", "[View Cltn]",
++ {"<", "主選單", {MC_MAIN,3,{'m','<',','}}, KS_EXITMODE},
++ {">", "[檢視總集]",
+ {MC_CHOICE,5,{'v','>','.',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVC_MENU,
+ NEXTC_MENU,
+@@ -313,15 +313,15 @@
+ static struct key context_cfg_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"E", "Exit Setup", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+- {"C", "[Change]", {MC_EDIT,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"E", "離開設定", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"C", "[修改]", {MC_EDIT,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVC_MENU,
+ NEXTC_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"A", "Add Cltn", {MC_ADD,1,{'a'}}, KS_NONE},
++ {"A", "新增總集", {MC_ADD,1,{'a'}}, KS_NONE},
+ DELC_MENU,
+- {"$", "Shuffle", {MC_SHUFFLE,1,{'$'}},KS_NONE},
++ {"$", "重整", {MC_SHUFFLE,1,{'$'}},KS_NONE},
+ WHEREIS_MENU,
+
+ HELP_MENU,
+@@ -340,9 +340,9 @@
+
+ static struct key context_select_keys[] =
+ {HELP_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ NULL_MENU,
+- {">", "[View Cltn]",
++ {">", "[檢視總集]",
+ {MC_CHOICE, 5, {'v','>','.',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVC_MENU,
+ NEXTC_MENU,
+@@ -356,9 +356,9 @@
+
+ static struct key context_fcc_keys[] =
+ {HELP_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ NULL_MENU,
+- {">", "[View Cltn]",
++ {">", "[檢視總集]",
+ {MC_CHOICE, 5, {'v','>','.',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVC_MENU,
+ NEXTC_MENU,
+@@ -373,16 +373,16 @@
+ static struct key folder_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"<", NULL, {MC_EXIT,3,{' ','<',','}}, KS_NONE},
+- {">", "[View Fldr]",
++ {"M", NULL, {MC_EXIT,3,{' ','<',','}}, KS_NONE},
++ {">", "[檢視檔案匣]",
+ {MC_CHOICE,5,{'v','>','.',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVF_MENU,
+ NEXTF_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"A","Add",{MC_ADDFLDR,1,{'a'}},KS_NONE},
++ {"A","新增",{MC_ADDFLDR,1,{'a'}},KS_NONE},
+ DELETE_MENU,
+- {"R","Rename",{MC_RENAMEFLDR,1,{'r'}}, KS_NONE},
++ {"R","更名",{MC_RENAMEFLDR,1,{'r'}}, KS_NONE},
+ WHEREIS_MENU,
+
+ HELP_MENU,
+@@ -394,9 +394,9 @@
+ CIND_MENU,
+ COMPOSE_MENU,
+ PRYNTTXT_MENU,
+- {"Z", "ZoomMode", {MC_ZOOM,1,{'z'}}, KS_NONE},
+- {";","Select",{MC_SELECT,1,{';'}},KS_SELECT},
+- {":","SelectCur",{MC_SELCUR,1,{':'}},KS_SELECT}};
++ {"Z", "縮放模式", {MC_ZOOM,1,{'z'}}, KS_NONE},
++ {";","選擇",{MC_SELECT,1,{';'}},KS_SELECT},
++ {":","選擇目前的",{MC_SELCUR,1,{':'}},KS_SELECT}};
+ INST_KEY_MENU(folder_km, folder_keys);
+ #define KM_COL_KEY 2
+ #define KM_SEL_KEY 3
+@@ -408,9 +408,9 @@
+
+ static struct key folder_sel_keys[] =
+ {HELP_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+- {"<", "Collections", {MC_COLLECTIONS,2,{'<',','}}, KS_NONE},
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}},KS_NONE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"<", "總集", {MC_COLLECTIONS,2,{'<',','}}, KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}},KS_NONE},
+ PREVF_MENU,
+ NEXTF_MENU,
+ PREVPAGE_MENU,
+@@ -424,9 +424,9 @@
+
+ static struct key folder_sub_sel_keys[] =
+ {HELP_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ NULL_MENU,
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}},KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}},KS_NONE},
+ PREVF_MENU,
+ NEXTF_MENU,
+ PREVPAGE_MENU,
+@@ -440,9 +440,9 @@
+
+ static struct key folder_fcc_keys[] =
+ {HELP_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+- {"<", "Collections", {MC_COLLECTIONS,2,{'<',','}}, KS_NONE},
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"<", "總集", {MC_COLLECTIONS,2,{'<',','}}, KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}},
+ KS_NONE},
+ PREVF_MENU,
+ NEXTF_MENU,
+@@ -458,9 +458,9 @@
+
+ static struct key folder_sub_keys[] =
+ {HELP_MENU,
+- {"S", "Subscribe", {MC_CHOICE,1,{'s'}}, KS_NONE},
+- {"E", "ExitSubscb", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+- {NULL, "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"S", "訂閱\", {MC_CHOICE,1,{'s'}}, KS_NONE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {NULL, "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVF_MENU,
+ NEXTF_MENU,
+ PREVPAGE_MENU,
+@@ -477,8 +477,8 @@
+ static struct key folder_post_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+- {"S", "[Select]", {MC_CHOICE, 3, {'s',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"S", "[選擇]", {MC_CHOICE, 3, {'s',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREVF_MENU,
+ NEXTF_MENU,
+ PREVPAGE_MENU,
+@@ -573,12 +573,12 @@
+ mailcap_free(); /* free resources we won't be using for a while */
+
+ memset(&css, 0, sizeof(CONT_SCR_S));
+- css.title = "SETUP COLLECTION LIST";
++ css.title = "設定總集列表";
+ css.print_string = "contexts ";
+ css.start = ps->context_current;
+ css.contexts = &ps_global->context_list;
+ css.help.text = h_collection_maint;
+- css.help.title = "HELP FOR SETUP COLLECTION";
++ css.help.title = "設定總集的輔助說明";
+ css.keymenu = &c_cfg_km;
+ css.edit = 1;
+
+@@ -867,7 +867,7 @@
+ /* leave (*new_dir)->ref == NULL */
+ }
+
+- sprintf(tmp_20k_buf, "List of folders matching \"%s*\"", folder);
++ sprintf(tmp_20k_buf, "符合 \"%s*\" 的資料匣列表", folder);
+ (*new_dir)->desc = cpystr(tmp_20k_buf);
+ }
+
+@@ -966,12 +966,12 @@
+ CONT_SCR_S css;
+
+ memset(&css, 0, sizeof(CONT_SCR_S));
+- css.title = "COLLECTION LIST";
++ css.title = "總集列表";
+ css.print_string = "contexts ";
+ css.start = start;
+ css.contexts = &ps_global->context_list;
+ css.help.text = h_collection_screen;
+- css.help.title = "HELP FOR COLLECTION LIST";
++ css.help.title = "總集列表的輔助說明";
+ css.keymenu = km;
+ css.edit = edit_config;
+
+@@ -1042,7 +1042,7 @@
+ pbuf.browse_help = h_composer_browse;
+ pbuf.attach_help = h_composer_ctrl_j;
+ pbuf.composer_help = h_composer;
+- sprintf(tmp, "FOLDER COLLECTION %s", func);
++ sprintf(tmp, "資料匣總集 %s", func);
+ pbuf.pine_anchor = set_titlebar(tmp, ps_global->mail_stream,
+ ps_global->context_current,
+ ps_global->cur_folder,ps_global->msgmap,
+@@ -1278,10 +1278,10 @@
+ else
+ exists = (i & FEX_ISDIR);
+
+- sprintf(prompt, "Exit%s" ,
++ sprintf(prompt, "離開%s" ,
+ exists
+- ? " and save changes"
+- : ", saving changes and creating Path");
++ ? " 並存檔"
++ : ",存檔並建立路徑");
+ if(want_to(prompt, 'y', 0, NO_HELP, WT_NORM) == 'y'){
+ if(!exists && !mail_create(NULL, tmp)){
+ flush_status_messages(1); /* mail_create gripes */
+@@ -1313,7 +1313,7 @@
+ char *rstr = NULL;
+ void (*redraw)() = ps_global->redrawer;
+ #define CCA_PROMPT \
+- "Cancel Add (answering \"Yes\" will abandon any changes made) "
++ "取消新增 (回答 \"Yes\" 將放棄先前做過的任何改變) "
+
+ ps_global->redrawer = redraw_pico;
+ fix_windsize(ps_global);
+@@ -1430,7 +1430,7 @@
+ /*BUG: test writing with NNTP to misc.test via mark's code. reasonable err msg?*/
+ if(NEWS_TEST(fs->context)) {
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't save messages to bulletin boards or news groups!");
++ "無法將訊息存至電子佈告欄或新聞組群上!");
+ return(0);
+ }
+ #endif
+@@ -1445,7 +1445,7 @@
+ FSTATE_S *fs;
+ {
+ if(!strncmp(f->prefix, "SUB", 3)){
+- q_status_message1(SM_ORDER, 0, 4, "Already subscribed to \"%s\"",
++ q_status_message1(SM_ORDER, 0, 4, "已訂閱\至 \"%s\"",
+ FLDR_NAME(f));
+ return(0);
+ }
+@@ -1458,7 +1458,7 @@
+ fl_hdr_gen(ps)
+ struct pine *ps;
+ {
+- set_titlebar("FOLDER LIST", ps->mail_stream, ps->context_current,
++ set_titlebar("信件匣列表", ps->mail_stream, ps->context_current,
+ ps->cur_folder, ps->msgmap, 1, FolderName, 0, 0);
+ }
+
+@@ -1573,7 +1573,7 @@
+ {
+ int ch, cmd, mangled_footer, mangled_header,
+ n, rc, cur_row, cur_col, km_size, was_dir = -1,
+- km_popped = 0, listmode = 0, done = 0;
++ km_popped = 0, listmode = 0, done = 0, exit_to_main = 0;
+ unsigned short new_col;
+ FOLDER_S *cur_f = NULL;
+ STRINGLIST *sl = NULL;
+@@ -1676,7 +1676,7 @@
+ }
+ else{
+ clrbitn(KM_MAIN_KEY, bitmap);
+- km.keys[KM_COL_KEY].label = "Main Menu";
++ km.keys[KM_COL_KEY].label = "主選單";
+ km.keys[KM_COL_KEY].bind.cmd = MC_MAIN;
+ km.keys[KM_COL_KEY].bind.ch[0] = 'm';
+ }
+@@ -1696,14 +1696,14 @@
+ if(listmode){
+ clrbitn(SB_LIST_KEY, bitmap);
+ km.keys[SB_SEL_KEY].name = "X";
+- km.keys[SB_SEL_KEY].label = "[Set/Unset]";
++ km.keys[SB_SEL_KEY].label = "[設定/取消設定]";
+ km.keys[SB_SEL_KEY].bind.cmd = MC_SELCUR;
+ km.keys[SB_SEL_KEY].bind.ch[0] = 'x';
+ }
+ else{
+ clrbitn(SB_SUB_KEY, bitmap);
+ km.keys[SB_SEL_KEY].name = "S";
+- km.keys[SB_SEL_KEY].label = "[Subscribe]";
++ km.keys[SB_SEL_KEY].label = "[訂閱\]";
+ km.keys[SB_SEL_KEY].bind.cmd = MC_CHOICE;
+ km.keys[SB_SEL_KEY].bind.ch[0] = 's';
+ }
+@@ -1717,7 +1717,7 @@
+ }
+
+ if(cur_f && cur_f->isdir){
+- static struct key sel_key = {">", "[View Dir]",
++ static struct key sel_key = {">", "[檢視目錄]",
+ {MC_CHOICE,5,
+ {'s','>','.',
+ ctrl('M'),ctrl('J')}},
+@@ -1843,8 +1843,15 @@
+ /*---------------------- Key left --------------*/
+ case MC_CHARLEFT :
+ case MC_PREVITEM :
++ if (exit_to_main)
++ {
++ ps_global->next_screen = main_menu_screen;
++ done++;
++ }
+ if((n = folder_lister_prev(fs)) >= 0)
+ fs->folder_index = n;
++ else
++ exit_to_main = 1;
+
+ break;
+
+@@ -1852,6 +1859,7 @@
+ /*--------------------- Key right -------------------*/
+ case MC_CHARRIGHT :
+ case MC_NEXTITEM :
++ exit_to_main = 0;
+ if(n = folder_lister_next(fs))
+ fs->folder_index = n;
+
+@@ -1873,7 +1881,7 @@
+ rc--;
+
+ if(rc < 0){
+- q_status_message(SM_ORDER, 0, 1, "Already on first line.");
++ q_status_message(SM_ORDER, 0, 1, "已經到第一行了。");
+ if(fs->top_row != 0){ /* make sure! */
+ fs->top_row = 0;
+ fs->prev_index = -1;
+@@ -1919,7 +1927,7 @@
+ FOLDERS(fs->context))->d_line + 1;
+
+ if(rc > fs->last_row){
+- q_status_message(SM_ORDER, 0, 1, "Already on last line.");
++ q_status_message(SM_ORDER, 0, 1, "已經到最後一行了。");
+ break;
+ }
+
+@@ -2038,7 +2046,7 @@
+ rc++;
+ }
+ else
+- q_status_message(SM_ORDER,0,1,"Already on first page.");
++ q_status_message(SM_ORDER,0,1,"已經到第一頁了。");
+
+ break;
+
+@@ -2051,7 +2059,7 @@
+ if((rc = fs->top_row + fs->display_rows) > fs->last_row){
+ if((int)folder_entry(fs->folder_index,
+ FOLDERS(fs->context))->d_line >= fs->last_row){
+- q_status_message(SM_ORDER,0,1,"Already on last page.");
++ q_status_message(SM_ORDER,0,1,"已經到最後一頁了。");
+ break;
+ }
+ else
+@@ -2092,7 +2100,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Sorry, no help text available");
++ "很抱歉,文字說明無法取得");
+
+ break;
+
+@@ -2101,7 +2109,7 @@
+ case MC_CHOICE :
+ if(!folder_total(FOLDERS(fs->context))){
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Empty folder collection. Nothing to select!");
++ "空的資料匣總集。沒有東西可供選擇!");
+ }
+ else if(folder_lister_select(cur_f, fs, listmode)){
+ mangled_footer++;
+@@ -2163,7 +2171,7 @@
+ mangled_footer++;
+ }
+ else
+- q_status_message(SM_ORDER, 0, 4, "Already in List Mode");
++ q_status_message(SM_ORDER, 0, 4, "已經在列表模式了。");
+
+ break;
+
+@@ -2296,8 +2304,8 @@
+ case MC_DELETE :
+ if(!ALL_FOUND(fs->context) || (fs->context->use & CNTXT_PSEUDO)){
+ q_status_message1(SM_ORDER | SM_DING, 0, 3,
+- "No folder selected to delete. %s list.",
+- ALL_FOUND(fs->context) ? "Empty" : "Expand");
++ "尚未選擇供刪除的資料匣。%s列表。",
++ ALL_FOUND(fs->context) ? "空" : "展開");
+ break;
+ }
+
+@@ -2375,13 +2383,13 @@
+ if(fs->zoomed = !fs->zoomed){ /* clear all the prefixes */
+ (void) folder_lister_nearest_selected(fs);
+ q_status_message1(SM_ORDER, 0, 3,
+- "In Zoomed list of %s folders. Use \"Z\" to restore regular list",
++ "在 %s 個資料匣縮放的列表中。使用 \"Z\" 來回復正常列表",
+ int2string(n));
+
+ }
+ else{
+ q_status_message(SM_ORDER, 0, 3,
+- "Folder List Zoom mode is now off");
++ "資料匣列表縮放模式目前為關閉狀態");
+ }
+
+ create_folder_display(fs, ps->ttyo->screen_cols);
+@@ -2389,7 +2397,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 3,
+- "No selected folders to Zoom on");
++ "尚未選擇供放大的資料匣。");
+
+
+ break;
+@@ -2403,12 +2411,12 @@
+ break;
+
+ case 0 :
+- q_status_message(SM_ORDER | SM_DING, 0, 2, "Word not found");
++ q_status_message(SM_ORDER | SM_DING, 0, 2, "找不到該字");
+ break;
+
+ case 2 :
+ q_status_message(SM_ORDER, 0, 2,
+- "Search wrapped to beginning");
++ "從頭搜尋");
+ break;
+ }
+
+@@ -2469,8 +2477,8 @@
+ && ALL_FOUND(fs->context))
+ return(fs->folder_index + 1);
+
+- q_status_message1(SM_ORDER, 0, 1, "Already on last %sfolder",
+- fs->zoomed ? "Zoomed " : "");
++ q_status_message1(SM_ORDER, 0, 1, "已經在最後一個%s資料匣了",
++ fs->zoomed ? "縮放後的" : "");
+ return(0);
+ }
+
+@@ -2491,8 +2499,8 @@
+ else if(fs->folder_index > 0 && ALL_FOUND(fs->context))
+ return(fs->folder_index - 1);
+
+- q_status_message1(SM_ORDER, 0, 1, "Already on first %sfolder",
+- fs->zoomed ? "Zoomed " : "");
++ q_status_message1(SM_ORDER, 0, 1, "已經在第一個%s資料匣了",
++ fs->zoomed ? "縮放後的" : "");
+ return(-1);
+ }
+
+@@ -2507,7 +2515,7 @@
+ if(listmode){
+ if(NEWS_TEST(fs->context) && !strncmp(f->prefix, "SUB", 3)){
+ q_status_message1(SM_ORDER, 0, 3,
+- "Already subscribed to \"%s\"",
++ "已訂閱\至 \"%s\"",
+ FLDR_NAME(f));
+ }
+ else{
+@@ -2517,7 +2525,7 @@
+ }
+ else{
+ if(f->isdir){
+- q_status_message(SM_ORDER, 0, 3, "Can't select directories");
++ q_status_message(SM_ORDER, 0, 3, "無法選擇目錄");
+ }
+ else
+ folder_select_toggle(fs, f);
+@@ -2574,13 +2582,13 @@
+ extern char *sel_pmt2;
+
+ if((f = folder_entry(fs->folder_index, FOLDERS(fs->context)))->isdir){
+- q_status_message(SM_ORDER | SM_DING, 0, 3, "Can't Select directories");
++ q_status_message(SM_ORDER | SM_DING, 0, 3, "無法選擇目錄");
+ return(0);
+ }
+
+ sel_opts = self_opts2;
+ if(old_tot = selected_folders(fs)){
+- sel_opts1[1].label = "unselect Cur" + (f->selected ? 0 : 2);
++ sel_opts1[1].label = "取消目前選擇" + (f->selected ? 0 : 2);
+ sel_opts += 2; /* disable extra options */
+ switch(q = radio_buttons(SEL_ALTER_PMT, -FOOTER_ROWS(ps_global),
+ sel_opts1, 'c', 'x', help, RB_NORM)){
+@@ -2605,7 +2613,7 @@
+
+ default :
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Unsupported Select option");
++ "未支援的選項");
+ return(0);
+ }
+ }
+@@ -2641,10 +2649,10 @@
+ create_folder_display(fs, ps_global->ttyo->screen_cols);
+ }
+
+- q_status_message4(SM_ORDER, 0, 2, "%s%s folder%s %sselected",
+- old_tot ? "" : "All ",
++ q_status_message3(SM_ORDER, 0, 2, "%s%s 個資料匣已被%s選擇",
++ old_tot ? "" : "全部 ",
+ comatose(old_tot ? old_tot : n),
+- plural(old_tot ? old_tot : n), old_tot ? "UN" : "");
++ old_tot ? "取消" : "");
+ return(1);
+
+ case 't' : /* Text */
+@@ -2661,7 +2669,7 @@
+
+ default :
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Unsupported Select option");
++ "未支援的選項");
+ return(0);
+ }
+
+@@ -2690,35 +2698,30 @@
+
+ if(!(diff = (total = selected_folders(fs)) - old_tot)){
+ if(narrow)
+- q_status_message4(SM_ORDER, 0, 2,
+- "%s. %s folder%s remain%s selected.",
+- j ? "No change resulted"
+- : "No messages in intersection",
+- comatose(old_tot), plural(old_tot),
+- (old_tot == 1L) ? "s" : "");
++ q_status_message2(SM_ORDER, 0, 2,
++ "%s。 仍有 %s 個資料匣被選擇。",
++ j ? "沒有導致改變"
++ : "交點中沒有信件", comatose(old_tot));
+ else if(old_tot && j)
+ q_status_message(SM_ORDER, 0, 2,
+- "No change resulted. Matching folders already selected.");
++ "沒有導致改變。符合的資料匣已經被選擇了。");
+ else
+ q_status_message1(SM_ORDER | SM_DING, 0, 2,
+- "Select failed! No %sfolders selected.",
+- old_tot ? "additional " : "");
++ "選擇失敗!沒有%s資料匣被選擇。",
++ old_tot ? "額外的 " : "");
+ }
+ else{
+ if(old_tot){
+ sprintf(tmp_20k_buf,
+- "Select matched %ld folder%s! %s %sfolder%s %sselected.",
++ "選擇符合的 %ld 個資料匣!共計 %s 個資料匣被%s選擇.",
+ (diff > 0) ? diff : old_tot + diff,
+- plural((diff > 0) ? diff : old_tot + diff),
+ comatose((diff > 0) ? total : -diff),
+- (diff > 0) ? "total " : "",
+- plural((diff > 0) ? total : -diff),
+- (diff > 0) ? "" : "UN");
++ (diff > 0) ? "" : "取消");
+ q_status_message(SM_ORDER, 0, 2, tmp_20k_buf);
+ }
+ else{
+- q_status_message2(SM_ORDER, 0, 2, "Select matched %s folder%s!",
+- comatose(diff), plural(diff));
++ q_status_message1(SM_ORDER, 0, 2, "選擇符合的 %s 個資料匣!",
++ comatose(diff));
+
+ if(F_OFF(F_SELECTED_SHOWN_BOLD, ps_global)){
+ folder_prefixes(fs, " ");
+@@ -2833,7 +2836,7 @@
+ fp = next_folder_dir(fs->context, tmpf->name);
+
+ /* Provide context in new collection header */
+- sprintf(tmp_20k_buf, "Dir: %s",
++ sprintf(tmp_20k_buf, "目錄:%s",
+ ((p = strstr(fs->context->context, "%s")) && !*(p+2)
+ && !strncmp(fp->ref, fs->context->context,
+ p - fs->context->context))
+@@ -2854,9 +2857,9 @@
+
+ fs->prev_index = -1; /* redraw display */
+
+- q_status_message2(SM_ORDER, 0, 3, "Now in %sdirectory: %s",
++ q_status_message2(SM_ORDER, 0, 3, "目前在 %s目錄中:%s",
+ folder_total(FOLDERS(fs->context))
+- ? "" : "EMPTY ", fp->ref);
++ ? "" : "空的 ", fp->ref);
+ rv++;
+ }
+ else
+@@ -2902,12 +2905,12 @@
+ fs->prev_index = -1; /* redraw display */
+
+ if(fp->status & CNTXT_SUBDIR)
+- q_status_message1(SM_ORDER, 0, 3, "Now in directory: %s",
++ q_status_message1(SM_ORDER, 0, 3, "目前所在目錄:%s",
+ strsquish(tmp_20k_buf + 500, fp->ref,
+ fs->display_cols - 22));
+ else
+ q_status_message(SM_ORDER, 0, 3,
+- "Returned to collection's top directory");
++ "回到總集的最上層目錄");
+
+ rv++;
+ }
+@@ -3473,12 +3476,12 @@
+ if(fs->context->use & CNTXT_INCMNG){
+ char inbox_host[MAXPATH], *beg, *end = NULL;
+ ESCKEY_S *special_key;
+- static ESCKEY_S host_key[] = {{ctrl('X'),12,"^X","Use Inbox Host"},
++ static ESCKEY_S host_key[] = {{ctrl('X'),12,"^X","使用 Inbox 的主機"},
+ {-1, 0, NULL, NULL}};
+
+ if(ps_global->readonly_pinerc){
+ q_status_message(SM_ORDER,3,5,
+- "Addition cancelled: config file not editable");
++ "取消新增:無法編輯設定檔");
+ return(FALSE);
+ }
+
+@@ -3500,7 +3503,7 @@
+ else
+ special_key = NULL;
+
+- sprintf(tmp, "Name of server to contain added folder : ");
++ sprintf(tmp, "包含新增資料匣的主機名:");
+ help = NO_HELP;
+ while(1){
+ int flags = OE_APPEND_CURRENT;
+@@ -3518,7 +3521,7 @@
+ }
+ else if(rc == 1){
+ q_status_message(SM_ORDER,0,2,
+- "Addition of new folder cancelled");
++ "取消新增資料匣");
+ return(FALSE);
+ }
+ else if(rc == 0)
+@@ -3528,7 +3531,7 @@
+
+ if(offset = strlen(add_folder)){ /* must be host for incoming */
+ int i;
+- sprintf(tmp, "Folder on \"%s\" to add : ", add_folder);
++ sprintf(tmp, "加入在 \"%s\" 上的資料匣:", add_folder);
+ for(i = offset;i >= 0; i--)
+ add_folder[i+1] = add_folder[i];
+
+@@ -3537,7 +3540,7 @@
+ add_folder[++offset] = '\0'; /* +2, total */
+ }
+ else
+- sprintf(tmp, "Folder name to add : ");
++ sprintf(tmp, "新增資料匣名稱:");
+
+ help = NO_HELP;
+ while(1){
+@@ -3545,14 +3548,14 @@
+
+ p = NULL;
+ if(isdir){
+- add_key[0].label = "Create Folder";
++ add_key[0].label = "建立資料匣";
+ if(tmp[0] == 'F')
+- rplstr(tmp, 6, "Directory");
++ rplstr(tmp, 6, "目錄");
+ }
+ else{
+- add_key[0].label = "Create Directory";
++ add_key[0].label = "建立目錄";
+ if(tmp[0] == 'D')
+- rplstr(tmp, 9, "Folder");
++ rplstr(tmp, 9, "資料匣");
+ }
+
+ flags = OE_APPEND_CURRENT;
+@@ -3566,7 +3569,7 @@
+ if(!ps_global->show_dot_names && add_folder[offset] == '.'){
+ if(cnt++ <= 0)
+ q_status_message(SM_ORDER,3,3,
+- "Folder name can't begin with dot");
++ "資料匣不能以點 \".\" 為名稱開頭");
+ else{
+ NAMEVAL_S *feat;
+ int i;
+@@ -3576,7 +3579,7 @@
+ ;/* do nothing */
+
+ q_status_message1(SM_ORDER,3,3,
+- "Config feature \"%s\" enables names beginning with dot",
++ "設定檔中 \"%s\" 的功\能可使資料匣以點 \".\" 為名稱開頭",
+ feat && feat->name ? feat->name : "");
+ }
+
+@@ -3596,7 +3599,7 @@
+ }
+ else if(*p == fs->context->dir->delim){
+ q_status_message(SM_ORDER|SM_DING, 3, 3,
+- "Can't have trailing directory delimiters!");
++ "不能有目錄尾端的分隔號 \"/\"!");
+ display_message('X');
+ continue;
+ }
+@@ -3618,7 +3621,7 @@
+ : NO_HELP;
+ }
+ else if(rc == 1 || add_folder[0] == '\0') {
+- q_status_message(SM_ORDER,0,2, "Addition of new folder cancelled");
++ q_status_message(SM_ORDER,0,2, "取消新增資料匣");
+ return(FALSE);
+ }
+ }
+@@ -3637,7 +3640,7 @@
+
+ help = NO_HELP;
+ if(fs->context->use & CNTXT_INCMNG){
+- sprintf(tmp, "Nickname for folder \"%s\" : ", &add_folder[offset]);
++ sprintf(tmp, "資料匣\"%s\" 的暱稱:", &add_folder[offset]);
+ while(1){
+ int flags = OE_APPEND_CURRENT;
+
+@@ -3658,7 +3661,7 @@
+ }
+ else if(rc == 1 || (rc != 3 && !*nickname)){
+ q_status_message(SM_ORDER,0,2,
+- "Addition of new folder cancelled");
++ "取消新增資料匣");
+ return(FALSE);
+ }
+ }
+@@ -3673,7 +3676,7 @@
+ f = folder_entry(offset, FOLDERS(fs->context));
+ if(!strucmp(FLDR_NAME(f), nickname[0] ? nickname : add_folder)){
+ q_status_message1(SM_ORDER | SM_DING, 0, 3,
+- "Incoming folder \"%s\" already exists",
++ "新進資料匣(Incoming folder) \"%s\" 已存在",
+ nickname[0] ? nickname : add_folder);
+ return(FALSE);
+ }
+@@ -3726,7 +3729,7 @@
+ if(nickname[0])
+ strcpy(add_folder, nickname); /* known by new name */
+
+- q_status_message1(SM_ORDER, 0, 3, "Folder \"%s\" created",add_folder);
++ q_status_message1(SM_ORDER, 0, 3, "資料匣 \"%s\" 已建立",add_folder);
+ return_val = add_folder;
+ }
+ else if(context_isambig(add_folder)){
+@@ -3742,15 +3745,15 @@
+ */
+ refresh_folder_list(fs, TRUE);
+
+- q_status_message2(SM_ORDER, 0, 3, "%s \"%s\" created",
+- isdir ? "Directory" : "Folder", add_folder);
++ q_status_message2(SM_ORDER, 0, 3, "%s \"%s\" 已建立",
++ isdir ? "目錄" : "資料匣", add_folder);
+ }
+
+ return_val = add_folder;
+ }
+ else
+ q_status_message1(SM_ORDER, 0, 3,
+- "Folder \"%s\" created outside current collection",
++ "資料匣 \"%s\" 建立於目前的總集之外",
+ add_folder);
+
+ return(return_val != NULL);
+@@ -3789,13 +3792,13 @@
+ subscribe_keys[i = 0].ch = ctrl('T');
+ subscribe_keys[i].rval = 12;
+ subscribe_keys[i].name = "^T";
+- subscribe_keys[i++].label = "To All Grps";
++ subscribe_keys[i++].label = "給所有的組群";
+
+ if(F_ON(F_ENABLE_TAB_COMPLETE,ps_global)){
+ subscribe_keys[i].ch = ctrl('I');
+ subscribe_keys[i].rval = 11;
+ subscribe_keys[i].name = "TAB";
+- subscribe_keys[i++].label = "Complete";
++ subscribe_keys[i++].label = "完成";
+ }
+
+ subscribe_keys[i].ch = -1;
+@@ -3855,7 +3858,7 @@
+ }
+ else{
+ q_status_message(SM_ORDER, 0, 2,
+- "No group substring to match! Use ^T to list all news groups.");
++ "沒有符合的組群字串!請用 ^T 列出所有新聞組群。");
+ continue;
+ }
+
+@@ -3908,10 +3911,10 @@
+ else{
+ if(rc == 12)
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "No groups to select from!");
++ "沒有可供選擇的組群!");
+ else
+ q_status_message1(SM_ORDER, 3, 3,
+- "News group \"%s\" didn't match any existing groups",
++ "新聞組群 \"%s\" 不符合任何現存的組群",
+ folder);
+
+ continue;
+@@ -3959,7 +3962,7 @@
+
+ if(rc < 0){
+ if(rc == -1)
+- q_status_message(SM_ORDER, 0, 3, "Subscribe cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消訂閱\");
+ }
+ else{
+ if(folders){ /*------ Actually do the subscription -----*/
+@@ -3981,7 +3984,7 @@
+ */
+ q_status_message1(errors ?SM_INFO : SM_ORDER,
+ errors ? 0 : 3, 3,
+- "Error subscribing to \"%s\"",
++ "訂閱\至 \"%s\" 時發生錯誤",
+ (char *) flp->text.data);
+ errors++;
+ }
+@@ -4005,13 +4008,13 @@
+
+ if(n == 0)
+ q_status_message(SM_ORDER | SM_DING, 3, 5,
+- "Subscriptions failed, subscribed to no new groups");
++ "訂閱\失敗,沒有訂閱\任何新組群");
+ else
+ q_status_message3(SM_ORDER | (errors ? SM_DING : 0),
+ errors ? 3 : 0,3,
+- "Subscribed to %s new groups%s%s",
++ "訂閱\至 %s 個新組群%s%s",
+ comatose((long)n),
+- errors ? ", failed on " : "",
++ errors ? ",發生錯誤於 " : "",
+ errors ? comatose((long)errors) : "");
+
+ mail_free_stringlist(&folders);
+@@ -4020,7 +4023,7 @@
+ (void) context_apply(tmp_20k_buf, &subscribe_cntxt, folder);
+ if(mail_subscribe(NULL, tmp_20k_buf) == 0L){
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Error subscribing to \"%s\"", folder);
++ "訂閱\至 \"%s\" 時發生錯誤", folder);
+ }
+ else if(ALL_FOUND(cntxt)){
+ /*---- Update the screen display data structures -----*/
+@@ -4034,7 +4037,7 @@
+ }
+
+ if(folder[0])
+- q_status_message1(SM_ORDER, 0, 3, "Subscribed to \"%s\"", folder);
++ q_status_message1(SM_ORDER, 0, 3, "訂閱\至 \"%s\"", folder);
+ }
+
+ free_fdir(&subscribe_cntxt.dir, 1);
+@@ -4074,19 +4077,19 @@
+
+ if(NEWS_TEST(fs->context)){
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Can't rename bulletin boards or news groups!");
++ "無法更改電子佈告欄或新聞組群的名稱!");
+ return(0);
+ }
+ else if(!folder_total(FOLDERS(fs->context))){
+ q_status_message(SM_ORDER | SM_DING, 0, 4,
+- "Empty folder collection. No folder to rename!");
++ "空的資料匣總集。沒有可供更名的資料匣!");
+ return(0);
+ }
+ else if((new_f = folder_entry(fs->folder_index, FOLDERS(fs->context)))
+ && (!strucmp(FLDR_NAME(new_f), ps_global->inbox_name)
+ || new_f->parent)) {
+ q_status_message1(SM_ORDER | SM_DING, 3, 4,
+- "Can't change special folder name \"%s\"",
++ "無法更改特殊資料匣 \"%s\" 的名稱",
+ new_f->parent
+ ? new_f->nickname
+ : ps_global->inbox_name);
+@@ -4102,11 +4105,11 @@
+
+ ren_cur = strcmp(folder, ps_global->cur_folder) == 0;
+
+- sprintf(prompt, "Rename %s to : ",
++ sprintf(prompt, "將 %s 更名為:",
+ (fs->context->use & CNTXT_INCMNG)
+- ? "nickname"
++ ? "暱稱"
+ : (isdir = new_f->isdir)
+- ? "directory" : "folder");
++ ? "目錄" : "資料匣");
+ help = NO_HELP;
+ strcpy(new_name, folder);
+ while(1) {
+@@ -4127,7 +4130,7 @@
+ if(!ps_global->show_dot_names && *new_name == '.'){
+ if(cnt++ <= 0)
+ q_status_message(SM_ORDER,3,3,
+- "Folder name can't begin with dot");
++ "資料匣不能以點 \".\" 為名稱開頭");
+ else{
+ NAMEVAL_S *feat;
+ int i;
+@@ -4137,7 +4140,7 @@
+ ;/* do nothing */
+
+ q_status_message1(SM_ORDER,3,3,
+- "Config feature \"%s\" enables names beginning with dot",
++ "設定檔中 \"%s\" 的功\能可使資料匣以點 \".\" 為名稱開頭",
+ feat && feat->name ? feat->name : "");
+ }
+
+@@ -4147,13 +4150,13 @@
+
+ if(folder_index(new_name, fs->context, FI_ANY) >= 0){
+ q_status_message1(SM_ORDER, 3, 3,
+- "Folder \"%s\" already exists",
++ "資料匣 \"%s\" 已存在",
+ pretty_fn(new_name));
+ display_message(NO_OP_COMMAND);
+ continue;
+ }
+ else if(!strucmp(new_name, ps_global->inbox_name)){
+- q_status_message1(SM_ORDER, 3, 3, "Can't rename folder to %s",
++ q_status_message1(SM_ORDER, 3, 3, "無法將資料匣更名至 %s",
+ ps_global->inbox_name);
+ display_message(NO_OP_COMMAND);
+ continue;
+@@ -4176,7 +4179,7 @@
+ if(rc == 1
+ || !(*new_name || (fs->context->use & CNTXT_INCMNG))
+ || !strcmp(new_name, folder)){
+- q_status_message(SM_ORDER, 0, 2, "Folder rename cancelled");
++ q_status_message(SM_ORDER, 0, 2, "取消資料匣更名");
+ return(0);
+ }
+
+@@ -4258,7 +4261,7 @@
+ /* renaming sent-mail or saved-messages */
+ if(context_create(fs->context, NULL, folder)){
+ q_status_message3(SM_ORDER,0,3,
+- "Folder \"%s\" renamed to \"%s\". New \"%s\" created",
++ "資料匣 \"%s\" 名稱改為 \"%s\"。建立新的 \"%s\"",
+ folder, new_name,
+ pretty_fn(
+ (strcmp(ps_global->VAR_DEFAULT_SAVE_FOLDER,
+@@ -4269,7 +4272,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 4,
+- "Error creating new \"%s\"", folder);
++ "建立新的資料匣 \"%s\" 時發生錯誤", folder);
+
+ dprint(2, (debugfile, "Error creating \"%s\" in %s context\n",
+ folder, fs->context->context));
+@@ -4277,7 +4280,7 @@
+ }
+ else
+ q_status_message2(SM_ORDER, 0, 3,
+- "Folder \"%s\" renamed to \"%s\"",
++ "資料匣 \"%s\" 名稱改為 \"%s\"",
+ pretty_fn(folder), pretty_fn(new_name));
+
+ /* Rebuild folder list */
+@@ -4326,7 +4329,7 @@
+ int ret, close_opened = 0, blast_folder = 1;
+
+ if(NEWS_TEST(fs->context)){
+- static char fmt[] = "Really unsubscribe from \"%.*s\"";
++ static char fmt[] = "確定自 \"%.*s\" 中解除訂閱\嗎";
+
+ folder = folder_entry(fs->folder_index, FOLDERS(fs->context))->name;
+ /* 4 is strlen("%.*s") */
+@@ -4348,7 +4351,7 @@
+ (void) context_apply(tmp_20k_buf, fs->context, folder);
+ if(!mail_unsubscribe(NULL, tmp_20k_buf)){
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Error unsubscribing from \"%s\"", folder);
++ "自 \"%s\" 取消訂閱\時發生錯誤", folder);
+ return(0);
+ }
+
+@@ -4366,7 +4369,7 @@
+
+ if(!folder_total(FOLDERS(fs->context))){
+ q_status_message(SM_ORDER | SM_DING, 0, 4,
+- "Empty folder collection. No folder to delete!");
++ "空的資料匣總集。沒有東西可供刪除!");
+ return(0);
+ }
+
+@@ -4376,12 +4379,12 @@
+
+ if(ps_global->readonly_pinerc && (fs->context->use & CNTXT_INCMNG)){
+ q_status_message(SM_ORDER,3,5,
+- "Deletion cancelled: config file not editable");
++ "取消刪除:無法編輯設定檔");
+ return(0);
+ }
+ else if(strucmp(folder, ps_global->inbox_name) == 0 || fp->parent) {
+ q_status_message1(SM_ORDER | SM_DING, 3, 4,
+- "Can't delete special folder \"%s\".", ps_global->inbox_name);
++ "無法刪除特殊資料匣 \"%s\"。", ps_global->inbox_name);
+ return(0);
+ }
+ else if(fs->context == ps_global->context_current
+@@ -4396,7 +4399,7 @@
+
+ if(ret){
+ q_status_message1(SM_ORDER | SM_DING, 3, 4,
+- "Can't delete non-empty directory \"%s\".",
++ "無法刪除非空的目錄 \"%s\"。",
+ folder);
+ return(0);
+ }
+@@ -4407,19 +4410,19 @@
+ */
+ if(folder_index(folder, fs->context, FI_FOLDER) >= 0
+ && (ret = want_to(DIR_FOLD_PMT,'n','x',NO_HELP,WT_NORM)) != 'y'){
+- q_status_message(SM_ORDER,0,3, (ret == 'x') ? "Delete cancelled"
+- : "No folder deleted");
++ q_status_message(SM_ORDER,0,3, (ret == 'x') ? "取消刪除"
++ : "沒有任何資料匣被刪除");
+ return(0);
+ }
+ }
+
+ if(fs->context->use & CNTXT_INCMNG){
+ static ESCKEY_S delf_opts[] = {
+- {'n', 'n', "N", "Nickname only"},
+- {'b', 'b', "B", "Both Folder and Nickname"},
++ {'n', 'n', "N", "僅有暱稱"},
++ {'b', 'b', "B", "資料匣與暱稱"},
+ {-1, 0, NULL, NULL}
+ };
+-#define DELF_PROMPT "DELETE only Nickname or Both nickname and folder? "
++#define DELF_PROMPT "刪除「僅有暱稱」或「資料匣與暱稱」?"
+
+ switch(radio_buttons(DELF_PROMPT, -FOOTER_ROWS(ps_global),
+ delf_opts,'n','x',NO_HELP,RB_NORM)){
+@@ -4436,13 +4439,13 @@
+ }
+ }
+ else{
+- sprintf(ques_buf, "DELETE \"%s\"%s", folder,
+- close_opened ? " (the currently open folder)"
+- : fp->isdir ? " (a directory)" : "");
++ sprintf(ques_buf, "刪除 \"%s\"%s", folder,
++ close_opened ? " (目前開啟的資料匣)"
++ : fp->isdir ? " (目錄)" : "");
+
+ if((ret = want_to(ques_buf, 'n', 'x', NO_HELP, WT_NORM)) != 'y'){
+- q_status_message(SM_ORDER,0,3, (ret == 'x') ? "Delete cancelled"
+- : "No folder deleted");
++ q_status_message(SM_ORDER,0,3, (ret == 'x') ? "取消刪除"
++ : "沒有任何資料匣被刪除");
+ return(0);
+ }
+ }
+@@ -4485,13 +4488,13 @@
+ /*
+ * BUG: what if sent-mail or saved-messages????
+ */
+- q_status_message1(SM_ORDER,3,3,"Delete of \"%s\" Failed!", folder);
++ q_status_message1(SM_ORDER,3,3,"刪除 \"%s\" 失敗!", folder);
+ return(0);
+ }
+ }
+
+- q_status_message2(SM_ORDER, 0, 3, "%s \"%s\" deleted!",
+- blast_folder ? "Folder" : "Nickname", folder);
++ q_status_message2(SM_ORDER, 0, 3, "%s \"%s\" 已被刪除!",
++ blast_folder ? "資料匣" : "暱稱", folder);
+
+
+ if(fs->context->use & CNTXT_INCMNG){
+@@ -4636,7 +4639,7 @@
+ int flags;
+
+ pat[0] = '\0';
+- sprintf(prompt, "String in folder %s to match : ", kind);
++ sprintf(prompt, "資料匣 %s 中欲符合的字串:", kind);
+
+ while(1){
+ flags = OE_APPEND_CURRENT | OE_DISALLOW_HELP;
+@@ -4761,7 +4764,7 @@
+ if(!strucmp(folder = f->name, ps_global->inbox_name))
+ return(FEX_ISFILE);
+
+- sprintf(tmp, "Scanning \"%.*s\"", 40, FLDR_NAME(f));
++ sprintf(tmp, "正在掃描 \"%.*s\"", 40, FLDR_NAME(f));
+ we_cancel = busy_alarm(1, tmp, NULL, 0);
+
+ mm_list_info = &ldata; /* tie down global reference */
+@@ -4926,7 +4929,7 @@
+ while(1){
+ flags = OE_APPEND_CURRENT | OE_DISALLOW_HELP;
+ sprintf(number, "%ld", *count);
+- sprintf(prompt, "Select folders with messages %s : ", tense[*cmp]);
++ sprintf(prompt, "選擇有信件 %s 的資料匣:", tense[*cmp]);
+ r = optionally_enter(number, -FOOTER_ROWS(ps_global), 0, 31,
+ prompt, sel_num_opt, NO_HELP, &flags);
+ switch (r){
+@@ -4935,7 +4938,7 @@
+ break;
+ else if((*count = atol(number)) < 0L)
+ q_status_message(SM_ORDER, 3, 3,
+- "Can't have NEGATIVE message count!");
++ "不可有「負的」信件數量!");
+ else
+ return(1); /* success */
+
+@@ -5141,14 +5144,14 @@
+ int rc, t_index, done = 0;
+ static char search_string[MAX_SEARCH+1];
+ static ESCKEY_S search_keys[] = {{0, 0, NULL, NULL},
+- {ctrl('Y'), 10, "^Y","First Fldr"},
+- {ctrl('V'), 11, "^V","Last Fldr"},
++ {ctrl('Y'), 10, "^Y","第一個資料匣"},
++ {ctrl('V'), 11, "^V","最後一個資料匣"},
+ {-1, 0, NULL, NULL} };
+
+ nsearch_string[0] = '\0';
+ if(!folder_total(FOLDERS(fd->context))){
+ q_status_message(SM_ORDER | SM_DING, 0, 4,
+- "Empty folder collection. No folders to search!");
++ "空的資料匣總集。沒有東西可供搜尋!");
+ return(0);
+ }
+ else{
+@@ -5156,7 +5159,7 @@
+ search_keys[0].ch = ctrl('X');
+ search_keys[0].rval = 9;
+ search_keys[0].name = "^X";
+- search_keys[0].label = "List Matches";
++ search_keys[0].label = "列出符合者";
+ }
+ else{
+ search_keys[0].ch = 0;
+@@ -5167,7 +5170,7 @@
+ }
+
+ t_index = fd->folder_index;
+- sprintf(prompt, "Folder name to search for %s%s%s: ",
++ sprintf(prompt, "欲搜尋的資料匣名稱 %s%s%s:",
+ (*search_string == '\0') ? "" : "[",
+ search_string,
+ (*search_string == '\0') ? "" : "] ");
+@@ -5178,7 +5181,7 @@
+ switch(optionally_enter(nsearch_string, ask_line, 0, MAX_SEARCH,
+ prompt, search_keys, help, &flags)){
+ case -1 :
+- q_status_message(SM_ORDER | SM_DING, 3, 3, "Error reading word");
++ q_status_message(SM_ORDER | SM_DING, 3, 3, "讀取字元時發生錯誤");
+ return(0);
+
+ case 0 : /*----- Search away ------*/
+@@ -5235,9 +5238,9 @@
+ }
+
+ if(rc){
+- q_status_message2(SM_ORDER, 0, 3,
+- "Searched matched %s folder%s",
+- int2string(count), plural(count));
++ q_status_message1(SM_ORDER, 0, 3,
++ "共有 %s 個資料匣符合搜尋條件",
++ int2string(count));
+ fd->prev_index = -1; /* repaint! */
+ }
+
+@@ -5251,14 +5254,14 @@
+ while((t_index = folder_lister_prev(fd)) >= 0)
+ fd->folder_index = t_index;
+
+- q_status_message(SM_ORDER, 0, 3, "Searched to First Folder.");
++ q_status_message(SM_ORDER, 0, 3, "搜尋至第一個資料匣。");
+ return(3);
+
+ case 11 :
+ while((t_index = folder_lister_next(fd)))
+ fd->folder_index = t_index;
+
+- q_status_message(SM_ORDER, 0, 3, "Searched to Last Folder.");
++ q_status_message(SM_ORDER, 0, 3, "搜尋至最後一個資料匣。");
+ return(3);
+
+ default :
+@@ -6251,7 +6254,7 @@
+
+ if(p = context_digest(c_string, dcontext, host, rcontext, view)){
+ q_status_message2(SM_ORDER | SM_DING, 3, 4,
+- "Bad context, %s : %s", p, c_string);
++ "錯誤的內容,%s:%s", p, c_string);
+ fs_give((void **) &c_string);
+ if(nickname)
+ fs_give((void **)&nickname);
+@@ -6292,14 +6295,14 @@
+
+ /* fix up label */
+ if(NEWS_TEST(c)){
+- sprintf(tmp_20k_buf, "%sews groups%s%s",
+- (*host) ? "N" : "Local n", (*host) ? " on " : "",
++ sprintf(tmp_20k_buf, "%s文組群%s%s",
++ (*host) ? "新" : "本地的新", (*host) ? " 於 " : "",
+ (*host) ? host : "");
+ }
+ else{
+ p = srchstr(rcontext, "[]");
+- sprintf(tmp_20k_buf, "%solders%s%s in %.*s%s",
+- (*host) ? "F" : "Local f", (*host) ? " on " : "",
++ sprintf(tmp_20k_buf, "%s料匣%s%s在 %.*s%s",
++ (*host) ? "資" : "本地的資", (*host) ? " 於 " : "",
+ (*host) ? host : "", p ? p - rcontext : 0,
+ rcontext, (p && (p - rcontext) > 0) ? "" : "home directory");
+ }
+@@ -7482,7 +7485,7 @@
+ if(error && num_in_error){
+ cnt_errs = num_in_error;
+ memset((void *)ng_error, 0, (size_t)90);
+- sprintf(ng_error, "Unknown news group%s: ", plural(num_in_error));
++ sprintf(ng_error, "未知的新聞組群:");
+ ep = ng_error + strlen(ng_error);
+ }
+ for(ntmp = nglist; ntmp; ntmp = ntmp->next){
diff --git a/chinese/pine4/files/patch-as b/chinese/pine4/files/patch-as
index 854046b5d8d6..50e97fc0e63d 100644
--- a/chinese/pine4/files/patch-as
+++ b/chinese/pine4/files/patch-as
@@ -1,84 +1,101 @@
---- pine/send.c.orig Sat Jan 17 19:54:07 1998
-+++ pine/send.c Sat Jan 17 21:22:38 1998
-@@ -50,6 +50,7 @@
- #include "../c-client/smtp.h"
- #include "../c-client/nntp.h"
+--- pine/help.c.orig Wed Jul 1 06:22:26 1998
++++ pine/help.c Wed Jul 15 17:02:33 1998
+@@ -50,15 +50,15 @@
-+#define bitstrip(x) (x)
+ static struct key help_keys[] =
+ {MAIN_MENU,
+- {"E","Exit Help",{MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E","離開",{MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ {NULL,NULL,{MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ {NULL,NULL,{MC_VIEW_HANDLE,3,{'v',ctrl('m'),ctrl('j')}},KS_NONE},
+- {"^B","PrevLink",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
+- {"^F","NextLink",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
++ {"^B","前一連結",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
++ {"^F","次一連結",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ PRYNTMSG_MENU,
+- {"Z","Print All",{MC_PRINTALL,1,{'z'}},KS_NONE},
++ {"Z","列印全部",{MC_PRINTALL,1,{'z'}},KS_NONE},
+ NULL_MENU,
+ WHEREIS_MENU};
+ INST_KEY_MENU(help_keymenu, help_keys);
+@@ -77,7 +77,7 @@
+ static struct key gripe_modal_keys[] =
+ {NULL_MENU,
+ NULL_MENU,
+- {"Ret","Finished",{MC_EXIT,2,{ctrl('m'),ctrl('j')}},KS_NONE},
++ {"Ret","完畢",{MC_EXIT,2,{ctrl('m'),ctrl('j')}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -269,7 +269,7 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = CharStar;
+- sargs.text.desc = "help text";
++ sargs.text.desc = "輔助說明文字";
+ sargs.text.handles = handles;
+ if(!(sargs.bar.title = title)){
+ if(!struncmp(shown_text[0], "<html>", 6)){
+@@ -297,7 +297,7 @@
+ }
- #ifndef TCPSTREAM
- #define TCPSTREAM void
-@@ -1076,31 +1077,31 @@
- */
- static struct headerentry he_template[]={
- {"From : ", "From", h_composer_from, 10, 0, NULL,
-- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
-+ build_address, NULL, NULL, addr_book_compose, "地址列表",
- 0, 1, 0, 1, 0, 1, 0, 0, 0, KS_TOADDRBOOK},
- {"Reply-To: ", "Reply To", h_composer_reply_to, 10, 0, NULL,
-- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
-+ build_address, NULL, NULL, addr_book_compose, "地址列表",
- 0, 1, 0, 1, 0, 1, 0, 0, 0, KS_TOADDRBOOK},
- {"To : ", "To", h_composer_to, 10, 0, NULL,
-- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
-+ build_address, NULL, NULL, addr_book_compose, "地址列表",
- 0, 1, 0, 0, 0, 1, 0, 0, 0, KS_TOADDRBOOK},
- {"Cc : ", "Cc", h_composer_cc, 10, 0, NULL,
-- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
-+ build_address, NULL, NULL, addr_book_compose, "地址列表",
- 0, 1, 0, 0, 0, 1, 0, 0, 0, KS_TOADDRBOOK},
- {"Bcc : ", "Bcc", h_composer_bcc, 10, 0, NULL,
-- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
-+ build_address, NULL, NULL, addr_book_compose, "地址列表",
- 0, 1, 0, 1, 0, 1, 0, 0, 0, KS_TOADDRBOOK},
- {"Newsgrps: ", "Newsgroups", h_composer_news, 10, 0, NULL,
-- news_build, NULL, NULL, news_group_selector, "To NwsGrps",
-+ news_build, NULL, NULL, news_group_selector, "新聞組群列表",
- 0, 1, 0, 1, 0, 1, 0, 0, 0, KS_NONE},
- {"Fcc : ", "Fcc", h_composer_fcc, 10, 0, NULL,
-- NULL, NULL, NULL, folders_for_fcc, "To Fldrs",
-+ NULL, NULL, NULL, folders_for_fcc, "信夾列表",
- 0, 0, 0, 1, 1, 1, 0, 0, 0, KS_NONE},
- {"Lcc : ", "Lcc", h_composer_lcc, 10, 0, NULL,
-- build_addr_lcc, NULL, NULL, addr_book_compose_lcc,"To AddrBk",
-+ build_addr_lcc, NULL, NULL, addr_book_compose_lcc,"地址列表",
- 0, 1, 0, 1, 0, 1, 0, 0, 0, KS_NONE},
- {"Attchmnt: ", "Attchmnt", h_composer_attachment, 10, 0, NULL,
-- NULL, NULL, NULL, NULL, "To Files",
-+ NULL, NULL, NULL, NULL, "檔案列表",
- 0, 1, 1, 0, 0, 1, 0, 0, 0, KS_NONE},
- {"Subject : ", "Subject", h_composer_subject, 10, 0, NULL,
- valid_subject, NULL, NULL, NULL, NULL,
-@@ -1132,7 +1133,7 @@
+ if(!sargs.bar.title)
+- sargs.bar.title = "HELP TEXT";
++ sargs.bar.title = "輔助說明文字";
+ }
- static struct headerentry he_custom_addr_templ={
- NULL, NULL, h_composer_custom_addr,10, 0, NULL,
-- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
-+ build_address, NULL, NULL, addr_book_compose, "地址列表",
- 0, 1, 0, 1, 0, 1, 0, 0, 0, KS_TOADDRBOOK};
- static struct headerentry he_custom_free_templ={
- NULL, NULL, h_composer_custom_free,10, 0, NULL,
-@@ -1407,7 +1408,7 @@
- ekey[0].ch = ctrl('T');
- ekey[0].rval = 2;
- ekey[0].name = "^T";
-- ekey[0].label = "To AddrBk";
-+ ekey[0].label = "地址列表";
- ekey[1].ch = -1;
+ sargs.bar.style = TextPercent;
+@@ -313,13 +313,13 @@
+ setbitmap(sargs.keys.bitmap);
+ if(flags & HLPD_FROMHELP){
+ km.keys[HLP_EXIT_KEY].name = "P";
+- km.keys[HLP_EXIT_KEY].label = "Prev Help";
++ km.keys[HLP_EXIT_KEY].label = "前一說明";
+ km.keys[HLP_EXIT_KEY].bind.cmd = MC_FINISH;
+ km.keys[HLP_EXIT_KEY].bind.ch[0] = 'p';
+ }
+ else{
+ km.keys[HLP_EXIT_KEY].name = "E";
+- km.keys[HLP_EXIT_KEY].label = "Exit Help";
++ km.keys[HLP_EXIT_KEY].label = "離開";
+ km.keys[HLP_EXIT_KEY].bind.cmd = MC_EXIT;
+ km.keys[HLP_EXIT_KEY].bind.ch[0] = 'e';
+ clrbitn(HLP_SUBEXIT_KEY, sargs.keys.bitmap);
+@@ -478,7 +478,7 @@
+ }
- /*----------------------------------------------------------------------
-@@ -3419,12 +3420,12 @@
- opts[i].ch = 'y';
- opts[i].rval = 'y';
- opts[i].name = "Y";
-- opts[i++].label = "Yes";
-+ opts[i++].label = "是";
+ sparms->keys.menu->keys[HLP_VIEW_HANDLE].name = "V";
+- sparms->keys.menu->keys[HLP_VIEW_HANDLE].label = "[View Link]";
++ sparms->keys.menu->keys[HLP_VIEW_HANDLE].label = "[檢視連結]";
+ }
+ }
- opts[i].ch = 'n';
- opts[i].rval = 'n';
- opts[i].name = "N";
-- opts[i++].label = "No";
-+ opts[i++].label = "否";
+@@ -559,7 +559,7 @@
+ #endif
+ if(ps_global->intr_pending){
+ q_status_message(SM_ORDER, 3, 3,
+- "Print of all help cancelled");
++ "取消列印所有的輔助說明");
+ break;
+ }
- if(filters){
- /* set global_filter_pointer to desired filter or NULL if none */
+@@ -948,7 +948,7 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = tmp_text;
+ sargs.text.src = CharStar;
+- sargs.text.desc = "journal";
++ sargs.text.desc = "日誌";
+ sargs.bar.title = title;
+ sargs.start.on = LastPage;
+
+@@ -1304,7 +1304,7 @@
+ #endif
+ }
+ else if(ch == 'x'){
+- q_status_message(SM_ORDER, 0, 3, "Bug report cancelled.");
++ q_status_message(SM_ORDER, 0, 3, "取消錯誤回報。");
+ return(-1);
+ }
+ }
diff --git a/chinese/pine4/files/patch-au b/chinese/pine4/files/patch-au
index e94ec47a26be..9cb237ecf3fd 100644
--- a/chinese/pine4/files/patch-au
+++ b/chinese/pine4/files/patch-au
@@ -1,48 +1,326 @@
---- pico/composer.c.orig Sat Jan 17 20:06:00 1998
-+++ pico/composer.c Sat Jan 17 20:09:52 1998
-@@ -164,12 +164,12 @@
-
-
- static KEYMENU menu_header[] = {
-- {"^G", "Get Help", KS_SCREENHELP}, {"^X", "Send", KS_SEND},
-- {"^R", "Rich Hdr", KS_RICHHDR}, {"^Y", "PrvPg/Top", KS_PREVPAGE},
-- {"^K", "Cut Line", KS_CURPOSITION}, {"^O", "Postpone", KS_POSTPONE},
-- {"^C", "Cancel", KS_CANCEL}, {"^D", "Del Char", KS_NONE},
-- {"^J", "Attach", KS_ATTACH}, {"^V", "NxtPg/End", KS_NEXTPAGE},
-- {"^U", "UnDel Line", KS_NONE}, {NULL, NULL}
-+ {"^G", "輔助說明", KS_SCREENHELP}, {"^X", "送出", KS_SEND},
-+ {"^R", "完整標頭", KS_RICHHDR}, {"^Y", "上一頁", KS_PREVPAGE},
-+ {"^K", "剪下一行", KS_CURPOSITION}, {"^O", "暫緩寫信", KS_POSTPONE},
-+ {"^C", "取消", KS_CANCEL}, {"^D", "刪除字元", KS_NONE},
-+ {"^J", "夾附件", KS_ATTACH}, {"^V", "下一頁", KS_NEXTPAGE},
-+ {"^U", "恢復刪除", KS_NONE}, {NULL, NULL}
- };
- #define SEND_KEY 1
- #define RICH_KEY 2
-@@ -3110,22 +3110,22 @@
- menu_header[DEL_KEY].name = NULL;
- menu_header[UDEL_KEY].name = NULL;
- menu_header[SEND_KEY].label = (gmode & MDHDRONLY)
-- ? "eXit/Save" : "eXit";
-+ ? "離開/儲存" : "離開";
- }
- else{
- menu_header[CUT_KEY].name = "^K";
- menu_header[DEL_KEY].name = "^D";
- menu_header[UDEL_KEY].name = "^U";
-- menu_header[SEND_KEY].label = "Send";
-+ menu_header[SEND_KEY].label = "送出";
- }
-
- if(gmode & MDHDRONLY){
-- menu_header[RICH_KEY].label = "RichView";
-+ menu_header[RICH_KEY].label = "完整標頭";
- menu_header[PONE_KEY].name = NULL;
- menu_header[ATT_KEY].name = NULL;
- }
- else{
-- menu_header[RICH_KEY].label = "Rich Hdr";
-+ menu_header[RICH_KEY].label = "完整標頭";
- menu_header[PONE_KEY].name = "^O";
- menu_header[ATT_KEY].name = "^J";
+--- pine/mailindx.c.orig Wed Jul 1 03:49:02 1998
++++ pine/mailindx.c Wed Jul 15 17:02:33 1998
+@@ -55,10 +55,10 @@
+ /*
+ * Some common Command Bindings
+ */
+-#define VIEWMSG_MENU {">", "[ViewMsg]", \
++#define VIEWMSG_MENU {">", "[檢視信件]", \
+ {MC_VIEW_TEXT, 5,{'v','.','>',ctrl('M'),ctrl('J')}}, \
+ KS_VIEW}
+-#define FLDRSORT_MENU {"$", "SortIndex", {MC_SORT,1,{'$'}}, KS_SORT}
++#define FLDRSORT_MENU {"$", "排序索引", {MC_SORT,1,{'$'}}, KS_SORT}
+
+
+ /*
+@@ -67,7 +67,7 @@
+ static struct key index_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"<", "FldrList", {MC_FOLDERS,2,{'<',','}}, KS_NONE},
++ {"<", "信件匣列表", {MC_FOLDERS,2,{'<',','}}, KS_NONE},
+ VIEWMSG_MENU,
+ PREVMSG_MENU,
+ NEXTMSG_MENU,
+@@ -94,9 +94,9 @@
+ HELP_MENU,
+ OTHER_MENU,
+ {"X",NULL,{MC_EXPUNGE,1,{'x'}},KS_NONE},
+- {"&","unXclude",{MC_UNEXCLUDE,1,{'&'}},KS_NONE},
+- {";","Select",{MC_SELECT,1,{';'}},KS_SELECT},
+- {"A","Apply",{MC_APPLY,1,{'a'}},KS_APPLY},
++ {"&","取消排除(exclude)",{MC_UNEXCLUDE,1,{'&'}},KS_NONE},
++ {";","選擇",{MC_SELECT,1,{';'}},KS_SELECT},
++ {"A","套用",{MC_APPLY,1,{'a'}},KS_APPLY},
+ FLDRSORT_MENU,
+ JUMP_MENU,
+ HDRMODE_MENU,
+@@ -106,8 +106,8 @@
+
+ HELP_MENU,
+ OTHER_MENU,
+- {":","SelectCur",{MC_SELCUR,1,{':'}},KS_SELECTCUR},
+- {"Z","ZoomMode",{MC_ZOOM,1,{'z'}},KS_NONE},
++ {":","選擇",{MC_SELCUR,1,{':'}},KS_SELECTCUR},
++ {"Z","縮放模式",{MC_ZOOM,1,{'z'}},KS_NONE},
+ LISTFLD_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -175,9 +175,9 @@
+
+ static struct key simple_index_keys[] =
+ {HELP_MENU,
+- {"E","ExitSelect",{MC_EXIT,1,{'e'}},KS_EXITMODE},
++ {"E","離開",{MC_EXIT,1,{'e'}},KS_EXITMODE},
+ NULL_MENU,
+- {"S","[Select]",{MC_SELECT,3,{'s',ctrl('M'),ctrl('J')}},KS_SELECT},
++ {"S","[選擇]",{MC_SELECT,3,{'s',ctrl('M'),ctrl('J')}},KS_SELECT},
+ PREVMSG_MENU,
+ NEXTMSG_MENU,
+ PREVPAGE_MENU,
+@@ -344,14 +344,14 @@
+ if(flags & INDX_HEADER)
+ set_titlebar((stream == ps_global->mail_stream)
+ ? (style == MsgIndex || style == MultiMsgIndex)
+- ? "MESSAGE INDEX"
+- : "ZOOMED MESSAGE INDEX"
++ ? "信件索引"
++ : "縮放後的信件索引"
+ : (!strcmp(folder, INTERRUPTED_MAIL))
+- ? "COMPOSE: SELECT INTERRUPTED"
++ ? "編輯:選擇被中斷的"
+ : (ps_global->VAR_FORM_FOLDER
+ && !strcmp(ps_global->VAR_FORM_FOLDER, folder))
+- ? "COMPOSE: SELECT FORM LETTER"
+- : "COMPOSE: SELECT POSTPONED",
++ ? "編輯:選擇樣版信件"
++ : "編輯:選擇被暫緩的",
+ stream, cntxt, folder, msgmap, 1, MessageNumber, 0, 0);
+
+ if(flags & INDX_FOOTER) {
+@@ -398,6 +398,7 @@
+
+ menu_clear_binding(km, KEY_LEFT);
+ menu_clear_binding(km, KEY_RIGHT);
++
+ if(F_ON(F_ARROW_NAV, ps_global)){
+ if((cmd = menu_clear_binding(km, '<')) != MC_UNKNOWN){
+ menu_add_binding(km, '<', cmd);
+@@ -443,7 +444,7 @@
+ {
+ dprint(1, (debugfile, "\n\n ---- MAIL INDEX ----\n"));
+ if(!state->mail_stream) {
+- q_status_message(SM_ORDER, 0, 3, "No folder is currently open");
++ q_status_message(SM_ORDER, 0, 3, "目前尚無已開啟的信件匣");
+ state->prev_screen = mail_index_screen;
+ state->next_screen = main_menu_screen;
+ return;
+@@ -624,7 +625,7 @@
+ if(F_ON(F_SHOW_CURSOR, state) && cur_row < 0){
+ q_status_message(SM_ORDER,
+ (ch==NO_OP_IDLE || ch==NO_OP_COMMAND) ? 0 : 3, 5,
+- "No messages in folder");
++ "信件匣中沒有信");
+ cur_row = state->ttyo->screen_rows - FOOTER_ROWS(state);
+ display_message(ch);
+ }
+@@ -741,7 +742,7 @@
+ k = i;
+ if(++j >= id.lines_per_page){
+ if((id.msg_at_top = i) == 1L)
+- q_status_message(SM_ORDER, 0, 1, "First Index page");
++ q_status_message(SM_ORDER, 0, 1, "索引第一頁");
+
+ break;
+ }
+@@ -750,7 +751,7 @@
+ if(i <= 1L){
+ if(mn_get_cur(msgmap) == 1L)
+ q_status_message(SM_ORDER, 0, 1,
+- "Already at start of Index");
++ "已經在索引的起頭了");
+
+ break;
+ }
+@@ -770,7 +771,7 @@
+ k = i;
+ if(++j >= id.lines_per_page){
+ if(i+id.lines_per_page >= mn_get_total(msgmap))
+- q_status_message(SM_ORDER, 0, 1, "Last Index page");
++ q_status_message(SM_ORDER, 0, 1, "索引最終頁");
+
+ id.msg_at_top = i;
+ break;
+@@ -779,7 +780,7 @@
+
+ if(i >= mn_get_total(msgmap)){
+ if(mn_get_cur(msgmap) == k)
+- q_status_message(SM_ORDER,0,1,"Already at end of Index");
++ q_status_message(SM_ORDER,0,1,"已經在索引的結尾了");
+
+ break;
+ }
+@@ -961,9 +962,9 @@
+ }
+
+ q_status_message2(SM_ORDER, 0, 1,
+- "Message %s %sdeleted",
++ "信件 %s %s刪除",
+ long2string(mn_get_cur(msgmap)),
+- (del) ? "" : "already ");
++ (del) ? "" : "已");
+ }
+
+ break;
+@@ -985,9 +986,9 @@
+ }
+
+ q_status_message2(SM_ORDER, 0, 1,
+- "Message %s %sdeleted",
++ "信件 %s %s刪除",
+ long2string(mn_get_cur(msgmap)),
+- (del) ? "UN" : "NOT ");
++ (del) ? "已遭復原" : "未被");
+ }
+
+ break;
+@@ -1787,7 +1788,7 @@
+ dprint(1, (debugfile,
+ "parse_index_format: unrecognized token: %s\n", q));
+ q_status_message1(SM_ORDER | SM_DING, 0, 3,
+- "Unrecognized string in index-format: %s", q);
++ "索引格式中出現無法辨識的字串:%s", q);
+ continue;
+ }
+
+@@ -1829,7 +1830,7 @@
+ if(!column){
+ dprint(1, (debugfile, "Completely unrecognizable index-format\n"));
+ q_status_message(SM_ORDER | SM_DING, 0, 3,
+- "Configured \"index-format\" unrecognizable. Using default.");
++ "無法辨識已設定的 \"index-format\"。使用預設值。");
+ return(0);
}
+
+@@ -2320,7 +2321,7 @@
+ sprintf(str, "%ld", idata->msgno);
+ else if(idata->bogus < 2 && cdesc->ctype == iSubject)
+ sprintf(str, "%-*.*s", width, width,
+- "[ No Message Text Available ]");
++ "[ 無法取得信件 ]");
+ }
+ else
+ switch(cdesc->ctype){
+@@ -2954,8 +2955,8 @@
+ HelpType help;
+ static char search_string[MAX_SEARCH+1] = { '\0' };
+ static ESCKEY_S header_search_key[] = { {0, 0, NULL, NULL },
+- {ctrl('Y'), 10, "^Y", "First Msg"},
+- {ctrl('V'), 11, "^V", "Last Msg"},
++ {ctrl('Y'), 10, "^Y", "第一封信"},
++ {ctrl('V'), 11, "^V", "最後一封信"},
+ {-1, 0, NULL, NULL} };
+
+ dprint(4, (debugfile, "\n - search headers - \n"));
+@@ -2964,7 +2965,7 @@
+ return;
+ }
+ else if(mn_total_cur(msgmap) > 1L){
+- q_status_message1(SM_ORDER, 0, 2, "%s msgs selected; Can't search",
++ q_status_message1(SM_ORDER, 0, 2, "已選擇 %s 封信件;無法搜尋",
+ comatose(mn_total_cur(msgmap)));
+ return;
+ }
+@@ -2975,13 +2976,13 @@
+ new_string[0] = '\0';
+
+ while(1) {
+- sprintf(prompt, "Word to search for [%s] : ", search_string);
++ sprintf(prompt, "搜尋[%s]:", search_string);
+
+ if(F_ON(F_ENABLE_AGG_OPS, ps_global)){
+ header_search_key[0].ch = ctrl('X');
+ header_search_key[0].rval = 12;
+ header_search_key[0].name = "^X";
+- header_search_key[0].label = "Select Matches";
++ header_search_key[0].label = "選取符合者";
+ }
+ else{
+ header_search_key[0].ch = header_search_key[0].rval = 0;
+@@ -3000,7 +3001,7 @@
+ continue;
+ }
+ else if(rc == 10){
+- q_status_message(SM_ORDER, 0, 3, "Searched to First Message.");
++ q_status_message(SM_ORDER, 0, 3, "搜尋至第一封信件。");
+ if(any_lflagged(msgmap, MN_HIDE)){
+ do{
+ selected = sorted_msg;
+@@ -3016,7 +3017,7 @@
+ return;
+ }
+ else if(rc == 11){
+- q_status_message(SM_ORDER, 0, 3, "Searched to Last Message.");
++ q_status_message(SM_ORDER, 0, 3, "搜尋至最後一封信件。");
+ if(any_lflagged(msgmap, MN_HIDE)){
+ do{
+ selected = sorted_msg;
+@@ -3041,7 +3042,7 @@
+ }
+
+ if(rc == 1 || (new_string[0] == '\0' && search_string[0] == '\0')) {
+- cmd_cancelled("Search");
++ cmd_cancelled("搜尋");
+ return;
+ }
+
+@@ -3080,21 +3081,21 @@
+ }
+
+ if(ps_global->intr_pending){
+- q_status_message1(SM_ORDER, 0, 3, "Search cancelled.%s",
++ q_status_message1(SM_ORDER, 0, 3, "取消搜尋。%s",
+ select_all ? " Selected set may be incomplete.":"");
+ }
+ else if(select_all){
+- q_status_message1(SM_ORDER, 0, 3, "%s messages found matching word",
++ q_status_message1(SM_ORDER, 0, 3, "共 %s 封信件找到符合的字串",
+ long2string(selected));
+ }
+ else if(selected){
+- q_status_message1(SM_ORDER, 0, 3, "Word found%s",
++ q_status_message1(SM_ORDER, 0, 3, "字串已找到%s",
+ (i <= sorted_msg)
+- ? ". Search wrapped to beginning" : "");
++ ? "。重頭搜尋" : "");
+ mn_set_cur(msgmap, i);
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "Word not found");
++ q_status_message(SM_ORDER, 0, 3, "找不到字串");
+
+ #ifndef DOS
+ intr_handling_off();
+@@ -3232,7 +3233,7 @@
+ && LEVELSORT(ps_global->mail_stream)))
+ sort_func = percent_sorted;
+
+- sprintf(sort_msg, "Sorting \"%s\"",
++ sprintf(sort_msg, "正在排序 \"%s\"",
+ strsquish(tmp_20k_buf + 500, ps_global->cur_folder,
+ ps_global->ttyo->screen_cols - 20));
+ we_cancel = busy_alarm(1, sort_msg, sort_func, 1);
+@@ -3284,8 +3285,8 @@
+ new_sort = mn_get_sort(msgmap);
+ new_rev = mn_get_revsort(msgmap);
+ q_status_message2(SM_ORDER, 3, 3,
+- "Sort %s! Restored %s sort.",
+- g_sort_prog->abort ? "Canceled" : "Failed",
++ "排序%s!回復至 %s 排序。",
++ g_sort_prog->abort ? "已取消" : "失敗",
+ sort_name(new_sort));
+ }
+ else if(mn_get_total(msgmap) < g_sort_prog->nmsgs)
+@@ -4043,7 +4044,7 @@
+ icache.name = temp_nam(NULL, "pi");
+
+ if((icache.cache = (void *)fopen(icache.name,"w+b")) == NULL){
+- sprintf(tmp_20k_buf, "Can't open index cache: %s",icache.name);
++ sprintf(tmp_20k_buf, "無法開啟索引快取:%s",icache.name);
+ fatal(tmp_20k_buf);
+ }
+
+@@ -4396,10 +4397,10 @@
+ && format_message(mn_m2raw(ps_global->msgmap,
+ mn_get_cur(ps_global->msgmap)),
+ env, body, FM_NEW_MESS, pc)){
+- sprintf(title, "Folder %s -- Message %ld of %ld",
++ sprintf(title, "信件匣 %s -- %ld 封信件中的第 %ld 封",
+ strsquish(tmp_20k_buf + 500, ps_global->cur_folder, 50),
+- mn_get_cur(ps_global->msgmap),
+- mn_get_total(ps_global->msgmap));
++ mn_get_total(ps_global->msgmap),
++ mn_get_cur(ps_global->msgmap));
+ *text = so_text(so);
+ *l = strlen((char *)so_text(so));
+ *style = GETTEXT_TEXT;
diff --git a/chinese/pine4/files/patch-av b/chinese/pine4/files/patch-av
index 4cf184942472..fd3084b81bcf 100644
--- a/chinese/pine4/files/patch-av
+++ b/chinese/pine4/files/patch-av
@@ -1,120 +1,307 @@
---- pico/display.c.orig Sat Jan 31 15:57:10 1998
-+++ pico/display.c Sat Jan 31 16:07:16 1998
-@@ -76,32 +76,32 @@
- * Standard pico keymenus...
- */
- static KEYMENU menu_pico[] = {
-- {"^G", "Get Help", KS_SCREENHELP}, {"^O", "WriteOut", KS_SAVEFILE},
-- {"^R", "Read File", KS_READFILE}, {"^Y", "Prev Pg", KS_PREVPAGE},
-- {"^K", "Cut Text", KS_NONE}, {"^C", "Cur Pos", KS_CURPOSITION},
-- {"^X", "Exit", KS_EXIT}, {"^J", "Justify", KS_JUSTIFY},
-- {"^W", "Where is", KS_WHEREIS}, {"^V", "Next Pg", KS_NEXTPAGE},
-+ {"^G", "輔助說明", KS_SCREENHELP}, {"^O", "暫停工作", KS_SAVEFILE},
-+ {"^R", "讀取檔案", KS_READFILE}, {"^Y", "上一頁", KS_PREVPAGE},
-+ {"^K", "剪下一行", KS_NONE}, {"^C", "目前位置", KS_CURPOSITION},
-+ {"^X", "離開", KS_EXIT}, {"^J", "重整段落", KS_JUSTIFY},
-+ {"^W", "搜尋", KS_WHEREIS}, {"^V", "下一頁", KS_NEXTPAGE},
- {"^U", NULL, KS_NONE},
- #if defined(SPELLER) && !defined(__FreeBSD__)
-- {"^T", "To Spell", KS_SPELLCHK}
-+ {"^T", "拼字檢查", KS_SPELLCHK}
- #else
-- {"^D", "Del Char", KS_NONE}
-+ {"^D", "刪除字元", KS_NONE}
- #endif
- };
- #define UNCUT_KEY 10
-
-
- static KEYMENU menu_compose[] = {
-- {"^G", "Get Help", KS_SCREENHELP}, {"^X", NULL, KS_SEND},
-- {"^R", "Read File", KS_READFILE}, {"^Y", "Prev Pg", KS_PREVPAGE},
-- {"^K", "Cut Text", KS_NONE}, {"^O", "Postpone", KS_POSTPONE},
-- {"^C", "Cancel", KS_CANCEL}, {"^J", "Justify", KS_JUSTIFY},
-- {NULL, NULL, KS_NONE}, {"^V", "Next Pg", KS_NEXTPAGE},
-+ {"^G", "輔助說明", KS_SCREENHELP}, {"^X", NULL, KS_SEND},
-+ {"^R", "讀取檔案", KS_READFILE}, {"^Y", "上一頁", KS_PREVPAGE},
-+ {"^K", "剪下一行", KS_NONE}, {"^O", "暫緩寫信", KS_POSTPONE},
-+ {"^C", "取消", KS_CANCEL}, {"^J", "重整段落", KS_JUSTIFY},
-+ {NULL, NULL, KS_NONE}, {"^V", "下一頁", KS_NEXTPAGE},
- {"^U", NULL, KS_NONE},
- #ifdef SPELLER
-- {"^T", "To Spell", KS_SPELLCHK}
-+ {"^T", "拼字檢查", KS_SPELLCHK}
- #else
-- {"^D", "Del Char", KS_NONE}
-+ {"^D", "刪除字元", KS_NONE}
- #endif
- };
- #define EXIT_KEY 1
-@@ -737,12 +737,12 @@
+--- pine/mailpart.c.orig Fri Jun 26 02:28:42 1998
++++ pine/mailpart.c Wed Jul 15 17:02:34 1998
+@@ -135,18 +135,18 @@
+ {HELP_MENU,
+ OTHER_MENU,
+ {"<",NULL,{MC_EXIT,2,{'<',','}},KS_EXITMODE},
+- {">","[View]",{MC_VIEW_ATCH,5,{'v','>','.',ctrl('M'),ctrl('J')}},
++ {">","[檢視]",{MC_VIEW_ATCH,5,{'v','>','.',ctrl('M'),ctrl('J')}},
+ KS_VIEW},
+- {"P", "PrevAttch",{MC_PREVITEM,4,{'p',ctrl('B'),ctrl('P'),KEY_UP}},
++ {"P", "前一附件",{MC_PREVITEM,4,{'p',ctrl('B'),ctrl('P'),KEY_UP}},
+ KS_PREVMSG},
+- {"N", "NextAtch",
++ {"N", "次一附件",
+ {MC_NEXTITEM, 5, {'n','\t',ctrl('F'),ctrl('N'), KEY_DOWN}},
+ KS_NEXTMSG},
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ DELETE_MENU,
+ UNDELETE_MENU,
+- {"S", "Save", {MC_SAVETEXT,1,{'s'}}, KS_SAVE},
++ {"S", "存檔", {MC_SAVETEXT,1,{'s'}}, KS_SAVE},
+ {NULL, NULL, {MC_EXPORT, 1, {'e'}}, KS_EXPORT},
+
+ HELP_MENU,
+@@ -155,9 +155,9 @@
+ QUIT_MENU,
+ PIPE_MENU,
+ BOUNCE_MENU,
+- {"A","AboutAttch",{MC_ABOUTATCH,1,{'a'}},KS_NONE},
++ {"A","關於附件",{MC_ABOUTATCH,1,{'a'}},KS_NONE},
+ WHEREIS_MENU,
+- {"%", "Print", MC_PRINTMSG,1,{'%'}, KS_PRINT},
++ {"%", "列印", MC_PRINTMSG,1,{'%'}, KS_PRINT},
+ INDEX_MENU,
+ REPLY_MENU,
+ FORWARD_MENU};
+@@ -174,11 +174,11 @@
+ static struct key att_view_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"<",NULL,{MC_EXIT,2,{'<',','}},KS_EXITMODE},
+- {"Ret","[View Hilite]",{MC_VIEW_HANDLE,3,
++ {"<",NULL,{MC_EXIT,3,{'<',',',KEY_LEFT}},KS_EXITMODE},
++ {"Ret","[檢視 Hilite]",{MC_VIEW_HANDLE,3,
+ {ctrl('m'),ctrl('j'),KEY_RIGHT}},KS_NONE},
+- {"^B","Prev URL",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
+- {"^F","Next URL",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
++ {"^B","前一 URL",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
++ {"^F","次一 URL",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ DELETE_MENU,
+@@ -194,7 +194,7 @@
+ BOUNCE_MENU,
+ NULL_MENU,
+ WHEREIS_MENU,
+- {"%", "Print", MC_PRINTMSG,1,{'%'}, KS_PRINT},
++ {"%", "列印", MC_PRINTMSG,1,{'%'}, KS_PRINT},
+ NULL_MENU,
+ REPLY_MENU,
+ FORWARD_MENU};
+@@ -324,12 +324,12 @@
+
+ if(mn_total_cur(ps->msgmap) > 1L){
+ q_status_message(SM_ORDER | SM_DING, 0, 3,
+- "Can only view one message's attachments at a time!");
++ "同一時間僅能檢視一封信的附件!");
+ return;
+ }
+ else if(ps->atmts && !(ps->atmts + 1)->description)
+ q_status_message1(SM_ASYNC, 0, 3,
+- "Message %s has only one part (the message body), and no attachments.",
++ "信件 %s 僅有一部分(信件本體),沒有附件。",
+ long2string(mn_get_cur(ps->msgmap)));
+
+ /*
+@@ -465,7 +465,7 @@
+ break;
+
+ if(ps->mangled_header){
+- set_titlebar("ATTACHMENT INDEX", ps->mail_stream,
++ set_titlebar("附件索引", ps->mail_stream,
+ ps->context_current, ps->cur_folder, ps->msgmap, 1,
+ MessageNumber, 0, 0);
+ ps->mangled_header = 0;
+@@ -529,7 +529,7 @@
+ clrbitn(ATT_PRINT_KEY, bitmap);
+
+ km->keys[ATT_EXPORT_KEY].name = "E";
+- km->keys[ATT_EXPORT_KEY].label = "Export";
++ km->keys[ATT_EXPORT_KEY].label = "匯出";
}
- if(lastflag&CFFILL){
-- menu_pico[UNCUT_KEY].label = "UnJustify";
-+ menu_pico[UNCUT_KEY].label = "取消重整";
- emlwrite("Can now UnJustify!", NULL);
- mpresf = HUGE; /* remove this after next keystroke! */
+ if(km_popped){
+@@ -624,7 +624,7 @@
+ if(ctmp = next_attline(current))
+ current = ctmp;
+ else
+- q_status_message(SM_ORDER, 0, 1, "Already on last attachment");
++ q_status_message(SM_ORDER, 0, 1, "已經到最後一附件了");
+
+ break;
+
+@@ -632,7 +632,7 @@
+ if(ctmp = prev_attline(current))
+ current = ctmp;
+ else
+- q_status_message(SM_ORDER, 0, 1, "Already on first attachment");
++ q_status_message(SM_ORDER, 0, 1, "已經到第一個附件了");
+
+ break;
+
+@@ -646,7 +646,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on last page of attachments");
++ "已經在附件的最後一頁了");
+
+
+ break;
+@@ -667,7 +667,7 @@
}
else
-- menu_pico[UNCUT_KEY].label = "UnCut Text";
-+ menu_pico[UNCUT_KEY].label = "復原刪字";
-
- wkeyhelp(menu_pico);
- sgarbk = FALSE;
-@@ -932,18 +932,18 @@
- ShowPrompt();
- else{
- menu_compose[EXIT_KEY].label = (Pmaster->headents)
-- ? "Send" :"Exit";
-+ ? "送出" :"離開";
- menu_compose[PSTPN_KEY].name = (Pmaster->headents)
- ? "^O" : NULL;
- menu_compose[PSTPN_KEY].label = (Pmaster->headents)
-- ? "Postpone" : NULL;
-+ ? "暫緩寫信" : NULL;
- menu_compose[WHERE_KEY].name = (Pmaster->alt_ed) ? "^_" : "^W";
- menu_compose[WHERE_KEY].label = (Pmaster->alt_ed) ? "Alt Edit"
-- : "Where is";
-+ : "搜尋";
- KS_OSDATASET(&menu_compose[WHERE_KEY],
- (Pmaster->alt_ed) ? KS_ALTEDITOR : KS_WHEREIS);
-- menu_compose[UNCUT_KEY].label = (thisflag&CFFILL) ? "UnJustify"
-- : "UnCut Text";
-+ menu_compose[UNCUT_KEY].label = (thisflag&CFFILL) ? "取消重整"
-+ : "復原刪字";
- wkeyhelp(menu_compose);
- #ifdef _WINDOWS
- /* When alt editor is available "Where is" is not on the menu
-@@ -1134,11 +1134,11 @@
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on first page of attachments");
++ "已經在附件的第一頁了");
+
+ break;
+
+@@ -1035,7 +1035,7 @@
+ {
+ bitmap_t bitmap;
+
+- set_titlebar("ATTACHMENT INDEX", ps_global->mail_stream,
++ set_titlebar("附件索引", ps_global->mail_stream,
+ ps_global->context_current, ps_global->cur_folder,
+ ps_global->msgmap, 1, FolderName,0,0);
+
+@@ -1204,7 +1204,7 @@
+ gf_io_t pc;
+ STORE_S *store;
+ static ESCKEY_S att_save_opts[] = {
+- {ctrl('T'), 10, "^T", "To Files"},
++ {ctrl('T'), 10, "^T", "檔案列表"},
+ {-1, 0, NULL, NULL},
+ {-1, 0, NULL, NULL},
+ {-1, 0, NULL, NULL}};
+@@ -1236,7 +1236,7 @@
+ att_save_opts[++r].ch = ctrl('V');
+ att_save_opts[r].rval = 12;
+ att_save_opts[r].name = "^V";
+- att_save_opts[r].label = "Downld Msg";
++ att_save_opts[r].label = "下載信件";
}
+ #endif /* !(DOS || MAC) */
- menu_yesno[1].name = "Y";
-- menu_yesno[1].label = (dflt == TRUE) ? "[Yes]" : "Yes";
-+ menu_yesno[1].label = (dflt == TRUE) ? "[是]" : "是";
- menu_yesno[6].name = "^C";
- menu_yesno[6].label = "Cancel";
- menu_yesno[7].name = "N";
-- menu_yesno[7].label = (dflt == FALSE) ? "[No]" : "No";
-+ menu_yesno[7].label = (dflt == FALSE) ? "[否]" : "否";
- wkeyhelp(menu_yesno); /* paint generic menu */
- sgarbk = TRUE; /* mark menu dirty */
- if(Pmaster && curwp)
-@@ -1304,7 +1304,7 @@
- #endif
-
- menu_mlreply[0].name = "^G";
-- menu_mlreply[0].label = "Get Help";
-+ menu_mlreply[0].label = "輔助說明";
- KS_OSDATASET(&menu_mlreply[0], KS_SCREENHELP);
- for(j = 0, i = 1; i < 6; i++){ /* insert odd extras */
- menu_mlreply[i].name = NULL;
-@@ -1324,7 +1324,7 @@
+@@ -1244,7 +1244,7 @@
+ att_save_opts[++r].ch = ctrl('I');
+ att_save_opts[r].rval = 11;
+ att_save_opts[r].name = "TAB";
+- att_save_opts[r].label = "Complete";
++ att_save_opts[r].label = "完成";
}
- menu_mlreply[6].name = "^C";
-- menu_mlreply[6].label = "Cancel";
-+ menu_mlreply[6].label = "取消";
- KS_OSDATASET(&menu_mlreply[6], KS_NONE);
- for(j = 0, i = 7; i < 12; i++){ /* insert even extras */
- menu_mlreply[i].name = NULL;
+ att_save_opts[++r].ch = -1;
+@@ -1597,7 +1597,7 @@
+ ATTACH_S *ap = a;
+ STORE_S *store;
+ static ESCKEY_S opts[] = {
+- {ctrl('T'), 10, "^T", "To Files"},
++ {ctrl('T'), 10, "^T", "檔案列表"},
+ {-1, 0, NULL, NULL},
+ {-1, 0, NULL, NULL}};
+
+@@ -1605,7 +1605,7 @@
+ opts[i].ch = ctrl('I');
+ opts[i].rval = 11;
+ opts[i].name = "TAB";
+- opts[i].label = "Complete";
++ opts[i].label = "完成";
+ }
+
+ filename[0] = full_filename[0] = '\0';
+@@ -1670,7 +1670,7 @@
+ ATTACH_S *ap;
+ STORE_S *store;
+ static ESCKEY_S opts[] = {
+- {ctrl('T'), 10, "^T", "To Files"},
++ {ctrl('T'), 10, "^T", "檔案列表"},
+ {-1, 0, NULL, NULL},
+ {-1, 0, NULL, NULL}};
+
+@@ -1678,7 +1678,7 @@
+ opts[i].ch = ctrl('I');
+ opts[i].rval = 11;
+ opts[i].name = "TAB";
+- opts[i].label = "Complete";
++ opts[i].label = "完成";
+ }
+
+ filename[0] = full_filename[0] = '\0';
+@@ -1899,14 +1899,14 @@
+ /*----- Can't display this type ------*/
+ if(a->body->encoding < ENCOTHER)
+ q_status_message4(SM_ORDER | SM_DING, 3, 5,
+- "Don't know how to display %s%s%s attachments.%s",
++ "不知如何顯示 %s%s%s 的附件。%s",
+ body_type_names(a->body->type),
+ a->body->subtype ? "/" : "",
+ a->body->subtype ? a->body->subtype :"",
+- (flags & DA_SAVE) ? " Try Save." : "");
++ (flags & DA_SAVE) ? " 試試存檔。" : "");
+ else
+ q_status_message1(SM_ORDER | SM_DING, 3, 5,
+- "Don't know how to unpack \"%s\" encoding",
++ "不知如何解開 \"%s\" 的編碼",
+ body_encodings[(a->body->encoding <= ENCMAX)
+ ? a->body->encoding : ENCOTHER]);
+
+@@ -2095,7 +2095,7 @@
+ gf_set_so_writec(&pc, store);
+ (void) decode_text(a, msgno, pc, QStatus, FM_DISPLAY | FM_HANDLES);
+ gf_clear_so_writec(store);
+- scroll_attachment("ATTACHED TEXT", store, src, handles, a, flags);
++ scroll_attachment("附件文字", store, src, handles, a, flags);
+ free_handles(&handles);
+ so_give(&store); /* free resources associated with store */
+ }
+@@ -2270,22 +2270,22 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = src;
+- sargs.text.desc = "attachment";
++ sargs.text.desc = "附件";
+ sargs.text.handles = handles;
+ sargs.bar.title = title;
+ sargs.proc.tool = process_attachment_cmd;
+ sargs.proc.data.p = (void *) a;
+ sargs.help.text = h_mail_text_att_view;
+- sargs.help.title = "HELP FOR ATTACHED TEXT VIEW";
++ sargs.help.title = "檢視附件文字的輔助說明";
+ sargs.keys.menu = &att_view_keymenu;
+ setbitmap(sargs.keys.bitmap);
+
+ /* First, fix up "back" key */
+ if(flags & DA_FROM_VIEW){
+- att_view_keymenu.keys[ATV_BACK_KEY].label = "MsgText";
++ att_view_keymenu.keys[ATV_BACK_KEY].label = "信件文字";
+ }
+ else{
+- att_view_keymenu.keys[ATV_BACK_KEY].label = "AttchIndex";
++ att_view_keymenu.keys[ATV_BACK_KEY].label = "附件索引";
+ }
+
+ if(!handles){
+@@ -2698,10 +2698,10 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = CharStar;
+- sargs.text.desc = "attachment info";
+- sargs.bar.title = "ABOUT ATTACHMENT";
++ sargs.text.desc = "附件資訊";
++ sargs.bar.title = "關於附件";
+ sargs.help.text = h_simple_text_view;
+- sargs.help.title = "HELP FOR \"ABOUT ATTACHMENT\"";
++ sargs.help.title = "\"關於附件\"的輔助說明";
+
+ scrolltool(&sargs);
+
+@@ -2763,7 +2763,7 @@
+ else /* partially formatted outgoing message */
+ pine_send(outgoing, &body,
+ ps_global->nr_mode
+- ? "SEND MESSAGE" : "FORWARD MESSAGE",
++ ? "送出信件" : "轉寄信件",
+ NULL, NULL, NULL, NULL, NULL, FALSE);
+
+ ps_global->mangled_screen = 1;
+@@ -2849,7 +2849,7 @@
+ pine_simple_send(outgoing, &body, NULL, NULL, NULL, 1);
+ else /* partially formatted outgoing message */
+ pine_send(outgoing, &body,
+- ps_global->nr_mode ? "SEND MESSAGE" : "FORWARD MESSAGE",
++ ps_global->nr_mode ? "送出信件" : "轉寄信件",
+ NULL, NULL, NULL, NULL, NULL, FALSE);
+
+ ps_global->mangled_screen = 1;
+@@ -2946,7 +2946,7 @@
+ tp = body_partno(stream, msgno, a->body),
+ msgtext, prefix, include_text)){
+ /* partially formatted outgoing message */
+- pine_send(outgoing, &body, "COMPOSE MESSAGE REPLY",
++ pine_send(outgoing, &body, "編輯信件回函",
+ fcc.tptr, NULL, NULL, NULL, NULL, 0);
+
+ pine_free_body(&body);
+@@ -3027,7 +3027,7 @@
+
+ sprintf(prompt, "Pipe %sattachment %s to %s: ", raw ? "RAW " : "",
+ a->number, capture ? "" : "(Free Output) ");
+- pipe_opt[1].label = raw ? "DecodedData" : "Raw Data";
++ pipe_opt[1].label = raw ? "解碼後的資料" : "原始資料";
+ pipe_opt[2].label = capture ? "Free Output" : "Capture Output";
+ flags = OE_APPEND_CURRENT | OE_SEQ_SENSITIVE;
+ rc = optionally_enter(pipe_command, -FOOTER_ROWS(ps_global), 0,
diff --git a/chinese/pine4/files/patch-aw b/chinese/pine4/files/patch-aw
index 6b6fae07015d..0a1a789a468f 100644
--- a/chinese/pine4/files/patch-aw
+++ b/chinese/pine4/files/patch-aw
@@ -1,24 +1,477 @@
---- pico/pico.c.orig Sat Jan 17 20:21:35 1998
-+++ pico/pico.c Sat Jan 17 20:23:21 1998
-@@ -585,17 +585,17 @@
+--- pine/mailview.c.orig Tue Jul 7 10:05:59 1998
++++ pine/mailview.c Wed Jul 15 17:02:35 1998
+@@ -142,8 +142,8 @@
+ static struct key view_keys[] =
+ {HELP_MENU,
+ OTHER_MENU,
+- {"<","MsgIndex",{MC_INDEX,3,{'i','<',','}},KS_FLDRINDEX},
+- {">","ViewAttch",{MC_VIEW_ATCH,3,{'v','>','.'}},KS_NONE},
++ {"<","索引",{MC_INDEX,3,{'i','<',','}},KS_FLDRINDEX},
++ {">","檢視附件",{MC_VIEW_ATCH,3,{'v','>','.'}},KS_NONE},
+ PREVMSG_MENU,
+ NEXTMSG_MENU,
+ PREVPAGE_MENU,
+@@ -168,11 +168,11 @@
+
+ HELP_MENU,
+ OTHER_MENU,
+- {"Ret","[View Hilite]",{MC_VIEW_HANDLE,3,
++ {"Ret","[檢視 Hilite]",{MC_VIEW_HANDLE,3,
+ {ctrl('m'),ctrl('j'),KEY_RIGHT}},KS_NONE},
+- {":","SelectCur",{MC_SELCUR,1,{':'}},KS_SELECTCUR},
+- {"^B","Prev URL",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
+- {"^F","Next URL",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
++ {":","選擇",{MC_SELCUR,1,{':'}},KS_SELECTCUR},
++ {"^B","前一 URL",{MC_PREV_HANDLE,1,{ctrl('B')}},KS_NONE},
++ {"^F","次一 URL",{MC_NEXT_HANDLE,1,{ctrl('F')}},KS_NONE},
+ JUMP_MENU,
+ TAB_MENU,
+ HDRMODE_MENU,
+@@ -189,7 +189,7 @@
+ #define FLAG_KEY 34
+ #define VIEW_PIPE_KEY 35
+
+-static struct key nr_anon_view_keys[] =
++static struct key nr_anon_view_keys[] =
+ {HELP_MENU,
+ WHEREIS_MENU,
+ QUIT_MENU,
+@@ -213,7 +213,7 @@
+ NEXTMSG_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"F", "Fwd Email", {MC_FORWARD,1,{'f'}}, KS_FORWARD},
++ {"F", "信件轉寄", {MC_FORWARD,1,{'f'}}, KS_FORWARD},
+ JUMP_MENU,
+ PRYNTTXT_MENU,
+ SAVE_MENU,
+@@ -235,7 +235,7 @@
+ static struct key simple_text_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"E","Exit Viewer",{MC_EXIT,1,{'e'}},KS_NONE},
++ {"E","離開",{MC_EXIT,1,{'e'}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -244,7 +244,7 @@
+ PRYNTTXT_MENU,
+ WHEREIS_MENU,
+ FWDEMAIL_MENU,
+- {"S", "Save", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
++ {"S", "存檔", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
+ INST_KEY_MENU(simple_text_keymenu, simple_text_keys);
+
+
+@@ -379,7 +379,7 @@
+ * we were viewing. If so, make sure we don't just come back.
+ */
+ if(mn_get_total(ps->msgmap) <= 0L || !ps->mail_stream){
+- q_status_message(SM_ORDER, 0, 3, "No messages to read!");
++ q_status_message(SM_ORDER, 0, 3, "沒有可供讀取的信件!");
+ ps->next_screen = mail_index_screen;
+ break;
+ }
+@@ -393,7 +393,7 @@
+ body = NULL;
+ if(!(env = mail_fetchstructure(ps->mail_stream, raw_msgno, &body))
+ || !(mc = mail_elt(ps->mail_stream, raw_msgno))){
+- q_status_message1(SM_ORDER, 3, 3, "Error getting message %s data",
++ q_status_message1(SM_ORDER, 3, 3, "取得信件 %s 的資料時發生錯誤",
+ comatose(mn_get_cur(ps->msgmap)));
+ dprint(1, (debugfile, "!!!! ERROR fetching %s of msg %ld\n",
+ env ? "elt" : "env", mn_get_cur(ps->msgmap)));
+@@ -446,7 +446,7 @@
+ memset(&scrollargs, 0, sizeof(SCROLL_S));
+ scrollargs.text.text = so_text(store);
+ scrollargs.text.src = src;
+- scrollargs.text.desc = "message";
++ scrollargs.text.desc = "信件";
+
+ /*
+ * make first selectable handle the default
+@@ -465,11 +465,11 @@
+ else
+ scrollargs.body_valid = 1;
+
+- scrollargs.bar.title = "MESSAGE TEXT";
++ scrollargs.bar.title = "信件文字";
+ scrollargs.end_scroll = view_end_scroll;
+ scrollargs.resize_exit = 1;
+ scrollargs.help.text = h_mail_view;
+- scrollargs.help.title = "HELP FOR MESSAGE TEXT VIEW";
++ scrollargs.help.title = "信件文字的輔助說明";
+ scrollargs.keys.menu = &view_keymenu;
+ scrollargs.keys.what = save_what;
+ setbitmap(scrollargs.keys.bitmap);
+@@ -1192,7 +1192,7 @@
+ /*---- format and copy envelope ----*/
+ if(ps_global->full_header)
+ q_status_message(SM_INFO, 0, 3,
+- "Full header mode ON. All header text being included");
++ "完整標頭模式開啟。所有的標頭文字都包含在內");
+
+ HD_INIT(&h, ps_global->VAR_VIEW_HEADERS, ps_global->view_all_except,
+ FE_DEFAULT);
+@@ -1231,7 +1231,7 @@
+ if(append_file_name)
+ fs_give((void **)&append_file_name);
+
+- q_status_message1(SM_ORDER,3,3,"Can't make temp file: %s",
++ q_status_message1(SM_ORDER,3,3,"無法建立暫存檔:%s",
+ error_description(errno));
+ return(0);
}
+@@ -1525,7 +1525,7 @@
+ write_error:
+
+ if(!(flgs & FM_DISPLAY))
+- q_status_message1(SM_ORDER, 3, 4, "Error writing message: %s",
++ q_status_message1(SM_ORDER, 3, 4, "寫入信件時發生錯誤:%s",
+ decode_err ? decode_err : error_description(errno));
+
+ return(0);
+@@ -1855,8 +1855,8 @@
+ char prompt[256], tmp[MAILTMPLEN];
+ int rc, flags, local_h;
+ static ESCKEY_S launch_opts[] = {
+- {'y', 'y', "Y", "Yes"},
+- {'n', 'n', "N", "No"},
++ {'y', 'y', "Y", "是"},
++ {'n', 'n', "N", "否"},
+ {-2, 0, NULL, NULL},
+ {-2, 0, NULL, NULL},
+ {0, 'u', "U", "editURL"},
+@@ -1877,7 +1877,7 @@
+ else{
+ launch_opts[5].ch = -1;
+ if(!local_h){
+- if(want_to("No Web-Browser application defined! Define now",
++ if(want_to("尚未定義 Web-Browser!現在定義",
+ 'y', 0, NO_HELP, WT_SEQ_SENSITIVE) == 'y'){
+ /* Prompt for the displayer? */
+ tmp[0] = '\0';
+@@ -1921,7 +1921,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 2, 2,
+- "Browser not found: %s",
++ "找不到瀏覽器:%s",
+ error_description(errno));
+ continue;
+ }
+@@ -1950,8 +1950,8 @@
+ return(1);
+
+ while(1){
+- sprintf(prompt, "View selected %s %s%.37s%s? ",
+- (handle->type == URL) ? "URL" : "Attachment",
++ sprintf(prompt, "檢視選擇的 %s %s%.37s%s? ",
++ (handle->type == URL) ? "URL" : "附件",
+ (handle->type == URL) ? "\"" : "",
+ (handle->type == URL) ? handle->h.url.path : "",
+ (handle->type == URL)
+@@ -2416,11 +2416,11 @@
+ mode = PIPE_RESET | PIPE_USER ;
+ if(syspipe = open_system_pipe(cmd, NULL, NULL, mode)){
+ close_system_pipe(&syspipe);
+- q_status_message(SM_ORDER, 0, 4, "VIEWER command completed");
++ q_status_message(SM_ORDER, 0, 4, "VIEWER 命令完成");
+ }
+ else
+ q_status_message1(SM_ORDER, 3, 4,
+- "Cannot spawn command : %s", cmd);
++ "無法起始命令:%s", cmd);
+ }
+ else if(f = url_local_handler(handle->h.url.path)){
+ if((*f)(handle->h.url.path) > 1)
+@@ -2428,7 +2428,7 @@
}
- else switch(mlyesno(Pmaster->headents
-- ? "Cancel message (answering \"Yes\" will abandon your mail message)"
-+ ? "\"取消\"這個動作將會放棄你目前的信件. 取消嗎 ?"
- : (anycb() == FALSE)
-- ? "Cancel Edit (and abandon changes)"
-- : "Cancel Edit",
-+ ? "取消編輯(並放棄所有的改變)"
-+ : "取消編輯",
- FALSE)){
- case TRUE:
- pico_all_done = COMP_CANCEL;
- return(TRUE);
-
- case ABORT:
-- emlwrite("\007Cancel Cancelled", NULL);
-+ emlwrite("\007取消", NULL);
- break;
-
- default:
+ else
+ q_status_message1(SM_ORDER, 2, 2,
+- "\"Web-Browser\" not defined: Can't open %s",
++ "尚未定義 \"Web-Browser\":無法開啟 %s",
+ handle->h.url.path);
+
+ return(rv);
+@@ -2748,7 +2748,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't create space for composer");
++ "無法替編輯器建立空間");
+
+ if(outgoing)
+ mail_free_envelope(&outgoing);
+@@ -2835,7 +2835,7 @@
+ if(uid_val != ps_global->mail_stream->uid_validity){
+ /* Complain! */
+ q_status_message(SM_ORDER|SM_DING, 3, 3,
+- "Warning! Referenced folder changed since URL recorded");
++ "警告!參考資料匣已於 URL 記錄後改變");
+ }
+
+ if(uid){
+@@ -2851,7 +2851,7 @@
+
+ if(i > mn_get_total(ps_global->msgmap))
+ q_status_message(SM_ORDER, 2, 3,
+- "Couldn't find specified article number");
++ "找不到指定的文章編號");
+ }
+ else if(search){
+ /*
+@@ -2872,9 +2872,9 @@
+ if(i = any_lflagged(ps_global->msgmap, MN_SLCT)){
+ extern long zoom_index();
+
+- q_status_message2(SM_ORDER, 0, 3,
+- "%s message%s selected",
+- long2string(i), plural(i));
++ q_status_message1(SM_ORDER, 0, 3,
++ "已選擇 %s 封信件",
++ long2string(i));
+ /* Zoom the index! */
+ zoom_index(ps_global, ps_global->msgmap);
+ }
+@@ -3013,9 +3013,9 @@
+
+ if(auth && *auth != '*')
+ q_status_message1(SM_ORDER, 3, 3,
+- "Unsupported authentication method. %s.",
+- user ? "Using standard login"
+- : "Logging in as \"Anonymous\"");
++ "未支援的認證模式。%s。",
++ user ? "使用標準登入"
++ : "以 \"Anonymous\" 登入");
+
+ /*
+ * At this point our structure should contain the
+@@ -3100,7 +3100,7 @@
+
+ if(i > mn_get_total(ps_global->msgmap))
+ q_status_message(SM_ORDER, 2, 3,
+- "Couldn't find specified article number");
++ "找不到指定的文章編號");
+ }
+
+ break;
+@@ -3179,7 +3179,7 @@
+ }
+ else
+ q_status_message1(SM_ORDER | SM_DING, 0, 3,
+- "Can't find fragment: %s", fragment);
++ "找不到片斷:%s", fragment);
+
+ return(1);
+ }
+@@ -3190,10 +3190,10 @@
+ url_local_phone_home(url)
+ char *url;
+ {
+- if(want_to("Request document", 'y', 0, NO_HELP, WT_FLUSH_IN) == 'y')
++ if(want_to("要求文件", 'y', 0, NO_HELP, WT_FLUSH_IN) == 'y')
+ phone_home(url + 18); /* 18 == length of "x-pine-phone-home:" */
+ else
+- q_status_message(SM_ORDER, 0, 3, "No request sent");
++ q_status_message(SM_ORDER, 0, 3, "請求未送出");
+
+ return(1);
+ }
+@@ -3210,7 +3210,7 @@
+ dprint(2, (debugfile, "-- bogus url \"%s\": %s\n",
+ url ? url : "<NULL URL>", reason));
+ if(url)
+- q_status_message3(SM_ORDER|SM_DING, 2, 3, "Malformed \"%.*s\" URL: %s",
++ q_status_message3(SM_ORDER|SM_DING, 2, 3, "格式錯誤的 \"%.*s\" URL:%s",
+ (void *) (strchr(url, ':') - url), url, reason);
+
+ return(0);
+@@ -3354,7 +3354,7 @@
+
+ write_error:
+ if(style == QStatus)
+- q_status_message1(SM_ORDER, 3, 4, "Error writing message: %s",
++ q_status_message1(SM_ORDER, 3, 4, "寫入信件時發生錯誤:%s",
+ error_description(errno));
+
+ return(1);
+@@ -3604,7 +3604,7 @@
+ gf_set_so_writec(&tmp_pc, df_store);
+ if(errstr = dfilter(display_filter, tmp_store, tmp_pc, NULL)){
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Formatting error: %s", errstr);
++ "格式錯誤:%s", errstr);
+ rv = FHT_WRTERR;
+ }
+ else{
+@@ -3616,7 +3616,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "No space for filtered text: %s", errstr);
++ "沒有足夠的空間過濾文字:%s", errstr);
+ rv = FHT_WRTERR;
+ }
+ }
+@@ -3641,7 +3641,7 @@
+ if(errstr = gf_pipe(tmp_gc, final_pc)){
+ rv = FHT_WRTERR;
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Can't build header : %s", errstr);
++ "無法建立標頭:%s", errstr);
+ }
+ }
+
+@@ -3780,7 +3780,7 @@
+ format_newsgroup_string("Newsgroups: ", e->newsgroups, prefix, pc);
+ if(e->ngbogus)
+ q_status_message(SM_ORDER, 0, 3,
+- "Unverified Newsgroup header -- Message MAY or MAY NOT have been posted");
++ "未經證實的新聞組群標頭 -- 訊息可能從未被張貼");
+ }
+
+ if((which & FE_FOLLOWUPTO) && e->followup_to)
+@@ -4404,7 +4404,7 @@
+ }
+
+ if(!sparms->bar.title)
+- sparms->bar.title = "Text";
++ sparms->bar.title = "文字";
+
+ if(sparms->bar.style == TitleBarNone)
+ sparms->bar.style = MsgTextPercent;
+@@ -4553,7 +4553,7 @@
+ }
+
+ if(first_view && num_display_lines >= get_scroll_text_lines())
+- q_status_message1(SM_INFO, 0, 1, "ALL of %s", STYLE_NAME(sparms));
++ q_status_message1(SM_INFO, 0, 1, "%s 全部", STYLE_NAME(sparms));
+
+
+ force = 0; /* may not need to next time around */
+@@ -4669,7 +4669,7 @@
+ whereis_pos.row = 0;
+ if(sparms->help.text == NO_HELP || ps_global->nr_mode){
+ q_status_message(SM_ORDER, 0, 5,
+- "No help text currently available");
++ "目前尚無輔助說明");
+ break;
+ }
+
+@@ -4708,12 +4708,12 @@
+ cur_top_line -= scroll_lines;
+ if(cur_top_line <= 0){
+ cur_top_line = 0;
+- q_status_message1(SM_INFO, 0, 1, "START of %s",
++ q_status_message1(SM_INFO, 0, 1, "%s起始",
+ STYLE_NAME(sparms));
+ }
+ }
+ else
+- q_status_message1(SM_ORDER, 0, 1, "Already at start of %s",
++ q_status_message1(SM_ORDER, 0, 1, "已經在%s的起始",
+ STYLE_NAME(sparms));
+ break;
+
+@@ -4727,12 +4727,12 @@
+ cur_top_line += scroll_lines;
+
+ if(cur_top_line + num_display_lines >= get_scroll_text_lines())
+- q_status_message1(SM_INFO, 0, 1, "END of %s",
++ q_status_message1(SM_INFO, 0, 1, "%s結尾",
+ STYLE_NAME(sparms));
+ }
+ else if(!sparms->end_scroll
+ || !(done = (*sparms->end_scroll)(sparms)))
+- q_status_message1(SM_ORDER, 0, 1, "Already at end of %s",
++ q_status_message1(SM_ORDER, 0, 1, "已經在%s的結尾",
+ STYLE_NAME(sparms));
+
+ break;
+@@ -4749,11 +4749,11 @@
+ cur_top_line++;
+ if(cur_top_line + num_display_lines
+ >= get_scroll_text_lines())
+- q_status_message1(SM_INFO, 0, 1, "END of %s",
++ q_status_message1(SM_INFO, 0, 1, "%s結尾",
+ STYLE_NAME(sparms));
+ }
+ else
+- q_status_message1(SM_ORDER, 0, 1, "Already at end of %s",
++ q_status_message1(SM_ORDER, 0, 1, "已經在%s的結尾",
+ STYLE_NAME(sparms));
+ }
+
+@@ -4770,11 +4770,11 @@
+ if(cur_top_line){
+ cur_top_line--;
+ if(cur_top_line == 0)
+- q_status_message1(SM_INFO, 0, 1, "START of %s",
++ q_status_message1(SM_INFO, 0, 1, "%s起始",
+ STYLE_NAME(sparms));
+ }
+ else
+- q_status_message1(SM_ORDER, 0, 1, "Already at start of %s",
++ q_status_message1(SM_ORDER, 0, 1, "已經在%s的起始",
+ STYLE_NAME(sparms));
+ }
+
+@@ -4805,7 +4805,7 @@
+ }
+
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on last selectable item");
++ "已經在最後一個可選擇的項目上");
+ }
+
+ break;
+@@ -4835,7 +4835,7 @@
+ }
+
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on first selectable item");
++ "已經在第一個可選擇的項目上");
+ }
+
+ break;
+@@ -4941,14 +4941,14 @@
+ q_status_message(SM_ORDER, 0, 3, tmp_20k_buf);
+ else
+ q_status_message2(SM_ORDER, 0, 3,
+- "%sFound on line %s on screen",
+- result ? "Search wrapped to start. " : "",
++ "%s在畫面上第 %s 行找到",
++ result ? "重頭搜尋。" : "",
+ int2string(whereis_pos.row));
+ }
+ else if(found_on == -1)
+ cmd_cancelled("Search");
+ else
+- q_status_message(SM_ORDER | SM_DING, 0, 3, "Word not found");
++ q_status_message(SM_ORDER | SM_DING, 0, 3, "找不到該字");
+
+ break;
+
+@@ -6065,10 +6065,10 @@
+ if(*msg_p[0])
+ for(i = 0; i < msg_q; i++)
+ q_status_message2(SM_ORDER, 3, 4,
+- "%s Result: %s", title, msg_p[i]);
++ "%s 結果:%s", title, msg_p[i]);
+ else
+ q_status_message2(SM_ORDER, 0, 4, "%s%s", title,
+- alt_msg ? alt_msg : " command completed");
++ alt_msg ? alt_msg : " 命令完成");
+ }
+ else{
+ SCROLL_S sargs;
+@@ -6079,7 +6079,7 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = f;
+ sargs.text.src = FileStar;
+- sargs.text.desc = "help text";
++ sargs.text.desc = "輔助說明文字";
+ sargs.bar.title = title;
+ sargs.bar.style = TextPercent;
+ sargs.help.text = h_simple_text_view;
diff --git a/chinese/pine4/files/patch-ax b/chinese/pine4/files/patch-ax
index ef3ffa3e750c..026ac2e73d0f 100644
--- a/chinese/pine4/files/patch-ax
+++ b/chinese/pine4/files/patch-ax
@@ -1,16 +1,65 @@
---- pico/search.c.orig Sat Jan 17 20:23:39 1998
-+++ pico/search.c Sat Jan 17 20:24:28 1998
-@@ -222,11 +222,11 @@
- EXTRAKEYS menu_pat[3];
+--- pine/newmail.c.orig Fri Mar 27 07:28:33 1998
++++ pine/newmail.c Wed Jul 15 17:02:35 1998
+@@ -289,38 +289,28 @@
+ ENVELOPE *e;
+ char subject[200], from[2*MAX_SCREEN_COLS],
+ intro[MAX_SCREEN_COLS+1];
+- static char *carray[] = { "regarding",
+- "concerning",
+- "about",
+- "as to",
+- "as regards",
+- "as respects",
+- "in re",
+- "re",
+- "respecting",
+- "in point of",
+- "with regard to",
+- "subject:"
++ static char *carray[] = { "關於",
++ "有關"
+ };
- menu_pat[0].name = "^Y";
-- menu_pat[0].label = "FirstLine";
-+ menu_pat[0].label = "第一行";
- menu_pat[0].key = (CTRL|'Y');
- KS_OSDATASET(&menu_pat[0], KS_NONE);
- menu_pat[1].name = "^V";
-- menu_pat[1].label = "LastLine";
-+ menu_pat[1].label = "最後一行";
- menu_pat[1].key = (CTRL|'V');
- KS_OSDATASET(&menu_pat[1], KS_NONE);
- menu_pat[2].name = NULL;
+ e = mail_fetchstructure(stream, max_num, NULL);
+
+ if(!folder) {
+ if(number > 1)
+- sprintf(intro, "%ld new messages!", number);
++ sprintf(intro, "%ld 封新信件!", number);
+ else
+- sprintf(intro, "New mail%s!",
+- (e && address_is_us(e->to, ps_global)) ? " to you" : "");
++ sprintf(intro, "%s新信!",
++ (e && address_is_us(e->to, ps_global)) ? "您有" : "");
+ }
+ else {
+ if(number > 1)
+- sprintf(intro,"%ld messages saved to folder \"%s\"", number, folder);
++ sprintf(intro,"%ld 封信件被存至資料匣 \"%s\"", number, folder);
+ else
+- sprintf(intro, "Mail saved to folder \"%s\"", folder);
++ sprintf(intro, "信件被存至資料匣 \"%s\"", folder);
+ }
+
+ if(e && e->from){
+- sprintf(from, " %srom ", (number > 1L) ? "Most recent f" : "F");
++ sprintf(from, "%s自", (number > 1L) ? "最近來" : "來");
+ if(e->from->personal)
+ istrncpy(from + ((number > 1L) ? 18 : 6),
+ (char *) rfc1522_decode((unsigned char *) tmp_20k_buf,
+@@ -337,13 +327,13 @@
+
+ if(number <= 1L) {
+ if(e && e->subject){
+- sprintf(subject, " %s ", carray[(unsigned)random()%12]);
++ sprintf(subject, " %s ", carray[(unsigned)random()%2]);
+ istrncpy(subject + strlen(subject),
+ (char *) rfc1522_decode((unsigned char *) tmp_20k_buf,
+ e->subject, NULL), 100);
+ }
+ else
+- strcpy(subject, " with no subject");
++ strcpy(subject, " 沒有主題");
+
+ if(!from[0])
+ subject[1] = toupper((unsigned char)subject[1]);
diff --git a/chinese/pine4/files/patch-ay b/chinese/pine4/files/patch-ay
index 0386a9814fc9..716ebc651ea0 100644
--- a/chinese/pine4/files/patch-ay
+++ b/chinese/pine4/files/patch-ay
@@ -1,878 +1,1468 @@
---- pine/addrbook.c.orig Sat Jan 17 20:28:24 1998
-+++ pine/addrbook.c Sat Jan 17 21:01:08 1998
-@@ -514,9 +514,9 @@
-
- #define CLICKHERE "[ Select Here to See Expanded List ]"
- #define NO_PERMISSION "[ Permission Denied ]"
--#define EMPTY "[ Empty ]"
--#define READONLY "(ReadOnly)"
--#define NOACCESS "(Un-readable)"
-+#define EMPTY "[ 沒有任何項目 ]"
-+#define READONLY "(唯讀)"
-+#define NOACCESS "(無法讀取)"
- #define DISTLIST "DISTRIBUTION LIST:"
-
- #define MAX_FCC MAX_ADDRESS
-@@ -760,7 +760,7 @@
- readonly_warning(NO_DING, NULL);
- else if(pab->access == NoAccess)
- q_status_message(SM_ORDER, 0, 4,
-- "AddressBook not accessible, permission denied");
-+ "禁止存取地址簿");
+--- pine/other.c.orig Thu Jul 9 05:35:12 1998
++++ pine/other.c Wed Jul 15 17:02:36 1998
+@@ -51,16 +51,16 @@
+
+ #define BODY_LINES(X) ((X)->ttyo->screen_rows -HEADER_ROWS(X)-FOOTER_ROWS(X))
+
+-#define CONFIG_SCREEN_TITLE "SETUP CONFIGURATION"
+-#define CONFIG_SCREEN_HELP_TITLE "HELP FOR SETUP CONFIGURATION"
++#define CONFIG_SCREEN_TITLE "環境設定"
++#define CONFIG_SCREEN_HELP_TITLE "環境設定的輔助說明"
+ #define R_SELD '*'
+-#define EXIT_PMT "Commit changes (\"Yes\" replaces settings, \"No\" abandons changes)"
+-static char *empty_val = "Empty Value";
+-static char *empty_val2 = "<Empty Value>";
++#define EXIT_PMT "送出改變 (\"是\" 取代設定,\"否\" 放棄改變)"
++static char *empty_val = "空的設定值";
++static char *empty_val2 = "<空的設定值>";
+ #define EMPTY_VAL_LEN 11
+-static char *no_val = "No Value Set";
++static char *no_val = "尚未定義設定值";
+ #define NO_VAL_LEN 12
+-static char *fixed_val = "Value is Fixed";
++static char *fixed_val = "設定值已固定";
+
+ typedef struct proto_conf_line {
+ short type, /* type of line treatment */
+@@ -311,9 +311,9 @@
+ char prompt[50];
+
+ sprintf(prompt,
+- "%s password to LOCK keyboard %s: ",
+- i ? "Retype" : "Enter",
+- i > 1 ? "(Yes, again) " : "");
++ "%s鎖定鍵盤的密碼 %s:",
++ i ? "重新輸入" : "輸入",
++ i > 1 ? "(是的,再一次) " : "");
+
+ flags = OE_PASSWD;
+ rc = optionally_enter(pw, -FOOTER_ROWS(ps), 0, 30,
+@@ -322,7 +322,7 @@
+ if(rc == 3)
+ help = help == NO_HELP ? h_kb_lock : NO_HELP;
+ else if(rc == 1 || pw[0] == '\0'){
+- q_status_message(SM_ORDER, 0, 2, "Keyboard lock cancelled");
++ q_status_message(SM_ORDER, 0, 2, "取消鍵盤鎖定");
+ return(-1);
+ }
+ else if(rc != 4)
+@@ -333,14 +333,14 @@
+ strcpy(inpasswd, pw);
+ else if(strcmp(inpasswd, pw)){
+ q_status_message(SM_ORDER, 0, 2,
+- "Mismatch with initial password: keyboard lock cancelled");
++ "和初始密碼不符:取消鍵盤鎖定");
+ return(-1);
}
+ }
+
+- if(want_to("Really lock keyboard with entered password", 'y', 'n',
++ if(want_to("確定以輸入的密碼鎖定鍵盤", 'y', 'n',
+ NO_HELP, WT_NORM) != 'y'){
+- q_status_message(SM_ORDER, 0, 2, "Keyboard lock cancelled");
++ q_status_message(SM_ORDER, 0, 2, "取消鍵盤鎖定");
+ return(-1);
+ }
- /*
-@@ -921,7 +921,7 @@
-
- dprint(2, (debugfile, "parse_format: ignoring unrecognized word \"%s\" in address-book-formats\n", p));
- q_status_message1(SM_ORDER, warnings++==0 ? 1 : 0, 4,
-- "Ignoring unrecognized word \"%s\" in address-book-formats", p);
-+ "在地址簿格式中忽略無法辨識的字 \"%s\"", p);
- /* put back space */
- if(r)
- *r = SPACE;
-@@ -991,7 +991,7 @@
-
- if(column == 0){
- q_status_message(SM_ORDER, 0, 4,
-- "address-book-formats has no recognizable words, using default format");
-+ "由於在地址簿格式中找不到足以辨識的字, 因此使用預設模式");
- goto assign_default;
+@@ -354,7 +354,7 @@
+ while(strcmp(inpasswd, passwd)){
+ if(passwd[0])
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Password to UNLOCK doesn't match password used to LOCK");
++ "密碼不符");
+
+ help = NO_HELP;
+ while(1){
+@@ -362,7 +362,7 @@
+
+ flags = OE_PASSWD | OE_DISALLOW_CANCEL;
+ rc = optionally_enter(passwd, -FOOTER_ROWS(ps), 0, 30,
+- "Enter password to UNLOCK keyboard : ",NULL,
++ "輸入解除鎖定的密碼:",NULL,
+ help, &flags);
+ if(rc == 3) {
+ help = help == NO_HELP ? h_oe_keylock : NO_HELP;
+@@ -377,7 +377,7 @@
+ if(old_suspend)
+ F_TURN_ON(F_CAN_SUSPEND, ps_global);
+
+- q_status_message(SM_ORDER, 0, 3, "Keyboard Unlocked");
++ q_status_message(SM_ORDER, 0, 3, "解除鍵盤鎖定");
+ return(0);
+ }
+
+@@ -412,7 +412,7 @@
+ PICO pbuf;
+
+ if(!signature_path(sigfile, sig_path, MAXPATH)){
+- q_status_message(SM_ORDER, 3, 4, "No signature file defined.");
++ q_status_message(SM_ORDER, 3, 4, "尚未定義簽名檔。");
+ return;
}
-@@ -1526,7 +1526,7 @@
- if(want_status == Open){
- new_status = HalfOpen; /* best we can do */
- q_status_message1(SM_ORDER | SM_DING, *warning?1:3, 4,
-- "Error opening/creating address book %s",
-+ "於開啟/建立在地址簿 %s 時發生錯誤",
- pab->nickname);
- if(*warning)
- q_status_message2(SM_ORDER, 3, 4, "%s: %s",
-@@ -1603,7 +1603,7 @@
- if(want_status == Open){
- new_status = HalfOpen; /* best we can do */
- q_status_message1(SM_ORDER | SM_DING, 3, 4,
-- "Insufficient permissions for opening address book %s",
-+ "沒有足夠的權限開啟地址簿 %s",
- pab->nickname);
+@@ -442,7 +442,7 @@
+ pbuf.browse_help = h_composer_browse;
+ pbuf.attach_help = h_composer_ctrl_j;
+
+- pbuf.pine_anchor = set_titlebar("SIGNATURE EDITOR",
++ pbuf.pine_anchor = set_titlebar("簽名檔編輯器",
+ ps_global->mail_stream,
+ ps_global->context_current,
+ ps_global->cur_folder,
+@@ -486,7 +486,7 @@
+ */
+ if(!(msgso = so_get(PicoText, NULL, EDIT_ACCESS))){
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Error allocating space for signature file");
++ "配置簽名檔空間時發生錯誤");
+ dprint(1, (debugfile, "Can't alloc space for signature_edit"));
+ return;
+ }
+@@ -496,7 +496,7 @@
+ if(can_access(sig_path, READ_ACCESS) == 0
+ && !(tmpso = so_get(FileStar, sig_path, READ_ACCESS))){
+ char *problem = error_description(errno);
+- q_status_message2(SM_ORDER | SM_DING, 3, 3, "Error editing %s: %s",
++ q_status_message2(SM_ORDER | SM_DING, 3, 3, "編輯 %s 時發生錯誤:%s",
+ sig_path, problem ? problem : "<NULL>");
+ dprint(1, (debugfile, "signature_edit: can't open %s: %s", sig_path,
+ problem ? problem : "<NULL>"));
+@@ -508,7 +508,7 @@
+ gf_filter_init(); /* no filters needed */
+ if(errstr = gf_pipe(gc, pc)){
+ q_status_message1(SM_ORDER | SM_DING, 3, 5,
+- "Error reading signature \"%s\"", errstr);
++ "編輯簽名檔時發生錯誤 \"%s\"", errstr);
+ }
+
+ gf_clear_so_readc(tmpso);
+@@ -547,7 +547,7 @@
+ gf_filter_init(); /* no filters needed */
+ if(errstr = gf_pipe(gc, pc)){
+ q_status_message1(SM_ORDER | SM_DING, 3, 5,
+- "Error writing signature \"%s\"",
++ "寫入簽名檔時發生錯誤 \"%s\"",
+ errstr);
+ }
+
+@@ -557,7 +557,7 @@
}
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Error writing %s", sig_path);
++ "寫入 %s 時發生錯誤", sig_path);
+ dprint(1, (debugfile, "signature_edit: can't write %s",
+ sig_path));
+ }
+@@ -581,8 +581,8 @@
+ char *rstr = NULL;
+ void (*redraw)() = ps_global->redrawer;
+ static ESCKEY_S opts[] = {
+- {'y', 'y', "Y", "Yes"},
+- {'n', 'n', "N", "No"},
++ {'y', 'y', "Y", "是"},
++ {'n', 'n', "N", "否"},
+ {-1, 0, NULL, NULL}
+ };
+
+@@ -590,18 +590,18 @@
+ fix_windsize(ps_global);
+
+ while(1){
+- rv = radio_buttons("Exit editor and apply changes? ",
++ rv = radio_buttons("結束編輯並套用改變?",
+ -FOOTER_ROWS(ps_global), opts,
+ 'y', 'x', NO_HELP, RB_NORM);
+ if(rv == 'y'){ /* user ACCEPTS! */
+ break;
+ }
+ else if(rv == 'n'){ /* Declined! */
+- rstr = "No Changes Saved";
++ rstr = "改變並未存檔";
+ break;
+ }
+ else if(rv == 'x'){ /* Cancelled! */
+- rstr = "Exit Cancelled";
++ rstr = "取消";
+ break;
+ }
+ }
+@@ -616,24 +616,24 @@
+ * * * * * * Start of Config Screen Support Code * * * * *
+ */
+
+-#define PREV_MENU {"P", "Prev", {MC_PREVITEM, 1, {'p'}}, KS_NONE}
+-#define NEXT_MENU {"N", "Next", {MC_NEXTITEM, 2, {'n','\t'}}, KS_NONE}
++#define PREV_MENU {"P", "前一個", {MC_PREVITEM, 1, {'p'}}, KS_NONE}
++#define NEXT_MENU {"N", "後一個", {MC_NEXTITEM, 2, {'n','\t'}}, KS_NONE}
+ #define EXIT_SETUP_MENU \
+- {"E", "Exit Setup", {MC_EXIT,1,{'e'}}, KS_EXITMODE}
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE}
+ #define TOGGLE_MENU \
+- {"X", "[Set/Unset]", {MC_TOGGLE,3,{'x',ctrl('M'),ctrl('J')}}, KS_NONE}
++ {"X", "[設定/解除設定]", {MC_TOGGLE,3,{'x',ctrl('M'),ctrl('J')}}, KS_NONE}
+
+ static struct key config_text_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+ EXIT_SETUP_MENU,
+- {"C", "[Change Val]", {MC_EDIT,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"C", "[改變設定值]", {MC_EDIT,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"A", "Add Value", {MC_ADD,1,{'a'}}, KS_NONE},
+- {"D", "Delete Val", {MC_DELETE,1,{'d'}}, KS_NONE},
++ {"A", "新增設定值", {MC_ADD,1,{'a'}}, KS_NONE},
++ {"D", "刪除設定值", {MC_DELETE,1,{'d'}}, KS_NONE},
+ PRYNTTXT_MENU,
+ WHEREIS_MENU};
+ INST_KEY_MENU(config_text_keymenu, config_text_keys);
+@@ -657,7 +657,7 @@
+ {HELP_MENU,
+ NULL_MENU,
+ EXIT_SETUP_MENU,
+- {"*", "[Select]", {MC_CHOICE,3,{'*',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"*", "[選擇]", {MC_CHOICE,3,{'*',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+@@ -672,7 +672,7 @@
+ {HELP_MENU,
+ NULL_MENU,
+ EXIT_SETUP_MENU,
+- {"C", "[Change]", {MC_TOGGLE,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"C", "[修改]", {MC_TOGGLE,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+@@ -1377,14 +1377,14 @@
+ {HELP_MENU,
+ PRYNTTXT_MENU,
+ EXIT_SETUP_MENU,
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"A", "Add Printer", {MC_ADD,1,{'a'}}, KS_NONE},
+- {"D", "DeletePrint", {MC_DELETE,1,{'d'}}, KS_NONE},
+- {"C", "Change", {MC_EDIT,1,{'c'}}, KS_NONE},
++ {"A", "新增印表機", {MC_ADD,1,{'a'}}, KS_NONE},
++ {"D", "刪除印表機", {MC_DELETE,1,{'d'}}, KS_NONE},
++ {"C", "修改", {MC_EDIT,1,{'c'}}, KS_NONE},
+ WHEREIS_MENU};
+ INST_KEY_MENU(printer_edit_keymenu, printer_edit_keys);
+
+@@ -1392,7 +1392,7 @@
+ {HELP_MENU,
+ PRYNTTXT_MENU,
+ EXIT_SETUP_MENU,
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+@@ -1425,7 +1425,7 @@
+ char *saved_printer;
+ OPT_SCREEN_S screen;
+
+- if(fixed_var(&ps_global->vars[V_PRINTER], "change", "printer"))
++ if(fixed_var(&ps_global->vars[V_PRINTER], "修改", "印表機"))
+ return;
+
+ saved_printer = cpystr(ps->VAR_PRINTER);
+@@ -1794,7 +1794,7 @@
+
+ vsave = save_config_vars(ps);
+ switch(conf_scroll_screen(ps, &screen, start_line,
+- "SETUP PRINTER", "printer config ", 1)){
++ "設定印表機", "printer config ", 1)){
+ case 0:
+ break;
+
+@@ -1835,8 +1835,8 @@
+ fs_give((void **)def_printer_line);
+
+ *def_printer_line = fs_get(36 + strlen(p) + 1);
+- sprintf(*def_printer_line, "Default printer currently %s%s%s",
+- set ? "set to \"" : "unset", set ? p : "", set ? "\"." : ".");
++ sprintf(*def_printer_line, "預設印表機目前%s%s%s",
++ set ? "設定為 \"" : "未設定", set ? p : "", set ? "\"." : ".");
+
+ fs_give((void **)&nick);
+ fs_give((void **)&cmd);
+@@ -1846,7 +1846,7 @@
+ static struct key flag_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"E", "Exit Flags", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ TOGGLE_MENU,
+ PREV_MENU,
+ NEXT_MENU,
+@@ -2000,9 +2000,9 @@
+
+ static struct key addr_select_keys[] =
+ {HELP_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ NULL_MENU,
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+@@ -2016,29 +2016,29 @@
+ static struct key addr_select_with_goback_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"<", "AddbkList", {MC_ADDRBOOK,2,{'<',','}}, KS_NONE},
+- {"S", "[Select]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"<", "地址簿列表", {MC_ADDRBOOK,2,{'<',','}}, KS_NONE},
++ {"S", "[選擇]", {MC_CHOICE,3,{'s',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ NULL_MENU,
+ NULL_MENU,
+- {"E", "ExitSelect", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+ WHEREIS_MENU};
+ INST_KEY_MENU(addr_s_km_with_goback, addr_select_with_goback_keys);
+
+ static struct key addr_select_with_view_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"<", "AddbkList", {MC_ADDRBOOK,2,{'<',','}}, KS_NONE},
+- {">", "[View]",
++ {"<", "地址簿列表", {MC_ADDRBOOK,2,{'<',','}}, KS_NONE},
++ {">", "[檢視]",
+ {MC_VIEW_TEXT,5,{'v','>','.',ctrl('M'),ctrl('J')}}, KS_NONE},
+ PREV_MENU,
+ NEXT_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"C", "ComposeTo", {MC_COMPOSE,1,{'c'}}, KS_COMPOSER},
++ {"C", "編修", {MC_COMPOSE,1,{'c'}}, KS_COMPOSER},
+ FWDEMAIL_MENU,
+ SAVE_MENU,
+ WHEREIS_MENU};
+@@ -2047,7 +2047,7 @@
+ static struct key addr_select_exit_keys[] =
+ {NULL_MENU,
+ NULL_MENU,
+- {"E", "[Exit]", {MC_EXIT,3,{'e',ctrl('M'),ctrl('J')}},
++ {"E", "[離開]", {MC_EXIT,3,{'e',ctrl('M'),ctrl('J')}},
+ KS_EXITMODE},
+ NULL_MENU,
+ NULL_MENU,
+@@ -2063,7 +2063,7 @@
+ static struct key addr_select_goback_keys[] =
+ {NULL_MENU,
+ NULL_MENU,
+- {"E", "[Exit]", {MC_ADDRBOOK,3,{'e',ctrl('M'),ctrl('J')}},
++ {"E", "[離開]", {MC_ADDRBOOK,3,{'e',ctrl('M'),ctrl('J')}},
+ KS_EXITMODE},
+ NULL_MENU,
+ NULL_MENU,
+@@ -2404,7 +2404,7 @@
+ sprintf(ee+2, "%s, No Matches Returned",
+ ldap_err2string(wp_err->ldap_errno));
+ else
+- strcat(ee, "No Matches");
++ strcat(ee, "沒有符合的");
+
+ strcat(ee, " -- Choose Exit ]");
+ ctmpa->value = cpystr(ee);
+@@ -2498,7 +2498,7 @@
+ case MC_CHOICE :
+ if(flags & CF_PRIVATE){
+ q_status_message(SM_ORDER | SM_DING, 0, 3,
+- "No email address available for this entry; choose another or ExitSelect");
++ "無法針對此項目獲得電子郵件地址;請選擇其他的或離開");
+ }
+ else if(some_selectable){
+ (*cl)->d.a.ac->selected_ld = (*cl)->d.a.ld;
+@@ -2561,15 +2561,15 @@
+ static struct key direct_config_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"E", "Exit Setup", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
+- {"C", "[Change]", {MC_EDIT,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
+- {"P", "PrevDir", {MC_PREVITEM, 1, {'p'}}, KS_NONE},
+- {"N", "NextDir", {MC_NEXTITEM, 2, {'n', TAB}}, KS_NONE},
++ {"E", "離開", {MC_EXIT,1,{'e'}}, KS_EXITMODE},
++ {"C", "[修改]", {MC_EDIT,3,{'c',ctrl('M'),ctrl('J')}}, KS_NONE},
++ {"P", "前一目錄", {MC_PREVITEM, 1, {'p'}}, KS_NONE},
++ {"N", "次一目錄", {MC_NEXTITEM, 2, {'n', TAB}}, KS_NONE},
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+- {"A", "Add Dir", {MC_ADD,1,{'a'}}, KS_NONE},
+- {"D", "Del Dir", {MC_DELETE,1,{'d'}}, KS_NONE},
+- {"$", "Shuffle", {MC_SHUFFLE,1,{'$'}}, KS_NONE},
++ {"A", "新增目錄", {MC_ADD,1,{'a'}}, KS_NONE},
++ {"D", "刪除目錄", {MC_DELETE,1,{'d'}}, KS_NONE},
++ {"$", "重整", {MC_SHUFFLE,1,{'$'}}, KS_NONE},
+ WHEREIS_MENU};
+ INST_KEY_MENU(dir_conf_km, direct_config_keys);
+
+@@ -2655,7 +2655,7 @@
+ */
+ if(!ps->VAR_LDAP_SERVERS || !ps->VAR_LDAP_SERVERS[0] ||
+ !ps->VAR_LDAP_SERVERS[0][0]){
+- if(!fixed_var(&ps->vars[V_LDAP_SERVERS], "modify", "directory list")){
++ if(!fixed_var(&ps->vars[V_LDAP_SERVERS], "修改", "地址列表")){
+ unsigned flags = 0;
+
+ opt_screen = &screen;
+@@ -2665,7 +2665,7 @@
+ #endif /* notdef */
+
+ (void)conf_scroll_screen(ps, &screen, first_line,
+- "SETUP DIRECTORY SERVERS", "servers ", 1);
++ "設定地址伺服器", "servers ", 1);
+ ps->mangled_screen = 1;
+ }
+
+@@ -2685,20 +2685,20 @@
+ case MC_DELETE :
+ if(first_one)
+ q_status_message(SM_ORDER|SM_DING, 0, 3,
+- "Nothing to Delete, use Add");
++ "沒有可供刪除的項目,請用新增");
+ else
+ dir_config_del(ps, cl);
+
+ break;
+
+ case MC_ADD :
+- if(!fixed_var((*cl)->var, NULL, "directory list"))
++ if(!fixed_var((*cl)->var, NULL, "地址列表"))
+ dir_config_add(ps, cl);
+
+ break;
+
+ case MC_EDIT :
+- if(!fixed_var((*cl)->var, NULL, "directory list")){
++ if(!fixed_var((*cl)->var, NULL, "地址列表")){
+ if(first_one)
+ dir_config_add(ps, cl);
+ else
+@@ -2708,10 +2708,10 @@
+ break;
+
+ case MC_SHUFFLE :
+- if(!fixed_var((*cl)->var, NULL, "directory list")){
++ if(!fixed_var((*cl)->var, NULL, "地址列表")){
+ if(first_one)
+ q_status_message(SM_ORDER|SM_DING, 0, 3,
+- "Nothing to Shuffle, use Add");
++ "沒有可供重整的項目,請用新增");
else
-@@ -3929,7 +3929,7 @@
- mailcap_free(); /* free resources we won't be using for a while */
-
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "重設地址簿...");
- dprint(1, (debugfile, "RESETTING address book... addr_book_screen!\n"));
- addrbook_reset();
+ dir_config_shuffle(ps, cl);
+ }
+@@ -2840,7 +2840,7 @@
+ write_pinerc(ps);
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "Add cancelled, no server name");
++ q_status_message(SM_ORDER, 0, 3, "沒有伺服器名稱,取消新增");
+ }
+
+ free_ldap_server_info(&info);
+@@ -2870,7 +2870,7 @@
+
+ if(cnt < 2){
+ q_status_message(SM_ORDER, 0, 3,
+- "Shuffle only makes sense when there is more than one server defined");
++ "僅在定義了多個伺服器之後,重整才能發揮作用");
+ return;
+ }
+
+@@ -2881,12 +2881,12 @@
+ opts[i].ch = 'u';
+ opts[i].rval = 'u';
+ opts[i].name = "U";
+- opts[i++].label = "Up";
++ opts[i++].label = "上";
+
+ opts[i].ch = 'd';
+ opts[i].rval = 'd';
+ opts[i].name = "D";
+- opts[i++].label = "Down";
++ opts[i++].label = "下";
+
+ opts[i].ch = -1;
+ deefault = 'u';
+@@ -2898,11 +2898,11 @@
+ else if(current_num == cnt - 1) /* no down */
+ opts[1].ch = -2;
+
+- sprintf(tmp, "Shuffle \"%s\" %s%s%s ? ",
++ sprintf(tmp, "重整 \"%s\" %s%s%s ? ",
+ (*cl)->value,
+- (opts[0].ch != -2) ? "UP" : "",
++ (opts[0].ch != -2) ? "往上" : "",
+ (opts[0].ch != -2 && opts[1].ch != -2) ? " or " : "",
+- (opts[1].ch != -2) ? "DOWN" : "");
++ (opts[1].ch != -2) ? "往下" : "");
+ help = (opts[0].ch == -2) ? h_dir_shuf_down
+ : (opts[1].ch == -2) ? h_dir_shuf_up
+ : h_dir_shuf;
+@@ -2912,7 +2912,7 @@
+
+ switch(rv){
+ case 'x':
+- q_status_message(SM_ORDER, 0, 3, "Shuffle cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消重整");
+ return;
+
+ case 'u':
+@@ -2950,7 +2950,7 @@
+ free_list_array(&new_list);
+ if(j){
+ q_status_message(SM_ORDER, 0, 3,
+- "Shuffle cancelled: couldn't save configuration file");
++ "取消重整:無法存入設定檔");
+ set_current_val((*cl)->var, TRUE, FALSE);
+ return;
}
-@@ -3959,7 +3959,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book... addr_book_compose!\n"));
- addrbook_reset();
-@@ -4000,7 +4000,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book... addr_book_compose_lcc!\n"));
- addrbook_reset();
-@@ -4034,7 +4034,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book... addr_book_change_list!\n"));
- addrbook_reset();
-@@ -4081,7 +4081,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book...addr_book_takeaddr!\n"));
- addrbook_reset();
-@@ -4112,7 +4112,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book...addr_book_nick_for_edit!\n"));
- addrbook_reset();
-@@ -4143,7 +4143,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book...addr_book_selnick!\n"));
- addrbook_reset();
-@@ -4174,7 +4174,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book...addr_book_seladdr!\n"));
- addrbook_reset();
-@@ -4206,7 +4206,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile,"RESETTING address book...addr_book_seladdr_nofull!\n"));
- addrbook_reset();
-@@ -4237,7 +4237,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1,
- (debugfile, "RESETTING address book...addr_book_manynicks!\n"));
- addrbook_reset();
-@@ -4249,18 +4249,18 @@
-
-
- static struct key ab_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"P","PrevEntry",KS_NONE}, {"N","NextEntry",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"D","Delete",KS_DELETE}, {"A","AddNew",KS_NONE},
-- {"C","ComposeTo",KS_COMPOSER}, {"W","WhereIs",KS_WHEREIS},
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"Q","Quit",KS_EXIT}, {NULL,NULL,KS_NONE},
-- {"L","ListFldrs",KS_FLDRLIST}, {"G","GotoFldr",KS_GOTOFLDR},
-- {"I","Index",KS_FLDRINDEX}, {NULL,NULL,KS_NONE},
-- {"Y","prYnt",KS_PRINT}, {"T","TakeAddr",KS_TAKEADDR},
-- {"X","eXport",KS_EXPORT}, {"F","Forward",KS_NONE}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"D","刪除",KS_DELETE}, {"A","加入",KS_NONE},
-+ {"C","寫信",KS_COMPOSER}, {"W","搜尋",KS_WHEREIS},
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {"Q","離開",KS_EXIT}, {NULL,NULL,KS_NONE},
-+ {"L","列出信件夾",KS_FLDRLIST}, {"G","進入信件夾",KS_GOTOFLDR},
-+ {"I","索引",KS_FLDRINDEX}, {NULL,NULL,KS_NONE},
-+ {"Y","列印",KS_PRINT}, {"T","取得地址",KS_TAKEADDR},
-+ {"X","匯出",KS_EXPORT}, {"F","轉寄",KS_NONE}};
- INST_KEY_MENU(ab_keymenu, ab_keys);
- #define OTHER_KEY 1
- #define MAIN_KEY 2
-@@ -4376,7 +4376,7 @@
- what = FirstMenu;
-
- if(!init_addrbooks(HalfOpen, 1, 1, !are_selecting)){
-- q_status_message(SM_ORDER | SM_DING,3,4,"No Address Book Configured");
-+ q_status_message(SM_ORDER | SM_DING,3,4,"無法找到已設定的地址簿");
- if(!are_selecting)
- ps_global->next_screen = ps_global->prev_screen;
+@@ -3002,10 +3002,10 @@
+ info = break_up_ldap_server(raw_server);
+
+ if(strcmp((*cl)->var->current_val.l[(*cl)->varmem], raw_server) == 0)
+- q_status_message(SM_ORDER, 0, 3, "No change, cancelled");
++ q_status_message(SM_ORDER, 0, 3, "沒有任何改變,取消");
+ else if(!(info && info->serv && *info->serv))
+ q_status_message(SM_ORDER, 0, 3,
+- "Change cancelled, use Delete if you want to remove this server");
++ "已取消改變,如欲刪除此伺服器,請用刪除");
+ else{
+ char tmp[900];
+ char *subtitle;
+@@ -3740,7 +3740,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 3, 3,
+- "Can't delete sys-admin defined value");
++ "無法刪除系統管理員定義的設定值。");
+ }
+ else{
+ int cnt, ans = 0;
+@@ -3763,8 +3763,8 @@
+ */
+ if(!(*cl)->var->user_val.l && cnt > 1){
+ static ESCKEY_S opts[] = {
+- {'i', 'i', "I", "Ignore All"},
+- {'r', 'r', "R", "Remove One"},
++ {'i', 'i', "I", "忽略全部"},
++ {'r', 'r', "R", "移除一個"},
+ {-1, 0, NULL, NULL}};
+ ans = radio_buttons(
+ "Ignore all default directory servers or just remove this one ? ",
+@@ -3870,7 +3870,7 @@
+ CONF_S *first_line = NULL;
+
+ q_status_message(SM_ORDER, 0, 3,
+- "Reverting to default directory server");
++ "回復至預設的地址伺服器");
+ dir_init_display(ps, cl, servers,
+ &ps->vars[V_LDAP_SERVERS], &first_line);
+ *cl = first_line;
+@@ -3910,7 +3910,7 @@
+ }
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "Server not deleted");
++ q_status_message(SM_ORDER, 0, 3, "伺服器未被刪除");
+ }
+
+ if(rv == 1){
+@@ -4416,7 +4416,7 @@
+ ps->mangled_screen = 1;
+ }
+ else
+- q_status_message(SM_ORDER,0,3,"No help yet!");
++ q_status_message(SM_ORDER,0,3,"輔助說明尚未存在!");
+
+ break;
@@ -4473,7 +4473,7 @@
- as.cur = cur_addr_book();
- pab = &as.adrbks[as.cur];
- if(as.cur != old_cur)
-- q_status_message1(SM_ORDER, 0, 2, "Now in addressbook %s",
-+ q_status_message1(SM_ORDER, 0, 2, "現在正在地址簿 %s 中",
- pab->nickname);
- #ifdef _WINDOWS
- {
-@@ -4506,7 +4506,7 @@
- as.cur = cur_addr_book();
- pab = &as.adrbks[as.cur];
- if(as.cur != old_cur)
-- q_status_message1(SM_ORDER, 0, 2, "Now in addressbook %s",
-+ q_status_message1(SM_ORDER, 0, 2, "現在正在地址簿 %s 中",
- pab->nickname);
- }
-
-@@ -4531,10 +4531,10 @@
- if(are_selecting){
- km->how_many = 1;
- ab_keys[MAIN_KEY].name = "E";
-- ab_keys[MAIN_KEY].label = "ExitSelect";
-+ ab_keys[MAIN_KEY].label = "離開";
- KS_OSDATASET(&ab_keys[MAIN_KEY], KS_EXITMODE);
- ab_keys[SELECT_KEY].name = "S";
-- ab_keys[SELECT_KEY].label = "[Select]";
-+ ab_keys[SELECT_KEY].label = "[選擇]";
- def_cmd = F_ON(F_USE_FK,ps_global) ? PF4 : 's';
- KS_OSDATASET(&ab_keys[SELECT_KEY], KS_NONE);
- clrbitn(OTHER_KEY, bitmap);
-@@ -4545,18 +4545,18 @@
- KS_OSDATASET(&ab_keys[DELETE_KEY], KS_NONE);
- if(as.checkboxes){
- ab_keys[DELETE_KEY].name = "X";
-- ab_keys[DELETE_KEY].label = "[Set/Unset]";
-- ab_keys[SELECT_KEY].label = "Select";
-+ ab_keys[DELETE_KEY].label = "[設定/取消設定]";
-+ ab_keys[SELECT_KEY].label = "選擇";
- def_cmd = F_ON(F_USE_FK,ps_global) ? PF9 : 'x';
- if(entry_is_clickable(as.top_ent+as.cur_row)){
- def_cmd = F_ON(F_USE_FK,ps_global) ? PF4 : 's';
-- ab_keys[DELETE_KEY].label = "Set/Unset";
-- ab_keys[SELECT_KEY].label = "[Select]";
-+ ab_keys[DELETE_KEY].label = "設定/取消設定";
-+ ab_keys[SELECT_KEY].label = "[選擇]";
- }
- }
- else if(listmode_ok){
- ab_keys[DELETE_KEY].name = "L";
-- ab_keys[DELETE_KEY].label = "ListMode";
-+ ab_keys[DELETE_KEY].label = "列表模式";
- }
+ if(i)
+ config_scroll_up(i);
else
- clrbitn(DELETE_KEY, bitmap);
-@@ -4564,23 +4564,23 @@
- else{
- km->how_many = 2;
- ab_keys[MAIN_KEY].name = "M";
-- ab_keys[MAIN_KEY].label = "Main Menu";
-+ ab_keys[MAIN_KEY].label = "主選單";
- KS_OSDATASET(&ab_keys[MAIN_KEY], KS_MAINMENU);
- if(entry_is_clickable(as.top_ent+as.cur_row)){
- ab_keys[SELECT_KEY].name = "S";
-- ab_keys[SELECT_KEY].label = "[Select]";
-+ ab_keys[SELECT_KEY].label = "[選擇]";
- def_cmd = F_ON(F_USE_FK,ps_global) ? PF4 : 's';
- KS_OSDATASET(&ab_keys[SELECT_KEY], KS_NONE);
- }
- else{
- ab_keys[SELECT_KEY].name = "V";
-- ab_keys[SELECT_KEY].label = "[View/Edit]";
-+ ab_keys[SELECT_KEY].label = "[檢視/編輯]";
- def_cmd = F_ON(F_USE_FK,ps_global) ? PF4 : 'v';
- KS_OSDATASET(&ab_keys[SELECT_KEY], KS_NONE);
- }
+- q_status_message(SM_ORDER,0,1, "Already at end of screen");
++ q_status_message(SM_ORDER,0,1, "已經在畫面的結尾了");
+ }
- ab_keys[DELETE_KEY].name = "D";
-- ab_keys[DELETE_KEY].label = "Delete";
-+ ab_keys[DELETE_KEY].label = "刪除";
- KS_OSDATASET(&ab_keys[DELETE_KEY], KS_DELETE);
- if(was_clickable_last_time) /* it's still *this* time now */
- clrbitn(SENDTO_KEY, bitmap);
-@@ -4648,7 +4648,7 @@
- #endif
- orig_c = c;
-
-- if(c == ctrl('M') || c == ctrl('J')) /* set up default */
-+ if(c == ctrl('M') || c == ctrl('J') || c == KEY_RIGHT) /* set up default */
- c = def_cmd;
-
- if(c < 'z' && isupper((unsigned char)c))
-@@ -4749,13 +4749,14 @@
-
-
- /*------------- Back to main menu or exit to caller -------*/
-+ case KEY_LEFT:
- case PF3:
- case 'm':
- case 'e':
- if(!are_selecting && c == 'e'){
- /* backwards compatibility message */
- q_status_message(SM_ORDER | SM_DING, 0, 2,
-- "Command \"E\" not defined. Use \"View/Edit\" to edit an entry");
-+ "\"E\" 這個命令尚未被定義. 請使用 \"View/Edit\" 編輯選項");
- break;
+ break;
+@@ -4497,7 +4497,7 @@
}
+ else
+ q_status_message(SM_ORDER, 0, 1,
+- "Already at start of screen");
++ "已經在畫面的起始了");
-@@ -4766,7 +4767,7 @@
- ps_global->next_screen = main_menu_screen;
-
- if(!(are_selecting && as.checkboxes && checkedn > 0)
-- || want_to("Really abandon your selections ",
-+ || want_to("確定放棄你的選擇 ",
- 'y', 'x', NO_HELP, 0, 0) == 'y')
- quit = 1;
-
-@@ -4780,7 +4781,7 @@
- if(c == 's'
- && !(are_selecting || entry_is_clickable(as.top_ent+as.cur_row))){
- q_status_message(SM_ORDER | SM_DING, 0, 2,
-- "Command \"S\" not defined. Use \"AddNew\" to create a list");
-+ "\"S\" 這個命令尚未被定義. 請使用 \"AddNew\" 建立列表");
- break;
+ break;
+
+@@ -4540,7 +4540,7 @@
+
+ if(ctmpa == screen->current){
+ q_status_message(SM_ORDER,0,1,
+- "Already at end of screen");
++ "已經在畫面的結尾了");
+ goto no_down;
+ }
+
+@@ -4571,7 +4571,7 @@
+ if(ctmpa){
+ if(ctmpa == screen->current)
+ q_status_message(SM_ORDER, 0, 1,
+- "Already at start of screen");
++ "已經在畫面的起始了");
+
+ screen->current = ctmpa;
}
+@@ -4651,13 +4651,13 @@
+ HelpType help;
+ static ESCKEY_S ekey[] = {
+ {0, 0, "", ""},
+- {ctrl('Y'), 10, "^Y", "Top"},
+- {ctrl('V'), 11, "^V", "Bottom"},
++ {ctrl('Y'), 10, "^Y", "頂端"},
++ {ctrl('V'), 11, "^V", "底端"},
+ {-1, 0, NULL, NULL}};
-@@ -4843,7 +4844,7 @@
- /* Select an entry to mail to or a nickname to add to */
- if(!any_addrs_avail(as.top_ent+as.cur_row)){
- q_status_message(SM_ORDER | SM_DING, 0, 4,
-- "No entries in address book. Use ExitSelect to leave address book");
-+ "地址簿中找不到任何項目. 請以 離開選擇(E) 離開");
- break;
- }
-
-@@ -4874,7 +4875,7 @@
- }
- else if(as.checkboxes && checkedn <= 0){
- q_status_message(SM_ORDER, 0, 1,
-- "Use \"X\" to mark addresses or lists");
-+ "使用 \"X\" 標記地址或列表");
- break;
- }
- else if(as.checkboxes){
-@@ -4978,7 +4979,7 @@
- if(selecting_mult_nicks){
- if(dl->type != ListHead && style == SelectAddrLccCom){
- q_status_message(SM_ORDER, 0, 4,
-- "You may only select lists for lcc, use bcc for other addresses");
-+ "僅能選擇 lcc 列表, 其他的地址請用 bcc");
- break;
- }
- else{
-@@ -5004,7 +5005,7 @@
- }
- else if(dl->type == ListHead && no_fullname){
- q_status_message(SM_ORDER, 0, 4,
-- "You may not select a list, select a single address instead");
-+ "無法選擇一個列表, 改以選擇單一地址取代之");
- break;
- }
- else{
-@@ -5074,8 +5075,8 @@
- return(addr); /* Caller frees this */
- }
- else{
-- q_status_message1(SM_ORDER, 3, 4, "No %s selected",
-- selecting_nick ? "nickname" : "address");
-+ q_status_message1(SM_ORDER, 3, 4, "尚未選取%s",
-+ selecting_nick ? "暱稱" : "地址");
- break;
- }
+ ps->mangled_footer = 1;
+ buf[0] = '\0';
+- sprintf(tmp, "Word to find %s%s%s: ",
++ sprintf(tmp, "欲搜尋的單字 %s%s%s: ",
+ (last[0]) ? "[" : "",
+ (last[0]) ? last : "",
+ (last[0]) ? "]" : "");
+@@ -4779,7 +4779,7 @@
+ result = "Searched to bottom";
+ }
+ else
+- result = "WhereIs cancelled";
++ result = "取消搜尋";
+
+ if((found & FOUND_IT) && ctmpa){
+ strcpy(last, buf);
+@@ -4798,7 +4798,7 @@
+ screen->current = ctmpa;
+ }
+
+- q_status_message(SM_ORDER,0,3,result ? result : "Word not found");
++ q_status_message(SM_ORDER,0,3,result ? result : "找不到該字");
}
-@@ -5092,7 +5093,7 @@
- edit:
- if((c == 'v' || c == PF4 || c == KEY_MOUSE)
- && !any_addrs_avail(as.top_ent+as.cur_row)){
-- q_status_message(SM_ORDER, 0, 4, "No entries to view");
-+ q_status_message(SM_ORDER, 0, 4, "沒有可供檢視的項目");
- break;
- }
-
-@@ -5161,7 +5162,7 @@
+
+ break;
+@@ -4813,10 +4813,10 @@
+ if(edit_config
+ && (ps_global->restricted || ps_global->readonly_pinerc)){
+ q_status_message1(SM_ORDER, 0, 3,
+- "%s can't change options or settings",
+- ps_global->restricted ? "Pine demo"
+- : "Config file not changeable,");
+- if(cmd == MC_EXIT){
++ "%s無法改變選項或設定",
++ ps_global->restricted ? "Pine 展示版"
++ : "設定檔無法改變,");
++ if(cmd == MC_EXIT || cmd == KEY_LEFT){
+ retval = 0;
+ done++;
}
- else{
- q_status_message(SM_ORDER, 0, 3,
-- "Current line is not editable");
-+ "無法編輯本行");
+@@ -4831,9 +4831,9 @@
+ &screen->current, flags)){
+ case -1:
+ q_status_message2(SM_ORDER, 0, 2,
+- "Command \"%s\" not defined here.%s",
++ "命令 \"%s\" 未在此定義。%s",
+ pretty_command(ch),
+- F_ON(F_BLANK_KEYMENU,ps) ? "" : " See key menu below.");
++ F_ON(F_BLANK_KEYMENU,ps) ? "" : "請參考下列的按鍵清單。");
break;
- }
- }
-@@ -5212,7 +5213,7 @@
- r = prev_selectable_line(as.cur_row+as.top_ent, &new_line);
- if(r == 0){
-- q_status_message(SM_INFO, 0, 1, "Already on first line.");
-+ q_status_message(SM_INFO, 0, 1, "已經到第一行了.");
- break;
+ case 0:
+@@ -5368,11 +5368,11 @@
+ ekey[1].ch = ctrl('P');
+ ekey[1].rval = ctrl('P');
+ ekey[1].name = "^P";
+- ekey[1].label = "Decrease";
++ ekey[1].label = "減少";
+ ekey[2].ch = ctrl('N');
+ ekey[2].rval = ctrl('N');
+ ekey[2].name = "^N";
+- ekey[2].label = "Increase";
++ ekey[2].label = "增加";
+ ekey[3].ch = KEY_DOWN;
+ ekey[3].rval = ctrl('P');
+ ekey[3].name = "";
+@@ -5387,12 +5387,12 @@
+ sval[0] = '\0';
+ switch(cmd){
+ case MC_ADD: /* add to list */
+- if(fixed_var((*cl)->var, "add to", NULL)){
++ if(fixed_var((*cl)->var, "新增", NULL)){
+ break;
+ }
+ else if(!(*cl)->var->is_list && (*cl)->var->user_val.p){
+ q_status_message(SM_ORDER, 3, 3,
+- "Only single value allowed. Use \"Change\".");
++ "僅允許\單一設定值。請用 \"Change\".");
+ }
+ else{
+ int maxwidth =min(80,ps->ttyo->screen_cols) - 15;
+@@ -5416,7 +5416,7 @@
}
-@@ -5254,7 +5255,7 @@
+ sprintf(prompt,
+- "Enter text to insert before \"%.*s\": ",k,tmpval);
++ "輸入插在 \"%.*s\" 之前的字串:",k,tmpval);
+ }
+ else if((*cl)->var->is_list
+ && !(*cl)->var->user_val.l
+@@ -5425,13 +5425,13 @@
+ ekey[0].ch = 'r';
+ ekey[0].rval = 'r';
+ ekey[0].name = "R";
+- ekey[0].label = "Replace";
++ ekey[0].label = "取代";
+ ekey[1].ch = 'a';
+ ekey[1].rval = 'a';
+ ekey[1].name = "A";
+- ekey[1].label = "Add To";
++ ekey[1].label = "加至";
+ ekey[2].ch = -1;
+- strcpy(prompt, "Replace or Add To default value ? ");
++ strcpy(prompt, "取代(R)或加至(A)預設值?");
+ switch(radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'a', 'x',
+ h_config_replace_add, RB_NORM)){
+ case 'a':
+@@ -5445,25 +5445,25 @@
+ }
- r = next_selectable_line(as.cur_row+as.top_ent, &new_line);
- if(r == 0){
-- q_status_message(SM_INFO, 0, 1, "Already on last line.");
-+ q_status_message(SM_INFO, 0, 1, "已經到最後一行了.");
+ add_text:
+- sprintf(prompt, "Enter the %stext to be added : ",
+- flags&CF_NUMBER ? "numeric " : "");
++ sprintf(prompt, "輸入想加入的%s字:",
++ flags&CF_NUMBER ? "數 " : "文");
break;
- }
-
-@@ -5341,7 +5342,7 @@
+
+ case 'r':
+ replace_text:
+- sprintf(prompt, "Enter the %sreplacement text : ",
+- flags&CF_NUMBER ? "numeric " : "");
++ sprintf(prompt, "輸入想取代的%s字:",
++ flags&CF_NUMBER ? "數 " : "文");
break;
-
- if(as.top_ent == new_top_ent && as.cur_row == (fl-as.top_ent)){
-- q_status_message(SM_INFO, 0, 1, "Already on first page.");
-+ q_status_message(SM_INFO, 0, 1, "已經到第一頁了.");
+
+ case 'x':
+ i = 1;
+- q_status_message(SM_ORDER,0,3,"Add cancelled");
++ q_status_message(SM_ORDER,0,3,"取消新增");
break;
}
-
-@@ -5365,7 +5366,7 @@
- else{
- new_top_ent = as.top_ent;
- if(as.cur_row == (fl - as.top_ent)){ /* no change */
-- q_status_message(SM_INFO,0,1,"Already on last page.");
-+ q_status_message(SM_INFO,0,1,"已經到最後一頁了.");
- break;
+ }
+ else
+- sprintf(prompt, "Enter the %stext to be added : ",
+- flags&CF_NUMBER ? "numeric " : "");
++ sprintf(prompt, "輸入想加入的%s字:",
++ flags&CF_NUMBER ? "數 " : "文");
+
+ ps->mangled_footer = 1;
+
+@@ -5480,7 +5480,7 @@
+ ekey[0].ch = ctrl('W');
+ ekey[0].rval = 5;
+ ekey[0].name = "^W";
+- ekey[0].label = after ? "InsertBefore" : "InsertAfter";
++ ekey[0].label = after ? "插在前面" : "插在後面";
+ ekey[1].ch = -1;
+ }
+ else if(!(flags&CF_NUMBER))
+@@ -5534,7 +5534,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER, 0, 3,
+- "Can't add %s to list", empty_val);
++ "無法將 %s 加至列表中", empty_val);
+ rv = ps->mangled_body = 0;
+ }
+
+@@ -5542,7 +5542,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER, 0, 3,
+- "Can't add %s to list", empty_val);
++ "無法將 %s 加至列表中", empty_val);
+ }
+ }
+ else{
+@@ -5550,7 +5550,7 @@
+ && !(isdigit((unsigned char)sval[0])
+ || sval[0] == '-' || sval[0] == '+')){
+ q_status_message(SM_ORDER,3,3,
+- "Entry must be numeric");
++ "該項目必須是數字");
+ i = 3; /* to keep loop going */
+ continue;
+ }
+@@ -5563,7 +5563,7 @@
}
}
-@@ -5398,7 +5399,7 @@
- goto bleep;
-
- if(!any_addrs_avail(as.top_ent+as.cur_row)){
-- q_status_message(SM_ORDER, 0, 4, "No entries to delete");
-+ q_status_message(SM_ORDER, 0, 4, "沒有可供刪除的項目");
- break;
- }
-
-@@ -5467,7 +5468,7 @@
- goto bleep;
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Add cancelled");
++ q_status_message(SM_ORDER,0,3,"取消新增");
+ }
+ else if(i == 3){
+ help = help == NO_HELP ? h_config_add : NO_HELP;
+@@ -5586,8 +5586,8 @@
+ }
- if(!any_addrs_avail(as.top_ent+as.cur_row)){
-- q_status_message(SM_ORDER, 0, 4, "No entries to select");
-+ q_status_message(SM_ORDER, 0, 4, "沒有可供選擇的項目");
- break;
+ sprintf(prompt,
+- "Enter text to insert %s \"%.*s\": ",
+- after ? "after" : "before", k, tmpval);
++ "輸入想要插在 \"%.*s\" %s的文字",
++ k, tmpval, after ? "之後" : "之前");
+ continue;
+ }
+ else if(i == ctrl('P')){
+@@ -5607,7 +5607,7 @@
+ */
+ if(++repeat_key > 0){
+ q_status_message1(SM_ORDER,3,3,
+- "Minimum value is %s", comatose(lowrange));
++ "最小值是 %s", comatose(lowrange));
+ repeat_key = -5;
+ }
+ }
+@@ -5631,7 +5631,7 @@
+ if(numval == hirange){
+ if(++repeat_key > 0){
+ q_status_message1(SM_ORDER,3,3,
+- "Maximum value is %s", comatose(hirange));
++ "最大值是 %s", comatose(hirange));
+ repeat_key = -5;
+ }
+ }
+@@ -5684,7 +5684,7 @@
+ }
+ else if(((*cl)->var->is_list && !(*cl)->var->user_val.l)
+ || (!(*cl)->var->is_list && !(*cl)->var->user_val.p)){
+- q_status_message(SM_ORDER, 0, 3, "No set value to delete");
++ q_status_message(SM_ORDER, 0, 3, "沒有可供刪除的設定值");
+ }
+ else{
+ if((*cl)->var->is_fixed)
+@@ -5700,7 +5700,8 @@
+ : "<NULL VALUE>",
+ (*cl)->var->name);
+ else
+- sprintf(prompt, "Really delete %s%.20s from %.30s ",
++ sprintf(prompt, "確定自 %.30s 刪除 %s%.20s ",
++ (*cl)->var->name,
+ (*cl)->var->is_list ? "item " : "",
+ (*cl)->var->is_list
+ ? int2string((*cl)->varmem + 1)
+@@ -5708,8 +5709,7 @@
+ ? (!*(*cl)->var->user_val.p)
+ ? empty_val2
+ : (*cl)->var->user_val.p
+- : "<NULL VALUE>",
+- (*cl)->var->name);
++ : "<NULL VALUE>");
+
+ ps->mangled_footer = 1;
+ if(want_to(prompt, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
+@@ -5724,7 +5724,7 @@
+ }
}
+ else
+- q_status_message(SM_ORDER, 0, 3, "Value not deleted");
++ q_status_message(SM_ORDER, 0, 3, "設定值未被刪除");
+ }
-@@ -5486,7 +5487,7 @@
-
- if(style == SelectAddrLccCom && dl->type != ListHead)
- q_status_message(SM_ORDER, 0, 4,
-- "You may only select lists for lcc, use bcc for personal entries");
-+ "僅能選擇 lcc 列表, 個人項目請用 bcc");
- else if(dl->type == ListHead || dl->type == Simple){
- current_changed_flag++;
- if(entry_is_checked(pab->address_book->checks,
-@@ -6803,7 +6804,7 @@
- if(full_to && *full_to)
- fs_give((void **)full_to);
-
-- q_status_message(SM_ORDER, 3, 5, "Resetting address book...");
-+ q_status_message(SM_ORDER, 3, 5, "正在重設地址簿...");
- dprint(1, (debugfile,
- "RESETTING address book... verify_addr(%s)!\n", to));
- addrbook_reset();
-@@ -6849,12 +6850,12 @@
- ps_global->redrawer = NULL;
- fix_windsize(ps_global);
-
-- switch(want_to("Exit and save changes ", 'y', 0, NO_HELP, 0, 0)){
-+ switch(want_to("離開並儲存改變 ", 'y', 0, NO_HELP, 0, 0)){
- case 'y':
break;
+@@ -5853,7 +5853,7 @@
+ && !(isdigit((unsigned char)sval[0])
+ || sval[0] == '-' || sval[0] == '+')){
+ q_status_message(SM_ORDER,3,3,
+- "Entry must be numeric");
++ "該項目必須是數字");
+ continue;
+ }
- case 'n':
-- rstr = "Use ^C to abandon changes you've made";
-+ rstr = "以 ^C 放棄已經做過的改變";
- break;
+@@ -5867,7 +5867,7 @@
+ }
+ }
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Change cancelled");
++ q_status_message(SM_ORDER,0,3,"取消修改");
+ }
+ else if(i == 3){
+ help = help == NO_HELP ? h_config_change : NO_HELP;
+@@ -5885,7 +5885,7 @@
+ */
+ if(++repeat_key > 0){
+ q_status_message1(SM_ORDER,3,3,
+- "Minimum value is %s", comatose(lowrange));
++ "最小值是 %s", comatose(lowrange));
+ repeat_key = -5;
+ }
+ }
+@@ -5901,7 +5901,7 @@
+ if(numval == hirange){
+ if(++repeat_key > 0){
+ q_status_message1(SM_ORDER,3,3,
+- "Maximum value is %s", comatose(hirange));
++ "最大值是 %s", comatose(hirange));
+ repeat_key = -5;
+ }
+ }
+@@ -5988,15 +5988,15 @@
+ if(flags & CF_CHANGES){
+ switch(want_to(EXIT_PMT, 'y', 'x', h_config_undo, WT_FLUSH_IN)){
+ case 'y':
+- q_status_message1(SM_ORDER,0,3,"%s changes saved", cmd);
++ q_status_message1(SM_ORDER,0,3,"%s 的改變已存檔", cmd);
+ return(2);
+
+ case 'n':
+- q_status_message1(SM_ORDER,3,5,"No %s changes saved", cmd);
++ q_status_message1(SM_ORDER,3,5,"%s 改變未存檔", cmd);
+ return(10);
+
+ case 'x': /* ^C */
+- q_status_message(SM_ORDER,3,5,"Changes not yet saved");
++ q_status_message(SM_ORDER,3,5,"改變尚未被存檔");
+ return(0);
+ }
+ }
+@@ -6288,7 +6288,7 @@
+ && want_to("Delete old unused personal option setting",
+ 'y', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
+ fs_give((void **)&(*cl)->var->user_val.p);
+- q_status_message(SM_ORDER, 0, 3, "Deleted");
++ q_status_message(SM_ORDER, 0, 3, "已刪除");
+ rv = 1;
+ }
- #ifdef OLDWAY
-@@ -6884,8 +6885,8 @@
- char *rstr = NULL;
- void (*redraw)() = ps_global->redrawer;
+@@ -6427,7 +6427,7 @@
+ && want_to("Delete old unused personal option setting",
+ 'y', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
+ fs_give((void **)&(*cl)->var->user_val.p);
+- q_status_message(SM_ORDER, 0, 3, "Deleted");
++ q_status_message(SM_ORDER, 0, 3, "已刪除");
+ rv = 1;
+ }
-- strcat(strcat(strcpy(prompt, "Cancel "), word),
-- " (answering \"Yes\" will abandon any changes made) ");
-+ strcat(strcat(strcpy(prompt, "取消 "), word),
-+ " (回答 \"Yes\" 將放棄所有曾做過的改變) ");
- ps_global->redrawer = NULL;
- fix_windsize(ps_global);
-
-@@ -7020,7 +7021,7 @@
- abe = ae(cur_line);
+@@ -6517,15 +6517,15 @@
+ fs_give((void **)&q);
+ }
- if(dl->type == ListHead && listmem_count_from_abe(abe) == 0){
-- error = "List is empty, nothing to export!";
-+ error = "列表是空的, 無法匯出任河東西!";
- good_addr = 0;
- }
- else if(dl->type == ListEnt){
-@@ -7073,7 +7074,7 @@
+- q_status_message3(SM_ORDER,0,3, "Default printer %s%s%s",
+- p ? "set to \"" : "unset", p ? p : "", p ? "\"" : "");
++ q_status_message3(SM_ORDER,0,3, "預設印表機目前%s%s%s",
++ p ? "設定為 \"" : "未設", p ? p : "", p ? "\"" : "");
- if(addr && *addr){
- static ESCKEY_S export_opts[] = {
-- {ctrl('T'), 10, "^T", "To Files"},
-+ {ctrl('T'), 10, "^T", "信夾列表"},
- {-1, 0, NULL, NULL}};
- HelpType help;
- char filename[MAXPATH+1], full_filename[MAXPATH+1];
-@@ -8115,7 +8116,7 @@
- ? (char *)rfc1522_decode((unsigned char *)tmp_20k_buf,
- abe->fullname, NULL)
- : abe->nickname ? abe->nickname : "";
-- cmd = "Really delete \"%.50s\"";
-+ cmd = "確定刪除 \"%.50s\"";
- break;
-
- case ListHead:
-@@ -8123,13 +8124,13 @@
- ? (char *)rfc1522_decode((unsigned char *)tmp_20k_buf,
- abe->fullname, NULL)
- : abe->nickname ? abe->nickname : "";
-- cmd = "Really delete ENTIRE list \"%.50s\"";
-+ cmd = "確定刪除 \"整個\" 列表 \"%.50s\"";
- break;
-
- case ListEnt:
- dname = (char *)rfc1522_decode((unsigned char *)tmp_20k_buf,
- listmem_from_dl(abook, dl), NULL);
-- cmd = "Really delete \"%.100s\" from list";
-+ cmd = "確定自列表中刪除 \"%.100s\"";
- break;
- }
-
-@@ -8198,7 +8199,7 @@
-
- if(rc == 0){
- q_status_message(SM_ORDER, 0, 3,
-- "Entry deleted, address book updated");
-+ "已刪除該項目並更新地址簿");
- dprint(2, (debugfile, "abook: Entry %s\n",
- (dl->type == Simple || dl->type == ListHead) ? "deleted"
- : "modified"));
-@@ -8215,7 +8216,7 @@
-
- if(rc != -5)
- q_status_message1(SM_ORDER | SM_DING, 3, 5,
-- "Error updating address book: %s",
-+ "更新地址簿時發生錯誤: %s",
- error_description(errno));
- pab = &as.adrbks[as.cur];
- dprint(1, (debugfile, "Error deleting entry from %s (%s): %s\n",
-@@ -8225,7 +8226,7 @@
- return 0;
- }
- else{
-- q_status_message(SM_INFO, 0, 2, "Entry not deleted");
-+ q_status_message(SM_INFO, 0, 2, "該項目並未被刪除");
- return 0;
- }
- }
-@@ -8275,7 +8276,7 @@
- ekey[0].ch = ctrl('T');
- ekey[0].rval = 2;
- ekey[0].name = "^T";
-- ekey[0].label = "To AddrBk";
-+ ekey[0].label = "地址列表";
+ if(p)
+ fs_give((void **)&p);
+ }
+ else
+ q_status_message(SM_ORDER,3,5,
+- "Trouble setting default printer");
++ "有問題的預設印表機");
- ekey[1].ch = -1;
+ retval = 1;
+ }
+@@ -6536,11 +6536,11 @@
+ set_variable(V_PERSONAL_PRINT_CATEGORY,
+ comatose(ps->printer_category), 0);
+ q_status_message1(SM_ORDER,0,3,
+- "Default printer set to \"%s\"", ANSI_PRINTER);
++ "預設印表機設定為 \"%s\"", ANSI_PRINTER);
+ }
+ else
+ q_status_message(SM_ORDER,3,5,
+- "Trouble setting default printer");
++ "有問題的預設印表機");
-@@ -8305,7 +8306,7 @@
+ retval = 1;
}
+@@ -6555,11 +6555,11 @@
+ set_variable(V_PERSONAL_PRINT_CATEGORY,
+ comatose(ps->printer_category), 0);
+ q_status_message1(SM_ORDER,0,3,
+- "Default printer set to \"%s\"", aname);
++ "預設印表機設定為 \"%s\"", aname);
+ }
+ else
+ q_status_message(SM_ORDER,3,5,
+- "Trouble setting default printer");
++ "有問題的預設印表機");
- q_status_message1(SM_ORDER, 0, 4,
-- "Already an entry with nickname \"%s\"", edit_buf);
-+ "已經有一個暱稱為 \"%s\" 的項目", edit_buf);
- }
+ retval = 1;
+ }
+@@ -6609,7 +6609,7 @@
+ switch(cmd){
+ case MC_ADD: /* add to list */
+ sval[0] = '\0';
+- if(!fixed_var((*cl)->var, "add to", NULL)){
++ if(!fixed_var((*cl)->var, "新增", NULL)){
+
+ if((*cl)->var->user_val.l && (*cl)->value){
+ strcpy(prompt, "Enter printer name : ");
+@@ -6641,17 +6641,17 @@
+ ltmp[k + 1] = ltmp[k] = NULL;
+
+ add_text:
+- strcpy(prompt, "Enter name of printer to be added : ");
++ strcpy(prompt, "欲新增的印表機名稱:");
+ break;
+
+ case 'r':
+ replace_text:
+ strcpy(prompt,
+- "Enter the name for replacement printer : ");
++ "欲取代的印表機名稱:");
+ break;
+
+ case 'x':
+- q_status_message(SM_ORDER,0,3,"Add cancelled");
++ q_status_message(SM_ORDER,0,3,"取消新增");
+ break;
+ }
- if(rc == 3)
-@@ -8429,12 +8430,12 @@
- ekey[1].ch = ctrl('Y');
- ekey[1].rval = 10;
- ekey[1].name = "^Y";
-- ekey[1].label = "First Adr";
-+ ekey[1].label = "第一個地址";
-
- ekey[2].ch = ctrl('V');
- ekey[2].rval = 11;
- ekey[2].name = "^V";
-- ekey[2].label = "Last Adr";
-+ ekey[2].label = "最後的地址";
-
- ekey[3].ch = -1;
-
-@@ -8450,11 +8451,11 @@
- warp_to_beginning(); /* go to top of addrbooks */
- if((nl=first_selectable_line(0L)) != NO_LINE){
- *new_line = nl;
-- q_status_message(SM_INFO, 0, 2, "Searched to first entry");
-+ q_status_message(SM_INFO, 0, 2, "搜尋至第一個項目");
- return 0;
+@@ -6659,7 +6659,7 @@
+ break;
}
- else{
-- q_status_message(SM_INFO, 0, 2, "No entries");
-+ q_status_message(SM_INFO, 0, 2, "沒有任何項目");
- return -1;
+ else
+- strcpy(prompt, "Enter name of printer to be added : ");
++ strcpy(prompt, "欲新增的印表機名稱:");
+
+ ps->mangled_footer = 1;
+ help = NO_HELP;
+@@ -6671,7 +6671,7 @@
+ ekey[0].ch = ctrl('W');
+ ekey[0].rval = 5;
+ ekey[0].name = "^W";
+- ekey[0].label = after ? "InsertBefore" : "InsertAfter";
++ ekey[0].label = after ? "插在之前" : "插在之後";
+ ekey[1].ch = -1;
+ }
+ else
+@@ -6688,7 +6688,7 @@
+ removing_trailing_white_space(name);
+ }
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Add cancelled");
++ q_status_message(SM_ORDER,0,3,"取消新增");
+ }
+ else if(i == 3){
+ help = (help == NO_HELP) ? h_config_insert_after : NO_HELP;
+@@ -6742,7 +6742,7 @@
+ * Don't allow input of multiple entries at once.
+ */
+ q_status_message(SM_ORDER,3,5,
+- "No commas allowed in command");
++ "命令中不可有逗號");
+ i = 2;
+ continue;
+ }
+@@ -6757,10 +6757,10 @@
+ }
+ else
+ q_status_message1(SM_ORDER, 0, 3,
+- "Can't add %s to list", empty_val);
++ "無法新增 %s 至列表中", empty_val);
+ }
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Add cancelled");
++ q_status_message(SM_ORDER,0,3,"取消新增");
+ }
+ else if(i == 3){
+ help = help == NO_HELP ? h_config_print_cmd : NO_HELP;
+@@ -6798,19 +6798,19 @@
}
}
-@@ -8463,11 +8464,11 @@
- warp_to_end(); /* go to bottom */
- if((nl=first_selectable_line(0L)) != NO_LINE){
- *new_line = nl;
-- q_status_message(SM_INFO, 0, 2, "Searched to last entry");
-+ q_status_message(SM_INFO, 0, 2, "搜尋至最終項");
- return 0;
+ else if(!(*cl)->var->user_val.l){
+- q_status_message(SM_ORDER, 0, 3, "No set value to delete");
++ q_status_message(SM_ORDER, 0, 3, "沒有任何設定值遭刪除");
+ }
+ else{
+ if((*cl)->var->is_fixed){
+ parse_printer((*cl)->var->user_val.l[(*cl)->varmem],
+ &nick, &p, NULL, NULL, NULL, NULL);
+- sprintf(prompt, "Delete (unused) printer %.30s ",
++ sprintf(prompt, "刪除 (未使用的) 印表機 %.30s ",
+ *nick ? nick : (!*p) ? empty_val2 : p);
+ fs_give((void **)&nick);
+ fs_give((void **)&p);
}
- else{
-- q_status_message(SM_INFO, 0, 2, "No entries");
-+ q_status_message(SM_INFO, 0, 2, "沒有任何項目");
- return -1;
+ else
+- sprintf(prompt, "Really delete item %.20s from printer list ",
++ sprintf(prompt, "確定自印表機列表中刪除 %.20s",
+ int2string((*cl)->varmem + 1));
+
+ ps->mangled_footer = 1;
+@@ -6820,7 +6820,7 @@
+ config_del_list_item(cl, &newval);
}
+ else
+- q_status_message(SM_ORDER, 0, 3, "Printer not deleted");
++ q_status_message(SM_ORDER, 0, 3, "印表機未被刪除");
}
-@@ -9016,7 +9017,7 @@
-
- memcpy(save_jmp_buf, addrbook_changed_unexpectedly, sizeof(jmp_buf));
- if(setjmp(addrbook_changed_unexpectedly)){
-- q_status_message(SM_ORDER, 5, 10, "Resetting address book...");
-+ q_status_message(SM_ORDER, 5, 10, "正在重設地址簿...");
- dprint(1, (debugfile,
- "RESETTING address book... take_to_addrbooks_frontend!\n"));
- addrbook_reset();
-@@ -9095,7 +9096,7 @@
- abe = adrbk_lookup_by_nick(abook, new_nickname, &entry_num);
- if(!abe){ /* this shouldn't happen */
- q_status_message1(SM_ORDER, 0, 4,
-- "Already an entry %s in address book!",
-+ "已經在地址簿中發現 %s 這個項目!",
- new_nickname);
- goto take_to_addrbooks_cancel;
- }
-@@ -9103,7 +9104,7 @@
- old_tag = abe->tag;
-
- sprintf(prompt,
-- "%s %s (%s) exists, replace or add addresses to it ? ",
-+ "%s %s (%s) 已存在, 取代或加入新的地址於其中 ? ",
- abe->tag == List ? "List" : "Entry",
- new_nickname,
- (abe->fullname && abe->fullname[0])
-@@ -9129,7 +9130,7 @@
- if((long)abook->count > MAX_ADRBK_SIZE ||
- (old_tag == NotSet && (long)abook->count >= MAX_ADRBK_SIZE)){
- q_status_message(SM_ORDER, 3, 5,
-- "Address book is at maximum size. TakeAddr cancelled.");
-+ "地址簿容量已達上限. 取消 TakeAddr.");
- dprint(2, (debugfile, "Addrbook at Max size, TakeAddr cancelled\n"));
- goto take_to_addrbooks_cancel;
- }
-@@ -9225,7 +9226,7 @@
- save_state(state);
- if(as.n_addrbk == 0){
-- q_status_message(SM_ORDER, 3, 4, "Can't open address book!");
-+ q_status_message(SM_ORDER, 3, 4, "無法開啟地址簿!");
- return NULL;
- }
- else
-@@ -9238,7 +9239,7 @@
- init_abook(pab, Open);
+ break;
+@@ -6831,7 +6831,7 @@
+ && !strucmp(ps->VAR_PRINTER,(*cl)->var->current_val.l[(*cl)->varmem]))
+ changing_selected = 1;
+
+- if(fixed_var((*cl)->var, NULL, "printer"))
++ if(fixed_var((*cl)->var, NULL, "印表機"))
+ break;
+ else if(!(*cl)->var->user_val.l && (*cl)->var->current_val.l)
+ goto replace_text;
+@@ -6843,22 +6843,22 @@
+ ekey[0].ch = 'n';
+ ekey[0].rval = 'n';
+ ekey[0].name = "N";
+- ekey[0].label = "Name";
++ ekey[0].label = "名稱";
+ ekey[1].ch = 'c';
+ ekey[1].rval = 'c';
+ ekey[1].name = "C";
+- ekey[1].label = "Command";
++ ekey[1].label = "命令";
+ ekey[2].ch = 'o';
+ ekey[2].rval = 'o';
+ ekey[2].name = "O";
+- ekey[2].label = "Options";
++ ekey[2].label = "選項";
+ ekey[3].ch = -1;
+- strcpy(prompt, "Change Name or Command or Options ? ");
++ strcpy(prompt, "修改名稱、命令或選項?");
+ i = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'c', 'x',
+ h_config_print_name_cmd, RB_NORM);
+
+ if(i == 'x'){
+- q_status_message(SM_ORDER,0,3,"Change cancelled");
++ q_status_message(SM_ORDER,0,3,"取消修改");
+ break;
+ }
+ else if(i == 'c'){
+@@ -6867,7 +6867,7 @@
+ parse_printer((*cl)->var->user_val.l[(*cl)->varmem],
+ NULL, &p, NULL, NULL, NULL, &all_but_cmd);
+
+- strcpy(prompt, "Change command : ");
++ strcpy(prompt, "修改命令:");
+ strcpy(sval, p ? p : "");
+ fs_give((void **)&p);
+
+@@ -6906,12 +6906,12 @@
+ * Don't allow input of multiple entries at once.
+ */
+ q_status_message(SM_ORDER,3,5,
+- "No commas allowed in command");
++ "命令中不可有逗號");
+ continue;
+ }
+ }
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Change cancelled");
++ q_status_message(SM_ORDER,0,3,"取消修改");
+ }
+ else if(i == 3){
+ help = help == NO_HELP ? h_config_change : NO_HELP;
+@@ -6930,7 +6930,7 @@
+ parse_printer((*cl)->var->user_val.l[(*cl)->varmem],
+ &p, NULL, NULL, NULL, &all_but_nick, NULL);
+
+- strcpy(prompt, "Change name : ");
++ strcpy(prompt, "修改名稱:");
+ strcpy(name, p ? p : "");
+ fs_give((void **)&p);
+
+@@ -6960,7 +6960,7 @@
+ newval = &(*cl)->value;
+ }
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Change cancelled");
++ q_status_message(SM_ORDER,0,3,"取消修改");
+ }
+ else if(i == 3){
+ help = help == NO_HELP ? h_config_change : NO_HELP;
+@@ -6981,18 +6981,18 @@
+ ekey[0].ch = 'i';
+ ekey[0].rval = 'i';
+ ekey[0].name = "I";
+- ekey[0].label = "Init";
++ ekey[0].label = "初始";
+ ekey[1].ch = 't';
+ ekey[1].rval = 't';
+ ekey[1].name = "T";
+- ekey[1].label = "Trailer";
++ ekey[1].label = "結束";
+ ekey[2].ch = -1;
+- strcpy(prompt, "Change Init string or Trailer string ? ");
++ strcpy(prompt, "修改初始或結束字串?");
+ j = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'i', 'x',
+ h_config_print_opt_choice, RB_NORM);
+
+ if(j == 'x'){
+- q_status_message(SM_ORDER,0,3,"Change cancelled");
++ q_status_message(SM_ORDER,0,3,"取消修改");
+ break;
+ }
+ else{
+@@ -7001,8 +7001,8 @@
+ parse_printer((*cl)->var->user_val.l[(*cl)->varmem],
+ &nick, &p, &init, &trailer, NULL, NULL);
+
+- sprintf(prompt, "Change %s string : ",
+- (j == 'i') ? "INIT" : "TRAILER");
++ sprintf(prompt, "修改 %s 字串:",
++ (j == 'i') ? "初始" : "結束");
+ strcpy(sval, (j == 'i') ? init : trailer);
+
+ tmp = string_to_cstring(sval);
+@@ -7057,7 +7057,7 @@
+ newval = &(*cl)->value;
+ }
+ else if(i == 1){
+- q_status_message(SM_ORDER,0,3,"Change cancelled");
++ q_status_message(SM_ORDER,0,3,"取消修改");
+ }
+ else if(i == 3){
+ help=(help == NO_HELP)?h_config_print_init:NO_HELP;
+@@ -7135,18 +7135,18 @@
+
+ case MC_DELETE :
+ if((*cl)->d.c.ct->use & CNTXT_INCMNG)
+- q_status_message1(SM_ORDER, 0, 3, "Sorry, Can't delete %s",
++ q_status_message1(SM_ORDER, 0, 3, "很抱歉,無法刪除 %s",
+ (*cl)->d.c.ct->nickname);
+- else if(!fixed_var((*cl)->var, "delete", "collection"))
++ else if(!fixed_var((*cl)->var, "刪除", "總集"))
+ context_select_delete(ps, cl);
- if(pab->ostatus != Open){
-- q_status_message(SM_ORDER, 3, 4, "Can't open address book!");
-+ q_status_message(SM_ORDER, 3, 4, "無法開啟地址簿!");
- return NULL;
- }
+ break;
-@@ -9247,7 +9248,7 @@
- readonly_warning(NO_DING, NULL);
- else if(pab->access == NoAccess)
- q_status_message(SM_ORDER, 3, 4,
-- "AddressBook not accessible, permission denied");
-+ "禁址存取地址簿");
+ case MC_EDIT :
+ if((*cl)->d.c.ct->use & CNTXT_INCMNG)
+- q_status_message1(SM_ORDER, 0, 3, "Sorry, Can't rename %s",
++ q_status_message1(SM_ORDER, 0, 3, "很抱歉,無法更名 %s",
+ (*cl)->d.c.ct->nickname);
+- else if(!fixed_var((*cl)->var, "add to", "collection")){
++ else if(!fixed_var((*cl)->var, "新增", "總集")){
+ context_select_edit(ps, cl);
+ ps->mangled_screen = 1;
+ }
+@@ -7154,7 +7154,7 @@
+ break;
- return NULL;
- }
-@@ -9469,7 +9470,7 @@
- if(full_lcc && *full_lcc)
- fs_give((void **)full_lcc);
-
-- q_status_message(SM_ORDER, 3, 5, "Resetting address book...");
-+ q_status_message(SM_ORDER, 3, 5, "正在重設地址簿...");
- dprint(1, (debugfile,
- "RESETTING address book... build_address(%s)!\n", lcc));
- addrbook_reset();
-@@ -9723,7 +9724,7 @@
- if(full_to && *full_to)
- fs_give((void **)full_to);
-
-- q_status_message(SM_ORDER, 3, 5, "Resetting address book...");
-+ q_status_message(SM_ORDER, 3, 5, "正在重設地址簿...");
- dprint(1, (debugfile,
- "RESETTING address book... build_address(%s)!\n", to));
- addrbook_reset();
-@@ -10617,7 +10618,7 @@
- if(state.dlc_to_warp_to)
- fs_give((void **)&(state.dlc_to_warp_to));
-
-- q_status_message(SM_ORDER, 3, 5, "Resetting address book...");
-+ q_status_message(SM_ORDER, 3, 5, "正在重設地址簿...");
- dprint(1, (debugfile,
- "RESETTING address book... get_nickname_from_addr()!\n"));
- addrbook_reset();
-@@ -10668,7 +10669,7 @@
- if(state.dlc_to_warp_to)
- fs_give((void **)&(state.dlc_to_warp_to));
-
-- q_status_message(SM_ORDER, 3, 5, "Resetting address book...");
-+ q_status_message(SM_ORDER, 3, 5, "正在重設地址簿...");
- dprint(1, (debugfile,
- "RESETTING address book... get_fcc_from_addr()!\n"));
- addrbook_reset();
-@@ -11484,21 +11485,21 @@
-
-
- static struct key takeaddr_keys_listmode[] =
-- {{"?","Help",KS_SCREENHELP}, {"W","WhereIs",KS_WHEREIS},
-- {"E","ExitTake",KS_EXITMODE}, {"T","Take",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next", KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"X","[Set/Unset]",KS_NONE}, {"A","SetAll",KS_NONE},
-- {"U","UnSetAll",KS_NONE}, {"S","SinglMode",KS_NONE}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {"W","搜尋",KS_WHEREIS},
-+ {"E","離開",KS_EXITMODE}, {"T","取得",KS_NONE},
-+ {"P","上一個",KS_NONE}, {"N","下一個", KS_NONE},
-+ {"-","前一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"X","[設定/取消設定]",KS_NONE}, {"A","設定全部",KS_NONE},
-+ {"U","取消設定全部",KS_NONE}, {"S","單一模式",KS_NONE}};
- INST_KEY_MENU(takeaddr_keymenu_listmode, takeaddr_keys_listmode);
-
- static struct key takeaddr_keys_singlemode[] =
-- {{"?","Help",KS_SCREENHELP}, {"W","WhereIs",KS_WHEREIS},
-- {"E","ExitTake",KS_EXITMODE}, {"T","[Take]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next", KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {NULL,NULL,KS_NONE}, {"L","ListMode",KS_NONE}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {"W","搜尋",KS_WHEREIS},
-+ {"E","離開",KS_EXITMODE}, {"T","[取得]",KS_NONE},
-+ {"P","上一個",KS_NONE}, {"N","下一個", KS_NONE},
-+ {"-","前一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-+ {NULL,NULL,KS_NONE}, {"L","列表模式",KS_NONE}};
- INST_KEY_MENU(takeaddr_keymenu_singlemode, takeaddr_keys_singlemode);
-
-
-@@ -11692,6 +11693,7 @@
- break;
+ case MC_ADD :
+- if(!fixed_var((*cl)->var, "add to", "collection")){
++ if(!fixed_var((*cl)->var, "新增", "總集")){
+ context_select_add(ps, cl);
+ ps->mangled_screen = 1;
+ }
+@@ -7163,9 +7163,9 @@
- case 'e': /* exit takeaddr screen */
-+ case KEY_LEFT:
- case PF3:
- case ctrl('C'):
- cancel_warning(NO_DING, "addition");
-@@ -11699,10 +11701,11 @@
- break;
+ case MC_SHUFFLE :
+ if((*cl)->d.c.ct->use & CNTXT_INCMNG)
+- q_status_message1(SM_ORDER, 0, 3, "Sorry, Can't Shuffle %s",
++ q_status_message1(SM_ORDER, 0, 3, "很抱歉,無法重整 %s",
+ (*cl)->d.c.ct->nickname);
+- else if(!fixed_var((*cl)->var, "Shuffle", "collection"))
++ else if(!fixed_var((*cl)->var, "重整", "總集"))
+ context_select_shuffle(ps, cl);
- case 't': /* take */
-+ case KEY_RIGHT:
- case PF4:
- case ctrl('M'):
- case ctrl('J'):
-- if((ch == ctrl('M') || ch == ctrl('J'))
-+ if((ch == ctrl('M') || ch == ctrl('J') || ch == KEY_RIGHT)
- && screen.mode == ListMode)
- goto SelectCase; /* default is different in this case */
-
-@@ -11727,7 +11730,7 @@
- if(ctmp = next_sel_taline(current))
- current = ctmp;
- else
-- q_status_message(SM_INFO, 0, 1, "Already on last line.");
-+ q_status_message(SM_INFO, 0, 1, "已經到最後一行了.");
+ break;
+@@ -7232,7 +7232,7 @@
+ struct key_menu *km;
+ CONT_SCR_S *cs;
- break;
+- if(raw_ctxt = context_edit_screen(ps, "ADD", NULL, NULL, NULL, NULL)){
++ if(raw_ctxt = context_edit_screen(ps, "新增", NULL, NULL, NULL, NULL)){
-@@ -11739,7 +11742,7 @@
- if(ctmp = pre_sel_taline(current))
- current = ctmp;
- else
-- q_status_message(SM_INFO, 0, 1, "Already on first line.");
-+ q_status_message(SM_INFO, 0, 1, "已經到第一行了.");
+ /* create a corresponding new CONF_S */
+ new_ctxt = new_context(raw_ctxt, NULL);
+@@ -7311,7 +7311,7 @@
- break;
+ /* Tell the user it was a huge success... */
+ q_status_message(SM_ORDER, 0, 3,
+- "New collection added! Use \"$\" to adjust order.");
++ "新的總集加入了!請用 \"$\" 調整順序。");
+ }
+ }
-@@ -11759,7 +11762,7 @@
- }
+@@ -7330,11 +7330,11 @@
- if(give_warn_message)
-- q_status_message(SM_INFO, 0, 1, "Already on last page.");
-+ q_status_message(SM_INFO, 0, 1, "已經在最後一頁了.");
+ if(!((*cl)->var->user_val.l && (*cl)->var->user_val.l[0])){
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Can't delete default value. Try rename.");
++ "無法刪除預設值。試試更名。");
+ return;
+ }
- break;
+- sprintf(tmp, "Delete the collection definition for \"%.40s\"",
++ sprintf(tmp, "刪除 \"%.40s\" 的總集定義",
+ old_cl->value);
+ if(want_to(tmp, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
+ /* Remove from var list */
+@@ -7446,12 +7446,12 @@
+ ps->mangled_body = 1;
+ q_status_message(SM_ORDER, 0, 3,
+ (old_cl == *cl)
+- ? "Last collection deleted. Using default."
+- : "Collection deleted");
++ ? "最後一個總集已被刪除。使用預設值。"
++ : "褻陘w被刪除");
-@@ -11789,7 +11792,7 @@
- }
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "No collections deleted");
++ q_status_message(SM_ORDER, 0, 3, "沒有任何總集被刪除");
+ }
- if(give_warn_message)
-- q_status_message(SM_INFO, 0, 1, "Already on first page.");
-+ q_status_message(SM_INFO, 0, 1, "已經在第一頁了.");
- break;
+@@ -7473,7 +7473,7 @@
+ if(p = strstr(tpath, "%s"))
+ *p = '\0';
-@@ -11873,25 +11876,25 @@
- case PF12:
- if(screen.mode == ListMode && ch == 'l'){
- q_status_message(SM_INFO, 0, 1,
-- "Already in ListMode. Press \"S\" for Single entry mode.");
-+ "已經在列表模式. 以 \"S\" 進入單一選項模式.");
- break;
- }
+- if(raw_ctxt = context_edit_screen(ps, "EDIT", (*cl)->d.c.ct->nickname,
++ if(raw_ctxt = context_edit_screen(ps, "編輯", (*cl)->d.c.ct->nickname,
+ (*cl)->d.c.ct->server, tpath,
+ (*cl)->d.c.ct->dir->view.user)){
- if(screen.mode == SingleMode && ch == 's'){
- q_status_message(SM_INFO, 0, 1,
-- "Already in SingleMode. Press \"L\" for List entry mode.");
-+ "已經在單一選項模式. 以 \"L\" 進入列表模式.");
- break;
- }
+@@ -7543,7 +7543,7 @@
- if(screen.mode == ListMode){
- screen.mode = SingleMode;
- q_status_message(SM_INFO, 0, 1,
-- "Single mode: Use \"P\" or \"N\" to select desired address");
-+ "單一選項模式: 以 \"P\" 或 \"N\" 選擇需要的地址");
- }
- else{
- screen.mode = ListMode;
- q_status_message(SM_INFO, 0, 1,
-- "List mode: Use \"X\" to mark addresses to be included in list");
-+ "列表模式: 以 \"X\" 標註欲加入列表中的地址");
-
- if(how_many_selected <= 1){
- how_many_selected =
-@@ -12083,24 +12086,24 @@
- }
- else if(rc == 10){
- current = first_sel_taline(current);
-- result = "Searched to top";
-+ result = "向前搜尋";
- }
- else if(rc == 11){
- current = last_sel_taline(current);
-- result = "Searched to bottom";
-+ result = "向後搜尋";
- }
- else{
- current = NULL;
-- result = "WhereIs cancelled";
-+ result = "取消搜尋";
- }
+ set_current_val((*cl)->var, TRUE, FALSE);
- if(found){
- current = p;
-- result = wrapped ? "Search wrapped to beginning" : "Word found";
-+ result = wrapped ? "從頭搜尋" : "找不到該字";
- strcpy(last, buf);
+- q_status_message(SM_ORDER, 0, 3, "Collection list entry updated");
++ q_status_message(SM_ORDER, 0, 3, "已更新總集列表");
}
-
-- q_status_message(SM_ORDER,0,3,result ? result : "Word not found");
-+ q_status_message(SM_ORDER,0,3,result ? result : "找不到該字");
- return(current);
}
-@@ -12770,7 +12773,7 @@
- &body);
- if(!env){
- q_status_message(SM_ORDER | SM_DING, 3, 4,
-- "Can't take address into address book. Error accessing folder");
-+ "無法將地址存入地址簿中. 檔案夾存取錯誤");
- goto bomb;
+@@ -7585,7 +7585,7 @@
+ if((cmd = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey,
+ (n == 1) ? 'd' : 0, 'x',
+ NO_HELP, RB_NORM)) == 'x'){
+- cmd_cancelled("Shuffle");
++ cmd_cancelled("重整");
+ }
+ else if((cmd == 'u' && (ctmp = context_select_prev(*cl)))
+ || (cmd == 'd' && (ctmp = context_select_next(*cl)))){
+@@ -7684,7 +7684,7 @@
}
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "Sorry, nothing to Shuffle");
++ q_status_message(SM_ORDER, 0, 3, "很抱歉,沒有東西可供重整");
+ }
+
-@@ -12809,7 +12812,7 @@
- body_h);
- if(!env){
- q_status_message(SM_ORDER | SM_DING, 3, 4,
-- "Can't take address into address book. Error accessing folder");
-+ "無法將地址存入地址簿中. 檔案夾存取錯誤");
- goto bomb;
+@@ -8146,7 +8146,7 @@
+ if(cl->var->current_val.l){
+ int i, l, l2;
+
+- sstrcpy(&p, ": using \"");
++ sstrcpy(&p, ":目前使用 \"");
+ for(i = 0; cl->var->current_val.l[i]; i++){
+ if(i)
+ *p++ = ',';
+@@ -8178,7 +8178,7 @@
+ sprintf(tmp, cl->var->is_fixed
+ ? "<%s%s%s%s>%*s" : "<%s%s%s%s>%*s",
+ cl->var->is_fixed ? fixed_val : no_val,
+- (cl->var->current_val.p) ? ": using \"" : "",
++ (cl->var->current_val.p) ? ":目前使用 \"" : "",
+ (cl->var->current_val.p) ? cl->var->current_val.p : "",
+ (cl->var->current_val.p) ? "\"" : "",
+ max(0, ps->ttyo->screen_cols - cl->valoffset - 13
+@@ -8320,7 +8320,7 @@
+ p = (struncmp(*vp, "no-", 3)) ? *vp : *vp + 3;
+ if(!strucmp(p, f->name) || (og && !strucmp(p, "old-growth"))){
+ q_status_message(SM_ORDER, 3, 3,
+- "Can't change value fixed by sys-admin.");
++ "無法修改系統管理員定義的設定值。");
+ return;
}
+ }
+@@ -8355,7 +8355,7 @@
+ (void *)(F_ON(f->value,ps) ? 1 : 0));
+ else if(f->value == F_ENABLE_INCOMING && F_ON(f->value, ps)){
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Folder List changes will take effect your next pine session.");
++ "資料匣列表的改變將在下次啟動 pine 時生效。");
+ }
+ else if(f->value == F_PRESERVE_START_STOP){
+ /* toggle raw mode settings to make tty driver aware of new setting */
+@@ -8524,8 +8524,8 @@
+ {
+ if(v && v->is_fixed){
+ q_status_message2(SM_ORDER, 3, 3,
+- "Can't %s sys-admin defined %s.",
+- action ? action : "change", name ? name : "value");
++ "無法%s系統管理員定義的%s。",
++ action ? action : "修改", name ? name : "設定值");
+ return(1);
+ }
+@@ -8824,7 +8824,7 @@
+ && var->is_list
+ && !var->user_val.l
+ && var->current_val.l)))
+- q_status_message(SM_ORDER,0,3,"Using default value");
++ q_status_message(SM_ORDER,0,3,"使用預設值");
+
+ if(var == &ps->vars[V_USER_DOMAIN]){
+ char *p, *q;
+@@ -8835,7 +8835,7 @@
+ if(*(++p)){
+ if(!revert)
+ q_status_message2(SM_ORDER, 3, 5,
+- "User-domain (%s) cannot contain \"@\"; using %s",
++ "User-domain (%s) 不可包括 \"@\"; 使用 %s",
+ ps->VAR_USER_DOMAIN, p);
+ q = ps->VAR_USER_DOMAIN;
+ while((*q++ = *p++) != '\0')
+@@ -8844,7 +8844,7 @@
+ else{
+ if(!revert)
+ q_status_message1(SM_ORDER, 3, 5,
+- "User-domain (%s) cannot contain \"@\"; deleting",
++ "User-domain (%s) 不可包括 \"@\"; 刪除中",
+ ps->VAR_USER_DOMAIN);
+ fs_give((void **)&ps->USR_USER_DOMAIN);
+ set_current_val(&ps->vars[V_USER_DOMAIN], TRUE, TRUE);
+@@ -8904,7 +8904,7 @@
+ else if(var == &ps->vars[V_INIT_CMD_LIST]){
+ if(!revert)
+ q_status_message(SM_ASYNC, 0, 3,
+- "Initial command changes will affect your next pine session.");
++ "初始命令的改變將在下次啟動 pine 時生效。");
+ }
+ else if(var == &ps->vars[V_VIEW_HEADERS]){
+ ps->view_all_except = 0;
+@@ -8963,10 +8963,10 @@
+ }
+ else if(timeo == 0L && !revert){
+ q_status_message(SM_ORDER, 4, 6,
+-"Warning: automatic new mail checking and mailbox checkpointing is disabled");
++"警告:已解除自動檢查新郵件與信箱檢查點");
+ if(ps->VAR_INBOX_PATH && ps->VAR_INBOX_PATH[0] == '{')
+ q_status_message(SM_ASYNC, 3, 6,
+-"Warning: mail-check-interval=0 may cause IMAP server connection to time out");
++"警告:mail-check-interval=0 可能導致 IMAP 伺服器連線作業逾時");
+ }
+ }
+ #if defined(DOS) || defined(OS2)
diff --git a/chinese/pine4/files/patch-az b/chinese/pine4/files/patch-az
index 7da31ace19ea..d2ec75a29319 100644
--- a/chinese/pine4/files/patch-az
+++ b/chinese/pine4/files/patch-az
@@ -1,151 +1,280 @@
---- pine/folder.c.orig Wed May 15 09:25:19 1996
-+++ pine/folder.c Sat Jan 17 21:04:13 1998
-@@ -159,18 +159,18 @@
-
-
- static struct key folder_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"P","PrevFldr",KS_NONE}, {"N","NextFldr",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"D","Delete",KS_NONE}, {"A","Add",KS_NONE},
-- {"R","Rename",KS_NONE}, {"W","WhereIs",KS_NONE},
--
-- {"?","Help",KS_NONE}, {"O","OTHER CMDS",KS_NONE},
-- {"Q","Quit",KS_EXIT}, {"C","Compose",KS_COMPOSER},
-- {NULL,NULL,KS_NONE}, {"G","GotoFldr",KS_GOTOFLDR},
-- {"I","CurIndex",KS_FLDRINDEX}, {"W","WhereIs",KS_WHEREIS},
-- {"Y","prYnt",KS_PRINT}, {NULL,NULL,KS_NONE},
-+ {"P","前一信夾",KS_NONE}, {"N","後一信夾",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"D","刪除",KS_NONE}, {"A","加入",KS_NONE},
-+ {"R","更名",KS_NONE}, {"W","搜尋",KS_NONE},
-+
-+ {"?","輔助說明",KS_NONE}, {"O","其它命令",KS_NONE},
-+ {"Q","離開",KS_EXIT}, {"C","寫信",KS_COMPOSER},
-+ {NULL,NULL,KS_NONE}, {"G","進入信件夾",KS_GOTOFLDR},
-+ {"I","目前索引",KS_FLDRINDEX}, {"W","搜尋",KS_WHEREIS},
-+ {"Y","列印",KS_PRINT}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE}};
- INST_KEY_MENU(folder_keymenu, folder_keys);
- #define MAIN_KEY 2 /* Sometimes Main, sometimes Exit */
-@@ -438,24 +438,24 @@
- folder_keys[DELETE_KEY].name = "D";
- folder_keys[ADD_KEY].name = "A";
- folder_keys[RENAME_KEY].name = "R";
-- folder_keys[RENAME_KEY].label = "Rename";
-+ folder_keys[RENAME_KEY].label = "更名";
- if(fs->context->type & FTYPE_BBOARD) {
-- folder_keys[ADD_KEY].label = "Subscribe";
-- folder_keys[DELETE_KEY].label = "UnSbscrbe";
-+ folder_keys[ADD_KEY].label = "訂閱\";
-+ folder_keys[DELETE_KEY].label = "不訂閱\";
- KS_OSDATASET(&folder_keys[DELETE_KEY], KS_NONE);
- } else {
-- folder_keys[ADD_KEY].label = "Add";
-- folder_keys[DELETE_KEY].label = "Delete";
-+ folder_keys[ADD_KEY].label = "增加";
-+ folder_keys[DELETE_KEY].label = "刪除";
- KS_OSDATASET(&folder_keys[DELETE_KEY], KS_NONE);
- }
- if(do_what == FolderMaint){
- km->how_many = 2;
- folder_keys[MAIN_KEY].name = "M";
-- folder_keys[MAIN_KEY].label = "Main Menu";
-+ folder_keys[MAIN_KEY].label = "主選單";
- KS_OSDATASET(&folder_keys[MAIN_KEY], KS_MAINMENU);
- folder_keys[SELECT_KEY].name = "V";
- folder_keys[SELECT_KEY].label =
-- (fs->context->use & CNTXT_PSEUDO) ? "[Select]":"[ViewFldr]";
-+ (fs->context->use & CNTXT_PSEUDO) ? "[選擇]":"[檢視信件夾]";
- KS_OSDATASET(&folder_keys[SELECT_KEY], KS_NONE);
- clrbitn(WHEREIS_KEY, bitmap); /* the one in the 1st menu */
+--- pine/pine.c.orig Thu Jul 9 03:22:35 1998
++++ pine/pine.c Wed Jul 15 17:02:36 1998
+@@ -107,12 +107,12 @@
+ OTHER_MENU,
+ NULL_MENU,
+ NULL_MENU,
+- {"P","PrevCmd",{MC_PREVITEM,3,{'p',ctrl('P'),KEY_UP}},KS_NONE},
+- {"N","NextCmd",{MC_NEXTITEM,3,{'n',ctrl('N'),KEY_DOWN}},KS_NONE},
++ {"P","前一命令",{MC_PREVITEM,3,{'p',ctrl('P'),KEY_UP}},KS_NONE},
++ {"N","次一命令",{MC_NEXTITEM,3,{'n',ctrl('N'),KEY_DOWN}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+- {"R","RelNotes",{MC_RELNOTES,1,{'r'}},KS_NONE},
+- {"K","KBLock",{MC_KBLOCK,1,{'k'}},KS_NONE},
++ {"R","出版說明",{MC_RELNOTES,1,{'r'}},KS_NONE},
++ {"K","鍵盤鎖定",{MC_KBLOCK,1,{'k'}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+
+@@ -122,10 +122,10 @@
+ COMPOSE_MENU,
+ LISTFLD_MENU,
+ GOTO_MENU,
+- {"I","Index",{MC_INDEX,1,{'i'}},KS_FLDRINDEX},
+- {"J","Journal",{MC_JOURNAL,1,{'j'}},KS_REVIEW},
+- {"S","Setup",{MC_SETUP,1,{'s'}},KS_NONE},
+- {"A","AddrBook",{MC_ADDRBOOK,1,{'a'}},KS_ADDRBOOK},
++ {"I","索引",{MC_INDEX,1,{'i'}},KS_FLDRINDEX},
++ {"J","日誌",{MC_JOURNAL,1,{'j'}},KS_REVIEW},
++ {"S","設定",{MC_SETUP,1,{'s'}},KS_NONE},
++ {"A","地址簿",{MC_ADDRBOOK,1,{'a'}},KS_ADDRBOOK},
+ NULL_MENU,
+ NULL_MENU};
+ INST_KEY_MENU(main_keymenu, main_keys);
+@@ -518,7 +518,7 @@
+ static struct key simple_file_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+- {"Q","Quit Viewer",{MC_EXIT,1,{'q'}},KS_NONE},
++ {"Q","離開",{MC_EXIT,1,{'q'}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -527,15 +527,15 @@
+ PRYNTTXT_MENU,
+ WHEREIS_MENU,
+ FWDEMAIL_MENU,
+- {"S", "Save", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
++ {"S", "存檔", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
+ INST_KEY_MENU(simple_file_keymenu, simple_file_keys);
+ #define SAVE_KEY 9
+
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = src;
+- sargs.text.desc = "file";
+- sargs.bar.title = "FILE VIEW";
++ sargs.text.desc = "檔案";
++ sargs.bar.title = "檢視檔案";
+ sargs.bar.style = FileTextPercent;
+ sargs.keys.menu = &simple_file_keymenu;
+ setbitmap(sargs.keys.bitmap);
+@@ -716,7 +716,7 @@
+ if(!pine_state->VAR_INBOX_PATH || !pine_state->VAR_INBOX_PATH[0]
+ || strucmp(pine_state->VAR_INBOX_PATH, "inbox") == 0){
+ HelpType help = NO_HELP;
+- static ESCKEY_S ekey[] = {{ctrl(T), 2, "^T", "To Fldrs"},
++ static ESCKEY_S ekey[] = {{ctrl(T), 2, "^T", "資料匣"},
+ {-1, 0, NULL, NULL}};
+
+ pine_state->mangled_footer = 1;
+@@ -726,7 +726,7 @@
+
+ rv = optionally_enter(int_mail, -FOOTER_ROWS(pine_state),
+ 0, MAXPATH,
+- "No inbox! Folder to open as inbox : ",
++ "沒有新進信件匣(inbox)!信件匣開啟為 inbox:",
+ /* ekey */ NULL, help, &flags);
+ if(rv == 3){
+ help = (help == NO_HELP) ? h_sticky_inbox : NO_HELP;
+@@ -738,7 +738,7 @@
+ }
+
+ if(rv == 1){
+- q_status_message(SM_ORDER, 0, 2 ,"Folder open cancelled");
++ q_status_message(SM_ORDER, 0, 2 ,"取消開啟信件匣");
+ rv = 0; /* reset rv */
+ }
+ else if(rv == 2){
+@@ -757,7 +757,7 @@
+ removing_leading_white_space(int_mail);
+ if((!pine_state->VAR_INBOX_PATH
+ || strucmp(pine_state->VAR_INBOX_PATH, "inbox") == 0)
+- && want_to("Preserve folder as \"inbox-path\" in PINERC",
++ && want_to("在 PINERC 中保留資料匣為 \"inbox-path\"",
+ 'y', 'n', NO_HELP, WT_NORM) == 'y'){
+ set_variable(V_INBOX_PATH, int_mail, 1);
+ }
+@@ -902,25 +902,25 @@
+ *news_addition;
+ int key_index; /* index into keymenu array for this cmd */
+ } mkeys[] = {
+- {" %s HELP - Get help using Pine",
++ {" %s 使用說明 - Pine 的使用說明",
+ NULL, MAIN_HELP_KEY},
+ {"", NULL, UNUSED},
+- {" %s COMPOSE MESSAGE - Compose and send%s a message",
++ {" %s 寫信 - 寫信或是發表文章",
+ "/post", MAIN_COMPOSE_KEY},
+ {"", NULL, UNUSED},
+- {" %s MESSAGE INDEX - View messages in current folder",
++ {" %s 查看信件匣 - 查看目前信件匣內的信件",
+ NULL, MAIN_INDEX_KEY},
+ {"", NULL, UNUSED},
+- {" %s FOLDER LIST - Select a folder%s to view",
+- " OR news group", MAIN_FOLDER_KEY},
++ {" %s 信件匣列表 - 列出信件匣%s以供選擇",
++ "或是新聞組群", MAIN_FOLDER_KEY},
+ {"", NULL, UNUSED},
+- {" %s ADDRESS BOOK - Update address book",
++ {" %s 地址簿 - 更新或修改地址簿的內容",
+ NULL, MAIN_ADDRESS_KEY},
+ {"", NULL, UNUSED},
+- {" %s SETUP - Configure Pine Options",
++ {" %s 設定 - 設定 Pine 的內部參數",
+ NULL, MAIN_SETUP_KEY},
+ {"", NULL, UNUSED},
+- {" %s QUIT - Leave the Pine program",
++ {" %s 離開 - 結束 Pine 的使用",
+ NULL, MAIN_QUIT_KEY}
+ };
+
+@@ -1213,7 +1213,7 @@
+ pine_state->mangled_footer = 1;
+ }
+ else{
+- helper(main_menu_tx, "HELP FOR MAIN MENU", 0);
++ helper(main_menu_tx, "主選單的輔助說明", 0);
+ pine_state->mangled_screen = 1;
}
-@@ -463,23 +463,23 @@
- km->how_many = 1;
- folder_keys[MAIN_KEY].name = "E";
- folder_keys[MAIN_KEY].label = do_what != Subscribe ?
-- "ExitSelect" : "ExitSubscb";
-+ "離開選擇" : "ExitSubsc";
-
- folder_keys[SELECT_KEY].name = "S";
- folder_keys[SELECT_KEY].label = do_what != Subscribe ?
-- "[Select]" : "[Subscribe]";
-+ "[選擇]" : "[訂閱\]";
- KS_OSDATASET(&folder_keys[SELECT_KEY], KS_NONE);
- clrbitn(OTHER_KEY, bitmap);
- clrbitn(RENAME_KEY, bitmap);
- if(do_what == Subscribe){
- if(doing_listmode){
- folder_keys[DELETE_KEY].name = "X";
-- folder_keys[DELETE_KEY].label = "[Set/Unset]";
-- folder_keys[SELECT_KEY].label = "Subscribe";
-+ folder_keys[DELETE_KEY].label = "[設定/取消設定]";
-+ folder_keys[SELECT_KEY].label = "訂閱\";
- }
- else{
- folder_keys[DELETE_KEY].name = "L";
-- folder_keys[DELETE_KEY].label = "ListMode";
-+ folder_keys[DELETE_KEY].label = "列表模式";
- }
- }
- else
-@@ -610,8 +610,8 @@
-
-
- /*---------------------- Key left --------------*/
-+ case KEY_LEFT:
- case ctrl('B'):
-- case KEY_LEFT:
- case PF5:
- case 'p':
- if(fs->folder_index > 0 && ALL_FOUND(fs->context)){
-@@ -628,7 +628,18 @@
- fs->folder_index = 0;
+
+@@ -1241,7 +1241,7 @@
+ just_a_navigate_cmd++;
+ }
+ else
+- q_status_message(SM_ORDER, 0, 2, "Already at top of list");
++ q_status_message(SM_ORDER, 0, 2, "已經在列表頂端了");
+
+ break;
+
+@@ -1257,14 +1257,14 @@
+ just_a_navigate_cmd++;
}
else
-- q_status_message(SM_ORDER,0,1,"Already on first folder.");
-+ {
-+ /* GaryLee :3
-+ q_status_message(0,0,1,"\007已經在第一個信件夾了.");
-+ */
-+ if((do_what != FolderMaint && ch == 'm')
-+ || (do_what == FolderMaint && ch == 'e'))
-+ goto bleep;
-+ ps_global->redrawer = (void (*)())NULL;
-+ for(tc = fs->context_list; tc ; tc = tc->next)
-+ free_folders_in_context(tc);
-+ return(0);
-+ }
+- q_status_message(SM_ORDER, 0, 2, "Already at bottom of list");
++ q_status_message(SM_ORDER, 0, 2, "已經在列表底端了");
break;
-
-@@ -996,8 +1007,7 @@
- /*-- save message, subscribe or post --- */
- if((do_what == GetFcc || do_what == SaveMessage)
- && (fs->context->type & FTYPE_BBOARD)) {
-- q_status_message(SM_ORDER | SM_DING, 3, 4,
-- "Can't save messages to bulletin boards or news groups!");
-+ q_status_message(SM_ORDER | SM_DING, 3, 4, "無法將訊息存至電子佈告欄或新聞組群上!");
- break;
- }
-
-@@ -2407,7 +2417,7 @@
- folder = new_f->name;
- ren_cur = strcmp(folder, ps_global->cur_folder) == 0;
-
-- prompt = "Rename folder to : ";
-+ prompt = "將信件匣更名為: ";
- help = NO_HELP;
- strcpy(new_foldername, folder);
- while(1) {
-@@ -2608,7 +2618,7 @@
- && strcmp(folder, ps_global->cur_folder) == 0)
- close_opened++;
-
-- sprintf(ques_buf, "Really delete \"%s\"%s", folder,
-+ sprintf(ques_buf, "確定刪除 \"%s\"%s", folder,
- close_opened ? " (the currently open folder)" : "");
-
- if((ret=want_to(ques_buf, 'n', 'x', NO_HELP, 0, 0)) != 'y'){
+
+
+ /*---------- Release Notes ----------*/
+ case MC_RELNOTES :
+- helper(h_news, "PINE RELEASE NOTES", 0);
++ helper(h_news, "PINE 出版摘要", 0);
+ pine_state->mangled_screen = 1;
+ break;
+
+@@ -1493,7 +1493,7 @@
+
+ /* paint the titlebar if needed */
+ if(ps->mangled_header){
+- set_titlebar("MAIN MENU", ps->mail_stream, ps->context_current,
++ set_titlebar("主選單", ps->mail_stream, ps->context_current,
+ ps->cur_folder, ps->msgmap, 1, FolderName, 0, 0);
+ ps->mangled_header = 0;
+ }
+@@ -1658,13 +1658,13 @@
+ {
+ char prompt[80];
+ char letters[20];
+- char *printer = "Printer";
+- char *passwd = "Newpassword";
+- char *config = "Config";
+- char *update = "Update";
+- char *sigedit = "Signature";
+- char *abooks = "AddressBooks";
+- char *clctns = "collectionList";
++ char *printer = "印表機";
++ char *passwd = "設定新密碼";
++ char *config = "環境設定";
++ char *update = "更新環境";
++ char *sigedit = "編輯簽名檔";
++ char *abooks = "地址簿";
++ char *clctns = "總集列表";
+ #ifdef ENABLE_LDAP
+ char *dir = "Directory";
+ #endif
+@@ -1742,13 +1742,13 @@
+ }
+
+ sprintf(prompt,
+- "Choose a setup task from %s : ",
+- F_ON(F_BLANK_KEYMENU,ps_global) ? letters : "the menu below");
++ "請從%s選擇你所要設定的工作:",
++ F_ON(F_BLANK_KEYMENU,ps_global) ? letters : "下列表單中");
+
+ s = radio_buttons(prompt, ql, setup_names, deefault, 'x', help, RB_NORM);
+ /* ^C */
+ if(s == 'x') {
+- q_status_message(SM_ORDER,0,3,"Setup command cancelled");
++ q_status_message(SM_ORDER,0,3,"取消設定指令");
+ s = 'e';
+ }
+
+@@ -1861,14 +1861,14 @@
+ HELP_MENU,
+ NULL_MENU,
+ {"E",NULL,{MC_EXIT,1,{'e',ctrl('M'),ctrl('J')}},KS_NONE},
+- {"Ret","[GetDocument]",{MC_VIEW_HANDLE,2,{ctrl('M'),ctrl('J')}},KS_NONE},
++ {"Ret","[取得文件]",{MC_VIEW_HANDLE,2,{ctrl('M'),ctrl('J')}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ PRYNTMSG_MENU,
+ NULL_MENU,
+- {"R","RelNotes",{MC_RELNOTES,1,{'r'}},KS_NONE},
++ {"R","出版說明",{MC_RELNOTES,1,{'r'}},KS_NONE},
+ NULL_MENU};
+ INST_KEY_MENU(nuov_keymenu, nuov_keys);
+ #define NUOV_EXIT 2
+@@ -1957,13 +1957,13 @@
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.text = so_text(store);
+ sargs.text.src = CharStar;
+- sargs.text.desc = "greeting text";
++ sargs.text.desc = "問候文字";
+ sargs.text.handles = handles;
+- sargs.bar.title = "GREETING TEXT";
++ sargs.bar.title = "問候文字";
+ sargs.bar.style = TextPercent;
+ sargs.proc.tool = nuov_processor;
+ sargs.help.text = main_menu_tx;
+- sargs.help.title = "MAIN PINE HELP";
++ sargs.help.title = "PINE 的主要輔助說明";
+ sargs.resize_exit = 1;
+ sargs.force_h = 1;
+ sargs.keys.menu = &km;
+@@ -1974,11 +1974,11 @@
+ setbitmap(sargs.keys.bitmap);
+
+ if(ps->phone_home){
+- km.keys[NUOV_EXIT].label = "Exit Greeting";
++ km.keys[NUOV_EXIT].label = "離開";
+ km.keys[NUOV_EXIT].bind.nch = 1;
+ }
+ else{
+- km.keys[NUOV_EXIT].label = "[Exit Greeting]";
++ km.keys[NUOV_EXIT].label = "[離開]";
+ km.keys[NUOV_EXIT].bind.nch = 3;
+ clrbitn(NUOV_VIEW, sargs.keys.bitmap);
+ }
+@@ -2034,7 +2034,7 @@
+ break;
+
+ case MC_RELNOTES :
+- helper(h_news, "PINE RELEASE NOTES", 0);
++ helper(h_news, "PINE 出版摘要", 0);
+ ps_global->mangled_screen = 1;
+ break;
+
+@@ -2153,7 +2153,7 @@
+ dprint(1, (debugfile, "\n\n ---- QUIT SCREEN ----\n"));
+
+ if(!pine_state->nr_mode && F_OFF(F_QUIT_WO_CONFIRM,pine_state)
+- && want_to("Really quit pine", 'y', 0, NO_HELP, WT_NORM) != 'y') {
++ && want_to("真的要離開 Pine 嗎?", 'y', 0, NO_HELP, WT_NORM) != 'y') {
+ pine_state->next_screen = pine_state->prev_screen;
+ return;
+ }
diff --git a/chinese/pine4/files/patch-ba b/chinese/pine4/files/patch-ba
index f99dacebd798..6f924708cdf2 100644
--- a/chinese/pine4/files/patch-ba
+++ b/chinese/pine4/files/patch-ba
@@ -1,173 +1,132 @@
---- pine/mailcmd.c.orig Tue Feb 25 05:57:22 1997
-+++ pine/mailcmd.c Sat Jan 17 21:05:19 1998
-@@ -128,14 +128,14 @@
+--- pine/pine.h.orig Tue Jul 7 10:06:18 1998
++++ pine/pine.h Wed Jul 15 17:02:37 1998
+@@ -348,7 +348,7 @@
+ && (s) && !strucmp((s),"X-VCARD")))
+ #define MIME_VCARD_A(a) MIME_VCARD((a)->body->type, (a)->body->subtype)
- static char *sel_pmt3 = "APPLY command : ";
- static ESCKEY_S sel_opts3[] = {
-- {'d', 'd', "D", "Del"},
-- {'u', 'u', "U", "Undel"},
-- {'r', 'r', "R", "Reply"},
-- {'f', 'f', "F", "Forward"},
-- {'y', 'y', "Y", "prYnt"},
-+ {'d', 'd', "D", "刪除"},
-+ {'u', 'u', "U", "救回刪除"},
-+ {'r', 'r', "R", "回信"},
-+ {'f', 'f', "F", "轉寄"},
-+ {'y', 'y', "Y", "列印"},
- {'t', 't', "T", "TakeAddr"},
-- {'s', 's', "S", "Save"},
-- {'e', 'e', "E", "Export"},
-+ {'s', 's', "S", "存檔"},
-+ {'e', 'e', "E", "匯出"},
- { -1, 0, NULL, NULL},
- { -1, 0, NULL, NULL},
- { -1, 0, NULL, NULL},
-@@ -203,6 +203,9 @@
- int command, in_index, orig_command;
- int *force_mailchk;
- {
-+/* GaryLee :3 */
-+ static char WhereFrom = 0 ;
-+ static char current_cmd_status ;
- int question_line, a_changed, is_unread, we_cancel;
- long new_msgno, del_count, old_msgno, cur_msgno, i,
- hide_count, exld_count, select_count, old_max_msgno;
-@@ -225,6 +228,12 @@
- a_changed = 0;
- *force_mailchk = 0;
+-#define STYLE_NAME(a) ((a)->text.desc ? (a)->text.desc : "text")
++#define STYLE_NAME(a) ((a)->text.desc ? (a)->text.desc : "文字")
-+/* GaryLee:3 */
-+ if(state->prev_screen == main_menu_screen )
-+ WhereFrom = 'm' ;
-+ else if( state->prev_screen == folder_screen )
-+ WhereFrom = 'l' ;
-+
- switch (command)
- {
- /*------------- Help --------*/
-@@ -253,6 +262,16 @@
+ /*
+@@ -1581,91 +1581,91 @@
+ * Some standard Key/Command Bindings
+ */
+ #define NULL_MENU {NULL, NULL, {MC_NONE}, KS_NONE}
+-#define HELP_MENU {"?", "Help", \
++#define HELP_MENU {"?", "輔助說明", \
+ {MC_HELP, 2, {'?',ctrl('G')}}, \
+ KS_SCREENHELP}
+-#define OTHER_MENU {"O", "OTHER CMDS", \
++#define OTHER_MENU {"O", "其他命令", \
+ {MC_OTHER, 1, {'o'}}, \
+ KS_NONE}
+-#define WHEREIS_MENU {"W", "WhereIs", \
++#define WHEREIS_MENU {"W", "搜尋", \
+ {MC_WHEREIS, 2, {'w',ctrl('W')}}, \
+ KS_WHEREIS}
+-#define MAIN_MENU {"M", "Main Menu", \
++#define MAIN_MENU {"M", "主選單", \
+ {MC_MAIN, 1, {'m'}}, \
+ KS_MAINMENU}
+-#define QUIT_MENU {"Q", "Quit Pine", \
++#define QUIT_MENU {"Q", "離開 Pine", \
+ {MC_QUIT, 1, {'q'}}, \
+ KS_EXIT}
+-#define PREVMSG_MENU {"P", "PrevMsg", \
++#define PREVMSG_MENU {"P", "前一個", \
+ {MC_PREVITEM, 1, {'p'}}, \
+ KS_PREVMSG}
+-#define NEXTMSG_MENU {"N", "NextMsg", \
++#define NEXTMSG_MENU {"N", "下一個", \
+ {MC_NEXTITEM, 1, {'n'}}, \
+ KS_NEXTMSG}
+-#define PREVPAGE_MENU {"-", "PrevPage", \
++#define PREVPAGE_MENU {"-", "前一頁", \
+ {MC_PAGEUP, 3, {'-',ctrl('Y'),KEY_PGUP}}, \
+ KS_PREVPAGE}
+-#define NEXTPAGE_MENU {"Spc", "NextPage", \
++#define NEXTPAGE_MENU {"Spc", "下一頁", \
+ {MC_PAGEDN, 4, {'+',' ',ctrl('V'),KEY_PGDN}}, \
+ KS_NEXTPAGE}
+-#define JUMP_MENU {"J", "Jump", \
++#define JUMP_MENU {"J", "跳至", \
+ {MC_JUMP, 1, {'j'}}, \
+ KS_JUMPTOMSG}
+-#define FWDEMAIL_MENU {"F", "Fwd Email", \
++#define FWDEMAIL_MENU {"F", "信件轉寄", \
+ {MC_FWDTEXT,1,{'f'}}, \
+ KS_FORWARD}
+-#define PRYNTMSG_MENU {"%", "Print", \
++#define PRYNTMSG_MENU {"%", "列印", \
+ {MC_PRINTMSG,1,{'%'}}, \
+ KS_PRINT}
+-#define PRYNTTXT_MENU {"%", "Print", \
++#define PRYNTTXT_MENU {"%", "列印", \
+ {MC_PRINTTXT,1,{'%'}}, \
+ KS_PRINT}
+-#define SAVE_MENU {"S", "Save", \
++#define SAVE_MENU {"S", "存檔", \
+ {MC_SAVE,1,{'s'}}, \
+ KS_SAVE}
+-#define EXPORT_MENU {"E", "Export", \
++#define EXPORT_MENU {"E", "匯出", \
+ {MC_EXPORT, 1, {'e'}}, \
+ KS_EXPORT}
+-#define COMPOSE_MENU {"C", "Compose", \
++#define COMPOSE_MENU {"C", "編修", \
+ {MC_COMPOSE,1,{'c'}}, \
+ KS_COMPOSER}
+-#define DELETE_MENU {"D", "Delete", \
++#define DELETE_MENU {"D", "刪除", \
+ {MC_DELETE,2,{'d',KEY_DEL}}, \
+ KS_DELETE}
+-#define UNDELETE_MENU {"U", "Undelete", \
++#define UNDELETE_MENU {"U", "復原刪除", \
+ {MC_UNDELETE,1,{'u'}}, \
+ KS_UNDELETE}
+-#define REPLY_MENU {"R", "Reply", \
++#define REPLY_MENU {"R", "回覆", \
+ {MC_REPLY,1,{'r'}}, \
+ KS_REPLY}
+-#define FORWARD_MENU {"F", "Forward", \
++#define FORWARD_MENU {"F", "轉寄", \
+ {MC_FORWARD,1,{'f'}}, \
+ KS_FORWARD}
+-#define LISTFLD_MENU {"L", "ListFldrs", \
++#define LISTFLD_MENU {"L", "資料匣列表", \
+ {MC_COLLECTIONS,1,{'l'}}, \
+ KS_FLDRLIST}
+-#define INDEX_MENU {"I", "Index", \
++#define INDEX_MENU {"I", "索引", \
+ {MC_INDEX,1,{'i'}}, \
+ KS_FLDRINDEX}
+-#define GOTO_MENU {"G", "GotoFldr", \
++#define GOTO_MENU {"G", "切換資料匣", \
+ {MC_GOTO,1,{'g'}}, \
+ KS_GOTOFLDR}
+-#define TAKE_MENU {"T", "TakeAddr", \
++#define TAKE_MENU {"T", "取得地址", \
+ {MC_TAKE,1,{'t'}}, \
+ KS_TAKEADDR}
+-#define FLAG_MENU {"*", "Flag", \
++#define FLAG_MENU {"*", "旗標", \
+ {MC_FLAG,1,{'*'}}, \
+ KS_FLAG}
+-#define PIPE_MENU {"|", "Pipe", \
++#define PIPE_MENU {"|", "轉向(Pipe)", \
+ {MC_PIPE,1,{'|'}}, \
+ KS_NONE}
+-#define BOUNCE_MENU {"B", "Bounce", \
++#define BOUNCE_MENU {"B", "退信", \
+ {MC_BOUNCE,1,{'b'}}, \
+ KS_BOUNCE}
+-#define HDRMODE_MENU {"H", "HdrMode", \
++#define HDRMODE_MENU {"H", "完整標頭", \
+ {MC_FULLHDR,1,{'h'}}, \
+ KS_HDRMODE}
+-#define TAB_MENU {"Tab", "NextNew", \
++#define TAB_MENU {"Tab", "下一個新的", \
+ {MC_TAB,1,{TAB}}, \
+ KS_NONE}
- /*--------- Return to main menu ------------*/
-+ case KEY_LEFT:
-+ if(current_cmd_status)
-+ goto do_index ;
-+ /* GaryLee :3 */
-+ if (WhereFrom == 'l')
-+ {
-+ state->next_screen = folder_screen;
-+ break;
-+ }
-+
- case PF3:
- case 'm':
- if(state->nr_mode && command == 'm')
-@@ -269,6 +288,7 @@
-
- /*------- View mail or attachment --------*/
- case ctrl('M'):
-+ case KEY_RIGHT:
- case ctrl('J'):
- if(!in_index){
- q_status_message(SM_ORDER | SM_DING, 0, 3,
-@@ -278,6 +298,7 @@
-
- case PF4:
- case 'v':
-+ current_cmd_status = 1 ;
- if(in_index) {
- if(any_messages(msgmap, NULL, "to View")){
- state->next_screen = mail_view_screen;
-@@ -489,6 +510,7 @@
- case OPF7:
- case 'i':
- do_index:
-+ current_cmd_status = 0 ;
- if(!in_index) {
- #if defined(DOS) && !defined(WIN32)
- flush_index_cache(); /* save room on PC */
-@@ -1871,7 +1893,7 @@
- ekey[rc].ch = ctrl('T');
- ekey[rc].rval = 2;
- ekey[rc].name = "^T";
-- ekey[rc++].label = "To Fldrs";
-+ ekey[rc++].label = "信夾列表";
-
- if(saveable_count > 1){
- ekey[rc].ch = ctrl('P');
-@@ -1889,7 +1911,7 @@
- ekey[rc].ch = TAB;
- ekey[rc].rval = 12;
- ekey[rc].name = "TAB";
-- ekey[rc++].label = "Complete";
-+ ekey[rc++].label = "完成";
- }
-
- if(saveable_count > 1){
-@@ -2753,7 +2775,7 @@
- STORE_S *store;
- struct variable *vars = ps_global->vars;
- static ESCKEY_S export_opts[] = {
-- {ctrl('T'), 10, "^T", "To Files"},
-+ {ctrl('T'), 10, "^T", "檔案列表"},
- {-1, 0, NULL, NULL},
- {-1, 0, NULL, NULL},
- {-1, 0, NULL, NULL}};
-@@ -2774,7 +2796,7 @@
- export_opts[++i].ch = ctrl('V');
- export_opts[i].rval = 12;
- export_opts[i].name = "^V";
-- export_opts[i].label = "Downld Msg";
-+ export_opts[i].label = "下載";
- }
- #endif /* !(DOS || MAC) */
-
-@@ -2782,7 +2804,7 @@
- export_opts[++i].ch = ctrl('I');
- export_opts[i].rval = 11;
- export_opts[i].name = "TAB";
-- export_opts[i].label = "Complete";
-+ export_opts[i].label = "完成";
- }
-
- export_opts[++i].ch = -1;
-@@ -2888,7 +2910,7 @@
- || !format_message(mn_m2raw(msgmap, mn_get_cur(msgmap)),
- env, b, FM_NEW_MESS|FM_DO_PRINT, pc)){
- q_status_message(SM_ORDER | SM_DING, 3, 3,
-- errstr = "Error writing tempfile for download");
-+ errstr = "寫入下載暫存檔時發生錯誤");
- break;
- }
-
-@@ -2900,18 +2922,18 @@
- (void) close_system_pipe(&syspipe);
- else
- q_status_message(SM_ORDER | SM_DING, 3, 3,
-- errstr = "Error running download command");
-+ errstr = "執行下載命令時發生錯誤");
- }
-
- unlink(tfp);
- }
- else
- q_status_message(SM_ORDER | SM_DING, 3, 3,
-- errstr = "Error building temp file for download");
-+ errstr = "無法建立下載用的暫存檔");
-
- fs_give((void **)&tfp);
- if(!errstr)
-- q_status_message(SM_ORDER, 0, 3, "Download Command Completed");
-+ q_status_message(SM_ORDER, 0, 3, "下載命令完成");
-
- goto fini;
- }
-@@ -3354,7 +3376,7 @@
- ekey[rc].ch = TAB;
- ekey[rc].rval = 12;
- ekey[rc].name = "TAB";
-- ekey[rc++].label = "Complete";
-+ ekey[rc++].label = "完成";
- }
-
- if(ps_global->context_list->next){
diff --git a/chinese/pine4/files/patch-bb b/chinese/pine4/files/patch-bb
index c1e1b758bc93..17e394848e61 100644
--- a/chinese/pine4/files/patch-bb
+++ b/chinese/pine4/files/patch-bb
@@ -1,128 +1,85 @@
---- pine/mailindx.c.orig Fri Jul 12 06:48:37 1996
-+++ pine/mailindx.c Sat Jan 17 21:06:20 1998
-@@ -53,28 +53,28 @@
+--- pine/reply.c.orig Tue Jun 23 12:08:03 1998
++++ pine/reply.c Wed Jul 15 17:02:37 1998
+@@ -411,7 +411,7 @@
+ #endif
+ /* partially formatted outgoing message */
+- pine_send(outgoing, &body, "COMPOSE MESSAGE REPLY",
++ pine_send(outgoing, &body, "編輯信件回函",
+ fcc.tptr, &reply, NULL, NULL, NULL, 0);
+ done:
+ pine_free_body(&body);
+@@ -485,7 +485,7 @@
+ (ADDRESS *) NULL, env->from, 0);
- static struct key index_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"M","Main Menu",KS_MAINMENU}, {"V","[ViewMsg]",KS_VIEW},
-- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"D","Delete",KS_DELETE}, {"U","Undelete",KS_UNDELETE},
-- {"R","Reply",KS_REPLY}, {"F","Forward",KS_FORWARD},
--
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"Q","Quit",KS_EXIT}, {"C","Compose",KS_COMPOSER},
-- {"L","ListFldrs",KS_FLDRLIST}, {"G","GotoFldr",KS_GOTOFLDR},
-- {"Tab","NextNew",KS_NONE}, {"W","WhereIs",KS_WHEREIS},
-- {"Y","prYnt",KS_PRINT}, {"T","TakeAddr",KS_TAKEADDR},
-- {"S","Save",KS_SAVE}, {"E","Export",KS_EXPORT},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {"M","回到主選單",KS_MAINMENU}, {"V","[看信]",KS_VIEW},
-+ {"P","前一個",KS_PREVMSG}, {"N","後一個",KS_NEXTMSG},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"D","刪除",KS_DELETE}, {"U","救回刪除",KS_UNDELETE},
-+ {"R","回信",KS_REPLY}, {"F","轉寄",KS_FORWARD},
-+
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {"Q","離開",KS_EXIT}, {"C","寫信",KS_COMPOSER},
-+ {"L","列出信件夾",KS_FLDRLIST}, {"G","進入信件夾",KS_GOTOFLDR},
-+ {"Tab","下一個",KS_NONE}, {"W","搜尋",KS_WHEREIS},
-+ {"Y","列印",KS_PRINT}, {"T","取得地址",KS_TAKEADDR},
-+ {"S","儲存",KS_SAVE}, {"E","匯出",KS_EXPORT},
+ if(ret == 'x') {
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ return(0);
+ }
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
- {"X",NULL,KS_NONE}, {"&","unXclude",KS_NONE},
-- {";","Select",KS_SELECT}, {"A","Apply",KS_APPLY},
-- {"$","SortIndex",KS_SORT}, {"J","Jump",KS_JUMPTOMSG},
-- {"H","HdrMode",KS_HDRMODE}, {"B","Bounce",KS_BOUNCE},
-- {"*","Flag",KS_FLAG}, {"|","Pipe",KS_NONE},
-+ {";","選擇",KS_SELECT}, {"A","Apply",KS_APPLY},
-+ {"$","索引排序",KS_SORT}, {"J","跳至",KS_JUMPTOMSG},
-+ {"H","標頭模式",KS_HDRMODE}, {"B","Bounce",KS_BOUNCE},
-+ {"*","旗標",KS_FLAG}, {"|","Pipe",KS_NONE},
+@@ -534,7 +534,7 @@
+ || (*saved_cc || *saved_resent))){
+ *flags &= ~RSF_QUERY_REPLY_ALL;
+ if((ret=want_to(ALL_PMT,'n','x',NO_HELP,WT_SEQ_SENSITIVE)) == 'x'){
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ return(0);
+ }
+ else if(ret == 'y')
+@@ -1099,8 +1099,8 @@
+ {
+ int ret, edited = 0;
+ static ESCKEY_S rtq_opts[] = {
+- {'y', 'y', "Y", "Yes"},
+- {'n', 'n', "N", "No"},
++ {'y', 'y', "Y", "是"},
++ {'n', 'n', "N", "否"},
+ {-1, 0, NULL, NULL}, /* may be overridden below */
+ {-1, 0, NULL, NULL}
+ };
+@@ -1133,7 +1133,7 @@
+ rtq_opts, edited ? 'y' : 'n',
+ 'x', NO_HELP, RB_SEQ_SENSITIVE)){
+ case 'x':
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ return(-1);
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
- {":","SelectCur",KS_SELECTCUR}, {"Z","ZoomMode",KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-@@ -94,32 +94,32 @@
- #define ZOOM_KEY 39
+ case 'r':
+@@ -1165,7 +1165,7 @@
+ break;
- static struct key nr_anon_index_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"W","WhereIs",KS_WHEREIS},
-- {"Q","Quit",KS_EXIT}, {"V","[ViewMsg]",KS_VIEW},
-- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"F","Fwd Email",KS_FORWARD}, {"J","Jump",KS_JUMPTOMSG},
-- {"$","SortIndex",KS_SORT}, {NULL,NULL,KS_NONE}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {"W","搜尋",KS_WHEREIS},
-+ {"Q","離開",KS_EXIT}, {"V","[ViewMsg]",KS_VIEW},
-+ {"P","前一個",KS_PREVMSG}, {"N","後一個",KS_NEXTMSG},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"F","轉寄",KS_FORWARD}, {"J","跳至",KS_JUMPTOMSG},
-+ {"$","重新排序",KS_SORT}, {NULL,NULL,KS_NONE}};
- INST_KEY_MENU(nr_anon_index_keymenu, nr_anon_index_keys);
+ case 1:
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
- static struct key nr_index_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
- {"Q","Quit",KS_EXIT}, {"V","[ViewMsg]",KS_VIEW},
- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
- {"F","Fwd Email",KS_FORWARD}, {"J","Jump",KS_JUMPTOMSG},
-- {"Y","prYnt",KS_PRINT}, {"S","Save",KS_SAVE},
-+ {"Y","列印",KS_PRINT}, {"S","Save",KS_SAVE},
+ case -1:
+ return(-1);
+@@ -1542,7 +1542,7 @@
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
- {"E","Export",KS_EXPORT}, {"C","Compose",KS_COMPOSER},
- {"$","SortIndex",KS_SORT}, {NULL,NULL,KS_NONE},
-- {NULL,NULL,KS_NONE}, {"W","WhereIs",KS_WHEREIS},
-+ {NULL,NULL,KS_NONE}, {"W","搜尋",KS_WHEREIS},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE}};
- INST_KEY_MENU(nr_index_keymenu, nr_index_keys);
-
- static struct key simple_index_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
- {"E","ExitSelect",KS_EXITMODE}, {"S","[Select]",KS_SELECT},
- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-@@ -630,7 +630,7 @@
- if(i <= 1L){
- if(mn_get_cur(msgmap) == 1L)
- q_status_message(SM_ORDER, 0, 1,
-- "Already at start of Index");
-+ "已經在索引的起頭了");
+ case 'x' : /* cancel or unknown response */
+ default :
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ ret = 0;
+ break;
+ }
+@@ -1708,7 +1708,7 @@
+ * up...
+ */
+ if(ret == 'x'){
+- q_status_message(SM_ORDER, 0, 3, "Forward message cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消信件轉寄");
+ goto clean_early;
+ }
+ else if(ret == 'y'){ /* attach message[s]!!! */
+@@ -1840,7 +1840,7 @@
+ pine_simple_send(outgoing, &body, NULL, NULL, NULL, 1);
+ else /* partially formatted outgoing message */
+ pine_send(outgoing, &body,
+- ps->nr_mode ? "SEND MESSAGE" : "FORWARD MESSAGE",
++ ps->nr_mode ? "送出信件" : "轉寄信件",
+ NULL, NULL, NULL, NULL, NULL, FALSE);
- break;
- }
-@@ -664,7 +664,7 @@
-
- if(i >= mn_get_total(msgmap)){
- if(mn_get_cur(msgmap) == k)
-- q_status_message(SM_ORDER,0,1,"Already at end of Index");
-+ q_status_message(SM_ORDER,0,1,"已經在索引的結尾了");
-
- break;
- }
-@@ -884,6 +884,7 @@
-
- break;
-
-+ case KEY_LEFT:
- case 'e': /* exit */
- case 'E':
- case PF3:
-@@ -897,6 +898,7 @@
-
- case 's': /* select */
- case ctrl('M'):
-+ case KEY_RIGHT:
- case ctrl('J'):
- case PF4:
- ps_global->redrawer = NULL;
+ clean:
diff --git a/chinese/pine4/files/patch-bc b/chinese/pine4/files/patch-bc
index f3c338f13e31..c2d1f32557cd 100644
--- a/chinese/pine4/files/patch-bc
+++ b/chinese/pine4/files/patch-bc
@@ -1,71 +1,109 @@
---- pine/mailpart.c.orig Thu May 30 05:47:17 1996
-+++ pine/mailpart.c Sat Jan 17 21:06:54 1998
-@@ -74,12 +74,12 @@
+--- pine/screen.c.orig Fri Jun 5 04:09:17 1998
++++ pine/screen.c Wed Jul 15 17:02:37 1998
+@@ -433,7 +433,7 @@
- static struct key att_index_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"E","Exit Index",KS_EXITMODE}, {"V","[View]",KS_VIEW},
-- {"P","PrevAttch",KS_NONE}, {"N","NextAttch",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"A","AboutAttch",KS_NONE}, {"S","Save",KS_SAVE},
-- {"|","Pipe",KS_NONE}, {"W","WhereIs",KS_WHEREIS}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"E","離開索引",KS_EXITMODE}, {"V","[檢視]",KS_VIEW},
-+ {"P","前一附件",KS_NONE}, {"N","後一附件",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"A","附件資料",KS_NONE}, {"S","儲存",KS_SAVE},
-+ {"|","Pipe",KS_NONE}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(att_index_keymenu, att_index_keys);
- #define ATT_PIPE_KEY 10
+ static struct key cancel_keys[] =
+- {{NULL,NULL,KS_NONE}, {"^C","Cancel",KS_NONE},
++ {{NULL,NULL,KS_NONE}, {"^C","取消",KS_NONE},
+ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
+ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
+ {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
+@@ -1124,10 +1124,10 @@
+ as.page_column = -1;
+ is_context = strlen(as.context_name);
+ sprintf(version, "PINE %s", pine_version);
+- ss_string = as.stream_status == Closed ? "(CLOSED)" :
++ ss_string = as.stream_status == Closed ? "(已關閉)" :
+ (as.stream_status == ReadOnly
+ && !IS_NEWS(as.stream))
+- ? "(READONLY)" : "";
++ ? "(唯讀)" : "";
+ ss_len = strlen(ss_string);
-@@ -354,6 +354,7 @@
- ps->mangled_screen = 1;
+ tit_len = strlen(as.title); /* fixed title field width */
+@@ -1144,17 +1144,17 @@
+ /*
+ * set location field's length and value based on requested style
+ */
+- loc_label = (is_context) ? "Msg" : "Message";
++ loc_label = (is_context) ? "信" : "信件";
+ loc_len = strlen(loc_label);
+ if(!mn_get_total(as.msgmap)){
+- sprintf(tmp_20k_buf, "No %ss", loc_label);
++ sprintf(tmp_20k_buf, "沒有%s", loc_label);
+ loc_len += 4;
+ }else{
+ switch(as.style){
+ case FolderName : /* "x,xxx <loc_label>s" */
+ loc_len += digit_count(mn_get_total(as.msgmap)) + 3;
+- sprintf(tmp_20k_buf, "%s %s%s", comatose(mn_get_total(as.msgmap)),
+- loc_label, plural(mn_get_total(as.msgmap)));
++ sprintf(tmp_20k_buf, "%s 封%s", comatose(mn_get_total(as.msgmap)),
++ loc_label);
break;
+ case MessageNumber : /* "<loc_label> xxx of xxx DEL" */
+ num_len = digit_count(mn_get_total(as.msgmap));
+@@ -1162,7 +1162,7 @@
+ as.cur_mess_col = sc - (2 * num_len) - 10;
+ as.del_column = as.cur_mess_col + num_len
+ + digit_count(as.current_msg) + 5;
+- sprintf(tmp_20k_buf, "%s %s of %s %s", loc_label,
++ sprintf(tmp_20k_buf, "%s %s 之 %s %s", loc_label,
+ strcpy(tmp_20k_buf + 1000, comatose(as.current_msg)),
+ strcpy(tmp_20k_buf + 1500, comatose(mn_get_total(as.msgmap))),
+ BAR_STATUS(as.msg_state));
+@@ -1174,7 +1174,7 @@
+ as.percent_column = as.cur_mess_col + num_len
+ + digit_count(as.current_msg) + 7;
+ as.del_column = as.percent_column + 4;
+- sprintf(tmp_20k_buf, "%s %s of %s %s %s", loc_label,
++ sprintf(tmp_20k_buf, "%s %s 之 %s %s %s", loc_label,
+ strcpy(tmp_20k_buf + 1000, comatose(as.current_msg)),
+ strcpy(tmp_20k_buf + 1500, comatose(mn_get_total(as.msgmap))),
+ percentage(as.current_line, as.total_lines, 1),
+@@ -1185,7 +1185,7 @@
+ case FileTextPercent :
+ as.page_column = sc - (14 + 2*(num_len = digit_count(as.total_lines)));
+ loc_len = 17 + 2*num_len;
+- sprintf(tmp_20k_buf, "Line %*ld of %*ld %s ",
++ sprintf(tmp_20k_buf, "行 %*ld 之 %*ld %s ",
+ num_len, as.current_line,
+ num_len, as.total_lines,
+ percentage(as.current_line, as.total_lines, 1));
+@@ -1259,7 +1259,7 @@
+ ss_string);
+ }
+ else{
+- char *fmt = "Folder: %s%s";
++ char *fmt = "信件匣:%s%s";
+ if(fold_len + ss_len + 8 < avail) /* all of folder fit? */
+ sprintf(fold_tmp, fmt, as.folder_name, ss_string);
+ else if((fold_len/2) + ss_len + 8 < avail)
+@@ -1307,7 +1307,7 @@
+ as.current_msg = mn_get_cur(as.msgmap);
-+ case KEY_LEFT :
- case 'e' : /* exit attachment screen */
- case PF3 :
- done++;
-@@ -362,7 +363,6 @@
- case 'n' : /* next list element */
- case '\t' :
- case ctrl('F') :
-- case KEY_RIGHT :
- case ctrl('N'): /* down arrow */
- case KEY_DOWN :
- case PF6 :
-@@ -377,7 +377,6 @@
+ if(as.style == MsgTextPercent){
+- PutLine5(0, as.cur_mess_col, "%s of %s %s %s%s",
++ PutLine5(0, as.cur_mess_col, "%s 之 %s %s %s%s",
+ strcpy(tmp_20k_buf + 1000, comatose(as.current_msg)),
+ strcpy(tmp_20k_buf + 1500,
+ comatose(mn_get_total(as.msgmap))),
+@@ -1317,7 +1317,7 @@
+ as.del_column += delta;
+ as.percent_column += delta;
+ } else {
+- PutLine4(0, as.cur_mess_col, "%s of %s %s%s",
++ PutLine4(0, as.cur_mess_col, "%s 之 %s %s%s",
+ strcpy(tmp_20k_buf + 1000, comatose(as.current_msg)),
+ strcpy(tmp_20k_buf + 1500,
+ comatose(mn_get_total(as.msgmap))),
+@@ -1420,7 +1420,7 @@
- case 'p' : /* previous list element */
- case ctrl('B') :
-- case KEY_LEFT :
- case ctrl('P') : /* up arrow */
- case KEY_UP :
- case PF5 :
-@@ -506,7 +505,7 @@
- }
- }
- else
-- result = "WhereIs cancelled";
-+ result = "搜尋指令已取消";
+ as.current_line = new_line_number;
- if(found && ctmp){
- strcpy(last, buf);
-@@ -530,6 +529,7 @@
- ps->mangled_screen = 1;
- break;
-
-+ case KEY_RIGHT:
- case 'v': /* View command */
- case ctrl('M'):
- case PF4 :
-@@ -855,7 +855,7 @@
- char *err;
- struct variable *vars = ps_global->vars;
- static ESCKEY_S att_save_opts[] = {
-- {ctrl('T'), 10, "^T", "To Files"},
-+ {ctrl('T'), 10, "^T", "信夾列表"},
- {-1, 0, NULL, NULL},
- {-1, 0, NULL, NULL},
- {-1, 0, NULL, NULL}};
+- sprintf(tmp_20k_buf, "%*ld of %*ld %s ",
++ sprintf(tmp_20k_buf, "%*ld 之 %*ld %s ",
+ digit_count(as.total_lines), as.current_line,
+ digit_count(as.total_lines), as.total_lines,
+ percentage(as.current_line, as.total_lines, 0));
diff --git a/chinese/pine4/files/patch-bd b/chinese/pine4/files/patch-bd
index d4bb4bd2f804..7b3e48880ff2 100644
--- a/chinese/pine4/files/patch-bd
+++ b/chinese/pine4/files/patch-bd
@@ -1,180 +1,675 @@
---- pine/mailview.c.orig Fri Jul 12 06:49:32 1996
-+++ pine/mailview.c Sat Jan 17 21:07:22 1998
-@@ -1955,12 +1955,12 @@
- * is stored with each entry and it could be different for each.
- */
- static struct key help_keys[] =
-- {{"M","Main Menu",KS_MAINMENU}, {NULL,NULL,KS_NONE},
-- {"E","Exit Help",KS_EXITMODE}, {NULL,NULL,KS_NONE},
-+ {{"M","主選單",KS_MAINMENU}, {NULL,NULL,KS_NONE},
-+ {"E","離開",KS_EXITMODE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"Y","prYnt",KS_PRINT}, {"Z","Print All",KS_NONE},
-- {"B","Report Bug",KS_NONE}, {"W","WhereIs",KS_WHEREIS}};
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"Y","列印",KS_PRINT}, {"Z","Print All",KS_NONE},
-+ {"B","錯誤回報",KS_NONE}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(help_keymenu, help_keys);
- #define HLP_MAIN_KEY 0
- #define HLP_ALL_KEY 9
-@@ -1968,34 +1968,34 @@
-
- static struct key review_keys[] =
- {{NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"E","Exit",KS_EXITMODE}, {NULL,NULL,KS_NONE},
-+ {"E","離開",KS_EXITMODE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"Y","prYnt",KS_PRINT}, {NULL,NULL,KS_NONE},
-- {NULL,NULL,KS_NONE}, {"W","WhereIs",KS_WHEREIS}};
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"Y","列印",KS_PRINT}, {NULL,NULL,KS_NONE},
-+ {NULL,NULL,KS_NONE}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(review_keymenu, review_keys);
-
- static struct key view_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"M","Main Menu",KS_MAINMENU}, {"V","ViewAttch",KS_VIEW},
-- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"D","Delete",KS_DELETE}, {"U","Undelete",KS_UNDELETE},
-- {"R","Reply",KS_REPLY}, {"F","Forward",KS_FORWARD},
--
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"Q","Quit",KS_EXIT}, {"C","Compose",KS_COMPOSER},
-- {"L","ListFldrs",KS_FLDRLIST}, {"G","GotoFldr",KS_GOTOFLDR},
-- {"I","Index",KS_FLDRINDEX}, {"W","WhereIs",KS_WHEREIS},
-- {"Y","prYnt",KS_PRINT}, {"T","TakeAddr",KS_TAKEADDR},
-- {"S","Save",KS_SAVE}, {"E","Export",KS_EXPORT},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {"M","主選單",KS_MAINMENU}, {"V","檢視附件",KS_VIEW},
-+ {"P","前一個",KS_PREVMSG}, {"N","後一個",KS_NEXTMSG},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"D","刪除",KS_DELETE}, {"U","救回刪除",KS_UNDELETE},
-+ {"R","回信",KS_REPLY}, {"F","轉寄",KS_FORWARD},
-+
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {"Q","離開",KS_EXIT}, {"C","編輯",KS_COMPOSER},
-+ {"L","列出信件夾",KS_FLDRLIST}, {"G","進入信件夾",KS_GOTOFLDR},
-+ {"I","索引",KS_FLDRINDEX}, {"W","搜尋",KS_WHEREIS},
-+ {"Y","列印",KS_PRINT}, {"T","取得地址",KS_TAKEADDR},
-+ {"S","儲存",KS_SAVE}, {"E","匯出",KS_EXPORT},
-
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"J","Jump",KS_JUMPTOMSG}, {"TAB","NextNew",KS_NONE},
-- {"H","HdrMode",KS_HDRMODE}, {"B","Bounce",KS_BOUNCE},
-- {"*","Flag",KS_FLAG}, {"|","Pipe",KS_NONE}};
-+ {"J","跳至",KS_JUMPTOMSG}, {"TAB","下一個",KS_NONE},
-+ {"H","標頭模式",KS_HDRMODE}, {"B","Bounce",KS_BOUNCE},
-+ {"*","旗標",KS_FLAG}, {"|","Pipe",KS_NONE}};
- INST_KEY_MENU(view_keymenu, view_keys);
- #define VIEW_FULL_HEADERS_KEY 32
- #define BOUNCE_KEY 33
-@@ -2003,49 +2003,49 @@
- #define VIEW_PIPE_KEY 35
-
- static struct key nr_anon_view_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"W","WhereIs",KS_WHEREIS},
-- {"Q", "Quit",KS_EXIT}, {NULL,NULL,KS_NONE},
-- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"F","Fwd Email",KS_FORWARD}, {"J","Jump",KS_JUMPTOMSG},
-- {"I", "Index",KS_FLDRINDEX}, {NULL, NULL,KS_NONE}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {"W","搜尋",KS_WHEREIS},
-+ {"Q", "離開",KS_EXIT}, {NULL,NULL,KS_NONE},
-+ {"P","前一個",KS_PREVMSG}, {"N","後一個",KS_NEXTMSG},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"F","轉寄",KS_FORWARD}, {"J","跳至",KS_JUMPTOMSG},
-+ {"I", "索引",KS_FLDRINDEX}, {NULL, NULL,KS_NONE}};
- INST_KEY_MENU(nr_anon_view_keymenu, nr_anon_view_keys);
-
- static struct key nr_view_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"Q","Quit",KS_EXIT}, {NULL,NULL,KS_NONE},
-- {"P","PrevMsg",KS_PREVMSG}, {"N","NextMsg",KS_NEXTMSG},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"F","Fwd Email",KS_FORWARD}, {"J","Jump",KS_JUMPTOMSG},
-- {"Y","prYnt",KS_PRINT}, {"S","Save",KS_SAVE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"O","其它命令",KS_NONE},
-+ {"Q","離開",KS_EXIT}, {NULL,NULL,KS_NONE},
-+ {"P","前一個",KS_PREVMSG}, {"N","後一個",KS_NEXTMSG},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"F","轉寄",KS_FORWARD}, {"J","跳至",KS_JUMPTOMSG},
-+ {"Y","列印",KS_PRINT}, {"S","儲存",KS_SAVE},
-
-- {"?","Help",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-- {"E","Export",KS_EXPORT}, {"C","Compose",KS_COMPOSER},
-+ {"?","輔助說明",KS_SCREENHELP}, {"O","OTHER CMDS",KS_NONE},
-+ {"E","匯出",KS_EXPORT}, {"C","編輯",KS_COMPOSER},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"I","Index",KS_FLDRINDEX}, {"W","WhereIs",KS_WHEREIS},
-+ {"I","索引",KS_FLDRINDEX}, {"W","搜尋",KS_WHEREIS},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE}};
- INST_KEY_MENU(nr_view_keymenu, nr_view_keys);
-
- static struct key text_att_view_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"E","Exit Viewer",KS_EXITMODE}, {NULL,NULL,KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"E","離開",KS_EXITMODE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"Y","prYnt",KS_PRINT}, {"S","Save",KS_SAVE},
-- {"|","Pipe",KS_NONE}, {"W", "WhereIs",KS_WHEREIS}};
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"Y","列印",KS_PRINT}, {"S","儲存",KS_SAVE},
-+ {"|","Pipe",KS_NONE}, {"W", "搜尋",KS_WHEREIS}};
- INST_KEY_MENU(text_att_view_keymenu, text_att_view_keys);
- #define ATT_SAVE_KEY 9
- #define ATT_PIPE_KEY 10
-
-
- static struct key simple_view_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"Q","Quit Viewer",KS_NONE}, {NULL,NULL,KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"Q","離開",KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"F","Fwd Email",KS_FORWARD}, {"S","Save",KS_SAVE},
-- {NULL,NULL,KS_NONE}, {"W","WhereIs",KS_WHEREIS}};
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"F","轉寄",KS_FORWARD}, {"S","儲存",KS_SAVE},
-+ {NULL,NULL,KS_NONE}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(simple_view_keymenu, simple_view_keys);
- #define SAVE_KEY 9
-
-@@ -2342,7 +2342,7 @@
+--- pine/send.c.orig Thu Jul 2 02:32:53 1998
++++ pine/send.c Wed Jul 15 17:24:57 1998
+@@ -366,14 +366,14 @@
+ mail_close(stream);
+ if(ret == 'x'){
+ q_status_message(SM_ORDER, 0, 3,
+- "Composition cancelled");
++ "取消編輯");
+ return;
+ }
+ }
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Can't open Interrupted mailbox: %s",
++ "無法開被中斷的信箱:%s",
+ file_path);
+ if(stream)
+ mail_close(stream);
+@@ -442,14 +442,14 @@
+
+ if(ret == 'x'){
+ q_status_message(SM_ORDER, 0, 3,
+- "Composition cancelled");
++ "取消編輯");
+ done++;
+ }
+ }
}
- if(style == HelpText || style == MainHelpText
- || style == ComposerHelpText) {
-- q_status_message(SM_ORDER, 0, 5, "Already in Help");
-+ q_status_message(SM_ORDER, 0, 5, "已經在輔助選單中");
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Can't open Postponed mailbox: %s", mbox);
++ "無法開遭暫緩的信箱:%s", mbox);
+ if(stream)
+ mail_close(stream);
+ }
+@@ -524,7 +524,7 @@
+
+ if(ret == 'x'){
+ q_status_message(SM_ORDER, 0, 3,
+- "Composition cancelled");
++ "取消編輯");
+ done++;
+ }
+ }
+@@ -608,7 +608,7 @@
+ fs_give((void **)&tmp_fcc);
+ }
+
+- pine_send(outgoing, &body, "COMPOSE MESSAGE", fcc,
++ pine_send(outgoing, &body, "編輯信件", fcc,
+ reply, redraft_pos, lcc, custom, fcc_is_sticky);
+
+ if(reply){
+@@ -675,7 +675,7 @@
+ */
+ if(!stream->nmsgs){
+ q_status_message(SM_ORDER | SM_DING, 3, 5,
+- "Empty folder. No messages really postponed!");
++ "空的信件匣。沒有信件真正被暫緩!");
+ return(redraft_cleanup(stream, TRUE));
+ }
+ else if(stream == ps_global->mail_stream){
+@@ -711,7 +711,7 @@
+ mn_give(&msgmap);
+
+ if(rv){
+- q_status_message(SM_ORDER, 0, 3, "Composition cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消編輯");
+ (void) redraft_cleanup(stream, FALSE);
+ return(0); /* special case */
+ }
+@@ -949,7 +949,7 @@
+ if(b->type == TYPEMULTIPART){
+ if(strucmp(b->subtype, "mixed")){
+ q_status_message1(SM_INFO, 3, 4,
+- "Converting Multipart/%s to Multipart/Mixed",
++ "轉換 Multipart/%s to Multipart/Mixed",
+ b->subtype);
+ fs_give((void **)&b->subtype);
+ b->subtype = cpystr("mixed");
+@@ -957,7 +957,7 @@
+ }
+ else{
+ q_status_message2(SM_ORDER | SM_DING, 3, 4,
+- "Unable to resume type %s/%s message",
++ "無法繼續形態為 %s/%s 的信件",
+ body_types[b->type], b->subtype);
+ return(redraft_cleanup(stream, TRUE));
+ }
+@@ -971,7 +971,7 @@
+ set_mime_type_by_grope(&part->body, NULL);
+ if(part->body.type != TYPETEXT){
+ q_status_message2(SM_ORDER | SM_DING, 3, 4,
+- "Unable to resume; first part is non-text: %s/%s",
++ "無法繼續;第一部份非純文字:%s/%s",
+ body_types[part->body.type],
+ part->body.subtype);
+ return(redraft_cleanup(stream, TRUE));
+@@ -1299,7 +1299,7 @@
+
+ if(rc == 1 || (rc == 0 && !answer)) {
+ q_status_message(SM_ORDER, 3, 4,
+- "Send cancelled (User-id must be provided before sending)");
++ "取消寄件(寄件前必須提供使用者代號)");
+ return(0);
+ }
+
+@@ -1388,7 +1388,7 @@
+
+ if(rc == 1 || (rc == 0 && !answer)) {
+ q_status_message(SM_ORDER, 3, 4,
+- "Send cancelled (Host/domain name must be provided before sending)");
++ "取消寄件(寄件前必須提供 主機/領域 名稱)");
+ return(0);
+ }
+
+@@ -1444,7 +1444,7 @@
+
+ if(rc == 1 || (rc == 0 && answer[0] == '\0')) {
+ q_status_message(SM_ORDER, 3, 4,
+- "Send cancelled (SMTP server must be provided before sending)");
++ "取消寄件(寄件前必須提供 SMTP 伺服器)");
+ return(0);
+ }
+
+@@ -1471,31 +1471,31 @@
+ */
+ static struct headerentry he_template[]={
+ {"From : ", "From", h_composer_from, 10, 0, NULL,
+- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
++ build_address, NULL, NULL, addr_book_compose, "地址簿",
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK},
+ {"Reply-To: ", "Reply To", h_composer_reply_to, 10, 0, NULL,
+- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
++ build_address, NULL, NULL, addr_book_compose, "地址簿",
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK},
+ {"To : ", "To", h_composer_to, 10, 0, NULL,
+- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
++ build_address, NULL, NULL, addr_book_compose, "地址簿",
+ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK},
+ {"Cc : ", "Cc", h_composer_cc, 10, 0, NULL,
+- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
++ build_address, NULL, NULL, addr_book_compose, "地址簿",
+ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK},
+ {"Bcc : ", "Bcc", h_composer_bcc, 10, 0, NULL,
+- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
++ build_address, NULL, NULL, addr_book_compose, "地址簿",
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK},
+ {"Newsgrps: ", "Newsgroups", h_composer_news, 10, 0, NULL,
+- news_build, NULL, NULL, news_group_selector, "To NwsGrps",
++ news_build, NULL, NULL, news_group_selector, "新聞組群列表",
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_NONE},
+ {"Fcc : ", "Fcc", h_composer_fcc, 10, 0, NULL,
+- NULL, NULL, NULL, folders_for_fcc, "To Fldrs",
++ NULL, NULL, NULL, folders_for_fcc, "資料匣列表",
+ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, KS_NONE},
+ {"Lcc : ", "Lcc", h_composer_lcc, 10, 0, NULL,
+- build_addr_lcc, NULL, NULL, addr_book_compose_lcc,"To AddrBk",
++ build_addr_lcc, NULL, NULL, addr_book_compose_lcc,"地址簿",
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_NONE},
+ {"Attchmnt: ", "Attchmnt", h_composer_attachment, 10, 0, NULL,
+- NULL, NULL, NULL, NULL, "To Files",
++ NULL, NULL, NULL, NULL, "檔案列表",
+ 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, KS_NONE},
+ {"Subject : ", "Subject", h_composer_subject, 10, 0, NULL,
+ valid_subject, NULL, NULL, NULL, NULL,
+@@ -1530,7 +1530,7 @@
+
+ static struct headerentry he_custom_addr_templ={
+ NULL, NULL, h_composer_custom_addr,10, 0, NULL,
+- build_address, NULL, NULL, addr_book_compose, "To AddrBk",
++ build_address, NULL, NULL, addr_book_compose, "地址簿",
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK};
+ static struct headerentry he_custom_free_templ={
+ NULL, NULL, h_composer_custom_free,10, 0, NULL,
+@@ -1821,7 +1821,7 @@
+ ekey[0].ch = ctrl('T');
+ ekey[0].rval = 2;
+ ekey[0].name = "^T";
+- ekey[0].label = "To AddrBk";
++ ekey[0].label = "地址簿";
+ ekey[1].ch = -1;
+
+ /*----------------------------------------------------------------------
+@@ -1932,12 +1932,12 @@
+ opts[i].ch = 'y';
+ opts[i].rval = 'y';
+ opts[i].name = "Y";
+- opts[i++].label = "Yes";
++ opts[i++].label = "是";
+
+ opts[i].ch = 'n';
+ opts[i].rval = 'n';
+ opts[i].name = "N";
+- opts[i++].label = "No";
++ opts[i++].label = "否";
+
+ verbose_requested = 0;
+ if(F_ON(F_VERBOSE_POST, ps_global)){
+@@ -1984,7 +1984,7 @@
+ dsn_show = (dsn_requested & DSN_SHOW);
+ sprintf(tmp_20k_buf,
+ "%s%s%s%s%s%sto \"%s\" ? ",
+- prmpt_cnf ? prmpt_cnf : "Send message ",
++ prmpt_cnf ? prmpt_cnf : "送信 ",
+ (verbose_requested || dsn_show)
+ ? "(" : "",
+ (verbose_requested)
+@@ -2164,7 +2164,7 @@
+ }
+ }
+ else{
+- q_status_message(SM_ORDER, 0, 3, "Send cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消寄件");
+ retval = -1;
+ }
+ }
+@@ -2192,7 +2192,7 @@
+ break;
+
+ case 1:
+- q_status_message(SM_ORDER, 0, 3, "Send cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消寄件");
+ done++;
+ retval = -1;
+ break;
+@@ -2436,7 +2436,7 @@
+ break;
+
+ case 'x': /* ^C */
+- q_status_message(SM_ORDER, 0, 3, "Message cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消信件");
+ dprint(4, (debugfile, "=== send: cancelled\n"));
+ return;
+
+@@ -2853,7 +2853,7 @@
+ #endif
+ if(pf->canedit || !he->rich_header)
+ q_status_message(SM_ORDER, 3, 3,
+- "Not allowed to change header \"From\"");
++ "不允許\改變標頭 \"From\"");
+
+ memset(he, 0, (size_t)sizeof(*he));
+ pf->he = NULL;
+@@ -3196,7 +3196,7 @@
+ ? "CANCEL" : "HUH?"));
+ if((editor_result & COMP_CANCEL)
+ && F_ON(F_QUELL_DEAD_LETTER, ps_global)){
+- q_status_message(SM_ORDER, 0, 3, "Message cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消信件");
+ break;
+ }
+
+@@ -3474,15 +3474,15 @@
+ if(fcc_result && folder)
+ lc = last_cmpnt(folder);
+
+- q_status_message3(SM_ORDER, 0, 3, "Message cancelled%s%s%s",
+- (lc && *lc) ? " and copied to \"" : "",
++ q_status_message3(SM_ORDER, 0, 3, "取消信件%s%s%s",
++ (lc && *lc) ? " 並複製到 \"" : "",
+ (lc && *lc) ? lc : "",
+ (lc && *lc) ? "\" file" : "");
break;
+ }
+ else{
+ q_status_message(SM_ORDER, 0, 4,
+- "Continuing composition. Message not postponed or sent");
++ "繼續編輯。信件未被暫緩或送出");
+ body_start = 1;
+ continue; /* postpone failed, jump back in to composer */
+ }
+@@ -3547,8 +3547,8 @@
+ && !filter_message_text(sending_filter_requested, outgoing,
+ *body, &orig_so)){
+ q_status_message1(SM_ORDER, 3, 3,
+- "Problem filtering! Nothing sent%s.",
+- fcc ? " or saved to fcc" : "");
++ "過濾器有問題!沒有東西被送出%s。",
++ fcc ? "或存至 fcc" : "");
+ continue;
+ }
+
+@@ -3938,23 +3938,23 @@
+ char *buf;
+ int *goodorbad;
+ {
+- sprintf(buf, "Message %s%s%s%s%s%s%s.",
++ sprintf(buf, "信件 %s%s%s%s%s%s%s.",
+ (result & P_NEWS_WIN)
+- ? "posted"
++ ? "已刊登"
+ : (result & P_NEWS_LOSE)
+- ? "NOT posted" : "",
++ ? "未被刊登" : "",
+ ((result & P_NEWS_BITS) && (result & P_MAIL_BITS)
+ && (result & P_FCC_BITS))
+ ? ", "
+ : ((result & P_NEWS_BITS) && (result & P_MAIL_BITS))
+- ? " and " : "",
++ ? " 並 " : "",
+ (result & P_MAIL_WIN)
+- ? "sent"
++ ? "已寄出"
+ : (result & P_MAIL_LOSE)
+- ? "NOT SENT" : "",
++ ? "未寄出" : "",
+ ((result & (P_MAIL_BITS | P_NEWS_BITS)) && (result & P_FCC_BITS))
+- ? " and copied to "
+- : (result & P_FCC_WIN) ? "ONLY copied to " : "",
++ ? " 並被複製到 "
++ : (result & P_FCC_WIN) ? "僅被複製到 " : "",
+ (result & P_FCC_WIN) ? "\"" : "",
+ (result & P_FCC_WIN) ? fcc_name : "",
+ (result & P_FCC_WIN) ? "\"" : "");
+@@ -4281,12 +4281,12 @@
+ opts[i].ch = 'y';
+ opts[i].rval = 'y';
+ opts[i].name = "Y";
+- opts[i++].label = "Yes";
++ opts[i++].label = "是";
+
+ opts[i].ch = 'n';
+ opts[i].rval = 'n';
+ opts[i].name = "N";
+- opts[i++].label = "No";
++ opts[i++].label = "否";
+
+ if(filters){
+ /* set global_filter_pointer to desired filter or NULL if none */
+@@ -4294,12 +4294,12 @@
+ opts[i].ch = ctrl('P');
+ opts[i].rval = 10;
+ opts[i].name = "^P";
+- opts[i++].label = "Prev Filter";
++ opts[i++].label = "前一個過濾器";
+
+ opts[i].ch = ctrl('N');
+ opts[i].rval = 11;
+ opts[i].name = "^N";
+- opts[i++].label = "Next Filter";
++ opts[i++].label = "下一個過濾器";
+
+ if(F_ON(F_FIRST_SEND_FILTER_DFLT, ps_global))
+ filters = filters->next;
+@@ -4369,23 +4369,23 @@
+ p = NULL;
+
+ dsn_show = (dsn_requested & DSN_SHOW);
+- sprintf(tmp_20k_buf, "Send message%s%s%s%s%s%s%s%s%s%s%s%s? ",
++ sprintf(tmp_20k_buf, "送出信件%s%s%s%s%s%s%s%s%s%s%s%s? ",
+ (filters || verbose_requested || background_requested
+ || dsn_show)
+ ? " (" : "",
+- (filters && filters->filter) ? "filtered thru \"" : "",
++ (filters && filters->filter) ? "經由過濾器 \"" : "",
+ (filters)
+ ? (filters->filter
+ ? filters->filter
+- : "unfiltered")
++ : "未經過濾")
+ : "",
+ (filters && filters->filter) ? "\"" : "",
+ (filters && (verbose_requested || background_requested))
+ ? " " : "",
+ (verbose_requested || background_requested)
+ ? "in " : "",
+- (verbose_requested) ? "verbose " : "",
+- (background_requested) ? "background " : "",
++ (verbose_requested) ? "顯示細節 " : "",
++ (background_requested) ? "背景送出 " : "",
+ (verbose_requested || background_requested)
+ ? "mode" : "",
+ (dsn_show
+@@ -4400,11 +4400,11 @@
+ *p = ' ';
+
+ if(verbose_label)
+- opts[verbose_label].label = verbose_requested ? "Normal" : "Verbose";
++ opts[verbose_label].label = verbose_requested ? "通常" : "顯示細節";
+
+ if(bg_label)
+ opts[bg_label].label = background_requested
+- ? "Foreground" : "Background";
++ ? "前景" : "背景";
+
+ if(F_ON(F_DSN, ps_global)){
+ if(dsn_requested & DSN_SHOW){
+@@ -4428,11 +4428,11 @@
+ break;
+ }
+ else if(rv == 'n'){ /* Declined! */
+- rstr = "No Message Sent";
++ rstr = "沒有任何信件被送出";
+ break;
+ }
+ else if(rv == 'z'){ /* Cancelled! */
+- rstr = "Send Cancelled";
++ rstr = "取消送件";
+ break;
+ }
+ else if(rv == 10) /* PREVIOUS filter */
+@@ -4614,7 +4614,7 @@
+ if(body->type != TYPEOTHER){
+ rv = 1;
+ q_status_message3(SM_ORDER, 0, 3,
+- "File %s attached as type %s/%s", file,
++ "檔案 %s 附加為 %s/%s", file,
+ body_types[body->type],
+ body->subtype ? body->subtype : rfc822_default_subtype(body->type));
+ }
+@@ -4663,7 +4663,7 @@
+ (void) close_system_pipe(&syspipe);
+ if((l = name_file_size(fname)) < 0L){
+ q_status_message2(SM_ORDER | SM_DING, 3, 4,
+- "Error determining size of %s: %s", fname,
++ "決定檔案 %s 大小時發生錯誤:%s", fname,
+ fnp = error_description(errno));
+ dprint(1, (debugfile,
+ "!!! Upload cmd \"%s\" failed for \"%s\": %s\n",
+@@ -4675,7 +4675,7 @@
+ return(l >= 0);
+ }
+ else
+- q_status_message(SM_ORDER | SM_DING, 3, 4, "Error opening pipe");
++ q_status_message(SM_ORDER | SM_DING, 3, 4, "開啟管線時發生錯誤");
+
+ return(0);
+ }
+@@ -4728,7 +4728,7 @@
+ else if(reply->flags == REPLY_MSGNO)
+ return;
+
+- we_cancel = busy_alarm(1, "Updating \"Answered\" Flags", NULL, 1);
++ we_cancel = busy_alarm(1, "正在更新 \"已回覆\" 旗標", NULL, 1);
+ if(!stream){
+ if(stream = mail_open(NULL, reply->mailbox, OP_SILENT)){
+ ourstream++;
+@@ -4806,7 +4806,7 @@
+ so_give(&tmpf_so);
}
+ else
+- errstr = "Can't create space for filter temporary file.";
++ errstr = "無法建立過濾器的暫存檔。";
+ }
-@@ -2722,7 +2722,7 @@
+ if(!errstr){
+@@ -4830,13 +4830,13 @@
+ so_give(&tmpf_so);
+ }
+ else
+- errstr = "Can't open temp file filter wrote.";
++ errstr = "無法開啟過濾器的暫存檔。";
+ }
+ else
+- errstr = "Filter command returned error.";
++ errstr = "過濾器指令傳回錯誤值。";
+ }
+ else
+- errstr = "Can't exec filter text.";
++ errstr = "無法執行過濾器。";
}
- else if((ch == 'z' || ch == PF10) && style == MainHelpText){
- print_all_help();
-- }else if(!ps_global->nr_mode && (ch == PF3 || ch == 'e')) {
-+ }else if(!ps_global->nr_mode && (ch == PF3 || ch == 'e' || ch == KEY_LEFT)) {
- /*----------- Done -----------*/
- done = 1;
- }else if((ch == 'y' && !ps_global->anonymous) ||
-@@ -2843,8 +2843,8 @@
- int rc;
- static char search_string[MAX_SEARCH+1] = { '\0' };
- static ESCKEY_S word_search_key[] = { { 0, 0, "", "" },
-- {ctrl('Y'), 10, "^Y", "First Line"},
-- {ctrl('V'), 11, "^V", "Last Line"},
-+ {ctrl('Y'), 10, "^Y", "第一行"},
-+ {ctrl('V'), 11, "^V", "最後一行"},
- {-1, 0, NULL, NULL}
- };
+ else
+ errstr = gf_filter(cmd, key ? filter_session_key() : NULL,
+@@ -4847,7 +4847,7 @@
+ if(errstr){
+ int ch;
+
+- fprintf(stdout, "\r\n%s Hit return to continue.", errstr);
++ fprintf(stdout, "\r\n%s 鍵入 return 繼續。", errstr);
+ fflush(stdout);
+ while((ch = read_char(300)) != ctrl('M')
+ && ch != NO_OP_IDLE)
+@@ -4940,7 +4940,7 @@
+ if(tmp_so)
+ so_give(&tmp_so);
+
+- q_status_message1(SM_ORDER | SM_DING, 3, 6, "Problem filtering: %s",
++ q_status_message1(SM_ORDER | SM_DING, 3, 6, "過濾過程有問題:%s",
+ errstr);
+ dprint(1, (debugfile, "Filter FAILED: %s\n", errstr));
+ }
+@@ -5072,7 +5072,7 @@
+
+ if(!pf){
+ q_status_message(SM_ORDER,3,3,
+- "Can't send message. No recipients specified!");
++ "無法送信。尚未指定收信人!");
+ return(0);
+ }
+
+@@ -5081,7 +5081,7 @@
+ gf_filter_init(); /* zero piped byte count, 'n */
+ send_bytes_to_send = send_body_size(body); /* count body bytes */
+ ps_global->c_client_error[0] = error_buf[0] = '\0';
+- we_cancel = busy_alarm(1, "Sending mail",
++ we_cancel = busy_alarm(1, "正在寄信",
+ send_bytes_to_send ? sent_percent : NULL, 1);
+
+ /* try posting via local "<mta> <-t>" if specified */
+@@ -5263,7 +5263,7 @@
+ struct headerentry *last_he = NULL;
+
+ sprintf(error_buf,
+- "Mail not sent. Sending error%s%.40s",
++ "信件未被寄出。寄件錯誤%s%.40s",
+ (sending_stream && sending_stream->reply) ? ": ": ".",
+ (sending_stream && sending_stream->reply)
+ ? sending_stream->reply : "");
+@@ -5334,7 +5334,7 @@
+ TIME_STAMP("smtp done", 1);
+ }
+ else if(!error_mess)
+- sprintf(error_mess = error_buf, "Error sending: %.60s",
++ sprintf(error_mess = error_buf, "寄信時發生錯誤:%.60s",
+ ps_global->c_client_error);
+
+ if(verbose_file){
+@@ -5431,12 +5431,12 @@
+ if(folder_index(fcc, *fcc_cntxt, FI_FOLDER) < 0){
+ if(ps_global->context_list->next)
+ sprintf(tmp_20k_buf,
+- "Folder \"%.20s\" in <%.30s> doesn't exist. Create",
++ "信件匣 \"%.20s\" 在 <%.30s> 尚不存在。要新建",
+ strsquish(tmp_20k_buf + 500, fcc, 20),
+ strsquish(tmp_20k_buf + 1000,(*fcc_cntxt)->nickname,30));
+ else
+ sprintf(tmp_20k_buf,
+- "Folder \"%s\" doesn't exist. Create",
++ "信件匣 \"%s\" 尚不存在。要新建",
+ strsquish(tmp_20k_buf + 500, fcc, 40));
+
+ if(force || want_to(tmp_20k_buf,'y','n',NO_HELP,WT_NORM) == 'y'){
+@@ -5473,7 +5473,7 @@
+ ok++;
+ }
+ else{
+- sprintf(tmp_20k_buf,"Folder \"%s\" doesn't exist. Create",
++ sprintf(tmp_20k_buf,"信件匣 \"%s\" 尚不存在。要新建",
+ strsquish(tmp_20k_buf + 500, fcc, 40));
+ if(force || want_to(tmp_20k_buf,'y','n',NO_HELP,WT_NORM) == 'y'){
+ /*
+@@ -5507,8 +5507,8 @@
+
+ if(ok == 0){
+ if(ps_global->mm_log_error){
+- s1 = err_prefix ? err_prefix : "Fcc Error: ";
+- s2 = err_suffix ? err_suffix : " Message NOT sent or copied.";
++ s1 = err_prefix ? err_prefix : "Fcc 錯誤:";
++ s2 = err_suffix ? err_suffix : " 信件沒有被寄出或複製。";
+
+ l1 = strlen(s1);
+ l2 = strlen(s2);
+@@ -5526,10 +5526,10 @@
+
+ }
+ else
+- errstr = "Fcc creation error. Message NOT sent or copied.";
++ errstr = "建立 Fcc 時發生錯誤。信件沒有被送出或複製。";
+ }
+ else
+- errstr = "Fcc creation rejected. Message NOT sent or copied.";
++ errstr = "Fcc 之建立遭拒絕。信件沒有被送出或複製。";
+
+ q_status_message(SM_ORDER | SM_DING, 3, 3, errstr);
+ }
+@@ -5577,7 +5577,7 @@
+ if(label && *label){
+ char msg_buf[80];
+
+- strncat(strcpy(msg_buf, "Writing "), label, 70);
++ strncat(strcpy(msg_buf, "正在寫入 "), label, 70);
+ we_cancel = busy_alarm(1, msg_buf, NULL, 1);
+ }
+ else
+@@ -5613,7 +5613,7 @@
+ we_cancel = 0;
+
+ q_status_message1(SM_ORDER | SM_DING, 3, 5,
+- "Write to \"%s\" FAILED!!!", fcc);
++ "寫入 \"%s\" 失敗!!!", fcc);
+ dprint(1, (debugfile, "ERROR appending %s in \"%s\"",
+ fcc, cntxt ? cntxt->context : "NULL"));
+ return(0);
+@@ -6089,7 +6089,7 @@
+ if((file_contents = (void *)so_get(FileStar, pa->filename,
+ READ_ACCESS)) == NULL){
+ q_status_message2(SM_ORDER | SM_DING, 3, 4,
+- "Error \"%s\", couldn't attach file \"%s\"",
++ "錯誤 \"%s\",無法附加檔案 \"%s\"",
+ error_description(errno), pa->filename);
+ display_message('x');
+ continue;
+@@ -6616,13 +6616,17 @@
+ body->subtype = cpystr("octet-stream");
+ }
+
+- /*
+- * Apply maximal encoding regardless of previous
+- * setting. This segment's either not text, or is
+- * unlikely to be readable with > 30% of the
+- * text encoded anyway, so we might as well save space...
+- */
+- new_encoding = ENCBINARY; /* > 30% 8 bit chars */
++ if(body->type == TYPETEXT)
++ /* Use ENC8BIT rather than ENCBINARY for TEXT */
++ new_encoding = ENC8BIT;
++ else
++ /*
++ * Apply maximal encoding regardless of previous
++ * setting. This segment's either not text, or is
++ * unlikely to be readable with > 30% of the
++ * text encoded anyway, so we might as well save space...
++ */
++ new_encoding = ENCBINARY; /* > 30% 8 bit chars */
+ }
+ }
+
+@@ -6791,6 +6795,9 @@
+ value = rfc1522_encode(tmp_20k_buf, (unsigned char *) text,
+ ps_global->VAR_CHAR_SET);
+
++ if (!strcmp(field, "Subject"))
++ value = text;
++
+ if(value && value == text){ /* no encoding was done, have to fold */
+ int fold_by = 75, len;
+ char *actual_field;
+@@ -7111,7 +7118,7 @@
+ break;
+
+ default:
+- q_status_message1(SM_ORDER,3,7,"Unknown header type: %s",pf->name);
++ q_status_message1(SM_ORDER,3,7,"未知的標頭形態:%s",pf->name);
+ break;
+ }
+ }
+@@ -7439,7 +7446,8 @@
+
+ switch (body->encoding) { /* all else needs filtering */
+ case ENC8BIT: /* encode 8BIT into QUOTED-PRINTABLE */
+- gf_link_filter(gf_8bit_qp, NULL);
++ if(F_OFF(F_ENABLE_8BIT, ps_global)) /* unless 8BIT enabled */
++ gf_link_filter(gf_8bit_qp, NULL);
+ break;
+
+ case ENCBINARY: /* encode binary into BASE64 */
+@@ -7453,7 +7461,7 @@
+
+ if(encode_error = gf_pipe(gc, l_putc)){ /* shove body part down pipe */
+ q_status_message1(SM_ORDER | SM_DING, 3, 4,
+- "Encoding Error \"%s\"", encode_error);
++ "編碼時發生錯誤 \"%s\"", encode_error);
+ display_message('x');
+ }
+
+@@ -7506,7 +7514,7 @@
+ sprintf (*dst += strlen (*dst),"Content-Transfer-Encoding: %s\015\012",
+ body_encodings[(body->encoding == ENCBINARY)
+ ? ENCBASE64
+- : (body->encoding == ENC8BIT)
++ : (body->encoding == ENC8BIT && F_OFF(F_ENABLE_8BIT, ps_global))
+ ? ENCQUOTEDPRINTABLE
+ : (body->encoding <= ENCMAX)
+ ? body->encoding : ENCOTHER]);
+@@ -8063,7 +8071,7 @@
+ || (forbid = pine_header_forbidden(name))){
+ if(forbid)
+ q_status_message1(SM_ORDER, 3, 3,
+- "Not allowed to change header \"%s\"", name);
++ "不允許\改變標頭 \"%s\"", name);
+ *t = save;
+ continue;
diff --git a/chinese/pine4/files/patch-be b/chinese/pine4/files/patch-be
index e15dc1315223..d41961817d33 100644
--- a/chinese/pine4/files/patch-be
+++ b/chinese/pine4/files/patch-be
@@ -1,395 +1,38 @@
---- pine/other.c.orig Thu Jul 11 07:05:59 1996
-+++ pine/other.c Sat Jan 17 21:08:31 1998
-@@ -248,8 +248,8 @@
- char prompt[50];
-
- sprintf(prompt,
-- "%s password to LOCK keyboard %s: ",
-- i ? "Retype" : "Enter",
-+ "%s鎖定鍵盤的密碼 %s: ",
-+ i ? "重新輸入" : "輸入",
- i > 1 ? "(Yes, again) " : "");
-
- rc = optionally_enter(pw, -FOOTER_ROWS(ps), 0, 30, 0, 1,
-@@ -506,8 +506,8 @@
- char *rstr = NULL;
- void (*redraw)() = ps_global->redrawer;
- static ESCKEY_S opts[] = {
-- {'y', 'y', "Y", "Yes"},
-- {'n', 'n', "N", "No"},
-+ {'y', 'y', "Y", "是"},
-+ {'n', 'n', "N", "否"},
- {-1, 0, NULL, NULL}
- };
-
-@@ -515,18 +515,18 @@
- fix_windsize(ps_global);
+--- pine/signals.c.orig Tue Jul 7 07:42:45 1998
++++ pine/signals.c Wed Jul 15 17:02:38 1998
+@@ -386,7 +386,7 @@
+ ps_global->inbox_stream->rdonly = 1; /* and become read-only */
+ mail_ping(ps_global->inbox_stream);
+ q_status_message(SM_ASYNC, 3, 7,
+- "Another Pine is accessing Inbox. Session now Read-Only.");
++ "另外一份 Pine 正在存取 Inbox。這個 session 進入唯讀狀態。");
+ dprint(1, (debugfile, "** INBOX went read-only **\n\n"));
+ }
- while(1){
-- rv = radio_buttons("Exit editor and apply changes? ",
-+ rv = radio_buttons("結束編輯並套用改變? ",
- -FOOTER_ROWS(ps_global), opts,
- 'y', 'x', NO_HELP, RB_NORM);
- if(rv == 'y'){ /* user ACCEPTS! */
- break;
- }
- else if(rv == 'n'){ /* Declined! */
-- rstr = "No Changes Saved";
-+ rstr = "改變並未存檔";
- break;
+@@ -398,7 +398,7 @@
+ ps_global->mail_stream->rdonly = 1; /* and become read-only */
+ mail_ping(ps_global->mail_stream);
+ q_status_message(SM_ASYNC, 3, 7,
+- "Another Pine is accessing folder. Session now Read-Only.");
++ "另外一份 Pine 正在存取資料匣。這個 session 進入唯讀狀態。");
+ dprint(1, (debugfile, "** secondary folder went read-only **\n\n"));
+ }
+ }
+@@ -536,7 +536,7 @@
+ int retval = 1;
+
+ dprint(9,(debugfile, "busy_alarm(%d, %s, %p, %d)\n",
+- seconds, msg ? msg : "Busy", pc_func, init_msg));
++ seconds, msg ? msg : "請稍後", pc_func, init_msg));
+
+ /*
+ * If we're already busy'ing, and we don't have something special,
+@@ -560,7 +560,7 @@
+ final_message = 1;
}
- else if(rv == 'x'){ /* Cancelled! */
-- rstr = "Exit Cancelled";
-+ rstr = "取消";
- break;
+ else{
+- strcpy(busy_message, "Busy");
++ strcpy(busy_message, "請稍後");
+ final_message = 0;
}
- }
-@@ -542,39 +542,39 @@
- */
-
- static struct key config_text_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"E","Exit Config",KS_EXITMODE},{"C","[Change Val]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-- {"A","Add Value",KS_NONE}, {"D","Delete Val",KS_NONE},
-- {"Y","prYnt",KS_PRINT}, {"W","WhereIs",KS_WHEREIS}};
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"E","停止設定",KS_EXITMODE},{"C","[修改設定值]",KS_NONE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
-+ {"A","加入設定值",KS_NONE}, {"D","刪除設定值",KS_NONE},
-+ {"Y","列印",KS_PRINT}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(config_text_keymenu, config_text_keys);
-
- static struct key config_checkbox_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"E","Exit Config",KS_EXITMODE},{"X","[Set/Unset]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"E","停止設定",KS_EXITMODE},{"X","[設定/取消設定]",KS_NONE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"Y","prYnt",KS_PRINT}, {"W","WhereIs",KS_WHEREIS}};
-+ {"Y","列印",KS_PRINT}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(config_checkbox_keymenu, config_checkbox_keys);
-
- static struct key config_radiobutton_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"E","Exit Config",KS_EXITMODE},{"*","[Select]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"E","停止設定",KS_EXITMODE},{"*","[選擇]",KS_NONE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"Y","prYnt",KS_PRINT}, {"W","WhereIs",KS_WHEREIS}};
-+ {"Y","列印",KS_PRINT}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(config_radiobutton_keymenu, config_radiobutton_keys);
-
- static struct key config_yesno_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-- {"E","Exit Config",KS_EXITMODE},{"C","[Change]",KS_NONE},
-- {"P","Prev", KS_NONE}, {"N","Next", KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {"E","停止設定",KS_EXITMODE},{"C","[修改]",KS_NONE},
-+ {"P","前一個", KS_NONE}, {"N","後一個", KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"Y","prYnt",KS_PRINT}, {"W","WhereIs",KS_WHEREIS}};
-+ {"Y","列印",KS_PRINT}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(config_yesno_keymenu, config_yesno_keys);
-
- /*
-@@ -1137,21 +1137,21 @@
-
- #ifndef DOS
- static struct key printer_edit_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"Y","prYnt",KS_PRINT},
-- {"E","Exit Config",KS_EXITMODE},{"S","[Select]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"Y","列印",KS_PRINT},
-+ {"E","停止設定",KS_EXITMODE},{"S","[Select]",KS_NONE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {"A","Add Printer",KS_NONE}, {"D","DeletePrint",KS_NONE},
-- {"C","Change",KS_SELECT}, {"W","WhereIs",KS_WHEREIS}};
-+ {"C","Change",KS_SELECT}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(printer_edit_keymenu, printer_edit_keys);
-
- static struct key printer_select_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"Y","prYnt",KS_PRINT},
-- {"E","Exit Config",KS_EXITMODE},{"S","[Select]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"Y","列印",KS_PRINT},
-+ {"E","停止設定",KS_EXITMODE},{"S","[Select]",KS_NONE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {NULL,NULL,KS_NONE}, {"W","WhereIs",KS_WHEREIS}};
-+ {NULL,NULL,KS_NONE}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(printer_select_keymenu, printer_select_keys);
-
- /*
-@@ -1604,12 +1604,12 @@
-
-
- static struct key flag_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {NULL,NULL,KS_NONE},
- {"E","Exit Flags",KS_EXITMODE}, {"X","[Set/Unset]",KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {"Y","prYnt",KS_PRINT}, {"W","WhereIs",KS_WHEREIS}};
-+ {"Y","列印",KS_PRINT}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(flag_keymenu, flag_keys);
-
- /*----------------------------------------------------------------------
-@@ -2139,7 +2139,7 @@
- "%s can't change options or settings",
- ps_global->restricted ? "Pine demo"
- : "Config file not editable,");
-- if(ch == 'e' || ch == PF3){
-+ if(ch == 'e' || ch == PF3 || ch == KEY_LEFT){
- retval = 0;
- done++;
- }
-@@ -2717,7 +2717,7 @@
- }
-
- sprintf(prompt,
-- "Enter text to insert before \"%.*s\": ",k,tmpval);
-+ "鍵入要插在 \"%.*s\" 之前的文字: ",k,tmpval);
- }
- else if((*cl)->var->is_list
- && !(*cl)->var->user_val.l
-@@ -2726,13 +2726,13 @@
- ekey[0].ch = 'r';
- ekey[0].rval = 'r';
- ekey[0].name = "R";
-- ekey[0].label = "Replace";
-+ ekey[0].label = "取代";
- ekey[1].ch = 'a';
- ekey[1].rval = 'a';
- ekey[1].name = "A";
-- ekey[1].label = "Add To";
-+ ekey[1].label = "加至";
- ekey[2].ch = -1;
-- strcpy(prompt, "Replace or Add To default value ? ");
-+ strcpy(prompt, "取代(R)或加至(A)預設值 ? ");
- switch(radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'a', 'x',
- h_config_replace_add, RB_NORM)){
- case 'a':
-@@ -2746,14 +2746,14 @@
- }
-
- add_text:
-- sprintf(prompt, "Enter the %stext to be added : ",
-- flags&CF_NUMBER ? "numeric " : "");
-+ sprintf(prompt, "輸入想加入的%s字 : ",
-+ flags&CF_NUMBER ? "數" : "文");
- break;
-
- case 'r':
- replace_text:
-- sprintf(prompt, "Enter the %sreplacement text : ",
-- flags&CF_NUMBER ? "numeric " : "");
-+ sprintf(prompt, "輸入想取代的%s字 : ",
-+ flags&CF_NUMBER ? "數" : "文");
- break;
-
- case 'x':
-@@ -2763,8 +2763,8 @@
- }
- }
- else
-- sprintf(prompt, "Enter the %stext to be added : ",
-- flags&CF_NUMBER ? "numeric " : "");
-+ sprintf(prompt, "輸入想加入的%s字 : ",
-+ flags&CF_NUMBER ? "數" : "文");
-
- ps->mangled_footer = 1;
- help = NO_HELP;
-@@ -2880,8 +2880,8 @@
- }
-
- sprintf(prompt,
-- "Enter text to insert %s \"%.*s\": ",
-- after ? "after" : "before", k, tmpval);
-+ "輸入想要插在 \"%.*s\" %s的文字: ",
-+ k, tmpval, after ? "之後" : "之前");
- continue;
- }
- else if(i == ctrl('P')){
-@@ -2995,7 +2995,8 @@
- : "<NULL VALUE>",
- (*cl)->var->name);
- else
-- sprintf(prompt, "Really delete %s%.20s from %.30s ",
-+ sprintf(prompt, "確定 自 %.30s 刪除 %s%.20s",
-+ (*cl)->var->name,
- (*cl)->var->is_list ? "item " : "",
- (*cl)->var->is_list
- ? int2string((*cl)->varmem + 1)
-@@ -3003,8 +3004,7 @@
- ? (!*(*cl)->var->user_val.p)
- ? empty_val2
- : (*cl)->var->user_val.p
-- : "<NULL VALUE>",
-- (*cl)->var->name);
-+ : "<NULL VALUE>");
-
- ps->mangled_footer = 1;
- if(want_to(prompt, 'n', 'n', NO_HELP, 0, 1) == 'y'){
-@@ -3213,6 +3213,7 @@
-
- break;
-
-+ /* case KEY_LEFT:*/
- case 'e' : /* exit */
- case PF3 :
- rv = config_exit_cmd(flags);
-@@ -3498,6 +3499,7 @@
-
- break;
-
-+ case KEY_LEFT:
- case 'e' : /* exit */
- case PF3 :
- rv = config_exit_cmd(flags);
-@@ -3542,6 +3544,7 @@
- rv = 1;
- break;
-
-+ case KEY_LEFT:
- case 'e' : /* exit */
- case PF3 :
- rv = flag_exit_cmd(flags);
-@@ -3678,6 +3681,7 @@
-
- break;
-
-+ case KEY_LEFT:
- case 'e' : /* exit */
- case PF3 :
- rv = config_exit_cmd(flags);
-@@ -3749,6 +3753,7 @@
-
- break;
-
-+ case KEY_LEFT:
- case 'e' : /* exit */
- case PF3 :
- rv = config_exit_cmd(flags);
-@@ -3775,6 +3780,7 @@
- struct variable *vtmp;
-
- switch(cmd){
-+ case KEY_LEFT:
- case 'e':
- case PF3:
- retval = config_exit_cmd(flags);
-@@ -3914,20 +3920,20 @@
- int maxwidth = min(80,ps->ttyo->screen_cols) - 15;
-
- if((*cl)->var->user_val.l && (*cl)->value){
-- strcpy(prompt, "Enter printer name : ");
-+ strcpy(prompt, "輸入印表機名稱 : ");
- }
- else if(!(*cl)->var->user_val.l && (*cl)->var->current_val.l){
- /* Add to list which doesn't exist, but default does exist */
- ekey[0].ch = 'r';
- ekey[0].rval = 'r';
- ekey[0].name = "R";
-- ekey[0].label = "Replace";
-+ ekey[0].label = "取代";
- ekey[1].ch = 'a';
- ekey[1].rval = 'a';
- ekey[1].name = "A";
-- ekey[1].label = "Add To";
-+ ekey[1].label = "加至";
- ekey[2].ch = -1;
-- strcpy(prompt, "Replace or Add To default value ? ");
-+ strcpy(prompt, "取代(R)或加至(A)預設值 ? ");
- switch(i = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'a',
- 'x', h_config_replace_add, RB_NORM)){
- case 'a':
-@@ -3951,7 +3957,7 @@
- break;
-
- case 'x':
-- q_status_message(SM_ORDER,0,3,"Add cancelled");
-+ q_status_message(SM_ORDER,0,3,"取消加入的動作");
- break;
- }
-
-@@ -3985,7 +3991,7 @@
- removing_trailing_white_space(name);
- }
- else if(i == 1){
-- q_status_message(SM_ORDER,0,3,"Add cancelled");
-+ q_status_message(SM_ORDER,0,3,"取消加入的動作");
- }
- else if(i == 3){
- help = (help == NO_HELP) ? h_config_insert_after : NO_HELP;
-@@ -4051,7 +4057,7 @@
- "Can't add %s to list", empty_val);
- }
- else if(i == 1){
-- q_status_message(SM_ORDER,0,3,"Add cancelled");
-+ q_status_message(SM_ORDER,0,3,"取消加入的動作");
- }
- else if(i == 3){
- help = help == NO_HELP ? h_config_print_cmd : NO_HELP;
-@@ -4076,7 +4082,7 @@
- if(!(*cl)->var->user_val.l && (*cl)->var->current_val.l){
- char pmt[40];
-
-- sprintf(pmt, "Override default with %s", empty_val2);
-+ sprintf(pmt, "將預設值以 %s 蓋\過", empty_val2);
- if(want_to(pmt, 'n', 'n', NO_HELP, 0, 1) == 'y'){
- char **ltmp;
-
-@@ -4102,7 +4108,7 @@
- fs_give((void **)&p);
- }
- else
-- sprintf(prompt, "Really delete item %.20s from printer list ",
-+ sprintf(prompt, "確定自列印列表中刪除 %.20s ",
- int2string((*cl)->varmem + 1));
-
- ps->mangled_footer = 1;
-@@ -4371,6 +4377,7 @@
-
- break;
-
-+ case KEY_LEFT:
- case 'e': /* exit */
- case PF3:
- rv = config_exit_cmd(flags);
-@@ -5776,12 +5783,12 @@
-
-
- static struct key gripe_keys[] =
-- {{"?","Help",KS_SCREENHELP}, {"^C","Cancel",KS_NONE},
-+ {{"?","輔助說明",KS_SCREENHELP}, {"^C","取消",KS_NONE},
- {NULL,NULL,KS_NONE}, {"S",NULL,KS_NONE},
-- {"P","Prev",KS_NONE}, {"N","Next",KS_NONE},
-- {"-","PrevPage",KS_PREVPAGE}, {"Spc","NextPage",KS_NEXTPAGE},
-+ {"P","前一個",KS_NONE}, {"N","後一個",KS_NONE},
-+ {"-","上一頁",KS_PREVPAGE}, {"Spc","下一頁",KS_NEXTPAGE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
-- {NULL,NULL,KS_NONE}, {"W","WhereIs",KS_WHEREIS}};
-+ {NULL,NULL,KS_NONE}, {"W","搜尋",KS_WHEREIS}};
- INST_KEY_MENU(gripe_keymenu, gripe_keys);
- #define SELECT_KEY 3
diff --git a/chinese/pine4/files/patch-bf b/chinese/pine4/files/patch-bf
index 7cefb4ba2bd3..3511b27d750d 100644
--- a/chinese/pine4/files/patch-bf
+++ b/chinese/pine4/files/patch-bf
@@ -1,142 +1,40 @@
---- pine/pine.c.orig Thu Feb 27 06:50:46 1997
-+++ pine/pine.c Sat Jan 17 21:09:06 1998
-@@ -190,30 +190,30 @@
-
-
- static struct key main_keys[] =
-- {{"?","Help",KS_SCREENHELP},
-- {"O","OTHER CMDS",KS_NONE},
-+ {{"?","說明",KS_SCREENHELP},
-+ {"O","其它命令",KS_NONE},
- {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE},
-- {"P","PrevCmd",KS_NONE},
-- {"N","NextCmd",KS_NONE},
-+ {"P","前一個命令",KS_NONE},
-+ {"N","後一個命令",KS_NONE},
- {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE},
-- {"R","RelNotes",KS_NONE},
-- {"K","KBLock",KS_NONE},
-+ {"R","版權說明",KS_NONE},
-+ {"K","鍵盤鎖定",KS_NONE},
- {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE},
-
-- {"?","Help",KS_SCREENHELP},
-- {"O","OTHER CMDS",KS_NONE},
-- {"Q","Quit",KS_EXIT},
-- {"C","Compose",KS_COMPOSER},
-- {"L","ListFldrs",KS_FLDRLIST},
-- {"G","GotoFldr",KS_GOTOFLDR},
-- {"I","Index",KS_FLDRINDEX},
-+ {"?","說明",KS_SCREENHELP},
-+ {"O","其它命令",KS_NONE},
-+ {"Q","離開",KS_EXIT},
-+ {"C","寫信",KS_COMPOSER},
-+ {"L","列出信件",KS_FLDRLIST},
-+ {"G","進入信件夾",KS_GOTOFLDR},
-+ {"I","索引",KS_FLDRINDEX},
- {"J","Journal",KS_REVIEW},
-- {"S","Setup",KS_NONE},
-- {"A","AddrBook",KS_ADDRBOOK},
-- {"B","Report Bug",KS_NONE},
-+ {"S","設定",KS_NONE},
-+ {"A","地址簿",KS_ADDRBOOK},
-+ {"B","錯誤回報",KS_NONE},
- {NULL,NULL,KS_NONE}};
- INST_KEY_MENU(main_keymenu, main_keys);
- #define MAIN_HELP_KEY 0
-@@ -916,25 +916,25 @@
- unsigned int key; /* alpha key that invokes this action */
- unsigned int keymenu_number; /* index into keymenu array for this cmd */
- } mkeys[] = {
-- {" %s HELP - Get help using Pine",
-+ {" %s 使用說明 - PINE 的使用說明",
- NULL, PF1, '?', MAIN_HELP_KEY},
- {"", NULL, UNUSED, UNUSED, UNUSED},
-- {" %s COMPOSE MESSAGE - Compose and send%s a message",
-+ {" %s 寫信 - 寫信或是發表文章",
- "/post", OPF4, 'C', MAIN_COMPOSE_KEY},
- {"", NULL, UNUSED, UNUSED, UNUSED},
-- {" %s FOLDER INDEX - View messages in current folder",
-+ {" %s 查看信件夾 - 查看目前信件夾內的信件",
- NULL, OPF7, 'I', MAIN_INDEX_KEY},
- {"", NULL, UNUSED, UNUSED, UNUSED},
-- {" %s FOLDER LIST - Select a folder%s to view",
-+ {" %s 信件夾列表 - 列出信件夾或是 NEWS GROUP 以供選擇",
- " OR news group", OPF5, 'L', MAIN_FOLDER_KEY},
- {"", NULL, UNUSED, UNUSED, UNUSED},
-- {" %s ADDRESS BOOK - Update address book",
-+ {" %s 地址簿 - 更新或修改地址簿的內容",
- NULL, OPF10, 'A', MAIN_ADDRESS_KEY},
- {"", NULL, UNUSED, UNUSED, UNUSED},
-- {" %s SETUP - Configure or update Pine",
-+ {" %s 設定 PINE - 設定 PINE 的架構或是內部參數",
- NULL, OPF9, 'S', MAIN_SETUP_KEY},
- {"", NULL, UNUSED, UNUSED, UNUSED},
-- {" %s QUIT - Exit the Pine program",
-+ {" %s 離開 PINE - 結束 PINE 的使用",
- NULL, OPF3, 'Q', MAIN_QUIT_KEY},
- {NULL, NULL, UNUSED, UNUSED, UNUSED}
+--- pine/status.c.orig Sat Jun 27 07:36:34 1998
++++ pine/status.c Wed Jul 15 17:02:38 1998
+@@ -72,7 +72,7 @@
+ static struct key modal_message_keys[] =
+ {NULL_MENU,
+ NULL_MENU,
+- {"Ret","Finished",{MC_EXIT,2,{ctrl('m'),ctrl('j')}},KS_NONE},
++ {"Ret","完畢",{MC_EXIT,2,{ctrl('m'),ctrl('j')}},KS_NONE},
+ NULL_MENU,
+ NULL_MENU,
+ NULL_MENU,
+@@ -931,8 +931,8 @@
+ * want_to's array passed to radio_buttions...
+ */
+ static ESCKEY_S yorn[] = {
+- {'y', 'y', "Y", "Yes"},
+- {'n', 'n', "N", "No"},
++ {'y', 'y', "Y", "是"},
++ {'n', 'n', "N", "否"},
+ {-1, 0, NULL, NULL}
};
-@@ -1103,7 +1103,7 @@
- ch = PF2OPF(ch);
-
- /*----- Validate the command ----*/
-- if(ch == ctrl('M') || ch == ctrl('J') || ch == PF4){
-+ if(ch == ctrl('M') || ch == ctrl('J') || ch == PF4 || ch == KEY_RIGHT){
- ch = F_ON(F_USE_FK,pine_state)
- ? mkeys[current_default_menu_item].f_key
- : mkeys[current_default_menu_item].key;
-@@ -1302,6 +1302,7 @@
- #endif /* !NO_KEYBOARD_LOCK */
-
- /*---------- Quit pine ----------*/
-+ case KEY_LEFT:
- case OPF3:
- case 'q':
- quit_case :
-@@ -1683,11 +1684,11 @@
- {
- char prompt[80];
- char letters[20];
-- char *printer = "Printer";
-- char *passwd = "Newpassword";
-- char *config = "Config";
-- char *update = "Update";
-- char *sigedit = "Signature";
-+ char *printer = "*印表機";
-+ char *passwd = "設定新密碼";
-+ char *config = "環境設定";
-+ char *update = "更新環境";
-+ char *sigedit = "簽名檔";
- HelpType help = h_mini_setup;
- int deefault = 'p';
- int s, ekey_num;
-@@ -1758,13 +1759,13 @@
- }
-
- sprintf(prompt,
-- "Choose a setup task from %s : ",
-- F_ON(F_BLANK_KEYMENU,ps_global) ? letters : "the menu below");
-+ "請從%s選擇你所要設定的工作 :",
-+ F_ON(F_BLANK_KEYMENU,ps_global) ? letters : "下列表單中");
-
- s = radio_buttons(prompt, ql, setup_names, deefault, 'x', help, RB_NORM);
- /* ^C */
- if(s == 'x') {
-- q_status_message(SM_ORDER,0,3,"Setup command cancelled");
-+ q_status_message(SM_ORDER,0,3,"設定指令已取消");
- s = 'e';
- }
-
-@@ -2104,7 +2105,7 @@
- dprint(1, (debugfile, "\n\n ---- QUIT SCREEN ----\n"));
- if(!pine_state->nr_mode && F_OFF(F_QUIT_WO_CONFIRM,pine_state)
-- && want_to("Really quit pine", 'y', 0, NO_HELP, 0, 0) != 'y') {
-+ && want_to("真的要離開本程式嗎?", 'y', 0, NO_HELP, 0, 0) != 'y') {
- pine_state->next_screen = pine_state->prev_screen;
- return;
- }
+@@ -1139,7 +1139,7 @@
+ memset(fkey_table, NO_OP_COMMAND, 12 * sizeof(int));
+ if(help_text != NO_HELP){ /* if shown, always at position 0 */
+ rb_keymenu.keys[0].name = "?";
+- rb_keymenu.keys[0].label = "Help";
++ rb_keymenu.keys[0].label = "輔助說明";
+ setbitn(0, bitmap);
+ fkey_table[0] = ctrl('G');
+ start++;
+@@ -1147,7 +1147,7 @@
+
+ if(on_ctrl_C){ /* if shown, always at position 1 */
+ rb_keymenu.keys[1].name = "^C";
+- rb_keymenu.keys[1].label = "Cancel";
++ rb_keymenu.keys[1].label = "取消";
+ setbitn(1, bitmap);
+ fkey_table[1] = ctrl('C');
+ start++;
diff --git a/chinese/pine4/files/patch-bg b/chinese/pine4/files/patch-bg
index b76ec9708c5f..f8387b0df223 100644
--- a/chinese/pine4/files/patch-bg
+++ b/chinese/pine4/files/patch-bg
@@ -1,11 +1,56 @@
---- pine/screen.c.orig Wed May 8 09:05:40 1996
-+++ pine/screen.c Sat Jan 17 21:09:32 1998
-@@ -380,7 +380,7 @@
+--- pine/takeaddr.c.orig Fri Jun 26 02:26:36 1998
++++ pine/takeaddr.c Wed Jul 15 17:02:38 1998
+@@ -785,7 +785,7 @@
+ return;
+ take_to_addrbooks_cancel:
+- cancel_warning(NO_DING, "addition");
++ cancel_warning(NO_DING, "新增");
+ if(tas && *tas){
+ restore_state(&((*tas)->state));
+ (*tas)->pab = NULL;
+@@ -1267,7 +1267,7 @@
+ break;
- static struct key cancel_keys[] =
-- {{NULL,NULL,KS_NONE}, {"^C","Cancel",KS_NONE},
-+ {{NULL,NULL,KS_NONE}, {"^C","取消",KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
+ case MC_EXIT: /* exit takeaddr screen */
+- cancel_warning(NO_DING, "addition");
++ cancel_warning(NO_DING, "新增");
+ ret = 1;
+ done++;
+ break;
+@@ -2698,7 +2698,7 @@
+
+ switch(j){
+ case 'x':
+- cancel_warning(NO_DING, "save");
++ cancel_warning(NO_DING, "存檔");
+ return;
+
+ case 'e':
+@@ -2798,7 +2798,7 @@
+
+ switch(i){
+ case 'x':
+- cancel_warning(NO_DING, "export");
++ cancel_warning(NO_DING, "匯出");
+ return;
+
+ case 'a':
+@@ -4737,7 +4737,7 @@
+
+ switch(j){
+ case 'x':
+- cancel_warning(NO_DING, "Save");
++ cancel_warning(NO_DING, "存檔");
+ break;
+
+ case 'e':
+@@ -4957,7 +4957,7 @@
+
+ switch(j){
+ case 'x':
+- cancel_warning(NO_DING, "Export");
++ cancel_warning(NO_DING, "匯出");
+ break;
+
+ case 't':
diff --git a/chinese/pine4/files/patch-bh b/chinese/pine4/files/patch-bh
index 6f0e2b76d698..87f51d4e53dd 100644
--- a/chinese/pine4/files/patch-bh
+++ b/chinese/pine4/files/patch-bh
@@ -1,20 +1,52 @@
---- pine/signals.c.orig Wed Jun 5 12:47:21 1996
-+++ pine/signals.c Sat Jan 17 21:23:52 1998
-@@ -493,7 +493,7 @@
- int retval = 1;
+--- build.orig Tue Jun 16 01:35:10 1998
++++ build Wed Jul 15 17:02:29 1998
+@@ -256,11 +256,11 @@
- dprint(9,(debugfile, "busy_alarm(%d, %s, %p, %d)\n",
-- seconds, msg ? msg : "Busy", pc_func, init_msg));
-+ seconds, msg ? msg : "請稍後", pc_func, init_msg));
-
- /*
- * If we're already busy'ing, and we don't have something special,
-@@ -517,7 +517,7 @@
- final_message = 1;
- }
- else{
-- strcpy(busy_message, "Busy");
-+ strcpy(busy_message, "請稍後");
- final_message = 0;
- }
+ if [ -s c-client ] ; then rm -f c-client ; fi
+ ln -s imap/c-client c-client
+- if [ -s mtest ] ; then rm -f mtest ; fi
+- ln -s imap/mtest mtest
+- if [ -s imapd ] ; then rm -f imapd ; fi
+- ln -s imap/imapd imapd
+- echo "Making c-client library, mtest and imapd"
++# if [ -s mtest ] ; then rm -f mtest ; fi
++# ln -s imap/mtest mtest
++# if [ -s imapd ] ; then rm -f imapd ; fi
++# ln -s imap/imapd imapd
++ echo "Making c-client library"
+ eval echo make "$makeargs" "$K1" "$K2" $ccltarg
+ cd $PHOME/imap
+ eval make "$makeargs" "$K1" "$K2" $ccltarg
+@@ -281,14 +281,16 @@
+ cd $PHOME/bin
+ rm -f pine mtest imapd pico pilot
+ if [ -s ../pine/pine ] ; then ln ../pine/pine pine ; fi
+- if [ -s ../mtest/mtest ] ; then ln ../mtest/mtest mtest ; fi
+- if [ -s ../imapd/imapd ] ; then ln ../imapd/imapd imapd ; fi
++# if [ -s ../mtest/mtest ] ; then ln ../mtest/mtest mtest ; fi
++# if [ -s ../imapd/imapd ] ; then ln ../imapd/imapd imapd ; fi
+ if [ -s ../pico/pico ] ; then ln ../pico/pico pico ; fi
+ if [ -s ../pico/pilot ] ; then ln ../pico/pilot pilot ; fi
++ if [ -s ../pico/libpico.so.1.3 ] ;
++ then ln ../pico/libpico.so.1.3 libpico.so.1.3 ; fi
+ cd $PHOME
+ echo ''
+ echo "Links to executables are in bin directory:"
+- size bin/pine bin/mtest bin/imapd bin/pico bin/pilot
++ size bin/pine bin/pico bin/pilot bin/libpico.so.1.3
+ echo "Done"
+ ;;
+@@ -299,10 +301,10 @@
+ make clean
+ echo "Cleaning Pine"
+ cd $PHOME/pine
+- make -f makefile.ult clean
++ make -f makefile.bsf clean
+ echo "Cleaning pico"
+ cd $PHOME/pico
+- make $makeargs -f makefile.ult clean
++ make $makeargs -f makefile.bsf clean
+ echo "Done"
+ cd $PHOME
+ ;;
diff --git a/chinese/pine4/files/patch-bi b/chinese/pine4/files/patch-bi
deleted file mode 100644
index 47bef19c93bd..000000000000
--- a/chinese/pine4/files/patch-bi
+++ /dev/null
@@ -1,31 +0,0 @@
---- pine/status.c.orig Tue Feb 25 05:57:40 1997
-+++ pine/status.c Sat Jan 17 21:24:26 1998
-@@ -829,8 +829,8 @@
- * want_to's array passed to radio_buttions...
- */
- static ESCKEY_S yorn[] = {
-- {'y', 'y', "Y", "Yes"},
-- {'n', 'n', "N", "No"},
-+ {'y', 'y', "Y", "是"},
-+ {'n', 'n', "N", "否"},
- {-1, 0, NULL, NULL}
- };
-
-@@ -1021,7 +1021,7 @@
- memset(fkey_table, NO_OP_COMMAND, 12 * sizeof(int));
- if(help_text != NO_HELP){ /* if shown, always at position 0 */
- rb_keymenu.keys[0].name = "?";
-- rb_keymenu.keys[0].label = "Help";
-+ rb_keymenu.keys[0].label = "輔助說明";
- setbitn(0, bitmap);
- fkey_table[0] = ctrl('G');
- start++;
-@@ -1029,7 +1029,7 @@
-
- if(on_ctrl_C){ /* if shown, always at position 1 */
- rb_keymenu.keys[1].name = "^C";
-- rb_keymenu.keys[1].label = "Cancel";
-+ rb_keymenu.keys[1].label = "取消";
- setbitn(1, bitmap);
- fkey_table[1] = ctrl('C');
- start++;
diff --git a/chinese/pine4/files/patch-bj b/chinese/pine4/files/patch-bj
deleted file mode 100644
index ca71372d9b9f..000000000000
--- a/chinese/pine4/files/patch-bj
+++ /dev/null
@@ -1,13 +0,0 @@
---- pine/ttyin.c.orig Tue Feb 25 05:57:44 1997
-+++ pine/ttyin.c Sat Jan 17 21:25:02 1998
-@@ -1645,8 +1645,8 @@
-
-
- static struct key oe_keys[] =
-- {{"^G","Help",KS_SCREENHELP}, {"^C","Cancel",KS_NONE},
-- {"^T","xxx",KS_NONE}, {"Ret","Accept",KS_NONE},
-+ {{"^G","輔助說明",KS_SCREENHELP}, {"^C","取消",KS_NONE},
-+ {"^T","xxx",KS_NONE}, {"Ret","同意",KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
- {NULL,NULL,KS_NONE}, {NULL,NULL,KS_NONE},
diff --git a/chinese/pine4/files/pine.conf b/chinese/pine4/files/pine.conf
new file mode 100644
index 000000000000..eaca17236393
--- /dev/null
+++ b/chinese/pine4/files/pine.conf
@@ -0,0 +1,43 @@
+# Updated by Pine(tm) 4.00, copyright 1989-1998 University of Washington.
+#
+# Pine configuration file -- customize as needed.
+#
+# This file sets the configuration options used by Pine and PC-Pine. If you
+# are using Pine on a Unix system, there may be a system-wide configuration
+# file which sets the defaults for these variables. There are comments in
+# this file to explain each variable, but if you have questions about
+# specific settings see the section on configuration options in the Pine
+# notes. On Unix, run pine -conf to see how system defaults have been set.
+# For variables that accept multiple values, list elements are separated
+# by commas. A line beginning with a space or tab is considered to be a
+# continuation of the previous line. For a variable to be unset its value
+# must be blank. To set a variable to the empty string its value should
+# be "". You can override system defaults by setting a variable to the
+# empty string. Switch variables are set to either "yes" or "no", and
+# default to "no".
+# Lines beginning with "#" are comments, and ignored by Pine.
+
+############################### Preferences ################################
+
+# List of features; see Pine's Setup/options menu for the current set.
+# e.g. feature-list= select-without-confirm, signature-at-bottom
+# Default condition for all of the features is no-.
+feature-list=enable-8bit-esmtp-negotiation,
+ enable-arrow-navigation
+
+#
+# needed for qmail 1.01 (also compatible with sendmail)
+#smtp-server=localhost
+#
+# needed for qmail 1.03 (also compatible with sendmail)
+inbox-path=$MAIL
+
+# This names the path to an alternative program, and any necessary arguments,
+# to be used in posting mail messages. Example:
+# /usr/lib/sendmail -oem -t -oi
+# or,
+# /usr/local/bin/sendit.sh
+# The latter a script found in Pine distribution's contrib/util directory.
+# NOTE: The program MUST read the message to be posted on standard input,
+# AND operate in the style of sendmail's "-t" option.
+sendmail-path=/usr/sbin/sendmail -oem -oi -t
diff --git a/chinese/pine4/pkg-comment b/chinese/pine4/pkg-comment
index 0784fb8cb833..94e181117777 100644
--- a/chinese/pine4/pkg-comment
+++ b/chinese/pine4/pkg-comment
@@ -1 +1 @@
-Program for Internet E-mail and News with Chinese support
+a Program for Internet News & Email with Chinese(BIG-5) support
diff --git a/chinese/pine4/pkg-descr b/chinese/pine4/pkg-descr
index 1fa7653efe05..72d4ca9d0d5e 100644
--- a/chinese/pine4/pkg-descr
+++ b/chinese/pine4/pkg-descr
@@ -1,12 +1,14 @@
-Pine for FreeBSD 2.x is a tool for reading, sending, and managing
-electronic messages. It was designed specifically with novice
-computer users in mind, but can be tailored to accommodate the needs
-of "power users" as well. Pine uses Internet message protocols (e.g.
-RFC-822, SMTP, MIME, IMAP, NNTP) and runs on Unix and PCs. This
-package also includes the Pico editor, the IMAP daemon, a POP2 server,
-and a POP3 server.
+Pine (Program for Internet News & Email) is a tool for reading, sending,
+and managing electronic messages. It was designed specifically with
+novice computer users in mind, but can be tailored to accommodate the
+needs of "power users" as well. Pine uses Internet message protocols
+(e.g. RFC-822, SMTP, MIME, IMAP, NNTP) and runs on Unix and PCs.
-If you want to use the spell checking feature of pine, set the
+Besides Pine this package includes the Pico editor, the Pilot file browser
+and also the IMAPv4r1 daemon and POP2/POP3 servers (these daemons are not
+built by default).
+
+If you want to use the spell checking feature of Pine, set the
environment variable SPELL to "/usr/local/bin/ispell -l".
An optional configuration file "pine.conf" can be put into /usr/local/etc
diff --git a/chinese/pine4/pkg-plist b/chinese/pine4/pkg-plist
index b08055036b10..9d38f1a6d045 100644
--- a/chinese/pine4/pkg-plist
+++ b/chinese/pine4/pkg-plist
@@ -1,16 +1,16 @@
+bin/pgpencrypt
+bin/pgpdecode
+bin/pgpsign
bin/pico
bin/pilot
bin/pine
+etc/dot.pinerc.pgp.sample
+etc/dot.pinerc.sample
+etc/pine.conf
lib/libpico.so.1.3
@exec /sbin/ldconfig -m %B
@unexec /sbin/ldconfig -R
-bin/pgpencrypt
-bin/pgpdecode
-bin/pgpsign
-etc/dot.pinerc.pgp.sample
-etc/pine.conf.fixed
man/man1/pico.1.gz
man/man1/pilot.1.gz
man/man1/pine.1.gz
share/doc/pine/tech-notes.txt
-@dirrm share/doc/pine