1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include "package.h"
9
10 #include <errno.h>
11 #include <getopt.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include <package/hpkg/HPKGDefs.h>
17
18
19 extern const char* __progname;
20 const char* kCommandName = __progname;
21
22
23 static const char* kUsage =
24 "Usage: %s <command> <command args>\n"
25 "Creates, inspects, or extracts a Haiku package.\n"
26 "\n"
27 "Commands:\n"
28 " add [ <options> ] <package> <entries>...\n"
29 " Adds the specified entries <entries> to package file <package>.\n"
30 "\n"
31 " -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best\n"
32 " compression. Defaults to 9.\n"
33 " -C <dir> - Change to directory <dir> before adding entries.\n"
34 " -f - Force adding, replacing already existing entries. Without\n"
35 " this option adding will fail when encountering a\n"
36 " pre-existing entry (directories will be merged, though).\n"
37 " -i <info> - Use the package info file <info>. It will be added as\n"
38 " \".PackageInfo\", overriding a \".PackageInfo\" file,\n"
39 " existing.\n"
40 " -q - Be quiet (don't show any output except for errors).\n"
41 " -v - Be verbose (show more info about created package).\n"
42 "\n"
43 " checksum [ <options> ] [ <package> ]\n"
44 " Computes the checksum of package file <package>. If <package> is omitted\n"
45 " or \"-\", the file is read from stdin. This is only supported, if the\n"
46 " package is uncompressed.\n"
47 "\n"
48 " -q - Be quiet (don't show any output except for errors).\n"
49 " -v - Be verbose (show more info about created package).\n"
50 "\n"
51 " create [ <options> ] <package>\n"
52 " Creates package file <package> from contents of current directory.\n"
53 "\n"
54 " -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best\n"
55 " compression. Defaults to 9.\n"
56 " -b - Create an empty build package. Only the .PackageInfo will\n"
57 " be added.\n"
58 " -C <dir> - Change to directory <dir> before adding entries.\n"
59 " -i <info> - Use the package info file <info>. It will be added as\n"
60 " \".PackageInfo\", overriding a \".PackageInfo\" file,\n"
61 " existing.\n"
62 " -I <path> - Set the package's installation path to <path>. This is\n"
63 " an option only for use in package building. It will cause\n"
64 " the package .self link to point to <path>, which is useful\n"
65 " to redirect a \"make install\". Only allowed with -b.\n"
66 " -z <type> - Specify compression method to use.\n"
67 " -q - Be quiet (don't show any output except for errors).\n"
68 " -v - Be verbose (show more info about created package).\n"
69 "\n"
70 " dump [ <options> ] <package>\n"
71 " Dumps the TOC section of package file <package>. For debugging only.\n"
72 "\n"
73 " extract [ <options> ] <package> [ <entries>... ]\n"
74 " Extracts the contents of package file <package>. If <entries> are\n"
75 " specified, only those entries are extracted (directories recursively).\n"
76 "\n"
77 " -C <dir> - Change to directory <dir> before extracting the contents\n"
78 " of the archive.\n"
79 " -i <info> - Extract the .PackageInfo file to <info> instead.\n"
80 "\n"
81 " info [ <options> ] <package>\n"
82 " Prints individual meta information of package file <package>.\n"
83 "\n"
84 " -f <format>, --format <format>\n"
85 " - Print the given format string, performing the following\n"
86 " replacements:\n"
87 " %%fileName%% - the package's canonical file name\n"
88 " %%name%% - the package name\n"
89 " %%version%% - the package version\n"
90 " %%%% - %%\n"
91 " \\n - new line\n"
92 " \\t - tab\n"
93 "\n"
94 " list [ <options> ] <package>\n"
95 " Lists the contents of package file <package>.\n"
96 "\n"
97 " -a - Also list the file attributes.\n"
98 " -i - Only print the meta information, not the files.\n"
99 " -p - Only print a list of file paths.\n"
100 "\n"
101 " recompress [ <options> ] <input package> <output package>\n"
102 " Reads the package file <input package> and writes it to new package\n"
103 " <output package> using the specified compression options. If the\n"
104 " compression level 0 is specified (i.e. no compression), "
105 "<output package>\n"
106 " can be \"-\", in which case the data are written to stdout.\n"
107 " If the input files doesn't use compression <input package>\n"
108 " can be \"-\", in which case the data are read from stdin.\n"
109 "\n"
110 " -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best\n"
111 " compression. Defaults to 9.\n"
112 " -z <type> - Specify compression method to use.\n"
113 " -q - Be quiet (don't show any output except for errors).\n"
114 " -v - Be verbose (show more info about created package).\n"
115 "\n"
116 "Common Options:\n"
117 " -h, --help - Print this usage info.\n"
118 ;
119
120
121 void
print_usage_and_exit(bool error)122 print_usage_and_exit(bool error)
123 {
124 fprintf(error ? stderr : stdout, kUsage, kCommandName);
125 exit(error ? 1 : 0);
126 }
127
128
129 int32
parse_compression_argument(const char * arg)130 parse_compression_argument(const char* arg)
131 {
132 if (arg == NULL) {
133 // Default compression method.
134 #ifdef ZSTD_DEFAULT
135 return BPackageKit::BHPKG::B_HPKG_COMPRESSION_ZSTD;
136 #else
137 return BPackageKit::BHPKG::B_HPKG_COMPRESSION_ZLIB;
138 #endif
139 }
140
141 if (strcmp(arg, "zstd") == 0) {
142 return BPackageKit::BHPKG::B_HPKG_COMPRESSION_ZSTD;
143 } else if (strcmp(arg, "zlib") == 0) {
144 return BPackageKit::BHPKG::B_HPKG_COMPRESSION_ZLIB;
145 } else {
146 fprintf(stderr, "error: unknown compression method '%s'\n", arg);
147 exit(1);
148 }
149 }
150
151
152 int
main(int argc,const char * const * argv)153 main(int argc, const char* const* argv)
154 {
155 if (argc < 2)
156 print_usage_and_exit(true);
157
158 const char* command = argv[1];
159 if (strcmp(command, "add") == 0)
160 return command_add(argc - 1, argv + 1);
161
162 if (strcmp(command, "checksum") == 0)
163 return command_checksum(argc - 1, argv + 1);
164
165 if (strcmp(command, "create") == 0)
166 return command_create(argc - 1, argv + 1);
167
168 if (strcmp(command, "dump") == 0)
169 return command_dump(argc - 1, argv + 1);
170
171 if (strcmp(command, "extract") == 0)
172 return command_extract(argc - 1, argv + 1);
173
174 if (strcmp(command, "list") == 0)
175 return command_list(argc - 1, argv + 1);
176
177 if (strcmp(command, "info") == 0)
178 return command_info(argc - 1, argv + 1);
179
180 if (strcmp(command, "recompress") == 0)
181 return command_recompress(argc - 1, argv + 1);
182
183 if (strcmp(command, "help") == 0)
184 print_usage_and_exit(false);
185 else
186 print_usage_and_exit(true);
187
188 // never gets here
189 return 0;
190 }
191