######################################################################## PHA 仕様 ver 0.01 ------------------------------------------------------------------------ 名称 PPMD Highlevel Archiver とも Public domain Highlevel Archiver とも。  前者は PPMD を使用しなくなる可能性もあり不適当であるし、後者も Public Domain じゃない部分も存在しているので、不適当かもしれない。  P-de H-na Archiver とか Pseudo Humbug Archiver とか Poor Humble Archiver とかいろいろ可能性がある。 PPMD Highlevel Archiver : PPMD 高水準アーカイバ  Public domain Highlevel Archiver : 公的領有物高水準アーカイバ P-de H-na Archiver : P〜でエッチなアーカイバ  Pseudo Humbug Archiver : 偽で詐りのアーカイバ  Poor Humble Archiver : 貧しく卑しいアーカイバ ------------------------------------------------------------------------ 特徴  アーカイブとしての機能を第一として考えている。圧縮に関しては  すでに存在する圧縮ツールを組み込むだけしかしていない。現在は、PPMD  を使用しているが、著作権や特許的にフリーな圧縮ツールを選択したい。  格納ファイル情報については冗長性があるが、かなり融通の利くように  している。入出力はメモリ、ファイルの2種類を選択できる。それぞれの  場合でサポートするサイズは OS 依存であるが、Windows では通常、  32bitのメモリサイズ、64ビットのファイルサイズを指定できる。  ソースは公開、コマンドラインプログラム、ライブラリ、DLL を用意する。  Shared Library については知識がないので今のところ用意していない。  プラットホームについてはサポートできうる限り多くする。メモリの使用は  たくさん必要とするだろう。著作権については、ソースごとに分かれるが、  基本的に Public Domain。日本では著作人格権は放棄できないので、  ほとんど著作権を主張しない形式となる。修正した版の公開に GPL など  制限の大きいものはなるべく使用しないで欲しい。BSD ライセンスなどで  あれば問題ない。GPL な修正については本ソースに取り入れることはない。  オブジェクトコードについては開発環境によるが通常のフリーソフトとしての  扱いである。 ソースの修正  ソースの修正を本流のソースに統合したい場合は、Public Domain に  なるべくして欲しい。著作人格権は放棄できないので、あくまで、  Public Domain 的になるたけ著作権を主張しないという形式である。  GPL 等の制限の強い修正は本流のソースには統合しないし、無視する  可能性がある。Public Domain よりは強いが BSD ライセンスなどの  弱い制限のものについては、別途のソースファイルにまとめるなどして  用意して欲しい。修正ソースを準備された方は ChangeLog、Author  に名前を記述する。 オブジェクトコード  ソースをコンパイルしたものに関するライセンスについては、使用した  ソース及びコンパイル環境の制約を受けるが、それ以上の制限は  ない。 使用ソース  crc32.c : CRC32 の計算については、zlib のソースを流用して用意した。 zlib は Jean-loup Gailly and Mark Adler に著作権がある。 PPMD 関連 : PPMD は Dmitry Shkarin の Public Domain プログラムであり、 PHA では圧縮に関して全面を PPMD に負っている。PHA ではそのソースを    改変して使用している。 その他の条件  再配布や改変、コンパイルしたものの利用についてはほとんど制約は  ないが、細かい部分については使用したソースにおける条件を参照すること。  このアーカイバの作者らが保証や責任を提供することはないので、利用者が  保証や責任を設定する必要があると思う。商用利用などは可能であろう。 法律上の制限  暗号アルゴリズムを含むので、この配布物自体の制限ではないが、USA に  輸出した場合 USA から再輸出できないなどは考慮されるべきである。 ------------------------------------------------------------------------ ------------------------------------------------------------------------ 書式   ABC5 ABC は固定長で 5バイトである。 ABC ABC は可変長である。サイズば別のところで指定。 sABC2、uABC8 sABC は符号付2バイト(16ビット)整数。 uABC は符号付8バイト(64ビット)整数。 sABC、uABC sABC は可変長符号付整数。サイズはデータに含まれる。 uABC は可変長符号なし整数。サイズはデータに含まれる。 rABC rABC はランダムデータである。 例: fc4d を格納する場合、uABC2=fc4d uABC=02fc4d 可変長整数 sINT、uINT = SIZEofINTEGER1,INTEGER SIZEofINTEGER1 : INTEGER のサイズ INTEGER : 整数(リトルエンディアン) 整数  少なくとも 32bit整数をアーカイバはサポートする。  サポートしない整数については基本的にエラー扱いにする。  が、32bit整数までしか使用できない環境で、64bit整数が  出てきても32bitより上位のビットが 0 であるならエラーに  しない。 Windows では 64bit 整数のファイルサイズまでサポートしている  ので、32bit整数までしか使えなくてもなんとかサポートする。  アーカイブに格納される整数はリトルエンディアンのみである。  基本の整数のサイズは 32bit だが、環境で最適なサイズを基本の  サイズとしてもよい。ファイルサイズ、ブロックの場所を指す  ポインタは最大の整数サイズを取ることが必要。 CRC CRC は 32bitCRC を基本とする。アーカイバによってサポートする CRC 以外が出てきたときはエラーにするか CRC を無視する。 CRC はオプションにより無視することができる。 現在は、32bitCRC を提供する crc32() しか用意していない。 ======================================================================== PHA の構造 HEADER16 BLOCK BLOCK . . . BLOCK ======================================================================== HEADER16 uCRC4,'-PHA-',uVERSION2,rRAND6 uCRC4 : CRC4 以降の部分の 32bitCRC uVERSION2 : バージョン。 rRAND6 : ランダムな6バイトデータ。アーカイバの新規作成ごとに     ランダムに作成される。アーカイバの操作時は変更されない。 ======================================================================== BLOCK HEADER6,uID1,CONTENT HEADER6: '-PH'c'B-' cの上位4ビット : ヘッダバージョン。 cの下位4ビット : ブロック加工。 0 : 無加工(初期値) 1 : 反転 2 : バイトごと1bit左シフト(ループ) 3 : バイトごと左1bit、右3bit交互にシフト(ループ) 6 : 暗号化(このブロックの前にある暗号ブロックオプションを使用) 7 : ネスト可能暗号化(暗号化の暗号化も可能)   ブロック加工はファイルの内容を簡単に読み取れなくするために    あるが、暗号化されているかも識別する。また、PHA アーカイブを    無圧縮で格納している PHA アーカイブの一部が壊れた場合、その    復旧時に、格納されている PHA アーカイブのヘッダ情報と間違わない    ための理由もある。 uID1: ブロックID。ブロックの種類を示す。 CONTENT : ブロックの内容    ブロックのサイズは ID により種別される ------------------------------------------------------------------------ BLOCK の内容 uID1=0xh : ベーシックブロックID ------------------------------------------------------------------------ uID1=00h : None(無意味なブロック) uSIZE,uCRC,CONTENT uSIZE : uSIZE 以降のサイズ    uCRC : uCRC 以降のサイズ    CONTENT : ブロックの中身   無視されるべきブロック。この中身に関してアーカイバは関知しない。 ------------------------------------------------------------------------ uID1=01h : Symple(通常のブロック) uSIZE,uCRC,CONTENT uSIZE : uSIZE 以降のサイズ    uCRC : uCRC 以降のサイズ    CONTENT : ブロックの中身   ファイルの圧縮内容などが含まれる。 ------------------------------------------------------------------------ uID1=02h : List(リストブロック) uNUMBER,BLOCK1,BLOCK2,... uNUMBER : 続く BLOCK の個数 BLOCK1,BLOCK2,... : ブロックのリスト   ファイル情報のリストが収めらる。   ファイルの圧縮内容などが分割して格納されるときも   この形式となる。 ------------------------------------------------------------------------ uID1=03h : EndOfList32(リストブロックの最後のブロック) uCRC4,rRAND28    uCRC4 : uCRC4 以降の 32bitCRC rRAND28 : ランダムデータ28バイト   List の最後のブロックとしてこのブロックを指定できるが   必要性はない。 ------------------------------------------------------------------------ uID1=1xh : オプションブロックID   ブロックがない場合は各初期値に設定される。 ------------------------------------------------------------------------ ID1=11h : ArchiverType(アーカイバの種類) uSIZE2,uCRC4,uTYPE1,OPTION uSIZE2 : uSIZE2 以降のサイズ    uCRC4 : uCRC4 以降の 32bitCRC uTYPE1 : アーカイバのタイプ OPTION : オプション uType1=01h(初期値) 通常アーカイブ(通常のアーカイブ、FileInfoBlockは繰り返しになる) HEADER OptionBlock . . ListBlock of FileInfoBlock FileInfoBlock FileContentBlock FileInfoBlock FileContentBlock . . アーカイブ作成時、格納ファイル情報を ListBlock of FileInfoBlock に すべて格納し出力する。ファイルごとに FileInfoBlock を出力し、    ファイルの内容を圧縮出力する。これを繰り返すが、圧縮出力した後、    その情報を ListBlock of FileInfoBlock 及び FileInfoBlock に適用する。     FileInfoBlock は二重手間になる。通常、 ListBlock of FileInfoBlock の    情報を使うが、 ListBlock of FileInfoBlock が何らかの原因により壊れた    時は、 FileInfoBlock の情報を使用する。 アーカイブ更新時はつねにテンポラリアーカイバを作成して行う。 uType1=02h 追加アーカイバ(追加していくのに適する) HEADER OptionBlock . . FileInfoBlock FileContentBlock FileInfoBlock FileContentBlock . .    通常アーカイブと比較して ListBlock of FileInfoBlock がない。    これは、アーカイブ更新時に重複ファイルがなくファイルを後ろへ    次々追加していくだけのときには、テンポラリアーカイブを作成    しなくてもよくするためである。重複ファイルが存在するときは、    テンポラリアーカイブを作成して行う。 uType1=01h ソリッドアーカイブ(ソリッドモードを使う) HEADER OptionBlock . . ListBlock of FileInfoBlock FileContentBlock アーカイブ作成時、格納ファイル情報を ListBlock of FileInfoBlock に  すべて格納する。その後、格納ファイルの内容を読みながら圧縮していく。    ファイル読み込みごとに読み取ることができたファイルサイズを     FileInfoBlock に適用するが、圧縮自体は連続して行う。    展開時は、 ListBlock of FileInfoBlock を元に、ファイルを解凍して    ファイルサイズごとにファイルを作成していく。 uType1=02h 混沌アーカイブ(ファイルの重複可能) HEADER OptionBlock . . FileInfoBlock FileContentBlock FileInfoBlock FileContentBlock . .    格納するファイルの重複を許す追加アーカイブモードである。    テンポラリアーカイブをまったく作成しない。バックアップ用    である。 ------------------------------------------------------------------------ uID1=12h : ArchiveInfo(アーカイブ情報) uSIZE,uCRC,uNUMBER,uAID2,uASIZE,AINFO[,uAID2,uASIZE,AINFO[,...]] uSIZE : uSIZE 以降のサイズ uCRC : uCRC 以降の CRC uNUMBER : uAID2,uASIZE,AINFO の繰り返しの数。 uAID2 : アーカイブ情報ID uASIZE : AINFO のサイズ AINFO : アーカイブ情報の内容(いくつかはファイル情報の        ところと重なる)     uAID2==0001h uASIZE AINFO=FileName(ファイル名)       文字列。ファイル名。     uAID2==0002h uASIZE AINFO=Name(名称)       文字列。アーカイブの名称。     uAID2==0003h uASIZE AINFO=Presentation(説明)       文字列。アーカイブの説明。     uAID2==0011h uASIZE=18 AINFO=CreatedTime(作成時間) uYear2,uMonth1,uDay1,uHour1,uMinute1,uSecond1,uMiliSecond1,Local     uAID2==0012h uASIZE=18 AINFO=ModifiedTime(更新時間) uYear2,uMonth1,uDay1,uHour1,uMinute1,uSecond1,uMiliSecond1,Local     uAID2==0013h uASIZE=18 AINFO=AccessedTime(参照時間) uYear2,uMonth1,uDay1,uHour1,uMinute1,uSecond1,uMiliSecond1,Local     uAID2==0021h uASIZE AINFO=Author(作成者)       文字列     uAID2==0031h uASIZE AINFO=Comment(コメント)       文字列。     uAID2==0111h uASIZE=4 AINFO=ArchiverID(作成アーカイバID)       アーカイブを作成したアーカイバのID。     uAID2==0112h uASIZE AINFO=ArchiverName(作成アーカイバ名)       文字列。アーカイブを作成したアーカイバ名。     uAID2==0113h uASIZE AINFO=ArchiverVersionName(作成アーカイバのバージョン名)       文字列。アーカイブを作成したアーカイバのバージョン。     uAID2==0121h uASIZE AINFO=OSID(OSID)       文字列。アーカイブを作成した環境の OS の ID。     uAID2==0122h uASIZE AINFO=OS(OS名)       文字列。アーカイブを作成した環境の OS名。     uAID2==0123h uASIZE AINFO=OSVersion(OSのバージョン)       文字列。アーカイブを作成した環境の OSのバージョン。     uAID2==0301h uASIZE=4 AINFO=CharType(文字タイプ、情報に使用されている文字コード) CharType=00000000h : NONE CharType=00000001h : ASCII CharType=00010001h : UNICODE CharType=00020001h : SJIS(Japanese) CharType=00020002h : JIS(Japanese) CharType=00020003h : EUC(Japanese)     uAID2==0302h uASIZE AINFO=DirectorySeparator(ディレクトリのセパレータ文字) '/','\'     uAID2==0303h uASIZE AINFO=ReturnCode(改行コード) 13h,13h10h,10h     4000h<=uAID2<=7fffh uASIZE AINFO=アーカイバ定義情報       アーカイバごとに定義できる情報。     uAID2>=8000h uASIZE AINFO=ユーザー定義情報       ユーザーごとに定義できる情報。 ------------------------------------------------------------------------ ID1=13h : Crypt(暗号) uSIZE,uCRC,uTYPE2,OPTION uSIZE : uSIZE 以降のサイズ    uCRC : uCRC 以降の CRC uTYPE1 : 暗号のタイプ OPTION : オプション(公開鍵を格納したりする) Type2 : 暗号の種類    0000h : 非暗号化(初期値)    0001h : 暗号情報クリア 以前の暗号ブロックの情報をクリアする。    0011h : XOR(内容暗号化法)    0021h : DES(内容暗号化法)(未実装)    0031h : RC(内容暗号化法)(未実装)    0041h : RSA(内容暗号化法)(未実装)    0051h : CAST-128(内容暗号化法)(未実装)    0052h : CAST-128(内容暗号化法)+RSA(キー暗号化法)(未実装)   ブロックの一番前のブロックの暗号ブロックの暗号化が   適用される。暗号ブロックをさらに暗号化することも可能である。   暗号ブロックが出ない前のブロックは暗号化されない。   暗号はサイズ変更されないものを使用する。 ------------------------------------------------------------------------ ID1=14h : CryptOption(暗号オプション) uSIZE,uCRC,CONTENT uSIZE : uSIZE 以降のサイズ    uCRC : uCRC 以降の CRC CONTENT : 暗号オプションの内容   Cryptブロックで格納できない部分を格納する ------------------------------------------------------------------------ ID1=2xh : 情報ブロックID ------------------------------------------------------------------------ ID1=21h : FileInfo(ファイル情報) ファイル格納前と後でサイズが変更される内容は格納できない。 uSIZE,uCRC,uNUMBER,uFID2,uFSIZE,FINFO[,uFID2,uFSIZE,FINFO,[...]] uSIZE: uSIZE以降のサイズ uCRC: uCRC 以降の CRC uNUMBER : ファイル情報(uFID2,uFSIZE,FINFO)の繰り返し数 uFID2: ファイル情報ID uFSIZE: ファイル情報サイズ FINFO: ファイル情報 uFID2=01xxh : ファイル情報システム uFID2=02xxh : ファイル情報オプショナル uFID2=04xxh : その他のファイル情報 4000h<=uFID2<=7fffh : アーカイバ定義情報(アーカイバごとに設定できる) uFID2>=8000h : ユーザー定義情報(ユーザーごとに設定できる) uFID2=0101h uFSIZE=8 FINFO=EncodeType(エンコードの種類) uTYPE1,OPTIONS (初期値) TYPE=00h :無圧縮 OPTIONSなし TYPE=01h :PPMD OPTIONS=uMemory1,uModelOrder1 TYPE=02h :PPMD、Solid OPTIONS=uMemory1,uModelOrder1 TYPE=11h :BZIP2 OPTIONS=uBlockSize1 TYPE=12h :BZIP2、Solid OPTIONS=uBlockSize1 uFID2=0102h (ソリッドモード時はなし) uFSIZE= FINFO=uContentBlockPointer (ファイル内容のブロックの開始絶対ポインタ) uFID2=0103h (ソリッドモード時はなし) uFSIZE= FINFO=uContentBlockSize (ファイル内容のブロックのサイズ) uFID2=0104h uFSIZE FINFO=PathName(パス名) パス変換(OS間) Windows DOS/UNIX //PCName/CommonName/.. -> PCName/CommonName/.. DOS/Windows UNIX C:/Dir1/Dir2/.. -> C/Dir1/Dir2 相対パス変換 C:/Dir1/Dir2/.. -> Dir1/Dir2 /Dir1/Dir2/.. -> Dir1/Dir2 LongFileName -> 8.3 Name abcdefghij.klmopq.rstuvw -> abcdefgh.rst -> abcdef~1.rst (重複時) . . -> abcde~10.rst .abcdefghij -> abcde~1 . . その他ファイル名にできない文字部分については その文字を除外して、~1 を付ける。 abc++de.fg+hi -> abcde~1.deh 絶対パスでも展開は通常相対パスとして行う。    オプションにより絶対パス展開は有効にできる。 uFID2=0105h uFSIZE=1 FINFO=FileType(ファイルの種類) File:01h,Directory:02h,SymbolicLink:03h,HardLink:04h オプションによって、SymbolicLink、HardLink がアーカイブ内の ファイルを指しているときはそのファイルのコピーを作成できる。 uFID2=0106h uFSIZE= FINFO=SizeOriginal(元のサイズ) uFID2=0107h uFSIZE= FINFO=SizeCompressed(圧縮時のサイズ) uContentBlockSize と同一である。 uFID2=0108h uFSIZE= FINFO=OriginalContentCRC(ファイル内容の CRC) オリジナル(展開後)の内容の CRC uFID2=0201h uFSIZE=2 FINFO=ModeUnix2 : oooo 2byte Misc,User,Group,Other 8bitごと uFID2=0202h uFSIZE=1 FINFO=ModeDos1 : oooo 1byte ReadOnly,System,Hidden,Archiver の5ビット uFID2=0203h uFSIZE FINFO=PathNameDos : パス名(DOS用 8.3、大文字規則) uFID2=0204h uFSIZE=18(18が望ましいが、8以上であればよい) FINFO=TimeModified(変更時刻) Year2,Month1,Day1,Hour1,Minute1,Second1,MiliSecond1,Local Local : 時間の地域を指す文字列 zzz[+/-]d[d][lll] 'GMT'0 'JST-9'0 +dddd : UTC からの差 '+0900'0 環境変数 TZ があるときはそれを付加します。 Windows では Win32API を使用して UTC にします。展開する ときは UTC から LocalTime にします。 上記以外のときは付加しませんが 'UTC' という意味になります。 uFID2=0205h uFSIZE=18(18が望ましいが、8以上であればよい) FINFO=TimeCreated(作成時刻) Year2,Month1,Day1,Hour1,Minute1,Second1,MiliSecond1,Local Local : 時間の地域を指す文字列 uFID2=0206h uFSIZE=18(18が望ましいが、8以上であればよい) FINFO=TimeAccessed(参照時刻) Year2,Month1,Day1,Hour1,Minute1,Second1,MiliSecond1,Local Local : 時間の地域を指す文字列 uFID2=0207h uFSIZE=4 FINFO=UID (UserID) uFID2=0208h uFSIZE=4 FINFO=GID (GroupID) uFID2=0301h FSIZE=4 FINFO=CharType(文字タイプ、情報に使用されている文字コード) ArchiveInfo.CharType の代わりに使う。 参照)ArchiveInfo.CharType uFID2=0302h uFSIZE FINFO=DirectorySeparator ArchiveInfo.DirectorySeparator の代わりに使う。 参照)ArchiveInfo.DirectorySeparator FID2=0303h uFSIZE FINFO=ReturnCode(改行コード) 13h,13h10h,10h ArchiveInfo.ReturnCode の代わりに使う。 参照)ArchiveInfo.ReturnCode FID2=0304h uFSIZE=2 FINFO=ContentType(ファイルの内容のタイプ) Binary:0001h,Text:0002h ArchiveInfo.ContentType の代わりに使う。 参照)ArchiveInfo.ContentType ------------------------------------------------------------------------ 40h<=ID1<=7fh : アーカイバ定義ブロック   各アーカイバが独自に定義できるブロック。作成アーカイバ情報を   取得して有効な場合このブロックの情報を使う。 uSIZE,CONTENT uSIZE : uSIZE 以降のサイズ ------------------------------------------------------------------------ ID1>=80h : ユーザ定義ブロック   各ユーザが独自に定義できるブロック。 uSIZE,CONTENT uSIZE : uSIZE 以降のサイズ ------------------------------------------------------------------------ ======================================================================== ラッパー  PHA アーカイブバイナリ自体をラップするフォーマット(仮) TextWrapper テキストでラップするフォーマット 構造 HEADER,RC CONTENT,RC TERMINATION,RC HEADER : ヘッダ '####-PHA-TEXT-WRAPPER-',TYPE,'-',NAME,'-',VOLUME,'-' HEADERTEXTWRAP : '####-PHA-TEXT-WRAPPER-' TYPE : 'UU','UUMB','BASE64','BASE64MB','ISH','ISHMB' NAME : 共通名(空白,'-'を除く文字)。マルチボリュームでは         すべて同一にする。 VOLUME : 'XXX/XXX' '1/10' など。省略可能 CONTENT : 内容 TERMINATION HEADER,'-END-' RC : リターンコード 一行は 80 文字未満にする。 BinaryWrapper   バイナリでラップするフォーマット(マルチボリューム) 構造 HEADER32 ARCHIVENAME BLOCK TERMINATION HEADER40, uCRC4,'-PHAMB-',uVERSION2,NAME16,VOLUME4,VOLUMEMAX4,rRAND7 uCRC4 : uCRC4 以降の 32bitCRC uVERSION2 : バージョン NAME : マルチボリュームの共通の名前。マルチボリュームでは         すべて同一にする。 VOLUME4 : マルチボリューム時の番号 VOLUMEMAX4 : マルチボリューム時の総数 rRAND7 : ランダムデータ ARCHIVENAME uSIZE,NAME uSIZE : uSIZE 以降のサイズ NAME : アーカイブ名(ファイル名を指定する)。    このブロックはマルチボリューム全体で一つあればよい。    ないときはマルチボリュームファイルの拡張子を取って、 PHA の拡張子をつけたものになる。   BLOCK uSIZE,CONTENT uSIZE : uSIZE 以降のサイズ     CONTENT : 内容 TERMINATION44 HEADER40,'-END-' HEADER40 : 上の HEADER40 と同一内容 ######################################################################## 2000/09/16