| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- // 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>
- 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;
- }
|