aboutsummaryrefslogtreecommitdiffstats
path: root/src/sash/cmd_gzip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sash/cmd_gzip.c')
-rw-r--r--src/sash/cmd_gzip.c698
1 files changed, 0 insertions, 698 deletions
diff --git a/src/sash/cmd_gzip.c b/src/sash/cmd_gzip.c
deleted file mode 100644
index 6bcec11..0000000
--- a/src/sash/cmd_gzip.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- * Copyright (c) 2014 by David I. Bell
- * Permission is granted to use, distribute, or modify this source,
- * provided that this copyright notice remains intact.
- *
- * The "gzip" and "gunzip" built-in commands.
- * These commands are optionally built into sash.
- * This uses the zlib library by Jean-loup Gailly to compress and
- * uncompress the files.
- */
-
-#if HAVE_GZIP
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <zlib.h>
-
-#include "sash.h"
-
-
-#define GZ_EXT ".gz"
-#define TGZ_EXT ".tgz"
-#define Z_EXT ".Z"
-#define TAR_EXT ".tar"
-#define NO_EXT ""
-
-
-/*
- * Tables of conversions to make to file extensions.
- */
-typedef struct
-{
- const char * input;
- const char * output;
-} CONVERT;
-
-
-static const CONVERT gzipConvertTable[] =
-{
- {TAR_EXT, TGZ_EXT},
- {NO_EXT, GZ_EXT}
-};
-
-
-static const CONVERT gunzipConvertTable[] =
-{
- {TGZ_EXT, TAR_EXT},
- {GZ_EXT, NO_EXT},
- {Z_EXT, NO_EXT},
- {NO_EXT, NO_EXT}
-};
-
-
-/*
- * Local routines to compress and uncompress files.
- */
-static BOOL gzip(const char * inputFile, const char * outputFile);
-static BOOL gunzip(const char * inputFile, const char * outputFile);
-
-static const char * convertName
- (const CONVERT * table, const char * inFile);
-
-
-int
-do_gzip(int argc, const char ** argv)
-{
- const char * outPath;
- const char * inFile;
- const char * outFile;
- int i;
- int r;
-
- r = 0;
- argc--;
- argv++;
-
- /*
- * Look for the -o option if it is present.
- * If present, it must be at the end of the command.
- * Remember the output path and remove it if found.
- */
- outPath = NULL;
-
- if ((argc >= 2) && (strcmp(argv[argc - 2], "-o") == 0) &&
- (argv[argc - 1][0] != '-'))
- {
- argc -= 2;
- outPath = argv[argc + 1];
- }
-
- /*
- * Now make sure that there are no more options.
- */
- for (i = 0; i < argc; i++)
- {
- if (argv[i][0] == '-')
- {
- if (strcmp(argv[i], "-o") == 0)
- fprintf(stderr, "Illegal use of -o\n");
- else
- fprintf(stderr, "Illegal option\n");
-
- return 1;
- }
- }
-
- /*
- * If there is no output path specified, then compress each of
- * the input files in place using their full paths. The input
- * file names are then deleted.
- */
- if (outPath == NULL)
- {
- while (!intFlag && (argc-- > 0))
- {
- inFile = *argv++;
-
- outFile = convertName(gzipConvertTable, inFile);
-
- /*
- * Try to compress the file.
- */
- if (!gzip(inFile, outFile))
- {
- r = 1;
-
- continue;
- }
-
- /*
- * This was successful.
- * Try to delete the original file now.
- */
- if (unlink(inFile) < 0)
- {
- fprintf(stderr, "%s: %s\n", inFile,
- "Compressed ok but unlink failed");
-
- r = 1;
- }
- }
-
- return r;
- }
-
- /*
- * There is an output path specified.
- * If it is not a directory, then either compress the single
- * specified input file to the exactly specified output path,
- * or else complain.
- */
- if (!isDirectory(outPath))
- {
- if (argc == 1)
- r = !gzip(*argv, outPath);
- else
- {
- fprintf(stderr, "Exactly one input file is required\n");
- r = 1;
- }
-
- return r;
- }
-
- /*
- * There was an output directory specified.
- * Compress each of the input files into the specified
- * output directory, converting their extensions if possible.
- */
- while (!intFlag && (argc-- > 0))
- {
- inFile = *argv++;
-
- /*
- * Strip the path off of the input file name to make
- * the beginnings of the output file name.
- */
- outFile = strrchr(inFile, '/');
-
- if (outFile)
- outFile++;
- else
- outFile = inFile;
-
- /*
- * Convert the extension of the output file name if possible.
- * If we can't, then that is ok.
- */
- outFile = convertName(gzipConvertTable, outFile);
-
- /*
- * Now build the output path name by prefixing it with
- * the output directory.
- */
- outFile = buildName(outPath, outFile);
-
- /*
- * Compress the input file without deleting the input file.
- */
- if (!gzip(inFile, outFile))
- r = 1;
- }
-
- return r;
-}
-
-
-int
-do_gunzip(int argc, const char ** argv)
-{
- const char * outPath;
- const char * inFile;
- const char * outFile;
- int i;
- int r;
-
- r = 0;
- argc--;
- argv++;
-
- /*
- * Look for the -o option if it is present.
- * If present, it must be at the end of the command.
- * Remember the output path and remove it if found.
- */
- outPath = NULL;
-
- if ((argc >= 2) && (strcmp(argv[argc - 2], "-o") == 0) &&
- (argv[argc - 1][0] != '-'))
- {
- argc -= 2;
- outPath = argv[argc + 1];
- }
-
- /*
- * Now make sure that there are no more options.
- */
- for (i = 0; i < argc; i++)
- {
- if (argv[i][0] == '-')
- {
- if (strcmp(argv[i], "-o") == 0)
- fprintf(stderr, "Illegal use of -o\n");
- else
- fprintf(stderr, "Illegal option\n");
-
- return 1;
- }
- }
-
- /*
- * If there is no output path specified, then uncompress each of
- * the input files in place using their full paths. They must
- * have one of the proper compression extensions which is converted.
- * The input file names are then deleted.
- */
- if (outPath == NULL)
- {
- while (!intFlag && (argc-- > 0))
- {
- inFile = *argv++;
-
- outFile = convertName(gunzipConvertTable, inFile);
-
- if (inFile == outFile)
- {
- fprintf(stderr, "%s: %s\n", inFile,
- "missing compression extension");
- r = 1;
-
- continue;
- }
-
- /*
- * Try to uncompress the file.
- */
- if (!gunzip(inFile, outFile))
- {
- r = 1;
- continue;
- }
-
- /*
- * This was successful.
- * Try to delete the original file now.
- */
- if (unlink(inFile) < 0)
- {
- fprintf(stderr, "%s: %s\n", inFile,
- "Uncompressed ok but unlink failed");
- r = 1;
- }
- }
-
- return r;
- }
-
- /*
- * There is an output path specified.
- * If the output path is a device file then uncompress each of
- * the input files to the device file.
- */
- if (isDevice(outPath))
- {
- while (!intFlag && (argc-- > 0))
- {
- if (!gunzip(*argv++, outPath))
- r = 1;
- }
-
- return r;
- }
-
- /*
- * If the output path is not a directory then either uncompress the
- * single specified input file to the exactly specified output path,
- * or else complain.
- */
- if (!isDirectory(outPath))
- {
- if (argc == 1)
- return !gunzip(*argv, outPath);
- else
- fprintf(stderr, "Exactly one input file is required\n");
-
- return 1;
- }
-
- /*
- * There was an output directory specified.
- * Uncompress each of the input files into the specified
- * output directory, converting their extensions if possible.
- */
- while (!intFlag && (argc-- > 0))
- {
- inFile = *argv++;
-
- /*
- * Strip the path off of the input file name to make
- * the beginnings of the output file name.
- */
- outFile = strrchr(inFile, '/');
-
- if (outFile)
- outFile++;
- else
- outFile = inFile;
-
- /*
- * Convert the extension of the output file name if possible.
- * If we can't, then that is ok.
- */
- outFile = convertName(gunzipConvertTable, outFile);
-
- /*
- * Now build the output path name by prefixing it with
- * the output directory.
- */
- outFile = buildName(outPath, outFile);
-
- /*
- * Uncompress the input file without deleting the input file.
- */
- if (!gunzip(inFile, outFile))
- r = 1;
- }
-
- return r;
-}
-
-
-/*
- * Compress the specified input file to produce the output file.
- * Returns TRUE if successful.
- */
-static BOOL
-gzip(const char * inputFileName, const char * outputFileName)
-{
- gzFile outGZ;
- int inFD;
- int len;
- int err;
- struct stat statBuf1;
- struct stat statBuf2;
- char buf[BUF_SIZE];
-
- outGZ = NULL;
- inFD = -1;
-
- /*
- * See if the output file is the same as the input file.
- * If so, complain about it.
- */
- if (stat(inputFileName, &statBuf1) < 0)
- {
- perror(inputFileName);
-
- return FALSE;
- }
-
- if (stat(outputFileName, &statBuf2) < 0)
- {
- statBuf2.st_ino = -1;
- statBuf2.st_dev = -1;
- }
-
- if ((statBuf1.st_dev == statBuf2.st_dev) &&
- (statBuf1.st_ino == statBuf2.st_ino))
- {
- fprintf(stderr,
- "Cannot compress file \"%s\" on top of itself\n",
- inputFileName);
-
- return FALSE;
- }
-
- /*
- * Open the input file.
- */
- inFD = open(inputFileName, O_RDONLY);
-
- if (inFD < 0)
- {
- perror(inputFileName);
-
- goto failed;
- }
-
- /*
- * Ask the zlib library to open the output file.
- */
- outGZ = gzopen(outputFileName, "wb9");
-
- if (outGZ == NULL)
- {
- fprintf(stderr, "%s: gzopen failed\n", outputFileName);
-
- goto failed;
- }
-
- /*
- * Read the uncompressed data from the input file and write
- * the compressed data to the output file.
- */
- while ((len = read(inFD, buf, sizeof(buf))) > 0)
- {
- if (gzwrite(outGZ, buf, len) != len)
- {
- fprintf(stderr, "%s: %s\n", inputFileName,
- gzerror(outGZ, &err));
-
- goto failed;
- }
-
- if (intFlag)
- goto failed;
- }
-
- if (len < 0)
- {
- perror(inputFileName);
-
- goto failed;
- }
-
- /*
- * All done, close the files.
- */
- if (close(inFD))
- {
- perror(inputFileName);
-
- goto failed;
- }
-
- inFD = -1;
-
- if (gzclose(outGZ) != Z_OK)
- {
- fprintf(stderr, "%s: gzclose failed\n", outputFileName);
-
- goto failed;
- }
-
- outGZ = NULL;
-
- /*
- * Success.
- */
- return TRUE;
-
-
-/*
- * Here on an error, to clean up.
- */
-failed:
- if (inFD >= 0)
- (void) close(inFD);
-
- if (outGZ != NULL)
- (void) gzclose(outGZ);
-
- return FALSE;
-}
-
-
-/*
- * Uncompress the input file to produce the output file.
- * Returns TRUE if successful.
- */
-static BOOL
-gunzip(const char * inputFileName, const char * outputFileName)
-{
- gzFile inGZ;
- int outFD;
- int len;
- int err;
- struct stat statBuf1;
- struct stat statBuf2;
- char buf[BUF_SIZE];
-
- inGZ = NULL;
- outFD = -1;
-
- /*
- * See if the output file is the same as the input file.
- * If so, complain about it.
- */
- if (stat(inputFileName, &statBuf1) < 0)
- {
- perror(inputFileName);
-
- return FALSE;
- }
-
- if (stat(outputFileName, &statBuf2) < 0)
- {
- statBuf2.st_ino = -1;
- statBuf2.st_dev = -1;
- }
-
- if ((statBuf1.st_dev == statBuf2.st_dev) &&
- (statBuf1.st_ino == statBuf2.st_ino))
- {
- fprintf(stderr,
- "Cannot uncompress file \"%s\" on top of itself\n",
- inputFileName);
-
- return FALSE;
- }
-
- /*
- * Ask the zlib library to open the input file.
- */
- inGZ = gzopen(inputFileName, "rb");
-
- if (inGZ == NULL)
- {
- fprintf(stderr, "%s: gzopen failed\n", inputFileName);
-
- return FALSE;
- }
-
- /*
- * Create the output file.
- */
- if (isDevice(outputFileName))
- outFD = open(outputFileName, O_WRONLY);
- else
- outFD = open(outputFileName, O_WRONLY|O_CREAT|O_TRUNC, 0666);
-
- if (outFD < 0)
- {
- perror(outputFileName);
-
- goto failed;
- }
-
- /*
- * Read the compressed data from the input file and write
- * the uncompressed data extracted from it to the output file.
- */
- while ((len = gzread(inGZ, buf, sizeof(buf))) > 0)
- {
- if (fullWrite(outFD, buf, len) < 0)
- {
- perror(outputFileName);
-
- goto failed;
- }
-
- if (intFlag)
- goto failed;
- }
-
- if (len < 0)
- {
- fprintf(stderr, "%s: %s\n", inputFileName,
- gzerror(inGZ, &err));
-
- goto failed;
- }
-
- /*
- * All done, close the files.
- */
- if (close(outFD))
- {
- perror(outputFileName);
-
- goto failed;
- }
-
- outFD = -1;
-
- if (gzclose(inGZ) != Z_OK)
- {
- fprintf(stderr, "%s: gzclose failed\n", inputFileName);
-
- goto failed;
- }
-
- inGZ = NULL;
-
- /*
- * Success.
- */
- return TRUE;
-
-
-/*
- * Here on an error, to clean up.
- */
-failed:
- if (outFD >= 0)
- (void) close(outFD);
-
- if (inGZ != NULL)
- (void) gzclose(inGZ);
-
- return FALSE;
-}
-
-
-/*
- * Convert an input file name to an output file name according to
- * the specified convertion table. The returned name points into a
- * static buffer which is overwritten on each call. The table must
- * end in an entry which always specifies a successful conversion.
- * If no conversion is done the original input file name pointer is
- * returned.
- */
-const char *
-convertName(const CONVERT * table, const char * inputFile)
-{
- int inputLength;
- int testLength;
- static char buf[PATH_LEN];
-
- inputLength = strlen(inputFile);
-
- for (;;)
- {
- testLength = strlen(table->input);
-
- if ((inputLength >= testLength) &&
- (memcmp(table->input,
- inputFile + inputLength - testLength,
- testLength) == 0))
- {
- break;
- }
-
- table++;
- }
-
- /*
- * If no conversion was done, return the original pointer.
- */
- if ((testLength == 0) && (table->output[0] == '\0'))
- return inputFile;
-
- /*
- * Build the new name and return it.
- */
- memcpy(buf, inputFile, inputLength - testLength);
-
- memcpy(buf + inputLength - testLength, table->output,
- strlen(table->output) + 1);
-
- return buf;
-}
-
-
-#endif
-
-/* END CODE */