Path: ccsf.homeunix.org!CALA-MUZIK!newsfeed.media.kyoto-u.ac.jp!newsfeed.s-kddi1.home.ne.jp!news.home.ne.jp!news-virt.s-kddi1.home.ne.jp.POSTED!53ab2750!not-for-mail Newsgroups: fj.sources Subject: FDclone 2.09a patch [1/3] References: Followup-To: fj.sources.d Organization: UNIX users From: shirai@unixusers.net (Takashi SHIRAI) Lines: 1981 Message-ID: Date: Tue, 31 Oct 2006 12:33:50 GMT NNTP-Posting-Host: 61.46.104.74 X-Complaints-To: abuse@home.ne.jp X-Trace: news-virt.s-kddi1.home.ne.jp 1162298030 61.46.104.74 (Tue, 31 Oct 2006 21:33:50 JST) NNTP-Posting-Date: Tue, 31 Oct 2006 21:33:50 JST Xref: ccsf.homeunix.org fj.sources:195  しらいです。  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 . # 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, -# 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, -# 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 @@ -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 .\" 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 .\" 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 -- しらい たかし