* 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 <package/PackageInfo.h>
#include <package/hpkg/HPKGDefs.h>
#include <package/hpkg/PackageWriter.h>
#include "package.h"
#include "PackageWriterListener.h"
#include "PackageWritingUtils.h"
using namespace BPackageKit::BHPKG;
int
command_add(int argc, const char* const* argv)
{
const char* changeToDirectory = NULL;
const char* packageInfoFileName = NULL;
bool quiet = false;
bool verbose = false;
bool force = false;
int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST;
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, "+0123456789C:fhi: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 'C':
changeToDirectory = optarg;
break;
case 'h':
print_usage_and_exit(false);
break;
case 'f':
force = true;
break;
case 'i':
packageInfoFileName = optarg;
break;
case 'q':
quiet = true;
break;
case 'v':
verbose = true;
break;
default:
print_usage_and_exit(true);
break;
}
}
if (optind >= argc)
print_usage_and_exit(true);
const char* packageFileName = argv[optind++];
if (optind >= argc && packageInfoFileName == NULL)
print_usage_and_exit(true);
const char* const* entriesToAdd = argv + optind;
int entriesToAddCount = argc - optind;
BPackageWriterParameters writerParameters;
writerParameters.SetFlags(
B_HPKG_WRITER_UPDATE_PACKAGE | (force ? B_HPKG_WRITER_FORCE_ADD : 0));
writerParameters.SetCompressionLevel(compressionLevel);
if (compressionLevel == 0) {
writerParameters.SetCompression(
BPackageKit::BHPKG::B_HPKG_COMPRESSION_NONE);
}
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));
}
}
if (changeToDirectory != NULL) {
if (chdir(changeToDirectory) != 0) {
listener.PrintError(
"Error: Failed to change the current working directory to "
"\"%s\": %s\n", changeToDirectory, strerror(errno));
}
}
for (int i = 0; i < entriesToAddCount; i++) {
const char* entry = entriesToAdd[i];
if (strcmp(entry, ".") == 0) {
if (add_current_directory_entries(packageWriter,
listener, packageInfoFileName != NULL) != B_OK)
return 1;
} else {
if (packageInfoFileName != NULL
&& strcmp(entry, B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
continue;
}
if (packageWriter.AddEntry(entry) != B_OK)
return 1;
}
}
if (packageInfoFileName != NULL) {
result = packageWriter.AddEntry(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;
}