FDclone 2.09a patch [1/3]
しらいです。
file & directory 管理ツール FDclone 2.09a の patch その 1
です。
Submitted-by: shirai@chandra2
Archive-name: FD-2.09a.patch/part01
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is FD-2.09a.patch, a shell archive (produced by GNU sharutils 4.2)
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2006-10-31 00:00 JST by <shirai@chandra2>.
# Source directory was `/usr/home/shirai/src/fd2'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This is part 1 of a multipart archive.
# Do not concatenate these parts, unpack them in order with `/bin/sh'.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 113842 -rw-r--r-- FD-2.09a.patch
#
echo=echo
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh00584; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
if test -r _sh00584/seq; then
$echo 'Must unpack archives in sequence!'
$echo 'Please unpack part' '`cat _sh00584/seq`' 'next!'
exit 1
fi
# ============= FD-2.09a.patch ==============
if test -f 'FD-2.09a.patch' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'FD-2.09a.patch' '(file already exists)'
rm -f _sh00584/new
else
> _sh00584/new
$echo 'x -' extracting 'FD-2.09a.patch' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'FD-2.09a.patch' &&
diff -urNP ../FD-2.09/HISTORY ./HISTORY
--- ../FD-2.09/HISTORY Tue Aug 22 00:00:00 2006
+++ ./HISTORY Tue Oct 31 00:00:00 2006
@@ -1,3 +1,11 @@
+Ver. 2.09a GNU tar のハードリンクされたアーカイブファイルに対応。
+ (10/31/06) ファイルロック時にタイムアウトを設定。
+ Cygwin で共有フォルダを扱えなかった点を修正。
+ 幾つかの漢字コード設定で UTF8-mac が効かなかった点を修正。
+ PTYMODE=1 時に日本語入力の文字化けが起こることがある点を修正。
+ IGNORECASE=1 時にファイル名ソート順がおかしかった点を修正。
+ 一部端末環境でファンクションキーが効かなかった点を修正。
+
X Ver. 2.09 内部変数 IMEKEY, IMEBUFFER の追加。
X (08/22/06) 内部変数 BASICCUSTOM の追加。
X 内部変数 PROGRESSBAR, PRECOPYMENU の追加。
diff -urNP ../FD-2.09/HISTORY.eng ./HISTORY.eng
--- ../FD-2.09/HISTORY.eng Tue Aug 22 00:00:00 2006
+++ ./HISTORY.eng Tue Oct 31 00:00:00 2006
@@ -1,3 +1,11 @@
+Ver. 2.09a Support hard-linked archive files with GNU tar.
+ (10/31/06) Support timeout of locking files.
+ Bug that shared folder cannot be accessed on Cygwin is fixed.
+ Bug that UTF8-mac cannot work in some code settings is fixed.
+ Bug that some Japanese input is broken on PTYMODE=1 is fixed.
+ Mis-sorting order for filenames on IGNORECASE=1 is fixed.
+ Bug that function keys cannot work in some terminals is fixed.
+
X Ver. 2.09 Add 'IMEKEY', 'IMEBUFFER' internal variables.
X (08/22/06) Add 'BASICCUSTOM' internal variable.
X Add 'PROGRESSBAR', 'PRECOPYMENU' internal variables.
diff -urNP ../FD-2.09/LICENSES ./LICENSES
--- ../FD-2.09/LICENSES Tue Aug 22 00:00:00 2006
+++ ./LICENSES Tue Oct 31 00:00:00 2006
@@ -114,7 +114,7 @@
X 責任を持って対処することを作者は希望します。
X
X 但し、使用にあたって生じた如何なる損害に対しても、作者は保
-障し兼ねますので、各利用者は自己責任にてご利用下さい。
+証し兼ねますので、各利用者は自己責任にてご利用下さい。
X
X
X <5.ソース頒布登録について>
diff -urNP ../FD-2.09/README ./README
--- ../FD-2.09/README Tue Aug 22 00:00:00 2006
+++ ./README Tue Oct 31 00:00:00 2006
@@ -3,7 +3,7 @@
X # FDclone Ver. 2.09 に関して
X #
X # Takashi SHIRAI, <shirai@unixusers.net>
-# Aug 22, 2006
+# Oct 31, 2006
X #
X ############################################################
X
diff -urNP ../FD-2.09/README.eng ./README.eng
--- ../FD-2.09/README.eng Tue Aug 22 00:00:00 2006
+++ ./README.eng Tue Oct 31 00:00:00 2006
@@ -3,7 +3,7 @@
X # About FDclone Ver. 2.09
X #
X # Takashi SHIRAI, <shirai@unixusers.net>
-# Aug 22, 2006
+# Oct 31, 2006
X #
X ############################################################
X
diff -urNP ../FD-2.09/TECHKNOW ./TECHKNOW
--- ../FD-2.09/TECHKNOW Tue Aug 22 00:00:00 2006
+++ ./TECHKNOW Tue Oct 31 00:00:00 2006
@@ -52,6 +52,10 @@
X CWDINPATH
X コマンドサーチパスに暗黙の了解としてカレントディレク
X トリが含まれています。
+DOUBLESLASH
+ // (または \\) で始まるパス名が、特殊な意味を持つパ
+ ス名 (実例としては Cygwin に於ける共有フォルダ) とし
+ て許容されている。
X USEMANLANG
X man(1) の参照する検索パス名が、/usr/man/ja_JP.SJIS/
X のように環境変数 LANG で示される文字列を含み、多国語
diff -urNP ../FD-2.09/TECHKNOW.eng ./TECHKNOW.eng
--- ../FD-2.09/TECHKNOW.eng Tue Aug 22 00:00:00 2006
+++ ./TECHKNOW.eng Tue Oct 31 00:00:00 2006
@@ -53,6 +53,10 @@
X CWDINPATH
X The current work directory is always included in
X the command search path implicitly.
+DOUBLESLASH
+ The pathname which starts with // (or \\) is allowed
+ as the some special pathname (e.g. the shared folder
+ on Cygwin).
X USEMANLANG
X The search pathname referred to man(1) includes the
X string shown by the environment variable LANG, such
diff -urNP ../FD-2.09/apply.c ./apply.c
--- ../FD-2.09/apply.c Tue Aug 22 00:00:00 2006
+++ ./apply.c Tue Oct 31 00:00:00 2006
@@ -250,8 +250,7 @@
X
X #ifndef _NODOSDRIVE
X destdrive = -1;
- if ((drive = dospath3(dir))
- && (destdrive = preparedrv(drive)) < 0) {
+ if ((drive = dospath3(dir)) && (destdrive = preparedrv(drive)) < 0) {
X warning(-1, dir);
X free(dir);
X return(NULL);
@@ -298,10 +297,13 @@
X static int NEAR getcopypolicy(s)
X char *s;
X {
-#if !defined (_NOEXTRACOPY) && !defined (_NODOSDRIVE)
+#ifndef _NOEXTRACOPY
+# ifndef _NODOSDRIVE
X int dupdestdrive;
-#endif
- char *cp, *str[MAXCOPYITEM];
+# endif
+ char *cp;
+#endif /* !_NOEXTRACOPY */
+ char *str[MAXCOPYITEM];
X int n, ch, val[MAXCOPYITEM];
X
X for (;;) {
@@ -855,7 +857,7 @@
X char dest[MAXPATHLEN];
X
X if (getdestpath(path, dest, &st) < 0) return(APL_CANCEL);
- st.st_nlink = destnlink;
+ st.st_nlink = (destnlink | TCH_IGNOREERR);
X st.st_mode = destmode;
X st.st_mtime = destmtime;
X st.st_atime = destatime;
@@ -900,7 +902,7 @@
X char dest[MAXPATHLEN];
X
X if (getdestpath(path, dest, &st) < 0) return(APL_CANCEL);
- st.st_nlink = destnlink;
+ st.st_nlink = (destnlink | TCH_IGNOREERR);
X st.st_mode = destmode;
X st.st_mtime = destmtime;
X st.st_atime = destatime;
@@ -1637,7 +1639,7 @@
X
X helpbar();
X for (filepos = 0; filepos < maxfile; filepos++) {
- if (intrkey()) {
+ if (intrkey(K_ESC)) {
X endmes = NULL;
X break;
X }
@@ -1718,7 +1720,7 @@
X char *cp, *fname, path[MAXPATHLEN], **dirlist;
X int ret, ndir, max, dupnlink;
X
- if (intrkey()) return(APL_CANCEL);
+ if (intrkey(K_ESC)) return(APL_CANCEL);
X
X if (verbose) {
X Xlocate(0, L_CMDLINE);
@@ -1785,7 +1787,7 @@
X if (!(dirp = Xopendir(dir))) warning(-1, dir);
X else {
X while ((dp = Xreaddir(dirp))) {
- if (intrkey()) {
+ if (intrkey(K_ESC)) {
X ret = APL_CANCEL;
X break;
X }
@@ -2017,7 +2019,8 @@
X st.st_flags = (u_long)-1;
X #endif
X
- st.st_nlink = (TCH_MODE | TCH_UID | TCH_GID | TCH_ATIME | TCH_MTIME);
+ st.st_nlink = (TCH_MODE | TCH_UID | TCH_GID
+ | TCH_ATIME | TCH_MTIME | TCH_IGNOREERR);
X if (touchfile(dest, &st) < 0) return(APL_ERROR);
X
X return(APL_OK);
@@ -2058,7 +2061,8 @@
X st.st_flags = (u_long)-1;
X #endif
X
- st.st_nlink = (TCH_MODE | TCH_UID | TCH_GID | TCH_ATIME | TCH_MTIME);
+ st.st_nlink = (TCH_MODE | TCH_UID | TCH_GID
+ | TCH_ATIME | TCH_MTIME | TCH_IGNOREERR);
X if (touchfile(dest, &st) < 0) return(APL_ERROR);
X
X return(APL_OK);
diff -urNP ../FD-2.09/archive.c ./archive.c
--- ../FD-2.09/archive.c Tue Aug 22 00:00:00 2006
+++ ./archive.c Tue Oct 31 00:00:00 2006
@@ -30,8 +30,6 @@
X extern off_t marksize;
X extern namelist filestack[];
X extern char fullpath[];
-extern char typesymlist[];
-extern u_short typelist[];
X #ifndef _NOCOLOR
X extern int ansicolor;
X #endif
@@ -149,7 +147,9 @@
X #define isarchbr(l) (((l) -> topskip) < (u_char)255)
X #endif /* FD < 2 */
X
-#define iswhitespace(c) ((c) == ' ' || (c) == '\t')
+#define IGNORETYPESYM "-VMNLhC"
+#define SYMLINKSTR "->"
+#define GNULINKSTR "link to"
X
X #ifndef _NOBROWSE
X static VOID NEAR copyargvar __P_((int, char **));
@@ -170,6 +170,9 @@
X # else
X static char *NEAR readfname __P_((char *, int));
X # endif
+# ifndef NOSYMLINK
+static char *NEAR readlinkname __P_((char *, char *));
+# endif
X static int NEAR readfileent __P_((namelist *, char *, char *, int));
X #else /* FD < 2 */
X static int NEAR countfield __P_((char *, u_char [], int, int *));
@@ -196,6 +199,10 @@
X static char *NEAR genfullpath __P_((char *, char *, char *, char *));
X static int NEAR archdostmpdir __P_((char *, char **, char *));
X #endif
+#ifndef NOSYMLINK
+static int NEAR archrealpath __P_((char *, char *));
+static int NEAR unpacklink __P_((namelist *, char *));
+#endif
X
X int maxlaunch = 0;
X int maxarchive = 0;
@@ -261,6 +268,13 @@
X char **browsevar = NULL;
X #endif
X
+#ifndef NOSYMLINK
+static CONST strtable linklist[] = {
+ {strsize(SYMLINKSTR), SYMLINKSTR},
+ {strsize(GNULINKSTR), GNULINKSTR},
+};
+#define LINKLISTSIZ arraysize(linklist)
+#endif /* !NOSYMLINK */
X #if FD >= 2
X static char *autoformat[] = {
X # if MSDOS
@@ -463,21 +477,18 @@
X namelist *tmp;
X char *buf;
X {
- int i, c, len;
- u_int mode;
+ int i, len;
+ u_int n, mode;
X
X len = strlen(buf);
X if (len < 9) {
X mode = (tmp -> st_mode & S_IFMT) | S_IREAD_ALL | S_IWRITE_ALL;
X while (--len >= 0) {
- c = tolower2(buf[len]);
- for (i = 0; typesymlist[i]; i++)
- if (c == typesymlist[i]) break;
- if (typesymlist[i]) {
+ if ((n = getfmode(buf[len])) != (u_int)-1) {
X mode &= ~S_IFMT;
- mode |= typelist[i];
+ mode |= n;
X }
- else switch (c) {
+ else switch (tolower2(buf[len])) {
X case 'a':
X mode |= S_ISVTX;
X break;
@@ -544,13 +555,11 @@
X else if (buf[i] == 'T') mode |= S_ISVTX;
X else if (buf[i] != '-') return(0);
X
- if (len >= 10 && buf[len - 10] != '-') {
- c = tolower2(buf[len - 10]);
- for (i = 0; typesymlist[i]; i++)
- if (c == typesymlist[i]) break;
- if (!typesymlist[i]) return(0);
+ if (len >= 10 && !strchr(IGNORETYPESYM, buf[len - 10])) {
+ n = getfmode(buf[len - 10]);
+ if (n == (u_int)-1) return(0);
X mode &= ~S_IFMT;
- mode |= typelist[i];
+ mode |= n;
X }
X }
X tmp -> st_mode = mode;
@@ -565,14 +574,14 @@
X {
X int i, len;
X
- if (iswhitespace(*s)) {
+ if (isblank2(*s)) {
X (*scorep)++;
- for (s++; iswhitespace(*s); s++);
+ s = skipspace(&(s[1]));
X }
X for (i = 0; s[len = i]; i++) {
- if (iswhitespace(s[i])) {
+ if (isblank2(s[i])) {
X (*scorep)++;
- for (i++; iswhitespace(s[i]); i++);
+ for (i++; isblank2(s[i]); i++);
X if (!s[i]) break;
X *scorep += 4;
X }
@@ -596,6 +605,24 @@
X }
X # endif /* !_NOKANJIFCONV */
X
+# ifndef NOSYMLINK
+static char *NEAR readlinkname(s, eol)
+char *s, *eol;
+{
+ int i;
+
+ for (i = 0; i < LINKLISTSIZ; i++) {
+ if (&(s[linklist[i].no]) > eol) continue;
+ if (!strncmp(s, linklist[i].str, linklist[i].no)) {
+ s += linklist[i].no;
+ return(skipspace(s));
+ }
+ }
+
+ return(NULL);
+}
+# endif /* !NOSYMLINK */
+
X static int NEAR readfileent(tmp, line, form, skip)
X namelist *tmp;
X char *line, *form;
@@ -607,11 +634,14 @@
X uid_t uid;
X gid_t gid;
X # endif
+# ifndef NOSYMLINK
+ char *lname;
+# endif
X time_t now;
X struct tm tm, *tp;
X off_t n;
X int i, ch, l, len, hit, err, err2, score;
- char *cp, *s, *buf, *rawbuf;
+ char *cp, *s, *buf, *eol, *rawbuf;
X
X if (skip && skip > strlen(form)) return(-1);
X
@@ -630,14 +660,14 @@
X tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
X score = 0;
X
- while (*form) if (iswhitespace(*form)) {
- while (iswhitespace(*line)) line++;
+ while (*form) if (isblank2(*form)) {
+ line = skipspace(line);
X form++;
X }
X else if (*form == '\n') {
X if (*line != *(form++)) score += 20;
X else line++;
- while (iswhitespace(*line)) line++;
+ line = skipspace(line);
X }
X else if (*form != '%' || *(++form) == '%') {
X ch = *(form++);
@@ -686,14 +716,14 @@
X }
X
X if (len < 0) {
- if (!iswhitespace(*form)
+ if (!isblank2(*form)
X && (*form != '%' || *(form + 1) == '%'))
X ch = *form;
X for (len = 0; line[len]; len++) {
X if (ch) {
X if (ch == line[len]) break;
X }
- else if (iswhitespace(line[len])) break;
+ else if (isblank2(line[len])) break;
X }
X }
X
@@ -792,28 +822,31 @@
X tm.tm_sec = i;
X break;
X case 'f':
+ eol = &(rawbuf[len]);
+# ifndef NOSYMLINK
+ lname = NULL;
+# endif
X for (i = 0; i < len; i++) {
+ cp = &(rawbuf[i]);
X # if MSDOS
X # ifdef BSPATHDELIM
- if (rawbuf[i] == '/') rawbuf[i] = _SC_;
+ if (*cp == '/') *cp = _SC_;
X # else
- if (rawbuf[i] == '\\')
- rawbuf[i] = _SC_;
+ if (*cp == '\\') *cp = _SC_;
X if (iskanji1(rawbuf, i)) {
X i++;
X continue;
X }
X # endif
X # endif /* MSDOS */
- if (!iswhitespace(rawbuf[i])) continue;
- cp = &(rawbuf[i]);
- for (cp++; iswhitespace(*cp); cp++);
- if (cp >= &(rawbuf[len])) {
+ if (!isblank2(*cp)) continue;
+ cp = skipspace(&(cp[1]));
+ if (cp >= eol) {
X if (!ch) i = len;
X break;
X }
X # ifndef NOSYMLINK
- if (cp[0] == '-' && cp[1] == '>')
+ if ((lname = readlinkname(cp, eol)))
X break;
X # endif
X }
@@ -830,17 +863,17 @@
X hit++;
X err = 0;
X # ifndef NOSYMLINK
- while (iswhitespace(*cp)) cp++;
+ if (!lname) break;
+ cp = skipspace(cp);
X if (ch && cp >= &(line[len])) break;
- if (cp[0] != '-' || cp[1] != '>') break;
- for (cp += 2; iswhitespace(*cp); cp++);
- for (i = 0; cp[i]; i++)
- if (iswhitespace(cp[i])) break;
+ lname = &(line[lname - rawbuf]);
+ for (i = 0; lname[i]; i++)
+ if (isblank2(lname[i])) break;
X if (i) {
X if (tmp -> linkname)
X free(tmp -> linkname);
- tmp -> linkname = readfname(cp, i);
- i = &(cp[i]) - line;
+ tmp -> linkname = readfname(lname, i);
+ i = &(lname[i]) - line;
X if (i > len) len = i;
X }
X # endif
@@ -869,7 +902,7 @@
X else if (hit <= err2) score += err2;
X score += err;
X line += len;
- if (!ch) while (iswhitespace(*line)) line++;
+ if (!ch) line = skipspace(line);
X }
X
X if (score >= MAXSCORE || !(tmp -> name) || !*(tmp -> name)) {
@@ -939,12 +972,12 @@
X j++;
X sp = (j < MAXLAUNCHSEP) ? (int)sep[j] : 255;
X for (; sp == 255 || i < sp; i++)
- if (!iswhitespace(line[i])) break;
+ if (!isblank2(line[i])) break;
X if (f < 0) f = 1;
X else f++;
X s = 0;
X }
- else if (iswhitespace(line[i])) s = 1;
+ else if (isblank2(line[i])) s = 1;
X else if (s) {
X f++;
X s = 0;
@@ -956,7 +989,7 @@
X if (eolp) {
X for (j = i; line[j]; j++) {
X if ((sp < 255 && j >= sp)
- || iswhitespace(line[j]))
+ || isblank2(line[j]))
X break;
X }
X *eolp = j;
@@ -1372,13 +1405,13 @@
X for (i = 0; !ret && argv[i]; i++) {
X s1 = argv[i];
X s2 = s;
- if (!iswhitespace(s1[0])) while (iswhitespace(*s2)) s2++;
+ if (!isblank2(s1[0])) s2 = skipspace(s2);
X len = strlen(s1);
- if (!len || iswhitespace(s1[len - 1])) s2 = strdup2(s2);
+ if (!len || isblank2(s1[len - 1])) s2 = strdup2(s2);
X else {
X len = strlen(s2);
X for (len--; len >= 0; len--)
- if (!iswhitespace(s2[len])) break;
+ if (!isblank2(s2[len])) break;
X s2 = strndup2(s2, ++len);
X }
X re = regexp_init(s1, -1);
@@ -1441,7 +1474,7 @@
X lvar[++nline] = NULL;
X }
X
- if (isttyiomode && intrkey()) return(-2);
+ if (isttyiomode && intrkey(K_ESC)) return(-2);
X #if FD >= 2
X if (matchlist(lvar[0], lign)) {
X free(lvar[0]);
@@ -2526,6 +2559,77 @@
X return((ret) ? 0 : 1);
X }
X
+#ifndef NOSYMLINK
+static int NEAR archrealpath(path, resolved)
+char *path, *resolved;
+{
+ char *cp, tmp[MAXPATHLEN];
+ int n;
+
+ if (!*path || (n = isdotdir(path)) == 2) /*EMPTY*/;
+ else if (n == 1) {
+ cp = strrdelim(resolved, 0);
+ if (!cp) return(-1);
+ *cp = '\0';
+ }
+ else if ((cp = strdelim(path, 0))) {
+ strncpy2(tmp, path, cp - path);
+ if (archrealpath(tmp, resolved) < 0) return(-1);
+ if (archrealpath(++cp, resolved) < 0) return(-1);
+ }
+ else {
+ cp = strcatdelim(resolved);
+ strncpy2(cp, path, MAXPATHLEN - 1 - (cp - resolved));
+ }
+
+ return(0);
+}
+
+static int NEAR unpacklink(list, dir)
+namelist *list;
+char *dir;
+{
+ namelist duplist;
+ char *cp, path[MAXPATHLEN], duparcdir[MAXPATHLEN];
+ int i, ret;
+
+ if (!(list -> linkname)) return(0);
+
+ if (!islink(list)) cp = list -> linkname;
+ else {
+ strcatdelim2(duparcdir, archivedir, list -> linkname);
+ cp = duparcdir;
+ }
+ *path = '\0';
+ if (archrealpath(cp, path) < 0) return(-1);
+
+ for (i = 0; i < maxarcf; i++) {
+ *duparcdir = '\0';
+ if (archrealpath(arcflist[i].name, duparcdir) < 0) continue;
+ if (!strcmp(path, duparcdir)) break;
+ }
+ if (i >= maxarcf) return(-1);
+
+ if (unpacklink(&(arcflist[i]), dir) < 0) return(-1);
+
+ strcpy(duparcdir, archivedir);
+ memcpy(&duplist, &(filelist[filepos]), sizeof(namelist));
+ memcpy(&(filelist[filepos]), &(arcflist[i]), sizeof(namelist));
+ if (!(cp = strrdelim(filelist[filepos].name, 0))) *archivedir = '\0';
+ else {
+ strncpy2(archivedir,
+ filelist[filepos].name, cp - filelist[filepos].name);
+ filelist[filepos].name = ++cp;
+ }
+ ret = unpack(archivefile, dir, NULL,
+ 0, F_ARGSET | F_ISARCH | F_NOADDOPT);
+ memcpy(&(filelist[filepos]), &duplist, sizeof(namelist));
+ strcpy(archivedir, duparcdir);
+
+ return(ret);
+}
+#endif /* !NOSYMLINK */
+
X char *tmpunpack(single)
X int single;
X {
@@ -2547,7 +2651,12 @@
X for (i = 0; i < maxfile; i++)
X if (ismark(&(filelist[i]))) filelist[i].tmpflags |= F_WSMRK;
X dupmark = mark;
- if (single) mark = 0;
+ if (single) {
+ mark = 0;
+#ifndef NOSYMLINK
+ VOID_C unpacklink(&(filelist[filepos]), path);
+#endif
+ }
X ret = unpack(archivefile, path, NULL,
X 0, F_ARGSET | F_ISARCH | F_NOADDOPT);
X mark = dupmark;
diff -urNP ../FD-2.09/backend.c ./backend.c
--- ../FD-2.09/backend.c Tue Aug 22 00:00:00 2006
+++ ./backend.c Tue Oct 31 00:00:00 2006
@@ -20,6 +20,7 @@
X #define MAXESCPARAM 16
X #define MAXESCCHAR 4
X #define MAXTABSTOP 255
+#define MAXLASTUCS2 (MAXNFLEN - 1)
X
X typedef struct _ptyterm_t {
X short cur_x, cur_y;
@@ -36,6 +37,9 @@
X short escparam[MAXESCPARAM];
X u_char escchar[MAXESCCHAR];
X u_short tabstop[MAXTABSTOP];
+#ifndef _NOKANJICONV
+ u_short last_ucs2[MAXLASTUCS2];
+#endif
X u_short attr;
X u_short termflags;
X char codeselect[MAXESCCHAR + 2];
@@ -71,6 +75,10 @@
X #ifdef SIGWINCH
X static int ptywinched = 0;
X #endif
+#ifndef _NOKANJICONV
+static u_char ptyungetbuf[MAXUTF8LEN * MAXNFLEN * sizeof(short)];
+static int ptyungetnum = 0;
+#endif
X
X static VOID NEAR resettermattr __P_((int));
X static VOID NEAR resettermcode __P_((int));
@@ -85,12 +93,24 @@
X static VOID NEAR evalsignal __P_((VOID_A));
X #endif
X static int NEAR convkey __P_((int, keyseq_t *));
-#ifndef _NOKANJICONV
-static int NEAR ptygetch __P_((int));
+#ifdef _NOKANJICONV
+#define ptyrecvbuf(b, n) recvbuf(emufd, b, n)
+#define ptyrecvword(n) recvword(emufd, n)
+#define ptyrecvstring(c) recvstring(emufd, c)
+#else /* !_NOKANJICONV */
+static int NEAR ptyrecvbuf __P_((VOID_P, int));
+static int NEAR ptyrecvword __P_((int *));
+static int NEAR ptyrecvstring __P_((char **));
+static VOID NEAR ptyungetch __P_((int));
+static int NEAR ptygetch __P_((VOID_A));
+static u_int NEAR ptygetucs2 __P_((int));
+static VOID NEAR getiocode __P_((int, int *, int *));
X static char *NEAR ptykconv __P_((char *, char *, int, int));
-#endif
+static u_int NEAR evalnf __P_((int, char *));
+#endif /* !_NOKANJICONV */
X static VOID NEAR evalscroll __P_((int, int, int));
X static VOID NEAR evallf __P_((int));
+static VOID NEAR outputnormal __P_((int, char *, int));
X static VOID NEAR evalnormal __P_((int, int));
X static VOID NEAR evalcontrol __P_((int, int));
X static VOID NEAR evalescape __P_((int, int));
@@ -98,8 +118,8 @@
X static VOID NEAR evalcodeselect __P_((int, int));
X static VOID NEAR evaloutput __P_((int));
X static int NEAR chgattr __P_((int, int));
-static int NEAR directoutput __P_((int, int));
-static int NEAR evalinput __P_((int));
+static int NEAR directoutput __P_((int));
+static int NEAR evalinput __P_((VOID_A));
X
X
X static VOID NEAR resettermattr(w)
@@ -138,6 +158,9 @@
X VOID resetptyterm(w, clean)
X int w, clean;
X {
+#ifndef _NOKANJICONV
+ int i;
+#endif
X int min_x, min_y, max_y;
X
X last_x = last_y = (short)-1;
@@ -170,6 +193,10 @@
X pty[w].max_scroll = pty[w].max_y - 1;
X pty[w].escmode = '\0';
X pty[w].last1 = pty[w].last2 = (short)-1;
+#ifndef _NOKANJICONV
+ for (i = 0; i < MAXLASTUCS2; i++)
+ pty[w].last_ucs2[i] = (u_short)0;
+#endif
X pty[w].termflags = (u_short)0;
X resettermattr(w);
X resettermcode(w);
@@ -370,15 +397,123 @@
X }
X
X #ifndef _NOKANJICONV
-static int NEAR ptygetch(fd)
-int fd;
+static int NEAR ptyrecvbuf(buf, nbytes)
+VOID_P buf;
+int nbytes;
+{
+ char *cp;
+ int len;
+
+ cp = (char *)buf;
+ if (ptyungetnum) {
+ len = nbytes;
+ if (len > ptyungetnum) len = ptyungetnum;
+ memcpy(cp, (char *)ptyungetbuf, len * sizeof(u_char));
+ cp += len;
+ nbytes -= len;
+ ptyungetnum -= len;
+ memmove((char *)ptyungetbuf, (char *)&(ptyungetbuf[len]),
+ ptyungetnum * sizeof(u_char));
+ }
+
+ return(recvbuf(emufd, cp, nbytes));
+}
+
+static int NEAR ptyrecvword(np)
+int *np;
+{
+ short w;
+
+ if (ptyrecvbuf(&w, sizeof(w)) < 0) return(-1);
+ *np = (int)w;
+
+ return(0);
+}
+
+static int NEAR ptyrecvstring(cpp)
+char **cpp;
+{
+ char *cp;
+ ALLOC_T len;
+
+ if (ptyrecvbuf(&cp, sizeof(cp)) < 0) return(-1);
+ if (cp) {
+ if (ptyrecvbuf(&len, sizeof(len)) < 0) return(-1);
+ cp = malloc2(len + 1);
+ if (ptyrecvbuf(cp, len) < 0) {
+ free(cp);
+ return(-1);
+ }
+ cp[len] = '\0';
+ }
+ *cpp = cp;
+
+ return(0);
+}
+
+static VOID NEAR ptyungetch(c)
+int c;
X {
X u_short ch;
X
- if (recvbuf(fd, &ch, sizeof(ch)) < 0 || (ch & 0xff00)) return(-1);
+ ch = c;
+ if (ptyungetnum + sizeof(ch) > arraysize(ptyungetbuf)) return;
+ memmove((char *)&(ptyungetbuf[sizeof(ch)]), (char *)&(ptyungetbuf[0]),
+ ptyungetnum * sizeof(u_char));
+ memcpy((char *)ptyungetbuf, (char *)&ch, sizeof(ch));
+ ptyungetnum += sizeof(ch);
+}
+
+static int NEAR ptygetch(VOID_A)
+{
+ u_short ch;
+
+ if (ptyrecvbuf(&ch, sizeof(ch)) < 0) return(-1);
+ if (ch & 0xff00) {
+ ptyungetch(ch);
+ return(-1);
+ }
+
X return(ch);
X }
X
+static u_int NEAR ptygetucs2(ch)
+int ch;
+{
+ char buf[MAXUTF8LEN + 1];
+ int n;
+
+ n = 0;
+ buf[n++] = ch;
+ if (!ismsb(ch)) /*EMPTY*/;
+ else if ((ch = ptygetch()) < 0) return((u_int)-1);
+ else {
+ buf[n++] = ch;
+ if (isutf2(buf[0], buf[1])) /*EMPTY*/;
+ else if ((ch = ptygetch()) < 0) {
+ ptyungetch((u_char)(buf[1]));
+ return((u_int)-1);
+ }
+ else buf[n++] = ch;
+ }
+ buf[n] = '\0';
+
+ return(ucs2fromutf8((u_char *)buf, NULL));
+}
+
+static VOID NEAR getiocode(w, incodep, outcodep)
+int w, *incodep, *outcodep;
+{
+ int incode, outcode;
+
+ outcode = (outputkcode != NOCNV) ? outputkcode : DEFCODE;
+ incode = (w < MAXWINDOWS && ptylist[w].outcode != NOCNV)
+ ? ptylist[w].outcode : outcode;
+
+ if (incodep) *incodep = incode;
+ if (outcodep) *outcodep = outcode;
+}
+
X static char *NEAR ptykconv(buf, buf2, incode, outcode)
X char *buf, *buf2;
X int incode, outcode;
@@ -393,6 +528,51 @@
X
X return(cp);
X }
+
+static u_int NEAR evalnf(w, buf)
+int w;
+char *buf;
+{
+ u_short ubuf[MAXLASTUCS2 + 1 + 1];
+ char tmp[MAXUTF8LEN + 1];
+ u_int u;
+ int i, n, next, width, incode;
+
+ getiocode(w, &incode, NULL);
+ for (i = 0; i < MAXLASTUCS2 && pty[w].last_ucs2[i]; i++)
+ ubuf[i] = pty[w].last_ucs2[i];
+
+ if (!buf) {
+ next = 0;
+ buf = tmp;
+ }
+ else {
+ u = ucs2fromutf8((u_char *)buf, NULL);
+ if (incode != M_UTF8) return(u);
+ ubuf[i++] = u;
+ next = selectpty(1, &(ptylist[w].fd), NULL, WAITMETA * 1000L);
+ }
+ ubuf[i] = (u_short)0;
+
+ pty[w].last1 = pty[w].last2 = (short)-1;
+ n = 0;
+ while (ubuf[n]) {
+ u = ucs2denormalization(ubuf, &n, incode - UTF8);
+ if (next > 0 && n <= 1 && i <= MAXLASTUCS2) {
+ n = 0;
+ break;
+ }
+ buf[ucs2toutf8(buf, 0, u)] = '\0';
+ width = (iswucs2(u)) ? 2 : 1;
+ outputnormal(w, buf, width);
+ if (next > 0) break;
+ }
+
+ for (i = 0; i < MAXLASTUCS2; i++)
+ if ((pty[w].last_ucs2[i] = ubuf[n])) n++;
+
+ return((u_int)0);
+}
X #endif /* !_NOKANJICONV */
X
X static VOID NEAR evalscroll(w, n, c)
@@ -415,28 +595,71 @@
X else reallocate(w, pty[w].cur_x, pty[w].cur_y + 1);
X }
X
+static VOID NEAR outputnormal(w, buf, width)
+int w;
+char *buf;
+int width;
+{
+#ifndef _NOKANJICONV
+ char buf2[MAXKANJIBUF + 1];
+ int incode, outcode;
+#endif
+ char *cp;
+
+ if (pty[w].cur_x + width > pty[w].max_x) {
+ pty[w].cur_x = pty[w].min_x;
+ evallf(w);
+ }
+
+ surelocate(w, 0);
+ settermattr(w);
+ settermcode(w);
+ cp = buf;
+ if (pty[w].attr & A_INVISIBLE) {
+ memset(buf, ' ', width);
+ buf[width] = '\0';
+ }
+#ifndef _NOKANJICONV
+ else if (!(pty[w].termflags & T_MULTIBYTE)) {
+ getiocode(w, &incode, &outcode);
+ if (incode != outcode)
+ cp = ptykconv(buf, buf2, incode, outcode);
+ }
+#endif
+
+ cputs2(cp);
+ tflush();
+ pty[w].cur_x += width;
+ last_x += width;
+
+ if (n_lastcolumn < n_column && pty[w].cur_x >= pty[w].max_x) {
+ pty[w].cur_x = pty[w].min_x;
+ evallf(w);
+ }
+}
+
X static VOID NEAR evalnormal(w, c)
X int w, c;
X {
X #ifndef _NOKANJICONV
- char buf[MAXKANJIBUF + 1], buf2[MAXKANJIBUF + 1];
X u_int u;
- int incode, outcode;
+ int incode;
X #endif
+ char buf[MAXKANJIBUF + 1];
X int i, width;
X
X #ifndef _NOKANJICONV
- outcode = (outputkcode != NOCNV) ? outputkcode : DEFCODE;
- incode = (w < MAXWINDOWS && ptylist[w].outcode != NOCNV)
- ? ptylist[w].outcode : outcode;
+ getiocode(w, &incode, NULL);
X #endif
X
X if ((pty[w].termflags & T_NOAUTOMARGIN)
X && pty[w].cur_x >= pty[w].max_x - 1)
X return;
X
+ i = 0;
X width = 1;
X if (pty[w].last1 >= (short)0) {
+ buf[i++] = pty[w].last1;
X if (pty[w].termflags & T_MULTIBYTE) width++;
X #ifdef _NOKANJICONV
X # ifdef CODEEUC
@@ -447,22 +670,13 @@
X if (pty[w].last1 != C_EKANA) width++;
X }
X else if (incode >= UTF8) {
- if (!ismsb(c)) pty[w].last1 = pty[w].last2 = (short)-1;
- else if (pty[w].last2 >= (short)0) /*EMPTY*/;
+ if (!ismsb(c)) i = 0;
+ else if (pty[w].last2 >= (short)0)
+ buf[i++] = pty[w].last2;
X else if (!isutf2(pty[w].last1, c)) {
X pty[w].last2 = c;
X return;
X }
-
- i = 0;
- if (pty[w].last1 >= (short)0) buf[i++] = pty[w].last1;
- if (pty[w].last2 >= (short)0) buf[i++] = pty[w].last2;
- if (i) {
- buf[i++] = c;
- buf[i] = '\0';
- u = ucs2fromutf8((u_char *)buf, NULL);
- if (u < 0xff61 || u > 0xff9f) width++;
- }
X }
X #endif /* !_NOKANJICONV */
X else width++;
@@ -485,43 +699,21 @@
X return;
X }
X
- if (pty[w].cur_x + width > pty[w].max_x) {
- pty[w].cur_x = pty[w].min_x;
- evallf(w);
- }
+ buf[i++] = c;
+ buf[i] = '\0';
X
- surelocate(w, 0);
- settermattr(w);
- settermcode(w);
- if (pty[w].attr & A_INVISIBLE) for (i = 0; i < width; i++) putch2(' ');
X #ifndef _NOKANJICONV
- else if (!(pty[w].termflags & T_MULTIBYTE) && incode != outcode) {
- i = 0;
- if (pty[w].last1 >= (short)0) buf[i++] = pty[w].last1;
- if (pty[w].last2 >= (short)0) buf[i++] = pty[w].last2;
- if (!i) putch2(c);
- else {
- buf[i++] = c;
- buf[i] = '\0';
- cputs2(ptykconv(buf, buf2, incode, outcode));
- }
- }
-#endif /* !_NOKANJICONV */
- else {
- if (pty[w].last1 >= (short)0) putch2(pty[w].last1);
- if (pty[w].last2 >= (short)0) putch2(pty[w].last2);
- putch2(c);
- }
- tflush();
- pty[w].cur_x += width;
- last_x += width;
-
- if (n_lastcolumn < n_column && pty[w].cur_x >= pty[w].max_x) {
- pty[w].cur_x = pty[w].min_x;
- evallf(w);
+ if (incode >= UTF8) {
+ if (!(u = evalnf(w, buf))) return;
+ if (iswucs2(u)) width++;
X }
+#endif
X
+ outputnormal(w, buf, width);
X pty[w].last1 = pty[w].last2 = (short)-1;
+#ifndef _NOKANJICONV
+ for (i = 0; i < MAXLASTUCS2; i++) pty[w].last_ucs2[i] = (u_short)0;
+#endif
X }
X
X static VOID NEAR evalcontrol(w, c)
@@ -752,12 +944,6 @@
X case 28:
X pty[w].attr &= ~A_INVISIBLE;
X break;
- case 37:
- pty[w].fg = (short)-1;
- break;
- case 47:
- pty[w].bg = (short)-1;
- break;
X case 100:
X pty[w].fg = pty[w].bg = (short)-1;
X break;
@@ -1017,7 +1203,8 @@
X }
X
X pty[w].codeselect[0] = pty[w].escmode;
- memcpy(&(pty[w].codeselect[1]), pty[w].escchar, pty[w].nchar);
+ memcpy(&(pty[w].codeselect[1]), (char *)(pty[w].escchar),
+ pty[w].nchar);
X pty[w].codeselect[++(pty[w].nchar)] = c;
X pty[w].codeselect[++(pty[w].nchar)] = '\0';
X
@@ -1034,6 +1221,9 @@
X
X switch (pty[w].escmode) {
X case '\033':
+#ifndef _NOKANJICONV
+ VOID_C evalnf(w, NULL);
+#endif
X evalescape(w, uc);
X break;
X case '[':
@@ -1056,8 +1246,13 @@
X evalcodeselect(w, uc);
X break;
X default:
- if (uc < ' ' || uc == '\177') evalcontrol(w, uc);
- else evalnormal(w, uc);
+ if (uc >= ' ' && uc != '\177') evalnormal(w, uc);
+ else {
+#ifndef _NOKANJICONV
+ VOID_C evalnf(w, NULL);
+#endif
+ evalcontrol(w, uc);
+ }
X break;
X }
X }
@@ -1155,8 +1350,8 @@
X return(-1);
X }
X
-static int NEAR directoutput(fd, n)
-int fd, n;
+static int NEAR directoutput(n)
+int n;
X {
X ptyinfo_t tmp;
X char *s, *arg, *cwd;
@@ -1164,7 +1359,7 @@
X short w1, w2, row[MAXWINDOWS];
X int i;
X
- if (recvbuf(fd, &w1, sizeof(w1)) < 0) return(0);
+ if (ptyrecvbuf(&w1, sizeof(w1)) < 0) return(0);
X
X switch (n) {
X case TE_PUTCH2:
@@ -1178,7 +1373,7 @@
X break;
X case TE_CPUTS2:
X s = malloc2(w1 + 1);
- if (recvbuf(fd, s, w1) >= 0) {
+ if (ptyrecvbuf(s, w1) >= 0) {
X surelocate(MAXWINDOWS, 0);
X settermattr(MAXWINDOWS);
X settermcode(MAXWINDOWS);
@@ -1203,7 +1398,7 @@
X tflush();
X break;
X case TE_SETSCROLL:
- if (recvbuf(fd, &w2, sizeof(w2)) < 0) break;
+ if (ptyrecvbuf(&w2, sizeof(w2)) < 0) break;
X
X if (w2 <= (short)0) w2 = pty[MAXWINDOWS].max_y - 1;
X biasxy(MAXWINDOWS, NULL, &w1);
@@ -1214,7 +1409,7 @@
X }
X break;
X case TE_LOCATE:
- if (recvbuf(fd, &w2, sizeof(w2)) < 0) break;
+ if (ptyrecvbuf(&w2, sizeof(w2)) < 0) break;
X
X reallocate(MAXWINDOWS, w1, w2);
X for (i = 0; i < MAXWINDOWS; i++) {
@@ -1229,7 +1424,7 @@
X evallf(MAXWINDOWS);
X break;
X case TE_CHGCOLOR:
- if (recvword(fd, &n) < 0) break;
+ if (ptyrecvword(&n) < 0) break;
X
X if (n) {
X pty[MAXWINDOWS].fg = (w1 == ANSI_BLACK)
@@ -1241,8 +1436,8 @@
X }
X break;
X case TE_MOVECURSOR:
- if (recvbuf(fd, &w2, sizeof(w2)) < 0
- || recvword(fd, &n) < 0)
+ if (ptyrecvbuf(&w2, sizeof(w2)) < 0
+ || ptyrecvword(&n) < 0)
X break;
X if (w1 < (short)0) w1 = w2;
X if ((n = chgattr(w1, n)) < 0) break;
@@ -1251,7 +1446,7 @@
X tflush();
X break;
X case TE_CHANGEWIN:
- if (recvbuf(fd, &pid, sizeof(pid)) < 0) break;
+ if (ptyrecvbuf(&pid, sizeof(pid)) < 0) break;
X
X win = w1;
X if (pid < (p_id_t)0) break;
@@ -1271,11 +1466,11 @@
X if (i >= MAXWINDOWS) return(-1);
X break;
X case TE_CHANGEWSIZE:
- if (recvword(fd, &n) < 0) break;
+ if (ptyrecvword(&n) < 0) break;
X if (n > MAXWINDOWS) n = MAXWINDOWS;
X
X for (i = 0; i < n; i++)
- if (recvbuf(fd, &(row[i]), sizeof(row[i])) < 0)
+ if (ptyrecvbuf(&(row[i]), sizeof(row[i])) < 0)
X break;
X
X wheader = w1;
@@ -1291,7 +1486,7 @@
X }
X break;
X case TE_INSERTWIN:
- if (recvword(fd, &n) < 0) break;
+ if (ptyrecvword(&n) < 0) break;
X memcpy((char *)&tmp, (char *)&(ptylist[n - 1]),
X sizeof(ptyinfo_t));
X memmove((char *)&(ptylist[w1 + 1]),
@@ -1306,7 +1501,7 @@
X /*NOTREACHED*/
X break;
X case TE_DELETEWIN:
- if (recvword(fd, &n) < 0) break;
+ if (ptyrecvword(&n) < 0) break;
X memcpy((char *)&tmp, (char *)&(ptylist[w1]),
X sizeof(ptyinfo_t));
X memmove((char *)&(ptylist[w1]),
@@ -1329,28 +1524,28 @@
X break;
X #ifndef _NOKANJICONV
X case TE_CHANGEKCODE:
- if (recvbuf(fd, &w2, sizeof(w2)) < 0) break;
+ if (ptyrecvbuf(&w2, sizeof(w2)) < 0) break;
X inputkcode = w1;
X outputkcode = w2;
X break;
X case TE_CHANGEINKCODE:
- if (recvbuf(fd, &w2, sizeof(w2)) < 0) break;
+ if (ptyrecvbuf(&w2, sizeof(w2)) < 0) break;
X ptylist[w1].incode = (u_char)w2;
X break;
X case TE_CHANGEOUTKCODE:
- if (recvbuf(fd, &w2, sizeof(w2)) < 0) break;
+ if (ptyrecvbuf(&w2, sizeof(w2)) < 0) break;
X ptylist[w1].outcode = (u_char)w2;
X break;
X #endif /* !_NOKANJICONV */
X case TE_AWAKECHILD:
- if (recvbuf(fd, &n, sizeof(n)) < 0
- || recvstring(fd, &s) < 0)
+ if (ptyrecvbuf(&n, sizeof(n)) < 0
+ || ptyrecvstring(&s) < 0)
X break;
- if (recvstring(fd, &arg) < 0) {
+ if (ptyrecvstring(&arg) < 0) {
X if (s) free(s);
X break;
X }
- if (recvstring(fd, &cwd) < 0) cwd = NULL;
+ if (ptyrecvstring(&cwd) < 0) cwd = NULL;
X resetptyterm(w1, 1);
X
X sendbuf(ptylist[w1].fd, &n, sizeof(n));
@@ -1368,19 +1563,20 @@
X return(0);
X }
X
-static int NEAR evalinput(fd)
-int fd;
+static int NEAR evalinput(VOID_A)
X {
X #ifdef _NOKANJICONV
- char buf[2];
+ char buf[MAXKLEN];
X #else
+ u_short ubuf[MAXNFLEN];
X char buf[MAXKANJIBUF + 1], buf2[MAXKANJIBUF + 1];
- int cnv, incode, outcode;
+ u_int u;
+ int i, ch, len, cnv, incode, outcode;
X #endif
X keyseq_t key;
X int n;
X
- if (recvbuf(fd, &(key.code), sizeof((key.code))) < 0) return(0);
+ if (ptyrecvbuf(&(key.code), sizeof((key.code))) < 0) return(0);
X
X #ifndef _NOKANJICONV
X cnv = 0;
@@ -1395,21 +1591,26 @@
X buf[0] = K_ESC;
X buf[1] = (key.code & 0xff);
X }
-#if !defined (_NOKANJICONV) || defined (CODEEUC)
-# ifdef _NOKANJICONV
+#ifdef _NOKANJICONV
+# ifdef CODEEUC
X else if (isekana2(key.code)) {
-# else
+ key.len = (u_char)2;
+ key.str = buf;
+ buf[0] = C_EKANA;
+ buf[1] = (key.code & 0xff);
+ }
+# endif
+#else /* !_NOKANJICONV */
X else if (incode == EUC && isekana2(key.code)) {
X if (incode != outcode) cnv++;
-# endif
X key.len = (u_char)2;
X key.str = buf;
X buf[0] = C_EKANA;
X buf[1] = (key.code & 0xff);
X }
-#endif /* !_NOKANJICONV || CODEEUC */
- else if (!(key.code & 01000) && key.code > K_MAX) {
- n = directoutput(fd, key.code);
+#endif /* !_NOKANJICONV */
+ else if (!(key.code & K_ALTERNATE) && key.code > K_MAX) {
+ n = directoutput(key.code);
X if (win < MAXWINDOWS) {
X surelocate(win, 1);
X last_x = last_y = (short)-1;
@@ -1425,21 +1626,47 @@
X #ifndef _NOKANJICONV
X if (incode == outcode) /*EMPTY*/;
X else if (incode == SJIS && iskana2(key.code)) cnv++;
- else if (incode >= UTF8) {
- if (!ismsb(key.code)) /*EMPTY*/;
- else if ((n = ptygetch(fd)) >= 0) {
+ else if (incode == EUC && key.code == C_EKANA
+ && (n = ptygetch()) >= 0) {
+ if (!iskana2(n)) ptyungetch((u_char)n);
+ else {
+ cnv++;
X buf[1] = n;
X (key.len)++;
- if (isutf2(buf[0], buf[1])) cnv++;
- else if ((n = ptygetch(fd)) >= 0) {
- cnv++;
- buf[2] = n;
- (key.len)++;
+ }
+ }
+ else if (incode >= UTF8) {
+ cnv++;
+ i = 0;
+ ch = key.code;
+ for (;;) {
+ if ((u = ptygetucs2(ch)) == (u_int)-1) {
+ if (i) ptyungetch((u_char)ch);
+ break;
X }
+ ubuf[i++] = u;
+ if (i >= MAXNFLEN) break;
+ if (incode != M_UTF8 || (ch = ptygetch()) < 0)
+ break;
+ }
+ len = i;
+ i = 0;
+ if (!len) {
+ u = key.code;
+ cnv = 0;
+ }
+ else if (incode != M_UTF8) u = ubuf[i++];
+ else u = ucs2denormalization(ubuf, &i, incode - UTF8);
+
+ while (len-- > i) {
+ n = ucs2toutf8(buf, 0, ubuf[len]);
+ while (n-- > 0) ptyungetch((u_char)(buf[n]));
X }
+ key.len = ucs2toutf8(buf, 0, u);
+ if (key.len <= 1) cnv = 0;
X }
X else if (isinkanji1(key.code, incode)
- && (n = ptygetch(fd)) >= 0) {
+ && (n = ptygetch()) >= 0) {
X cnv++;
X buf[1] = n;
X (key.len)++;
@@ -1487,7 +1714,7 @@
X fds[i] = emufd;
X if (selectpty(MAXWINDOWS + 1, fds, result, -1) <= 0) continue;
X
- if (result[MAXWINDOWS] && (n = evalinput(emufd)) > 0) continue;
+ if (result[MAXWINDOWS] && (n = evalinput()) > 0) continue;
X
X x = last_x;
X y = last_y;
diff -urNP ../FD-2.09/browse.c ./browse.c
--- ../FD-2.09/browse.c Tue Aug 22 00:00:00 2006
+++ ./browse.c Tue Oct 31 00:00:00 2006
@@ -14,7 +14,6 @@
X #endif
X
X #if MSDOS
-extern int getcurdrv __P_((VOID_A));
X extern int setcurdrv __P_((int, int));
X #endif
X
@@ -173,10 +172,6 @@
X # endif
X #endif /* FD >= 2 */
X };
-char typesymlist[] = "dbclsp";
-u_short typelist[] = {
- S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO
-};
X #ifdef HAVEFLAGS
X char fflagsymlist[] = "ANacuacu";
X u_long fflaglist[] = {
@@ -202,6 +197,10 @@
X int calc_x = -1;
X int calc_y = -1;
X
+static CONST char typesymlist[] = "dbclsp";
+static CONST u_short typelist[] = {
+ S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO
+};
X static CONST u_short modelist[] = {
X S_IFDIR, S_IFLNK, S_IFSOCK, S_IFIFO, S_IFBLK, S_IFCHR
X };
@@ -590,6 +589,18 @@
X }
X
X Xtflush();
+}
+
+u_int getfmode(c)
+int c;
+{
+ int i;
+
+ c = tolower2(c);
+ for (i = 0; typesymlist[i]; i++)
+ if (c == typesymlist[i]) return(typelist[i]);
+
+ return((u_int)-1);
X }
X
X int putmode(buf, mode, notype)
diff -urNP ../FD-2.09/doscom.c ./doscom.c
--- ../FD-2.09/doscom.c Tue Aug 22 00:00:00 2006
+++ ./doscom.c Tue Oct 31 00:00:00 2006
@@ -32,6 +32,11 @@
X
X #if MSDOS && !defined (FD)
X #define VOL_FAT32 "FAT32"
+# ifdef DOUBLESLASH
+# define MNTDIRSIZ MAXPATHLEN
+# else
+# define MNTDIRSIZ (3 + 1)
+# endif
X #endif /* MSDOS && !FD */
X
X #if MSDOS
@@ -307,6 +312,7 @@
X extern char *realloc2 __P_((VOID_P, ALLOC_T));
X extern char *c_realloc __P_((char *, ALLOC_T, ALLOC_T *));
X extern char *strdup2 __P_((char *));
+extern char *strncpy2 __P_((char *, char *, int));
X
X #ifdef FD
X extern int getinfofs __P_((char *, off_t *, off_t *, off_t *));
@@ -331,7 +337,7 @@
X # endif
X # define ttyiomode(n)
X # define stdiomode()
-# define getkey2(n) getch();
+# define getkey3(n, c) getch();
X # else /* !MSDOS */
X # define realpath2(p, r, f) \
X realpath(p, r)
@@ -340,7 +346,7 @@
X static VOID NEAR ttymode __P_((int));
X # define ttyiomode(n) (ttymode(1))
X # define stdiomode() (ttymode(0))
-static int NEAR getkey2 __P_((int));
+static int NEAR getkey3 __P_((int, int));
X # endif /* !MSDOS */
X static int NEAR touchfile __P_((char *, struct stat *));
X #ifndef NODIRLOOP
@@ -455,13 +461,29 @@
X off_t *totalp, *freep, *bsizep;
X {
X # if MSDOS
+# ifdef DOUBLESLASH
+ char *cp;
+ int len;
+# endif
X struct SREGS sreg;
X __dpmi_regs reg;
- char drv[4], buf[128];
-# endif
+ char drv[MNTDIRSIZ], buf[128];
+# endif /* !MSDOS */
X statfs_t fsbuf;
X
X # if MSDOS
+# ifdef DOUBLESLASH
+ if ((len = isdslash(path))) {
+ if ((cp = strdelim(&(path[len]), 0))) {
+ len = cp - path;
+ if (!(cp = strdelim(&(path[len + 1]), 0)))
+ cp += strlen(cp);
+ len = cp - path;
+ }
+ strncpy2(drv, path, len);
+ }
+ else
+# endif
X VOID_C gendospath(drv, toupper2(path[0]), _SC_);
X
X reg.x.ax = 0x71a0;
@@ -634,8 +656,8 @@
X }
X
X /*ARGSUSED*/
-static int NEAR getkey2(sig)
-int sig;
+static int NEAR getkey3(sig, code)
+int sig, code;
X {
X u_char ch;
X int i;
@@ -797,7 +819,7 @@
X int c;
X
X ttyiomode(1);
- c = getkey2(0);
+ c = getkey3(0, inputkcode);
X stdiomode();
X if (c == EOF) c = -1;
X else if (c == cc_intr) {
@@ -1199,15 +1221,17 @@
X static VOID NEAR showfnameb(dirp)
X struct filestat_t *dirp;
X {
- char buf[MAXPATHLEN];
+ char *cp, buf[MAXPATHLEN];
X int i;
X
X if (dirflag & DF_SUBDIR) {
+ cp = dirwd;
X if (dirflag & DF_LOWER) {
X for (i = 0; dirwd[i]; i++) buf[i] = tolower2(dirwd[i]);
- dirwd = buf;
+ buf[i] = '\0';
+ cp = buf;
X }
- fprintf2(stdout, "%k%c", dirwd, _SC_);
+ fprintf2(stdout, "%k%c", cp, _SC_);
X }
X
X if (dirflag & DF_LOWER)
@@ -1557,7 +1581,7 @@
X }
X else {
X i = file - buf;
- if (isrootdir(buf) || *file != _SC_) file++;
+ if (isrootpath(buf) || *file != _SC_) file++;
X *file = '\0';
X dir = buf;
X file = &(argv[n][++i]);
@@ -1570,11 +1594,7 @@
X return(RET_FAIL);
X }
X if (dir != buf) strcpy(wd, cwd);
- else {
- if (chdir2(buf) < 0) {
- dosperror(buf);
- return(RET_FAIL);
- }
+ else if (chdir2(buf) >= 0) {
X if (!Xgetwd(wd)) {
X dosperror(NULL);
X return(RET_FAIL);
@@ -1584,6 +1604,13 @@
X return(RET_FAIL);
X }
X }
+#ifdef DOUBLESLASH
+ else if (isdslash(buf)) realpath2(buf, wd, 1);
+#endif
+ else {
+ dosperror(buf);
+ return(RET_FAIL);
+ }
X if (getinfofs(wd, &total, &fre, &bsize) < 0) total = fre = (off_t)-1;
X
X if (dirtype != 'B') fputnl(stdout);
@@ -1666,7 +1693,7 @@
X char *argv[];
X {
X char *buf, **wild;
- int i, n, key, flag, ret;
+ int i, n, c, flag, ret;
X
X flag = 0;
X for (n = 1; n < argc; n++) {
@@ -1704,10 +1731,10 @@
X stdiomode();
X if (!buf) return(RET_SUCCESS);
X if (!isatty(STDIN_FILENO)) fputnl(stdout);
- key = *buf;
+ c = *buf;
X free(buf);
- } while (!strchr("ynYN", key));
- if (key == 'n' || key == 'N') return(RET_SUCCESS);
+ } while (!strchr("ynYN", c));
+ if (c == 'n' || c == 'N') return(RET_SUCCESS);
X }
X if (!(wild = evalwild(argv[n], 0))) {
X doserror(argv[n], ER_FILENOTFOUND);
@@ -1720,16 +1747,15 @@
X fprintf2(stdout,
X "%k, Delete (Y/N)?", wild[i]);
X fflush(stdout);
- if ((key = inputkey()) < 0) {
+ if ((c = inputkey()) < 0) {
X freevar(wild);
X return(ret);
X }
- if (key <= (int)MAXUTYPE(u_char)
- && isprint2(key))
- fputc(key, stdout);
+ if (c <= (int)MAXUTYPE(u_char) && isprint2(c))
+ fputc(c, stdout);
X fputnl(stdout);
- } while (!strchr("ynYN", key));
- if (key == 'n' || key == 'N') continue;
+ } while (!strchr("ynYN", c));
+ if (c == 'n' || c == 'N') continue;
X }
X if (Xunlink(wild[i]) < 0) {
X dosperror(wild[i]);
@@ -1872,15 +1898,9 @@
X char *cp;
X
X if (bin < 0) return(-1);
- if ((cp = strchr(name, DOSCOMOPT))) {
- if (!cp[1] || (cp[2] && cp[3])) {
- doserror(cp, ER_INVALIDSW);
- return(-1);
- }
- *(cp++) = '\0';
- if (toupper2(*cp) == 'B') bin = CF_BINARY;
- else if (toupper2(*cp) == 'A') bin = CF_TEXT;
- }
+ if (!(cp = strchr(name, DOSCOMOPT)) || !cp[1] || cp[2]) /*EMPTY*/;
+ else if (toupper2(*cp) == 'B') bin = CF_BINARY;
+ else if (toupper2(*cp) == 'A') bin = CF_TEXT;
X
X return(bin);
X }
@@ -2081,9 +2101,11 @@
X }
X
X #ifdef FD
- stp -> st_nlink = (TCH_ATIME | TCH_MTIME);
-#endif
+ stp -> st_nlink = (TCH_ATIME | TCH_MTIME | TCH_IGNOREERR);
X if (!tty && touchfile(dest, stp) < 0) return(-1);
+#else
+ if (!tty) VOID_C touchfile(dest, stp);
+#endif
X
X return(1);
X }
diff -urNP ../FD-2.09/dosdisk.c ./dosdisk.c
--- ../FD-2.09/dosdisk.c Tue Aug 22 00:00:00 2006
+++ ./dosdisk.c Tue Oct 31 00:00:00 2006
@@ -184,7 +184,6 @@
X extern time_t timelocal2 __P_((struct tm *));
X extern u_int unifysjis __P_((u_int, int));
X extern u_int cnvunicode __P_((u_int, int));
-extern int intrkey __P_((VOID_A));
X #else /* !FD */
X #ifndef NOTZFILEH
X #include <tzfile.h>
@@ -2229,14 +2228,12 @@
X break;
X }
X while ((cc = read(fd, buf, sectsizelist[i])) < 0) {
-# ifdef FD
- if (intrkey()) {
+ if (dosintrfunc && (*dosintrfunc)()) {
X close(fd);
X doserrno = EINTR;
X errno = duperrno;
X return(-1);
X }
-# endif
X if (errno != EINTR) break;
X }
X if (cc >= 0) break;
diff -urNP ../FD-2.09/dosdisk.h ./dosdisk.h
--- ../FD-2.09/dosdisk.h Tue Aug 22 00:00:00 2006
+++ ./dosdisk.h Tue Oct 31 00:00:00 2006
@@ -235,9 +235,10 @@
X #define fd2clust(fd) (dd2clust(dosflist[fd]._file))
X #define fd2offset(fd) (dd2offset(dosflist[fd]._file))
X
-#define dosfeof(p) (((((dosFILE *)(p)) -> _flag) & O_IOEOF) != 0)
-#define dosferror(p) (((((dosFILE *)(p)) -> _flag) & O_IOERR) != 0)
-#define dosclearerr(p) (((dosFILE *)(p)) -> _flag &= ~(O_IOERR | O_IOEOF))
+#define dosfflag(p) (((dosFILE *)((VOID_P)(p))) -> _flag)
+#define dosfeof(p) ((dosfflag(p) & O_IOEOF) != 0)
+#define dosferror(p) ((dosfflag(p) & O_IOERR) != 0)
+#define dosclearerr(p) (dosfflag(p) &= ~(O_IOERR | O_IOEOF))
X
X typedef struct _dosdirdesc {
X int dd_id;
diff -urNP ../FD-2.09/dosemu.c ./dosemu.c
--- ../FD-2.09/dosemu.c Tue Aug 22 00:00:00 2006
+++ ./dosemu.c Tue Oct 31 00:00:00 2006
@@ -75,7 +75,7 @@
X
X drive = *cp;
X if (!buf) return(drive);
- len = MAXPATHLEN - 1;
+ len = sizeof(tmp) - 1;
X if (cp == buf) {
X strncpy2(tmp, cp, len);
X cp = tmp;
@@ -256,14 +256,14 @@
X if (!dp) return(NULL);
X
X dest = ((struct dirent *)&buf) -> d_name;
-#ifdef CYGWIN
+# ifdef CYGWIN
X /* Some versions of Cygwin have neither d_fileno nor d_ino */
X if (dos) {
X src = ((struct dosdirent *)dp) -> d_name;
X wrap_reclen(&buf) = ((struct dosdirent *)dp) -> d_reclen;
X }
X else
-#endif
+# endif
X {
X src = dp -> d_name;
X memcpy((char *)(&buf), (char *)dp, dest - (char *)&buf);
@@ -418,7 +418,11 @@
X char conv[MAXPATHLEN];
X int n;
X
+#ifdef _NOROCKRIDGE
+ path = convput(conv, path, 1, 0, NULL, NULL);
+#else
X path = convput(conv, path, 1, 0, rpath, NULL);
+#endif
X #ifndef _NODOSDRIVE
X if (_dospath(path)) n = doslstat(path, stp);
X else
@@ -475,7 +479,8 @@
X
X path = convput(conv, path, 1, 0, lbuf, &c);
X #ifndef _NOROCKRIDGE
- if (*lbuf && (n = rrreadlink(lbuf, lbuf, MAXPATHLEN)) >= 0) /*EMPTY*/;
+ if (*lbuf && (n = rrreadlink(lbuf, lbuf, sizeof(lbuf) - 1)) >= 0)
+ /*EMPTY*/;
X else
X #endif
X #ifndef _NODOSDRIVE
@@ -487,7 +492,7 @@
X lbuf[n] = '\0';
X #ifndef _NOKANJIFCONV
X path = kanjiconv2(conv, lbuf,
- MAXPATHLEN - 1, c, DEFCODE, L_FNAME);
+ strsize(conv), c, DEFCODE, L_FNAME);
X #else
X path = lbuf;
X #endif
diff -urNP ../FD-2.09/expfunc.c ./expfunc.c
--- ../FD-2.09/expfunc.c Tue Aug 22 00:00:00 2006
+++ ./expfunc.c Tue Oct 31 00:00:00 2006
@@ -80,10 +80,10 @@
X cp = skipspace(&(line[len]));
X if (*cp != '(') return(NULL);
X
- cp = skipspace(++cp);
+ cp = skipspace(&(cp[1]));
X if (*cp != ')') return(NULL);
X
- cp = skipspace(++cp);
+ cp = skipspace(&(cp[1]));
X if (*cp != '{') return(NULL);
X
X func[funcno] = strndup2(line, len);
diff -urNP ../FD-2.09/fd.man ./fd.man
--- ../FD-2.09/fd.man Tue Aug 22 00:00:00 2006
+++ ./fd.man Tue Oct 31 00:00:00 2006
@@ -2,9 +2,9 @@
X .\" Copyright (C) 1995-2006 Takashi SHIRAI
X .\" <shirai@unixusers.net>
X .\"
-.\" @(#)fd.1 2.09 08/22/06
+.\" @(#)fd.1 2.09a 10/31/06
X .\" fd - File & Directory maintenance tool
-.TH FD 1 "August 22, 2006"
+.TH FD 1 "October 31, 2006"
X .de sh
X .br
X .PP
diff -urNP ../FD-2.09/fd_e.man ./fd_e.man
--- ../FD-2.09/fd_e.man Tue Aug 22 00:00:00 2006
+++ ./fd_e.man Tue Oct 31 00:00:00 2006
@@ -2,9 +2,9 @@
X .\" Copyright (C) 1995-2006 Takashi SHIRAI
X .\" <shirai@unixusers.net>
X .\"
-.\" @(#)fd.1 2.09 08/22/06
+.\" @(#)fd.1 2.09a 10/31/06
X .\" fd - File & Directory maintenance tool
-.TH FD 1 "August 22, 2006"
+.TH FD 1 "October 31, 2006"
X .de sh
X .br
X .PP
diff -urNP ../FD-2.09/file.c ./file.c
--- ../FD-2.09/file.c Tue Aug 22 00:00:00 2006
+++ ./file.c Tue Oct 31 00:00:00 2006
@@ -65,7 +65,7 @@
X #endif /* !L_SET */
X
X #ifndef NOFLOCK
-static int NEAR fcntllock __P_((int, int));
+static int NEAR fcntllock __P_((char *, int, int));
X #endif
X static char *NEAR excllock __P_((char *, int));
X #ifdef _NODOSDRIVE
@@ -427,7 +427,8 @@
X }
X
X #ifndef NOFLOCK
-static int NEAR fcntllock(fd, mode)
+static int NEAR fcntllock(path, fd, mode)
+char *path;
X int fd, mode;
X {
X static int lockmode[] = {
@@ -435,32 +436,64 @@
X F_RDLCK, F_WRLCK, F_UNLCK,
X # else /* !USEFCNTLOCK */
X # ifdef USELOCKF
- F_LOCK, F_LOCK, F_ULOCK,
+ F_TLOCK, F_TLOCK, F_ULOCK,
X # else
- LOCK_SH, LOCK_EX, LOCK_UN,
+ LOCK_SH | LOCK_NB, LOCK_EX | LOCK_NB, LOCK_UN,
X # endif
X # endif /* !USEFCNTLOCK */
X };
X # ifdef USEFCNTLOCK
X struct flock lock;
X # endif
+ int i, n;
X
X # ifndef _NODOSDRIVE
X if (fd >= DOSFDOFFSET) return(0);
X # endif
X
+ n = -1;
+ errno = 0;
+ for (i = 0; i < LCK_MAXRETRY; i++) {
X # ifdef USEFCNTLOCK
- lock.l_type = lockmode[mode];
- lock.l_start = lock.l_len = (off_t)0;
- lock.l_whence = SEEK_SET;
- return(fcntl(fd, F_SETLKW, &lock));
+ lock.l_type = lockmode[mode];
+ lock.l_start = lock.l_len = (off_t)0;
+ lock.l_whence = SEEK_SET;
+ n = fcntl(fd, F_SETLK, &lock);
X # else /* !USEFCNTLOCK */
X # ifdef USELOCKF
- return(lockf(fd, lockmode[mode], (off_t)0));
+ n = lockf(fd, lockmode[mode], (off_t)0);
X # else
- return(flock(fd, lockmode[mode]));
+ n = flock(fd, lockmode[mode]);
X # endif
X # endif /* !USEFCNTLOCK */
+ if (n >= 0) break;
+# ifdef EACCES
+ else if (errno == EACCES) /*EMPTY*/;
+# endif
+# ifdef EAGAIN
+ else if (errno == EAGAIN) /*EMPTY*/;
+# endif
+# ifdef EWOULDBLOCK
+ else if (errno == EWOULDBLOCK) /*EMPTY*/;
+# endif
+ else break;
+
+ if (intrkey(-1)) break;
+# if !MSDOS || defined (DJGPP)
+ usleep(100000L);
+# endif
+ }
+ if (i >= LCK_MAXRETRY) {
+#ifdef ETIMEDOUT
+ errno = ETIMEDOUT;
+#else
+ errno = EEXIST;
+#endif
+ if (isttyiomode) warning(-1, path);
+ else perror2(path);
+ }
+
+ return(n);
X }
X #endif /* !NOFLOCK */
X
@@ -516,15 +549,28 @@
X #else
X snprintf2(path, sizeof(path), "%s.%s", file, LOCKEXT);
X #endif
- for (;;) {
+
+ fd = -1;
+ for (i = 0; i < LCK_MAXRETRY; i++) {
X fd = Xopen(path, O_BINARY | O_WRONLY | O_CREAT | O_EXCL,
X 0666 & ~tmpumask);
- if (fd >= 0) break;
- if (errno != EEXIST) return(NULL);
+ if (fd >= 0 || errno != EEXIST) break;
+
+ if (intrkey(-1)) break;
X #if !MSDOS || defined (DJGPP)
X usleep(100000L);
X #endif
X }
+ if (i >= LCK_MAXRETRY) {
+#ifdef ETIMEDOUT
+ errno = ETIMEDOUT;
+#else
+ errno = EEXIST;
+#endif
+ if (isttyiomode) warning(-1, path);
+ else perror2(path);
+ }
+ if (fd < 0) return(NULL);
X
X Xclose(fd);
X cp = strdup2(path);
@@ -559,13 +605,13 @@
X if ((flags & O_ACCMODE) == O_WRONLY || errno != ENOENT)
X return(NULL);
X }
- else if (fcntllock(fd, lckmode) < 0) {
+ else if (fcntllock(path, fd, lckmode) < 0) {
SHAR_EOF
: || $echo 'restore of' 'FD-2.09a.patch' 'failed'
fi
$echo 'End of' 'FD-2.09a.patch' 'part' '1'
$echo 'File' 'FD-2.09a.patch' 'is continued in part' '2'
echo 2 > _sh00584/seq
exit 0
--
しらい たかし
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735