summaryrefslogtreecommitdiff
path: root/chinese/pine4
diff options
context:
space:
mode:
authorVanilla I. Shu <vanilla@FreeBSD.org>1998-07-30 12:30:41 +0000
committerVanilla I. Shu <vanilla@FreeBSD.org>1998-07-30 12:30:41 +0000
commit0a5e44aa586cc7e9c6297a5cc4eb64fb011d7303 (patch)
treef0af86997e5c0c9e0a31463d35992a31a252faae /chinese/pine4
parentUpgrade to 2.1b1. (diff)
Upgrade to 4.02,
Submitted by: maintainer
Notes
Notes: svn path=/head/; revision=12217
Diffstat (limited to 'chinese/pine4')
-rw-r--r--chinese/pine4/Makefile21
-rw-r--r--chinese/pine4/distinfo2
-rw-r--r--chinese/pine4/files/dot.pinerc.sample8
-rw-r--r--chinese/pine4/files/patch-aa37
-rw-r--r--chinese/pine4/files/patch-ab4
-rw-r--r--chinese/pine4/files/patch-ac6
-rw-r--r--chinese/pine4/files/patch-ad4
-rw-r--r--chinese/pine4/files/patch-af2
-rw-r--r--chinese/pine4/files/patch-ag23
-rw-r--r--chinese/pine4/files/patch-ah22
-rw-r--r--chinese/pine4/files/patch-ai2
-rw-r--r--chinese/pine4/files/patch-aj2
-rw-r--r--chinese/pine4/files/patch-ak22
-rw-r--r--chinese/pine4/files/patch-al128
-rw-r--r--chinese/pine4/files/patch-am148
-rw-r--r--chinese/pine4/files/patch-an5436
-rw-r--r--chinese/pine4/files/patch-ao122
-rw-r--r--chinese/pine4/files/patch-ap1338
-rw-r--r--chinese/pine4/files/patch-aq842
-rw-r--r--chinese/pine4/files/patch-ar6672
-rw-r--r--chinese/pine4/files/patch-as118
-rw-r--r--chinese/pine4/files/patch-au963
-rw-r--r--chinese/pine4/files/patch-av1560
-rw-r--r--chinese/pine4/files/patch-aw540
-rw-r--r--chinese/pine4/files/patch-ax77
-rw-r--r--chinese/pine4/files/patch-ay2322
-rw-r--r--chinese/pine4/files/patch-az544
-rw-r--r--chinese/pine4/files/patch-ba497
-rw-r--r--chinese/pine4/files/patch-bb598
-rw-r--r--chinese/pine4/files/patch-bc164
-rw-r--r--chinese/pine4/files/patch-bd2025
-rw-r--r--chinese/pine4/files/patch-be310
-rw-r--r--chinese/pine4/files/patch-bf175
-rw-r--r--chinese/pine4/files/patch-bg209
-rw-r--r--chinese/pine4/files/patch-bh157
-rw-r--r--chinese/pine4/files/patch-bi689
-rw-r--r--chinese/pine4/files/patch-bj38
-rw-r--r--chinese/pine4/files/patch-bk40
-rw-r--r--chinese/pine4/files/patch-bl56
-rw-r--r--chinese/pine4/files/patch-bm52
-rw-r--r--chinese/pine4/files/pine.conf4
-rw-r--r--chinese/pine4/pkg-plist15
42 files changed, 13036 insertions, 12958 deletions
diff --git a/chinese/pine4/Makefile b/chinese/pine4/Makefile
index 1792895ae3aa..179bcf5d5d1e 100644
--- a/chinese/pine4/Makefile
+++ b/chinese/pine4/Makefile
@@ -3,17 +3,18 @@
# Date created: 19 Nov1997
# Whom: Wu Ching-hong <woju@FreeBSD.ee.Ntu.edu.TW>
#
-# $Id: Makefile,v 1.3 1998/07/21 14:11:30 vanilla Exp $
+# $Id: Makefile,v 1.4 1998/07/21 15:27:41 asami Exp $
#
-DISTNAME= pine4.00
-PKGNAME= zh-pine-4.00
+DISTNAME= pine4.02
+PKGNAME= zh-pine-4.02
CATEGORIES= chinese mail news
-MASTER_SITES= ftp://ftp.cac.washington.edu/pine/old/
-EXTRACT_SUFX= .tar.Z
+MASTER_SITES= ftp://ftp.cac.washington.edu/pine/
MAINTAINER= avatar@www.mmlab.cse.yzu.edu.tw
+NO_LATEST_LINK= yes
+
MAN1= pine.1 pico.1 pilot.1
do-build:
@@ -28,17 +29,21 @@ do-install:
${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}/dot.pinerc.pgp.sample \
+ ${PREFIX}/etc/dot.pinerc.pgp.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} -d -o ${SHAREOWN} -g ${SHAREGRP} \
+ ${PREFIX}/share/doc/pine/tech-notes
+ ${INSTALL_DATA} ${WRKSRC}/doc/brochure.txt ${PREFIX}/share/doc/pine
${INSTALL_DATA} ${WRKSRC}/doc/tech-notes.txt ${PREFIX}/share/doc/pine
+ ${INSTALL_DATA} ${WRKSRC}/doc/tech-notes/*.html \
+ ${PREFIX}/share/doc/pine/tech-notes/
.endif
post-install:
diff --git a/chinese/pine4/distinfo b/chinese/pine4/distinfo
index 5624383a91fe..9ddf8a40e7d0 100644
--- a/chinese/pine4/distinfo
+++ b/chinese/pine4/distinfo
@@ -1 +1 @@
-MD5 (pine4.00.tar.Z) = 90fb60b941983218df130fa6e040cbe4
+MD5 (pine4.02.tar.gz) = 688979b5649473169bdbf22ea1c82fe7
diff --git a/chinese/pine4/files/dot.pinerc.sample b/chinese/pine4/files/dot.pinerc.sample
index 9b9ef28749cc..88e352fec011 100644
--- a/chinese/pine4/files/dot.pinerc.sample
+++ b/chinese/pine4/files/dot.pinerc.sample
@@ -23,13 +23,13 @@
personal-name=
# Sets domain part of From: and local addresses in outgoing mail.
-user-domain=brahms.mmlab.cse.yzu.edu.tw
+user-domain=
# List of SMTP servers for sending mail. If blank: Unix Pine uses sendmail.
-smtp-server=brahms.mmlab.cse.yzu.edu.tw
+smtp-server=
# NNTP server for posting news. Also sets news-collections for news reading.
-nntp-server=news.yzu.edu.tw
+nntp-server=
# Path of (local or remote) INBOX, e.g. ={mail.somewhere.edu}inbox
# Normal Unix default is the local INBOX (usually /usr/spool/mail/$USER).
@@ -126,7 +126,7 @@ 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=
+character-set=ISO-8859-1
# Specifies the program invoked by ^_ in the Composer,
# or the "enable-alternate-editor-implicitly" feature.
diff --git a/chinese/pine4/files/patch-aa b/chinese/pine4/files/patch-aa
index 6d30bc5ae927..77e51cdba8ae 100644
--- a/chinese/pine4/files/patch-aa
+++ b/chinese/pine4/files/patch-aa
@@ -1,5 +1,5 @@
---- 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
+--- imap/src/osdep/unix/Makefile.orig Fri Jul 17 03:12:53 1998
++++ imap/src/osdep/unix/Makefile Tue Jul 28 08:34:59 1998
@@ -75,7 +75,7 @@
# Commands possibly overriden by the individual port
@@ -14,38 +14,7 @@
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)
++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 b92d69d2aa96..63666faf4c4a 100644
--- a/chinese/pine4/files/patch-ab
+++ b/chinese/pine4/files/patch-ab
@@ -1,5 +1,5 @@
---- 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
+--- imap/src/osdep/unix/os_bsi.h.orig Sat Jul 11 17:29:33 1998
++++ imap/src/osdep/unix/os_bsi.h Tue Jul 28 08:34:59 1998
@@ -37,7 +37,12 @@
#include <unistd.h>
#include <string.h>
diff --git a/chinese/pine4/files/patch-ac b/chinese/pine4/files/patch-ac
index 019b2b798002..6c7f80761c01 100644
--- a/chinese/pine4/files/patch-ac
+++ b/chinese/pine4/files/patch-ac
@@ -1,6 +1,6 @@
---- 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 @@
+--- imap/src/osdep/unix/unix.c.orig Thu Jul 16 09:52:38 1998
++++ imap/src/osdep/unix/unix.c Tue Jul 28 08:34:59 1998
+@@ -1008,7 +1008,11 @@
/* try again if file exists(?) */
if (!stat (hitch,&sb)) break;
/* punt silently if paranoid site */
diff --git a/chinese/pine4/files/patch-ad b/chinese/pine4/files/patch-ad
index 90b84b4c3253..28c07fa6e437 100644
--- a/chinese/pine4/files/patch-ad
+++ b/chinese/pine4/files/patch-ad
@@ -1,5 +1,5 @@
---- imap/Makefile.orig Wed Apr 29 07:38:46 1998
-+++ imap/Makefile Wed Jul 15 17:02:29 1998
+--- imap/Makefile.orig Thu Jul 16 14:54:19 1998
++++ imap/Makefile Tue Jul 28 08:34:58 1998
@@ -250,12 +250,12 @@
$(TOOLS)/$@ "$(LN)" src/charset c-client
$(LN) `pwd`/src/kerberos/* c-client
diff --git a/chinese/pine4/files/patch-af b/chinese/pine4/files/patch-af
index 5b02a1835d24..7a6b0314be26 100644
--- a/chinese/pine4/files/patch-af
+++ b/chinese/pine4/files/patch-af
@@ -1,5 +1,5 @@
--- 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
++++ pico/osdep/os-bsf.h Tue Jul 28 08:35:00 1998
@@ -23,7 +23,7 @@
#define USE_DIRENT
diff --git a/chinese/pine4/files/patch-ag b/chinese/pine4/files/patch-ag
index b1e3da93a6a2..db69313600dd 100644
--- a/chinese/pine4/files/patch-ag
+++ b/chinese/pine4/files/patch-ag
@@ -1,11 +1,12 @@
---- 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;
-
+--- pico/osdep/term.cap.orig Sat Feb 28 08:14:53 1998
++++ pico/osdep/term.cap Tue Jul 28 08:35:00 1998
+@@ -270,7 +270,8 @@
+ _kppu = tgetstr("kP", &p);
+ _kppd = tgetstr("kN", &p);
+ _kphome = tgetstr("kh", &p);
+- _kpend = tgetstr("kH", &p);
++ if((_kpend = tgetstr("@7", &p)) == NULL)
++ _kpend = tgetstr("kH",&p);
+ _kpdel = tgetstr("kD", &p);
+ _kf1 = tgetstr("k1", &p);
+ _kf2 = tgetstr("k2", &p);
diff --git a/chinese/pine4/files/patch-ah b/chinese/pine4/files/patch-ah
index 32d85be0d037..2451fcb7dcda 100644
--- a/chinese/pine4/files/patch-ah
+++ b/chinese/pine4/files/patch-ah
@@ -1,5 +1,5 @@
---- pico/browse.c.orig Fri May 29 06:39:05 1998
-+++ pico/browse.c Wed Jul 15 17:02:30 1998
+--- pico/browse.c.orig Sat Jul 11 06:41:25 1998
++++ pico/browse.c Tue Jul 28 08:34:59 1998
@@ -126,12 +126,12 @@
@@ -111,7 +111,7 @@
@@ -806,17 +806,17 @@
while(i++ < 2){ /* verify twice!! */
if(i == 1){
- if(fexist(child, "w", (long *)NULL) != FIOSUC)
+ if(fexist(child, "w", (off_t *)NULL) != FIOSUC)
- strcpy(tmp, "File is write protected! OVERRIDE");
+ strcpy(tmp, "檔案為防寫! 要跳過防寫保護");
else
@@ -237,7 +237,7 @@
@@ -995,7 +995,7 @@
sprintf(child, "%s%c%s", gmp->dname, C_FILESEP, tmp);
- if((status = fexist(child, "w", (long *)NULL)) == FIOSUC){
+ if((status = fexist(child, "w", (off_t *)NULL)) == FIOSUC){
- sprintf(tmp,"File \"%.*s\" already exists!",
+ sprintf(tmp,"檔案 \"%.*s\" 已存在!",
NLINE - 20, child);
@@ -307,7 +307,7 @@
@@ -1108,12 +1108,12 @@
sprintf(child, "%s%c%s", gmp->dname, C_FILESEP, tmp);
- if((status = fexist(child, "w", (long *)NULL)) == FIOSUC){
+ if((status = fexist(child, "w", (off_t *)NULL)) == FIOSUC){
- sprintf(tmp,"File \"%.*s\" exists! OVERWRITE",
+ sprintf(tmp,"檔案 \"%.*s\" 已存在! 要覆蓋\嗎",
NLINE - 20, child);
@@ -367,7 +367,7 @@
break;
case FALSE:
@@ -1216,13 +1216,13 @@
- status = fexist(child, "w", (long *)NULL);
+ status = fexist(child, "w", (off_t *)NULL);
if(status == FIOSUC || status == FIOFNF){
if(status == FIOSUC){
- sprintf(tmp,"File \"%.*s\" exists! OVERWRITE",
@@ -507,7 +507,7 @@
zotmaster(&mp);
return(NULL);
}
-@@ -1608,7 +1608,7 @@
+@@ -1610,7 +1610,7 @@
while(nentries--){ /* stat filtered files */
/* get a new cell */
if((ncp=(struct fcell *)malloc(sizeof(struct fcell))) == NULL){
@@ -516,7 +516,7 @@
zotfcells(mp->head); /* clean up cells */
free((char *) filtnames);
free((char *) mp);
-@@ -1778,22 +1778,22 @@
+@@ -1780,22 +1780,22 @@
BrowserKeys()
{
menu_browse[QUIT_KEY].name = (gmode&MDBRONLY) ? "Q" : "E";
@@ -546,7 +546,7 @@
}
wkeyhelp(menu_browse);
-@@ -1896,7 +1896,7 @@
+@@ -1898,7 +1898,7 @@
if((tp = tp->next) == NULL){ /* above top? */
if(secondtry++){
@@ -555,7 +555,7 @@
return(-1);
}
else{
-@@ -2062,10 +2062,10 @@
+@@ -2064,10 +2064,10 @@
if(!p) /* no suitable length! */
p = &dir[l-(term.t_ncol-i-19)];
@@ -568,7 +568,7 @@
if(i < j) /* keep it centered */
j = j - i; /* as long as we can */
-@@ -2194,18 +2194,18 @@
+@@ -2196,18 +2196,18 @@
if((line = (buf[i] == '\n') ? 0 : line + 1) >= LA_LINE_LIMIT
|| !buf[i]){
rv = FALSE;
diff --git a/chinese/pine4/files/patch-ai b/chinese/pine4/files/patch-ai
index de248a4d94ec..a146ad687216 100644
--- a/chinese/pine4/files/patch-ai
+++ b/chinese/pine4/files/patch-ai
@@ -1,5 +1,5 @@
--- pico/composer.c.orig Fri Jul 3 07:00:40 1998
-+++ pico/composer.c Wed Jul 15 17:02:30 1998
++++ pico/composer.c Tue Jul 28 08:34:59 1998
@@ -136,12 +136,12 @@
diff --git a/chinese/pine4/files/patch-aj b/chinese/pine4/files/patch-aj
index 223012340858..f16858a81017 100644
--- a/chinese/pine4/files/patch-aj
+++ b/chinese/pine4/files/patch-aj
@@ -1,5 +1,5 @@
--- pico/display.c.orig Sat Jun 20 01:19:53 1998
-+++ pico/display.c Wed Jul 15 17:02:30 1998
++++ pico/display.c Tue Jul 28 08:34:59 1998
@@ -71,32 +71,32 @@
* Standard pico keymenus...
*/
diff --git a/chinese/pine4/files/patch-ak b/chinese/pine4/files/patch-ak
index dc35ee22e609..64ca1f6f0a5e 100644
--- a/chinese/pine4/files/patch-ak
+++ b/chinese/pine4/files/patch-ak
@@ -1,11 +1,11 @@
---- 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
+--- pico/ebind.h.orig Sat Feb 28 08:10:31 1998
++++ pico/ebind.h Tue Jul 28 08:35:00 1998
+@@ -145,7 +145,7 @@
+ {CTRL|'O', filewrite},
+ {CTRL|'P', backline},
+ {CTRL|'R', insfile},
+-#ifdef SPELLER
++#if defined(SPELLER) && !defined(__FreeBSD__)
+ {CTRL|'T', spell},
+ #endif /* SPELLER */
+ {CTRL|'U', yank},
diff --git a/chinese/pine4/files/patch-al b/chinese/pine4/files/patch-al
index 4d0a775a03f6..d8eecf43fc2b 100644
--- a/chinese/pine4/files/patch-al
+++ b/chinese/pine4/files/patch-al
@@ -1,117 +1,11 @@
---- 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);
- }
-
+--- pico/edef.h.orig Thu Apr 23 07:53:44 1998
++++ pico/edef.h Tue Jul 28 08:35:00 1998
+@@ -59,7 +59,7 @@
+ int ComposerEditing = FALSE; /* TRUE if message line is open */
+ int revexist = FALSE; /* does reverse video exist? */
+ char modecode[] = "WCSEVO"; /* letters to represent modes */
+-long gmode = MDWRAP; /* global editor mode */
++long gmode = MDWRAP | MDTCAPWINS; /* global editor mode */
+ int sgarbf = TRUE; /* TRUE if screen is garbage */
+ int mpresf = FALSE; /* TRUE if message in last line */
+ int clexec = FALSE; /* command line execution flag */
diff --git a/chinese/pine4/files/patch-am b/chinese/pine4/files/patch-am
index be59a33310c6..113499e53a0f 100644
--- a/chinese/pine4/files/patch-am
+++ b/chinese/pine4/files/patch-am
@@ -1,137 +1,11 @@
---- 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;
+--- pico/estruct.h.orig Fri May 29 06:56:52 1998
++++ pico/estruct.h Tue Jul 28 08:35:00 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-an b/chinese/pine4/files/patch-an
index b617d04de358..e499f5e34f5e 100644
--- a/chinese/pine4/files/patch-an
+++ b/chinese/pine4/files/patch-an
@@ -1,5416 +1,20 @@
---- 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);
-+}
-+
-+
+--- pico/main.c.orig Thu Jul 16 16:30:47 1998
++++ pico/main.c Tue Jul 28 08:35:00 1998
+@@ -66,7 +66,7 @@
+ { F9, (CTRL|'K')},
+ { F10, (CTRL|'U')},
+ { F11, (CTRL|'C')},
+-#ifdef SPELLER
++#if defined(SPELLER) && !defined(__FreeBSD__)
+ { F12, (CTRL|'T')}
+ #else
+ { F12, (CTRL|'D')}
+@@ -424,7 +424,7 @@
+ gmode ^= MDSSPD;
+ break;
+ case 'q': /* -q for termcap takes precedence */
+- gmode ^= MDTCAPWINS;
++ gmode |= MDTCAPWINS;
+ break;
+ case 'w': /* -w turn off word wrap */
+ gmode ^= MDWRAP;
diff --git a/chinese/pine4/files/patch-ao b/chinese/pine4/files/patch-ao
index aa19f2338c1d..2e6181be755c 100644
--- a/chinese/pine4/files/patch-ao
+++ b/chinese/pine4/files/patch-ao
@@ -1,11 +1,117 @@
---- 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
+--- pico/pico.c.orig Tue Jul 7 05:41:45 1998
++++ pico/pico.c Tue Jul 28 08:35:00 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-ap b/chinese/pine4/files/patch-ap
index ce5e2d6eb0dd..e63c25c70c12 100644
--- a/chinese/pine4/files/patch-ap
+++ b/chinese/pine4/files/patch-ap
@@ -1,1331 +1,11 @@
---- 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 時發生");
-
+--- pico/pilot.c.orig Thu Jul 16 16:30:46 1998
++++ pico/pilot.c Tue Jul 28 08:35:01 1998
+@@ -222,7 +222,7 @@
+ sup_keyhelp = !sup_keyhelp;
break;
-
-@@ -2923,7 +2923,7 @@
- }
- else
- q_status_message(SM_ORDER | SM_DING, 3, 4,
-- "Can't happen in MC_POPUP");
-+ "無法在 MC_POPUP 時發生");
-
+ case 'q': /* -q for termcap takes precedence */
+- gmode ^= MDTCAPWINS;
++ gmode |= MDTCAPWINS;
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;
- }
- }
+ case 'z': /* -z to suspend */
+ gmode ^= MDSSPD;
diff --git a/chinese/pine4/files/patch-aq b/chinese/pine4/files/patch-aq
index a014d6f16518..1764b9e8a450 100644
--- a/chinese/pine4/files/patch-aq
+++ b/chinese/pine4/files/patch-aq
@@ -1,693 +1,165 @@
---- 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";
-+ "動作取消:系統管理員不允許\改變整體的地址簿設定";
+--- pico/search.c.orig Fri Jun 26 05:48:14 1998
++++ pico/search.c Tue Jul 28 08:35:01 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;
+
+@@ -263,12 +263,12 @@
+ (*term.t_rev)(0);
+
+ if (repl_all)
+- strcpy(prompt, "Replace every \"");
++ strcpy(prompt, "取代每一個 \"");
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;
+- strcpy(prompt, "Replace \"");
++ strcpy(prompt, "取代 \"");
+
+ expandp(&defpat[0], &prompt[strlen(prompt)], NPAT/2);
+- strcat(prompt, "\" with");
++ strcat(prompt, "\" 為");
+ if(rpat[0] != 0){
+ strcat(prompt, " [");
+ expandp(rpat, &prompt[strlen(prompt)], NPAT/2);
+@@ -286,9 +286,9 @@
+ case HELPCH: /* help requested */
+ if(Pmaster)
+ (*Pmaster->helper)(Pmaster->search_help,
+- "Help for Searching", 1);
++ "搜尋的輔助說明", 1);
+ else
+- pico_help(SearchHelpText, "Help for Searching", 1);
++ pico_help(SearchHelpText, "搜尋的輔助說明", 1);
+
+ case (CTRL|'L'): /* redraw requested */
+ refresh(FALSE, 1);
+@@ -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 = "取代一個";
}
-@@ -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 @@
+ 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
-- 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;
+- emlwrite("No more matches for \"%s\"", orig);
++ emlwrite("沒有符合 \"%s\" 的字串了", orig);
+ return (FALSE);
}
}
-@@ -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("取消");
- }
-
-
+@@ -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-ar b/chinese/pine4/files/patch-ar
index d70d02915af1..60458238b332 100644
--- a/chinese/pine4/files/patch-ar
+++ b/chinese/pine4/files/patch-ar
@@ -1,1260 +1,5416 @@
---- 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++;
+--- pine/osdep/os-bsf.c.orig Tue Jul 28 08:35:04 1998
++++ pine/osdep/os-bsf.c Tue Jul 28 08:35:05 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((n = folder_lister_prev(fs)) >= 0)
- fs->folder_index = n;
++
++ 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 %.50s%susing \"%.50s\" ? ",
++ desc ? desc : "",
++ (desc && *desc && desc[strlen(desc) - 1] != ' ') ? " " : "",
++ *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
-+ 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){
++ _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-as b/chinese/pine4/files/patch-as
index 50e97fc0e63d..4bc85d6e567c 100644
--- a/chinese/pine4/files/patch-as
+++ b/chinese/pine4/files/patch-as
@@ -1,101 +1,31 @@
---- 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 @@
+--- pine/osdep/os-bsf.h.orig Fri Jun 26 14:19:54 1998
++++ pine/osdep/os-bsf.h Tue Jul 28 08:35:05 1998
+@@ -87,7 +87,7 @@
+ 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 */
++#define BACKGROUND_POST /* comment out to disable posting from child */
- 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 @@
- }
- if(!sargs.bar.title)
-- sargs.bar.title = "HELP TEXT";
-+ sargs.bar.title = "輔助說明文字";
- }
- 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 @@
- }
+@@ -219,7 +219,9 @@
+ /*----------------------------------------------------------------------
+ If no nntp-servers are defined, this program will be used to post news.
+ ----*/
+-#define SENDNEWS "/usr/local/news/inews -h" /* news posting cmd */
++#define SENDNEWS "/usr/local/news/lib/inews -h" /* For NN inews */
++/*#define SENDNEWS "/usr/local/bin/inews -h" /* For INN inews */
++/*#define SENDNEWS "/usr/local/bin/inews -h" /* For Cnews inews */
- 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 = "[檢視連結]";
- }
- }
-@@ -559,7 +559,7 @@
- #endif
- if(ps_global->intr_pending){
- q_status_message(SM_ORDER, 3, 3,
-- "Print of all help cancelled");
-+ "取消列印所有的輔助說明");
- break;
- }
+ /*--------- Program employed by users to change their password ---------*/
+@@ -268,7 +270,7 @@
+ 8
+ 9 logs gross details of command execution
+ ----*/
+-#define DEFAULT_DEBUG 2
++#define DEFAULT_DEBUG 0
+
-@@ -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 9cb237ecf3fd..d3c20205d920 100644
--- a/chinese/pine4/files/patch-au
+++ b/chinese/pine4/files/patch-au
@@ -1,326 +1,695 @@
---- 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[] =
+--- pine/adrbkcmd.c.orig Sat Jul 11 01:32:16 1998
++++ pine/adrbkcmd.c Tue Jul 28 08:35:01 1998
+@@ -112,23 +112,23 @@
+ static struct key abook_view_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 @@
+- {"<","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,
-- {":","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,
+- {"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,
-@@ -175,9 +175,9 @@
-
- static struct key simple_index_keys[] =
+@@ -144,7 +144,7 @@
+ static struct key abook_text_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 @@
+- {"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",
+- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
++ 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",
+- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
++ 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)();
{
- 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;
- }
+- return(pico_cancelexit_for_adrbk("take", redraw_pico));
++ return(pico_cancelexit_for_adrbk("擷取", redraw_pico));
+ }
-@@ -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);
+
+@@ -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;
}
-@@ -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;
+ 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;
}
- 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;
+@@ -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 ? "修改" : "新增");
}
-@@ -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 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{
- 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 @@
+
+@@ -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}};
- if(rc == 1 || (new_string[0] == '\0' && search_string[0] == '\0')) {
-- cmd_cancelled("Search");
-+ cmd_cancelled("搜尋");
- return;
+ 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 = "下移";
-@@ -3080,21 +3081,21 @@
+ 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("動作取消:系統管理員不允許\改變地址簿設定");
- 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.":"");
+ return -1;
}
- 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));
+
+ 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;
}
- 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);
+@@ -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 = "完成";
}
- 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));
+
+ 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);
}
- 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);
+
+@@ -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("取消");
+ }
+
-@@ -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 fd3084b81bcf..8abda44e81ef 100644
--- a/chinese/pine4/files/patch-av
+++ b/chinese/pine4/files/patch-av
@@ -1,307 +1,1319 @@
---- 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 @@
+--- pine/folder.c.orig Wed Jul 22 06:01:07 1998
++++ pine/folder.c Tue Jul 28 08:35:02 1998
+@@ -62,13 +62,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)
+
+@@ -269,18 +269,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,
- {"<",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},
+- {"<", "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,
+@@ -312,15 +312,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,
- 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},
+- {"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,
-@@ -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[] =
+@@ -339,9 +339,9 @@
+
+ static struct key context_select_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},
+- {"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,
+@@ -355,9 +355,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,
+@@ -372,16 +372,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,
-@@ -194,7 +194,7 @@
- BOUNCE_MENU,
- NULL_MENU,
+- {"R","Rename",{MC_RENAMEFLDR,1,{'r'}}, KS_NONE},
++ {"R","更名",{MC_RENAMEFLDR,1,{'r'}}, KS_NONE},
WHEREIS_MENU,
-- {"%", "Print", MC_PRINTMSG,1,{'%'}, KS_PRINT},
-+ {"%", "列印", MC_PRINTMSG,1,{'%'}, KS_PRINT},
+
+ HELP_MENU,
+@@ -393,9 +393,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
+@@ -407,9 +407,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,
+@@ -423,9 +423,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,
- 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 = "匯出";
+- {"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,
+@@ -439,9 +439,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,
+@@ -457,9 +457,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,
+@@ -476,8 +476,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,
+@@ -572,12 +572,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;
+
+@@ -866,7 +866,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);
+ }
+
+@@ -965,12 +965,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;
+
+@@ -1041,7 +1041,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,
+@@ -1277,10 +1277,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 */
+@@ -1312,7 +1312,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);
+@@ -1429,7 +1429,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
+@@ -1444,7 +1444,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);
+ }
+@@ -1457,7 +1457,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);
+ }
+
+@@ -1572,7 +1572,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;
+@@ -1682,7 +1682,7 @@
+ km.keys[KM_MAIN_KEY].bind.cmd = MC_NONE;
+ km.keys[KM_MAIN_KEY].bind.nch = 0;
+
+- 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';
+ }
+@@ -1702,14 +1702,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';
+ }
+@@ -1723,7 +1723,7 @@
}
- 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, "已經到最後一附件了");
+ 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')}},
+@@ -1849,8 +1849,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;
+
+@@ -1858,6 +1865,7 @@
+ /*--------------------- Key right -------------------*/
+ case MC_CHARRIGHT :
+ case MC_NEXTITEM :
++ exit_to_main = 0;
+ if(n = folder_lister_next(fs))
+ fs->folder_index = n;
+
+@@ -1879,7 +1887,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;
+@@ -1925,7 +1933,7 @@
+ FOLDERS(fs->context))->d_line + 1;
-@@ -632,7 +632,7 @@
- if(ctmp = prev_attline(current))
- current = ctmp;
+ if(rc > fs->last_row){
+- q_status_message(SM_ORDER, 0, 1, "Already on last line.");
++ q_status_message(SM_ORDER, 0, 1, "已經到最後一行了。");
+ break;
+ }
+
+@@ -2044,7 +2052,7 @@
+ rc++;
+ }
else
-- q_status_message(SM_ORDER, 0, 1, "Already on first attachment");
-+ q_status_message(SM_ORDER, 0, 1, "已經到第一個附件了");
+- q_status_message(SM_ORDER,0,1,"Already on first page.");
++ q_status_message(SM_ORDER,0,1,"已經到第一頁了。");
+
+ break;
+
+@@ -2057,7 +2065,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
+@@ -2098,7 +2106,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Sorry, no help text available");
++ "很抱歉,文字說明無法取得");
break;
-@@ -646,7 +646,7 @@
+@@ -2107,7 +2115,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++;
+@@ -2169,7 +2177,7 @@
+ mangled_footer++;
}
else
- q_status_message(SM_ORDER, 0, 1,
-- "Already on last page of attachments");
-+ "已經在附件的最後一頁了");
-
+- q_status_message(SM_ORDER, 0, 4, "Already in List Mode");
++ q_status_message(SM_ORDER, 0, 4, "已經在列表模式了。");
break;
-@@ -667,7 +667,7 @@
+
+@@ -2302,8 +2310,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;
+ }
+
+@@ -2381,13 +2389,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);
+@@ -2395,7 +2403,7 @@
}
else
- q_status_message(SM_ORDER, 0, 1,
-- "Already on first page of attachments");
-+ "已經在附件的第一頁了");
+ q_status_message(SM_ORDER, 0, 3,
+- "No selected folders to Zoom on");
++ "尚未選擇供放大的資料匣。");
+
break;
+@@ -2405,16 +2413,16 @@
+ case MC_WHEREIS :
+ switch(search_folders(fs, -FOOTER_ROWS(ps))){
+ case -1 :
+- cmd_cancelled("Folder name search");
++ cmd_cancelled("搜尋檔案匣名稱");
+ 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) */
-
-@@ -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 = "完成";
- }
-
- 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) ? " 試試存檔。" : "");
+ 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;
+ }
+
+@@ -2475,8 +2483,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);
+ }
+
+@@ -2497,8 +2505,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);
+ }
+
+@@ -2513,7 +2521,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{
+@@ -2523,7 +2531,7 @@
+ }
+ else{
+ if(f->isdir){
+- q_status_message(SM_ORDER, 0, 3, "Can't select directories");
++ q_status_message(SM_ORDER, 0, 3, "無法選擇目錄");
+ }
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 = "信件文字";
+ folder_select_toggle(fs, f);
+@@ -2580,13 +2588,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)){
+@@ -2611,7 +2619,7 @@
+
+ default :
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Unsupported Select option");
++ "未支援的選項");
+ return(0);
+ }
+ }
+@@ -2625,7 +2633,7 @@
+ */
+ switch(q){
+ case 'x': /* cancel */
+- cmd_cancelled("Select command");
++ cmd_cancelled("選取命令");
+ return(0);
+
+ case 'c' : /* toggle current's selected state */
+@@ -2647,10 +2655,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 */
+@@ -2667,7 +2675,7 @@
+
+ default :
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Unsupported Select option");
++ "未支援的選項");
+ return(0);
+ }
+
+@@ -2696,35 +2704,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{
-- 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,
+ 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, " ");
+@@ -2839,7 +2842,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))
+@@ -2860,9 +2863,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
+@@ -2908,12 +2911,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++;
+ }
+@@ -3479,12 +3482,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);
+ }
+
+@@ -3506,7 +3509,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;
+@@ -3524,7 +3527,7 @@
+ }
+ else if(rc == 1){
+ q_status_message(SM_ORDER,0,2,
+- "Addition of new folder cancelled");
++ "取消新增資料匣");
+ return(FALSE);
+ }
+ else if(rc == 0)
+@@ -3534,7 +3537,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];
+
+@@ -3543,7 +3546,7 @@
+ add_folder[++offset] = '\0'; /* +2, total */
+ }
+ else
+- sprintf(tmp, "Folder name to add : ");
++ sprintf(tmp, "新增資料匣名稱:");
+
+ help = NO_HELP;
+ while(1){
+@@ -3551,14 +3554,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;
+@@ -3572,7 +3575,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;
+@@ -3582,7 +3585,7 @@
+ ;/* do nothing */
+
+ q_status_message1(SM_ORDER,3,3,
+- "Config feature \"%s\" enables names beginning with dot",
++ "設定檔中 \"%s\" 的功\能可使資料匣以點 \".\" 為名稱開頭",
+ feat && feat->name ? feat->name : "");
+ }
+
+@@ -3602,7 +3605,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;
+ }
+@@ -3624,7 +3627,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);
+ }
+ }
+@@ -3643,7 +3646,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;
+
+@@ -3664,7 +3667,7 @@
+ }
+ else if(rc == 1 || (rc != 3 && !*nickname)){
+ q_status_message(SM_ORDER,0,2,
+- "Addition of new folder cancelled");
++ "取消新增資料匣");
+ return(FALSE);
+ }
+ }
+@@ -3679,7 +3682,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);
+ }
+@@ -3732,7 +3735,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)){
+@@ -3748,15 +3751,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);
+@@ -3795,13 +3798,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;
+@@ -3861,7 +3864,7 @@
+ }
+ else{
+ q_status_message(SM_ORDER, 0, 2,
+- "No group substring to match! Use ^T to list all news groups.");
++ "沒有符合的組群字串!請用 ^T 列出所有新聞組群。");
+ continue;
+ }
+
+@@ -3914,10 +3917,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;
+@@ -3965,7 +3968,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 -----*/
+@@ -3987,7 +3990,7 @@
+ */
+ q_status_message1(errors ?SM_INFO : SM_ORDER,
+ errors ? 0 : 3, 3,
+- "Error subscribing to \"%s\"",
++ "訂閱\至 \"%s\" 時發生錯誤",
+ (char *) flp->text.data);
+ errors++;
+ }
+@@ -4011,13 +4014,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);
+@@ -4026,7 +4029,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 -----*/
+@@ -4040,7 +4043,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);
+@@ -4080,19 +4083,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);
+@@ -4108,11 +4111,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) {
+@@ -4133,7 +4136,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;
+@@ -4143,7 +4146,7 @@
+ ;/* do nothing */
+
+ q_status_message1(SM_ORDER,3,3,
+- "Config feature \"%s\" enables names beginning with dot",
++ "設定檔中 \"%s\" 的功\能可使資料匣以點 \".\" 為名稱開頭",
+ feat && feat->name ? feat->name : "");
+ }
+
+@@ -4153,13 +4156,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;
+@@ -4182,7 +4185,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);
+ }
+
+@@ -4264,7 +4267,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,
+@@ -4275,7 +4278,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));
+@@ -4283,7 +4286,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 */
+@@ -4332,7 +4335,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") */
+@@ -4354,7 +4357,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);
+ }
+
+@@ -4372,7 +4375,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);
+ }
+
+@@ -4382,12 +4385,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
+@@ -4402,7 +4405,7 @@
+
+ if(ret){
+ q_status_message1(SM_ORDER | SM_DING, 3, 4,
+- "Can't delete non-empty directory \"%s\".",
++ "無法刪除非空的目錄 \"%s\"。",
+ folder);
+ return(0);
+ }
+@@ -4413,19 +4416,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)){
+@@ -4434,7 +4437,7 @@
+ break;
+
+ case 'x' :
+- cmd_cancelled("Delete");
++ cmd_cancelled("刪除");
+ return(0);
+
+ default :
+@@ -4442,13 +4445,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);
+ }
+ }
+@@ -4491,13 +4494,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){
+@@ -4642,7 +4645,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;
+@@ -4658,7 +4661,7 @@
+ return(1);
+
+ case 1 :
+- cmd_cancelled("Select");
++ cmd_cancelled("選擇");
+
+ default :
+ return(0);
+@@ -4734,7 +4737,7 @@
+ return(1);
+ }
+
+- cmd_cancelled("Select");
++ cmd_cancelled("選擇");
+ return(0);
+ }
+
+@@ -4767,7 +4770,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 */
+@@ -4910,7 +4913,7 @@
+ return(1);
+ }
+
+- cmd_cancelled("Select");
++ cmd_cancelled("選擇");
+ return(0);
+ }
+
+@@ -4932,7 +4935,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){
+@@ -4941,7 +4944,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 */
+
+@@ -5102,7 +5105,7 @@
+ for(; i >= 0; i--)
+ folder_entry(i, FOLDERS(fs->context))->scanned = 0;
+
+- cmd_cancelled("Select");
++ cmd_cancelled("選擇");
+ rv = 0;
+ break;
+ }
+@@ -5147,14 +5150,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{
+@@ -5162,7 +5165,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;
+@@ -5173,7 +5176,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') ? "" : "] ");
+@@ -5184,7 +5187,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 ------*/
+@@ -5241,9 +5244,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! */
+ }
+
+@@ -5257,14 +5260,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 :
+@@ -6273,7 +6276,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);
+@@ -6314,14 +6317,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");
+ }
+@@ -7503,7 +7506,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-aw b/chinese/pine4/files/patch-aw
index 0a1a789a468f..ac9fa6d8cd01 100644
--- a/chinese/pine4/files/patch-aw
+++ b/chinese/pine4/files/patch-aw
@@ -1,477 +1,101 @@
---- 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,
+--- pine/help.c.orig Wed Jul 1 06:22:26 1998
++++ pine/help.c Tue Jul 28 08:35:02 1998
+@@ -50,15 +50,15 @@
+
+ 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,
-- {"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,
+ PRYNTMSG_MENU,
+- {"Z","Print All",{MC_PRINTALL,1,{'z'}},KS_NONE},
++ {"Z","列印全部",{MC_PRINTALL,1,{'z'}},KS_NONE},
NULL_MENU,
-- {"E","Exit Viewer",{MC_EXIT,1,{'e'}},KS_NONE},
-+ {"E","離開",{MC_EXIT,1,{'e'}},KS_NONE},
+ 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,
-@@ -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
- 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);
+ 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 @@
+ }
+
+ if(!sargs.bar.title)
+- sargs.bar.title = "HELP TEXT";
++ sargs.bar.title = "輔助說明文字";
}
-@@ -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;
+ 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{
-@@ -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);
- }
+ 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 @@
}
-@@ -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");
-+ "未經證實的新聞組群標頭 -- 訊息可能從未被張貼");
+ 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 = "[檢視連結]";
}
+ }
- 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));
+@@ -559,7 +559,7 @@
+ #endif
+ if(ps_global->intr_pending){
+ q_status_message(SM_ORDER, 3, 3,
+- "Print of all help cancelled");
++ "取消列印所有的輔助說明");
+ break;
}
-@@ -4805,7 +4805,7 @@
- }
-
- q_status_message(SM_ORDER, 0, 1,
-- "Already on last selectable item");
-+ "已經在最後一個可選擇的項目上");
+@@ -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
}
-
- break;
-@@ -4835,7 +4835,7 @@
- }
-
- q_status_message(SM_ORDER, 0, 1,
-- "Already on first selectable item");
-+ "已經在第一個可選擇的項目上");
+ else if(ch == 'x'){
+- q_status_message(SM_ORDER, 0, 3, "Bug report cancelled.");
++ q_status_message(SM_ORDER, 0, 3, "取消錯誤回報。");
+ return(-1);
}
-
- 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 026ac2e73d0f..9c619dd3c144 100644
--- a/chinese/pine4/files/patch-ax
+++ b/chinese/pine4/files/patch-ax
@@ -1,65 +1,12 @@
---- 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[] = { "關於",
-+ "有關"
- };
-
- 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]);
+--- pine/init.c.orig Fri Jul 17 02:22:22 1998
++++ pine/init.c Tue Jul 28 08:35:02 1998
+@@ -579,6 +579,9 @@
+ GLO_SMTP_SERVER = parse_list(DF_SMTP_SERVER, 1, NULL);
+ #endif
+
++ F_TURN_ON(F_TCAP_WINS,ps);
++ F_TURN_ON(F_QUELL_INTERNAL_MSG,ps);
++
+ /* Set the default mail directory */
+ build_path(buf, GLO_MAIL_DIRECTORY, "[]");
+ GLO_FOLDER_SPEC = parse_list(buf, 1, NULL);
diff --git a/chinese/pine4/files/patch-ay b/chinese/pine4/files/patch-ay
index 716ebc651ea0..9b6456497a7a 100644
--- a/chinese/pine4/files/patch-ay
+++ b/chinese/pine4/files/patch-ay
@@ -1,1468 +1,1044 @@
---- 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);
+--- pine/mailcmd.c.orig Fri Jul 17 13:57:21 1998
++++ pine/mailcmd.c Tue Jul 28 08:35:03 1998
+@@ -110,39 +110,39 @@
+ /*
+ * List of Select options used by apply_* functions...
+ */
+-static char *sel_pmt1 = "ALTER message selection : ";
++static char *sel_pmt1 = "更改信件的選擇:";
+ ESCKEY_S sel_opts1[] = {
+- {'a', 'a', "A", "unselect All"},
++ {'a', 'a', "A", "取消所有選擇"},
+ {'c', '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}
+ };
+
+
+-char *sel_pmt2 = "SELECT criteria : ";
++char *sel_pmt2 = "選擇標準:";
+ static ESCKEY_S sel_opts2[] = {
+- {'a', 'a', "A", "select All"},
+- {'c', 'c', "C", "select Cur"},
+- {'n', 'n', "N", "Number"},
+- {'d', 'd', "D", "Date"},
+- {'t', 't', "T", "Text"},
+- {'s', 's', "S", "Status"},
++ {'a', 'a', "A", "選擇所有"},
++ {'c', 'c', "C", "選擇目前的"},
++ {'n', 'n', "N", "數目"},
++ {'d', 'd', "D", "日期"},
++ {'t', 't', "T", "文字"},
++ {'s', 's', "S", "狀態"},
+ {-1, 0, NULL, NULL}
+ };
+
+
+-static char *sel_pmt3 = "APPLY command : ";
++static char *sel_pmt3 = "套用命令:";
+ static ESCKEY_S sel_opts3[] = {
+- {'d', 'd', "D", "Del"},
+- {'u', 'u', "U", "Undel"},
+- {'r', 'r', "R", "Reply"},
+- {'f', 'f', "F", "Forward"},
+- {'%', '%', "%", "Print"},
+- {'t', 't', "T", "TakeAddr"},
+- {'s', 's', "S", "Save"},
+- {'e', 'e', "E", "Export"},
++ {'d', 'd', "D", "刪除"},
++ {'u', 'u', "U", "復原刪除"},
++ {'r', 'r', "R", "回覆"},
++ {'f', 'f', "F", "轉寄"},
++ {'%', '%', "%", "列印"},
++ {'t', 't', "T", "地址簿"},
++ {'s', 's', "S", "存檔"},
++ {'e', 'e', "E", "匯出"},
+ { -1, 0, NULL, NULL},
+ { -1, 0, NULL, NULL},
+ { -1, 0, NULL, NULL},
+@@ -152,24 +152,24 @@
+
+
+ static char *sel_flag =
+- "Select New, Deleted, Answered, or Important messages ? ";
++ "選擇 新的,已刪除的,已回覆的,或重要的信件?";
+ static char *sel_flag_not =
+- "Select NOT New, NOT Deleted, NOT Answered or NOT Tagged msgs ? ";
++ "選擇 非新的,非已刪除的,非已回覆的,或非被標記的信件?";
+ static ESCKEY_S sel_flag_opt[] = {
+- {'n', 'n', "N", "New"},
+- {'*', '*', "*", "Important"},
+- {'d', 'd', "D", "Deleted"},
+- {'a', 'a', "A", "Answered"},
+- {'!', '!', "!", "Not"},
++ {'n', 'n', "N", "新的"},
++ {'*', '*', "*", "重要的"},
++ {'d', 'd', "D", "已刪除的"},
++ {'a', 'a', "A", "已回覆的"},
++ {'!', '!', "!", "非"},
+ {-1, 0, NULL, NULL}
+ };
+
+
+ static ESCKEY_S sel_date_opt[] = {
+ {0, 0, NULL, NULL},
+- {ctrl('P'), 12, "^P", "Prev Day"},
+- {ctrl('N'), 13, "^N", "Next Day"},
+- {ctrl('X'), 11, "^X", "Cur Msg"},
++ {ctrl('P'), 12, "^P", "前一天"},
++ {ctrl('N'), 13, "^N", "後一天"},
++ {ctrl('X'), 11, "^X", "目前的"},
+ {ctrl('W'), 14, "^W", "Toggle When"},
+ {KEY_UP, 12, "", ""},
+ {KEY_DOWN, 13, "", ""},
+@@ -179,18 +179,18 @@
+
+ static char *sel_text =
+ #ifdef RECIPIENT
+- "Select based on To, From, Cc, Recip, Subject fields or All message text ? ";
++ "選擇以 收件人,寄件人,副本,領受者,主題 等欄位為主,或所有的訊息文字?";
+ #else /* RECIPIENT */
+- "Select based on To, From, Cc, Subject fields or All message text ? ";
++ "選擇以 收件人,寄件人,副本,主題 等欄位為主,或所有的訊息文字?";
+ #endif /* RECIPIENT */
+ static ESCKEY_S sel_text_opt[] = {
+- {'f', 'f', "F", "From"},
+- {'s', 's', "S", "Subject"},
+- {'t', 't', "T", "To"},
+- {'a', 'a', "A", "All Text"},
+- {'c', 'c', "C", "Cc"},
++ {'f', 'f', "F", "寄件人"},
++ {'s', 's', "S", "主題"},
++ {'t', 't', "T", "收件人"},
++ {'a', 'a', "A", "所有的訊息文字"},
++ {'c', 'c', "C", "副本"},
+ #ifdef RECIPIENT
+- {'r', 'r', "R", "Recipient"},
++ {'r', 'r', "R", "領受者"},
+ #endif /* RECIPIENT */
+ {-1, 0, NULL, NULL}
+ };
+@@ -244,7 +244,7 @@
+ case MC_HELP :
+ if(state->nr_mode) {
+ q_status_message(SM_ORDER, 0, 3,
+- "No help text currently available");
++ "目前無法取得文字說明");
+ break;
+ }
+
+@@ -273,7 +273,7 @@
+
+ /*------- View message text --------*/
+ case MC_VIEW_TEXT :
+- if(any_messages(msgmap, NULL, "to View")){
++ if(any_messages(msgmap, NULL, "可供檢視")){
+ state->next_screen = mail_view_screen;
+ #if defined(DOS) && !defined(WIN32)
+ flush_index_cache(); /* save room on PC */
+@@ -297,10 +297,10 @@
+ mn_dec_cur(stream, msgmap);
+ if(i == mn_get_cur(msgmap))
+ q_status_message(SM_ORDER, 0, 2,
+- "Already on first message in Zoomed Index");
++ "已經到縮放索引中的第一封訊息了");
}
- 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);
+ else
+- q_status_message(SM_ORDER, 0, 1, "Already on first message");
++ q_status_message(SM_ORDER, 0, 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);
- }
+ break;
+@@ -312,7 +312,7 @@
+ && (i = mn_get_cur(msgmap)) < mn_get_total(msgmap)){
+ mn_inc_cur(stream, msgmap);
+ if(i == mn_get_cur(msgmap))
+- any_messages(NULL, "more", "in Zoomed Index");
++ any_messages(NULL, "更多的", "在可縮放索引中");
+ }
+ else{
+ prompt[0] = '\0';
+@@ -329,7 +329,7 @@
+ strcat(prompt, ". No more folders to TAB to.");
+ }
-@@ -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);
- }
+- any_messages(NULL, (mn_get_total(msgmap) > 0L) ? "more" : NULL,
++ any_messages(NULL, (mn_get_total(msgmap) > 0L) ? "更多的" : NULL,
+ prompt[0] ? prompt : NULL);
-@@ -412,7 +412,7 @@
- PICO pbuf;
+ if(!IS_NEWS(stream))
+@@ -474,9 +474,9 @@
+ }
+ }
+ else
+- q_status_message1(SM_ORDER, 0, 2, "No more %ss",
++ q_status_message1(SM_ORDER, 0, 2, "沒有更多的%s了",
+ (state->context_current->use&CNTXT_INCMNG)
+- ? "incoming folder" : "news group");
++ ? "新進資料匣" : "新聞組群");
+
+ break;
+ }
+@@ -493,9 +493,9 @@
+ */
+ if(F_OFF(F_AUTO_OPEN_NEXT_UNREAD, state)){
+ static ESCKEY_S next_opt[] = {
+- {'y', 'y', "Y", "Yes"},
+- {'n', 'n', "N", "No"},
+- {TAB, 'n', "Tab", "NextNew"},
++ {'y', 'y', "Y", "是"},
++ {'n', 'n', "N", "否"},
++ {TAB, 'n', "Tab", "下一新的"},
+ {-1, 0, NULL, NULL}
+ };
+
+@@ -521,7 +521,7 @@
+ else
+ any_messages(NULL,
+ (mn_get_total(msgmap) > 0L)
+- ? IS_NEWS(stream) ? "more undeleted" : "more new"
++ ? IS_NEWS(stream) ? "更多遭復原刪除的" : "更多新的"
+ : NULL,
+ NULL);
+ }
+@@ -539,7 +539,7 @@
+ * global "zoom mode" flag to suppress messags from the index
+ * should suffice.
+ */
+- if(any_messages(msgmap, NULL, "to Zoom on")){
++ if(any_messages(msgmap, NULL, "可供放大")){
+ if(unzoom_index(state, msgmap)){
+ dprint(4, (debugfile, "\n\n ---- Exiting ZOOM mode ----\n"));
+ q_status_message(SM_ORDER,0,2, "Index Zoom Mode is now off");
+@@ -551,7 +551,7 @@
+ comatose(i), plural(i));
+ }
+ else
+- any_messages(NULL, "selected", "to Zoom on");
++ any_messages(NULL, "被選中的", "可供放大");
+ }
- 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;
- }
+ break;
+@@ -559,7 +559,7 @@
-@@ -442,7 +442,7 @@
- pbuf.browse_help = h_composer_browse;
- pbuf.attach_help = h_composer_ctrl_j;
+ /*---------- print message on paper ----------*/
+ case MC_PRINTMSG :
+- if(any_messages(msgmap, NULL, "to print"))
++ if(any_messages(msgmap, NULL, "可供列印"))
+ cmd_print(state, msgmap, 0, in_index);
-- 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);
- }
+ break;
+@@ -567,7 +567,7 @@
- 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);
- }
+ /*---------- Take Address ----------*/
+ case MC_TAKE :
+- if(any_messages(msgmap, NULL, "to Take address from"))
++ if(any_messages(msgmap, NULL, "可供取得地址"))
+ cmd_take_addr(state, msgmap, 0);
-@@ -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}
- };
+ break;
+@@ -575,7 +575,7 @@
-@@ -590,18 +590,18 @@
- fix_windsize(ps_global);
+ /*---------- Save Message ----------*/
+ case MC_SAVE :
+- if(any_messages(msgmap, NULL, "to Save"))
++ if(any_messages(msgmap, NULL, "可供存檔"))
+ cmd_save(state, msgmap, 0);
- 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;
+ break;
+@@ -583,7 +583,7 @@
+
+ /*---------- Export message ----------*/
+ case MC_EXPORT :
+- if(any_messages(msgmap, NULL, "to Export")){
++ if(any_messages(msgmap, NULL, "可供匯出")){
+ cmd_export(state, msgmap, question_line, 0);
+ state->mangled_footer = 1;
}
- else if(rv == 'n'){ /* Declined! */
-- rstr = "No Changes Saved";
-+ rstr = "改變並未存檔";
+@@ -597,29 +597,28 @@
+ if(IS_NEWS(stream) && stream->rdonly){
+ if((del_count = count_flagged(stream, F_DEL)) > 0L){
+ state->mangled_footer = 1;
+- sprintf(prompt, "Exclude %ld message%s from %s", del_count,
+- plural(del_count), pretty_fn(state->cur_folder));
++ sprintf(prompt, "自 %s 中排除 %ld 封信件",
++ pretty_fn(state->cur_folder), del_count);
+ if(F_ON(F_AUTO_EXPUNGE, state)
+ || want_to(prompt, 'y', 0, NO_HELP, WT_NORM) == 'y'){
+ msgno_exclude(stream, msgmap);
+ clear_index_cache();
+ state->mangled_body = 1;
+ state->mangled_header = 1;
+- q_status_message2(SM_ORDER, 0, 4, "%s message%s excluded",
+- long2string(del_count),
+- plural(del_count));
++ q_status_message1(SM_ORDER, 0, 4, "%s 封信件被排除了",
++ long2string(del_count));
+ }
+ else
+- any_messages(NULL, NULL, "Excluded");
++ any_messages(NULL, NULL, "排除在外");
+ }
+ else
+- any_messages(NULL, "deleted", "to Exclude");
++ any_messages(NULL, "被刪除", "可供排除");
+
break;
}
- else if(rv == 'x'){ /* Cancelled! */
-- rstr = "Exit Cancelled";
-+ rstr = "取消";
+ else if(READONLY_FOLDER){
+ q_status_message(SM_ORDER, 0, 4,
+- "Can't expunge. Folder is read-only");
++ "無法刪除。信件匣是唯讀的");
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");
-+ "無法針對此項目獲得電子郵件地址;請選擇其他的或離開");
+@@ -634,7 +633,7 @@
+ break;
+ }
+ else if(ret == 'x') { /* ^C */
+- cmd_cancelled("Expunge");
++ cmd_cancelled("刪除");
+ break;
+ }
}
- 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);
+@@ -685,11 +684,11 @@
+ if(state->expunge_count <= 0)
+ if(del_count)
+ q_status_message1(SM_ORDER, 0, 3,
+- "No messages expunged from folder \"%s\"",
++ "沒有任何信件自信件匣 \"%s\" 中刪除",
+ pretty_fn(state->cur_folder));
+ else
+ q_status_message(SM_ORDER, 0, 3,
+- "No messages marked deleted. No messages expunged.");
++ "沒有任何信件被標示為刪除。沒有信件被刪除。");
break;
- case MC_ADD :
-- if(!fixed_var((*cl)->var, NULL, "directory list"))
-+ if(!fixed_var((*cl)->var, NULL, "地址列表"))
- dir_config_add(ps, cl);
+@@ -719,16 +718,15 @@
+ */
+ refresh_sort(msgmap, FALSE);
+ state->mangled_header = 1;
+- q_status_message2(SM_ORDER, 0, 4,
+- "%s message%s UNexcluded",
+- long2string(del_count),
+- plural(del_count));
++ q_status_message1(SM_ORDER, 0, 4,
++ "%s 封信件被復原排除",
++ long2string(del_count));
+ }
+ else
+- any_messages(NULL, NULL, "UNexcluded");
++ any_messages(NULL, NULL, "復原排除");
+ }
+ else
+- any_messages(NULL, "excluded", "to UNexclude");
++ any_messages(NULL, "被排除", "可供復原排除");
+ }
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);
+@@ -736,7 +734,7 @@
+
+ /*------- Make Selection -----------*/
+ case MC_SELECT :
+- if(any_messages(msgmap, NULL, "to Select")){
++ if(any_messages(msgmap, NULL, "可供選擇")){
+ aggregate_select(state, msgmap, question_line, in_index);
+ if(in_index && any_lflagged(msgmap, MN_SLCT) > 0L
+ && !any_lflagged(msgmap, MN_HIDE)
+@@ -768,7 +766,7 @@
+ unzoom_index(state, msgmap);
+ }
else
-@@ -2708,10 +2708,10 @@
+- any_messages(NULL, NULL, "to Apply command to. Try \"Select\"");
++ any_messages(NULL, NULL, "可供套用命令。試試 \"選擇\"");
+ }
+
break;
+@@ -846,21 +844,21 @@
+ {
+ if(cmd == ctrl('Q') || cmd == ctrl('S'))
+ q_status_message1(SM_ASYNC, 0, 2,
+- "%s char received. Set \"preserve-start-stop\" feature in Setup/Config.",
++ "收到 %s 字元。以 設定/環境設定 開啟 \"preserve-start-stop\"。",
+ pretty_command(cmd));
+ else if(cmd == KEY_JUNK)
+ q_status_message3(SM_ORDER, 0, 2,
+- "Invalid key pressed.%s%s%s",
+- (help) ? " Use " : "",
++ "輸入了無效的按鍵。%s%s%s",
++ (help) ? "請以 " : "",
+ (help) ? help : "",
+- (help) ? " for help" : "");
++ (help) ? " 呼叫輔助說明" : "");
+ else
+ q_status_message4(SM_ORDER, 0, 2,
+- "Command \"%s\" not defined for this screen.%s%s%s",
++ "命令 \"%s\" 未在此畫面定義。%s%s%s",
+ pretty_command(cmd),
+- (help) ? " Use " : "",
++ (help) ? "請以 " : "",
+ (help) ? help : "",
+- (help) ? " for help" : "");
++ (help) ? " 呼叫輔助說明。" : "");
+ }
- 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
- 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, "沒有伺服器名稱,取消新增");
+
+@@ -1133,11 +1131,9 @@
+ char *type, *cmd;
+ {
+ if(mn_get_total(map) <= 0L){
+- q_status_message4(SM_ORDER, 0, 2, "No %s%smessages%s%s",
++ q_status_message2(SM_ORDER, 0, 2, "沒有%s信件%s",
+ type ? type : "",
+- type ? " " : "",
+- (!cmd || *cmd != '.') ? " " : "",
+- cmd ? cmd : "in folder");
++ cmd ? cmd : "在信件匣中");
+ return(FALSE);
}
- 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;
+@@ -1161,8 +1157,8 @@
+ {
+ if(READONLY_FOLDER || state->dead_stream){
+ q_status_message2(SM_ORDER | (state->dead_stream ? SM_DING : 0), 0, 3,
+- "Can't %s message. Folder is %s.", cmd,
+- (state->dead_stream) ? "closed" : "read-only");
++ "無法%s信件。信件匣是%s的。", cmd,
++ (state->dead_stream) ? "關閉" : "唯讀");
+ return(FALSE);
}
-@@ -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;
+@@ -1182,7 +1178,7 @@
+ cmd_cancelled(cmd)
+ char *cmd;
+ {
+- q_status_message1(SM_INFO, 0, 2, "%s cancelled", cmd ? cmd : "Command");
++ q_status_message1(SM_INFO, 0, 2, "取消%s", cmd ? cmd : "命令");
+ }
- 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;
- }
-@@ -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");
-+ "無法刪除系統管理員定義的設定值。");
+
+@@ -1208,7 +1204,7 @@
+
+ dprint(4, (debugfile, "\n - delete message -\n"));
+ if(!(any_messages(msgmap, NULL, "to Delete")
+- && can_set_flag(state, "delete")))
++ && can_set_flag(state, "刪除")))
+ return;
+
+ if(state->io_error_on_stream) {
+@@ -1218,16 +1214,15 @@
+
+ if(agg){
+ sequence = selected_sequence(state->mail_stream, msgmap, &del_count);
+- sprintf(prompt, "%ld selected message%s marked for deletion",
+- del_count, plural(del_count));
++ sprintf(prompt, "%ld 封信件被標示為待刪除", del_count);
}
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, "伺服器未被刪除");
+ msgno = mn_get_cur(msgmap);
+ del_count = 1L; /* return current */
+ sequence = cpystr(long2string(mn_m2raw(msgmap, mn_get_cur(msgmap))));
+ lastmsg = (msgno >= mn_get_total(msgmap));
+- sprintf(prompt, "%s%s marked for deletion",
+- lastmsg ? "Last message" : "Message ",
++ sprintf(prompt, "%s%s 被標示為待刪除",
++ lastmsg ? "最後一封信" : "信件 ",
+ lastmsg ? "" : long2string(msgno));
}
- 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,"輔助說明尚未存在!");
+@@ -1289,7 +1284,7 @@
- break;
+ dprint(4, (debugfile, "\n - undelete -\n"));
+ if(!(any_messages(msgmap, NULL, "to Undelete")
+- && can_set_flag(state, "undelete")))
++ && can_set_flag(state, "復原刪除")))
+ return;
-@@ -4473,7 +4473,7 @@
- if(i)
- config_scroll_up(i);
- else
-- q_status_message(SM_ORDER,0,1, "Already at end of screen");
-+ q_status_message(SM_ORDER,0,1, "已經在畫面的結尾了");
- }
+ if(agg){
+@@ -1380,7 +1375,7 @@
+ };
- break;
-@@ -4497,7 +4497,7 @@
- }
- else
- q_status_message(SM_ORDER, 0, 1,
-- "Already at start of screen");
-+ "已經在畫面的起始了");
+ if(!(any_messages(msgmap, NULL, "to Flag")
+- && can_set_flag(state, "flag")))
++ && can_set_flag(state, "標示")))
+ return;
- break;
+ if(state->io_error_on_stream) {
+@@ -1735,7 +1730,7 @@
+ if(msgno_any_exceptions(state->mail_stream, msgmap)
+ && want_to("Saved copy will NOT include entire message! Continue",
+ 'y', 'n', NO_HELP, WT_FLUSH_IN | WT_SEQ_SENSITIVE) != 'y'){
+- cmd_cancelled("Save message");
++ cmd_cancelled("信件存檔");
+ return;
+ }
-@@ -4540,7 +4540,7 @@
+@@ -1858,32 +1853,32 @@
+ 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');
+ ekey[rc].rval = 10;
+ ekey[rc].name = "^P";
+- ekey[rc++].label = "Prev Collection";
++ ekey[rc++].label = "前一總集";
+
+ ekey[rc].ch = ctrl('N');
+ ekey[rc].rval = 11;
+ ekey[rc].name = "^N";
+- ekey[rc++].label = "Next Collection";
++ ekey[rc++].label = "後一總集";
+ }
- if(ctmpa == screen->current){
- q_status_message(SM_ORDER,0,1,
-- "Already at end of screen");
-+ "已經在畫面的結尾了");
- goto no_down;
- }
+ if(F_ON(F_ENABLE_TAB_COMPLETE, ps_global)){
+ ekey[rc].ch = TAB;
+ ekey[rc].rval = 12;
+ ekey[rc].name = "TAB";
+- ekey[rc++].label = "Complete";
++ ekey[rc++].label = "完成";
+ }
-@@ -4571,7 +4571,7 @@
- if(ctmpa){
- if(ctmpa == screen->current)
- q_status_message(SM_ORDER, 0, 1,
-- "Already at start of screen");
-+ "已經在畫面的起始了");
+ if(F_ON(F_ENABLE_SUB_LISTS, ps_global)){
+ ekey[rc].ch = ctrl('X');
+ ekey[rc].rval = 14;
+ ekey[rc].name = "^X";
+- ekey[rc++].label = "ListMatches";
++ ekey[rc++].label = "列出符合";
+ }
- 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}};
-
- 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 : "找不到該字");
- }
+ if(saveable_count > 1){
+@@ -2021,7 +2016,7 @@
+ /* else fall thru like they cancelled */
+ case 1 :
+- cmd_cancelled("Save message");
++ cmd_cancelled("信件存檔");
+ done--;
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++;
- }
-@@ -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;
-
- 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 @@
- }
- 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 @@
- }
+@@ -3126,16 +3121,16 @@
+ {
+ if(context && ps_global->context_list->next && context_isambig(folder)){
+ sprintf(tmp_20k_buf,
+- "Folder \"%.15s%s\" in <%.15s%s> doesn't exist. Create",
++ "信件匣 \"%.15s%s\" 在 <%.15s%s> 不存在。要建立",
+ folder, (strlen(folder) > 15) ? "..." : "",
+ context->nickname,
+ (strlen(context->nickname) > 15) ? "..." : "");
+ }
+ else
+- sprintf(tmp_20k_buf,"Folder \"%.40s\" doesn't exist. Create", folder);
++ sprintf(tmp_20k_buf,"信件匣 \"%.40s\" 不存在。要建立", folder);
- 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':
- i = 1;
-- q_status_message(SM_ORDER,0,3,"Add cancelled");
-+ q_status_message(SM_ORDER,0,3,"取消新增");
- 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;
- }
+ if(want_to(tmp_20k_buf, 'y', 'n', NO_HELP, WT_SEQ_SENSITIVE) != 'y'){
+- cmd_cancelled("Save message");
++ cmd_cancelled("信件存檔");
+ return(-1);
+ }
-@@ -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 @@
- }
- }
- 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 @@
- }
+@@ -3259,14 +3254,14 @@
+ export_opts[i = 0].ch = ctrl('T');
+ export_opts[i].rval = 10;
+ export_opts[i].name = "^T";
+- export_opts[i++].label = "To Files";
++ export_opts[i++].label = "檔案列表";
+
+ #if !defined(DOS) && !defined(MAC) && !defined(OS2)
+ if(ps_global->VAR_DOWNLOAD_CMD && ps_global->VAR_DOWNLOAD_CMD[0]){
+ 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) */
+
+@@ -3274,7 +3269,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 = "完成";
+ }
- 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, "設定值未被刪除");
+ #if 0
+@@ -3283,7 +3278,7 @@
+ export_opts[i].ch = ctrl('X');
+ export_opts[i].rval = 14;
+ export_opts[i].name = "^X";
+- export_opts[i++].label = "ListMatches";
++ export_opts[i++].label = "列出符合";
+ }
+ #endif
+
+@@ -3297,7 +3292,7 @@
+ if(r < 0){
+ switch(r){
+ case -1:
+- cmd_cancelled("Export message");
++ cmd_cancelled("匯出信件");
+ break;
+
+ case -2:
+@@ -3319,7 +3314,7 @@
+
+ if(ps_global->restricted){
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- "Download disallowed in restricted mode");
++ "限制模式中不允許\下載");
+ goto fini;
}
- 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;
- }
+@@ -3338,7 +3333,7 @@
+ || !format_message(mn_m2raw(msgmap, mn_get_cur(msgmap)),
+ env, b, FM_NEW_MESS | FM_NOWRAP, pc)){
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- err = "Error writing tempfile for download");
++ err = "寫入下載暫存檔時發生錯誤");
+ 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;
+@@ -3351,18 +3346,18 @@
+ (void) close_system_pipe(&syspipe);
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- err = "Error running download command");
++ err = "執行下載命令時發生錯誤");
}
-@@ -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;
- }
+ unlink(tfp);
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 3,
+- err = "Error building temp file for download");
++ err = "無法建立供下載使用的暫存檔");
-@@ -6517,15 +6517,15 @@
- fs_give((void **)&q);
- }
+ fs_give((void **)&tfp);
+ if(!err)
+- q_status_message(SM_ORDER, 0, 3, "Download Command Completed");
++ q_status_message(SM_ORDER, 0, 3, "下載命令完成");
-- 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 ? "\"" : "");
+ goto fini;
+ }
+@@ -3482,7 +3477,7 @@
+ simple_export_opts[r].ch = ctrl('I');
+ simple_export_opts[r].rval = 11;
+ simple_export_opts[r].name = "TAB";
+- simple_export_opts[r].label = "Complete";
++ simple_export_opts[r].label = "完成";
+ }
- if(p)
- fs_give((void **)&p);
- }
- else
- q_status_message(SM_ORDER,3,5,
-- "Trouble setting default printer");
-+ "有問題的預設印表機");
+ if(!srctext){
+@@ -3555,7 +3550,7 @@
+ break;
- 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");
-+ "有問題的預設印表機");
+ case -1:
+- cmd_cancelled("Export");
++ cmd_cancelled("匯出");
+ break;
- 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");
-+ "有問題的預設印表機");
+ case -2:
+@@ -4131,32 +4126,32 @@
+ ekey[rc].ch = (allow_list) ? ctrl('T') : 0 ;
+ ekey[rc].rval = (allow_list) ? 2 : 0;
+ ekey[rc].name = (allow_list) ? "^T" : "";
+- ekey[rc++].label = (allow_list) ? "ToFldrs" : "";
++ ekey[rc++].label = (allow_list) ? "檔案列表" : "";
+
+ if(ps_global->context_list->next){
+ ekey[rc].ch = ctrl('P');
+ ekey[rc].rval = 10;
+ ekey[rc].name = "^P";
+- ekey[rc++].label = "Prev Collection";
++ ekey[rc++].label = "前一總集";
+
+ ekey[rc].ch = ctrl('N');
+ ekey[rc].rval = 11;
+ ekey[rc].name = "^N";
+- ekey[rc++].label = "Next Collection";
++ ekey[rc++].label = "後一總集";
+ }
- 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(F_ON(F_ENABLE_TAB_COMPLETE,ps_global)){
+ ekey[rc].ch = TAB;
+ ekey[rc].rval = 12;
+ ekey[rc].name = "TAB";
+- ekey[rc++].label = "Complete";
++ ekey[rc++].label = "完成";
+ }
-@@ -6659,7 +6659,7 @@
- break;
- }
- 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;
- }
+ if(F_ON(F_ENABLE_SUB_LISTS, ps_global)){
+ ekey[rc].ch = ctrl('X');
+ ekey[rc].rval = 14;
+ ekey[rc].name = "^X";
+- ekey[rc++].label = "ListMatches";
++ ekey[rc++].label = "列出符合";
+ }
+
+ if(ps_global->context_list->next){
+@@ -4272,15 +4267,15 @@
+ newfolder);
+ else if(tc->use & CNTXT_INCMNG)
+ q_status_message1(SM_ORDER, 0, 3,
+- "Can't find Incoming Folder: %s",
++ "找不到新進信件匣:%s",
+ newfolder);
+ else if(context_isambig(newfolder))
+ q_status_message3(SM_ORDER, 0, 3,
+- "Can't find folder \"%s\" in %.*s",
+- newfolder, (void *) 50, tc->nickname);
++ "在 %.*s 中找不到信件匣 \"%s\"",
++ (void *) 50, tc->nickname, newfolder);
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 @@
- }
+ q_status_message1(SM_ORDER, 0, 3,
+- "Can't find folder \"%s\"",
++ "找不到信件匣 \"%s\"",
+ newfolder);
+
+ return(NULL);
+@@ -4293,7 +4288,7 @@
+ /* fall thru like they cancelled */
+
+ case 1 : /* o_e says user cancel */
+- cmd_cancelled("Open folder");
++ cmd_cancelled("開啟信件匣");
+ return(NULL);
+
+ case 2 : /* o_e says user wants list */
+@@ -4529,7 +4524,7 @@
+ else if ((new_context->use & CNTXT_INCMNG)
+ && (folder_index(newfolder, new_context, FI_FOLDER) < 0)){
+ q_status_message1(SM_ORDER, 3, 4,
+- "Can't find Incoming Folder %s.", newfolder);
++ "找不到新進信件匣 %s。", newfolder);
+ 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
-- 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, "印表機未被刪除");
+ }
+@@ -4610,7 +4605,7 @@
}
+ }
- 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);
-
- break;
+- strcat(strncat(strcpy(status_msg, "Opening \""),
++ strcat(strncat(strcpy(status_msg, "正在開啟 \""),
+ pretty_fn(newfolder), 70), "\"");
+ we_cancel = busy_alarm(1, status_msg, NULL, 1);
+
+@@ -4693,7 +4688,7 @@
+ && !mn_get_revsort(ps_global->msgmap)))
+ refresh_sort(ps_global->msgmap, FALSE);
+
+- q_status_message1(SM_ORDER, 0, 3, "Folder \"%s\" reopened",
++ q_status_message1(SM_ORDER, 0, 3, "重新開啟資料匣 \"%s\"",
+ old_folder);
+ }
+ }
+@@ -4774,14 +4769,13 @@
+
+ /* UWIN doesn't want to see this message */
+ if(!ps_global->nr_mode)
+- q_status_message7(SM_ORDER, 0, 4, "%s \"%s\" opened with %s message%s%s",
++ q_status_message7(SM_ORDER, 0, 4, "%s \"%s\" 已開啟,共 %s 封信%s",
+ IS_NEWS(ps_global->mail_stream)
+- ? "News group" : "Folder",
++ ? "新聞組群" : "信件匣",
+ pretty_fn(newfolder),
+ comatose(mn_get_total(ps_global->msgmap)),
+- plural(mn_get_total(ps_global->msgmap)),
+- READONLY_FOLDER ?" READONLY" : "",
+- NULL, NULL);
++ READONLY_FOLDER ?" 唯讀" : "",
++ NULL, NULL, NULL);
+
+ sort_folder(ps_global->msgmap, ps_global->def_sort,
+ ps_global->def_sort_rev, TRUE);
+@@ -4947,9 +4941,9 @@
+ char ing[4];
+
+ if(final_msg)
+- strcpy(ing, "ed");
++ strcpy(ing, "已");
+ else
+- strcpy(ing, "ing");
++ strcpy(ing, "正");
- 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;
+ buff1[0] = '\0';
+ buff2[0] = '\0';
+@@ -4958,7 +4952,7 @@
+ stream->mailbox));
+ if(!stream->rdonly){
- 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 @@
+- q_status_message1(SM_INFO, 0, 1, "Closing \"%s\"...", folder);
++ q_status_message1(SM_INFO, 0, 1, "正在關閉 \"%s\"...", folder);
+ flush_status_messages(1);
- 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);
+ /* Save read messages? */
+@@ -4998,10 +4992,8 @@
+ }
+ else{
+ sprintf(prompt_b,
+- "Expunge the %ld deleted message%s from \"%s\"",
+- delete_count,
+- delete_count == 1 ? "" : "s",
+- short_folder_name);
++ "自 \"%s\" 中刪除 %ld 封信件", short_folder_name,
++ delete_count);
+ ret = want_to(prompt_b, 'y', 0, NO_HELP, WT_NORM);
+ }
- break;
-@@ -7232,7 +7232,7 @@
- struct key_menu *km;
- CONT_SCR_S *cs;
+@@ -5012,13 +5004,10 @@
+
+ if(ret == 'y'){
+ sprintf(buff2,
+- "Clos%s \"%.30s\". %s %s message%s and delet%s %s.",
++ "%s關閉 \"%.30s\"。保留 %s 封並刪除 %s 封信件。",
+ ing,
+ pretty_fn(folder),
+- final_msg ? "Kept" : "Keeping",
+ comatose((stream->nmsgs - delete_count)),
+- plural(stream->nmsgs - delete_count),
+- ing,
+ long2string(delete_count));
+ if(final_msg)
+ *final_msg = cpystr(buff2);
+@@ -5042,17 +5031,15 @@
+ if(ret != 'y'){
+ if(stream->nmsgs){
+ sprintf(buff2,
+- "Clos%s folder \"%s\". %s%s%s message%s.",
++ "%s關閉信件匣 \"%s\"。保留%s%s 封信件。",
+ ing,
+ pretty_fn(folder),
+- final_msg ? "Kept" : "Keeping",
+- (stream->nmsgs == 1L) ? " single" : " all ",
++ (stream->nmsgs == 1L) ? " 一" : "全部共 ",
+ (stream->nmsgs > 1L)
+- ? comatose(stream->nmsgs) : "",
+- plural(stream->nmsgs));
++ ? comatose(stream->nmsgs) : "");
+ }
+ else{
+- sprintf(buff2, "Clos%s empty folder \"%s\"",
++ sprintf(buff2, "%s關閉空的信件匣 \"%s\"",
+ ing, pretty_fn(folder));
+ }
-- if(raw_ctxt = context_edit_screen(ps, "ADD", NULL, NULL, NULL, NULL)){
-+ if(raw_ctxt = context_edit_screen(ps, "新增", NULL, NULL, NULL, NULL)){
+@@ -5071,7 +5058,7 @@
+ q_status_message(SM_ORDER,
+ F_ON(F_AUTO_READ_MSGS,ps_global) ? 0 : 3, 5, moved_msg);
- /* create a corresponding new CONF_S */
- new_ctxt = new_context(raw_ctxt, NULL);
-@@ -7311,7 +7311,7 @@
+- sprintf(buff2, "Clos%s news group \"%s\"",
++ sprintf(buff2, "%s關閉新聞組群 \"%s\"",
+ ing, pretty_fn(folder));
- /* Tell the user it was a huge success... */
- q_status_message(SM_ORDER, 0, 3,
-- "New collection added! Use \"$\" to adjust order.");
-+ "新的總集加入了!請用 \"$\" 調整順序。");
+ if(F_ON(F_NEWS_CROSS_DELETE, ps_global))
+@@ -5079,7 +5066,7 @@
+ }
+ else
+ sprintf(buff2,
+- "Clos%s read-only folder \"%s\". No changes to save",
++ "%s關閉唯讀的信件匣 \"%s\"。未存入任何改變",
+ ing, pretty_fn(folder));
+
+ if(final_msg)
+@@ -5368,18 +5355,18 @@
+ if(in_index && F_ON(F_PRINT_INDEX, state)){
+ char m[10];
+ static ESCKEY_S prt_opts[] = {
+- {'i', 'i', "I", "Index"},
++ {'i', 'i', "I", "索引"},
+ {'m', 'm', "M", NULL},
+ {-1, 0, NULL, NULL}};
+
+- sprintf(m, "Message%s", (msgs>1L) ? "s" : "");
++ sprintf(m, "信件");
+ prt_opts[1].label = m;
+- sprintf(prompt, "Print %sFolder Index or %s %s? ",
+- agg ? "selected " : "", agg ? "selected" : "current", m);
++ sprintf(prompt, "印出 %s信件匣索引或 %s %s? ",
++ agg ? "已被選擇的 " : "", agg ? "已被選擇的" : "目前的", m);
+ switch(radio_buttons(prompt, -FOOTER_ROWS(state), prt_opts, 'm', 'x',
+ NO_HELP, RB_NORM|RB_SEQ_SENSITIVE)){
+ case 'x' :
+- cmd_cancelled("Print");
++ cmd_cancelled("列印");
+ if(agg)
+ restore_selected(msgmap);
+
+@@ -5396,11 +5383,11 @@
}
- }
-@@ -7330,11 +7330,11 @@
+ if(do_index)
+- sprintf(prompt, "%sFolder Index ", agg ? "Selected " : "");
++ sprintf(prompt, "%s信件匣索引 ", agg ? "已被選擇的" : "");
+ else if(msgs > 1L)
+- sprintf(prompt, "%s messages ", long2string(msgs));
++ sprintf(prompt, "%s 封信件 ", long2string(msgs));
+ else
+- sprintf(prompt, "Message %s ", long2string(mn_get_cur(msgmap)));
++ sprintf(prompt, "第 %s 封信件", long2string(mn_get_cur(msgmap)));
+
+ if(open_printer(prompt) < 0){
+ if(agg)
+@@ -5663,7 +5650,7 @@
+ /* else fall thru as if cancelled */
+
+ case 1 :
+- cmd_cancelled("Pipe command");
++ cmd_cancelled("導向(Pipe)命令");
+ done++;
+ break;
- 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.");
-+ "無法刪除預設值。試試更名。");
+@@ -5746,7 +5733,7 @@
+ sel_opts = sel_opts2;
+ if(old_tot = any_lflagged(msgmap, MN_SLCT)){
+ i = get_lflag(state->mail_stream, msgmap, mn_get_cur(msgmap), MN_SLCT);
+- sel_opts1[1].label = "unselect Cur" + (i ? 0 : 2);
++ sel_opts1[1].label = "取消目前選擇" + (i ? 0 : 2);
+ sel_opts += 2; /* disable extra options */
+ switch(q = radio_buttons(sel_pmt1, q_line, sel_opts1, 'c', 'x', help,
+ RB_NORM)){
+@@ -5790,7 +5777,7 @@
+ */
+ switch(q){
+ case 'x': /* cancel */
+- cmd_cancelled("Select command");
++ cmd_cancelled("選取命令");
return;
+
+ case 'c' : /* select/unselect current */
+@@ -5998,14 +5985,14 @@
+ sel_opts3[i].ch = '*';
+ sel_opts3[i].rval = '*';
+ sel_opts3[i].name = "*";
+- sel_opts3[i++].label = "Flag";
++ sel_opts3[i++].label = "旗標";
}
-- 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被刪除");
+ if(F_ON(F_ENABLE_PIPE,state)){ /* pipe? */
+ sel_opts3[i].ch = '|';
+ sel_opts3[i].rval = '|';
+ sel_opts3[i].name = "|";
+- sel_opts3[i++].label = "Pipe";
++ sel_opts3[i++].label = "導向(Pipe)";
+ }
+ /*
+@@ -6017,7 +6004,7 @@
+ sel_opts3[i].ch = 'b';
+ sel_opts3[i].rval = 'b';
+ sel_opts3[i].name = "B";
+- sel_opts3[i++].label = "Bounce";
++ sel_opts3[i++].label = "退信";
}
- else
-- q_status_message(SM_ORDER, 0, 3, "No collections deleted");
-+ q_status_message(SM_ORDER, 0, 3, "沒有任何總集被刪除");
- }
+ if(F_ON(F_ENABLE_PRYNT, state)){
+@@ -6088,7 +6075,7 @@
+ break;
-@@ -7473,7 +7473,7 @@
- if(p = strstr(tpath, "%s"))
- *p = '\0';
+ case 'x' : /* cancel */
+- cmd_cancelled("Apply command");
++ cmd_cancelled("套用命令");
+ rv = 0;
+ 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)){
+@@ -6205,7 +6192,7 @@
+ *t = '\0';
-@@ -7543,7 +7543,7 @@
+ if(r == 1 || numbers[0] == '\0'){
+- cmd_cancelled("Selection by number");
++ cmd_cancelled("根據數字選擇");
+ return(1);
+ }
+ else
+@@ -6331,7 +6318,7 @@
+ prompt, sel_date_opt, help, &flags);
+ switch (r){
+ case 1 :
+- cmd_cancelled("Selection by date");
++ cmd_cancelled("根據日期選擇");
+ return(1);
+
+ case 3 :
+@@ -6441,15 +6428,15 @@
+ ekey[0].ch = ctrl('T');
+ ekey[0].name = "^T";
+ ekey[0].rval = 10;
+- ekey[0].label = "Cur To";
++ ekey[0].label = "目前收信人";
+ ekey[1].ch = ctrl('R');
+ ekey[1].name = "^R";
+ ekey[1].rval = 11;
+- ekey[1].label = "Cur From";
++ ekey[1].label = "目前寄件人";
+ ekey[2].ch = ctrl('W');
+ ekey[2].name = "^W";
+ ekey[2].rval = 12;
+- ekey[2].label = "Cur Cc";
++ ekey[2].label = "目前副本";
+ break;
- set_current_val((*cl)->var, TRUE, FALSE);
+ case 's' :
+@@ -6457,7 +6444,7 @@
+ ekey[0].ch = ctrl('X');
+ ekey[0].name = "^X";
+ ekey[0].rval = 13;
+- ekey[0].label = "Cur Subject";
++ ekey[0].label = "目前主題";
+ break;
-- q_status_message(SM_ORDER, 0, 3, "Collection list entry updated");
-+ q_status_message(SM_ORDER, 0, 3, "已更新總集列表");
+ case 'a' :
+@@ -6556,7 +6543,7 @@
}
- }
-@@ -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 @@
- }
+ if(type == 'x' || r == 'x'){
+- cmd_cancelled("Selection by text");
++ cmd_cancelled("根據文字選擇");
+ return(1);
}
- else
-- q_status_message(SM_ORDER, 0, 3, "Sorry, nothing to Shuffle");
-+ q_status_message(SM_ORDER, 0, 3, "很抱歉,沒有東西可供重整");
- }
-
-@@ -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;
+@@ -6735,7 +6722,7 @@
+ NO_HELP, RB_NORM);
+
+ if(s == 'x'){
+- cmd_cancelled("Selection by status");
++ cmd_cancelled("根據狀態選擇");
+ return(1);
}
+ else if(s == '!')
+@@ -6832,7 +6819,7 @@
+
+ /*----- String together the prompt ------*/
+ tmp[1] = '\0';
+- strcpy(prompt, "Choose type of sort, or Reverse current sort : ");
++ strcpy(prompt, "選取排序方式,或反轉目前的排序:");
+ for(i = 0; state->sort_types[i] != EndofList && i < 8; i++) {
+ sorts[i].rval = i;
+ p = sorts[i].label = sort_name(state->sort_types[i]);
+@@ -6849,7 +6836,7 @@
+ sorts[i].ch = 'r';
+ sorts[i].rval = 'r';
+ sorts[i].name = cpystr("R");
+- sorts[i].label = "Reverse";
++ sorts[i].label = "反轉";
+ sorts[++i].ch = -1;
+ help = h_select_sort;
+
+@@ -6862,7 +6849,7 @@
}
-@@ -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);
+ else{
+ retval = 0;
+- cmd_cancelled("Sort");
++ cmd_cancelled("排序");
}
-@@ -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)
+ while(--i >= 0)
diff --git a/chinese/pine4/files/patch-az b/chinese/pine4/files/patch-az
index d2ec75a29319..ef2c86a0453b 100644
--- a/chinese/pine4/files/patch-az
+++ b/chinese/pine4/files/patch-az
@@ -1,280 +1,318 @@
---- 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 @@
+--- pine/mailindx.c.orig Tue Jul 21 01:21:48 1998
++++ pine/mailindx.c Tue Jul 28 08:35:03 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,
- 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,
+- {"<", "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 @@
-@@ -122,10 +122,10 @@
- COMPOSE_MENU,
+ 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,
- 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
+ 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);
- 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}};
+ if(flags & INDX_FOOTER) {
+@@ -443,7 +443,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 +624,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 +741,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, "索引第一頁");
- pine_state->mangled_footer = 1;
-@@ -726,7 +726,7 @@
+ break;
+ }
+@@ -750,7 +750,7 @@
+ if(i <= 1L){
+ if(mn_get_cur(msgmap) == 1L)
+ q_status_message(SM_ORDER, 0, 1,
+- "Already at start of Index");
++ "已經在索引的起頭了");
- 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 @@
- }
+ break;
+ }
+@@ -770,7 +770,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, "索引最終頁");
- 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}
- };
+ id.msg_at_top = i;
+ break;
+@@ -779,7 +779,7 @@
-@@ -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;
- }
+ 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,"已經在索引的結尾了");
-@@ -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;
+ }
+@@ -961,9 +961,9 @@
+ }
- break;
+ q_status_message2(SM_ORDER, 0, 1,
+- "Message %s %sdeleted",
++ "信件 %s %s刪除",
+ long2string(mn_get_cur(msgmap)),
+- (del) ? "" : "already ");
++ (del) ? "" : "已");
+ }
-@@ -1257,14 +1257,14 @@
- just_a_navigate_cmd++;
- }
- else
-- q_status_message(SM_ORDER, 0, 2, "Already at bottom of list");
-+ q_status_message(SM_ORDER, 0, 2, "已經在列表底端了");
+ break;
+@@ -985,9 +985,9 @@
+ }
- break;
+ q_status_message2(SM_ORDER, 0, 1,
+- "Message %s %sdeleted",
++ "信件 %s %s刪除",
+ long2string(mn_get_cur(msgmap)),
+- (del) ? "UN" : "NOT ");
++ (del) ? "已遭復原" : "未被");
+ }
+ break;
+@@ -1787,7 +1787,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;
+ }
- /*---------- Release Notes ----------*/
- case MC_RELNOTES :
-- helper(h_news, "PINE RELEASE NOTES", 0);
-+ helper(h_news, "PINE 出版摘要", 0);
- pine_state->mangled_screen = 1;
- break;
+@@ -1829,7 +1829,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);
+ }
-@@ -1493,7 +1493,7 @@
+@@ -2320,7 +2320,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){
+@@ -2959,8 +2959,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} };
- /* 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;
+ dprint(4, (debugfile, "\n - search headers - \n"));
+@@ -2969,7 +2969,7 @@
+ return;
}
-@@ -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 @@
+ 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;
}
+@@ -2980,13 +2980,13 @@
+ new_string[0] = '\0';
- 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 : "下列表單中");
+ while(1) {
+- sprintf(prompt, "Word to search for [%s] : ", search_string);
++ sprintf(prompt, "搜尋[%s]:", search_string);
- 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';
+ 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;
+@@ -3005,7 +3005,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;
+@@ -3021,7 +3021,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;
+@@ -3046,7 +3046,7 @@
}
-@@ -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(rc == 1 || (new_string[0] == '\0' && search_string[0] == '\0')) {
+- cmd_cancelled("Search");
++ cmd_cancelled("搜尋");
+ return;
+ }
- 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;
+@@ -3085,21 +3085,21 @@
+ }
- case MC_RELNOTES :
-- helper(h_news, "PINE RELEASE NOTES", 0);
-+ helper(h_news, "PINE 出版摘要", 0);
- ps_global->mangled_screen = 1;
- break;
+ 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, "找不到字串");
-@@ -2153,7 +2153,7 @@
- dprint(1, (debugfile, "\n\n ---- QUIT SCREEN ----\n"));
+ #ifndef DOS
+ intr_handling_off();
+@@ -3236,7 +3236,7 @@
+ && LEVELSORT(ps_global->mail_stream)))
+ sort_func = percent_sorted;
- 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;
- }
+- 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);
+@@ -3286,8 +3286,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)
+@@ -4045,7 +4045,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);
+ }
+
+@@ -4398,10 +4398,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-ba b/chinese/pine4/files/patch-ba
index 6f924708cdf2..eae02aa22ed5 100644
--- a/chinese/pine4/files/patch-ba
+++ b/chinese/pine4/files/patch-ba
@@ -1,132 +1,367 @@
---- 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)
-
--#define STYLE_NAME(a) ((a)->text.desc ? (a)->text.desc : "text")
-+#define STYLE_NAME(a) ((a)->text.desc ? (a)->text.desc : "文字")
-
-
- /*
-@@ -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}
+--- pine/mailpart.c.orig Tue Jul 21 03:18:49 1998
++++ pine/mailpart.c Tue Jul 28 08:35:04 1998
+@@ -134,18 +134,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,
+@@ -154,9 +154,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};
+@@ -173,11 +173,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,
+@@ -193,7 +193,7 @@
+ BOUNCE_MENU,
+ NULL_MENU,
+ WHEREIS_MENU,
+- {"%", "Print", MC_PRINTMSG,1,{'%'}, KS_PRINT},
++ {"%", "列印", MC_PRINTMSG,1,{'%'}, KS_PRINT},
+ NULL_MENU,
+ REPLY_MENU,
+ FORWARD_MENU};
+@@ -323,12 +323,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->description && !(ps->atmts + 1)->description)
++ 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)));
+
+ /*
+@@ -471,7 +471,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;
+@@ -535,7 +535,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(km_popped){
+@@ -630,7 +630,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;
+
+@@ -638,7 +638,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;
+
+@@ -652,7 +652,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on last page of attachments");
++ "已經在附件的最後一頁了");
+
+
+ break;
+@@ -673,7 +673,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on first page of attachments");
++ "已經在附件的第一頁了");
+
+ break;
+
+@@ -1041,7 +1041,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);
+
+@@ -1210,7 +1210,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}};
+@@ -1242,7 +1242,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) */
+
+@@ -1250,7 +1250,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 = "完成";
+ }
+
+ att_save_opts[++r].ch = -1;
+@@ -1469,7 +1469,7 @@
+ a->number,
+ save_folder);
+ else if(rv == -1)
+- cmd_cancelled("Attached message Save");
++ cmd_cancelled("存入附加訊息");
+ /* else whatever broke in save_fetch_append shoulda bitched */
+
+ so_give(&so);
+@@ -1545,11 +1545,11 @@
+
+ if(rv == 1)
+ q_status_message2(SM_ORDER, 0, 4,
+- "Attached digest (part %s) saved to \"%s\"",
++ "附加的 digest(第 %s 部份) 存為 \"%s\"",
+ a->number,
+ save_folder);
+ else if(rv == -1)
+- cmd_cancelled("Attached digest Save");
++ cmd_cancelled("存入附加的 digest");
+ /* else whatever broke in save_fetch_append shoulda bitched */
+
+ if(our_stream)
+@@ -1603,7 +1603,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}};
+
+@@ -1611,7 +1611,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';
+@@ -1624,7 +1624,7 @@
+ if(rv < 0){
+ switch(rv){
+ case -1:
+- cmd_cancelled("Export");
++ cmd_cancelled("匯出檔案");
+ break;
+
+ case -2:
+@@ -1676,7 +1676,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}};
+
+@@ -1684,7 +1684,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';
+@@ -1697,7 +1697,7 @@
+ if(rv < 0){
+ switch(rv){
+ case -1:
+- cmd_cancelled("Export");
++ cmd_cancelled("匯出檔案");
+ break;
+
+ case -2:
+@@ -1905,14 +1905,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]);
+
+@@ -2101,7 +2101,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 */
+ }
+@@ -2276,22 +2276,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){
+@@ -2705,10 +2705,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);
+
+@@ -2770,7 +2770,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;
+@@ -2856,7 +2856,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;
+@@ -2953,7 +2953,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);
+@@ -3034,7 +3034,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,
+@@ -3052,7 +3052,7 @@
+ }
+ else if(rc == 0){
+ if(pipe_command[0] == '\0'){
+- cmd_cancelled("Pipe command");
++ cmd_cancelled("導向命令");
+ break;
+ }
+
+@@ -3126,7 +3126,7 @@
+ break;
+ }
+ else if(rc == 1){
+- cmd_cancelled("Pipe");
++ cmd_cancelled("導向");
+ break;
+ }
+ else if(rc = 3)
diff --git a/chinese/pine4/files/patch-bb b/chinese/pine4/files/patch-bb
index 17e394848e61..db71f8e1162e 100644
--- a/chinese/pine4/files/patch-bb
+++ b/chinese/pine4/files/patch-bb
@@ -1,85 +1,525 @@
---- 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);
-
- if(ret == 'x') {
-- cmd_cancelled("Reply");
-+ cmd_cancelled("回覆");
- return(0);
- }
+--- pine/mailview.c.orig Fri Jul 17 15:10:35 1998
++++ pine/mailview.c Tue Jul 28 08:35:04 1998
+@@ -140,8 +140,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,
+@@ -166,11 +166,11 @@
-@@ -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[] = {
+ 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,
+@@ -187,7 +187,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,
+@@ -211,7 +211,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,
+@@ -233,7 +233,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,
+@@ -242,7 +242,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);
+
+
+@@ -377,7 +377,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;
+ }
+@@ -391,7 +391,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)));
+@@ -444,7 +444,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
+@@ -463,11 +463,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);
+@@ -1190,7 +1190,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);
+@@ -1229,7 +1229,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);
+ }
+@@ -1523,7 +1523,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);
+@@ -1853,8 +1853,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", "否"},
- {-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);
-
- case 'r':
-@@ -1165,7 +1165,7 @@
- break;
-
- case 1:
-- cmd_cancelled("Reply");
-+ cmd_cancelled("回覆");
-
- case -1:
- return(-1);
-@@ -1542,7 +1542,7 @@
-
- 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;
+ {-2, 0, NULL, NULL},
+ {-2, 0, NULL, NULL},
+ {0, 'u', "U", "editURL"},
+@@ -1875,7 +1875,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';
+@@ -1919,7 +1919,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 2, 2,
+- "Browser not found: %s",
++ "找不到瀏覽器:%s",
+ error_description(errno));
+ continue;
+ }
+@@ -1948,8 +1948,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)
+@@ -2414,11 +2414,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)
+@@ -2426,7 +2426,7 @@
+ }
+ 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);
+@@ -2746,7 +2746,7 @@
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Can't create space for composer");
++ "無法替編輯器建立空間");
+
+ if(outgoing)
+ mail_free_envelope(&outgoing);
+@@ -2810,7 +2810,7 @@
+ else if(errstr)
+ q_status_message(SM_ORDER|SM_DING, 3, 3, errstr);
+ else
+- cmd_cancelled("URL Launch");
++ cmd_cancelled("檢視 URL");
+
+ break;
+
+@@ -2833,7 +2833,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){
+@@ -2849,7 +2849,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){
+ /*
+@@ -2870,9 +2870,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);
+ }
+@@ -3011,9 +3011,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
+@@ -3098,7 +3098,7 @@
+
+ if(i > mn_get_total(ps_global->msgmap))
+ q_status_message(SM_ORDER, 2, 3,
+- "Couldn't find specified article number");
++ "找不到指定的文章編號");
+ }
+
+ break;
+@@ -3177,7 +3177,7 @@
+ }
+ else
+ q_status_message1(SM_ORDER | SM_DING, 0, 3,
+- "Can't find fragment: %s", fragment);
++ "找不到片斷:%s", fragment);
+
+ return(1);
+ }
+@@ -3204,7 +3204,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);
+@@ -3344,7 +3344,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);
+@@ -3594,7 +3594,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{
+@@ -3606,7 +3606,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "No space for filtered text: %s", errstr);
++ "沒有足夠的空間過濾文字:%s", errstr);
+ rv = FHT_WRTERR;
+ }
+ }
+@@ -3631,7 +3631,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);
+ }
+ }
+
+@@ -3770,7 +3770,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");
++ "未經證實的新聞組群標頭 -- 訊息可能從未被張貼");
}
- 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);
-
- clean:
+
+ if((which & FE_FOLLOWUPTO) && e->followup_to)
+@@ -4394,7 +4394,7 @@
+ }
+
+ if(!sparms->bar.title)
+- sparms->bar.title = "Text";
++ sparms->bar.title = "文字";
+
+ if(sparms->bar.style == TitleBarNone)
+ sparms->bar.style = MsgTextPercent;
+@@ -4543,7 +4543,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 */
+@@ -4659,7 +4659,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;
+ }
+
+@@ -4698,12 +4698,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;
+
+@@ -4717,12 +4717,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;
+@@ -4739,11 +4739,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));
+ }
+
+@@ -4760,11 +4760,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));
+ }
+
+@@ -4795,7 +4795,7 @@
+ }
+
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on last selectable item");
++ "已經在最後一個可選擇的項目上");
+ }
+
+ break;
+@@ -4825,7 +4825,7 @@
+ }
+
+ q_status_message(SM_ORDER, 0, 1,
+- "Already on first selectable item");
++ "已經在第一個可選擇的項目上");
+ }
+
+ break;
+@@ -4844,7 +4844,7 @@
+ break;
+
+ case -1 :
+- cmd_cancelled("View");
++ cmd_cancelled("檢視");
+ break;
+
+ default :
+@@ -4931,14 +4931,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");
++ cmd_cancelled("搜尋");
+ else
+- q_status_message(SM_ORDER | SM_DING, 0, 3, "Word not found");
++ q_status_message(SM_ORDER | SM_DING, 0, 3, "找不到該字");
+
+ break;
+
+@@ -4994,7 +4994,7 @@
+ break;
+
+ case -1 :
+- cmd_cancelled("View");
++ cmd_cancelled("檢視");
+ break;
+
+ default :
+@@ -5239,13 +5239,13 @@
+ int rc, flags;
+ 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}
+ };
+
+ report[0] = '\0';
+- sprintf(prompt, "Word to search for [%s] : ", search_string);
++ sprintf(prompt, "搜尋字串[%s]:", search_string);
+ help = NO_HELP;
+ nsearch_string[0] = '\0';
+
+@@ -5260,13 +5260,13 @@
+ continue;
+ }
+ else if(rc == 10){
+- strcpy(report, "Searched to First Line.");
++ strcpy(report, "搜尋至第一行。");
+ cursor_pos->row = 0;
+ cursor_pos->col = 0;
+ return(0);
+ }
+ else if(rc == 11){
+- strcpy(report, "Searched to Last Line.");
++ strcpy(report, "搜尋至最後一行。");
+ cursor_pos->row = max(get_scroll_text_lines() - 1, 0);
+ cursor_pos->col = 0;
+ return(cursor_pos->row);
+@@ -6055,10 +6055,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;
+@@ -6069,7 +6069,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-bc b/chinese/pine4/files/patch-bc
index c2d1f32557cd..b8143f7f5978 100644
--- a/chinese/pine4/files/patch-bc
+++ b/chinese/pine4/files/patch-bc
@@ -1,109 +1,65 @@
---- 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 @@
+--- pine/newmail.c.orig Fri Mar 27 07:28:33 1998
++++ pine/newmail.c Tue Jul 28 08:35:04 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[] = { "關於",
++ "有關"
+ };
+ e = mail_fetchstructure(stream, max_num, NULL);
- 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);
+ 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);
+ }
- 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);
-
- 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 @@
+ 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 @@
- as.current_line = new_line_number;
+ 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, " 沒有主題");
-- 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));
+ if(!from[0])
+ subject[1] = toupper((unsigned char)subject[1]);
diff --git a/chinese/pine4/files/patch-bd b/chinese/pine4/files/patch-bd
index 7b3e48880ff2..a2f415c1c445 100644
--- a/chinese/pine4/files/patch-bd
+++ b/chinese/pine4/files/patch-bd
@@ -1,675 +1,1476 @@
---- 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;
- }
- }
+--- pine/other.c.orig Thu Jul 16 09:09:27 1998
++++ pine/other.c Tue Jul 28 08:35:05 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{
- 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++;
- }
+ 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);
+ }
+
+@@ -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;
+ }
+
+@@ -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,
-- "Can't open Postponed mailbox: %s", mbox);
-+ "無法開遭暫緩的信箱:%s", mbox);
- if(stream)
- mail_close(stream);
+- "Error writing %s", sig_path);
++ "寫入 %s 時發生錯誤", sig_path);
+ dprint(1, (debugfile, "signature_edit: can't write %s",
+ sig_path));
}
-@@ -524,7 +524,7 @@
+@@ -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}
+ };
- if(ret == 'x'){
- q_status_message(SM_ORDER, 0, 3,
-- "Composition cancelled");
-+ "取消編輯");
- done++;
- }
- }
-@@ -608,7 +608,7 @@
- fs_give((void **)&tmp_fcc);
+@@ -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,
+@@ -696,7 +696,6 @@
+ || (F) == F_DISABLE_DFLT_IN_BUG_RPT \
+ || (F) == F_DISABLE_ALARM \
+ || (F) == F_ALLOW_CHANGING_FROM \
+- || (F) == F_TCAP_WINS \
+ || (F) == F_QUELL_PARTIAL_FETCH \
+ || (F) == F_AGG_SEQ_COPY)
+
+@@ -1377,14 +1376,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);
-- pine_send(outgoing, &body, "COMPOSE MESSAGE", fcc,
-+ pine_send(outgoing, &body, "編輯信件", fcc,
- reply, redraft_pos, lcc, custom, fcc_is_sticky);
+@@ -1392,7 +1391,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 +1424,7 @@
+ char *saved_printer;
+ OPT_SCREEN_S screen;
- if(reply){
-@@ -675,7 +675,7 @@
+- 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 +1793,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 +1834,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 +1845,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 +1999,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 +2015,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 +2046,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 +2062,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 +2403,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 +2497,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 +2560,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 +2654,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 */
+ 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 +2664,7 @@
+ #endif /* notdef */
+
+ (void)conf_scroll_screen(ps, &screen, first_line,
+- "SETUP DIRECTORY SERVERS", "servers ", 1);
++ "設定地址伺服器", "servers ", 1);
+ ps->mangled_screen = 1;
+ }
+
+@@ -2685,20 +2684,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 +2707,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
+ dir_config_shuffle(ps, cl);
}
-@@ -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);
+@@ -2840,7 +2839,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 +2869,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 +2880,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 +2897,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 +2911,7 @@
-@@ -1388,7 +1388,7 @@
+ switch(rv){
+ case 'x':
+- q_status_message(SM_ORDER, 0, 3, "Shuffle cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消重整");
+ return;
- 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);
+ case 'u':
+@@ -2950,7 +2949,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;
+ }
+@@ -3002,10 +3001,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 +3739,7 @@
}
+ else
+ q_status_message(SM_ORDER, 3, 3,
+- "Can't delete sys-admin defined value");
++ "無法刪除系統管理員定義的設定值。");
+ }
+ else{
+ int cnt, ans = 0;
+@@ -3763,8 +3762,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 +3869,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 +3909,7 @@
+ }
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "Server not deleted");
++ q_status_message(SM_ORDER, 0, 3, "伺服器未被刪除");
+ }
+
+ if(rv == 1){
+@@ -4416,7 +4415,7 @@
+ ps->mangled_screen = 1;
+ }
+ else
+- q_status_message(SM_ORDER,0,3,"No help yet!");
++ q_status_message(SM_ORDER,0,3,"輔助說明尚未存在!");
-@@ -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;
+@@ -4473,7 +4472,7 @@
+ if(i)
+ config_scroll_up(i);
+ else
+- q_status_message(SM_ORDER,0,1, "Already at end of screen");
++ q_status_message(SM_ORDER,0,1, "已經在畫面的結尾了");
+ }
+
break;
-@@ -2436,7 +2436,7 @@
- break;
+@@ -4497,7 +4496,7 @@
+ }
+ else
+ q_status_message(SM_ORDER, 0, 1,
+- "Already at start of screen");
++ "已經在畫面的起始了");
- 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;
+ break;
+
+@@ -4540,7 +4539,7 @@
+
+ if(ctmpa == screen->current){
+ q_status_message(SM_ORDER,0,1,
+- "Already at end of screen");
++ "已經在畫面的結尾了");
+ goto no_down;
+ }
+
+@@ -4571,7 +4570,7 @@
+ if(ctmpa){
+ if(ctmpa == screen->current)
+ q_status_message(SM_ORDER, 0, 1,
+- "Already at start of screen");
++ "已經在畫面的起始了");
+
+ screen->current = ctmpa;
}
+@@ -4651,13 +4650,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}};
-@@ -3474,15 +3474,15 @@
- if(fcc_result && folder)
- lc = last_cmpnt(folder);
+ 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 +4778,7 @@
+ result = "Searched to bottom";
+ }
+ else
+- result = "WhereIs cancelled";
++ result = "取消搜尋";
-- 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;
+ if((found & FOUND_IT) && ctmpa){
+ strcpy(last, buf);
+@@ -4798,7 +4797,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 : "找不到該字");
}
-@@ -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 = "沒有任何信件被送出";
+@@ -4813,10 +4812,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++;
+ }
+@@ -4831,9 +4830,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;
+
+ case 0:
+@@ -5370,11 +5369,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 = "";
+@@ -5389,12 +5388,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(rv == 'z'){ /* Cancelled! */
-- rstr = "Send Cancelled";
-+ rstr = "取消送件";
- 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 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, "開啟管線時發生錯誤");
+ else{
+ int maxwidth =min(80,ps->ttyo->screen_cols) - 15;
+@@ -5418,7 +5417,7 @@
+ }
- 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);
+ sprintf(prompt,
+- "Enter text to insert before \"%.*s\": ",k,tmpval);
++ "輸入插在 \"%.*s\" 之前的字串:",k,tmpval);
+ }
+ else if((*cl)->var->is_list
+ && !(*cl)->var->user_val.l
+@@ -5427,13 +5426,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':
+@@ -5447,25 +5446,25 @@
+ }
+
+ 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':
+ i = 1;
+- q_status_message(SM_ORDER,0,3,"Add cancelled");
++ q_status_message(SM_ORDER,0,3,"取消新增");
+ break;
+ }
}
else
-- errstr = "Can't create space for filter temporary file.";
-+ errstr = "無法建立過濾器的暫存檔。";
- }
+- sprintf(prompt, "Enter the %stext to be added : ",
+- flags&CF_NUMBER ? "numeric " : "");
++ sprintf(prompt, "輸入想加入的%s字:",
++ flags&CF_NUMBER ? "數 " : "文");
+
+ ps->mangled_footer = 1;
- if(!errstr){
-@@ -4830,13 +4830,13 @@
- so_give(&tmpf_so);
+@@ -5482,7 +5481,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))
+@@ -5536,7 +5535,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;
}
- else
-- errstr = "Can't open temp file filter wrote.";
-+ errstr = "無法開啟過濾器的暫存檔。";
+
+@@ -5544,7 +5543,7 @@
+ }
+ else{
+ q_status_message1(SM_ORDER, 0, 3,
+- "Can't add %s to list", empty_val);
++ "無法將 %s 加至列表中", empty_val);
}
- else
-- errstr = "Filter command returned error.";
-+ errstr = "過濾器指令傳回錯誤值。";
}
- else
-- errstr = "Can't exec filter text.";
-+ errstr = "無法執行過濾器。";
+ else{
+@@ -5552,7 +5551,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;
+ }
+@@ -5565,7 +5564,7 @@
+ }
}
- 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 @@
+ 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;
+@@ -5588,8 +5587,8 @@
+ }
- if(!pf){
- q_status_message(SM_ORDER,3,3,
-- "Can't send message. No recipients specified!");
-+ "無法送信。尚未指定收信人!");
- return(0);
- }
+ sprintf(prompt,
+- "Enter text to insert %s \"%.*s\": ",
+- after ? "after" : "before", k, tmpval);
++ "輸入想要插在 \"%.*s\" %s的文字",
++ k, tmpval, after ? "之後" : "之前");
+ continue;
+ }
+ else if(i == ctrl('P')){
+@@ -5609,7 +5608,7 @@
+ */
+ if(++repeat_key > 0){
+ q_status_message1(SM_ORDER,3,3,
+- "Minimum value is %s", comatose(lowrange));
++ "最小值是 %s", comatose(lowrange));
+ repeat_key = -5;
+ }
+ }
+@@ -5633,7 +5632,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;
+ }
+ }
+@@ -5686,7 +5685,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)
+@@ -5702,7 +5701,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)
+@@ -5710,8 +5710,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'){
+@@ -5726,7 +5725,7 @@
+ }
+ }
+ else
+- q_status_message(SM_ORDER, 0, 3, "Value not deleted");
++ q_status_message(SM_ORDER, 0, 3, "設定值未被刪除");
+ }
+
+ break;
+@@ -5855,7 +5854,7 @@
+ && !(isdigit((unsigned char)sval[0])
+ || sval[0] == '-' || sval[0] == '+')){
+ q_status_message(SM_ORDER,3,3,
+- "Entry must be numeric");
++ "該項目必須是數字");
+ continue;
+ }
+
+@@ -5869,7 +5868,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;
+@@ -5887,7 +5886,7 @@
+ */
+ if(++repeat_key > 0){
+ q_status_message1(SM_ORDER,3,3,
+- "Minimum value is %s", comatose(lowrange));
++ "最小值是 %s", comatose(lowrange));
+ repeat_key = -5;
+ }
+ }
+@@ -5903,7 +5902,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;
+ }
+ }
+@@ -5990,15 +5989,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);
-@@ -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);
+ case 'x': /* ^C */
+- q_status_message(SM_ORDER,3,5,"Changes not yet saved");
++ q_status_message(SM_ORDER,3,5,"改變尚未被存檔");
+ return(0);
+ }
}
- 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));
+@@ -6290,7 +6289,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;
+ }
+
+@@ -6429,7 +6428,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;
+ }
+
+@@ -6519,15 +6518,15 @@
+ fs_give((void **)&q);
+ }
+
+- 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(p)
+ fs_give((void **)&p);
+ }
+ else
+ q_status_message(SM_ORDER,3,5,
+- "Trouble setting default printer");
++ "有問題的預設印表機");
+
+ retval = 1;
+ }
+@@ -6538,11 +6537,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");
++ "有問題的預設印表機");
+
+ retval = 1;
+ }
+@@ -6557,11 +6556,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");
++ "有問題的預設印表機");
+
+ retval = 1;
+ }
+@@ -6611,7 +6610,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 : ");
+@@ -6643,17 +6642,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;
+ }
+
+@@ -6661,7 +6660,7 @@
+ break;
+ }
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++;
+- strcpy(prompt, "Enter name of printer to be added : ");
++ strcpy(prompt, "欲新增的印表機名稱:");
+
+ ps->mangled_footer = 1;
+ help = NO_HELP;
+@@ -6673,7 +6672,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
+@@ -6690,7 +6689,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;
+@@ -6744,7 +6743,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;
+ }
+@@ -6759,10 +6758,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;
+@@ -6800,19 +6799,19 @@
+ }
+ }
+ 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{
-- 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 @@
+ 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
+- sprintf(prompt, "Really delete item %.20s from printer list ",
++ sprintf(prompt, "確定自印表機列表中刪除 %.20s",
+ int2string((*cl)->varmem + 1));
+ ps->mangled_footer = 1;
+@@ -6822,7 +6821,7 @@
+ config_del_list_item(cl, &newval);
}
else
-- errstr = "Fcc creation error. Message NOT sent or copied.";
-+ errstr = "建立 Fcc 時發生錯誤。信件沒有被送出或複製。";
+- q_status_message(SM_ORDER, 0, 3, "Printer not deleted");
++ q_status_message(SM_ORDER, 0, 3, "印表機未被刪除");
}
- else
-- errstr = "Fcc creation rejected. Message NOT sent or copied.";
-+ errstr = "Fcc 之建立遭拒絕。信件沒有被送出或複製。";
- q_status_message(SM_ORDER | SM_DING, 3, 3, errstr);
+ break;
+@@ -6833,7 +6832,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;
+@@ -6845,22 +6844,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'){
+@@ -6869,7 +6868,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);
+
+@@ -6908,12 +6907,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;
+@@ -6932,7 +6931,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);
+
+@@ -6962,7 +6961,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;
+@@ -6983,18 +6982,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{
+@@ -7003,8 +7002,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);
+@@ -7059,7 +7058,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;
+@@ -7137,18 +7136,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);
+
+ break;
+
+ 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;
+ }
+@@ -7156,7 +7155,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;
+ }
+@@ -7165,9 +7164,9 @@
+
+ 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);
+
+ break;
+@@ -7234,7 +7233,7 @@
+ struct key_menu *km;
+ CONT_SCR_S *cs;
+
+- if(raw_ctxt = context_edit_screen(ps, "ADD", NULL, NULL, NULL, NULL)){
++ if(raw_ctxt = context_edit_screen(ps, "新增", NULL, NULL, NULL, NULL)){
+
+ /* create a corresponding new CONF_S */
+ new_ctxt = new_context(raw_ctxt, NULL);
+@@ -7313,7 +7312,7 @@
+
+ /* Tell the user it was a huge success... */
+ q_status_message(SM_ORDER, 0, 3,
+- "New collection added! Use \"$\" to adjust order.");
++ "新的總集加入了!請用 \"$\" 調整順序。");
}
-@@ -5577,7 +5577,7 @@
- if(label && *label){
- char msg_buf[80];
+ }
+
+@@ -7332,11 +7331,11 @@
-- strncat(strcpy(msg_buf, "Writing "), label, 70);
-+ strncat(strcpy(msg_buf, "正在寫入 "), label, 70);
- we_cancel = busy_alarm(1, msg_buf, NULL, 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;
}
- 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 */
- }
+- 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 */
+@@ -7448,12 +7447,12 @@
+ ps->mangled_body = 1;
+ q_status_message(SM_ORDER, 0, 3,
+ (old_cl == *cl)
+- ? "Last collection deleted. Using default."
+- : "Collection deleted");
++ ? "最後一個總集已被刪除。使用預設值。"
++ : "褻陘w被刪除");
+
}
+ else
+- q_status_message(SM_ORDER, 0, 3, "No collections deleted");
++ q_status_message(SM_ORDER, 0, 3, "沒有任何總集被刪除");
+ }
-@@ -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;
+@@ -7475,7 +7474,7 @@
+ if(p = strstr(tpath, "%s"))
+ *p = '\0';
+
+- 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)){
+
+@@ -7545,7 +7544,7 @@
+
+ set_current_val((*cl)->var, TRUE, FALSE);
+
+- q_status_message(SM_ORDER, 0, 3, "Collection list entry updated");
++ q_status_message(SM_ORDER, 0, 3, "已更新總集列表");
+ }
+ }
+
+@@ -7587,7 +7586,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)))){
+@@ -7686,7 +7685,7 @@
}
}
-@@ -7439,7 +7446,8 @@
+ else
+- q_status_message(SM_ORDER, 0, 3, "Sorry, nothing to Shuffle");
++ q_status_message(SM_ORDER, 0, 3, "很抱歉,沒有東西可供重整");
+ }
- 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 @@
+@@ -8148,7 +8147,7 @@
+ if(cl->var->current_val.l){
+ int i, l, l2;
- 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');
+- sstrcpy(&p, ": using \"");
++ sstrcpy(&p, ":目前使用 \"");
+ for(i = 0; cl->var->current_val.l[i]; i++){
+ if(i)
+ *p++ = ',';
+@@ -8180,7 +8179,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
+@@ -8322,7 +8321,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;
+ }
+ }
+@@ -8360,7 +8359,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 */
+@@ -8529,8 +8528,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);
}
-@@ -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;
+@@ -8829,7 +8828,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;
+@@ -8840,7 +8839,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')
+@@ -8849,7 +8848,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);
+@@ -8909,7 +8908,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;
+@@ -8968,10 +8967,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-be b/chinese/pine4/files/patch-be
index d41961817d33..75442b9f9eab 100644
--- a/chinese/pine4/files/patch-be
+++ b/chinese/pine4/files/patch-be
@@ -1,38 +1,280 @@
---- 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"));
+--- pine/pine.c.orig Wed Jul 22 06:02:36 1998
++++ pine/pine.c Tue Jul 28 08:35:06 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);
+@@ -511,7 +511,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,
+@@ -520,15 +520,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);
+@@ -709,7 +709,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;
+@@ -719,7 +719,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;
+@@ -731,7 +731,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){
+@@ -750,7 +750,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);
+ }
+@@ -895,25 +895,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}
+ };
+
+@@ -1206,7 +1206,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;
+ }
+
+@@ -1234,7 +1234,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;
+
+@@ -1250,14 +1250,14 @@
+ just_a_navigate_cmd++;
+ }
+ else
+- q_status_message(SM_ORDER, 0, 2, "Already at bottom of list");
++ q_status_message(SM_ORDER, 0, 2, "已經在列表底端了");
+
+ break;
+
+
+ /*---------- Release Notes ----------*/
+ case MC_RELNOTES :
+- helper(h_news, "PINE RELEASE NOTES", 0);
++ helper(h_news, "PINE 出版摘要", 0);
+ pine_state->mangled_screen = 1;
+ break;
+
+@@ -1486,7 +1486,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;
}
+@@ -1651,13 +1651,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
+@@ -1735,13 +1735,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 : "下列表單中");
-@@ -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"));
+ 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';
}
- }
-@@ -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{
-- strcpy(busy_message, "Busy");
-+ strcpy(busy_message, "請稍後");
- final_message = 0;
- }
+@@ -1854,14 +1854,14 @@
+ HELP_MENU,
+ NULL_MENU,
+ {"E",NULL,{MC_EXIT,1,{'e',ctrl('M'),ctrl('J')}},KS_NONE},
+- {"Ret","[Be Counted!]",{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
+@@ -1950,13 +1950,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;
+@@ -1967,11 +1967,11 @@
+ setbitmap(sargs.keys.bitmap);
+
+ if(ps->phone_home){
+- km.keys[NUOV_EXIT].label = "Exit this greeting";
++ km.keys[NUOV_EXIT].label = "離開";
+ km.keys[NUOV_EXIT].bind.nch = 1;
+ }
+ else{
+- km.keys[NUOV_EXIT].label = "[Exit this greeting]";
++ km.keys[NUOV_EXIT].label = "[離開]";
+ km.keys[NUOV_EXIT].bind.nch = 3;
+ clrbitn(NUOV_VIEW, sargs.keys.bitmap);
+ }
+@@ -2029,7 +2029,7 @@
+ break;
+
+ case MC_RELNOTES :
+- helper(h_news, "PINE RELEASE NOTES", 0);
++ helper(h_news, "PINE 出版摘要", 0);
+ ps_global->mangled_screen = 1;
+ break;
+
+@@ -2148,7 +2148,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-bf b/chinese/pine4/files/patch-bf
index 3511b27d750d..b4119c77fb4f 100644
--- a/chinese/pine4/files/patch-bf
+++ b/chinese/pine4/files/patch-bf
@@ -1,40 +1,141 @@
---- 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...
+--- pine/pine.h.orig Wed Jul 22 06:02:49 1998
++++ pine/pine.h Tue Jul 28 08:35:06 1998
+@@ -348,7 +348,7 @@
+ && (s) && !strucmp((s),"X-VCARD")))
+ #define MIME_VCARD_A(a) MIME_VCARD((a)->body->type, (a)->body->subtype)
+
+-#define STYLE_NAME(a) ((a)->text.desc ? (a)->text.desc : "text")
++#define STYLE_NAME(a) ((a)->text.desc ? (a)->text.desc : "文字")
+
+
+ /*
+@@ -1582,91 +1582,91 @@
+ * Some standard Key/Command Bindings
*/
- static ESCKEY_S yorn[] = {
-- {'y', 'y', "Y", "Yes"},
-- {'n', 'n', "N", "No"},
-+ {'y', 'y', "Y", "是"},
-+ {'n', 'n', "N", "否"},
- {-1, 0, NULL, NULL}
- };
+ #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}
+
+@@ -2304,7 +2304,7 @@
+ } ATABLE_S;
-@@ -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++;
+-#define TAG_EMBED '\377' /* Announces embedded data in text string */
++#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'
diff --git a/chinese/pine4/files/patch-bg b/chinese/pine4/files/patch-bg
index f8387b0df223..c4f9f9bd948f 100644
--- a/chinese/pine4/files/patch-bg
+++ b/chinese/pine4/files/patch-bg
@@ -1,56 +1,155 @@
---- 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;
-
- 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){
+--- pine/reply.c.orig Wed Jul 15 08:40:00 1998
++++ pine/reply.c Tue Jul 28 08:35:06 1998
+@@ -88,9 +88,9 @@
+ /*
+ * Little defs to keep the code a bit neater...
+ */
+-#define FRM_PMT "Use \"Reply-To:\" address instead of \"From:\" address"
+-#define ALL_PMT "Reply to all recipients"
+-#define NEWS_PMT "Follow-up to news group(s), Reply via email to author or Both? "
++#define FRM_PMT "使用 \"Reply-To:\" 地址代替 \"From:\" 地址"
++#define ALL_PMT "回覆給所有的收信者"
++#define NEWS_PMT "回覆至新聞組群,回函給作者或兩者皆要?"
+
+ /*
+ * standard type of storage object used for body parts...
+@@ -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);
+
+ if(ret == 'x') {
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ return(0);
+ }
+
+@@ -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}
+ };
+@@ -1110,19 +1110,18 @@
+ return(1);
+
+ while(1){
+- sprintf(tmp_20k_buf, "Include %s%soriginal message%s in Reply%s%s%s? ",
+- (many > 1L) ? comatose(many) : "",
+- (many > 1L) ? " " : "",
+- (many > 1L) ? "s" : "",
+- F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? " (using \"" : "",
++ sprintf(tmp_20k_buf, "在回函%s%s%s中包含%s%s原本的訊息?",
++ F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? "(使用 \"" : "",
+ F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? *prefix : "",
+- F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? "\")" : "");
++ F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? "\" 為引言標示代號)" : "",
++ (many > 1L) ? comatose(many) : "",
++ (many > 1L) ? " " : "");
+
+ if(F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps)){
+ rtq_opts[2].ch = ctrl('R');
+ rtq_opts[2].rval = 'r';
+ rtq_opts[2].name = "^R";
+- rtq_opts[2].label = "Edit Indent String";
++ rtq_opts[2].label = "編輯引言標示代號";
+ }
+ else
+ rtq_opts[2].ch = -1;
+@@ -1133,7 +1132,7 @@
+ rtq_opts, edited ? 'y' : 'n',
+ 'x', NO_HELP, RB_SEQ_SENSITIVE)){
case 'x':
-- cancel_warning(NO_DING, "Export");
-+ cancel_warning(NO_DING, "匯出");
- break;
-
- case 't':
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ return(-1);
+
+ case 'r':
+@@ -1152,7 +1151,7 @@
+
+ switch(optionally_enter(buf, ps->ttyo->screen_rows > 4
+ ? -FOOTER_ROWS(ps_global) : -1,
+- 0, 63, "Reply prefix : ",
++ 0, 63, "引言標示代號:",
+ NULL, NO_HELP, &flags)){
+ case 0: /* entry successful, continue */
+ if(flags & OE_USER_MODIFIED){
+@@ -1165,7 +1164,7 @@
+ break;
+
+ case 1:
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+
+ case -1:
+ return(-1);
+@@ -1518,9 +1517,9 @@
+ ENVELOPE *env, *outgoing;
+ {
+ int ret = 1;
+- static ESCKEY_S news_opt[] = { {'f', 'f', "F", "Follow-up"},
+- {'r', 'r', "R", "Reply"},
+- {'b', 'b', "B", "Both"},
++ static ESCKEY_S news_opt[] = { {'f', 'f', "F", "回覆至版上"},
++ {'r', 'r', "R", "回給作者"},
++ {'b', 'b', "B", "兩者皆要"},
+ {-1, 0, NULL, NULL} };
+
+ if(env->newsgroups && *env->newsgroups && !reply_poster_followup(env))
+@@ -1544,7 +1543,7 @@
+
+ case 'x' : /* cancel or unknown response */
+ default :
+- cmd_cancelled("Reply");
++ cmd_cancelled("回覆");
+ ret = 0;
+ break;
+ }
+@@ -1552,7 +1551,7 @@
+ if(ret > 1){
+ if(env->followup_to){
+ q_status_message(SM_ORDER, 2, 3,
+- "Posting to specified Followup-To groups");
++ "刊登至特定的回覆組群");
+ outgoing->newsgroups = cpystr(env->followup_to);
+ }
+ else if(!outgoing->newsgroups)
+@@ -1710,7 +1709,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]!!! */
+@@ -1842,7 +1841,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);
+
+ clean:
diff --git a/chinese/pine4/files/patch-bh b/chinese/pine4/files/patch-bh
index 87f51d4e53dd..b2f4dd7dffa9 100644
--- a/chinese/pine4/files/patch-bh
+++ b/chinese/pine4/files/patch-bh
@@ -1,52 +1,109 @@
---- build.orig Tue Jun 16 01:35:10 1998
-+++ build Wed Jul 15 17:02:29 1998
-@@ -256,11 +256,11 @@
+--- pine/screen.c.orig Fri Jun 5 04:09:17 1998
++++ pine/screen.c Tue Jul 28 08:35:06 1998
+@@ -433,7 +433,7 @@
- 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
- ;;
+ 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);
+
+ 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);
+
+ 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 @@
+
+ as.current_line = new_line_number;
+
+- 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-bi b/chinese/pine4/files/patch-bi
new file mode 100644
index 000000000000..1e6bff27732b
--- /dev/null
+++ b/chinese/pine4/files/patch-bi
@@ -0,0 +1,689 @@
+--- pine/send.c.orig Tue Jul 21 03:02:18 1998
++++ pine/send.c Tue Jul 28 08:35:07 1998
+@@ -374,14 +374,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);
+@@ -450,14 +450,14 @@
+
+ if(ret == 'x'){
+ q_status_message(SM_ORDER, 0, 3,
+- "Composition cancelled");
++ "取消編輯");
+ done++;
+ }
+ }
+ }
+ else{
+ q_status_message1(SM_ORDER | SM_DING, 3, 3,
+- "Can't open Postponed mailbox: %s", mbox);
++ "無法開遭暫緩的信箱:%s", mbox);
+ if(stream)
+ mail_close(stream);
+ }
+@@ -532,7 +532,7 @@
+
+ if(ret == 'x'){
+ q_status_message(SM_ORDER, 0, 3,
+- "Composition cancelled");
++ "取消編輯");
+ done++;
+ }
+ }
+@@ -616,7 +616,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){
+@@ -683,7 +683,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){
+@@ -719,7 +719,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 */
+ }
+@@ -957,7 +957,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");
+@@ -965,7 +965,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));
+ }
+@@ -979,7 +979,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));
+@@ -1307,7 +1307,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);
+ }
+
+@@ -1396,7 +1396,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);
+ }
+
+@@ -1452,7 +1452,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);
+ }
+
+@@ -1479,31 +1479,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,
+@@ -1538,7 +1538,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,
+@@ -1831,7 +1831,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;
+
+ /*----------------------------------------------------------------------
+@@ -1942,12 +1942,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)){
+@@ -1994,7 +1994,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)
+@@ -2174,7 +2174,7 @@
+ }
+ }
+ else{
+- q_status_message(SM_ORDER, 0, 3, "Send cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消寄件");
+ retval = -1;
+ }
+ }
+@@ -2202,7 +2202,7 @@
+ break;
+
+ case 1:
+- q_status_message(SM_ORDER, 0, 3, "Send cancelled");
++ q_status_message(SM_ORDER, 0, 3, "取消寄件");
+ done++;
+ retval = -1;
+ break;
+@@ -2446,7 +2446,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;
+
+@@ -2863,7 +2863,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;
+@@ -3206,7 +3206,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;
+ }
+
+@@ -3484,15 +3484,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 */
+ }
+@@ -3557,8 +3557,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;
+ }
+
+@@ -3948,23 +3948,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) ? "\"" : "");
+@@ -4291,12 +4291,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 */
+@@ -4304,12 +4304,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;
+@@ -4379,23 +4379,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
+@@ -4410,11 +4410,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){
+@@ -4438,11 +4438,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 */
+@@ -4624,7 +4624,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));
+ }
+@@ -4673,7 +4673,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",
+@@ -4685,7 +4685,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);
+ }
+@@ -4738,7 +4738,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++;
+@@ -4816,7 +4816,7 @@
+ so_give(&tmpf_so);
+ }
+ else
+- errstr = "Can't create space for filter temporary file.";
++ errstr = "無法建立過濾器的暫存檔。";
+ }
+
+ if(!errstr){
+@@ -4840,13 +4840,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
+ errstr = gf_filter(cmd, key ? filter_session_key() : NULL,
+@@ -4857,7 +4857,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)
+@@ -4950,7 +4950,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));
+ }
+@@ -5035,11 +5035,11 @@
+
+ loser = pine_simple_send(outgoing, &body, NULL, NULL, NULL, 0);
+
+- q_status_message(SM_ORDER, 0, 3, "Thanks for being counted!");
++ q_status_message(SM_ORDER, 0, 3, "感謝您願意被計算為 Pine 的使用者!");
+ }
+ else
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+- "Problem creating space for message text.");
++ "建立訊息文字空間時發生錯誤。");
+
+ mail_free_envelope(&outgoing);
+ pine_free_body(&body);
+@@ -5123,7 +5123,7 @@
+
+ if(!pf){
+ q_status_message(SM_ORDER,3,3,
+- "Can't send message. No recipients specified!");
++ "無法送信。尚未指定收信人!");
+ return(0);
+ }
+
+@@ -5132,7 +5132,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 */
+@@ -5317,7 +5317,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 : "");
+@@ -5390,7 +5390,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){
+@@ -5487,12 +5487,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'){
+@@ -5529,7 +5529,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'){
+ /*
+@@ -5563,8 +5563,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);
+@@ -5582,10 +5582,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);
+ }
+@@ -5633,7 +5633,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
+@@ -5669,7 +5669,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);
+@@ -6145,7 +6145,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;
+@@ -6672,13 +6672,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 */
+ }
+ }
+
+@@ -6847,6 +6851,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, len;
+ char *actual_field;
+@@ -7180,7 +7187,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;
+ }
+ }
+@@ -7508,7 +7515,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 */
+@@ -7522,7 +7530,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');
+ }
+
+@@ -7575,7 +7583,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]);
+@@ -8137,7 +8145,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-bj b/chinese/pine4/files/patch-bj
new file mode 100644
index 000000000000..c8e60c07c613
--- /dev/null
+++ b/chinese/pine4/files/patch-bj
@@ -0,0 +1,38 @@
+--- pine/signals.c.orig Tue Jul 7 07:42:45 1998
++++ pine/signals.c Tue Jul 28 08:35:07 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"));
+ }
+
+@@ -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{
+- strcpy(busy_message, "Busy");
++ strcpy(busy_message, "請稍後");
+ final_message = 0;
+ }
+
diff --git a/chinese/pine4/files/patch-bk b/chinese/pine4/files/patch-bk
new file mode 100644
index 000000000000..eb017e28227b
--- /dev/null
+++ b/chinese/pine4/files/patch-bk
@@ -0,0 +1,40 @@
+--- pine/status.c.orig Sat Jun 27 07:36:34 1998
++++ pine/status.c Tue Jul 28 08:35:07 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}
+ };
+
+@@ -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-bl b/chinese/pine4/files/patch-bl
new file mode 100644
index 000000000000..28d46c24b640
--- /dev/null
+++ b/chinese/pine4/files/patch-bl
@@ -0,0 +1,56 @@
+--- pine/takeaddr.c.orig Fri Jun 26 02:26:36 1998
++++ pine/takeaddr.c Tue Jul 28 08:35:08 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;
+
+ 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-bm b/chinese/pine4/files/patch-bm
new file mode 100644
index 000000000000..02ab5e1e4dfe
--- /dev/null
+++ b/chinese/pine4/files/patch-bm
@@ -0,0 +1,52 @@
+--- build.orig Tue Jun 16 01:35:10 1998
++++ build Tue Jul 28 08:34:58 1998
+@@ -256,11 +256,11 @@
+
+ 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/pine.conf b/chinese/pine4/files/pine.conf
index eaca17236393..883488f1bb20 100644
--- a/chinese/pine4/files/pine.conf
+++ b/chinese/pine4/files/pine.conf
@@ -25,6 +25,10 @@
feature-list=enable-8bit-esmtp-negotiation,
enable-arrow-navigation
+# 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=ISO-8859-1
+
#
# needed for qmail 1.01 (also compatible with sendmail)
#smtp-server=localhost
diff --git a/chinese/pine4/pkg-plist b/chinese/pine4/pkg-plist
index 9d38f1a6d045..e248682c9eaf 100644
--- a/chinese/pine4/pkg-plist
+++ b/chinese/pine4/pkg-plist
@@ -1,16 +1,27 @@
-bin/pgpencrypt
bin/pgpdecode
+bin/pgpencrypt
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
man/man1/pico.1.gz
man/man1/pilot.1.gz
man/man1/pine.1.gz
+share/doc/pine/brochure.txt
share/doc/pine/tech-notes.txt
+share/doc/pine/tech-notes/background.html
+share/doc/pine/tech-notes/cmd-line.html
+share/doc/pine/tech-notes/config-notes.html
+share/doc/pine/tech-notes/config.html
+share/doc/pine/tech-notes/index.html
+share/doc/pine/tech-notes/installation.html
+share/doc/pine/tech-notes/introduction.html
+share/doc/pine/tech-notes/low-level.html
+share/doc/pine/tech-notes/porting.html
+@dirrm share/doc/pine/tech-notes
+@dirrm share/doc/pine