]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
Move manpages from doc/ to doc/man1/
[wimlib] / programs / imagex.c
index 7914573f59fa45a5213e610316ae7eae817c371f..e80d3e6ce6aecd111d98e216e27c469ae0092a2e 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 /*
- * Copyright (C) 2012, 2013 Eric Biggers
+ * Copyright (C) 2012, 2013, 2014 Eric Biggers
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -167,6 +167,7 @@ enum {
        IMAGEX_LAZY_OPTION,
        IMAGEX_LOOKUP_TABLE_OPTION,
        IMAGEX_METADATA_OPTION,
+       IMAGEX_NEW_IMAGE_OPTION,
        IMAGEX_NOCHECK_OPTION,
        IMAGEX_NORPFIX_OPTION,
        IMAGEX_NOT_PIPABLE_OPTION,
@@ -197,6 +198,7 @@ enum {
        IMAGEX_UNIX_DATA_OPTION,
        IMAGEX_UPDATE_OF_OPTION,
        IMAGEX_VERBOSE_OPTION,
+       IMAGEX_WIMBOOT_OPTION,
        IMAGEX_XML_OPTION,
 };
 
@@ -217,6 +219,7 @@ static const struct option apply_options[] = {
 
        /* --resume is undocumented for now as it needs improvement.  */
        {T("resume"),      no_argument,       NULL, IMAGEX_RESUME_OPTION},
