install-sh
ltmain.sh
missing
+release
+.*.swp
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
-INLINE_INHERITED_MEMB = NO
+INLINE_INHERITED_MEMB = YES
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = @top_srcdir@
+INPUT = @top_srcdir@/zipper.hh
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.
-GENERATE_HTMLHELP = NO
+GENERATE_HTMLHELP = YES
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
-GENERATE_CHI = NO
+GENERATE_CHI = YES
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
-GENERATE_LATEX = NO
+GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
-GENERATE_RTF = NO
+GENERATE_RTF = YES
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
-GENERATE_MAN = NO
+GENERATE_MAN = YES
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# generate an XML file that captures the structure of
# the code including all documentation.
-GENERATE_XML = NO
+GENERATE_XML = YES
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
// along with libzipper. If not, see <http://www.gnu.org/licenses/>.
#include "zipper.hh"
+#include "strerror.hh"
#include <cassert>
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <string.h>
#include <unistd.h>
using namespace zipper;
if (m_fd < 0)
{
- char buf[1024];
- strerror_r(errno, buf, sizeof(buf));
+ std::string errMsg(zipper::strerror(errno));
std::stringstream message;
message << "Could not open file \"" << filename << "\": " <<
- buf;
+ errMsg;
throw IOException(message.str());
}
initSize();
}
else if ((currentBytes < 0) && (errno != EINTR))
{
- char buf[1024];
- strerror_r(errno, buf, sizeof(buf));
- throw IOException(buf);
+ std::string errMsg(zipper::strerror(errno));
+ throw IOException(errMsg);
}
}
}
int errnoLocal = errno;
close();
- char buf[1024];
- strerror_r(errnoLocal, buf, sizeof(buf));
+ std::string errMsg(zipper::strerror(errnoLocal));
std::stringstream message;
message << "Could not get filesize for file " <<
- "\"" << m_filename << "\": " << buf;
+ "\"" << m_filename << "\": " << errMsg;
throw IOException(message.str());
}
else
// along with libzipper. If not, see <http://www.gnu.org/licenses/>.
#include "zipper.hh"
+#include "strerror.hh"
#include <algorithm>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <string.h>
#include <unistd.h>
using namespace zipper;
if (m_fd < 0)
{
- char buf[1024];
- strerror_r(errno, buf, sizeof(buf));
+ std::string errMsg(zipper::strerror(errno));
std::stringstream message;
message << "Could not open file \"" << filename << "\": " <<
- buf;
+ errMsg;
throw IOException(message.str());
}
}
}
else if ((currentBytes < 0) && (errno != EINTR))
{
- char buf[1024];
- strerror_r(errno, buf, sizeof(buf));
- throw IOException(buf);
+ std::string errMsg(zipper::strerror(errno));
+ throw IOException(errMsg);
}
}
}
--- /dev/null
+libzipper
+Michael McMaster <michael@codesrc.com>
+
+Pre-Requisites
+ g++ (4.5.3)
+ make (GNU make 3.81)
+ zlib (1.2.3)
+ doxygen (1.7.4)
+
+Optional
+ automake (1.11), autoconf (2.68), libtool (2.4)
+ (Required if building from git)
+
+ graphviz (2.26.3) (for dependency diagrams in the generated docs)
+
+When building from sources obtained from the git repository, the configure
+script must be created first using the autoconf/automake/libtool packages.
+The supplied autogen.sh script automates this process.
+
+*NOTE: it is not necessary to run the autogen.sh script when using a
+source distribution release. ie. If you obtained the sources via
+libzipper-major.minor.patch.tar.gz, do not run autogen.sh
+
+ ./autogen.sh
+
+The configure script creates the makefiles specific to your host. eg. It
+allows the paths to dependant packages to be specified.
+
+ ./configure --prefix=/usr
+
+The --prefix option specifies the base installation directory, and defaults
+to /usr/local (in which case, the library would be installed in /usr/local/lib,
+and the zipper binary would be installed in /usr/local/bin).
+
+To obtain a complete listing of configure options, use the --help option.
+
+ ./configure --help
+
+Once the configure script is run, the software can be compiled.
+
+ make
+
+Now it's time to install the software. This step must be run by a user with
+write access to the installation directory (/usr/local by default).
+
+ make install
+
dist_noinst_SCRIPTS = autogen.sh
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libzipper-1.0.pc
+pkgconfig_DATA = libzipper1.pc
EXTRA_DIST = \
- configure.ac \
- Makefile.am \
COPYING \
+ INSTALL \
NEWS \
README \
VERSION
gzip.cc \
gzip.hh \
Reader.cc \
+ split.hh \
+ strerror.cc \
+ strerror.hh \
util.hh \
Writer.cc \
zip.hh \
libzipper_la_LDFLAGS = ${ZLIB_LIBS} -version-info 1:0
libzipper_la_CFLAGS = ${ZLIB_CFLAGS}
-EXTRA_PROGRAMS = zipper
+bin_PROGRAMS = zipper
+man_MANS = zipper.1
zipper_SOURCES = \
zipper.cc
MOSTLYCLEANFILES=$(DX_CLEANFILES)
+install-data-local: doxygen-install
+all-local: doxygen-doc
+
+2011-05-22 Version 1.0.1
+ - Removed private classes from doxygen output
+ - Removed private symbols from shared library
+
2011-05-21 Version 1.0.0
- Initial release
libzipper
Michael McMaster <michael@codesrc.com>
-libzipper offers a flexible C++ interface for reading compressed files in
-multiple formats.
+libzipper offers a flexible C++ interface for reading and writing compressed
+files in multiple formats. It is intended for use in reading small compressed
+data files, such as configuration files and saved games.
-Supported Formats
- - raw (ie. not compressed)
- - gzip
- - zip
+libzipper currently supports plain, zip, and gzip formats.
-Missing Features
- - zip64 support
+libzipper is not a general-purpose archive management library, as it
+does not provide access to the filesystem attributes of each file.
+(ie. libzipper does not support the concepts of file owner, group,
+permissions, or timestamps.
-Requirements
- - zlib
+Missing Features
+ - zip64 support (for >4Gb zip files)
# along with libzipper. If not, see <http:#www.gnu.org/licenses/>.
SRC=`pwd`
-BUILD=`mktemp -d --tmpdir libzipper-debuild.XXXXXXXXXX`
+BUILD=/tmp/libzipper-build
+if [ -d $BUILD ]; then
+ rm -rf $BUILD/*
+else
+ mkdir $BUILD
+fi
VERSION=`cat VERSION`
cd ${BUILD}
$SRC/configure
make dist
-mv libzipper-${VERSION}.tar.gz libzipper_${VERSION}.orig.tar.gz
-tar xzvf libzipper_${VERSION}.orig.tar.gz
+cp libzipper-${VERSION}.tar.gz libzipper1_${VERSION}.orig.tar.gz
+tar xzvf libzipper1_${VERSION}.orig.tar.gz
cp -a ${SRC}/debian libzipper-${VERSION}
dpkg-source -b libzipper-${VERSION}/
+if [ ! -f ${BUILD}/libzipper1_${VERSION}*.dsc ]; then
+ echo "ERROR: Source package not created."
+ exit 1
+fi
# Remove intermediate results.
make distclean
rm -rf libzipper-${VERSION}/
# Now we have the source package, copy then build it
-tar xzvf libzipper_*.orig.tar.gz
+tar xzvf libzipper1_*.orig.tar.gz
cd libzipper-${VERSION}
-tar xzvf ../libzipper_*.debian.tar.gz
+tar xzvf ../libzipper1_*.debian.tar.gz
dpkg-buildpackage -rfakeroot -uc -b
-echo
+if ! lintian --color auto --fail-on-warnings -i ${BUILD}/libzipper1_1.0.1-1.dsc; then
+ echo "Build failed"
+ exit 1;
+elif ! lintian --color auto --fail-on-warnings -i ${BUILD}/libzipper1_1.0.1-1_amd64.changes; then
+ echo "Build failed"
+ exit 1;
+else
+ echo "Congratulations, your package is lintian clean"
+fi
+
+echo ------------------------------------------
+echo BUILD SUCCESS
+echo ------------------------------------------
echo
echo "Debian source package:"
-echo ${BUILD}/libzipper_*.orig.tar.gz
-echo ${BUILD}/libzipper_*.debian.tar.gz
-echo ${BUILD}/libzipper_*.dsc
+echo ${BUILD}/libzipper1_*.orig.tar.gz
+echo ${BUILD}/libzipper1_*.debian.tar.gz
+echo ${BUILD}/libzipper1_*.dsc
echo "Debian binary packages:"
-echo ${BUILD}/libzipper_*.deb
+echo ${BUILD}/libzipper1_*.deb
echo ${BUILD}/libzipper-dev_*.deb
+echo ${BUILD}/libzipper-tools_*.deb
+echo ${BUILD}/libzipper-doc_*.deb
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_HEADERS([autoconfig.h])
-AC_CONFIG_FILES([Makefile Doxyfile libzipper-1.0.pc])
+AC_CONFIG_FILES([Makefile Doxyfile libzipper1.pc zipper.1])
AM_MAINTAINER_MODE
-libzipper (1.0.0-1) unstable; urgency=low
+libzipper1 (1.0.1-1) unstable; urgency=low
+
+ * Fixed packaging to meet debian policy (renamed package, fixed shlibs file
+ and symlinks
+
+ -- Michael McMaster <michael@codesrc.com> Sat, 22 May 2011 21:48:11 +1000
+
+libzipper1 (1.0.0-1) unstable; urgency=low
* Initial release
-Source: libzipper
-Priority: extra
+Source: libzipper1
+Priority: optional
Maintainer: Michael McMaster <michael@codesrc.com>
-Build-Depends: debhelper (>= 7.0.50~), autotools-dev, cdbs, zlib1g-dev
-Standards-Version: 3.9.1
+Build-Depends: debhelper (>= 7.0.50~), autotools-dev, cdbs, zlib1g-dev, doxygen, graphviz
+Standards-Version: 3.9.2
Section: libs
Homepage: http://www.codesrc.com/src/libzipper
-#Vcs-Git: git://git.debian.org/collab-maint/libzipper.git
-#Vcs-Browser: http://git.debian.org/?p=collab-maint/libzipper.git;a=summary
+Vcs-Git: git://www.codesrc.com/git/libzipper
+Vcs-Browser: http://www.codesrc.com/gitweb/index.cgi?p=libzipper.git;a=summary
Package: libzipper-dev
Section: libdevel
Architecture: any
-Depends: libzipper (= ${binary:Version})
+Depends: libzipper1 (= ${binary:Version}), ${misc:Depends}
+Suggests: libzipper-doc
Homepage: http://www.codesrc.com/src/libzipper
-Description: A C++ interface for reading compressed.
- libzipper offers a flexible C++ interface for reading compressed files in
- multiple formats.
+Description: simple interface for reading and writing compressed files
+ libzipper offers a flexible C++ interface for reading and writing compressed
+ files in multiple formats. It is intended for use in reading small compressed
+ data files, such as configuration files and saved games.
+ .
+ libzipper currently supports plain, zip, and gzip formats.
+ .
+ This package includes the files necessary to build applications that make use
+ of libzipper.
-Package: libzipper
+Package: libzipper1
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
+Suggests: libzipper-tools
Homepage: http://www.codesrc.com/src/libzipper
-Description: A C++ interface for reading compressed.
- libzipper offers a flexible C++ interface for reading compressed files in
- multiple formats.
+Description: simple interface for reading and writing compressed files
+ libzipper offers a flexible C++ interface for reading and writing compressed
+ files in multiple formats. It is intended for use in reading small compressed
+ data files, such as configuration files and saved games.
+ .
+ libzipper currently supports plain, zip, and gzip formats.
+
+Package: libzipper-tools
+Section: utils
+Architecture: any
+Depends: libzipper1, ${shlibs:Depends}, ${misc:Depends}
+Homepage: http://www.codesrc.com/src/libzipper
+Description: utilities for reading and writing compressed files
+ libzipper offers a flexible C++ interface for reading and writing compressed
+ files in multiple formats. It is intended for use in reading small compressed
+ data files, such as configuration files and saved games.
+ .
+ libzipper currently supports plain, zip, and gzip formats.
+ .
+ This package includes the command-line 'zipper' tool for compressing and
+ extracing files.
+
+Package: libzipper-doc
+Section: doc
+Architecture: any
+Depends: libjs-jquery, ${misc:Depends}
+Homepage: http://www.codesrc.com/src/libzipper
+Description: simple interface for reading and writing compressed files
+ libzipper offers a flexible C++ interface for reading and writing compressed
+ files in multiple formats. It is intended for use in reading small compressed
+ data files, such as configuration files and saved games.
+ .
+ libzipper currently supports plain, zip, and gzip formats.
+ .
+ This package includes the API documentation, which is useful when developing
+ applications that use the libzipper library.
--- /dev/null
+usr/share/doc/libzipper-doc/html
--- /dev/null
+Document: libzipper-api
+Title: libzipper API documentation
+Author: Michael McMaster <michael@codesrc.com>
+Abstract: libzipper API documentation
+ This is the documentation for libzipper, a flexible C++ interface for
+ reading and writing compressed files in multiple formats.
+Section: Programming/C++
+
+Format: HTML
+Index: /usr/share/doc/libzipper-doc/html/index.html
+Files: /usr/share/doc/libzipper-doc/html/*.html
--- /dev/null
+usr/share/doc/libzipper/html usr/share/doc/libzipper-doc/
--- /dev/null
+usr/bin
+usr/share/man/man1
--- /dev/null
+usr/bin/zipper
+usr/share/man/man1/zipper.1
#!/usr/bin/make -f
+
+DEB_DH_MAKESHLIBS_ARGS_ALL=--version-info "libzipper1 (>= 1.0.1)"
+
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk
+# Make use of the libjs-jquery package
+# Required by lintian rule: embedded-javascript-library
+install/libzipper-doc::
+ rm $(DEB_DESTDIR)/usr/share/doc/libzipper/html/jquery.js
+ ln -s ../../../javascript/jquery/jquery.js $(DEB_DESTDIR)/usr/share/doc/libzipper/html/jquery.js
+
## Format-independent Doxygen rules. ##
## --------------------------------- ##
+DOXYGEN_INSTALL=
+
if DX_COND_doc
## ------------------------------- ##
DX_CLEAN_HTML = @DX_DOCDIR@/html
+doxygen-install-html:
+ $(INSTALL) -d $(DESTDIR)$(docdir)/html; \
+ $(INSTALL_DATA) @DX_DOCDIR@/html/* $(DESTDIR)$(docdir)/html;
+
+DOXYGEN_INSTALL+= doxygen-install-html
+
endif DX_COND_html
## ------------------------------ ##
endif DX_COND_chi
+doxygen-install-chm:
+ $(INSTALL) -d $(DESTDIR)$(docdir)/chm; \
+ $(INSTALL_DATA) @DX_DOCDIR@/chm/* $(DESTDIR)$(docdir)/chm;
+
+DOXYGEN_INSTALL+= doxygen-install-chm
+
endif DX_COND_chm
## ------------------------------ ##
DX_CLEAN_MAN = @DX_DOCDIR@/man
+doxygen-install-man:
+ $(INSTALL) -d $(DESTDIR)$(docdir)/man; \
+ $(INSTALL_DATA) @DX_DOCDIR@/man/* $(DESTDIR)$(docdir)/man;
+
+DOXYGEN_INSTALL+= doxygen-install-man
endif DX_COND_man
## ------------------------------ ##
DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+doxygen-install-rtf:
+ $(INSTALL) -d $(DESTDIR)$(docdir)/rtf; \
+ $(INSTALL_DATA) @DX_DOCDIR@/rtf/* $(DESTDIR)$(docdir)/rtf;
+
+DOXYGEN_INSTALL+= doxygen-install-rtf
endif DX_COND_rtf
## ------------------------------ ##
DX_CLEAN_XML = @DX_DOCDIR@/xml
+doxygen-install-xml:
+ $(INSTALL) -d $(DESTDIR)$(docdir)/xml; \
+ $(INSTALL_DATA) @DX_DOCDIR@/xml/* $(DESTDIR)$(docdir)/xml;
+
+DOXYGEN_INSTALL+= doxygen-install-xml
+
endif DX_COND_xml
## ----------------------------- ##
done; \
$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
+doxygen-install-ps:
+ $(INSTALL_DATA) @DX_DOCDIR@/@PACKAGE@.ps $(DESTDIR)$(docdir);
+
+DOXYGEN_INSTALL+= doxygen-install-ps
endif DX_COND_ps
## ------------------------------ ##
done; \
mv refman.pdf ../@PACKAGE@.pdf
+doxygen-install-pdf:
+ $(INSTALL_DATA) @DX_DOCDIR@/@PACKAGE@.pdf $(DESTDIR)$(docdir);
+
+DOXYGEN_INSTALL+= doxygen-install-pdf
endif DX_COND_pdf
## ------------------------------------------------- ##
DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+doxygen-install-latex:
+ $(INSTALL) -d $(DESTDIR)$(docdir)/latex; \
+ $(INSTALL_DATA) @DX_DOCDIR@/latex/* $(DESTDIR)$(docdir)/latex;
+
+DOXYGEN_INSTALL+= doxygen-install-latex
endif DX_COND_latex
-.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+.PHONY: doxygen-run doxygen-doc doxygen-install $(DX_PS_GOAL) $(DX_PDF_GOAL)
.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+doxygen-install: $(DOXYGEN_INSTALL)
+
@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
rm -rf @DX_DOCDIR@
$(DX_ENV) $(DX_DOXYGEN) $(DX_CONFIG)
+++ /dev/null
-Format: 3.0 (quilt)
-Source: libzipper
-Binary: libzipper-dev, libzipper
-Architecture: any
-Version: 1.0.0-1
-Maintainer: Michael McMaster <michael@codesrc.com>
-Homepage: http://www.codesrc.com/src/libzipper
-Standards-Version: 3.9.1
-Build-Depends: debhelper (>= 7.0.50~), autotools-dev, cdbs, zlib1g-dev
-Checksums-Sha1:
- c29f90960ea70b8cef7dbbba0e66ee85554a7dff 373654 libzipper_1.0.0.orig.tar.gz
- f2233453ef321adb381240be634980cbf4c6acfc 1607 libzipper_1.0.0-1.debian.tar.gz
-Checksums-Sha256:
- 4a646f633eb27e4a943c662ad4fbc86f4f6a28c8db2c9dfd2691d29f7183b239 373654 libzipper_1.0.0.orig.tar.gz
- 82cdfa713630fbe1b3d0aca42782f2e622e05903385dcd725243cba77a935928 1607 libzipper_1.0.0-1.debian.tar.gz
-Files:
- 04c557161633986694f186079587d386 373654 libzipper_1.0.0.orig.tar.gz
- d78cc7d36cd6fe2d03bf6bbe2dd1e7a5 1607 libzipper_1.0.0-1.debian.tar.gz
+++ /dev/null
-Format: 1.8
-Date: Sat, 21 May 2011 23:23:11 +1000
-Source: libzipper
-Binary: libzipper-dev libzipper
-Architecture: amd64
-Version: 1.0.0-1
-Distribution: unstable
-Urgency: low
-Maintainer: Michael McMaster <michael@codesrc.com>
-Changed-By: Michael McMaster <michael@codesrc.com>
-Description:
- libzipper - A C++ interface for reading compressed.
- libzipper-dev - A C++ interface for reading compressed.
-Changes:
- libzipper (1.0.0-1) unstable; urgency=low
- .
- * Initial release
-Checksums-Sha1:
- 0d9c7496b71a307738c80288893876b2e1d86f8d 57860 libzipper-dev_1.0.0-1_amd64.deb
- e3e75f5b51211fab97e7c9fe7e225cc17d0ad78d 33532 libzipper_1.0.0-1_amd64.deb
-Checksums-Sha256:
- 411179ab37deda3b2ab584c9cea1530417424d82b48a4a9378aad707887516d5 57860 libzipper-dev_1.0.0-1_amd64.deb
- 973c096cee24b2d3afd7ccca69b72ca285e84ba5ba0e6eb0f177d3bf758098de 33532 libzipper_1.0.0-1_amd64.deb
-Files:
- f7b1237a709b9f7cf594b566493fc476 57860 libdevel extra libzipper-dev_1.0.0-1_amd64.deb
- 5cabf912b7c726af9d09f2bc4e03c684 33532 libs extra libzipper_1.0.0-1_amd64.deb
+++ /dev/null
-libzipper_1.0.0.orig.tar.gz
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2011 Michael McMaster <michael@codesrc.com>
+//
+// This file is part of libzipper.
+//
+// libzipper 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 3 of the License, or
+// (at your option) any later version.
+//
+// libzipper 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 libzipper. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef zipper_split_hh
+#define zipper_split_hh
+
+#include <string>
+
+namespace zipper
+{
+
+ template<typename OutputIterator>
+ void
+ split(const std::string& in, char delim, OutputIterator out)
+ {
+ std::string::size_type start(0);
+ std::string::size_type pos(0);
+ while (pos < in.size())
+ {
+ if (in[pos] == delim)
+ {
+ if (pos != start)
+ {
+ *out = in.substr(start, pos - start);
+ ++out;
+ }
+ ++pos;
+ start = pos;
+ }
+ else
+ {
+ ++pos;
+ }
+ }
+
+ if (pos != start)
+ {
+ *out = in.substr(start, pos - start);
+ ++out;
+ }
+ }
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2011 Michael McMaster <michael@codesrc.com>
+//
+// This file is part of libzipper.
+//
+// libzipper 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 3 of the License, or
+// (at your option) any later version.
+//
+// libzipper 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 libzipper. If not, see <http://www.gnu.org/licenses/>.
+
+#include "strerror.hh"
+
+#include <string.h>
+
+using namespace zipper;
+
+std::string
+zipper::strerror(int errnum)
+{
+ char buf[1024];
+ char* message(NULL);
+
+#ifdef _GNU_SOURCE
+ // The GNU-specific strerror_r may use the provided buffer, OR a static
+ // buffer.
+ message = strerror_r(errnum, buf, sizeof(buf));
+
+#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
+ int error(strerror_r(errnum, buf, sizeof(buf)));
+ if (error != 0)
+ {
+ message = "Unknown error";
+ }
+
+#else
+ // Thread-unsafe fallback
+ message = strerror(errnum);
+#endif
+
+ return std::string(message);
+}
+
--- /dev/null
+// Copyright (C) 2011 Michael McMaster <michael@codesrc.com>
+//
+// This file is part of libzipper.
+//
+// libzipper 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 3 of the License, or
+// (at your option) any later version.
+//
+// libzipper 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 libzipper. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef zipper_strerror_hh
+#define zipper_strerror_hh
+
+#include <string>
+
+namespace zipper
+{
+
+ std::string strerror(int errnum);
+}
+
+#endif
--- /dev/null
+.TH ZIPPER 1 "2011-05-26" "libzipper @libzipper_version@" "User Commands"
+.SH NAME
+zipper \- compress and extract files from archives
+.SH SYNOPSIS
+.B zipper
+{zip|gzip}
+.I archive file [files...]
+.PP
+.B zipper
+{unzip|gunzip}
+.I archive
+.SH DESCRIPTION
+.I zipper
+provides tools to manage compressed zip and gzip files.
+.PP
+.I zipper
+stores the full path of the specified files when creating an archive, but
+does not store any timestamp or permission information.
+.PP
+.I zipper
+extracts files to the full path specified within the archive; the original
+archive file is unchanged.
+.I zipper
+does not support restoring the original
+file timestamps or permissions, even if such information is recorded in the
+archive.
+.SH COMMANDS
+.TP
+.B zip
+Create a new zip archive
+.TP
+.B unzip
+Extract all files from a zip archive.
+.TP
+.B gzip
+Create a new gzip archive
+.TP
+.B gunzip
+Extract the first file from the gzip archive.
+.SH OPTIONS
+.TP
+.B archive
+Filename of the compressed zip/gzip file. The special '-' filename is treated
+as standard input/output. When creating a new archive, this file will
+be overwritten indiscriminately.
+.TP
+.B files
+A list of files to add into the archive. The special '-' filename is treated
+as standard input/output.
+.SH EXAMPLES
+.TP
+Create a zip file
+zipper zip /tmp/foo.zip bar.txt baz.txt
+.TP
+Extract a gzip file
+zipper gunzip /tmp/foo.gz
+.SH CONFORMING TO
+.I zipper
+supports the DEFLATE algorithm described by RFC1951, and the gzip file format
+described by RFC1952.
+.SH BUGS
+For gzip files,
+.I zipper
+is able to create an archive containing
+multiple files, but can only extract the first file.
+.SH SEE ALSO
+.BR gunzip (1),
+.BR gzip (1),
+.BR unzip (1),
+.BR zip (1)
// along with libzipper. If not, see <http://www.gnu.org/licenses/>.
#include "zipper.hh"
+#include "split.hh"
+#include "strerror.hh"
#include <cassert>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <sstream>
+#include <string>
using namespace zipper;
-int main()
+static std::string argv0;
+
+static void usage()
{
+ std::cerr <<
+ "libzipper Copyright (C) 2011 Michael McMaster <michael@codesrc.com>\n"
+ "This program comes with ABSOLUTELY NO WARRANTY.\n"
+ "This is free software, and you are welcome to redistribute it\n"
+ "under certain conditions.\n\n" <<
+
+ "Usage: \n" <<
+ argv0 << " {zip|gzip} archive [file...]\n" <<
+ argv0 << " {unzip|gunzip} archive" << std::endl;
+}
-/*
+static WriterPtr
+getWriter(const std::string& optionName)
+{
+ std::shared_ptr<FileWriter> writer;
+ if (optionName == "-")
{
- FileReader reader("test.gz");
- Decompressor decomp(reader);
- std::vector<CompressedFilePtr> entries(decomp.getEntries());
- for (size_t f = 0; f < entries.size(); ++f)
+ writer.reset(new FileWriter("stdout", 1, false));
+ }
+ else
{
- FileWriter writer(entries[f]->getPath(), 0660);
- entries[f]->decompress(writer);
+ writer.reset(new FileWriter(optionName, 0660));
+ }
+ return writer;
+}
+
+static ReaderPtr
+getReader(const std::string& optionName)
+{
+ std::shared_ptr<FileReader> reader;
+ if (optionName == "-")
+ {
+ reader.reset(new FileReader("stdin", 0, false));
}
+ else
+ {
+ reader.reset(new FileReader(optionName));
}
+ return reader;
+}
+static void
+command_zip(const std::deque<std::string>& options)
+{
+ if (options.size() < 2)
{
- FileReader reader("test.zip");
+ usage();
+ exit(EXIT_FAILURE);
+ }
+
+ WriterPtr writer(getWriter(options[0]));
+ Compressor comp(Container_zip, writer);
+ for (size_t i = 1; i < options.size(); ++i)
+ {
+ ReaderPtr reader(getReader(options[i]));
+ comp.addFile(*reader);
+ }
+}
+
+static void
+command_gzip(const std::deque<std::string>& options)
+{
+ if (options.size() != 2)
+ {
+ usage();
+ exit(EXIT_FAILURE);
+ }
+
+ WriterPtr writer(getWriter(options[0]));
+ Compressor comp(Container_gzip, writer);
+ for (size_t i = 1; i < options.size(); ++i)
+ {
+ ReaderPtr reader(getReader(options[i]));
+ comp.addFile(*reader);
+ }
+}
+
+static void
+command_extract(const std::deque<std::string>& options)
+{
+ if (options.size() != 1)
+ {
+ usage();
+ exit(EXIT_FAILURE);
+ }
+
+ ReaderPtr reader(getReader(options[0]));
Decompressor decomp(reader);
std::vector<CompressedFilePtr> entries(decomp.getEntries());
for (size_t f = 0; f < entries.size(); ++f)
{
+ std::deque<std::string> path;
+ split(
+ entries[f]->getPath(),
+ '/',
+ std::back_insert_iterator<std::deque<std::string> >(path));
+ path.pop_back(); // Remove extracted file.
+ std::stringstream builtPath;
+ for (std::deque<std::string>::iterator it(path.begin());
+ it != path.end();
+ ++it)
+ {
+ builtPath << *it;
+ int result(mkdir(builtPath.str().c_str(), 0775));
+ if (result != 0 && errno != EEXIST)
+ {
+ std::string errMsg(zipper::strerror(errno));
+
+ std::stringstream message;
+ message << "Could not create directory " <<
+ "\"" <<builtPath.str() << "\": " << errMsg;
+ throw IOException(message.str());
+ }
+
+ builtPath << '/';
+ }
FileWriter writer(entries[f]->getPath(), 0660);
entries[f]->decompress(writer);
}
- }
-*/
-
+}
+int main(int argc, char** argv)
+{
+ argv0 = argv[0];
+ if (argc < 3)
{
- FileReader reader("test");
- FileWriter writer("test.zip", 0660);
- {
- Compressor comp(Container_zip, writer);
- comp.addFile(reader);
+ usage();
+ exit(EXIT_FAILURE);
}
+
+ std::deque<std::string> options;
+ for (int i = 1; i < argc; ++i)
+ {
+ options.push_back(argv[i]);
}
+ std::string command(options[0]);
+ options.pop_front();
+ if (command == "zip")
+ {
+ command_zip(options);
+ }
+ else if (command == "gzip")
{
- FileReader reader("test");
- FileWriter writer("test.gz", 0660);
+ command_gzip(options);
+ }
+ else if (command == "gunzip" || command == "unzip")
{
- Compressor comp(Container_gzip, writer);
- comp.addFile(reader);
+ command_extract(options);
}
+ else
+ {
+ usage();
+ exit(EXIT_FAILURE);
}
+ return EXIT_SUCCESS;
}
+
public:
/// Create a Compressor to output the given compressed archived format
/// to writer.
+ /// \param writer destination of the compressed data
+ /// \param format determines the output archive file type to
+ /// create.
Compressor(ContainerFormat format, const WriterPtr& writer);
/// Create a Compressor to output the given compressed archived format
/// to writer.
///
- /// \param writer must remain in scope for the lifetime of the
- /// Compressor.
+ /// \param writer is the destination of the compressed data. writer
+ /// must remain in scope for the lifetime of the Compressor.
+ /// \param format determines the output archive file type to
+ /// create.
Compressor(ContainerFormat format, Writer& writer);
/// \brief Compressor dtor