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@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@suse.de +- Add support for the old LZW (.Z) format * Wed Jun 21 2006 - werner@suse.de - Remove self provide * Wed Jan 25 2006 - mls@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@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@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@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@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org