From 2fac6eaa6020569bf461de7a5884cb60362698dd Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 3 Jul 2011 04:31:59 +0200 Subject: [PATCH] Add "package add" command. --- src/bin/package/Jamfile | 1 + src/bin/package/command_add.cpp | 165 ++++++++++++++++++++++++++++++++ src/bin/package/package.cpp | 20 +++- src/bin/package/package.h | 1 + src/tools/package/Jamfile | 1 + 5 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 src/bin/package/command_add.cpp diff --git a/src/bin/package/Jamfile b/src/bin/package/Jamfile index b015b5f837..0ee72e967a 100644 --- a/src/bin/package/Jamfile +++ b/src/bin/package/Jamfile @@ -3,6 +3,7 @@ SubDir HAIKU_TOP src bin package ; UsePrivateHeaders kernel shared ; BinCommand package : + command_add.cpp command_create.cpp command_dump.cpp command_extract.cpp diff --git a/src/bin/package/command_add.cpp b/src/bin/package/command_add.cpp new file mode 100644 index 0000000000..36336842d3 --- /dev/null +++ b/src/bin/package/command_add.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2011, Oliver Tappe + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "package.h" +#include "PackageWriterListener.h" +#include "PackageWritingUtils.h" +#include "StandardErrorOutput.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; + + 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, "+C:fhi:qv", sLongOptions, + NULL); + if (c == -1) + break; + + switch (c) { + 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; + } + } + + // The remaining arguments are the package file and the entries to add. + if (optind >= argc) + print_usage_and_exit(true); + + const char* packageFileName = argv[optind++]; + + // entries must be specified, if a .PackageInfo hasn't been specified via + // an option + if (optind >= argc && packageInfoFileName == NULL) + print_usage_and_exit(true); + + const char* const* entriesToAdd = argv + optind; + int entriesToAddCount = argc - optind; + + // create package + PackageWriterListener listener(verbose, quiet); + BPackageWriter packageWriter(&listener); + status_t result = packageWriter.Init(packageFileName, + B_HPKG_WRITER_UPDATE_PACKAGE | (force ? B_HPKG_WRITER_FORCE_ADD : 0)); + if (result != B_OK) + return 1; + + // If a package info file has been specified explicitly, open it. + 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)); + } + } + + // change directory, if requested + if (changeToDirectory != NULL) { + if (chdir(changeToDirectory) != 0) { + listener.PrintError( + "Error: Failed to change the current working directory to " + "\"%s\": %s\n", changeToDirectory, strerror(errno)); + } + } + + // add the entries + for (int i = 0; i < entriesToAddCount; i++) { + const char* entry = entriesToAdd[i]; + + if (strcmp(entry, ".") == 0) { + // add all entries in the current directory; skip .PackageInfo, + // if a different file was specified + if (add_current_directory_entries(packageWriter, + listener, packageInfoFileName != NULL) != B_OK) + return 1; + } else { + // skip .PackageInfo, if a different file was specified + if (packageInfoFileName != NULL + && strcmp(entry, B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) { + continue; + } + + if (packageWriter.AddEntry(entry) != B_OK) + return 1; + } + } + + // add the .PackageInfo, if explicitly specified + if (packageInfoFileName != NULL) { + result = packageWriter.AddEntry(B_HPKG_PACKAGE_INFO_FILE_NAME, + packageInfoFD); + if (result != B_OK) + return 1; + } + + // write the package + result = packageWriter.Finish(); + if (result != B_OK) + return 1; + + if (verbose) + printf("\nsuccessfully created package '%s'\n", packageFileName); + + return 0; +} diff --git a/src/bin/package/package.cpp b/src/bin/package/package.cpp index cebeff5fc4..93797fd656 100644 --- a/src/bin/package/package.cpp +++ b/src/bin/package/package.cpp @@ -23,10 +23,25 @@ static const char* kUsage = "Creates, inspects, or extracts a Haiku package.\n" "\n" "Commands:\n" + " add [ ] ...\n" + " Adds the specified entries to package file .\n" + "\n" + " -C - Change to directory before adding entries.\n" + " -f - Force adding, replacing already existing entries. " + "Without\n" + " this option adding will fail when encountering a " + "pre-exiting\n" + " entry (directories will be merged, though).\n" + " -i - Use the package info file . It will be added as\n" + " \".PackageInfo\", overriding a \".PackageInfo\" file,\n" + " existing.\n" + " -q - Be quiet (don't show any output except for errors).\n" + " -v - Be verbose (show more info about created package).\n" + "\n" " create [ ] \n" " Creates package file from contents of current directory.\n" "\n" - " -C - Change to directory before starting.\n" + " -C - Change to directory before adding entries.\n" " -i - Use the package info file . It will be added as\n" " \".PackageInfo\", overriding a \".PackageInfo\" file,\n" " existing.\n" @@ -71,6 +86,9 @@ main(int argc, const char* const* argv) print_usage_and_exit(true); const char* command = argv[1]; + if (strcmp(command, "add") == 0) + return command_add(argc - 1, argv + 1); + if (strcmp(command, "create") == 0) return command_create(argc - 1, argv + 1); diff --git a/src/bin/package/package.h b/src/bin/package/package.h index b1b5d9a6fb..05ebf17fde 100644 --- a/src/bin/package/package.h +++ b/src/bin/package/package.h @@ -8,6 +8,7 @@ void print_usage_and_exit(bool error); +int command_add(int argc, const char* const* argv); int command_create(int argc, const char* const* argv); int command_dump(int argc, const char* const* argv); int command_extract(int argc, const char* const* argv); diff --git a/src/tools/package/Jamfile b/src/tools/package/Jamfile index 1f08a8d597..2609ede7ad 100644 --- a/src/tools/package/Jamfile +++ b/src/tools/package/Jamfile @@ -7,6 +7,7 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin package ] ; USES_BE_API on package = true ; BuildPlatformMain package : + command_add.cpp command_create.cpp command_dump.cpp command_extract.cpp