* Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.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 <Entry.h>
#include <Path.h>
#include <package/PackageInfo.h>
#include <package/hpkg/HPKGDefs.h>
#include <package/hpkg/PackageWriter.h>
#include "package.h"
#include "PackageWriterListener.h"
#include "PackageWritingUtils.h"
using BPackageKit::BHPKG::BPackageWriter;
using BPackageKit::BHPKG::BPackageWriterListener;
using BPackageKit::BHPKG::BPackageWriterParameters;
int
command_create(int argc, const char* const* argv)
{
const char* changeToDirectory = NULL;
const char* packageInfoFileName = NULL;
const char* installPath = NULL;
bool isBuildPackage = false;
bool quiet = false;
bool verbose = false;
int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST;
int32 compression = parse_compression_argument(NULL);
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;
int c = getopt_long(argc, (char**)argv, "+b0123456789C:hi:I:z:qv",
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 'b':
isBuildPackage = true;
break;
case 'C':
changeToDirectory = optarg;
break;
case 'h':
print_usage_and_exit(false);
break;
case 'i':
packageInfoFileName = optarg;
break;
case 'I':
installPath = optarg;
break;
case 'z':
compression = parse_compression_argument(optarg);
break;
case 'q':
quiet = true;
break;
case 'v':
verbose = true;
break;
default:
print_usage_and_exit(true);
break;
}
}
if (optind + 1 != argc)
print_usage_and_exit(true);
const char* packageFileName = argv[optind++];
if (installPath != NULL && !isBuildPackage) {
fprintf(stderr, "Error: \"-I\" is only allowed when \"-b\" is "
"given.\n");
return 1;
}
BPath outputPath(packageFileName, NULL, true);
BPath inputPath(changeToDirectory, NULL, true);
BPath parent;
while (outputPath.GetParent(&parent) == B_OK) {
if (outputPath == inputPath) {
fprintf(stderr, "Error: output package can't be in the same "
"directory as input files.");
return 1;
}
outputPath = parent;
}
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);
status_t result = packageWriter.Init(packageFileName, &writerParameters);
if (result != B_OK)
return 1;
int packageInfoFD = -1;
if (packageInfoFileName != NULL) {
packageInfoFD = open(packageInfoFileName, O_RDONLY);
if (packageInfoFD < 0) {
fprintf(stderr, "Error: Failed to open package info file \"%s\": "
"%s\n", packageInfoFileName, strerror(errno));
return 1;
}
}
if (changeToDirectory != NULL) {
if (chdir(changeToDirectory) != 0) {
listener.PrintError(
"Error: Failed to change the current working directory to "
"\"%s\": %s\n", changeToDirectory, strerror(errno));
return 1;
}
}
if (isBuildPackage)
packageWriter.SetCheckLicenses(false);
if (installPath != NULL) {
result = packageWriter.SetInstallPath(installPath);
if (result != B_OK) {
fprintf(stderr, "Error: Failed to set the package install path: "
"%s\n", strerror(result));
return 1;
}
}
if (!isBuildPackage) {
if (add_current_directory_entries(packageWriter, listener, true)
!= B_OK) {
return 1;
}
}
result = packageWriter.AddEntry(
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME, packageInfoFD);
if (result != B_OK)
return 1;
result = packageWriter.Finish();
if (result != B_OK)
return 1;
if (verbose)
printf("\nsuccessfully created package '%s'\n", packageFileName);
return 0;
}