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
19extern const char* __progname;
20const char* kCommandName = __progname;
21
22
23static 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 compression.\n"
32	"                 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 pre-exiting\n"
36	"                 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 package\n"
46	"    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 compression.\n"
55	"                 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 compression.\n"
111	"                 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
121void
122print_usage_and_exit(bool error)
123{
124    fprintf(error ? stderr : stdout, kUsage, kCommandName);
125    exit(error ? 1 : 0);
126}
127
128
129int32
130parse_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
152int
153main(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