/***********************************************************************1* *2* This software is part of the zlib package *3* Copyright (c) 1996-2003 Jean-loup Gailly and Mark Adler *4* *5* This software is provided 'as-is', without any express or implied *6* warranty. In no event will the authors be held liable for any *7* damages arising from the use of this software. *8* *9* Permission is granted to anyone to use this software for any *10* purpose, including commercial applications, and to alter it and *11* redistribute it freely, subject to the following restrictions: *12* *13* 1. The origin of this software must not be misrepresented; *14* you must not claim that you wrote the original software. If *15* you use this software in a product, an acknowledgment in the *16* product documentation would be appreciated but is not *17* required. *18* *19* 2. Altered source versions must be plainly marked as such, *20* and must not be misrepresented as being the original *21* software. *22* *23* 3. This notice may not be removed or altered from any source *24* distribution. *25* *26* This software is provided "as-is", without any express or implied *27* warranty. In no event will the authors be held liable for any damages*28* arising from the use of this software. *29* *30* Permission is granted to anyone to use this software for any purpose,*31* including commercial applications, and to alter it and redistribute i*32* freely, subject to the following restrictions: *33* *34* 1. The origin of this software must not be misrepresented; you must n*35* claim that you wrote the original software. If you use this softwa*36* in a product, an acknowledgment in the product documentation would*37* be appreciated but is not required. *38* *39* 2. Altered source versions must be plainly marked as such, and must n*40* be misrepresented as being the original software. *41* *42* 3. This notice may not be removed or altered from any source *43* distribution. *44* *45* Julian R Seward *46* *47***********************************************************************/48#pragma prototyped4950/*51* sfio bzip discipline52*/5354#include <sfio_t.h>55#include <ast.h>56#include <bzlib.h>57#include <sfdcbzip.h>5859#define bzsync(p,o) (-1)6061typedef struct62{63Sfdisc_t disc; /* sfio discipline */64Bz_t* bz; /* bz handle */65} Sfbzip_t;6667/*68* bzip exception handler69* free on close70*/7172static int73sfbzexcept(Sfio_t* sp, int op, void* val, Sfdisc_t* dp)74{75register Sfbzip_t* bz = (Sfbzip_t*)dp;76int r;7778NoP(sp);79#if 180{81static char aha[] = "AHA sfdcbzip event 0\n";82static int init;8384if (!init)85init = getenv("SFBZ_DEBUG") ? 1 : -1;86if (init > 0)87{88aha[sizeof(aha) - 3] = '0' + op;89write(2, aha, sizeof(aha) - 1);90}91}92#endif93switch (op)94{95case SF_ATEXIT:96sfdisc(sp, SF_POPDISC);97return 0;98case SF_CLOSING:99case SF_DPOP:100case SF_FINAL:101if (bz->bz)102{103r = bzclose(bz->bz) ? -1 : 0;104bz->bz = 0;105}106else107r = 0;108if (op != SF_CLOSING)109free(dp);110return r;111case SF_DBUFFER:112return 1;113case SF_READ:114case SF_WRITE:115return *((ssize_t*)val) < 0 ? -1 : 0;116case SF_SYNC:117return val ? 0 : bzflush(bz->bz);118case SFBZ_HANDLE:119return (*((Bz_t**)val) = bz->bz) ? 1 : -1;120case SFBZ_GETPOS:121return (*((Sfoff_t*)val) = bzsync(bz->bz, (z_off_t)(-1))) == -1 ? -1 : 0;122case SFBZ_SETPOS:123return bzsync(bz->bz, (z_off_t)(*((Sfoff_t*)val))) == -1 ? -1 : 0;124}125return 0;126}127128/*129* sfio bzip discipline read130*/131132static ssize_t133sfbzread(Sfio_t* fp, Void_t* buf, size_t size, Sfdisc_t* dp)134{135register Sfbzip_t* bz = (Sfbzip_t*)dp;136137return bzread(bz->bz, buf, size);138}139140/*141* sfio bzip discipline write142*/143144static ssize_t145sfbzwrite(Sfio_t* fp, const Void_t* buf, size_t size, Sfdisc_t* dp)146{147register Sfbzip_t* bz = (Sfbzip_t*)dp;148149return (bzwrite(bz->bz, (void*)buf, size) < 0) ? -1 : size;150}151152/*153* create and push the sfio bzip discipline154*155* (flags&SFBZ_VERIFY) return156* >0 is a bzip file157* 0 not a bzip file158* <0 error159* otherwise return160* >0 discipline pushed161* 0 discipline not needed162* <0 error163*/164165int166sfdcbzip(Sfio_t* sp, int flags)167{168char* m;169Sfbzip_t* bz;170char mode[10];171172if (sfset(sp, 0, 0) & SF_READ)173{174register unsigned char* s;175register int n;176177/*178* peek the first 4 bytes to verify the magic179*180* BZh[0-9] sfdcbzip bzip181*/182183if (!(n = sfset(sp, 0, 0) & SF_SHARE))184sfset(sp, SF_SHARE, 1);185s = (unsigned char*)sfreserve(sp, 4, 1);186if (!n)187sfset(sp, SF_SHARE, 0);188if (!s)189return -1;190n = s[0] == 'B' && s[1] == 'Z' && s[2] == 'h' && (s[3] >= '0' && s[3] <= '9');191sfread(sp, s, 0);192if (!n || (flags & SFBZ_VERIFY))193return n;194}195else if (flags & SFBZ_VERIFY)196return -1;197if (!(bz = newof(0, Sfbzip_t, 1, 0)))198return -1;199bz->disc.exceptf = sfbzexcept;200if (sfset(sp, 0, 0) & SF_READ)201bz->disc.readf = sfbzread;202else203bz->disc.writef = sfbzwrite;204m = mode;205*m++ = (sfset(sp, 0, 0) & SF_READ) ? 'r' : 'w';206*m++ = 'o';207if ((flags &= 0xf) > 0 && flags <= 9)208*m++ = '0' + flags;209*m = 0;210if (sfdisc(sp, &bz->disc) != &bz->disc || !(bz->bz = bzdopen(sffileno(sp), mode)))211{212free(bz);213return -1;214}215sfsetbuf(sp, NiL, SF_BUFSIZE);216if (!(sfset(sp, 0, 0) & SF_READ))217sfset(sp, SF_IOCHECK, 1);218return 1;219}220221222