/** * @file utils.h Zlib module utility functions * * $Id: utils.h,v 1.6 2003/01/01 06:22:34 chipx86 Exp $ * * @Copyright (C) 2001-2003 The GNUpdate Project. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _MOD_ZLIB_UTILS_H_ #define _MOD_ZLIB_UTILS_H_ #include #include /* * Some code was borrowed from zlib, as zlib does not provide public * functions for retrieving the information we need. zlib's copyright * notice is shown below: * * zlib.h -- interface of the 'zlib' general purpose compression library * version 1.1.3, July 9th, 1998 * * Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * Jean-loup Gailly Mark Adler * jloup@gzip.org madler@alumni.caltech.edu * * * The data format used by the zlib library is described by RFCs (Request for * Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt * (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ /* A copy of the gz_stream struct in zlib. */ typedef struct { z_stream stream; int z_err; /* error code for last stream operation */ int z_eof; /* set if end of input file */ FILE *file; /* .gz file */ Byte *inbuf; /* input buffer */ Byte *outbuf; /* output buffer */ uLong crc; /* crc32 of uncompressed data */ char *msg; /* error message */ char *path; /* path name for debugging only */ int transparent; /* 1 if input file is not a .gz file */ char mode; /* 'w' or 'r' */ long startpos; /* start of compressed data in file */ /* (header skipped) */ } _gz_stream; /* Macros for getting two-byte and four-byte header values. */ #define SH(p) ((unsigned short)(unsigned char)((p)[0]) | \ ((unsigned short)(unsigned char)((p)[1]) << 8)) #define LG(p) ((unsigned long)(SH(p)) | ((unsigned long)(SH((p)+2)) << 16)) #define tolow(c) (isupper(c) ? (c) - 'A' + 'a' : (c)) static char * __strlwr(char *s) { char *t; for (t = s; *t; t++) *t = tolow(*t); return s; } /* * XXX I am almost certain that this function is wrong! */ static long __getTotalFileSize(FILE *fp) { long bytesIn; long bytesOut = -1L; bytesIn = (long)gzseek(fp, (off_t)(-8), SEEK_END); if (bytesIn != -1L) { unsigned char buf[8]; bytesIn += 8L; if (fread((char *)buf, sizeof(unsigned char), sizeof(buf), fp) != sizeof(buf)) { return -1; /* Read error. */ } bytesOut = LG(buf + 4); } return bytesOut; } /* XXX zlib's tailor.h does more than this. */ #define MAX_SUFFIX 30 /* XXX BAD BAD BAD! Don't assume, check in configure.in! */ #define PATH_SEP '/' #define MAX_PATH_LEN 260 static char * __getSuffix(char *name) { int nlen, slen; char suffix[MAX_SUFFIX + 3]; /* last chars of name, forced to lower case. */ static char *knownSuffixes[] = { ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z", "z", NULL }; char **suf = knownSuffixes; /* XXX Strip a version number from the filename here! */ nlen = strlen(name); if (nlen < MAX_SUFFIX + 2) strcpy(suffix, name); else strcpy(suffix, name + nlen - MAX_SUFFIX - 2); __strlwr(suffix); slen = strlen(suffix); do { int s = strlen(*suf); if (slen > s && suffix[slen - s - 1] != PATH_SEP && !strcmp(suffix + slen - s, *suf)) { return name + nlen - s; } } while (*++suf != NULL); return NULL; } static char * __makeOutputFilename(const char *ifname) { char ofname[MAX_PATH_LEN]; char *suff; /* ofname z suffix */ if (ifname == NULL) return strdup("unknown"); strcpy(ofname, ifname); /* Strip a version number if any and get the gzip suffix if present: */ suff = __getSuffix(ofname); if (suff == NULL) { return strdup(ofname); /* return NULL; */ } /* Make a special case for .tgz and .taz: */ __strlwr(suff); if (!strcmp(suff, ".tgz") || !strcmp(suff, ".taz")) strcpy(suff, ".tar"); else *suff = '\0'; /* strip the z suffix */ return strdup(ofname); } #endif /* _MOD_ZLIB_UTILS_H_ */