btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / package_repo / command_create.cpp
blob1d8c1d04721b08f70c07a6080c2ee53bb8a545d1
1 /*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Distributed under the terms of the MIT License.
4 */
7 #include <dirent.h>
8 #include <errno.h>
9 #include <getopt.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include <Entry.h>
15 #include <Path.h>
17 #include <package/hpkg/HPKGDefs.h>
18 #include <package/hpkg/RepositoryWriter.h>
19 #include <package/PackageInfo.h>
20 #include <package/RepositoryInfo.h>
22 #include "package_repo.h"
25 using BPackageKit::BHPKG::BRepositoryWriterListener;
26 using BPackageKit::BHPKG::BRepositoryWriter;
27 using namespace BPackageKit;
30 class RepositoryWriterListener : public BRepositoryWriterListener {
31 public:
32 RepositoryWriterListener(bool verbose, bool quiet)
33 : fVerbose(verbose), fQuiet(quiet)
37 virtual void PrintErrorVarArgs(const char* format, va_list args)
39 vfprintf(stderr, format, args);
42 virtual void OnPackageAdded(const BPackageInfo& packageInfo)
44 if (fQuiet)
45 return;
47 printf("%s (%s)\n", packageInfo.Name().String(),
48 packageInfo.Version().ToString().String());
49 if (fVerbose) {
50 printf("\tsummary: %s\n", packageInfo.Summary().String());
51 printf("\tvendor: %s\n", packageInfo.Vendor().String());
52 printf("\tpackager: %s\n", packageInfo.Packager().String());
53 printf("\tchecksum: %s\n", packageInfo.Checksum().String());
54 if (uint32 flags = packageInfo.Flags()) {
55 printf("\tflags:\n");
56 if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
57 printf("\t\tapprove_license\n");
58 if ((flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
59 printf("\t\tsystem_package\n");
61 } else
62 printf("\tchecksum: %s\n", packageInfo.Checksum().String());
65 virtual void OnRepositoryInfoSectionDone(uint32 uncompressedSize)
67 if (fQuiet || !fVerbose)
68 return;
70 printf("----- Repository Info Section --------------------\n");
71 printf("repository info size: %10" B_PRIu32 " (uncompressed)\n",
72 uncompressedSize);
75 virtual void OnPackageAttributesSectionDone(uint32 stringCount,
76 uint32 uncompressedSize)
78 if (fQuiet || !fVerbose)
79 return;
81 printf("----- Package Attribute Section -------------------\n");
82 printf("string count: %10" B_PRIu32 "\n", stringCount);
83 printf("package attributes size: %10" B_PRIu32 " (uncompressed)\n",
84 uncompressedSize);
87 virtual void OnRepositoryDone(uint32 headerSize, uint32 repositoryInfoSize,
88 uint32 licenseCount, uint32 packageCount, uint32 packageAttributesSize,
89 uint64 totalSize)
91 if (fQuiet)
92 return;
94 printf("----- Package Repository Info -----\n");
95 if (fVerbose)
96 printf("embedded license count %10" B_PRIu32 "\n", licenseCount);
97 printf("package count %10" B_PRIu32 "\n", packageCount);
98 printf("-----------------------------------\n");
99 printf("header size: %10" B_PRIu32 "\n", headerSize);
100 printf("repository header size: %10" B_PRIu32 "\n",
101 repositoryInfoSize);
102 printf("package attributes size: %10" B_PRIu32 "\n",
103 packageAttributesSize);
104 printf("total size: %10" B_PRIu64 "\n", totalSize);
105 printf("-----------------------------------\n");
108 private:
109 bool fVerbose;
110 bool fQuiet;
115 command_create(int argc, const char* const* argv)
117 const char* changeToDirectory = NULL;
118 bool quiet = false;
119 bool verbose = false;
121 while (true) {
122 static struct option sLongOptions[] = {
123 { "help", no_argument, 0, 'h' },
124 { "quiet", no_argument, 0, 'q' },
125 { "verbose", no_argument, 0, 'v' },
126 { 0, 0, 0, 0 }
129 opterr = 0; // don't print errors
130 int c = getopt_long(argc, (char**)argv, "+C:hqv", sLongOptions, NULL);
131 if (c == -1)
132 break;
134 switch (c) {
135 case 'C':
136 changeToDirectory = optarg;
137 break;
139 case 'h':
140 print_usage_and_exit(false);
141 break;
143 case 'q':
144 quiet = true;
145 break;
147 case 'v':
148 verbose = true;
149 break;
151 default:
152 print_usage_and_exit(true);
153 break;
157 // The remaining arguments are the repository info file plus one or more
158 // package files, i.e. at least two more arguments.
159 if (optind + 2 > argc)
160 print_usage_and_exit(true);
162 const char* repositoryInfoFileName = argv[optind++];
163 const char* const* packageFileNames = argv + optind;
165 RepositoryWriterListener listener(verbose, quiet);
167 BEntry repositoryInfoEntry(repositoryInfoFileName);
168 if (!repositoryInfoEntry.Exists()) {
169 listener.PrintError(
170 "Error: given repository-info file '%s' doesn't exist!\n",
171 repositoryInfoFileName);
172 return 1;
175 // determine path for 'repo' file from given info file
176 BEntry repositoryParentEntry;
177 repositoryInfoEntry.GetParent(&repositoryParentEntry);
178 BPath repositoryPath;
179 if (repositoryParentEntry.GetPath(&repositoryPath) != B_OK) {
180 listener.PrintError(
181 "Error: can't determine path of given repository-info file!\n");
182 return 1;
184 repositoryPath.Append("repo");
186 // create repository
187 BRepositoryInfo repositoryInfo(repositoryInfoEntry);
188 status_t result = repositoryInfo.InitCheck();
189 if (result != B_OK) {
190 listener.PrintError(
191 "Error: can't parse given repository-info file : %s\n",
192 strerror(result));
193 return 1;
195 BRepositoryWriter repositoryWriter(&listener, &repositoryInfo);
196 if ((result = repositoryWriter.Init(repositoryPath.Path())) != B_OK) {
197 listener.PrintError("Error: can't initialize repository-writer : %s\n",
198 strerror(result));
199 return 1;
202 // change directory, if requested
203 if (changeToDirectory != NULL) {
204 if (chdir(changeToDirectory) != 0) {
205 listener.PrintError(
206 "Error: Failed to change the current working directory to "
207 "\"%s\": %s\n", changeToDirectory, strerror(errno));
208 return 1;
212 // add all given package files
213 for (int i = 0; i < argc - optind; ++i) {
214 if (verbose)
215 printf("reading package '%s' ...\n", packageFileNames[i]);
216 BEntry entry(packageFileNames[i]);
217 if (!entry.Exists()) {
218 printf("package '%s' does not exist\n", packageFileNames[i]);
219 return 1;
221 result = repositoryWriter.AddPackage(entry);
222 if (result != B_OK)
223 return 1;
226 // write the repository
227 result = repositoryWriter.Finish();
228 if (result != B_OK)
229 return 1;
231 if (verbose) {
232 printf("\nsuccessfully created repository '%s'\n",
233 repositoryPath.Path());
236 return 0;