Add --command option to wimlib-imagex update
authorEric Biggers <ebiggers3@gmail.com>
Mon, 20 May 2013 19:30:03 +0000 (14:30 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 20 May 2013 19:30:03 +0000 (14:30 -0500)
NEWS
doc/imagex-update.1.in
include/wimlib/util.h
include/wimlib_tchar.h
programs/imagex.c
src/win32_apply.c

diff --git a/NEWS b/NEWS
index 570bfe1..28ccd95 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,9 @@ Version 1.4.1:
        `wimlib-imagex update' will now complain if no image is specified when
        trying to update a multi-image WIM.
 
+       `wimlib-imagex update' now supports specifying a single update command
+       directly on the command line using the --command option.
+
        wimlib-imagex will now choose different units for progress messages,
        depending on the amount of data that needs to be processed.
 
index 35c2e46..ceca0fc 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 @IMAGEX_PROGNAME@-update \- Update a WIM image
 .SH SYNOPSIS
-\fB@IMAGEX_PROGNAME@ update\fR \fIWIMFILE\fR [\fIIMAGE\fR] [\fIOPTION\fR...] < \fICMDFILE\fR
+\fB@IMAGEX_PROGNAME@ update\fR \fIWIMFILE\fR [\fIIMAGE\fR] [\fIOPTION\fR...] [< \fICMDFILE\fR]
 .SH DESCRIPTION
 \fB@IMAGEX_PROGNAME@ update\fR modifies the specified \fIIMAGE\fR in the Windows
 Imaging (WIM) file \fIWIMFILE\fR by adding, deleting, or renaming files or
@@ -16,7 +16,8 @@ index of an image in the WIM or the name of an image in the WIM.  Use the
 The modifications to perform on the WIM image are specified as a sequence of
 commands, one per line, read in a text file from standard input.  It is
 recommended that standard input be redirected from a file (\fICMDFILE\fR), as
-shown above, rather than typing in commands interactively.
+shown above, rather than typing in commands interactively.  Alternatively, to
+specify a command directly on the command line, see the \fB--command\fR option.
 .SH AVAILABLE COMMANDS
 This section documents the commands that may appear in the \fICMDFILE\fR
 described above.
@@ -124,6 +125,12 @@ Rebuild the entire WIM rather than appending the updated data to the end of it.
 Rebuilding the WIM is slower, but will save a little bit of space that would
 otherwise be left as a hole in the WIM.  Also see
 \fB@IMAGEX_PROGNAME@-optimize\fR (1).
+.TP
+\fB--command\fR=\fISTRING\fR
+Instead of reading update commands from standard input, read a single update
+command directly from the string \fISTRING\fR specified on the command line.
+This option cannot be provided more than one time and cannot be used to specify
+more than one update command.
 .SH NOTES
 \fB@IMAGEX_PROGNAME@ update\fR is partly redundant with \fB@IMAGEX_PROGNAME@
 mountrw\fR, since if a WIM image can be mounted read-write, then there
index 889a3f5..3293683 100644 (file)
@@ -75,7 +75,7 @@ wimlib_strdup(const char *str) _malloc_attribute;
 #  define      REALLOC wimlib_realloc
 #  define      CALLOC  wimlib_calloc
 #  define      STRDUP  wimlib_strdup
-#  define      WSTRDUP wimlib_wcsdup
+#  define      WCSDUP  wimlib_wcsdup
 #else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
 #  include <stdlib.h>
 #  include <string.h>
@@ -84,7 +84,7 @@ wimlib_strdup(const char *str) _malloc_attribute;
 #  define      REALLOC realloc
 #  define      CALLOC  calloc
 #  define      STRDUP  strdup
-#  define       WSTRDUP wcsdup
+#  define       WCSDUP  wcsdup
 #endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
 
 extern void *
index 6d81f02..f0b17f0 100644 (file)
@@ -50,10 +50,11 @@ typedef wchar_t tchar;
 #  define tunlink      _wunlink
 #  define tstrerror    _wcserror
 #  define taccess      _waccess
+#  define tstrdup      wcsdup
 /* The following "tchar" functions do not have exact wide-character equivalents
  * on Windows so require parameter rearrangement or redirection to a replacement
  * function defined ourselves. */
-#  define TSTRDUP      WSTRDUP
+#  define TSTRDUP      WCSDUP
 #  define tmkdir(path, mode) _wmkdir(path)
 #  define tstrerror_r   win32_strerror_r_replacement
 #  define trename      win32_rename_replacement
@@ -107,6 +108,7 @@ typedef char tchar;
 #  define tstrtod      strtod
 #  define tstrtoul     strtoul
 #  define tmkdir       mkdir
+#  define tstrdup      strdup
 #  define TSTRDUP      STRDUP
 #  define tstrerror_r  strerror_r
 #  define trename      rename
index 297c65f..f8ffc7c 100644 (file)
@@ -176,7 +176,7 @@ IMAGEX_PROGNAME" unmount DIRECTORY [--commit] [--check] [--rebuild] [--lazy]\n"
 T(
 IMAGEX_PROGNAME" update WIMFILE [IMAGE_NUM | IMAGE_NAME] [--check] [--rebuild]\n"
 "                       [--threads=NUM_THREADS] [DEFAULT_ADD_OPTIONS]\n"
-"                       [DEFAULT_DELETE_OPTIONS] < CMDFILE\n"
+"                       [DEFAULT_DELETE_OPTIONS] [--command=STRING] [< CMDFILE]\n"
 ),
 };
 
