diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2005-12-28 15:18:37 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2005-12-28 15:18:37 (GMT) |
commit | bc1548b236515514c138da8b59f61af2efbfc4a5 (patch) | |
tree | ab8ab5b2bceca941f363ca7064248ece6779b617 /Utilities/cmtar/libtar.c | |
parent | 552842d11f845ad53e4f34be549aa4007737564b (diff) | |
download | CMake-bc1548b236515514c138da8b59f61af2efbfc4a5.zip CMake-bc1548b236515514c138da8b59f61af2efbfc4a5.tar.gz CMake-bc1548b236515514c138da8b59f61af2efbfc4a5.tar.bz2 |
ENH: Initial import
Diffstat (limited to 'Utilities/cmtar/libtar.c')
-rw-r--r-- | Utilities/cmtar/libtar.c | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/Utilities/cmtar/libtar.c b/Utilities/cmtar/libtar.c new file mode 100644 index 0000000..1068959 --- /dev/null +++ b/Utilities/cmtar/libtar.c @@ -0,0 +1,377 @@ +/* +** Copyright 1998-2003 University of Illinois Board of Trustees +** Copyright 1998-2003 Mark D. Roth +** All rights reserved. +** +** libtar.c - demo driver program for libtar +** +** Mark D. Roth <roth@uiuc.edu> +** Campus Information Technologies and Educational Services +** University of Illinois at Urbana-Champaign +*/ +#include <libtar/config.h> +#include <libtar/libtar.h> + +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#ifdef _MSC_VER +#include <libtar/compat.h> +#include <io.h> +#else +#include <sys/param.h> +#endif + +#ifdef STDC_HEADERS +# include <string.h> +#endif + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#ifdef DEBUG +# include <signal.h> +#endif + +#ifdef HAVE_LIBZ +# include <cmzlib/zlib.h> +#endif + +#include <libtar/compat.h> + + +char *progname; +int verbose = 0; +int use_gnu = 0; + +#ifdef DEBUG +void +segv_handler(int sig) +{ + puts("OOPS! Caught SIGSEGV, bailing out..."); + fflush(stdout); + fflush(stderr); +} +#endif + + +#ifdef HAVE_LIBZ + +int use_zlib = 0; + +int +gzopen_frontend(char *pathname, int oflags, int mode) +{ + char *gzoflags; + gzFile gzf; + int fd; + + switch (oflags & O_ACCMODE) + { + case O_WRONLY: + gzoflags = "wb"; + break; + case O_RDONLY: + gzoflags = "rb"; + break; + default: + case O_RDWR: + errno = EINVAL; + return -1; + } + + fd = open(pathname, oflags, mode); + if (fd == -1) + return -1; + +#ifndef _MSC_VER + if ((oflags & O_CREAT) && fchmod(fd, mode)) + return -1; +#endif + + gzf = gzdopen(fd, gzoflags); + if (!gzf) + { + errno = ENOMEM; + return -1; + } + + return (int)gzf; +} + +tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose, + (readfunc_t) gzread, (writefunc_t) gzwrite +}; + +#endif /* HAVE_LIBZ */ + + +int +create(char *tarfile, char *rootdir, libtar_list_t *l) +{ + TAR *t; + char *pathname; + char buf[MAXPATHLEN]; + libtar_listptr_t lp; + + if (tar_open(&t, tarfile, +#ifdef HAVE_LIBZ + (use_zlib ? &gztype : NULL), +#else + NULL, +#endif + O_WRONLY | O_CREAT, 0644, + (verbose ? TAR_VERBOSE : 0) + | (use_gnu ? TAR_GNU : 0)) == -1) + { + fprintf(stderr, "tar_open(): %s\n", strerror(errno)); + return -1; + } + + libtar_listptr_reset(&lp); + while (libtar_list_next(l, &lp) != 0) + { + pathname = (char *)libtar_listptr_data(&lp); + if (pathname[0] != '/' && rootdir != NULL) + snprintf(buf, sizeof(buf), "%s/%s", rootdir, pathname); + else + strlcpy(buf, pathname, sizeof(buf)); + if (tar_append_tree(t, buf, pathname) != 0) + { + fprintf(stderr, + "tar_append_tree(\"%s\", \"%s\"): %s\n", buf, + pathname, strerror(errno)); + tar_close(t); + return -1; + } + } + + if (tar_append_eof(t) != 0) + { + fprintf(stderr, "tar_append_eof(): %s\n", strerror(errno)); + tar_close(t); + return -1; + } + + if (tar_close(t) != 0) + { + fprintf(stderr, "tar_close(): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + + +int +list(char *tarfile) +{ + TAR *t; + int i; + + if (tar_open(&t, tarfile, +#ifdef HAVE_LIBZ + (use_zlib ? &gztype : NULL), +#else + NULL, +#endif + O_RDONLY, 0, + (verbose ? TAR_VERBOSE : 0) + | (use_gnu ? TAR_GNU : 0)) == -1) + { + fprintf(stderr, "tar_open(): %s\n", strerror(errno)); + return -1; + } + + while ((i = th_read(t)) == 0) + { + th_print_long_ls(t); +#ifdef DEBUG + th_print(t); +#endif + if (TH_ISREG(t) && tar_skip_regfile(t) != 0) + { + fprintf(stderr, "tar_skip_regfile(): %s\n", + strerror(errno)); + return -1; + } + } + +#ifdef DEBUG + printf("th_read() returned %d\n", i); + printf("EOF mark encountered after %ld bytes\n", +# ifdef HAVE_LIBZ + (use_zlib + ? gzseek((gzFile) t->fd, 0, SEEK_CUR) + : +# endif + lseek(t->fd, 0, SEEK_CUR) +# ifdef HAVE_LIBZ + ) +# endif + ); +#endif + + if (tar_close(t) != 0) + { + fprintf(stderr, "tar_close(): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + + +int +extract(char *tarfile, char *rootdir) +{ + TAR *t; + +#ifdef DEBUG + puts("opening tarfile..."); +#endif + if (tar_open(&t, tarfile, +#ifdef HAVE_LIBZ + (use_zlib ? &gztype : NULL), +#else + NULL, +#endif + O_RDONLY, 0, + (verbose ? TAR_VERBOSE : 0) + | (use_gnu ? TAR_GNU : 0)) == -1) + { + fprintf(stderr, "tar_open(): %s\n", strerror(errno)); + return -1; + } + +#ifdef DEBUG + puts("extracting tarfile..."); +#endif + if (tar_extract_all(t, rootdir) != 0) + { + fprintf(stderr, "tar_extract_all(): %s\n", strerror(errno)); + return -1; + } + +#ifdef DEBUG + puts("closing tarfile..."); +#endif + if (tar_close(t) != 0) + { + fprintf(stderr, "tar_close(): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + + +void +usage() +{ + printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t filename.tar\n", + progname); + printf(" %s [-C rootdir] [-g] [-z] -c filename.tar ...\n", + progname); + exit(-1); +} + + +#define MODE_LIST 1 +#define MODE_CREATE 2 +#define MODE_EXTRACT 3 + +int +main(int argc, char *argv[]) +{ + char *tarfile = NULL; + char *rootdir = NULL; + int c; + int mode = 0; + libtar_list_t *l; +#ifdef _WIN32 + int optind; +#endif + progname = basename(argv[0]); + +#ifndef _WIN32 + while ((c = getopt(argc, argv, "cC:gtvVxz")) != -1) + switch (c) + { + case 'V': + printf("libtar %s by Mark D. Roth <roth@uiuc.edu>\n", + libtar_version); + break; + case 'C': + rootdir = strdup(optarg); + break; + case 'v': + verbose = 1; + break; + case 'g': + use_gnu = 1; + break; + case 'c': + if (mode) + usage(); + mode = MODE_CREATE; + break; + case 'x': + if (mode) + usage(); + mode = MODE_EXTRACT; + break; + case 't': + if (mode) + usage(); + mode = MODE_LIST; + break; +#ifdef HAVE_LIBZ + case 'z': + use_zlib = 1; + break; +#endif /* HAVE_LIBZ */ + default: + usage(); + } + if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 2 : 1))) + { +#ifdef DEBUG + printf("argc - optind == %d\tmode == %d\n", argc - optind, + mode); +#endif + usage(); + } + +#else + mode = MODE_EXTRACT; + use_zlib=1; + optind = 1; +#endif + +#ifdef DEBUG + signal(SIGSEGV, segv_handler); +#endif + + switch (mode) + { + case MODE_EXTRACT: + return extract(argv[optind], rootdir); + case MODE_CREATE: + tarfile = argv[optind]; + l = libtar_list_new(LIST_QUEUE, NULL); + for (c = optind + 1; c < argc; c++) + libtar_list_add(l, argv[c]); + return create(tarfile, rootdir, l); + case MODE_LIST: + return list(argv[optind]); + default: + break; + } + + /* NOTREACHED */ + return -2; +} + + |