// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // clang-format off /*- * This is a compact "tar" program whose primary goal is small size. * Statically linked, it can be very small indeed. This serves a number * of goals: * o a testbed for libarchive (to check for link pollution), * o a useful tool for space-constrained systems (boot floppies, etc), * o a place to experiment with new implementation ideas for bsdtar, * o a small program to demonstrate libarchive usage. * * Use the following macros to suppress features: * NO_BZIP2 - Implies NO_BZIP2_CREATE and NO_BZIP2_EXTRACT * NO_BZIP2_CREATE - Suppress bzip2 compression support. * NO_BZIP2_EXTRACT - Suppress bzip2 auto-detection and decompression. * NO_COMPRESS - Implies NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT * NO_COMPRESS_CREATE - Suppress compress(1) compression support * NO_COMPRESS_EXTRACT - Suppress compress(1) auto-detect and decompression. * NO_CREATE - Suppress all archive creation support. * NO_CPIO_EXTRACT - Suppress auto-detect and dearchiving of cpio archives. * NO_GZIP - Implies NO_GZIP_CREATE and NO_GZIP_EXTRACT * NO_GZIP_CREATE - Suppress gzip compression support. * NO_GZIP_EXTRACT - Suppress gzip auto-detection and decompression. * NO_LOOKUP - Try to avoid getpw/getgr routines, which can be very large * NO_TAR_EXTRACT - Suppress tar extraction * * With all of the above macros defined (except NO_TAR_EXTRACT), you * get a very small program that can recognize and extract essentially * any uncompressed tar archive. On FreeBSD 5.1, this minimal program * is under 64k, statically linked, which compares rather favorably to * main(){printf("hello, world");} * which is over 60k statically linked on the same operating system. * Without any of the above macros, you get a static executable of * about 180k with a lot of very sophisticated modern features. * Obviously, it's trivial to add support for ISO, Zip, mtree, * lzma/xz, etc. Just fill in the appropriate setup calls. */ #include "minitar.h" // NOLINT(build/include) /* * NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE. */ #ifdef NO_CREATE #undef NO_BZIP2_CREATE #define NO_BZIP2_CREATE #undef NO_COMPRESS_CREATE #define NO_COMPRESS_CREATE #undef NO_GZIP_CREATE #define NO_GZIP_CREATE #endif /* * The combination of NO_BZIP2_CREATE and NO_BZIP2_EXTRACT is * equivalent to NO_BZIP2. */ #ifdef NO_BZIP2_CREATE #ifdef NO_BZIP2_EXTRACT #undef NO_BZIP2 #define NO_BZIP2 #endif #endif #ifdef NO_BZIP2 #undef NO_BZIP2_EXTRACT #define NO_BZIP2_EXTRACT #undef NO_BZIP2_CREATE #define NO_BZIP2_CREATE #endif /* * The combination of NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT is * equivalent to NO_COMPRESS. */ #ifdef NO_COMPRESS_CREATE #ifdef NO_COMPRESS_EXTRACT #undef NO_COMPRESS #define NO_COMPRESS #endif #endif #ifdef NO_COMPRESS #undef NO_COMPRESS_EXTRACT #define NO_COMPRESS_EXTRACT #undef NO_COMPRESS_CREATE #define NO_COMPRESS_CREATE #endif /* * The combination of NO_GZIP_CREATE and NO_GZIP_EXTRACT is * equivalent to NO_GZIP. */ #ifdef NO_GZIP_CREATE #ifdef NO_GZIP_EXTRACT #undef NO_GZIP #define NO_GZIP #endif #endif #ifdef NO_GZIP #undef NO_GZIP_EXTRACT #define NO_GZIP_EXTRACT #undef NO_GZIP_CREATE #define NO_GZIP_CREATE #endif int main(int unused_argc, const char** argv) { const char* filename = nullptr; int compress; int flags; int mode; int opt; mode = 'x'; int verbose = 0; compress = '\0'; flags = ARCHIVE_EXTRACT_TIME; /* Among other sins, getopt(3) pulls in printf(3). */ while (*++argv != nullptr && **argv == '-') { const char* p = *argv + 1; while ((opt = *p++) != '\0') { switch (opt) { #ifndef NO_CREATE case 'c': mode = opt; break; #endif case 'f': if (*p != '\0') filename = p; else filename = *++argv; p += strlen(p); break; #ifndef NO_BZIP2_CREATE case 'j': compress = opt; break; #endif case 'p': flags |= ARCHIVE_EXTRACT_PERM; flags |= ARCHIVE_EXTRACT_ACL; flags |= ARCHIVE_EXTRACT_FFLAGS; break; case 't': mode = opt; break; case 'v': verbose++; break; case 'x': mode = opt; break; #ifndef NO_BZIP2_CREATE case 'y': compress = opt; break; #endif #ifndef NO_COMPRESS_CREATE case 'Z': compress = opt; break; #endif #ifndef NO_GZIP_CREATE case 'z': compress = opt; break; #endif default: usage(); } } } switch (mode) { #ifndef NO_CREATE case 'c': create(filename, compress, argv, verbose); break; #endif case 't': extract(filename, 0, flags, verbose); break; case 'x': extract(filename, 1, flags, verbose); break; } return (0); } // clang-format on