@@ -199,6 +199,7 @@ enum {
        IMAGEX_ALLOW_OTHER_OPTION,
        IMAGEX_BOOT_OPTION,
        IMAGEX_CHECK_OPTION,
+       IMAGEX_COMMAND_OPTION,
        IMAGEX_COMMIT_OPTION,
        IMAGEX_COMPRESS_OPTION,
        IMAGEX_CONFIG_OPTION,
@@ -353,6 +354,7 @@ static const struct option update_options[] = {
        {T("threads"),     required_argument, NULL, IMAGEX_THREADS_OPTION},
        {T("check"),       no_argument,       NULL, IMAGEX_CHECK_OPTION},
        {T("rebuild"),     no_argument,       NULL, IMAGEX_REBUILD_OPTION},
+       {T("command"),     required_argument, NULL, IMAGEX_COMMAND_OPTION},
 
        /* Default delete options */
        {T("force"),       no_argument,       NULL, IMAGEX_FORCE_OPTION},
@@ -368,6 +370,7 @@ static const struct option update_options[] = {
        {T("noacls"),      no_argument,       NULL, IMAGEX_NO_ACLS_OPTION},
        {T("no-acls"),     no_argument,       NULL, IMAGEX_NO_ACLS_OPTION},
        {T("strict-acls"), no_argument,       NULL, IMAGEX_STRICT_ACLS_OPTION},
+
        {NULL, 0, NULL, 0},
 };
 
@@ -2985,11 +2988,12 @@ imagex_update(int argc, tchar **argv)
        int default_delete_flags = 0;
        unsigned num_threads = 0;
        int c;
-       tchar *cmd_file_contents;
+       tchar *cmd_file_contents = NULL;
        size_t cmd_file_nchars;
        struct wimlib_update_command *cmds;
        size_t num_cmds;
        int num_images;
+       tchar *command_str = NULL;
 
        const tchar *config_file = NULL;
        tchar *config_str;
@@ -3012,7 +3016,22 @@ imagex_update(int argc, tchar **argv)
                case IMAGEX_REBUILD_OPTION:
                        write_flags |= WIMLIB_WRITE_FLAG_REBUILD;
                        break;
-
+               case IMAGEX_COMMAND_OPTION:
+                       if (command_str) {
+                               imagex_error(T("--command may only be specified "
+                                              "one time.  Please provide\n"
+                                              "       the update commands "
+                                              "on standard input instead."));
+                               ret = -1;
+                               goto out;
+                       }
+                       command_str = tstrdup(optarg);
+                       if (!command_str) {
+                               imagex_error(T("Out of memory!"));
+                               ret = -1;
+                               goto out;
+                       }
+                       break;
                /* Default delete options */
                case IMAGEX_FORCE_OPTION:
                        default_delete_flags |= WIMLIB_DELETE_FLAG_FORCE;
@@ -3100,20 +3119,26 @@ imagex_update(int argc, tchar **argv)
                config = &default_capture_config;
        }
 
-       /* Read update commands from standard input */
-       if (isatty(STDIN_FILENO)) {
-               tputs(T("Reading update commands from standard input..."));
-               recommend_man_page(T("update"));
-       }
-       cmd_file_contents = stdin_get_text_contents(&cmd_file_nchars);
-       if (!cmd_file_contents) {
-               ret = -1;
-               goto out_free_config;
-       }
+       /* Read update commands from standard input, or the command string if
+        * specified.  */
+       if (command_str) {
+               cmds = parse_update_command_file(&command_str, tstrlen(command_str),
+                                                &num_cmds);
+       } else {
+               if (isatty(STDIN_FILENO)) {
+                       tputs(T("Reading update commands from standard input..."));
+                       recommend_man_page(T("update"));
+               }
+               cmd_file_contents = stdin_get_text_contents(&cmd_file_nchars);
+               if (!cmd_file_contents) {
+                       ret = -1;
+                       goto out_free_config;
+               }
 
-       /* Parse the update commands */
-       cmds = parse_update_command_file(&cmd_file_contents, cmd_file_nchars,
-                                        &num_cmds);
+               /* Parse the update commands */
+               cmds = parse_update_command_file(&cmd_file_contents, cmd_file_nchars,
+                                                &num_cmds);
+       }
        if (!cmds) {
                ret = -1;
                goto out_free_cmd_file_contents;
@@ -3164,6 +3189,7 @@ out_free_config:
 out_wimlib_free:
        wimlib_free(wim);
 out:
+       free(command_str);
        return ret;
 out_usage:
        usage(UPDATE);
index ffee267..7b7ff27 100644 (file)
@@ -1259,7 +1259,7 @@ win32_do_apply_dentry(const wchar_t *output_path,
                        /* Save extracted path for a later call to
                         * CreateHardLinkW() if this inode has multiple links.
                         * */
-                       inode->i_extracted_file = WSTRDUP(output_path);
+                       inode->i_extracted_file = WCSDUP(output_path);
                        if (!inode->i_extracted_file)
                                return WIMLIB_ERR_NOMEM;
                }