+       {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -249,6 +252,7 @@ static const struct option capture_or_append_options[] = {
        {T("not-pipable"), no_argument,       NULL, IMAGEX_NOT_PIPABLE_OPTION},
        {T("update-of"),   required_argument, NULL, IMAGEX_UPDATE_OF_OPTION},
        {T("delta-from"),  required_argument, NULL, IMAGEX_DELTA_FROM_OPTION},
+       {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -271,6 +275,7 @@ static const struct option export_options[] = {
        {T("nocheck"),     no_argument,       NULL, IMAGEX_NOCHECK_OPTION},
        {T("no-check"),    no_argument,       NULL, IMAGEX_NOCHECK_OPTION},
        {T("compress"),    required_argument, NULL, IMAGEX_COMPRESS_OPTION},
+       {T("compress-slow"), no_argument,     NULL, IMAGEX_COMPRESS_SLOW_OPTION},
        {T("pack-streams"),no_argument,       NULL, IMAGEX_PACK_STREAMS_OPTION},
        {T("solid"),       no_argument,       NULL, IMAGEX_PACK_STREAMS_OPTION},
        {T("chunk-size"),  required_argument, NULL, IMAGEX_CHUNK_SIZE_OPTION},
@@ -299,6 +304,7 @@ static const struct option extract_options[] = {
        {T("no-wildcards"), no_argument,      NULL, IMAGEX_NO_WILDCARDS_OPTION},
        {T("nullglob"),     no_argument,      NULL, IMAGEX_NULLGLOB_OPTION},
        {T("preserve-dir-structure"), no_argument, NULL, IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION},
+       {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -360,6 +366,7 @@ static const struct option unmount_options[] = {
        {T("check"),   no_argument, NULL, IMAGEX_CHECK_OPTION},
        {T("rebuild"), no_argument, NULL, IMAGEX_REBUILD_OPTION},
        {T("lazy"),    no_argument, NULL, IMAGEX_LAZY_OPTION},
+       {T("new-image"), no_argument, NULL, IMAGEX_NEW_IMAGE_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -410,6 +417,17 @@ imagex_error(const tchar *format, ...)
        va_end(va);
 }
 
+static void _format_attribute(printf, 1, 2)
+imagex_warning(const tchar *format, ...)
+{
+       va_list va;
+       va_start(va, format);
+       tfputs(T("WARNING: "), stderr);
+       tvfprintf(stderr, format, va);
+       tputc(T('\n'), stderr);
+       va_end(va);
+}
+
 /* Print formatted error message to stderr. */
 static void _format_attribute(printf, 1, 2)
 imagex_error_with_errno(const tchar *format, ...)
@@ -711,7 +729,7 @@ static bool
 is_comment_line(const tchar *line, size_t len)
 {
        for (;;) {
-               if (*line == T('#'))
+               if (*line == T('#') || *line == T(';'))
                        return true;
                if (!istspace(*line) && *line != T('\0'))
                        return false;
@@ -853,8 +871,8 @@ check_config_section(tchar *line, size_t len,
                         "of capture config file\n"),
                       stderr);
        } else {
-               imagex_error(T("Invalid capture config file section \"%"TS"\""),
-                            line - 1);
+               imagex_warning(T("Unknown capture config file section \"%"TS"\""),
+                              line - 1);
                return CAPTURE_CONFIG_INVALID_SECTION;
        }
        return CAPTURE_CONFIG_CHANGED_SECTION;
@@ -891,9 +909,8 @@ parse_capture_config_line(tchar *line, size_t len,
        int ret;
 
        ret = check_config_section(line, len, cur_section);
-       if (ret == CAPTURE_CONFIG_INVALID_SECTION)
-               return false;
-       if (ret == CAPTURE_CONFIG_CHANGED_SECTION)
+       if (ret == CAPTURE_CONFIG_CHANGED_SECTION ||
+           ret == CAPTURE_CONFIG_INVALID_SECTION)
                return true;
 
        switch (*cur_section) {
@@ -938,6 +955,10 @@ parse_capture_config(tchar **contents_p, size_t nchars,
                tchar *endp = tmemchr(p, T('\n'), nchars);
                size_t len = endp - p + 1;
                *endp = T('\0');
+               if (p != endp && *(endp - 1) == T('\r')) {
+                       *(endp - 1) = '\0';
+                       len--;
+               }
                if (!is_comment_line(p, len))
                        if (!parse_capture_config_line(p, len, &cur_section, config))
                                return -1;
@@ -1662,6 +1683,9 @@ imagex_apply(int argc, tchar **argv, int cmd)
                case IMAGEX_RESUME_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_RESUME;
                        break;
+               case IMAGEX_WIMBOOT_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_WIMBOOT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -1817,7 +1841,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
        tchar *source;
        tchar *source_copy;
 
-       const tchar *config_file = NULL;
+       tchar *config_file = NULL;
        tchar *config_str;
        struct wimlib_capture_config *config;
 
@@ -1938,6 +1962,9 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                                goto out_free_base_wimfiles;
                        write_flags |= WIMLIB_WRITE_FLAG_SKIP_EXTERNAL_WIMS;
                        break;
+               case IMAGEX_WIMBOOT_OPTION:
+                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_WIMBOOT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -1955,22 +1982,46 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
 
 
        if (compression_type == WIMLIB_COMPRESSION_TYPE_INVALID) {
-               compression_type = WIMLIB_COMPRESSION_TYPE_LZX;
-
-               if (!compress_slow) {
-                       struct wimlib_lzx_compressor_params params = {
-                               .hdr.size = sizeof(params),
-                               .algorithm = WIMLIB_LZX_ALGORITHM_FAST,
-                               .use_defaults = 1,
-                       };
-                       wimlib_set_default_compressor_params(WIMLIB_COMPRESSION_TYPE_LZX,
-                                                            &params.hdr);
+               if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) {
+                       compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS;
+               } else {
+                       compression_type = WIMLIB_COMPRESSION_TYPE_LZX;
+                       if (!compress_slow) {
+                               struct wimlib_lzx_compressor_params params = {
+                                       .hdr.size = sizeof(params),
+                                       .algorithm = WIMLIB_LZX_ALGORITHM_FAST,
+                                       .use_defaults = 1,
+                               };
+                               wimlib_set_default_compressor_params(WIMLIB_COMPRESSION_TYPE_LZX,
+                                                                    &params.hdr);
+                       }
                }
+
        }
 
        if (compress_slow)
                set_compress_slow();
 
+       /* Set default configuration file  */
+#ifdef __WIN32__
+       if ((add_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) && !config) {
+               struct stat st;
+
+               config_file = alloca(wcslen(source) * sizeof(wchar_t) + 100);
+               swprintf(config_file, L"%ls\\%ls",
+                        source,  L"Windows\\System32\\WimBootCompress.ini");
+
+               if (tstat(config_file, &st)) {
+                       imagex_printf(L"\"%ls\" does not exist; using "
+                                     "default configuration\n",
+                                     config_file);
+                       config_file = NULL;
+               } else {
+                       add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_WINCONFIG;
+               }
+       }
+#endif
+
        if (!tstrcmp(wimfile, T("-"))) {
                /* Writing captured WIM to standard output.  */
        #if 0
@@ -2110,6 +2161,11 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                ret = wimlib_set_output_chunk_size(wim, chunk_size);
                if (ret)
                        goto out_free_wim;
+       } else if ((add_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) &&
+                  compression_type == WIMLIB_COMPRESSION_TYPE_XPRESS) {
+               ret = wimlib_set_output_chunk_size(wim, 4096);
+               if (ret)
+                       goto out_free_wim;
        }
        if (pack_chunk_size != UINT32_MAX) {
                ret = wimlib_set_output_pack_chunk_size(wim, pack_chunk_size);
@@ -2731,6 +2787,10 @@ imagex_export(int argc, tchar **argv, int cmd)
                        if (compression_type == WIMLIB_COMPRESSION_TYPE_INVALID)
                                goto out_err;
                        break;
+               case IMAGEX_COMPRESS_SLOW_OPTION:
+                       write_flags |= WIMLIB_WRITE_FLAG_RECOMPRESS;
+                       set_compress_slow();
+                       break;
                case IMAGEX_PACK_STREAMS_OPTION:
                        write_flags |= WIMLIB_WRITE_FLAG_PACK_STREAMS;
                        break;
@@ -3002,6 +3062,9 @@ imagex_extract(int argc, tchar **argv, int cmd)
                case IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION:
                        notlist_extract_flags &= ~WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE;
                        break;
+               case IMAGEX_WIMBOOT_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_WIMBOOT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -3750,6 +3813,9 @@ imagex_unmount(int argc, tchar **argv, int cmd)
                case IMAGEX_LAZY_OPTION:
                        unmount_flags |= WIMLIB_UNMOUNT_FLAG_LAZY;
                        break;
+               case IMAGEX_NEW_IMAGE_OPTION:
+                       unmount_flags |= WIMLIB_UNMOUNT_FLAG_NEW_IMAGE;
+                       break;
                default:
                        goto out_usage;
                }
@@ -3759,6 +3825,15 @@ imagex_unmount(int argc, tchar **argv, int cmd)
        if (argc != 1)
                goto out_usage;
 
+       if (unmount_flags & WIMLIB_UNMOUNT_FLAG_NEW_IMAGE) {
+               if (!(unmount_flags & WIMLIB_UNMOUNT_FLAG_COMMIT)) {
+                       imagex_error(T("--new-image is meaningless "
+                                      "without --commit also specified!"));
+                       goto out_err;
+               }
+               imagex_printf(T("Committing changes as new image...\n"));
+       }
+
        ret = wimlib_unmount_image(argv[0], unmount_flags,
                                   imagex_progress_func);
        if (ret)
@@ -3768,6 +3843,7 @@ out:
 
 out_usage:
        usage(CMD_UNMOUNT, stderr);
+out_err:
        ret = -1;
        goto out;
 }
@@ -4108,6 +4184,7 @@ T(
 [CMD_UNMOUNT] =
 T(
 "    %"TS" DIRECTORY [--commit] [--check] [--rebuild] [--lazy]\n"
+"                    [--new-image]\n"
 ),
 #endif
 [CMD_UPDATE] =
@@ -4145,8 +4222,8 @@ version(void)
 {
        static const tchar *s =
        T(
-IMAGEX_PROGNAME " (" PACKAGE ") " PACKAGE_VERSION "\n"
-"Copyright (C) 2012, 2013 Eric Biggers\n"
+IMAGEX_PROGNAME " (distributed with " PACKAGE " " PACKAGE_VERSION ")\n"
+"Copyright (C) 2012, 2013, 2014 Eric Biggers\n"
 "License GPLv3+; GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n"
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n"