Version 1.10.0-BETA:
+ 'wimcapture' now requires confirmation before overwriting an existing
+ archive. Scripts that relied on the old behavior will need to add the
+ '--force' option, or delete the existing archive first.
+
+ 'wimappend' will now create the WIM archive if it doesn't yet exist
+ (thereby acting like 'wimcapture' in that scenario).
+
The LZX compression ratio has been slightly improved. The default mode,
LZX level 50, is now almost as good as the old LZX level 100, while
being nearly the same speed as before.
\fBwimlib-imagex append\fR \fISOURCE\fR \fIWIMFILE\fR [\fIIMAGE_NAME\fR \
[\fIIMAGE_DESCRIPTION\fR]] [\fIOPTION\fR...]
.SH DESCRIPTION
-The \fBwimlib-imagex capture\fR and \fBwimlib-imagex append\fR commands
-create a Windows Imaging (WIM) image from a directory tree. The
-\fBwimlib-imagex capture\fR command creates a new WIM file containing the
-captured image, while the \fBwimlib-imagex append\fR command appends the
-captured image to an existing WIM file.
-These commands are also available as simply \fBwimcapture\fR and \fBwimappend\fR
-if the appropriate hard links or batch files are installed.
+The \fBwimlib-imagex capture\fR and \fBwimlib-imagex append\fR commands create a
+Windows Imaging (WIM) image from a directory tree. If \fIWIMFILE\fR does not
+yet exist, then the two commands are equivalent, and both create a new WIM
+archive and save the image to it. Otherwise, \fBwimlib-imagex capture\fR will,
+with confirmation, overwrite the existing WIM archive with a new one; whereas
+\fBwimlib-imagex append\fR will append the new WIM image to the existing WIM
+archive. These commands are also available as simply \fBwimcapture\fR and
+\fBwimappend\fR if the appropriate hard links or batch files are installed.
.PP
Background information: A WIM image is an independent directory tree in a WIM
-file. A WIM file may contain any number of separate images. WIM files are
-single-instancing with regards to file data, so a file is stored only one time
-in the entire WIM, regardless of how many images the file appears in.
+archive (or "WIM file") A WIM archive may contain any number of separate
+images. WIM archives are single-instancing with regards to file data, so a
+file's data is stored only one time in the entire archive, regardless of how
+many images the file appears in.
.PP
\fISOURCE\fR specifies the location of the files to create the new WIM image
from. If \fISOURCE\fR is a directory, the WIM image is captured from that
\fIIMAGE_DESCRIPTION\fR is not specified, no description is given to the new
image.
.PP
-As a special case, if \fIWIMFILE\fR is "-", the \fB--pipable\fR option is
-assumed and the WIM file is written to standard output in a special pipable
-format. See the documentation for \fB--pipable\fR for more details.
+If \fIWIMFILE\fR is "-", the \fB--pipable\fR option is assumed and the WIM file
+is written to standard output in a special pipable format. See the
+documentation for \fB--pipable\fR for more details.
.SH DIRECTORY CAPTURE (UNIX)
This section documents how \fBwimlib-imagex\fR captures files from a
directory tree on UNIX-like systems. See \fBDIRECTORY CAPTURE (WINDOWS)\fR for
(UNIX)\fR mode from Linux.
.SH OPTIONS
.TP 6
+\fB--force\fR
+With \fBwimlib-imagex capture\fR, always overwrite the existing WIM archive; do
+not prompt.
+.TP
\fB--boot\fR
Specifies that the new image is to be made the bootable image of the WIM archive.
.TP
\fB--check\fR
-For \fBwimlib-imagex append\fR, before performing the append operation,
-check the integrity of \fIWIMFILE\fR if an integrity table is present.
-Furthermore, include an integrity table in the new WIM file
-(\fBwimlib-imagex capture\fR) or the modified WIM file (\fBwimlib-imagex
-append\fR). If this option is not specified, no integrity table is included in
-a WIM file created with \fBwimlib-imagex capture\fR, while a WIM file
-updated with \fBwimlib-imagex append\fR will be written with an integrity
-table if and only if one was present before.
+For \fBwimlib-imagex append\fR, before performing the append operation, check
+the integrity of \fIWIMFILE\fR if an integrity table is present. Furthermore,
+include an integrity table in the new or modified WIM archive. If this option
+is not specified, then an integrity table will be included only when appending
+to an archive that already had an integrity table.
.TP
\fB--compress\fR=\fITYPE\fR[:\fILEVEL\fR]
Specifies the compression format for the new WIM file. \fITYPE\fR may be
relative to the root of the directory tree being captured. When disabled
(\fB--norpfix\fR), absolute symbolic links will be captured exactly as is.
.IP ""
-The default behavior for \fBwimlib-imagex capture\fR is equivalent to
-\fB--rpfix\fR. The default behavior for \fBwimlib-imagex append\fR will be
+The default behavior for creating a new WIM archive is equivalent to
+\fB--rpfix\fR. The default behavior for appending to an existing WIM archive
\fB--rpfix\fR if reparse point fixups have previously been done on
\fIWIMFILE\fR, otherwise \fB--norpfix\fR.
.IP ""
(\fB--rebuild\fR is always implied), and also they aren't compatible with
Microsoft's software.
.IP ""
-\fBwimlib-imagex capture\fR and \fBwimlib-imagex append\fR can both
-write a pipable WIM directly to standard output; this is done automatically if
-\fIWIMFILE\fR is specified as "-". (In that case, \fB--pipable\fR is assumed.)
+\fBwimlib-imagex capture\fR can write a pipable WIM directly to standard output;
+this is done automatically if \fIWIMFILE\fR is specified as "-". (In that case,
+\fB--pipable\fR is assumed.)
.TP
\fB--not-pipable\fR
Ensure the resulting WIM is in the normal, non-pipable WIM format. This is the
};
static const struct option capture_or_append_options[] = {
+ {T("force"), no_argument, NULL, IMAGEX_FORCE_OPTION},
{T("boot"), no_argument, NULL, IMAGEX_BOOT_OPTION},
{T("check"), no_argument, NULL, IMAGEX_CHECK_OPTION},
{T("no-check"), no_argument, NULL, IMAGEX_NOCHECK_OPTION},
goto out_free_refglobs;
}
-/* Create a WIM image from a directory tree, NTFS volume, or multiple files or
- * directory trees. 'wimlib-imagex capture': create a new WIM file containing
- * the desired image. 'wimlib-imagex append': add a new image to an existing
- * WIM file. */
+static int
+handle_wimfile_argument(const tchar *wimfile, bool force, int *cmd_p)
+{
+ struct stat st;
+
+ if (stat(wimfile, &st) == 0) {
+ /* WIM file already exists. If invoked as 'wimcapture', make
+ * sure the user is certain about overwriting it. */
+ if (*cmd_p == CMD_CAPTURE && !force) {
+ if (isatty(STDIN_FILENO)) {
+ /* Interactive */
+ tprintf(
+"You invoked 'wimcapture' to create a new WIM archive at the following path:\n"
+"\t%"TS"\n"
+"However, this file already exists. 'wimcapture' can overwrite this file, which\n"
+"will cause this existing file to be permanently lost. If you actually want to\n"
+"add an image to an existing WIM archive rather than creating a brand new WIM\n"
+"archive, then you should cancel this operation and use 'wimappend' instead of\n"
+"'wimcapture'. It is also possible to use the '--force' option to suppress this\n"
+"prompt, making 'wimcapture' always overwrite existing files.\n"
+"\n"
+"Proceed with overwrite (y/n)? ", wimfile);
+ if (getchar() != 'y')
+ return -1;
+ } else {
+ /* Noninteractive */
+ imagex_error("\"%"TS"\" already exists. "
+ "Refusing to overwrite "
+ "without --force option.",
+ wimfile);
+ return -1;
+ }
+ }
+ } else if (errno == ENOENT) {
+ /* WIM file does not yet exist. Act like 'wimcapture', even if
+ * invoked as 'wimappend'. */
+ *cmd_p = CMD_CAPTURE;
+ } else {
+ imagex_error_with_errno(T("Error accessing \"%"TS"\""),
+ wimfile);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a WIM image from a directory tree, NTFS volume, or multiple files or
+ * directory trees. 'wimcapture' creates a new WIM archive to hold the new
+ * image. 'wimappend' appends to the existing WIM archive if there is one,
+ * otherwise (since wimlib v1.10.0) it creates a new one just like 'wimcapture'.
+ */
static int
imagex_capture_or_append(int argc, tchar **argv, int cmd)
{
int wim_fd;
const tchar *name;
STRING_LIST(image_properties);
+ bool force = false;
WIMStruct *wim;
STRING_LIST(base_wimfiles);
}
break;
case IMAGEX_DELTA_FROM_OPTION:
- if (cmd != CMD_CAPTURE) {
- imagex_error(T("'--delta-from' is only "
- "valid for capture!"));
- goto out_usage;
- }
ret = string_list_append(&base_wimfiles, optarg);
if (ret)
goto out;
add_flags |= WIMLIB_ADD_FLAG_WIMBOOT;
break;
case IMAGEX_UNSAFE_COMPACT_OPTION:
- if (cmd != CMD_APPEND) {
- imagex_error(T("'--unsafe-compact' is only "
- "valid for append!"));
- goto out_err;
- }
write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT;
break;
case IMAGEX_SNAPSHOT_OPTION:
add_flags |= WIMLIB_ADD_FLAG_SNAPSHOT;
break;
+ case IMAGEX_FORCE_OPTION:
+ force = true;
+ break;
default:
goto out_usage;
}
if (!tstrcmp(wimfile, T("-"))) {
/* Writing captured WIM to standard output. */
- #if 0
- if (!(write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) {
- imagex_error("Can't write a non-pipable WIM to "
- "standard output! Specify --pipable\n"
- " if you want to create a pipable WIM "
- "(but read the docs first).");
- goto out_err;
- }
- #else
write_flags |= WIMLIB_WRITE_FLAG_PIPABLE;
- #endif
if (cmd == CMD_APPEND) {
- imagex_error(T("Using standard output for append does "
- "not make sense."));
+ imagex_error(T("To write a WIM archive to standard "
+ "output, you must use 'wimcapture', "
+ "not 'wimappend'."));
goto out_err;
}
wim_fd = STDOUT_FILENO;
wimfile = NULL;
imagex_info_file = stderr;
set_fd_to_binary_mode(wim_fd);
+ } else {
+ ret = handle_wimfile_argument(wimfile, force, &cmd);
+ if (ret)
+ goto out;
+ }
+
+ if ((write_flags & WIMLIB_WRITE_FLAG_SKIP_EXTERNAL_WIMS) &&
+ cmd != CMD_CAPTURE)
+ {
+ imagex_error(T(
+ "'--delta-from' is only valid when creating a new WIM archive. Use\n"
+" 'wimcapture' (or 'wimlib-imagex capture') if you want to force creation\n"
+" of a new WIM archive."));
+ goto out_err;
+ }
+
+ if ((write_flags & WIMLIB_WRITE_FLAG_UNSAFE_COMPACT) &&
+ cmd != CMD_APPEND)
+ {
+ imagex_error(T(
+ "'--unsafe-compact' is only valid when appending to an existing WIM\n"
+" archive. If you want to append to an existing WIM archive, use\n"
+" 'wimappend' (or 'wimlib-imagex append') and pass it the path to an\n"
+" existing WIM archive."));
+ goto out_err;
}
/* If template image was specified using --update-of=IMAGE rather
"'--update-of' must specify "
"WIMFILE:IMAGE!"));
}
- goto out_usage;
+ goto out_err;
}
}
[CMD_CAPTURE] =
T(
" %"TS" " SOURCE_STR " WIMFILE [IMAGE_NAME [IMAGE_DESC]]\n"
-" [--compress=TYPE] [--boot] [--check] [--nocheck]\n"
+" [--force] [--compress=TYPE] [--boot] [--check] [--nocheck]\n"
" [--config=FILE] [--threads=NUM_THREADS]\n"
" [--no-acls] [--strict-acls] [--rpfix] [--norpfix]\n"
" [--update-of=[WIMFILE:]IMAGE] [--delta-from=WIMFILE]\n"
wimcapture()
{
- wimlib_imagex capture "$@" > /dev/null
+ wimlib_imagex capture "$@" --force > /dev/null
}
wimdelete()