diff options
author | vanilla <vanilla@FreeBSD.org> | 1998-07-30 20:30:41 +0800 |
---|---|---|
committer | vanilla <vanilla@FreeBSD.org> | 1998-07-30 20:30:41 +0800 |
commit | 54581800657a25369d0f03a2d3e88415b56af1b5 (patch) | |
tree | 65ef4473271c940079728fa4b2ada1b4162de457 /chinese/pine4/files | |
parent | 38ce42754980ad2434cd9880d4dbf152657abbff (diff) | |
download | freebsd-ports-gnome-54581800657a25369d0f03a2d3e88415b56af1b5.tar.gz freebsd-ports-gnome-54581800657a25369d0f03a2d3e88415b56af1b5.tar.zst freebsd-ports-gnome-54581800657a25369d0f03a2d3e88415b56af1b5.zip |
Upgrade to 4.02,
Submitted by: maintainer
Diffstat (limited to 'chinese/pine4/files')
39 files changed, 13009 insertions, 12947 deletions
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 |