| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 | 
							- //	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 "zipper.hh"
 
- #include "split.hh"
 
- #include <errno.h>
 
- #include "strerror.hh"
 
- #include <cassert>
 
- #include <cstdlib>
 
- #include <deque>
 
- #include <iostream>
 
- #include <sstream>
 
- #include <string>
 
- #include "config.h"
 
- using namespace zipper;
 
- 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 [files...]\n" <<
 
- 			argv0 << " {unzip|gunzip} archive" << std::endl;
 
- }
 
- static WriterPtr
 
- getWriter(const std::string& optionName)
 
- {
 
- 	std::shared_ptr<FileWriter> writer;
 
- 	if (optionName == "-")
 
- 	{
 
- 		writer.reset(new FileWriter("stdout", 1, false));
 
- 	}
 
- 	else
 
- 	{
 
- 		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)
 
- 	{
 
- 		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]->getModificationTime());
 
- 		entries[f]->decompress(writer);
 
- 	}
 
- }
 
- int main(int argc, char** argv)
 
- {
 
- 	argv0 = argv[0];
 
- 	if (argc < 3)
 
- 	{
 
- 		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")
 
- 	{
 
- 		command_gzip(options);
 
- 	}
 
- 	else if (command == "gunzip" || command == "unzip")
 
- 	{
 
- 		command_extract(options);
 
- 	}
 
- 	else
 
- 	{
 
- 		usage();
 
- 		exit(EXIT_FAILURE);
 
- 	}
 
- 	return EXIT_SUCCESS;
 
- }
 
 
  |