btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / package / command_add.cpp
blobf0f766140f8e19a94644f8a9c2d4ba303f874307
1 /*
2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
4 * Distributed under the terms of the MIT License.
5 */
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <getopt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
16 #include <Entry.h>
18 #include <package/PackageInfo.h>
19 #include <package/hpkg/HPKGDefs.h>
20 #include <package/hpkg/PackageWriter.h>
22 #include "package.h"
23 #include "PackageWriterListener.h"
24 #include "PackageWritingUtils.h"
27 using namespace BPackageKit::BHPKG;
30 int
31 command_add(int argc, const char* const* argv)
33 const char* changeToDirectory = NULL;
34 const char* packageInfoFileName = NULL;
35 bool quiet = false;
36 bool verbose = false;
37 bool force = false;
38 int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST;
40 while (true) {
41 static struct option sLongOptions[] = {
42 { "help", no_argument, 0, 'h' },
43 { "quiet", no_argument, 0, 'q' },
44 { "verbose", no_argument, 0, 'v' },
45 { 0, 0, 0, 0 }
48 opterr = 0; // don't print errors
49 int c = getopt_long(argc, (char**)argv, "+0123456789C:fhi:qv",
50 sLongOptions, NULL);
51 if (c == -1)
52 break;
54 switch (c) {
55 case '0':
56 case '1':
57 case '2':
58 case '3':
59 case '4':
60 case '5':
61 case '6':
62 case '7':
63 case '8':
64 case '9':
65 compressionLevel = c - '0';
66 break;
68 case 'C':
69 changeToDirectory = optarg;
70 break;
72 case 'h':
73 print_usage_and_exit(false);
74 break;
76 case 'f':
77 force = true;
78 break;
80 case 'i':
81 packageInfoFileName = optarg;
82 break;
84 case 'q':
85 quiet = true;
86 break;
88 case 'v':
89 verbose = true;
90 break;
92 default:
93 print_usage_and_exit(true);
94 break;
98 // The remaining arguments are the package file and the entries to add.
99 if (optind >= argc)
100 print_usage_and_exit(true);
102 const char* packageFileName = argv[optind++];
104 // entries must be specified, if a .PackageInfo hasn't been specified via
105 // an option
106 if (optind >= argc && packageInfoFileName == NULL)
107 print_usage_and_exit(true);
109 const char* const* entriesToAdd = argv + optind;
110 int entriesToAddCount = argc - optind;
112 // create package
113 BPackageWriterParameters writerParameters;
114 writerParameters.SetFlags(
115 B_HPKG_WRITER_UPDATE_PACKAGE | (force ? B_HPKG_WRITER_FORCE_ADD : 0));
116 writerParameters.SetCompressionLevel(compressionLevel);
117 if (compressionLevel == 0) {
118 writerParameters.SetCompression(
119 BPackageKit::BHPKG::B_HPKG_COMPRESSION_NONE);
122 PackageWriterListener listener(verbose, quiet);
123 BPackageWriter packageWriter(&listener);
124 status_t result = packageWriter.Init(packageFileName, &writerParameters);
125 if (result != B_OK)
126 return 1;
128 // If a package info file has been specified explicitly, open it.
129 int packageInfoFD = -1;
130 if (packageInfoFileName != NULL) {
131 packageInfoFD = open(packageInfoFileName, O_RDONLY);
132 if (packageInfoFD < 0) {
133 fprintf(stderr, "Error: Failed to open package info file \"%s\": "
134 "%s\n", packageInfoFileName, strerror(errno));
138 // change directory, if requested
139 if (changeToDirectory != NULL) {
140 if (chdir(changeToDirectory) != 0) {
141 listener.PrintError(
142 "Error: Failed to change the current working directory to "
143 "\"%s\": %s\n", changeToDirectory, strerror(errno));
147 // add the entries
148 for (int i = 0; i < entriesToAddCount; i++) {
149 const char* entry = entriesToAdd[i];
151 if (strcmp(entry, ".") == 0) {
152 // add all entries in the current directory; skip .PackageInfo,
153 // if a different file was specified
154 if (add_current_directory_entries(packageWriter,
155 listener, packageInfoFileName != NULL) != B_OK)
156 return 1;
157 } else {
158 // skip .PackageInfo, if a different file was specified
159 if (packageInfoFileName != NULL
160 && strcmp(entry, B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
161 continue;
164 if (packageWriter.AddEntry(entry) != B_OK)
165 return 1;
169 // add the .PackageInfo, if explicitly specified
170 if (packageInfoFileName != NULL) {
171 result = packageWriter.AddEntry(B_HPKG_PACKAGE_INFO_FILE_NAME,
172 packageInfoFD);
173 if (result != B_OK)
174 return 1;
177 // write the package
178 result = packageWriter.Finish();
179 if (result != B_OK)
180 return 1;
182 if (verbose)
183 printf("\nsuccessfully created package '%s'\n", packageFileName);
185 return 0;