lha/ 755 4263 151 0 5162047050 4631 lha/CHANGES 644 4263 151 5200 5162045500 5704 LHx 0.01 -> 0.02 Usage の f オプションの説明表示がずれるのを直した。 lhadd.c の 49 行目の Warning (&hdr->method)を修正した。 strucmp.c の toupper() を static 関数に変更した。 lharc.h の malloc(),realloc() の返り値の宣言(Warning)を修正。 lhadd.c の 336 行目の copyfile() に第4引数 0 を追加。 malloc 関連の Warning を修正(cast)した。 patmatch.c の toupper を行なう条件に islower() を追加。 stdlib.h をインクルードする箇所に || defined(sony_news) を追加。 -lh0- のファイルをテストすると内容を表示するバグを修正。 展開時ヘッダレベル1に対応した。 crcio.c で putc() の代わりに fwrite() を使用するよう変更。 _errmsg() を使用しないよう変更。 石川@三菱電機さんの rename.c を付属。 memset() のないマシンのために memset.c を追加。(書き下ろし) LHx 0.02 -> LHa 0.03 名称を LHx から LHa に変更。 owner が root のときのみ chown() するよう変更。 本間隆之さんの timezone 関係のパッチを含めた。 lharc.c の135 行目を #endif /* MULTIBYTE_CHAR */ に変更。 g option 使用時にディレクトリ以下を圧縮できないバグを修正。 z option なしで標準入力からファイル名を読み込むように変更。 put_indicator() を append.c から crcio.c に移した。 crcio.c で fwrite() の返り値の比較対象を EOF から 0 に修正。 アーカイブ名に - を使用することで標準入出力を利用可能にした。 倉島@東大さんの EUC パッチを含めた。 ヘッダ関係を lharc.c から分離し header.c とした。 archive_is_msdos_sfx1() と skip_msdos_sfx1_code() を util.c に移した。 圧縮および展開をヘッダレベル1、2に対応。 デフォルトのヘッダレベルを1に変更。 デフォルトの圧縮方式を -lh5- に変更。h オプションを廃止。 無圧縮格納(z)オプションを追加。 LHarc 互換形式圧縮(o)オプションを追加。 標準入力のリダイレクト時にオーバーライト確認をしないよう変更。 uchar,ushort,uint,ulong を使用しないよう変更。typedef.h を削除。 LHa 0.03 -> LHa 0.04 (beta) -lh0- file で e, t option を有効にした。(by 倉島@東大さん) 引数にアーカイブのみ指定時に list 表示するよう変更。(by 倉島@東大さん) -DMKTIME でタイムスタンプが正常でないバグを修正。(by 渡邊@東北大さん) NEED_INCREMENTAL_INDICATOR 設定時の変数宣言を追加した。 lhadd.c の encode_stored_crc() の宣言の綴を修正した。(by 本間隆之さん) NULL が 0 でなくても動作するよう slide.c を変更した。 header.c の fwrite() で返り値を NULL ではなく 0 と比較するよう変更。 圧縮形式が正しくない時 Segmentation fault するバグを修正。 ディレクトリの圧縮形式を -lhd- にするよう変更。 strdup.c の strlib.h 読み込みの条件を修正。 header level 2 で圧縮できないバグを修正した。 386MINIX に対応。(by youchan@日経MIX さん) サブディレクトリのアーカイブと同名のファイルを圧縮できるようにした。 -DNOFTRUNCATE で石川@三菱電機さんの rename() を使うよう変更。 TITAN でコンパイルできるよう(?) lharc.h を変更。 lha/INSTALL 644 4263 151 4574 5162045503 5762 以下は、Makefile 中の CFLAGS マクロのフラグについて記述します。 ディレクトリの読み込み。 もし、opendir(), readdir(), closedr() が標準ライブラリにあり、そ れが direct 構造体を使用しているならばなにもいらない。 direct 構造体を使用していなければ、-DSYSV_SYSTEM_DIR を CFLAGS マ クロに追加。 もし、標準ライブラリになければ、 lhdir.o を Makefile の OBJS マク ロに追加して、-DNONSYSTEM_DIR_LIBRARY を CFLAGS マクロに追加。 これは、デリレクトリを直接 open/read/write して opendir などをエ ミュレートする。 それでもだめならあきらめて -DNODIRECTORY を CFLAGS マクロに追加。 これを指定した場合、ディレクトリを指定してのアーカイブができなく なる。 メモリー比較、コピー、ゼロフィル関係。 bcmp、bcopy、bzero のライブラリがないマシン(多くの System-V マシ ン)は、-DNOBSTRING を CFLAGS マクロに追加。これによって memcmp、memcpy、memset を使うようになる。それもなければ、以下と 等価なものを書きなさい。 int bcmp (a, b, n) char *a, *b; int n; { while (n--) if (*a++ != *b++) return (a[-1] & 0xff) - (b[-1] & 0xff); return 0; } void bcopy (s, d, n) char *s, *d; int n; { while (n--) *d++ = *s++; } void bzero (d, n) char *d; int n; { while (n--) *d++ = 0; } 時刻を扱う構造体 sys/time.h で struct tm を定義していなければ(time.h に定義してあるならば)、-DSYSTIME_HAS_NO_TM を CFLAGS マクロに追加。 ファイル I/O (多くの System-V で)ftruncate システムコールがなければ、 -DNOFTRUNCATE を CFLAGS マクロに追加。 # これをつけることにより、テンポラリファイルからコピーするときに # rename システムコールを使わなくなるだけ。 ファイルモード もし、(まだ見たことないが運わるく)stat で得られるファイルモード の意味が以下のものと違うならば、-DNOT_COMPATIBLE_MODE を CFLAGS マクロに追加し、ソースをそれなりに書き直す。 #define UNIX_FILE_TYPEMASK 0170000 #define UNIX_FILE_REGULAR 0100000 #define UNIX_FILE_DIRECTORY 0040000 #define UNIX_SETUID 0004000 #define UNIX_SETGID 0002000 #define UNIX_STYCKYBIT 0001000 #define UNIX_OWNER_READ_PERM 0000400 #define UNIX_OWNER_WRITE_PERM 0000200 #define UNIX_OWNER_EXEC_PERM 0000100 #define UNIX_GROUP_READ_PERM 0000040 #define UNIX_GROUP_WRITE_PERM 0000020 #define UNIX_GROUP_EXEC_PERM 0000010 #define UNIX_OTHER_READ_PERM 0000004 #define UNIX_OTHER_WRITE_PERM 0000002 #define UNIX_OTHER_EXEC_PERM 0000001 #define UNIX_RW_RW_RW 0000666 これ以上は各自にまかせる。以上。検討を祈る。 1989.09.18 Y.Tagawa 圧縮できないバグを修正した。 386MINIX に対応。(by youchan@日経MIX さん) サブディレクトリのアーカイブと同名のファイルを圧縮できlha/Makefile 644 4263 151 5354 5162045510 6364 # Makefile for LHarc UNIX Archiver Driver # Copyright(C) MCMLXXXIX Yooichi.Tagawa # V0.01 Alpha Version 1989.05.28 Y.Tagawa # V0.02 Alpha Version R2 1989.05.29 Y.Tagawa # V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa # V0.03b Modified 1989.07.13 Y.Tagawa # V1.00 Fixed 1989.09.19 Y.Tagawa # # for OSK # V1.08 1990.10.09 Sakura Tomozou # V2.00 + lzhuf4/5 1990.10.26 # # LHa for UNIX # V0.01 Alpha Version 1991.10.17 Masaru Oki # V0.02 Alpha Version Rel.2 1991.11.26 Masaru Oki # V0.03 Beta Version 1991.12.03 Masaru Oki # V0.04 Beta Version Rel.2 1992.01.17 Masaru Oki #----------------------------------------------------------------------- # CFLAGS macro definitions... #----------------------------------------------------------------------- # DIRECTORY ACCESS STUFF # The default (no need swtich) is your machine has # opendir(),readdir(),closedir() library and 'direct' structure used. # If your machine has no opendir (), readdir (), closedir () # -DNONSYSTEM_DIR_LIBRARY # and add lhdir.o into OBJS macro (see bellow) # If your machine are 'dirent' (not 'direct') structure used, # -DSYSV_SYSTEM_DIR # Otherwise "Give up!" # -DNODIRECTORY # #----------------------------------------------------------------------- # MEMORY ACCESS STUFF # Your machine has no BSTRING library (bcmp,bcopy,bzero). # -DNOBSTRING # #----------------------------------------------------------------------- # TIME STUFF # Your include file '' has no 'struct tm', define this. # -DSYSTIME_HAS_NO_TM # #----------------------------------------------------------------------- # FILE I/O STUFF # Your machine has no ftruncate system-call, define this. # -DNOFTRUNCATE #----------------------------------------------------------------------- # STRING STUFF # Your machine has no strdup(), define this. # -DNOSTRDUP #----------------------------------------------------------------------- LHOBJS = lharc.o lhadd.o lhlist.o lhext.o header.o HUFOBJS = append.o crcio.o dhuf.o extract.o huf.o larc.o maketbl.o \ maketree.o shuf.o slide.o util.o # missing library objects. # memset.o LIBRARYOBJS = memmove.o strucmp.o patmatch.o strdup.o rename.o OPTIMIZE = -O -DNOSTRDUP# -fstrength-reduce -fomit-frame-pointer SWITCHIES = -DEUC # -DNO_VOID OBJS = $(LHOBJS) $(HUFOBJS) $(LIBRARYOBJS) CC = cc CFLAGS = $(OPTIMIZE) $(SWITCHIES) DISTDIR = /usr/local/bin lha : $(OBJS) $(CC) -o $@ $(OBJS) $(LDFLAGS) lharc.o lhadd.o lhext.o lhlist.o header.o append.o slide.o extract.o : lharc.h $(HUFOBJS) : slidehuf.h crcio.o extract.o slide.o : intrface.h lharc.man : lharc.n jnroff -man lharc.n >lharc.man clean: rm -f core lha $(OBJS) moreclean: rm -f core *.o lha.tar lha.tar.Z *~ \#* install: install -s lha $(DISTDIR)/lha define UNIX_OTHER_EXEC_PERM 0000001 #define UNIX_RW_RW_RW 0000666 これ以上は各自にまかせる。以上。検討を祈る。 1989.09.18 Y.Tagawa 圧縮できないバグを修正した。 386MINIX に対応。(by youchan@日経MIX さん) サブディレクトリのアーカイブと同名のファイルを圧縮できlha/PROBLEMS 644 4263 151 2625 5162045513 6073 1)アーカイブ内の漢字ファイル名に対応していない 0.01 のときに内田@富士通さんから指摘されてい たのですがまだ対処していません。(すみません) また、対処の方法もいくつか選択肢があります。 アーカイブ内のファイル名はすべて S-JIS として 扱うべきなのか、UNIX であれば EUC を含めて良い のか、などなど。 2)マシン別の Makefile の設定がまとまっていない config.h をつくってそこにマシン別のマクロ定義を いれてみたいと思います。現在はまだ Makefile で 指定して下さい。 3)oooo... (NEED_INCREMENTAL_INDICATOR) を動的に変更可能にしていない q option で『まったく表示しない』指示は可能ですが、 表示形式の変更はまだサポートしていません。 また、細かい表示形式は好みの問題もあり決定が困難 な気がします。(しかし好みを主張する人も少ない…) 4)シンボリックリンクに対応していない NIFTY-Serve からの情報によると、X68000 版 LHa が シンボリックリンクに対応したようです。 リンクファイルの本家が後追いというのもちょっと情 けないですけど、互換をとる形でサポートしてみます。 …といいたいところですが、早期リリースを目指すた めに 1.00 ではサポートしません。 5)タイムスタンプ比較オプションがない どなたか余力のある方、お願いします。(_ _) 1.00 ではサポートしません。 6)標準入力からファイル名を入力する時 256 個以上入力できない ベクタ用の配列を静的に確保しているのが原因です。 7)g option と 1 or 2 option を併用すると展開できないアーカイブを生成 してしまう。(しかし、g option は廃止したいのでほおってある (^_^;) ---------- LHOBJS = lharc.o lhadd.o lhlist.o lhext.o header.o HUFOBJS = append.o crcio.o dhuf.o extract.lha/README 644 4263 151 5627 5162045520 5610 LHa for UNIX version 0.04(beta ver.) Jan 20 1991 by Masaru Oki. 新しくサポートされた -lh5- 圧縮形式での圧縮/展開が 可能なアーカイバ LHa の UNIX 版です。 UNIX 版 LHarc 1.02 (by Y.Tagawa) を改造し MS-DOS 版 LHx C2.01E (by 吉崎 栄泰) のアルゴリズムを付加した LHx(arc) V2.00 for OSK (by ももぞう) を、さらに私が UNIX 上で動作するようにしました。 src ディレクトリ上で、INSTALL を参考にして Makefile を適宜変更し、 make してください。_memset がないと ld におこられるときは、 Makefile 中の LIBRARYOBJS を編集して memset.o をリンクする ようにしてください。 現在コンパイルおよび動作確認されているプラットフォームは o Sun(SS2) SunOS 4.1.1 with JLE, with cc/gcc です。以前のバージョンが以下のプラットフォームで動作確認さ れていますので参考にして下さい。おそらく本バージョンも最小 限の変更で動作するはずです。 o Sun3 SunOS 4.0.3 with JLE, with cc o CISC NEWS (NEWS-821) NEWS-OS 2.2, 3.3a with cc o CISC NEWS (NEWS-830) NEWS-OS 4.1C with cc o POP NEWS (PWS-1550) NEWS-OS 4.1C with cc/gcc o RISC NEWS (NEWS-3460) NEWS-OS 4.1R with cc/gcc o Sequent Symmetry DYNIX(R) V3.0.17.v3 NFS #2 () o HP9000/300,375 HP-UX 7.0, 8.0 o MIPS RS3230/RS3330 RISC/os 4.51 with bsd cc o PFU Astation240 SX/A E60B o NEC EWS4800/10,220 EWS-UX/V (Rel. 4.0) R2.1 o NeXT NeXT OS 2.0, 2.1 with cc o LUNA UNIOS-B 1.50 with cc o LUNA(SX-9100/DT) UNIOS-U 2.00 with /bin/cc o VAX Ultrix v4.1 (Rev.52) o DEC5100 Ultrix v4.0(Rev.179)System #7 o stardent TITAN3000 OS 2.5 o IBM POWERstation530 o MELCOM ME200 SVR3.0 o その他いくつか… (^_^; コンパイル時および動作に問題が発生した場合は連絡をお願いします。 対象プラットフォーム(機種、OSバージョン、コンパイラ)および 症状を詳しくお知らせ下さい。また、LHa のソース変更によって正し く動作させることができた時には変更点をお知らせ下さい。 可能ならば次回配布に反映したいと思います。 また、新しいプラットフォームでのコンパイルおよび動作確認ができ たならば、お知らせ下さい。動作確認プラットフォームの情報を更新 したいと思います。 doc/* には LHx(arc) for OSK に附属していたドキュメント類を そのまま入れています。参考にして下さい。 (正式配布時にこれらは入れないようにするつもりです) config.txt にこれまで報告のあったプラットフォームのコンパイル オプションについて記述しています。これを元に config.h を作成 するつもりですので、修正、追加などあれば御連絡下さい。 前回配布との変更点 CHANGES を参照して下さい。 わかっている不具合 PROBLEMS を参照して下さい。 連絡先 JUNET: oki@wbg.telcom.oki.co.JP NIFTY-Serve: GGC02412 (ともに 1992 年 1 月 20 日現在) 謝辞 LHarc および LHa の原作者である吉崎栄泰さん、LHarc UNIX の作者である Y.Tagawa さん、LHx(arc) for OSK を作成され た ももぞう さん、それから LHa for UNIX メーリングリスト 等にて協力してくれた皆様に感謝致します。 最後に 今回の配布はベータ版です。1.00 は機能、操作ともに本配布 のままの予定です。あとはドキュメント類を整備して、でき れば config.h を組み込んでコンパイルしやすい形にしてか ら発表したいと思います。 1991 年 1 月 20 日 沖 勝 lha/README.P.SHY 644 4263 151 1150 5162045525 6440 Well, this is the LHA version for unix that I downloaded from an ftp server in Japan this morning, it compiled OK on my ultrix server here in Monterrey Tech, Mexico. The patch files are already applied, and *maybe* the Makefile may need a little bit of tuning, the only thing I changed on it was adding a -DNOSTRDUP since our libs don't have it. Who knows, just play with it :) Well, gotta go. I'm not so good at legal stuff, so this is copyright by some Japanese compression genius (can't remember his name), if you distribute it do it freely and... make good use of it (?) -RangerElf a.k.a. Gus Cordova. ] maketree.c|] memmove.c]memset.c] patmatch.c]read.me] readme.OSK] readme.lhx]rename.c]shuf.c$]slide.c8] slidehuf.h8L]strdup.cLd] strdup.c.ori]x] strucmp.cx]util.cd550) NEWS-OS 4.1C with cc/gcc o RISC NEWS (NEWS-3460) NEWS-OS 4lha/append.c 644 4263 151 4777 5162045531 6352 /*********************************************************** append.c -- append to archive ***********************************************************/ #include "lharc.h" #include "intrface.h" #ifdef NEED_INCREMENTAL_INDICATOR #define MAX_INDICATOR_COUNT 64 long indicator_count; long indicator_threshold; #endif extern int quiet; extern int compress_method; extern long int reading_size; extern unsigned short dicbit; struct interfacing interface; int encode_lzhuf (infp, outfp, size, original_size_var, packed_size_var, name,hdr_method) FILE *infp; FILE *outfp; long size; long *original_size_var; long *packed_size_var; char *name; char *hdr_method; { static int method = -1; if (method < 0) { method = compress_method; if (method > 0) method = encode_alloc(method); } interface.method = method; if (interface.method > 0) { interface.infile = infp; interface.outfile = outfp; start_indicator (name, size, "Freezing",1< 100) pcnt = 100; /* (^_^) */ printf ("\r%s\t- %s(%d%%)\n", name, msg, pcnt); fflush (stdout); } void finish_indicator (name, msg) char *name; char *msg; { if (quiet) return; #ifdef NEED_INCREMENTAL_INDICATOR printf ("\r%s\t- %s\n", name, msg); #else printf ("%s\n", msg); #endif fflush (stdout); } Xlha/append.c.ori 644 4263 151 4767 5162045535 7145 /*********************************************************** append.c -- append to archive ***********************************************************/ #include "lharc.h" #include "intrface.h" #ifdef NEED_INCREMENTAL_INDICATOR #define MAX_INDICATOR_COUNT 64 long indicator_count; long indicator_threshold; #endif extern int quiet; extern int compress_method; extern long int reading_size; extern ushort dicbit; struct interfacing interface; int encode_lzhuf (infp, outfp, size, original_size_var, packed_size_var, name,hdr_method) FILE *infp; FILE *outfp; long size; long *original_size_var; long *packed_size_var; char *name; char *hdr_method; { static int method = -1; if (method < 0) { method = compress_method; if (method > 0) method = encode_alloc(method); } interface.method = method; if (interface.method > 0) { interface.infile = infp; interface.outfile = outfp; start_indicator (name, size, "Freezing",1< 100) pcnt = 100; /* (^_^) */ printf ("\r%s\t- %s(%d%%)\n", name, msg, pcnt); fflush (stdout); } void finish_indicator (name, msg) char *name; char *msg; { if (quiet) return; #ifdef NEED_INCREMENTAL_INDICATOR printf ("\r%s\t- %s\n", name, msg); #else printf ("%s\n", msg); #endif fflush (stdout); } out); } Xlha/config.txt 644 4263 151 4626 5162045542 6740 Sun Microsystems(ベンダは省略させていただきます) Sun3/80,SPARC Station SunOS 4.0.3(-JLE 1.0.3) cc,gcc version 1.37.1 Sun Microsystems(ベンダは省略させていただきます) Sun#/80,SPARC Station SunOS 4.1.1-JLE 1.1.1(/Rev.B) cc,gcc -traditional SONY NWS-1460 NEWS-OS 3.3a cc,gcc -traditional SWITCHES に -DNOSTRDUP を追加 SONY NWS-1750 NEWS-OS 3.4 cc,gcc -traditional SWITCHES に -DNOSTRDUP を追加 SONY NWS-1830/1850 NEWS-OS 4.0.1C/4.1C cc,gcc SWITCHES に -DNOSTRDUP を追加 SONY NWS-3260/3460 NEWS-OS 4.1R cc,gcc version 1.40 SWITCHES に -DNOSTRDUP を追加 SONY NWS-3860 NEWS-OS 3.91R cc SWITCHES に -DNOSTRDUP を追加 OMRON LUNA (SX-9100/DT) UNIOS-B 1.50 cc,gcc version 1.40 SWITCHES に -DNOSTRDUP を追加 OMRON OMRON SX-9100DT UniOS-U 2.00 /bin/cc SWITCHES に -DSYSV_SYSTEM_DIR -DSYSTIME_HAS_NO_TM -DNOFTRUNCATE -DNOBSTRING を追加 SX-9100Σ OMRONIX-Σ /bin/cc SWITCHES に -DNONSYSTEM_DIR_LIBRARY -DSYSTIME_HAS_NO_TM -DNOTRUNCATE -DNOBSTRING を追加 NeXT NeXT station NeXT OS 2.1J cc SWITCHES に -DNOSTRDUP を追加 NeXT NeXT Cube Mach 2.1 /bin/cc NeXT Release 2.0 SWITCHES に -DNOSTRDUP を追加 DEC DEC5100 ULTRIX V4.0 /usr/bin/cc MIPS C compiler SWITCHES に -DNOSTRDUP を追加 DEC DEC Station 3100 ULTRIX V4.1 SWITCHES に -DNOSTRDUP を追加 DEC MicroVAX-3600 ULTRIX V4.2 (Rev. 96) SWITCHES に -DNOSTRDUP を追加 Panasonic BE BE-OS 1.3 gcc version 1.37.1 SWITCHES に -DSYSV_SYSTEM_DIE -DSYSTIME_HAS_NO_TM -DTZEST -DNOFTRUNCATE を追加 MIPS RS3230/3330 RISC/os 4.51 cc SWITCHES に -DNOSTRDUP を追加 Sequent Computer Systems, Inc. Symmetry DYNIX(R) V3.0.17.v3 NFS #2() cc SWITCHES に -DJIS -DNOSTRDUP を追加,LIBRARYOBJS に memset.o を追加 Solbourne Series 5/600 OS/MP 4.0D_Export cc,gcc -traditional 三菱電機 ME-250/400 System V/68 Release R3V4 M68030 Version C00R9103 cc SWITCHES に -DSYSV_SYSTEM_DIR -DNOFTRUNCATE を,LIBRARYOBJS に rename.o を追加 NEC EWS4800/10 EWS-UX/V R8.1 cc,gcc -traditional SWITCHES に -I/usr/ucbinclude -DSYSTIME_HAS_NO_TM -DTZSET を追加,LDFLAGS=-ldir を追加 NEC EWS4800/220 EWS-UX/V (Rel 4.0)R2.1 /bin/cc,/usr/ucb/cc HP HP9000s300 HP-UX7.0 SWITCHES に -DSYSV_SYSTEM_DIR -DNOBSTRING -DSYSTIME_HAS_NO_TM を追加 HP HP9000s730 HP-UX 8.0 SWITCHES に -DSYSV_SYSTEM_DIR -DNOBSTRING -DSYSTIME_HAS_NO_TM を追加 日立 HIDIC V90/45 RENIX-V /bin/cc SWITCHES に -DTZSET -DSYSV_SYSTEM_DIR -DNOBSTRING -DNOFTRUNCATE を追加 東芝 J3100SGT UX/386 (SysVR3) /bin/cc SWITCHES に -DTZSET -DSYSV_SYSTEM_DIR -DNOBSTRING -DNOFTRUNCATE,LIBRARYOBJS に rename.o を追加 TOR printf ("\r%s\t- %s\n", name, msg); #else printf ("%s\n", msg); #endif fflush (stdout); } out); } Xlha/crcio.c 644 4263 151 14135 5162045547 6216 /*********************************************************** crcio.c -- input/output ***********************************************************/ #ifdef __STDC__ #include #include #endif #include #include "slidehuf.h" #include "intrface.h" extern int text_mode; extern int prev_char; extern int verify_mode; #ifdef EUC extern int euc_mode; extern int generic_format; #endif long reading_size; #define CRCPOLY 0xA001 /* CRC-16 */ #define UPDATE_CRC(c) \ crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT) FILE *infile, *outfile; unsigned short crc, bitbuf; static unsigned short crctable[UCHAR_MAX + 1]; static unsigned char subbitbuf, bitcount; #ifdef EUC static int putc_euc_cache; #endif static int getc_euc_cache; void make_crctable(void) { unsigned int i, j, r; for (i = 0; i <= UCHAR_MAX; i++) { r = i; for (j = 0; j < CHAR_BIT; j++) if (r & 1) r = (r >> 1) ^ CRCPOLY; else r >>= 1; crctable[i] = r; } } #ifdef NEED_INCREMENTAL_INDICATOR extern int quiet; extern int indicator_count; extern int indicator_threshold; static void put_indicator( count ) long int count; { if (!quiet) { while ( count > indicator_count) { putchar ('o'); fflush (stdout); indicator_count += indicator_threshold; } } } #endif unsigned short calccrc( p , n ) unsigned char *p; unsigned int n; { reading_size += n; #ifdef NEED_INCREMENTAL_INDICATOR put_indicator( reading_size ); #endif while (n-- > 0) UPDATE_CRC(*p++); return crc; } void fillbuf(n) /* Shift bitbuf n bits left, read n bits */ unsigned char n; { while (n > bitcount) { n -= bitcount; bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount)); if (compsize != 0) { compsize--; subbitbuf = (unsigned char) getc(infile); } else subbitbuf = 0; bitcount = CHAR_BIT; } bitcount -= n; bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n)); subbitbuf <<= n; } unsigned short getbits(n) unsigned char n; { unsigned short x; x = bitbuf >> (2 * CHAR_BIT - n); fillbuf(n); return x; } void putcode( n , x ) /* Write rightmost n bits of x */ unsigned char n; unsigned short x; { while (n >= bitcount) { n -= bitcount; subbitbuf += x >> (USHRT_BIT - bitcount); x <<= bitcount; if (compsize < origsize) { if (fwrite(&subbitbuf, 1, 1, outfile) == 0) /* fileerror(WTERR, outfile); */ exit( errno ); compsize++; } else unpackable = 1; subbitbuf = 0; bitcount = CHAR_BIT; } subbitbuf += x >> (USHRT_BIT - bitcount); bitcount -= n; } void putbits( n , x ) /* Write rightmost n bits of x */ unsigned char n; unsigned short x; { x <<= USHRT_BIT - n; while (n >= bitcount) { n -= bitcount; subbitbuf += x >> (USHRT_BIT - bitcount); x <<= bitcount; if (compsize < origsize) { if (fwrite(&subbitbuf, 1, 1, outfile) == 0) /* fileerror(WTERR, outfile); */ exit( errno ); compsize++; } else unpackable = 1; subbitbuf = 0; bitcount = CHAR_BIT; } subbitbuf += x >> (USHRT_BIT - bitcount); bitcount -= n; } int fread_crc( p, n, fp ) unsigned char *p; int n; FILE *fp; { if ( text_mode ) n = fread_txt(p, n, fp); else n = fread(p, 1, n, fp); calccrc(p, n); return n; } void fwrite_crc( p, n, fp ) unsigned char *p; int n; FILE *fp; { calccrc(p,n); if ( verify_mode ) return; if ( fp ) { if ( text_mode ) { if ( fwrite_txt(p , n , fp) ) fatal_error("File write error\n"); } else { if (fwrite(p, 1, n, fp) < n) fatal_error("File write error\n"); } } } void init_code_cache(void) /* called from copyfile() in util.c */ { #ifdef EUC putc_euc_cache = EOF; #endif getc_euc_cache = EOF; } void init_getbits(void) { bitbuf = 0; subbitbuf = 0; bitcount = 0; fillbuf(2 * CHAR_BIT); #ifdef EUC putc_euc_cache = EOF; #endif } void init_putbits(void) { bitcount = CHAR_BIT; subbitbuf = 0; getc_euc_cache = EOF; } #ifdef EUC void putc_euc(c, fd) int c; FILE *fd; { int d; if (putc_euc_cache == EOF) { if (!euc_mode || c < 0x81 || c > 0xFC) { putc(c, fd); return; } if (c >= 0xA0 && c < 0xE0) { putc(0x8E, fd); /* single shift */ putc(c, fd); return; } putc_euc_cache = c; /* save first byte */ return; } d = putc_euc_cache; putc_euc_cache = EOF; if (d >= 0xA0) d -= 0xE0 - 0xA0; if (c > 0x9E) { c = c - 0x9F + 0x21; d = (d - 0x81) * 2 + 0x22; } else { if (c > 0x7E) c --; c -= 0x1F; d = (d - 0x81) * 2 + 0x21; } putc(0x80 | d, fd); putc(0x80 | c, fd); } #endif int fwrite_txt( p , n , fp ) unsigned char *p; int n; FILE *fp; { while ( --n>=0 ) { if ( *p!='\015' && *p!='\032' ) { #ifdef EUC putc_euc( *p , fp ); #else putc( *p , fp ); #endif } prev_char = *p++; } return ( ferror( fp ) ); } int fread_txt( p , n , fp ) unsigned char *p; int n; FILE *fp; { int c; int cnt = 0; while (cnt < n) { if (getc_euc_cache != EOF) { c = getc_euc_cache; getc_euc_cache = EOF; } else { if ((c = fgetc(fp)) == EOF) break; if (c == '\n') { getc_euc_cache = c; c = '\r'; } #ifdef EUC else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF)) { int d = fgetc(fp); if (d == EOF) { *p++ = c; cnt ++; break; } if (c == 0x8E) /* single shift (KANA) */ { if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF)) c = d | 0x80; else getc_euc_cache = d; } else { if (0xA0 < d && d < 0xFF) /* if GR */ { c &= 0x7F; /* convert to MS-kanji */ d &= 0x7F; if (!(c & 1)) { c --; d += 0x7F - 0x21; } if ((d += 0x40 - 0x21) > 0x7E) d ++; if ((c = (c >> 1) + 0x71) >= 0xA0) c += 0xE0 - 0xA0; } getc_euc_cache = d; } } #endif } *p++ = c; cnt ++; } return cnt; } r( count ) long int count; { if (!quiet) { while ( count > indicator_count) { putchar ('o'); fflush (stdout); indicator_count += indicator_threshold; } } } #endif unsigned short calccrc( p , n ) unsigned char *p; unsigned int n; { reading_size += n; #ifdef NEED_INCREMENTAL_INDICATOR put_indicator( reading_size ); #endif while (n-- > 0) UPDATE_CRC(*p++); return crc; } void fillbuf(n) /* Shift blha/dhuf.c 644 4263 151 12552 5162045553 6043 /************************************************************** title dhuf.c *************************************************************** Dynamic Huffman routine H.Yoshizaki **************************************************************/ #include #include "slidehuf.h" #define N_CHAR (256 + 60 - THRESHOLD + 1) #define TREESIZE_C (N_CHAR * 2) #define TREESIZE_P (128 * 2) #define TREESIZE (TREESIZE_C + TREESIZE_P) #define ROOT_C 0 #define ROOT_P TREESIZE_C unsigned int n_max; static short child [TREESIZE], parent[TREESIZE], block [TREESIZE], edge [TREESIZE], stock [TREESIZE], node [TREESIZE / 2]; static unsigned short freq[TREESIZE]; static unsigned short total_p; static int avail, n1; static int most_p, nn; static unsigned long nextcount; void start_c_dyn(void) { int i, j, f; n1 = (n_max >= 256 + maxmatch - THRESHOLD + 1) ? 512 : n_max - 1; for (i = 0; i < TREESIZE_C; i++) { stock[i] = i; block[i] = 0; } for (i = 0, j = n_max * 2 - 2; i < n_max; i++, j--) { freq[j] = 1; child[j] = ~i; node[i] = j; block[j] = 1; } avail = 2; edge[1] = n_max - 1; i = n_max * 2 - 2; while (j >= 0) { f = freq[j] = freq[i] + freq[i - 1]; child[j] = i; parent[i] = parent[i - 1] = j; if (f == freq[j + 1]) { edge[block[j] = block[j + 1]] = j; } else { edge[block[j] = stock[avail++]] = j; } i -= 2; j--; } } static void start_p_dyn(void) { freq[ROOT_P] = 1; child[ROOT_P] = ~(N_CHAR); node[N_CHAR] = ROOT_P; edge[block[ROOT_P] = stock[avail++]] = ROOT_P; most_p = ROOT_P; total_p = 0; nn = 1 << dicbit; nextcount = 64; } void decode_start_dyn(void) { n_max = 286; maxmatch = MAXMATCH; init_getbits(); start_c_dyn(); start_p_dyn(); } static void reconst( start , end ) int start; int end; { int i, j, k, l, b; unsigned int f, g; for (i = j = start; i < end; i++) { if ((k = child[i]) < 0) { freq[j] = (freq[i] + 1) / 2; child[j] = k; j++; } if (edge[b = block[i]] == i) { stock[--avail] = b; } } j--; i = end - 1; l = end - 2; while (i >= start) { while (i >= l) { freq[i] = freq[j]; child[i] = child[j]; i--, j--; } f = freq[l] + freq[l + 1]; for (k = start; f < freq[k]; k++); while(j >= k) { freq[i] = freq[j]; child[i] = child[j]; i--, j--; } freq[i] = f; child[i] = l + 1; i--; l -= 2; } f = 0; for (i = start; i < end; i++) { if ((j = child[i]) < 0) node[~j] = i; else parent[j] = parent[j - 1] = i; if ((g = freq[i]) == f) { block[i] = b; } else { edge[b = block[i] = stock[avail++]] = i; f = g; } } } static int swap_inc(p) int p; { int b, q, r, s; b = block[p]; if ((q = edge[b]) != p) { /* swap for leader */ r = child[p]; s = child[q]; child[p] = s; child[q] = r; if (r >= 0) parent[r] = parent[r - 1] = q; else node[~r] = q; if (s >= 0) parent[s] = parent[s - 1] = p; else node[~s] = p; p = q; goto Adjust; } else if (b == block[p + 1]) { Adjust: edge[b]++; if (++freq[p] == freq[p - 1]) { block[p] = block[p - 1]; } else { edge[block[p] = stock[avail++]] = p; /* create block */ } } else if (++freq[p] == freq[p - 1]) { stock[--avail] = b; /* delete block */ block[p] = block[p - 1]; } return parent[p]; } static void update_c(p) int p; { int q; if (freq[ROOT_C] == 0x8000) { reconst(0, n_max * 2 - 1); } freq[ROOT_C]++; q = node[p]; do { q = swap_inc(q); } while (q != ROOT_C); } static void update_p(p) int p; { int q; if (total_p == 0x8000) { reconst(ROOT_P, most_p + 1); total_p = freq[ROOT_P]; freq[ROOT_P] = 0xffff; } q = node[p + N_CHAR]; while (q != ROOT_P) { q = swap_inc(q); } total_p++; } static void make_new_node(p) int p; { int q, r; r = most_p + 1; q = r + 1; node[~(child[r] = child[most_p])] = r; child[q] = ~(p + N_CHAR); child[most_p] = q; freq[r] = freq[most_p]; freq[q] = 0; block[r] = block[most_p]; if (most_p == ROOT_P) { freq[ROOT_P] = 0xffff; edge[block[ROOT_P]]++; } parent[r] = parent[q] = most_p; edge[block[q] = stock[avail++]] = node[p + N_CHAR] = most_p = q; update_p(p); } static void encode_c_dyn(c) int c; { unsigned int bits; int p, d, cnt; d = c - n1; if (d >= 0) { c = n1; } cnt = bits = 0; p = node[c]; do { bits >>= 1; if (p & 1) { bits |= 0x8000; } if (++cnt == 16) { putcode(16, bits); cnt = bits = 0; } } while ((p = parent[p]) != ROOT_C); putcode(cnt, bits); if (d >= 0) putbits(8, d); update_c(c); } unsigned short decode_c_dyn(void) { int c; short buf, cnt; c = child[ROOT_C]; buf = bitbuf; cnt = 0; do { c = child[c - (buf < 0)]; buf <<= 1; if (++cnt == 16) { fillbuf(16); buf = bitbuf; cnt = 0; } } while (c > 0); fillbuf(cnt); c = ~c; update_c(c); if (c == n1) c += getbits(8); return c; } unsigned short decode_p_dyn(void) { int c; short buf, cnt; while (count > nextcount) { make_new_node(nextcount / 64); if ((nextcount += 64) >= nn) nextcount = 0xffffffff; } c = child[ROOT_P]; buf = bitbuf; cnt = 0; while (c > 0) { c = child[c - (buf < 0)]; buf <<= 1; if (++cnt == 16) { fillbuf(16); buf = bitbuf; cnt = 0; } } fillbuf(cnt); c = (~c) - N_CHAR; update_p(c); return (c << 6) + getbits(6); } void output_dyn( code , pos ) int code; unsigned int pos; { encode_c_dyn(code); if (code >= 0x100) { encode_p_st0(pos); } } void encode_end_dyn(void) { putcode(7, 0); } lha/extract.c 644 4263 151 2475 5162045557 6556 /*********************************************************** extract.c -- extract file from archive ***********************************************************/ #include "lharc.h" #include "intrface.h" extern int verify_mode; int decode_lzhuf (infp, outfp, original_size, packed_size,name , method) FILE *infp; FILE *outfp; long original_size; long packed_size; char *name; int method; { interface.method = method; interface.dicbit = 13; /* method + 8; */ interface.infile = infp; interface.outfile = outfp; interface.original = original_size; interface.packed = packed_size; switch (method) { case 0: case 8: start_indicator (name, original_size , verify_mode ? "Testing " : "Melting ",2048); copyfile(infp, (verify_mode ? NULL : outfp), original_size, 2); break; case 6: /* -lzs- */ interface.dicbit = 11; start_indicator (name, original_size , verify_mode ? "Testing " : "Melting " , 1<> 8); } static long get_longword () { long b0, b1, b2, b3; b0 = get_byte (); b1 = get_byte (); b2 = get_byte (); b3 = get_byte (); return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0; } static void put_longword (v) long v; { put_byte (v); put_byte (v >> 8); put_byte (v >> 16); put_byte (v >> 24); } static void msdos_to_unix_filename (name, len) register char *name; register int len; { register int i; #ifdef MULTIBYTE_CHAR for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (name[i] == '\\') name[i] = '/'; else if (isupper (name[i])) name[i] = tolower (name[i]); } #else for (i = 0; i < len; i ++) { if (name[i] == '\\') name[i] = '/'; else if (isupper (name[i])) name[i] = tolower (name[i]); } #endif } static void generic_to_unix_filename (name, len) register char *name; register int len; { register int i; boolean lower_case_used = FALSE; #ifdef MULTIBYTE_CHAR for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (islower (name[i])) { lower_case_used = TRUE; break; } } for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (name[i] == '\\') name[i] = '/'; else if (!lower_case_used && isupper (name[i])) name[i] = tolower (name[i]); } #else for (i = 0; i < len; i ++) if (islower (name[i])) { lower_case_used = TRUE; break; } for (i = 0; i < len; i ++) { if (name[i] == '\\') name[i] = '/'; else if (!lower_case_used && isupper (name[i])) name[i] = tolower (name[i]); } #endif } static void macos_to_unix_filename (name, len) register char *name; register int len; { register int i; for (i = 0; i < len; i ++) { if (name[i] == ':') name[i] = '/'; else if (name[i] == '/') name[i] = ':'; } } static void unix_to_generic_filename (name, len) register char *name; register int len; { register int i; for (i = 0; i < len; i ++) { if (name[i] == '/') name[i] = '\\'; else if (islower (name[i])) name[i] = toupper (name[i]); } } /*----------------------------------------------------------------------*/ /* */ /* Generic stamp format: */ /* */ /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */ /* |<-------- year ------->|<- month ->|<-- day -->| */ /* */ /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */ /* |<--- hour --->|<---- minute --->|<- second*2 ->| */ /* */ /*----------------------------------------------------------------------*/ /* NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2) returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET. */ /* choose one */ #if defined(MKTIME) #ifdef TIMELOCAL #undef TIMELOCAL #endif #endif /* defined(MKTIME) */ #if defined(MKTIME) || defined(TIMELOCAL) #ifdef TZSET #undef TZSET #endif #endif /* defined(MKTIME) || defined(TIMELOCAL) */ #if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET) #ifdef FTIME #undef FTIME #endif #endif #if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET) || defined(FTIME) #ifdef GETTIMEOFDAY #undef GETTIMEOFDAY #endif #else #ifndef GETTIMEOFDAY #define GETTIMEOFDAY /* use gettimeofday() */ #endif #endif #ifdef FTIME #include #endif /* You may define as : #define TIMEZONE_HOOK \ extern long timezone ; \ extern void tzset(); */ #ifdef TIMEZONE_HOOK TIMEZONE_HOOK /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */ #endif #if defined(TZSET) && defined(_MINIX) extern long timezone; /* not defined in time.h */ #endif #if defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET) static long gettz () #ifdef TZSET { tzset(); return timezone; } #elif defined(FTIME) { struct timeb buf; ftime(&buf); return buf.timezone * 60L; } #else /* maybe defined(GETTIMEOFDAY) */ { struct timeval tp; struct timezone tzp; gettimeofday (&tp, &tzp); /* specific to 4.3BSD */ /* return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L * 60L : 0));*/ return (tzp.tz_minuteswest * 60L); } #endif #endif /* defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET) */ #ifdef NOT_USED static struct tm * msdos_to_unix_stamp_tm (a) long a; { static struct tm t; t.tm_sec = ( a & 0x1f) * 2; t.tm_min = (a >> 5) & 0x3f; t.tm_hour = (a >> 11) & 0x1f; t.tm_mday = (a >> 16) & 0x1f; t.tm_mon = ((a >> 16+5) & 0x0f) - 1; t.tm_year = ((a >> 16+9) & 0x7f) + 80; return &t; } #endif static time_t generic_to_unix_stamp (t) long t; #if defined(MKTIME) || defined(TIMELOCAL) { struct tm dostm; /* special case: if MSDOS format date and time were zero, then we set time to be zero here too. */ if (t == 0) return (time_t)0; dostm.tm_sec = (t & 0x1f) * 2; dostm.tm_min = t >> 5 & 0x3f; dostm.tm_hour = t >> 11 & 0x1f; dostm.tm_mday = t >> 16 & 0x1f; dostm.tm_mon = (t >> 16+5 & 0x0f) - 1; /* 0..11 */ dostm.tm_year = (t >> 16+9 & 0x7f) + 80; dostm.tm_isdst = 0; /* correct? */ #ifdef MKTIME return (time_t)mktime(&dostm); #else /* maybe defined(TIMELOCAL) */ return (time_t)timelocal(&dostm); #endif } #else /* defined(MKTIME) || defined(TIMELOCAL) */ { int year, month, day, hour, min, sec; long longtime; static unsigned int dsboy[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; unsigned int days; /* special case: if MSDOS format date and time were zero, then we set time to be zero here too. */ if (t == 0) return (time_t)0; year = ((int)(t >> 16+9) & 0x7f) + 1980; month = (int)(t >> 16+5) & 0x0f; /* 1..12 means Jan..Dec */ day = (int)(t >> 16) & 0x1f; /* 1..31 means 1st,...31st */ hour = ((int)t >> 11) & 0x1f; min = ((int)t >> 5) & 0x3f; sec = ((int)t & 0x1f) * 2; /* Calculate days since 1970.01.01 */ days = (365 * (year - 1970) + /* days due to whole years */ (year - 1970 + 1) / 4 + /* days due to leap years */ dsboy[month-1] + /* days since beginning of this year */ day-1); /* days since beginning of month */ if ((year % 4 == 0) && (year % 400 != 0) && (month >= 3)) /* if this is a leap year and month */ days ++; /* is March or later, add a day */ /* Knowing the days, we can find seconds */ longtime = (((days * 24) + hour) * 60 + min) * 60 + sec; longtime += gettz (); /* adjust for timezone */ /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */ return (time_t)longtime; } #endif /* defined(MKTIME) || defined(TIMELOCAL) */ static long unix_to_generic_stamp (t) time_t t; { struct tm *tm = localtime (&t); return ((((long)(tm->tm_year - 80)) << 25) + (((long)(tm->tm_mon + 1)) << 21) + (((long)tm->tm_mday) << 16) + (long)((tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2))); } /*----------------------------------------------------------------------*/ /* build header functions */ /*----------------------------------------------------------------------*/ boolean get_header (fp, hdr) FILE *fp; register LzHeader *hdr; { int header_size; int name_length; char data[LZHEADER_STRAGE]; char dirname[FILENAME_LENGTH]; int dir_length = 0; int checksum; int i; char *ptr; bzero (hdr, sizeof (LzHeader)); if (((header_size = getc (fp)) == EOF) || (header_size == 0)) { return FALSE; /* finish */ } if (fread (data + I_HEADER_CHECKSUM, sizeof (char), header_size + 1, fp) < header_size + 1) { fatal_error ("Invalid header (LHarc file ?)"); return FALSE; /* finish */ } setup_get (data + I_HEADER_CHECKSUM); checksum = get_byte(); hdr->header_size = header_size; bcopy (data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE); #ifdef OLD if ((bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) != 0)) { warning ("Unknown method (LHarc file ?)", ""); return FALSE; /* invalid method */ } #endif setup_get (data + I_PACKED_SIZE); hdr->packed_size = get_longword (); hdr->original_size = get_longword (); hdr->last_modified_stamp = get_longword (); hdr->attribute = get_byte (); if ((hdr->header_level = get_byte ()) != 2) { if (calc_sum (data + I_METHOD, header_size) != checksum) warning ("Checksum error (LHarc file?)", ""); name_length = get_byte (); for (i = 0; i < name_length; i ++) hdr->name[i] =(char)get_byte (); hdr->name[name_length] = '\0'; } else { hdr->unix_last_modified_stamp = hdr->last_modified_stamp; name_length = 0; } /* defaults for other type */ hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW; hdr->unix_gid = 0; hdr->unix_uid = 0; if (header_size - name_length >= 24) { /* EXTEND FORMAT */ hdr->crc = get_word (); hdr->extend_type = get_byte (); hdr->has_crc = TRUE; } else if (header_size - name_length == 22) { /* Generic with CRC */ hdr->crc = get_word (); hdr->extend_type = EXTEND_GENERIC; hdr->has_crc = TRUE; } else if (header_size - name_length == 20) { /* Generic no CRC */ hdr->extend_type = EXTEND_GENERIC; hdr->has_crc = FALSE; } else { warning ("Unknown header (LHarc file ?)", ""); return FALSE; } if (hdr->extend_type == EXTEND_UNIX && hdr->header_level == 0) { hdr->minor_version = get_byte (); hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); return TRUE; } if (hdr->header_level > 0) { /* Extend Header */ if (hdr->header_level != 2) setup_get(data + hdr->header_size); ptr = get_ptr; while((header_size = get_word()) != 0) { if (hdr->header_level != 2 && ((data + LZHEADER_STRAGE - get_ptr < header_size) || fread(get_ptr, sizeof(char), header_size, fp) < header_size)) { fatal_error ("Invalid header (LHa file ?)"); return FALSE; } switch (get_byte()) { case 0: /* * header crc */ setup_get(get_ptr + header_size - 3); break; case 1: /* * filename */ for (i = 0; i < header_size - 3; i++) hdr->name[i] =(char)get_byte (); hdr->name[header_size - 3] = '\0'; break; case 2: /* * directory */ for (i = 0; i < header_size - 3; i++) dirname[i] = (char)get_byte (); dirname[header_size - 3] = '\0'; convdelim(dirname, DELIM); dir_length = header_size-3; break; case 0x40: /* * MS-DOS attribute */ if (hdr->extend_type == EXTEND_MSDOS || hdr->extend_type == EXTEND_HUMAN || hdr->extend_type == EXTEND_GENERIC) hdr->attribute = get_word(); break; case 0x50: /* * UNIX permission */ if (hdr->extend_type == EXTEND_UNIX) hdr->unix_mode = get_word(); break; case 0x51: /* * UNIX gid and uid */ if (hdr->extend_type == EXTEND_UNIX) { hdr->unix_gid = get_word(); hdr->unix_uid = get_word(); } break; case 0x52: /* * UNIX group name */ setup_get(get_ptr + header_size - 3); break; case 0x53: /* * UNIX user name */ setup_get(get_ptr + header_size - 3); break; case 0x54: /* * UNIX last modified time */ if (hdr->extend_type == EXTEND_UNIX) hdr->unix_last_modified_stamp = (time_t)get_longword(); break; default: /* * other headers */ setup_get(get_ptr + header_size - 3); break; } } if (hdr->header_level != 2 && get_ptr - ptr != 2) { hdr->packed_size -= get_ptr - ptr - 2; hdr->header_size += get_ptr - ptr - 2; } } if (dir_length) { strcat(dirname, hdr->name); strcpy(hdr->name, dirname); name_length += dir_length; } switch (hdr->extend_type) { case EXTEND_MSDOS: msdos_to_unix_filename (hdr->name, name_length); case EXTEND_HUMAN: if (hdr->header_level == 2) hdr->unix_last_modified_stamp = hdr->last_modified_stamp; else hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); break; #ifdef OSK case EXTEND_OS68K: case EXTEND_XOSK: #endif case EXTEND_UNIX: break; case EXTEND_MACOS: macos_to_unix_filename (hdr->name, name_length); hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); break; default: generic_to_unix_filename (hdr->name, name_length); if (hdr->header_level == 2) hdr->unix_last_modified_stamp = hdr->last_modified_stamp; else hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); } return TRUE; } void init_header (name, v_stat, hdr) char *name; struct stat *v_stat; LzHeader *hdr; { int len; if ( compress_method == 5 ) bcopy (LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE); else if ( compress_method ) bcopy (LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE); else bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE); hdr->packed_size = 0; hdr->original_size = v_stat->st_size; hdr->last_modified_stamp = unix_to_generic_stamp (v_stat->st_mtime); hdr->attribute = GENERIC_ATTRIBUTE; hdr->header_level = header_level; strcpy (hdr->name, name); len = strlen (name); hdr->crc = 0x0000; hdr->extend_type = EXTEND_UNIX; hdr->unix_last_modified_stamp = v_stat->st_mtime; /* since 00:00:00 JAN.1.1970 */ #ifdef NOT_COMPATIBLE_MODE /* Please need your modification in this space. */ #else hdr->unix_mode = v_stat->st_mode; #endif hdr->unix_uid = v_stat->st_uid; hdr->unix_gid = v_stat->st_gid; if (is_directory (v_stat)) { bcopy (LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE); hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE; hdr->original_size = 0; if (len > 0 && hdr->name[len-1] != '/') strcpy (&hdr->name[len++], "/"); } if (generic_format) unix_to_generic_filename (hdr->name, len); } /* Write unix extended header or generic header. */ void write_header (nafp, hdr) FILE *nafp; LzHeader *hdr; { int header_size; int name_length; char data[LZHEADER_STRAGE]; char *p; bzero (data, LZHEADER_STRAGE); bcopy (hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE); setup_put (data + I_PACKED_SIZE); put_longword (hdr->packed_size); put_longword (hdr->original_size); if (hdr->header_level == HEADER_LEVEL2) put_longword ((long)hdr->unix_last_modified_stamp); else put_longword (hdr->last_modified_stamp); switch (hdr->header_level) { case HEADER_LEVEL0: put_byte (hdr->attribute); break; case HEADER_LEVEL1: case HEADER_LEVEL2: put_byte (0x20); break; } put_byte (hdr->header_level); convdelim(hdr->name, DELIM2); if (hdr->header_level != HEADER_LEVEL2) { if (p = (char *)rindex(hdr->name, DELIM2)) name_length = strlen(++p); else name_length = strlen(hdr->name); put_byte (name_length); bcopy (p ? p : hdr->name, data + I_NAME, name_length); setup_put (data + I_NAME + name_length); } put_word (hdr->crc); if (generic_format) { header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length; data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); } else if (header_level == HEADER_LEVEL0) { /* write old-style extend header */ put_byte (EXTEND_UNIX); put_byte (CURRENT_UNIX_MINOR_VERSION); put_longword ((long)hdr->unix_last_modified_stamp); put_word (hdr->unix_mode); put_word (hdr->unix_uid); put_word (hdr->unix_gid); header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length; data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); } else { /* write extend header. */ char *ptr; put_byte (EXTEND_UNIX); ptr = put_ptr; put_word(5); if (hdr->header_level == HEADER_LEVEL1) header_size = put_ptr - data - 2; put_byte(0x50); /* permission */ put_word(hdr->unix_mode); put_word(7); put_byte(0x51); /* gid and uid */ put_word(hdr->unix_gid); put_word(hdr->unix_uid); if (p = (char *)rindex(hdr->name, DELIM2)) { int i; name_length = p - hdr->name + 1; put_word(name_length + 3); put_byte(2); /* dirname */ for (i = 0; i < name_length; i++) put_byte(hdr->name[i]); } if (header_level != HEADER_LEVEL2) { put_word(7); put_byte(0x54); /* time stamp */ put_longword(hdr->unix_last_modified_stamp); hdr->packed_size += put_ptr - ptr; ptr = put_ptr; setup_put (data + I_PACKED_SIZE); put_longword (hdr->packed_size); put_ptr = ptr; data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); } else { int i; if (p = (char *)rindex(hdr->name, DELIM2)) name_length = strlen(++p); else { p = hdr->name; name_length = strlen(hdr->name); } put_word(name_length + 3); put_byte(1); /* filename */ for (i = 0; i < name_length; i++) put_byte(*p++); } header_size = put_ptr - data; } if (header_level == HEADER_LEVEL2) { setup_put(data + I_HEADER_SIZE); put_word(header_size); } if (fwrite (data, sizeof (char), header_size + 2, nafp) == 0) fatal_error ("Cannot write to temporary file"); convdelim(hdr->name, DELIM); } minor_version = get_byte (); hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); return TRUE; } if (hdr->header_level > 0) { /* Extend Header */ if (hdr->header_level != 2) setup_get(data + hdr->header_size); ptr = get_ptr; while((header_size = get_word()) != 0) { if (hdr->header_level != 2 && ((data + LZHEAlha/header.c.ori 644 4263 151 42222 5162045572 7133 /*----------------------------------------------------------------------*/ /* header.c (from lharc.c) -- header manipulate functions */ /* Original by Y.Tagawa */ /* modified Dec 16 1991 by M.Oki */ /*----------------------------------------------------------------------*/ #include "lharc.h" extern int header_level; int calc_sum (p, len) register char *p; register int len; { register int sum; for (sum = 0; len; len --) sum += *p++; return sum & 0xff; } static char *get_ptr; #define setup_get(PTR) (get_ptr = (PTR)) #define get_byte() (*get_ptr++ & 0xff) #define put_ptr get_ptr #define setup_put(PTR) (put_ptr = (PTR)) #define put_byte(c) (*put_ptr++ = (char)(c)) static unsigned short get_word () { int b0, b1; b0 = get_byte (); b1 = get_byte (); return (b1 << 8) + b0; } static void put_word (v) unsigned int v; { put_byte (v); put_byte (v >> 8); } static long get_longword () { long b0, b1, b2, b3; b0 = get_byte (); b1 = get_byte (); b2 = get_byte (); b3 = get_byte (); return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0; } static void put_longword (v) long v; { put_byte (v); put_byte (v >> 8); put_byte (v >> 16); put_byte (v >> 24); } static void msdos_to_unix_filename (name, len) register char *name; register int len; { register int i; #ifdef MULTIBYTE_CHAR for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (name[i] == '\\') name[i] = '/'; else if (isupper (name[i])) name[i] = tolower (name[i]); } #else for (i = 0; i < len; i ++) { if (name[i] == '\\') name[i] = '/'; else if (isupper (name[i])) name[i] = tolower (name[i]); } #endif } static void generic_to_unix_filename (name, len) register char *name; register int len; { register int i; boolean lower_case_used = FALSE; #ifdef MULTIBYTE_CHAR for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (islower (name[i])) { lower_case_used = TRUE; break; } } for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (name[i] == '\\') name[i] = '/'; else if (!lower_case_used && isupper (name[i])) name[i] = tolower (name[i]); } #else for (i = 0; i < len; i ++) if (islower (name[i])) { lower_case_used = TRUE; break; } for (i = 0; i < len; i ++) { if (name[i] == '\\') name[i] = '/'; else if (!lower_case_used && isupper (name[i])) name[i] = tolower (name[i]); } #endif } static void macos_to_unix_filename (name, len) register char *name; register int len; { register int i; for (i = 0; i < len; i ++) { if (name[i] == ':') name[i] = '/'; else if (name[i] == '/') name[i] = ':'; } } static void unix_to_generic_filename (name, len) register char *name; register int len; { register int i; for (i = 0; i < len; i ++) { if (name[i] == '/') name[i] = '\\'; else if (islower (name[i])) name[i] = toupper (name[i]); } } /*----------------------------------------------------------------------*/ /* */ /* Generic stamp format: */ /* */ /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */ /* |<-------- year ------->|<- month ->|<-- day -->| */ /* */ /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */ /* |<--- hour --->|<---- minute --->|<- second*2 ->| */ /* */ /*----------------------------------------------------------------------*/ /* NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2) returns bogus timezone information, try MKTIME or TZSET. */ #ifndef MKTIME static long gettz () { #ifdef _MINIX extern long timezone; /* not defined in time.h */ #endif #ifdef TZSET tzset(); return timezone; #else struct timeval tp; struct timezone tzp; gettimeofday (&tp, &tzp); /* specific to 4.3BSD */ /* return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L * 60L : 0));*/ return (tzp.tz_minuteswest * 60L); #endif } #endif #ifdef NOT_USED static struct tm * msdos_to_unix_stamp_tm (a) long a; { static struct tm t; t.tm_sec = ( a & 0x1f) * 2; t.tm_min = (a >> 5) & 0x3f; t.tm_hour = (a >> 11) & 0x1f; t.tm_mday = (a >> 16) & 0x1f; t.tm_mon = ((a >> 16+5) & 0x0f) - 1; t.tm_year = ((a >> 16+9) & 0x7f) + 80; return &t; } #endif static time_t generic_to_unix_stamp (t) long t; { #ifdef MKTIME struct tm dostm; #else int year, month, day, hour, min, sec; long longtime; static unsigned int dsboy[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; unsigned int days; #endif /* special case: if MSDOS format date and time were zero, then we set time to be zero here too. */ if (t == 0) return (time_t)0; #ifdef MKTIME dostm.tm_sec = (t & 0x1f) * 2; dostm.tm_min = t >> 5 & 0x3f; dostm.tm_hour = t >> 11 & 0x1f; dostm.tm_mday = t >> 16 & 0x1f; dostm.tm_mon = (t >> 16+5 & 0x0f) - 1; /* 0..11 */ dostm.tm_year = (t >> 16+9 & 0x7f) + 80; dostm.tm_isdst = 0; /* correct? */ return (time_t)mktime(&dostm); #else year = ((int)(t >> 16+9) & 0x7f) + 1980; month = (int)(t >> 16+5) & 0x0f; /* 1..12 means Jan..Dec */ day = (int)(t >> 16) & 0x1f; /* 1..31 means 1st,...31st */ hour = ((int)t >> 11) & 0x1f; min = ((int)t >> 5) & 0x3f; sec = ((int)t & 0x1f) * 2; /* Calculate days since 1970.01.01 */ days = (365 * (year - 1970) + /* days due to whole years */ (year - 1970 + 1) / 4 + /* days due to leap years */ dsboy[month-1] + /* days since beginning of this year */ day-1); /* days since beginning of month */ if ((year % 4 == 0) && (year % 400 != 0) && (month >= 3)) /* if this is a leap year and month */ days ++; /* is March or later, add a day */ /* Knowing the days, we can find seconds */ longtime = (((days * 24) + hour) * 60 + min) * 60 + sec; longtime += gettz (); /* adjust for timezone */ /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */ return (time_t)longtime; #endif } static long unix_to_generic_stamp (t) time_t t; { struct tm *tm = localtime (&t); return ((((long)(tm->tm_year - 80)) << 25) + (((long)(tm->tm_mon + 1)) << 21) + (((long)tm->tm_mday) << 16) + (long)((tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2))); } /*----------------------------------------------------------------------*/ /* build header functions */ /*----------------------------------------------------------------------*/ boolean get_header (fp, hdr) FILE *fp; register LzHeader *hdr; { int header_size; int name_length; char data[LZHEADER_STRAGE]; char dirname[FILENAME_LENGTH]; int dir_length = 0; int checksum; int i; char *ptr; bzero (hdr, sizeof (LzHeader)); if (((header_size = getc (fp)) == EOF) || (header_size == 0)) { return FALSE; /* finish */ } if (fread (data + I_HEADER_CHECKSUM, sizeof (char), header_size + 1, fp) < header_size + 1) { fatal_error ("Invalid header (LHarc file ?)"); return FALSE; /* finish */ } setup_get (data + I_HEADER_CHECKSUM); checksum = get_byte(); hdr->header_size = header_size; bcopy (data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE); #ifdef OLD if ((bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) != 0)) { warning ("Unknown method (LHarc file ?)", ""); return FALSE; /* invalid method */ } #endif setup_get (data + I_PACKED_SIZE); hdr->packed_size = get_longword (); hdr->original_size = get_longword (); hdr->last_modified_stamp = get_longword (); hdr->attribute = get_byte (); if ((hdr->header_level = get_byte ()) != 2) { if (calc_sum (data + I_METHOD, header_size) != checksum) warning ("Checksum error (LHarc file?)", ""); name_length = get_byte (); for (i = 0; i < name_length; i ++) hdr->name[i] =(char)get_byte (); hdr->name[name_length] = '\0'; } else { hdr->unix_last_modified_stamp = hdr->last_modified_stamp; name_length = 0; } /* defaults for other type */ hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW; hdr->unix_gid = 0; hdr->unix_uid = 0; if (header_size - name_length >= 24) { /* EXTEND FORMAT */ hdr->crc = get_word (); hdr->extend_type = get_byte (); hdr->has_crc = TRUE; } else if (header_size - name_length == 22) { /* Generic with CRC */ hdr->crc = get_word (); hdr->extend_type = EXTEND_GENERIC; hdr->has_crc = TRUE; } else if (header_size - name_length == 20) { /* Generic no CRC */ hdr->extend_type = EXTEND_GENERIC; hdr->has_crc = FALSE; } else { warning ("Unknown header (LHarc file ?)", ""); return FALSE; } if (hdr->extend_type == EXTEND_UNIX && hdr->header_level == 0) { hdr->minor_version = get_byte (); hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); return TRUE; } if (hdr->header_level > 0) { /* Extend Header */ if (hdr->header_level != 2) setup_get(data + hdr->header_size); ptr = get_ptr; while((header_size = get_word()) != 0) { if (hdr->header_level != 2 && ((data + LZHEADER_STRAGE - get_ptr < header_size) || fread(get_ptr, sizeof(char), header_size, fp) < header_size)) { fatal_error ("Invalid header (LHa file ?)"); return FALSE; } switch (get_byte()) { case 0: /* * header crc */ setup_get(get_ptr + header_size - 3); break; case 1: /* * filename */ for (i = 0; i < header_size - 3; i++) hdr->name[i] =(char)get_byte (); hdr->name[header_size - 3] = '\0'; break; case 2: /* * directory */ for (i = 0; i < header_size - 3; i++) dirname[i] = (char)get_byte (); dirname[header_size - 3] = '\0'; convdelim(dirname, DELIM); dir_length = header_size-3; break; case 0x40: /* * MS-DOS attribute */ if (hdr->extend_type == EXTEND_MSDOS || hdr->extend_type == EXTEND_HUMAN || hdr->extend_type == EXTEND_GENERIC) hdr->attribute = get_word(); break; case 0x50: /* * UNIX permission */ if (hdr->extend_type == EXTEND_UNIX) hdr->unix_mode = get_word(); break; case 0x51: /* * UNIX gid and uid */ if (hdr->extend_type == EXTEND_UNIX) { hdr->unix_gid = get_word(); hdr->unix_uid = get_word(); } break; case 0x52: /* * UNIX group name */ setup_get(get_ptr + header_size - 3); break; case 0x53: /* * UNIX user name */ setup_get(get_ptr + header_size - 3); break; case 0x54: /* * UNIX last modified time */ if (hdr->extend_type == EXTEND_UNIX) hdr->unix_last_modified_stamp = (time_t)get_longword(); break; default: /* * other headers */ setup_get(get_ptr + header_size - 3); break; } } if (hdr->header_level != 2 && get_ptr - ptr != 2) { hdr->packed_size -= get_ptr - ptr - 2; hdr->header_size += get_ptr - ptr - 2; } } if (dir_length) { strcat(dirname, hdr->name); strcpy(hdr->name, dirname); name_length += dir_length; } switch (hdr->extend_type) { case EXTEND_MSDOS: msdos_to_unix_filename (hdr->name, name_length); case EXTEND_HUMAN: if (hdr->header_level == 2) hdr->unix_last_modified_stamp = hdr->last_modified_stamp; else hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); break; #ifdef OSK case EXTEND_OS68K: case EXTEND_XOSK: #endif case EXTEND_UNIX: break; case EXTEND_MACOS: macos_to_unix_filename (hdr->name, name_length); hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); break; default: generic_to_unix_filename (hdr->name, name_length); if (hdr->header_level == 2) hdr->unix_last_modified_stamp = hdr->last_modified_stamp; else hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); } return TRUE; } void init_header (name, v_stat, hdr) char *name; struct stat *v_stat; LzHeader *hdr; { int len; if ( compress_method == 5 ) bcopy (LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE); else if ( compress_method ) bcopy (LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE); else bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE); hdr->packed_size = 0; hdr->original_size = v_stat->st_size; hdr->last_modified_stamp = unix_to_generic_stamp (v_stat->st_mtime); hdr->attribute = GENERIC_ATTRIBUTE; hdr->header_level = header_level; strcpy (hdr->name, name); len = strlen (name); hdr->crc = 0x0000; hdr->extend_type = EXTEND_UNIX; hdr->unix_last_modified_stamp = v_stat->st_mtime; /* since 00:00:00 JAN.1.1970 */ #ifdef NOT_COMPATIBLE_MODE /* Please need your modification in this space. */ #else hdr->unix_mode = v_stat->st_mode; #endif hdr->unix_uid = v_stat->st_uid; hdr->unix_gid = v_stat->st_gid; if (is_directory (v_stat)) { bcopy (LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE); hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE; hdr->original_size = 0; if (len > 0 && hdr->name[len-1] != '/') strcpy (&hdr->name[len++], "/"); } if (generic_format) unix_to_generic_filename (hdr->name, len); } /* Write unix extended header or generic header. */ void write_header (nafp, hdr) FILE *nafp; LzHeader *hdr; { int header_size; int name_length; char data[LZHEADER_STRAGE]; char *p; bzero (data, LZHEADER_STRAGE); bcopy (hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE); setup_put (data + I_PACKED_SIZE); put_longword (hdr->packed_size); put_longword (hdr->original_size); if (hdr->header_level == HEADER_LEVEL2) put_longword ((long)hdr->unix_last_modified_stamp); else put_longword (hdr->last_modified_stamp); switch (hdr->header_level) { case HEADER_LEVEL0: put_byte (hdr->attribute); break; case HEADER_LEVEL1: case HEADER_LEVEL2: put_byte (0x20); break; } put_byte (hdr->header_level); convdelim(hdr->name, DELIM2); if (hdr->header_level != HEADER_LEVEL2) { if (p = (char *)rindex(hdr->name, DELIM2)) name_length = strlen(++p); else name_length = strlen(hdr->name); put_byte (name_length); bcopy (p ? p : hdr->name, data + I_NAME, name_length); setup_put (data + I_NAME + name_length); } put_word (hdr->crc); if (generic_format) { header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length; data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); } else if (header_level == HEADER_LEVEL0) { /* write old-style extend header */ put_byte (EXTEND_UNIX); put_byte (CURRENT_UNIX_MINOR_VERSION); put_longword ((long)hdr->unix_last_modified_stamp); put_word (hdr->unix_mode); put_word (hdr->unix_uid); put_word (hdr->unix_gid); header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length; data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); } else { /* write extend header. */ char *ptr; put_byte (EXTEND_UNIX); ptr = put_ptr; put_word(5); if (hdr->header_level == HEADER_LEVEL1) header_size = put_ptr - data - 2; put_byte(0x50); /* permission */ put_word(hdr->unix_mode); put_word(7); put_byte(0x51); /* gid and uid */ put_word(hdr->unix_gid); put_word(hdr->unix_uid); if (p = (char *)rindex(hdr->name, DELIM2)) { int i; name_length = p - hdr->name + 1; put_word(name_length + 3); put_byte(2); /* dirname */ for (i = 0; i < name_length; i++) put_byte(hdr->name[i]); } if (header_level != HEADER_LEVEL2) { put_word(7); put_byte(0x54); /* time stamp */ put_longword(hdr->unix_last_modified_stamp); hdr->packed_size += put_ptr - ptr; ptr = put_ptr; setup_put (data + I_PACKED_SIZE); put_longword (hdr->packed_size); put_ptr = ptr; data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); } else { int i; if (p = (char *)rindex(hdr->name, DELIM2)) name_length = strlen(++p); else { p = hdr->name; name_length = strlen(hdr->name); } put_word(name_length + 3); put_byte(1); /* filename */ for (i = 0; i < name_length; i++) put_byte(*p++); } header_size = put_ptr - data; } if (header_level == HEADER_LEVEL2) { setup_put(data + I_HEADER_SIZE); put_word(header_size); } if (fwrite (data, sizeof (char), header_size + 2, nafp) == 0) fatal_error ("Cannot write to temporary file"); convdelim(hdr->name, DELIM); } minor_version = get_byte (); hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); return TRUE; } if (hdr->header_level > 0) { /* Extend Header */ if (hdr->header_level != 2) setup_get(data + hdr->header_size); ptr = gelha/huf.c 644 4263 151 16060 5162045601 5667 /*********************************************************** huf.c -- new static Huffman ***********************************************************/ #ifdef sony_news #include #define _SIZE_T #endif #if defined(__STDC__) || defined(NEWSOS) #include #endif #include "slidehuf.h" #define NP (MAX_DICBIT + 1) #define NT (USHRT_BIT + 3) #define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */ #define TBIT 5 /* smallest integer such that (1 << TBIT) > NT */ /*#if NT > NP #define NPT NT #else #define NPT NP #endif*/ #define NPT 0x80 unsigned short left[2 * NC - 1], right[2 * NC - 1]; unsigned char c_len[NC], pt_len[NPT]; unsigned short c_freq[2 * NC - 1], c_table[4096], c_code[NC], p_freq[2 * NP - 1], pt_table[256], pt_code[NPT], t_freq[2 * NT - 1]; static unsigned char *buf; static unsigned short bufsiz; static unsigned short blocksize; /***** encoding *****/ static void count_t_freq(void) { short i, k, n, count; for (i = 0; i < NT; i++) t_freq[i] = 0; n = NC; while (n > 0 && c_len[n - 1] == 0) n--; i = 0; while (i < n) { k = c_len[i++]; if (k == 0) { count = 1; while (i < n && c_len[i] == 0) { i++; count++; } if (count <= 2) t_freq[0] += count; else if (count <= 18) t_freq[1]++; else if (count == 19) { t_freq[0]++; t_freq[1]++; } else t_freq[2]++; } else t_freq[k + 2]++; } } static void write_pt_len(n, nbit, i_special) short n; short nbit; short i_special; { short i, k; while (n > 0 && pt_len[n - 1] == 0) n--; putbits(nbit, n); i = 0; while (i < n) { k = pt_len[i++]; if (k <= 6) putbits(3, k); else putbits(k - 3, USHRT_MAX << 1); if (i == i_special) { while (i < 6 && pt_len[i] == 0) i++; putbits(2, i - 3); } } } static void write_c_len(void) { short i, k, n, count; n = NC; while (n > 0 && c_len[n - 1] == 0) n--; putbits(CBIT, n); i = 0; while (i < n) { k = c_len[i++]; if (k == 0) { count = 1; while (i < n && c_len[i] == 0) { i++; count++; } if (count <= 2) { for (k = 0; k < count; k++) putcode(pt_len[0], pt_code[0]); } else if (count <= 18) { putcode(pt_len[1], pt_code[1]); putbits(4, count - 3); } else if (count == 19) { putcode(pt_len[0], pt_code[0]); putcode(pt_len[1], pt_code[1]); putbits(4, 15); } else { putcode(pt_len[2], pt_code[2]); putbits(CBIT, count - 20); } } else putcode(pt_len[k + 2], pt_code[k + 2]); } } static void encode_c(c) short c; { putcode(c_len[c], c_code[c]); } static void encode_p(p) unsigned short p; { unsigned short c, q; c = 0; q = p; while (q) { q >>= 1; c++; } putcode(pt_len[c], pt_code[c]); if (c > 1) putbits(c - 1, p); } static void send_block(void) { unsigned char flags; unsigned short i, k, root, pos, size; root = make_tree(NC, c_freq, c_len, c_code); size = c_freq[root]; putbits(16, size); if (root >= NC) { count_t_freq(); root = make_tree(NT, t_freq, pt_len, pt_code); if (root >= NT) { write_pt_len(NT, TBIT, 3); } else { putbits(TBIT, 0); putbits(TBIT, root); } write_c_len(); } else { putbits(TBIT, 0); putbits(TBIT, 0); putbits(CBIT, 0); putbits(CBIT, root); } root = make_tree(NP, p_freq, pt_len, pt_code); if (root >= NP) { write_pt_len(NP, PBIT, -1); } else { putbits(PBIT, 0); putbits(PBIT, root); } pos = 0; for (i = 0; i < size; i++) { if (i % CHAR_BIT == 0) flags = buf[pos++]; else flags <<= 1; if (flags & (1 << (CHAR_BIT - 1))) { encode_c(buf[pos++] + (1 << CHAR_BIT)); k = buf[pos++] << CHAR_BIT; k += buf[pos++]; encode_p(k); } else encode_c(buf[pos++]); if (unpackable) return; } for (i = 0; i < NC; i++) c_freq[i] = 0; for (i = 0; i < NP; i++) p_freq[i] = 0; } static unsigned short output_pos, output_mask; void output_st1(c, p) unsigned short c; unsigned short p; { static unsigned short cpos; if ((output_mask >>= 1) == 0) { output_mask = 1 << (CHAR_BIT - 1); if (output_pos >= bufsiz - 3 * CHAR_BIT) { send_block(); if (unpackable) return; output_pos = 0; } cpos = output_pos++; buf[cpos] = 0; } buf[output_pos++] = (unsigned char) c; c_freq[c]++; if (c >= (1 << CHAR_BIT)) { buf[cpos] |= output_mask; buf[output_pos++] = (unsigned char)(p >> CHAR_BIT); buf[output_pos++] = (unsigned char) p; c = 0; while (p) { p >>= 1; c++; } p_freq[c]++; } } unsigned char *alloc_buf(void) { bufsiz = 16 * 1024; /* 65408U; */ while ((buf = (unsigned char *)malloc(bufsiz)) == NULL) { bufsiz = (bufsiz / 10) * 9; if (bufsiz < 4 * 1024) break; } return buf; } void encode_start_st1(void) { int i; for (i = 0; i < NC; i++) c_freq[i] = 0; for (i = 0; i < NP; i++) p_freq[i] = 0; output_pos = output_mask = 0; init_putbits(); buf[0] = 0; } void encode_end_st1(void) { if (! unpackable) { send_block(); putbits(CHAR_BIT - 1, 0); /* flush remaining bits */ } } /***** decoding *****/ static void read_pt_len(nn, nbit, i_special) short nn; short nbit; short i_special; { short i, c, n; n = getbits(nbit); if (n == 0) { c = getbits(nbit); for (i = 0; i < nn; i++) pt_len[i] = 0; for (i = 0; i < 256; i++) pt_table[i] = c; } else { i = 0; while (i < n) { c = bitbuf >> (16 - 3); if (c == 7) { unsigned short mask = 1 << (16 - 4); while (mask & bitbuf) { mask >>= 1; c++; } } fillbuf((c < 7) ? 3 : c - 3); pt_len[i++] = c; if (i == i_special) { c = getbits(2); while (--c >= 0) pt_len[i++] = 0; } } while (i < nn) pt_len[i++] = 0; make_table(nn, pt_len, 8, pt_table); } } static void read_c_len(void) { short i, c, n; n = getbits(CBIT); if (n == 0) { c = getbits(CBIT); for (i = 0; i < NC; i++) c_len[i] = 0; for (i = 0; i < 4096; i++) c_table[i] = c; } else { i = 0; while (i < n) { c = pt_table[bitbuf >> (16 - 8)]; if (c >= NT) { unsigned short mask = 1 << (16 - 9); do { if (bitbuf & mask) c = right[c]; else c = left [c]; mask >>= 1; } while (c >= NT); } fillbuf(pt_len[c]); if (c <= 2) { if (c == 0) c = 1; else if (c == 1) c = getbits(4) + 3; else c = getbits(CBIT) + 20; while (--c >= 0) c_len[i++] = 0; } else c_len[i++] = c - 2; } while (i < NC) c_len[i++] = 0; make_table(NC, c_len, 12, c_table); } } unsigned short decode_c_st1(void) { unsigned short j, mask; if (blocksize == 0) { blocksize = getbits(16); read_pt_len(NT, TBIT, 3); read_c_len(); read_pt_len(NP, PBIT, -1); } blocksize--; j = c_table[bitbuf >> 4]; if (j < NC) fillbuf(c_len[j]); else { fillbuf(12); mask = 1 << (16 - 1); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; } while (j >= NC); fillbuf(c_len[j] - 12); } return j; } unsigned short decode_p_st1(void) { unsigned short j, mask; j = pt_table[bitbuf >> (16 - 8)]; if (j < NP) fillbuf(pt_len[j]); else { fillbuf(8); mask = 1 << (16 - 1); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; } while (j >= NP); fillbuf(pt_len[j] - 8); } if (j != 0) j = (1 << (j - 1)) + getbits(j - 1); return j; } void decode_start_st1(void) { init_getbits(); blocksize = 0; } nafp) == 0) fatal_error ("Cannot write to temporary file"); convdelim(hdr->name, DELIM); } minor_version = get_byte (); hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); return TRUE; } if (hdr->header_level > 0) { /* Extend Header */ if (hdr->header_level != 2) setup_get(data + hdr->header_size); ptr = gelha/huf.c.ori 644 4263 151 16040 5162045607 6463 /*********************************************************** huf.c -- new static Huffman ***********************************************************/ #ifdef sony_news #include #endif #if defined(__STDC__) || defined(NEWSOS) #include #endif #include "slidehuf.h" #define NP (MAX_DICBIT + 1) #define NT (USHRT_BIT + 3) #define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */ #define TBIT 5 /* smallest integer such that (1 << TBIT) > NT */ /*#if NT > NP #define NPT NT #else #define NPT NP #endif*/ #define NPT 0x80 unsigned short left[2 * NC - 1], right[2 * NC - 1]; unsigned char c_len[NC], pt_len[NPT]; unsigned short c_freq[2 * NC - 1], c_table[4096], c_code[NC], p_freq[2 * NP - 1], pt_table[256], pt_code[NPT], t_freq[2 * NT - 1]; static unsigned char *buf; static unsigned short bufsiz; static unsigned short blocksize; /***** encoding *****/ static void count_t_freq(void) { short i, k, n, count; for (i = 0; i < NT; i++) t_freq[i] = 0; n = NC; while (n > 0 && c_len[n - 1] == 0) n--; i = 0; while (i < n) { k = c_len[i++]; if (k == 0) { count = 1; while (i < n && c_len[i] == 0) { i++; count++; } if (count <= 2) t_freq[0] += count; else if (count <= 18) t_freq[1]++; else if (count == 19) { t_freq[0]++; t_freq[1]++; } else t_freq[2]++; } else t_freq[k + 2]++; } } static void write_pt_len(n, nbit, i_special) short n; short nbit; short i_special; { short i, k; while (n > 0 && pt_len[n - 1] == 0) n--; putbits(nbit, n); i = 0; while (i < n) { k = pt_len[i++]; if (k <= 6) putbits(3, k); else putbits(k - 3, USHRT_MAX << 1); if (i == i_special) { while (i < 6 && pt_len[i] == 0) i++; putbits(2, i - 3); } } } static void write_c_len(void) { short i, k, n, count; n = NC; while (n > 0 && c_len[n - 1] == 0) n--; putbits(CBIT, n); i = 0; while (i < n) { k = c_len[i++]; if (k == 0) { count = 1; while (i < n && c_len[i] == 0) { i++; count++; } if (count <= 2) { for (k = 0; k < count; k++) putcode(pt_len[0], pt_code[0]); } else if (count <= 18) { putcode(pt_len[1], pt_code[1]); putbits(4, count - 3); } else if (count == 19) { putcode(pt_len[0], pt_code[0]); putcode(pt_len[1], pt_code[1]); putbits(4, 15); } else { putcode(pt_len[2], pt_code[2]); putbits(CBIT, count - 20); } } else putcode(pt_len[k + 2], pt_code[k + 2]); } } static void encode_c(c) short c; { putcode(c_len[c], c_code[c]); } static void encode_p(p) unsigned short p; { unsigned short c, q; c = 0; q = p; while (q) { q >>= 1; c++; } putcode(pt_len[c], pt_code[c]); if (c > 1) putbits(c - 1, p); } static void send_block(void) { unsigned char flags; unsigned short i, k, root, pos, size; root = make_tree(NC, c_freq, c_len, c_code); size = c_freq[root]; putbits(16, size); if (root >= NC) { count_t_freq(); root = make_tree(NT, t_freq, pt_len, pt_code); if (root >= NT) { write_pt_len(NT, TBIT, 3); } else { putbits(TBIT, 0); putbits(TBIT, root); } write_c_len(); } else { putbits(TBIT, 0); putbits(TBIT, 0); putbits(CBIT, 0); putbits(CBIT, root); } root = make_tree(NP, p_freq, pt_len, pt_code); if (root >= NP) { write_pt_len(NP, PBIT, -1); } else { putbits(PBIT, 0); putbits(PBIT, root); } pos = 0; for (i = 0; i < size; i++) { if (i % CHAR_BIT == 0) flags = buf[pos++]; else flags <<= 1; if (flags & (1 << (CHAR_BIT - 1))) { encode_c(buf[pos++] + (1 << CHAR_BIT)); k = buf[pos++] << CHAR_BIT; k += buf[pos++]; encode_p(k); } else encode_c(buf[pos++]); if (unpackable) return; } for (i = 0; i < NC; i++) c_freq[i] = 0; for (i = 0; i < NP; i++) p_freq[i] = 0; } static unsigned short output_pos, output_mask; void output_st1(c, p) unsigned short c; unsigned short p; { static unsigned short cpos; if ((output_mask >>= 1) == 0) { output_mask = 1 << (CHAR_BIT - 1); if (output_pos >= bufsiz - 3 * CHAR_BIT) { send_block(); if (unpackable) return; output_pos = 0; } cpos = output_pos++; buf[cpos] = 0; } buf[output_pos++] = (unsigned char) c; c_freq[c]++; if (c >= (1 << CHAR_BIT)) { buf[cpos] |= output_mask; buf[output_pos++] = (unsigned char)(p >> CHAR_BIT); buf[output_pos++] = (unsigned char) p; c = 0; while (p) { p >>= 1; c++; } p_freq[c]++; } } unsigned char *alloc_buf(void) { bufsiz = 16 * 1024; /* 65408U; */ while ((buf = (unsigned char *)malloc(bufsiz)) == NULL) { bufsiz = (bufsiz / 10) * 9; if (bufsiz < 4 * 1024) break; } return buf; } void encode_start_st1(void) { int i; for (i = 0; i < NC; i++) c_freq[i] = 0; for (i = 0; i < NP; i++) p_freq[i] = 0; output_pos = output_mask = 0; init_putbits(); buf[0] = 0; } void encode_end_st1(void) { if (! unpackable) { send_block(); putbits(CHAR_BIT - 1, 0); /* flush remaining bits */ } } /***** decoding *****/ static void read_pt_len(nn, nbit, i_special) short nn; short nbit; short i_special; { short i, c, n; n = getbits(nbit); if (n == 0) { c = getbits(nbit); for (i = 0; i < nn; i++) pt_len[i] = 0; for (i = 0; i < 256; i++) pt_table[i] = c; } else { i = 0; while (i < n) { c = bitbuf >> (16 - 3); if (c == 7) { unsigned short mask = 1 << (16 - 4); while (mask & bitbuf) { mask >>= 1; c++; } } fillbuf((c < 7) ? 3 : c - 3); pt_len[i++] = c; if (i == i_special) { c = getbits(2); while (--c >= 0) pt_len[i++] = 0; } } while (i < nn) pt_len[i++] = 0; make_table(nn, pt_len, 8, pt_table); } } static void read_c_len(void) { short i, c, n; n = getbits(CBIT); if (n == 0) { c = getbits(CBIT); for (i = 0; i < NC; i++) c_len[i] = 0; for (i = 0; i < 4096; i++) c_table[i] = c; } else { i = 0; while (i < n) { c = pt_table[bitbuf >> (16 - 8)]; if (c >= NT) { unsigned short mask = 1 << (16 - 9); do { if (bitbuf & mask) c = right[c]; else c = left [c]; mask >>= 1; } while (c >= NT); } fillbuf(pt_len[c]); if (c <= 2) { if (c == 0) c = 1; else if (c == 1) c = getbits(4) + 3; else c = getbits(CBIT) + 20; while (--c >= 0) c_len[i++] = 0; } else c_len[i++] = c - 2; } while (i < NC) c_len[i++] = 0; make_table(NC, c_len, 12, c_table); } } unsigned short decode_c_st1(void) { unsigned short j, mask; if (blocksize == 0) { blocksize = getbits(16); read_pt_len(NT, TBIT, 3); read_c_len(); read_pt_len(NP, PBIT, -1); } blocksize--; j = c_table[bitbuf >> 4]; if (j < NC) fillbuf(c_len[j]); else { fillbuf(12); mask = 1 << (16 - 1); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; } while (j >= NC); fillbuf(c_len[j] - 12); } return j; } unsigned short decode_p_st1(void) { unsigned short j, mask; j = pt_table[bitbuf >> (16 - 8)]; if (j < NP) fillbuf(pt_len[j]); else { fillbuf(8); mask = 1 << (16 - 1); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; } while (j >= NP); fillbuf(pt_len[j] - 8); } if (j != 0) j = (1 << (j - 1)) + getbits(j - 1); return j; } void decode_start_st1(void) { init_getbits(); blocksize = 0; } locksize = 0; } nafp) == 0) fatal_error ("Cannot write to temporary file"); convdelim(hdr->name, DELIM); } minor_version = get_byte (); hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); return TRUE; } if (hdr->header_level > 0) { /* Extend Header */ if (hdr->header_level != 2) setup_get(data + hdr->header_size); ptr = gelha/intrface.h 644 4263 151 1145 5162045620 6664 /* * intrface.h -- part of LHa for UNIX * * modified : Dec. 5, 1991, Masaru Oki. */ typedef short node; struct interfacing { FILE *infile; FILE *outfile; unsigned long original; unsigned long packed; int dicbit; int method; }; extern struct interfacing interface; /* from error.c void error(); void fileerror(); */ /* from slide.c */ extern node *next; int encode_alloc(); void encode(); void decode(); /* from crcio.c */ extern unsigned short crc; void make_crctable(); unsigned short calccrc(); /* from append.c */ void start_indicator(); void finish_indicator(); void finish_indicator2(); t node; struct interfacing { FILE *infile; FILE *outfile; unsigned long original; unsigned long packed; int dicbit; int method; }; extern struct interfacing interface; /* from error.c void error(); void fileerror(); */ /* from slide.c */ extern node *next; int encode_alloc(); void encode(); void decode(); /* from crcio.c */ extern unsigned short crc; void make_crctable(); unsigned short calccrlha/larc.c 644 4263 151 2346 5162045623 6014 /*********************************************************** larc.c -- extract *.lzs ***********************************************************/ #include #include "slidehuf.h" #define MAGIC0 18 #define MAGIC5 19 static int flag, flagcnt, matchpos; unsigned short decode_c_lzs(void) { if (getbits(1)) { return getbits(8); } else { matchpos = getbits(11); return getbits(4) + 0x100; } } unsigned short decode_p_lzs(void) { return (loc - matchpos - MAGIC0) & 0x7ff; } void decode_start_lzs(void) { init_getbits(); } unsigned short decode_c_lz5(void) { int c; if (flagcnt == 0) { flagcnt = 8; flag = getc(infile); } flagcnt--; c = getc(infile); if ((flag & 1) == 0) { matchpos = c; c = getc(infile); matchpos += (c & 0xf0) << 4; c &= 0x0f; c += 0x100; } flag >>= 1; return c; } unsigned short decode_p_lz5(void) { return (loc - matchpos - MAGIC5) & 0xfff; } void decode_start_lz5(void) { int i; flagcnt = 0; for (i = 0; i < 256; i++) memset(&text[i * 13 + 18], i, 13); for (i = 0; i < 256; i++) text[256 * 13 + 18 + i] = i; for (i = 0; i < 256; i++) text[256 * 13 + 256 + 18 + i] = 255 - i; memset(&text[256 * 13 + 512 + 18], 0, 128); memset(&text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18); } ort i, k, n, count; n = NC; while (n > 0 && c_len[n - 1] == 0) n--; putbits(CBIT, n); i = 0; while (i < n) { k = c_len[i++]; if (k == 0) { count = 1; while (i < n && c_len[i] == 0) { i++; count++; } if (count <= 2) { for (k = 0; k < count; k++) putcodlha/lhadd.c 644 4263 151 32576 5162045631 6176 /*----------------------------------------------------------------------*/ /* LHarc Add Command */ /* This is part of LHarc UNIX Archiver Driver */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V0.00 Original 1988.05.23 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V1.02 Bug fix 1990.01.19 Y.Tagawa */ /* V0.03 LHa for UNIX 1991.12.05 M.Oki */ /*----------------------------------------------------------------------*/ #include "lharc.h" extern int encode_lzhuf (); extern int encode_stored_crc (); static char new_archive_name_buffer [ FILENAME_LENGTH ]; static char *new_archive_name; FILE *temporary_fp = NULL; /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ static void add_one (fp, nafp, hdr) FILE *fp, *nafp; LzHeader *hdr; { long header_pos, next_pos, org_pos, data_pos; long v_original_size, v_packed_size; reading_filename = hdr->name; writting_filename = temporary_name; if (!fp && generic_format) /* [generic] doesn't need directory info. */ return; header_pos = ftell (nafp); write_header (nafp, hdr); /* DUMMY */ if (hdr->original_size == 0) /* empty file or directory */ return; /* previous write_header is not DUMMY. (^_^) */ org_pos = ftell (fp); data_pos = ftell (nafp); hdr->crc = encode_lzhuf (fp, nafp, hdr->original_size, &v_original_size, &v_packed_size, hdr->name, hdr->method); if (v_packed_size < v_original_size) { next_pos = ftell (nafp); } else { /* retry by stored method */ fseek (fp, org_pos, SEEK_SET); fseek (nafp, data_pos, SEEK_SET); hdr->crc = encode_stored_crc (fp, nafp, hdr->original_size, &v_original_size, &v_packed_size); fflush (nafp); next_pos = ftell (nafp); #ifndef NOFTRUNCATE ftruncate (fileno (nafp), next_pos); #endif bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE); } hdr->original_size = v_original_size; hdr->packed_size = v_packed_size; fseek (nafp, header_pos, SEEK_SET); write_header (nafp, hdr); fseek (nafp, next_pos, SEEK_SET); } FILE * append_it (name, oafp, nafp) char *name; FILE *oafp, *nafp; { LzHeader ahdr, hdr; FILE *fp; long old_header; int cmp; int filec; char **filev; int i; struct stat stbuf; boolean directory; if (stat (name, &stbuf) < 0) { error ("cannot access", name); /* See cleaning_files, Why? */ return oafp; } directory = is_directory (&stbuf); init_header (name, &stbuf, &hdr); if (!directory && !noexec) fp = xfopen (name, READ_BINARY); else fp = NULL; while (oafp) { old_header = ftell (oafp); if (!get_header (oafp, &ahdr)) { fclose (oafp); oafp = NULL; break; } else { cmp = STRING_COMPARE (ahdr.name, hdr.name); if (cmp < 0) { /* SKIP */ /* copy old to new */ if (!noexec) { fseek (oafp, old_header, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); } else fseek (oafp, ahdr.packed_size, SEEK_CUR); } else if (cmp == 0) { /* REPLACE */ /* drop old archive's */ fseek (oafp, ahdr.packed_size, SEEK_CUR); break; } else /* cmp > 0, INSERT */ { fseek (oafp, old_header, SEEK_SET); break; } } } if (update_if_newer) { if (!oafp || /* not in archive */ cmp > 0 || /* // */ ahdr.unix_last_modified_stamp < /* newer than archive's */ hdr.unix_last_modified_stamp) { if (noexec) printf ("ADD %s\n", name); else add_one (fp, nafp, &hdr); } else /* cmp == 0 */ { /* copy old to new */ if (!noexec) { fseek (oafp, old_header, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); } } } else { if (!oafp || cmp > 0) /* not in archive or dropped */ { if (noexec) printf ("ADD %s\n", name); else add_one (fp, nafp, &hdr); } else /* cmp == 0 */ /* replace */ { if (noexec) printf ("REPLACE\n"); else add_one (fp, nafp, &hdr); } } if (!directory) { if (!noexec) fclose (fp); } else { /* recurcive call */ if (find_files (name, &filec, &filev)) { for (i = 0; i < filec; i ++) oafp = append_it (filev[i], oafp, nafp); free_files (filec, filev); } } return oafp; } static void find_update_files (oafp) FILE *oafp; /* old archive */ { char name[FILENAME_LENGTH]; struct string_pool sp; LzHeader hdr; long pos; struct stat stbuf; int len; pos = ftell (oafp); init_sp (&sp); while (get_header (oafp, &hdr)) { if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR) { if (stat (hdr.name, &stbuf) >= 0) /* exist ? */ add_sp (&sp, hdr.name, strlen (hdr.name) + 1); } else if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY) { strcpy (name, hdr.name); len = strlen (name); if (len > 0 && name[len - 1] == '/') name[--len] = '\0'; /* strip tail '/' */ if (stat (name, &stbuf) >= 0) /* exist ? */ add_sp (&sp, name, len+1); } fseek (oafp, hdr.packed_size, SEEK_CUR); } fseek (oafp, pos, SEEK_SET); finish_sp (&sp, &cmd_filec, &cmd_filev); } static void delete (oafp, nafp) FILE *oafp, *nafp; { LzHeader ahdr; long old_header_pos; old_header_pos = ftell (oafp); while (get_header (oafp, &ahdr)) { if (need_file (ahdr.name)) { /* skip */ fseek (oafp, ahdr.packed_size, SEEK_CUR); if (noexec) printf ("DELETE %s\n", ahdr.name); else if (verbose) printf ("Delete %s\n", ahdr.name); } else { /* copy */ if (noexec) { fseek (oafp, ahdr.packed_size, SEEK_CUR); } else { fseek (oafp, old_header_pos, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); } } old_header_pos = ftell (oafp); } return; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ static FILE * build_temporary_file () { int old_umask; FILE *afp; build_temporary_name (); signal (SIGINT, interrupt); signal (SIGHUP, interrupt); old_umask = umask (077); afp = xfopen (temporary_name, WRITE_BINARY); remove_temporary_at_error = TRUE; temporary_fp = afp; umask (old_umask); return afp; } static void build_backup_file () { build_backup_name (backup_archive_name, archive_name); if (!noexec) { signal (SIGINT, SIG_IGN); signal (SIGHUP, SIG_IGN); if (rename (archive_name, backup_archive_name) < 0) fatal_error (archive_name); recover_archive_when_interrupt = TRUE; signal (SIGINT, interrupt); signal (SIGHUP, interrupt); } } static void report_archive_name_if_different () { if (!quiet && new_archive_name == new_archive_name_buffer) { /* warning at old archive is SFX */ printf ("New archive file is \"%s\"\n", new_archive_name); } } #ifdef TMP_FILENAME_TEMPLATE void temporary_to_new_archive_file (new_archive_size) long new_archive_size; { FILE *oafp, *nafp; oafp = xfopen (temporary_name, READ_BINARY); if (!strcmp(new_archive_name, "-")) { nafp = stdout; writting_filename = "starndard output"; } else { nafp = xfopen (new_archive_name, WRITE_BINARY); writting_filename = archive_name; } reading_filename = temporary_name; copyfile (oafp, nafp, new_archive_size, 0); if (nafp != stdout) fclose (nafp); fclose (oafp); recover_archive_when_interrupt = FALSE; unlink (temporary_name); remove_temporary_at_error = FALSE; } #else temporary_to_new_archive_file (new_archive_size) long new_archive_size; { char *p; p = (char *)rindex(new_archive_name,'/'); p = p ? p+1 : new_archive_name; unlink ( new_archive_name ); if ( rename ( temporary_name , p )<0 ) { fprintf(stderr, "Can't rename temporary_name '%s'\n", new_archive_name); exit(1); } } #endif static void set_archive_file_mode () { int umask_value; struct stat stbuf; if (archive_file_gid < 0) { umask (umask_value = umask (0)); archive_file_mode = (~umask_value) & 0666; /* rw-rw-rw- */ if (stat (".", &stbuf) >= 0) archive_file_gid = stbuf.st_gid; } if (archive_file_gid >= 0) chown (new_archive_name, getuid (), archive_file_gid); chmod (new_archive_name, archive_file_mode); } /*----------------------------------------------------------------------*/ /* REMOVE FILE/DIRECTORY */ /*----------------------------------------------------------------------*/ static void remove_files (); static void remove_one (name) char *name; { struct stat stbuf; int filec; char **filev; if (stat (name, &stbuf) < 0) { warning ("Cannot access", name); } else if (is_directory (&stbuf)) { if (find_files (name, &filec, &filev)) { remove_files (filec, filev); free_files (filec, filev); } else warning ("Cannot open directory", name); if (noexec) printf ("REMOVE DIRECTORY %s\n", name); else if (rmdir (name) < 0) warning ("Cannot remove directory", name); else if (verbose) printf ("Removed %s.\n", name); } else if (is_regularfile (&stbuf)) { if (noexec) printf ("REMOVE FILE %s.\n", name); else if (unlink (name) < 0) warning ("Cannot remove", name); else if (verbose) printf ("Removed %s.\n", name); } else { error ("Cannot remove (not a file or directory)", name); } } static void remove_files (filec, filev) int filec; char **filev; { int i; for (i = 0; i < filec; i++) remove_one (filev[i]); } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ void cmd_add () { LzHeader ahdr; FILE *oafp, *nafp; int i; long old_header; boolean old_archive_exist; long new_archive_size; /* exit if no operation */ if (!update_if_newer && cmd_filec == 0) { error ("No files given in argument, do nothing.", ""); return; } /* open old archive if exist */ if ((oafp = open_old_archive ()) == NULL) old_archive_exist = FALSE; else old_archive_exist = TRUE; if (update_if_newer && cmd_filec == 0 && !oafp) fatal_error (archive_name); /* exit if cannot execute automatic update */ errno = 0; if (new_archive && old_archive_exist) { fclose (oafp); oafp = NULL; } if (oafp && archive_is_msdos_sfx1 (archive_name)) { skip_msdos_sfx1_code (oafp); build_standard_archive_name (new_archive_name_buffer, archive_name); new_archive_name = new_archive_name_buffer; } else { new_archive_name = archive_name; } /* build temporary file */ if (!noexec) nafp = build_temporary_file (); /* find needed files when automatic update */ if (update_if_newer && cmd_filec == 0) find_update_files (oafp); /* build new archive file */ /* cleaning arguments */ cleaning_files (&cmd_filec, &cmd_filev); if (cmd_filec == 0) { if (oafp) fclose (oafp); if (!noexec) fclose (nafp); return; } for (i = 0; i < cmd_filec; i ++) oafp = append_it (cmd_filev[i], oafp, nafp); if (oafp) { old_header = ftell (oafp); while (get_header (oafp, &ahdr)) { if (noexec) fseek (oafp, ahdr.packed_size, SEEK_CUR); else { fseek (oafp, old_header, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); } old_header = ftell (oafp); } fclose (oafp); } if (!noexec) { write_archive_tail (nafp); new_archive_size = ftell (nafp); fclose (nafp); } /* build backup archive file */ if (old_archive_exist) build_backup_file (); report_archive_name_if_different (); /* copy temporary file to new archive file */ if (!noexec && (!strcmp(new_archive_name, "-") || rename (temporary_name, new_archive_name) < 0)) temporary_to_new_archive_file (new_archive_size); /* set new archive file mode/group */ set_archive_file_mode (); /* remove archived files */ if (delete_after_append) remove_files (cmd_filec, cmd_filev); return; } void cmd_delete () { FILE *oafp, *nafp; long new_archive_size; /* open old archive if exist */ if ((oafp = open_old_archive ()) == NULL) fatal_error (archive_name); errno = 0; /* exit if no operation */ if (cmd_filec == 0) { fclose (oafp); warning ("No files given in argument, do nothing.", ""); return; } if (archive_is_msdos_sfx1 (archive_name)) { skip_msdos_sfx1_code (oafp); build_standard_archive_name (new_archive_name_buffer, archive_name); new_archive_name = new_archive_name_buffer; } else { new_archive_name = archive_name; } /* build temporary file */ if (!noexec) nafp = build_temporary_file (); /* build new archive file */ delete (oafp, nafp); fclose (oafp); if (!noexec) { write_archive_tail (nafp); new_archive_size = ftell (nafp); fclose (nafp); } /* build backup archive file */ build_backup_file (); report_archive_name_if_different (); /* copy temporary file to new archive file */ if (!noexec && rename (temporary_name, new_archive_name) < 0) temporary_to_new_archive_file (new_archive_size); /* set new archive file mode/group */ set_archive_file_mode (); return; } ); while (get_header (oafp, &ahdr)) { if (need_file (ahdr.name)) { /* skip */ fseek (oafp, ahdr.packed_size, SEElha/lharc.c 644 4263 151 47732 5162045636 6220 /*----------------------------------------------------------------------*/ /* LHarc Archiver Driver for UNIX */ /* This is part of LHarc UNIX Archiver Driver */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* Thanks to H.Yoshizaki. (MS-DOS LHarc) */ /* */ /* V0.00 Original 1988.05.23 Y.Tagawa */ /* V0.01 Alpha Version (for 4.2BSD) 1989.05.28 Y.Tagawa */ /* V0.02 Alpha Version Rel.2 1989.05.29 Y.Tagawa */ /* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */ /* V0.03a Debug 1989.07.03 Y.Tagawa */ /* V0.03b Modified 1989.07.13 Y.Tagawa */ /* V0.03c Debug (Thanks to void@rena.dit.junet)1989.08.09 Y.Tagawa */ /* V0.03d Modified (quiet and verbose) 1989.09.14 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V1.01 Bug Fixed 1989.12.25 Y.Tagawa */ /* */ /* DOS-Version Original LHx V C2.01 (C) H.Yohizaki */ /* */ /* V2.00 UNIX Lharc + DOS LHx -> OSK LHx 1990.11.01 Momozou */ /* V2.01 Minor Modified 1990.11.24 Momozou */ /* */ /* V0.02 LHx for UNIX 1991.11.18 M.Oki */ /* V0.03 LHa for UNIX 1991.12.17 M.Oki */ /* V0.04 LHa for UNIX beta version 1992.01.20 M.Oki */ /*----------------------------------------------------------------------*/ #include "lharc.h" /*----------------------------------------------------------------------*/ /* PROGRAM */ /*----------------------------------------------------------------------*/ #define CMD_UNKNOWN 0 #define CMD_EXTRACT 1 #define CMD_ADD 2 #define CMD_LIST 3 #define CMD_DELETE 4 static int cmd = CMD_UNKNOWN; char **cmd_filev; int cmd_filec; char *archive_name; char expanded_archive_name[FILENAME_LENGTH]; char temporary_name[FILENAME_LENGTH]; char backup_archive_name[FILENAME_LENGTH]; /* static functions */ static void sort_files(); /* options */ boolean quiet = FALSE; boolean text_mode = FALSE; boolean verbose = FALSE; boolean noexec = FALSE; /* debugging option */ boolean force = FALSE; boolean prof = FALSE; int compress_method = 5; /* deafult -lh5- */ int header_level = HEADER_LEVEL1; #ifdef EUC boolean euc_mode = FALSE; #endif /* view command flags */ boolean verbose_listing = FALSE; /* extract command flags */ boolean output_to_stdout = FALSE; /* append command flags */ boolean new_archive = FALSE; boolean update_if_newer = FALSE; boolean delete_after_append = FALSE; boolean generic_format = FALSE; boolean remove_temporary_at_error = FALSE; boolean recover_archive_when_interrupt = FALSE; boolean remove_extracting_file_when_interrupt = FALSE; boolean get_filename_from_stdin = FALSE; boolean ignore_directory = FALSE; boolean verify_mode = FALSE; char *extract_directory = NULL; char *xfilev[257]; /*----------------------------------------------------------------------*/ /* NOTES : Text File Format */ /* GENERATOR NewLine */ /* [generic] 0D 0A */ /* [MS-DOS] 0D 0A */ /* [OS9][MacOS] 0D */ /* [UNIX] 0A */ /*----------------------------------------------------------------------*/ static void print_tiny_usage_and_exit () { fprintf (stderr, "\ LHarc for UNIX V 1.02 Copyright(C) 1989 Y.Tagawa\n\ LHx for MSDOS V C2.01 Copyright(C) 1990 H.Yoshizaki\n\ LHx(arc) for OSK V 2.01 Modified 1990 Momozou\n\ LHa for UNIX V 0.04 (beta ver.) 1991 Masaru Oki\n\ "); fprintf(stderr, "\ usage: lha -{axelvudmcp}[qvnfodizg012][w=] archive_file [file...]\n\ commands: options:\n\ a Add(or replace) to archive q quiet\n\ x,e EXtract from archive v verbose\n\ l,v List / Verbose List n not execute\n\ u Update newer files to archive f force (over write at extract)\n\ d Delete from archive t FILES are TEXT file\n\ m Move to archive (means 'ad') o use LHarc compatible method (a/u)\n\ c re-Construct new archive w= specify extract directory (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\ z files not compress (a/u)\n\ g [Generic] format (for compatiblity)\n\ 0/1/2 header level (a/u)\n\ "); #ifdef EUC fprintf (stderr, "\ e TEXT code convert from/to EUC\n\ "); #endif exit (1); } void main (argc, argv) int argc; char *argv[]; { char *p , inpbuf[256]; if (argc < 2) print_tiny_usage_and_exit (); if (argc < 3) { cmd = CMD_LIST; argv--; argc++; goto work; } if ( argv[1][0]=='-' ) argv[1]++; /* commands */ switch ( argv[1][0] ) { case 'x': case 'e': cmd = CMD_EXTRACT; break; case 'p': output_to_stdout = TRUE; cmd = CMD_EXTRACT; break; case 'c': new_archive = TRUE; cmd = CMD_ADD; break; case 'a': cmd = CMD_ADD; break; case 'd': cmd = CMD_DELETE; break; case 'u': update_if_newer = TRUE; cmd = CMD_ADD; break; case 'm': delete_after_append = TRUE; cmd = CMD_ADD; break; case 'v': verbose_listing = TRUE; cmd = CMD_LIST; break; case 'l': cmd = CMD_LIST; break; case 't': cmd = CMD_EXTRACT; verify_mode = TRUE; break; default: print_tiny_usage_and_exit (); } /* options */ p = &argv[1][1]; for (p = &argv[1][1]; *p; ) { switch ( (*p++) ) { case 'q': quiet = TRUE; break; case 'f': force = TRUE; break; case 'p': prof = TRUE; break; case 'v': verbose = TRUE; break; case 't': text_mode = TRUE; break; #ifdef EUC case 'e': text_mode = TRUE; euc_mode = TRUE; break; #endif case 'n': noexec = TRUE; break; case 'g': generic_format = TRUE; header_level = 0; break; case 'd': delete_after_append = TRUE; break; case 'o': compress_method = 1; header_level = 0; break; case 'z': compress_method = 0; break; case 'i': ignore_directory = TRUE; break; case 'w': if ( *p=='=' ) p++; extract_directory=p; while (*p) p++; break; case '0': header_level = HEADER_LEVEL0; break; case '1': header_level = HEADER_LEVEL1; break; case '2': header_level = HEADER_LEVEL2; break; default: fprintf(stderr, "LHa: Unknown option '%c'.\n", p[-1]); exit(1); } } work: /* archive file name */ archive_name = argv[2]; if (!strcmp(archive_name, "-")) { if (!isatty(1) && cmd == CMD_ADD) quiet = TRUE; } else { if (argc == 3 && !isatty(0)) get_filename_from_stdin = TRUE; } /* target file name */ if ( get_filename_from_stdin ) { cmd_filec = 0; while ( gets( inpbuf ) ) { if ( strlen( inpbuf )<1 ) continue; if ( (xfilev[cmd_filec++]=(char *)strdup(inpbuf))==NULL ) fatal_error("Virtual memory exhausted\n"); if ( cmd_filec>256 ) fatal_error("Too many file names\n"); } xfilev[cmd_filec] = NULL; cmd_filev = xfilev; } else { cmd_filec = argc - 3; cmd_filev = argv + 3; } sort_files (); /* make crc table */ make_crctable(); switch (cmd) { case CMD_EXTRACT: cmd_extract (); break; case CMD_ADD: cmd_add (); break; case CMD_LIST: cmd_list (); break; case CMD_DELETE: cmd_delete (); break; } #ifdef USE_PROF if (!prof) exit (0); #endif exit (0); } static void message_1 (title, subject, name) char *title, *subject, *name; { fprintf (stderr, "LHa: %s%s ", title, subject); fflush (stderr); if (errno == 0) fprintf (stderr, "%s\n", name); else perror (name); } void message (subject, name) char *subject, *name; { message_1 ("", subject, name); } void warning (subject, name) char *subject, *name; { message_1 ("Warning: ", subject, name); } void error (subject, msg) char *subject, *msg; { message_1 ("Error: ", subject, msg); } void fatal_error (msg) char *msg; { message_1 ("Fatal error:", "", msg); if (remove_temporary_at_error) unlink (temporary_name); exit (1); } char *writting_filename; char *reading_filename; void write_error () { fatal_error (writting_filename); } void read_error () { fatal_error (reading_filename); } void interrupt (signo) int signo; { errno = 0; message ("Interrupted\n", ""); if ( temporary_fp ) fclose (temporary_fp); unlink (temporary_name); if (recover_archive_when_interrupt) rename (backup_archive_name, archive_name); if (remove_extracting_file_when_interrupt) { errno = 0; message ("Removing", writting_filename); unlink (writting_filename); } signal (SIGINT, SIG_DFL); signal (SIGHUP, SIG_DFL); kill (getpid (), signo); } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ static int sort_by_ascii (a, b) char **a, **b; { register char *p, *q; register int c1, c2; p = *a, q = *b; if (generic_format) { do { c1 = *(unsigned char*)p ++; c2 = *(unsigned char*)q ++; if (!c1 || !c2) break; if (islower (c1)) c1 = toupper (c1); if (islower (c2)) c2 = toupper (c2); } while (c1 == c2) ; return c1 - c2; } else { while (*p == *q && *p != '\0') p ++, q ++; return *(unsigned char*)p - *(unsigned char*)q; } } static void sort_files () { if (cmd_filec > 1) qsort (cmd_filev, cmd_filec, sizeof (char*), sort_by_ascii); } char *xmalloc (size) int size; { char *p = (char *)malloc (size); if (!p) fatal_error ("Not enough memory"); return p; } char *xrealloc (old, size) char *old; int size; { char *p = (char *)realloc (old, size); if (!p) fatal_error ("Not enough memory"); return p; } /*----------------------------------------------------------------------*/ /* STRING POOL */ /*----------------------------------------------------------------------*/ /* * string pool : * +-------------+-------------+--- ---+-------------+----------+ * | N A M E 1 \0| N A M E 2 \0| ... | N A M E n \0| | * +-------------+-------------+--- ---+-------------+----------+ * ^ ^ ^ * buffer+0 buffer+used buffer+size */ /* * vector : * +---------------+---------------+------------- -------------+ * | pointer to | pointer to | pointer to ... pointer to | * | string pool | N A M E 1 | N A M E 2 ... N A M E n | * +---------------+---------------+------------- -------------+ * ^ ^ * malloc base returned */ void init_sp (sp) struct string_pool *sp; { sp->size = 1024 - 8; /* any ( >=0 ) */ sp->used = 0; sp->n = 0; sp->buffer = (char*)xmalloc (sp->size * sizeof (char)); } void add_sp (sp, name, len) struct string_pool *sp; char *name; /* stored '\0' at tail */ int len; /* include '\0' */ { while (sp->used + len > sp->size) { sp->size *= 2; sp->buffer = (char*) xrealloc (sp->buffer, sp->size * sizeof (char)); } bcopy (name, sp->buffer + sp->used, len); sp->used += len; sp->n ++; } void finish_sp (sp, v_count, v_vector) register struct string_pool *sp; int *v_count; char ***v_vector; { int i; register char *p; char **v; v = (char**) xmalloc ((sp->n + 1) * sizeof (char*)); *v++ = sp->buffer; *v_vector = v; *v_count = sp->n; p = sp->buffer; for (i = sp->n; i; i --) { *v++ = p; if (i - 1) p += strlen (p) + 1; } } void free_sp (vector) char **vector; { vector --; free (*vector); /* free string pool */ free (vector); } /*----------------------------------------------------------------------*/ /* READ DIRECTORY FILES */ /*----------------------------------------------------------------------*/ static boolean include_path_p (path, name) char *path, *name; { char *n = name; while (*path) if (*path++ != *n++) return (path[-1] == '/' && *n == '\0'); return (*n == '/' || (n != name && path[-1] == '/' && n[-1] == '/')); } #define STREQU(a,b) (((a)[0] == (b)[0]) ? (strcmp ((a),(b)) == 0) : FALSE) void cleaning_files (v_filec, v_filev) int *v_filec; char ***v_filev; { char *flags; struct stat stbuf; register char **filev = *v_filev; register int filec = *v_filec; register char *p; register int i, j; if (filec == 0) return; flags = xmalloc (filec * sizeof (char)); /* flags & 0x01 : 1: ignore */ /* flags & 0x02 : 1: directory, 0 : regular file */ /* flags & 0x04 : 1: need delete */ for (i = 0; i < filec; i ++) if (stat (filev[i], &stbuf) < 0) { flags[i] = 0x04; fprintf (stderr, "LHa: Cannot access \"%s\", ignored.\n", filev[i]); } else { if (is_regularfile (&stbuf)) flags[i] = 0x00; else if (is_directory (&stbuf)) flags[i] = 0x02; else { flags[i] = 0x04; fprintf (stderr, "LHa: Cannot archive \"%s\", ignored.\n", filev[i]); } } errno = 0; for (i = 0; i < filec; i ++) { p = filev[i]; if ((flags[i] & 0x07) == 0x00) { /* regular file, not deleted/ignored */ for (j = i + 1; j < filec; j ++) { if ((flags[j] & 0x07) == 0x00) { /* regular file, not deleted/ignored */ if (STREQU (p, filev[j])) flags[j] = 0x04; /* delete */ } } } else if ((flags[i] & 0x07) == 0x02) { /* directory, not deleted/ignored */ for (j = i + 1; j < filec; j ++) { if ((flags[j] & 0x07) == 0x00) { /* regular file, not deleted/ignored */ if (include_path_p (p, filev[j])) flags[j] = 0x04; /* delete */ } else if ((flags[j] & 0x07) == 0x02) { /* directory, not deleted/ignored */ if (include_path_p (p, filev[j])) flags[j] = 0x04; /* delete */ } } } } for (i = j = 0; i < filec; i ++) { if ((flags[i] & 0x04) == 0) { if (i != j) filev[j] = filev[i]; j ++; } } *v_filec = j; free (flags); } #ifdef NODIRECTORY /* please need your imprementation */ boolean find_files (name, v_filec, v_filev) char *name; int *v_filec; char ***v_filev; { return FALSE; /* DUMMY */ } void free_files (filec, filev) int filec; char **filev; { /* do nothing */ } #else boolean find_files (name, v_filec, v_filev) char *name; int *v_filec; char ***v_filev; { struct string_pool sp; char newname[FILENAME_LENGTH]; int len, n; DIR *dirp; DIRENTRY *dp; struct stat tmp_stbuf, arc_stbuf, fil_stbuf; strcpy (newname, name); len = strlen (name); if (len > 0 && newname[len-1] != '/') newname[len++] = '/'; dirp = opendir (name); if (!dirp) return FALSE; init_sp (&sp); GETSTAT(temporary_name, &tmp_stbuf); GETSTAT(archive_name, &arc_stbuf); for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) { n = NAMLEN (dp); strncpy (newname+len, dp->d_name, n); newname[len + n] = '\0'; if (GETSTAT(newname, &fil_stbuf) < 0) continue; if ((dp->d_ino != 0) && /* exclude '.' and '..' */ ((dp->d_name[0] != '.') || ((n != 1) && ((dp->d_name[1] != '.') || (n != 2)))) && ((tmp_stbuf.st_dev != fil_stbuf.st_dev || tmp_stbuf.st_ino != fil_stbuf.st_ino) && (arc_stbuf.st_dev != fil_stbuf.st_dev || arc_stbuf.st_ino != fil_stbuf.st_ino))) { add_sp (&sp, newname, len + n + 1); } } closedir (dirp); finish_sp (&sp, v_filec, v_filev); if (*v_filec > 1) qsort (*v_filev, *v_filec, sizeof (char*), sort_by_ascii); cleaning_files (v_filec, v_filev); return TRUE; } void free_files (filec, filev) int filec; char **filev; { free_sp (filev); } #endif /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ /* Build temporary file name and store to TEMPORARY_NAME */ void build_temporary_name () { #ifdef TMP_FILENAME_TEMPLATE /* "/tmp/lhXXXXXX" etc. */ strcpy (temporary_name, TMP_FILENAME_TEMPLATE); mktemp (temporary_name); #else char *p, *s; strcpy (temporary_name, archive_name); for (p = temporary_name, s = (char*)0; *p; p ++) if (*p == '/') s = p; strcpy ((s ? s+1 : temporary_name), "lhXXXXXX"); mktemp (temporary_name); #endif } static void modify_filename_extention (buffer, ext) char *buffer; char *ext; { register char *p, *dot; for (p = buffer, dot = (char*)0; *p; p ++) { if (*p == '.') dot = p; else if (*p == '/') dot = (char*)0; } if (dot) p = dot; strcpy (p, ext); } /* build backup file name */ void build_backup_name (buffer, original) char *buffer; char *original; { strcpy (buffer, original); modify_filename_extention (buffer, BACKUPNAME_EXTENTION); /* ".bak" */ } void build_standard_archive_name (buffer, orginal) char *buffer; char *orginal; { strcpy (buffer, orginal); modify_filename_extention (buffer, ARCHIVENAME_EXTENTION); /* ".lzh" */ } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ extern int patmatch(); boolean need_file (name) char *name; { int i; if (cmd_filec == 0) return TRUE; for (i = 0; i < cmd_filec; i ++) { if (patmatch(cmd_filev[i], name, 0 ) ) return TRUE; } return FALSE; } FILE * xfopen (name, mode) char *name, *mode; { FILE *fp; if ((fp = fopen (name, mode)) == NULL) fatal_error (name); return fp; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ int archive_file_mode; int archive_file_gid; static boolean open_old_archive_1 (name, v_fp) char *name; FILE **v_fp; { FILE *fp; struct stat stbuf; if (stat (name, &stbuf) >= 0 && is_regularfile (&stbuf) && (fp = fopen (name, READ_BINARY)) != NULL) { *v_fp = fp; archive_file_gid = stbuf.st_gid; archive_file_mode = stbuf.st_mode; return TRUE; } *v_fp = NULL; archive_file_gid = -1; return FALSE; } FILE * open_old_archive () { FILE *fp; char *p; if (!strcmp(archive_name, "-")) { if (cmd == CMD_EXTRACT || cmd == CMD_LIST) return stdin; else return NULL; } if (p = (char *)rindex(archive_name,'.')) { if ( strucmp(".LZH",p)==0 || strucmp(".LZS",p)==0 || strucmp(".COM",p)==0 /* DOS SFX */ || strucmp(".EXE",p)==0 || strucmp(".X" ,p)==0 /* HUMAN SFX */ || strucmp(".BAK",p)==0 ) /* for BackUp */ { open_old_archive_1 (archive_name, &fp ); return fp; } } if ( open_old_archive_1 (archive_name, &fp) ) return fp; sprintf( expanded_archive_name , "%s.lzh",archive_name); if ( open_old_archive_1 (expanded_archive_name, &fp) ) { archive_name = expanded_archive_name; return fp; } /* if ( (errno&0xffff)!=E_PNNF ) { archive_name = expanded_archive_name; return NULL; } */ sprintf( expanded_archive_name, "%s.lzs",archive_name); if ( open_old_archive_1 (expanded_archive_name, &fp ) ) { archive_name = expanded_archive_name; return fp; } /* if ( (errno&0xffff)!=E_PNNF ) { archive_name = expanded_archive_name; return NULL; } */ sprintf( expanded_archive_name , "%s.lzh",archive_name); archive_name = expanded_archive_name; return NULL; } int inquire (msg, name, selective) char *msg, *name, *selective; { char buffer[1024]; char *p; for (;;) { fprintf (stderr, "%s %s ", name, msg); fflush (stderr); fgets (buffer, 1024, stdin); for (p = selective; *p; p++) if (buffer[0] == *p) return p - selective; } /*NOTREACHED*/ } void write_archive_tail (nafp) FILE *nafp; { putc (0x00, nafp); } void copy_old_one (oafp, nafp, hdr) FILE *oafp, *nafp; LzHeader *hdr; { if (noexec) { fseek (oafp, (long)(hdr->header_size + 2) + hdr->packed_size, SEEK_CUR); } else { reading_filename = archive_name; writting_filename = temporary_name; copyfile (oafp, nafp, (long)(hdr->header_size + 2) + hdr->packed_size,0); } } ] == (b)[0]) ? (strcmp ((a),(b)) == 0)lha/lharc.c.ori 644 4263 151 47627 5162045645 7013 /*----------------------------------------------------------------------*/ /* LHarc Archiver Driver for UNIX */ /* This is part of LHarc UNIX Archiver Driver */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* Thanks to H.Yoshizaki. (MS-DOS LHarc) */ /* */ /* V0.00 Original 1988.05.23 Y.Tagawa */ /* V0.01 Alpha Version (for 4.2BSD) 1989.05.28 Y.Tagawa */ /* V0.02 Alpha Version Rel.2 1989.05.29 Y.Tagawa */ /* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */ /* V0.03a Debug 1989.07.03 Y.Tagawa */ /* V0.03b Modified 1989.07.13 Y.Tagawa */ /* V0.03c Debug (Thanks to void@rena.dit.junet)1989.08.09 Y.Tagawa */ /* V0.03d Modified (quiet and verbose) 1989.09.14 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V1.01 Bug Fixed 1989.12.25 Y.Tagawa */ /* */ /* DOS-Version Original LHx V C2.01 (C) H.Yohizaki */ /* */ /* V2.00 UNIX Lharc + DOS LHx -> OSK LHx 1990.11.01 Momozou */ /* V2.01 Minor Modified 1990.11.24 Momozou */ /* */ /* V0.02 LHx for UNIX 1991.11.18 M.Oki */ /* V0.03 LHa for UNIX 1991.12.17 M.Oki */ /* V0.04 LHa for UNIX beta version 1992.01.20 M.Oki */ /*----------------------------------------------------------------------*/ #include "lharc.h" /*----------------------------------------------------------------------*/ /* PROGRAM */ /*----------------------------------------------------------------------*/ #define CMD_UNKNOWN 0 #define CMD_EXTRACT 1 #define CMD_ADD 2 #define CMD_LIST 3 #define CMD_DELETE 4 static int cmd = CMD_UNKNOWN; char **cmd_filev; int cmd_filec; char *archive_name; char expanded_archive_name[FILENAME_LENGTH]; char temporary_name[FILENAME_LENGTH]; char backup_archive_name[FILENAME_LENGTH]; /* static functions */ static void sort_files(); /* options */ boolean quiet = FALSE; boolean text_mode = FALSE; boolean verbose = FALSE; boolean noexec = FALSE; /* debugging option */ boolean force = FALSE; boolean prof = FALSE; int compress_method = 5; /* deafult -lh5- */ int header_level = HEADER_LEVEL1; #ifdef EUC boolean euc_mode = FALSE; #endif /* view command flags */ boolean verbose_listing = FALSE; /* extract command flags */ boolean output_to_stdout = FALSE; /* append command flags */ boolean new_archive = FALSE; boolean update_if_newer = FALSE; boolean delete_after_append = FALSE; boolean generic_format = FALSE; boolean remove_temporary_at_error = FALSE; boolean recover_archive_when_interrupt = FALSE; boolean remove_extracting_file_when_interrupt = FALSE; boolean get_filename_from_stdin = FALSE; boolean ignore_directory = FALSE; boolean verify_mode = FALSE; char *extract_directory = NULL; char *xfilev[257]; /*----------------------------------------------------------------------*/ /* NOTES : Text File Format */ /* GENERATOR NewLine */ /* [generic] 0D 0A */ /* [MS-DOS] 0D 0A */ /* [OS9][MacOS] 0D */ /* [UNIX] 0A */ /*----------------------------------------------------------------------*/ static void print_tiny_usage_and_exit () { fprintf (stderr, "\ LHarc for UNIX V 1.02 Copyright(C) 1989 Y.Tagawa\n\ LHx for MSDOS V C2.01 Copyright(C) 1990 H.Yoshizaki\n\ LHx(arc) for OSK V 2.01 Modified 1990 Momozou\n\ LHa for UNIX V 0.04 (beta ver.) 1991 Masaru Oki\n\ "); fprintf(stderr, "\ usage: lha -{axelvudmcp}[qvnfodizg012][w=] archive_file [file...]\n\ commands: options:\n\ a Add(or replace) to archive q quiet\n\ x,e EXtract from archive v verbose\n\ l,v List / Verbose List n not execute\n\ u Update newer files to archive f force (over write at extract)\n\ d Delete from archive t FILES are TEXT file\n\ m Move to archive (means 'ad') o use LHarc compatible method (a/u)\n\ c re-Construct new archive w= specify extract directory (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\ z files not compress (a/u)\n\ g [Generic] format (for compatiblity)\n\ 0/1/2 header level (a/u)\n\ "); #ifdef EUC fprintf (stderr, "\ e TEXT code convert from/to EUC\n\ "); #endif exit (1); } void main (argc, argv) int argc; char *argv[]; { char *p , inpbuf[256]; if (argc < 2) print_tiny_usage_and_exit (); if (argc < 3) { cmd = CMD_LIST; argv--; argc++; goto work; } if ( argv[1][0]=='-' ) argv[1]++; /* commands */ switch ( argv[1][0] ) { case 'x': case 'e': cmd = CMD_EXTRACT; break; case 'p': output_to_stdout = TRUE; cmd = CMD_EXTRACT; break; case 'c': new_archive = TRUE; cmd = CMD_ADD; break; case 'a': cmd = CMD_ADD; break; case 'd': cmd = CMD_DELETE; break; case 'u': update_if_newer = TRUE; cmd = CMD_ADD; break; case 'm': delete_after_append = TRUE; cmd = CMD_ADD; break; case 'v': verbose_listing = TRUE; cmd = CMD_LIST; break; case 'l': cmd = CMD_LIST; break; case 't': cmd = CMD_EXTRACT; verify_mode = TRUE; break; default: print_tiny_usage_and_exit (); } /* options */ p = &argv[1][1]; for (p = &argv[1][1]; *p; ) { switch ( (*p++) ) { case 'q': quiet = TRUE; break; case 'f': force = TRUE; break; case 'p': prof = TRUE; break; case 'v': verbose = TRUE; break; case 't': text_mode = TRUE; break; #ifdef EUC case 'e': text_mode = TRUE; euc_mode = TRUE; break; #endif case 'n': noexec = TRUE; break; case 'g': generic_format = TRUE; header_level = 0; break; case 'd': delete_after_append = TRUE; break; case 'o': compress_method = 1; header_level = 0; break; case 'z': compress_method = 0; break; case 'i': ignore_directory = TRUE; break; case 'w': if ( *p=='=' ) p++; extract_directory=p; while (*p) p++; break; case '0': header_level = HEADER_LEVEL0; break; case '1': header_level = HEADER_LEVEL1; break; case '2': header_level = HEADER_LEVEL2; break; default: fprintf(stderr, "LHa: Unknown option '%c'.\n", p[-1]); exit(1); } } work: /* archive file name */ archive_name = argv[2]; if (!strcmp(archive_name, "-")) { if (!isatty(1) && cmd == CMD_ADD) quiet = TRUE; } else { if (argc == 3 && !isatty(0)) get_filename_from_stdin = TRUE; } /* target file name */ if ( get_filename_from_stdin ) { cmd_filec = 0; while ( gets( inpbuf ) ) { if ( strlen( inpbuf )<1 ) continue; if ( (xfilev[cmd_filec++]=(char *)strdup(inpbuf))==NULL ) fatal_error("Virtual memory exhausted\n"); if ( cmd_filec>256 ) fatal_error("Too many file names\n"); } xfilev[cmd_filec] = NULL; cmd_filev = xfilev; } else { cmd_filec = argc - 3; cmd_filev = argv + 3; } sort_files (); /* make crc table */ make_crctable(); switch (cmd) { case CMD_EXTRACT: cmd_extract (); break; case CMD_ADD: cmd_add (); break; case CMD_LIST: cmd_list (); break; case CMD_DELETE: cmd_delete (); break; } #ifdef USE_PROF if (!prof) exit (0); #endif exit (0); } static void message_1 (title, subject, name) char *title, *subject, *name; { fprintf (stderr, "LHa: %s%s ", title, subject); fflush (stderr); if (errno == 0) fprintf (stderr, "%s\n", name); else perror (name); } void message (subject, name) char *subject, *name; { message_1 ("", subject, name); } void warning (subject, name) char *subject, *name; { message_1 ("Warning: ", subject, name); } void error (subject, msg) char *subject, *msg; { message_1 ("Error: ", subject, msg); } void fatal_error (msg) char *msg; { message_1 ("Fatal error:", "", msg); if (remove_temporary_at_error) unlink (temporary_name); exit (1); } char *writting_filename; char *reading_filename; void write_error () { fatal_error (writting_filename); } void read_error () { fatal_error (reading_filename); } void interrupt (signo) int signo; { errno = 0; message ("Interrupted\n", ""); if ( temporary_fp ) fclose (temporary_fp); unlink (temporary_name); if (recover_archive_when_interrupt) rename (backup_archive_name, archive_name); if (remove_extracting_file_when_interrupt) { errno = 0; message ("Removing", writting_filename); unlink (writting_filename); } signal (SIGINT, SIG_DFL); signal (SIGHUP, SIG_DFL); kill (getpid (), signo); } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ static int sort_by_ascii (a, b) char **a, **b; { register char *p, *q; register int c1, c2; p = *a, q = *b; if (generic_format) { do { c1 = *(unsigned char*)p ++; c2 = *(unsigned char*)q ++; if (!c1 || !c2) break; if (islower (c1)) c1 = toupper (c1); if (islower (c2)) c2 = toupper (c2); } while (c1 == c2) ; return c1 - c2; } else { while (*p == *q && *p != '\0') p ++, q ++; return *(unsigned char*)p - *(unsigned char*)q; } } static void sort_files () { if (cmd_filec > 1) qsort (cmd_filev, cmd_filec, sizeof (char*), sort_by_ascii); } char *xmalloc (size) int size; { char *p = (char *)malloc (size); if (!p) fatal_error ("Not enough memory"); return p; } char *xrealloc (old, size) char *old; int size; { char *p = (char *)realloc (old, size); if (!p) fatal_error ("Not enough memory"); return p; } /*----------------------------------------------------------------------*/ /* STRING POOL */ /*----------------------------------------------------------------------*/ /* * string pool : * +-------------+-------------+--- ---+-------------+----------+ * | N A M E 1 \0| N A M E 2 \0| ... | N A M E n \0| | * +-------------+-------------+--- ---+-------------+----------+ * ^ ^ ^ * buffer+0 buffer+used buffer+size */ /* * vector : * +---------------+---------------+------------- -------------+ * | pointer to | pointer to | pointer to ... pointer to | * | string pool | N A M E 1 | N A M E 2 ... N A M E n | * +---------------+---------------+------------- -------------+ * ^ ^ * malloc base returned */ void init_sp (sp) struct string_pool *sp; { sp->size = 1024 - 8; /* any ( >=0 ) */ sp->used = 0; sp->n = 0; sp->buffer = (char*)xmalloc (sp->size * sizeof (char)); } void add_sp (sp, name, len) struct string_pool *sp; char *name; /* stored '\0' at tail */ int len; /* include '\0' */ { while (sp->used + len > sp->size) { sp->size *= 2; sp->buffer = (char*) xrealloc (sp->buffer, sp->size * sizeof (char)); } bcopy (name, sp->buffer + sp->used, len); sp->used += len; sp->n ++; } void finish_sp (sp, v_count, v_vector) register struct string_pool *sp; int *v_count; char ***v_vector; { int i; register char *p; char **v; v = (char**) xmalloc ((sp->n + 1) * sizeof (char*)); *v++ = sp->buffer; *v_vector = v; *v_count = sp->n; p = sp->buffer; for (i = sp->n; i; i --) { *v++ = p; if (i - 1) p += strlen (p) + 1; } } void free_sp (vector) char **vector; { vector --; free (*vector); /* free string pool */ free (vector); } /*----------------------------------------------------------------------*/ /* READ DIRECTORY FILES */ /*----------------------------------------------------------------------*/ static boolean include_path_p (path, name) char *path, *name; { char *n = name; while (*path) if (*path++ != *n++) return (path[-1] == '/' && *n == '\0'); return (*n == '/' || (n != name && path[-1] == '/' && n[-1] == '/')); } #define STREQU(a,b) (((a)[0] == (b)[0]) ? (strcmp ((a),(b)) == 0) : FALSE) void cleaning_files (v_filec, v_filev) int *v_filec; char ***v_filev; { char *flags; struct stat stbuf; register char **filev = *v_filev; register int filec = *v_filec; register char *p; register int i, j; if (filec == 0) return; flags = xmalloc (filec * sizeof (char)); /* flags & 0x01 : 1: ignore */ /* flags & 0x02 : 1: directory, 0 : regular file */ /* flags & 0x04 : 1: need delete */ for (i = 0; i < filec; i ++) if (stat (filev[i], &stbuf) < 0) { flags[i] = 0x04; fprintf (stderr, "LHa: Cannot access \"%s\", ignored.\n", filev[i]); } else { if (is_regularfile (&stbuf)) flags[i] = 0x00; else if (is_directory (&stbuf)) flags[i] = 0x02; else { flags[i] = 0x04; fprintf (stderr, "LHa: Cannot archive \"%s\", ignored.\n", filev[i]); } } errno = 0; for (i = 0; i < filec; i ++) { p = filev[i]; if ((flags[i] & 0x07) == 0x00) { /* regular file, not deleted/ignored */ for (j = i + 1; j < filec; j ++) { if ((flags[j] & 0x07) == 0x00) { /* regular file, not deleted/ignored */ if (STREQU (p, filev[j])) flags[j] = 0x04; /* delete */ } } } else if ((flags[i] & 0x07) == 0x02) { /* directory, not deleted/ignored */ for (j = i + 1; j < filec; j ++) { if ((flags[j] & 0x07) == 0x00) { /* regular file, not deleted/ignored */ if (include_path_p (p, filev[j])) flags[j] = 0x04; /* delete */ } else if ((flags[j] & 0x07) == 0x02) { /* directory, not deleted/ignored */ if (include_path_p (p, filev[j])) flags[j] = 0x04; /* delete */ } } } } for (i = j = 0; i < filec; i ++) { if ((flags[i] & 0x04) == 0) { if (i != j) filev[j] = filev[i]; j ++; } } *v_filec = j; free (flags); } #ifdef NODIRECTORY /* please need your imprementation */ boolean find_files (name, v_filec, v_filev) char *name; int *v_filec; char ***v_filev; { return FALSE; /* DUMMY */ } void free_files (filec, filev) int filec; char **filev; { /* do nothing */ } #else boolean find_files (name, v_filec, v_filev) char *name; int *v_filec; char ***v_filev; { struct string_pool sp; char newname[FILENAME_LENGTH]; int len, n; DIR *dirp; DIRENTRY *dp; struct stat tmp_stbuf, arc_stbuf, fil_stbuf; strcpy (newname, name); len = strlen (name); if (len > 0 && newname[len-1] != '/') newname[len++] = '/'; dirp = opendir (name); if (!dirp) return FALSE; init_sp (&sp); GETSTAT(temporary_name, &tmp_stbuf); GETSTAT(archive_name, &arc_stbuf); for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) { n = NAMLEN (dp); strncpy (newname+len, dp->d_name, n); newname[len + n] = '\0'; if (GETSTAT(newname, &fil_stbuf) < 0) continue; if ((dp->d_ino != 0) && /* exclude '.' and '..' */ ((dp->d_name[0] != '.') || ((n != 1) && ((dp->d_name[1] != '.') || (n != 2)))) && ((tmp_stbuf.st_dev != fil_stbuf.st_dev || tmp_stbuf.st_ino != fil_stbuf.st_ino) && (arc_stbuf.st_dev != fil_stbuf.st_dev || arc_stbuf.st_ino != fil_stbuf.st_ino))) { add_sp (&sp, newname, len + n + 1); } } closedir (dirp); finish_sp (&sp, v_filec, v_filev); if (*v_filec > 1) qsort (*v_filev, *v_filec, sizeof (char*), sort_by_ascii); cleaning_files (v_filec, v_filev); return TRUE; } void free_files (filec, filev) int filec; char **filev; { free_sp (filev); } #endif /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ /* Build temporary file name and store to TEMPORARY_NAME */ void build_temporary_name () { #ifdef TMP_FILENAME_TEMPLATE /* "/tmp/lhXXXXXX" etc. */ strcpy (temporary_name, TMP_FILENAME_TEMPLATE); mktemp (temporary_name); #else char *p, *s; strcpy (temporary_name, archive_name); for (p = temporary_name, s = (char*)0; *p; p ++) if (*p == '/') s = p; strcpy ((s ? s+1 : temporary_name), "lhXXXXXX"); mktemp (temporary_name); #endif } static void modify_filename_extention (buffer, ext) char *buffer; char *ext; { register char *p, *dot; for (p = buffer, dot = (char*)0; *p; p ++) { if (*p == '.') dot = p; else if (*p == '/') dot = (char*)0; } if (dot) p = dot; strcpy (p, ext); } /* build backup file name */ void build_backup_name (buffer, original) char *buffer; char *original; { strcpy (buffer, original); modify_filename_extention (buffer, BACKUPNAME_EXTENTION); /* ".bak" */ } void build_standard_archive_name (buffer, orginal) char *buffer; char *orginal; { strcpy (buffer, orginal); modify_filename_extention (buffer, ARCHIVENAME_EXTENTION); /* ".lzh" */ } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ extern int patmatch(); boolean need_file (name) char *name; { int i; if (cmd_filec == 0) return TRUE; for (i = 0; i < cmd_filec; i ++) { if (patmatch(cmd_filev[i], name, 0 ) ) return TRUE; } return FALSE; } FILE * xfopen (name, mode) char *name, *mode; { FILE *fp; if ((fp = fopen (name, mode)) == NULL) fatal_error (name); return fp; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ int archive_file_mode; int archive_file_gid; static boolean open_old_archive_1 (name, v_fp) char *name; FILE **v_fp; { FILE *fp; struct stat stbuf; if (stat (name, &stbuf) >= 0 && is_regularfile (&stbuf) && (fp = fopen (name, READ_BINARY)) != NULL) { *v_fp = fp; archive_file_gid = stbuf.st_gid; archive_file_mode = stbuf.st_mode; return TRUE; } *v_fp = NULL; archive_file_gid = -1; return FALSE; } FILE * open_old_archive () { FILE *fp; char *p; if (!strcmp(archive_name, "-")) { if (cmd == CMD_EXTRACT || cmd == CMD_LIST) return stdin; else return NULL; } if (p = (char *)rindex(archive_name,'.')) { if ( strucmp(".LZH",p)==0 || strucmp(".LZS",p)==0 || strucmp(".COM",p)==0 /* DOS SFX */ || strucmp(".EXE",p)==0 || strucmp(".X" ,p)==0 /* HUMAN SFX */ || strucmp(".BAK",p)==0 ) /* for BackUp */ { open_old_archive_1 (archive_name, &fp ); return fp; } } sprintf( expanded_archive_name , "%s.lzh",archive_name); if ( open_old_archive_1 (expanded_archive_name, &fp) ) { archive_name = expanded_archive_name; return fp; } /* if ( (errno&0xffff)!=E_PNNF ) { archive_name = expanded_archive_name; return NULL; } */ sprintf( expanded_archive_name, "%s.lzs",archive_name); if ( open_old_archive_1 (expanded_archive_name, &fp ) ) { archive_name = expanded_archive_name; return fp; } /* if ( (errno&0xffff)!=E_PNNF ) { archive_name = expanded_archive_name; return NULL; } */ sprintf( expanded_archive_name , "%s.lzh",archive_name); archive_name = expanded_archive_name; return NULL; } int inquire (msg, name, selective) char *msg, *name, *selective; { char buffer[1024]; char *p; for (;;) { fprintf (stderr, "%s %s ", name, msg); fflush (stderr); fgets (buffer, 1024, stdin); for (p = selective; *p; p++) if (buffer[0] == *p) return p - selective; } /*NOTREACHED*/ } void write_archive_tail (nafp) FILE *nafp; { putc (0x00, nafp); } void copy_old_one (oafp, nafp, hdr) FILE *oafp, *nafp; LzHeader *hdr; { if (noexec) { fseek (oafp, (long)(hdr->header_size + 2) + hdr->packed_size, SEEK_CUR); } else { reading_filename = archive_name; writting_filename = temporary_name; copyfile (oafp, nafp, (long)(hdr->header_size + 2) + hdr->packed_size,0); } } & path[-1] == '/' && n[-1] == '/')); } #define STREQU(a,b) (((a)[0] == (b)[0]) ? (strcmp ((a),(b)) == 0)lha/lharc.doc 644 4263 151 23021 5162045650 6520 ------------------------------------------------------------------------------ LHarc UNIX V1.00 Copyright (C) 1989 Yooichi.Tagawa 1989.09.22 c m oMIX ID: y.tagawa ------------------------------------------------------------------------------ UNIX LHarc B vO FREEWARE zzB AfAUNIX LHarc (LHarc UNIX) LHarc B ygz lharc {axelvudmcp}[qvnftgvd] archive_file [files or directories...] R}hAaxelvudmcp wB(s) IvV qvnftgvd w\B (\BW@\) yA[JCut@Cz wt@Ct@CA.lzh t@Ct BATtBbNX\B KA^pATtBbNX .lzh ]vB .com .exe TbtBNXAMS-DOS LHarc SFX (ゥWJ@\tkt@C) BALHarc UNIX ASFX `ョt@C BSFX `ョA[JCut@C/s ATbtBbNX .lzh B SFX B yR}hz a A[JCut@Cwt@Ci[B fBNgwATufBNg i[B x e A[JCut@Cwt@Ct@ CoB l v A[JCut@Ci[wt@C t@C\ヲBv A oB u wt@CA[JCut@Ci[t@ CVAA[JCut@Ci[ i[B d A[JCut@Cwt@CB m A[JCut@Cwt@Ci[Aw t@CB c A[JCut@CejAVKA[JCut@C wt@Ci[B p A[JCut@Cwt@Ce WooB yIvVz q bZ[W}sB v bZ[WoB n タsBAfobOcB f ot@CsB t eLXg[hBMS-DOS eLXgt@CsR[h sB g A[JCu [generic] B d A[JCut@CB yz MS-DOS LHarc V1.13c (AO) A[JCut@ CBSFX `ョA Warning b Z[WoB LHarc UNIX A[JCut@CATufBNgw AMS-DOS LHarc B yzzKz AzzA]AB 1. \ヲB 2. zzeA a. zze(\[XR[hAhLgA vO}[)zzK BAヲhL gpB b. LHarc tltzz wBA tltヲhLgp B c. oCizzB(tl) 3. VzzB(`) 4. vOgpQS B 5. メAvOsA` B 6. vOASvOg pBAvO LHarc ALHarc B 7. pALAL FB a. vOCp~B b. pvOgpメsKf zzB c. CXg[igpAvOg BApメsB AQApメSCB d. ptlsvOgpA pメAT|[gsB yz BSD Symbolic-link t@CvB n[hNBAメZpb` BPW MS-DOS LHarc t@CWJB A FIX B yz LZHUF @b LZARI @\FA Nifty AALArc メOaFAA v LZHUF @yAMS-DOS LHarc gh AJlBAbZ[Wn a(MIX ID:k.ishi)AA|[g ApXY (MIX ID:kmori)モB L V1.00: * 9. VAX 11/785 UNIX 4.3BSD /`FbNsB (`FbNR) * 16. lharc.c lhio.c unsigned char @Asizeof(int) != sizeof (long) @oOB * 17. A[JCut@CXB iOAlharc a .a xxx wA.lzh t@C BA.a.lzh j * 18. SIGINT SIGHUP nhOsB * 19. v (verbose) IvVAbZ[WVv XBAl v R}htB * 20. d (delete after add) IvVB * 21. oO FIX B L V0.03b: * 14. lharc.c find_file BUG B * 15. g IvVIBAUNIX [generic] `ョvQBB UNIX eLXgt@C LHarc MS-DOS AJgfBNgt@ClA lharc cgt BAkTCYA LHarc MS-DOS LHarc UNIX kASY BAWJvB L V0.03a: * 14. lhio.c read_generic_text_file BUG B L V0.03: * 1. quiet text_mode IvVtB text_mode IvVAdl gB 2. G[bZ[WsKB + 3. o Overwrite `FbNsA B(^_^) + 4. TufBNg~\[g A[JCut@CB * 5. k/WJASYAMS-DOS LHarc V1.13c Rp`u B LArc type 4 yAtype 5 B * 6. MS-DOS ZtGNXgNgA[JCu`ョ B 7. MS-DOS V1.13c A[JCut@C [MS-DOS] A [generic] AMS-DOS (\) [MS-DOS] FッtH[}bgvB(^_^) 8. MS-DOS V1.13c TufBNgwpX WJB 9. VAX 11/785 UNIX 4.2BSD /`FbNsB (`FbNR) + 10. vAMS-DOS <--> UNIX A[JCut@C ]oCisB * 11. System-V AesB(lhdir.c lhdir.h) * 12. v l R}h\ヲ`XsB * 13. lzhuf.c @B(v) L V0.02: 1. verbose/quiet/text_mode option B 2. G[bZ[WsKB * 3. o Overwrite `FbNsA B(^_^) * 4. TufBNg~\[g A[JCut@CB 5. k/WJASYAMS-DOS LHarc V1.13c Rp`u vB 6. AMS-DOS ZtGNXgNgA[JCu`ョ B 7. MS-DOS V1.13c A[JCut@C [MS-DOS] A [generic] AMS-DOS (\) [MS-DOS] FッtH[}bgvB(^_^) 8. MS-DOS V1.13c TufBNgwpX WJB 9. VAX 11/785 UNIX 4.2BSD /`FbNsB (`FbNR) * 10. vAMS-DOS <--> UNIX A[JCut@C ]oCisB L V0.01: 1. verbose/quiet/text_mode option B 2. G[bZ[WsKB 3. o Overwrite `FbNsB 4. TufBNg~\[gB 5. k/WJASYAMS-DOS LHarc V1.13c Rp`u vB 6. AMS-DOS ZtGNXgNgA[JCu`ョ B 7. MS-DOS V1.13c A[JCut@C [MS-DOS] A [generic] AMS-DOS (\) [MS-DOS] FッtH[}bgvB(^_^) 8. MS-DOS V1.13c TufBNgwpX WJB 9. VAX 11/785 UNIX 4.2BSD /`FbNsB (`FbNR) ------------------------------------------------------------------------------ QS B 5. メAvOsA` B 6. vOASvOg pBAvO LHarc ALHarc B 7. pALAL FB a. vOCp~B b. pvOgpメsKf lha/lharc.h 644 4263 151 24515 5162045654 6217 /*----------------------------------------------------------------------*/ /* LHarc Archiver Driver for UNIX */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V0.03 LHa for UNIX 1991.12.18 M.Oki */ /*----------------------------------------------------------------------*/ #include #include #include #include #include #include /* most of System V, define SYSTIME_HAS_NO_TM */ #ifdef SYSTIME_HAS_NO_TM #include #endif #if defined(titan) || !defined(SYSTIME_HAS_NO_TM) #include #endif /*----------------------------------------------------------------------*/ /* DIRECTORY ACCESS STUFF */ /*----------------------------------------------------------------------*/ #ifndef NODIRECTORY #ifdef SYSV_SYSTEM_DIR #include #define DIRENTRY struct dirent #define NAMLEN(p) strlen (p->d_name) #else /* not SYSV_SYSTEM_DIR */ #ifdef NONSYSTEM_DIR_LIBRARY #include "lhdir.h" #else /* not NONSYSTEM_DIR_LIBRARY */ # ifdef OSK # include # else # include # endif #endif /* not NONSYSTEM_DIR_LIBRARY */ #define DIRENTRY struct direct #define NAMLEN(p) p->d_namlen extern DIR *opendir (); extern struct direct *readdir (); #endif /* not SYSV_SYSTEM_DIR */ #endif /*----------------------------------------------------------------------*/ /* FILE ATTRIBUTES */ /*----------------------------------------------------------------------*/ /* If file mode is not compatible between your Machine/OS and LHarc standard UNIX file mode. (See UNIX Manual stat(1), , and/or below UNIX_* definitions. ) */ /* #define NOT_COMPATIBLE_MODE */ #define is_directory(statp) (((statp)->st_mode & S_IFMT) == S_IFDIR) #define is_regularfile(statp) (((statp)->st_mode & S_IFMT) == S_IFREG) /* #define WRITE_BINARY "wb" */ /* #define READ_BINARy "rb" */ #define WRITE_BINARY "w" #define READ_BINARY "r" /*----------------------------------------------------------------------*/ /* MEMORY AND STRING FUNCTIONS */ /*----------------------------------------------------------------------*/ #ifndef USG #include #else #include #endif /* USG */ #ifdef NOINDEX #define index strchr #define rindex strrchr #endif /* NOINDEX */ #ifdef NOBSTRING #define bcmp(a,b,n) memcmp ((a),(b),(n)) #define bzero(d,n) memset((d),0,(n)) #define bcopy(s,d,n) memmove((d),(s),(n)) #endif /* NOBSTRING */ #ifdef ultrix #define strucmp(p,q) strcasecmp((p),(q)) #endif /*----------------------------------------------------------------------*/ /* YOUR CUSTOMIZIES */ /*----------------------------------------------------------------------*/ /* These difinitions are changable to you like. */ /* #define ARCHIVENAME_EXTENTION ".LZH" */ /* #define BACKUPNAME_EXTENTION ".BAK" */ /* #define TMP_FILENAME_TEMPLATE "/usr/tmp/lhXXXXXX" */ /* #define MULTIBYTE_CHAR */ /* #define USE_PROF */ #ifndef ARCHIVENAME_EXTENTION #define ARCHIVENAME_EXTENTION ".lzh" #endif #ifndef BACKUPNAME_EXTENTION #define BACKUPNAME_EXTENTION ".bak" #endif #ifndef TMP_FILENAME_TEMPLATE #define TMP_FILENAME_TEMPLATE "/tmp/lhXXXXXX" #endif #define SJC_FIRST_P(c) \ (((unsigned char)(c) >= 0x80) && \ (((unsigned char)(c) < 0xa0) || \ ((unsigned char)(c) >= 0xe0) && \ ((unsigned char)(c) < 0xfd))) #define SJC_SECOND_P(c) \ (((unsigned char)(c) >= 0x40) && \ ((unsigned char)(c) < 0xfd) && \ ((ungigned char)(c) != 0x7f)) #ifdef MULTIBYTE_CHAR #define MULTIBYTE_FIRST_P SJC_FIRST_P #define MULTIBYTE_SECOND_P SJC_SECOND_P #endif /* MULTIBYTE_CHAR */ /*----------------------------------------------------------------------*/ /* OTHER DIFINITIONS */ /*----------------------------------------------------------------------*/ /* Your C-Compiler has no 'void' */ #ifdef NO_VOID #define void #endif #ifndef SEEK_SET #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #endif #define FILENAME_LENGTH 1024 /* non-integral functions */ extern struct tm *localtime (); extern char *getenv (); #ifndef _MINIX #ifndef __STDC__ extern char *malloc (); extern char *realloc (); #endif #endif /* external variables */ extern int errno; #define FALSE 0 #define TRUE 1 typedef int boolean; /*----------------------------------------------------------------------*/ /* LHarc FILE DEFINITIONS */ /*----------------------------------------------------------------------*/ #define METHOD_TYPE_STRAGE 5 #define LZHUFF0_METHOD "-lh0-" #define LZHUFF1_METHOD "-lh1-" #define LZHUFF2_METHOD "-lh2-" #define LZHUFF3_METHOD "-lh3-" #define LZHUFF4_METHOD "-lh4-" #define LZHUFF5_METHOD "-lh5-" #define LARC4_METHOD "-lz4-" #define LARC5_METHOD "-lz5-" #define LZHDIRS_METHOD "-lhd-" #define I_HEADER_SIZE 0 #define I_HEADER_CHECKSUM 1 #define I_METHOD 2 #define I_PACKED_SIZE 7 #define I_ORIGINAL_SIZE 11 #define I_LAST_MODIFIED_STAMP 15 #define I_ATTRIBUTE 19 #define I_HEADER_LEVEL 20 #define I_NAME_LENGTH 21 #define I_NAME 22 #define I_CRC 22 /* + name_length */ #define I_EXTEND_TYPE 24 /* + name_length */ #define I_MINOR_VERSION 25 /* + name_length */ #define I_UNIX_LAST_MODIFIED_STAMP 26 /* + name_length */ #define I_UNIX_MODE 30 /* + name_length */ #define I_UNIX_UID 32 /* + name_length */ #define I_UNIX_GID 34 /* + name_length */ #define I_UNIX_EXTEND_BOTTOM 36 /* + name_length */ #define I_GENERIC_HEADER_BOTTOM I_EXTEND_TYPE #define EXTEND_GENERIC 0 #define EXTEND_UNIX 'U' #define EXTEND_MSDOS 'M' #define EXTEND_MACOS 'm' #define EXTEND_OS9 '9' #define EXTEND_OS2 '2' #define EXTEND_OS68K 'K' #define EXTEND_OS386 '3' /* OS-9000??? */ #define EXTEND_HUMAN 'H' #define EXTEND_CPM 'C' #define EXTEND_FLEX 'F' #define EXTEND_RUNSER 'R' /* this OS type is not official */ #define EXTEND_TOWNSOS 'T' #define EXTEND_XOSK 'X' /*------------------------------*/ #define GENERIC_ATTRIBUTE 0x20 #define GENERIC_DIRECTORY_ATTRIBUTE 0x10 #define HEADER_LEVEL0 0x00 #define HEADER_LEVEL1 0x01 #define HEADER_LEVEL2 0x02 #define CURRENT_UNIX_MINOR_VERSION 0x00 #define DELIM ('/') #define DELIM2 (0xff) #define DELIMSTR "/" typedef struct LzHeader { unsigned char header_size; char method[METHOD_TYPE_STRAGE]; long packed_size; long original_size; long last_modified_stamp; unsigned char attribute; unsigned char header_level; char name[256]; unsigned short crc; boolean has_crc; unsigned char extend_type; unsigned char minor_version; /* extend_type == EXTEND_UNIX and convert from other type. */ time_t unix_last_modified_stamp; unsigned short unix_mode; unsigned short unix_uid; unsigned short unix_gid; } LzHeader; #define OSK_RW_RW_RW 0000033 #define OSK_FILE_REGULAR 0000000 #define OSK_DIRECTORY_PERM 0000200 #define OSK_SHARED_PERM 0000100 #define OSK_OTHER_EXEC_PERM 0000040 #define OSK_OTHER_WRITE_PERM 0000020 #define OSK_OTHER_READ_PERM 0000010 #define OSK_OWNER_EXEC_PERM 0000004 #define OSK_OWNER_WRITE_PERM 0000002 #define OSK_OWNER_READ_PERM 0000001 #define UNIX_FILE_TYPEMASK 0170000 #define UNIX_FILE_REGULAR 0100000 #define UNIX_FILE_DIRECTORY 0040000 #define UNIX_SETUID 0004000 #define UNIX_SETGID 0002000 #define UNIX_STYCKYBIT 0001000 #define UNIX_OWNER_READ_PERM 0000400 #define UNIX_OWNER_WRITE_PERM 0000200 #define UNIX_OWNER_EXEC_PERM 0000100 #define UNIX_GROUP_READ_PERM 0000040 #define UNIX_GROUP_WRITE_PERM 0000020 #define UNIX_GROUP_EXEC_PERM 0000010 #define UNIX_OTHER_READ_PERM 0000004 #define UNIX_OTHER_WRITE_PERM 0000002 #define UNIX_OTHER_EXEC_PERM 0000001 #define UNIX_RW_RW_RW 0000666 #define LZHEADER_STRAGE 4096 #ifdef S_IFLNK #define GETSTAT lstat #else #define GETSTAT stat #endif /* used by qsort() for alphabetic-sort */ #define STRING_COMPARE(a,b) strcmp((a),(b)) struct string_pool { int used; int size; int n; char *buffer; }; /*----------------------------------------------------------------------*/ /* OPTIONS */ /*----------------------------------------------------------------------*/ /* command line options (common options) */ extern boolean quiet; extern boolean text_mode; extern boolean verbose; extern boolean noexec; /* debugging option */ extern boolean force; extern boolean prof; extern boolean delete_after_append; /* list command flags */ extern boolean verbose_listing; /* extract/print command flags */ extern boolean output_to_stdout; /* add/update/delete command flags */ extern boolean new_archive; extern boolean update_if_newer; extern boolean generic_format; /*----------------------------------------------------------------------*/ /* VARIABLES */ /*----------------------------------------------------------------------*/ extern char **cmd_filev; extern int cmd_filec; extern char *archive_name; extern char expanded_archive_name[FILENAME_LENGTH]; extern char temporary_name[FILENAME_LENGTH]; extern char backup_archive_name[FILENAME_LENGTH]; extern char *reading_filename, *writting_filename; extern boolean remove_temporary_at_error; extern boolean recover_archive_when_interrupt; extern boolean remove_extracting_file_when_interrupt; extern int archive_file_mode; extern int archive_file_gid; /*----------------------------------------------------------------------*/ /* Functions */ /*----------------------------------------------------------------------*/ extern void interrupt (); extern void message (); extern void warning (); extern void error (); extern void fatal_error (); extern boolean need_file (); extern int inquire (); extern FILE *xfopen (); extern boolean find_files (); extern void free_files (); extern void init_sp (); extern void add_sp (); extern void finish_sp (); extern void free_sp (); extern void cleaning_files (); extern void build_temporary_name (); extern void build_backup_file_name (); extern void build_standard_archive_name (); extern FILE *open_old_archive (); extern void init_header (); extern boolean get_header (); extern boolean archive_is_msdos_sfx1 (); extern boolean skip_msdos_sfx1_code (); extern void write_header (); extern void write_archive_tail (); extern void copy_old_one (); extern unsigned char *convdelim (); extern long copyfile (); extern void cmd_list (), cmd_extract (), cmd_add (), cmd_delete (); extern boolean ignore_directory; extern boolean compress_method; extern boolean verify_mode; extern char *extract_directory; extern FILE *temporary_fp; ; return fp; } /*----------------------------------------------------------------------*/ /* */ /*-------------------------------------------------------------------lha/lharc.h.ori 644 4263 151 24413 5162045661 7002 /*----------------------------------------------------------------------*/ /* LHarc Archiver Driver for UNIX */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V0.03 LHa for UNIX 1991.12.18 M.Oki */ /*----------------------------------------------------------------------*/ #include #include #include #include #include #include /* most of System V, define SYSTIME_HAS_NO_TM */ #ifdef SYSTIME_HAS_NO_TM #include #endif #if defined(titan) || !defined(SYSTIME_HAS_NO_TM) #include #endif /*----------------------------------------------------------------------*/ /* DIRECTORY ACCESS STUFF */ /*----------------------------------------------------------------------*/ #ifndef NODIRECTORY #ifdef SYSV_SYSTEM_DIR #include #define DIRENTRY struct dirent #define NAMLEN(p) strlen (p->d_name) #else /* not SYSV_SYSTEM_DIR */ #ifdef NONSYSTEM_DIR_LIBRARY #include "lhdir.h" #else /* not NONSYSTEM_DIR_LIBRARY */ # ifdef OSK # include # else # include # endif #endif /* not NONSYSTEM_DIR_LIBRARY */ #define DIRENTRY struct direct #define NAMLEN(p) p->d_namlen extern DIR *opendir (); extern struct direct *readdir (); #endif /* not SYSV_SYSTEM_DIR */ #endif /*----------------------------------------------------------------------*/ /* FILE ATTRIBUTES */ /*----------------------------------------------------------------------*/ /* If file mode is not compatible between your Machine/OS and LHarc standard UNIX file mode. (See UNIX Manual stat(1), , and/or below UNIX_* definitions. ) */ /* #define NOT_COMPATIBLE_MODE */ #define is_directory(statp) (((statp)->st_mode & S_IFMT) == S_IFDIR) #define is_regularfile(statp) (((statp)->st_mode & S_IFMT) == S_IFREG) /* #define WRITE_BINARY "wb" */ /* #define READ_BINARy "rb" */ #define WRITE_BINARY "w" #define READ_BINARY "r" /*----------------------------------------------------------------------*/ /* MEMORY AND STRING FUNCTIONS */ /*----------------------------------------------------------------------*/ #ifndef NOBSTRING #include #else #include #define index strchr #define rindex strrchr #define bcmp(a,b,n) memcmp ((a),(b),(n)) #define bzero(d,n) memset((d),0,(n)) #define bcopy(s,d,n) memmove((d),(s),(n)) #endif /* NOBSTRING */ #ifdef ultrix #define strucmp(p,q) strcasecmp((p),(q)) #endif /*----------------------------------------------------------------------*/ /* YOUR CUSTOMIZIES */ /*----------------------------------------------------------------------*/ /* These difinitions are changable to you like. */ /* #define ARCHIVENAME_EXTENTION ".LZH" */ /* #define BACKUPNAME_EXTENTION ".BAK" */ /* #define TMP_FILENAME_TEMPLATE "/usr/tmp/lhXXXXXX" */ /* #define MULTIBYTE_CHAR */ /* #define USE_PROF */ #ifndef ARCHIVENAME_EXTENTION #define ARCHIVENAME_EXTENTION ".lzh" #endif #ifndef BACKUPNAME_EXTENTION #define BACKUPNAME_EXTENTION ".bak" #endif #ifndef TMP_FILENAME_TEMPLATE #define TMP_FILENAME_TEMPLATE "/tmp/lhXXXXXX" #endif #define SJC_FIRST_P(c) \ (((unsigned char)(c) >= 0x80) && \ (((unsigned char)(c) < 0xa0) || \ ((unsigned char)(c) >= 0xe0) && \ ((unsigned char)(c) < 0xfd))) #define SJC_SECOND_P(c) \ (((unsigned char)(c) >= 0x40) && \ ((unsigned char)(c) < 0xfd) && \ ((ungigned char)(c) != 0x7f)) #ifdef MULTIBYTE_CHAR #define MULTIBYTE_FIRST_P SJC_FIRST_P #define MULTIBYTE_SECOND_P SJC_SECOND_P #endif /* MULTIBYTE_CHAR */ /*----------------------------------------------------------------------*/ /* OTHER DIFINITIONS */ /*----------------------------------------------------------------------*/ /* Your C-Compiler has no 'void' */ #ifdef NO_VOID #define void #endif #ifndef SEEK_SET #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #endif #define FILENAME_LENGTH 1024 /* non-integral functions */ extern struct tm *localtime (); extern char *getenv (); #ifndef _MINIX #ifndef __STDC__ extern char *malloc (); extern char *realloc (); #endif #endif /* external variables */ extern int errno; #define FALSE 0 #define TRUE 1 typedef int boolean; /*----------------------------------------------------------------------*/ /* LHarc FILE DEFINITIONS */ /*----------------------------------------------------------------------*/ #define METHOD_TYPE_STRAGE 5 #define LZHUFF0_METHOD "-lh0-" #define LZHUFF1_METHOD "-lh1-" #define LZHUFF2_METHOD "-lh2-" #define LZHUFF3_METHOD "-lh3-" #define LZHUFF4_METHOD "-lh4-" #define LZHUFF5_METHOD "-lh5-" #define LARC4_METHOD "-lz4-" #define LARC5_METHOD "-lz5-" #define LZHDIRS_METHOD "-lhd-" #define I_HEADER_SIZE 0 #define I_HEADER_CHECKSUM 1 #define I_METHOD 2 #define I_PACKED_SIZE 7 #define I_ORIGINAL_SIZE 11 #define I_LAST_MODIFIED_STAMP 15 #define I_ATTRIBUTE 19 #define I_HEADER_LEVEL 20 #define I_NAME_LENGTH 21 #define I_NAME 22 #define I_CRC 22 /* + name_length */ #define I_EXTEND_TYPE 24 /* + name_length */ #define I_MINOR_VERSION 25 /* + name_length */ #define I_UNIX_LAST_MODIFIED_STAMP 26 /* + name_length */ #define I_UNIX_MODE 30 /* + name_length */ #define I_UNIX_UID 32 /* + name_length */ #define I_UNIX_GID 34 /* + name_length */ #define I_UNIX_EXTEND_BOTTOM 36 /* + name_length */ #define I_GENERIC_HEADER_BOTTOM I_EXTEND_TYPE #define EXTEND_GENERIC 0 #define EXTEND_UNIX 'U' #define EXTEND_MSDOS 'M' #define EXTEND_MACOS 'm' #define EXTEND_OS9 '9' #define EXTEND_OS2 '2' #define EXTEND_OS68K 'K' #define EXTEND_OS386 '3' /* OS-9000??? */ #define EXTEND_HUMAN 'H' #define EXTEND_CPM 'C' #define EXTEND_FLEX 'F' #define EXTEND_RUNSER 'R' /* this OS type is not official */ #define EXTEND_TOWNSOS 'T' #define EXTEND_XOSK 'X' /*------------------------------*/ #define GENERIC_ATTRIBUTE 0x20 #define GENERIC_DIRECTORY_ATTRIBUTE 0x10 #define HEADER_LEVEL0 0x00 #define HEADER_LEVEL1 0x01 #define HEADER_LEVEL2 0x02 #define CURRENT_UNIX_MINOR_VERSION 0x00 #define DELIM ('/') #define DELIM2 (0xff) #define DELIMSTR "/" typedef struct LzHeader { unsigned char header_size; char method[METHOD_TYPE_STRAGE]; long packed_size; long original_size; long last_modified_stamp; unsigned char attribute; unsigned char header_level; char name[256]; unsigned short crc; boolean has_crc; unsigned char extend_type; unsigned char minor_version; /* extend_type == EXTEND_UNIX and convert from other type. */ time_t unix_last_modified_stamp; unsigned short unix_mode; unsigned short unix_uid; unsigned short unix_gid; } LzHeader; #define OSK_RW_RW_RW 0000033 #define OSK_FILE_REGULAR 0000000 #define OSK_DIRECTORY_PERM 0000200 #define OSK_SHARED_PERM 0000100 #define OSK_OTHER_EXEC_PERM 0000040 #define OSK_OTHER_WRITE_PERM 0000020 #define OSK_OTHER_READ_PERM 0000010 #define OSK_OWNER_EXEC_PERM 0000004 #define OSK_OWNER_WRITE_PERM 0000002 #define OSK_OWNER_READ_PERM 0000001 #define UNIX_FILE_TYPEMASK 0170000 #define UNIX_FILE_REGULAR 0100000 #define UNIX_FILE_DIRECTORY 0040000 #define UNIX_SETUID 0004000 #define UNIX_SETGID 0002000 #define UNIX_STYCKYBIT 0001000 #define UNIX_OWNER_READ_PERM 0000400 #define UNIX_OWNER_WRITE_PERM 0000200 #define UNIX_OWNER_EXEC_PERM 0000100 #define UNIX_GROUP_READ_PERM 0000040 #define UNIX_GROUP_WRITE_PERM 0000020 #define UNIX_GROUP_EXEC_PERM 0000010 #define UNIX_OTHER_READ_PERM 0000004 #define UNIX_OTHER_WRITE_PERM 0000002 #define UNIX_OTHER_EXEC_PERM 0000001 #define UNIX_RW_RW_RW 0000666 #define LZHEADER_STRAGE 4096 #ifdef S_IFLNK #define GETSTAT lstat #else #define GETSTAT stat #endif /* used by qsort() for alphabetic-sort */ #define STRING_COMPARE(a,b) strcmp((a),(b)) struct string_pool { int used; int size; int n; char *buffer; }; /*----------------------------------------------------------------------*/ /* OPTIONS */ /*----------------------------------------------------------------------*/ /* command line options (common options) */ extern boolean quiet; extern boolean text_mode; extern boolean verbose; extern boolean noexec; /* debugging option */ extern boolean force; extern boolean prof; extern boolean delete_after_append; /* list command flags */ extern boolean verbose_listing; /* extract/print command flags */ extern boolean output_to_stdout; /* add/update/delete command flags */ extern boolean new_archive; extern boolean update_if_newer; extern boolean generic_format; /*----------------------------------------------------------------------*/ /* VARIABLES */ /*----------------------------------------------------------------------*/ extern char **cmd_filev; extern int cmd_filec; extern char *archive_name; extern char expanded_archive_name[FILENAME_LENGTH]; extern char temporary_name[FILENAME_LENGTH]; extern char backup_archive_name[FILENAME_LENGTH]; extern char *reading_filename, *writting_filename; extern boolean remove_temporary_at_error; extern boolean recover_archive_when_interrupt; extern boolean remove_extracting_file_when_interrupt; extern int archive_file_mode; extern int archive_file_gid; /*----------------------------------------------------------------------*/ /* Functions */ /*----------------------------------------------------------------------*/ extern void interrupt (); extern void message (); extern void warning (); extern void error (); extern void fatal_error (); extern boolean need_file (); extern int inquire (); extern FILE *xfopen (); extern boolean find_files (); extern void free_files (); extern void init_sp (); extern void add_sp (); extern void finish_sp (); extern void free_sp (); extern void cleaning_files (); extern void build_temporary_name (); extern void build_backup_file_name (); extern void build_standard_archive_name (); extern FILE *open_old_archive (); extern void init_header (); extern boolean get_header (); extern boolean archive_is_msdos_sfx1 (); extern boolean skip_msdos_sfx1_code (); extern void write_header (); extern void write_archive_tail (); extern void copy_old_one (); extern unsigned char *convdelim (); extern long copyfile (); extern void cmd_list (), cmd_extract (), cmd_add (), cmd_delete (); extern boolean ignore_directory; extern boolean compress_method; extern boolean verify_mode; extern char *extract_directory; extern FILE *temporary_fp; r #define bcmp(a,b,n) memcmp ((a),(b),(n)) #define bzero(d,n) memset((d),0,(n)) #define bcopy(s,d,n) memmove((d),(s),(n)) #endif /* NOBSTRING */ #ifdef ultrix #define strucmp(p,q) strcasecmp((p),(q)) #endif /*----------------------------------lha/lharc.man 644 4263 151 15227 5162045665 6545 LHARC(N) LHarc UNIX Users Manual LHARC(N) NAME O LHarc - kA[JCo SYNOPSIS `ョ lharc { key } [ options ] archive_file [ name ... ] DESCRIPTION LHarc AkASYt@CA[JCoB LZHUF @ LZSS @KI Huffman @g kョAA[JCo [BIWi MS-DOS h At@C UNIX LHarc UNIX B archive_file A[JCut@CwAw t@CifBNgjt@CA.lzh t@CtBA TtBbNX\BKA^pA TtBbNX.lzh ]v B.com .exe TbtBNXAMS-DOS LHarc SFX(ゥWJ@\tkt@C) BALHarc UNIX ASFX `ョ t@CBSFX `ョA[JCut@ C/sATbtBbNX.lzh B SFX B key KwB a BA[JCut@Cwt@C name i[B name fBNgATuf BNgi[B x e oBA[JCut@C name wt@ CAA[JCut@Ci[t @CoB l v BA[JCut@Ci[ name w t@CAt@C\ヲB v AoB u XVB name wt@CA[JCut@C i[t@CVAA[JCut@ Ci[i[Bname w AA[JCut@Ci[t @CifBNgjVt@Ci[ B d BA[JCut@C name wt@ CB Printed 9/22/89 September 19, 1989 1 LHARC(N) LHarc UNIX Users Manual LHARC(N) m BA[JCut@C name wt@Ci [At@CBkey option ad wB c VKi[BA[JCut@CejAVKA [JCut@C name wt@C i[B p \ヲBA[JCut@C name wt@ CeWooB { key @\C@\ options wB q }BbZ[W}sB v BbZ[WoB n タsBAタsemFB f IBot@C sAt@CBi[ m R}h d IvVpA sB t eLXg[hBMS-DOS eLXgt@Cs R[hsB g A[JCu [generic] Bl i[fCNgw ipXjBAi [t@CiXg\ヲ jB d A[JCut@CBu R}h gpAA[JCut@CeV i[B FILES t@C *.lzh - A[JCut@Cgq(ftHg) *.bak - obNAbvt@C /tmp/lh* - e|t@C *.com *.exe - MS-DOS SFX t@C SEE ALSO A tar(1), ar(1), compress(1) DISTRIBUTION zz AzzA]AB 1. \ヲB Printed 9/22/89 September 19, 1989 2 LHARC(N) LHarc UNIX Users Manual LHARC(N) 2. zzeA a. zze(\[XR[hAh LgAvO}[)zz KB AヲhLgpB b. LHarc tltzz wB Atltヲ hLgpB c. oCizzB(tl ) 3. VzzB(`) 4. vOgpQ SB 5. メAvOsA `B 6. vOASvOg pBAvO LHarc ALHarc B 7. pALAL FB a. vOCp~B b. pvOgpメsK fzzB c. CXg[igpAvO gBAp メsBAQApメ SCB d. ptlsvOgp ApメAT|[gsB LZHUF @b LZARI @\F A Nifty AALArc メOaF AAv LZHUF @yAMS-DOS LHarc ghAJlBAbZ[W na(MIX ID:k.ishi)AA |[gApX Y (MIX ID:kmori)モB Printed 9/22/89 September 19, 1989 3 ATbtBbNX.lzh B SFX B key KwB a BA[JCut@Cwt@C name i[B name fBNgATuf BNgi[B x e oBA[JCutlha/lharc.n 644 4263 151 13277 5162045671 6227 .\" Copyright (c) 1989 Y.Tagawa .\" This is Freeware .\" .\" @(#)lharc.n 1.00 (Y.Tagawa) 9/22/89 .TH LHARC N "September 22, 1989" "" "LHarc UNIX Users Manual" .SH "NAME O" LHarc \- kA[JCo .SH "SYNOPSIS `ョ" .B lharc { .B key }[ .B options ] archive_file [ name ... ] .SH "DESCRIPTION " .I LHarc AkASYt@CA[JCoB LZHUF @ LZSS @KI Huffman @g kョA A[JCo[B IWi MS-DOS hA t@C UNIX .I "LHarc UNIX" B .PP .I archive_file A[JCut@CwA wt@CifBNgjt@CA .I ".lzh" t@CtB ATtBbNX\B KA^pATtBbNX .I ".lzh" ]vB .I ".com" .I ".exe" TbtBNXAMS-DOS .I LHarc .IR SFX (ゥWJ@\tkt@C) B A .I "LHarc UNIX" ASFX `ョt@CB SFX `ョA[JCut@C/sA TbtBbNX .I ".lzh" B SFX B .PP .I key KwB .TP 8 .B a BA[JCut@Cwt@C .I " name i[B .I " name fBNgATufBNgi[B .TP 8 .B "x e" oB A[JCut@C .I " name wt@CA A[JCut@Ci[t@CoB .TP 8 .B "l v" B A[JCut@Ci[ .I " name wt@CAt@C\ヲB .B " v AoB .TP 8 .B u XVB .I " name wt@CA[JCut@Ci[t@C VAA[JCut@Ci[i[B name wAA[JCut@Ci[t@C ifBNgjVt@Ci[B .TP 8 .B d B A[JCut@C .I " name wt@CB .TP 8 .B m B A[JCut@C .I " name wt@Ci[A t@CB .I key .I option ad wB .TP 8 .B c VKi[B A[JCut@CejA VKA[JCut@C .I " name wt@Ci[B .TP 8 .B p \ヲB A[JCut@C .I " name wt@Ce WooB .PP { .I " key @\C@\ .I " options wB .TP 8 .B q }B bZ[W}sB .TP 8 .B v B bZ[WoB .TP 8 .B n タsB AタsemFB .TP 8 .B f IB ot@CsA t@CB i[ m R}h d IvVpA sB .TP 8 .B t eLXg[hB MS-DOS eLXgt@CsR[h sB .TP 8 .B g A[JCu [generic] B li[fCNgw ipXjBAi[ t@CiXg\ヲj B .TP 8 .B d A[JCut@CB u R}hgpAA[JCut@Ce Vi[B .PP .SH "FILES t@C" .ta \w'*.com *.exe 'u *.lzh - A[JCut@Cgq(ftHg) .br *.bak - obNAbvt@C .br /tmp/lh* - e|t@C .br *.com *.exe - MS-DOS SFX t@C .PP .SH "SEE ALSO A" tar(1), ar(1), compress(1) .SH "DISTRIBUTION zz" .PP AzzA]AB .IP 1. \ヲB .IP 2. zzeA .RS .IP a. zze(\[XR[hAhLgA vO}[)zzK BAヲhL gpB .IP b. LHarc tltzz wBA tltヲhLgp B .IP c. oCizzB(tl) .RE .IP 3. VzzB(`) .IP 4. vOgpQS B .IP 5. メAvOsA` B .IP 6. vOASvOg pBAvO LHarc ALHarc B .IP 7. pALAL FB .RS .IP a. vOCp~B .IP b. pvOgpメsKf zzB .IP c. CXg[igpAvOg BApメsB AQApメSCB .IP d. ptlsvOgpA pメAT|[gsB .RE .PP .SH "" LZHUF @b LZARI @\FA Nifty AALArc メOaFAA v LZHUF @yAMS-DOS LHarc gh AJlBAbZ[Wn a(MIX ID:k.ishi)AA|[g ApXY (MIX ID:kmori)モB ; long last_modified_stamp; unsigned char attribute; unsigned char header_level; char name[256]; unsigned short crc; boolean has_crc; unsigned char extend_type; unsigned char minor_version; /* extend_type == EXTEND_UNIX and convert from other type. */ time_t unix_last_modified_stamp; unsilha/lhdir.c 644 4263 151 3733 5162045674 6204 /*----------------------------------------------------------------------*/ /* Directory access routine for LHarc UNIX */ /* This is part of LHarc UNIX Archiver Driver */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* Emulate opendir(),readdir(),closedir() function for LHarc */ /* */ /* V0.00 Original 1988.05.31 Y.Tagawa */ /* V0.03 Release #3 for LHarc UNIX 1988.07.02 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /*----------------------------------------------------------------------*/ #include /* Where is O_RDONLY ? (^_^) */ #include #ifndef O_RDONLY #include #endif #define direct old_direct #include #undef direct #ifndef DIRSIZ /* Warning : Are you sure? (normally defined in */ #define DIRSIZ 14 #endif #include "lhdir.h" DIR * opendir (name) char *name; { register DIR *dirp; register int fd; if ((fd = open (name, O_RDONLY)) >= 0) { if ((dirp = (DIR*)malloc (sizeof (DIR))) != (DIR*)0) { dirp->dd_fd = fd; dirp->dd_loc = 0; dirp->dd_size = 0; return dirp; } close (fd); } return (DIR*)0; } struct direct * readdir (dirp) register DIR *dirp; { static struct direct lhdir; register struct old_direct *dp; do { if (dirp->dd_loc >= dirp->dd_size) { dirp->dd_loc = 0; if ((dirp->dd_size = read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) return (struct direct *)0; } dp = (struct old_direct *)(dirp->dd_buf + dirp->dd_loc); if (dirp->dd_loc + sizeof (struct old_direct) > dirp->dd_size) return (struct direct *)0; dirp->dd_loc += sizeof (struct old_direct); } while (dp->d_ino == 0) ; /* construct new format */ lhdir.d_ino = dp->d_ino; strncpy (lhdir.d_name, dp->d_name, DIRSIZ); lhdir.d_name[DIRSIZ] = '\0'; lhdir.d_namlen = strlen (lhdir.d_name); return &lhdir; } closedir (dirp) DIR *dirp; { close (dirp->dd_fd); free (dirp); } i[B name wlha/lhdir.h 644 4263 151 1566 5162045676 6215 /*----------------------------------------------------------------------*/ /* Directory access routine for LHarc UNIX */ /* This is part of LHarc UNIX Archiver Driver */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* Emulate opendir(),readdir(),closedir() function for LHarc */ /* */ /* V0.00 Original 1988.05.31 Y.Tagawa */ /* V0.03 Release #3 for LHarc UNIX 1988.07.02 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /*----------------------------------------------------------------------*/ /* DIRBLKSIZ must be sizeof (SYSTEM struct direct) * N !!! */ #ifndef DIRBLKSIZ #define DIRBLKSIZ 512 #endif struct direct { int d_ino; int d_namlen; char d_name[256]; }; typedef struct { int dd_fd; int dd_loc; int dd_size; char dd_buf[DIRBLKSIZ]; } DIR; extern DIR *opendir (); extern struct direct *readdir (); extern closedir (); me) char *name; { register DIR *dirp; register int fd; if ((fd = open (name, O_RDONLY)) >= 0) { if ((dirp = (DIR*)malha/lhext.c 644 4263 151 15433 5162045702 6236 /*----------------------------------------------------------------------*/ /* LHarc Extract Command */ /* This is part of LHarc UNIX Archiver Driver */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V0.00 Original 1988.05.23 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V0.03 LHa for UNIX 1991.12.17 M.Oki */ /*----------------------------------------------------------------------*/ #include "lharc.h" extern int decode_lzhuf (); static boolean inquire_extract (name) char *name; { struct stat stbuf; if (stat (name, &stbuf) >= 0) { if (!is_regularfile (&stbuf)) { error ("Already exist (not a file)", name); return FALSE; } if (noexec) { printf ("EXTRACT %s but file is exist.\n", name); return FALSE; } else if (!force) { if (!isatty(0)) return FALSE; switch (inquire ("OverWrite ?(Yes/No/All)", name, "YyNnAa")) { case 0: case 1: /* Y/y */ break; case 2: case 3: /* N/n */ return FALSE; case 4: case 5: /* A/a */ force = TRUE; break; } } } if (noexec) printf ("EXTRACT %s\n", name); return TRUE; } static boolean make_parent_path (name) char *name; { char path[FILENAME_LENGTH]; struct stat stbuf; register char *p; /* make parent directory name into PATH for recursive call */ strcpy (path, name); for (p = path + strlen (path); p > path; p--) if (p[-1] == '/') { *--p = '\0'; break; } if (p == path) { message ("Why?", "ROOT"); return FALSE; /* no more parent. */ } if (stat (path, &stbuf) >= 0) { if (is_directory (&stbuf)) return TRUE; error ("Not a directory", path); return FALSE; } errno = 0; if (verbose) printf ("Making directory \"%s\".", path); if (mkdir (path, 0777) >= 0)/* try */ return TRUE; /* successful done. */ errno = 0; if (!make_parent_path (path)) return FALSE; if (mkdir (path, 0777) < 0) /* try again */ { message ("Cannot make directory", path); return FALSE; } return TRUE; } static FILE * open_with_make_path (name) char *name; { FILE *fp; if ((fp = fopen (name, WRITE_BINARY)) == NULL) { errno = 0; if (!make_parent_path (name) || (fp = fopen (name, WRITE_BINARY)) == NULL) error ("Cannot extract", name); errno = 0; } return fp; } static void adjust_info (name,hdr) char *name; LzHeader *hdr; { time_t utimebuf[2]; /* adjust file stamp */ utimebuf[0] = utimebuf[1] = hdr->unix_last_modified_stamp; utime (name, utimebuf); if (hdr->extend_type == EXTEND_UNIX || hdr->extend_type == EXTEND_OS68K || hdr->extend_type == EXTEND_XOSK) { #ifdef NOT_COMPATIBLE_MODE Please need your modification in this space. #else chmod (name, hdr->unix_mode); #endif if(!getuid()) chown (name, hdr->unix_uid, hdr->unix_gid); errno = 0; } } static char *methods[10] = { "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-", "-lh5-", "-lzs-", "-lz5-", "-lz4-", NULL }; static void extract_one (afp, hdr) FILE *afp; /* archive file */ LzHeader *hdr; { FILE *fp; /* output file */ char name[257]; int crc; int method; boolean save_quiet, save_verbose; char *q = hdr->name , c; if ( ignore_directory && rindex(hdr->name,'/') ) { q = (char *)rindex(hdr->name,'/') + 1; } else { if ( *q=='/' ) { q++; /* * if OSK then strip device name */ if (hdr->extend_type == EXTEND_OS68K || hdr->extend_type == EXTEND_XOSK ) { do c=(*q++); while ( c && c!='/' ); if ( !c || !*q ) q = "."; /* if device name only */ } } } if (extract_directory) sprintf (name, "%s/%s", extract_directory, q); else strcpy (name, q); if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR) { for (method = 0; ; method++) { if (methods[method] == NULL) { error ("Unknown method skiped ...", name); return; } if (bcmp (hdr->method, methods[method], 5) == 0) break; } reading_filename = archive_name; writting_filename = name; if (output_to_stdout || verify_mode) { if (noexec) { printf ("%s %s\n", verify_mode ? "VERIFY" : "EXTRACT",name); if (afp == stdin) { int i = hdr->packed_size; while(i--) fgetc(afp); } return; } save_quiet = quiet; save_verbose = verbose; if (!quiet && output_to_stdout) { printf ("::::::::\n%s\n::::::::\n", name); quiet = TRUE; verbose = FALSE; } else if (verify_mode) { quiet = FALSE; verbose = TRUE; } crc = decode_lzhuf (afp, stdout, hdr->original_size, hdr->packed_size, name, method); quiet = save_quiet; verbose = save_verbose; } else { if (!inquire_extract (name)) return; if (noexec) { if (afp == stdin) { int i = hdr->packed_size; while(i--) fgetc(afp); } return; } signal (SIGINT, interrupt); signal (SIGHUP, interrupt); unlink (name); errno = 0; remove_extracting_file_when_interrupt = TRUE; if ((fp = open_with_make_path (name)) != NULL) { crc = decode_lzhuf (afp, fp, hdr->original_size, hdr->packed_size, name, method); fclose (fp); } remove_extracting_file_when_interrupt = FALSE; signal (SIGINT, SIG_DFL); signal (SIGHUP, SIG_DFL); if (!fp) return; } errno = 0; if (hdr->has_crc && crc != hdr->crc) error ("CRC error", name); } else if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY) { if (!ignore_directory && !verify_mode) { if (noexec) { printf ("EXTRACT %s (directory)\n", name); return; } /* NAME has trailing SLASH '/', (^_^) */ if (!output_to_stdout && !make_parent_path (name)) return; } } else { error ("Unknown information", name); } if (!output_to_stdout) adjust_info (name,hdr); } /*----------------------------------------------------------------------*/ /* EXTRACT COMMAND MAIN */ /*----------------------------------------------------------------------*/ void cmd_extract () { LzHeader hdr; long pos; FILE *afp; /* open archive file */ if ((afp = open_old_archive ()) == NULL) fatal_error (archive_name); if (archive_is_msdos_sfx1 (archive_name)) skip_msdos_sfx1_code (afp); /* extract each files */ while (get_header (afp, &hdr)) { if (need_file (hdr.name)) { pos = ftell (afp); extract_one (afp, &hdr); fseek (afp, pos + hdr.packed_size, SEEK_SET); } else { if (afp != stdin) fseek (afp, hdr.packed_size, SEEK_CUR); else { int i = hdr.packed_size; while(i--) fgetc(afp); } } } /* close archive file */ fclose (afp); return; } && rindex(hdr->name,'/') ) { q = (char *)rindex(hdr->name,'/') + 1; } else { if ( *q=='/' ) { q++; /* * if OSK then strip device name */ if (hdr->extend_type == EXTEND_OS68K || lha/lhlist.c 644 4263 151 16125 5162045710 6407 /*----------------------------------------------------------------------*/ /* LHarc List Command */ /* This is part of LHarc UNIX Archiver Driver */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V0.00 Original 1988.05.23 Y.Tagawa */ /* V1.00 Fixed 1989.09.22 Y.Tagawa */ /* V1.01 Bug Fix for month name 1989.12.25 Y.Tagawa */ /*----------------------------------------------------------------------*/ #include "lharc.h" static long packed_size_total; static long original_size_total; static int list_files; /*----------------------------------------------------------------------*/ /* Print Stuff */ /*----------------------------------------------------------------------*/ /* need 14 or 22 (when verbose_listing is TRUE) column spaces */ static void print_size (packed_size, original_size) long packed_size, original_size; { if (verbose_listing) printf ("%7d ", packed_size); printf ("%7d ", original_size); if (original_size == 0L) printf ("******"); else printf ("%3d.%1d%%", (int)((packed_size * 100L) / original_size), (int)((packed_size * 1000L) / original_size) % 10); } /* need 12 or 17 (when verbose_listing is TRUE) column spaces */ static void print_stamp (t) time_t t; { static boolean got_now = FALSE; static time_t now; static unsigned int threshold; static char t_month[12*3+1] = "JanFebMarAprMayJunJulAugSepOctNovDec"; struct tm *p; if (t == 0) { printf (" "); /* 12 spaces */ return; } if (!got_now) { now = time ((time_t*)0); p = localtime (&now); threshold = p->tm_year * 12 + p->tm_mon - 6; got_now = TRUE; } p = localtime (&t); if (p->tm_year * 12 + p->tm_mon > threshold) printf ("%.3s %2d %02d:%02d", &t_month[p->tm_mon * 3], p->tm_mday, p->tm_hour, p->tm_min); else printf ("%.3s %2d %04d", &t_month[p->tm_mon * 3], p->tm_mday, p->tm_year + 1900); } static void print_bar () { char *p, *q; /* 17+1+(0 or 7+1)+7+1+6+1+(0 or 1+4)+(12 or 17)+1+20 */ /* 12345678901234567_ 1234567_123456 _123456789012 1234 */ if (verbose_listing) { p = "- ------ ---------- "; q = " -------------"; } else { p = " "; q = " --------------------"; } if (verbose) q = ""; printf ("----------------- ------- ------%s------------%s\n", p, q); } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ static void list_header () { char *p, *q; if (verbose_listing) { p = "PACKED SIZE RATIO CRC "; q = " NAME"; } else { p = " SIZE RATIO"; q = " NAME"; } if (verbose) q = ""; printf (" PERMSSN UID GID %s STAMP%s\n", p, q); #if 0 printf (" PERMSSN UID GID %s SIZE RATIO%s %s STAMP%s%s\n", verbose_listing ? " PACKED " : "", /* 8,0 */ verbose_listing ? " CRC" : "", /* 5,0 */ verbose_listing ? " " : "", /* 2,0 */ verbose_listing ? " " : " ", /* 6,3 */ verbose ? "" : " NAME"); #endif print_bar (); } static void list_one (hdr) register LzHeader *hdr; { register int mode; register char *p; char method[6]; if (verbose) printf ("%s\n", hdr->name); strncpy(method,hdr->method,5); method[5]='\0'; switch ( mode=hdr->extend_type ) { case EXTEND_UNIX: mode=hdr->unix_mode; printf ("%c%c%c%c%c%c%c%c%c%4d/%-4d", ((mode & UNIX_OWNER_READ_PERM) ? 'r' : '-'), ((mode & UNIX_OWNER_WRITE_PERM) ? 'w' : '-'), ((mode & UNIX_OWNER_EXEC_PERM) ? 'x' : '-'), ((mode & UNIX_GROUP_READ_PERM) ? 'r' : '-'), ((mode & UNIX_GROUP_WRITE_PERM) ? 'w' : '-'), ((mode & UNIX_GROUP_EXEC_PERM) ? 'x' : '-'), ((mode & UNIX_OTHER_READ_PERM) ? 'r' : '-'), ((mode & UNIX_OTHER_WRITE_PERM) ? 'w' : '-'), ((mode & UNIX_OTHER_EXEC_PERM) ? 'x' : '-'), hdr->unix_uid, hdr->unix_gid); break; case EXTEND_OS68K: /**/ case EXTEND_XOSK: /**/ mode=hdr->unix_mode; printf ("%c%c%c%c%c%c%c%c %4d/%-4d", ((mode & OSK_DIRECTORY_PERM) ? 'd' : '-'), ((mode & OSK_SHARED_PERM) ? 's' : '-'), ((mode & OSK_OTHER_EXEC_PERM) ? 'e' : '-'), ((mode & OSK_OTHER_WRITE_PERM)? 'w' : '-'), ((mode & OSK_OTHER_READ_PERM) ? 'r' : '-'), ((mode & OSK_OWNER_EXEC_PERM) ? 'e' : '-'), ((mode & OSK_OWNER_WRITE_PERM)? 'w' : '-'), ((mode & OSK_OWNER_READ_PERM) ? 'r' : '-'), hdr->unix_uid, hdr->unix_gid); break; default: switch (hdr->extend_type) { /* max 18 characters */ case EXTEND_GENERIC:p = "[generic]"; break; case EXTEND_CPM: p = "[CP/M]"; break; case EXTEND_FLEX: p = "[FLEX]"; break; case EXTEND_OS9: p = "[OS-9]"; break; case EXTEND_OS68K: p = "[OS-9/68K]"; break; case EXTEND_MSDOS: p = "[MS-DOS]"; break; case EXTEND_MACOS: p = "[Mac OS]"; break; case EXTEND_OS2: p = "[OS/2]"; break; case EXTEND_HUMAN: p = "[Human68K]"; break; case EXTEND_OS386: p = "[OS-386]"; break; case EXTEND_RUNSER: p = "[Runser]"; break; #ifdef EXTEND_TOWNSOS /* This ID isn't fixed */ case EXTEND_TOWNSOS: p = "[TownsOS]"; break; #endif /* Ouch! Please customize it's ID. */ default: p = "[unknown]"; break; } printf ("%-18.18s", p); break; } print_size (hdr->packed_size, hdr->original_size); if (verbose_listing) if (hdr->has_crc) printf (" %s %04x", method,hdr->crc); else printf (" %s ****",method); printf (" "); print_stamp (hdr->unix_last_modified_stamp); if (!verbose) printf (" %s", hdr->name); printf ("\n"); } static void list_tailer () { struct stat stbuf; print_bar (); printf (" Total %4d file%c ", list_files, (list_files == 1) ? ' ' : 's'); print_size (packed_size_total, original_size_total); printf (" "); if (verbose_listing) printf (" "); if (stat (archive_name, &stbuf) < 0) print_stamp ((time_t)0); else print_stamp (stbuf.st_mtime); printf ("\n"); } /*----------------------------------------------------------------------*/ /* LIST COMMAND MAIN */ /*----------------------------------------------------------------------*/ void cmd_list () { FILE *afp; LzHeader hdr; int i; /* initialize total count */ packed_size_total = 0L; original_size_total = 0L; list_files = 0; /* open archive file */ if ((afp = open_old_archive ()) == NULL) fatal_error (archive_name); if (archive_is_msdos_sfx1 (archive_name)) skip_msdos_sfx1_code (afp); /* print header message */ if (!quiet) list_header (); /* print each file information */ while (get_header (afp, &hdr)) { if (need_file (hdr.name)) { list_one (&hdr); list_files ++; packed_size_total += hdr.packed_size; original_size_total += hdr.original_size; } if (afp != stdin) fseek (afp, hdr.packed_size, SEEK_CUR); else { i = hdr.packed_size; while(i--) fgetc(afp); } } /* close archive file */ fclose (afp); /* print tailer message */ if (!quiet) list_tailer (); return; } ose ? "" : " NAME"); #endif print_bar (); } static void list_one (hdr) register LzHeader *hdr; { register int mode; register char *p; char method[6]; if (verbose) printf ("%s\n", hdr->name); strncpy(method,hdr->method,5); method[5]='\0'; switch ( mode=hdr->extend_type ) { case EXTEND_UNIX: mode=hdr->unix_mode; printf ("%c%c%c%c%c%c%c%c%c%4d/%-4d", ((mode & UNIX_OWNER_READ_lha/lhx.doc 644 4263 151 40646 5162045717 6242 ------------------------------------------------------------------------ kgbdl Ver.C2.01 1990/07/27 ------------------------------------------------------------------------ SDI00506 g@h pcs02846 Yoshi ------------------------------------------------------------------------ @ALHxiLH bjAPB @o[WANIFTY-Serve flabo JB]] AkEASYAnrA ]Bt[\tgEFAy ]AT[rXI]fB @dlAメvタdl\ BA{vOgpAQ Aog B @-o IvVt LHarc \A JALHarc KmF JBVk@AJB @AIIdlAB 1. gp@ A. Iョ @LHx [-