しらいです。

 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
-- 
                                               しらい たかし