Browse code

create tag for release of clamav-0.74

git-svn-id: file:///var/lib/svn/clamav-devel/tags/clamav-0.74@2763 77e5149b-7576-45b1-b177-96237e5ba77b

Sven Strickroth authored on 2007/02/18 22:46:10
Showing 25 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Jun 30 00:00:13 CEST 2004 (tk)
2
+----------------------------------
3
+  V 0.74 (Based on CVS, with PowerPoint-VBA, MSCAB, PE and UPX code excluded)
4
+
1 5
 Tue Jun 29 23:24:44 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   * doc: update
... ...
@@ -2055,7 +2055,7 @@ fi
2055 2055
 
2056 2056
 # Define the identity of the package.
2057 2057
  PACKAGE=clamav
2058
- VERSION="devel-`date +%Y%m%d`"
2058
+ VERSION="0.74"
2059 2059
 
2060 2060
 
2061 2061
 cat >>confdefs.h <<_ACEOF
... ...
@@ -17,7 +17,7 @@ dnl   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
 
18 18
 AC_INIT(clamscan/clamscan.c)
19 19
 AC_CREATE_TARGET_H(target.h)
20
-AM_INIT_AUTOMAKE(clamav, "devel-`date +%Y%m%d`")
20
+AM_INIT_AUTOMAKE(clamav, "0.74")
21 21
 AM_CONFIG_HEADER(clamav-config.h)
22 22
 
23 23
 LC_CURRENT=1
24 24
new file mode 100644
... ...
@@ -0,0 +1,75 @@
0
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1
+
2
+<!--Converted with LaTeX2HTML 2K.1beta (1.48)
3
+original version by:  Nikos Drakos, CBLU, University of Leeds
4
+* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
5
+* with significant contributions from:
6
+  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
7
+<HTML>
8
+<HEAD>
9
+<TITLE>Core developers</TITLE>
10
+<META NAME="description" CONTENT="Core developers">
11
+<META NAME="keywords" CONTENT="clamdoc">
12
+<META NAME="resource-type" CONTENT="document">
13
+<META NAME="distribution" CONTENT="global">
14
+
15
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
16
+<META NAME="Generator" CONTENT="LaTeX2HTML v2K.1beta">
17
+<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
18
+
19
+<LINK REL="STYLESHEET" HREF="clamdoc.css">
20
+
21
+<LINK REL="previous" HREF="node85.html">
22
+<LINK REL="up" HREF="node82.html">
23
+<LINK REL="next" HREF="node87.html">
24
+</HEAD>
25
+
26
+<BODY >
27
+<!--Navigation Panel-->
28
+<A NAME="tex2html1433"
29
+  HREF="node87.html">
30
+<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
31
+ SRC="/usr/share/latex2html/icons/next.png"></A> 
32
+<A NAME="tex2html1429"
33
+  HREF="node82.html">
34
+<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
35
+ SRC="/usr/share/latex2html/icons/up.png"></A> 
36
+<A NAME="tex2html1425"
37
+  HREF="node85.html">
38
+<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
39
+ SRC="/usr/share/latex2html/icons/prev.png"></A> 
40
+<A NAME="tex2html1431"
41
+  HREF="node1.html">
42
+<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
43
+ SRC="/usr/share/latex2html/icons/contents.png"></A>  
44
+<BR>
45
+<B> Next:</B> <A NAME="tex2html1434"
46
+  HREF="node87.html">Bibliography</A>
47
+<B> Up:</B> <A NAME="tex2html1430"
48
+  HREF="node82.html">Authors</A>
49
+<B> Previous:</B> <A NAME="tex2html1426"
50
+  HREF="node85.html">Graphics</A>
51
+ &nbsp <B>  <A NAME="tex2html1432"
52
+  HREF="node1.html">Contents</A></B> 
53
+<BR>
54
+<BR>
55
+<!--End of Navigation Panel-->
56
+
57
+<H2><A NAME="SECTION00094000000000000000">
58
+Core developers</A>
59
+</H2>
60
+    Nigel Horne &lt;njh*clamav.net&gt; is a very active ClamAV developer
61
+    responsible for the mbox code and clamav-milter. Trog
62
+    &lt;trog*clamav.net&gt; developes the OLE2 code and the new thread
63
+    manager in clamd. Thomas Lamy is a great memory leak killer and code
64
+    stabilizer. Tomasz Kojm &lt;tkojm*clamav.net&gt;  navigates the project
65
+    and keeps an eye on everything <code>8-)</code>
66
+
67
+<P>
68
+<BR><HR>
69
+<ADDRESS>
70
+Tomasz Kojm
71
+2004-06-29
72
+</ADDRESS>
73
+</BODY>
74
+</HTML>
0 75
new file mode 100644
... ...
@@ -0,0 +1,75 @@
0
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1
+
2
+<!--Converted with LaTeX2HTML 2K.1beta (1.48)
3
+original version by:  Nikos Drakos, CBLU, University of Leeds
4
+* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
5
+* with significant contributions from:
6
+  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
7
+<HTML>
8
+<HEAD>
9
+<TITLE>Bibliography</TITLE>
10
+<META NAME="description" CONTENT="Bibliography">
11
+<META NAME="keywords" CONTENT="clamdoc">
12
+<META NAME="resource-type" CONTENT="document">
13
+<META NAME="distribution" CONTENT="global">
14
+
15
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
16
+<META NAME="Generator" CONTENT="LaTeX2HTML v2K.1beta">
17
+<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
18
+
19
+<LINK REL="STYLESHEET" HREF="clamdoc.css">
20
+
21
+<LINK REL="next" HREF="node88.html">
22
+<LINK REL="previous" HREF="node82.html">
23
+<LINK REL="up" HREF="clamdoc.html">
24
+<LINK REL="next" HREF="node88.html">
25
+</HEAD>
26
+
27
+<BODY >
28
+<!--Navigation Panel-->
29
+<A NAME="tex2html1445"
30
+  HREF="node88.html">
31
+<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
32
+ SRC="/usr/share/latex2html/icons/next.png"></A> 
33
+<A NAME="tex2html1441"
34
+  HREF="clamdoc.html">
35
+<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
36
+ SRC="/usr/share/latex2html/icons/up.png"></A> 
37
+<A NAME="tex2html1435"
38
+  HREF="node86.html">
39
+<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
40
+ SRC="/usr/share/latex2html/icons/prev.png"></A> 
41
+<A NAME="tex2html1443"
42
+  HREF="node1.html">
43
+<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
44
+ SRC="/usr/share/latex2html/icons/contents.png"></A>  
45
+<BR>
46
+<B> Next:</B> <A NAME="tex2html1446"
47
+  HREF="node88.html">About this document ...</A>
48
+<B> Up:</B> <A NAME="tex2html1442"
49
+  HREF="clamdoc.html">clamdoc</A>
50
+<B> Previous:</B> <A NAME="tex2html1436"
51
+  HREF="node86.html">Core developers</A>
52
+ &nbsp <B>  <A NAME="tex2html1444"
53
+  HREF="node1.html">Contents</A></B> 
54
+<BR><BR>
55
+<!--End of Navigation Panel-->
56
+ 
57
+<H2><A NAME="SECTION000100000000000000000">
58
+Bibliography</A>
59
+</H2><DL COMPACT><DD><P></P><DT><A NAME="clr">1</A>
60
+<DD>
61
+	    Cormen, Leiserson, Rivest: <I>Introduction to Algorithms</I>,
62
+	    Chapter 34, MIT Press.
63
+	<P></P><DT><A NAME="acwww">2</A>
64
+<DD>
65
+	    <FONT SIZE="-1">	    <TT><A NAME="tex2html163"
66
+  HREF="http://www-sr.informatik.uni-tuebingen.de/~buehler/AC/AC.html">http://www-sr.informatik.uni-tuebingen.de/~buehler/AC/AC.html</A></TT></FONT>:
67
+<BR>	    Aho-Corasick algorithm description
68
+</DL><BR><HR>
69
+<ADDRESS>
70
+Tomasz Kojm
71
+2004-06-29
72
+</ADDRESS>
73
+</BODY>
74
+</HTML>
0 75
new file mode 100644
... ...
@@ -0,0 +1,79 @@
0
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1
+
2
+<!--Converted with LaTeX2HTML 2K.1beta (1.48)
3
+original version by:  Nikos Drakos, CBLU, University of Leeds
4
+* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
5
+* with significant contributions from:
6
+  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
7
+<HTML>
8
+<HEAD>
9
+<TITLE>About this document ...</TITLE>
10
+<META NAME="description" CONTENT="About this document ...">
11
+<META NAME="keywords" CONTENT="clamdoc">
12
+<META NAME="resource-type" CONTENT="document">
13
+<META NAME="distribution" CONTENT="global">
14
+
15
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
16
+<META NAME="Generator" CONTENT="LaTeX2HTML v2K.1beta">
17
+<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
18
+
19
+<LINK REL="STYLESHEET" HREF="clamdoc.css">
20
+
21
+<LINK REL="previous" HREF="node87.html">
22
+<LINK REL="up" HREF="clamdoc.html">
23
+</HEAD>
24
+
25
+<BODY >
26
+<!--Navigation Panel-->
27
+<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
28
+ SRC="/usr/share/latex2html/icons/next_g.png"> 
29
+<A NAME="tex2html1451"
30
+  HREF="clamdoc.html">
31
+<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
32
+ SRC="/usr/share/latex2html/icons/up.png"></A> 
33
+<A NAME="tex2html1447"
34
+  HREF="node87.html">
35
+<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
36
+ SRC="/usr/share/latex2html/icons/prev.png"></A> 
37
+<A NAME="tex2html1453"
38
+  HREF="node1.html">
39
+<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
40
+ SRC="/usr/share/latex2html/icons/contents.png"></A>  
41
+<BR>
42
+<B> Up:</B> <A NAME="tex2html1452"
43
+  HREF="clamdoc.html">clamdoc</A>
44
+<B> Previous:</B> <A NAME="tex2html1448"
45
+  HREF="node87.html">Bibliography</A>
46
+ &nbsp <B>  <A NAME="tex2html1454"
47
+  HREF="node1.html">Contents</A></B> 
48
+<BR>
49
+<BR>
50
+<!--End of Navigation Panel-->
51
+
52
+<H1><A NAME="SECTION000110000000000000000">
53
+About this document ...</A>
54
+</H1>
55
+ <P>
56
+This document was generated using the
57
+<A HREF="http://www-texdev.mpce.mq.edu.au/l2h/docs/manual/"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A> translator Version 2K.1beta (1.48)
58
+<P>
59
+Copyright &#169; 1993, 1994, 1995, 1996,
60
+<A HREF="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</A>, 
61
+Computer Based Learning Unit, University of Leeds.
62
+<BR>
63
+Copyright &#169; 1997, 1998, 1999,
64
+<A HREF="http://www.maths.mq.edu.au/~ross/">Ross Moore</A>, 
65
+Mathematics Department, Macquarie University, Sydney.
66
+<P>
67
+The command line arguments were: <BR>
68
+ <STRONG>latex2html</STRONG> <TT><A NAME="tex2html164"
69
+  HREF="../clamdoc.tex">clamdoc.tex</A></TT>
70
+<P>
71
+The translation was initiated by Tomasz Kojm on 2004-06-29
72
+<BR><HR>
73
+<ADDRESS>
74
+Tomasz Kojm
75
+2004-06-29
76
+</ADDRESS>
77
+</BODY>
78
+</HTML>
... ...
@@ -80,21 +80,6 @@ libclamav_la_SOURCES = \
80 80
 	vba_extract.h \
81 81
 	cltypes.h \
82 82
 	msexpand.c \
83
-	msexpand.h \
84
-	pe.c \
85
-	pe.h \
86
-	mspack/cabd.c \
87
-	mspack/cab.h \
88
-	mspack/lzxd.c \
89
-	mspack/lzx.h \
90
-	mspack/mspack.h \
91
-	mspack/mszipd.c \
92
-	mspack/mszip.h \
93
-	mspack/qtmd.c \
94
-	mspack/qtm.h \
95
-	mspack/system.c \
96
-	mspack/system.h \
97
-	upx.c \
98
-	upx.h
83
+	msexpand.h
99 84
 
100 85
 lib_LTLIBRARIES = libclamav.la
... ...
@@ -76,26 +76,21 @@ am_libclamav_la_OBJECTS = matcher.lo md5.lo others.lo readdb.lo cvd.lo \
76 76
 	dsig.lo str.lo scanners.lo unrarlib.lo zzip-dir.lo zzip-err.lo \
77 77
 	zzip-file.lo zzip-info.lo zzip-io.lo zzip-stat.lo zzip-zip.lo \
78 78
 	strc.lo blob.lo mbox.lo message.lo snprintf.lo strrcpy.lo \
79
-	table.lo text.lo ole2_extract.lo vba_extract.lo msexpand.lo \
80
-	pe.lo cabd.lo lzxd.lo mszipd.lo qtmd.lo system.lo upx.lo
79
+	table.lo text.lo ole2_extract.lo vba_extract.lo msexpand.lo
81 80
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
82 81
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
83 82
 depcomp = $(SHELL) $(top_srcdir)/depcomp
84 83
 am__depfiles_maybe = depfiles
85
-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/blob.Plo ./$(DEPDIR)/cabd.Plo \
86
-@AMDEP_TRUE@	./$(DEPDIR)/cvd.Plo ./$(DEPDIR)/dsig.Plo \
87
-@AMDEP_TRUE@	./$(DEPDIR)/lzxd.Plo ./$(DEPDIR)/matcher.Plo \
84
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/blob.Plo ./$(DEPDIR)/cvd.Plo \
85
+@AMDEP_TRUE@	./$(DEPDIR)/dsig.Plo ./$(DEPDIR)/matcher.Plo \
88 86
 @AMDEP_TRUE@	./$(DEPDIR)/mbox.Plo ./$(DEPDIR)/md5.Plo \
89 87
 @AMDEP_TRUE@	./$(DEPDIR)/message.Plo ./$(DEPDIR)/msexpand.Plo \
90
-@AMDEP_TRUE@	./$(DEPDIR)/mszipd.Plo \
91 88
 @AMDEP_TRUE@	./$(DEPDIR)/ole2_extract.Plo \
92
-@AMDEP_TRUE@	./$(DEPDIR)/others.Plo ./$(DEPDIR)/pe.Plo \
93
-@AMDEP_TRUE@	./$(DEPDIR)/qtmd.Plo ./$(DEPDIR)/readdb.Plo \
89
+@AMDEP_TRUE@	./$(DEPDIR)/others.Plo ./$(DEPDIR)/readdb.Plo \
94 90
 @AMDEP_TRUE@	./$(DEPDIR)/scanners.Plo ./$(DEPDIR)/snprintf.Plo \
95 91
 @AMDEP_TRUE@	./$(DEPDIR)/str.Plo ./$(DEPDIR)/strc.Plo \
96
-@AMDEP_TRUE@	./$(DEPDIR)/strrcpy.Plo ./$(DEPDIR)/system.Plo \
97
-@AMDEP_TRUE@	./$(DEPDIR)/table.Plo ./$(DEPDIR)/text.Plo \
98
-@AMDEP_TRUE@	./$(DEPDIR)/unrarlib.Plo ./$(DEPDIR)/upx.Plo \
92
+@AMDEP_TRUE@	./$(DEPDIR)/strrcpy.Plo ./$(DEPDIR)/table.Plo \
93
+@AMDEP_TRUE@	./$(DEPDIR)/text.Plo ./$(DEPDIR)/unrarlib.Plo \
99 94
 @AMDEP_TRUE@	./$(DEPDIR)/vba_extract.Plo \
100 95
 @AMDEP_TRUE@	./$(DEPDIR)/zzip-dir.Plo ./$(DEPDIR)/zzip-err.Plo \
101 96
 @AMDEP_TRUE@	./$(DEPDIR)/zzip-file.Plo \
... ...
@@ -283,22 +278,7 @@ libclamav_la_SOURCES = \
283 283
 	vba_extract.h \
284 284
 	cltypes.h \
285 285
 	msexpand.c \
286
-	msexpand.h \
287
-	pe.c \
288
-	pe.h \
289
-	mspack/cabd.c \
290
-	mspack/cab.h \
291
-	mspack/lzxd.c \
292
-	mspack/lzx.h \
293
-	mspack/mspack.h \
294
-	mspack/mszipd.c \
295
-	mspack/mszip.h \
296
-	mspack/qtmd.c \
297
-	mspack/qtm.h \
298
-	mspack/system.c \
299
-	mspack/system.h \
300
-	upx.c \
301
-	upx.h
286
+	msexpand.h
302 287
 
303 288
 lib_LTLIBRARIES = libclamav.la
304 289
 all: all-am
... ...
@@ -371,31 +351,24 @@ distclean-compile:
371 371
 	-rm -f *.tab.c
372 372
 
373 373
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blob.Plo@am__quote@
374
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cabd.Plo@am__quote@
375 374
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvd.Plo@am__quote@
376 375
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsig.Plo@am__quote@
377
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzxd.Plo@am__quote@
378 376
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matcher.Plo@am__quote@
379 377
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbox.Plo@am__quote@
380 378
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
381 379
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@
382 380
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msexpand.Plo@am__quote@
383
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mszipd.Plo@am__quote@
384 381
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ole2_extract.Plo@am__quote@
385 382
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/others.Plo@am__quote@
386
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe.Plo@am__quote@
387
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qtmd.Plo@am__quote@
388 383
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readdb.Plo@am__quote@
389 384
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanners.Plo@am__quote@
390 385
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Plo@am__quote@
391 386
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@
392 387
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strc.Plo@am__quote@
393 388
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strrcpy.Plo@am__quote@
394
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Plo@am__quote@
395 389
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Plo@am__quote@
396 390
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text.Plo@am__quote@
397 391
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unrarlib.Plo@am__quote@
398
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upx.Plo@am__quote@
399 392
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vba_extract.Plo@am__quote@
400 393
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zzip-dir.Plo@am__quote@
401 394
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zzip-err.Plo@am__quote@
... ...
@@ -621,126 +594,6 @@ strc.lo: zziplib/strc.c
621 621
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
622 622
 @am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strc.lo `test -f 'zziplib/strc.c' || echo '$(srcdir)/'`zziplib/strc.c
623 623
 
624
-cabd.o: mspack/cabd.c
625
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cabd.o -MD -MP -MF "$(DEPDIR)/cabd.Tpo" -c -o cabd.o `test -f 'mspack/cabd.c' || echo '$(srcdir)/'`mspack/cabd.c; \
626
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/cabd.Tpo" "$(DEPDIR)/cabd.Po"; else rm -f "$(DEPDIR)/cabd.Tpo"; exit 1; fi
627
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/cabd.c' object='cabd.o' libtool=no @AMDEPBACKSLASH@
628
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/cabd.Po' tmpdepfile='$(DEPDIR)/cabd.TPo' @AMDEPBACKSLASH@
629
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
630
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cabd.o `test -f 'mspack/cabd.c' || echo '$(srcdir)/'`mspack/cabd.c
631
-
632
-cabd.obj: mspack/cabd.c
633
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cabd.obj -MD -MP -MF "$(DEPDIR)/cabd.Tpo" -c -o cabd.obj `if test -f 'mspack/cabd.c'; then $(CYGPATH_W) 'mspack/cabd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/cabd.c'; fi`; \
634
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/cabd.Tpo" "$(DEPDIR)/cabd.Po"; else rm -f "$(DEPDIR)/cabd.Tpo"; exit 1; fi
635
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/cabd.c' object='cabd.obj' libtool=no @AMDEPBACKSLASH@
636
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/cabd.Po' tmpdepfile='$(DEPDIR)/cabd.TPo' @AMDEPBACKSLASH@
637
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
638
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cabd.obj `if test -f 'mspack/cabd.c'; then $(CYGPATH_W) 'mspack/cabd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/cabd.c'; fi`
639
-
640
-cabd.lo: mspack/cabd.c
641
-@am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cabd.lo -MD -MP -MF "$(DEPDIR)/cabd.Tpo" -c -o cabd.lo `test -f 'mspack/cabd.c' || echo '$(srcdir)/'`mspack/cabd.c; \
642
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/cabd.Tpo" "$(DEPDIR)/cabd.Plo"; else rm -f "$(DEPDIR)/cabd.Tpo"; exit 1; fi
643
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/cabd.c' object='cabd.lo' libtool=yes @AMDEPBACKSLASH@
644
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/cabd.Plo' tmpdepfile='$(DEPDIR)/cabd.TPlo' @AMDEPBACKSLASH@
645
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
646
-@am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cabd.lo `test -f 'mspack/cabd.c' || echo '$(srcdir)/'`mspack/cabd.c
647
-
648
-lzxd.o: mspack/lzxd.c
649
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzxd.o -MD -MP -MF "$(DEPDIR)/lzxd.Tpo" -c -o lzxd.o `test -f 'mspack/lzxd.c' || echo '$(srcdir)/'`mspack/lzxd.c; \
650
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/lzxd.Tpo" "$(DEPDIR)/lzxd.Po"; else rm -f "$(DEPDIR)/lzxd.Tpo"; exit 1; fi
651
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/lzxd.c' object='lzxd.o' libtool=no @AMDEPBACKSLASH@
652
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/lzxd.Po' tmpdepfile='$(DEPDIR)/lzxd.TPo' @AMDEPBACKSLASH@
653
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
654
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzxd.o `test -f 'mspack/lzxd.c' || echo '$(srcdir)/'`mspack/lzxd.c
655
-
656
-lzxd.obj: mspack/lzxd.c
657
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzxd.obj -MD -MP -MF "$(DEPDIR)/lzxd.Tpo" -c -o lzxd.obj `if test -f 'mspack/lzxd.c'; then $(CYGPATH_W) 'mspack/lzxd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/lzxd.c'; fi`; \
658
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/lzxd.Tpo" "$(DEPDIR)/lzxd.Po"; else rm -f "$(DEPDIR)/lzxd.Tpo"; exit 1; fi
659
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/lzxd.c' object='lzxd.obj' libtool=no @AMDEPBACKSLASH@
660
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/lzxd.Po' tmpdepfile='$(DEPDIR)/lzxd.TPo' @AMDEPBACKSLASH@
661
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
662
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzxd.obj `if test -f 'mspack/lzxd.c'; then $(CYGPATH_W) 'mspack/lzxd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/lzxd.c'; fi`
663
-
664
-lzxd.lo: mspack/lzxd.c
665
-@am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzxd.lo -MD -MP -MF "$(DEPDIR)/lzxd.Tpo" -c -o lzxd.lo `test -f 'mspack/lzxd.c' || echo '$(srcdir)/'`mspack/lzxd.c; \
666
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/lzxd.Tpo" "$(DEPDIR)/lzxd.Plo"; else rm -f "$(DEPDIR)/lzxd.Tpo"; exit 1; fi
667
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/lzxd.c' object='lzxd.lo' libtool=yes @AMDEPBACKSLASH@
668
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/lzxd.Plo' tmpdepfile='$(DEPDIR)/lzxd.TPlo' @AMDEPBACKSLASH@
669
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
670
-@am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzxd.lo `test -f 'mspack/lzxd.c' || echo '$(srcdir)/'`mspack/lzxd.c
671
-
672
-mszipd.o: mspack/mszipd.c
673
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mszipd.o -MD -MP -MF "$(DEPDIR)/mszipd.Tpo" -c -o mszipd.o `test -f 'mspack/mszipd.c' || echo '$(srcdir)/'`mspack/mszipd.c; \
674
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/mszipd.Tpo" "$(DEPDIR)/mszipd.Po"; else rm -f "$(DEPDIR)/mszipd.Tpo"; exit 1; fi
675
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/mszipd.c' object='mszipd.o' libtool=no @AMDEPBACKSLASH@
676
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/mszipd.Po' tmpdepfile='$(DEPDIR)/mszipd.TPo' @AMDEPBACKSLASH@
677
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
678
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mszipd.o `test -f 'mspack/mszipd.c' || echo '$(srcdir)/'`mspack/mszipd.c
679
-
680
-mszipd.obj: mspack/mszipd.c
681
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mszipd.obj -MD -MP -MF "$(DEPDIR)/mszipd.Tpo" -c -o mszipd.obj `if test -f 'mspack/mszipd.c'; then $(CYGPATH_W) 'mspack/mszipd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/mszipd.c'; fi`; \
682
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/mszipd.Tpo" "$(DEPDIR)/mszipd.Po"; else rm -f "$(DEPDIR)/mszipd.Tpo"; exit 1; fi
683
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/mszipd.c' object='mszipd.obj' libtool=no @AMDEPBACKSLASH@
684
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/mszipd.Po' tmpdepfile='$(DEPDIR)/mszipd.TPo' @AMDEPBACKSLASH@
685
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
686
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mszipd.obj `if test -f 'mspack/mszipd.c'; then $(CYGPATH_W) 'mspack/mszipd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/mszipd.c'; fi`
687
-
688
-mszipd.lo: mspack/mszipd.c
689
-@am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mszipd.lo -MD -MP -MF "$(DEPDIR)/mszipd.Tpo" -c -o mszipd.lo `test -f 'mspack/mszipd.c' || echo '$(srcdir)/'`mspack/mszipd.c; \
690
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/mszipd.Tpo" "$(DEPDIR)/mszipd.Plo"; else rm -f "$(DEPDIR)/mszipd.Tpo"; exit 1; fi
691
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/mszipd.c' object='mszipd.lo' libtool=yes @AMDEPBACKSLASH@
692
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/mszipd.Plo' tmpdepfile='$(DEPDIR)/mszipd.TPlo' @AMDEPBACKSLASH@
693
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
694
-@am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mszipd.lo `test -f 'mspack/mszipd.c' || echo '$(srcdir)/'`mspack/mszipd.c
695
-
696
-qtmd.o: mspack/qtmd.c
697
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qtmd.o -MD -MP -MF "$(DEPDIR)/qtmd.Tpo" -c -o qtmd.o `test -f 'mspack/qtmd.c' || echo '$(srcdir)/'`mspack/qtmd.c; \
698
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/qtmd.Tpo" "$(DEPDIR)/qtmd.Po"; else rm -f "$(DEPDIR)/qtmd.Tpo"; exit 1; fi
699
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/qtmd.c' object='qtmd.o' libtool=no @AMDEPBACKSLASH@
700
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/qtmd.Po' tmpdepfile='$(DEPDIR)/qtmd.TPo' @AMDEPBACKSLASH@
701
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
702
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qtmd.o `test -f 'mspack/qtmd.c' || echo '$(srcdir)/'`mspack/qtmd.c
703
-
704
-qtmd.obj: mspack/qtmd.c
705
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qtmd.obj -MD -MP -MF "$(DEPDIR)/qtmd.Tpo" -c -o qtmd.obj `if test -f 'mspack/qtmd.c'; then $(CYGPATH_W) 'mspack/qtmd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/qtmd.c'; fi`; \
706
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/qtmd.Tpo" "$(DEPDIR)/qtmd.Po"; else rm -f "$(DEPDIR)/qtmd.Tpo"; exit 1; fi
707
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/qtmd.c' object='qtmd.obj' libtool=no @AMDEPBACKSLASH@
708
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/qtmd.Po' tmpdepfile='$(DEPDIR)/qtmd.TPo' @AMDEPBACKSLASH@
709
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
710
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qtmd.obj `if test -f 'mspack/qtmd.c'; then $(CYGPATH_W) 'mspack/qtmd.c'; else $(CYGPATH_W) '$(srcdir)/mspack/qtmd.c'; fi`
711
-
712
-qtmd.lo: mspack/qtmd.c
713
-@am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qtmd.lo -MD -MP -MF "$(DEPDIR)/qtmd.Tpo" -c -o qtmd.lo `test -f 'mspack/qtmd.c' || echo '$(srcdir)/'`mspack/qtmd.c; \
714
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/qtmd.Tpo" "$(DEPDIR)/qtmd.Plo"; else rm -f "$(DEPDIR)/qtmd.Tpo"; exit 1; fi
715
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/qtmd.c' object='qtmd.lo' libtool=yes @AMDEPBACKSLASH@
716
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/qtmd.Plo' tmpdepfile='$(DEPDIR)/qtmd.TPlo' @AMDEPBACKSLASH@
717
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
718
-@am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qtmd.lo `test -f 'mspack/qtmd.c' || echo '$(srcdir)/'`mspack/qtmd.c
719
-
720
-system.o: mspack/system.c
721
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system.o -MD -MP -MF "$(DEPDIR)/system.Tpo" -c -o system.o `test -f 'mspack/system.c' || echo '$(srcdir)/'`mspack/system.c; \
722
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/system.Tpo" "$(DEPDIR)/system.Po"; else rm -f "$(DEPDIR)/system.Tpo"; exit 1; fi
723
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/system.c' object='system.o' libtool=no @AMDEPBACKSLASH@
724
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/system.Po' tmpdepfile='$(DEPDIR)/system.TPo' @AMDEPBACKSLASH@
725
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
726
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system.o `test -f 'mspack/system.c' || echo '$(srcdir)/'`mspack/system.c
727
-
728
-system.obj: mspack/system.c
729
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system.obj -MD -MP -MF "$(DEPDIR)/system.Tpo" -c -o system.obj `if test -f 'mspack/system.c'; then $(CYGPATH_W) 'mspack/system.c'; else $(CYGPATH_W) '$(srcdir)/mspack/system.c'; fi`; \
730
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/system.Tpo" "$(DEPDIR)/system.Po"; else rm -f "$(DEPDIR)/system.Tpo"; exit 1; fi
731
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/system.c' object='system.obj' libtool=no @AMDEPBACKSLASH@
732
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/system.Po' tmpdepfile='$(DEPDIR)/system.TPo' @AMDEPBACKSLASH@
733
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
734
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system.obj `if test -f 'mspack/system.c'; then $(CYGPATH_W) 'mspack/system.c'; else $(CYGPATH_W) '$(srcdir)/mspack/system.c'; fi`
735
-
736
-system.lo: mspack/system.c
737
-@am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system.lo -MD -MP -MF "$(DEPDIR)/system.Tpo" -c -o system.lo `test -f 'mspack/system.c' || echo '$(srcdir)/'`mspack/system.c; \
738
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/system.Tpo" "$(DEPDIR)/system.Plo"; else rm -f "$(DEPDIR)/system.Tpo"; exit 1; fi
739
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mspack/system.c' object='system.lo' libtool=yes @AMDEPBACKSLASH@
740
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/system.Plo' tmpdepfile='$(DEPDIR)/system.TPlo' @AMDEPBACKSLASH@
741
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
742
-@am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system.lo `test -f 'mspack/system.c' || echo '$(srcdir)/'`mspack/system.c
743
-
744 624
 mostlyclean-libtool:
745 625
 	-rm -f *.lo
746 626
 
747 627
deleted file mode 100644
... ...
@@ -1,127 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * libmspack is free software; you can redistribute it and/or modify it under
5
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6
- *
7
- * For further details, see the file COPYING.LIB distributed with libmspack
8
- */
9
-
10
-#ifndef MSPACK_CAB_H
11
-#define MSPACK_CAB_H 1
12
-
13
-#include <mszip.h>
14
-#include <qtm.h>
15
-#include <lzx.h>
16
-
17
-/* generic CAB definitions */
18
-
19
-/* structure offsets */
20
-#define cfhead_Signature         (0x00)
21
-#define cfhead_CabinetSize       (0x08)
22
-#define cfhead_FileOffset        (0x10)
23
-#define cfhead_MinorVersion      (0x18)
24
-#define cfhead_MajorVersion      (0x19)
25
-#define cfhead_NumFolders        (0x1A)
26
-#define cfhead_NumFiles          (0x1C)
27
-#define cfhead_Flags             (0x1E)
28
-#define cfhead_SetID             (0x20)
29
-#define cfhead_CabinetIndex      (0x22)
30
-#define cfhead_SIZEOF            (0x24)
31
-#define cfheadext_HeaderReserved (0x00)
32
-#define cfheadext_FolderReserved (0x02)
33
-#define cfheadext_DataReserved   (0x03)
34
-#define cfheadext_SIZEOF         (0x04)
35
-#define cffold_DataOffset        (0x00)
36
-#define cffold_NumBlocks         (0x04)
37
-#define cffold_CompType          (0x06)
38
-#define cffold_SIZEOF            (0x08)
39
-#define cffile_UncompressedSize  (0x00)
40
-#define cffile_FolderOffset      (0x04)
41
-#define cffile_FolderIndex       (0x08)
42
-#define cffile_Date              (0x0A)
43
-#define cffile_Time              (0x0C)
44
-#define cffile_Attribs           (0x0E)
45
-#define cffile_SIZEOF            (0x10)
46
-#define cfdata_CheckSum          (0x00)
47
-#define cfdata_CompressedSize    (0x04)
48
-#define cfdata_UncompressedSize  (0x06)
49
-#define cfdata_SIZEOF            (0x08)
50
-
51
-/* flags */
52
-#define cffoldCOMPTYPE_MASK            (0x000f)
53
-#define cffoldCOMPTYPE_NONE            (0x0000)
54
-#define cffoldCOMPTYPE_MSZIP           (0x0001)
55
-#define cffoldCOMPTYPE_QUANTUM         (0x0002)
56
-#define cffoldCOMPTYPE_LZX             (0x0003)
57
-#define cfheadPREV_CABINET             (0x0001)
58
-#define cfheadNEXT_CABINET             (0x0002)
59
-#define cfheadRESERVE_PRESENT          (0x0004)
60
-#define cffileCONTINUED_FROM_PREV      (0xFFFD)
61
-#define cffileCONTINUED_TO_NEXT        (0xFFFE)
62
-#define cffileCONTINUED_PREV_AND_NEXT  (0xFFFF)
63
-
64
-/* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed
65
- * blocks have zero growth. MSZIP guarantees that it won't grow above
66
- * uncompressed size by more than 12 bytes. LZX guarantees it won't grow
67
- * more than 6144 bytes. Quantum has no documentation, but the largest
68
- * block seen in the wild is 337 bytes above uncompressed size.
69
- */
70
-#define CAB_BLOCKMAX (32768)
71
-#define CAB_INPUTMAX (CAB_BLOCKMAX+6144)
72
-
73
-/* CAB compression definitions */
74
-
75
-struct mscab_compressor_p {
76
-  struct mscab_compressor base;
77
-  struct mspack_system *system;
78
-  /* todo */
79
-};
80
-
81
-/* CAB decompression definitions */
82
-
83
-struct mscabd_decompress_state {
84
-  struct mscabd_folder_p *folder;    /* current folder we're extracting from */
85
-  struct mscabd_folder_data *data;   /* current folder split we're in        */
86
-  unsigned int offset;               /* uncompressed offset within folder    */
87
-  unsigned int block;                /* which block are we decompressing?    */
88
-  struct mspack_system sys;          /* special I/O code for decompressor    */
89
-  int comp_type;                     /* type of compression used by folder   */
90
-  int (*decompress)(void *, off_t);  /* decompressor code                    */
91
-  void *state;                       /* decompressor state                   */
92
-  struct mscabd_cabinet_p *incab;    /* cabinet where input data comes from  */
93
-  struct mspack_file *infh;          /* input file handle                    */
94
-  struct mspack_file *outfh;         /* output file handle                   */
95
-  unsigned char *i_ptr, *i_end;      /* input data consumed, end             */
96
-  unsigned char input[CAB_INPUTMAX]; /* one input block of data              */
97
-};
98
-
99
-struct mscab_decompressor_p {
100
-  struct mscab_decompressor base;
101
-  struct mscabd_decompress_state *d;
102
-  struct mspack_system *system;
103
-  int param[3]; /* !!! MATCH THIS TO NUM OF PARAMS IN MSPACK.H !!! */
104
-  int error;
105
-};
106
-
107
-struct mscabd_cabinet_p {
108
-  struct mscabd_cabinet base;
109
-  off_t blocks_off;                  /* offset to data blocks                */
110
-  int block_resv;                    /* reserved space in data blocks        */
111
-};
112
-
113
-/* there is one of these for every cabinet a folder spans */
114
-struct mscabd_folder_data {
115
-  struct mscabd_folder_data *next;
116
-  struct mscabd_cabinet_p *cab;      /* cabinet file of this folder span     */
117
-  off_t offset;                      /* cabinet offset of first datablock    */
118
-};
119
-
120
-struct mscabd_folder_p {
121
-  struct mscabd_folder base;
122
-  struct mscabd_folder_data data;    /* where are the data blocks?           */
123
-  struct mscabd_file *merge_prev;    /* do we need to merge backwards?       */
124
-  struct mscabd_file *merge_next;    /* do we need to merge forwards?        */
125
-};
126
-
127
-#endif
128 1
deleted file mode 100644
... ...
@@ -1,1519 +0,0 @@
1
-/* WARNING: This version also supports dopen for descriptor opening and
2
- *	    is not compatible with the original version. -- T. Kojm
3
- *
4
- * This file is part of libmspack.
5
- * (C) 2003-2004 Stuart Caie.
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * For further details, see the file COPYING.LIB distributed with libmspack
11
- */
12
-
13
-/* Cabinet (.CAB) files are a form of file archive. Each cabinet contains
14
- * "folders", which are compressed spans of data. Each cabinet has
15
- * "files", whose metadata is in the cabinet header, but whose actual data
16
- * is stored compressed in one of the "folders". Cabinets can span more
17
- * than one physical file on disk, in which case they are a "cabinet set",
18
- * and usually the last folder of each cabinet extends into the next
19
- * cabinet.
20
- *
21
- * For a complete description of the format, get the official Microsoft
22
- * CAB SDK. It can be found at the following URL:
23
- *
24
- *   http://msdn.microsoft.com/library/en-us/dncabsdk/html/cabdl.asp
25
- *
26
- * It is a self-extracting ZIP file, which can be extracted with the unzip
27
- * command.
28
- */
29
-
30
-/* CAB decompression implementation */
31
-
32
-#if HAVE_CONFIG_H
33
-#include "clamav-config.h"
34
-#endif
35
-
36
-#include <mspack.h>
37
-#include <system.h>
38
-#include <cab.h>
39
-
40
-/* Notes on compliance with cabinet specification:
41
- *
42
- * One of the main changes between cabextract 0.6 and libmspack's cab
43
- * decompressor is the move from block-oriented decompression to
44
- * stream-oriented decompression.
45
- *
46
- * cabextract would read one data block from disk, decompress it with the
47
- * appropriate method, then write the decompressed data. The CAB
48
- * specification is specifically designed to work like this, as it ensures
49
- * compression matches do not span the maximum decompressed block size
50
- * limit of 32kb.
51
- *
52
- * However, the compression algorithms used are stream oriented, with
53
- * specific hacks added to them to enforce the "individual 32kb blocks"
54
- * rule in CABs. In other file formats, they do not have this limitation.
55
- *
56
- * In order to make more generalised decompressors, libmspack's CAB
57
- * decompressor has moved from being block-oriented to more stream
58
- * oriented. This also makes decompression slightly faster.
59
- *
60
- * However, this leads to incompliance with the CAB specification. The
61
- * CAB controller can no longer ensure each block of input given to the
62
- * decompressors is matched with their output. The "decompressed size" of
63
- * each individual block is thrown away.
64
- *
65
- * Each CAB block is supposed to be seen as individually compressed. This
66
- * means each consecutive data block can have completely different
67
- * "uncompressed" sizes, ranging from 1 to 32768 bytes. However, in
68
- * reality, all data blocks in a folder decompress to exactly 32768 bytes,
69
- * excepting the final block. 
70
- *
71
- * Given this situation, the decompression algorithms are designed to
72
- * realign their input bitstreams on 32768 output-byte boundaries, and
73
- * various other special cases have been made. libmspack will not
74
- * correctly decompress LZX or Quantum compressed folders where the blocks
75
- * do not follow this "32768 bytes until last block" pattern. It could be
76
- * implemented if needed, but hopefully this is not necessary -- it has
77
- * not been seen in over 3Gb of CAB archives.
78
- */
79
-
80
-/* prototypes */
81
-static struct mscabd_cabinet * cabd_open(
82
-  struct mscab_decompressor *base, char *filename);
83
-static struct mscabd_cabinet * cabd_dopen(
84
-  struct mscab_decompressor *base, int desc);
85
-static void cabd_close(
86
-  struct mscab_decompressor *base, struct mscabd_cabinet *origcab);
87
-static int cabd_read_headers(
88
-  struct mspack_system *sys, struct mspack_file *fh,
89
-  struct mscabd_cabinet_p *cab, off_t offset, int quiet);
90
-static char *cabd_read_string(
91
-  struct mspack_system *sys, struct mspack_file *fh,
92
-  struct mscabd_cabinet_p *cab, int *error);
93
-
94
-static struct mscabd_cabinet *cabd_search(
95
-  struct mscab_decompressor *base, char *filename);
96
-static struct mscabd_cabinet *cabd_dsearch(
97
-  struct mscab_decompressor *base, int desc);
98
-static int cabd_find(
99
-  struct mscab_decompressor_p *this, unsigned char *buf,
100
-  struct mspack_file *fh, char *filename, int desc, off_t flen,
101
-  unsigned int *firstlen, struct mscabd_cabinet_p **firstcab);
102
-
103
-static int cabd_prepend(
104
-  struct mscab_decompressor *base, struct mscabd_cabinet *cab,
105
-  struct mscabd_cabinet *prevcab);
106
-static int cabd_append(
107
-  struct mscab_decompressor *base, struct mscabd_cabinet *cab,
108
-  struct mscabd_cabinet *nextcab);
109
-static int cabd_merge(
110
-  struct mscab_decompressor *base, struct mscabd_cabinet *lcab,
111
-  struct mscabd_cabinet *rcab);
112
-
113
-static int cabd_extract(
114
-  struct mscab_decompressor *base, struct mscabd_file *file, char *filename);
115
-static int cabd_init_decomp(
116
-  struct mscab_decompressor_p *this, unsigned int ct);
117
-static void cabd_free_decomp(
118
-  struct mscab_decompressor_p *this);
119
-static int cabd_sys_read(
120
-  struct mspack_file *file, void *buffer, int bytes);
121
-static int cabd_sys_write(
122
-  struct mspack_file *file, void *buffer, int bytes);
123
-static int cabd_sys_read_block(
124
-  struct mspack_system *sys, struct mscabd_decompress_state *d, int *out,
125
-  int ignore_cksum);
126
-static unsigned int cabd_checksum(
127
-  unsigned char *data, unsigned int bytes, unsigned int cksum);
128
-static struct noned_state *noned_init(
129
-  struct mspack_system *sys, struct mspack_file *in, struct mspack_file *out,
130
-  int bufsize);
131
-
132
-static int noned_decompress(
133
-  struct noned_state *s, off_t bytes);
134
-static void noned_free(
135
-  struct noned_state *state);
136
-
137
-static int cabd_param(
138
-  struct mscab_decompressor *base, int param, int value);
139
-
140
-static int cabd_error(
141
-  struct mscab_decompressor *base);
142
-
143
-
144
-/***************************************
145
- * MSPACK_CREATE_CAB_DECOMPRESSOR
146
- ***************************************
147
- * constructor
148
- */
149
-struct mscab_decompressor *
150
-  mspack_create_cab_decompressor(struct mspack_system *sys)
151
-{
152
-  struct mscab_decompressor_p *this = NULL;
153
-
154
-  if (!sys) sys = mspack_default_system;
155
-  if (!mspack_valid_system(sys)) return NULL;
156
-
157
-  if ((this = sys->alloc(sys, sizeof(struct mscab_decompressor_p)))) {
158
-    this->base.open       = &cabd_open;
159
-    this->base.dopen      = &cabd_dopen;
160
-    this->base.close      = &cabd_close;
161
-    this->base.search     = &cabd_search;
162
-    this->base.dsearch    = &cabd_dsearch;
163
-    this->base.extract    = &cabd_extract;
164
-    this->base.prepend    = &cabd_prepend;
165
-    this->base.append     = &cabd_append;
166
-    this->base.set_param  = &cabd_param;
167
-    this->base.last_error = &cabd_error;
168
-    this->system          = sys;
169
-    this->d               = NULL;
170
-    this->error           = MSPACK_ERR_OK;
171
-
172
-    this->param[MSCABD_PARAM_SEARCHBUF] = 32768;
173
-    this->param[MSCABD_PARAM_FIXMSZIP]  = 0;
174
-    this->param[MSCABD_PARAM_DECOMPBUF] = 4096;
175
-  }
176
-  return (struct mscab_decompressor *) this;
177
-}
178
-
179
-/***************************************
180
- * MSPACK_DESTROY_CAB_DECOMPRESSOR
181
- ***************************************
182
- * destructor
183
- */
184
-void mspack_destroy_cab_decompressor(struct mscab_decompressor *base) {
185
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
186
-  if (this) {
187
-    struct mspack_system *sys = this->system;
188
-    cabd_free_decomp(this);
189
-    if (this->d) {
190
-      if (this->d->infh) sys->close(this->d->infh);
191
-      sys->free(this->d);
192
-    }
193
-    sys->free(this);
194
-  }
195
-}
196
-
197
-
198
-/***************************************
199
- * CABD_OPEN
200
- ***************************************
201
- * opens a file and tries to read it as a cabinet file
202
- */
203
-static struct mscabd_cabinet *cabd_open(struct mscab_decompressor *base,
204
-					char *filename)
205
-{
206
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
207
-  struct mscabd_cabinet_p *cab = NULL;
208
-  struct mspack_system *sys;
209
-  struct mspack_file *fh;
210
-  int error;
211
-
212
-  if (!base) return NULL;
213
-  sys = this->system;
214
-
215
-  if ((fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ))) {
216
-    if ((cab = sys->alloc(sys, sizeof(struct mscabd_cabinet_p)))) {
217
-      cab->base.filename = filename;
218
-      /* cab->base.desc = 0; */
219
-      error = cabd_read_headers(sys, fh, cab, (off_t) 0, 0);
220
-      if (error) {
221
-	cabd_close(base, (struct mscabd_cabinet *) cab);
222
-	cab = NULL;
223
-      }
224
-      this->error = error;
225
-    }
226
-    else {
227
-      this->error = MSPACK_ERR_NOMEMORY;
228
-    }
229
-    sys->close(fh);
230
-  }
231
-  else {
232
-    this->error = MSPACK_ERR_OPEN;
233
-  }
234
-  return (struct mscabd_cabinet *) cab;
235
-}
236
-
237
-static struct mscabd_cabinet *cabd_dopen(struct mscab_decompressor *base,
238
-					int desc)
239
-{
240
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
241
-  struct mscabd_cabinet_p *cab = NULL;
242
-  struct mspack_system *sys;
243
-  struct mspack_file *fh;
244
-  int error;
245
-
246
-  if (!base) return NULL;
247
-  sys = this->system;
248
-
249
-  if ((fh = sys->dopen(sys, desc, MSPACK_SYS_OPEN_READ))) {
250
-    if ((cab = sys->alloc(sys, sizeof(struct mscabd_cabinet_p)))) {
251
-      cab->base.filename = "descriptor";
252
-      cab->base.desc = desc;
253
-      error = cabd_read_headers(sys, fh, cab, (off_t) 0, 0);
254
-      if (error) {
255
-	cabd_close(base, (struct mscabd_cabinet *) cab);
256
-	cab = NULL;
257
-      }
258
-      this->error = error;
259
-    }
260
-    else {
261
-      this->error = MSPACK_ERR_NOMEMORY;
262
-    }
263
-    sys->close(fh);
264
-  }
265
-  else {
266
-    this->error = MSPACK_ERR_OPEN;
267
-  }
268
-  return (struct mscabd_cabinet *) cab;
269
-}
270
-
271
-/***************************************
272
- * CABD_CLOSE
273
- ***************************************
274
- * frees all memory associated with a given mscabd_cabinet.
275
- */
276
-static void cabd_close(struct mscab_decompressor *base,
277
-		       struct mscabd_cabinet *origcab)
278
-{
279
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
280
-  struct mscabd_folder_data *dat, *ndat;
281
-  struct mscabd_cabinet *cab, *ncab;
282
-  struct mscabd_folder *fol, *nfol;
283
-  struct mscabd_file *fi, *nfi;
284
-  struct mspack_system *sys;
285
-
286
-  if (!base) return;
287
-  sys = this->system;
288
-
289
-  this->error = MSPACK_ERR_OK;
290
-
291
-  while (origcab) {
292
-    /* free files */
293
-    for (fi = origcab->files; fi; fi = nfi) {
294
-      nfi = fi->next;
295
-      sys->free(fi->filename);
296
-      sys->free(fi);
297
-    }
298
-
299
-    /* free folders */
300
-    for (fol = origcab->folders; fol; fol = nfol) {
301
-      nfol = fol->next;
302
-
303
-      /* free folder decompression state if it has been decompressed */
304
-      if (this->d && (this->d->folder == (struct mscabd_folder_p *) fol)) {
305
-	if (this->d->infh) sys->close(this->d->infh);
306
-	cabd_free_decomp(this);
307
-	sys->free(this->d);
308
-	this->d = NULL;
309
-      }
310
-
311
-      /* free folder data segments */
312
-      for (dat = ((struct mscabd_folder_p *)fol)->data.next; dat; dat = ndat) {
313
-	ndat = dat->next;
314
-	sys->free(dat);
315
-      }
316
-      sys->free(fol);
317
-    }
318
-
319
-    /* free predecessor cabinets (and the original cabinet's strings) */
320
-    for (cab = origcab; cab; cab = ncab) {
321
-      ncab = cab->prevcab;
322
-      sys->free(cab->prevname);
323
-      sys->free(cab->nextname);
324
-      sys->free(cab->previnfo);
325
-      sys->free(cab->nextinfo);
326
-      if (cab != origcab) sys->free(cab);
327
-    }
328
-
329
-    /* free successor cabinets */
330
-    for (cab = origcab->nextcab; cab; cab = ncab) {
331
-      ncab = cab->nextcab;
332
-      sys->free(cab->prevname);
333
-      sys->free(cab->nextname);
334
-      sys->free(cab->previnfo);
335
-      sys->free(cab->nextinfo);
336
-      sys->free(cab);
337
-    }
338
-
339
-    /* free actual cabinet structure */
340
-    cab = origcab->next;
341
-    sys->free(origcab);
342
-
343
-    /* repeat full procedure again with the cab->next pointer (if set) */
344
-    origcab = cab;
345
-  }
346
-}
347
-
348
-/***************************************
349
- * CABD_READ_HEADERS
350
- ***************************************
351
- * reads the cabinet file header, folder list and file list.
352
- * fills out a pre-existing mscabd_cabinet structure, allocates memory
353
- * for folders and files as necessary
354
- */
355
-static int cabd_read_headers(struct mspack_system *sys,
356
-			     struct mspack_file *fh,
357
-			     struct mscabd_cabinet_p *cab,
358
-			     off_t offset, int quiet)
359
-{
360
-  int num_folders, num_files, folder_resv, i, x;
361
-  struct mscabd_folder_p *fol, *linkfol = NULL;
362
-  struct mscabd_file *file, *linkfile = NULL;
363
-  unsigned char buf[64];
364
-
365
-  /* initialise pointers */
366
-  cab->base.next     = NULL;
367
-  cab->base.files    = NULL;
368
-  cab->base.folders  = NULL;
369
-  cab->base.prevcab  = cab->base.nextcab  = NULL;
370
-  cab->base.prevname = cab->base.nextname = NULL;
371
-  cab->base.previnfo = cab->base.nextinfo = NULL;
372
-
373
-  cab->base.base_offset = offset;
374
-
375
-  /* seek to CFHEADER */
376
-  if (sys->seek(fh, offset, MSPACK_SYS_SEEK_START)) {
377
-    return MSPACK_ERR_SEEK;
378
-  }
379
-
380
-  /* read in the CFHEADER */
381
-  if (sys->read(fh, &buf[0], cfhead_SIZEOF) != cfhead_SIZEOF) {
382
-    return MSPACK_ERR_READ;
383
-  }
384
-
385
-  /* check for "MSCF" signature */
386
-  if (EndGetI32(&buf[cfhead_Signature]) != 0x4643534D) {
387
-    return MSPACK_ERR_SIGNATURE;
388
-  }
389
-
390
-  /* some basic header fields */
391
-  cab->base.length    = EndGetI32(&buf[cfhead_CabinetSize]);
392
-  cab->base.set_id    = EndGetI16(&buf[cfhead_SetID]);
393
-  cab->base.set_index = EndGetI16(&buf[cfhead_CabinetIndex]);
394
-
395
-  /* get the number of folders */
396
-  num_folders = EndGetI16(&buf[cfhead_NumFolders]);
397
-  if (num_folders == 0) {
398
-    if (!quiet) sys->message(fh, "no folders in cabinet.");
399
-    return MSPACK_ERR_DATAFORMAT;
400
-  }
401
-
402
-  /* get the number of files */
403
-  num_files = EndGetI16(&buf[cfhead_NumFiles]);
404
-  if (num_files == 0) {
405
-    if (!quiet) sys->message(fh, "no files in cabinet.");
406
-    return MSPACK_ERR_DATAFORMAT;
407
-  }
408
-
409
-  /* check cabinet version */
410
-  if ((buf[cfhead_MajorVersion] != 1) && (buf[cfhead_MinorVersion] != 3)) {
411
-    if (!quiet) sys->message(fh, "WARNING; cabinet version is not 1.3");
412
-  }
413
-
414
-  /* read the reserved-sizes part of header, if present */
415
-  cab->base.flags = EndGetI16(&buf[cfhead_Flags]);
416
-  if (cab->base.flags & cfheadRESERVE_PRESENT) {
417
-    if (sys->read(fh, &buf[0], cfheadext_SIZEOF) != cfheadext_SIZEOF) {
418
-      return MSPACK_ERR_READ;
419
-    }
420
-    cab->base.header_resv = EndGetI16(&buf[cfheadext_HeaderReserved]);
421
-    folder_resv           = buf[cfheadext_FolderReserved];
422
-    cab->block_resv       = buf[cfheadext_DataReserved];
423
-
424
-    if (cab->base.header_resv > 60000) {
425
-      if (!quiet) sys->message(fh, "WARNING; reserved header > 60000.");
426
-    }
427
-
428
-    /* skip the reserved header */
429
-    if (cab->base.header_resv) {
430
-      if (sys->seek(fh, (off_t) cab->base.header_resv, MSPACK_SYS_SEEK_CUR)) {
431
-	return MSPACK_ERR_SEEK;
432
-      }
433
-    }
434
-  }
435
-  else {
436
-    cab->base.header_resv = 0;
437
-    folder_resv           = 0; 
438
-    cab->block_resv       = 0;
439
-  }
440
-
441
-  /* read name and info of preceeding cabinet in set, if present */
442
-  if (cab->base.flags & cfheadPREV_CABINET) {
443
-    cab->base.prevname = cabd_read_string(sys, fh, cab, &x); if (x) return x;
444
-    cab->base.previnfo = cabd_read_string(sys, fh, cab, &x); if (x) return x;
445
-  }
446
-
447
-  /* read name and info of next cabinet in set, if present */
448
-  if (cab->base.flags & cfheadNEXT_CABINET) {
449
-    cab->base.nextname = cabd_read_string(sys, fh, cab, &x); if (x) return x;
450
-    cab->base.nextinfo = cabd_read_string(sys, fh, cab, &x); if (x) return x;
451
-  }
452
-
453
-  /* read folders */
454
-  for (i = 0; i < num_folders; i++) {
455
-    if (sys->read(fh, &buf[0], cffold_SIZEOF) != cffold_SIZEOF) {
456
-      return MSPACK_ERR_READ;
457
-    }
458
-    if (folder_resv) {
459
-      if (sys->seek(fh, (off_t) folder_resv, MSPACK_SYS_SEEK_CUR)) {
460
-	return MSPACK_ERR_SEEK;
461
-      }
462
-    }
463
-
464
-    if (!(fol = sys->alloc(sys, sizeof(struct mscabd_folder_p)))) {
465
-      return MSPACK_ERR_NOMEMORY;
466
-    }
467
-    fol->base.next       = NULL;
468
-    fol->base.comp_type  = EndGetI16(&buf[cffold_CompType]);
469
-    fol->base.num_blocks = EndGetI16(&buf[cffold_NumBlocks]);
470
-    fol->data.next       = NULL;
471
-    fol->data.cab        = (struct mscabd_cabinet_p *) cab;
472
-    fol->data.offset     = offset + (off_t)
473
-      ( (unsigned int) EndGetI32(&buf[cffold_DataOffset]) );
474
-    fol->merge_prev      = NULL;
475
-    fol->merge_next      = NULL;
476
-
477
-    /* link folder into list of folders */
478
-    if (!linkfol) cab->base.folders = (struct mscabd_folder *) fol;
479
-    else linkfol->base.next = (struct mscabd_folder *) fol;
480
-    linkfol = fol;
481
-  }
482
-
483
-  /* read files */
484
-  for (i = 0; i < num_files; i++) {
485
-    if (sys->read(fh, &buf[0], cffile_SIZEOF) != cffile_SIZEOF) {
486
-      return MSPACK_ERR_READ;
487
-    }
488
-
489
-    if (!(file = sys->alloc(sys, sizeof(struct mscabd_file)))) {
490
-      return MSPACK_ERR_NOMEMORY;
491
-    }
492
-
493
-    file->next     = NULL;
494
-    file->length   = EndGetI32(&buf[cffile_UncompressedSize]);
495
-    file->attribs  = EndGetI16(&buf[cffile_Attribs]);
496
-    file->offset   = EndGetI32(&buf[cffile_FolderOffset]);
497
-
498
-    /* set folder pointer */
499
-    x = EndGetI16(&buf[cffile_FolderIndex]);
500
-    if (x < cffileCONTINUED_FROM_PREV) {
501
-      /* normal folder index; count up to the correct folder. the folder
502
-       * pointer will be NULL if folder index is invalid */
503
-      struct mscabd_folder *ifol = cab->base.folders; 
504
-      while (x--) if (ifol) ifol = ifol->next;
505
-      file->folder = ifol;
506
-
507
-      if (!ifol) {
508
-	sys->free(file);
509
-	D(("invalid folder index"))
510
-	return MSPACK_ERR_DATAFORMAT;
511
-      }
512
-    }
513
-    else {
514
-      /* either CONTINUED_TO_NEXT, CONTINUED_FROM_PREV or
515
-       * CONTINUED_PREV_AND_NEXT */
516
-      if ((x == cffileCONTINUED_TO_NEXT) ||
517
-	  (x == cffileCONTINUED_PREV_AND_NEXT))
518
-      {
519
-	/* get last folder */
520
-	struct mscabd_folder *ifol = cab->base.folders;
521
-	while (ifol->next) ifol = ifol->next;
522
-	file->folder = ifol;
523
-
524
-	/* set "merge next" pointer */
525
-	fol = (struct mscabd_folder_p *) ifol;
526
-	if (!fol->merge_next) fol->merge_next = file;
527
-      }
528
-
529
-      if ((x == cffileCONTINUED_FROM_PREV) ||
530
-	  (x == cffileCONTINUED_PREV_AND_NEXT))
531
-      {
532
-	/* get first folder */
533
-	file->folder = cab->base.folders;
534
-
535
-	/* set "merge prev" pointer */
536
-	fol = (struct mscabd_folder_p *) file->folder;
537
-	if (!fol->merge_prev) fol->merge_prev = file;
538
-      }
539
-    }
540
-
541
-    /* get time */
542
-    x = EndGetI16(&buf[cffile_Time]);
543
-    file->time_h = x >> 11;
544
-    file->time_m = (x >> 5) & 0x3F;
545
-    file->time_s = (x << 1) & 0x3E;
546
-
547
-    /* get date */
548
-    x = EndGetI16(&buf[cffile_Date]);
549
-    file->date_d = x & 0x1F;
550
-    file->date_m = (x >> 5) & 0xF;
551
-    file->date_y = (x >> 9) + 1980;
552
-
553
-    /* get filename */
554
-    file->filename = cabd_read_string(sys, fh, cab, &x);
555
-    if (x) { 
556
-      sys->free(file);
557
-      return x;
558
-    }
559
-
560
-    /* link file entry into file list */
561
-    if (!linkfile) cab->base.files = file;
562
-    else linkfile->next = file;
563
-    linkfile = file;
564
-  }
565
-
566
-  return MSPACK_ERR_OK;
567
-}
568
-
569
-static char *cabd_read_string(struct mspack_system *sys,
570
-			      struct mspack_file *fh,
571
-			      struct mscabd_cabinet_p *cab, int *error)
572
-{
573
-  off_t base = sys->tell(fh);
574
-  char buf[256], *str;
575
-  unsigned int len, i, ok;
576
-
577
-  /* read up to 256 bytes */
578
-  len = sys->read(fh, &buf[0], 256);
579
-
580
-  /* search for a null terminator in the buffer */
581
-  for (i = 0, ok = 0; i < len; i++) if (!buf[i]) { ok = 1; break; }
582
-  if (!ok) {
583
-    *error = MSPACK_ERR_DATAFORMAT;
584
-    return NULL;
585
-  }
586
-
587
-  len = i + 1;
588
-
589
-  /* set the data stream to just after the string and return */
590
-  if (sys->seek(fh, base + (off_t)len, MSPACK_SYS_SEEK_START)) {
591
-    *error = MSPACK_ERR_SEEK;
592
-    return NULL;
593
-  }
594
-
595
-  if (!(str = sys->alloc(sys, len))) {
596
-    *error = MSPACK_ERR_NOMEMORY;
597
-    return NULL;
598
-  }
599
-
600
-  sys->copy(&buf[0], str, len);
601
-  *error = MSPACK_ERR_OK;
602
-  return str;
603
-}
604
-    
605
-/***************************************
606
- * CABD_SEARCH, CABD_FIND
607
- ***************************************
608
- * cabd_search opens a file, finds its extent, allocates a search buffer,
609
- * then reads through the whole file looking for possible cabinet headers.
610
- * if it finds any, it tries to read them as real cabinets. returns a linked
611
- * list of results
612
- *
613
- * cabd_find is the inner loop of cabd_search, to make it easier to
614
- * break out of the loop and be sure that all resources are freed
615
- */
616
-static struct mscabd_cabinet *cabd_search(struct mscab_decompressor *base,
617
-					  char *filename)
618
-{
619
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
620
-  struct mscabd_cabinet_p *cab = NULL;
621
-  struct mspack_system *sys;
622
-  unsigned char *search_buf;
623
-  struct mspack_file *fh;
624
-  unsigned int firstlen = 0;
625
-  off_t filelen;
626
-
627
-  if (!base) return NULL;
628
-  sys = this->system;
629
-
630
-  /* allocate a search buffer */
631
-  search_buf = sys->alloc(sys, (size_t) this->param[MSCABD_PARAM_SEARCHBUF]);
632
-  if (!search_buf) {
633
-    this->error = MSPACK_ERR_NOMEMORY;
634
-    return NULL;
635
-  }
636
-
637
-  /* open file and get its full file length */
638
-  if ((fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ))) {
639
-    if (!(this->error = mspack_sys_filelen(sys, fh, &filelen))) {
640
-      this->error = cabd_find(this, search_buf, fh, filename, 0,
641
-			      filelen, &firstlen, &cab);
642
-    }
643
-
644
-    /* truncated / extraneous data warning: */
645
-    if (firstlen && (firstlen != filelen) &&
646
-	(!cab || (cab->base.base_offset == 0)))
647
-    {
648
-      if (firstlen < filelen) {
649
-	sys->message(fh, "WARNING; possible %u extra bytes at end of file.",
650
-		     (unsigned int) (filelen - firstlen));
651
-      }
652
-      else {
653
-	sys->message(fh, "WARNING; file possibly truncated by %u bytes.",
654
-		     (unsigned int) (firstlen - filelen));
655
-      }
656
-    }
657
-    
658
-    sys->close(fh);
659
-  }
660
-  else {
661
-    this->error = MSPACK_ERR_OPEN;
662
-  }
663
-
664
-  /* free the search buffer */
665
-  sys->free(search_buf);
666
-
667
-  return (struct mscabd_cabinet *) cab;
668
-}
669
-
670
-static struct mscabd_cabinet *cabd_dsearch(struct mscab_decompressor *base,
671
-					  int desc)
672
-{
673
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
674
-  struct mscabd_cabinet_p *cab = NULL;
675
-  struct mspack_system *sys;
676
-  unsigned char *search_buf;
677
-  struct mspack_file *fh;
678
-  unsigned int firstlen = 0;
679
-  off_t filelen;
680
-  char *filename = "descriptor-";
681
-
682
-  if (!base) return NULL;
683
-  sys = this->system;
684
-
685
-  /* allocate a search buffer */
686
-  search_buf = sys->alloc(sys, (size_t) this->param[MSCABD_PARAM_SEARCHBUF]);
687
-  if (!search_buf) {
688
-    this->error = MSPACK_ERR_NOMEMORY;
689
-    return NULL;
690
-  }
691
-
692
-  /* open file and get its full file length */
693
-  if ((fh = sys->dopen(sys, desc, MSPACK_SYS_OPEN_READ))) {
694
-    if (!(this->error = mspack_sys_filelen(sys, fh, &filelen))) {
695
-      this->error = cabd_find(this, search_buf, fh, filename, desc,
696
-			      filelen, &firstlen, &cab);
697
-    }
698
-
699
-    /* truncated / extraneous data warning: */
700
-    if (firstlen && (firstlen != filelen) &&
701
-	(!cab || (cab->base.base_offset == 0)))
702
-    {
703
-      if (firstlen < filelen) {
704
-	sys->message(fh, "WARNING; possible %u extra bytes at end of file.",
705
-		     (unsigned int) (filelen - firstlen));
706
-      }
707
-      else {
708
-	sys->message(fh, "WARNING; file possibly truncated by %u bytes.",
709
-		     (unsigned int) (firstlen - filelen));
710
-      }
711
-    }
712
-    
713
-    /* sys->close(fh); */
714
-  }
715
-  else {
716
-    this->error = MSPACK_ERR_OPEN;
717
-  }
718
-
719
-  /* free the search buffer */
720
-  sys->free(search_buf);
721
-
722
-  return (struct mscabd_cabinet *) cab;
723
-}
724
-
725
-
726
-static int cabd_find(struct mscab_decompressor_p *this, unsigned char *buf,
727
-		     struct mspack_file *fh, char *filename, int desc, off_t flen,
728
-		     unsigned int *firstlen,
729
-		     struct mscabd_cabinet_p **firstcab)
730
-{
731
-  struct mscabd_cabinet_p *cab, *link = NULL;
732
-  off_t caboff, offset, foffset=0, cablen=0;
733
-  struct mspack_system *sys = this->system;
734
-  unsigned char *p, *pend, state = 0;
735
-  int false_cabs = 0, length;
736
-
737
-  /* search through the full file length */
738
-  for (offset = 0; offset < flen; offset += length) {
739
-    /* search length is either the full length of the search buffer, or the
740
-     * amount of data remaining to the end of the file, whichever is less. */
741
-    length = flen - offset;
742
-    if (length > this->param[MSCABD_PARAM_SEARCHBUF]) {
743
-      length = this->param[MSCABD_PARAM_SEARCHBUF];
744
-    }
745
-
746
-    /* fill the search buffer with data from disk */
747
-    if (sys->read(fh, &buf[0], length) != length) {
748
-      return MSPACK_ERR_READ;
749
-    }
750
-
751
-    /* FAQ avoidance strategy */
752
-    if ((offset == 0) && (EndGetI32(&buf[0]) == 0x28635349)) {
753
-      sys->message(fh, "WARNING; found InstallShield header. "
754
-		   "This is probably an InstallShield file. "
755
-		   "Use UNSHIELD (http://synce.sf.net) to unpack it.");
756
-    }
757
-
758
-    /* read through the entire buffer. */
759
-    for (p = &buf[0], pend = &buf[length]; p < pend; ) {
760
-      switch (state) {
761
-	/* starting state */
762
-      case 0:
763
-	/* we spend most of our time in this while loop, looking for
764
-	 * a leading 'M' of the 'MSCF' signature */
765
-	while (p < pend && *p != 0x4D) p++;
766
-	/* if we found tht 'M', advance state */
767
-	if (p++ < pend) state = 1;
768
-	break;
769
-
770
-      /* verify that the next 3 bytes are 'S', 'C' and 'F' */
771
-      case 1: state = (*p++ == 0x53) ? 2 : 0; break;
772
-      case 2: state = (*p++ == 0x43) ? 3 : 0; break;
773
-      case 3: state = (*p++ == 0x46) ? 4 : 0; break;
774
-
775
-      /* we don't care about bytes 4-7 (see default: for action) */
776
-
777
-      /* bytes 8-11 are the overall length of the cabinet */
778
-      case 8:  cablen  = *p++;       state++; break;
779
-      case 9:  cablen |= *p++ << 8;  state++; break;
780
-      case 10: cablen |= *p++ << 16; state++; break;
781
-      case 11: cablen |= *p++ << 24; state++; break;
782
-
783
-      /* we don't care about bytes 12-15 (see default: for action) */
784
-
785
-      /* bytes 16-19 are the offset within the cabinet of the filedata */
786
-      case 16: foffset  = *p++;       state++; break;
787
-      case 17: foffset |= *p++ << 8;  state++; break;
788
-      case 18: foffset |= *p++ << 16; state++; break;
789
-      case 19: foffset |= *p++ << 24;
790
-	/* now we have recieved 20 bytes of potential cab header. work out
791
-	 * the offset in the file of this potential cabinet */
792
-	caboff = offset + (p - &buf[0]) - 20;
793
-
794
-	/* should reading cabinet fail, restart search just after 'MSCF' */
795
-	offset = caboff + 4;
796
-
797
-	/* capture the "length of cabinet" field if there is a cabinet at
798
-	 * offset 0 in the file, regardless of whether the cabinet can be
799
-	 * read correctly or not */
800
-	if (caboff == 0) *firstlen = cablen;
801
-
802
-	/* check that the files offset is less than the alleged length of
803
-	 * the cabinet, and that the offset + the alleged length are
804
-	 * 'roughly' within the end of overall file length */
805
-	if ((foffset < cablen) &&
806
-	    ((caboff + foffset) < (flen + 32)) &&
807
-	    ((caboff + cablen)  < (flen + 32)) )
808
-	{
809
-	  /* likely cabinet found -- try reading it */
810
-	  if (!(cab = sys->alloc(sys, sizeof(struct mscabd_cabinet_p)))) {
811
-	    return MSPACK_ERR_NOMEMORY;
812
-	  }
813
-	  cab->base.filename = filename;
814
-	  cab->base.desc = desc;
815
-	  if (cabd_read_headers(sys, fh, cab, caboff, 1)) {
816
-	    /* destroy the failed cabinet */
817
-	    cabd_close((struct mscab_decompressor *) this,
818
-		       (struct mscabd_cabinet *) cab);
819
-	    false_cabs++;
820
-	  }
821
-	  else {
822
-	    /* cabinet read correctly! */
823
-
824
-	    /* cause the search to restart after this cab's data. */
825
-	    offset = caboff + cablen;
826
-	      
827
-	    /* link the cab into the list */
828
-	    if (!link) *firstcab = cab;
829
-	    else link->base.next = (struct mscabd_cabinet *) cab;
830
-	    link = cab;
831
-	  }
832
-	}
833
-
834
-	/* restart search */
835
-	if (offset >= flen) return MSPACK_ERR_OK;
836
-	if (sys->seek(fh, offset, MSPACK_SYS_SEEK_START))
837
-	  return MSPACK_ERR_SEEK;
838
-	length = 0;
839
-	p = pend;
840
-	state = 0;
841
-	break;
842
-
843
-      /* for bytes 4-7 and 12-15, just advance state/pointer */
844
-      default:
845
-	p++, state++;
846
-      } /* switch(state) */
847
-    } /* for (... p < pend ...) */
848
-  } /* for (... offset < length ...) */
849
-
850
-  if (false_cabs) {
851
-    D(("%d false cabinets found", false_cabs))
852
-  }
853
-
854
-  return MSPACK_ERR_OK;
855
-}
856
-					     
857
-/***************************************
858
- * CABD_MERGE, CABD_PREPEND, CABD_APPEND
859
- ***************************************
860
- * joins cabinets together, also merges split folders between these two
861
- * cabinets only. this includes freeing the duplicate folder and file(s)
862
- * and allocating a further mscabd_folder_data structure to append to the
863
- * merged folder's data parts list.
864
- */
865
-static int cabd_prepend(struct mscab_decompressor *base,
866
-			struct mscabd_cabinet *cab,
867
-			struct mscabd_cabinet *prevcab)
868
-{
869
-  return cabd_merge(base, prevcab, cab);
870
-}
871
-
872
-static int cabd_append(struct mscab_decompressor *base,
873
-			struct mscabd_cabinet *cab,
874
-			struct mscabd_cabinet *nextcab)
875
-{
876
-  return cabd_merge(base, cab, nextcab);
877
-}
878
-
879
-static int cabd_merge(struct mscab_decompressor *base,
880
-		      struct mscabd_cabinet *lcab,
881
-		      struct mscabd_cabinet *rcab)
882
-{
883
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
884
-  struct mscabd_folder_data *data, *ndata;
885
-  struct mscabd_folder_p *lfol, *rfol;
886
-  struct mscabd_file *fi, *rfi, *lfi;
887
-  struct mscabd_cabinet *cab;
888
-  struct mspack_system *sys;
889
-
890
-  if (!this) return MSPACK_ERR_ARGS;
891
-  sys = this->system;
892
-
893
-  /* basic args check */
894
-  if (!lcab || !rcab || (lcab == rcab)) {
895
-    D(("lcab NULL, rcab NULL or lcab = rcab"))
896
-    return this->error = MSPACK_ERR_ARGS;
897
-  }
898
-
899
-  /* check there's not already a cabinet attached */
900
-  if (lcab->nextcab || rcab->prevcab) {
901
-    D(("cabs already joined"))
902
-    return this->error = MSPACK_ERR_ARGS;
903
-  }
904
-
905
-  /* do not create circular cabinet chains */
906
-  for (cab = lcab->prevcab; cab; cab = cab->prevcab) {
907
-    if (cab == rcab) {D(("circular!")) return this->error = MSPACK_ERR_ARGS;}
908
-  }
909
-  for (cab = rcab->nextcab; cab; cab = cab->nextcab) {
910
-    if (cab == lcab) {D(("circular!")) return this->error = MSPACK_ERR_ARGS;}
911
-  }
912
-
913
-  /* warn about odd set IDs or indices */
914
-  if (lcab->set_id != rcab->set_id) {
915
-    sys->message(NULL, "WARNING; merged cabinets with differing Set IDs.");
916
-  }
917
-
918
-  if (lcab->set_index > rcab->set_index) {
919
-    sys->message(NULL, "WARNING; merged cabinets with odd order.");
920
-  }
921
-
922
-  /* merging the last folder in lcab with the first folder in rcab */
923
-  lfol = (struct mscabd_folder_p *) lcab->folders;
924
-  rfol = (struct mscabd_folder_p *) rcab->folders;
925
-  while (lfol->base.next) lfol = (struct mscabd_folder_p *) lfol->base.next;
926
-
927
-  /* do we need to merge folders? */
928
-  if (!lfol->merge_next && !rfol->merge_prev) {
929
-    /* no, at least one of the folders is not for merging */
930
-
931
-    /* attach cabs */
932
-    lcab->nextcab = rcab;
933
-    rcab->prevcab = lcab;
934
-
935
-    /* attach folders */
936
-    lfol->base.next = (struct mscabd_folder *) rfol;
937
-
938
-    /* attach files */
939
-    fi = lcab->files;
940
-    while (fi->next) fi = fi->next;
941
-    fi->next = rcab->files;
942
-  }
943
-  else {
944
-    /* folder merge required */
945
-
946
-    if (!lfol->merge_next) {
947
-      D(("rcab has merge files, lcab doesn't"))
948
-      return this->error = MSPACK_ERR_DATAFORMAT;
949
-    }
950
-
951
-    if (!rfol->merge_prev) {
952
-      D(("lcab has merge files, rcab doesn't"))
953
-      return this->error = MSPACK_ERR_DATAFORMAT;
954
-    }
955
-
956
-    /* check that both folders use the same compression method/settings */
957
-    if (lfol->base.comp_type != rfol->base.comp_type) {
958
-      D(("compression type mismatch"))
959
-      return this->error = MSPACK_ERR_DATAFORMAT;
960
-    }
961
-
962
-    /* for all files in lfol (which is the last folder in whichever cab),
963
-     * compare them to the files from rfol. they should be identical in
964
-     * number and order. to verify this, check the OFFSETS of each file. */
965
-    lfi = lfol->merge_next;
966
-    rfi = rfol->merge_prev;
967
-    while (lfi) {
968
-      if (!rfi || (lfi->offset !=  rfi->offset)) {
969
-	D(("folder merge mismatch"))
970
-	return this->error = MSPACK_ERR_DATAFORMAT;
971
-      }
972
-      lfi = lfi->next;
973
-      rfi = rfi->next;
974
-    }
975
-
976
-    /* allocate a new folder data structure */
977
-    if (!(data = sys->alloc(sys, sizeof(struct mscabd_folder_data)))) {
978
-      return this->error = MSPACK_ERR_NOMEMORY;
979
-    }
980
-
981
-    /* attach cabs */
982
-    lcab->nextcab = rcab;
983
-    rcab->prevcab = lcab;
984
-
985
-    /* append rfol's data to lfol */
986
-    ndata = &lfol->data;
987
-    while (ndata->next) ndata = ndata->next;
988
-    ndata->next = data;
989
-    *data = rfol->data;
990
-    rfol->data.next = NULL;
991
-
992
-    /* lfol becomes rfol.
993
-     * NOTE: special case, don't merge if rfol is merge prev and next,
994
-     * rfol->merge_next is going to be deleted, so keep lfol's version
995
-     * instead */
996
-    lfol->base.num_blocks += rfol->base.num_blocks - 1;
997
-    if ((rfol->merge_next == NULL) ||
998
-	(rfol->merge_next->folder != (struct mscabd_folder *) rfol))
999
-    {
1000
-      lfol->merge_next = rfol->merge_next;
1001
-    }
1002
-
1003
-    /* attach the rfol's folder (except the merge folder) */
1004
-    while (lfol->base.next) lfol = (struct mscabd_folder_p *) lfol->base.next;
1005
-    lfol->base.next = rfol->base.next;
1006
-
1007
-    /* free disused merge folder */
1008
-    sys->free(rfol);
1009
-
1010
-    /* attach rfol's files */
1011
-    fi = lcab->files;
1012
-    while (fi->next) fi = fi->next;
1013
-    fi->next = rcab->files;
1014
-
1015
-    /* delete all files from rfol's merge folder */
1016
-    lfi = NULL;
1017
-    for (fi = lcab->files; fi ; fi = rfi) {
1018
-      rfi = fi->next;
1019
-      /* if file's folder matches the merge folder, unlink and free it */
1020
-      if (fi->folder == (struct mscabd_folder *) rfol) {
1021
-	if (lfi) lfi->next = rfi; else lcab->files = rfi;
1022
-	sys->free(fi->filename);
1023
-	sys->free(fi);
1024
-      }
1025
-      else lfi = fi;
1026
-    }
1027
-  }
1028
-
1029
-  /* all done! fix files and folders pointers in all cabs so they all
1030
-   * point to the same list  */
1031
-  for (cab = lcab->prevcab; cab; cab = cab->prevcab) {
1032
-    cab->files   = lcab->files;
1033
-    cab->folders = lcab->folders;
1034
-  }
1035
-
1036
-  for (cab = lcab->nextcab; cab; cab = cab->nextcab) {
1037
-    cab->files   = lcab->files;
1038
-    cab->folders = lcab->folders;
1039
-  }
1040
-
1041
-  return this->error = MSPACK_ERR_OK;
1042
-}
1043
-
1044
-/***************************************
1045
- * CABD_EXTRACT
1046
- ***************************************
1047
- * extracts a file from a cabinet
1048
- */
1049
-static int cabd_extract(struct mscab_decompressor *base,
1050
-			 struct mscabd_file *file, char *filename)
1051
-{
1052
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
1053
-  struct mscabd_folder_p *fol;
1054
-  struct mspack_system *sys;
1055
-  struct mspack_file *fh;
1056
-
1057
-  if (!this) return MSPACK_ERR_ARGS;
1058
-  if (!file) return this->error = MSPACK_ERR_ARGS;
1059
-
1060
-  sys = this->system;
1061
-  fol = (struct mscabd_folder_p *) file->folder;
1062
-
1063
-  /* check if file can be extracted */
1064
-  if ((!fol) || (fol->merge_prev) ||
1065
-      (((file->offset + file->length) / CAB_BLOCKMAX) > fol->base.num_blocks))
1066
-  {
1067
-    sys->message(NULL, "ERROR; file \"%s\" cannot be extracted, "
1068
-		 "cabinet set is incomplete.", file->filename);
1069
-    return this->error = MSPACK_ERR_DATAFORMAT;
1070
-  }
1071
-
1072
-  /* allocate generic decompression state */
1073
-  if (!this->d) {
1074
-    this->d = sys->alloc(sys, sizeof(struct mscabd_decompress_state));
1075
-    if (!this->d) return this->error = MSPACK_ERR_NOMEMORY;
1076
-    this->d->folder     = NULL;
1077
-    this->d->data       = NULL;
1078
-    this->d->sys        = *sys;
1079
-    this->d->sys.read   = &cabd_sys_read;
1080
-    this->d->sys.write  = &cabd_sys_write;
1081
-    this->d->state      = NULL;
1082
-    this->d->infh       = NULL;
1083
-    this->d->incab      = NULL;
1084
-  }
1085
-
1086
-  /* do we need to change folder or reset the current folder? */
1087
-  if ((this->d->folder != fol) || (this->d->offset > file->offset)) {
1088
-    /* do we need to open a new cab file? */
1089
-
1090
-    if (!this->d->infh || (fol->data.cab != this->d->incab)) {
1091
-      if (this->d->infh) sys->close(this->d->infh);
1092
-      this->d->incab = fol->data.cab;
1093
-
1094
-      if(fol->data.cab->base.desc) {
1095
-        this->d->infh = sys->dopen(sys, fol->data.cab->base.desc,
1096
-				MSPACK_SYS_OPEN_READ);
1097
-      } else {
1098
-        this->d->infh = sys->open(sys, fol->data.cab->base.filename,
1099
-				MSPACK_SYS_OPEN_READ);
1100
-      }
1101
-      if (!this->d->infh) return this->error = MSPACK_ERR_OPEN;
1102
-    }
1103
-
1104
-    /* seek to start of data blocks */
1105
-    if (sys->seek(this->d->infh, fol->data.offset, MSPACK_SYS_SEEK_START)) {
1106
-      return this->error = MSPACK_ERR_SEEK;
1107
-    }
1108
-
1109
-    /* set up decompressor */
1110
-    if (cabd_init_decomp(this, (unsigned int) fol->base.comp_type)) {
1111
-      return this->error;
1112
-    }
1113
-
1114
-    /* initialise new folder state */
1115
-    this->d->folder = fol;
1116
-    this->d->data   = &fol->data;
1117
-    this->d->offset = 0;
1118
-    this->d->block  = 0;
1119
-    this->d->i_ptr = this->d->i_end = &this->d->input[0];
1120
-  }
1121
-
1122
-  /* open file for output */
1123
-  if (!(fh = sys->open(sys, filename, MSPACK_SYS_OPEN_WRITE))) {
1124
-    return this->error = MSPACK_ERR_OPEN;
1125
-  }
1126
-
1127
-  this->error = MSPACK_ERR_OK;
1128
-
1129
-  /* if file has more than 0 bytes */
1130
-  if (file->length) {
1131
-    off_t bytes;
1132
-    int error;
1133
-    /* get to correct offset.
1134
-     * - use NULL fh to say 'no writing' to cabd_sys_write()
1135
-     * - MSPACK_ERR_READ returncode indicates error in cabd_sys_read(),
1136
-     *   the real error will already be stored in this->error
1137
-     */
1138
-    this->d->outfh = NULL;
1139
-    if ((bytes = file->offset - this->d->offset)) {
1140
-      error = this->d->decompress(this->d->state, bytes);
1141
-      if (error != MSPACK_ERR_READ) this->error = error;
1142
-    }
1143
-
1144
-    /* if getting to the correct offset was error free, unpack file */
1145
-    if (!this->error) {
1146
-      this->d->outfh = fh;
1147
-      error = this->d->decompress(this->d->state, (off_t) file->length);
1148
-      if (error != MSPACK_ERR_READ) this->error = error;
1149
-    }
1150
-  }
1151
-
1152
-  /* close output file */
1153
-  sys->close(fh);
1154
-  this->d->outfh = NULL;
1155
-
1156
-  return this->error;
1157
-}
1158
-
1159
-/***************************************
1160
- * CABD_INIT_DECOMP, CABD_FREE_DECOMP
1161
- ***************************************
1162
- * cabd_init_decomp initialises decompression state, according to which
1163
- * decompression method was used. relies on this->d->folder being the same
1164
- * as when initialised.
1165
- *
1166
- * cabd_free_decomp frees decompression state, according to which method
1167
- * was used.
1168
- */
1169
-static int cabd_init_decomp(struct mscab_decompressor_p *this, unsigned int ct)
1170
-{
1171
-  struct mspack_file *fh = (struct mspack_file *) this;
1172
-
1173
-  if (!this || !this->d) {
1174
-    return this->error = MSPACK_ERR_ARGS;
1175
-  }
1176
-
1177
-  /* free any existing decompressor */
1178
-  cabd_free_decomp(this);
1179
-
1180
-  this->d->comp_type = ct;
1181
-
1182
-  switch (ct & cffoldCOMPTYPE_MASK) {
1183
-  case cffoldCOMPTYPE_NONE:
1184
-    this->d->decompress = (int (*)(void *, off_t)) &noned_decompress;
1185
-    this->d->state = noned_init(&this->d->sys, fh, fh,
1186
-				this->param[MSCABD_PARAM_DECOMPBUF]);
1187
-    break;
1188
-  case cffoldCOMPTYPE_MSZIP:
1189
-    this->d->decompress = (int (*)(void *, off_t)) &mszipd_decompress;
1190
-    this->d->state = mszipd_init(&this->d->sys, fh, fh,
1191
-				 this->param[MSCABD_PARAM_DECOMPBUF],
1192
-				 this->param[MSCABD_PARAM_FIXMSZIP]);
1193
-    break;
1194
-  case cffoldCOMPTYPE_QUANTUM:
1195
-    this->d->decompress = (int (*)(void *, off_t)) &qtmd_decompress;
1196
-    this->d->state = qtmd_init(&this->d->sys, fh, fh, (int) (ct >> 8) & 0x1f,
1197
-			       this->param[MSCABD_PARAM_DECOMPBUF]);
1198
-    break;
1199
-  case cffoldCOMPTYPE_LZX:
1200
-    this->d->decompress = (int (*)(void *, off_t)) &lzxd_decompress;
1201
-    this->d->state = lzxd_init(&this->d->sys, fh, fh, (int) (ct >> 8) & 0x1f, 0,
1202
-			       this->param[MSCABD_PARAM_DECOMPBUF], (off_t) 0);
1203
-    break;
1204
-  default:
1205
-    return this->error = MSPACK_ERR_DATAFORMAT;
1206
-  }
1207
-  return this->error = (this->d->state) ? MSPACK_ERR_OK : MSPACK_ERR_NOMEMORY;
1208
-}
1209
-
1210
-static void cabd_free_decomp(struct mscab_decompressor_p *this) {
1211
-  if (!this || !this->d || !this->d->folder || !this->d->state) return;
1212
-
1213
-  switch (this->d->comp_type & cffoldCOMPTYPE_MASK) {
1214
-  case cffoldCOMPTYPE_NONE:    noned_free(this->d->state);   break;
1215
-  case cffoldCOMPTYPE_MSZIP:   mszipd_free(this->d->state);  break;
1216
-  case cffoldCOMPTYPE_QUANTUM: qtmd_free(this->d->state);    break;
1217
-  case cffoldCOMPTYPE_LZX:     lzxd_free(this->d->state);    break;
1218
-  }
1219
-  this->d->decompress = NULL;
1220
-  this->d->state      = NULL;
1221
-}
1222
-
1223
-/***************************************
1224
- * CABD_SYS_READ, CABD_SYS_WRITE
1225
- ***************************************
1226
- * cabd_sys_read is the internal reader function which the decompressors
1227
- * use. will read data blocks (and merge split blocks) from the cabinet
1228
- * and serve the read bytes to the decompressors
1229
- *
1230
- * cabd_sys_write is the internal writer function which the decompressors
1231
- * use. it either writes data to disk (this->d->outfh) with the real
1232
- * sys->write() function, or does nothing with the data when
1233
- * this->d->outfh == NULL. advances this->d->offset
1234
- */
1235
-static int cabd_sys_read(struct mspack_file *file, void *buffer, int bytes) {
1236
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) file;
1237
-  unsigned char *buf = (unsigned char *) buffer;
1238
-  struct mspack_system *sys = this->system;
1239
-  int avail, todo, outlen, ignore_cksum;
1240
-
1241
-  ignore_cksum = this->param[MSCABD_PARAM_FIXMSZIP] &&
1242
-    ((this->d->comp_type & cffoldCOMPTYPE_MASK) == cffoldCOMPTYPE_MSZIP);
1243
-
1244
-  todo = bytes;
1245
-  while (todo > 0) {
1246
-    avail = this->d->i_end - this->d->i_ptr;
1247
-
1248
-    /* if out of input data, read a new block */
1249
-    if (avail) {
1250
-      /* copy as many input bytes available as possible */
1251
-      if (avail > todo) avail = todo;
1252
-      sys->copy(this->d->i_ptr, buf, (size_t) avail);
1253
-      this->d->i_ptr += avail;
1254
-      buf  += avail;
1255
-      todo -= avail;
1256
-    }
1257
-    else {
1258
-      /* out of data, read a new block */
1259
-
1260
-      /* check if we're out of input blocks, advance block counter */
1261
-      if (this->d->block++ >= this->d->folder->base.num_blocks) {
1262
-	this->error = MSPACK_ERR_DATAFORMAT;
1263
-	break;
1264
-      }
1265
-
1266
-      /* read a block */
1267
-      this->error = cabd_sys_read_block(sys, this->d, &outlen, ignore_cksum);
1268
-      if (this->error) return -1;
1269
-
1270
-      /* special Quantum hack -- trailer byte to allow the decompressor
1271
-       * to realign itself. CAB Quantum blocks, unlike LZX blocks, can have
1272
-       * anything from 0 to 4 trailing null bytes. */
1273
-      if ((this->d->comp_type & cffoldCOMPTYPE_MASK)==cffoldCOMPTYPE_QUANTUM) {
1274
-	*this->d->i_end++ = 0xFF;
1275
-      }
1276
-
1277
-      /* is this the last block? */
1278
-      if (this->d->block >= this->d->folder->base.num_blocks) {
1279
-	/* last block */
1280
-	if ((this->d->comp_type & cffoldCOMPTYPE_MASK) == cffoldCOMPTYPE_LZX) {
1281
-	  /* special LZX hack -- on the last block, inform LZX of the
1282
-	   * size of the output data stream. */
1283
-	  lzxd_set_output_length(this->d->state, (off_t)
1284
-				 ((this->d->block-1) * CAB_BLOCKMAX + outlen));
1285
-	}
1286
-      }
1287
-      else {
1288
-	/* not the last block */
1289
-	if (outlen != CAB_BLOCKMAX) {
1290
-	  this->system->message(this->d->infh,
1291
-				"WARNING; non-maximal data block");
1292
-	}
1293
-      }
1294
-    } /* if (avail) */
1295
-  } /* while (todo > 0) */
1296
-  return bytes - todo;
1297
-}
1298
-
1299
-static int cabd_sys_write(struct mspack_file *file, void *buffer, int bytes) {
1300
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) file;
1301
-  this->d->offset += bytes;
1302
-  if (this->d->outfh) {
1303
-    return this->system->write(this->d->outfh, buffer, bytes);
1304
-  }
1305
-  return bytes;
1306
-}
1307
-
1308
-/***************************************
1309
- * CABD_SYS_READ_BLOCK
1310
- ***************************************
1311
- * reads a whole data block from a cab file. the block may span more than
1312
- * one cab file, if it does then the fragments will be reassembled
1313
- */
1314
-static int cabd_sys_read_block(struct mspack_system *sys,
1315
-			       struct mscabd_decompress_state *d,
1316
-			       int *out, int ignore_cksum)
1317
-{
1318
-  unsigned char hdr[cfdata_SIZEOF];
1319
-  unsigned int cksum;
1320
-  int len;
1321
-
1322
-  /* reset the input block pointer and end of block pointer */
1323
-  d->i_ptr = d->i_end = &d->input[0];
1324
-
1325
-  do {
1326
-    /* read the block header */
1327
-    if (sys->read(d->infh, &hdr[0], cfdata_SIZEOF) != cfdata_SIZEOF) {
1328
-      return MSPACK_ERR_READ;
1329
-    }
1330
-
1331
-    /* skip any reserved block headers */
1332
-    if (d->data->cab->block_resv &&
1333
-	sys->seek(d->infh, (off_t) d->data->cab->block_resv,
1334
-		  MSPACK_SYS_SEEK_CUR))
1335
-    {
1336
-      return MSPACK_ERR_SEEK;
1337
-    }
1338
-
1339
-    /* blocks must not be over CAB_INPUTMAX in size */
1340
-    len = EndGetI16(&hdr[cfdata_CompressedSize]);
1341
-    if (((d->i_end - d->i_ptr) + len) > CAB_INPUTMAX) {
1342
-      D(("block size > CAB_INPUTMAX (%d + %d)", d->i_end - d->i_ptr, len))
1343
-      return MSPACK_ERR_DATAFORMAT;
1344
-    }
1345
-
1346
-     /* blocks must not expand to more than CAB_BLOCKMAX */
1347
-    if (EndGetI16(&hdr[cfdata_UncompressedSize]) > CAB_BLOCKMAX) {
1348
-      D(("block size > CAB_BLOCKMAX"))
1349
-      return MSPACK_ERR_DATAFORMAT;
1350
-    }
1351
-
1352
-    /* read the block data */
1353
-    if (sys->read(d->infh, d->i_end, len) != len) {
1354
-      return MSPACK_ERR_READ;
1355
-    }
1356
-
1357
-    /* perform checksum test on the block (if one is stored) */
1358
-    if ((cksum = EndGetI32(&hdr[cfdata_CheckSum]))) {
1359
-      unsigned int sum2 = cabd_checksum(d->i_end, (unsigned int) len, 0);
1360
-      if (cabd_checksum(&hdr[4], 4, sum2) != cksum) {
1361
-	if (!ignore_cksum) return MSPACK_ERR_CHECKSUM;
1362
-	sys->message(d->infh, "WARNING; bad block checksum found");
1363
-      }
1364
-    }
1365
-
1366
-    /* advance end of block pointer to include newly read data */
1367
-    d->i_end += len;
1368
-
1369
-    /* uncompressed size == 0 means this block was part of a split block
1370
-     * and it continues as the first block of the next cabinet in the set.
1371
-     * otherwise, this is the last part of the block, and no more block
1372
-     * reading needs to be done.
1373
-     */
1374
-    /* EXIT POINT OF LOOP -- uncompressed size != 0 */
1375
-    if ((*out = EndGetI16(&hdr[cfdata_UncompressedSize]))) {
1376
-      return MSPACK_ERR_OK;
1377
-    }
1378
-
1379
-    /* otherwise, advance to next cabinet */
1380
-
1381
-    /* close current file handle */
1382
-    sys->close(d->infh);
1383
-    d->infh = NULL;
1384
-
1385
-    /* advance to next member in the cabinet set */
1386
-    if (!(d->data = d->data->next)) {
1387
-      D(("ran out of splits in cabinet set"))
1388
-      return MSPACK_ERR_DATAFORMAT;
1389
-    }
1390
-
1391
-    /* open next cab file */
1392
-    d->incab = d->data->cab;
1393
-    if (!(d->infh = sys->open(sys, d->incab->base.filename,
1394
-			      MSPACK_SYS_OPEN_READ)))
1395
-    {
1396
-      return MSPACK_ERR_OPEN;
1397
-    }
1398
-
1399
-    /* seek to start of data blocks */
1400
-    if (sys->seek(d->infh, d->data->offset, MSPACK_SYS_SEEK_START)) {
1401
-      return MSPACK_ERR_SEEK;
1402
-    }
1403
-  } while (1);
1404
-
1405
-  /* not reached */
1406
-  return MSPACK_ERR_OK;
1407
-}
1408
-
1409
-static unsigned int cabd_checksum(unsigned char *data, unsigned int bytes,
1410
-				  unsigned int cksum)
1411
-{
1412
-  unsigned int len, ul = 0;
1413
-
1414
-  for (len = bytes >> 2; len--; data += 4) {
1415
-    cksum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
1416
-  }
1417
-
1418
-  switch (bytes & 3) {
1419
-  case 3: ul |= *data++ << 16;
1420
-  case 2: ul |= *data++ <<  8;
1421
-  case 1: ul |= *data;
1422
-  }
1423
-  cksum ^= ul;
1424
-
1425
-  return cksum;
1426
-}
1427
-
1428
-/***************************************
1429
- * NONED_INIT, NONED_DECOMPRESS, NONED_FREE
1430
- ***************************************
1431
- * the "not compressed" method decompressor
1432
- */
1433
-struct noned_state {
1434
-  struct mspack_system *sys;
1435
-  struct mspack_file *i;
1436
-  struct mspack_file *o;
1437
-  unsigned char *buf;
1438
-  int bufsize;
1439
-};
1440
-
1441
-static struct noned_state *noned_init(struct mspack_system *sys,
1442
-				      struct mspack_file *in,
1443
-				      struct mspack_file *out,
1444
-				      int bufsize)
1445
-{
1446
-  struct noned_state *state = sys->alloc(sys, sizeof(struct noned_state));
1447
-  unsigned char *buf = sys->alloc(sys, (size_t) bufsize);
1448
-  if (state && buf) {
1449
-    state->sys     = sys;
1450
-    state->i       = in;
1451
-    state->o       = out;
1452
-    state->buf     = buf;
1453
-    state->bufsize = bufsize;
1454
-  }
1455
-  else {
1456
-    sys->free(buf);
1457
-    sys->free(state);
1458
-    state = NULL;
1459
-  }
1460
-  return state;
1461
-}
1462
-
1463
-static int noned_decompress(struct noned_state *s, off_t bytes) {
1464
-  int run;
1465
-  while (bytes > 0) {
1466
-    run = (bytes > s->bufsize) ? s->bufsize : (int) bytes;
1467
-    if (s->sys->read(s->i, &s->buf[0], run) != run) return MSPACK_ERR_READ;
1468
-    if (s->sys->write(s->o, &s->buf[0], run) != run) return MSPACK_ERR_WRITE;
1469
-    bytes -= run;
1470
-  }
1471
-  return MSPACK_ERR_OK;
1472
-}
1473
-
1474
-static void noned_free(struct noned_state *state) {
1475
-  struct mspack_system *sys;
1476
-  if (state) {
1477
-    sys = state->sys;
1478
-    sys->free(state->buf);
1479
-    sys->free(state);
1480
-  }
1481
-}
1482
-
1483
-
1484
-/***************************************
1485
- * CABD_PARAM
1486
- ***************************************
1487
- * allows a parameter to be set
1488
- */
1489
-static int cabd_param(struct mscab_decompressor *base, int param, int value) {
1490
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
1491
-  if (!this) return MSPACK_ERR_ARGS;
1492
-
1493
-  switch (param) {
1494
-  case MSCABD_PARAM_SEARCHBUF:
1495
-    if (value < 4) return MSPACK_ERR_ARGS;
1496
-    this->param[MSCABD_PARAM_SEARCHBUF] = value;
1497
-    break;
1498
-  case MSCABD_PARAM_FIXMSZIP:
1499
-    this->param[MSCABD_PARAM_FIXMSZIP] = value;
1500
-    break;
1501
-  case MSCABD_PARAM_DECOMPBUF:
1502
-    if (value < 4) return MSPACK_ERR_ARGS;
1503
-    this->param[MSCABD_PARAM_DECOMPBUF] = value;
1504
-    break;
1505
-  default:
1506
-    return MSPACK_ERR_ARGS;
1507
-  }
1508
-  return MSPACK_ERR_OK;
1509
-}
1510
-
1511
-/***************************************
1512
- * CABD_ERROR
1513
- ***************************************
1514
- * returns the last error that occurred
1515
- */
1516
-static int cabd_error(struct mscab_decompressor *base) {
1517
-  struct mscab_decompressor_p *this = (struct mscab_decompressor_p *) base;
1518
-  return (this) ? this->error : MSPACK_ERR_ARGS;
1519
-}
1520 1
deleted file mode 100644
... ...
@@ -1,167 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
5
- * by Microsoft Corporation.
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * For further details, see the file COPYING.LIB distributed with libmspack
11
- */
12
-
13
-#ifndef MSPACK_LZX_H
14
-#define MSPACK_LZX_H 1
15
-
16
-/* LZX compression / decompression definitions */
17
-
18
-/* some constants defined by the LZX specification */
19
-#define LZX_MIN_MATCH                (2)
20
-#define LZX_MAX_MATCH                (257)
21
-#define LZX_NUM_CHARS                (256)
22
-#define LZX_BLOCKTYPE_INVALID        (0)   /* also blocktypes 4-7 invalid */
23
-#define LZX_BLOCKTYPE_VERBATIM       (1)
24
-#define LZX_BLOCKTYPE_ALIGNED        (2)
25
-#define LZX_BLOCKTYPE_UNCOMPRESSED   (3)
26
-#define LZX_PRETREE_NUM_ELEMENTS     (20)
27
-#define LZX_ALIGNED_NUM_ELEMENTS     (8)   /* aligned offset tree #elements */
28
-#define LZX_NUM_PRIMARY_LENGTHS      (7)   /* this one missing from spec! */
29
-#define LZX_NUM_SECONDARY_LENGTHS    (249) /* length tree #elements */
30
-
31
-/* LZX huffman defines: tweak tablebits as desired */
32
-#define LZX_PRETREE_MAXSYMBOLS  (LZX_PRETREE_NUM_ELEMENTS)
33
-#define LZX_PRETREE_TABLEBITS   (6)
34
-#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8)
35
-#define LZX_MAINTREE_TABLEBITS  (12)
36
-#define LZX_LENGTH_MAXSYMBOLS   (LZX_NUM_SECONDARY_LENGTHS+1)
37
-#define LZX_LENGTH_TABLEBITS    (12)
38
-#define LZX_ALIGNED_MAXSYMBOLS  (LZX_ALIGNED_NUM_ELEMENTS)
39
-#define LZX_ALIGNED_TABLEBITS   (7)
40
-#define LZX_LENTABLE_SAFETY (64)  /* table decoding overruns are allowed */
41
-
42
-#define LZX_FRAME_SIZE (32768) /* the size of a frame in LZX */
43
-
44
-struct lzxd_stream {
45
-  struct mspack_system *sys;      /* I/O routines                            */
46
-  struct mspack_file   *input;    /* input file handle                       */
47
-  struct mspack_file   *output;   /* output file handle                      */
48
-
49
-  off_t   offset;                 /* number of bytes actually output         */
50
-  off_t   length;                 /* overall decompressed length of stream   */
51
-
52
-  unsigned char *window;          /* decoding window                         */
53
-  unsigned int   window_size;     /* window size                             */
54
-  unsigned int   window_posn;     /* decompression offset within window      */
55
-  unsigned int   frame_posn;      /* current frame offset within in window   */
56
-  unsigned int   frame;           /* the number of 32kb frames processed     */
57
-  unsigned int   reset_interval;  /* which frame do we reset the compressor? */
58
-
59
-  unsigned int   R0, R1, R2;      /* for the LRU offset system               */
60
-  unsigned int   block_length;    /* uncompressed length of this LZX block   */
61
-  unsigned int   block_remaining; /* uncompressed bytes still left to decode */
62
-
63
-  signed int     intel_filesize;  /* magic header value used for transform   */
64
-  signed int     intel_curpos;    /* current offset in transform space       */
65
-
66
-  unsigned char  intel_started;   /* has intel E8 decoding started?          */
67
-  unsigned char  block_type;      /* type of the current block               */
68
-  unsigned char  header_read;     /* have we started decoding at all yet?    */
69
-  unsigned char  posn_slots;      /* how many posn slots in stream?          */
70
-  unsigned char  input_end;       /* have we reached the end of input?       */
71
-
72
-  int error;
73
-
74
-  /* I/O buffering */
75
-  unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
76
-  unsigned int  bit_buffer, bits_left, inbuf_size;
77
-
78
-  /* huffman code lengths */
79
-  unsigned char PRETREE_len  [LZX_PRETREE_MAXSYMBOLS  + LZX_LENTABLE_SAFETY];
80
-  unsigned char MAINTREE_len [LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
81
-  unsigned char LENGTH_len   [LZX_LENGTH_MAXSYMBOLS   + LZX_LENTABLE_SAFETY];
82
-  unsigned char ALIGNED_len  [LZX_ALIGNED_MAXSYMBOLS  + LZX_LENTABLE_SAFETY];
83
-
84
-  /* huffman decoding tables */
85
-  unsigned short PRETREE_table [(1 << LZX_PRETREE_TABLEBITS) +
86
-				(LZX_PRETREE_MAXSYMBOLS * 2)];
87
-  unsigned short MAINTREE_table[(1 << LZX_MAINTREE_TABLEBITS) +
88
-				(LZX_MAINTREE_MAXSYMBOLS * 2)];
89
-  unsigned short LENGTH_table  [(1 << LZX_LENGTH_TABLEBITS) +
90
-				(LZX_LENGTH_MAXSYMBOLS * 2)];
91
-  unsigned short ALIGNED_table [(1 << LZX_ALIGNED_TABLEBITS) +
92
-				(LZX_ALIGNED_MAXSYMBOLS * 2)];
93
-
94
-  /* this is used purely for doing the intel E8 transform */
95
-  unsigned char  e8_buf[LZX_FRAME_SIZE];
96
-};
97
-
98
-/* allocates LZX decompression state for decoding the given stream.
99
- *
100
- * - returns NULL if window_bits is outwith the range 15 to 21 (inclusive).
101
- *
102
- * - uses system->alloc() to allocate memory
103
- *
104
- * - returns NULL if not enough memory
105
- *
106
- * - window_bits is the size of the LZX window, from 32Kb (15) to 2Mb (21).
107
- *
108
- * - reset_interval is how often the bitstream is reset, measured in
109
- *   multiples of 32Kb bytes output. For CAB LZX streams, this is always 0
110
- *   (does not occur).
111
- *
112
- * - input_buffer_size is how many bytes to use as an input bitstream buffer
113
- *
114
- * - output_length is the length in bytes of the entirely decompressed
115
- *   output stream, if known in advance. It is used to correctly perform
116
- *   the Intel E8 transformation, which must stop 6 bytes before the very
117
- *   end of the decompressed stream. It is not otherwise used or adhered
118
- *   to. If the full decompressed length is known in advance, set it here.
119
- *   If it is NOT known, use the value 0, and call lzxd_set_output_length()
120
- *   once it is known. If never set, 4 of the final 6 bytes of the output
121
- *   stream may be incorrect.
122
- */
123
-extern struct lzxd_stream *lzxd_init(struct mspack_system *system,
124
-				     struct mspack_file *input,
125
-				     struct mspack_file *output,
126
-				     int window_bits,
127
-				     int reset_interval,
128
-				     int input_buffer_size,
129
-				     off_t output_length);
130
-
131
-/* see description of output_length in lzxd_init() */
132
-extern void lzxd_set_output_length(struct lzxd_stream *lzx,
133
-				   off_t output_length);
134
-
135
-/* decompresses, or decompresses more of, an LZX stream.
136
- *
137
- * - out_bytes of data will be decompressed and the function will return
138
- *   with an MSPACK_ERR_OK return code.
139
- *
140
- * - decompressing will stop as soon as out_bytes is reached. if the true
141
- *   amount of bytes decoded spills over that amount, they will be kept for
142
- *   a later invocation of lzxd_decompress().
143
- *
144
- * - the output bytes will be passed to the system->write() function given in
145
- *   lzxd_init(), using the output file handle given in lzxd_init(). More
146
- *   than one call may be made to system->write().
147
- *
148
- * - LZX will read input bytes as necessary using the system->read() function
149
- *   given in lzxd_init(), using the input file handle given in lzxd_init().
150
- *   This will continue until system->read() returns 0 bytes, or an error.
151
- *   input streams should convey an "end of input stream" by refusing to
152
- *   supply all the bytes that LZX asks for when they reach the end of the
153
- *   stream, rather than return an error code.
154
- *
155
- * - if an error code other than MSPACK_ERR_OK is returned, the stream should
156
- *   be considered unusable and lzxd_decompress() should not be called again
157
- *   on this stream.
158
- */
159
-extern int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes);
160
-
161
-/* frees all state associated with an LZX data stream
162
- *
163
- * - calls system->free() using the system pointer given in lzxd_init()
164
- */
165
-void lzxd_free(struct lzxd_stream *lzx);
166
-
167
-#endif
168 1
deleted file mode 100644
... ...
@@ -1,902 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
5
- * by Microsoft Corporation.
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * For further details, see the file COPYING.LIB distributed with libmspack
11
- */
12
-
13
-/* LZX decompression implementation */
14
-
15
-#if HAVE_CONFIG_H
16
-#include "clamav-config.h"
17
-#endif
18
-
19
-#include <mspack.h>
20
-#include <system.h>
21
-#include <lzx.h>
22
-
23
-/* Microsoft's LZX document and their implementation of the
24
- * com.ms.util.cab Java package do not concur.
25
- *
26
- * In the LZX document, there is a table showing the correlation between
27
- * window size and the number of position slots. It states that the 1MB
28
- * window = 40 slots and the 2MB window = 42 slots. In the implementation,
29
- * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the
30
- * first slot whose position base is equal to or more than the required
31
- * window size'. This would explain why other tables in the document refer
32
- * to 50 slots rather than 42.
33
- *
34
- * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
35
- * is not defined in the specification.
36
- *
37
- * The LZX document does not state the uncompressed block has an
38
- * uncompressed length field. Where does this length field come from, so
39
- * we can know how large the block is? The implementation has it as the 24
40
- * bits following after the 3 blocktype bits, before the alignment
41
- * padding.
42
- *
43
- * The LZX document states that aligned offset blocks have their aligned
44
- * offset huffman tree AFTER the main and length trees. The implementation
45
- * suggests that the aligned offset tree is BEFORE the main and length
46
- * trees.
47
- *
48
- * The LZX document decoding algorithm states that, in an aligned offset
49
- * block, if an extra_bits value is 1, 2 or 3, then that number of bits
50
- * should be read and the result added to the match offset. This is
51
- * correct for 1 and 2, but not 3, where just a huffman symbol (using the
52
- * aligned tree) should be read.
53
- *
54
- * Regarding the E8 preprocessing, the LZX document states 'No translation
55
- * may be performed on the last 6 bytes of the input block'. This is
56
- * correct.  However, the pseudocode provided checks for the *E8 leader*
57
- * up to the last 6 bytes. If the leader appears between -10 and -7 bytes
58
- * from the end, this would cause the next four bytes to be modified, at
59
- * least one of which would be in the last 6 bytes, which is not allowed
60
- * according to the spec.
61
- *
62
- * The specification states that the huffman trees must always contain at
63
- * least one element. However, many CAB files contain blocks where the
64
- * length tree is completely empty (because there are no matches), and
65
- * this is expected to succeed.
66
- */
67
-
68
-
69
-/* LZX decompressor input macros
70
- *
71
- * STORE_BITS        stores bitstream state in lzxd_stream structure
72
- * RESTORE_BITS      restores bitstream state from lzxd_stream structure
73
- * READ_BITS(var,n)  takes N bits from the buffer and puts them in var
74
- * ENSURE_BITS(n)    ensures there are at least N bits in the bit buffer.
75
- * PEEK_BITS(n)      extracts without removing N bits from the bit buffer
76
- * REMOVE_BITS(n)    removes N bits from the bit buffer
77
- *
78
- * These bit access routines work by using the area beyond the MSB and the
79
- * LSB as a free source of zeroes when shifting. This avoids having to
80
- * mask any bits. So we have to know the bit width of the bit buffer
81
- * variable.
82
- *
83
- * The bit buffer datatype should be at least 32 bits wide: it must be
84
- * possible to ENSURE_BITS(16), so it must be possible to add 16 new bits
85
- * to the bit buffer when the bit buffer already has 1 to 15 bits left.
86
- */
87
-
88
-#if HAVE_LIMITS_H
89
-# include <limits.h>
90
-#endif
91
-#ifndef CHAR_BIT
92
-# define CHAR_BIT (8)
93
-#endif
94
-#define BITBUF_WIDTH (sizeof(bit_buffer) * CHAR_BIT)
95
-
96
-#define STORE_BITS do {                                                 \
97
-  lzx->i_ptr      = i_ptr;                                              \
98
-  lzx->i_end      = i_end;                                              \
99
-  lzx->bit_buffer = bit_buffer;                                         \
100
-  lzx->bits_left  = bits_left;                                          \
101
-} while (0)
102
-
103
-#define RESTORE_BITS do {                                               \
104
-  i_ptr      = lzx->i_ptr;                                              \
105
-  i_end      = lzx->i_end;                                              \
106
-  bit_buffer = lzx->bit_buffer;                                         \
107
-  bits_left  = lzx->bits_left;                                          \
108
-} while (0)
109
-
110
-#define ENSURE_BITS(nbits)                                              \
111
-  while (bits_left < (nbits)) {                                         \
112
-    if (i_ptr >= i_end) {                                               \
113
-      if (lzxd_read_input(lzx)) return lzx->error;                      \
114
-      i_ptr = lzx->i_ptr;                                               \
115
-      i_end = lzx->i_end;                                               \
116
-    }                                                                   \
117
-    bit_buffer |= ((i_ptr[1] << 8) | i_ptr[0])                          \
118
-                  << (BITBUF_WIDTH - 16 - bits_left);                   \
119
-    bits_left  += 16;                                                   \
120
-    i_ptr      += 2;                                                    \
121
-  }
122
-
123
-#define PEEK_BITS(nbits) (bit_buffer >> (BITBUF_WIDTH - (nbits)))
124
-
125
-#define REMOVE_BITS(nbits) ((bit_buffer <<= (nbits)), (bits_left -= (nbits)))
126
-
127
-#define READ_BITS(val, nbits) do {                                      \
128
-  ENSURE_BITS(nbits);                                                   \
129
-  (val) = PEEK_BITS(nbits);                                             \
130
-  REMOVE_BITS(nbits);                                                   \
131
-} while (0)
132
-
133
-static int lzxd_read_input(struct lzxd_stream *lzx) {
134
-  int read = lzx->sys->read(lzx->input, &lzx->inbuf[0], (int)lzx->inbuf_size);
135
-  if (read < 0) return lzx->error = MSPACK_ERR_READ;
136
-
137
-  /* huff decode's ENSURE_BYTES(16) might overrun the input stream, even
138
-   * if those bits aren't used, so fake 2 more bytes */
139
-  if (read == 0) {
140
-    if (lzx->input_end) {
141
-      D(("out of input bytes"))
142
-      return lzx->error = MSPACK_ERR_READ;
143
-    }
144
-    else {
145
-      read = 2;
146
-      lzx->inbuf[0] = lzx->inbuf[1] = 0;
147
-      lzx->input_end = 1;
148
-    }
149
-  }
150
-
151
-  lzx->i_ptr = &lzx->inbuf[0];
152
-  lzx->i_end = &lzx->inbuf[read];
153
-
154
-  return MSPACK_ERR_OK;
155
-}
156
-
157
-/* Huffman decoding macros */
158
-
159
-/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
160
- * bitstream using the stated table and puts it in var.
161
- */
162
-#define READ_HUFFSYM(tbl, var) do {                                     \
163
-  /* huffman symbols can be up to 16 bits long */                       \
164
-  ENSURE_BITS(16);                                                      \
165
-  /* immediate table lookup of [tablebits] bits of the code */          \
166
-  sym = lzx->tbl##_table[PEEK_BITS(LZX_##tbl##_TABLEBITS)];             \
167
-  /* is the symbol is longer than [tablebits] bits? (i=node index) */   \
168
-  if (sym >= LZX_##tbl##_MAXSYMBOLS) {                                  \
169
-    /* decode remaining bits by tree traversal */                       \
170
-    i = 1 << (BITBUF_WIDTH - LZX_##tbl##_TABLEBITS);                    \
171
-    do {                                                                \
172
-      /* one less bit. error if we run out of bits before decode */     \
173
-      i >>= 1;                                                          \
174
-      if (i == 0) {                                                     \
175
-        D(("out of bits in huffman decode"))                            \
176
-        return lzx->error = MSPACK_ERR_DECRUNCH;                        \
177
-      }                                                                 \
178
-      /* double node index and add 0 (left branch) or 1 (right) */      \
179
-      sym <<= 1; sym |= (bit_buffer & i) ? 1 : 0;                       \
180
-      /* hop to next node index / decoded symbol */                     \
181
-      sym = lzx->tbl##_table[sym];                                      \
182
-      /* while we are still in node indicies, not decoded symbols */    \
183
-    } while (sym >= LZX_##tbl##_MAXSYMBOLS);                            \
184
-  }                                                                     \
185
-  /* result */                                                          \
186
-  (var) = sym;                                                          \
187
-  /* look up the code length of that symbol and discard those bits */   \
188
-  i = lzx->tbl##_len[sym];                                              \
189
-  REMOVE_BITS(i);                                                       \
190
-} while (0)
191
-
192
-/* BUILD_TABLE(tbl) builds a huffman lookup table from code lengths */
193
-#define BUILD_TABLE(tbl)                                                \
194
-  if (make_decode_table(LZX_##tbl##_MAXSYMBOLS, LZX_##tbl##_TABLEBITS,  \
195
-			&lzx->tbl##_len[0], &lzx->tbl##_table[0]))      \
196
-  {                                                                     \
197
-    D(("failed to build %s table", #tbl))                               \
198
-    return lzx->error = MSPACK_ERR_DECRUNCH;                            \
199
-  }
200
-
201
-/* make_decode_table(nsyms, nbits, length[], table[])
202
- *
203
- * This function was coded by David Tritscher. It builds a fast huffman
204
- * decoding table from a canonical huffman code lengths table.
205
- *
206
- * nsyms  = total number of symbols in this huffman tree.
207
- * nbits  = any symbols with a code length of nbits or less can be decoded
208
- *          in one lookup of the table.
209
- * length = A table to get code lengths from [0 to syms-1]
210
- * table  = The table to fill up with decoded symbols and pointers.
211
- *
212
- * Returns 0 for OK or 1 for error
213
- */
214
-
215
-static int make_decode_table(unsigned int nsyms, unsigned int nbits,
216
-			     unsigned char *length, unsigned short *table)
217
-{
218
-  register unsigned short sym;
219
-  register unsigned int leaf, fill;
220
-  register unsigned char bit_num;
221
-  unsigned int pos         = 0; /* the current position in the decode table */
222
-  unsigned int table_mask  = 1 << nbits;
223
-  unsigned int bit_mask    = table_mask >> 1; /* don't do 0 length codes */
224
-  unsigned int next_symbol = bit_mask; /* base of allocation for long codes */
225
-
226
-  /* fill entries for codes short enough for a direct mapping */
227
-  for (bit_num = 1; bit_num <= nbits; bit_num++) {
228
-    for (sym = 0; sym < nsyms; sym++) {
229
-      if (length[sym] != bit_num) continue;
230
-      leaf = pos;
231
-      if((pos += bit_mask) > table_mask) return 1; /* table overrun */
232
-      /* fill all possible lookups of this symbol with the symbol itself */
233
-      for (fill = bit_mask; fill-- > 0;) table[leaf++] = sym;
234
-    }
235
-    bit_mask >>= 1;
236
-  }
237
-
238
-  /* full table already? */
239
-  if (pos == table_mask) return 0;
240
-
241
-  /* clear the remainder of the table */
242
-  for (sym = pos; sym < table_mask; sym++) table[sym] = 0xFFFF;
243
-
244
-  /* allow codes to be up to nbits+16 long, instead of nbits */
245
-  pos <<= 16;
246
-  table_mask <<= 16;
247
-  bit_mask = 1 << 15;
248
-
249
-  for (bit_num = nbits+1; bit_num <= 16; bit_num++) {
250
-    for (sym = 0; sym < nsyms; sym++) {
251
-      if (length[sym] != bit_num) continue;
252
-
253
-      leaf = pos >> 16;
254
-      for (fill = 0; fill < bit_num - nbits; fill++) {
255
-	/* if this path hasn't been taken yet, 'allocate' two entries */
256
-	if (table[leaf] == 0xFFFF) {
257
-	  table[(next_symbol << 1)] = 0xFFFF;
258
-	  table[(next_symbol << 1) + 1] = 0xFFFF;
259
-	  table[leaf] = next_symbol++;
260
-	}
261
-	/* follow the path and select either left or right for next bit */
262
-	leaf = table[leaf] << 1;
263
-	if ((pos >> (15-fill)) & 1) leaf++;
264
-      }
265
-      table[leaf] = sym;
266
-
267
-      if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
268
-    }
269
-    bit_mask >>= 1;
270
-  }
271
-
272
-  /* full table? */
273
-  if (pos == table_mask) return 0;
274
-
275
-  /* either erroneous table, or all elements are 0 - let's find out. */
276
-  for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
277
-  return 0;
278
-}
279
-
280
-
281
-/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
282
- * first to last in the given table. The code lengths are stored in their
283
- * own special LZX way.
284
- */
285
-#define READ_LENGTHS(tbl, first, last) do {                            \
286
-  STORE_BITS;                                                          \
287
-  if (lzxd_read_lens(lzx, &lzx->tbl##_len[0], (first),                 \
288
-    (unsigned int)(last))) return lzx->error;                          \
289
-  RESTORE_BITS;                                                        \
290
-} while (0)
291
-
292
-static int lzxd_read_lens(struct lzxd_stream *lzx, unsigned char *lens,
293
-			  unsigned int first, unsigned int last)
294
-{
295
-  /* bit buffer and huffman symbol decode variables */
296
-  register unsigned int bit_buffer;
297
-  register int bits_left, i;
298
-  register unsigned short sym;
299
-  unsigned char *i_ptr, *i_end;
300
-
301
-  unsigned int x, y;
302
-  int z;
303
-
304
-  RESTORE_BITS;
305
-  
306
-  /* read lengths for pretree (20 symbols, lengths stored in fixed 4 bits) */
307
-  for (x = 0; x < 20; x++) {
308
-    READ_BITS(y, 4);
309
-    lzx->PRETREE_len[x] = y;
310
-  }
311
-  BUILD_TABLE(PRETREE);
312
-
313
-  for (x = first; x < last; ) {
314
-    READ_HUFFSYM(PRETREE, z);
315
-    if (z == 17) {
316
-      /* code = 17, run of ([read 4 bits]+4) zeros */
317
-      READ_BITS(y, 4); y += 4;
318
-      while (y--) lens[x++] = 0;
319
-    }
320
-    else if (z == 18) {
321
-      /* code = 18, run of ([read 5 bits]+20) zeros */
322
-      READ_BITS(y, 5); y += 20;
323
-      while (y--) lens[x++] = 0;
324
-    }
325
-    else if (z == 19) {
326
-      /* code = 19, run of ([read 1 bit]+4) [read huffman symbol] */
327
-      READ_BITS(y, 1); y += 4;
328
-      READ_HUFFSYM(PRETREE, z);
329
-      z = lens[x] - z; if (z < 0) z += 17;
330
-      while (y--) lens[x++] = z;
331
-    }
332
-    else {
333
-      /* code = 0 to 16, delta current length entry */
334
-      z = lens[x] - z; if (z < 0) z += 17;
335
-      lens[x++] = z;
336
-    }
337
-  }
338
-
339
-  STORE_BITS;
340
-
341
-  return MSPACK_ERR_OK;
342
-}
343
-
344
-/* LZX static data tables:
345
- *
346
- * LZX uses 'position slots' to represent match offsets.  For every match,
347
- * a small 'position slot' number and a small offset from that slot are
348
- * encoded instead of one large offset.
349
- *
350
- * position_base[] is an index to the position slot bases
351
- *
352
- * extra_bits[] states how many bits of offset-from-base data is needed.
353
- */
354
-static unsigned int  position_base[51];
355
-static unsigned char extra_bits[51];
356
-
357
-static void lzxd_static_init() {
358
-  int i, j;
359
-
360
-  for (i = 0, j = 0; i < 51; i += 2) {
361
-    extra_bits[i]   = j; /* 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7... */
362
-    if(i < 50)
363
-	extra_bits[i+1] = j;
364
-    if ((i != 0) && (j < 17)) j++; /* 0,0,1,2,3,4...15,16,17,17,17,17... */
365
-  }
366
-
367
-  for (i = 0, j = 0; i < 51; i++) {
368
-    position_base[i] = j; /* 0,1,2,3,4,6,8,12,16,24,32,... */
369
-    j += 1 << extra_bits[i]; /* 1,1,1,1,2,2,4,4,8,8,16,16,32,32,... */
370
-  }
371
-}
372
-
373
-static void lzxd_reset_state(struct lzxd_stream *lzx) {
374
-  int i;
375
-
376
-  lzx->R0              = 1;
377
-  lzx->R1              = 1;
378
-  lzx->R2              = 1;
379
-  lzx->header_read     = 0;
380
-  lzx->block_remaining = 0;
381
-  lzx->block_type      = LZX_BLOCKTYPE_INVALID;
382
-
383
-  /* initialise tables to 0 (because deltas will be applied to them) */
384
-  for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) lzx->MAINTREE_len[i] = 0;
385
-  for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)   lzx->LENGTH_len[i]   = 0;
386
-}
387
-
388
-/*-------- main LZX code --------*/
389
-
390
-struct lzxd_stream *lzxd_init(struct mspack_system *system,
391
-			      struct mspack_file *input,
392
-			      struct mspack_file *output,
393
-			      int window_bits,
394
-			      int reset_interval,
395
-			      int input_buffer_size,
396
-			      off_t output_length)
397
-{
398
-  unsigned int window_size = 1 << window_bits;
399
-  struct lzxd_stream *lzx;
400
-
401
-  if (!system) return NULL;
402
-
403
-  /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
404
-  if (window_bits < 15 || window_bits > 21) return NULL;
405
-
406
-  input_buffer_size = (input_buffer_size + 1) & -2;
407
-  if (!input_buffer_size) return NULL;
408
-
409
-  /* initialise static data */
410
-  lzxd_static_init();
411
-
412
-  /* allocate decompression state */
413
-  if (!(lzx = system->alloc(system, sizeof(struct lzxd_stream)))) {
414
-    return NULL;
415
-  }
416
-
417
-  /* allocate decompression window and input buffer */
418
-  lzx->window = system->alloc(system, (size_t) window_size);
419
-  lzx->inbuf  = system->alloc(system, (size_t) input_buffer_size);
420
-  if (!lzx->window || !lzx->inbuf) {
421
-    system->free(lzx->window);
422
-    system->free(lzx->inbuf);
423
-    system->free(lzx);
424
-    return NULL;
425
-  }
426
-
427
-  /* initialise decompression state */
428
-  lzx->sys             = system;
429
-  lzx->input           = input;
430
-  lzx->output          = output;
431
-  lzx->offset          = 0;
432
-  lzx->length          = output_length;
433
-
434
-  lzx->inbuf_size      = input_buffer_size;
435
-  lzx->window_size     = 1 << window_bits;
436
-  lzx->window_posn     = 0;
437
-  lzx->frame_posn      = 0;
438
-  lzx->frame           = 0;
439
-  lzx->reset_interval  = reset_interval;
440
-  lzx->intel_filesize  = 0;
441
-  lzx->intel_curpos    = 0;
442
-
443
-  /* window bits:    15  16  17  18  19  20  21
444
-   * position slots: 30  32  34  36  38  42  50  */
445
-  lzx->posn_slots      = ((window_bits == 21) ? 50 :
446
-			  ((window_bits == 20) ? 42 : (window_bits << 1)));
447
-  lzx->intel_started   = 0;
448
-  lzx->input_end       = 0;
449
-
450
-  lzx->error = MSPACK_ERR_OK;
451
-
452
-  lzx->i_ptr = lzx->i_end = &lzx->inbuf[0];
453
-  lzx->o_ptr = lzx->o_end = &lzx->e8_buf[0];
454
-  lzx->bit_buffer = lzx->bits_left = 0;
455
-
456
-  lzxd_reset_state(lzx);
457
-  return lzx;
458
-}
459
-
460
-void lzxd_set_output_length(struct lzxd_stream *lzx, off_t out_bytes) {
461
-  if (lzx) lzx->length = out_bytes;
462
-}
463
-
464
-int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
465
-  /* bitstream reading and huffman variables */
466
-  register unsigned int bit_buffer;
467
-  register int bits_left, i=0;
468
-  register unsigned short sym;
469
-  unsigned char *i_ptr, *i_end;
470
-
471
-  int match_length, length_footer, extra, verbatim_bits, bytes_todo;
472
-  int this_run, main_element, aligned_bits, j;
473
-  unsigned char *window, *runsrc, *rundest, buf[12];
474
-  unsigned int frame_size=0, end_frame, match_offset, window_posn;
475
-  unsigned int R0, R1, R2;
476
-
477
-  /* easy answers */
478
-  if (!lzx || (out_bytes < 0)) return MSPACK_ERR_ARGS;
479
-  if (lzx->error) return lzx->error;
480
-
481
-  /* flush out any stored-up bytes before we begin */
482
-  i = lzx->o_end - lzx->o_ptr;
483
-  if ((off_t) i > out_bytes) i = (int) out_bytes;
484
-  if (i) {
485
-    if (lzx->sys->write(lzx->output, lzx->o_ptr, i) != i) {
486
-      return lzx->error = MSPACK_ERR_WRITE;
487
-    }
488
-    lzx->o_ptr  += i;
489
-    lzx->offset += i;
490
-    out_bytes   -= i;
491
-  }
492
-  if (out_bytes == 0) return MSPACK_ERR_OK;
493
-
494
-  /* restore local state */
495
-  RESTORE_BITS;
496
-  window = lzx->window;
497
-  window_posn = lzx->window_posn;
498
-  R0 = lzx->R0;
499
-  R1 = lzx->R1;
500
-  R2 = lzx->R2;
501
-
502
-  end_frame = (unsigned int)((lzx->offset + out_bytes) / LZX_FRAME_SIZE) + 1;
503
-
504
-  while (lzx->frame < end_frame) {
505
-    /* have we reached the reset interval? (if there is one?) */
506
-    if (lzx->reset_interval && ((lzx->frame % lzx->reset_interval) == 0)) {
507
-      if (lzx->block_remaining) {
508
-	D(("%d bytes remaining at reset interval", lzx->block_remaining))
509
-	return lzx->error = MSPACK_ERR_DECRUNCH;
510
-      }
511
-
512
-      /* re-read the intel header and reset the huffman lengths */
513
-      lzxd_reset_state(lzx);
514
-    }
515
-
516
-    /* read header if necessary */
517
-    if (!lzx->header_read) {
518
-      /* read 1 bit. if bit=0, intel filesize = 0.
519
-       * if bit=1, read intel filesize (32 bits) */
520
-      j = 0; READ_BITS(i, 1); if (i) { READ_BITS(i, 16); READ_BITS(j, 16); }
521
-      lzx->intel_filesize = (i << 16) | j;
522
-      lzx->header_read = 1;
523
-    } 
524
-
525
-    /* calculate size of frame: all frames are 32k except the final frame
526
-     * which is 32kb or less. this can only be calculated when lzx->length
527
-     * has been filled in. */
528
-    frame_size = LZX_FRAME_SIZE;
529
-    if (lzx->length && (lzx->length - lzx->offset) < (off_t)frame_size) {
530
-      frame_size = lzx->length - lzx->offset;
531
-    }
532
-
533
-    /* decode until one more frame is available */
534
-    bytes_todo = lzx->frame_posn + frame_size - window_posn;
535
-    while (bytes_todo > 0) {
536
-      /* initialise new block, if one is needed */
537
-      if (lzx->block_remaining == 0) {
538
-	/* realign if previous block was an odd-sized UNCOMPRESSED block */
539
-	if ((lzx->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) &&
540
-	    (lzx->block_length & 1))
541
-	{
542
-	  if (i_ptr == i_end) {
543
-	    if (lzxd_read_input(lzx)) return lzx->error;
544
-	    i_ptr = lzx->i_ptr;
545
-	    i_end = lzx->i_end;
546
-	  }
547
-	  i_ptr++;
548
-	}
549
-
550
-	/* read block type (3 bits) and block length (24 bits) */
551
-	READ_BITS(lzx->block_type, 3);
552
-	READ_BITS(i, 16); READ_BITS(j, 8);
553
-	lzx->block_remaining = lzx->block_length = (i << 8) | j;
554
-	/*D(("new block t%d len %u", lzx->block_type, lzx->block_length))*/
555
-
556
-	/* read individual block headers */
557
-	switch (lzx->block_type) {
558
-	case LZX_BLOCKTYPE_ALIGNED:
559
-	  /* read lengths of and build aligned huffman decoding tree */
560
-	  for (i = 0; i < 8; i++) { READ_BITS(j, 3); lzx->ALIGNED_len[i] = j; }
561
-	  BUILD_TABLE(ALIGNED);
562
-	  /* no break -- rest of aligned header is same as verbatim */
563
-	case LZX_BLOCKTYPE_VERBATIM:
564
-	  /* read lengths of and build main huffman decoding tree */
565
-	  READ_LENGTHS(MAINTREE, 0, 256);
566
-	  READ_LENGTHS(MAINTREE, 256, LZX_NUM_CHARS + (lzx->posn_slots << 3));
567
-	  BUILD_TABLE(MAINTREE);
568
-	  /* if the literal 0xE8 is anywhere in the block... */
569
-	  if (lzx->MAINTREE_len[0xE8] != 0) lzx->intel_started = 1;
570
-	  /* read lengths of and build lengths huffman decoding tree */
571
-	  READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
572
-	  BUILD_TABLE(LENGTH);
573
-	  break;
574
-
575
-	case LZX_BLOCKTYPE_UNCOMPRESSED:
576
-	  /* because we can't assume otherwise */
577
-	  lzx->intel_started = 1;
578
-
579
-	  /* read 1-16 (not 0-15) bits to align to bytes */
580
-	  ENSURE_BITS(16);
581
-	  if (bits_left > 16) i_ptr -= 2;
582
-	  bits_left = 0; bit_buffer = 0;
583
-
584
-	  /* read 12 bytes of stored R0 / R1 / R2 values */
585
-	  for (rundest = &buf[0], i = 0; i < 12; i++) {
586
-	    if (i_ptr == i_end) {
587
-	      if (lzxd_read_input(lzx)) return lzx->error;
588
-	      i_ptr = lzx->i_ptr;
589
-	      i_end = lzx->i_end;
590
-	    }
591
-	    *rundest++ = *i_ptr++;
592
-	  }
593
-	  R0 = buf[0] | (buf[1] << 8) | (buf[2]  << 16) | (buf[3]  << 24);
594
-	  R1 = buf[4] | (buf[5] << 8) | (buf[6]  << 16) | (buf[7]  << 24);
595
-	  R2 = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24);
596
-	  break;
597
-
598
-	default:
599
-	  D(("bad block type"))
600
-	  return lzx->error = MSPACK_ERR_DECRUNCH;
601
-	}
602
-      }
603
-
604
-      /* decode more of the block:
605
-       * run = min(what's available, what's needed) */
606
-      this_run = lzx->block_remaining;
607
-      if (this_run > bytes_todo) this_run = bytes_todo;
608
-
609
-      /* assume we decode exactly this_run bytes, for now */
610
-      bytes_todo           -= this_run;
611
-      lzx->block_remaining -= this_run;
612
-
613
-      /* decode at least this_run bytes */
614
-      switch (lzx->block_type) {
615
-      case LZX_BLOCKTYPE_VERBATIM:
616
-	while (this_run > 0) {
617
-	  READ_HUFFSYM(MAINTREE, main_element);
618
-	  if (main_element < LZX_NUM_CHARS) {
619
-	    /* literal: 0 to LZX_NUM_CHARS-1 */
620
-	    window[window_posn++] = main_element;
621
-	    this_run--;
622
-	  }
623
-	  else {
624
-	    /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
625
-	    main_element -= LZX_NUM_CHARS;
626
-
627
-	    /* get match length */
628
-	    match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
629
-	    if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
630
-	      READ_HUFFSYM(LENGTH, length_footer);
631
-	      match_length += length_footer;
632
-	    }
633
-	    match_length += LZX_MIN_MATCH;
634
-	  
635
-	    /* get match offset */
636
-	    switch ((match_offset = (main_element >> 3))) {
637
-	    case 0: match_offset = R0;                                  break;
638
-	    case 1: match_offset = R1; R1=R0;        R0 = match_offset; break;
639
-	    case 2: match_offset = R2; R2=R0;        R0 = match_offset; break;
640
-	    case 3: match_offset = 1;  R2=R1; R1=R0; R0 = match_offset; break;
641
-	    default:
642
-	      extra = extra_bits[match_offset];
643
-	      READ_BITS(verbatim_bits, extra);
644
-	      match_offset = position_base[match_offset] - 2 + verbatim_bits;
645
-	      R2 = R1; R1 = R0; R0 = match_offset;
646
-	    }
647
-
648
-	    if ((window_posn + match_length) > lzx->window_size) {
649
-	      D(("match ran over window wrap"))
650
-	      return lzx->error = MSPACK_ERR_DECRUNCH;
651
-	    }
652
-	    
653
-	    /* copy match */
654
-	    rundest = &window[window_posn];
655
-	    i = match_length;
656
-	    /* does match offset wrap the window? */
657
-	    if (match_offset > window_posn) {
658
-	      /* j = length from match offset to end of window */
659
-	      j = match_offset - window_posn;
660
-	      if (j > (int) lzx->window_size) {
661
-		D(("match offset beyond window boundaries"))
662
-		return lzx->error = MSPACK_ERR_DECRUNCH;
663
-	      }
664
-	      runsrc = &window[lzx->window_size - j];
665
-	      if (j < i) {
666
-		/* if match goes over the window edge, do two copy runs */
667
-		i -= j; while (j-- > 0) *rundest++ = *runsrc++;
668
-		runsrc = window;
669
-	      }
670
-	      while (i-- > 0) *rundest++ = *runsrc++;
671
-	    }
672
-	    else {
673
-	      runsrc = rundest - match_offset;
674
-	      while (i-- > 0) *rundest++ = *runsrc++;
675
-	    }
676
-
677
-	    this_run    -= match_length;
678
-	    window_posn += match_length;
679
-	  }
680
-	} /* while (this_run > 0) */
681
-	break;
682
-
683
-      case LZX_BLOCKTYPE_ALIGNED:
684
-	while (this_run > 0) {
685
-	  READ_HUFFSYM(MAINTREE, main_element);
686
-	  if (main_element < LZX_NUM_CHARS) {
687
-	    /* literal: 0 to LZX_NUM_CHARS-1 */
688
-	    window[window_posn++] = main_element;
689
-	    this_run--;
690
-	  }
691
-	  else {
692
-	    /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
693
-	    main_element -= LZX_NUM_CHARS;
694
-
695
-	    /* get match length */
696
-	    match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
697
-	    if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
698
-	      READ_HUFFSYM(LENGTH, length_footer);
699
-	      match_length += length_footer;
700
-	    }
701
-	    match_length += LZX_MIN_MATCH;
702
-
703
-	    /* get match offset */
704
-	    switch ((match_offset = (main_element >> 3))) {
705
-	    case 0: match_offset = R0;                             break;
706
-	    case 1: match_offset = R1; R1 = R0; R0 = match_offset; break;
707
-	    case 2: match_offset = R2; R2 = R0; R0 = match_offset; break;
708
-	    default:
709
-	      extra = extra_bits[match_offset];
710
-	      match_offset = position_base[match_offset] - 2;
711
-	      if (extra > 3) {
712
-		/* verbatim and aligned bits */
713
-		extra -= 3;
714
-		READ_BITS(verbatim_bits, extra);
715
-		match_offset += (verbatim_bits << 3);
716
-		READ_HUFFSYM(ALIGNED, aligned_bits);
717
-		match_offset += aligned_bits;
718
-	      }
719
-	      else if (extra == 3) {
720
-		/* aligned bits only */
721
-		READ_HUFFSYM(ALIGNED, aligned_bits);
722
-		match_offset += aligned_bits;
723
-	      }
724
-	      else if (extra > 0) { /* extra==1, extra==2 */
725
-		/* verbatim bits only */
726
-		READ_BITS(verbatim_bits, extra);
727
-		match_offset += verbatim_bits;
728
-	      }
729
-	      else /* extra == 0 */ {
730
-		/* ??? not defined in LZX specification! */
731
-		match_offset = 1;
732
-	      }
733
-	      /* update repeated offset LRU queue */
734
-	      R2 = R1; R1 = R0; R0 = match_offset;
735
-	    }
736
-
737
-	    if ((window_posn + match_length) > lzx->window_size) {
738
-	      D(("match ran over window wrap"))
739
-	      return lzx->error = MSPACK_ERR_DECRUNCH;
740
-	    }
741
-
742
-	    /* copy match */
743
-	    rundest = &window[window_posn];
744
-	    i = match_length;
745
-	    /* does match offset wrap the window? */
746
-	    if (match_offset > window_posn) {
747
-	      /* j = length from match offset to end of window */
748
-	      j = match_offset - window_posn;
749
-	      if (j > (int) lzx->window_size) {
750
-		D(("match offset beyond window boundaries"))
751
-		return lzx->error = MSPACK_ERR_DECRUNCH;
752
-	      }
753
-	      runsrc = &window[lzx->window_size - j];
754
-	      if (j < i) {
755
-		/* if match goes over the window edge, do two copy runs */
756
-		i -= j; while (j-- > 0) *rundest++ = *runsrc++;
757
-		runsrc = window;
758
-	      }
759
-	      while (i-- > 0) *rundest++ = *runsrc++;
760
-	    }
761
-	    else {
762
-	      runsrc = rundest - match_offset;
763
-	      while (i-- > 0) *rundest++ = *runsrc++;
764
-	    }
765
-
766
-	    this_run    -= match_length;
767
-	    window_posn += match_length;
768
-	  }
769
-	} /* while (this_run > 0) */
770
-	break;
771
-
772
-      case LZX_BLOCKTYPE_UNCOMPRESSED:
773
-	/* as this_run is limited not to wrap a frame, this also means it
774
-	 * won't wrap the window (as the window is a multiple of 32k) */
775
-	rundest = &window[window_posn];
776
-	window_posn += this_run;
777
-	while (this_run > 0) {
778
-	  if ((i = i_end - i_ptr)) {
779
-	    if (i > this_run) i = this_run;
780
-	    lzx->sys->copy(i_ptr, rundest, (size_t) i);
781
-	    rundest  += i;
782
-	    i_ptr    += i;
783
-	    this_run -= i;
784
-	  }
785
-	  else {
786
-	    if (lzxd_read_input(lzx)) return lzx->error;
787
-	    i_ptr = lzx->i_ptr;
788
-	    i_end = lzx->i_end;
789
-	  }
790
-	}
791
-	break;
792
-
793
-      default:
794
-	return lzx->error = MSPACK_ERR_DECRUNCH; /* might as well */
795
-      }
796
-
797
-      /* did the final match overrun our desired this_run length? */
798
-      if (this_run < 0) {
799
-	if ((unsigned int)(-this_run) > lzx->block_remaining) {
800
-	  D(("overrun went past end of block by %d (%d remaining)",
801
-	     -this_run, lzx->block_remaining ))
802
-	  return lzx->error = MSPACK_ERR_DECRUNCH;
803
-	}
804
-	lzx->block_remaining -= -this_run;
805
-      }
806
-    } /* while (bytes_todo > 0) */
807
-
808
-    /* streams don't extend over frame boundaries */
809
-    if ((window_posn - lzx->frame_posn) != frame_size) {
810
-      D(("decode beyond output frame limits! %d != %d",
811
-	 window_posn - lzx->frame_posn, frame_size))
812
-      return lzx->error = MSPACK_ERR_DECRUNCH;
813
-    }
814
-
815
-    /* re-align input bitstream */
816
-    if (bits_left > 0) ENSURE_BITS(16);
817
-    if (bits_left & 15) REMOVE_BITS(bits_left & 15);
818
-
819
-    /* check that we've used all of the previous frame first */
820
-    if (lzx->o_ptr != lzx->o_end) {
821
-      D(("%d avail bytes, new %d frame", lzx->o_end-lzx->o_ptr, frame_size))
822
-      return lzx->error = MSPACK_ERR_DECRUNCH;
823
-    }
824
-
825
-    /* does this intel block _really_ need decoding? */
826
-    if (lzx->intel_started && lzx->intel_filesize &&
827
-	(lzx->frame <= 32768) && (frame_size > 10))
828
-    {
829
-      unsigned char *data    = &lzx->e8_buf[0];
830
-      unsigned char *dataend = &lzx->e8_buf[frame_size - 10];
831
-      signed int curpos      = lzx->intel_curpos;
832
-      signed int filesize    = lzx->intel_filesize;
833
-      signed int abs_off, rel_off;
834
-
835
-      /* copy e8 block to the e8 buffer and tweak if needed */
836
-      lzx->o_ptr = data;
837
-      lzx->sys->copy(&lzx->window[lzx->frame_posn], data, frame_size);
838
-
839
-      while (data < dataend) {
840
-	if (*data++ != 0xE8) { curpos++; continue; }
841
-	abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
842
-	if ((abs_off >= -curpos) && (abs_off < filesize)) {
843
-	  rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
844
-	  data[0] = (unsigned char) rel_off;
845
-	  data[1] = (unsigned char) (rel_off >> 8);
846
-	  data[2] = (unsigned char) (rel_off >> 16);
847
-	  data[3] = (unsigned char) (rel_off >> 24);
848
-	}
849
-	data += 4;
850
-	curpos += 5;
851
-      }
852
-      lzx->intel_curpos += frame_size;
853
-    }
854
-    else {
855
-      lzx->o_ptr = &lzx->window[lzx->frame_posn];
856
-      if (lzx->intel_filesize) lzx->intel_curpos += frame_size;
857
-    }
858
-    lzx->o_end = &lzx->o_ptr[frame_size];
859
-
860
-    /* write a frame */
861
-    i = (out_bytes < (off_t)frame_size) ? (unsigned int)out_bytes : frame_size;
862
-    if (lzx->sys->write(lzx->output, lzx->o_ptr, i) != i) {
863
-      return lzx->error = MSPACK_ERR_WRITE;
864
-    }
865
-    lzx->o_ptr  += i;
866
-    lzx->offset += i;
867
-    out_bytes   -= i;
868
-
869
-    /* advance frame start position */
870
-    lzx->frame_posn += frame_size;
871
-    lzx->frame++;
872
-
873
-    /* wrap window / frame position pointers */
874
-    if (window_posn == lzx->window_size)     window_posn = 0;
875
-    if (lzx->frame_posn == lzx->window_size) lzx->frame_posn = 0;
876
-
877
-  } /* while (lzx->frame < end_frame) */
878
-
879
-  if (out_bytes) {
880
-    D(("bytes left to output"))
881
-    return lzx->error = MSPACK_ERR_DECRUNCH;
882
-  }
883
-
884
-  /* store local state */
885
-  STORE_BITS;
886
-  lzx->window_posn = window_posn;
887
-  lzx->R0 = R0;
888
-  lzx->R1 = R1;
889
-  lzx->R2 = R2;
890
-
891
-  return MSPACK_ERR_OK;
892
-}
893
-
894
-void lzxd_free(struct lzxd_stream *lzx) {
895
-  struct mspack_system *sys;
896
-  if (lzx) {
897
-    sys = lzx->sys;
898
-    sys->free(lzx->inbuf);
899
-    sys->free(lzx->window);
900
-    sys->free(lzx);
901
-  }
902
-}
903 1
deleted file mode 100644
... ...
@@ -1,1494 +0,0 @@
1
-/* WARNING: This version also supports dopen for descriptor opening and
2
- *	    is not compatible with the original version. -- T. Kojm
3
- *
4
- * libmspack -- a library for working with Microsoft compression formats.
5
- * (C) 2003-2004 Stuart Caie <kyzer@4u.net>
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
- * GNU Lesser General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU Lesser General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
- */
19
-
20
-/** \mainpage
21
- *
22
- * \section intro Introduction
23
- *
24
- * libmspack is a library which provides compressors and decompressors,
25
- * archivers and dearchivers for Microsoft compression formats.
26
- *
27
- * \section formats Formats supported
28
- *
29
- * The following file formats are supported:
30
- * - SZDD files, which use LZSS compression
31
- * - KWAJ files, which use LZSS, LZSS+Huffman or deflate compression
32
- * - .HLP (MS Help) files, which use LZSS compression
33
- * - .CAB (MS Cabinet) files, which use deflate, LZX or Quantum compression
34
- * - .CHM (HTML Help) files, which use LZX compression
35
- * - .LIT (MS EBook) files, which use LZX compression and DES encryption
36
- *
37
- * To determine the capabilities of the library, and the binary
38
- * compatibility version of any particular compressor or decompressor, use
39
- * the mspack_version() function. The UNIX library interface version is
40
- * defined as the highest-versioned library component.
41
- *
42
- * \section starting Getting started
43
- *
44
- * The macro MSPACK_SYS_SELFTEST() should be used to ensure the library can
45
- * be used. In particular, it checks if the caller is using 32-bit file I/O
46
- * when the library is compiled for 64-bit file I/O and vice versa.
47
- *
48
- * If compiled normally, the library includes basic file I/O and memory
49
- * management functionality using the standard C library. This can be
50
- * customised and replaced entirely by creating a mspack_system structure.
51
- *
52
- * A compressor or decompressor for the required format must be
53
- * instantiated before it can be used. Each construction function takes
54
- * one parameter, which is either a pointer to a custom mspack_system
55
- * structure, or NULL to use the default. The instantiation returned, if
56
- * not NULL, contains function pointers (methods) to work with the given
57
- * file format.
58
- * 
59
- * For compression:
60
- * - mspack_create_cab_compressor() creates a mscab_compressor
61
- * - mspack_create_chm_compressor() creates a mschm_compressor
62
- * - mspack_create_lit_compressor() creates a mslit_compressor
63
- * - mspack_create_hlp_compressor() creates a mshlp_compressor
64
- * - mspack_create_szdd_compressor() creates a msszdd_compressor
65
- * - mspack_create_kwaj_compressor() creates a mskwaj_compressor
66
- *
67
- * For decompression:
68
- * - mspack_create_cab_decompressor() creates a mscab_decompressor
69
- * - mspack_create_chm_decompressor() creates a mschm_decompressor
70
- * - mspack_create_lit_decompressor() creates a mslit_decompressor
71
- * - mspack_create_hlp_decompressor() creates a mshlp_decompressor
72
- * - mspack_create_szdd_decompressor() creates a msszdd_decompressor
73
- * - mspack_create_kwaj_decompressor() creates a mskwaj_decompressor
74
- *
75
- * Once finished working with a format, each kind of
76
- * compressor/decompressor has its own specific destructor:
77
- * - mspack_destroy_cab_compressor()
78
- * - mspack_destroy_cab_decompressor()
79
- * - mspack_destroy_chm_compressor()
80
- * - mspack_destroy_chm_decompressor()
81
- * - mspack_destroy_lit_compressor()
82
- * - mspack_destroy_lit_decompressor()
83
- * - mspack_destroy_hlp_compressor()
84
- * - mspack_destroy_hlp_decompressor()
85
- * - mspack_destroy_szdd_compressor()
86
- * - mspack_destroy_szdd_decompressor()
87
- * - mspack_destroy_kwaj_compressor()
88
- * - mspack_destroy_kwaj_decompressor()
89
- *
90
- * Destroying a compressor or decompressor does not destroy any objects,
91
- * structures or handles that have been created using that compressor or
92
- * decompressor. Ensure that everything created or opened is destroyed or
93
- * closed before compressor/decompressor is itself destroyed.
94
- *
95
- * \section errors Error codes
96
- *
97
- * All compressors and decompressors use the same set of error codes. Most
98
- * methods return an error code directly. For methods which do not
99
- * return error codes directly, the error code can be obtained with the
100
- * last_error() method.
101
- *
102
- * - #MSPACK_ERR_OK is used to indicate success. This error code is defined
103
- *   as zero, all other code are non-zero.
104
- * - #MSPACK_ERR_ARGS indicates that a method was called with inappropriate
105
- *   arguments.
106
- * - #MSPACK_ERR_OPEN indicates that mspack_system::open() failed.
107
- * - #MSPACK_ERR_READ indicates that mspack_system::read() failed.
108
- * - #MSPACK_ERR_WRITE indicates that mspack_system::write() failed.
109
- * - #MSPACK_ERR_SEEK indicates that mspack_system::seek() failed.
110
- * - #MSPACK_ERR_NOMEMORY indicates that mspack_system::alloc() failed.
111
- * - #MSPACK_ERR_SIGNATURE indicates that the file being read does not
112
- *   have the correct "signature". It is probably not a valid file for
113
- *   whatever format is being read.
114
- * - #MSPACK_ERR_DATAFORMAT indicates that the file being used or read
115
- *   is corrupt.
116
- * - #MSPACK_ERR_CHECKSUM indicates that a data checksum has failed.
117
- * - #MSPACK_ERR_CRUNCH indicates an error occured during compression.
118
- * - #MSPACK_ERR_DECRUNCH indicates an error occured during decompression.
119
- */
120
-
121
-#ifndef LIB_MSPACK_H
122
-#define LIB_MSPACK_H 1
123
-
124
-#ifdef __cplusplus
125
-extern "C" {
126
-#endif
127
-
128
-#include <sys/types.h>
129
-#include <unistd.h>
130
-
131
-/**
132
- * System self-test function, to ensure both library and calling program
133
- * can use one another.
134
- *
135
- * A result of MSPACK_ERR_OK means the library and caller are
136
- * compatible. Any other result indicates that the library and caller are
137
- * not compatible and should not be used. In particular, a value of
138
- * MSPACK_ERR_SEEK means the library and caller use different off_t
139
- * datatypes.
140
- *
141
- * It should be used like so:
142
- *
143
- * @code
144
- * int selftest_result;
145
- * MSPACK_SYS_SELFTEST(selftest_result);
146
- * if (selftest_result != MSPACK_ERR_OK) {
147
- *   fprintf(stderr, "incompatible with this build of libmspack\n");
148
- *   exit(0);
149
- * }
150
- * @endcode
151
- *
152
- * @param  result   an int variable to store the result of the self-test
153
- */
154
-#define MSPACK_SYS_SELFTEST(result)  do { \
155
-  (result) = mspack_sys_selftest_internal(sizeof(off_t)); \
156
-} while (0)
157
-
158
-/** Part of the MSPACK_SYS_SELFTEST() macro, must not be used directly. */
159
-extern int mspack_sys_selftest_internal(int);
160
-
161
-/**
162
- * Enquire about the binary compatibility version of a specific interface in
163
- * the library. Currently, the following interfaces are defined:
164
- *
165
- * - #MSPACK_VER_LIBRARY: the overall library
166
- * - #MSPACK_VER_SYSTEM: the mspack_system interface
167
- * - #MSPACK_VER_MSCABD: the mscab_decompressor interface
168
- * - #MSPACK_VER_MSCABC: the mscab_compressor interface
169
- * - #MSPACK_VER_MSCHMD: the mschm_decompressor interface
170
- * - #MSPACK_VER_MSCHMC: the mschm_compressor interface
171
- * - #MSPACK_VER_MSLITD: the mslit_decompressor interface
172
- * - #MSPACK_VER_MSLITC: the mslit_compressor interface
173
- * - #MSPACK_VER_MSHLPD: the mshlp_decompressor interface
174
- * - #MSPACK_VER_MSHLPC: the mshlp_compressor interface
175
- * - #MSPACK_VER_MSSZDDD: the msszdd_decompressor interface
176
- * - #MSPACK_VER_MSSZDDC: the msszdd_compressor interface
177
- * - #MSPACK_VER_MSKWAJD: the mskwaj_decompressor interface
178
- * - #MSPACK_VER_MSKWAJC: the mskwaj_compressor interface
179
- *
180
- * The result of the function should be interpreted as follows:
181
- * - -1: this interface is completely unknown to the library
182
- * - 0: this interface is known, but non-functioning
183
- * - 1: this interface has all basic functionality
184
- * - 2, 3, ...: this interface has additional functionality, clearly marked
185
- *   in the documentation as "version 2", "version 3" and so on.
186
- *
187
- * @param interface the interface to request current version of
188
- * @return the version of the requested interface
189
- */
190
-extern int mspack_version(int interface);
191
-
192
-/** Pass to mspack_version() to get the overall library version */
193
-#define MSPACK_VER_LIBRARY   (0)
194
-/** Pass to mspack_version() to get the mspack_system version */
195
-#define MSPACK_VER_SYSTEM    (1)
196
-/** Pass to mspack_version() to get the mscab_decompressor version */
197
-#define MSPACK_VER_MSCABD    (2)
198
-/** Pass to mspack_version() to get the mscab_compressor version */
199
-#define MSPACK_VER_MSCABC    (3)
200
-/** Pass to mspack_version() to get the mschm_decompressor version */
201
-#define MSPACK_VER_MSCHMD    (4)
202
-/** Pass to mspack_version() to get the mschm_compressor version */
203
-#define MSPACK_VER_MSCHMC    (5)
204
-/** Pass to mspack_version() to get the mslit_decompressor version */
205
-#define MSPACK_VER_MSLITD    (6)
206
-/** Pass to mspack_version() to get the mslit_compressor version */
207
-#define MSPACK_VER_MSLITC    (7)
208
-/** Pass to mspack_version() to get the mshlp_decompressor version */
209
-#define MSPACK_VER_MSHLPD    (8)
210
-/** Pass to mspack_version() to get the mshlp_compressor version */
211
-#define MSPACK_VER_MSHLPC    (9)
212
-/** Pass to mspack_version() to get the msszdd_decompressor version */
213
-#define MSPACK_VER_MSSZDDD   (10)
214
-/** Pass to mspack_version() to get the msszdd_compressor version */
215
-#define MSPACK_VER_MSSZDDC   (11)
216
-/** Pass to mspack_version() to get the mskwaj_decompressor version */
217
-#define MSPACK_VER_MSKWAJD   (12)
218
-/** Pass to mspack_version() to get the mskwaj_compressor version */
219
-#define MSPACK_VER_MSKWAJC   (13)
220
-
221
-/* --- file I/O abstraction ------------------------------------------------ */
222
-
223
-/**
224
- * A structure which abstracts file I/O and memory management.
225
- *
226
- * The library always uses the mspack_system structure for interaction
227
- * with the file system and to allocate, free and copy all memory. It also
228
- * uses it to send literal messages to the library user.
229
- *
230
- * When the library is compiled normally, passing NULL to a compressor or
231
- * decompressor constructor will result in a default mspack_system being
232
- * used, where all methods are implemented with the standard C library.
233
- * However, all constructors support being given a custom created
234
- * mspack_system structure, with the library user's own methods. This
235
- * allows for more abstract interaction, such as reading and writing files
236
- * directly to memory, or from a network socket or pipe.
237
- *
238
- * Implementors of an mspack_system structure should read all
239
- * documentation entries for every structure member, and write methods
240
- * which conform to those standards.
241
- */
242
-struct mspack_system {
243
-  /**
244
-   * Opens a file for reading, writing, appending or updating.
245
-   *
246
-   * @param this     a self-referential pointer to the mspack_system
247
-   *                 structure whose open() method is being called. If
248
-   *                 this pointer is required by close(), read(), write(),
249
-   *                 seek() or tell(), it should be stored in the result
250
-   *                 structure at this time.
251
-   * @param filename the file to be opened. It is passed directly from the
252
-   *                 library caller without being modified, so it is up to
253
-   *                 the caller what this parameter actually represents.
254
-   * @param mode     one of #MSPACK_SYS_OPEN_READ (open an existing file
255
-   *                 for reading), #MSPACK_SYS_OPEN_WRITE (open a new file
256
-   *                 for writing), #MSPACK_SYS_OPEN_UPDATE (open an existing
257
-   *                 file for reading/writing from the start of the file) or
258
-   *                 #MSPACK_SYS_OPEN_APPEND (open an existing file for
259
-   *                 reading/writing from the end of the file)
260
-   * @return a pointer to a mspack_file structure. This structure officially
261
-   *         contains no members, its true contents are up to the
262
-   *         mspack_system implementor. It should contain whatever is needed
263
-   *         for other mspack_system methods to operate.
264
-   * @see close(), read(), write(), seek(), tell(), message()
265
-   */
266
-  struct mspack_file * (*open)(struct mspack_system *this,
267
-			       char *filename,
268
-			       int mode);
269
-
270
-  struct mspack_file * (*dopen)(struct mspack_system *this,
271
-			       int desc,
272
-			       int mode);
273
-
274
-  /**
275
-   * Closes a previously opened file. If any memory was allocated for this
276
-   * particular file handle, it should be freed at this time.
277
-   * 
278
-   * @param file the file to close
279
-   * @see open()
280
-   */
281
-  void (*close)(struct mspack_file *file);
282
-
283
-  /**
284
-   * Reads a given number of bytes from an open file.
285
-   *
286
-   * @param file    the file to read from
287
-   * @param buffer  the location where the read bytes should be stored
288
-   * @param bytes   the number of bytes to read from the file.
289
-   * @return the number of bytes successfully read (this can be less than
290
-   *         the number requested), zero to mark the end of file, or less
291
-   *         than zero to indicate an error.
292
-   * @see open(), write()
293
-   */
294
-  int (*read)(struct mspack_file *file,
295
-	      void *buffer,
296
-	      int bytes);
297
-
298
-  /**
299
-   * Writes a given number of bytes to an open file.
300
-   *
301
-   * @param file    the file to write to
302
-   * @param buffer  the location where the written bytes should be read from
303
-   * @param bytes   the number of bytes to write to the file.
304
-   * @return the number of bytes successfully written, this can be less
305
-   *         than the number requested. Zero or less can indicate an error
306
-   *         where no bytes at all could be written. All cases where less
307
-   *         bytes were written than requested are considered by the library
308
-   *         to be an error.
309
-   * @see open(), read()
310
-   */
311
-  int (*write)(struct mspack_file *file,
312
-	       void *buffer,
313
-	       int bytes);
314
-
315
-  /**
316
-   * Seeks to a specific file offset within an open file.
317
-   *
318
-   * Sometimes the library needs to know the length of a file. It does
319
-   * this by seeking to the end of the file with seek(file, 0,
320
-   * MSPACK_SYS_SEEK_END), then calling tell(). Implementations may want
321
-   * to make a special case for this.
322
-   *
323
-   * Due to the potentially varying 32/64 bit datatype off_t on some
324
-   * architectures, the #MSPACK_SYS_SELFTEST macro MUST be used before
325
-   * using the library. If not, the error caused by the library passing an
326
-   * inappropriate stackframe to seek() is subtle and hard to trace.
327
-   *
328
-   * @param file   the file to be seeked
329
-   * @param offset an offset to seek, measured in bytes
330
-   * @param mode   one of #MSPACK_SYS_SEEK_START (the offset should be
331
-   *               measured from the start of the file), #MSPACK_SYS_SEEK_CUR
332
-   *               (the offset should be measured from the current file offset)
333
-   *               or #MSPACK_SYS_SEEK_END (the offset should be measured from
334
-   *               the end of the file)
335
-   * @return zero for success, non-zero for an error
336
-   * @see open(), tell()
337
-   */
338
-  int (*seek)(struct mspack_file *file,
339
-	      off_t offset,
340
-	      int mode);
341
-
342
-  /**
343
-   * Returns the current file position (in bytes) of the given file.
344
-   *
345
-   * @param file the file whose file position is wanted
346
-   * @return the current file position of the file
347
-   * @see open(), seek()
348
-   */
349
-  off_t (*tell)(struct mspack_file *file);
350
-  
351
-  /**
352
-   * Used to send messages from the library to the user.
353
-   *
354
-   * Occasionally, the library generates warnings or other messages in
355
-   * plain english to inform the human user. These are informational only
356
-   * and can be ignored if not wanted.
357
-   *
358
-   * @param file   may be a file handle returned from open() if this message
359
-   *               pertains to a specific open file, or NULL if not related to
360
-   *               a specific file.
361
-   * @param format a printf() style format string. It does NOT include a
362
-   *               trailing newline.
363
-   * @see open()
364
-   */
365
-  void (*message)(struct mspack_file *file,
366
-		  char *format,
367
-		  ...);
368
-
369
-  /**
370
-   * Allocates memory.
371
-   *
372
-   * @param this     a self-referential pointer to the mspack_system
373
-   *                 structure whose alloc() method is being called.
374
-   * @param bytes    the number of bytes to allocate
375
-   * @result a pointer to the requested number of bytes, or NULL if
376
-   *         not enough memory is available
377
-   * @see free()
378
-   */
379
-  void * (*alloc)(struct mspack_system *this,
380
-		  size_t bytes);
381
-  
382
-  /**
383
-   * Frees memory.
384
-   * 
385
-   * @param ptr the memory to be freed.
386
-   * @see alloc()
387
-   */
388
-  void (*free)(void *ptr);
389
-
390
-  /**
391
-   * Copies from one region of memory to another.
392
-   * 
393
-   * The regions of memory are guaranteed not to overlap, are usually less
394
-   * than 256 bytes, and may not be aligned. Please note that the source
395
-   * parameter comes before the destination parameter, unlike the standard
396
-   * C function memcpy().
397
-   *
398
-   * @param src   the region of memory to copy from
399
-   * @param dest  the region of memory to copy to
400
-   * @param bytes the size of the memory region, in bytes
401
-   */
402
-  void (*copy)(void *src,
403
-	       void *dest,
404
-	       size_t bytes);
405
-
406
-  /**
407
-   * A null pointer to mark the end of mspack_system. It must equal NULL.
408
-   *
409
-   * Should the mspack_system structure extend in the future, this NULL
410
-   * will be seen, rather than have an invalid method pointer called.
411
-   */
412
-  void *null_ptr;
413
-};
414
-
415
-/** mspack_system::open() mode: open existing file for reading. */
416
-#define MSPACK_SYS_OPEN_READ   (0)
417
-/** mspack_system::open() mode: open new file for writing */
418
-#define MSPACK_SYS_OPEN_WRITE  (1)
419
-/** mspack_system::open() mode: open existing file for writing */
420
-#define MSPACK_SYS_OPEN_UPDATE (2)
421
-/** mspack_system::open() mode: open existing file for writing */
422
-#define MSPACK_SYS_OPEN_APPEND (3)
423
-
424
-/** mspack_system::seek() mode: seek relative to start of file */
425
-#define MSPACK_SYS_SEEK_START  (0)
426
-/** mspack_system::seek() mode: seek relative to current offset */
427
-#define MSPACK_SYS_SEEK_CUR    (1)
428
-/** mspack_system::seek() mode: seek relative to end of file */
429
-#define MSPACK_SYS_SEEK_END    (2)
430
-
431
-/** 
432
- * A structure which represents an open file handle. The contents of this
433
- * structure are determined by the implementation of the
434
- * mspack_system::open() method.
435
- */
436
-struct mspack_file {
437
-  int dummy;
438
-};
439
-
440
-/* --- error codes --------------------------------------------------------- */
441
-
442
-/** Error code: no error */
443
-#define MSPACK_ERR_OK          (0)
444
-/** Error code: bad arguments to method */
445
-#define MSPACK_ERR_ARGS        (1)
446
-/** Error code: error opening file */
447
-#define MSPACK_ERR_OPEN        (2)
448
-/** Error code: error reading file */
449
-#define MSPACK_ERR_READ        (3)
450
-/** Error code: error writing file */
451
-#define MSPACK_ERR_WRITE       (4)
452
-/** Error code: seek error */
453
-#define MSPACK_ERR_SEEK        (5)
454
-/** Error code: out of memory */
455
-#define MSPACK_ERR_NOMEMORY    (6)
456
-/** Error code: bad "magic id" in file */
457
-#define MSPACK_ERR_SIGNATURE   (7)
458
-/** Error code: bad or corrupt file format */
459
-#define MSPACK_ERR_DATAFORMAT  (8)
460
-/** Error code: bad checksum or CRC */
461
-#define MSPACK_ERR_CHECKSUM    (9)
462
-/** Error code: error during compression */
463
-#define MSPACK_ERR_CRUNCH      (10)
464
-/** Error code: error during decompression */
465
-#define MSPACK_ERR_DECRUNCH    (11)
466
-
467
-/* --- functions available in library -------------------------------------- */
468
-
469
-/** Creates a new CAB compressor.
470
- * @param sys a custom mspack_system structure, or NULL to use the default
471
- * @return a #mscab_compressor or NULL
472
- */
473
-extern struct mscab_compressor *
474
-  mspack_create_cab_compressor(struct mspack_system *sys);
475
-
476
-/** Creates a new CAB decompressor.
477
- * @param sys a custom mspack_system structure, or NULL to use the default
478
- * @return a #mscab_decompressor or NULL
479
- */
480
-extern struct mscab_decompressor *
481
-  mspack_create_cab_decompressor(struct mspack_system *sys);
482
-
483
-/** Destroys an existing CAB compressor.
484
- * @param this the #mscab_compressor to destroy
485
- */
486
-extern void mspack_destroy_cab_compressor(struct mscab_compressor *this);
487
-
488
-/** Destroys an existing CAB decompressor.
489
- * @param this the #mscab_decompressor to destroy
490
- */
491
-extern void mspack_destroy_cab_decompressor(struct mscab_decompressor *this);
492
-
493
-
494
-/** Creates a new CHM compressor.
495
- * @param sys a custom mspack_system structure, or NULL to use the default
496
- * @return a #mschm_compressor or NULL
497
- */
498
-extern struct mschm_compressor *
499
-  mspack_create_chm_compressor(struct mspack_system *sys);
500
-
501
-/** Creates a new CHM decompressor.
502
- * @param sys a custom mspack_system structure, or NULL to use the default
503
- * @return a #mschm_decompressor or NULL
504
- */
505
-extern struct mschm_decompressor *
506
-  mspack_create_chm_decompressor(struct mspack_system *sys);
507
-
508
-/** Destroys an existing CHM compressor.
509
- * @param this the #mschm_compressor to destroy
510
- */
511
-extern void mspack_destroy_chm_compressor(struct mschm_compressor *this);
512
-
513
-/** Destroys an existing CHM decompressor.
514
- * @param this the #mschm_decompressor to destroy
515
- */
516
-extern void mspack_destroy_chm_decompressor(struct mschm_decompressor *this);
517
-
518
-
519
-/** Creates a new LIT compressor.
520
- * @param sys a custom mspack_system structure, or NULL to use the default
521
- * @return a #mslit_compressor or NULL
522
- */
523
-extern struct mslit_compressor *
524
-  mspack_create_lit_compressor(struct mspack_system *sys);
525
-
526
-/** Creates a new LIT decompressor.
527
- * @param sys a custom mspack_system structure, or NULL to use the default
528
- * @return a #mslit_decompressor or NULL
529
- */
530
-extern struct mslit_decompressor *
531
-  mspack_create_lit_decompressor(struct mspack_system *sys);
532
-
533
-/** Destroys an existing LIT compressor.
534
- * @param this the #mslit_compressor to destroy
535
- */
536
-extern void mspack_destroy_lit_compressor(struct mslit_compressor *this);
537
-
538
-/** Destroys an existing LIT decompressor.
539
- * @param this the #mslit_decompressor to destroy
540
- */
541
-extern void mspack_destroy_lit_decompressor(struct mslit_decompressor *this);
542
-
543
-
544
-/** Creates a new HLP compressor.
545
- * @param sys a custom mspack_system structure, or NULL to use the default
546
- * @return a #mshlp_compressor or NULL
547
- */
548
-extern struct mshlp_compressor *
549
-  mspack_create_hlp_compressor(struct mspack_system *sys);
550
-
551
-/** Creates a new HLP decompressor.
552
- * @param sys a custom mspack_system structure, or NULL to use the default
553
- * @return a #mshlp_decompressor or NULL
554
- */
555
-extern struct mshlp_decompressor *
556
-  mspack_create_hlp_decompressor(struct mspack_system *sys);
557
-
558
-/** Destroys an existing hlp compressor.
559
- * @param this the #mshlp_compressor to destroy
560
- */
561
-extern void mspack_destroy_hlp_compressor(struct mshlp_compressor *this);
562
-
563
-/** Destroys an existing hlp decompressor.
564
- * @param this the #mshlp_decompressor to destroy
565
- */
566
-extern void mspack_destroy_hlp_decompressor(struct mshlp_decompressor *this);
567
-
568
-
569
-/** Creates a new SZDD compressor.
570
- * @param sys a custom mspack_system structure, or NULL to use the default
571
- * @return a #msszdd_compressor or NULL
572
- */
573
-extern struct msszdd_compressor *
574
-  mspack_create_szdd_compressor(struct mspack_system *sys);
575
-
576
-/** Creates a new SZDD decompressor.
577
- * @param sys a custom mspack_system structure, or NULL to use the default
578
- * @return a #msszdd_decompressor or NULL
579
- */
580
-extern struct msszdd_decompressor *
581
-  mspack_create_szdd_decompressor(struct mspack_system *sys);
582
-
583
-/** Destroys an existing SZDD compressor.
584
- * @param this the #msszdd_compressor to destroy
585
- */
586
-extern void mspack_destroy_szdd_compressor(struct msszdd_compressor *this);
587
-
588
-/** Destroys an existing SZDD decompressor.
589
- * @param this the #msszdd_decompressor to destroy
590
- */
591
-extern void mspack_destroy_szdd_decompressor(struct msszdd_decompressor *this);
592
-
593
-
594
-/** Creates a new KWAJ compressor.
595
- * @param sys a custom mspack_system structure, or NULL to use the default
596
- * @return a #mskwaj_compressor or NULL
597
- */
598
-extern struct mskwaj_compressor *
599
-  mspack_create_kwaj_compressor(struct mspack_system *sys);
600
-
601
-/** Creates a new KWAJ decompressor.
602
- * @param sys a custom mspack_system structure, or NULL to use the default
603
- * @return a #mskwaj_decompressor or NULL
604
- */
605
-extern struct mskwaj_decompressor *
606
-  mspack_create_kwaj_decompressor(struct mspack_system *sys);
607
-
608
-/** Destroys an existing KWAJ compressor.
609
- * @param this the #mskwaj_compressor to destroy
610
- */
611
-extern void mspack_destroy_kwaj_compressor(struct mskwaj_compressor *this);
612
-
613
-/** Destroys an existing KWAJ decompressor.
614
- * @param this the #mskwaj_decompressor to destroy
615
- */
616
-extern void mspack_destroy_kwaj_decompressor(struct mskwaj_decompressor *this);
617
-
618
-
619
-/* --- support for .CAB (MS Cabinet) file format --------------------------- */
620
-
621
-/**
622
- * A structure which represents a single cabinet file.
623
- *
624
- * All fields are READ ONLY.
625
- *
626
- * If this cabinet is part of a merged cabinet set, the #files and #folders
627
- * fields are common to all cabinets in the set, and will be identical.
628
- *
629
- * @see mscab_decompressor::open(), mscab_decompressor::close(),
630
- *      mscab_decompressor::search()
631
- */
632
-struct mscabd_cabinet {
633
-  /**
634
-   * The next cabinet in a chained list, if this cabinet was opened with
635
-   * mscab_decompressor::search(). May be NULL to mark the end of the
636
-   * list.
637
-   */
638
-  struct mscabd_cabinet *next;
639
-
640
-  /**
641
-   * The filename of the cabinet. More correctly, the filename of the
642
-   * physical file that the cabinet resides in. This is given by the
643
-   * library user and may be in any format.
644
-   */
645
-  char *filename;
646
-
647
-  int desc;
648
-
649
-  
650
-  /** The file offset of cabinet within the physical file it resides in. */
651
-  off_t base_offset;
652
-
653
-  /** The length of the cabinet file in bytes. */
654
-  unsigned int length;
655
-
656
-  /** The previous cabinet in a cabinet set, or NULL. */
657
-  struct mscabd_cabinet *prevcab;
658
-
659
-  /** The next cabinet in a cabinet set, or NULL. */
660
-  struct mscabd_cabinet *nextcab;
661
-
662
-  /** The filename of the previous cabinet in a cabinet set, or NULL. */
663
-  char *prevname;
664
-
665
-  /** The filename of the next cabinet in a cabinet set, or NULL. */
666
-  char *nextname;
667
-
668
-  /** The name of the disk containing the previous cabinet in a cabinet
669
-   * set, or NULL.
670
-   */
671
-  char *previnfo;
672
-
673
-  /** The name of the disk containing the next cabinet in a cabinet set,
674
-   * or NULL.
675
-   */
676
-  char *nextinfo;
677
-
678
-  /** A list of all files in the cabinet or cabinet set. */
679
-  struct mscabd_file *files;
680
-
681
-  /** A list of all folders in the cabinet or cabinet set. */
682
-  struct mscabd_folder *folders;
683
-
684
-  /** 
685
-   * The set ID of the cabinet. All cabinets in the same set should have
686
-   * the same set ID.
687
-   */
688
-  unsigned short set_id;
689
-
690
-  /**
691
-   * The index number of the cabinet within the set. Numbering should
692
-   * start from 0 for the first cabinet in the set, and increment by 1 for
693
-   * each following cabinet.
694
-   */
695
-  unsigned short set_index;
696
-
697
-  /**
698
-   * The number of bytes reserved in the header area of the cabinet.
699
-   *
700
-   * If this is non-zero and flags has MSCAB_HDR_RESV set, this data can
701
-   * be read by the calling application. It is of the given length,
702
-   * located at offset (base_offset + MSCAB_HDR_RESV_OFFSET) in the
703
-   * cabinet file.
704
-   *
705
-   * @see flags
706
-   */
707
-  unsigned short header_resv;
708
-
709
-  /**
710
-   * Header flags.
711
-   *
712
-   * - MSCAB_HDR_PREVCAB indicates the cabinet is part of a cabinet set, and
713
-   *                     has a predecessor cabinet.
714
-   * - MSCAB_HDR_NEXTCAB indicates the cabinet is part of a cabinet set, and
715
-   *                     has a successor cabinet.
716
-   * - MSCAB_HDR_RESV indicates the cabinet has reserved header space.
717
-   *
718
-   * @see prevname, previnfo, nextname, nextinfo, header_resv
719
-   */
720
-  int flags;
721
-};
722
-
723
-/** Offset from start of cabinet to the reserved header data (if present). */
724
-#define MSCAB_HDR_RESV_OFFSET (0x28)
725
-
726
-/** Cabinet header flag: cabinet has a predecessor */
727
-#define MSCAB_HDR_PREVCAB (0x01)
728
-/** Cabinet header flag: cabinet has a successor */
729
-#define MSCAB_HDR_NEXTCAB (0x02)
730
-/** Cabinet header flag: cabinet has reserved header space */
731
-#define MSCAB_HDR_RESV    (0x04)
732
-
733
-/**
734
- * A structure which represents a single folder in a cabinet or cabinet set.
735
- *
736
- * All fields are READ ONLY.
737
- *
738
- * A folder is a single compressed stream of data. When uncompressed, it
739
- * holds the data of one or more files. A folder may be split across more
740
- * than one cabinet.
741
- */
742
-struct mscabd_folder {
743
-  /**
744
-   * A pointer to the next folder in this cabinet or cabinet set, or NULL
745
-   * if this is the final folder.
746
-   */
747
-  struct mscabd_folder *next;
748
-
749
-  /** 
750
-   * The compression format used by this folder.
751
-   *
752
-   * The macro MSCABD_COMP_METHOD() should be used on this field to get
753
-   * the algorithm used. The macro MSCABD_COMP_LEVEL() should be used to get
754
-   * the "compression level".
755
-   *
756
-   * @see MSCABD_COMP_METHOD(), MSCABD_COMP_LEVEL()
757
-   */
758
-  int comp_type;
759
-
760
-  /**
761
-   * The total number of data blocks used by this folder. This includes
762
-   * data blocks present in other files, if this folder spans more than
763
-   * one cabinet.
764
-   */
765
-  unsigned int num_blocks;
766
-};
767
-
768
-/**
769
- * Returns the compression method used by a folder.
770
- *
771
- * @param comp_type a mscabd_folder::comp_type value
772
- * @return one of #MSCAB_COMP_NONE, #MSCAB_COMP_MSZIP, #MSCAB_COMP_QUANTUM
773
- *         or #MSCAB_COMP_LZX
774
- */
775
-#define MSCABD_COMP_METHOD(comp_type) ((comp_type) & 0x0F)
776
-/**
777
- * Returns the compression level used by a folder.
778
- *
779
- * @param comp_type a mscabd_folder::comp_type value
780
- * @return the compression level. This is only defined by LZX and Quantum
781
- *         compression
782
- */
783
-#define MSCABD_COMP_LEVEL(comp_type) (((comp_type) >> 8) & 0x1F)
784
-
785
-/** Compression mode: no compression. */
786
-#define MSCAB_COMP_NONE       (0)
787
-/** Compression mode: MSZIP (deflate) compression. */
788
-#define MSCAB_COMP_MSZIP      (1)
789
-/** Compression mode: Quantum compression */
790
-#define MSCAB_COMP_QUANTUM    (2)
791
-/** Compression mode: LZX compression */
792
-#define MSCAB_COMP_LZX        (3)
793
-
794
-/**
795
- * A structure which represents a single file in a cabinet or cabinet set.
796
- *
797
- * All fields are READ ONLY.
798
- */
799
-struct mscabd_file {
800
-  /**
801
-   * The next file in the cabinet or cabinet set, or NULL if this is the
802
-   * final file.
803
-   */
804
-  struct mscabd_file *next;
805
-
806
-  /**
807
-   * The filename of the file.
808
-   *
809
-   * A null terminated string of up to 255 bytes in length, it may be in
810
-   * either ISO-8859-1 or UTF8 format, depending on the file attributes.
811
-   *
812
-   * @see attribs
813
-   */
814
-  char *filename;
815
-
816
-  /** The uncompressed length of the file, in bytes. */
817
-  unsigned int length;
818
-
819
-  /**
820
-   * File attributes.
821
-   *
822
-   * The following attributes are defined:
823
-   * - #MSCAB_ATTRIB_RDONLY indicates the file is write protected.
824
-   * - #MSCAB_ATTRIB_HIDDEN indicates the file is hidden.
825
-   * - #MSCAB_ATTRIB_SYSTEM indicates the file is a operating system file.
826
-   * - #MSCAB_ATTRIB_ARCH indicates the file is "archived".
827
-   * - #MSCAB_ATTRIB_EXEC indicates the file is an executable program.
828
-   * - #MSCAB_ATTRIB_UTF_NAME indicates the filename is in UTF8 format rather
829
-   *   than ISO-8859-1.
830
-   */
831
-  int attribs;
832
-
833
-  /** File's last modified time, hour field. */
834
-  char time_h;
835
-  /** File's last modified time, minute field. */
836
-  char time_m;
837
-  /** File's last modified time, second field. */
838
-  char time_s;
839
-
840
-  /** File's last modified date, day field. */
841
-  char date_d;
842
-  /** File's last modified date, month field. */
843
-  char date_m;
844
-  /** File's last modified date, year field. */
845
-  int date_y;
846
-
847
-  /** A pointer to the folder that contains this file. */
848
-  struct mscabd_folder *folder;
849
-
850
-  /** The uncompressed offset of this file in its folder. */
851
-  unsigned int offset;
852
-};
853
-
854
-/** mscabd_file::attribs attribute: file is read-only. */
855
-#define MSCAB_ATTRIB_RDONLY   (0x01)
856
-/** mscabd_file::attribs attribute: file is hidden. */
857
-#define MSCAB_ATTRIB_HIDDEN   (0x02)
858
-/** mscabd_file::attribs attribute: file is an operating system file. */
859
-#define MSCAB_ATTRIB_SYSTEM   (0x04)
860
-/** mscabd_file::attribs attribute: file is "archived". */
861
-#define MSCAB_ATTRIB_ARCH     (0x20)
862
-/** mscabd_file::attribs attribute: file is an executable program. */
863
-#define MSCAB_ATTRIB_EXEC     (0x40)
864
-/** mscabd_file::attribs attribute: filename is UTF8, not ISO-8859-1. */
865
-#define MSCAB_ATTRIB_UTF_NAME (0x80)
866
-
867
-/** mscab_decompressor::set_param() parameter: search buffer size. */
868
-#define MSCABD_PARAM_SEARCHBUF (0)
869
-/** mscab_decompressor::set_param() parameter: repair MS-ZIP streams? */
870
-#define MSCABD_PARAM_FIXMSZIP  (1)
871
-/** mscab_decompressor::set_param() parameter: size of decompression buffer */
872
-#define MSCABD_PARAM_DECOMPBUF (2)
873
-
874
-/** TODO */
875
-struct mscab_compressor {
876
-  int dummy; 
877
-};
878
-
879
-/**
880
- * A decompressor for .CAB (Microsoft Cabinet) files
881
- *
882
- * All fields are READ ONLY.
883
- *
884
- * @see mspack_create_cab_decompressor(), mspack_destroy_cab_decompressor()
885
- */
886
-struct mscab_decompressor {
887
-  /**
888
-   * Opens a cabinet file and reads its contents.
889
-   *
890
-   * If the file opened is a valid cabinet file, all headers will be read
891
-   * and a mscabd_cabinet structure will be returned, with a full list of
892
-   * folders and files.
893
-   *
894
-   * In the case of an error occuring, NULL is returned and the error code
895
-   * is available from last_error().
896
-   *
897
-   * The filename pointer should be considered "in use" until close() is
898
-   * called on the cabinet.
899
-   *
900
-   * @param  this     a self-referential pointer to the mscab_decompressor
901
-   *                  instance being called
902
-   * @param  filename the filename of the cabinet file. This is passed
903
-   *                  directly to mspack_system::open().
904
-   * @return a pointer to a mscabd_cabinet structure, or NULL on failure
905
-   * @see close(), search(), last_error()
906
-   */
907
-  struct mscabd_cabinet * (*open) (struct mscab_decompressor *this,
908
-				   char *filename);
909
-
910
-  struct mscabd_cabinet * (*dopen) (struct mscab_decompressor *this,
911
-				   int desc);
912
-  /**
913
-   * Closes a previously opened cabinet or cabinet set.
914
-   *
915
-   * This closes a cabinet, all cabinets associated with it via the
916
-   * mscabd_cabinet::next, mscabd_cabinet::prevcab and
917
-   * mscabd_cabinet::nextcab pointers, and all folders and files. All
918
-   * memory used by these entities is freed.
919
-   *
920
-   * The cabinet pointer is now invalid and cannot be used again. All
921
-   * mscabd_folder and mscabd_file pointers from that cabinet or cabinet
922
-   * set are also now invalid, and cannot be used again.
923
-   *
924
-   * If the cabinet pointer given was created using search(), it MUST be
925
-   * the cabinet pointer returned by search() and not one of the later
926
-   * cabinet pointers further along the mscabd_cabinet::next chain.
927
-
928
-   * If extra cabinets have been added using append() or prepend(), these
929
-   * will all be freed, even if the cabinet pointer given is not the first
930
-   * cabinet in the set. Do NOT close() more than one cabinet in the set.
931
-   *
932
-   * The mscabd_cabinet::filename is not freed by the library, as it is
933
-   * not allocated by the library. The caller should free this itself if
934
-   * necessary, before it is lost forever.
935
-   *
936
-   * @param  this     a self-referential pointer to the mscab_decompressor
937
-   *                  instance being called
938
-   * @param  cab      the cabinet to close
939
-   * @see open(), search(), append(), prepend()
940
-   */
941
-  void (*close)(struct mscab_decompressor *this,
942
-		struct mscabd_cabinet *cab);
943
-
944
-  /**
945
-   * Searches a regular file for embedded cabinets.
946
-   *
947
-   * This opens a normal file with the given filename and will search the
948
-   * entire file for embedded cabinet files
949
-   *
950
-   * If any cabinets are found, the equivalent of open() is called on each
951
-   * potential cabinet file at the offset it was found. All successfully
952
-   * open()ed cabinets are kept in a list.
953
-   *
954
-   * The first cabinet found will be returned directly as the result of
955
-   * this method. Any further cabinets found will be chained in a list
956
-   * using the mscabd_cabinet::next field.
957
-   *
958
-   * In the case of an error occuring anywhere other than the simulated
959
-   * open(), NULL is returned and the error code is available from
960
-   * last_error().
961
-   *
962
-   * If no error occurs, but no cabinets can be found in the file, NULL is
963
-   * returned and last_error() returns MSPACK_ERR_OK.
964
-   *
965
-   * The filename pointer should be considered in use until close() is
966
-   * called on the cabinet.
967
-   *
968
-   * close() should only be called on the result of search(), not on any
969
-   * subsequent cabinets in the mscabd_cabinet::next chain.
970
-   *
971
-   * @param  this     a self-referential pointer to the mscab_decompressor
972
-   *                  instance being called
973
-   * @param  filename the filename of the file to search for cabinets. This
974
-   *                  is passed directly to mspack_system::open().
975
-   * @return a pointer to a mscabd_cabinet structure, or NULL
976
-   * @see close(), open(), last_error()
977
-   */
978
-  struct mscabd_cabinet * (*search) (struct mscab_decompressor *this,
979
-				     char *filename);
980
-
981
-  struct mscabd_cabinet * (*dsearch) (struct mscab_decompressor *this,
982
-				     int desc);
983
-
984
-  /**
985
-   * Appends one mscabd_cabinet to another, forming or extending a cabinet
986
-   * set.
987
-   *
988
-   * This will attempt to append one cabinet to another such that
989
-   * <tt>(cab->nextcab == nextcab) && (nextcab->prevcab == cab)</tt> and
990
-   * any folders split between the two cabinets are merged.
991
-   *
992
-   * The cabinets MUST be part of a cabinet set -- a cabinet set is a
993
-   * cabinet that spans more than one physical cabinet file on disk -- and
994
-   * must be appropriately matched.
995
-   *
996
-   * It can be determined if a cabinet has further parts to load by
997
-   * examining the mscabd_cabinet::flags field:
998
-   *
999
-   * - if <tt>(flags & MSCAB_HDR_PREVCAB)</tt> is non-zero, there is a
1000
-   *   predecessor cabinet to open() and prepend(). Its MS-DOS
1001
-   *   case-insensitive filename is mscabd_cabinet::prevname
1002
-   * - if <tt>(flags & MSCAB_HDR_NEXTCAB)</tt> is non-zero, there is a
1003
-   *   successor cabinet to open() and append(). Its MS-DOS case-insensitive
1004
-   *   filename is mscabd_cabinet::nextname
1005
-   *
1006
-   * If the cabinets do not match, an error code will be returned. Neither
1007
-   * cabinet has been altered, and both should be closed seperately.
1008
-   *
1009
-   * Files and folders in a cabinet set are a single entity. All cabinets
1010
-   * in a set use the same file list, which is updated as cabinets in the
1011
-   * set are added. All pointers to mscabd_folder and mscabd_file
1012
-   * structures in either cabinet must be discarded and re-obtained after
1013
-   * merging.
1014
-   *
1015
-   * @param  this     a self-referential pointer to the mscab_decompressor
1016
-   *                  instance being called
1017
-   * @param  cab      the cabinet which will be appended to,
1018
-   *                  predecessor of nextcab
1019
-   * @param  nextcab  the cabinet which will be appended,
1020
-   *                  successor of cab
1021
-   * @return an error code, or MSPACK_ERR_OK if successful
1022
-   * @see prepend(), open(), close()
1023
-   */
1024
-  int (*append) (struct mscab_decompressor *this,
1025
-		 struct mscabd_cabinet *cab,
1026
-		 struct mscabd_cabinet *nextcab);
1027
-
1028
-  /**
1029
-   * Prepends one mscabd_cabinet to another, forming or extending a
1030
-   * cabinet set.
1031
-   *
1032
-   * This will attempt to prepend one cabinet to another, such that
1033
-   * <tt>(cab->prevcab == prevcab) && (prevcab->nextcab == cab)</tt>. In
1034
-   * all other respects, it is identical to append(). See append() for the
1035
-   * full documentation.
1036
-   *
1037
-   * @param  this     a self-referential pointer to the mscab_decompressor
1038
-   *                  instance being called
1039
-   * @param  cab      the cabinet which will be prepended to,
1040
-   *                  successor of prevcab
1041
-   * @param  prevcab  the cabinet which will be prepended,
1042
-   *                  predecessor of cab
1043
-   * @return an error code, or MSPACK_ERR_OK if successful
1044
-   * @see append(), open(), close()
1045
-   */
1046
-  int (*prepend) (struct mscab_decompressor *this,
1047
-		  struct mscabd_cabinet *cab,
1048
-		  struct mscabd_cabinet *prevcab);
1049
-
1050
-  /**
1051
-   * Extracts a file from a cabinet or cabinet set.
1052
-   *
1053
-   * This extracts a compressed file in a cabinet and writes it to the given
1054
-   * filename.
1055
-   *
1056
-   * The MS-DOS filename of the file, mscabd_file::filename, is NOT USED
1057
-   * by extract(). The caller must examine this MS-DOS filename, copy and
1058
-   * change it as necessary, create directories as necessary, and provide
1059
-   * the correct filename as a parameter, which will be passed unchanged
1060
-   * to the decompressor's mspack_system::open()
1061
-   *
1062
-   * If the file belongs to a split folder in a multi-part cabinet set,
1063
-   * and not enough parts of the cabinet set have been loaded and appended
1064
-   * or prepended, an error will be returned immediately.
1065
-   *
1066
-   * @param  this     a self-referential pointer to the mscab_decompressor
1067
-   *                  instance being called
1068
-   * @param  file     the file to be decompressed
1069
-   * @param  filename the filename of the file being written to
1070
-   * @return an error code, or MSPACK_ERR_OK if successful
1071
-   */
1072
-  int (*extract)(struct mscab_decompressor *this,
1073
-		 struct mscabd_file *file,
1074
-		 char *filename);
1075
-
1076
-  /**
1077
-   * Sets a CAB decompression engine parameter.
1078
-   *
1079
-   * The following parameters are defined:
1080
-   * - #MSCABD_PARAM_SEARCHBUF: How many bytes should be allocated as a
1081
-   *   buffer when using search()? The minimum value is 4.  The default
1082
-   *   value is 32768.
1083
-   * - #MSCABD_PARAM_FIXMSZIP: If non-zero, extract() will ignore bad
1084
-   *   checksums and recover from decompression errors in MS-ZIP
1085
-   *   compressed folders. The default value is 0 (don't recover).
1086
-   * - #MSCABD_PARAM_DECOMPBUF: How many bytes should be used as an input
1087
-   *   bit buffer by decompressors? The minimum value is 4. The default
1088
-   *   value is 4096.
1089
-   *
1090
-   * @param  this     a self-referential pointer to the mscab_decompressor
1091
-   *                  instance being called
1092
-   * @param  param    the parameter to set
1093
-   * @param  value    the value to set the parameter to
1094
-   * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1095
-   *         is a problem with either parameter or value.
1096
-   * @see search(), extract()
1097
-   */
1098
-  int (*set_param)(struct mscab_decompressor *this,
1099
-		   int param,
1100
-		   int value);
1101
-
1102
-  /**
1103
-   * Returns the error code set by the most recently called method.
1104
-   *
1105
-   * This is useful for open() and search(), which do not return an error
1106
-   * code directly.
1107
-   *
1108
-   * @param  this     a self-referential pointer to the mscab_decompressor
1109
-   *                  instance being called
1110
-   * @return the most recent error code
1111
-   * @see open(), search()
1112
-   */
1113
-  int (*last_error)(struct mscab_decompressor *);
1114
-};
1115
-
1116
-/* --- support for .CHM (HTMLHelp) file format ----------------------------- */
1117
-
1118
-/**
1119
- * A structure which represents a section of a CHM helpfile.
1120
- *
1121
- * All fields are READ ONLY.
1122
- *
1123
- * Not used directly, but used as a generic base type for
1124
- * mschmd_sec_uncompressed and mschmd_sec_mscompressed.
1125
- */
1126
-struct mschmd_section {
1127
-  /** A pointer to the CHM helpfile that contains this section. */
1128
-  struct mschmd_header *chm;
1129
-
1130
-  /**
1131
-   * The section ID. Either 0 for the uncompressed section
1132
-   * mschmd_sec_uncompressed, or 1 for the LZX compressed section
1133
-   * mschmd_sec_mscompressed. No other section IDs are known.
1134
-   */
1135
-  unsigned int id;
1136
-};
1137
-
1138
-/**
1139
- * A structure which represents the uncompressed section of a CHM helpfile.
1140
- * 
1141
- * All fields are READ ONLY.
1142
- */
1143
-struct mschmd_sec_uncompressed {
1144
-  /** Generic section data. */
1145
-  struct mschmd_section base;
1146
-
1147
-  /** The file offset of where this section begins in the CHM helpfile. */
1148
-  off_t offset;
1149
-};
1150
-
1151
-/**
1152
- * A structure which represents the compressed section of a CHM helpfile. 
1153
- * 
1154
- * All fields are READ ONLY.
1155
- */
1156
-struct mschmd_sec_mscompressed {
1157
-  /** Generic section data. */
1158
-  struct mschmd_section base;
1159
-
1160
-  /** A pointer to the meta-file which represents all LZX compressed data. */
1161
-  struct mschmd_file *content;
1162
-
1163
-  /** A pointer to the file which contains the LZX control data. */
1164
-  struct mschmd_file *control;
1165
-
1166
-  /** A pointer to the file which contains the LZX reset table. */
1167
-  struct mschmd_file *rtable;
1168
-};
1169
-
1170
-/**
1171
- * A structure which represents a CHM helpfile.
1172
- * 
1173
- * All fields are READ ONLY.
1174
- */
1175
-struct mschmd_header {
1176
-  /** The version of the CHM file format used in this file. */
1177
-  unsigned int version;
1178
-
1179
-  /**
1180
-   * The "timestamp" of the CHM helpfile. 
1181
-   *
1182
-   * It is the lower 32 bits of a 64-bit value representing the number of
1183
-   * centiseconds since 1601-01-01 00:00:00 UTC, plus 42. It is not useful
1184
-   * as a timestamp, but it is useful as a semi-unique ID.
1185
-   */
1186
-  unsigned int timestamp;
1187
-
1188
-      
1189
-  /**
1190
-   * The default Language and Country ID (LCID) of the user who ran the
1191
-   * HTMLHelp Compiler. This is not the language of the CHM file itself.
1192
-   */
1193
-  unsigned int language;
1194
-
1195
-  /**
1196
-   * The filename of the CHM helpfile. This is given by the library user
1197
-   * and may be in any format.
1198
-   */
1199
-  char *filename;
1200
-
1201
-  /** The length of the CHM helpfile, in bytes. */
1202
-  off_t length;
1203
-
1204
-  /** A list of all non-system files in the CHM helpfile. */
1205
-  struct mschmd_file *files;
1206
-
1207
-  /**
1208
-   * A list of all system files in the CHM helpfile.
1209
-   *
1210
-   * System files are files which begin with "::". They are meta-files
1211
-   * generated by the CHM creation process.
1212
-   */
1213
-  struct mschmd_file *sysfiles;
1214
-
1215
-  /** The section 0 (uncompressed) data in this CHM helpfile. */
1216
-  struct mschmd_sec_uncompressed sec0;
1217
-
1218
-  /** The section 1 (MSCompressed) data in this CHM helpfile. */
1219
-  struct mschmd_sec_mscompressed sec1;
1220
-
1221
-  /** The file offset of the first PMGL/PMGI directory chunk. */
1222
-  off_t dir_offset;
1223
-
1224
-  /** The number of PMGL/PMGI directory chunks in this CHM helpfile. */
1225
-  unsigned int num_chunks;
1226
-
1227
-  /** The size of each PMGL/PMGI chunk, in bytes. */
1228
-  unsigned int chunk_size;
1229
-
1230
-  /** The "density" of the quick-reference section in PMGL/PMGI chunks. */
1231
-  unsigned int density;
1232
-
1233
-  /** The depth of the index tree.
1234
-   *
1235
-   * - if 1, there are no PMGI chunks, only PMGL chunks.
1236
-   * - if 2, there is 1 PMGI chunk. All chunk indices point to PMGL chunks.
1237
-   * - if 3, the root PMGI chunk points to secondary PMGI chunks, which in
1238
-   *         turn point to PMGL chunks.
1239
-   * - and so on...
1240
-   */
1241
-  unsigned int depth;
1242
-
1243
-  /**
1244
-   * The number of the root PGMI chunk.
1245
-   *
1246
-   * If there is no index in the CHM helpfile, this will be 0xFFFFFFFF.
1247
-   */
1248
-  unsigned int index_root;
1249
-};
1250
-
1251
-/**
1252
- * A structure which represents a file stored in a CHM helpfile.
1253
- * 
1254
- * All fields are READ ONLY.
1255
- */
1256
-struct mschmd_file {
1257
-  /**
1258
-   * A pointer to the next file in the list, or NULL if this is the final
1259
-   * file.
1260
-   */
1261
-  struct mschmd_file *next;
1262
-
1263
-  /**
1264
-   * A pointer to the section that this file is located in. Indirectly,
1265
-   * it also points to the CHM helpfile the file is located in.
1266
-   */
1267
-  struct mschmd_section *section;
1268
-
1269
-  /** The offset within the section data that this file is located at. */
1270
-  off_t offset;
1271
-
1272
-  /** The length of this file, in bytes */
1273
-  off_t length;
1274
-
1275
-  /** The filename of this file -- a null terminated string in UTF8. */
1276
-  char *filename;
1277
-};
1278
-
1279
-/** TODO */
1280
-struct mschm_compressor {
1281
-  int dummy;
1282
-};
1283
-
1284
-/**
1285
- * A decompressor for .CHM (Microsoft HTMLHelp) files
1286
- *
1287
- * All fields are READ ONLY.
1288
- *
1289
- * @see mspack_create_chm_decompressor(), mspack_destroy_chm_decompressor()
1290
- */
1291
-struct mschm_decompressor {
1292
-  /**
1293
-   * Opens a CHM helpfile and reads its contents.
1294
-   *
1295
-   * If the file opened is a valid CHM helpfile, all headers will be read
1296
-   * and a mschmd_header structure will be returned, with a full list of
1297
-   * files.
1298
-   *
1299
-   * In the case of an error occuring, NULL is returned and the error code
1300
-   * is available from last_error().
1301
-   *
1302
-   * The filename pointer should be considered "in use" until close() is
1303
-   * called on the CHM helpfile.
1304
-   *
1305
-   * @param  this     a self-referential pointer to the mschm_decompressor
1306
-   *                  instance being called
1307
-   * @param  filename the filename of the CHM helpfile. This is passed
1308
-   *                  directly to mspack_system::open().
1309
-   * @return a pointer to a mschmd_header structure, or NULL on failure
1310
-   * @see close()
1311
-   */
1312
-  struct mschmd_header *(*open)(struct mschm_decompressor *this,
1313
-				char *filename);
1314
-
1315
-  /**
1316
-   * Closes a previously opened CHM helpfile.
1317
-   *
1318
-   * This closes a CHM helpfile, frees the mschmd_header and all
1319
-   * mschmd_file structures associated with it (if any). This works on
1320
-   * both helpfiles opened with open() and helpfiles opened with
1321
-   * fast_open().
1322
-   *
1323
-   * The CHM header pointer is now invalid and cannot be used again. All
1324
-   * mschmd_file pointers referencing that CHM are also now invalid, and
1325
-   * cannot be used again.
1326
-   *
1327
-   * @param  this     a self-referential pointer to the mschm_decompressor
1328
-   *                  instance being called
1329
-   * @param  chm      the CHM helpfile to close
1330
-   * @see open(), fast_open()
1331
-   */
1332
-  void (*close)(struct mschm_decompressor *this,
1333
-		struct mschmd_header *chm);
1334
-
1335
-  /**
1336
-   * Extracts a file from a CHM helpfile.
1337
-   *
1338
-   * This extracts a file from a CHM helpfile and writes it to the given
1339
-   * filename. The filename of the file, mscabd_file::filename, is not
1340
-   * used by extract(), but can be used by the caller as a guide for
1341
-   * constructing an appropriate filename.
1342
-   *
1343
-   * This method works both with files found in the mschmd_header::files
1344
-   * and mschmd_header::sysfiles list and mschmd_file structures generated
1345
-   * on the fly by fast_find().
1346
-   *
1347
-   * @param  this     a self-referential pointer to the mscab_decompressor
1348
-   *                  instance being called
1349
-   * @param  file     the file to be decompressed
1350
-   * @param  filename the filename of the file being written to
1351
-   * @return an error code, or MSPACK_ERR_OK if successful
1352
-   */
1353
-  int (*extract)(struct mschm_decompressor *this,
1354
-		 struct mschmd_file *file,
1355
-		 char *filename);
1356
-
1357
-  /**
1358
-   * Returns the error code set by the most recently called method.
1359
-   *
1360
-   * This is useful for open() and fast_open(), which do not return an
1361
-   * error code directly.
1362
-   *
1363
-   * @param  this     a self-referential pointer to the mschm_decompressor
1364
-   *                  instance being called
1365
-   * @return the most recent error code
1366
-   * @see open(), search()
1367
-   */
1368
-  int (*last_error)(struct mschm_decompressor *this);
1369
-
1370
-  /**
1371
-   * Opens a CHM helpfile quickly.
1372
-   *
1373
-   * If the file opened is a valid CHM helpfile, only essential headers
1374
-   * will be read. A mschmd_header structure will be still be returned, as
1375
-   * with open(), but the mschmd_header::files field will be NULL. No
1376
-   * files details will be automatically read.  The fast_find() method
1377
-   * must be used to obtain file details.
1378
-   *
1379
-   * In the case of an error occuring, NULL is returned and the error code
1380
-   * is available from last_error().
1381
-   *
1382
-   * The filename pointer should be considered "in use" until close() is
1383
-   * called on the CHM helpfile.
1384
-   *
1385
-   * @param  this     a self-referential pointer to the mschm_decompressor
1386
-   *                  instance being called
1387
-   * @param  filename the filename of the CHM helpfile. This is passed
1388
-   *                  directly to mspack_system::open().
1389
-   * @return a pointer to a mschmd_header structure, or NULL on failure
1390
-   * @see open(), close(), fast_find(), extract()
1391
-   */
1392
-  struct mschmd_header *(*fast_open)(struct mschm_decompressor *this,
1393
-				     char *filename);
1394
-
1395
-  /**
1396
-   * Finds file details quickly.
1397
-   *
1398
-   * Instead of reading all CHM helpfile headers and building a list of
1399
-   * files, fast_open() and fast_find() are intended for finding file
1400
-   * details only when they are needed. The CHM file format includes an
1401
-   * on-disk file index to allow this.
1402
-   *
1403
-   * Given a case-sensitive filename, fast_find() will search the on-disk
1404
-   * index for that file.
1405
-   *
1406
-   * If the file was found, the caller-provided mschmd_file structure will
1407
-   * be filled out like so:
1408
-   * - section: the correct value for the found file
1409
-   * - offset: the correct value for the found file
1410
-   * - length: the correct value for the found file
1411
-   * - all other structure elements: NULL or 0
1412
-   *
1413
-   * If the file was not found, MSPACK_ERR_OK will still be returned as the
1414
-   * result, but the caller-provided structure will be filled out like so:
1415
-   * - section: NULL
1416
-   * - offset: 0
1417
-   * - length: 0
1418
-   * - all other structure elements: NULL or 0
1419
-   *
1420
-   * This method is intended to be used in conjunction with CHM helpfiles
1421
-   * opened with fast_open(), but it also works with helpfiles opened
1422
-   * using the regular open().
1423
-   *
1424
-   * @param  this     a self-referential pointer to the mschm_decompressor
1425
-   *                  instance being called
1426
-   * @param  chm      the CHM helpfile to search for the file
1427
-   * @param  filename the filename of the file to search for
1428
-   * @param  f_ptr    a pointer to a caller-provded mschmd_file structure
1429
-   * @param  f_size   <tt>sizeof(struct mschmd_file)</tt>
1430
-   * @return MSPACK_ERR_OK, or an error code
1431
-   * @see open(), close(), fast_find(), extract()
1432
-   */
1433
-  int (*fast_find)(struct mschm_decompressor *this,
1434
-		   struct mschmd_header *chm,
1435
-		   char *filename,
1436
-		   struct mschmd_file *f_ptr,
1437
-		   int f_size);
1438
-};
1439
-
1440
-/* --- support for .LIT (EBook) file format -------------------------------- */
1441
-
1442
-/** TODO */
1443
-struct mslit_compressor {
1444
-  int dummy; 
1445
-};
1446
-
1447
-/** TODO */
1448
-struct mslit_decompressor {
1449
-  int dummy; 
1450
-};
1451
-
1452
-
1453
-/* --- support for .HLP (MS Help) file format ------------------------------ */
1454
-
1455
-/** TODO */
1456
-struct mshlp_compressor {
1457
-  int dummy; 
1458
-};
1459
-
1460
-/** TODO */
1461
-struct mshlp_decompressor {
1462
-  int dummy; 
1463
-};
1464
-
1465
-
1466
-/* --- support for SZDD file format ---------------------------------------- */
1467
-
1468
-/** TODO */
1469
-struct msszdd_compressor {
1470
-  int dummy; 
1471
-};
1472
-
1473
-/** TODO */
1474
-struct msszdd_decompressor {
1475
-  int dummy; 
1476
-};
1477
-
1478
-/* --- support for KWAJ file format ---------------------------------------- */
1479
-
1480
-/** TODO */
1481
-struct mskwaj_compressor {
1482
-  int dummy; 
1483
-};
1484
-
1485
-/** TODO */
1486
-struct mskwaj_decompressor {
1487
-  int dummy; 
1488
-};
1489
-
1490
-#ifdef __cplusplus
1491
-};
1492
-#endif
1493
-
1494
-#endif
1495 1
deleted file mode 100644
... ...
@@ -1,114 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * The deflate method was created by Phil Katz. MSZIP is equivalent to the
5
- * deflate method.
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * For further details, see the file COPYING.LIB distributed with libmspack
11
- */
12
-
13
-#ifndef MSPACK_MSZIP_H
14
-#define MSPACK_MSZIP_H 1
15
-
16
-/* MSZIP (deflate) compression / (inflate) decompression definitions */
17
-
18
-#define MSZIP_FRAME_SIZE          (32768) /* size of LZ history window */
19
-#define MSZIP_MAX_HUFFBITS        (16)    /* maximum huffman code length */
20
-#define MSZIP_LITERAL_MAXSYMBOLS  (288)   /* literal/length huffman tree */
21
-#define MSZIP_LITERAL_TABLEBITS   (9)
22
-#define MSZIP_DISTANCE_MAXSYMBOLS (32)    /* distance huffman tree */
23
-#define MSZIP_DISTANCE_TABLEBITS  (6)
24
-
25
-/* if there are less direct lookup entries than symbols, the longer
26
- * code pointers will be <= maxsymbols. This must not happen, or we
27
- * will decode entries badly */
28
-#if (1 << MSZIP_LITERAL_TABLEBITS) < (MSZIP_LITERAL_MAXSYMBOLS * 2)
29
-# define MSZIP_LITERAL_TABLESIZE (MSZIP_LITERAL_MAXSYMBOLS * 4)
30
-#else
31
-# define MSZIP_LITERAL_TABLESIZE ((1 << MSZIP_LITERAL_TABLEBITS) + \
32
-				  (MSZIP_LITERAL_MAXSYMBOLS * 2))
33
-#endif
34
-
35
-#if (1 << MSZIP_DISTANCE_TABLEBITS) < (MSZIP_DISTANCE_MAXSYMBOLS * 2)
36
-# define MSZIP_DISTANCE_TABLESIZE (MSZIP_DISTANCE_MAXSYMBOLS * 4)
37
-#else
38
-# define MSZIP_DISTANCE_TABLESIZE ((1 << MSZIP_DISTANCE_TABLEBITS) + \
39
-				  (MSZIP_DISTANCE_MAXSYMBOLS * 2))
40
-#endif
41
-
42
-struct mszipd_stream {
43
-  struct mspack_system *sys;            /* I/O routines          */
44
-  struct mspack_file   *input;          /* input file handle     */
45
-  struct mspack_file   *output;         /* output file handle    */
46
-  unsigned int window_posn;             /* offset within window  */
47
-
48
-  /* inflate() will call this whenever the window should be emptied. */
49
-  int (*flush_window)(struct mszipd_stream *, unsigned int);
50
-
51
-  int error, repair_mode, bytes_output;
52
-
53
-  /* I/O buffering */
54
-  unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
55
-  unsigned int bit_buffer, bits_left, inbuf_size;
56
-
57
-
58
-  /* huffman code lengths */
59
-  unsigned char  LITERAL_len[MSZIP_LITERAL_MAXSYMBOLS];
60
-  unsigned char  DISTANCE_len[MSZIP_DISTANCE_MAXSYMBOLS];
61
-
62
-  /* huffman decoding tables */
63
-  unsigned short LITERAL_table [MSZIP_LITERAL_TABLESIZE];
64
-  unsigned short DISTANCE_table[MSZIP_DISTANCE_TABLESIZE];
65
-
66
-  /* 32kb history window */
67
-  unsigned char window[MSZIP_FRAME_SIZE];
68
-};
69
-
70
-/* allocates MS-ZIP decompression stream for decoding the given stream.
71
- *
72
- * - uses system->alloc() to allocate memory
73
- *
74
- * - returns NULL if not enough memory
75
- *
76
- * - input_buffer_size is how many bytes to use as an input bitstream buffer
77
- *
78
- * - if repair_mode is non-zero, errors in decompression will be skipped
79
- *   and 'holes' left will be filled with zero bytes. This allows at least
80
- *   a partial recovery of erroneous data.
81
- */
82
-extern struct mszipd_stream *mszipd_init(struct mspack_system *system,
83
-					struct mspack_file *input,
84
-					struct mspack_file *output,
85
-					int input_buffer_size,
86
-					int repair_mode);
87
-
88
-/* decompresses, or decompresses more of, an MS-ZIP stream.
89
- *
90
- * - out_bytes of data will be decompressed and the function will return
91
- *   with an MSPACK_ERR_OK return code.
92
- *
93
- * - decompressing will stop as soon as out_bytes is reached. if the true
94
- *   amount of bytes decoded spills over that amount, they will be kept for
95
- *   a later invocation of mszipd_decompress().
96
- *
97
- * - the output bytes will be passed to the system->write() function given in
98
- *   mszipd_init(), using the output file handle given in mszipd_init(). More
99
- *   than one call may be made to system->write()
100
- *
101
- * - MS-ZIP will read input bytes as necessary using the system->read()
102
- *   function given in mszipd_init(), using the input file handle given in
103
- *   mszipd_init(). This will continue until system->read() returns 0 bytes,
104
- *   or an error.
105
- */
106
-extern int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes);
107
-
108
-/* frees all stream associated with an MS-ZIP data stream
109
- *
110
- * - calls system->free() using the system pointer given in mszipd_init()
111
- */
112
-void mszipd_free(struct mszipd_stream *zip);
113
-
114
-#endif
115 1
deleted file mode 100644
... ...
@@ -1,652 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * The deflate method was created by Phil Katz. MSZIP is equivalent to the
5
- * deflate method.
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * For further details, see the file COPYING.LIB distributed with libmspack
11
- */
12
-
13
-/* MS-ZIP decompression implementation. */
14
-
15
-#if HAVE_CONFIG_H
16
-#include "clamav-config.h"
17
-#endif
18
-
19
-#include <mspack.h>
20
-#include <system.h>
21
-#include <mszip.h>
22
-
23
-/* match lengths for literal codes 257.. 285 */
24
-static const unsigned short lit_lengths[29] = {
25
-  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27,
26
-  31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
27
-};
28
-
29
-/* match offsets for distance codes 0 .. 29 */
30
-static const unsigned short dist_offsets[30] = {
31
-  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
32
-  513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
33
-};
34
-
35
-/* extra bits required for literal codes 257.. 285 */
36
-static const unsigned char lit_extrabits[29] = {
37
-  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
38
-  2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
39
-};
40
-
41
-/* extra bits required for distance codes 0 .. 29 */
42
-static const unsigned char dist_extrabits[30] = {
43
-  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
44
-  6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
45
-};
46
-
47
-/* the order of the bit length Huffman code lengths */
48
-static const unsigned char bitlen_order[19] = {
49
-  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
50
-};
51
-
52
-/* ANDing with bit_mask[n] masks the lower n bits */
53
-static const unsigned short bit_mask[17] = {
54
- 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
55
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
56
-};
57
-
58
-#define STORE_BITS do {                                                 \
59
-  zip->i_ptr      = i_ptr;                                              \
60
-  zip->i_end      = i_end;                                              \
61
-  zip->bit_buffer = bit_buffer;                                         \
62
-  zip->bits_left  = bits_left;                                          \
63
-} while (0)
64
-
65
-#define RESTORE_BITS do {                                               \
66
-  i_ptr      = zip->i_ptr;                                              \
67
-  i_end      = zip->i_end;                                              \
68
-  bit_buffer = zip->bit_buffer;                                         \
69
-  bits_left  = zip->bits_left;                                          \
70
-} while (0)
71
-
72
-#define ENSURE_BITS(nbits) do {                                         \
73
-  while (bits_left < (nbits)) {                                         \
74
-    if (i_ptr >= i_end) {                                               \
75
-      if (zipd_read_input(zip)) return zip->error;                      \
76
-      i_ptr = zip->i_ptr;                                               \
77
-      i_end = zip->i_end;                                               \
78
-    }                                                                   \
79
-    bit_buffer |= *i_ptr++ << bits_left; bits_left  += 8;               \
80
-  }                                                                     \
81
-} while (0)
82
-
83
-#define PEEK_BITS(nbits)   (bit_buffer & ((1<<(nbits))-1))
84
-#define PEEK_BITS_T(nbits) (bit_buffer & bit_mask[(nbits)])
85
-
86
-#define REMOVE_BITS(nbits) ((bit_buffer >>= (nbits)), (bits_left -= (nbits)))
87
-
88
-#define READ_BITS(val, nbits) do {                                      \
89
-  ENSURE_BITS(nbits); (val) = PEEK_BITS(nbits); REMOVE_BITS(nbits);     \
90
-} while (0)
91
-
92
-#define READ_BITS_T(val, nbits) do {                                    \
93
-  ENSURE_BITS(nbits); (val) = PEEK_BITS_T(nbits); REMOVE_BITS(nbits);   \
94
-} while (0)
95
-
96
-static int zipd_read_input(struct mszipd_stream *zip) {
97
-  int read = zip->sys->read(zip->input, &zip->inbuf[0], (int)zip->inbuf_size);
98
-  if (read < 0) return zip->error = MSPACK_ERR_READ;
99
-  zip->i_ptr = &zip->inbuf[0];
100
-  zip->i_end = &zip->inbuf[read];
101
-
102
-  return MSPACK_ERR_OK;
103
-}
104
-
105
-/* inflate() error codes */
106
-#define INF_ERR_BLOCKTYPE   (-1)  /* unknown block type                      */
107
-#define INF_ERR_COMPLEMENT  (-2)  /* block size complement mismatch          */
108
-#define INF_ERR_FLUSH       (-3)  /* error from flush_window() callback      */
109
-#define INF_ERR_BITBUF      (-4)  /* too many bits in bit buffer             */
110
-#define INF_ERR_SYMLENS     (-5)  /* too many symbols in blocktype 2 header  */
111
-#define INF_ERR_BITLENTBL   (-6)  /* failed to build bitlens huffman table   */
112
-#define INF_ERR_LITERALTBL  (-7)  /* failed to build literals huffman table  */
113
-#define INF_ERR_DISTANCETBL (-8)  /* failed to build distance huffman table  */
114
-#define INF_ERR_BITOVERRUN  (-9)  /* bitlen RLE code goes over table size    */
115
-#define INF_ERR_BADBITLEN   (-10) /* invalid bit-length code                 */
116
-#define INF_ERR_LITCODE     (-11) /* out-of-range literal code               */
117
-#define INF_ERR_DISTCODE    (-12) /* out-of-range distance code              */
118
-#define INF_ERR_DISTANCE    (-13) /* somehow, distance is beyond 32k         */
119
-#define INF_ERR_HUFFSYM     (-14) /* out of bits decoding huffman symbol     */
120
-
121
-/* make_decode_table(nsyms, nbits, length[], table[])
122
- *
123
- * This function was coded by David Tritscher. It builds a fast huffman
124
- * decoding table out of just a canonical huffman code lengths table.
125
- *
126
- * NOTE: this is NOT identical to the make_decode_table() in lzxd.c. This
127
- * one reverses the quick-lookup bit pattern. Bits are read MSB to LSB in LZX,
128
- * but LSB to MSB in MSZIP.
129
- *
130
- * nsyms  = total number of symbols in this huffman tree.
131
- * nbits  = any symbols with a code length of nbits or less can be decoded
132
- *          in one lookup of the table.
133
- * length = A table to get code lengths from [0 to nsyms-1]
134
- * table  = The table to fill up with decoded symbols and pointers.
135
- *
136
- * Returns 0 for OK or 1 for error
137
- */
138
-static int make_decode_table(unsigned int nsyms, unsigned int nbits,
139
-			     unsigned char *length, unsigned short *table)
140
-{
141
-  register unsigned int leaf, reverse, fill;
142
-  register unsigned short sym, next_sym;
143
-  register unsigned char bit_num;
144
-  unsigned int pos         = 0; /* the current position in the decode table */
145
-  unsigned int table_mask  = 1 << nbits;
146
-  unsigned int bit_mask    = table_mask >> 1; /* don't do 0 length codes */
147
-
148
-  /* fill entries for codes short enough for a direct mapping */
149
-  for (bit_num = 1; bit_num <= nbits; bit_num++) {
150
-    for (sym = 0; sym < nsyms; sym++) {
151
-      if (length[sym] != bit_num) continue;
152
-
153
-      /* reverse the significant bits */
154
-      fill = length[sym]; reverse = pos >> (nbits - fill); leaf = 0;
155
-      do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
156
-
157
-      if((pos += bit_mask) > table_mask) return 1; /* table overrun */
158
-
159
-      /* fill all possible lookups of this symbol with the symbol itself */
160
-      fill = bit_mask; next_sym = 1 << bit_num;
161
-      do { table[leaf] = sym; leaf += next_sym; } while (--fill);
162
-    }
163
-    bit_mask >>= 1;
164
-  }
165
-
166
-  /* exit with success if table is now complete */
167
-  if (pos == table_mask) return 0;
168
-
169
-  /* mark all remaining table entries as unused */
170
-  for (sym = pos; sym < table_mask; sym++) {
171
-    reverse = sym; leaf = 0; fill = nbits;
172
-    do { leaf <<= 1; leaf |= reverse & 1; reverse >>= 1; } while (--fill);
173
-    table[leaf] = 0xFFFF;
174
-  }
175
-
176
-  /* where should the longer codes be allocated from? */
177
-  next_sym = ((table_mask >> 1) < nsyms) ? nsyms : (table_mask >> 1);
178
-
179
-  /* give ourselves room for codes to grow by up to 16 more bits.
180
-   * codes now start at bit nbits+16 and end at (nbits+16-codelength) */
181
-  pos <<= 16;
182
-  table_mask <<= 16;
183
-  bit_mask = 1 << 15;
184
-
185
-  for (bit_num = nbits+1; bit_num <= MSZIP_MAX_HUFFBITS; bit_num++) {
186
-    for (sym = 0; sym < nsyms; sym++) {
187
-      if (length[sym] != bit_num) continue;
188
-
189
-      /* leaf = the first nbits of the code, reversed */
190
-      reverse = pos >> 16; leaf = 0; fill = nbits;
191
-      do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
192
-
193
-      for (fill = 0; fill < (bit_num - nbits); fill++) {
194
-	/* if this path hasn't been taken yet, 'allocate' two entries */
195
-	if (table[leaf] == 0xFFFF) {
196
-	  table[(next_sym << 1)     ] = 0xFFFF;
197
-	  table[(next_sym << 1) + 1 ] = 0xFFFF;
198
-	  table[leaf] = next_sym++;
199
-	}
200
-	/* follow the path and select either left or right for next bit */
201
-	leaf = (table[leaf] << 1) | ((pos >> (15 - fill)) & 1);
202
-      }
203
-      table[leaf] = sym;
204
-
205
-      if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
206
-    }
207
-    bit_mask >>= 1;
208
-  }
209
-
210
-  /* full table? */
211
-  return (pos != table_mask) ? 1 : 0;
212
-}
213
-
214
-/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
215
- * bitstream using the stated table and puts it in var.
216
- */
217
-#define READ_HUFFSYM(tbl, var) do {                                     \
218
-  /* huffman symbols can be up to 16 bits long */                       \
219
-  ENSURE_BITS(MSZIP_MAX_HUFFBITS);                                      \
220
-  /* immediate table lookup of [tablebits] bits of the code */          \
221
-  sym = zip->tbl##_table[PEEK_BITS(MSZIP_##tbl##_TABLEBITS)];		\
222
-  /* is the symbol is longer than [tablebits] bits? (i=node index) */   \
223
-  if (sym >= MSZIP_##tbl##_MAXSYMBOLS) {                                \
224
-    /* decode remaining bits by tree traversal */                       \
225
-    i = MSZIP_##tbl##_TABLEBITS - 1;					\
226
-    do {                                                                \
227
-      /* check next bit. error if we run out of bits before decode */	\
228
-      if (i++ > MSZIP_MAX_HUFFBITS) {					\
229
-        D(("out of bits in huffman decode"))                            \
230
-        return INF_ERR_HUFFSYM;                                         \
231
-      }                                                                 \
232
-      /* double node index and add 0 (left branch) or 1 (right) */	\
233
-      sym = zip->tbl##_table[(sym << 1) | ((bit_buffer >> i) & 1)];	\
234
-      /* while we are still in node indicies, not decoded symbols */    \
235
-    } while (sym >= MSZIP_##tbl##_MAXSYMBOLS);                          \
236
-  }                                                                     \
237
-  /* result */                                                          \
238
-  (var) = sym;                                                          \
239
-  /* look up the code length of that symbol and discard those bits */   \
240
-  i = zip->tbl##_len[sym];                                              \
241
-  REMOVE_BITS(i);                                                       \
242
-} while (0)
243
-
244
-static int zip_read_lens(struct mszipd_stream *zip) {
245
-  /* for the bit buffer and huffman decoding */
246
-  register unsigned int bit_buffer;
247
-  register int bits_left;
248
-  unsigned char *i_ptr, *i_end;
249
-
250
-  /* bitlen Huffman codes -- immediate lookup, 7 bit max code length */
251
-  unsigned short bl_table[(1 << 7)];
252
-  unsigned char bl_len[19];
253
-
254
-  unsigned char lens[MSZIP_LITERAL_MAXSYMBOLS + MSZIP_DISTANCE_MAXSYMBOLS];
255
-  unsigned int lit_codes, dist_codes, code, last_code=0, bitlen_codes, i, run;
256
-
257
-  RESTORE_BITS;
258
-
259
-  /* read the number of codes */
260
-  READ_BITS(lit_codes,    5); lit_codes    += 257;
261
-  READ_BITS(dist_codes,   5); dist_codes   += 1;
262
-  READ_BITS(bitlen_codes, 4); bitlen_codes += 4;
263
-  if (lit_codes  > MSZIP_LITERAL_MAXSYMBOLS)  return INF_ERR_SYMLENS;
264
-  if (dist_codes > MSZIP_DISTANCE_MAXSYMBOLS) return INF_ERR_SYMLENS;
265
-
266
-  /* read in the bit lengths in their unusual order */
267
-  for (i = 0; i < bitlen_codes; i++) READ_BITS(bl_len[bitlen_order[i]], 3);
268
-  while (i < 19) bl_len[bitlen_order[i++]] = 0;
269
-
270
-  /* create decoding table with an immediate lookup */
271
-  if (make_decode_table(19, 7, &bl_len[0], &bl_table[0])) {
272
-    return INF_ERR_BITLENTBL;
273
-  }
274
-
275
-  /* read literal / distance code lengths */
276
-  for (i = 0; i < (lit_codes + dist_codes); i++) {
277
-    /* single-level huffman lookup */
278
-    ENSURE_BITS(7);
279
-    code = bl_table[PEEK_BITS(7)];
280
-    REMOVE_BITS(bl_len[code]);
281
-
282
-    if (code < 16) lens[i] = last_code = code;
283
-    else {
284
-      switch (code) {
285
-      case 16: READ_BITS(run, 2); run += 3;  code = last_code; break;
286
-      case 17: READ_BITS(run, 3); run += 3;  code = 0;         break;
287
-      case 18: READ_BITS(run, 7); run += 11; code = 0;         break;
288
-      default: D(("bad code!: %u", code)) return INF_ERR_BADBITLEN;
289
-      }
290
-      if ((i + run) > (lit_codes + dist_codes)) return INF_ERR_BITOVERRUN;
291
-      while (run--) lens[i++] = code;
292
-      i--;
293
-    }
294
-  }
295
-
296
-  /* copy LITERAL code lengths and clear any remaining */
297
-  i = lit_codes;
298
-  zip->sys->copy(&lens[0], &zip->LITERAL_len[0], i);
299
-  while (i < MSZIP_LITERAL_MAXSYMBOLS) zip->LITERAL_len[i++] = 0;
300
-
301
-  i = dist_codes;
302
-  zip->sys->copy(&lens[lit_codes], &zip->DISTANCE_len[0], i);
303
-  while (i < MSZIP_DISTANCE_MAXSYMBOLS) zip->DISTANCE_len[i++] = 0;
304
-
305
-  STORE_BITS;
306
-  return 0;
307
-}
308
-
309
-/* a clean implementation of RFC 1951 / inflate */
310
-static int inflate(struct mszipd_stream *zip) {
311
-  unsigned int last_block, block_type, distance, length, this_run, i;
312
-
313
-  /* for the bit buffer and huffman decoding */
314
-  register unsigned int bit_buffer;
315
-  register int bits_left;
316
-  register unsigned short sym;
317
-  unsigned char *i_ptr, *i_end;
318
-
319
-  RESTORE_BITS;
320
-
321
-  do {
322
-    /* read in last block bit */
323
-    READ_BITS(last_block, 1);
324
-
325
-    /* read in block type */
326
-    READ_BITS(block_type, 2);
327
-    D(("block_type=%u last_block=%u", block_type, last_block))
328
-
329
-    if (block_type == 0) {
330
-      /* uncompressed block */
331
-      unsigned char lens_buf[4];
332
-
333
-      /* go to byte boundary */
334
-      i = bits_left & 7; REMOVE_BITS(i);
335
-
336
-      /* read 4 bytes of data, emptying the bit-buffer if necessary */
337
-      for (i = 0; (bits_left >= 8); i++) {
338
-	if (i == 4) return INF_ERR_BITBUF;
339
-	lens_buf[i] = PEEK_BITS(8);
340
-	REMOVE_BITS(8);
341
-      }
342
-      if (bits_left != 0) return INF_ERR_BITBUF;
343
-      while (i < 4) {
344
-	if (i_ptr >= i_end) {
345
-	  if (zipd_read_input(zip)) return zip->error;
346
-	  i_ptr = zip->i_ptr;
347
-	  i_end = zip->i_end;
348
-	}
349
-	lens_buf[i++] = *i_ptr++;
350
-      }
351
-
352
-      /* get the length and its complement */
353
-      length = lens_buf[0] | (lens_buf[1] << 8);
354
-      i      = lens_buf[2] | (lens_buf[3] << 8);
355
-      if (length != (~i & 0xFFFF)) return INF_ERR_COMPLEMENT;
356
-
357
-      /* read and copy the uncompressed data into the window */
358
-      while (length > 0) {
359
-	if (i_ptr >= i_end) {
360
-	  if (zipd_read_input(zip)) return zip->error;
361
-	  i_ptr = zip->i_ptr;
362
-	  i_end = zip->i_end;
363
-	}
364
-
365
-	this_run = length;
366
-	if (this_run > (unsigned int)(i_end - i_ptr)) this_run = i_end - i_ptr;
367
-	if (this_run > (MSZIP_FRAME_SIZE - zip->window_posn))
368
-	  this_run = MSZIP_FRAME_SIZE - zip->window_posn;
369
-
370
-	zip->sys->copy(i_ptr, &zip->window[zip->window_posn], this_run);
371
-	zip->window_posn += this_run;
372
-	i_ptr    += this_run;
373
-	length   -= this_run;
374
-
375
-	if (zip->window_posn == MSZIP_FRAME_SIZE) {
376
-	  if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) return INF_ERR_FLUSH;
377
-	  zip->window_posn = 0;
378
-	}
379
-      }
380
-    }
381
-    else if ((block_type == 1) || (block_type == 2)) {
382
-      /* Huffman-compressed LZ77 block */
383
-      unsigned int window_posn, match_posn, code;
384
-
385
-      if (block_type == 1) {
386
-	/* block with fixed Huffman codes */
387
-	i = 0;
388
-	while (i < 144) zip->LITERAL_len[i++] = 8;
389
-	while (i < 256) zip->LITERAL_len[i++] = 9;
390
-	while (i < 280) zip->LITERAL_len[i++] = 7;
391
-	while (i < 288) zip->LITERAL_len[i++] = 8;
392
-	for (i = 0; i < 32; i++) zip->DISTANCE_len[i] = 5;
393
-      }
394
-      else {
395
-	/* block with dynamic Huffman codes */
396
-	STORE_BITS;
397
-	if ((i = zip_read_lens(zip))) return i;
398
-	RESTORE_BITS;
399
-      }
400
-
401
-      /* now huffman lengths are read for either kind of block, 
402
-       * create huffman decoding tables */
403
-      if (make_decode_table(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS,
404
-			    &zip->LITERAL_len[0], &zip->LITERAL_table[0]))
405
-      {
406
-	return INF_ERR_LITERALTBL;
407
-      }
408
-
409
-      if (make_decode_table(MSZIP_DISTANCE_MAXSYMBOLS,MSZIP_DISTANCE_TABLEBITS,
410
-			    &zip->DISTANCE_len[0], &zip->DISTANCE_table[0]))
411
-      {
412
-	return INF_ERR_DISTANCETBL;
413
-      }
414
-
415
-      /* decode forever until end of block code */
416
-      window_posn = zip->window_posn;
417
-      while (1) {
418
-	READ_HUFFSYM(LITERAL, code);
419
-	if (code < 256) {
420
-	  zip->window[window_posn++] = (unsigned char) code;
421
-	  if (window_posn == MSZIP_FRAME_SIZE) {
422
-	    if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) return INF_ERR_FLUSH;
423
-	    window_posn = 0;
424
-	  }
425
-	}
426
-	else if (code == 256) {
427
-	  /* END OF BLOCK CODE: loop break point */
428
-	  break;
429
-	}
430
-	else {
431
-	  code -= 257;
432
-	  if (code > 29) return INF_ERR_LITCODE;
433
-	  READ_BITS_T(length, lit_extrabits[code]);
434
-	  length += lit_lengths[code];
435
-
436
-	  READ_HUFFSYM(DISTANCE, code);
437
-	  if (code > 30) return INF_ERR_DISTCODE;
438
-	  READ_BITS_T(distance, dist_extrabits[code]);
439
-	  distance += dist_offsets[code];
440
-
441
-	  /* match position is window position minus distance. If distance
442
-	   * is more than window position numerically, it must 'wrap
443
-	   * around' the frame size. */ 
444
-	  match_posn = ((distance > window_posn) ? MSZIP_FRAME_SIZE : 0)
445
-	    + window_posn - distance;
446
-
447
-	  /* copy match */
448
-	  if (length < 12) {
449
-	    /* short match, use slower loop but no loop setup code */
450
-	    while (length--) {
451
-	      zip->window[window_posn++] = zip->window[match_posn++];
452
-	      match_posn &= MSZIP_FRAME_SIZE - 1;
453
-
454
-	      if (window_posn == MSZIP_FRAME_SIZE) {
455
-		if (zip->flush_window(zip, MSZIP_FRAME_SIZE))
456
-		  return INF_ERR_FLUSH;
457
-		window_posn = 0;
458
-	      }
459
-	    }
460
-	  }
461
-	  else {
462
-	    /* longer match, use faster loop but with setup expense */
463
-	    unsigned char *runsrc, *rundest;
464
-	    do {
465
-	      this_run = length;
466
-	      if ((match_posn + this_run) > MSZIP_FRAME_SIZE)
467
-		this_run = MSZIP_FRAME_SIZE - match_posn;
468
-	      if ((window_posn + this_run) > MSZIP_FRAME_SIZE)
469
-		this_run = MSZIP_FRAME_SIZE - window_posn;
470
-
471
-	      rundest = &zip->window[window_posn]; window_posn += this_run;
472
-	      runsrc  = &zip->window[match_posn];  match_posn  += this_run;
473
-	      length -= this_run;
474
-	      while (this_run--) *rundest++ = *runsrc++;
475
-
476
-	      /* flush if necessary */
477
-	      if (window_posn == MSZIP_FRAME_SIZE) {
478
-		if (zip->flush_window(zip, MSZIP_FRAME_SIZE))
479
-		  return INF_ERR_FLUSH;
480
-		window_posn = 0;
481
-	      }
482
-	      if (match_posn == MSZIP_FRAME_SIZE) match_posn = 0;
483
-	    } while (length > 0);
484
-	  }
485
-
486
-	} /* else (code >= 257) */
487
-
488
-      } /* while (forever) -- break point at 'code == 256' */
489
-      zip->window_posn = window_posn;
490
-    }
491
-    else {
492
-      /* block_type == 3 -- bad block type */
493
-      return INF_ERR_BLOCKTYPE;
494
-    }
495
-  } while (!last_block);
496
-
497
-  /* flush the remaining data */
498
-  if (zip->window_posn) {
499
-    if (zip->flush_window(zip, zip->window_posn)) return INF_ERR_FLUSH;
500
-  }
501
-  STORE_BITS;
502
-
503
-  /* return success */
504
-  return 0;
505
-}
506
-
507
-/* inflate() calls this whenever the window should be flushed. As
508
- * MSZIP only expands to the size of the window, the implementation used
509
- * simply keeps track of the amount of data flushed, and if more than 32k
510
- * is flushed, an error is raised.
511
- */  
512
-static int mszipd_flush_window(struct mszipd_stream *zip,
513
-			       unsigned int data_flushed)
514
-{
515
-  zip->bytes_output += data_flushed;
516
-  if (zip->bytes_output > MSZIP_FRAME_SIZE) {
517
-    D(("overflow: %u bytes flushed, total is now %u",
518
-       data_flushed, zip->bytes_output))
519
-    return 1;
520
-  }
521
-  return 0;
522
-}
523
-
524
-struct mszipd_stream *mszipd_init(struct mspack_system *system,
525
-				  struct mspack_file *input,
526
-				  struct mspack_file *output,
527
-				  int input_buffer_size,
528
-				  int repair_mode)
529
-{
530
-  struct mszipd_stream *zip;
531
-
532
-  if (!system) return NULL;
533
-
534
-  input_buffer_size = (input_buffer_size + 1) & -2;
535
-  if (!input_buffer_size) return NULL;
536
-
537
-  /* allocate decompression state */
538
-  if (!(zip = system->alloc(system, sizeof(struct mszipd_stream)))) {
539
-    return NULL;
540
-  }
541
-
542
-  /* allocate input buffer */
543
-  zip->inbuf  = system->alloc(system, (size_t) input_buffer_size);
544
-  if (!zip->inbuf) {
545
-    system->free(zip);
546
-    return NULL;
547
-  }
548
-
549
-  /* initialise decompression state */
550
-  zip->sys             = system;
551
-  zip->input           = input;
552
-  zip->output          = output;
553
-  zip->inbuf_size      = input_buffer_size;
554
-  zip->error           = MSPACK_ERR_OK;
555
-  zip->repair_mode     = repair_mode;
556
-  zip->flush_window    = &mszipd_flush_window;
557
-
558
-  zip->i_ptr = zip->i_end = &zip->inbuf[0];
559
-  zip->o_ptr = zip->o_end = NULL;
560
-  zip->bit_buffer = 0; zip->bits_left = 0;
561
-  return zip;
562
-}
563
-
564
-int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) {
565
-  /* for the bit buffer */
566
-  register unsigned int bit_buffer;
567
-  register int bits_left;
568
-  unsigned char *i_ptr, *i_end;
569
-
570
-  int i, state, error;
571
-
572
-  /* easy answers */
573
-  if (!zip || (out_bytes < 0)) return MSPACK_ERR_ARGS;
574
-  if (zip->error) return zip->error;
575
-
576
-  /* flush out any stored-up bytes before we begin */
577
-  i = zip->o_end - zip->o_ptr;
578
-  if ((off_t) i > out_bytes) i = (int) out_bytes;
579
-  if (i) {
580
-    if (zip->sys->write(zip->output, zip->o_ptr, i) != i) {
581
-      return zip->error = MSPACK_ERR_WRITE;
582
-    }
583
-    zip->o_ptr  += i;
584
-    out_bytes   -= i;
585
-  }
586
-  if (out_bytes == 0) return MSPACK_ERR_OK;
587
-
588
-
589
-  while (out_bytes > 0) {
590
-    /* unpack another block */
591
-    RESTORE_BITS;
592
-
593
-    /* skip to next read 'CK' header */
594
-    i = bits_left & 7; REMOVE_BITS(i); /* align to bytestream */
595
-    state = 0;
596
-    do {
597
-      READ_BITS(i, 8);
598
-      if (i == 'C') state = 1;
599
-      else if ((state == 1) && (i == 'K')) state = 2;
600
-      else state = 0;
601
-    } while (state != 2);
602
-
603
-    /* inflate a block, repair and realign if necessary */
604
-    zip->window_posn = 0;
605
-    zip->bytes_output = 0;
606
-    STORE_BITS;
607
-    if ((error = inflate(zip))) {
608
-      D(("inflate error %d", i))
609
-      if (zip->repair_mode) {
610
-	zip->sys->message(NULL, "MSZIP error, %u bytes of data lost.",
611
-			  MSZIP_FRAME_SIZE - zip->bytes_output);
612
-	for (i = zip->bytes_output; i < MSZIP_FRAME_SIZE; i++) {
613
-	  zip->window[i] = '\0';
614
-	}
615
-	zip->bytes_output = MSZIP_FRAME_SIZE;
616
-      }
617
-      else {
618
-	return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH;
619
-      }
620
-    }
621
-    zip->o_ptr = &zip->window[0];
622
-    zip->o_end = &zip->o_ptr[zip->bytes_output];
623
-
624
-    /* write a frame */
625
-    i = (out_bytes < (off_t)zip->bytes_output) ?
626
-      (int)out_bytes : zip->bytes_output;
627
-    if (zip->sys->write(zip->output, zip->o_ptr, i) != i) {
628
-      return zip->error = MSPACK_ERR_WRITE;
629
-    }
630
-
631
-    /* mspack errors (i.e. read errors) are fatal and can't be recovered */
632
-    if ((error > 0) && zip->repair_mode) return error;
633
-
634
-    zip->o_ptr  += i;
635
-    out_bytes   -= i;
636
-  }
637
-
638
-  if (out_bytes) {
639
-    D(("bytes left to output"))
640
-    return zip->error = MSPACK_ERR_DECRUNCH;
641
-  }
642
-  return MSPACK_ERR_OK;
643
-}
644
-
645
-void mszipd_free(struct mszipd_stream *zip) {
646
-  struct mspack_system *sys;
647
-  if (zip) {
648
-    sys = zip->sys;
649
-    sys->free(zip->inbuf);
650
-    sys->free(zip);
651
-  }
652
-}
653 1
deleted file mode 100644
... ...
@@ -1,120 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * The Quantum method was created by David Stafford, adapted by Microsoft
5
- * Corporation.
6
- *
7
- * libmspack is free software; you can redistribute it and/or modify it under
8
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9
- *
10
- * For further details, see the file COPYING.LIB distributed with libmspack
11
- */
12
-
13
-#ifndef MSPACK_QTM_H
14
-#define MSPACK_QTM_H 1
15
-
16
-/* Quantum compression / decompression definitions */
17
-
18
-#define QTM_FRAME_SIZE (32768)
19
-
20
-struct qtmd_modelsym {
21
-  unsigned short sym, cumfreq;
22
-};
23
-
24
-struct qtmd_model {
25
-  int shiftsleft, entries;
26
-  struct qtmd_modelsym *syms;
27
-};
28
-
29
-struct qtmd_stream {
30
-  struct mspack_system *sys;      /* I/O routines                            */
31
-  struct mspack_file   *input;    /* input file handle                       */
32
-  struct mspack_file   *output;   /* output file handle                      */
33
-
34
-  unsigned char *window;          /* decoding window                         */
35
-  unsigned int window_size;       /* window size                             */
36
-  unsigned int window_posn;       /* decompression offset within window      */
37
-  unsigned int frame_start;       /* start of current frame within window    */
38
-
39
-  unsigned short H, L, C;         /* high/low/current: arith coding state    */
40
-  unsigned char header_read;      /* have we started decoding a new frame?   */
41
-
42
-  int error;
43
-
44
-  /* I/O buffers */
45
-  unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
46
-  unsigned int  bit_buffer, inbuf_size;
47
-  unsigned char bits_left;
48
-
49
-  /* four literal models, each representing 64 symbols
50
-   * model0 for literals from   0 to  63 (selector = 0)
51
-   * model1 for literals from  64 to 127 (selector = 1)
52
-   * model2 for literals from 128 to 191 (selector = 2)
53
-   * model3 for literals from 129 to 255 (selector = 3) */
54
-  struct qtmd_model model0, model1, model2, model3;
55
-
56
-  /* three match models.
57
-   * model4 for match with fixed length of 3 bytes
58
-   * model5 for match with fixed length of 4 bytes
59
-   * model6 for variable length match, encoded with model6len model */
60
-  struct qtmd_model model4, model5, model6, model6len;
61
-
62
-  /* selector model. 0-6 to say literal (0,1,2,3) or match (4,5,6) */
63
-  struct qtmd_model model7;
64
-
65
-  /* symbol arrays for all models */
66
-  struct qtmd_modelsym m0sym[64 + 1];
67
-  struct qtmd_modelsym m1sym[64 + 1];
68
-  struct qtmd_modelsym m2sym[64 + 1];
69
-  struct qtmd_modelsym m3sym[64 + 1];
70
-  struct qtmd_modelsym m4sym[24 + 1];
71
-  struct qtmd_modelsym m5sym[36 + 1];
72
-  struct qtmd_modelsym m6sym[42 + 1], m6lsym[27 + 1];
73
-  struct qtmd_modelsym m7sym[7 + 1];
74
-};
75
-
76
-/* allocates Quantum decompression state for decoding the given stream.
77
- *
78
- * - returns NULL if window_bits is outwith the range 10 to 21 (inclusive).
79
- *
80
- * - uses system->alloc() to allocate memory
81
- *
82
- * - returns NULL if not enough memory
83
- *
84
- * - window_bits is the size of the Quantum window, from 1Kb (10) to 2Mb (21).
85
- *
86
- * - input_buffer_size is the number of bytes to use to store bitstream data.
87
- */
88
-extern struct qtmd_stream *qtmd_init(struct mspack_system *system,
89
-				     struct mspack_file *input,
90
-				     struct mspack_file *output,
91
-				     int window_bits,
92
-				     int input_buffer_size);
93
-
94
-/* decompresses, or decompresses more of, a Quantum stream.
95
- *
96
- * - out_bytes of data will be decompressed and the function will return
97
- *   with an MSPACK_ERR_OK return code.
98
- *
99
- * - decompressing will stop as soon as out_bytes is reached. if the true
100
- *   amount of bytes decoded spills over that amount, they will be kept for
101
- *   a later invocation of qtmd_decompress().
102
- *
103
- * - the output bytes will be passed to the system->write() function given in
104
- *   qtmd_init(), using the output file handle given in qtmd_init(). More
105
- *   than one call may be made to system->write()
106
- *
107
- * - Quantum will read input bytes as necessary using the system->read()
108
- *   function given in qtmd_init(), using the input file handle given in
109
- *   qtmd_init(). This will continue until system->read() returns 0 bytes,
110
- *   or an error.
111
- */
112
-extern int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes);
113
-
114
-/* frees all state associated with a Quantum data stream
115
- *
116
- * - calls system->free() using the system pointer given in qtmd_init()
117
- */
118
-void qtmd_free(struct qtmd_stream *qtm);
119
-
120
-#endif
121 1
deleted file mode 100644
... ...
@@ -1,488 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * The Quantum method was created by David Stafford, adapted by Microsoft
5
- * Corporation.
6
- *
7
- * This decompressor is based on an implementation by Matthew Russotto, used
8
- * with permission.
9
- *
10
- * libmspack is free software; you can redistribute it and/or modify it under
11
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
12
- *
13
- * For further details, see the file COPYING.LIB distributed with libmspack
14
- */
15
-
16
-/* Quantum decompression implementation */
17
-
18
-/* This decompressor was researched and implemented by Matthew Russotto. It
19
- * has since been tidied up by Stuart Caie. More information can be found at
20
- * http://www.speakeasy.org/~russotto/quantumcomp.html
21
- */
22
-
23
-#if HAVE_CONFIG_H
24
-#include "clamav-config.h"
25
-#endif
26
-
27
-#include <mspack.h>
28
-#include <system.h>
29
-#include <qtm.h>
30
-
31
-/* Quantum decompressor bitstream reading macros
32
- *
33
- * STORE_BITS        stores bitstream state in qtmd_stream structure
34
- * RESTORE_BITS      restores bitstream state from qtmd_stream structure
35
- * READ_BITS(var,n)  takes N bits from the buffer and puts them in var
36
- * FILL_BUFFER       if there is room for another 16 bits, reads another
37
- *                   16 bits from the input stream.
38
- * PEEK_BITS(n)      extracts without removing N bits from the bit buffer
39
- * REMOVE_BITS(n)    removes N bits from the bit buffer
40
- *
41
- * These bit access routines work by using the area beyond the MSB and the
42
- * LSB as a free source of zeroes. This avoids having to mask any bits.
43
- * So we have to know the bit width of the bitbuffer variable.
44
- */
45
-
46
-#ifdef HAVE_LIMITS_H
47
-# include <limits.h>
48
-#endif
49
-#ifndef CHAR_BIT
50
-# define CHAR_BIT (8)
51
-#endif
52
-#define BITBUF_WIDTH (sizeof(unsigned int) * CHAR_BIT)
53
-
54
-#define STORE_BITS do {                                                 \
55
-  qtm->i_ptr      = i_ptr;                                              \
56
-  qtm->i_end      = i_end;                                              \
57
-  qtm->bit_buffer = bit_buffer;                                         \
58
-  qtm->bits_left  = bits_left;                                          \
59
-} while (0)
60
-
61
-#define RESTORE_BITS do {                                               \
62
-  i_ptr      = qtm->i_ptr;                                              \
63
-  i_end      = qtm->i_end;                                              \
64
-  bit_buffer = qtm->bit_buffer;                                         \
65
-  bits_left  = qtm->bits_left;                                          \
66
-} while (0)
67
-
68
-/* adds 16 bits to bit buffer, if there's space for the new bits */
69
-#define FILL_BUFFER do {                                                \
70
-  if (bits_left <= (BITBUF_WIDTH - 16)) {                               \
71
-    if (i_ptr >= i_end) {                                               \
72
-      if (qtmd_read_input(qtm)) return qtm->error;                      \
73
-      i_ptr = qtm->i_ptr;                                               \
74
-      i_end = qtm->i_end;                                               \
75
-    }                                                                   \
76
-    bit_buffer |= ((i_ptr[0] << 8) | i_ptr[1])                          \
77
-                  << (BITBUF_WIDTH - 16 - bits_left);                   \
78
-    bits_left  += 16;                                                   \
79
-    i_ptr      += 2;                                                    \
80
-  }                                                                     \
81
-} while (0)
82
-
83
-#define PEEK_BITS(n)   (bit_buffer >> (BITBUF_WIDTH - (n)))
84
-#define REMOVE_BITS(n) ((bit_buffer <<= (n)), (bits_left -= (n)))
85
-
86
-#define READ_BITS(val, bits) do {                                       \
87
-  (val) = 0;                                                            \
88
-  for (bits_needed = (bits); bits_needed > 0; bits_needed -= bit_run) { \
89
-    FILL_BUFFER;                                                        \
90
-    bit_run = (bits_left < bits_needed) ? bits_left : bits_needed;      \
91
-    (val) = ((val) << bit_run) | PEEK_BITS(bit_run);                    \
92
-    REMOVE_BITS(bit_run);                                               \
93
-  }                                                                     \
94
-} while (0)
95
-
96
-static int qtmd_read_input(struct qtmd_stream *qtm) {
97
-  int read = qtm->sys->read(qtm->input, &qtm->inbuf[0], (int)qtm->inbuf_size);
98
-  if (read < 0) return qtm->error = MSPACK_ERR_READ;
99
-
100
-  qtm->i_ptr = &qtm->inbuf[0];
101
-  qtm->i_end = &qtm->inbuf[read];
102
-  return MSPACK_ERR_OK;
103
-}
104
-
105
-/* Quantum static data tables:
106
- *
107
- * Quantum uses 'position slots' to represent match offsets.  For every
108
- * match, a small 'position slot' number and a small offset from that slot
109
- * are encoded instead of one large offset.
110
- *
111
- * position_base[] is an index to the position slot bases
112
- *
113
- * extra_bits[] states how many bits of offset-from-base data is needed.
114
- *
115
- * length_base[] and length_extra[] are equivalent in function, but are
116
- * used for encoding selector 6 (variable length match) match lengths,
117
- * instead of match offsets.
118
- */
119
-static unsigned int  position_base[42];
120
-static unsigned char extra_bits[42], length_base[27], length_extra[27];
121
-
122
-static void qtmd_static_init() {
123
-  unsigned int i, offset;
124
-
125
-  for (i = 0, offset = 0; i < 42; i++) {
126
-    position_base[i] = offset;
127
-    extra_bits[i] = ((i < 2) ? 0 : (i - 2)) >> 1;
128
-    offset += 1 << extra_bits[i];
129
-  }
130
-
131
-  for (i = 0, offset = 0; i < 26; i++) {
132
-    length_base[i] = offset;
133
-    length_extra[i] = (i < 2 ? 0 : i - 2) >> 2;
134
-    offset += 1 << length_extra[i];
135
-  }
136
-  length_base[26] = 254; length_extra[26] = 0;
137
-}
138
-
139
-
140
-/* Arithmetic decoder:
141
- * 
142
- * GET_SYMBOL(model, var) fetches the next symbol from the stated model
143
- * and puts it in var.
144
- *
145
- * If necessary, qtmd_update_model() is called.
146
- */
147
-#define GET_SYMBOL(model, var) do {                                     \
148
-  range = ((H - L) & 0xFFFF) + 1;                                       \
149
-  symf = ((((C - L + 1) * model.syms[0].cumfreq)-1) / range) & 0xFFFF;  \
150
-                                                                        \
151
-  for (i = 1; i < model.entries; i++) {                                 \
152
-    if (model.syms[i].cumfreq <= symf) break;                           \
153
-  }                                                                     \
154
-  (var) = model.syms[i-1].sym;                                          \
155
-                                                                        \
156
-  range = (H - L) + 1;                                                  \
157
-  symf = model.syms[0].cumfreq;                                         \
158
-  H = L + ((model.syms[i-1].cumfreq * range) / symf) - 1;               \
159
-  L = L + ((model.syms[i].cumfreq   * range) / symf);                   \
160
-                                                                        \
161
-  do { model.syms[--i].cumfreq += 8; } while (i > 0);                   \
162
-  if (model.syms[0].cumfreq > 3800) qtmd_update_model(&model);          \
163
-                                                                        \
164
-  while (1) {                                                           \
165
-    if ((L & 0x8000) != (H & 0x8000)) {                                 \
166
-      if ((L & 0x4000) && !(H & 0x4000)) {                              \
167
-        /* underflow case */                                            \
168
-        C ^= 0x4000; L &= 0x3FFF; H |= 0x4000;                          \
169
-      }                                                                 \
170
-      else break;                                                       \
171
-    }                                                                   \
172
-    L <<= 1; H = (H << 1) | 1;                                          \
173
-    FILL_BUFFER;                                                        \
174
-    C  = (C << 1) | PEEK_BITS(1);                                       \
175
-    REMOVE_BITS(1);                                                     \
176
-  }                                                                     \
177
-} while (0)
178
-
179
-static void qtmd_update_model(struct qtmd_model *model) {
180
-  struct qtmd_modelsym tmp;
181
-  int i, j;
182
-
183
-  if (--model->shiftsleft) {
184
-    for (i = model->entries - 1; i >= 0; i--) {
185
-      /* -1, not -2; the 0 entry saves this */
186
-      model->syms[i].cumfreq >>= 1;
187
-      if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
188
-	model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
189
-      }
190
-    }
191
-  }
192
-  else {
193
-    model->shiftsleft = 50;
194
-    for (i = 0; i < model->entries; i++) {
195
-      /* no -1, want to include the 0 entry */
196
-      /* this converts cumfreqs into frequencies, then shifts right */
197
-      model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
198
-      model->syms[i].cumfreq++; /* avoid losing things entirely */
199
-      model->syms[i].cumfreq >>= 1;
200
-    }
201
-
202
-    /* now sort by frequencies, decreasing order -- this must be an
203
-     * inplace selection sort, or a sort with the same (in)stability
204
-     * characteristics */
205
-    for (i = 0; i < model->entries - 1; i++) {
206
-      for (j = i + 1; j < model->entries; j++) {
207
-	if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
208
-	  tmp = model->syms[i];
209
-	  model->syms[i] = model->syms[j];
210
-	  model->syms[j] = tmp;
211
-	}
212
-      }
213
-    }
214
-
215
-    /* then convert frequencies back to cumfreq */
216
-    for (i = model->entries - 1; i >= 0; i--) {
217
-      model->syms[i].cumfreq += model->syms[i+1].cumfreq;
218
-    }
219
-  }
220
-}
221
-
222
-/* Initialises a model to decode symbols from [start] to [start]+[len]-1 */
223
-static void qtmd_init_model(struct qtmd_model *model,
224
-			    struct qtmd_modelsym *syms, int start, int len)
225
-{
226
-  int i;
227
-
228
-  model->shiftsleft = 4;
229
-  model->entries    = len;
230
-  model->syms       = syms;
231
-
232
-  for (i = 0; i <= len; i++) {
233
-    syms[i].sym     = start + i; /* actual symbol */
234
-    syms[i].cumfreq = len - i;   /* current frequency of that symbol */
235
-  }
236
-}
237
-
238
-
239
-/*-------- main Quantum code --------*/
240
-
241
-struct qtmd_stream *qtmd_init(struct mspack_system *system,
242
-			      struct mspack_file *input,
243
-			      struct mspack_file *output,
244
-			      int window_bits, int input_buffer_size)
245
-{
246
-  unsigned int window_size = 1 << window_bits;
247
-  struct qtmd_stream *qtm;
248
-  int i;
249
-
250
-  if (!system) return NULL;
251
-
252
-  /* Quantum supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
253
-  if (window_bits < 10 || window_bits > 21) return NULL;
254
-
255
-  input_buffer_size = (input_buffer_size + 1) & -2;
256
-  if (input_buffer_size < 2) return NULL;
257
-
258
-  /* initialise static data */
259
-  qtmd_static_init();
260
-
261
-  /* allocate decompression state */
262
-  if (!(qtm = system->alloc(system, sizeof(struct qtmd_stream)))) {
263
-    return NULL;
264
-  }
265
-
266
-  /* allocate decompression window and input buffer */
267
-  qtm->window = system->alloc(system, (size_t) window_size);
268
-  qtm->inbuf  = system->alloc(system, (size_t) input_buffer_size);
269
-  if (!qtm->window || !qtm->inbuf) {
270
-    system->free(qtm->window);
271
-    system->free(qtm->inbuf);
272
-    system->free(qtm);
273
-    return NULL;
274
-  }
275
-
276
-  /* initialise decompression state */
277
-  qtm->sys         = system;
278
-  qtm->input       = input;
279
-  qtm->output      = output;
280
-  qtm->inbuf_size  = input_buffer_size;
281
-  qtm->window_size = window_size;
282
-  qtm->window_posn = 0;
283
-  qtm->frame_start = 0;
284
-  qtm->header_read = 0;
285
-  qtm->error       = MSPACK_ERR_OK;
286
-
287
-  qtm->i_ptr = qtm->i_end = &qtm->inbuf[0];
288
-  qtm->o_ptr = qtm->o_end = &qtm->window[0];
289
-  qtm->bits_left = 0;
290
-  qtm->bit_buffer = 0;
291
-
292
-  /* initialise arithmetic coding models
293
-   * - model 4    depends on window size, ranges from 20 to 24
294
-   * - model 5    depends on window size, ranges from 20 to 36
295
-   * - model 6pos depends on window size, ranges from 20 to 42
296
-   */
297
-  i = window_bits * 2;
298
-  qtmd_init_model(&qtm->model0,    &qtm->m0sym[0],   0, 64);
299
-  qtmd_init_model(&qtm->model1,    &qtm->m1sym[0],  64, 64);
300
-  qtmd_init_model(&qtm->model2,    &qtm->m2sym[0], 128, 64);
301
-  qtmd_init_model(&qtm->model3,    &qtm->m3sym[0], 192, 64);
302
-  qtmd_init_model(&qtm->model4,    &qtm->m4sym[0],   0, (i > 24) ? 24 : i);
303
-  qtmd_init_model(&qtm->model5,    &qtm->m5sym[0],   0, (i > 36) ? 36 : i);
304
-  qtmd_init_model(&qtm->model6,    &qtm->m6sym[0],   0, i);
305
-  qtmd_init_model(&qtm->model6len, &qtm->m6lsym[0],  0, 27);
306
-  qtmd_init_model(&qtm->model7,    &qtm->m7sym[0],   0, 7);
307
-
308
-  /* all ok */
309
-  return qtm;
310
-}
311
-
312
-int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
313
-  unsigned int frame_start, frame_end, window_posn, match_offset, range;
314
-  unsigned char *window, *i_ptr, *i_end, *runsrc, *rundest;
315
-  int i, j, selector, extra, sym, match_length;
316
-  unsigned short H, L, C, symf;
317
-
318
-  register unsigned int bit_buffer;
319
-  register unsigned char bits_left;
320
-  unsigned char bits_needed, bit_run;
321
-
322
-  /* easy answers */
323
-  if (!qtm || (out_bytes < 0)) return MSPACK_ERR_ARGS;
324
-  if (qtm->error) return qtm->error;
325
-
326
-  /* flush out any stored-up bytes before we begin */
327
-  i = qtm->o_end - qtm->o_ptr;
328
-  if ((off_t) i > out_bytes) i = (int) out_bytes;
329
-  if (i) {
330
-    if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
331
-      return qtm->error = MSPACK_ERR_WRITE;
332
-    }
333
-    qtm->o_ptr  += i;
334
-    out_bytes   -= i;
335
-  }
336
-  if (out_bytes == 0) return MSPACK_ERR_OK;
337
-
338
-  /* restore local state */
339
-  RESTORE_BITS;
340
-  window = qtm->window;
341
-  window_posn = qtm->window_posn;
342
-  frame_start = qtm->frame_start;
343
-  H = qtm->H;
344
-  L = qtm->L;
345
-  C = qtm->C;
346
-
347
-  /* while we do not have enough decoded bytes in reserve: */
348
-  while ((qtm->o_end - qtm->o_ptr) < out_bytes) {
349
-
350
-    /* read header if necessary. Initialises H, L and C */
351
-    if (!qtm->header_read) {
352
-      H = 0xFFFF; L = 0; READ_BITS(C, 16);
353
-      qtm->header_read = 1;
354
-    }
355
-
356
-    /* decode more, at most up to to frame boundary */
357
-    frame_end = window_posn + (out_bytes - (qtm->o_end - qtm->o_ptr));
358
-    if ((frame_start + QTM_FRAME_SIZE) < frame_end) {
359
-      frame_end = frame_start + QTM_FRAME_SIZE;
360
-    }
361
-
362
-    while (window_posn < frame_end) {
363
-      GET_SYMBOL(qtm->model7, selector);
364
-      if (selector < 4) {
365
-	struct qtmd_model *mdl = (selector == 0) ? &qtm->model0 :
366
-	                        ((selector == 1) ? &qtm->model1 :
367
-				((selector == 2) ? &qtm->model2 :
368
-                                                   &qtm->model3));
369
-	GET_SYMBOL((*mdl), sym);
370
-	window[window_posn++] = sym;
371
-      }
372
-      else {
373
-	switch (selector) {
374
-	case 4: /* selector 4 = fixed length match (3 bytes) */
375
-	  GET_SYMBOL(qtm->model4, sym);
376
-	  READ_BITS(extra, extra_bits[sym]);
377
-	  match_offset = position_base[sym] + extra + 1;
378
-	  match_length = 3;
379
-	  break;
380
-
381
-	case 5: /* selector 5 = fixed length match (4 bytes) */
382
-	  GET_SYMBOL(qtm->model5, sym);
383
-	  READ_BITS(extra, extra_bits[sym]);
384
-	  match_offset = position_base[sym] + extra + 1;
385
-	  match_length = 4;
386
-	  break;
387
-
388
-	case 6: /* selector 6 = variable length match */
389
-	  GET_SYMBOL(qtm->model6len, sym);
390
-	  READ_BITS(extra, length_extra[sym]);
391
-	  match_length = length_base[sym] + extra + 5;
392
-
393
-	  GET_SYMBOL(qtm->model6, sym);
394
-	  READ_BITS(extra, extra_bits[sym]);
395
-	  match_offset = position_base[sym] + extra + 1;
396
-	  break;
397
-
398
-	default:
399
-	  /* should be impossible, model7 can only return 0-6 */
400
-	  return qtm->error = MSPACK_ERR_DECRUNCH;
401
-	}
402
-
403
-	rundest = &window[window_posn];
404
-	i = match_length;
405
-	/* does match offset wrap the window? */
406
-	if (match_offset > window_posn) {
407
-	  /* j = length from match offset to end of window */
408
-	  j = match_offset - window_posn;
409
-	  if (j > (int) qtm->window_size) {
410
-	    D(("match offset beyond window boundaries"))
411
-	    return qtm->error = MSPACK_ERR_DECRUNCH;
412
-	  }
413
-	  runsrc = &window[qtm->window_size - j];
414
-	  if (j < i) {
415
-	    /* if match goes over the window edge, do two copy runs */
416
-	    i -= j; while (j-- > 0) *rundest++ = *runsrc++;
417
-	    runsrc = window;
418
-	  }
419
-	  while (i-- > 0) *rundest++ = *runsrc++;
420
-	}
421
-	else {
422
-	  runsrc = rundest - match_offset;
423
-	  while (i-- > 0) *rundest++ = *runsrc++;
424
-	}
425
-	window_posn += match_length;
426
-      }
427
-    } /* while (window_posn < frame_end) */
428
-
429
-    qtm->o_end = &window[window_posn];
430
-
431
-    /* another frame completed? */
432
-    if ((window_posn - frame_start) >= QTM_FRAME_SIZE) {
433
-      if ((window_posn - frame_start) != QTM_FRAME_SIZE) {
434
-	D(("overshot frame alignment"))
435
-	return qtm->error = MSPACK_ERR_DECRUNCH;
436
-      }
437
-
438
-      /* re-align input */
439
-      if (bits_left & 7) REMOVE_BITS(bits_left & 7);
440
-      do { READ_BITS(i, 8); } while (i != 0xFF);
441
-      qtm->header_read = 0;
442
-
443
-      /* window wrap? */
444
-      if (window_posn == qtm->window_size) {
445
-	/* flush all currently stored data */
446
-	i = (qtm->o_end - qtm->o_ptr);
447
-	if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
448
-	  return qtm->error = MSPACK_ERR_WRITE;
449
-	}
450
-	out_bytes -= i;
451
-	qtm->o_ptr = &window[0];
452
-	qtm->o_end = &window[0];
453
-	window_posn = 0;
454
-      }
455
-
456
-      frame_start = window_posn;
457
-    }
458
-
459
-  } /* while (more bytes needed) */
460
-
461
-  if (out_bytes) {
462
-    i = (int) out_bytes;
463
-    if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
464
-      return qtm->error = MSPACK_ERR_WRITE;
465
-    }
466
-    qtm->o_ptr += i;
467
-  }
468
-
469
-  /* store local state */
470
-  STORE_BITS;
471
-  qtm->window_posn = window_posn;
472
-  qtm->frame_start = frame_start;
473
-  qtm->H = H;
474
-  qtm->L = L;
475
-  qtm->C = C;
476
-
477
-  return MSPACK_ERR_OK;
478
-}
479
-
480
-void qtmd_free(struct qtmd_stream *qtm) {
481
-  struct mspack_system *sys;
482
-  if (qtm) {
483
-    sys = qtm->sys;
484
-    sys->free(qtm->window);
485
-    sys->free(qtm->inbuf);
486
-    sys->free(qtm);
487
-  }
488
-}
489 1
deleted file mode 100644
... ...
@@ -1,251 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * libmspack is free software; you can redistribute it and/or modify it under
5
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6
- *
7
- * For further details, see the file COPYING.LIB distributed with libmspack
8
- */
9
-
10
-#if HAVE_CONFIG_H
11
-#include "clamav-config.h"
12
-#endif
13
-
14
-#include <mspack.h>
15
-#include "others.h"
16
-
17
-int mspack_version(int entity) {
18
-  switch (entity) {
19
-  case MSPACK_VER_LIBRARY:
20
-  case MSPACK_VER_SYSTEM:
21
-  case MSPACK_VER_MSCABD:
22
-  case MSPACK_VER_MSCHMD:
23
-    return 1;
24
-  case MSPACK_VER_MSCABC:
25
-  case MSPACK_VER_MSCHMC:
26
-  case MSPACK_VER_MSLITD:
27
-  case MSPACK_VER_MSLITC:
28
-  case MSPACK_VER_MSHLPD:
29
-  case MSPACK_VER_MSHLPC:
30
-  case MSPACK_VER_MSSZDDD:
31
-  case MSPACK_VER_MSSZDDC:
32
-  case MSPACK_VER_MSKWAJD:
33
-  case MSPACK_VER_MSKWAJC:
34
-    return 0;
35
-  }
36
-  return -1;
37
-}
38
-
39
-int mspack_sys_selftest_internal(int offt_size) {
40
-  return (sizeof(off_t) == offt_size) ? MSPACK_ERR_OK : MSPACK_ERR_SEEK;
41
-}
42
-
43
-/* validates a system structure */
44
-int mspack_valid_system(struct mspack_system *sys) {
45
-  return (sys != NULL) && (sys->open != NULL) && (sys->close != NULL) &&
46
-    (sys->read != NULL) && (sys->write != NULL) && (sys->seek != NULL) &&
47
-    (sys->tell != NULL) && (sys->message != NULL) && (sys->alloc != NULL) &&
48
-    (sys->free != NULL) && (sys->copy != NULL) && (sys->null_ptr == NULL);
49
-}
50
-
51
-/* returns the length of a file opened for reading */
52
-int mspack_sys_filelen(struct mspack_system *system,
53
-		       struct mspack_file *file, off_t *length)
54
-{
55
-  off_t current;
56
-
57
-  if (!system || !file || !length) return MSPACK_ERR_OPEN;
58
-
59
-  /* get current offset */
60
-  current = system->tell(file);
61
-
62
-  /* seek to end of file */
63
-  if (system->seek(file, (off_t) 0, MSPACK_SYS_SEEK_END)) {
64
-    return MSPACK_ERR_SEEK;
65
-  }
66
-
67
-  /* get offset of end of file */
68
-  *length = system->tell(file);
69
-
70
-  /* seek back to original offset */
71
-  if (system->seek(file, current, MSPACK_SYS_SEEK_START)) {
72
-    return MSPACK_ERR_SEEK;
73
-  }
74
-
75
-  return MSPACK_ERR_OK;
76
-}
77
-
78
-
79
-
80
-/* definition of mspack_default_system -- if the library is compiled with
81
- * MSPACK_NO_DEFAULT_SYSTEM, no default system will be provided. Otherwise,
82
- * an appropriate default system (e.g. the standard C library, or some native
83
- * API calls)
84
- */
85
-
86
-#ifdef MSPACK_NO_DEFAULT_SYSTEM
87
-struct mspack_system *mspack_default_system = NULL;
88
-#else
89
-
90
-/* implementation of mspack_default_system for standard C library */
91
-
92
-#include <stdio.h>
93
-#include <stdlib.h>
94
-#include <string.h>
95
-#include <stdarg.h>
96
-
97
-struct mspack_file_p {
98
-  FILE *fh;
99
-  char *name;
100
-  int desc;
101
-};
102
-
103
-static struct mspack_file *msp_open(struct mspack_system *this,
104
-				    char *filename, int mode)
105
-{
106
-  struct mspack_file_p *fh;
107
-  char *fmode;
108
-
109
-  switch (mode) {
110
-  case MSPACK_SYS_OPEN_READ:   fmode = "rb";  break;
111
-  case MSPACK_SYS_OPEN_WRITE:  fmode = "wb";  break;
112
-  case MSPACK_SYS_OPEN_UPDATE: fmode = "r+b"; break;
113
-  case MSPACK_SYS_OPEN_APPEND: fmode = "ab";  break;
114
-  default: return NULL;
115
-  }
116
-
117
-  if ((fh = malloc(sizeof(struct mspack_file_p)))) {
118
-    fh->name = filename;
119
-    fh->desc = 0;
120
-    if ((fh->fh = fopen(filename, fmode))) return (struct mspack_file *) fh;
121
-    free(fh);
122
-  }
123
-  return NULL;
124
-}
125
-
126
-static struct mspack_file *msp_dopen(struct mspack_system *this,
127
-				    int desc, int mode)
128
-{
129
-  struct mspack_file_p *fh;
130
-  char *fmode;
131
-
132
-  switch (mode) {
133
-  case MSPACK_SYS_OPEN_READ:   fmode = "rb";  break;
134
-  case MSPACK_SYS_OPEN_WRITE:  fmode = "wb";  break;
135
-  case MSPACK_SYS_OPEN_UPDATE: fmode = "r+b"; break;
136
-  case MSPACK_SYS_OPEN_APPEND: fmode = "ab";  break;
137
-  default: return NULL;
138
-  }
139
-
140
-  if ((fh = malloc(sizeof(struct mspack_file_p)))) {
141
-    fh->name = "descriptor";
142
-    fh->desc = desc;
143
-    if ((fh->fh = fdopen(desc, fmode))) return (struct mspack_file *) fh;
144
-    free(fh);
145
-  }
146
-  return NULL;
147
-}
148
-
149
-static void msp_close(struct mspack_file *file) {
150
-  struct mspack_file_p *this = (struct mspack_file_p *) file;
151
-  if (this) {
152
-    fclose(this->fh);
153
-    free(this);
154
-  }
155
-}
156
-
157
-static int msp_read(struct mspack_file *file, void *buffer, int bytes) {
158
-  struct mspack_file_p *this = (struct mspack_file_p *) file;
159
-  if (this) {
160
-    size_t count = fread(buffer, 1, (size_t) bytes, this->fh);
161
-    if (!ferror(this->fh)) return (int) count;
162
-  }
163
-  return -1;
164
-}
165
-
166
-static int msp_write(struct mspack_file *file, void *buffer, int bytes) {
167
-  struct mspack_file_p *this = (struct mspack_file_p *) file;
168
-  if (this) {
169
-    size_t count = fwrite(buffer, 1, (size_t) bytes, this->fh);
170
-    if (!ferror(this->fh)) return (int) count;
171
-  }
172
-  return -1;
173
-}
174
-
175
-static int msp_seek(struct mspack_file *file, off_t offset, int mode) {
176
-  struct mspack_file_p *this = (struct mspack_file_p *) file;
177
-  if (this) {
178
-    switch (mode) {
179
-    case MSPACK_SYS_SEEK_START: mode = SEEK_SET; break;
180
-    case MSPACK_SYS_SEEK_CUR:   mode = SEEK_CUR; break;
181
-    case MSPACK_SYS_SEEK_END:   mode = SEEK_END; break;
182
-    default: return -1;
183
-    }
184
-#ifdef HAVE_FSEEKO
185
-    return fseeko(this->fh, offset, mode);
186
-#else
187
-    return fseek(this->fh, offset, mode);
188
-#endif
189
-  }
190
-  return -1;
191
-}
192
-
193
-static off_t msp_tell(struct mspack_file *file) {
194
-  struct mspack_file_p *this = (struct mspack_file_p *) file;
195
-#ifdef HAVE_FSEEKO
196
-  return (this) ? (off_t) ftello(this->fh) : 0;
197
-#else
198
-  return (this) ? (off_t) ftell(this->fh) : 0;
199
-#endif
200
-}
201
-
202
-static void msp_msg(struct mspack_file *file, char *format, ...) {
203
-  va_list ap;
204
-  char buff[512];
205
-
206
-  va_start(ap, format);
207
-  vsnprintf(buff, 512, format, ap);
208
-  va_end(ap);
209
-  cli_dbgmsg("libmspack: %s\n", buff);
210
-}
211
-
212
-static void *msp_alloc(struct mspack_system *this, size_t bytes) {
213
-#ifdef DEBUG
214
-  /* make uninitialised data obvious */
215
-  char *buf = malloc(bytes + 8);
216
-  if (buf) memset(buf, 0xDC, bytes);
217
-  *((size_t *)buf) = bytes;
218
-  return &buf[8];
219
-#else
220
-  return malloc(bytes);
221
-#endif
222
-}
223
-
224
-static void msp_free(void *buffer) {
225
-#ifdef DEBUG
226
-  char *buf = buffer;
227
-  size_t bytes;
228
-  if (buf) {
229
-    buf -= 8;
230
-    bytes = *((size_t *)buf);
231
-    /* make freed data obvious */
232
-    memset(buf, 0xED, bytes);
233
-    free(buf);
234
-  }
235
-#else
236
-  free(buffer);
237
-#endif
238
-}
239
-
240
-static void msp_copy(void *src, void *dest, size_t bytes) {
241
-  memcpy(dest, src, bytes);
242
-}
243
-
244
-static struct mspack_system msp_system = {
245
-  &msp_open, &msp_dopen, &msp_close, &msp_read,  &msp_write, &msp_seek,
246
-  &msp_tell, &msp_msg, &msp_alloc, &msp_free, &msp_copy, NULL
247
-};
248
-
249
-struct mspack_system *mspack_default_system = &msp_system;
250
-
251
-#endif
252 1
deleted file mode 100644
... ...
@@ -1,58 +0,0 @@
1
-/* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
3
- *
4
- * libmspack is free software; you can redistribute it and/or modify it under
5
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6
- *
7
- * For further details, see the file COPYING.LIB distributed with libmspack
8
- */
9
-
10
-#ifndef MSPACK_SYSTEM_H
11
-#define MSPACK_SYSTEM_H 1
12
-
13
-#ifdef DEBUG
14
-# include <stdio.h>
15
-# define D(x) do { printf("%s:%d (%s) ",__FILE__, __LINE__, __FUNCTION__); \
16
-                   printf x ; fputc('\n', stdout); fflush(stdout);} while (0);
17
-#else
18
-# define D(x)
19
-#endif
20
-
21
-/* endian-neutral reading of little-endian data */
22
-#define __egi32(a,n) ( (((a)[n+3]) << 24) | (((a)[n+2]) << 16) | \
23
-		       (((a)[n+1]) <<  8) |  ((a)[n+0])        )
24
-#define EndGetI64(a) ((((unsigned long long int) __egi32(a,4)) << 32) | \
25
-		      ((unsigned int) __egi32(a,0)))
26
-#define EndGetI32(a) __egi32(a,0)
27
-#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
28
-
29
-/* endian-neutral reading of big-endian data */
30
-#define EndGetM32(a) ((((a)[0])<<24)|(((a)[1])<<16)|(((a)[2])<<8)|((a)[3]))
31
-#define EndGetM16(a) ((((a)[0])<<8)|((a)[1]))
32
-
33
-extern struct mspack_system *mspack_default_system;
34
-
35
-/* returns the length of a file opened for reading */
36
-extern int mspack_sys_filelen(struct mspack_system *system,
37
-			      struct mspack_file *file, off_t *length);
38
-
39
-/* validates a system structure */
40
-extern int mspack_valid_system(struct mspack_system *sys);
41
-
42
-/* inline memcmp() */
43
-static inline int memcmp(const void *s1, const void *s2, size_t n) {
44
-  unsigned char *c1 = (unsigned char *) s1;
45
-  unsigned char *c2 = (unsigned char *) s2;
46
-  if (n == 0) return 0;
47
-  while (--n && (*c1 == *c2)) c1++, c2++;
48
-  return *c1 - *c2;
49
-}
50
-
51
-/* inline strlen() */
52
-static inline size_t strlen(const char *s) {
53
-  const char *e = s;
54
-  while (*e) e++;
55
-  return e - s;
56
-}
57
-
58
-#endif
59 1
deleted file mode 100644
... ...
@@ -1,491 +0,0 @@
1
-/*
2
- *  Copyright (C) 2004 Tomasz Kojm <tkojm@clamav.net>
3
- *
4
- *  Implementation (header structures) based on the PE format description
5
- *  by B. Luevelsmeyer
6
- *
7
- *  This program is free software; you can redistribute it and/or modify
8
- *  it under the terms of the GNU General Public License as published by
9
- *  the Free Software Foundation; either version 2 of the License, or
10
- *  (at your option) any later version.
11
- *
12
- *  This program is distributed in the hope that it will be useful,
13
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- *  GNU General Public License for more details.
16
- *
17
- *  You should have received a copy of the GNU General Public License
18
- *  along with this program; if not, write to the Free Software
19
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
- */
21
-
22
-#if HAVE_CONFIG_H
23
-#include "clamav-config.h"
24
-#endif
25
-
26
-#include <stdio.h>
27
-#include <string.h>
28
-#include <sys/types.h>
29
-#include <sys/stat.h>
30
-#include <fcntl.h>
31
-#include <sys/stat.h>
32
-#include <unistd.h>
33
-#include <time.h>
34
-
35
-#include "cltypes.h"
36
-#include "clamav.h"
37
-#include "others.h"
38
-#include "upx.h"
39
-
40
-#define IMAGE_DOS_SIGNATURE	    0x5a4d	    /* MZ */
41
-#define IMAGE_NT_SIGNATURE	    0x00004550
42
-#define IMAGE_OPTIONAL_SIGNATURE    0x010b
43
-
44
-#define UPX_NRV2B "\x11\xc9\x75\x20\x41\x01\xdb\x75\x07\x8b\x1e\x83\xee\xfc\x11\xdb\x11\xc9\x01\xdb\x73\xef\x75\x09"
45
-#define UPX_NRV2D "\x8b\x1e\x83\xee\xfc\x11\xdb\x11\xc9\x01\xdb\x75\x07\x8b\x1e\x83\xee\xfc\x11\xdb\x11\xc9\x75\x20"
46
-#define UPX_NRV2E "\x83\xf0\xff\x74\x75\xd1\xf8\x89\xc5\xeb\x0b\x01\xdb\x75\x07\x8b\x1e\x83\xee\xfc\x11\xdb\x72\xcc"
47
-
48
-struct pe_image_file_hdr {
49
-    uint32_t Magic;
50
-    uint16_t Machine;
51
-    uint16_t NumberOfSections;
52
-    uint32_t TimeDateStamp;		    /* unreliable */
53
-    uint32_t PointerToSymbolTable;	    /* debug */
54
-    uint32_t NumberOfSymbols;		    /* debug */
55
-    uint16_t SizeOfOptionalHeader;	    /* == 224 */
56
-    uint16_t Characteristics;
57
-};
58
-
59
-struct pe_image_data_dir {
60
-    uint32_t VirtualAddress;
61
-    uint32_t Size;
62
-};
63
-
64
-struct pe_image_optional_hdr {
65
-    uint16_t Magic;
66
-    uint8_t  MajorLinkerVersion;		    /* unreliable */
67
-    uint8_t  MinorLinkerVersion;		    /* unreliable */
68
-    uint32_t SizeOfCode;			    /* unreliable */
69
-    uint32_t SizeOfInitializedData;		    /* unreliable */
70
-    uint32_t SizeOfUninitializedData;		    /* unreliable */
71
-    uint32_t AddressOfEntryPoint;
72
-    uint32_t BaseOfCode;
73
-    uint32_t BaseOfData;
74
-    uint32_t ImageBase;				    /* multiple of 64 KB */
75
-    uint32_t SectionAlignment;			    /* usually 32 or 4096 */
76
-    uint32_t FileAlignment;			    /* usually 32 or 512 */
77
-    uint16_t MajorOperatingSystemVersion;	    /* not used */
78
-    uint16_t MinorOperatingSystemVersion;	    /* not used */
79
-    uint16_t MajorImageVersion;			    /* unreliable */
80
-    uint16_t MinorImageVersion;			    /* unreliable */
81
-    uint16_t MajorSubsystemVersion;
82
-    uint16_t MinorSubsystemVersion;
83
-    uint32_t Win32VersionValue;			    /* ? */
84
-    uint32_t SizeOfImage;
85
-    uint32_t SizeOfHeaders;
86
-    uint32_t CheckSum;				    /* NT drivers only */
87
-    uint16_t Subsystem;
88
-    uint16_t DllCharacteristics;
89
-    uint32_t SizeOfStackReserve;
90
-    uint32_t SizeOfStackCommit;
91
-    uint32_t SizeOfHeapReserve;
92
-    uint32_t SizeOfHeapCommit;
93
-    uint32_t LoaderFlags;			    /* ? */
94
-    uint32_t NumberOfRvaAndSizes;		    /* unreliable */
95
-    struct pe_image_data_dir DataDirectory[16];
96
-};
97
-
98
-struct pe_image_section_hdr {
99
-    uint8_t Name[8];			    /* may not end with NULL */
100
-    /*
101
-    union {
102
-	uint32_t PhysicalAddress;
103
-	uint32_t VirtualSize;
104
-    } AddrSize;
105
-    */
106
-    uint32_t VirtualSize;
107
-    uint32_t VirtualAddress;
108
-    uint32_t SizeOfRawData;		    /* multiple of FileAlignment */
109
-    uint32_t PointerToRawData;		    /* offset to the section's data */
110
-    uint32_t PointerToRelocations;	    /* object files only */
111
-    uint32_t PointerToLinenumbers;	    /* object files only */
112
-    uint16_t NumberOfRelocations;	    /* object files only */
113
-    uint16_t NumberOfLinenumbers;	    /* object files only */
114
-    uint32_t Characteristics;
115
-};
116
-
117
-static uint32_t cli_rawaddr(uint32_t rva, struct pe_image_section_hdr *shp, uint16_t nos)
118
-{
119
-	int i, found = 0;
120
-
121
-
122
-    for(i = 0; i < nos; i++) {
123
-	if(shp[i].VirtualAddress <= rva && shp[i].VirtualAddress + shp[i].SizeOfRawData > rva) {
124
-	    found = 1;
125
-	    break;
126
-	}
127
-    }
128
-
129
-    if(!found) {
130
-	cli_dbgmsg("Can't calculate raw address from RVA 0x%x\n", rva);
131
-	return -1;
132
-    }
133
-
134
-    return rva - shp[i].VirtualAddress + shp[i].PointerToRawData;
135
-}
136
-
137
-static int cli_ddump(int desc, int offset, int size, const char *file)
138
-{
139
-	int pos, ndesc, bread, sum = 0;
140
-	char buff[FILEBUFF];
141
-
142
-
143
-    cli_dbgmsg("in ddump()\n");
144
-
145
-    if((pos = lseek(desc, 0, SEEK_CUR)) == -1) {
146
-	cli_dbgmsg("Invalid descriptor\n");
147
-	return CL_EIO;
148
-    }
149
-
150
-    if(lseek(desc, offset, SEEK_SET) == -1) {
151
-	cli_dbgmsg("lseek() failed\n");
152
-	lseek(desc, pos, SEEK_SET);
153
-	return CL_EIO;
154
-    }
155
-
156
-    if((ndesc = open(file, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
157
-	cli_dbgmsg("Can't create file %s\n", file);
158
-	lseek(desc, pos, SEEK_SET);
159
-	return CL_EIO;
160
-    }
161
-
162
-    while((bread = read(desc, buff, FILEBUFF)) > 0) {
163
-	if(sum + bread >= size) {
164
-	    if(write(ndesc, buff, size - sum) == -1) {
165
-		cli_dbgmsg("Can't write to file\n");
166
-		lseek(desc, pos, SEEK_SET);
167
-		close(ndesc);
168
-		unlink(file);
169
-		return CL_EIO;
170
-	    }
171
-	    break;
172
-	} else {
173
-	    if(write(ndesc, buff, bread) == -1) {
174
-		cli_dbgmsg("Can't write to file\n");
175
-		lseek(desc, pos, SEEK_SET);
176
-		close(ndesc);
177
-		unlink(file);
178
-		return CL_EIO;
179
-	    }
180
-	}
181
-	sum += bread;
182
-    }
183
-
184
-    close(ndesc);
185
-    lseek(desc, pos, SEEK_SET);
186
-    return 0;
187
-}
188
-
189
-int cli_scanpe(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev)
190
-{
191
-	uint16_t e_magic; /* DOS signature ("MZ") */
192
-	uint32_t e_lfanew; /* address of new exe header */
193
-	uint32_t ep; /* entry point (raw) */
194
-	struct pe_image_file_hdr file_hdr;
195
-	struct pe_image_optional_hdr optional_hdr;
196
-	struct pe_image_section_hdr *section_hdr;
197
-	struct stat sb;
198
-	char sname[9], buff[24], *tempfile;
199
-	int i, found;
200
-	int (*upxfn)(char *, int , char *, int) = NULL;
201
-
202
-
203
-    if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
204
-	cli_dbgmsg("Can't read DOS signature\n");
205
-	return CL_EIO;
206
-    }
207
-
208
-    if(e_magic != IMAGE_DOS_SIGNATURE) {
209
-	cli_dbgmsg("Invalid DOS signature\n");
210
-	return -1;
211
-    }
212
-
213
-    lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
214
-
215
-    if(read(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
216
-	cli_dbgmsg("Can't read new header address\n");
217
-	return -1;
218
-    }
219
-
220
-    cli_dbgmsg("e_lfanew == %d\n", e_lfanew);
221
-    if(!e_lfanew) {
222
-	cli_dbgmsg("Not a PE file\n");
223
-	return -2;
224
-    }
225
-
226
-    lseek(desc, e_lfanew, SEEK_SET);
227
-
228
-    if(read(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
229
-	cli_dbgmsg("Can't read file header\n");
230
-	return -1;
231
-    }
232
-
233
-    if(file_hdr.Magic != IMAGE_NT_SIGNATURE) {
234
-	cli_dbgmsg("Invalid PE signature (probably NE file)\n");
235
-	return -2;
236
-    }
237
-
238
-    /* cli_dbgmsg("Machine type: "); */
239
-    switch(file_hdr.Machine) {
240
-	case 0x14c:
241
-	    cli_dbgmsg("Machine type: 80386\n");
242
-	    break;
243
-	case 0x014d:
244
-	    cli_dbgmsg("Machine type: 80486\n");
245
-	    break;
246
-	case 0x014e:
247
-	    cli_dbgmsg("Machine type: 80586\n");
248
-	    break;
249
-	case 0x162:
250
-	    cli_dbgmsg("Machine type: R3000\n");
251
-	    break;
252
-	case 0x166:
253
-	    cli_dbgmsg("Machine type: R4000\n");
254
-	    break;
255
-	case 0x168:
256
-	    cli_dbgmsg("Machine type: R10000\n");
257
-	    break;
258
-	case 0x184:
259
-	    cli_dbgmsg("Machine type: DEC Alpha AXP\n");
260
-	    break;
261
-	case 0x1f0:
262
-	    cli_dbgmsg("Machine type: PowerPC\n");
263
-	    break;
264
-	default:
265
-	    cli_warnmsg("Unknown machine type in PE header\n");
266
-    }
267
-
268
-    cli_dbgmsg("NumberOfSections: %d\n", file_hdr.NumberOfSections);
269
-    cli_dbgmsg("TimeDateStamp: %s", ctime((time_t *) &file_hdr.TimeDateStamp));
270
-
271
-    cli_dbgmsg("SizeOfOptionalHeader: %d\n", file_hdr.SizeOfOptionalHeader);
272
-
273
-    if(file_hdr.SizeOfOptionalHeader != sizeof(struct pe_image_optional_hdr)) {
274
-	cli_warnmsg("Broken PE header detected.\n");
275
-	return -1;
276
-    }
277
-
278
-    if(read(desc, &optional_hdr, sizeof(struct pe_image_optional_hdr)) != sizeof(struct pe_image_optional_hdr)) {
279
-	cli_dbgmsg("Can't optional file header\n");
280
-	return -1;
281
-    }
282
-
283
-    cli_dbgmsg("MajorLinkerVersion: %d\n", optional_hdr.MajorLinkerVersion);
284
-    cli_dbgmsg("MinorLinkerVersion: %d\n", optional_hdr.MinorLinkerVersion);
285
-    cli_dbgmsg("SizeOfCode: %d\n", optional_hdr.SizeOfCode);
286
-    cli_dbgmsg("SizeOfInitializedData: %d\n", optional_hdr.SizeOfInitializedData);
287
-    cli_dbgmsg("SizeOfUninitializedData: %d\n", optional_hdr.SizeOfUninitializedData);
288
-    cli_dbgmsg("AddressOfEntryPoint: 0x%x\n", optional_hdr.AddressOfEntryPoint);
289
-    cli_dbgmsg("SectionAlignment: %d\n", optional_hdr.SectionAlignment);
290
-    cli_dbgmsg("FileAlignment: %d\n", optional_hdr.FileAlignment);
291
-    cli_dbgmsg("MajorSubsystemVersion: %d\n", optional_hdr.MajorSubsystemVersion);
292
-    cli_dbgmsg("MinorSubsystemVersion: %d\n", optional_hdr.MinorSubsystemVersion);
293
-    cli_dbgmsg("SizeOfImage: %d\n", optional_hdr.SizeOfImage);
294
-    cli_dbgmsg("SizeOfHeaders: %d\n", optional_hdr.SizeOfHeaders);
295
-
296
-    switch(optional_hdr.Subsystem) {
297
-	case 1:
298
-	    cli_dbgmsg("Subsystem: Native (a driver ?)\n");
299
-	    break;
300
-	case 2:
301
-	    cli_dbgmsg("Subsystem: Win32 GUI\n");
302
-	    break;
303
-	case 3:
304
-	    cli_dbgmsg("Subsystem: Win32 console\n");
305
-	    break;
306
-	case 5:
307
-	    cli_dbgmsg("Subsystem: OS/2 console\n");
308
-	    break;
309
-	case 7:
310
-	    cli_dbgmsg("Subsystem: POSIX console\n");
311
-	    break;
312
-	default:
313
-	    cli_warnmsg("Unknown subsystem in PE header\n");
314
-    }
315
-
316
-    cli_dbgmsg("NumberOfRvaAndSizes: %d\n", optional_hdr.NumberOfRvaAndSizes);
317
-
318
-    section_hdr = (struct pe_image_section_hdr *) cli_calloc(file_hdr.NumberOfSections, sizeof(struct pe_image_section_hdr));
319
-
320
-    if(!section_hdr) {
321
-	cli_dbgmsg("Can't allocate memory for section headers\n");
322
-	return CL_EMEM;
323
-    }
324
-
325
-    for(i = 0; i < file_hdr.NumberOfSections; i++) {
326
-
327
-	if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
328
-	    cli_dbgmsg("Can't read section header\n");
329
-	    cli_warnmsg("Possibly broken PE file\n");
330
-	    free(section_hdr);
331
-	    return CL_CLEAN;
332
-	}
333
-
334
-	strncpy(sname, section_hdr[i].Name, 8);
335
-	sname[8] = 0;
336
-	cli_dbgmsg("------------------------------------\n");
337
-	cli_dbgmsg("Section name: %s\n", sname);
338
-	cli_dbgmsg("VirtualSize: %d\n", section_hdr[i].VirtualSize);
339
-	cli_dbgmsg("VirtualAddress: 0x%x\n", section_hdr[i].VirtualAddress);
340
-	cli_dbgmsg("Section size: %d\n", section_hdr[i].SizeOfRawData);
341
-	cli_dbgmsg("PointerToRawData: 0x%x (%d)\n", section_hdr[i].PointerToRawData, section_hdr[i].PointerToRawData);
342
-
343
-	if(section_hdr[i].Characteristics & 0x20) {
344
-	    cli_dbgmsg("Section contains executable code\n");
345
-
346
-	    if(section_hdr[i].VirtualSize < section_hdr[i].SizeOfRawData) {
347
-		cli_dbgmsg("Section contains free space\n");
348
-		/*
349
-		cli_dbgmsg("Dumping %d bytes\n", section_hdr.SizeOfRawData - section_hdr.VirtualSize);
350
-		ddump(desc, section_hdr.PointerToRawData + section_hdr.VirtualSize, section_hdr.SizeOfRawData - section_hdr.VirtualSize, cl_gentemp(NULL));
351
-		*/
352
-
353
-	    }
354
-	}
355
-
356
-	if(section_hdr[i].Characteristics & 0x20000000)
357
-	    cli_dbgmsg("Section's memory is executable\n");
358
-
359
-/*
360
-	if(!strcmp(sname, "_winzip_")) {
361
-	    int ptrd = section_hdr.PointerToRawData & ~(optional_hdr.FileAlignment - 1);
362
-
363
-	    cli_dbgmsg("WinZip section\n");
364
-	    ddump(desc, ptrd, section_hdr.SizeOfRawData, cl_gentemp(NULL));
365
-	}
366
-*/
367
-
368
-    }
369
-
370
-    if(fstat(desc, &sb) == -1) {
371
-	cli_dbgmsg("fstat failed\n");
372
-	free(section_hdr);
373
-	return CL_EIO;
374
-    }
375
-
376
-    ep = cli_rawaddr(optional_hdr.AddressOfEntryPoint, section_hdr, file_hdr.NumberOfSections);
377
-
378
-    if(section_hdr[i].PointerToRawData + section_hdr[i].SizeOfRawData > sb.st_size || ep == -1) {
379
-	cli_warnmsg("Possibly broken PE file\n");
380
-	free(section_hdr);
381
-	return CL_CLEAN;
382
-    }
383
-
384
-    cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep);
385
-
386
-    if(lseek(desc, ep + 0x78, SEEK_SET) == -1) {
387
-	cli_dbgmsg("lseek() failed\n");
388
-	free(section_hdr);
389
-	return CL_EIO;
390
-    }
391
-
392
-    if(read(desc, buff, 24) != 24) {
393
-	cli_dbgmsg("Can't read 24 bytes at 0x%x (%d)\n", ep + 0x78, ep + 0x78);
394
-    } else {
395
-	if(!memcmp(buff, UPX_NRV2B, 24)) {
396
-	    cli_dbgmsg("UPX: NRV2B decompressor detected\n");
397
-	    upxfn = upx_inflate2b;
398
-	} else if(!memcmp(buff, UPX_NRV2D, 24)) {
399
-	    cli_dbgmsg("UPX: NRV2D decompressor detected\n");
400
-	    upxfn = upx_inflate2d;
401
-	} else if(!memcmp(buff, UPX_NRV2E, 24)) {
402
-            cli_dbgmsg("UPX: NRV2E decompressor detected\n");
403
-	    upxfn = upx_inflate2e;
404
-	}
405
-    }
406
-
407
-    if(upxfn) {
408
-	/* try to find the first section with physical size == 0 */
409
-	found = 0;
410
-	for(i = 0; i < file_hdr.NumberOfSections; i++) {
411
-	    if(!section_hdr[i].SizeOfRawData) {
412
-		found = 1;
413
-		break;
414
-	    }
415
-	}
416
-
417
-	if(found) {
418
-		uint32_t ssize, dsize;
419
-		char *src, *dest;
420
-
421
-	    /* we assume (i + 1) is UPX1 */
422
-	    if(strncmp(section_hdr[i].Name, "UPX0", 4) || strncmp(section_hdr[i + 1].Name, "UPX1", 4))
423
-		cli_dbgmsg("Possibly hacked UPX section headers\n");
424
-
425
-	    /* FIXME: use file operations in case of big files */
426
-	    ssize = section_hdr[i + 1].SizeOfRawData;
427
-	    dsize = section_hdr[i].VirtualSize + section_hdr[i + 1].VirtualSize;
428
-	    if((src = (char *) malloc(ssize)) == NULL) {
429
-		free(section_hdr);
430
-		return CL_EMEM;
431
-	    }
432
-
433
-	    if((dest = (char *) malloc(dsize)) == NULL) {
434
-		free(section_hdr);
435
-		free(src);
436
-		return CL_EMEM;
437
-	    }
438
-
439
-	    lseek(desc, section_hdr[i + 1].PointerToRawData, SEEK_SET);
440
-	    if(read(desc, src, ssize) != ssize) {
441
-		cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
442
-		free(section_hdr);
443
-		free(src);
444
-		free(dest);
445
-		return CL_EMEM;
446
-	    }
447
-
448
-	    if(upxfn(src, ssize, dest, dsize)) {
449
-		cli_dbgmsg("UPX decompression failed\n");
450
-	    } else {
451
-		    int ndesc;
452
-
453
-		tempfile = cl_gentemp(NULL);
454
-
455
-		if((ndesc = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
456
-		    cli_dbgmsg("Can't create file %s\n", tempfile);
457
-		    free(section_hdr);
458
-		    free(src);
459
-		    free(dest);
460
-		    return CL_EIO;
461
-		}
462
-
463
-		if(write(ndesc, dest, dsize) != dsize) {
464
-		    cli_dbgmsg("Can't write %d bytes\n", dsize);
465
-		    free(section_hdr);
466
-		    free(src);
467
-		    free(dest);
468
-		    return CL_EIO;
469
-		}
470
-
471
-		close(ndesc);
472
-
473
-		/* TODO: scan and unlink file */
474
-
475
-		/* unlink(tempfile); */
476
-		free(tempfile);
477
-	    }
478
-
479
-	    free(src);
480
-	    free(dest);
481
-
482
-	} else {
483
-	    cli_dbgmsg("UPX sections not found\n");
484
-	}
485
-    }
486
-
487
-    /* to be continued ... */
488
-
489
-    free(section_hdr);
490
-    return CL_CLEAN;
491
-}
492 1
deleted file mode 100644
... ...
@@ -1,26 +0,0 @@
1
-/*
2
- *  Copyright (C) 2004 Tomasz Kojm <tkojm@clamav.net>
3
- *
4
- *  This program is free software; you can redistribute it and/or modify
5
- *  it under the terms of the GNU General Public License as published by
6
- *  the Free Software Foundation; either version 2 of the License, or
7
- *  (at your option) any later version.
8
- *
9
- *  This program is distributed in the hope that it will be useful,
10
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
- *  GNU General Public License for more details.
13
- *
14
- *  You should have received a copy of the GNU General Public License
15
- *  along with this program; if not, write to the Free Software
16
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-#ifndef __PE_H
20
-#define __PE_H
21
-
22
-#include "clamav.h"
23
-
24
-int cli_scanpe(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev);
25
-
26
-#endif
... ...
@@ -30,8 +30,6 @@
30 30
 #include <fcntl.h>
31 31
 #include <dirent.h>
32 32
 
33
-#include <mspack.h>
34
-
35 33
 #ifdef CL_THREAD_SAFE
36 34
 #  include <pthread.h>
37 35
 pthread_mutex_t cli_scanrar_mutex = PTHREAD_MUTEX_INITIALIZER;
... ...
@@ -75,10 +73,6 @@ struct cli_magic_s {
75 75
 #define MAGIC_BUFFER_SIZE 26
76 76
 static const struct cli_magic_s cli_magic[] = {
77 77
 
78
-    /* Executables */
79
-
80
-/*  {0,  "MZ",				2,  "DOS/W32 executable", CL_DOSEXE},*/
81
-
82 78
     /* Archives */
83 79
 
84 80
     {0,  "Rar!",			4,  "RAR",		  CL_RARFILE},
... ...
@@ -86,7 +80,6 @@ static const struct cli_magic_s cli_magic[] = {
86 86
     {0,  "\037\213",			2,  "GZip",		  CL_GZFILE},
87 87
     {0,  "BZh",				3,  "BZip",		  CL_BZFILE},
88 88
     {0,  "SZDD",			4,  "compress.exe'd",	  CL_MSCFILE},
89
-    {0,  "MSCF",			4,  "MS CAB",		  CL_MSCABFILE},
90 89
 
91 90
     /* Mail */
92 91
 
... ...
@@ -716,61 +709,6 @@ static int cli_scanmscomp(int desc, const char **virname, long int *scanned, con
716 716
     return ret;
717 717
 }
718 718
 
719
-static int cli_scanmscab(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev)
720
-{
721
-	struct mscab_decompressor *cabd = NULL;
722
-	struct mscabd_cabinet *base, *cab;
723
-	struct mscabd_file *file;
724
-	const char *tmpdir;
725
-	char *tempname;
726
-	int ret = CL_CLEAN;
727
-
728
-
729
-    cli_dbgmsg("in cli_scanmscab()\n");
730
-
731
-    if((cabd = mspack_create_cab_decompressor(NULL)) == NULL) {
732
-	cli_dbgmsg("Can't create libmspack CAB decompressor\n");
733
-	return CL_EMSCAB;
734
-    }
735
-
736
-    if((base = cabd->dsearch(cabd, desc)) == NULL) {
737
-	cli_dbgmsg("I/O error or no valid cabinets found\n");
738
-	mspack_destroy_cab_decompressor(cabd);
739
-	return CL_EMSCAB;
740
-    }
741
-
742
-    if((tmpdir = getenv("TMPDIR")) == NULL)
743
-#ifdef P_tmpdir
744
-	tmpdir = P_tmpdir;
745
-#else
746
-	tmpdir = "/tmp";
747
-#endif
748
-
749
-    for(cab = base; cab; cab = cab->next) {
750
-	for(file = cab->files; file; file = file->next) {
751
-	    tempname = cl_gentemp(tmpdir);
752
-	    cli_dbgmsg("Extracting data to %s\n", tempname);
753
-	    if(cabd->extract(cabd, file, tempname)) {
754
-		cli_dbgmsg("libmscab error code: %d\n", cabd->last_error(cabd));
755
-	    } else {
756
-		ret = cli_scanfile(tempname, virname, scanned, root, limits, options, reclev);
757
-	    }
758
-	    if(!cli_leavetemps_flag)
759
-		unlink(tempname);
760
-	    free(tempname);
761
-	    if(ret == CL_VIRUS)
762
-		break;
763
-	}
764
-	if(ret == CL_VIRUS)
765
-	    break;
766
-    }
767
-
768
-    cabd->close(cabd, base);
769
-    mspack_destroy_cab_decompressor(cabd);
770
-
771
-    return ret;
772
-}
773
-
774 719
 static int cli_scandir(const char *dirname, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev)
775 720
 {
776 721
 	DIR *dd;
... ...
@@ -867,12 +805,6 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int *
867 867
 	free(vba_project->dir);
868 868
 	free(vba_project->offset);
869 869
 	free(vba_project);
870
-    } else if ((fullname = ppt_vba_read(dirname))) {
871
-    	if(cli_scandir(fullname, virname, scanned, root, limits, options, reclev) == CL_VIRUS) {
872
-	    ret = CL_VIRUS;
873
-	}
874
-	cli_rmdirs(fullname);
875
-    	free(fullname);
876 870
     } else if ((vba_project = (vba_project_t *) wm_dir_read(dirname))) {
877 871
     	for (i = 0; i < vba_project->count; i++) {
878 872
 		fullname = (char *) cli_malloc(strlen(vba_project->dir) + strlen(vba_project->name[i]) + 2);
... ...
@@ -1066,11 +998,6 @@ static int cli_magic_scandesc(int desc, const char **virname, long int *scanned,
1066 1066
     type = cli_filetype(magic, bread);
1067 1067
 
1068 1068
     switch(type) {
1069
-	case CL_DOSEXE:
1070
-	    /* temporarily the return code is ignored */
1071
-	    cli_scanpe(desc, virname, scanned, root, limits, options, reclev);
1072
-	    break;
1073
-
1074 1069
 	case CL_RARFILE:
1075 1070
 	    if(!DISABLE_RAR && SCAN_ARCHIVE && !cli_scanrar_inuse)
1076 1071
 		ret = cli_scanrar(desc, virname, scanned, root, limits, options, reclev);
... ...
@@ -1098,11 +1025,6 @@ static int cli_magic_scandesc(int desc, const char **virname, long int *scanned,
1098 1098
 		ret = cli_scanmscomp(desc, virname, scanned, root, limits, options, reclev);
1099 1099
 	    break;
1100 1100
 
1101
-	case CL_MSCABFILE:
1102
-	    if(SCAN_ARCHIVE)
1103
-		ret = cli_scanmscab(desc, virname, scanned, root, limits, options, reclev);
1104
-	    break;
1105
-
1106 1101
 	case CL_MAILFILE:
1107 1102
 	    if(SCAN_MAIL)
1108 1103
 		ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
... ...
@@ -22,7 +22,6 @@
22 22
 
23 23
 typedef enum {
24 24
     CL_UNKNOWN_TYPE = 0,
25
-    CL_DOSEXE,
26 25
     CL_DATAFILE,
27 26
     CL_MAILFILE,
28 27
     CL_GZFILE,
... ...
@@ -31,7 +30,6 @@ typedef enum {
31 31
     CL_RARFILE,
32 32
     CL_MSCFILE,
33 33
     CL_OLE2FILE,
34
-    CL_MSCABFILE
35 34
 } cli_file_t;
36 35
 
37 36
 cli_file_t cli_filetype(const char *buf, size_t buflen);
38 37
deleted file mode 100644
... ...
@@ -1,263 +0,0 @@
1
-/*
2
- *  Copyright (C) 2004 aCaB <acab@clamav.net>
3
- *
4
- *  This program is free software; you can redistribute it and/or modify
5
- *  it under the terms of the GNU General Public License as published by
6
- *  the Free Software Foundation; either version 2 of the License, or
7
- *  (at your option) any later version.
8
- *
9
- *  This program is distributed in the hope that it will be useful,
10
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
- *  GNU General Public License for more details.
13
- *
14
- *  You should have received a copy of the GNU General Public License
15
- *  along with this program; if not, write to the Free Software
16
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-/*
20
-** upxdec.c
21
-**
22
-** 05/05/2k4 - 1st attempt
23
-** 08/05/2k4 - Now works as a charm :D
24
-** 09/05/2k4 - Moved code outta main(), got rid of globals for thread safety, added bound checking, minor cleaning
25
-** 04/06/2k4 - Now we handle 2B, 2D and 2E :D
26
-*/
27
-
28
-/*
29
-** This code unpacks a dumped UPX1 section to a file.
30
-** It was written reversing the loader found on some Win32 UPX compressed trojans; while porting
31
-** it to C i've kinda followed the asm flow so it will probably be a bit hard to read.
32
-** This code DOES NOT revert the uncompressed section to its original state as no E8/E9 fixup and
33
-** of cause no IAT rebuild are performed.
34
-**
35
-** The Win32 asm unpacker is really a little programming jewel, pretty damn rare in these days of
36
-** bloatness. My gratitude to whoever wrote it.
37
-*/
38
-
39
-
40
-#include <stdio.h>
41
-#include <stdlib.h>
42
-#include <sys/types.h>
43
-#include <sys/stat.h>
44
-#include <unistd.h>
45
-#include <string.h>
46
-
47
-/* [doubleebx] */
48
-
49
-static int doubleebx(char *src, int *myebx, int *scur, int ssize)
50
-{
51
-  int oldebx = *myebx;
52
-
53
-  *myebx*=2;
54
-  if ( !(oldebx & 0x7fffffff)) {
55
-    if (*scur<0 || ssize-*scur<4)
56
-      return 0;
57
-    oldebx = *(int*)(src+*scur);
58
-    *myebx = oldebx*2+1;
59
-    *scur+=4;
60
-  }
61
-  return (oldebx>>31)&1;
62
-}
63
-
64
-/* [inflate] */
65
-
66
-int upx_inflate2b(char *src, int ssize, char *dst, int dsize)
67
-{
68
-  int backbytes, backsize, unp_offset = -1, i;
69
-  int myebx = 0;
70
-  int scur=0, dcur=0;
71
-
72
-  while (1) {
73
-    while (doubleebx(src, &myebx, &scur, ssize)) {
74
-      if (scur<0 || scur>=ssize || dcur<0 || dcur>=dsize)
75
-	return -1;
76
-      dst[dcur++] = src[scur++];
77
-    }
78
-
79
-    backbytes = 1;
80
-
81
-    while (1) {
82
-      backbytes = backbytes*2+doubleebx(src, &myebx, &scur, ssize);
83
-      if (doubleebx(src, &myebx, &scur, ssize))
84
-	break;
85
-    }
86
-
87
-    backsize = 0;	
88
-    backbytes-=3;
89
-  
90
-    if ( backbytes >= 0 ) {
91
-
92
-      if (scur<0 || scur>=ssize)
93
-	return -1;
94
-      backbytes<<=8;
95
-      backbytes+=(unsigned char)(src[scur++]);
96
-      backbytes^=0xffffffff;
97
-
98
-      if (!backbytes)
99
-	break;
100
-      unp_offset = backbytes;
101
-    }
102
-
103
-    backsize = doubleebx(src, &myebx, &scur, ssize);
104
-    backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
105
-    if (!backsize) {
106
-      backsize++;
107
-      do {
108
-	backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
109
-      } while (!doubleebx(src, &myebx, &scur, ssize));
110
-      backsize+=2;
111
-    }
112
-
113
-    if ( (unsigned int)unp_offset < 0xfffff300 )
114
-      backsize++;
115
-
116
-    backsize++;
117
-    for (i = 0; i < backsize; i++) {
118
-      if (dcur+i<0 || dcur+i>=dsize || dcur+unp_offset+i<0 || dcur+unp_offset+i>=dsize)
119
-	return -1;
120
-      dst[dcur + i] = dst[dcur + unp_offset + i];
121
-    }
122
-    dcur+=backsize;
123
-  }
124
-  return 0;
125
-}
126
-
127
-int upx_inflate2d(char *src, int ssize, char *dst, int dsize)
128
-{
129
-  int backbytes, backsize, unp_offset = -1, i;
130
-  int myebx = 0;
131
-  int scur=0, dcur=0;
132
-
133
-  while (1) {
134
-    while (doubleebx(src, &myebx, &scur, ssize)) {
135
-      if (scur<0 || scur>=ssize || dcur<0 || dcur>=dsize)
136
-	return -1;
137
-      dst[dcur++] = src[scur++];
138
-    }
139
-
140
-    backbytes = 1;
141
-
142
-    while (1) {
143
-      backbytes = backbytes*2+doubleebx(src, &myebx, &scur, ssize);
144
-      if (doubleebx(src, &myebx, &scur, ssize))
145
-	break;
146
-      backbytes--;
147
-      backbytes=backbytes*2+doubleebx(src, &myebx, &scur, ssize);
148
-    }
149
-
150
-    backsize = 0;	
151
-    backbytes-=3;
152
-  
153
-    if ( backbytes >= 0 ) {
154
-
155
-      if (scur<0 || scur>=ssize)
156
-	return -1;
157
-      backbytes<<=8;
158
-      backbytes+=(unsigned char)(src[scur++]);
159
-      backbytes^=0xffffffff;
160
-
161
-      if (!backbytes)
162
-	break;
163
-      backsize = backbytes & 1;
164
-      backbytes>>=1;
165
-      unp_offset = backbytes;
166
-    }
167
-    else
168
-      backsize = doubleebx(src, &myebx, &scur, ssize);
169
- 
170
-    backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
171
-    if (!backsize) {
172
-      backsize++;
173
-      do {
174
-	backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
175
-      } while (!doubleebx(src, &myebx, &scur, ssize));
176
-      backsize+=2;
177
-    }
178
-
179
-    if ( (unsigned int)unp_offset < 0xfffffb00 ) 
180
-      backsize++;
181
-
182
-    backsize++;
183
-    for (i = 0; i < backsize; i++) {
184
-      if (dcur+i<0 || dcur+i>=dsize || dcur+unp_offset+i<0 || dcur+unp_offset+i>=dsize)
185
-	return -1;
186
-      dst[dcur + i] = dst[dcur + unp_offset + i];
187
-    }
188
-    dcur+=backsize;
189
-  }
190
-  return 0;
191
-}
192
-
193
-int upx_inflate2e(char *src, int ssize, char *dst, int dsize)
194
-{
195
-  int backbytes, backsize, unp_offset = -1, i;
196
-  int myebx = 0;
197
-  int scur=0, dcur=0;
198
-
199
-  while (1) {
200
-    while (doubleebx(src, &myebx, &scur, ssize)) {
201
-      if (scur<0 || scur>=ssize || dcur<0 || dcur>=dsize)
202
-	return -1;
203
-      dst[dcur++] = src[scur++];
204
-    }
205
-
206
-    backbytes = 1;
207
-
208
-    while (1) {
209
-      backbytes = backbytes*2+doubleebx(src, &myebx, &scur, ssize);
210
-      if (doubleebx(src, &myebx, &scur, ssize))
211
-	break;
212
-      backbytes--;
213
-      backbytes=backbytes*2+doubleebx(src, &myebx, &scur, ssize);
214
-    }
215
-
216
-    backsize = 0;
217
-    backbytes-=3;
218
-  
219
-    if ( backbytes >= 0 ) {
220
-
221
-      if (scur<0 || scur>=ssize)
222
-	return -1;
223
-      backbytes<<=8;
224
-      backbytes+=(unsigned char)(src[scur++]);
225
-      backbytes^=0xffffffff;
226
-
227
-      if (!backbytes)
228
-	break;
229
-      backsize = backbytes & 1; /* Using backsize to carry on the shifted out bit (UPX uses CF) */
230
-      backbytes>>=1;
231
-      unp_offset = backbytes;
232
-    }
233
-    else
234
-      backsize = doubleebx(src, &myebx, &scur, ssize); /* Using backsize to carry on the doubleebx result (UPX uses CF) */
235
-
236
-    if (backsize) { /* i.e. IF ( last sar shifted out 1 bit || last doubleebx()==1 ) */
237
-      backsize = doubleebx(src, &myebx, &scur, ssize);
238
-    }
239
-    else {
240
-      backsize = 1;
241
-      if (doubleebx(src, &myebx, &scur, ssize))
242
-	backsize = 2 + doubleebx(src, &myebx, &scur, ssize);
243
-      else {
244
-	do {
245
-	  backsize = backsize * 2 + doubleebx(src, &myebx, &scur, ssize);
246
-	} while (!doubleebx(src, &myebx, &scur, ssize));
247
-	backsize+=2;
248
-      }
249
-    }
250
- 
251
-    if ( (unsigned int)unp_offset < 0xfffffb00 ) 
252
-      backsize++;
253
-
254
-    backsize+=2;
255
-    for (i = 0; i < backsize; i++) {
256
-      if (dcur+i<0 || dcur+i>=dsize || dcur+unp_offset+i<0 || dcur+unp_offset+i>=dsize)
257
-	return -1;
258
-      dst[dcur + i] = dst[dcur + unp_offset + i];
259
-    }
260
-    dcur+=backsize;
261
-  }
262
-  return 0;
263
-}
264 1
deleted file mode 100644
... ...
@@ -1,26 +0,0 @@
1
-/*
2
- *  Copyright (C) 2004 aCaB <acab@clamav.net>
3
- *
4
- *  This program is free software; you can redistribute it and/or modify
5
- *  it under the terms of the GNU General Public License as published by
6
- *  the Free Software Foundation; either version 2 of the License, or
7
- *  (at your option) any later version.
8
- *
9
- *  This program is distributed in the hope that it will be useful,
10
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
- *  GNU General Public License for more details.
13
- *
14
- *  You should have received a copy of the GNU General Public License
15
- *  along with this program; if not, write to the Free Software
16
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-#ifndef __UPX_H
20
-#define __UPX_H
21
-
22
-int upx_inflate2b(char *, int , char *, int);
23
-int upx_inflate2d(char *, int , char *, int);
24
-int upx_inflate2e(char *, int , char *, int);
25
-
26
-#endif