[Lha-users] LHa for UNIXにおいて解凍時にディレクトリの日付を復元するパッチ

Zurück zum Archiv-Index

Akihiro Iriyama iri****@bekko*****
2003年 12月 13日 (土) 02:07:44 JST


LHa for UNIX USERS メーリングリスト参加者の皆様

初めまして、入山と申します。
表題のとおり、先にBBSにて投稿したディレクトリ日付情報復元処理につい
てパッチを送付します。

長文で申し訳ありません。

圧縮アルゴリズムについては不勉強のため詳しくないのですが…
UNIXのtarでファイルを展開すると圧縮前のディレクトリの日付が復元される
のですが、LHaはWindows版もUNIX版も解凍した日付になってしまいます。

圧縮率を上げるために、-lh7-で再圧縮を行ったり、全く別のツールで圧縮し
たり、バックアップファイルをリストアしたり、日付情報が気になるときがあ
ります。

WindowsやUNIXではディレクトリにファイルを作成した時刻を元にディレクト
リの日付情報が更新されるため、LZH書庫ファイルをディレクトリ情報付きで
圧縮してあっても解凍時の日付情報になってしまいます。

実は私の利用している携帯の画面メモをSDカードリーダーでPCにバックアップ
するとディレクトリの日付情報がバックアップした日付情報になってしまうこ
とや、PC上のディレクトリツリーをバックアップ&リストアでディレクトリ
の日付が変わってしまうので色々オプションを調べて、見つからなかったので
ソース入手可能なLHa for UNIXを利用することを思い付きました。
#LHa for UNIX V1.17のソースは入手不可能なのでしょうか?

ディレクトリの日付復元は、"-lhd-"を元にディレクトリを作成する関数を呼
び出すときに作成ディレクトリ名称、LzHeaderをバッファに保存して、全解凍
終了後、保存したバッファの後ろから再度ディレクトリ属性の回復関数を呼び
出しています。

追加したコードは、
a. 構造体の宣言
b. 構造体の実体
c. データリスト追加関数
d. データリスト実行関数
e. 上記2関数の宣言
f. 同関数の呼び出し(計2箇所)
オリジナルソースとの差異は76行になります。

変更対象ファイルは、「lhext.c」のみです。

気に入らないところ
(1) 復元リストを単純に逆順で利用しているところ
 >文字列長などでソートしないと、親ディレクトリを回復してか
  ら子ディレクトリを回復することにより親ディレクトリの日付
  情報が解凍した時点になる可能性がないとはいえない。
(2) オプション情報などを無視している
 >自分の利用方法では問題ないので、無条件…
 ※"-lhd-"を元にディレクトリを作成する関数を呼び出すときに
  登録してるので、復元しないオプションを指定した場合、及
  びディレクトリ情報がなければ、実行されない(と思っている)か
  ら実害はないと思います。
(3) 関数名、変数名、構造体名などが完全独自
  LHaの命名規則などがわからないのでとりあえず…

% lha x LZHFILE
以外の動作は確認していませんm(__)m
コンパイル及び動作はWindows2000 SP3 + cygwin で行っております。
cygwinは次のバージョンです。
CYGWIN_NT-5.0 xxxx 1.5.5(0.94/3/2) 2003-09-20 16:31 i686 unknown unknown Cygwin

#最近はWindowsを使ってばっかり…

よろしくお願いします。
長文失礼しました。
以下、パッチです。

diff -u lha114i-unix/src/lhaext.c lha-1.14i-ac20030921/src
--- lha114i-unix/src/lhext.c	2003-07-13 02:53:50.000000000 +0900
+++ lha-1.14i-ac20030921/src/lhext.c	2003-12-12 01:37:54.231726400 +0900
@@ -25,6 +25,9 @@
     NULL
 };
 
+static void AddDerectory(char* name, LzHeader* hdr);
+static void AdjustDirectorys(/* void */);
+
 /* ------------------------------------------------------------------------ */
 static          boolean
 inquire_extract(name)
@@ -406,6 +409,8 @@
             } else { /* make directory */
                 if (!output_to_stdout && !make_parent_path(name))
                     return read_size;
+                /* save directory information */
+                AddDerectory(name, hdr);
             }
         }
     }
@@ -468,5 +473,76 @@
     /* close archive file */
     fclose(afp);
 
+    /* adjust directory information */
+    AdjustDirectorys();
+
     return;
 }
+
+/* ------------------------------------------------------------------------ */
+/* restor directory information Extention for directory time stamp          */
+/* add by A.Iriyama  2003.12.12  START                                      */
+/* ------------------------------------------------------------------------ */
+#define DIRECTORY_RESTOR_ALLOC_MIN     16
+typedef struct lhdDirectoryInfo_t {
+    int             n;
+    int             m;
+    struct _dirinfo_t {
+        LzHeader        hdr;
+        char            name[FILENAME_LENGTH];
+    } *dirbuf;
+} lhdDirInfo;
+
+static lhdDirInfo dirInfo = {
+    0, 0, NULL
+};
+
+static void AddDerectory(char* name, LzHeader* hdr)
+{
+    int   n = dirInfo.n;
+
+    if (memcmp(hdr->method, LZHDIRS_METHOD, 5) != 0) {
+        dirInfo.n = 0; /* safty */
+        return;
+    }
+    if (dirInfo.n == 0) {                      /* if first call alloc memory */
+        dirInfo.m = DIRECTORY_RESTOR_ALLOC_MIN;
+        dirInfo.dirbuf = calloc(sizeof(dirInfo.dirbuf[0]), dirInfo.m);
+/*        fprintf(stderr, "AddDirectory: alloc memory\n");    !* debug */
+    }
+    else if (dirInfo.m == dirInfo.n) {        /* if !first call realloc memory */
+        dirInfo.m += DIRECTORY_RESTOR_ALLOC_MIN;
+        dirInfo.dirbuf = realloc(dirInfo.dirbuf, sizeof(dirInfo.dirbuf[0]) * dirInfo.m);
+/*        fprintf(stderr, "AddDirectory: realloc memory\n");    !* debug */
+    }
+    if (dirInfo.dirbuf == NULL) {
+        /* print? error information */
+/*        fprintf(stderr, "AddDirectory: alloc memory error\n");    !* debug */
+        dirInfo.n = 0; /* safty */
+        return;
+    }
+    memcpy(&dirInfo.dirbuf[n].hdr, hdr, sizeof(LzHeader));
+    strcpy(dirInfo.dirbuf[n].name, name);
+/*    fprintf(stderr, "AddDirectory: %s add\n", name);    !* debug */
+    dirInfo.n++;
+}
+
+static void AdjustDirectorys(/* void */)
+{
+    int  i = 0;
+
+    if (0 < dirInfo.n) {
+        for (i = dirInfo.n-1; 0 <= i; --i) {
+            adjust_info(dirInfo.dirbuf[i].name, &dirInfo.dirbuf[i].hdr);
+        }
+    }
+    if (dirInfo.dirbuf != NULL) {
+        free(dirInfo.dirbuf);
+        dirInfo.dirbuf = NULL;
+    }
+    dirInfo.n      = 0;
+    dirInfo.m      = 0;
+}
+/* ------------------------------------------------------------------------ */
+/* add by A.Iriyama  2003.12.12  END                                        */
+/* ------------------------------------------------------------------------ */
--
Akihiro Iriyama
mailto:iri****@bekko*****



Lha-users メーリングリストの案内
Zurück zum Archiv-Index