1231200Smm/*-
2299529Smm * Copyright (c) 2008-2014 Michihiro NAKAJIMA
3231200Smm * All rights reserved.
4231200Smm *
5231200Smm * Redistribution and use in source and binary forms, with or without
6231200Smm * modification, are permitted provided that the following conditions
7231200Smm * are met:
8231200Smm * 1. Redistributions of source code must retain the above copyright
9231200Smm *    notice, this list of conditions and the following disclaimer.
10231200Smm * 2. Redistributions in binary form must reproduce the above copyright
11231200Smm *    notice, this list of conditions and the following disclaimer in the
12231200Smm *    documentation and/or other materials provided with the distribution.
13231200Smm *
14231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24231200Smm */
25231200Smm
26231200Smm#include "archive_platform.h"
27231200Smm
28231200Smm#ifdef HAVE_ERRNO_H
29231200Smm#include <errno.h>
30231200Smm#endif
31231200Smm#ifdef HAVE_LIMITS_H
32231200Smm#include <limits.h>
33231200Smm#endif
34231200Smm#ifdef HAVE_STDLIB_H
35231200Smm#include <stdlib.h>
36231200Smm#endif
37231200Smm#ifdef HAVE_STRING_H
38231200Smm#include <string.h>
39231200Smm#endif
40231200Smm
41231200Smm#include "archive.h"
42231200Smm#include "archive_entry.h"
43231200Smm#include "archive_entry_locale.h"
44231200Smm#include "archive_private.h"
45231200Smm#include "archive_read_private.h"
46231200Smm#include "archive_endian.h"
47231200Smm
48231200Smm
49231200Smm#define MAXMATCH		256	/* Maximum match length. */
50231200Smm#define MINMATCH		3	/* Minimum match length. */
51231200Smm/*
52231200Smm * Literal table format:
53231200Smm * +0              +256                      +510
54231200Smm * +---------------+-------------------------+
55231200Smm * | literal code  |       match length      |
56231200Smm * |   0 ... 255   |  MINMATCH ... MAXMATCH  |
57231200Smm * +---------------+-------------------------+
58231200Smm *  <---          LT_BITLEN_SIZE         --->
59231200Smm */
60231200Smm/* Literal table size. */
61231200Smm#define LT_BITLEN_SIZE		(UCHAR_MAX + 1 + MAXMATCH - MINMATCH + 1)
62231200Smm/* Position table size.
63231200Smm * Note: this used for both position table and pre literal table.*/
64231200Smm#define PT_BITLEN_SIZE		(3 + 16)
65231200Smm
66231200Smmstruct lzh_dec {
67231200Smm	/* Decoding status. */
68231200Smm	int     		 state;
69231200Smm
70231200Smm	/*
71231200Smm	 * Window to see last 8Ki(lh5),32Ki(lh6),64Ki(lh7) bytes of decoded
72231200Smm	 * data.
73231200Smm	 */
74231200Smm	int			 w_size;
75231200Smm	int			 w_mask;
76231200Smm	/* Window buffer, which is a loop buffer. */
77231200Smm	unsigned char		*w_buff;
78231200Smm	/* The insert position to the window. */
79231200Smm	int			 w_pos;
80231200Smm	/* The position where we can copy decoded code from the window. */
81231200Smm	int     		 copy_pos;
82231200Smm	/* The length how many bytes we can copy decoded code from
83231200Smm	 * the window. */
84231200Smm	int     		 copy_len;
85231200Smm
86231200Smm	/*
87231200Smm	 * Bit stream reader.
88231200Smm	 */
89231200Smm	struct lzh_br {
90231200Smm#define CACHE_TYPE		uint64_t
91231200Smm#define CACHE_BITS		(8 * sizeof(CACHE_TYPE))
92231200Smm	 	/* Cache buffer. */
93231200Smm		CACHE_TYPE	 cache_buffer;
94231200Smm		/* Indicates how many bits avail in cache_buffer. */
95231200Smm		int		 cache_avail;
96231200Smm	} br;
97231200Smm
98231200Smm	/*
99231200Smm	 * Huffman coding.
100231200Smm	 */
101231200Smm	struct huffman {
102231200Smm		int		 len_size;
103231200Smm		int		 len_avail;
104231200Smm		int		 len_bits;
105231200Smm		int		 freq[17];
106231200Smm		unsigned char	*bitlen;
107231200Smm
108231200Smm		/*
109231200Smm		 * Use a index table. It's faster than searching a huffman
110231200Smm		 * coding tree, which is a binary tree. But a use of a large
111231200Smm		 * index table causes L1 cache read miss many times.
112231200Smm		 */
113231200Smm#define HTBL_BITS	10
114231200Smm		int		 max_bits;
115231200Smm		int		 shift_bits;
116231200Smm		int		 tbl_bits;
117231200Smm		int		 tree_used;
118231200Smm		int		 tree_avail;
119231200Smm		/* Direct access table. */
120231200Smm		uint16_t	*tbl;
121231200Smm		/* Binary tree table for extra bits over the direct access. */
122231200Smm		struct htree_t {
123231200Smm			uint16_t left;
124231200Smm			uint16_t right;
125231200Smm		}		*tree;
126231200Smm	}			 lt, pt;
127231200Smm
128231200Smm	int			 blocks_avail;
129231200Smm	int			 pos_pt_len_size;
130231200Smm	int			 pos_pt_len_bits;
131231200Smm	int			 literal_pt_len_size;
132231200Smm	int			 literal_pt_len_bits;
133231200Smm	int			 reading_position;
134231200Smm	int			 loop;
135231200Smm	int			 error;
136231200Smm};
137231200Smm
138231200Smmstruct lzh_stream {
139231200Smm	const unsigned char	*next_in;
140299529Smm	int			 avail_in;
141231200Smm	int64_t			 total_in;
142299529Smm	const unsigned char	*ref_ptr;
143299529Smm	int			 avail_out;
144231200Smm	int64_t			 total_out;
145231200Smm	struct lzh_dec		*ds;
146231200Smm};
147231200Smm
148231200Smmstruct lha {
149231200Smm	/* entry_bytes_remaining is the number of bytes we expect.	    */
150231200Smm	int64_t                  entry_offset;
151231200Smm	int64_t                  entry_bytes_remaining;
152231200Smm	int64_t			 entry_unconsumed;
153231200Smm	uint16_t		 entry_crc_calculated;
154231200Smm
155231200Smm	size_t			 header_size;	/* header size		    */
156231200Smm	unsigned char		 level;		/* header level		    */
157231200Smm	char			 method[3];	/* compress type	    */
158231200Smm	int64_t			 compsize;	/* compressed data size	    */
159231200Smm	int64_t			 origsize;	/* original file size	    */
160231200Smm	int			 setflag;
161231200Smm#define BIRTHTIME_IS_SET	1
162231200Smm#define ATIME_IS_SET		2
163231200Smm#define UNIX_MODE_IS_SET	4
164231200Smm#define CRC_IS_SET		8
165231200Smm	time_t			 birthtime;
166231200Smm	long			 birthtime_tv_nsec;
167231200Smm	time_t			 mtime;
168231200Smm	long			 mtime_tv_nsec;
169231200Smm	time_t			 atime;
170231200Smm	long			 atime_tv_nsec;
171231200Smm	mode_t			 mode;
172231200Smm	int64_t			 uid;
173231200Smm	int64_t			 gid;
174231200Smm	struct archive_string 	 uname;
175231200Smm	struct archive_string 	 gname;
176231200Smm	uint16_t		 header_crc;
177231200Smm	uint16_t		 crc;
178231200Smm	struct archive_string_conv *sconv;
179231200Smm	struct archive_string_conv *opt_sconv;
180231200Smm
181231200Smm	struct archive_string 	 dirname;
182231200Smm	struct archive_string 	 filename;
183231200Smm	struct archive_wstring	 ws;
184231200Smm
185231200Smm	unsigned char		 dos_attr;
186231200Smm
187231200Smm	/* Flag to mark progress that an archive was read their first header.*/
188231200Smm	char			 found_first_header;
189231200Smm	/* Flag to mark that indicates an empty directory. */
190231200Smm	char			 directory;
191231200Smm
192231200Smm	/* Flags to mark progress of decompression. */
193231200Smm	char			 decompress_init;
194231200Smm	char			 end_of_entry;
195231200Smm	char			 end_of_entry_cleanup;
196231200Smm	char			 entry_is_compressed;
197231200Smm
198231200Smm	char			 format_name[64];
199231200Smm
200231200Smm	struct lzh_stream	 strm;
201231200Smm};
202231200Smm
203231200Smm/*
204231200Smm * LHA header common member offset.
205231200Smm */
206231200Smm#define H_METHOD_OFFSET	2	/* Compress type. */
207231200Smm#define H_ATTR_OFFSET	19	/* DOS attribute. */
208231200Smm#define H_LEVEL_OFFSET	20	/* Header Level.  */
209231200Smm#define H_SIZE		22	/* Minimum header size. */
210231200Smm
211231200Smmstatic int      archive_read_format_lha_bid(struct archive_read *, int);
212231200Smmstatic int      archive_read_format_lha_options(struct archive_read *,
213231200Smm		    const char *, const char *);
214231200Smmstatic int	archive_read_format_lha_read_header(struct archive_read *,
215231200Smm		    struct archive_entry *);
216231200Smmstatic int	archive_read_format_lha_read_data(struct archive_read *,
217231200Smm		    const void **, size_t *, int64_t *);
218231200Smmstatic int	archive_read_format_lha_read_data_skip(struct archive_read *);
219231200Smmstatic int	archive_read_format_lha_cleanup(struct archive_read *);
220231200Smm
221231200Smmstatic void	lha_replace_path_separator(struct lha *,
222231200Smm		    struct archive_entry *);
223231200Smmstatic int	lha_read_file_header_0(struct archive_read *, struct lha *);
224231200Smmstatic int	lha_read_file_header_1(struct archive_read *, struct lha *);
225231200Smmstatic int	lha_read_file_header_2(struct archive_read *, struct lha *);
226231200Smmstatic int	lha_read_file_header_3(struct archive_read *, struct lha *);
227231200Smmstatic int	lha_read_file_extended_header(struct archive_read *,
228231200Smm		    struct lha *, uint16_t *, int, size_t, size_t *);
229231200Smmstatic size_t	lha_check_header_format(const void *);
230231200Smmstatic int	lha_skip_sfx(struct archive_read *);
231231200Smmstatic time_t	lha_dos_time(const unsigned char *);
232231200Smmstatic time_t	lha_win_time(uint64_t, long *);
233231200Smmstatic unsigned char	lha_calcsum(unsigned char, const void *,
234248616Smm		    int, size_t);
235231200Smmstatic int	lha_parse_linkname(struct archive_string *,
236231200Smm		    struct archive_string *);
237231200Smmstatic int	lha_read_data_none(struct archive_read *, const void **,
238231200Smm		    size_t *, int64_t *);
239231200Smmstatic int	lha_read_data_lzh(struct archive_read *, const void **,
240231200Smm		    size_t *, int64_t *);
241299529Smmstatic void	lha_crc16_init(void);
242231200Smmstatic uint16_t lha_crc16(uint16_t, const void *, size_t);
243231200Smmstatic int	lzh_decode_init(struct lzh_stream *, const char *);
244231200Smmstatic void	lzh_decode_free(struct lzh_stream *);
245231200Smmstatic int	lzh_decode(struct lzh_stream *, int);
246231200Smmstatic int	lzh_br_fillup(struct lzh_stream *, struct lzh_br *);
247231200Smmstatic int	lzh_huffman_init(struct huffman *, size_t, int);
248231200Smmstatic void	lzh_huffman_free(struct huffman *);
249231200Smmstatic int	lzh_read_pt_bitlen(struct lzh_stream *, int start, int end);
250231200Smmstatic int	lzh_make_fake_table(struct huffman *, uint16_t);
251231200Smmstatic int	lzh_make_huffman_table(struct huffman *);
252232153Smmstatic inline int lzh_decode_huffman(struct huffman *, unsigned);
253231200Smmstatic int	lzh_decode_huffman_tree(struct huffman *, unsigned, int);
254231200Smm
255231200Smm
256231200Smmint
257231200Smmarchive_read_support_format_lha(struct archive *_a)
258231200Smm{
259231200Smm	struct archive_read *a = (struct archive_read *)_a;
260231200Smm	struct lha *lha;
261231200Smm	int r;
262231200Smm
263231200Smm	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
264231200Smm	    ARCHIVE_STATE_NEW, "archive_read_support_format_lha");
265231200Smm
266231200Smm	lha = (struct lha *)calloc(1, sizeof(*lha));
267231200Smm	if (lha == NULL) {
268231200Smm		archive_set_error(&a->archive, ENOMEM,
269231200Smm		    "Can't allocate lha data");
270231200Smm		return (ARCHIVE_FATAL);
271231200Smm	}
272231200Smm	archive_string_init(&lha->ws);
273231200Smm
274231200Smm	r = __archive_read_register_format(a,
275231200Smm	    lha,
276231200Smm	    "lha",
277231200Smm	    archive_read_format_lha_bid,
278231200Smm	    archive_read_format_lha_options,
279231200Smm	    archive_read_format_lha_read_header,
280231200Smm	    archive_read_format_lha_read_data,
281231200Smm	    archive_read_format_lha_read_data_skip,
282248616Smm	    NULL,
283299529Smm	    archive_read_format_lha_cleanup,
284299529Smm	    NULL,
285299529Smm	    NULL);
286231200Smm
287231200Smm	if (r != ARCHIVE_OK)
288231200Smm		free(lha);
289231200Smm	return (ARCHIVE_OK);
290231200Smm}
291231200Smm
292231200Smmstatic size_t
293231200Smmlha_check_header_format(const void *h)
294231200Smm{
295231200Smm	const unsigned char *p = h;
296231200Smm	size_t next_skip_bytes;
297231200Smm
298231200Smm	switch (p[H_METHOD_OFFSET+3]) {
299231200Smm	/*
300231200Smm	 * "-lh0-" ... "-lh7-" "-lhd-"
301231200Smm	 * "-lzs-" "-lz5-"
302231200Smm	 */
303231200Smm	case '0': case '1': case '2': case '3':
304231200Smm	case '4': case '5': case '6': case '7':
305231200Smm	case 'd':
306231200Smm	case 's':
307231200Smm		next_skip_bytes = 4;
308231200Smm
309231200Smm		/* b0 == 0 means the end of an LHa archive file.	*/
310231200Smm		if (p[0] == 0)
311231200Smm			break;
312231200Smm		if (p[H_METHOD_OFFSET] != '-' || p[H_METHOD_OFFSET+1] != 'l'
313231200Smm		    ||  p[H_METHOD_OFFSET+4] != '-')
314231200Smm			break;
315231200Smm
316231200Smm		if (p[H_METHOD_OFFSET+2] == 'h') {
317231200Smm			/* "-lh?-" */
318231200Smm			if (p[H_METHOD_OFFSET+3] == 's')
319231200Smm				break;
320231200Smm			if (p[H_LEVEL_OFFSET] == 0)
321231200Smm				return (0);
322231200Smm			if (p[H_LEVEL_OFFSET] <= 3 && p[H_ATTR_OFFSET] == 0x20)
323231200Smm				return (0);
324231200Smm		}
325231200Smm		if (p[H_METHOD_OFFSET+2] == 'z') {
326231200Smm			/* LArc extensions: -lzs-,-lz4- and -lz5- */
327231200Smm			if (p[H_LEVEL_OFFSET] != 0)
328231200Smm				break;
329231200Smm			if (p[H_METHOD_OFFSET+3] == 's'
330231200Smm			    || p[H_METHOD_OFFSET+3] == '4'
331231200Smm			    || p[H_METHOD_OFFSET+3] == '5')
332231200Smm				return (0);
333231200Smm		}
334231200Smm		break;
335231200Smm	case 'h': next_skip_bytes = 1; break;
336231200Smm	case 'z': next_skip_bytes = 1; break;
337231200Smm	case 'l': next_skip_bytes = 2; break;
338231200Smm	case '-': next_skip_bytes = 3; break;
339231200Smm	default : next_skip_bytes = 4; break;
340231200Smm	}
341231200Smm
342231200Smm	return (next_skip_bytes);
343231200Smm}
344231200Smm
345231200Smmstatic int
346231200Smmarchive_read_format_lha_bid(struct archive_read *a, int best_bid)
347231200Smm{
348231200Smm	const char *p;
349231200Smm	const void *buff;
350231200Smm	ssize_t bytes_avail, offset, window;
351231200Smm	size_t next;
352231200Smm
353231200Smm	/* If there's already a better bid than we can ever
354231200Smm	   make, don't bother testing. */
355231200Smm	if (best_bid > 30)
356231200Smm		return (-1);
357231200Smm
358231200Smm	if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL)
359231200Smm		return (-1);
360231200Smm
361231200Smm	if (lha_check_header_format(p) == 0)
362231200Smm		return (30);
363231200Smm
364231200Smm	if (p[0] == 'M' && p[1] == 'Z') {
365231200Smm		/* PE file */
366231200Smm		offset = 0;
367231200Smm		window = 4096;
368231200Smm		while (offset < (1024 * 20)) {
369231200Smm			buff = __archive_read_ahead(a, offset + window,
370231200Smm			    &bytes_avail);
371231200Smm			if (buff == NULL) {
372231200Smm				/* Remaining bytes are less than window. */
373231200Smm				window >>= 1;
374231200Smm				if (window < (H_SIZE + 3))
375231200Smm					return (0);
376231200Smm				continue;
377231200Smm			}
378231200Smm			p = (const char *)buff + offset;
379231200Smm			while (p + H_SIZE < (const char *)buff + bytes_avail) {
380231200Smm				if ((next = lha_check_header_format(p)) == 0)
381231200Smm					return (30);
382231200Smm				p += next;
383231200Smm			}
384231200Smm			offset = p - (const char *)buff;
385231200Smm		}
386231200Smm	}
387231200Smm	return (0);
388231200Smm}
389231200Smm
390231200Smmstatic int
391231200Smmarchive_read_format_lha_options(struct archive_read *a,
392231200Smm    const char *key, const char *val)
393231200Smm{
394231200Smm	struct lha *lha;
395231200Smm	int ret = ARCHIVE_FAILED;
396231200Smm
397231200Smm	lha = (struct lha *)(a->format->data);
398231200Smm	if (strcmp(key, "hdrcharset")  == 0) {
399231200Smm		if (val == NULL || val[0] == 0)
400231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
401231200Smm			    "lha: hdrcharset option needs a character-set name");
402231200Smm		else {
403231200Smm			lha->opt_sconv =
404231200Smm			    archive_string_conversion_from_charset(
405231200Smm				&a->archive, val, 0);
406231200Smm			if (lha->opt_sconv != NULL)
407231200Smm				ret = ARCHIVE_OK;
408231200Smm			else
409231200Smm				ret = ARCHIVE_FATAL;
410231200Smm		}
411232153Smm		return (ret);
412232153Smm	}
413231200Smm
414232153Smm	/* Note: The "warn" return is just to inform the options
415232153Smm	 * supervisor that we didn't handle it.  It will generate
416232153Smm	 * a suitable error if no one used this option. */
417232153Smm	return (ARCHIVE_WARN);
418231200Smm}
419231200Smm
420231200Smmstatic int
421231200Smmlha_skip_sfx(struct archive_read *a)
422231200Smm{
423231200Smm	const void *h;
424231200Smm	const char *p, *q;
425231200Smm	size_t next, skip;
426231200Smm	ssize_t bytes, window;
427231200Smm
428231200Smm	window = 4096;
429231200Smm	for (;;) {
430231200Smm		h = __archive_read_ahead(a, window, &bytes);
431231200Smm		if (h == NULL) {
432231200Smm			/* Remaining bytes are less than window. */
433231200Smm			window >>= 1;
434231200Smm			if (window < (H_SIZE + 3))
435231200Smm				goto fatal;
436231200Smm			continue;
437231200Smm		}
438231200Smm		if (bytes < H_SIZE)
439231200Smm			goto fatal;
440231200Smm		p = h;
441231200Smm		q = p + bytes;
442231200Smm
443231200Smm		/*
444231200Smm		 * Scan ahead until we find something that looks
445231200Smm		 * like the lha header.
446231200Smm		 */
447231200Smm		while (p + H_SIZE < q) {
448231200Smm			if ((next = lha_check_header_format(p)) == 0) {
449231200Smm				skip = p - (const char *)h;
450231200Smm				__archive_read_consume(a, skip);
451231200Smm				return (ARCHIVE_OK);
452231200Smm			}
453231200Smm			p += next;
454231200Smm		}
455231200Smm		skip = p - (const char *)h;
456231200Smm		__archive_read_consume(a, skip);
457231200Smm	}
458231200Smmfatal:
459231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
460231200Smm	    "Couldn't find out LHa header");
461231200Smm	return (ARCHIVE_FATAL);
462231200Smm}
463231200Smm
464231200Smmstatic int
465231200Smmtruncated_error(struct archive_read *a)
466231200Smm{
467231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
468231200Smm	    "Truncated LHa header");
469231200Smm	return (ARCHIVE_FATAL);
470231200Smm}
471231200Smm
472231200Smmstatic int
473231200Smmarchive_read_format_lha_read_header(struct archive_read *a,
474231200Smm    struct archive_entry *entry)
475231200Smm{
476231200Smm	struct archive_string linkname;
477231200Smm	struct archive_string pathname;
478231200Smm	struct lha *lha;
479231200Smm	const unsigned char *p;
480231200Smm	const char *signature;
481231200Smm	int err;
482231200Smm
483299529Smm	lha_crc16_init();
484299529Smm
485231200Smm	a->archive.archive_format = ARCHIVE_FORMAT_LHA;
486231200Smm	if (a->archive.archive_format_name == NULL)
487231200Smm		a->archive.archive_format_name = "lha";
488231200Smm
489231200Smm	lha = (struct lha *)(a->format->data);
490231200Smm	lha->decompress_init = 0;
491231200Smm	lha->end_of_entry = 0;
492231200Smm	lha->end_of_entry_cleanup = 0;
493231200Smm	lha->entry_unconsumed = 0;
494231200Smm
495231200Smm	if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) {
496231200Smm		/*
497231200Smm		 * LHa archiver added 0 to the tail of its archive file as
498231200Smm		 * the mark of the end of the archive.
499231200Smm		 */
500231200Smm		signature = __archive_read_ahead(a, sizeof(signature[0]), NULL);
501231200Smm		if (signature == NULL || signature[0] == 0)
502231200Smm			return (ARCHIVE_EOF);
503231200Smm		return (truncated_error(a));
504231200Smm	}
505231200Smm
506231200Smm	signature = (const char *)p;
507231200Smm	if (lha->found_first_header == 0 &&
508231200Smm	    signature[0] == 'M' && signature[1] == 'Z') {
509231200Smm                /* This is an executable?  Must be self-extracting... 	*/
510231200Smm		err = lha_skip_sfx(a);
511231200Smm		if (err < ARCHIVE_WARN)
512231200Smm			return (err);
513231200Smm
514231200Smm		if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
515231200Smm			return (truncated_error(a));
516231200Smm		signature = (const char *)p;
517231200Smm	}
518231200Smm	/* signature[0] == 0 means the end of an LHa archive file. */
519231200Smm	if (signature[0] == 0)
520231200Smm		return (ARCHIVE_EOF);
521231200Smm
522231200Smm	/*
523231200Smm	 * Check the header format and method type.
524231200Smm	 */
525231200Smm	if (lha_check_header_format(p) != 0) {
526231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
527231200Smm		    "Bad LHa file");
528231200Smm		return (ARCHIVE_FATAL);
529231200Smm	}
530231200Smm
531231200Smm	/* We've found the first header. */
532231200Smm	lha->found_first_header = 1;
533231200Smm	/* Set a default value and common data */
534231200Smm	lha->header_size = 0;
535231200Smm	lha->level = p[H_LEVEL_OFFSET];
536231200Smm	lha->method[0] = p[H_METHOD_OFFSET+1];
537231200Smm	lha->method[1] = p[H_METHOD_OFFSET+2];
538231200Smm	lha->method[2] = p[H_METHOD_OFFSET+3];
539231200Smm	if (memcmp(lha->method, "lhd", 3) == 0)
540231200Smm		lha->directory = 1;
541231200Smm	else
542231200Smm		lha->directory = 0;
543231200Smm	if (memcmp(lha->method, "lh0", 3) == 0 ||
544231200Smm	    memcmp(lha->method, "lz4", 3) == 0)
545231200Smm		lha->entry_is_compressed = 0;
546231200Smm	else
547231200Smm		lha->entry_is_compressed = 1;
548231200Smm
549231200Smm	lha->compsize = 0;
550231200Smm	lha->origsize = 0;
551231200Smm	lha->setflag = 0;
552231200Smm	lha->birthtime = 0;
553231200Smm	lha->birthtime_tv_nsec = 0;
554231200Smm	lha->mtime = 0;
555231200Smm	lha->mtime_tv_nsec = 0;
556231200Smm	lha->atime = 0;
557231200Smm	lha->atime_tv_nsec = 0;
558231200Smm	lha->mode = (lha->directory)? 0777 : 0666;
559231200Smm	lha->uid = 0;
560231200Smm	lha->gid = 0;
561231200Smm	archive_string_empty(&lha->dirname);
562231200Smm	archive_string_empty(&lha->filename);
563231200Smm	lha->dos_attr = 0;
564231200Smm	if (lha->opt_sconv != NULL)
565231200Smm		lha->sconv = lha->opt_sconv;
566231200Smm	else
567231200Smm		lha->sconv = NULL;
568231200Smm
569231200Smm	switch (p[H_LEVEL_OFFSET]) {
570231200Smm	case 0:
571231200Smm		err = lha_read_file_header_0(a, lha);
572231200Smm		break;
573231200Smm	case 1:
574231200Smm		err = lha_read_file_header_1(a, lha);
575231200Smm		break;
576231200Smm	case 2:
577231200Smm		err = lha_read_file_header_2(a, lha);
578231200Smm		break;
579231200Smm	case 3:
580231200Smm		err = lha_read_file_header_3(a, lha);
581231200Smm		break;
582231200Smm	default:
583231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
584231200Smm		    "Unsupported LHa header level %d", p[H_LEVEL_OFFSET]);
585231200Smm		err = ARCHIVE_FATAL;
586231200Smm		break;
587231200Smm	}
588231200Smm	if (err < ARCHIVE_WARN)
589231200Smm		return (err);
590231200Smm
591231200Smm
592231200Smm	if (!lha->directory && archive_strlen(&lha->filename) == 0)
593231200Smm		/* The filename has not been set */
594231200Smm		return (truncated_error(a));
595231200Smm
596231200Smm	/*
597231200Smm	 * Make a pathname from a dirname and a filename.
598231200Smm	 */
599231200Smm	archive_string_concat(&lha->dirname, &lha->filename);
600231200Smm	archive_string_init(&pathname);
601231200Smm	archive_string_init(&linkname);
602231200Smm	archive_string_copy(&pathname, &lha->dirname);
603231200Smm
604231200Smm	if ((lha->mode & AE_IFMT) == AE_IFLNK) {
605231200Smm		/*
606231200Smm	 	 * Extract the symlink-name if it's included in the pathname.
607231200Smm	 	 */
608231200Smm		if (!lha_parse_linkname(&linkname, &pathname)) {
609231200Smm			/* We couldn't get the symlink-name. */
610231200Smm			archive_set_error(&a->archive,
611231200Smm		    	    ARCHIVE_ERRNO_FILE_FORMAT,
612231200Smm			    "Unknown symlink-name");
613231200Smm			archive_string_free(&pathname);
614231200Smm			archive_string_free(&linkname);
615231200Smm			return (ARCHIVE_FAILED);
616231200Smm		}
617231200Smm	} else {
618231200Smm		/*
619231200Smm		 * Make sure a file-type is set.
620231200Smm		 * The mode has been overridden if it is in the extended data.
621231200Smm		 */
622231200Smm		lha->mode = (lha->mode & ~AE_IFMT) |
623231200Smm		    ((lha->directory)? AE_IFDIR: AE_IFREG);
624231200Smm	}
625231200Smm	if ((lha->setflag & UNIX_MODE_IS_SET) == 0 &&
626231200Smm	    (lha->dos_attr & 1) != 0)
627231200Smm		lha->mode &= ~(0222);/* read only. */
628231200Smm
629231200Smm	/*
630231200Smm	 * Set basic file parameters.
631231200Smm	 */
632231200Smm	if (archive_entry_copy_pathname_l(entry, pathname.s,
633231200Smm	    pathname.length, lha->sconv) != 0) {
634231200Smm		if (errno == ENOMEM) {
635231200Smm			archive_set_error(&a->archive, ENOMEM,
636231200Smm			    "Can't allocate memory for Pathname");
637231200Smm			return (ARCHIVE_FATAL);
638231200Smm		}
639231200Smm		archive_set_error(&a->archive,
640231200Smm		    ARCHIVE_ERRNO_FILE_FORMAT,
641231200Smm		    "Pathname cannot be converted "
642231200Smm		    "from %s to current locale.",
643231200Smm		    archive_string_conversion_charset_name(lha->sconv));
644231200Smm		err = ARCHIVE_WARN;
645231200Smm	}
646231200Smm	archive_string_free(&pathname);
647231200Smm	if (archive_strlen(&linkname) > 0) {
648231200Smm		if (archive_entry_copy_symlink_l(entry, linkname.s,
649231200Smm		    linkname.length, lha->sconv) != 0) {
650231200Smm			if (errno == ENOMEM) {
651231200Smm				archive_set_error(&a->archive, ENOMEM,
652231200Smm				    "Can't allocate memory for Linkname");
653231200Smm				return (ARCHIVE_FATAL);
654231200Smm			}
655231200Smm			archive_set_error(&a->archive,
656231200Smm			    ARCHIVE_ERRNO_FILE_FORMAT,
657231200Smm			    "Linkname cannot be converted "
658231200Smm			    "from %s to current locale.",
659231200Smm			    archive_string_conversion_charset_name(lha->sconv));
660231200Smm			err = ARCHIVE_WARN;
661231200Smm		}
662231200Smm	} else
663231200Smm		archive_entry_set_symlink(entry, NULL);
664231200Smm	archive_string_free(&linkname);
665231200Smm	/*
666231200Smm	 * When a header level is 0, there is a possibility that
667231200Smm	 * a pathname and a symlink has '\' character, a directory
668231200Smm	 * separator in DOS/Windows. So we should convert it to '/'.
669231200Smm	 */
670231200Smm	if (p[H_LEVEL_OFFSET] == 0)
671231200Smm		lha_replace_path_separator(lha, entry);
672231200Smm
673231200Smm	archive_entry_set_mode(entry, lha->mode);
674231200Smm	archive_entry_set_uid(entry, lha->uid);
675231200Smm	archive_entry_set_gid(entry, lha->gid);
676231200Smm	if (archive_strlen(&lha->uname) > 0)
677231200Smm		archive_entry_set_uname(entry, lha->uname.s);
678231200Smm	if (archive_strlen(&lha->gname) > 0)
679231200Smm		archive_entry_set_gname(entry, lha->gname.s);
680231200Smm	if (lha->setflag & BIRTHTIME_IS_SET) {
681231200Smm		archive_entry_set_birthtime(entry, lha->birthtime,
682231200Smm		    lha->birthtime_tv_nsec);
683231200Smm		archive_entry_set_ctime(entry, lha->birthtime,
684231200Smm		    lha->birthtime_tv_nsec);
685231200Smm	} else {
686231200Smm		archive_entry_unset_birthtime(entry);
687231200Smm		archive_entry_unset_ctime(entry);
688231200Smm	}
689231200Smm	archive_entry_set_mtime(entry, lha->mtime, lha->mtime_tv_nsec);
690231200Smm	if (lha->setflag & ATIME_IS_SET)
691231200Smm		archive_entry_set_atime(entry, lha->atime,
692231200Smm		    lha->atime_tv_nsec);
693231200Smm	else
694231200Smm		archive_entry_unset_atime(entry);
695231200Smm	if (lha->directory || archive_entry_symlink(entry) != NULL)
696231200Smm		archive_entry_unset_size(entry);
697231200Smm	else
698231200Smm		archive_entry_set_size(entry, lha->origsize);
699231200Smm
700231200Smm	/*
701231200Smm	 * Prepare variables used to read a file content.
702231200Smm	 */
703231200Smm	lha->entry_bytes_remaining = lha->compsize;
704231200Smm	lha->entry_offset = 0;
705231200Smm	lha->entry_crc_calculated = 0;
706231200Smm
707231200Smm	/*
708231200Smm	 * This file does not have a content.
709231200Smm	 */
710231200Smm	if (lha->directory || lha->compsize == 0)
711231200Smm		lha->end_of_entry = 1;
712231200Smm
713231200Smm	sprintf(lha->format_name, "lha -%c%c%c-",
714231200Smm	    lha->method[0], lha->method[1], lha->method[2]);
715231200Smm	a->archive.archive_format_name = lha->format_name;
716231200Smm
717231200Smm	return (err);
718231200Smm}
719231200Smm
720231200Smm/*
721231200Smm * Replace a DOS path separator '\' by a character '/'.
722231200Smm * Some multi-byte character set have  a character '\' in its second byte.
723231200Smm */
724231200Smmstatic void
725231200Smmlha_replace_path_separator(struct lha *lha, struct archive_entry *entry)
726231200Smm{
727231200Smm	const wchar_t *wp;
728231200Smm	size_t i;
729231200Smm
730231200Smm	if ((wp = archive_entry_pathname_w(entry)) != NULL) {
731231200Smm		archive_wstrcpy(&(lha->ws), wp);
732231200Smm		for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
733231200Smm			if (lha->ws.s[i] == L'\\')
734231200Smm				lha->ws.s[i] = L'/';
735231200Smm		}
736231200Smm		archive_entry_copy_pathname_w(entry, lha->ws.s);
737231200Smm	}
738231200Smm
739231200Smm	if ((wp = archive_entry_symlink_w(entry)) != NULL) {
740231200Smm		archive_wstrcpy(&(lha->ws), wp);
741231200Smm		for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
742231200Smm			if (lha->ws.s[i] == L'\\')
743231200Smm				lha->ws.s[i] = L'/';
744231200Smm		}
745231200Smm		archive_entry_copy_symlink_w(entry, lha->ws.s);
746231200Smm	}
747231200Smm}
748231200Smm
749231200Smm/*
750231200Smm * Header 0 format
751231200Smm *
752231200Smm * +0              +1         +2               +7                  +11
753231200Smm * +---------------+----------+----------------+-------------------+
754231200Smm * |header size(*1)|header sum|compression type|compressed size(*2)|
755231200Smm * +---------------+----------+----------------+-------------------+
756231200Smm *                             <---------------------(*1)----------*
757231200Smm *
758231200Smm * +11               +15       +17       +19            +20              +21
759231200Smm * +-----------------+---------+---------+--------------+----------------+
760231200Smm * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=0)|
761231200Smm * +-----------------+---------+---------+--------------+----------------+
762231200Smm * *--------------------------------(*1)---------------------------------*
763231200Smm *
764231200Smm * +21             +22       +22+(*3)   +22+(*3)+2       +22+(*3)+2+(*4)
765231200Smm * +---------------+---------+----------+----------------+------------------+
766231200Smm * |name length(*3)|file name|file CRC16|extra header(*4)|  compressed data |
767231200Smm * +---------------+---------+----------+----------------+------------------+
768231200Smm *                  <--(*3)->                             <------(*2)------>
769231200Smm * *----------------------(*1)-------------------------->
770231200Smm *
771231200Smm */
772231200Smm#define H0_HEADER_SIZE_OFFSET	0
773231200Smm#define H0_HEADER_SUM_OFFSET	1
774231200Smm#define H0_COMP_SIZE_OFFSET	7
775231200Smm#define H0_ORIG_SIZE_OFFSET	11
776231200Smm#define H0_DOS_TIME_OFFSET	15
777231200Smm#define H0_NAME_LEN_OFFSET	21
778231200Smm#define H0_FILE_NAME_OFFSET	22
779231200Smm#define H0_FIXED_SIZE		24
780231200Smmstatic int
781231200Smmlha_read_file_header_0(struct archive_read *a, struct lha *lha)
782231200Smm{
783231200Smm	const unsigned char *p;
784231200Smm	int extdsize, namelen;
785231200Smm	unsigned char headersum, sum_calculated;
786231200Smm
787231200Smm	if ((p = __archive_read_ahead(a, H0_FIXED_SIZE, NULL)) == NULL)
788231200Smm		return (truncated_error(a));
789231200Smm	lha->header_size = p[H0_HEADER_SIZE_OFFSET] + 2;
790231200Smm	headersum = p[H0_HEADER_SUM_OFFSET];
791231200Smm	lha->compsize = archive_le32dec(p + H0_COMP_SIZE_OFFSET);
792231200Smm	lha->origsize = archive_le32dec(p + H0_ORIG_SIZE_OFFSET);
793231200Smm	lha->mtime = lha_dos_time(p + H0_DOS_TIME_OFFSET);
794231200Smm	namelen = p[H0_NAME_LEN_OFFSET];
795231200Smm	extdsize = (int)lha->header_size - H0_FIXED_SIZE - namelen;
796231200Smm	if ((namelen > 221 || extdsize < 0) && extdsize != -2) {
797231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
798231200Smm		    "Invalid LHa header");
799231200Smm		return (ARCHIVE_FATAL);
800231200Smm	}
801231200Smm	if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
802231200Smm		return (truncated_error(a));
803231200Smm
804231200Smm	archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen);
805231200Smm	/* When extdsize == -2, A CRC16 value is not present in the header. */
806231200Smm	if (extdsize >= 0) {
807231200Smm		lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen);
808231200Smm		lha->setflag |= CRC_IS_SET;
809231200Smm	}
810231200Smm	sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
811231200Smm
812231200Smm	/* Read an extended header */
813231200Smm	if (extdsize > 0) {
814231200Smm		/* This extended data is set by 'LHa for UNIX' only.
815231200Smm		 * Maybe fixed size.
816231200Smm		 */
817231200Smm		p += H0_FILE_NAME_OFFSET + namelen + 2;
818231200Smm		if (p[0] == 'U' && extdsize == 12) {
819231200Smm			/* p[1] is a minor version. */
820231200Smm			lha->mtime = archive_le32dec(&p[2]);
821231200Smm			lha->mode = archive_le16dec(&p[6]);
822231200Smm			lha->uid = archive_le16dec(&p[8]);
823231200Smm			lha->gid = archive_le16dec(&p[10]);
824231200Smm			lha->setflag |= UNIX_MODE_IS_SET;
825231200Smm		}
826231200Smm	}
827231200Smm	__archive_read_consume(a, lha->header_size);
828231200Smm
829231200Smm	if (sum_calculated != headersum) {
830231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
831231200Smm		    "LHa header sum error");
832231200Smm		return (ARCHIVE_FATAL);
833231200Smm	}
834231200Smm
835231200Smm	return (ARCHIVE_OK);
836231200Smm}
837231200Smm
838231200Smm/*
839231200Smm * Header 1 format
840231200Smm *
841231200Smm * +0              +1         +2               +7            +11
842231200Smm * +---------------+----------+----------------+-------------+
843231200Smm * |header size(*1)|header sum|compression type|skip size(*2)|
844231200Smm * +---------------+----------+----------------+-------------+
845231200Smm *                             <---------------(*1)----------*
846231200Smm *
847231200Smm * +11               +15       +17       +19            +20              +21
848231200Smm * +-----------------+---------+---------+--------------+----------------+
849231200Smm * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=1)|
850231200Smm * +-----------------+---------+---------+--------------+----------------+
851231200Smm * *-------------------------------(*1)----------------------------------*
852231200Smm *
853231200Smm * +21             +22       +22+(*3)   +22+(*3)+2  +22+(*3)+3  +22+(*3)+3+(*4)
854231200Smm * +---------------+---------+----------+-----------+-----------+
855231200Smm * |name length(*3)|file name|file CRC16|  creator  |padding(*4)|
856231200Smm * +---------------+---------+----------+-----------+-----------+
857231200Smm *                  <--(*3)->
858231200Smm * *----------------------------(*1)----------------------------*
859231200Smm *
860231200Smm * +22+(*3)+3+(*4)  +22+(*3)+3+(*4)+2     +22+(*3)+3+(*4)+2+(*5)
861231200Smm * +----------------+---------------------+------------------------+
862231200Smm * |next header size| extended header(*5) |     compressed data    |
863231200Smm * +----------------+---------------------+------------------------+
864231200Smm * *------(*1)-----> <--------------------(*2)-------------------->
865231200Smm */
866231200Smm#define H1_HEADER_SIZE_OFFSET	0
867231200Smm#define H1_HEADER_SUM_OFFSET	1
868231200Smm#define H1_COMP_SIZE_OFFSET	7
869231200Smm#define H1_ORIG_SIZE_OFFSET	11
870231200Smm#define H1_DOS_TIME_OFFSET	15
871231200Smm#define H1_NAME_LEN_OFFSET	21
872231200Smm#define H1_FILE_NAME_OFFSET	22
873231200Smm#define H1_FIXED_SIZE		27
874231200Smmstatic int
875231200Smmlha_read_file_header_1(struct archive_read *a, struct lha *lha)
876231200Smm{
877231200Smm	const unsigned char *p;
878231200Smm	size_t extdsize;
879231200Smm	int i, err, err2;
880231200Smm	int namelen, padding;
881231200Smm	unsigned char headersum, sum_calculated;
882231200Smm
883231200Smm	err = ARCHIVE_OK;
884231200Smm
885231200Smm	if ((p = __archive_read_ahead(a, H1_FIXED_SIZE, NULL)) == NULL)
886231200Smm		return (truncated_error(a));
887231200Smm
888231200Smm	lha->header_size = p[H1_HEADER_SIZE_OFFSET] + 2;
889231200Smm	headersum = p[H1_HEADER_SUM_OFFSET];
890231200Smm	/* Note: An extended header size is included in a compsize. */
891231200Smm	lha->compsize = archive_le32dec(p + H1_COMP_SIZE_OFFSET);
892231200Smm	lha->origsize = archive_le32dec(p + H1_ORIG_SIZE_OFFSET);
893231200Smm	lha->mtime = lha_dos_time(p + H1_DOS_TIME_OFFSET);
894231200Smm	namelen = p[H1_NAME_LEN_OFFSET];
895231200Smm	/* Calculate a padding size. The result will be normally 0 only(?) */
896231200Smm	padding = ((int)lha->header_size) - H1_FIXED_SIZE - namelen;
897231200Smm
898231200Smm	if (namelen > 230 || padding < 0)
899231200Smm		goto invalid;
900231200Smm
901231200Smm	if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
902231200Smm		return (truncated_error(a));
903231200Smm
904231200Smm	for (i = 0; i < namelen; i++) {
905231200Smm		if (p[i + H1_FILE_NAME_OFFSET] == 0xff)
906231200Smm			goto invalid;/* Invalid filename. */
907231200Smm	}
908231200Smm	archive_strncpy(&lha->filename, p + H1_FILE_NAME_OFFSET, namelen);
909231200Smm	lha->crc = archive_le16dec(p + H1_FILE_NAME_OFFSET + namelen);
910231200Smm	lha->setflag |= CRC_IS_SET;
911231200Smm
912231200Smm	sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
913231200Smm	/* Consume used bytes but not include `next header size' data
914231200Smm	 * since it will be consumed in lha_read_file_extended_header(). */
915231200Smm	__archive_read_consume(a, lha->header_size - 2);
916231200Smm
917231200Smm	/* Read extended headers */
918231200Smm	err2 = lha_read_file_extended_header(a, lha, NULL, 2,
919238856Smm	    (size_t)(lha->compsize + 2), &extdsize);
920231200Smm	if (err2 < ARCHIVE_WARN)
921231200Smm		return (err2);
922231200Smm	if (err2 < err)
923231200Smm		err = err2;
924231200Smm	/* Get a real compressed file size. */
925231200Smm	lha->compsize -= extdsize - 2;
926231200Smm
927231200Smm	if (sum_calculated != headersum) {
928231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
929231200Smm		    "LHa header sum error");
930231200Smm		return (ARCHIVE_FATAL);
931231200Smm	}
932231200Smm	return (err);
933231200Smminvalid:
934231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
935231200Smm	    "Invalid LHa header");
936231200Smm	return (ARCHIVE_FATAL);
937231200Smm}
938231200Smm
939231200Smm/*
940231200Smm * Header 2 format
941231200Smm *
942231200Smm * +0              +2               +7                  +11               +15
943231200Smm * +---------------+----------------+-------------------+-----------------+
944231200Smm * |header size(*1)|compression type|compressed size(*2)|uncompressed size|
945231200Smm * +---------------+----------------+-------------------+-----------------+
946231200Smm *  <--------------------------------(*1)---------------------------------*
947231200Smm *
948231200Smm * +15               +19          +20              +21        +23         +24
949231200Smm * +-----------------+------------+----------------+----------+-----------+
950231200Smm * |data/time(time_t)| 0x20 fixed |header level(=2)|file CRC16|  creator  |
951231200Smm * +-----------------+------------+----------------+----------+-----------+
952231200Smm * *---------------------------------(*1)---------------------------------*
953231200Smm *
954231200Smm * +24              +26                 +26+(*3)      +26+(*3)+(*4)
955231200Smm * +----------------+-------------------+-------------+-------------------+
956231200Smm * |next header size|extended header(*3)| padding(*4) |  compressed data  |
957231200Smm * +----------------+-------------------+-------------+-------------------+
958231200Smm * *--------------------------(*1)-------------------> <------(*2)------->
959231200Smm *
960231200Smm */
961231200Smm#define H2_HEADER_SIZE_OFFSET	0
962231200Smm#define H2_COMP_SIZE_OFFSET	7
963231200Smm#define H2_ORIG_SIZE_OFFSET	11
964231200Smm#define H2_TIME_OFFSET		15
965231200Smm#define H2_CRC_OFFSET		21
966231200Smm#define H2_FIXED_SIZE		24
967231200Smmstatic int
968231200Smmlha_read_file_header_2(struct archive_read *a, struct lha *lha)
969231200Smm{
970231200Smm	const unsigned char *p;
971231200Smm	size_t extdsize;
972231200Smm	int err, padding;
973231200Smm	uint16_t header_crc;
974231200Smm
975231200Smm	if ((p = __archive_read_ahead(a, H2_FIXED_SIZE, NULL)) == NULL)
976231200Smm		return (truncated_error(a));
977231200Smm
978231200Smm	lha->header_size =archive_le16dec(p + H2_HEADER_SIZE_OFFSET);
979231200Smm	lha->compsize = archive_le32dec(p + H2_COMP_SIZE_OFFSET);
980231200Smm	lha->origsize = archive_le32dec(p + H2_ORIG_SIZE_OFFSET);
981231200Smm	lha->mtime = archive_le32dec(p + H2_TIME_OFFSET);
982231200Smm	lha->crc = archive_le16dec(p + H2_CRC_OFFSET);
983231200Smm	lha->setflag |= CRC_IS_SET;
984231200Smm
985231200Smm	if (lha->header_size < H2_FIXED_SIZE) {
986231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
987231200Smm		    "Invalid LHa header size");
988231200Smm		return (ARCHIVE_FATAL);
989231200Smm	}
990231200Smm
991231200Smm	header_crc = lha_crc16(0, p, H2_FIXED_SIZE);
992231200Smm	__archive_read_consume(a, H2_FIXED_SIZE);
993231200Smm
994231200Smm	/* Read extended headers */
995231200Smm	err = lha_read_file_extended_header(a, lha, &header_crc, 2,
996231200Smm		  lha->header_size - H2_FIXED_SIZE, &extdsize);
997231200Smm	if (err < ARCHIVE_WARN)
998231200Smm		return (err);
999231200Smm
1000231200Smm	/* Calculate a padding size. The result will be normally 0 or 1. */
1001231200Smm	padding = (int)lha->header_size - (int)(H2_FIXED_SIZE + extdsize);
1002231200Smm	if (padding > 0) {
1003231200Smm		if ((p = __archive_read_ahead(a, padding, NULL)) == NULL)
1004231200Smm			return (truncated_error(a));
1005231200Smm		header_crc = lha_crc16(header_crc, p, padding);
1006231200Smm		__archive_read_consume(a, padding);
1007231200Smm	}
1008231200Smm
1009231200Smm	if (header_crc != lha->header_crc) {
1010231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1011231200Smm		    "LHa header CRC error");
1012231200Smm		return (ARCHIVE_FATAL);
1013231200Smm	}
1014231200Smm	return (err);
1015231200Smm}
1016231200Smm
1017231200Smm/*
1018231200Smm * Header 3 format
1019231200Smm *
1020231200Smm * +0           +2               +7                  +11               +15
1021231200Smm * +------------+----------------+-------------------+-----------------+
1022231200Smm * | 0x04 fixed |compression type|compressed size(*2)|uncompressed size|
1023231200Smm * +------------+----------------+-------------------+-----------------+
1024231200Smm *  <-------------------------------(*1)-------------------------------*
1025231200Smm *
1026231200Smm * +15               +19          +20              +21        +23         +24
1027231200Smm * +-----------------+------------+----------------+----------+-----------+
1028231200Smm * |date/time(time_t)| 0x20 fixed |header level(=3)|file CRC16|  creator  |
1029231200Smm * +-----------------+------------+----------------+----------+-----------+
1030231200Smm * *--------------------------------(*1)----------------------------------*
1031231200Smm *
1032231200Smm * +24             +28              +32                 +32+(*3)
1033231200Smm * +---------------+----------------+-------------------+-----------------+
1034231200Smm * |header size(*1)|next header size|extended header(*3)| compressed data |
1035231200Smm * +---------------+----------------+-------------------+-----------------+
1036231200Smm * *------------------------(*1)-----------------------> <------(*2)----->
1037231200Smm *
1038231200Smm */
1039231200Smm#define H3_FIELD_LEN_OFFSET	0
1040231200Smm#define H3_COMP_SIZE_OFFSET	7
1041231200Smm#define H3_ORIG_SIZE_OFFSET	11
1042231200Smm#define H3_TIME_OFFSET		15
1043231200Smm#define H3_CRC_OFFSET		21
1044231200Smm#define H3_HEADER_SIZE_OFFSET	24
1045231200Smm#define H3_FIXED_SIZE		28
1046231200Smmstatic int
1047231200Smmlha_read_file_header_3(struct archive_read *a, struct lha *lha)
1048231200Smm{
1049231200Smm	const unsigned char *p;
1050231200Smm	size_t extdsize;
1051231200Smm	int err;
1052231200Smm	uint16_t header_crc;
1053231200Smm
1054231200Smm	if ((p = __archive_read_ahead(a, H3_FIXED_SIZE, NULL)) == NULL)
1055231200Smm		return (truncated_error(a));
1056231200Smm
1057231200Smm	if (archive_le16dec(p + H3_FIELD_LEN_OFFSET) != 4)
1058231200Smm		goto invalid;
1059231200Smm	lha->header_size =archive_le32dec(p + H3_HEADER_SIZE_OFFSET);
1060231200Smm	lha->compsize = archive_le32dec(p + H3_COMP_SIZE_OFFSET);
1061231200Smm	lha->origsize = archive_le32dec(p + H3_ORIG_SIZE_OFFSET);
1062231200Smm	lha->mtime = archive_le32dec(p + H3_TIME_OFFSET);
1063231200Smm	lha->crc = archive_le16dec(p + H3_CRC_OFFSET);
1064231200Smm	lha->setflag |= CRC_IS_SET;
1065231200Smm
1066231200Smm	if (lha->header_size < H3_FIXED_SIZE + 4)
1067231200Smm		goto invalid;
1068231200Smm	header_crc = lha_crc16(0, p, H3_FIXED_SIZE);
1069231200Smm	__archive_read_consume(a, H3_FIXED_SIZE);
1070231200Smm
1071231200Smm	/* Read extended headers */
1072231200Smm	err = lha_read_file_extended_header(a, lha, &header_crc, 4,
1073231200Smm		  lha->header_size - H3_FIXED_SIZE, &extdsize);
1074231200Smm	if (err < ARCHIVE_WARN)
1075231200Smm		return (err);
1076231200Smm
1077231200Smm	if (header_crc != lha->header_crc) {
1078231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1079231200Smm		    "LHa header CRC error");
1080231200Smm		return (ARCHIVE_FATAL);
1081231200Smm	}
1082231200Smm	return (err);
1083231200Smminvalid:
1084231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1085231200Smm	    "Invalid LHa header");
1086231200Smm	return (ARCHIVE_FATAL);
1087231200Smm}
1088231200Smm
1089231200Smm/*
1090231200Smm * Extended header format
1091231200Smm *
1092231200Smm * +0             +2        +3  -- used in header 1 and 2
1093231200Smm * +0             +4        +5  -- used in header 3
1094231200Smm * +--------------+---------+-------------------+--------------+--
1095231200Smm * |ex-header size|header id|        data       |ex-header size| .......
1096231200Smm * +--------------+---------+-------------------+--------------+--
1097231200Smm *  <-------------( ex-header size)------------> <-- next extended header --*
1098231200Smm *
1099231200Smm * If the ex-header size is zero, it is the make of the end of extended
1100231200Smm * headers.
1101231200Smm *
1102231200Smm */
1103231200Smmstatic int
1104231200Smmlha_read_file_extended_header(struct archive_read *a, struct lha *lha,
1105231200Smm    uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
1106231200Smm{
1107231200Smm	const void *h;
1108231200Smm	const unsigned char *extdheader;
1109231200Smm	size_t	extdsize;
1110231200Smm	size_t	datasize;
1111231200Smm	unsigned int i;
1112231200Smm	unsigned char extdtype;
1113231200Smm
1114231200Smm#define EXT_HEADER_CRC		0x00		/* Header CRC and information*/
1115231200Smm#define EXT_FILENAME		0x01		/* Filename 		    */
1116231200Smm#define EXT_DIRECTORY		0x02		/* Directory name	    */
1117231200Smm#define EXT_DOS_ATTR		0x40		/* MS-DOS attribute	    */
1118231200Smm#define EXT_TIMESTAMP		0x41		/* Windows time stamp	    */
1119231200Smm#define EXT_FILESIZE		0x42		/* Large file size	    */
1120231200Smm#define EXT_TIMEZONE		0x43		/* Time zone		    */
1121231200Smm#define EXT_UTF16_FILENAME	0x44		/* UTF-16 filename 	    */
1122231200Smm#define EXT_UTF16_DIRECTORY	0x45		/* UTF-16 directory name    */
1123231200Smm#define EXT_CODEPAGE		0x46		/* Codepage		    */
1124231200Smm#define EXT_UNIX_MODE		0x50		/* File permission	    */
1125231200Smm#define EXT_UNIX_GID_UID	0x51		/* gid,uid		    */
1126231200Smm#define EXT_UNIX_GNAME		0x52		/* Group name		    */
1127231200Smm#define EXT_UNIX_UNAME		0x53		/* User name		    */
1128231200Smm#define EXT_UNIX_MTIME		0x54		/* Modified time	    */
1129231200Smm#define EXT_OS2_NEW_ATTR	0x7f		/* new attribute(OS/2 only) */
1130231200Smm#define EXT_NEW_ATTR		0xff		/* new attribute	    */
1131231200Smm
1132231200Smm	*total_size = sizefield_length;
1133231200Smm
1134231200Smm	for (;;) {
1135231200Smm		/* Read an extended header size. */
1136231200Smm		if ((h =
1137231200Smm		    __archive_read_ahead(a, sizefield_length, NULL)) == NULL)
1138231200Smm			return (truncated_error(a));
1139231200Smm		/* Check if the size is the zero indicates the end of the
1140231200Smm		 * extended header. */
1141231200Smm		if (sizefield_length == sizeof(uint16_t))
1142231200Smm			extdsize = archive_le16dec(h);
1143231200Smm		else
1144231200Smm			extdsize = archive_le32dec(h);
1145231200Smm		if (extdsize == 0) {
1146231200Smm			/* End of extended header */
1147231200Smm			if (crc != NULL)
1148231200Smm				*crc = lha_crc16(*crc, h, sizefield_length);
1149231200Smm			__archive_read_consume(a, sizefield_length);
1150231200Smm			return (ARCHIVE_OK);
1151231200Smm		}
1152231200Smm
1153231200Smm		/* Sanity check to the extended header size. */
1154231200Smm		if (((uint64_t)*total_size + extdsize) >
1155231200Smm				    (uint64_t)limitsize ||
1156231200Smm		    extdsize <= (size_t)sizefield_length)
1157231200Smm			goto invalid;
1158231200Smm
1159231200Smm		/* Read the extended header. */
1160231200Smm		if ((h = __archive_read_ahead(a, extdsize, NULL)) == NULL)
1161231200Smm			return (truncated_error(a));
1162231200Smm		*total_size += extdsize;
1163231200Smm
1164231200Smm		extdheader = (const unsigned char *)h;
1165231200Smm		/* Get the extended header type. */
1166231200Smm		extdtype = extdheader[sizefield_length];
1167231200Smm		/* Calculate an extended data size. */
1168231200Smm		datasize = extdsize - (1 + sizefield_length);
1169231200Smm		/* Skip an extended header size field and type field. */
1170231200Smm		extdheader += sizefield_length + 1;
1171231200Smm
1172231200Smm		if (crc != NULL && extdtype != EXT_HEADER_CRC)
1173231200Smm			*crc = lha_crc16(*crc, h, extdsize);
1174231200Smm		switch (extdtype) {
1175231200Smm		case EXT_HEADER_CRC:
1176231200Smm			/* We only use a header CRC. Following data will not
1177231200Smm			 * be used. */
1178231200Smm			if (datasize >= 2) {
1179231200Smm				lha->header_crc = archive_le16dec(extdheader);
1180231200Smm				if (crc != NULL) {
1181231200Smm					static const char zeros[2] = {0, 0};
1182231200Smm					*crc = lha_crc16(*crc, h,
1183231200Smm					    extdsize - datasize);
1184231200Smm					/* CRC value itself as zero */
1185231200Smm					*crc = lha_crc16(*crc, zeros, 2);
1186231200Smm					*crc = lha_crc16(*crc,
1187231200Smm					    extdheader+2, datasize - 2);
1188231200Smm				}
1189231200Smm			}
1190231200Smm			break;
1191231200Smm		case EXT_FILENAME:
1192231200Smm			if (datasize == 0) {
1193231200Smm				/* maybe directory header */
1194231200Smm				archive_string_empty(&lha->filename);
1195231200Smm				break;
1196231200Smm			}
1197299529Smm			if (extdheader[0] == '\0')
1198299529Smm				goto invalid;
1199231200Smm			archive_strncpy(&lha->filename,
1200231200Smm			    (const char *)extdheader, datasize);
1201231200Smm			break;
1202231200Smm		case EXT_DIRECTORY:
1203299529Smm			if (datasize == 0 || extdheader[0] == '\0')
1204231200Smm				/* no directory name data. exit this case. */
1205299529Smm				goto invalid;
1206231200Smm
1207231200Smm			archive_strncpy(&lha->dirname,
1208231200Smm		  	    (const char *)extdheader, datasize);
1209231200Smm			/*
1210231200Smm			 * Convert directory delimiter from 0xFF
1211231200Smm			 * to '/' for local system.
1212231200Smm	 		 */
1213231200Smm			for (i = 0; i < lha->dirname.length; i++) {
1214231200Smm				if ((unsigned char)lha->dirname.s[i] == 0xFF)
1215231200Smm					lha->dirname.s[i] = '/';
1216231200Smm			}
1217231200Smm			/* Is last character directory separator? */
1218231200Smm			if (lha->dirname.s[lha->dirname.length-1] != '/')
1219231200Smm				/* invalid directory data */
1220231200Smm				goto invalid;
1221231200Smm			break;
1222231200Smm		case EXT_DOS_ATTR:
1223231200Smm			if (datasize == 2)
1224231200Smm				lha->dos_attr = (unsigned char)
1225231200Smm				    (archive_le16dec(extdheader) & 0xff);
1226231200Smm			break;
1227231200Smm		case EXT_TIMESTAMP:
1228231200Smm			if (datasize == (sizeof(uint64_t) * 3)) {
1229231200Smm				lha->birthtime = lha_win_time(
1230231200Smm				    archive_le64dec(extdheader),
1231231200Smm				    &lha->birthtime_tv_nsec);
1232231200Smm				extdheader += sizeof(uint64_t);
1233231200Smm				lha->mtime = lha_win_time(
1234231200Smm				    archive_le64dec(extdheader),
1235231200Smm				    &lha->mtime_tv_nsec);
1236231200Smm				extdheader += sizeof(uint64_t);
1237231200Smm				lha->atime = lha_win_time(
1238231200Smm				    archive_le64dec(extdheader),
1239231200Smm				    &lha->atime_tv_nsec);
1240231200Smm				lha->setflag |= BIRTHTIME_IS_SET |
1241231200Smm				    ATIME_IS_SET;
1242231200Smm			}
1243231200Smm			break;
1244231200Smm		case EXT_FILESIZE:
1245231200Smm			if (datasize == sizeof(uint64_t) * 2) {
1246231200Smm				lha->compsize = archive_le64dec(extdheader);
1247231200Smm				extdheader += sizeof(uint64_t);
1248231200Smm				lha->origsize = archive_le64dec(extdheader);
1249231200Smm			}
1250231200Smm			break;
1251231200Smm		case EXT_CODEPAGE:
1252231200Smm			/* Get an archived filename charset from codepage.
1253231200Smm			 * This overwrites the charset specified by
1254231200Smm			 * hdrcharset option. */
1255231200Smm			if (datasize == sizeof(uint32_t)) {
1256231200Smm				struct archive_string cp;
1257231200Smm				const char *charset;
1258231200Smm
1259231200Smm				archive_string_init(&cp);
1260231200Smm				switch (archive_le32dec(extdheader)) {
1261231200Smm				case 65001: /* UTF-8 */
1262231200Smm					charset = "UTF-8";
1263231200Smm					break;
1264231200Smm				default:
1265231200Smm					archive_string_sprintf(&cp, "CP%d",
1266231200Smm					    (int)archive_le32dec(extdheader));
1267231200Smm					charset = cp.s;
1268231200Smm					break;
1269231200Smm				}
1270231200Smm				lha->sconv =
1271231200Smm				    archive_string_conversion_from_charset(
1272231200Smm					&(a->archive), charset, 1);
1273231200Smm				archive_string_free(&cp);
1274231200Smm				if (lha->sconv == NULL)
1275231200Smm					return (ARCHIVE_FATAL);
1276231200Smm			}
1277231200Smm			break;
1278231200Smm		case EXT_UNIX_MODE:
1279231200Smm			if (datasize == sizeof(uint16_t)) {
1280231200Smm				lha->mode = archive_le16dec(extdheader);
1281231200Smm				lha->setflag |= UNIX_MODE_IS_SET;
1282231200Smm			}
1283231200Smm			break;
1284231200Smm		case EXT_UNIX_GID_UID:
1285231200Smm			if (datasize == (sizeof(uint16_t) * 2)) {
1286231200Smm				lha->gid = archive_le16dec(extdheader);
1287231200Smm				lha->uid = archive_le16dec(extdheader+2);
1288231200Smm			}
1289231200Smm			break;
1290231200Smm		case EXT_UNIX_GNAME:
1291231200Smm			if (datasize > 0)
1292231200Smm				archive_strncpy(&lha->gname,
1293231200Smm				    (const char *)extdheader, datasize);
1294231200Smm			break;
1295231200Smm		case EXT_UNIX_UNAME:
1296231200Smm			if (datasize > 0)
1297231200Smm				archive_strncpy(&lha->uname,
1298231200Smm				    (const char *)extdheader, datasize);
1299231200Smm			break;
1300231200Smm		case EXT_UNIX_MTIME:
1301231200Smm			if (datasize == sizeof(uint32_t))
1302231200Smm				lha->mtime = archive_le32dec(extdheader);
1303231200Smm			break;
1304231200Smm		case EXT_OS2_NEW_ATTR:
1305231200Smm			/* This extended header is OS/2 depend. */
1306231200Smm			if (datasize == 16) {
1307231200Smm				lha->dos_attr = (unsigned char)
1308231200Smm				    (archive_le16dec(extdheader) & 0xff);
1309231200Smm				lha->mode = archive_le16dec(extdheader+2);
1310231200Smm				lha->gid = archive_le16dec(extdheader+4);
1311231200Smm				lha->uid = archive_le16dec(extdheader+6);
1312231200Smm				lha->birthtime = archive_le32dec(extdheader+8);
1313231200Smm				lha->atime = archive_le32dec(extdheader+12);
1314231200Smm				lha->setflag |= UNIX_MODE_IS_SET
1315231200Smm				    | BIRTHTIME_IS_SET | ATIME_IS_SET;
1316231200Smm			}
1317231200Smm			break;
1318231200Smm		case EXT_NEW_ATTR:
1319231200Smm			if (datasize == 20) {
1320231200Smm				lha->mode = (mode_t)archive_le32dec(extdheader);
1321231200Smm				lha->gid = archive_le32dec(extdheader+4);
1322231200Smm				lha->uid = archive_le32dec(extdheader+8);
1323231200Smm				lha->birthtime = archive_le32dec(extdheader+12);
1324231200Smm				lha->atime = archive_le32dec(extdheader+16);
1325231200Smm				lha->setflag |= UNIX_MODE_IS_SET
1326231200Smm				    | BIRTHTIME_IS_SET | ATIME_IS_SET;
1327231200Smm			}
1328231200Smm			break;
1329231200Smm		case EXT_TIMEZONE:		/* Not supported */
1330231200Smm		case EXT_UTF16_FILENAME:	/* Not supported */
1331231200Smm		case EXT_UTF16_DIRECTORY:	/* Not supported */
1332231200Smm		default:
1333231200Smm			break;
1334231200Smm		}
1335231200Smm
1336231200Smm		__archive_read_consume(a, extdsize);
1337231200Smm	}
1338231200Smminvalid:
1339231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1340231200Smm	    "Invalid extended LHa header");
1341231200Smm	return (ARCHIVE_FATAL);
1342231200Smm}
1343231200Smm
1344231200Smmstatic int
1345299529Smmlha_end_of_entry(struct archive_read *a)
1346299529Smm{
1347299529Smm	struct lha *lha = (struct lha *)(a->format->data);
1348299529Smm	int r = ARCHIVE_EOF;
1349299529Smm
1350299529Smm	if (!lha->end_of_entry_cleanup) {
1351299529Smm		if ((lha->setflag & CRC_IS_SET) &&
1352299529Smm		    lha->crc != lha->entry_crc_calculated) {
1353299529Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1354299529Smm			    "LHa data CRC error");
1355299529Smm			r = ARCHIVE_WARN;
1356299529Smm		}
1357299529Smm
1358299529Smm		/* End-of-entry cleanup done. */
1359299529Smm		lha->end_of_entry_cleanup = 1;
1360299529Smm	}
1361299529Smm	return (r);
1362299529Smm}
1363299529Smm
1364299529Smmstatic int
1365231200Smmarchive_read_format_lha_read_data(struct archive_read *a,
1366231200Smm    const void **buff, size_t *size, int64_t *offset)
1367231200Smm{
1368231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1369231200Smm	int r;
1370231200Smm
1371231200Smm	if (lha->entry_unconsumed) {
1372231200Smm		/* Consume as much as the decompressor actually used. */
1373231200Smm		__archive_read_consume(a, lha->entry_unconsumed);
1374231200Smm		lha->entry_unconsumed = 0;
1375231200Smm	}
1376231200Smm	if (lha->end_of_entry) {
1377231200Smm		*offset = lha->entry_offset;
1378231200Smm		*size = 0;
1379231200Smm		*buff = NULL;
1380299529Smm		return (lha_end_of_entry(a));
1381231200Smm	}
1382231200Smm
1383231200Smm	if (lha->entry_is_compressed)
1384231200Smm		r =  lha_read_data_lzh(a, buff, size, offset);
1385231200Smm	else
1386231200Smm		/* No compression. */
1387231200Smm		r =  lha_read_data_none(a, buff, size, offset);
1388231200Smm	return (r);
1389231200Smm}
1390231200Smm
1391231200Smm/*
1392231200Smm * Read a file content in no compression.
1393231200Smm *
1394231200Smm * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
1395231200Smm * lha->end_of_entry if it consumes all of the data.
1396231200Smm */
1397231200Smmstatic int
1398231200Smmlha_read_data_none(struct archive_read *a, const void **buff,
1399231200Smm    size_t *size, int64_t *offset)
1400231200Smm{
1401231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1402231200Smm	ssize_t bytes_avail;
1403231200Smm
1404231200Smm	if (lha->entry_bytes_remaining == 0) {
1405231200Smm		*buff = NULL;
1406231200Smm		*size = 0;
1407231200Smm		*offset = lha->entry_offset;
1408231200Smm		lha->end_of_entry = 1;
1409231200Smm		return (ARCHIVE_OK);
1410231200Smm	}
1411231200Smm	/*
1412231200Smm	 * Note: '1' here is a performance optimization.
1413231200Smm	 * Recall that the decompression layer returns a count of
1414231200Smm	 * available bytes; asking for more than that forces the
1415231200Smm	 * decompressor to combine reads by copying data.
1416231200Smm	 */
1417231200Smm	*buff = __archive_read_ahead(a, 1, &bytes_avail);
1418231200Smm	if (bytes_avail <= 0) {
1419231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1420231200Smm		    "Truncated LHa file data");
1421231200Smm		return (ARCHIVE_FATAL);
1422231200Smm	}
1423231200Smm	if (bytes_avail > lha->entry_bytes_remaining)
1424238856Smm		bytes_avail = (ssize_t)lha->entry_bytes_remaining;
1425231200Smm	lha->entry_crc_calculated =
1426231200Smm	    lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
1427231200Smm	*size = bytes_avail;
1428231200Smm	*offset = lha->entry_offset;
1429231200Smm	lha->entry_offset += bytes_avail;
1430231200Smm	lha->entry_bytes_remaining -= bytes_avail;
1431231200Smm	if (lha->entry_bytes_remaining == 0)
1432231200Smm		lha->end_of_entry = 1;
1433231200Smm	lha->entry_unconsumed = bytes_avail;
1434231200Smm	return (ARCHIVE_OK);
1435231200Smm}
1436231200Smm
1437231200Smm/*
1438231200Smm * Read a file content in LZHUFF encoding.
1439231200Smm *
1440231200Smm * Returns ARCHIVE_OK if successful, returns ARCHIVE_WARN if compression is
1441231200Smm * unsupported, ARCHIVE_FATAL otherwise, sets lha->end_of_entry if it consumes
1442231200Smm * all of the data.
1443231200Smm */
1444231200Smmstatic int
1445231200Smmlha_read_data_lzh(struct archive_read *a, const void **buff,
1446231200Smm    size_t *size, int64_t *offset)
1447231200Smm{
1448231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1449231200Smm	ssize_t bytes_avail;
1450231200Smm	int r;
1451231200Smm
1452231200Smm	/* If we haven't yet read any data, initialize the decompressor. */
1453231200Smm	if (!lha->decompress_init) {
1454231200Smm		r = lzh_decode_init(&(lha->strm), lha->method);
1455231200Smm		switch (r) {
1456231200Smm		case ARCHIVE_OK:
1457231200Smm			break;
1458231200Smm		case ARCHIVE_FAILED:
1459231200Smm        		/* Unsupported compression. */
1460231200Smm			*buff = NULL;
1461231200Smm			*size = 0;
1462231200Smm			*offset = 0;
1463231200Smm			archive_set_error(&a->archive,
1464231200Smm			    ARCHIVE_ERRNO_FILE_FORMAT,
1465231200Smm			    "Unsupported lzh compression method -%c%c%c-",
1466231200Smm			    lha->method[0], lha->method[1], lha->method[2]);
1467231200Smm			/* We know compressed size; just skip it. */
1468231200Smm			archive_read_format_lha_read_data_skip(a);
1469231200Smm			return (ARCHIVE_WARN);
1470231200Smm		default:
1471231200Smm			archive_set_error(&a->archive, ENOMEM,
1472231200Smm			    "Couldn't allocate memory "
1473231200Smm			    "for lzh decompression");
1474231200Smm			return (ARCHIVE_FATAL);
1475231200Smm		}
1476231200Smm		/* We've initialized decompression for this stream. */
1477231200Smm		lha->decompress_init = 1;
1478231200Smm		lha->strm.avail_out = 0;
1479231200Smm		lha->strm.total_out = 0;
1480231200Smm	}
1481231200Smm
1482231200Smm	/*
1483231200Smm	 * Note: '1' here is a performance optimization.
1484231200Smm	 * Recall that the decompression layer returns a count of
1485231200Smm	 * available bytes; asking for more than that forces the
1486231200Smm	 * decompressor to combine reads by copying data.
1487231200Smm	 */
1488231200Smm	lha->strm.next_in = __archive_read_ahead(a, 1, &bytes_avail);
1489231200Smm	if (bytes_avail <= 0) {
1490231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1491231200Smm		    "Truncated LHa file body");
1492231200Smm		return (ARCHIVE_FATAL);
1493231200Smm	}
1494231200Smm	if (bytes_avail > lha->entry_bytes_remaining)
1495238856Smm		bytes_avail = (ssize_t)lha->entry_bytes_remaining;
1496231200Smm
1497299529Smm	lha->strm.avail_in = (int)bytes_avail;
1498231200Smm	lha->strm.total_in = 0;
1499299529Smm	lha->strm.avail_out = 0;
1500231200Smm
1501231200Smm	r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining);
1502231200Smm	switch (r) {
1503231200Smm	case ARCHIVE_OK:
1504231200Smm		break;
1505231200Smm	case ARCHIVE_EOF:
1506231200Smm		lha->end_of_entry = 1;
1507231200Smm		break;
1508231200Smm	default:
1509231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1510231200Smm		    "Bad lzh data");
1511231200Smm		return (ARCHIVE_FAILED);
1512231200Smm	}
1513231200Smm	lha->entry_unconsumed = lha->strm.total_in;
1514231200Smm	lha->entry_bytes_remaining -= lha->strm.total_in;
1515231200Smm
1516299529Smm	if (lha->strm.avail_out) {
1517231200Smm		*offset = lha->entry_offset;
1518299529Smm		*size = lha->strm.avail_out;
1519299529Smm		*buff = lha->strm.ref_ptr;
1520231200Smm		lha->entry_crc_calculated =
1521231200Smm		    lha_crc16(lha->entry_crc_calculated, *buff, *size);
1522231200Smm		lha->entry_offset += *size;
1523231200Smm	} else {
1524231200Smm		*offset = lha->entry_offset;
1525231200Smm		*size = 0;
1526231200Smm		*buff = NULL;
1527299529Smm		if (lha->end_of_entry)
1528299529Smm			return (lha_end_of_entry(a));
1529231200Smm	}
1530231200Smm	return (ARCHIVE_OK);
1531231200Smm}
1532231200Smm
1533231200Smm/*
1534231200Smm * Skip a file content.
1535231200Smm */
1536231200Smmstatic int
1537231200Smmarchive_read_format_lha_read_data_skip(struct archive_read *a)
1538231200Smm{
1539231200Smm	struct lha *lha;
1540238856Smm	int64_t bytes_skipped;
1541231200Smm
1542231200Smm	lha = (struct lha *)(a->format->data);
1543231200Smm
1544231200Smm	if (lha->entry_unconsumed) {
1545231200Smm		/* Consume as much as the decompressor actually used. */
1546231200Smm		__archive_read_consume(a, lha->entry_unconsumed);
1547231200Smm		lha->entry_unconsumed = 0;
1548231200Smm	}
1549231200Smm
1550231200Smm	/* if we've already read to end of data, we're done. */
1551231200Smm	if (lha->end_of_entry_cleanup)
1552231200Smm		return (ARCHIVE_OK);
1553231200Smm
1554231200Smm	/*
1555231200Smm	 * If the length is at the beginning, we can skip the
1556231200Smm	 * compressed data much more quickly.
1557231200Smm	 */
1558231200Smm	bytes_skipped = __archive_read_consume(a, lha->entry_bytes_remaining);
1559231200Smm	if (bytes_skipped < 0)
1560231200Smm		return (ARCHIVE_FATAL);
1561231200Smm
1562231200Smm	/* This entry is finished and done. */
1563231200Smm	lha->end_of_entry_cleanup = lha->end_of_entry = 1;
1564231200Smm	return (ARCHIVE_OK);
1565231200Smm}
1566231200Smm
1567231200Smmstatic int
1568231200Smmarchive_read_format_lha_cleanup(struct archive_read *a)
1569231200Smm{
1570231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1571231200Smm
1572231200Smm	lzh_decode_free(&(lha->strm));
1573231200Smm	archive_string_free(&(lha->dirname));
1574231200Smm	archive_string_free(&(lha->filename));
1575231200Smm	archive_string_free(&(lha->uname));
1576231200Smm	archive_string_free(&(lha->gname));
1577231200Smm	archive_wstring_free(&(lha->ws));
1578231200Smm	free(lha);
1579231200Smm	(a->format->data) = NULL;
1580231200Smm	return (ARCHIVE_OK);
1581231200Smm}
1582231200Smm
1583231200Smm/*
1584231200Smm * 'LHa for UNIX' utility has archived a symbolic-link name after
1585231200Smm * a pathname with '|' character.
1586231200Smm * This function extracts the symbolic-link name from the pathname.
1587231200Smm *
1588231200Smm * example.
1589231200Smm *   1. a symbolic-name is 'aaa/bb/cc'
1590231200Smm *   2. a filename is 'xxx/bbb'
1591231200Smm *  then a archived pathname is 'xxx/bbb|aaa/bb/cc'
1592231200Smm */
1593231200Smmstatic int
1594231200Smmlha_parse_linkname(struct archive_string *linkname,
1595231200Smm    struct archive_string *pathname)
1596231200Smm{
1597231200Smm	char *	linkptr;
1598248616Smm	size_t 	symlen;
1599231200Smm
1600231200Smm	linkptr = strchr(pathname->s, '|');
1601231200Smm	if (linkptr != NULL) {
1602231200Smm		symlen = strlen(linkptr + 1);
1603231200Smm		archive_strncpy(linkname, linkptr+1, symlen);
1604231200Smm
1605231200Smm		*linkptr = 0;
1606231200Smm		pathname->length = strlen(pathname->s);
1607231200Smm
1608231200Smm		return (1);
1609231200Smm	}
1610231200Smm	return (0);
1611231200Smm}
1612231200Smm
1613231200Smm/* Convert an MSDOS-style date/time into Unix-style time. */
1614231200Smmstatic time_t
1615231200Smmlha_dos_time(const unsigned char *p)
1616231200Smm{
1617231200Smm	int msTime, msDate;
1618231200Smm	struct tm ts;
1619231200Smm
1620231200Smm	msTime = archive_le16dec(p);
1621231200Smm	msDate = archive_le16dec(p+2);
1622231200Smm
1623231200Smm	memset(&ts, 0, sizeof(ts));
1624231200Smm	ts.tm_year = ((msDate >> 9) & 0x7f) + 80;   /* Years since 1900. */
1625231200Smm	ts.tm_mon = ((msDate >> 5) & 0x0f) - 1;     /* Month number.     */
1626231200Smm	ts.tm_mday = msDate & 0x1f;		    /* Day of month.     */
1627231200Smm	ts.tm_hour = (msTime >> 11) & 0x1f;
1628231200Smm	ts.tm_min = (msTime >> 5) & 0x3f;
1629231200Smm	ts.tm_sec = (msTime << 1) & 0x3e;
1630231200Smm	ts.tm_isdst = -1;
1631231200Smm	return (mktime(&ts));
1632231200Smm}
1633231200Smm
1634231200Smm/* Convert an MS-Windows-style date/time into Unix-style time. */
1635231200Smmstatic time_t
1636231200Smmlha_win_time(uint64_t wintime, long *ns)
1637231200Smm{
1638231200Smm#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1639231200Smm
1640231200Smm	if (wintime >= EPOC_TIME) {
1641231200Smm		wintime -= EPOC_TIME;	/* 1970-01-01 00:00:00 (UTC) */
1642231200Smm		if (ns != NULL)
1643231200Smm			*ns = (long)(wintime % 10000000) * 100;
1644231200Smm		return (wintime / 10000000);
1645231200Smm	} else {
1646231200Smm		if (ns != NULL)
1647231200Smm			*ns = 0;
1648231200Smm		return (0);
1649231200Smm	}
1650231200Smm}
1651231200Smm
1652231200Smmstatic unsigned char
1653248616Smmlha_calcsum(unsigned char sum, const void *pp, int offset, size_t size)
1654231200Smm{
1655231200Smm	unsigned char const *p = (unsigned char const *)pp;
1656231200Smm
1657231200Smm	p += offset;
1658248616Smm	for (;size > 0; --size)
1659231200Smm		sum += *p++;
1660231200Smm	return (sum);
1661231200Smm}
1662231200Smm
1663299529Smmstatic uint16_t crc16tbl[2][256];
1664299529Smmstatic void
1665299529Smmlha_crc16_init(void)
1666299529Smm{
1667299529Smm	unsigned int i;
1668299529Smm	static int crc16init = 0;
1669231200Smm
1670299529Smm	if (crc16init)
1671299529Smm		return;
1672299529Smm	crc16init = 1;
1673299529Smm
1674299529Smm	for (i = 0; i < 256; i++) {
1675299529Smm		unsigned int j;
1676299529Smm		uint16_t crc = (uint16_t)i;
1677299529Smm		for (j = 8; j; j--)
1678299529Smm			crc = (crc >> 1) ^ ((crc & 1) * 0xA001);
1679299529Smm		crc16tbl[0][i] = crc;
1680299529Smm	}
1681299529Smm
1682299529Smm	for (i = 0; i < 256; i++) {
1683299529Smm		crc16tbl[1][i] = (crc16tbl[0][i] >> 8)
1684299529Smm			^ crc16tbl[0][crc16tbl[0][i] & 0xff];
1685299529Smm	}
1686299529Smm}
1687299529Smm
1688231200Smmstatic uint16_t
1689231200Smmlha_crc16(uint16_t crc, const void *pp, size_t len)
1690231200Smm{
1691299529Smm	const unsigned char *p = (const unsigned char *)pp;
1692299529Smm	const uint16_t *buff;
1693299529Smm	const union {
1694299529Smm		uint32_t i;
1695299529Smm		char c[4];
1696299529Smm	} u = { 0x01020304 };
1697231200Smm
1698299529Smm	if (len == 0)
1699299529Smm		return crc;
1700299529Smm
1701299529Smm	/* Process unaligned address. */
1702299529Smm	if (((uintptr_t)p) & (uintptr_t)0x1) {
1703299529Smm		crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
1704299529Smm		len--;
1705231200Smm	}
1706299529Smm	buff = (const uint16_t *)p;
1707299529Smm	/*
1708299529Smm	 * Modern C compiler such as GCC does not unroll automatically yet
1709299529Smm	 * without unrolling pragma, and Clang is so. So we should
1710299529Smm	 * unroll this loop for its performance.
1711299529Smm	 */
1712299529Smm	for (;len >= 8; len -= 8) {
1713299529Smm		/* This if statement expects compiler optimization will
1714299529Smm		 * remove the stament which will not be executed. */
1715302075Smm#undef bswap16
1716299529Smm#if defined(_MSC_VER) && _MSC_VER >= 1400  /* Visual Studio */
1717299529Smm#  define bswap16(x) _byteswap_ushort(x)
1718305313Smm#elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ > 4)
1719305313Smm/* GCC 4.8 and later has __builtin_bswap16() */
1720299529Smm#  define bswap16(x) __builtin_bswap16(x)
1721305313Smm#elif defined(__clang__)
1722305313Smm/* All clang versions have __builtin_bswap16() */
1723305313Smm#  define bswap16(x) __builtin_bswap16(x)
1724299529Smm#else
1725299529Smm#  define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
1726299529Smm#endif
1727299529Smm#define CRC16W	do { 	\
1728299529Smm		if(u.c[0] == 1) { /* Big endian */		\
1729299529Smm			crc ^= bswap16(*buff); buff++;		\
1730299529Smm		} else						\
1731299529Smm			crc ^= *buff++;				\
1732299529Smm		crc = crc16tbl[1][crc & 0xff] ^ crc16tbl[0][crc >> 8];\
1733299529Smm} while (0)
1734299529Smm		CRC16W;
1735299529Smm		CRC16W;
1736299529Smm		CRC16W;
1737299529Smm		CRC16W;
1738299529Smm#undef CRC16W
1739299529Smm#undef bswap16
1740231200Smm	}
1741299529Smm
1742299529Smm	p = (const unsigned char *)buff;
1743299529Smm	for (;len; len--) {
1744299529Smm		crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
1745299529Smm	}
1746299529Smm	return crc;
1747231200Smm}
1748231200Smm
1749231200Smm/*
1750231200Smm * Initialize LZHUF decoder.
1751231200Smm *
1752231200Smm * Returns ARCHIVE_OK if initialization was successful.
1753231200Smm * Returns ARCHIVE_FAILED if method is unsupported.
1754231200Smm * Returns ARCHIVE_FATAL if initialization failed; memory allocation
1755231200Smm * error occurred.
1756231200Smm */
1757231200Smmstatic int
1758231200Smmlzh_decode_init(struct lzh_stream *strm, const char *method)
1759231200Smm{
1760231200Smm	struct lzh_dec *ds;
1761231200Smm	int w_bits, w_size;
1762231200Smm
1763231200Smm	if (strm->ds == NULL) {
1764231200Smm		strm->ds = calloc(1, sizeof(*strm->ds));
1765231200Smm		if (strm->ds == NULL)
1766231200Smm			return (ARCHIVE_FATAL);
1767231200Smm	}
1768231200Smm	ds = strm->ds;
1769231200Smm	ds->error = ARCHIVE_FAILED;
1770231200Smm	if (method == NULL || method[0] != 'l' || method[1] != 'h')
1771231200Smm		return (ARCHIVE_FAILED);
1772231200Smm	switch (method[2]) {
1773231200Smm	case '5':
1774231200Smm		w_bits = 13;/* 8KiB for window */
1775231200Smm		break;
1776231200Smm	case '6':
1777231200Smm		w_bits = 15;/* 32KiB for window */
1778231200Smm		break;
1779231200Smm	case '7':
1780231200Smm		w_bits = 16;/* 64KiB for window */
1781231200Smm		break;
1782231200Smm	default:
1783231200Smm		return (ARCHIVE_FAILED);/* Not supported. */
1784231200Smm	}
1785231200Smm	ds->error = ARCHIVE_FATAL;
1786299529Smm	/* Expand a window size up to 128 KiB for decompressing process
1787299529Smm	 * performance whatever its original window size is. */
1788299529Smm	ds->w_size = 1U << 17;
1789231200Smm	ds->w_mask = ds->w_size -1;
1790299529Smm	if (ds->w_buff == NULL) {
1791231200Smm		ds->w_buff = malloc(ds->w_size);
1792231200Smm		if (ds->w_buff == NULL)
1793231200Smm			return (ARCHIVE_FATAL);
1794231200Smm	}
1795299529Smm	w_size = 1U << w_bits;
1796299529Smm	memset(ds->w_buff + ds->w_size - w_size, 0x20, w_size);
1797231200Smm	ds->w_pos = 0;
1798231200Smm	ds->state = 0;
1799231200Smm	ds->pos_pt_len_size = w_bits + 1;
1800231200Smm	ds->pos_pt_len_bits = (w_bits == 15 || w_bits == 16)? 5: 4;
1801231200Smm	ds->literal_pt_len_size = PT_BITLEN_SIZE;
1802231200Smm	ds->literal_pt_len_bits = 5;
1803231200Smm	ds->br.cache_buffer = 0;
1804231200Smm	ds->br.cache_avail = 0;
1805231200Smm
1806231200Smm	if (lzh_huffman_init(&(ds->lt), LT_BITLEN_SIZE, 16)
1807231200Smm	    != ARCHIVE_OK)
1808231200Smm		return (ARCHIVE_FATAL);
1809231200Smm	ds->lt.len_bits = 9;
1810231200Smm	if (lzh_huffman_init(&(ds->pt), PT_BITLEN_SIZE, 16)
1811231200Smm	    != ARCHIVE_OK)
1812231200Smm		return (ARCHIVE_FATAL);
1813231200Smm	ds->error = 0;
1814231200Smm
1815231200Smm	return (ARCHIVE_OK);
1816231200Smm}
1817231200Smm
1818231200Smm/*
1819231200Smm * Release LZHUF decoder.
1820231200Smm */
1821231200Smmstatic void
1822231200Smmlzh_decode_free(struct lzh_stream *strm)
1823231200Smm{
1824231200Smm
1825231200Smm	if (strm->ds == NULL)
1826231200Smm		return;
1827231200Smm	free(strm->ds->w_buff);
1828231200Smm	lzh_huffman_free(&(strm->ds->lt));
1829231200Smm	lzh_huffman_free(&(strm->ds->pt));
1830231200Smm	free(strm->ds);
1831231200Smm	strm->ds = NULL;
1832231200Smm}
1833231200Smm
1834231200Smm/*
1835231200Smm * Bit stream reader.
1836231200Smm */
1837231200Smm/* Check that the cache buffer has enough bits. */
1838231200Smm#define lzh_br_has(br, n)	((br)->cache_avail >= n)
1839231200Smm/* Get compressed data by bit. */
1840231200Smm#define lzh_br_bits(br, n)				\
1841231200Smm	(((uint16_t)((br)->cache_buffer >>		\
1842231200Smm		((br)->cache_avail - (n)))) & cache_masks[n])
1843231200Smm#define lzh_br_bits_forced(br, n)			\
1844231200Smm	(((uint16_t)((br)->cache_buffer <<		\
1845231200Smm		((n) - (br)->cache_avail))) & cache_masks[n])
1846231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we
1847231200Smm * will use.
1848231200Smm *  True  : completed, there is enough data in the cache buffer.
1849231200Smm *  False : we met that strm->next_in is empty, we have to get following
1850231200Smm *          bytes. */
1851231200Smm#define lzh_br_read_ahead_0(strm, br, n)	\
1852231200Smm	(lzh_br_has(br, (n)) || lzh_br_fillup(strm, br))
1853231200Smm/*  True  : the cache buffer has some bits as much as we need.
1854231200Smm *  False : there are no enough bits in the cache buffer to be used,
1855231200Smm *          we have to get following bytes if we could. */
1856231200Smm#define lzh_br_read_ahead(strm, br, n)	\
1857231200Smm	(lzh_br_read_ahead_0((strm), (br), (n)) || lzh_br_has((br), (n)))
1858231200Smm
1859231200Smm/* Notify how many bits we consumed. */
1860231200Smm#define lzh_br_consume(br, n)	((br)->cache_avail -= (n))
1861231200Smm#define lzh_br_unconsume(br, n)	((br)->cache_avail += (n))
1862231200Smm
1863231200Smmstatic const uint16_t cache_masks[] = {
1864231200Smm	0x0000, 0x0001, 0x0003, 0x0007,
1865231200Smm	0x000F, 0x001F, 0x003F, 0x007F,
1866231200Smm	0x00FF, 0x01FF, 0x03FF, 0x07FF,
1867231200Smm	0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
1868231200Smm	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
1869231200Smm};
1870231200Smm
1871231200Smm/*
1872231200Smm * Shift away used bits in the cache data and fill it up with following bits.
1873231200Smm * Call this when cache buffer does not have enough bits you need.
1874231200Smm *
1875231200Smm * Returns 1 if the cache buffer is full.
1876231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty.
1877231200Smm */
1878231200Smmstatic int
1879231200Smmlzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
1880231200Smm{
1881231200Smm	int n = CACHE_BITS - br->cache_avail;
1882231200Smm
1883231200Smm	for (;;) {
1884299529Smm		const int x = n >> 3;
1885299529Smm		if (strm->avail_in >= x) {
1886299529Smm			switch (x) {
1887299529Smm			case 8:
1888231200Smm				br->cache_buffer =
1889231200Smm				    ((uint64_t)strm->next_in[0]) << 56 |
1890231200Smm				    ((uint64_t)strm->next_in[1]) << 48 |
1891231200Smm				    ((uint64_t)strm->next_in[2]) << 40 |
1892231200Smm				    ((uint64_t)strm->next_in[3]) << 32 |
1893231200Smm				    ((uint32_t)strm->next_in[4]) << 24 |
1894231200Smm				    ((uint32_t)strm->next_in[5]) << 16 |
1895231200Smm				    ((uint32_t)strm->next_in[6]) << 8 |
1896231200Smm				     (uint32_t)strm->next_in[7];
1897231200Smm				strm->next_in += 8;
1898231200Smm				strm->avail_in -= 8;
1899231200Smm				br->cache_avail += 8 * 8;
1900231200Smm				return (1);
1901299529Smm			case 7:
1902231200Smm				br->cache_buffer =
1903231200Smm		 		   (br->cache_buffer << 56) |
1904231200Smm				    ((uint64_t)strm->next_in[0]) << 48 |
1905231200Smm				    ((uint64_t)strm->next_in[1]) << 40 |
1906231200Smm				    ((uint64_t)strm->next_in[2]) << 32 |
1907231200Smm				    ((uint32_t)strm->next_in[3]) << 24 |
1908231200Smm				    ((uint32_t)strm->next_in[4]) << 16 |
1909231200Smm				    ((uint32_t)strm->next_in[5]) << 8 |
1910231200Smm				     (uint32_t)strm->next_in[6];
1911231200Smm				strm->next_in += 7;
1912231200Smm				strm->avail_in -= 7;
1913231200Smm				br->cache_avail += 7 * 8;
1914231200Smm				return (1);
1915299529Smm			case 6:
1916231200Smm				br->cache_buffer =
1917231200Smm		 		   (br->cache_buffer << 48) |
1918231200Smm				    ((uint64_t)strm->next_in[0]) << 40 |
1919231200Smm				    ((uint64_t)strm->next_in[1]) << 32 |
1920231200Smm				    ((uint32_t)strm->next_in[2]) << 24 |
1921231200Smm				    ((uint32_t)strm->next_in[3]) << 16 |
1922231200Smm				    ((uint32_t)strm->next_in[4]) << 8 |
1923231200Smm				     (uint32_t)strm->next_in[5];
1924231200Smm				strm->next_in += 6;
1925231200Smm				strm->avail_in -= 6;
1926231200Smm				br->cache_avail += 6 * 8;
1927231200Smm				return (1);
1928299529Smm			case 0:
1929299529Smm				/* We have enough compressed data in
1930299529Smm				 * the cache buffer.*/
1931299529Smm				return (1);
1932299529Smm			default:
1933299529Smm				break;
1934231200Smm			}
1935231200Smm		}
1936231200Smm		if (strm->avail_in == 0) {
1937231200Smm			/* There is not enough compressed data to fill up the
1938231200Smm			 * cache buffer. */
1939231200Smm			return (0);
1940231200Smm		}
1941231200Smm		br->cache_buffer =
1942231200Smm		   (br->cache_buffer << 8) | *strm->next_in++;
1943231200Smm		strm->avail_in--;
1944231200Smm		br->cache_avail += 8;
1945231200Smm		n -= 8;
1946231200Smm	}
1947231200Smm}
1948231200Smm
1949231200Smm/*
1950231200Smm * Decode LZHUF.
1951231200Smm *
1952231200Smm * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
1953231200Smm *    Please set available buffer and call this function again.
1954231200Smm * 2. Returns ARCHIVE_EOF if decompression has been completed.
1955231200Smm * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
1956231200Smm *    is broken or you do not set 'last' flag properly.
1957231200Smm * 4. 'last' flag is very important, you must set 1 to the flag if there
1958231200Smm *    is no input data. The lha compressed data format does not provide how
1959231200Smm *    to know the compressed data is really finished.
1960231200Smm *    Note: lha command utility check if the total size of output bytes is
1961231200Smm *    reached the uncompressed size recorded in its header. it does not mind
1962231200Smm *    that the decoding process is properly finished.
1963231200Smm *    GNU ZIP can decompress another compressed file made by SCO LZH compress.
1964231200Smm *    it handles EOF as null to fill read buffer with zero until the decoding
1965231200Smm *    process meet 2 bytes of zeros at reading a size of a next chunk, so the
1966231200Smm *    zeros are treated as the mark of the end of the data although the zeros
1967231200Smm *    is dummy, not the file data.
1968231200Smm */
1969231200Smmstatic int	lzh_read_blocks(struct lzh_stream *, int);
1970231200Smmstatic int	lzh_decode_blocks(struct lzh_stream *, int);
1971231200Smm#define ST_RD_BLOCK		0
1972231200Smm#define ST_RD_PT_1		1
1973231200Smm#define ST_RD_PT_2		2
1974231200Smm#define ST_RD_PT_3		3
1975231200Smm#define ST_RD_PT_4		4
1976231200Smm#define ST_RD_LITERAL_1		5
1977231200Smm#define ST_RD_LITERAL_2		6
1978231200Smm#define ST_RD_LITERAL_3		7
1979231200Smm#define ST_RD_POS_DATA_1	8
1980231200Smm#define ST_GET_LITERAL		9
1981231200Smm#define ST_GET_POS_1		10
1982231200Smm#define ST_GET_POS_2		11
1983231200Smm#define ST_COPY_DATA		12
1984231200Smm
1985231200Smmstatic int
1986231200Smmlzh_decode(struct lzh_stream *strm, int last)
1987231200Smm{
1988231200Smm	struct lzh_dec *ds = strm->ds;
1989299529Smm	int avail_in;
1990231200Smm	int r;
1991231200Smm
1992231200Smm	if (ds->error)
1993231200Smm		return (ds->error);
1994231200Smm
1995231200Smm	avail_in = strm->avail_in;
1996231200Smm	do {
1997231200Smm		if (ds->state < ST_GET_LITERAL)
1998231200Smm			r = lzh_read_blocks(strm, last);
1999231200Smm		else
2000231200Smm			r = lzh_decode_blocks(strm, last);
2001231200Smm	} while (r == 100);
2002231200Smm	strm->total_in += avail_in - strm->avail_in;
2003231200Smm	return (r);
2004231200Smm}
2005231200Smm
2006299529Smmstatic void
2007299529Smmlzh_emit_window(struct lzh_stream *strm, size_t s)
2008231200Smm{
2009299529Smm	strm->ref_ptr = strm->ds->w_buff;
2010299529Smm	strm->avail_out = (int)s;
2011299529Smm	strm->total_out += s;
2012231200Smm}
2013231200Smm
2014231200Smmstatic int
2015231200Smmlzh_read_blocks(struct lzh_stream *strm, int last)
2016231200Smm{
2017231200Smm	struct lzh_dec *ds = strm->ds;
2018231200Smm	struct lzh_br *br = &(ds->br);
2019231200Smm	int c = 0, i;
2020231200Smm	unsigned rbits;
2021231200Smm
2022231200Smm	for (;;) {
2023231200Smm		switch (ds->state) {
2024231200Smm		case ST_RD_BLOCK:
2025231200Smm			/*
2026231200Smm			 * Read a block number indicates how many blocks
2027231200Smm			 * we will handle. The block is composed of a
2028231200Smm			 * literal and a match, sometimes a literal only
2029231200Smm			 * in particular, there are no reference data at
2030231200Smm			 * the beginning of the decompression.
2031231200Smm			 */
2032231200Smm			if (!lzh_br_read_ahead_0(strm, br, 16)) {
2033231200Smm				if (!last)
2034231200Smm					/* We need following data. */
2035231200Smm					return (ARCHIVE_OK);
2036231200Smm				if (lzh_br_has(br, 8)) {
2037231200Smm					/*
2038231200Smm					 * It seems there are extra bits.
2039231200Smm					 *  1. Compressed data is broken.
2040231200Smm					 *  2. `last' flag does not properly
2041231200Smm					 *     set.
2042231200Smm					 */
2043231200Smm					goto failed;
2044231200Smm				}
2045231200Smm				if (ds->w_pos > 0) {
2046299529Smm					lzh_emit_window(strm, ds->w_pos);
2047299529Smm					ds->w_pos = 0;
2048299529Smm					return (ARCHIVE_OK);
2049231200Smm				}
2050231200Smm				/* End of compressed data; we have completely
2051231200Smm				 * handled all compressed data. */
2052231200Smm				return (ARCHIVE_EOF);
2053231200Smm			}
2054231200Smm			ds->blocks_avail = lzh_br_bits(br, 16);
2055231200Smm			if (ds->blocks_avail == 0)
2056231200Smm				goto failed;
2057231200Smm			lzh_br_consume(br, 16);
2058231200Smm			/*
2059231200Smm			 * Read a literal table compressed in huffman
2060231200Smm			 * coding.
2061231200Smm			 */
2062231200Smm			ds->pt.len_size = ds->literal_pt_len_size;
2063231200Smm			ds->pt.len_bits = ds->literal_pt_len_bits;
2064231200Smm			ds->reading_position = 0;
2065231200Smm			/* FALL THROUGH */
2066231200Smm		case ST_RD_PT_1:
2067231200Smm			/* Note: ST_RD_PT_1, ST_RD_PT_2 and ST_RD_PT_4 are
2068231200Smm			 * used in reading both a literal table and a
2069231200Smm			 * position table. */
2070231200Smm			if (!lzh_br_read_ahead(strm, br, ds->pt.len_bits)) {
2071231200Smm				if (last)
2072231200Smm					goto failed;/* Truncated data. */
2073231200Smm				ds->state = ST_RD_PT_1;
2074231200Smm				return (ARCHIVE_OK);
2075231200Smm			}
2076231200Smm			ds->pt.len_avail = lzh_br_bits(br, ds->pt.len_bits);
2077231200Smm			lzh_br_consume(br, ds->pt.len_bits);
2078231200Smm			/* FALL THROUGH */
2079231200Smm		case ST_RD_PT_2:
2080231200Smm			if (ds->pt.len_avail == 0) {
2081231200Smm				/* There is no bitlen. */
2082231200Smm				if (!lzh_br_read_ahead(strm, br,
2083231200Smm				    ds->pt.len_bits)) {
2084231200Smm					if (last)
2085231200Smm						goto failed;/* Truncated data.*/
2086231200Smm					ds->state = ST_RD_PT_2;
2087231200Smm					return (ARCHIVE_OK);
2088231200Smm				}
2089231200Smm				if (!lzh_make_fake_table(&(ds->pt),
2090231200Smm				    lzh_br_bits(br, ds->pt.len_bits)))
2091231200Smm					goto failed;/* Invalid data. */
2092231200Smm				lzh_br_consume(br, ds->pt.len_bits);
2093231200Smm				if (ds->reading_position)
2094231200Smm					ds->state = ST_GET_LITERAL;
2095231200Smm				else
2096231200Smm					ds->state = ST_RD_LITERAL_1;
2097231200Smm				break;
2098231200Smm			} else if (ds->pt.len_avail > ds->pt.len_size)
2099231200Smm				goto failed;/* Invalid data. */
2100231200Smm			ds->loop = 0;
2101231200Smm			memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
2102231200Smm			if (ds->pt.len_avail < 3 ||
2103231200Smm			    ds->pt.len_size == ds->pos_pt_len_size) {
2104231200Smm				ds->state = ST_RD_PT_4;
2105231200Smm				break;
2106231200Smm			}
2107231200Smm			/* FALL THROUGH */
2108231200Smm		case ST_RD_PT_3:
2109231200Smm			ds->loop = lzh_read_pt_bitlen(strm, ds->loop, 3);
2110231200Smm			if (ds->loop < 3) {
2111231200Smm				if (ds->loop < 0 || last)
2112231200Smm					goto failed;/* Invalid data. */
2113231200Smm				/* Not completed, get following data. */
2114231200Smm				ds->state = ST_RD_PT_3;
2115231200Smm				return (ARCHIVE_OK);
2116231200Smm			}
2117231200Smm			/* There are some null in bitlen of the literal. */
2118231200Smm			if (!lzh_br_read_ahead(strm, br, 2)) {
2119231200Smm				if (last)
2120231200Smm					goto failed;/* Truncated data. */
2121231200Smm				ds->state = ST_RD_PT_3;
2122231200Smm				return (ARCHIVE_OK);
2123231200Smm			}
2124231200Smm			c = lzh_br_bits(br, 2);
2125231200Smm			lzh_br_consume(br, 2);
2126231200Smm			if (c > ds->pt.len_avail - 3)
2127231200Smm				goto failed;/* Invalid data. */
2128231200Smm			for (i = 3; c-- > 0 ;)
2129231200Smm				ds->pt.bitlen[i++] = 0;
2130231200Smm			ds->loop = i;
2131231200Smm			/* FALL THROUGH */
2132231200Smm		case ST_RD_PT_4:
2133231200Smm			ds->loop = lzh_read_pt_bitlen(strm, ds->loop,
2134231200Smm			    ds->pt.len_avail);
2135231200Smm			if (ds->loop < ds->pt.len_avail) {
2136231200Smm				if (ds->loop < 0 || last)
2137231200Smm					goto failed;/* Invalid data. */
2138231200Smm				/* Not completed, get following data. */
2139231200Smm				ds->state = ST_RD_PT_4;
2140231200Smm				return (ARCHIVE_OK);
2141231200Smm			}
2142231200Smm			if (!lzh_make_huffman_table(&(ds->pt)))
2143231200Smm				goto failed;/* Invalid data */
2144231200Smm			if (ds->reading_position) {
2145231200Smm				ds->state = ST_GET_LITERAL;
2146231200Smm				break;
2147231200Smm			}
2148231200Smm			/* FALL THROUGH */
2149231200Smm		case ST_RD_LITERAL_1:
2150231200Smm			if (!lzh_br_read_ahead(strm, br, ds->lt.len_bits)) {
2151231200Smm				if (last)
2152231200Smm					goto failed;/* Truncated data. */
2153231200Smm				ds->state = ST_RD_LITERAL_1;
2154231200Smm				return (ARCHIVE_OK);
2155231200Smm			}
2156231200Smm			ds->lt.len_avail = lzh_br_bits(br, ds->lt.len_bits);
2157231200Smm			lzh_br_consume(br, ds->lt.len_bits);
2158231200Smm			/* FALL THROUGH */
2159231200Smm		case ST_RD_LITERAL_2:
2160231200Smm			if (ds->lt.len_avail == 0) {
2161231200Smm				/* There is no bitlen. */
2162231200Smm				if (!lzh_br_read_ahead(strm, br,
2163231200Smm				    ds->lt.len_bits)) {
2164231200Smm					if (last)
2165231200Smm						goto failed;/* Truncated data.*/
2166231200Smm					ds->state = ST_RD_LITERAL_2;
2167231200Smm					return (ARCHIVE_OK);
2168231200Smm				}
2169231200Smm				if (!lzh_make_fake_table(&(ds->lt),
2170231200Smm				    lzh_br_bits(br, ds->lt.len_bits)))
2171231200Smm					goto failed;/* Invalid data */
2172231200Smm				lzh_br_consume(br, ds->lt.len_bits);
2173231200Smm				ds->state = ST_RD_POS_DATA_1;
2174231200Smm				break;
2175231200Smm			} else if (ds->lt.len_avail > ds->lt.len_size)
2176231200Smm				goto failed;/* Invalid data */
2177231200Smm			ds->loop = 0;
2178231200Smm			memset(ds->lt.freq, 0, sizeof(ds->lt.freq));
2179231200Smm			/* FALL THROUGH */
2180231200Smm		case ST_RD_LITERAL_3:
2181231200Smm			i = ds->loop;
2182231200Smm			while (i < ds->lt.len_avail) {
2183231200Smm				if (!lzh_br_read_ahead(strm, br,
2184231200Smm				    ds->pt.max_bits)) {
2185231200Smm					if (last)
2186231200Smm						goto failed;/* Truncated data.*/
2187231200Smm					ds->loop = i;
2188231200Smm					ds->state = ST_RD_LITERAL_3;
2189231200Smm					return (ARCHIVE_OK);
2190231200Smm				}
2191231200Smm				rbits = lzh_br_bits(br, ds->pt.max_bits);
2192231200Smm				c = lzh_decode_huffman(&(ds->pt), rbits);
2193231200Smm				if (c > 2) {
2194231200Smm					/* Note: 'c' will never be more than
2195231200Smm					 * eighteen since it's limited by
2196231200Smm					 * PT_BITLEN_SIZE, which is being set
2197231200Smm					 * to ds->pt.len_size through
2198231200Smm					 * ds->literal_pt_len_size. */
2199231200Smm					lzh_br_consume(br, ds->pt.bitlen[c]);
2200231200Smm					c -= 2;
2201231200Smm					ds->lt.freq[c]++;
2202231200Smm					ds->lt.bitlen[i++] = c;
2203231200Smm				} else if (c == 0) {
2204231200Smm					lzh_br_consume(br, ds->pt.bitlen[c]);
2205231200Smm					ds->lt.bitlen[i++] = 0;
2206231200Smm				} else {
2207231200Smm					/* c == 1 or c == 2 */
2208231200Smm					int n = (c == 1)?4:9;
2209231200Smm					if (!lzh_br_read_ahead(strm, br,
2210231200Smm					     ds->pt.bitlen[c] + n)) {
2211231200Smm						if (last) /* Truncated data. */
2212231200Smm							goto failed;
2213231200Smm						ds->loop = i;
2214231200Smm						ds->state = ST_RD_LITERAL_3;
2215231200Smm						return (ARCHIVE_OK);
2216231200Smm					}
2217231200Smm					lzh_br_consume(br, ds->pt.bitlen[c]);
2218231200Smm					c = lzh_br_bits(br, n);
2219231200Smm					lzh_br_consume(br, n);
2220231200Smm					c += (n == 4)?3:20;
2221231200Smm					if (i + c > ds->lt.len_avail)
2222231200Smm						goto failed;/* Invalid data */
2223231200Smm					memset(&(ds->lt.bitlen[i]), 0, c);
2224231200Smm					i += c;
2225231200Smm				}
2226231200Smm			}
2227231200Smm			if (i > ds->lt.len_avail ||
2228231200Smm			    !lzh_make_huffman_table(&(ds->lt)))
2229231200Smm				goto failed;/* Invalid data */
2230231200Smm			/* FALL THROUGH */
2231231200Smm		case ST_RD_POS_DATA_1:
2232231200Smm			/*
2233231200Smm			 * Read a position table compressed in huffman
2234231200Smm			 * coding.
2235231200Smm			 */
2236231200Smm			ds->pt.len_size = ds->pos_pt_len_size;
2237231200Smm			ds->pt.len_bits = ds->pos_pt_len_bits;
2238231200Smm			ds->reading_position = 1;
2239231200Smm			ds->state = ST_RD_PT_1;
2240231200Smm			break;
2241231200Smm		case ST_GET_LITERAL:
2242231200Smm			return (100);
2243231200Smm		}
2244231200Smm	}
2245231200Smmfailed:
2246231200Smm	return (ds->error = ARCHIVE_FAILED);
2247231200Smm}
2248231200Smm
2249231200Smmstatic int
2250231200Smmlzh_decode_blocks(struct lzh_stream *strm, int last)
2251231200Smm{
2252231200Smm	struct lzh_dec *ds = strm->ds;
2253231200Smm	struct lzh_br bre = ds->br;
2254231200Smm	struct huffman *lt = &(ds->lt);
2255231200Smm	struct huffman *pt = &(ds->pt);
2256231200Smm	unsigned char *w_buff = ds->w_buff;
2257231200Smm	unsigned char *lt_bitlen = lt->bitlen;
2258231200Smm	unsigned char *pt_bitlen = pt->bitlen;
2259231200Smm	int blocks_avail = ds->blocks_avail, c = 0;
2260231200Smm	int copy_len = ds->copy_len, copy_pos = ds->copy_pos;
2261231200Smm	int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
2262231200Smm	int lt_max_bits = lt->max_bits, pt_max_bits = pt->max_bits;
2263231200Smm	int state = ds->state;
2264231200Smm
2265231200Smm	for (;;) {
2266231200Smm		switch (state) {
2267231200Smm		case ST_GET_LITERAL:
2268231200Smm			for (;;) {
2269231200Smm				if (blocks_avail == 0) {
2270231200Smm					/* We have decoded all blocks.
2271231200Smm					 * Let's handle next blocks. */
2272231200Smm					ds->state = ST_RD_BLOCK;
2273231200Smm					ds->br = bre;
2274231200Smm					ds->blocks_avail = 0;
2275231200Smm					ds->w_pos = w_pos;
2276231200Smm					ds->copy_pos = 0;
2277231200Smm					return (100);
2278231200Smm				}
2279231200Smm
2280231200Smm				/* lzh_br_read_ahead() always try to fill the
2281231200Smm				 * cache buffer up. In specific situation we
2282231200Smm				 * are close to the end of the data, the cache
2283231200Smm				 * buffer will not be full and thus we have to
2284231200Smm				 * determine if the cache buffer has some bits
2285231200Smm				 * as much as we need after lzh_br_read_ahead()
2286231200Smm				 * failed. */
2287231200Smm				if (!lzh_br_read_ahead(strm, &bre,
2288231200Smm				    lt_max_bits)) {
2289231200Smm					if (!last)
2290231200Smm						goto next_data;
2291231200Smm					/* Remaining bits are less than
2292231200Smm					 * maximum bits(lt.max_bits) but maybe
2293231200Smm					 * it still remains as much as we need,
2294231200Smm					 * so we should try to use it with
2295231200Smm					 * dummy bits. */
2296231200Smm					c = lzh_decode_huffman(lt,
2297231200Smm					      lzh_br_bits_forced(&bre,
2298231200Smm					        lt_max_bits));
2299231200Smm					lzh_br_consume(&bre, lt_bitlen[c]);
2300231200Smm					if (!lzh_br_has(&bre, 0))
2301231200Smm						goto failed;/* Over read. */
2302231200Smm				} else {
2303231200Smm					c = lzh_decode_huffman(lt,
2304231200Smm					      lzh_br_bits(&bre, lt_max_bits));
2305231200Smm					lzh_br_consume(&bre, lt_bitlen[c]);
2306231200Smm				}
2307231200Smm				blocks_avail--;
2308231200Smm				if (c > UCHAR_MAX)
2309231200Smm					/* Current block is a match data. */
2310231200Smm					break;
2311231200Smm				/*
2312231200Smm				 * 'c' is exactly a literal code.
2313231200Smm				 */
2314231200Smm				/* Save a decoded code to reference it
2315231200Smm				 * afterward. */
2316231200Smm				w_buff[w_pos] = c;
2317231200Smm				if (++w_pos >= w_size) {
2318231200Smm					w_pos = 0;
2319299529Smm					lzh_emit_window(strm, w_size);
2320299529Smm					goto next_data;
2321231200Smm				}
2322231200Smm			}
2323231200Smm			/* 'c' is the length of a match pattern we have
2324231200Smm			 * already extracted, which has be stored in
2325231200Smm			 * window(ds->w_buff). */
2326231200Smm			copy_len = c - (UCHAR_MAX + 1) + MINMATCH;
2327231200Smm			/* FALL THROUGH */
2328231200Smm		case ST_GET_POS_1:
2329231200Smm			/*
2330231200Smm			 * Get a reference position.
2331231200Smm			 */
2332231200Smm			if (!lzh_br_read_ahead(strm, &bre, pt_max_bits)) {
2333231200Smm				if (!last) {
2334231200Smm					state = ST_GET_POS_1;
2335231200Smm					ds->copy_len = copy_len;
2336231200Smm					goto next_data;
2337231200Smm				}
2338231200Smm				copy_pos = lzh_decode_huffman(pt,
2339231200Smm				    lzh_br_bits_forced(&bre, pt_max_bits));
2340231200Smm				lzh_br_consume(&bre, pt_bitlen[copy_pos]);
2341231200Smm				if (!lzh_br_has(&bre, 0))
2342231200Smm					goto failed;/* Over read. */
2343231200Smm			} else {
2344231200Smm				copy_pos = lzh_decode_huffman(pt,
2345231200Smm				    lzh_br_bits(&bre, pt_max_bits));
2346231200Smm				lzh_br_consume(&bre, pt_bitlen[copy_pos]);
2347231200Smm			}
2348231200Smm			/* FALL THROUGH */
2349231200Smm		case ST_GET_POS_2:
2350231200Smm			if (copy_pos > 1) {
2351231200Smm				/* We need an additional adjustment number to
2352231200Smm				 * the position. */
2353231200Smm				int p = copy_pos - 1;
2354231200Smm				if (!lzh_br_read_ahead(strm, &bre, p)) {
2355231200Smm					if (last)
2356231200Smm						goto failed;/* Truncated data.*/
2357231200Smm					state = ST_GET_POS_2;
2358231200Smm					ds->copy_len = copy_len;
2359231200Smm					ds->copy_pos = copy_pos;
2360231200Smm					goto next_data;
2361231200Smm				}
2362231200Smm				copy_pos = (1 << p) + lzh_br_bits(&bre, p);
2363231200Smm				lzh_br_consume(&bre, p);
2364231200Smm			}
2365231200Smm			/* The position is actually a distance from the last
2366231200Smm			 * code we had extracted and thus we have to convert
2367231200Smm			 * it to a position of the window. */
2368231200Smm			copy_pos = (w_pos - copy_pos - 1) & w_mask;
2369231200Smm			/* FALL THROUGH */
2370231200Smm		case ST_COPY_DATA:
2371231200Smm			/*
2372231200Smm			 * Copy `copy_len' bytes as extracted data from
2373231200Smm			 * the window into the output buffer.
2374231200Smm			 */
2375231200Smm			for (;;) {
2376231200Smm				int l;
2377231200Smm
2378231200Smm				l = copy_len;
2379231200Smm				if (copy_pos > w_pos) {
2380231200Smm					if (l > w_size - copy_pos)
2381231200Smm						l = w_size - copy_pos;
2382231200Smm				} else {
2383231200Smm					if (l > w_size - w_pos)
2384231200Smm						l = w_size - w_pos;
2385231200Smm				}
2386231200Smm				if ((copy_pos + l < w_pos)
2387231200Smm				    || (w_pos + l < copy_pos)) {
2388231200Smm					/* No overlap. */
2389231200Smm					memcpy(w_buff + w_pos,
2390231200Smm					    w_buff + copy_pos, l);
2391231200Smm				} else {
2392231200Smm					const unsigned char *s;
2393231200Smm					unsigned char *d;
2394231200Smm					int li;
2395231200Smm
2396231200Smm					d = w_buff + w_pos;
2397231200Smm					s = w_buff + copy_pos;
2398299529Smm					for (li = 0; li < l-1;) {
2399299529Smm						d[li] = s[li];li++;
2400299529Smm						d[li] = s[li];li++;
2401299529Smm					}
2402299529Smm					if (li < l)
2403231200Smm						d[li] = s[li];
2404231200Smm				}
2405299529Smm				w_pos += l;
2406299529Smm				if (w_pos == w_size) {
2407299529Smm					w_pos = 0;
2408299529Smm					lzh_emit_window(strm, w_size);
2409299529Smm					if (copy_len <= l)
2410299529Smm						state = ST_GET_LITERAL;
2411299529Smm					else {
2412299529Smm						state = ST_COPY_DATA;
2413299529Smm						ds->copy_len = copy_len - l;
2414299529Smm						ds->copy_pos =
2415299529Smm						    (copy_pos + l) & w_mask;
2416231200Smm					}
2417299529Smm					goto next_data;
2418231200Smm				}
2419231200Smm				if (copy_len <= l)
2420231200Smm					/* A copy of current pattern ended. */
2421231200Smm					break;
2422231200Smm				copy_len -= l;
2423231200Smm				copy_pos = (copy_pos + l) & w_mask;
2424231200Smm			}
2425231200Smm			state = ST_GET_LITERAL;
2426231200Smm			break;
2427231200Smm		}
2428231200Smm	}
2429231200Smmfailed:
2430231200Smm	return (ds->error = ARCHIVE_FAILED);
2431231200Smmnext_data:
2432231200Smm	ds->br = bre;
2433231200Smm	ds->blocks_avail = blocks_avail;
2434231200Smm	ds->state = state;
2435231200Smm	ds->w_pos = w_pos;
2436231200Smm	return (ARCHIVE_OK);
2437231200Smm}
2438231200Smm
2439231200Smmstatic int
2440231200Smmlzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
2441231200Smm{
2442231200Smm	int bits;
2443231200Smm
2444231200Smm	if (hf->bitlen == NULL) {
2445231200Smm		hf->bitlen = malloc(len_size * sizeof(hf->bitlen[0]));
2446231200Smm		if (hf->bitlen == NULL)
2447231200Smm			return (ARCHIVE_FATAL);
2448231200Smm	}
2449231200Smm	if (hf->tbl == NULL) {
2450231200Smm		if (tbl_bits < HTBL_BITS)
2451231200Smm			bits = tbl_bits;
2452231200Smm		else
2453231200Smm			bits = HTBL_BITS;
2454248616Smm		hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
2455231200Smm		if (hf->tbl == NULL)
2456231200Smm			return (ARCHIVE_FATAL);
2457231200Smm	}
2458231200Smm	if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
2459231200Smm		hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
2460231200Smm		hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
2461231200Smm		if (hf->tree == NULL)
2462231200Smm			return (ARCHIVE_FATAL);
2463231200Smm	}
2464248616Smm	hf->len_size = (int)len_size;
2465231200Smm	hf->tbl_bits = tbl_bits;
2466231200Smm	return (ARCHIVE_OK);
2467231200Smm}
2468231200Smm
2469231200Smmstatic void
2470231200Smmlzh_huffman_free(struct huffman *hf)
2471231200Smm{
2472231200Smm	free(hf->bitlen);
2473231200Smm	free(hf->tbl);
2474231200Smm	free(hf->tree);
2475231200Smm}
2476231200Smm
2477299529Smmstatic char bitlen_tbl[0x400] = {
2478299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2479299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2480299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2481299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2482299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2483299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2484299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2485299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2486299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2487299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2488299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2489299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2490299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2491299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2492299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2493299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2494299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2495299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2496299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2497299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2498299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2499299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2500299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2501299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2502299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2503299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2504299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2505299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2506299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2507299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2508299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2509299529Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2510299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2511299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2512299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2513299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2514299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2515299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2516299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2517299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2518299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2519299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2520299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2521299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2522299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2523299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2524299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2525299529Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2526299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2527299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2528299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2529299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2530299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2531299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2532299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2533299529Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2534299529Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2535299529Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2536299529Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2537299529Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2538299529Smm	11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2539299529Smm	11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2540299529Smm	12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2541299529Smm	13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16,  0
2542299529Smm};
2543231200Smmstatic int
2544231200Smmlzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end)
2545231200Smm{
2546231200Smm	struct lzh_dec *ds = strm->ds;
2547299529Smm	struct lzh_br *br = &(ds->br);
2548231200Smm	int c, i;
2549231200Smm
2550299529Smm	for (i = start; i < end; ) {
2551231200Smm		/*
2552231200Smm		 *  bit pattern     the number we need
2553231200Smm		 *     000           ->  0
2554231200Smm		 *     001           ->  1
2555231200Smm		 *     010           ->  2
2556231200Smm		 *     ...
2557231200Smm		 *     110           ->  6
2558231200Smm		 *     1110          ->  7
2559231200Smm		 *     11110         ->  8
2560231200Smm		 *     ...
2561231200Smm		 *     1111111111110 ->  16
2562231200Smm		 */
2563231200Smm		if (!lzh_br_read_ahead(strm, br, 3))
2564231200Smm			return (i);
2565231200Smm		if ((c = lzh_br_bits(br, 3)) == 7) {
2566231200Smm			if (!lzh_br_read_ahead(strm, br, 13))
2567231200Smm				return (i);
2568299529Smm			c = bitlen_tbl[lzh_br_bits(br, 13) & 0x3FF];
2569299529Smm			if (c)
2570299529Smm				lzh_br_consume(br, c - 3);
2571299529Smm			else
2572231200Smm				return (-1);/* Invalid data. */
2573231200Smm		} else
2574231200Smm			lzh_br_consume(br, 3);
2575231200Smm		ds->pt.bitlen[i++] = c;
2576231200Smm		ds->pt.freq[c]++;
2577231200Smm	}
2578231200Smm	return (i);
2579231200Smm}
2580231200Smm
2581231200Smmstatic int
2582231200Smmlzh_make_fake_table(struct huffman *hf, uint16_t c)
2583231200Smm{
2584231200Smm	if (c >= hf->len_size)
2585231200Smm		return (0);
2586231200Smm	hf->tbl[0] = c;
2587231200Smm	hf->max_bits = 0;
2588231200Smm	hf->shift_bits = 0;
2589231200Smm	hf->bitlen[hf->tbl[0]] = 0;
2590231200Smm	return (1);
2591231200Smm}
2592231200Smm
2593231200Smm/*
2594231200Smm * Make a huffman coding table.
2595231200Smm */
2596231200Smmstatic int
2597231200Smmlzh_make_huffman_table(struct huffman *hf)
2598231200Smm{
2599231200Smm	uint16_t *tbl;
2600231200Smm	const unsigned char *bitlen;
2601231200Smm	int bitptn[17], weight[17];
2602231200Smm	int i, maxbits = 0, ptn, tbl_size, w;
2603231200Smm	int diffbits, len_avail;
2604231200Smm
2605231200Smm	/*
2606231200Smm	 * Initialize bit patterns.
2607231200Smm	 */
2608231200Smm	ptn = 0;
2609231200Smm	for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
2610231200Smm		bitptn[i] = ptn;
2611231200Smm		weight[i] = w;
2612231200Smm		if (hf->freq[i]) {
2613231200Smm			ptn += hf->freq[i] * w;
2614231200Smm			maxbits = i;
2615231200Smm		}
2616231200Smm	}
2617231200Smm	if (ptn != 0x10000 || maxbits > hf->tbl_bits)
2618231200Smm		return (0);/* Invalid */
2619231200Smm
2620231200Smm	hf->max_bits = maxbits;
2621231200Smm
2622231200Smm	/*
2623231200Smm	 * Cut out extra bits which we won't house in the table.
2624231200Smm	 * This preparation reduces the same calculation in the for-loop
2625231200Smm	 * making the table.
2626231200Smm	 */
2627231200Smm	if (maxbits < 16) {
2628231200Smm		int ebits = 16 - maxbits;
2629231200Smm		for (i = 1; i <= maxbits; i++) {
2630231200Smm			bitptn[i] >>= ebits;
2631231200Smm			weight[i] >>= ebits;
2632231200Smm		}
2633231200Smm	}
2634231200Smm	if (maxbits > HTBL_BITS) {
2635299529Smm		unsigned htbl_max;
2636231200Smm		uint16_t *p;
2637231200Smm
2638231200Smm		diffbits = maxbits - HTBL_BITS;
2639231200Smm		for (i = 1; i <= HTBL_BITS; i++) {
2640231200Smm			bitptn[i] >>= diffbits;
2641231200Smm			weight[i] >>= diffbits;
2642231200Smm		}
2643231200Smm		htbl_max = bitptn[HTBL_BITS] +
2644231200Smm		    weight[HTBL_BITS] * hf->freq[HTBL_BITS];
2645231200Smm		p = &(hf->tbl[htbl_max]);
2646231200Smm		while (p < &hf->tbl[1U<<HTBL_BITS])
2647231200Smm			*p++ = 0;
2648231200Smm	} else
2649231200Smm		diffbits = 0;
2650231200Smm	hf->shift_bits = diffbits;
2651231200Smm
2652231200Smm	/*
2653231200Smm	 * Make the table.
2654231200Smm	 */
2655231200Smm	tbl_size = 1 << HTBL_BITS;
2656231200Smm	tbl = hf->tbl;
2657231200Smm	bitlen = hf->bitlen;
2658231200Smm	len_avail = hf->len_avail;
2659231200Smm	hf->tree_used = 0;
2660231200Smm	for (i = 0; i < len_avail; i++) {
2661231200Smm		uint16_t *p;
2662231200Smm		int len, cnt;
2663231200Smm		uint16_t bit;
2664231200Smm		int extlen;
2665231200Smm		struct htree_t *ht;
2666231200Smm
2667231200Smm		if (bitlen[i] == 0)
2668231200Smm			continue;
2669231200Smm		/* Get a bit pattern */
2670231200Smm		len = bitlen[i];
2671231200Smm		ptn = bitptn[len];
2672231200Smm		cnt = weight[len];
2673231200Smm		if (len <= HTBL_BITS) {
2674231200Smm			/* Calculate next bit pattern */
2675231200Smm			if ((bitptn[len] = ptn + cnt) > tbl_size)
2676231200Smm				return (0);/* Invalid */
2677231200Smm			/* Update the table */
2678231200Smm			p = &(tbl[ptn]);
2679299529Smm			if (cnt > 7) {
2680299529Smm				uint16_t *pc;
2681299529Smm
2682299529Smm				cnt -= 8;
2683299529Smm				pc = &p[cnt];
2684299529Smm				pc[0] = (uint16_t)i;
2685299529Smm				pc[1] = (uint16_t)i;
2686299529Smm				pc[2] = (uint16_t)i;
2687299529Smm				pc[3] = (uint16_t)i;
2688299529Smm				pc[4] = (uint16_t)i;
2689299529Smm				pc[5] = (uint16_t)i;
2690299529Smm				pc[6] = (uint16_t)i;
2691299529Smm				pc[7] = (uint16_t)i;
2692299529Smm				if (cnt > 7) {
2693299529Smm					cnt -= 8;
2694299529Smm					memcpy(&p[cnt], pc,
2695299529Smm						8 * sizeof(uint16_t));
2696299529Smm					pc = &p[cnt];
2697299529Smm					while (cnt > 15) {
2698299529Smm						cnt -= 16;
2699299529Smm						memcpy(&p[cnt], pc,
2700299529Smm							16 * sizeof(uint16_t));
2701299529Smm					}
2702299529Smm				}
2703299529Smm				if (cnt)
2704299529Smm					memcpy(p, pc, cnt * sizeof(uint16_t));
2705299529Smm			} else {
2706299529Smm				while (cnt > 1) {
2707299529Smm					p[--cnt] = (uint16_t)i;
2708299529Smm					p[--cnt] = (uint16_t)i;
2709299529Smm				}
2710299529Smm				if (cnt)
2711299529Smm					p[--cnt] = (uint16_t)i;
2712299529Smm			}
2713231200Smm			continue;
2714231200Smm		}
2715231200Smm
2716231200Smm		/*
2717231200Smm		 * A bit length is too big to be housed to a direct table,
2718231200Smm		 * so we use a tree model for its extra bits.
2719231200Smm		 */
2720231200Smm		bitptn[len] = ptn + cnt;
2721231200Smm		bit = 1U << (diffbits -1);
2722231200Smm		extlen = len - HTBL_BITS;
2723231200Smm
2724231200Smm		p = &(tbl[ptn >> diffbits]);
2725231200Smm		if (*p == 0) {
2726231200Smm			*p = len_avail + hf->tree_used;
2727231200Smm			ht = &(hf->tree[hf->tree_used++]);
2728231200Smm			if (hf->tree_used > hf->tree_avail)
2729231200Smm				return (0);/* Invalid */
2730231200Smm			ht->left = 0;
2731231200Smm			ht->right = 0;
2732231200Smm		} else {
2733231200Smm			if (*p < len_avail ||
2734231200Smm			    *p >= (len_avail + hf->tree_used))
2735231200Smm				return (0);/* Invalid */
2736231200Smm			ht = &(hf->tree[*p - len_avail]);
2737231200Smm		}
2738231200Smm		while (--extlen > 0) {
2739231200Smm			if (ptn & bit) {
2740231200Smm				if (ht->left < len_avail) {
2741231200Smm					ht->left = len_avail + hf->tree_used;
2742231200Smm					ht = &(hf->tree[hf->tree_used++]);
2743231200Smm					if (hf->tree_used > hf->tree_avail)
2744231200Smm						return (0);/* Invalid */
2745231200Smm					ht->left = 0;
2746231200Smm					ht->right = 0;
2747231200Smm				} else {
2748231200Smm					ht = &(hf->tree[ht->left - len_avail]);
2749231200Smm				}
2750231200Smm			} else {
2751231200Smm				if (ht->right < len_avail) {
2752231200Smm					ht->right = len_avail + hf->tree_used;
2753231200Smm					ht = &(hf->tree[hf->tree_used++]);
2754231200Smm					if (hf->tree_used > hf->tree_avail)
2755231200Smm						return (0);/* Invalid */
2756231200Smm					ht->left = 0;
2757231200Smm					ht->right = 0;
2758231200Smm				} else {
2759231200Smm					ht = &(hf->tree[ht->right - len_avail]);
2760231200Smm				}
2761231200Smm			}
2762231200Smm			bit >>= 1;
2763231200Smm		}
2764231200Smm		if (ptn & bit) {
2765231200Smm			if (ht->left != 0)
2766231200Smm				return (0);/* Invalid */
2767231200Smm			ht->left = (uint16_t)i;
2768231200Smm		} else {
2769231200Smm			if (ht->right != 0)
2770231200Smm				return (0);/* Invalid */
2771231200Smm			ht->right = (uint16_t)i;
2772231200Smm		}
2773231200Smm	}
2774231200Smm	return (1);
2775231200Smm}
2776231200Smm
2777231200Smmstatic int
2778231200Smmlzh_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
2779231200Smm{
2780231200Smm	struct htree_t *ht;
2781231200Smm	int extlen;
2782231200Smm
2783231200Smm	ht = hf->tree;
2784231200Smm	extlen = hf->shift_bits;
2785231200Smm	while (c >= hf->len_avail) {
2786231200Smm		c -= hf->len_avail;
2787231200Smm		if (extlen-- <= 0 || c >= hf->tree_used)
2788231200Smm			return (0);
2789231200Smm		if (rbits & (1U << extlen))
2790231200Smm			c = ht[c].left;
2791231200Smm		else
2792231200Smm			c = ht[c].right;
2793231200Smm	}
2794231200Smm	return (c);
2795231200Smm}
2796231200Smm
2797231200Smmstatic inline int
2798231200Smmlzh_decode_huffman(struct huffman *hf, unsigned rbits)
2799231200Smm{
2800231200Smm	int c;
2801231200Smm	/*
2802231200Smm	 * At first search an index table for a bit pattern.
2803231200Smm	 * If it fails, search a huffman tree for.
2804231200Smm	 */
2805231200Smm	c = hf->tbl[rbits >> hf->shift_bits];
2806299529Smm	if (c < hf->len_avail || hf->len_avail == 0)
2807231200Smm		return (c);
2808231200Smm	/* This bit pattern needs to be found out at a huffman tree. */
2809231200Smm	return (lzh_decode_huffman_tree(hf, rbits, c));
2810231200Smm}
2811231200Smm
2812