VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/fs/isomakercmd.cpp@ 67341

Last change on this file since 67341 was 67341, checked in by vboxsync, 8 years ago

IPRT: More ISO maker code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 51.0 KB
Line 
1/* $Id: isomakercmd.cpp 67341 2017-06-12 17:06:30Z vboxsync $ */
2/** @file
3 * IPRT - ISO Image Maker Command.
4 */
5
6/*
7 * Copyright (C) 2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_FS
32#include "internal/iprt.h"
33#include <iprt/fsisomaker.h>
34
35#include <iprt/assert.h>
36#include <iprt/buildconfig.h>
37#include <iprt/ctype.h>
38#include <iprt/file.h>
39#include <iprt/err.h>
40#include <iprt/getopt.h>
41#include <iprt/log.h>
42#include <iprt/mem.h>
43#include <iprt/message.h>
44#include <iprt/rand.h>
45#include <iprt/stream.h>
46#include <iprt/string.h>
47#include <iprt/vfs.h>
48
49
50/*********************************************************************************************************************************
51* Structures and Typedefs *
52*********************************************************************************************************************************/
53typedef enum RTFSISOMAKERCMDOPT
54{
55 RTFSISOMAKERCMD_OPT_FIRST = 1000,
56
57 RTFSISOMAKERCMD_OPT_IPRT_ISO_MAKER_FILE_MARKER,
58 RTFSISOMAKERCMD_OPT_OUTPUT_BUFFER_SIZE,
59 RTFSISOMAKERCMD_OPT_RANDOM_OUTPUT_BUFFER_SIZE,
60
61 /*
62 * Compatibility options:
63 */
64 RTFSISOMAKERCMD_OPT_ABSTRACT_FILE_ID,
65 RTFSISOMAKERCMD_OPT_ALLOW_LEADING_DOTS,
66 RTFSISOMAKERCMD_OPT_ALLOW_LIMITED_SIZE,
67 RTFSISOMAKERCMD_OPT_ALLOW_LOWERCASE,
68 RTFSISOMAKERCMD_OPT_ALLOW_MULTI_DOT,
69 RTFSISOMAKERCMD_OPT_ALPHA_BOOT,
70 RTFSISOMAKERCMD_OPT_APPLE,
71 RTFSISOMAKERCMD_OPT_BIBLIOGRAPHIC_FILE_ID,
72 RTFSISOMAKERCMD_OPT_CHECK_OLD_NAMES,
73 RTFSISOMAKERCMD_OPT_CHECK_SESSION,
74 RTFSISOMAKERCMD_OPT_COPYRIGHT_FILE_ID,
75 RTFSISOMAKERCMD_OPT_DETECT_HARDLINKS,
76 RTFSISOMAKERCMD_OPT_DIR_MODE,
77 RTFSISOMAKERCMD_OPT_DVD_VIDEO,
78 RTFSISOMAKERCMD_OPT_ELTORITO_ALT_BOOT,
79 RTFSISOMAKERCMD_OPT_ELTORITO_HARD_DISK_BOOT,
80 RTFSISOMAKERCMD_OPT_ELTORITO_INFO_TABLE,
81 RTFSISOMAKERCMD_OPT_ELTORITO_LOAD_SEG,
82 RTFSISOMAKERCMD_OPT_ELTORITO_LOAD_SIZE,
83 RTFSISOMAKERCMD_OPT_ELTORITO_NO_BOOT,
84 RTFSISOMAKERCMD_OPT_ELTORITO_NO_EMULATION_BOOT,
85 RTFSISOMAKERCMD_OPT_EXCLUDE_LIST,
86 RTFSISOMAKERCMD_OPT_FILE_MODE,
87 RTFSISOMAKERCMD_OPT_FORCE_RR,
88 RTFSISOMAKERCMD_OPT_GID,
89 RTFSISOMAKERCMD_OPT_GRAFT_POINTS,
90 RTFSISOMAKERCMD_OPT_GUI,
91 RTFSISOMAKERCMD_OPT_HFS_AUTO,
92 RTFSISOMAKERCMD_OPT_HFS_BLESS,
93 RTFSISOMAKERCMD_OPT_HFS_BOOT_FILE,
94 RTFSISOMAKERCMD_OPT_HFS_CAP,
95 RTFSISOMAKERCMD_OPT_HFS_CHRP_BOOT,
96 RTFSISOMAKERCMD_OPT_HFS_CLUSTER_SIZE,
97 RTFSISOMAKERCMD_OPT_HFS_CREATOR,
98 RTFSISOMAKERCMD_OPT_HFS_DAVE,
99 RTFSISOMAKERCMD_OPT_HFS_DOUBLE,
100 RTFSISOMAKERCMD_OPT_HFS_ENABLE,
101 RTFSISOMAKERCMD_OPT_HFS_ETHERSHARE,
102 RTFSISOMAKERCMD_OPT_HFS_EXCHANGE,
103 RTFSISOMAKERCMD_OPT_HFS_HIDE,
104 RTFSISOMAKERCMD_OPT_HFS_HIDE_LIST,
105 RTFSISOMAKERCMD_OPT_HFS_ICON_POSITION,
106 RTFSISOMAKERCMD_OPT_HFS_INPUT_CHARSET,
107 RTFSISOMAKERCMD_OPT_HFS_MAC_NAME,
108 RTFSISOMAKERCMD_OPT_HFS_MACBIN,
109 RTFSISOMAKERCMD_OPT_HFS_MAGIC,
110 RTFSISOMAKERCMD_OPT_HFS_MAP,
111 RTFSISOMAKERCMD_OPT_HFS_NETATALK,
112 RTFSISOMAKERCMD_OPT_HFS_NO_DESKTOP,
113 RTFSISOMAKERCMD_OPT_HFS_OSX_DOUBLE,
114 RTFSISOMAKERCMD_OPT_HFS_OSX_HFS,
115 RTFSISOMAKERCMD_OPT_HFS_OUTPUT_CHARSET,
116 RTFSISOMAKERCMD_OPT_HFS_PARMS,
117 RTFSISOMAKERCMD_OPT_HFS_PART,
118 RTFSISOMAKERCMD_OPT_HFS_PREP_BOOT,
119 RTFSISOMAKERCMD_OPT_HFS_PROBE,
120 RTFSISOMAKERCMD_OPT_HFS_ROOT_INFO,
121 RTFSISOMAKERCMD_OPT_HFS_SFM,
122 RTFSISOMAKERCMD_OPT_HFS_SGI,
123 RTFSISOMAKERCMD_OPT_HFS_SINGLE,
124 RTFSISOMAKERCMD_OPT_HFS_TYPE,
125 RTFSISOMAKERCMD_OPT_HFS_UNLOCK,
126 RTFSISOMAKERCMD_OPT_HFS_USHARE,
127 RTFSISOMAKERCMD_OPT_HFS_VOL_ID,
128 RTFSISOMAKERCMD_OPT_HFS_XINET,
129 RTFSISOMAKERCMD_OPT_HIDDEN,
130 RTFSISOMAKERCMD_OPT_HIDDEN_LIST,
131 RTFSISOMAKERCMD_OPT_HIDE,
132 RTFSISOMAKERCMD_OPT_HIDE_JOLIET,
133 RTFSISOMAKERCMD_OPT_HIDE_JOLIET_LIST,
134 RTFSISOMAKERCMD_OPT_HIDE_JOLIET_TRANS_TBL,
135 RTFSISOMAKERCMD_OPT_HIDE_LIST,
136 RTFSISOMAKERCMD_OPT_HIDE_RR_MOVED,
137 RTFSISOMAKERCMD_OPT_HPPA_BOOTLOADER,
138 RTFSISOMAKERCMD_OPT_HPPA_CMDLINE,
139 RTFSISOMAKERCMD_OPT_HPPA_KERNEL_32,
140 RTFSISOMAKERCMD_OPT_HPPA_KERNEL_64,
141 RTFSISOMAKERCMD_OPT_HPPA_RAMDISK,
142 RTFSISOMAKERCMD_OPT_INPUT_CHARSET,
143 RTFSISOMAKERCMD_OPT_ISO_LEVEL,
144 RTFSISOMAKERCMD_OPT_JIGDO_COMPRESS,
145 RTFSISOMAKERCMD_OPT_JIGDO_EXCLUDE,
146 RTFSISOMAKERCMD_OPT_JIGDO_FORCE_MD5,
147 RTFSISOMAKERCMD_OPT_JIGDO_JIGDO,
148 RTFSISOMAKERCMD_OPT_JIGDO_MAP,
149 RTFSISOMAKERCMD_OPT_JIGDO_MD5_LIST,
150 RTFSISOMAKERCMD_OPT_JIGDO_MIN_FILE_SIZE,
151 RTFSISOMAKERCMD_OPT_JIGDO_TEMPLATE,
152 RTFSISOMAKERCMD_OPT_JOLIET_CHARSET,
153 RTFSISOMAKERCMD_OPT_JOLIET_LEVEL,
154 RTFSISOMAKERCMD_OPT_JOLIET_LONG,
155 RTFSISOMAKERCMD_OPT_LOG_FILE,
156 RTFSISOMAKERCMD_OPT_MAX_ISO9660_FILENAMES,
157 RTFSISOMAKERCMD_OPT_MIPS_BOOT,
158 RTFSISOMAKERCMD_OPT_MIPSEL_BOOT,
159 RTFSISOMAKERCMD_OPT_NEW_DIR_MODE,
160 RTFSISOMAKERCMD_OPT_NO_BACKUP_FILES,
161 RTFSISOMAKERCMD_OPT_NO_DETECT_HARDLINKS,
162 RTFSISOMAKERCMD_OPT_NO_ISO_TRANSLATE,
163 RTFSISOMAKERCMD_OPT_NO_PAD,
164 RTFSISOMAKERCMD_OPT_NO_RR,
165 RTFSISOMAKERCMD_OPT_NO_SPLIT_SYMLINK_COMPONENTS,
166 RTFSISOMAKERCMD_OPT_NO_SPLIT_SYMLINK_FIELDS,
167 RTFSISOMAKERCMD_OPT_OLD_ROOT,
168 RTFSISOMAKERCMD_OPT_OUTPUT_CHARSET,
169 RTFSISOMAKERCMD_OPT_PAD,
170 RTFSISOMAKERCMD_OPT_PATH_LIST,
171 RTFSISOMAKERCMD_OPT_PRINT_SIZE,
172 RTFSISOMAKERCMD_OPT_QUIET,
173 RTFSISOMAKERCMD_OPT_RELAXED_FILENAMES,
174 RTFSISOMAKERCMD_OPT_ROOT,
175 RTFSISOMAKERCMD_OPT_SORT,
176 RTFSISOMAKERCMD_OPT_SPARC_BOOT,
177 RTFSISOMAKERCMD_OPT_SPARC_LABEL,
178 RTFSISOMAKERCMD_OPT_SPLIT_OUTPUT,
179 RTFSISOMAKERCMD_OPT_STREAM_FILE_NAME,
180 RTFSISOMAKERCMD_OPT_STREAM_MEDIA_SIZE,
181 RTFSISOMAKERCMD_OPT_SUNX86_BOOT,
182 RTFSISOMAKERCMD_OPT_SUNX86_LABEL,
183 RTFSISOMAKERCMD_OPT_SYSTEM_ID,
184 RTFSISOMAKERCMD_OPT_TRANS_TBL_NAME,
185 RTFSISOMAKERCMD_OPT_UDF,
186 RTFSISOMAKERCMD_OPT_UID,
187 RTFSISOMAKERCMD_OPT_USE_FILE_VERSION,
188 RTFSISOMAKERCMD_OPT_VOLUME_SET_ID,
189 RTFSISOMAKERCMD_OPT_VOLUME_SET_SEQ_NO,
190 RTFSISOMAKERCMD_OPT_VOLUME_SET_SIZE,
191 RTFSISOMAKERCMD_OPT_END
192} RTFSISOMAKERCMDOPT;
193
194/**
195 * ISO maker command options & state.
196 */
197typedef struct RTFSISOMAKERCMDOPTS
198{
199 /** The handle to the ISO maker. */
200 RTFSISOMAKER hIsoMaker;
201 /** Set if we're creating a virtual image maker, i.e. producing something
202 * that is going to be read from only and not written to disk. */
203 bool fVirtualImageMaker;
204 /** Extended error info. This is a stderr alternative for the
205 * fVirtualImageMaker case (stdout goes to LogRel). */
206 PRTERRINFO pErrInfo;
207
208 /** The output file.
209 * This is NULL when fVirtualImageMaker is set. */
210 const char *pszOutFile;
211 /** Special buffer size to use for testing the ISO maker code reading. */
212 uint32_t cbOutputReadBuffer;
213 /** Use random output read buffer size. cbOutputReadBuffer works as maximum
214 * when this is enabled. */
215 bool fRandomOutputReadBufferSize;
216
217
218 /** Number of items (files, directories, images, whatever) we've added. */
219 uint32_t cItemsAdded;
220} RTFSISOMAKERCMDOPTS;
221typedef RTFSISOMAKERCMDOPTS *PRTFSISOMAKERCMDOPTS;
222typedef RTFSISOMAKERCMDOPTS const *PCRTFSISOMAKERCMDOPTS;
223
224
225/*********************************************************************************************************************************
226* Global Variables *
227*********************************************************************************************************************************/
228/*
229 * Parse the command line. This is similar to genisoimage and mkisofs,
230 * thus the single dash long name aliases.
231 */
232static const RTGETOPTDEF g_aRtFsIsoMakerOptions[] =
233{
234 /*
235 * Unquie IPRT ISO maker options.
236 */
237 { "--iprt-iso-maker-file-marker", RTFSISOMAKERCMD_OPT_IPRT_ISO_MAKER_FILE_MARKER, RTGETOPT_REQ_NOTHING },
238 { "--output-buffer-size", RTFSISOMAKERCMD_OPT_OUTPUT_BUFFER_SIZE, RTGETOPT_REQ_UINT32 },
239 { "--random-output-buffer-size", RTFSISOMAKERCMD_OPT_RANDOM_OUTPUT_BUFFER_SIZE, RTGETOPT_REQ_NOTHING },
240
241
242 /*
243 * genisoimage/mkisofs compatibility:
244 */
245 { "--abstract", RTFSISOMAKERCMD_OPT_ABSTRACT_FILE_ID, RTGETOPT_REQ_STRING },
246 { "-abstract", RTFSISOMAKERCMD_OPT_ABSTRACT_FILE_ID, RTGETOPT_REQ_STRING },
247 { "--application-id", 'A', RTGETOPT_REQ_STRING },
248 { "--allow-limited-size", RTFSISOMAKERCMD_OPT_ALLOW_LIMITED_SIZE, RTGETOPT_REQ_NOTHING },
249 { "-allow-limited-size", RTFSISOMAKERCMD_OPT_ALLOW_LIMITED_SIZE, RTGETOPT_REQ_NOTHING },
250 { "--allow-leading-dots", RTFSISOMAKERCMD_OPT_ALLOW_LEADING_DOTS, RTGETOPT_REQ_NOTHING },
251 { "-allow-leading-dots", RTFSISOMAKERCMD_OPT_ALLOW_LEADING_DOTS, RTGETOPT_REQ_NOTHING },
252 { "--ldots", RTFSISOMAKERCMD_OPT_ALLOW_LEADING_DOTS, RTGETOPT_REQ_NOTHING },
253 { "-ldots", RTFSISOMAKERCMD_OPT_ALLOW_LEADING_DOTS, RTGETOPT_REQ_NOTHING },
254 { "--allow-lowercase", RTFSISOMAKERCMD_OPT_ALLOW_LOWERCASE, RTGETOPT_REQ_NOTHING },
255 { "-allow-lowercase", RTFSISOMAKERCMD_OPT_ALLOW_LOWERCASE, RTGETOPT_REQ_NOTHING },
256 { "--allow-multidot", RTFSISOMAKERCMD_OPT_ALLOW_MULTI_DOT, RTGETOPT_REQ_NOTHING },
257 { "-allow-multidot", RTFSISOMAKERCMD_OPT_ALLOW_MULTI_DOT, RTGETOPT_REQ_NOTHING },
258 { "--biblio", RTFSISOMAKERCMD_OPT_BIBLIOGRAPHIC_FILE_ID, RTGETOPT_REQ_STRING },
259 { "-biblio", RTFSISOMAKERCMD_OPT_BIBLIOGRAPHIC_FILE_ID, RTGETOPT_REQ_STRING },
260 { "--cache-inodes", RTFSISOMAKERCMD_OPT_DETECT_HARDLINKS, RTGETOPT_REQ_NOTHING },
261 { "-cache-inodes", RTFSISOMAKERCMD_OPT_DETECT_HARDLINKS, RTGETOPT_REQ_NOTHING },
262 { "--no-cache-inodes", RTFSISOMAKERCMD_OPT_NO_DETECT_HARDLINKS, RTGETOPT_REQ_NOTHING },
263 { "-no-cache-inodes", RTFSISOMAKERCMD_OPT_NO_DETECT_HARDLINKS, RTGETOPT_REQ_NOTHING },
264 { "--alpha-boot", RTFSISOMAKERCMD_OPT_ALPHA_BOOT, RTGETOPT_REQ_STRING },
265 { "-alpha-boot", RTFSISOMAKERCMD_OPT_ALPHA_BOOT, RTGETOPT_REQ_STRING },
266 { "--hppa-bootloader", RTFSISOMAKERCMD_OPT_HPPA_BOOTLOADER, RTGETOPT_REQ_STRING },
267 { "-hppa-bootloader", RTFSISOMAKERCMD_OPT_HPPA_BOOTLOADER, RTGETOPT_REQ_STRING },
268 { "--hppa-cmdline", RTFSISOMAKERCMD_OPT_HPPA_CMDLINE, RTGETOPT_REQ_STRING },
269 { "-hppa-cmdline", RTFSISOMAKERCMD_OPT_HPPA_CMDLINE, RTGETOPT_REQ_STRING },
270 { "--hppa-kernel-32", RTFSISOMAKERCMD_OPT_HPPA_KERNEL_32, RTGETOPT_REQ_STRING },
271 { "-hppa-kernel-32", RTFSISOMAKERCMD_OPT_HPPA_KERNEL_32, RTGETOPT_REQ_STRING },
272 { "--hppa-kernel-64", RTFSISOMAKERCMD_OPT_HPPA_KERNEL_64, RTGETOPT_REQ_STRING },
273 { "-hppa-kernel-64", RTFSISOMAKERCMD_OPT_HPPA_KERNEL_64, RTGETOPT_REQ_STRING },
274 { "--hppa-ramdisk", RTFSISOMAKERCMD_OPT_HPPA_RAMDISK, RTGETOPT_REQ_STRING },
275 { "-hppa-ramdisk", RTFSISOMAKERCMD_OPT_HPPA_RAMDISK, RTGETOPT_REQ_STRING },
276 { "--mips-boot", RTFSISOMAKERCMD_OPT_MIPS_BOOT, RTGETOPT_REQ_STRING },
277 { "-mips-boot", RTFSISOMAKERCMD_OPT_MIPS_BOOT, RTGETOPT_REQ_STRING },
278 { "--mipsel-boot", RTFSISOMAKERCMD_OPT_MIPSEL_BOOT, RTGETOPT_REQ_STRING },
279 { "-mipsel-boot", RTFSISOMAKERCMD_OPT_MIPSEL_BOOT, RTGETOPT_REQ_STRING },
280 { "--sparc-boot", 'B', RTGETOPT_REQ_STRING },
281 { "-sparc-boot", 'B', RTGETOPT_REQ_STRING },
282 { "--generic-boot", 'G', RTGETOPT_REQ_STRING },
283 { "--eltorito-boot", 'b', RTGETOPT_REQ_STRING },
284 { "--eltorito-alt-boot", RTFSISOMAKERCMD_OPT_ELTORITO_ALT_BOOT, RTGETOPT_REQ_NOTHING },
285 { "--hard-disk-boot", RTFSISOMAKERCMD_OPT_ELTORITO_HARD_DISK_BOOT, RTGETOPT_REQ_NOTHING },
286 { "-hard-disk-boot", RTFSISOMAKERCMD_OPT_ELTORITO_HARD_DISK_BOOT, RTGETOPT_REQ_NOTHING },
287 { "--no-emulation-boot", RTFSISOMAKERCMD_OPT_ELTORITO_NO_EMULATION_BOOT, RTGETOPT_REQ_NOTHING },
288 { "-no-emulation-boot", RTFSISOMAKERCMD_OPT_ELTORITO_NO_EMULATION_BOOT, RTGETOPT_REQ_NOTHING },
289 { "--no-boot", RTFSISOMAKERCMD_OPT_ELTORITO_NO_BOOT, RTGETOPT_REQ_NOTHING },
290 { "-no-boot", RTFSISOMAKERCMD_OPT_ELTORITO_NO_BOOT, RTGETOPT_REQ_NOTHING },
291 { "--boot-load-seg", RTFSISOMAKERCMD_OPT_ELTORITO_LOAD_SEG, RTGETOPT_REQ_UINT32 },
292 { "-boot-load-seg", RTFSISOMAKERCMD_OPT_ELTORITO_LOAD_SEG, RTGETOPT_REQ_UINT32 },
293 { "--boot-load-size", RTFSISOMAKERCMD_OPT_ELTORITO_LOAD_SIZE, RTGETOPT_REQ_UINT32 },
294 { "-boot-load-size", RTFSISOMAKERCMD_OPT_ELTORITO_LOAD_SIZE, RTGETOPT_REQ_UINT32 },
295 { "--boot-info-table", RTFSISOMAKERCMD_OPT_ELTORITO_INFO_TABLE, RTGETOPT_REQ_STRING },
296 { "-boot-info-table", RTFSISOMAKERCMD_OPT_ELTORITO_INFO_TABLE, RTGETOPT_REQ_STRING },
297 { "--cd-extra", 'C', RTGETOPT_REQ_STRING },
298 { "--boot-catalog", 'c', RTGETOPT_REQ_STRING },
299 { "--check-oldnames", RTFSISOMAKERCMD_OPT_CHECK_OLD_NAMES, RTGETOPT_REQ_NOTHING },
300 { "-check-oldnames", RTFSISOMAKERCMD_OPT_CHECK_OLD_NAMES, RTGETOPT_REQ_NOTHING },
301 { "--check-session", RTFSISOMAKERCMD_OPT_CHECK_SESSION, RTGETOPT_REQ_STRING },
302 { "-check-session", RTFSISOMAKERCMD_OPT_CHECK_SESSION, RTGETOPT_REQ_STRING },
303 { "--copyright", RTFSISOMAKERCMD_OPT_COPYRIGHT_FILE_ID, RTGETOPT_REQ_STRING },
304 { "-copyright", RTFSISOMAKERCMD_OPT_COPYRIGHT_FILE_ID, RTGETOPT_REQ_STRING },
305 { "--dont-append-dot", 'd', RTGETOPT_REQ_NOTHING },
306 { "--deep-directories", 'D', RTGETOPT_REQ_NOTHING },
307 { "--dir-mode", RTFSISOMAKERCMD_OPT_DIR_MODE, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
308 { "-dir-mode", RTFSISOMAKERCMD_OPT_DIR_MODE, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
309 { "--dvd-video", RTFSISOMAKERCMD_OPT_DVD_VIDEO, RTGETOPT_REQ_NOTHING },
310 { "-dvd-video", RTFSISOMAKERCMD_OPT_DVD_VIDEO, RTGETOPT_REQ_NOTHING },
311 { "--follow-symlinks", 'f', RTGETOPT_REQ_NOTHING },
312 { "-follow-symlinks", 'f', RTGETOPT_REQ_NOTHING },
313 { "--file-mode", RTFSISOMAKERCMD_OPT_FILE_MODE, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
314 { "-file-mode", RTFSISOMAKERCMD_OPT_FILE_MODE, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
315 { "--gid", RTFSISOMAKERCMD_OPT_GID, RTGETOPT_REQ_UINT32 },
316 { "-gid", RTFSISOMAKERCMD_OPT_GID, RTGETOPT_REQ_UINT32 },
317 { "--gui", RTFSISOMAKERCMD_OPT_GUI, RTGETOPT_REQ_NOTHING },
318 { "-gui", RTFSISOMAKERCMD_OPT_GUI, RTGETOPT_REQ_NOTHING },
319 { "--graft-points", RTFSISOMAKERCMD_OPT_GRAFT_POINTS, RTGETOPT_REQ_NOTHING },
320 { "-graft-points", RTFSISOMAKERCMD_OPT_GRAFT_POINTS, RTGETOPT_REQ_NOTHING },
321 { "--hide", RTFSISOMAKERCMD_OPT_HIDE, RTGETOPT_REQ_STRING },
322 { "-hide", RTFSISOMAKERCMD_OPT_HIDE, RTGETOPT_REQ_STRING },
323 { "--hide-list", RTFSISOMAKERCMD_OPT_HIDE_LIST, RTGETOPT_REQ_STRING },
324 { "-hide-list", RTFSISOMAKERCMD_OPT_HIDE_LIST, RTGETOPT_REQ_STRING },
325 { "--hidden", RTFSISOMAKERCMD_OPT_HIDDEN, RTGETOPT_REQ_STRING },
326 { "-hidden", RTFSISOMAKERCMD_OPT_HIDDEN, RTGETOPT_REQ_STRING },
327 { "--hidden-list", RTFSISOMAKERCMD_OPT_HIDDEN_LIST, RTGETOPT_REQ_STRING },
328 { "-hidden-list", RTFSISOMAKERCMD_OPT_HIDDEN_LIST, RTGETOPT_REQ_STRING },
329 { "--hide-joliet", RTFSISOMAKERCMD_OPT_HIDE_JOLIET, RTGETOPT_REQ_STRING },
330 { "-hide-joliet", RTFSISOMAKERCMD_OPT_HIDE_JOLIET, RTGETOPT_REQ_STRING },
331 { "--hide-joliet-list", RTFSISOMAKERCMD_OPT_HIDE_JOLIET_LIST, RTGETOPT_REQ_STRING },
332 { "-hide-joliet-list", RTFSISOMAKERCMD_OPT_HIDE_JOLIET_LIST, RTGETOPT_REQ_STRING },
333 { "--hide-joliet-trans-tbl", RTFSISOMAKERCMD_OPT_HIDE_JOLIET_TRANS_TBL, RTGETOPT_REQ_NOTHING },
334 { "-hide-joliet-trans-tbl", RTFSISOMAKERCMD_OPT_HIDE_JOLIET_TRANS_TBL, RTGETOPT_REQ_NOTHING },
335 { "--hide-rr-moved", RTFSISOMAKERCMD_OPT_HIDE_RR_MOVED, RTGETOPT_REQ_NOTHING },
336 { "-hide-rr-moved", RTFSISOMAKERCMD_OPT_HIDE_RR_MOVED, RTGETOPT_REQ_NOTHING },
337 { "--input-charset", RTFSISOMAKERCMD_OPT_INPUT_CHARSET, RTGETOPT_REQ_STRING },
338 { "-input-charset", RTFSISOMAKERCMD_OPT_INPUT_CHARSET, RTGETOPT_REQ_STRING },
339 { "--output-charset", RTFSISOMAKERCMD_OPT_OUTPUT_CHARSET, RTGETOPT_REQ_STRING },
340 { "-output-charset", RTFSISOMAKERCMD_OPT_OUTPUT_CHARSET, RTGETOPT_REQ_STRING },
341 { "--iso-level", RTFSISOMAKERCMD_OPT_ISO_LEVEL, RTGETOPT_REQ_UINT8 },
342 { "--joliet", 'J', RTGETOPT_REQ_NOTHING },
343 { "--joliet-long", RTFSISOMAKERCMD_OPT_JOLIET_LONG, RTGETOPT_REQ_NOTHING },
344 { "-joliet-long", RTFSISOMAKERCMD_OPT_JOLIET_LONG, RTGETOPT_REQ_NOTHING },
345 { "--jcharset", RTFSISOMAKERCMD_OPT_JOLIET_CHARSET, RTGETOPT_REQ_STRING },
346 { "-jcharset", RTFSISOMAKERCMD_OPT_JOLIET_CHARSET, RTGETOPT_REQ_STRING },
347 { "--long-names", 'l', RTGETOPT_REQ_NOTHING },
348 { "--leading-dot", 'L', RTGETOPT_REQ_NOTHING },
349 { "--jigdo-jigdo", RTFSISOMAKERCMD_OPT_JIGDO_JIGDO, RTGETOPT_REQ_STRING },
350 { "-jigdo-jigdo", RTFSISOMAKERCMD_OPT_JIGDO_JIGDO, RTGETOPT_REQ_STRING },
351 { "--jigdo-template", RTFSISOMAKERCMD_OPT_JIGDO_TEMPLATE, RTGETOPT_REQ_STRING },
352 { "-jigdo-template", RTFSISOMAKERCMD_OPT_JIGDO_TEMPLATE, RTGETOPT_REQ_STRING },
353 { "--jigdo-min-file-size", RTFSISOMAKERCMD_OPT_JIGDO_MIN_FILE_SIZE, RTGETOPT_REQ_UINT64 },
354 { "-jigdo-min-file-size", RTFSISOMAKERCMD_OPT_JIGDO_MIN_FILE_SIZE, RTGETOPT_REQ_UINT64 },
355 { "--jigdo-force-md5", RTFSISOMAKERCMD_OPT_JIGDO_FORCE_MD5, RTGETOPT_REQ_STRING },
356 { "-jigdo-force-md5", RTFSISOMAKERCMD_OPT_JIGDO_FORCE_MD5, RTGETOPT_REQ_STRING },
357 { "--jigdo-exclude", RTFSISOMAKERCMD_OPT_JIGDO_EXCLUDE, RTGETOPT_REQ_STRING },
358 { "-jigdo-exclude", RTFSISOMAKERCMD_OPT_JIGDO_EXCLUDE, RTGETOPT_REQ_STRING },
359 { "--jigdo-map", RTFSISOMAKERCMD_OPT_JIGDO_MAP, RTGETOPT_REQ_STRING },
360 { "-jigdo-map", RTFSISOMAKERCMD_OPT_JIGDO_MAP, RTGETOPT_REQ_STRING },
361 { "--md5-list", RTFSISOMAKERCMD_OPT_JIGDO_MD5_LIST, RTGETOPT_REQ_STRING },
362 { "-md5-list", RTFSISOMAKERCMD_OPT_JIGDO_MD5_LIST, RTGETOPT_REQ_STRING },
363 { "--jigdo-template-compress", RTFSISOMAKERCMD_OPT_JIGDO_COMPRESS, RTGETOPT_REQ_STRING },
364 { "-jigdo-template-compress", RTFSISOMAKERCMD_OPT_JIGDO_COMPRESS, RTGETOPT_REQ_STRING },
365 { "--log-file", RTFSISOMAKERCMD_OPT_LOG_FILE, RTGETOPT_REQ_STRING },
366 { "-log-file", RTFSISOMAKERCMD_OPT_LOG_FILE, RTGETOPT_REQ_STRING },
367 { "--exclude", 'm', RTGETOPT_REQ_STRING },
368 { "--exclude", 'x', RTGETOPT_REQ_STRING },
369 { "--exclude-list", RTFSISOMAKERCMD_OPT_EXCLUDE_LIST, RTGETOPT_REQ_STRING },
370 { "-exclude-list", RTFSISOMAKERCMD_OPT_EXCLUDE_LIST, RTGETOPT_REQ_STRING },
371 { "--max-iso9660-filenames", RTFSISOMAKERCMD_OPT_MAX_ISO9660_FILENAMES, RTGETOPT_REQ_NOTHING },
372 { "-max-iso9660-filenames", RTFSISOMAKERCMD_OPT_MAX_ISO9660_FILENAMES, RTGETOPT_REQ_NOTHING },
373 { "--merge", 'M', RTGETOPT_REQ_STRING },
374 { "--dev", 'M', RTGETOPT_REQ_STRING },
375 { "-dev", 'M', RTGETOPT_REQ_STRING },
376 { "--omit-version-numbers", 'N', RTGETOPT_REQ_NOTHING },
377 { "--new-dir-mode", RTFSISOMAKERCMD_OPT_NEW_DIR_MODE, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
378 { "-new-dir-mode", RTFSISOMAKERCMD_OPT_NEW_DIR_MODE, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
379 { "--nobak", RTFSISOMAKERCMD_OPT_NO_BACKUP_FILES, RTGETOPT_REQ_NOTHING },
380 { "-nobak", RTFSISOMAKERCMD_OPT_NO_BACKUP_FILES, RTGETOPT_REQ_NOTHING },
381 { "--no-bak", RTFSISOMAKERCMD_OPT_NO_BACKUP_FILES, RTGETOPT_REQ_NOTHING },
382 { "-no-bak", RTFSISOMAKERCMD_OPT_NO_BACKUP_FILES, RTGETOPT_REQ_NOTHING },
383 { "--force-rr", RTFSISOMAKERCMD_OPT_FORCE_RR, RTGETOPT_REQ_NOTHING },
384 { "-force-rr", RTFSISOMAKERCMD_OPT_FORCE_RR, RTGETOPT_REQ_NOTHING },
385 { "--no-rr", RTFSISOMAKERCMD_OPT_NO_RR, RTGETOPT_REQ_NOTHING },
386 { "-no-rr", RTFSISOMAKERCMD_OPT_NO_RR, RTGETOPT_REQ_NOTHING },
387 { "--no-split-symlink-components", RTFSISOMAKERCMD_OPT_NO_SPLIT_SYMLINK_COMPONENTS, RTGETOPT_REQ_NOTHING },
388 { "-no-split-symlink-components", RTFSISOMAKERCMD_OPT_NO_SPLIT_SYMLINK_COMPONENTS, RTGETOPT_REQ_NOTHING },
389 { "--no-split-symlink-fields", RTFSISOMAKERCMD_OPT_NO_SPLIT_SYMLINK_FIELDS, RTGETOPT_REQ_NOTHING },
390 { "-no-split-symlink-fields", RTFSISOMAKERCMD_OPT_NO_SPLIT_SYMLINK_FIELDS, RTGETOPT_REQ_NOTHING },
391 { "--output", 'o', RTGETOPT_REQ_STRING },
392 { "--pad", RTFSISOMAKERCMD_OPT_PAD, RTGETOPT_REQ_NOTHING },
393 { "-pad", RTFSISOMAKERCMD_OPT_PAD, RTGETOPT_REQ_NOTHING },
394 { "--no-pad", RTFSISOMAKERCMD_OPT_NO_PAD, RTGETOPT_REQ_NOTHING },
395 { "-no-pad", RTFSISOMAKERCMD_OPT_NO_PAD, RTGETOPT_REQ_NOTHING },
396 { "--path-list", RTFSISOMAKERCMD_OPT_PATH_LIST, RTGETOPT_REQ_STRING },
397 { "-path-list", RTFSISOMAKERCMD_OPT_PATH_LIST, RTGETOPT_REQ_STRING },
398 { "--publisher", 'P', RTGETOPT_REQ_STRING },
399 { "-publisher", 'P', RTGETOPT_REQ_STRING },
400 { "--preparer", 'p', RTGETOPT_REQ_STRING },
401 { "--print-size", RTFSISOMAKERCMD_OPT_PRINT_SIZE, RTGETOPT_REQ_NOTHING },
402 { "-print-size", RTFSISOMAKERCMD_OPT_PRINT_SIZE, RTGETOPT_REQ_NOTHING },
403 { "--quiet", RTFSISOMAKERCMD_OPT_QUIET, RTGETOPT_REQ_NOTHING },
404 { "-quiet", RTFSISOMAKERCMD_OPT_QUIET, RTGETOPT_REQ_NOTHING },
405 { "--rock-ridge", 'R', RTGETOPT_REQ_NOTHING },
406 { "--rock-ridge-relaxed", 'r', RTGETOPT_REQ_NOTHING },
407 { "--relaxed-filenames", RTFSISOMAKERCMD_OPT_RELAXED_FILENAMES, RTGETOPT_REQ_NOTHING },
408 { "-relaxed-filenames", RTFSISOMAKERCMD_OPT_RELAXED_FILENAMES, RTGETOPT_REQ_NOTHING },
409 { "--root", RTFSISOMAKERCMD_OPT_ROOT, RTGETOPT_REQ_STRING },
410 { "-root", RTFSISOMAKERCMD_OPT_ROOT, RTGETOPT_REQ_STRING },
411 { "--old-root", RTFSISOMAKERCMD_OPT_OLD_ROOT, RTGETOPT_REQ_STRING },
412 { "-old-root", RTFSISOMAKERCMD_OPT_OLD_ROOT, RTGETOPT_REQ_STRING },
413 { "--sort", RTFSISOMAKERCMD_OPT_SORT, RTGETOPT_REQ_STRING },
414 { "-sort", RTFSISOMAKERCMD_OPT_SORT, RTGETOPT_REQ_STRING },
415 { "--sparc-boot", RTFSISOMAKERCMD_OPT_SPARC_BOOT, RTGETOPT_REQ_STRING },
416 { "-sparc-boot", RTFSISOMAKERCMD_OPT_SPARC_BOOT, RTGETOPT_REQ_STRING },
417 { "--sparc-label", RTFSISOMAKERCMD_OPT_SPARC_LABEL, RTGETOPT_REQ_STRING },
418 { "-sparc-label", RTFSISOMAKERCMD_OPT_SPARC_LABEL, RTGETOPT_REQ_STRING },
419 { "--split-output", RTFSISOMAKERCMD_OPT_SPLIT_OUTPUT, RTGETOPT_REQ_NOTHING },
420 { "-split-output", RTFSISOMAKERCMD_OPT_SPLIT_OUTPUT, RTGETOPT_REQ_NOTHING },
421 { "--stream-media-size", RTFSISOMAKERCMD_OPT_STREAM_MEDIA_SIZE, RTGETOPT_REQ_UINT64 },
422 { "-stream-media-size", RTFSISOMAKERCMD_OPT_STREAM_MEDIA_SIZE, RTGETOPT_REQ_UINT64 },
423 { "--stream-file-name", RTFSISOMAKERCMD_OPT_STREAM_FILE_NAME, RTGETOPT_REQ_STRING },
424 { "-stream-file-name", RTFSISOMAKERCMD_OPT_STREAM_FILE_NAME, RTGETOPT_REQ_STRING },
425 { "--sunx86-boot", RTFSISOMAKERCMD_OPT_SUNX86_BOOT, RTGETOPT_REQ_STRING },
426 { "-sunx86-boot", RTFSISOMAKERCMD_OPT_SUNX86_BOOT, RTGETOPT_REQ_STRING },
427 { "--sunx86-label", RTFSISOMAKERCMD_OPT_SUNX86_LABEL, RTGETOPT_REQ_STRING },
428 { "-sunx86-label", RTFSISOMAKERCMD_OPT_SUNX86_LABEL, RTGETOPT_REQ_STRING },
429 { "--sysid", RTFSISOMAKERCMD_OPT_SYSTEM_ID, RTGETOPT_REQ_STRING },
430 { "-sysid", RTFSISOMAKERCMD_OPT_SYSTEM_ID, RTGETOPT_REQ_STRING },
431 { "--trans-tbl", 'T', RTGETOPT_REQ_NOTHING },
432 { "--table-name", RTFSISOMAKERCMD_OPT_TRANS_TBL_NAME, RTGETOPT_REQ_STRING },
433 { "-table-name", RTFSISOMAKERCMD_OPT_TRANS_TBL_NAME, RTGETOPT_REQ_STRING },
434 { "--ucs-level", RTFSISOMAKERCMD_OPT_JOLIET_LEVEL, RTGETOPT_REQ_UINT8 },
435 { "-ucs-level", RTFSISOMAKERCMD_OPT_JOLIET_LEVEL, RTGETOPT_REQ_UINT8 },
436 { "--udf", RTFSISOMAKERCMD_OPT_UDF, RTGETOPT_REQ_NOTHING },
437 { "-udf", RTFSISOMAKERCMD_OPT_UDF, RTGETOPT_REQ_NOTHING },
438 { "--uid", RTFSISOMAKERCMD_OPT_UID, RTGETOPT_REQ_UINT32 },
439 { "-uid", RTFSISOMAKERCMD_OPT_UID, RTGETOPT_REQ_UINT32 },
440 { "--use-fileversion", RTFSISOMAKERCMD_OPT_USE_FILE_VERSION, RTGETOPT_REQ_NOTHING },
441 { "-use-fileversion", RTFSISOMAKERCMD_OPT_USE_FILE_VERSION, RTGETOPT_REQ_NOTHING },
442 { "--untranslated-filenames", 'U', RTGETOPT_REQ_NOTHING },
443 { "--no-iso-translate", RTFSISOMAKERCMD_OPT_NO_ISO_TRANSLATE, RTGETOPT_REQ_NOTHING },
444 { "-no-iso-translate", RTFSISOMAKERCMD_OPT_NO_ISO_TRANSLATE, RTGETOPT_REQ_NOTHING },
445 { "--volume-id", 'V', RTGETOPT_REQ_STRING },
446 { "--volset", RTFSISOMAKERCMD_OPT_VOLUME_SET_ID, RTGETOPT_REQ_STRING },
447 { "-volset", RTFSISOMAKERCMD_OPT_VOLUME_SET_ID, RTGETOPT_REQ_STRING },
448 { "--volset-size", RTFSISOMAKERCMD_OPT_VOLUME_SET_SIZE, RTGETOPT_REQ_UINT32 },
449 { "-volset-size", RTFSISOMAKERCMD_OPT_VOLUME_SET_SIZE, RTGETOPT_REQ_UINT32 },
450 { "--volset-seqno", RTFSISOMAKERCMD_OPT_VOLUME_SET_SEQ_NO, RTGETOPT_REQ_UINT32 },
451 { "-volset-seqno", RTFSISOMAKERCMD_OPT_VOLUME_SET_SEQ_NO, RTGETOPT_REQ_UINT32 },
452 { "--transpared-compression", 'z', RTGETOPT_REQ_NOTHING },
453
454 /* HFS and ISO-9660 apple extensions. */
455 { "--hfs", RTFSISOMAKERCMD_OPT_HFS_ENABLE, RTGETOPT_REQ_NOTHING },
456 { "-hfs", RTFSISOMAKERCMD_OPT_HFS_ENABLE, RTGETOPT_REQ_NOTHING },
457 { "--apple", RTFSISOMAKERCMD_OPT_APPLE, RTGETOPT_REQ_NOTHING },
458 { "-apple", RTFSISOMAKERCMD_OPT_APPLE, RTGETOPT_REQ_NOTHING },
459 { "--map", RTFSISOMAKERCMD_OPT_HFS_MAP, RTGETOPT_REQ_STRING },
460 { "-map", RTFSISOMAKERCMD_OPT_HFS_MAP, RTGETOPT_REQ_STRING },
461 { "--magic", RTFSISOMAKERCMD_OPT_HFS_MAGIC, RTGETOPT_REQ_STRING },
462 { "-magic", RTFSISOMAKERCMD_OPT_HFS_MAGIC, RTGETOPT_REQ_STRING },
463 { "--hfs-creator", RTFSISOMAKERCMD_OPT_HFS_CREATOR, RTGETOPT_REQ_STRING },
464 { "-hfs-creator", RTFSISOMAKERCMD_OPT_HFS_CREATOR, RTGETOPT_REQ_STRING },
465 { "--hfs-type", RTFSISOMAKERCMD_OPT_HFS_TYPE, RTGETOPT_REQ_STRING },
466 { "-hfs-type", RTFSISOMAKERCMD_OPT_HFS_TYPE, RTGETOPT_REQ_STRING },
467 { "--probe", RTFSISOMAKERCMD_OPT_HFS_PROBE, RTGETOPT_REQ_NOTHING },
468 { "-probe", RTFSISOMAKERCMD_OPT_HFS_PROBE, RTGETOPT_REQ_NOTHING },
469 { "--no-desktop", RTFSISOMAKERCMD_OPT_HFS_NO_DESKTOP, RTGETOPT_REQ_NOTHING },
470 { "-no-desktop", RTFSISOMAKERCMD_OPT_HFS_NO_DESKTOP, RTGETOPT_REQ_NOTHING },
471 { "--mac-name", RTFSISOMAKERCMD_OPT_HFS_MAC_NAME, RTGETOPT_REQ_NOTHING },
472 { "-mac-name", RTFSISOMAKERCMD_OPT_HFS_MAC_NAME, RTGETOPT_REQ_NOTHING },
473 { "--boot-hfs-file", RTFSISOMAKERCMD_OPT_HFS_BOOT_FILE, RTGETOPT_REQ_STRING },
474 { "-boot-hfs-file", RTFSISOMAKERCMD_OPT_HFS_BOOT_FILE, RTGETOPT_REQ_STRING },
475 { "--part", RTFSISOMAKERCMD_OPT_HFS_PART, RTGETOPT_REQ_NOTHING },
476 { "-part", RTFSISOMAKERCMD_OPT_HFS_PART, RTGETOPT_REQ_NOTHING },
477 { "--auto", RTFSISOMAKERCMD_OPT_HFS_AUTO, RTGETOPT_REQ_STRING },
478 { "-auto", RTFSISOMAKERCMD_OPT_HFS_AUTO, RTGETOPT_REQ_STRING },
479 { "--cluster-size", RTFSISOMAKERCMD_OPT_HFS_CLUSTER_SIZE, RTGETOPT_REQ_UINT32 },
480 { "-cluster-size", RTFSISOMAKERCMD_OPT_HFS_CLUSTER_SIZE, RTGETOPT_REQ_UINT32 },
481 { "--hide-hfs", RTFSISOMAKERCMD_OPT_HFS_HIDE, RTGETOPT_REQ_STRING },
482 { "-hide-hfs", RTFSISOMAKERCMD_OPT_HFS_HIDE, RTGETOPT_REQ_STRING },
483 { "--hide-hfs-list", RTFSISOMAKERCMD_OPT_HFS_HIDE_LIST, RTGETOPT_REQ_STRING },
484 { "-hide-hfs-list", RTFSISOMAKERCMD_OPT_HFS_HIDE_LIST, RTGETOPT_REQ_STRING },
485 { "--hfs-volid", RTFSISOMAKERCMD_OPT_HFS_VOL_ID, RTGETOPT_REQ_STRING },
486 { "-hfs-volid", RTFSISOMAKERCMD_OPT_HFS_VOL_ID, RTGETOPT_REQ_STRING },
487 { "--icon-position", RTFSISOMAKERCMD_OPT_HFS_ICON_POSITION, RTGETOPT_REQ_NOTHING },
488 { "-icon-position", RTFSISOMAKERCMD_OPT_HFS_ICON_POSITION, RTGETOPT_REQ_NOTHING },
489 { "--root-info", RTFSISOMAKERCMD_OPT_HFS_ROOT_INFO, RTGETOPT_REQ_STRING },
490 { "-root-info", RTFSISOMAKERCMD_OPT_HFS_ROOT_INFO, RTGETOPT_REQ_STRING },
491 { "--prep-boot", RTFSISOMAKERCMD_OPT_HFS_PREP_BOOT, RTGETOPT_REQ_STRING },
492 { "-prep-boot", RTFSISOMAKERCMD_OPT_HFS_PREP_BOOT, RTGETOPT_REQ_STRING },
493 { "--chrp-boot", RTFSISOMAKERCMD_OPT_HFS_CHRP_BOOT, RTGETOPT_REQ_NOTHING },
494 { "-chrp-boot", RTFSISOMAKERCMD_OPT_HFS_CHRP_BOOT, RTGETOPT_REQ_NOTHING },
495 { "--input-hfs-charset", RTFSISOMAKERCMD_OPT_HFS_INPUT_CHARSET, RTGETOPT_REQ_STRING },
496 { "-input-hfs-charset", RTFSISOMAKERCMD_OPT_HFS_INPUT_CHARSET, RTGETOPT_REQ_STRING },
497 { "--output-hfs-charset", RTFSISOMAKERCMD_OPT_HFS_OUTPUT_CHARSET, RTGETOPT_REQ_STRING },
498 { "-output-hfs-charset", RTFSISOMAKERCMD_OPT_HFS_OUTPUT_CHARSET, RTGETOPT_REQ_STRING },
499 { "--hfs-unlock", RTFSISOMAKERCMD_OPT_HFS_UNLOCK, RTGETOPT_REQ_NOTHING },
500 { "-hfs-unlock", RTFSISOMAKERCMD_OPT_HFS_UNLOCK, RTGETOPT_REQ_NOTHING },
501 { "--hfs-bless", RTFSISOMAKERCMD_OPT_HFS_BLESS, RTGETOPT_REQ_STRING },
502 { "-hfs-bless", RTFSISOMAKERCMD_OPT_HFS_BLESS, RTGETOPT_REQ_STRING },
503 { "--hfs-parms", RTFSISOMAKERCMD_OPT_HFS_PARMS, RTGETOPT_REQ_STRING },
504 { "-hfs-parms", RTFSISOMAKERCMD_OPT_HFS_PARMS, RTGETOPT_REQ_STRING },
505 { "--cap", RTFSISOMAKERCMD_OPT_HFS_CAP, RTGETOPT_REQ_NOTHING },
506 { "--netatalk", RTFSISOMAKERCMD_OPT_HFS_NETATALK, RTGETOPT_REQ_NOTHING },
507 { "--double", RTFSISOMAKERCMD_OPT_HFS_DOUBLE, RTGETOPT_REQ_NOTHING },
508 { "--ethershare", RTFSISOMAKERCMD_OPT_HFS_ETHERSHARE, RTGETOPT_REQ_NOTHING },
509 { "--ushare", RTFSISOMAKERCMD_OPT_HFS_USHARE, RTGETOPT_REQ_NOTHING },
510 { "--exchange", RTFSISOMAKERCMD_OPT_HFS_EXCHANGE, RTGETOPT_REQ_NOTHING },
511 { "--sgi", RTFSISOMAKERCMD_OPT_HFS_SGI, RTGETOPT_REQ_NOTHING },
512 { "--xinet", RTFSISOMAKERCMD_OPT_HFS_XINET, RTGETOPT_REQ_NOTHING },
513 { "--macbin", RTFSISOMAKERCMD_OPT_HFS_MACBIN, RTGETOPT_REQ_NOTHING },
514 { "--single", RTFSISOMAKERCMD_OPT_HFS_SINGLE, RTGETOPT_REQ_NOTHING },
515 { "--dave", RTFSISOMAKERCMD_OPT_HFS_DAVE, RTGETOPT_REQ_NOTHING },
516 { "--sfm", RTFSISOMAKERCMD_OPT_HFS_SFM, RTGETOPT_REQ_NOTHING },
517 { "--osx-double", RTFSISOMAKERCMD_OPT_HFS_OSX_DOUBLE, RTGETOPT_REQ_NOTHING },
518 { "--osx-hfs", RTFSISOMAKERCMD_OPT_HFS_OSX_HFS, RTGETOPT_REQ_NOTHING },
519};
520
521
522/**
523 * Wrapper around RTErrInfoSetV / RTMsgErrorV.
524 *
525 * @returns @a rc
526 * @param pOpts The CMD instance.
527 * @param rc The return code.
528 * @param pszFormat The message format.
529 * @param ... The message format arguments.
530 */
531static int rtFsIsoMakerErrorRc(PRTFSISOMAKERCMDOPTS pOpts, int rc, const char *pszFormat, ...)
532{
533 va_list va;
534 va_start(va, pszFormat);
535 if (pOpts->pErrInfo)
536 RTErrInfoSetV(pOpts->pErrInfo, rc, pszFormat, va);
537 else
538 RTMsgErrorV(pszFormat, va);
539 va_end(va);
540 return rc;
541}
542
543
544/**
545 * Wrapper around RTErrInfoSetV / RTMsgErrorV for displaying syntax errors.
546 *
547 * @returns VERR_INVALID_PARAMETER
548 * @param pOpts The CMD instance.
549 * @param pszFormat The message format.
550 * @param ... The message format arguments.
551 */
552static int rtFsIsoMakerSyntaxError(PRTFSISOMAKERCMDOPTS pOpts, const char *pszFormat, ...)
553{
554 va_list va;
555 va_start(va, pszFormat);
556 if (pOpts->pErrInfo)
557 RTErrInfoSetV(pOpts->pErrInfo, VERR_INVALID_PARAMETER, pszFormat, va);
558 else
559 RTMsgErrorV(pszFormat, va);
560 va_end(va);
561 return VERR_INVALID_PARAMETER;
562}
563
564
565/**
566 * Wrapper around RTPrintfV / RTLogRelPrintfV.
567 *
568 * @param pOpts The CMD instance.
569 * @param pszFormat The message format.
570 * @param ... The message format arguments.
571 */
572static void rtFsIsoMakerPrintf(PRTFSISOMAKERCMDOPTS pOpts, const char *pszFormat, ...)
573{
574 va_list va;
575 va_start(va, pszFormat);
576 if (pOpts->pErrInfo)
577 RTLogRelPrintfV(pszFormat, va);
578 else
579 RTPrintfV(pszFormat, va);
580 va_end(va);
581}
582
583/**
584 * Deletes the state and returns @a rc.
585 *
586 * @returns @a rc.
587 * @param pOpts The CMD instance to delete.
588 * @param rc The status code to return.
589 */
590static int rtFsIsoMakerCmdDeleteState(PRTFSISOMAKERCMDOPTS pOpts, int rc)
591{
592 if (pOpts->hIsoMaker != NIL_RTFSISOMAKER)
593 {
594 RTFsIsoMakerRelease(pOpts->hIsoMaker);
595 pOpts->hIsoMaker = NIL_RTFSISOMAKER;
596 }
597
598 return rc;
599}
600
601
602static void rtFsIsoMakerCmdUsage(PRTFSISOMAKERCMDOPTS pOpts, const char *pszProgName)
603{
604 rtFsIsoMakerPrintf(pOpts, "usage: %s [options] <file>=<cdfile>\n", pszProgName);
605}
606
607
608/**
609 * Writes the image to file.
610 *
611 * @returns IPRT status code.
612 * @param pOpts The CMD instance.
613 * @param hVfsSrcFile The source file from the ISO maker.
614 */
615static int rtFsIsoMakerCmdWriteImage(PRTFSISOMAKERCMDOPTS pOpts, RTVFSFILE hVfsSrcFile)
616{
617 /*
618 * Get the image size and setup the copy buffer.
619 */
620 uint64_t cbImage;
621 int rc = RTVfsFileGetSize(hVfsSrcFile, &cbImage);
622 if (RT_SUCCESS(rc))
623 {
624 rtFsIsoMakerPrintf(pOpts, "Image size: %'RU64 (%#RX64) bytes\n", cbImage, cbImage);
625
626 uint32_t cbBuf = pOpts->cbOutputReadBuffer == 0 ? _1M : pOpts->cbOutputReadBuffer;
627 void *pvBuf = RTMemTmpAlloc(cbBuf);
628 if (pvBuf)
629 {
630 /*
631 * Open the output file.
632 */
633 RTVFSFILE hVfsDstFile;
634 uint32_t offError;
635 RTERRINFOSTATIC ErrInfo;
636 rc = RTVfsChainOpenFile(pOpts->pszOutFile, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE,
637 &hVfsDstFile, &offError, RTErrInfoInitStatic(&ErrInfo));
638 if (RT_SUCCESS(rc))
639 {
640 /*
641 * Copy the virtual image bits to the destination file.
642 */
643 uint64_t offImage = 0;
644 while (offImage < cbImage)
645 {
646 /* Figure out how much to copy this time. */
647 size_t cbToCopy = cbBuf;
648 if (pOpts->fRandomOutputReadBufferSize)
649 cbToCopy = RTRandU32Ex(1, (uint32_t)cbBuf - 1);
650 if (offImage + cbToCopy < cbImage)
651 { /* likely */ }
652 else
653 cbToCopy = (size_t)(cbImage - offImage);
654
655 /* Do the copying. */
656 rc = RTVfsFileReadAt(hVfsSrcFile, offImage, pvBuf, cbToCopy, NULL);
657 if (RT_SUCCESS(rc))
658 {
659 rc = RTVfsFileWriteAt(hVfsDstFile, offImage, pvBuf, cbToCopy, NULL);
660 if (RT_SUCCESS(rc))
661 offImage += cbToCopy;
662 else
663 {
664 rc = rtFsIsoMakerErrorRc(pOpts, rc, "Error %Rrc writing %#zx bytes at offset %#RX64 to '%s'",
665 rc, cbToCopy, offImage, pOpts->pszOutFile);
666 break;
667 }
668 }
669 else
670 {
671 rc = rtFsIsoMakerErrorRc(pOpts, rc, "Error %Rrc read %#zx bytes at offset %#RX64", rc, cbToCopy, offImage);
672 break;
673 }
674 }
675
676 /*
677 * Flush the output file before releasing it.
678 */
679 if (RT_SUCCESS(rc))
680 {
681 rc = RTVfsFileFlush(hVfsDstFile);
682 if (RT_FAILURE(rc))
683 rc = rtFsIsoMakerErrorRc(pOpts, rc, "RTVfsFileFlush failed on '%s': %Rrc", pOpts->pszOutFile, rc);
684 }
685
686 RTVfsFileRelease(hVfsDstFile);
687 }
688 else if (RTErrInfoIsSet(&ErrInfo.Core))
689 rc = rtFsIsoMakerErrorRc(pOpts, rc, "RTVfsChainOpenFile(%s) failed: %Rrc - %s",
690 pOpts->cbOutputReadBuffer, rc, ErrInfo.Core.pszMsg);
691 else
692 rc = rtFsIsoMakerErrorRc(pOpts, rc, "RTVfsChainOpenFile(%s) failed: %Rrc", pOpts->cbOutputReadBuffer, rc);
693
694 RTMemTmpFree(pvBuf);
695 }
696 else
697 rc = rtFsIsoMakerErrorRc(pOpts, rc, "RTMemTmpAlloc(%zu) failed: %Rrc", pOpts->cbOutputReadBuffer, rc);
698 }
699 else
700 rc = rtFsIsoMakerErrorRc(pOpts, rc, "RTVfsFileGetSize failed: %Rrc", rc);
701 return rc;
702}
703
704
705
706RTDECL(int) RTFsIsoMakerCmdEx(unsigned cArgs, char **papszArgs, PRTVFSFILE phVfsFile, PRTERRINFO pErrInfo)
707{
708 /*
709 * Create instance.
710 */
711 RTFSISOMAKERCMDOPTS Opts;
712 RT_ZERO(Opts);
713 Opts.hIsoMaker = NIL_RTFSISOMAKER;
714 Opts.pErrInfo = pErrInfo;
715 Opts.fVirtualImageMaker = phVfsFile != NULL;
716 if (phVfsFile)
717 *phVfsFile = NIL_RTVFSFILE;
718
719 /* Setup option parsing. */
720 RTGETOPTSTATE GetState;
721 int rc = RTGetOptInit(&GetState, cArgs, papszArgs, g_aRtFsIsoMakerOptions, RT_ELEMENTS(g_aRtFsIsoMakerOptions),
722 1 /*iFirst*/, 0 /*fFlags*/);
723 if (RT_FAILURE(rc))
724 return rtFsIsoMakerErrorRc(&Opts, rc, "RTGetOpt failed: %Rrc", rc);
725
726 /* Create the ISO creator instance. */
727 rc = RTFsIsoMakerCreate(&Opts.hIsoMaker);
728 if (RT_FAILURE(rc))
729 return rtFsIsoMakerErrorRc(&Opts, rc, "RTFsIsoMakerCreate failed: %Rrc", rc);
730
731 /*
732 * Parse parameters. Parameters are position dependent.
733 */
734 RTGETOPTUNION ValueUnion;
735 while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0)
736 {
737 switch (rc)
738 {
739 /*
740 * Files and directories.
741 */
742 case VINF_GETOPT_NOT_OPTION:
743 break;
744
745 /*
746 * Options specific to our ISO maker.
747 */
748
749
750 /*
751 * Options compatible with other ISO makers.
752 */
753 case 'o':
754 if (Opts.fVirtualImageMaker)
755 return rtFsIsoMakerSyntaxError(&Opts, "The --output option is not allowed");
756 if (Opts.pszOutFile)
757 return rtFsIsoMakerSyntaxError(&Opts, "The --output option is specified more than once");
758 Opts.pszOutFile = ValueUnion.psz;
759 break;
760
761 /*
762 * Standard bits.
763 */
764 case 'h':
765 rtFsIsoMakerCmdUsage(&Opts, papszArgs[0]);
766 return rtFsIsoMakerCmdDeleteState(&Opts, Opts.fVirtualImageMaker ? VERR_NOT_FOUND : VINF_SUCCESS);
767
768 case 'V':
769 rtFsIsoMakerPrintf(&Opts, "%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision());
770 return rtFsIsoMakerCmdDeleteState(&Opts, Opts.fVirtualImageMaker ? VERR_NOT_FOUND : VINF_SUCCESS);
771
772 default:
773 if (rc > 0 && RT_C_IS_GRAPH(rc))
774 rc = rtFsIsoMakerErrorRc(&Opts, VERR_GETOPT_UNKNOWN_OPTION, "Unhandled option: -%c", rc);
775 else if (rc > 0)
776 rc = rtFsIsoMakerErrorRc(&Opts, VERR_GETOPT_UNKNOWN_OPTION, "Unhandled option: %i (%#x)", rc, rc);
777 else if (rc == VERR_GETOPT_UNKNOWN_OPTION)
778 rc = rtFsIsoMakerErrorRc(&Opts, rc, "Unknown option: '%s'", ValueUnion.psz);
779 else if (ValueUnion.pDef)
780 rc = rtFsIsoMakerErrorRc(&Opts, rc, "%s: %Rrs\n", ValueUnion.pDef->pszLong, rc);
781 else
782 rc = rtFsIsoMakerErrorRc(&Opts, rc, "%Rrs\n", rc);
783 return rtFsIsoMakerCmdDeleteState(&Opts, rc);
784 }
785 }
786
787 /*
788 * Check for mandatory options.
789 */
790 if (!Opts.cItemsAdded)
791 rc = rtFsIsoMakerErrorRc(&Opts, VERR_NO_DATA, "Cowardly refuses to create empty ISO image");
792 else if (!Opts.pszOutFile && !Opts.fVirtualImageMaker)
793 rc = rtFsIsoMakerErrorRc(&Opts, VERR_INVALID_PARAMETER, "No output file specified (--output <file>)");
794 if (RT_SUCCESS(rc))
795 {
796 /*
797 * Finalize the image and get the virtual file.
798 */
799 rc = RTFsIsoMakerFinalize(Opts.hIsoMaker);
800 if (RT_SUCCESS(rc))
801 {
802 RTVFSFILE hVfsFile;
803 rc = RTFsIsoMakerCreateVfsOutputFile(Opts.hIsoMaker, &hVfsFile);
804 if (RT_SUCCESS(rc))
805 {
806 /*
807 * We're done now if we're only setting up a virtual image.
808 */
809 if (Opts.fVirtualImageMaker)
810 *phVfsFile = hVfsFile;
811 else
812 {
813 rc = rtFsIsoMakerCmdWriteImage(&Opts, hVfsFile);
814 RTVfsFileRelease(hVfsFile);
815 }
816 }
817 else
818 rc = rtFsIsoMakerErrorRc(&Opts, rc, "RTFsIsoMakerCreateVfsOutputFile failed: %Rrc", rc);
819 }
820 else
821 rc = rtFsIsoMakerErrorRc(&Opts, rc, "RTFsIsoMakerFinalize failed: %Rrc", rc);
822 }
823
824 return rtFsIsoMakerCmdDeleteState(&Opts, rc);
825}
826
827
828RTDECL(RTEXITCODE) RTFsIsoMakerCmd(unsigned cArgs, char **papszArgs)
829{
830 int rc = RTFsIsoMakerCmdEx(cArgs, papszArgs, NULL, NULL);
831 return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
832}
833
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette