/*
* Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <File.h>
#include <package/hpkg/HPKGDefs.h>
#include <package/hpkg/PackageReader.h>
#include <package/hpkg/PackageWriter.h>
#include <DataPositionIOWrapper.h>
#include <FdIO.h>
#include "package.h"
#include "PackageWriterListener.h"
using BPackageKit::BHPKG::BPackageReader;
using BPackageKit::BHPKG::BPackageWriter;
using BPackageKit::BHPKG::BPackageWriterListener;
using BPackageKit::BHPKG::BPackageWriterParameters;
static BPositionIO*
create_stdio(bool isInput)
{
BFdIO* dataIO = new BFdIO(isInput ? 0 : 1, false);
return new BDataPositionIOWrapper(dataIO);
}
int
command_recompress(int argc, const char* const* argv)
{
bool quiet = false;
bool verbose = false;
int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST;
int32 compression = BPackageKit::BHPKG::B_HPKG_COMPRESSION_ZLIB;
while (true) {
static struct option sLongOptions[] = {
{ "help", no_argument, 0, 'h' },
{ "quiet", no_argument, 0, 'q' },
{ "verbose", no_argument, 0, 'v' },
{ 0, 0, 0, 0 }
};
opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "+0123456789:hqvz",
sLongOptions, NULL);
if (c == -1)
break;
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
compressionLevel = c - '0';
break;
case 'h':
print_usage_and_exit(false);
break;
case 'q':
quiet = true;
break;
case 'v':
verbose = true;
break;
case 'z':
compression = BPackageKit::BHPKG::B_HPKG_COMPRESSION_ZSTD;
break;
default:
print_usage_and_exit(true);
break;
}
}
// The remaining arguments are the input package file and the output
// package file, i.e. two more arguments.
if (argc - optind != 2)
print_usage_and_exit(true);
const char* inputPackageFileName = argv[optind++];
const char* outputPackageFileName = argv[optind++];
// open the input package
status_t error = B_OK;
BPositionIO* inputFile;
if (strcmp(inputPackageFileName, "-") == 0) {
inputFile = create_stdio(true);
} else {
BFile* inputFileFile = new BFile;
error = inputFileFile->SetTo(inputPackageFileName, O_RDONLY);
if (error != B_OK) {
fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n",
inputPackageFileName, strerror(error));
return 1;
}
inputFile = inputFileFile;
}
// write the output package
BPackageWriterParameters writerParameters;
writerParameters.SetCompressionLevel(compressionLevel);
if (compressionLevel == 0) {
writerParameters.SetCompression(
BPackageKit::BHPKG::B_HPKG_COMPRESSION_NONE);
}
if (compressionLevel == 0)
compression = BPackageKit::BHPKG::B_HPKG_COMPRESSION_NONE;
writerParameters.SetCompression(compression);
PackageWriterListener listener(verbose, quiet);
BPackageWriter packageWriter(&listener);
if (strcmp(outputPackageFileName, "-") == 0) {
if (compressionLevel != 0) {
fprintf(stderr, "Error: Writing to stdout is supported only with "
"compression level 0.\n");
return 1;
}
error = packageWriter.Init(create_stdio(false), true,
&writerParameters);
} else
error = packageWriter.Init(outputPackageFileName, &writerParameters);
if (error != B_OK)
return 1;
error = packageWriter.Recompress(inputFile);
if (error != B_OK)
return 1;
if (verbose)
printf("\nsuccessfully wrote package '%s'\n", outputPackageFileName);
return 0;
}
↑ V773 The function was exited without releasing the 'inputFileFile' pointer. A memory leak is possible.