Hello community,
here is the log from the commit of package libzio
checked in at Thu Dec 14 02:00:23 CET 2006.
--------
--- libzio/libzio.changes 2006-06-21 17:07:23.000000000 +0200
+++ /mounts/work_src_done/STABLE/libzio/libzio.changes 2006-12-12 18:37:21.000000000 +0100
@@ -1,0 +2,5 @@
+Tue Dec 12 18:36:35 CET 2006 - werner(a)suse.de
+
+- Add support for the old LZW (.Z) format
+
+-------------------------------------------------------------------
Old:
----
libzio-0.2.tar.bz2
New:
----
libzio-0.3.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libzio.spec ++++++
--- /var/tmp/diff_new_pack.7BD8u6/_old 2006-12-14 02:00:03.000000000 +0100
+++ /var/tmp/diff_new_pack.7BD8u6/_new 2006-12-14 02:00:03.000000000 +0100
@@ -1,5 +1,5 @@
#
-# spec file for package libzio (Version 0.2)
+# spec file for package libzio (Version 0.3)
#
# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@@ -11,10 +11,10 @@
# norootforbuild
Name: libzio
-License: GPL
+License: GNU General Public License (GPL)
Group: System/Libraries
Autoreqprov: on
-Version: 0.2
+Version: 0.3
Release: 1
Summary: A Library for Accessing Compressed Text Files
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -53,11 +53,13 @@
%{_libdir}/libzio.a
%{_libdir}/libzio.so
%{_libdir}/libzio.so.0
-%{_libdir}/libzio.so.0.2
+%{_libdir}/libzio.so.0.3
%{_mandir}/man3/fzopen.3*
/usr/include/zio.h
%changelog -n libzio
+* Tue Dec 12 2006 - werner(a)suse.de
+- Add support for the old LZW (.Z) format
* Wed Jun 21 2006 - werner(a)suse.de
- Remove self provide
* Wed Jan 25 2006 - mls(a)suse.de
++++++ libzio-0.2.tar.bz2 -> libzio-0.3.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/libzio-0.2/Makefile new/libzio-0.3/Makefile
--- old/libzio-0.2/Makefile 2004-04-26 11:25:12.000000000 +0200
+++ new/libzio-0.3/Makefile 2006-12-13 18:26:42.000000000 +0100
@@ -4,10 +4,11 @@
# Author: Werner Fink, <werner(a)suse.de>
#
-CFLAGS = $(RPM_OPT_FLAGS) -pipe -Wall -D_REENTRANT
+LARGE = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+CFLAGS = $(RPM_OPT_FLAGS) -pipe -Wall -D_GNU_SOURCE -D_REENTRANT $(LARGE)
CC = gcc
MAJOR = 0
-MINOR = 2
+MINOR = 3
VERSION = $(MAJOR).$(MINOR)
libdir = /usr/lib
@@ -20,23 +21,33 @@
zioP.h \
zio.h.in \
testt.c \
+ lzw.h \
+ unlzw.c \
fzopen.3.in
all: libzio.so.$(VERSION) libzio.a
obj/zio.o: zio.c zioP.h zio.h
- mkdir obj/
+ test -d obj/ || mkdir obj/
$(CC) $(CFLAGS) -o $@ -c $<
obs/zio.o: zio.c zioP.h zio.h
- mkdir obs/
+ test -d obs/ || mkdir obs/
$(CC) $(CFLAGS) -fPIC -o $@ -c $<
-libzio.a: obj/zio.o
+obj/unlzw.o: unlzw.c lzw.h
+ test -d obj/ || mkdir obj/
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+obs/unlzw.o: unlzw.c lzw.h
+ test -d obs/ || mkdir obs/
+ $(CC) $(CFLAGS) -fPIC -o $@ -c $<
+
+libzio.a: obj/zio.o obj/unlzw.o
ar -rv $@ $^
ranlib $@
-libzio.so.$(VERSION): obs/zio.o
+libzio.so.$(VERSION): obs/zio.o obs/unlzw.o
gcc -shared -Wl,-soname,libzio.so.$(MAJOR),-stats,-lc -o $@ $^
zioP.h: /usr/include/bzlib.h /usr/include/zlib.h
@@ -45,6 +56,8 @@
fzopen.3: fzopen.3.in
sed 's/@@VERSION@@/$(VERSION)/' < $< > $@
+unlzw.c: lzw.h
+
install: libzio.so.$(VERSION) libzio.a zio.h fzopen.3
mkdir -p $(DESTDIR)$(libdir)
mkdir -p $(DESTDIR)/usr/include
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/libzio-0.2/README new/libzio-0.3/README
--- old/libzio-0.2/README 2004-04-26 11:25:12.000000000 +0200
+++ new/libzio-0.3/README 2006-12-13 18:26:42.000000000 +0100
@@ -17,7 +17,7 @@
_and_ -lz. For bzip2 files clearly the libbz2 with -lbz2
has to used at linking time.
-The libz and/or libbz2 librares iare required because the
+The libz and/or libbz2 librares are required because the
libzio is not linked with -lz nor with -lbz2. If the
appropiate library functions of libz or libbz2 are not
found the fzopen(3) function returns NULL and the errno
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/libzio-0.2/lzw.h new/libzio-0.3/lzw.h
--- old/libzio-0.2/lzw.h 1970-01-01 01:00:00.000000000 +0100
+++ new/libzio-0.3/lzw.h 2006-12-13 18:26:42.000000000 +0100
@@ -0,0 +1,120 @@
+/* lzw.h -- define the lzw functions.
+
+ Copyright (C) 1992-1993 Jean-loup Gailly.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef BITS
+# define BITS 16
+#endif
+#define INIT_BITS 9 /* Initial number of bits per code */
+
+#define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */
+
+#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */
+/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
+ * It's a pity that old uncompress does not check bit 0x20. That makes
+ * extension of the format actually undesirable because old compress
+ * would just crash on the new format instead of giving a meaningful
+ * error message. It does check the number of bits, but it's more
+ * helpful to say "unsupported format, get a new version" than
+ * "can only handle 16 bits".
+ */
+
+#define BLOCK_MODE 0x80
+/* Block compression: if table is full and compression rate is dropping,
+ * clear the dictionary.
+ */
+
+#define LZW_RESERVED 0x60 /* reserved bits */
+
+#define CLEAR 256 /* flush the dictionary */
+#define FIRST (CLEAR+1) /* first free entry */
+
+#include <stdint.h>
+#include <ucontext.h>
+
+#if defined _REENTRANT || defined _THREAD_SAFE
+# include <pthread.h>
+extern int pthread_sigmask(int, const sigset_t*, sigset_t*) __attribute__((weak));
+static inline int sigucmask(int how, const sigset_t * set, sigset_t * oset)
+{
+ if (&pthread_sigmask)
+ return pthread_sigmask(how, set, oset);
+ else
+ return sigprocmask(how, set, oset);
+}
+#else
+static inline int sigucmask(int how, const sigset_t * set, sigset_t * oset)
+{
+ return sigprocmask(how, set, oset);
+}
+#endif
+
+#if defined(__ia64__) /* Broken header sys/ucontext.h -> bits/sigcontext.h */
+static inline unsigned long int sig_ia64_mask(const sigset_t set)
+{
+ unsigned long int mask = 0;
+ int cnt = sizeof(unsigned long int);
+ while (--cnt >= 0) {
+ if (!sigismember(&set, cnt))
+ continue;
+ mask |= sigmask(cnt);
+ }
+ return mask;
+}
+#endif
+
+typedef struct _LZW_s {
+ uint8_t *inbuf;
+ uint8_t *outbuf;
+ uint16_t *d_buf;
+ uint8_t *tab_suffix;
+ uint16_t *tab_prefix;
+ uint8_t *transfer;
+ off_t bytes_in;
+ off_t bytes_out;
+ size_t insize;
+ size_t inptr;
+ size_t outpos;
+ size_t tcount;
+ ssize_t tsize;
+ ssize_t rsize;
+ struct unlzw_s {
+ uint8_t *stackp;
+ int32_t code;
+ int finchar;
+ int32_t oldcode;
+ int32_t incode;
+ uint32_t inbits;
+ uint32_t posbits;
+ uint32_t bitmask;
+ int32_t free_ent;
+ int32_t maxcode;
+ int32_t maxmaxcode;
+ off_t newdif;
+ int n_bits;
+ int block_mode;
+ int maxbits;
+ } n;
+ int ifd;
+ char *ifname;
+ ucontext_t *uc;
+ uint8_t *stack;
+} LZW_t;
+
+extern LZW_t *openlzw(const char*, const char*);
+extern ssize_t readlzw(LZW_t*, char*, const size_t);
+extern void closelzw(LZW_t*);
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/libzio-0.2/testt.c new/libzio-0.3/testt.c
--- old/libzio-0.2/testt.c 2004-04-26 11:25:12.000000000 +0200
+++ new/libzio-0.3/testt.c 2006-12-13 18:26:42.000000000 +0100
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/libzio-0.2/unlzw.c new/libzio-0.3/unlzw.c
--- old/libzio-0.2/unlzw.c 1970-01-01 01:00:00.000000000 +0100
+++ new/libzio-0.3/unlzw.c 2006-12-13 18:26:42.000000000 +0100
@@ -0,0 +1,453 @@
+/* unlzw.c -- decompress files in LZW format.
+ * The code in this file is directly derived from the public domain 'compress'
+ * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
+ * Ken Turkowski, Dave Mack and Peter Jannesen.
+ *
+ * This is a temporary version which will be rewritten in some future version
+ * to accommodate in-memory decompression.
+ *
+ * Tue Dec 12 17:54:07 CET 2006 - werner(a)suse.de
+ * Be able to emulate a zlib-like behaviour: open, read, and close .Z files
+ * in memory. I'm using context switchting and a global allocated structure
+ * to be able to read during the main loop in unlzw() does its work. For this
+ * nearly _all_ variables affected by the context switch are forward to this
+ * structure, even the stack and the context type its self.
+ * The oringal source was adopted from the gzip version 1.3.7.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define DIST_BUFSIZE 0x2000
+#define INBUFSIZ 0x2000
+#define WSIZE 0x2000
+#define INBUF_EXTRA 0x40
+#define OUTBUFSIZ 0x2000
+#define OUTBUF_EXTRA 0x800
+#define STACK_SIZE 0x1000
+
+#include "lzw.h"
+
+static void unlzw(LZW_t *in);
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty.
+ * Adopted from gzip version 1.3.7 util.c
+ */
+static inline int fill_inbuf(LZW_t *in)
+{
+ /* Read as much as possible */
+ in->insize = 0;
+ do {
+ ssize_t len = read(in->ifd, in->inbuf + in->insize, INBUFSIZ - in->insize);
+ if (len < 0) {
+ if (errno == EINTR)
+ continue;
+ perror(in->ifname);
+ break;
+ }
+ if (len == 0)
+ break;
+ in->insize += len;
+ } while (in->insize < INBUFSIZ);
+
+ if (in->insize == 0)
+ return EOF;
+
+ in->bytes_in += (off_t)in->insize;
+ in->inptr = 1;
+ return (in->inbuf)[0];
+}
+
+/* ===========================================================================
+ * Does the same as write(), but also handles partial pipe writes and checks
+ * for error return.
+ * Adopted from gzip version 1.3.7 util.c
+ * Note that this version uses context switching, switch back to old context.
+ */
+static inline void write_buf(LZW_t *in, const unsigned char* buf, size_t cnt)
+{
+ do {
+ if ((in->tsize = (in->tcount > cnt) ? cnt : in->tcount)) {
+ (void)memcpy(in->transfer, buf, in->tsize);
+ buf += in->tsize;
+ cnt -= in->tsize;
+ }
+ swapcontext(&in->uc[1], &in->uc[0]);
+ } while (cnt);
+}
+
+#define get_byte(in) ((in)->inptr < (in)->insize ? (in)->inbuf[(in)->inptr++] : fill_inbuf((in)))
+#define memzero(s,n) memset ((void*)(s), 0, (n))
+
+#define MAXCODE(n) (1L << (n))
+
+#ifndef BYTEORDER
+# define BYTEORDER 0000
+#endif
+
+#ifndef NOALLIGN
+# define NOALLIGN 0
+#endif
+
+
+union bytes {
+ long word;
+ struct {
+#if BYTEORDER == 4321
+ uint8_t b1;
+ uint8_t b2;
+ uint8_t b3;
+ uint8_t b4;
+#else
+#if BYTEORDER == 1234
+ uint8_t b4;
+ uint8_t b3;
+ uint8_t b2;
+ uint8_t b1;
+#else
+# undef BYTEORDER
+ int dummy;
+#endif
+#endif
+ } bytes;
+};
+
+#if BYTEORDER == 4321 && NOALLIGN == 1
+# define input(b,o,c,n,m){ \
+ (c) = (*(uint32_t *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \
+ (o) += (n); \
+ }
+#else
+# define input(b,o,c,n,m){ \
+ uint8_t *p = &(b)[(o)>>3]; \
+ (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
+ ((long)(p[2])<<16))>>((o)&0x7))&(m); \
+ (o) += (n); \
+ }
+#endif
+
+#define tab_prefixof(i) in->tab_prefix[i]
+#define clear_tab_prefixof(in) memzero((in)->tab_prefix, sizeof(unsigned short)*(1<<(BITS)));
+#define de_stack ((uint8_t *)(&in->d_buf[DIST_BUFSIZE-1]))
+#define tab_suffixof(i) in->tab_suffix[i]
+
+/* ============================================================================
+ * Decompress in to out. This routine adapts to the codes in the
+ * file building the "string" table on-the-fly; requiring no table to
+ * be stored in the compressed file.
+ * IN assertions: the buffer inbuf contains already the beginning of
+ * the compressed data, from offsets iptr to insize-1 included.
+ * The magic header has already been checked and skipped.
+ * bytes_in and bytes_out have been initialized.
+ *
+ * Adopted from gzip version 1.3.7 unlzw.c
+ * This is mainly the head of the old unlzw() before its main loop.
+ */
+LZW_t *openlzw(const char * path, const char *mode)
+{
+ LZW_t *in = (LZW_t*)0;
+ uint8_t magic[2];
+ sigset_t sigmask, oldmask;
+
+ if (!mode || *mode != 'r')
+ goto out;
+
+ if ((in = (LZW_t*)malloc(sizeof(LZW_t))) == (LZW_t*)0)
+ goto err;
+ memset(in, 0, sizeof(LZW_t));
+
+ if ((in->inbuf = (uint8_t*)malloc(sizeof(uint8_t)*(INBUFSIZ))) == (uint8_t*)0)
+ goto err;
+ if ((in->outbuf = (uint8_t*)malloc(sizeof(uint8_t)*(OUTBUFSIZ+OUTBUF_EXTRA))) == (uint8_t*)0)
+ goto err;
+ if ((in->d_buf = (uint16_t*)malloc(sizeof(uint16_t)*DIST_BUFSIZE)) == (uint16_t*)0)
+ goto err;
+ if ((in->tab_suffix = (uint8_t*) malloc(sizeof(uint8_t )*(2L*WSIZE))) == (uint8_t*)0)
+ goto err;
+ if ((in->tab_prefix = (uint16_t*)malloc(sizeof(uint16_t)*(1<<(BITS)))) == (uint16_t*)0)
+ goto err;
+ if ((in->ifname = strdup(path)) == (char*)0)
+ goto err;
+ if ((in->ifd = open(in->ifname, O_RDONLY)) < 0)
+ goto err;
+
+ if ((in->stack = (uint8_t*)malloc(STACK_SIZE)) == (uint8_t*)0)
+ goto err;
+ if ((in->uc = (ucontext_t*)malloc(2*sizeof(ucontext_t))) == (ucontext_t*)0)
+ goto err;
+ if (getcontext(&in->uc[1]) < 0)
+ goto err;
+ in->uc[1].uc_link = &in->uc[0];
+ in->uc[1].uc_stack.ss_sp = in->stack;
+ in->uc[1].uc_stack.ss_size = STACK_SIZE;
+ if (sigucmask(SIG_SETMASK, (sigset_t*)0, &sigmask) < 0)
+ goto err;
+ if (sigaddset(&sigmask, SIGINT) < 0)
+ goto err;
+ if (sigaddset(&sigmask, SIGQUIT) < 0)
+ goto err;
+#if defined(__ia64__) /* On ia64 the type of uc_sigmask is ulong not sigset_t */
+ in->uc[1].uc_sigmask = sig_ia64_mask(sigmask);
+#else
+ in->uc[1].uc_sigmask = sigmask;
+#endif
+ makecontext(&in->uc[1], (void(*)(void))unlzw, 1, in);
+
+ sigucmask(SIG_SETMASK, &sigmask, &oldmask);
+ magic[0] = get_byte(in);
+ magic[1] = get_byte(in);
+ sigucmask(SIG_SETMASK, &oldmask, &sigmask);
+
+ if (memcmp(magic, LZW_MAGIC, sizeof(magic)))
+ goto err;
+
+ in->n.block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */
+ in->rsize = in->insize;
+
+ in->n.maxbits = get_byte(in);
+ in->n.block_mode = in->n.maxbits & BLOCK_MODE;
+
+ if ((in->n.maxbits & LZW_RESERVED) != 0) {
+ fprintf(stderr, "%s: warning, unknown flags 0x%x\n",
+ in->ifname, in->n.maxbits & LZW_RESERVED);
+ }
+ in->n.maxbits &= BIT_MASK;
+ in->n.maxmaxcode = MAXCODE(in->n.maxbits);
+
+ if (in->n.maxbits > BITS) {
+ fprintf(stderr, "%s: compressed with %d bits, can only handle %d bits\n",
+ in->ifname, in->n.maxbits, BITS);
+ goto err;
+ }
+
+ in->n.maxcode = MAXCODE(in->n.n_bits = INIT_BITS)-1;
+ in->n.bitmask = (1<<in->n.n_bits)-1;
+ in->n.oldcode = -1;
+ in->n.finchar = 0;
+ in->n.posbits = in->inptr<<3;
+
+ in->n.free_ent = ((in->n.block_mode) ? FIRST : 256);
+
+ clear_tab_prefixof(in); /* Initialize the first 256 entries in the table. */
+
+ for (in->n.code = 255 ; in->n.code >= 0 ; --in->n.code) {
+ tab_suffixof(in->n.code) = (uint8_t)in->n.code;
+ }
+out:
+ return in;
+err:
+ closelzw(in);
+ return (LZW_t*)0;
+}
+
+/*
+ * New function, simply to free all allocated objects in
+ * reverse order and close the input file.
+ */
+void closelzw(LZW_t * in)
+{
+ if (in == (LZW_t*)0)
+ return;
+ if (in->uc) free(in->uc);
+ if (in->stack) free(in->stack);
+ if (in->ifd >= 0) close(in->ifd);
+ if (in->ifname) free(in->ifname);
+ if (in->tab_prefix) free(in->tab_prefix);
+ if (in->tab_suffix) free(in->tab_suffix);
+ if (in->d_buf) free(in->d_buf);
+ if (in->outbuf) free(in->outbuf);
+ if (in->inbuf) free(in->inbuf);
+ free(in);
+ in = (LZW_t*)0;
+}
+
+/*
+ * Adopted from gzip version 1.3.7 unlzw.c
+ * This is mainly the body of the old unlzw() which is its main loop.
+ */
+static void unlzw(LZW_t *in)
+{
+ do {
+ int i;
+ int e;
+ int o;
+
+ resetbuf:
+ e = in->insize - (o = (in->n.posbits>>3));
+
+ for (i = 0 ; i < e ; ++i) {
+ in->inbuf[i] = in->inbuf[i+o];
+ }
+ in->insize = e;
+ in->n.posbits = 0;
+
+ if (in->insize < INBUF_EXTRA) {
+ do {
+ in->rsize = read(in->ifd, in->inbuf + in->insize, INBUFSIZ - in->insize);
+ if (in->rsize < 0) {
+ if (errno == EINTR)
+ continue;
+ perror(in->ifname);
+ break;
+ }
+ if (in->rsize == 0)
+ break;
+ in->insize += in->rsize;
+ } while (in->insize < INBUFSIZ);
+ in->bytes_in += (off_t)in->insize;
+ }
+ in->n.inbits = ((in->rsize != 0) ? ((long)in->insize - in->insize%in->n.n_bits)<<3 :
+ ((long)in->insize<<3)-(in->n.n_bits-1));
+
+ while (in->n.inbits > in->n.posbits) {
+ if (in->n.free_ent > in->n.maxcode) {
+ in->n.posbits = ((in->n.posbits-1) +
+ ((in->n.n_bits<<3)-(in->n.posbits-1+(in->n.n_bits<<3))%(in->n.n_bits<<3)));
+ ++in->n.n_bits;
+ if (in->n.n_bits == in->n.maxbits) {
+ in->n.maxcode = in->n.maxmaxcode;
+ } else {
+ in->n.maxcode = MAXCODE(in->n.n_bits)-1;
+ }
+ in->n.bitmask = (1<<in->n.n_bits)-1;
+ goto resetbuf;
+ }
+ input(in->inbuf,in->n.posbits,in->n.code,in->n.n_bits,in->n.bitmask);
+
+ if (in->n.oldcode == -1) {
+ if (256 <= in->n.code)
+ fprintf(stderr, "%s: corrupt input.\n", in->ifname);
+ in->outbuf[in->outpos++] = (uint8_t)(in->n.finchar = (int)(in->n.oldcode=in->n.code));
+ continue;
+ }
+ if (in->n.code == CLEAR && in->n.block_mode) {
+ clear_tab_prefixof(in);
+ in->n.free_ent = FIRST - 1;
+ in->n.posbits = ((in->n.posbits-1) +
+ ((in->n.n_bits<<3)-(in->n.posbits-1+(in->n.n_bits<<3))%(in->n.n_bits<<3)));
+ in->n.maxcode = MAXCODE(in->n.n_bits = INIT_BITS)-1;
+ in->n.bitmask = (1<<in->n.n_bits)-1;
+ goto resetbuf;
+ }
+ in->n.incode = in->n.code;
+ in->n.stackp = de_stack;
+
+ if (in->n.code >= in->n.free_ent) { /* Special case for KwKwK string. */
+ if (in->n.code > in->n.free_ent) {
+#ifdef DEBUG
+ uint8_t *p;
+ in->n.posbits -= in->n.n_bits;
+ p = &in->inbuf[in->n.posbits>>3];
+ fprintf(stderr,
+ "code:%ld free_ent:%ld n_bits:%d insize:%lu\n",
+ in->n.code, in->n.free_ent, in->n.n_bits, in->insize);
+ fprintf(stderr,
+ "posbits:%ld inbuf:%02X %02X %02X %02X %02X\n",
+ in->n.posbits, p[-1],p[0],p[1],p[2],p[3]);
+#endif
+ if (in->outpos > 0) {
+ write_buf(in, in->outbuf, in->outpos);
+ in->bytes_out += (off_t)in->outpos;
+ in->outpos = 0;
+ }
+ fprintf(stderr, "%s: corrupt input.\n", in->ifname);
+ }
+ *--in->n.stackp = (uint8_t)in->n.finchar;
+ in->n.code = in->n.oldcode;
+ }
+
+ /* Generate output characters in reverse order */
+ while ((uint32_t)in->n.code >= (uint32_t)256) {
+ *--in->n.stackp = tab_suffixof(in->n.code);
+ in->n.code = tab_prefixof(in->n.code);
+ }
+ *--in->n.stackp = (uint8_t)(in->n.finchar = tab_suffixof(in->n.code));
+
+ /* And put them out in forward order */
+ if (in->outpos + (in->n.newdif = (de_stack - in->n.stackp)) >= OUTBUFSIZ) {
+ do {
+ if (in->n.newdif > OUTBUFSIZ - in->outpos)
+ in->n.newdif = OUTBUFSIZ - in->outpos;
+
+ if (in->n.newdif > 0) {
+ memcpy(in->outbuf + in->outpos, in->n.stackp, in->n.newdif);
+ in->outpos += in->n.newdif;
+ }
+ if (in->outpos >= OUTBUFSIZ) {
+ write_buf(in, in->outbuf, in->outpos);
+ in->bytes_out += (off_t)in->outpos;
+ in->outpos = 0;
+ }
+ in->n.stackp+= in->n.newdif;
+ } while ((in->n.newdif = (de_stack - in->n.stackp)) > 0);
+ } else {
+ memcpy(in->outbuf + in->outpos, in->n.stackp, in->n.newdif);
+ in->outpos += in->n.newdif;
+ }
+
+ if ((in->n.code = in->n.free_ent) < in->n.maxmaxcode) { /* Generate the new entry. */
+
+ tab_prefixof(in->n.code) = (uint16_t)in->n.oldcode;
+ tab_suffixof(in->n.code) = (uint8_t)in->n.finchar;
+ in->n.free_ent = in->n.code+1;
+ }
+ in->n.oldcode = in->n.incode; /* Remember previous code. */
+ }
+ } while (in->rsize != 0);
+
+ if (in->outpos > 0) {
+ write_buf(in, in->outbuf, in->outpos);
+ in->bytes_out += (off_t)in->outpos;
+ in->tsize = EOF;
+ in->outpos = 0;
+ }
+}
+
+/*
+ * New function, simply to read from the output buffer of unlzw().
+ * We do this by switching into the context of unlzw() and back
+ * to our old context if the provided buffer is filled.
+ */
+ssize_t readlzw(LZW_t * in, char* buffer, const size_t size)
+{
+ in->transfer = (uint8_t*)buffer;
+ in->tcount = size;
+ in->tsize = 0;
+ if (in->uc == (ucontext_t*)0)
+ return 0; /* For (f)lex scanner ... */
+ swapcontext(&in->uc[0], &in->uc[1]);
+ if (in->tsize < 0) {
+ free(in->uc); /* ... do not enter next */
+ in->uc = (ucontext_t*)0;
+ free(in->stack);
+ in->stack = (uint8_t*)0;
+ return 0;
+ }
+ return in->tsize;
+}
+
+#ifdef TEST
+int main()
+{
+ ssize_t len;
+ char buffer[1024];
+
+ LZW_t *lzw = openlzw("man.1.Z", "r");
+ if (!lzw)
+ return -1;
+
+ do {
+ len = readlzw(lzw, &buffer[0], sizeof(buffer));
+ write(1, &buffer[0], len);
+ } while (len != 0);
+
+ closelzw(lzw);
+ return 0;
+}
+#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/libzio-0.2/zio.c new/libzio-0.3/zio.c
--- old/libzio-0.2/zio.c 2004-04-26 11:25:12.000000000 +0200
+++ new/libzio-0.3/zio.c 2006-12-13 18:26:42.000000000 +0100
@@ -11,8 +11,21 @@
* Author: Werner Fink <werner(a)suse.de>
*/
+#define USE_PIPE_4LZW 0
+
#include "zioP.h"
#include "zio.h"
+#if defined(USE_PIPE_4LZW) && (USE_PIPE_4LZW == 1)
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/wait.h>
+ typedef struct LZW_s {
+ int lfd;
+ pid_t lpid;
+ } LZW_t;
+#else
+# include "lzw.h"
+#endif
static ssize_t zread(void *cookie, char *buf, size_t count)
{
@@ -72,6 +85,56 @@
.close = (cookie_close_function_t*)bzclose,
};
+static ssize_t lzwread(void *cookie, char *buf, size_t count)
+{
+#if defined(USE_PIPE_4LZW) && (USE_PIPE_4LZW == 1)
+ ssize_t ret = 0;
+ do {
+ ret = read(((LZW_t*)cookie)->lfd, buf, count);
+ } while ((ret < 0) && (errno == EINTR));
+ return ret;
+#else
+ return readlzw((LZW_t*)cookie, buf, count);
+#endif
+}
+
+static ssize_t lzwwrite(void *cookie, const char *buf, size_t count)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+static int lzwseek(void *cookie, off_t offset, int whence)
+{
+ errno = ESPIPE;
+ return -1;
+}
+
+static int lzwclose(void *cookie)
+{
+#if defined(USE_PIPE_4LZW) && (USE_PIPE_4LZW == 1)
+ int wstatus, status = close(((LZW_t*)cookie)->lfd);
+ pid_t wpid;
+ do {
+ wpid = waitpid(((LZW_t*)cookie)->lpid, &wstatus, 0);
+ } while ((wpid < 0) && (errno == EINTR));
+ if ((wpid < 0) || (wstatus != 0))
+ status = -1;
+ free(cookie);
+ return (status >= 0) ? 0 : EOF;
+#else
+ closelzw((LZW_t*)cookie);
+ return 0;
+#endif
+}
+
+static cookie_io_functions_t iolzw = {
+ .read = (cookie_read_function_t*) lzwread,
+ .seek = (cookie_seek_function_t*) lzwseek,
+ .write = (cookie_write_function_t*)lzwwrite,
+ .close = (cookie_close_function_t*)lzwclose,
+};
+
FILE * fzopen(const char *path, const char *mode)
{
FILE * ret = (FILE *)0;
@@ -113,10 +176,12 @@
goto out;
}
- if (strcasecmp(path + len - 2, ".z" ) == 0)
+ if (strcmp(path + len - 2, ".z" ) == 0)
what = 'z';
else if (strcmp(path + len - 3, ".gz" ) == 0)
- what = 'z';
+ what = 'g';
+ else if (strcmp(path + len - 3, ".Z" ) == 0)
+ what = 'Z';
else if (strcmp(path + len - 4, ".bz2") == 0)
what = 'b';
@@ -131,7 +196,7 @@
olderr = errno;
if (stat(strcat(ext, ".gz"), &st) == 0) {
- what = 'z';
+ what = 'g';
goto skip;
}
*(ext + len) = '\0';
@@ -140,21 +205,25 @@
goto skip;
}
*(ext + len) = '\0';
- if (stat(strcat(ext, ".Z"), &st) == 0) {
+ if (stat(strcat(ext, ".z"), &st) == 0) {
what = 'z';
goto skip;
}
*(ext + len) = '\0';
- if (stat(strcat(ext, ".z"), &st) == 0) {
- what = 'z';
+ if (stat(strcat(ext, ".Z"), &st) == 0) {
+ what = 'Z';
goto skip;
}
*(ext + len) = '\0';
- if ((fd = open(ext, O_RDONLY)) < 0)
+ if ((fd = open(ext, O_RDONLY|O_NOCTTY)) < 0)
goto skip;
if (read(fd, m, sizeof(m)) == sizeof(m)) {
- if (m[0] == '\037' && (m[1] == '\213' || m[1] == '\235'))
+ if (m[0] == '\037' && m[1] == '\213')
+ what = 'g';
+ if (m[0] == '\037' && m[1] == '\235')
+ what = 'Z';
+ if (m[0] == '\037' && m[1] == '\236')
what = 'z';
else if (m[0] == 'B' && m[1] == 'Z' && m[2] == 'h')
what = 'b';
@@ -167,7 +236,8 @@
ext = (char *)path;
switch (what) {
- case 'z':
+ case 'g':
+ case 'z': /* Is this correct? Old gzip magic */
{
gzFile cookie = (gzFile)0;
@@ -182,9 +252,87 @@
goto out;
}
- if (!(ret = fopencookie(cookie, check, ioz)))
+ if (!(ret = fopencookie(cookie, check, ioz))) {
+ gzclose(cookie);
+ errno = EINVAL;
+ goto out;
+ }
+#ifndef LIBIO_IS_FIXED
+ if (ret->_fileno < 0)
+ ret->_fileno = 0;
+#endif
+ }
+ break;
+ case 'Z':
+ {
+ LZW_t *cookie;
+#if defined(USE_PIPE_4LZW) && (USE_PIPE_4LZW == 1)
+ int pfd[2];
+
+ if (*mode != 'r') {
+ errno = ENOTSUP;
+ goto out;
+ }
+
+ if ((cookie = (LZW_t*)malloc(sizeof(LZW_t))) == (LZW_t*)0)
+ goto out;
+
+ if (pipe(pfd) < 0) {
+ if (!errno)
+ errno = EINVAL;
+ goto out;
+ }
+
+ switch ((cookie->lpid = fork())) {
+ case -1:
+ close(pfd[0]);
+ close(pfd[1]);
+ goto out;
+ case 0:
+ (void)signal(SIGINT, SIG_DFL);
+ (void)signal(SIGQUIT, SIG_DFL);
+ (void)signal(SIGSEGV, SIG_DFL);
+ (void)signal(SIGTERM, SIG_DFL);
+
+ close(pfd[0]);
+ if (pfd[1] != 1) {
+ if (dup2(pfd[1], 1) < 0)
+ exit(127);
+ close(pfd[1]);
+ }
+
+ execl("/bin/gzip", "gzip", "-dfcq", ext, (char*)0);
+ exit(127);
+ default:
+ close(pfd[1]);
+ cookie->lfd = pfd[0];
+ break;
+ }
+
+ if (!(ret = fopencookie(cookie, check, iolzw))) {
+ close(pfd[0]);
+ free(cookie);
errno = EINVAL;
+ goto out;
+ }
+#else
+ if (*mode != 'r') {
+ errno = ENOTSUP;
+ goto out;
+ }
+ if (!(cookie = openlzw(ext, mode))) {
+ if (!errno)
+ errno = ENOMEM;
+ goto out;
+ }
+
+ if (!(ret = fopencookie(cookie, check, iolzw))) {
+ closelzw(cookie);
+ errno = EINVAL;
+ goto out;
+ }
+#endif
#ifndef LIBIO_IS_FIXED
if (ret->_fileno < 0)
ret->_fileno = 0;
@@ -206,9 +354,11 @@
goto out;
}
- if (!(ret = fopencookie(cookie, check, iobz)))
+ if (!(ret = fopencookie(cookie, check, iobz))) {
+ BZ2_bzclose(cookie);
errno = EINVAL;
-
+ goto out;
+ }
#ifndef LIBIO_IS_FIXED
if (ret->_fileno < 0)
ret->_fileno = 0;
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: opensuse-commit+help(a)opensuse.org