[Lha-users] Ignore dot-files patch

Back to archive index

Koji Arai JCA02****@nifty*****
2002年 12月 15日 (日) 23:12:28 JST


新井です。

In message "Re: [Lha-users] Ignore dot-files patch"
  on Sat, 14 Dec 2002 14:00:49 +0900,
  Hiroto Sakai <sakai****@fan*****> wrote:
> 坂井です。
> 
> In Sat, 14 Dec 2002 06:56:40 +0900, Koji Arai wrote:
> >> GNU tar の -X のように除外したいファイルを指定できれば
> > っという方向にすべきでしょうか?(fnmatch(3) 使えばいいかな?)
> 
> そう思います。

一応、実装してみました。(まだ CVS に commit してません)tar 
の -X はファイルに除外ファイル(パターン)をリストしてそのファ
イルを指定するオプションなので、-x <pattern> にしました。(-x 
は、GNU diff にあるオプション)ちょっと eXtract と紛らわしい
ですが。

また、明示的に圧縮対象のファイルとして指定した場合は、パター
ンの方は無視されます。

つまり、

lha cx'*.o' src.lzh src/*.o

とかだとすべての .o は圧縮されます。(意図してそうなったので
はない^^;)

> ただ、Windows エクスプローラーではドットファイルは
> 作ることを許してくれないなど、あちらでもイレギュラーな
> 存在なので、一律に無視するのもありかなあとも思います。

.始まりなファイルは隠しファイルだとみなして-x で、パターンを
書かない場合に . で始まるファイルを無視(つまり、-x のデフォ
ルトパターンは、'.*')でもいいかもしれませんね。

Mac OS X での需要が高いのなら再度検討します。

> そういう意味では、毎回除外ファイルを指定するよりも
> Windows で都合の悪い/使わなさそうなファイルを一括して
> 無視してくれるオプションがあれば便利でよいですねえ ^_^;
> もちろん、任意のファイルを除外する機能もあれば素敵です。
> # lha -a hoge.lzh --windows -X huyo.txt hoge みたいな?

これはおそらくエクスプローラで扱えないファイルを無視するので
はなく、DOSでファイル名として無効な文字を置換してあげる機能
の方が便利ではないかと思います。他にも文字の大小の違いだけの
ファイルとか warning 出しつつ変えてあげるとか。

> MacLHA で MacBinary を指定した書庫でしか発生しないので
> 需要はあまり無いと思います。そうやって作った書庫を活用するのは
> きっと Mac ユーザですから MacLHA などで解凍するでしょうし。
> 
> Mac OS X 用に LHa for UNIX のフロントエンド(DropUnLHa)を
> 作ったんですが、リクエストは今のところありません。

りょっかい。

以下、-x オプションのパッチ。まだ、autoconf とかは考慮されてません。
(GNU でない free な fnmatch() を探さなきゃ)

realloc してる部分はとてもカッコ悪いのですが、lha のソースに
付属されたstring pool を使えばいいかなあっと思いつつ使い方を
調べてないので放置してます。

ま、仕様の方向性の検討が先ですから。


Index: src/lha.h
===================================================================
RCS file: /cvsroot/lha/lha/src/lha.h,v
retrieving revision 1.34
diff -u -u -p -r1.34 lha.h
--- src/lha.h	24 Nov 2002 18:16:14 -0000	1.34
+++ src/lha.h	15 Dec 2002 13:54:18 -0000
@@ -141,6 +141,15 @@ int utime(const char *, struct utimbuf *
 # endif
 #endif
 
+#if HAVE_FNMATCH_H
+# include <fnmatch.h>
+#else
+int fnmatch(const char *pattern, const char *string, int flags);
+# define FNM_PATHNAME 1
+# define FNM_NOESCAPE 2
+# define FNM_PERIOD   4
+#endif
+
 #ifndef SEEK_SET
 #define SEEK_SET        0
 #define SEEK_CUR        1
@@ -296,6 +305,7 @@ EXTERN boolean  recover_archive_when_int
 EXTERN boolean  remove_extracting_file_when_interrupt;
 EXTERN boolean  get_filename_from_stdin;
 EXTERN boolean  ignore_directory;
+EXTERN char   **exclude_files;
 EXTERN boolean  verify_mode;
 
 /* Indicator flag */
Index: src/lharc.c
===================================================================
RCS file: /cvsroot/lha/lha/src/lharc.c,v
retrieving revision 1.54
diff -u -u -p -r1.54 lharc.c
--- src/lharc.c	16 Nov 2002 19:03:23 -0000	1.54
+++ src/lharc.c	15 Dec 2002 13:54:18 -0000
@@ -90,6 +90,7 @@ init_variable()     /* Added N.Watazaki 
     remove_extracting_file_when_interrupt   = FALSE;
     get_filename_from_stdin                 = FALSE;
     ignore_directory                        = FALSE;
+    exclude_files                           = NULL;
     verify_mode                             = FALSE;
 
     noconvertcase                           = FALSE;
@@ -147,6 +148,7 @@ commands:                           opti
  c   re-Construct new archive        w=<dir> specify extract directory (a/u/m/x/e)\n\
  p   Print to STDOUT from archive    d  delete FILES after (a/u/c)\n\
  t   Test file CRC in archive        i  ignore directory path (x/e)\n\
+                                     x=<pattern>  eXclude files (a/u)\n\
                                      z  files not compress (a/u)\n\
                                      g  Generic format (for compatibility)\n\
                                         or not convert case when extracting\n\
@@ -336,6 +338,23 @@ main(argc, argv)
         case 'i':
             ignore_directory = TRUE;
             break;
+        case 'x':
+            if (*p == '=')
+                p++;
+            if (!exclude_files) {
+                exclude_files = (char**)xmalloc(sizeof(char*) * 1);
+                exclude_files[0] = 0;
+            }
+
+            for (i = 0; exclude_files[i]; i++)
+                ;
+            exclude_files = (char**)xrealloc(exclude_files,
+                                             sizeof(char*) * (i+1));
+            exclude_files[i] = xstrdup(p);
+            exclude_files[i+1] = 0;
+
+            p += strlen(p);
+            break;
         case 'w':
             if (*p == '=')
                 p++;
@@ -844,7 +863,7 @@ find_files(name, v_filec, v_filev)
 {
     struct string_pool sp;
     char            newname[FILENAME_LENGTH];
-    int             len, n;
+    int             len, n, i;
     DIR            *dirp;
     struct dirent  *dp;
     struct stat     tmp_stbuf, arc_stbuf, fil_stbuf;
@@ -864,6 +883,12 @@ find_files(name, v_filec, v_filev)
     GETSTAT(archive_name, &arc_stbuf);
 
     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+        for (i = 0; exclude_files && exclude_files[i]; i++) {
+            if (fnmatch(exclude_files[i], dp->d_name,
+                        FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD) == 0)
+                goto next;
+        }
+
         n = NAMLEN(dp);
         strncpy(newname + len, dp->d_name, n);
         newname[len + n] = '\0';
@@ -890,6 +915,7 @@ find_files(name, v_filec, v_filev)
             add_sp(&sp, newname, len + n + 1);
         }
 #endif
+    next:
     }
     closedir(dirp);
     finish_sp(&sp, v_filec, v_filev);



Lha-users メーリングリストの案内
Back to archive index