Makefile | 28 ++++++++++++++++------- testw.c | 41 +++++++++++++++++++++++++++++++++++ zio.c | 72 ++++++++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 107 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 604b655..ab8bb32 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ FILES = README \ zio.h.in \ testt.c \ tests.c \ + testw.c \ lzw.h \ unlzw.c \ zio.map \ @@ -62,8 +63,8 @@ endif all: shared static noweak: CFLAGS += -DNO_WEAK noweak: LINK += $(LIBS) -noweak: all -shared: libzio.so.$(VERSION) zio.map +noweak: shared +shared: libzio.so zio.map static: libzio.a obj/zio.o: zio.c zioP.h zio.h @@ -89,6 +90,12 @@ libzio.a: obj/zio.o obj/unlzw.o libzio.so.$(VERSION): obs/zio.o obs/unlzw.o gcc -shared -Wl,-soname,$(SONAME),-stats $(LDMAP) -o $@ $^ $(LINK) +$(SONAME): libzio.so.$(VERSION) + ln -sf libzio.so.$(VERSION) $(SONAME) + +libzio.so: $(SONAME) + ln -sf $(SONAME) libzio.so + zioP.h: /usr/include/bzlib.h /usr/include/zlib.h zio.h: zio.h.in /usr/include/stdio.h sed 's/@@VERSION@@/$(VERSION)/' < $< > $@ @@ -102,8 +109,8 @@ install: install-shared install-static install-data install-shared: libzio.so.$(VERSION) mkdir -p $(DESTDIR)$(libdir) install -m 0755 libzio.so.$(VERSION) $(DESTDIR)$(libdir)/ - ln -sf libzio.so.$(VERSION) $(DESTDIR)$(libdir)/libzio.so.$(MAJOR) - ln -sf libzio.so.$(MAJOR) $(DESTDIR)$(libdir)/libzio.so + ln -sf libzio.so.$(VERSION) $(DESTDIR)$(libdir)/$(SONAME) + ln -sf $(SONAME) $(DESTDIR)$(libdir)/libzio.so install-static: libzio.a mkdir -p $(DESTDIR)$(libdir) @@ -116,7 +123,7 @@ install-data: zio.h fzopen.3 install -m 0644 fzopen.3 $(DESTDIR)$(mandir)/man3/ clean: - rm -f *.a *.so* testt tests zio.h + rm -f *.a *.so* testt tests testw zio.h rm -rf obj/ obs/ rm -f libzio-$(VERSION).tar.gz @@ -126,8 +133,11 @@ dest: clean tar czf libzio-$(VERSION).tar.gz libzio-$(VERSION)/ rm -rf libzio-$(VERSION)/ -testt: testt.c libzio.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) +testt: testt.c libzio.so + $(CC) $(CFLAGS) -o $@ $^ -L. -lzio + +tests: tests.c libzio.so + $(CC) $(CFLAGS) -o $@ $^ -L. -lzio -tests: tests.c libzio.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) +testw: testw.c libzio.so + $(CC) $(CFLAGS) -o $@ $^ -L. -lzio diff --git a/testw.c b/testw.c new file mode 100644 index 0000000..93b8d30 --- /dev/null +++ b/testw.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include "zio.h" + +int main(int argc, char *argv[]) +{ + int rc = 0; + + while (argc > 1) { + FILE *file; + char line[1024]; + size_t len; + + argv++; + argc--; + + if (!(file = fzopen(*argv, "w"))) { + fprintf(stderr, "fzopen: %s: %s\n", *argv, strerror(errno)); + continue; + } + + while ((len = fread(line, sizeof(char), sizeof (line), stdin))) { + size_t ret = fwrite(line, sizeof(char), len, file); + if ((ret != len)) { + rc = 1; + fprintf(stderr, "fwrite: %s: %zu < %zu: %s\n", + *argv, ret, len, strerror(errno)); + break; + } + } + + if (fclose(file)) { + rc = 1; + fprintf(stderr, "fclose: %s: %s\n", *argv, strerror(errno)); + } + } + + return rc; +} diff --git a/zio.c b/zio.c index 95788d2..78e6769 100644 --- a/zio.c +++ b/zio.c @@ -104,7 +104,7 @@ static ssize_t bzwrite(void *cookie, const char *buf, size_t count) if (!bzf) goto out; if (bzf->file) - len = (ssize_t)BZ2_bzread(bzf->file, (void*)buf, count); + len = (ssize_t)BZ2_bzwrite(bzf->file, (void*)buf, count); if (len > 0) bzf->total_out += len; out: @@ -310,7 +310,7 @@ static ssize_t lzmawrite(void *cookie, const char *buf, size_t count) if (len && fwrite(lzma->buf, 1, len, lzma->file) != len) break; if (strm->avail_in == 0) - return len; + return count; } return -1; } @@ -584,12 +584,55 @@ static cookie_io_functions_t iolzw = { .close = (cookie_close_function_t*)&lzwclose, }; +static char +guess_by_magic(const char *path) +{ + char what = 'n'; + int fd; + int olderr = errno; + + if ((fd = open(path, O_RDONLY|O_NOCTTY)) < 0) { + errno = olderr; + return what; + } + + char m[5]; + + if (read(fd, m, sizeof(m)) == sizeof(m)) { + if (m[0] == '\037' && m[1] == '\213') + what = 'g'; + else if (m[0] == '\037' && m[1] == '\235') + what = 'Z'; + else if (m[0] == '\037' && m[1] == '\236') + what = 'z'; + else if (m[0] == 'B' && m[1] == 'Z' && m[2] == 'h') + what = 'b'; + else if (m[0] == ']' && m[1] == '\0' && m[2] == '\0' && m[3] == '\200') /* weak!! */ + what = 'l'; + else if (m[0] == '\377' && m[1] == 'L' && m[2] == 'Z' && m[3] == 'M' && m[4] == 'A') + what = 'l'; + else if (m[0] == '\375' && m[1] == '7' && m[2] == 'z' && m[3] == 'X' && m[4] == 'Z') + what = 'x'; + } + + close(fd); + errno = olderr; + return what; +} + static inline char autodetect(char **__restrict path, const char *__restrict check) { + char what = 'n'; + + if (*check == 'r') { + what = guess_by_magic(*path); + if (what != 'n') + return what; + } + const size_t len = strlen(*path); char *suff = strrchr(*path, '.'); char *ext = *path; - char what = 'n'; if (suff) { suff++; @@ -608,9 +651,8 @@ static inline char autodetect(char **__restrict path, const char *__restrict che } if (what == 'n' && *check == 'r') { - int olderr, fd; + int olderr; struct stat st; - char m[5]; ext = malloc(sizeof(char)*(len + 5 + 1)); if (!ext) goto out; @@ -648,26 +690,6 @@ static inline char autodetect(char **__restrict path, const char *__restrict che goto skip; } *suff = '\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') - 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'; - else if (m[0] == ']' && m[1] == '\0' && m[2] == '\0' && m[3] == '\200') /* weak!! */ - what = 'l'; - else if (m[0] == '\377' && m[1] == 'L' && m[2] == 'Z' && m[3] == 'M' && m[4] == 'A') - what = 'l'; - else if (m[0] == '\375' && m[1] == '7' && m[2] == 'z' && m[3] == 'X' && m[4] == 'Z') - what = 'x'; - } - close(fd); skip: errno = olderr; }