]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
wimlib-imagex: print version of library being used
[wimlib] / programs / imagex.c
index 8f2aa0efb4d5157a13a044f8bc2badecf336bab1..28f0266356429b91879b6d1e59f421f435bcecf5 100644 (file)
@@ -133,12 +133,29 @@ static void usage_all(FILE *fp);
 static void recommend_man_page(int cmd, FILE *fp);
 static const tchar *get_cmd_string(int cmd, bool only_short_form);
 
-static bool imagex_be_quiet = false;
 static FILE *imagex_info_file;
 
-#define imagex_printf(format, ...) \
+#define imagex_printf(format, ...)     \
+       if (imagex_info_file)           \
                tfprintf(imagex_info_file, format, ##__VA_ARGS__)
 
+static void imagex_suppress_output(void)
+{
+       imagex_info_file = NULL;
+}
+
+static void imagex_output_to_stderr(void)
+{
+       if (imagex_info_file)
+               imagex_info_file = stderr;
+}
+
+static void imagex_flush_output(void)
+{
+       if (imagex_info_file)
+               fflush(imagex_info_file);
+}
+
 enum {
        IMAGEX_ALLOW_OTHER_OPTION,
        IMAGEX_BLOBS_OPTION,
@@ -1141,8 +1158,6 @@ imagex_progress_func(enum wimlib_progress_msg msg,
        unsigned unit_shift;
        const tchar *unit_name;
 
-       if (imagex_be_quiet)
-               return WIMLIB_PROGRESS_STATUS_CONTINUE;
        switch (msg) {
        case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
                {
@@ -1381,7 +1396,7 @@ imagex_progress_func(enum wimlib_progress_msg msg,
        default:
                break;
        }
-       fflush(imagex_info_file);
+       imagex_flush_output();
        return WIMLIB_PROGRESS_STATUS_CONTINUE;
 }
 
@@ -1986,11 +2001,6 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        }
                        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;
@@ -2062,7 +2072,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                }
                wim_fd = STDOUT_FILENO;
                wimfile = NULL;
-               imagex_info_file = stderr;
+               imagex_output_to_stderr();
                set_fd_to_binary_mode(wim_fd);
        }
 
@@ -2504,21 +2514,21 @@ static const struct {
 #define TIMESTR_MAX 100
 
 static void
-timespec_to_string(const struct timespec *spec, tchar *buf)
+print_time(const tchar *type, const struct wimlib_timespec *wts,
+          int32_t high_part)
 {
-       time_t t = spec->tv_sec;
+       tchar timestr[TIMESTR_MAX];
+       time_t t;
        struct tm tm;
-       gmtime_r(&t, &tm);
-       tstrftime(buf, TIMESTR_MAX, T("%a %b %d %H:%M:%S %Y UTC"), &tm);
-       buf[TIMESTR_MAX - 1] = '\0';
-}
 
-static void
-print_time(const tchar *type, const struct timespec *spec)
-{
-       tchar timestr[TIMESTR_MAX];
+       if (sizeof(wts->tv_sec) == 4 && sizeof(t) > sizeof(wts->tv_sec))
+               t = (uint32_t)wts->tv_sec | ((uint64_t)high_part << 32);
+       else
+               t = wts->tv_sec;
 
-       timespec_to_string(spec, timestr);
+       gmtime_r(&t, &tm);
+       tstrftime(timestr, TIMESTR_MAX, T("%a %b %d %H:%M:%S %Y UTC"), &tm);
+       timestr[TIMESTR_MAX - 1] = '\0';
 
        tprintf(T("%-20"TS"= %"TS"\n"), type, timestr);
 }
@@ -2679,9 +2689,12 @@ print_dentry_detailed(const struct wimlib_dir_entry *dentry)
                                          dentry->security_descriptor_size);
        }
 
-       print_time(T("Creation Time"), &dentry->creation_time);
-       print_time(T("Last Write Time"), &dentry->last_write_time);
-       print_time(T("Last Access Time"), &dentry->last_access_time);
+       print_time(T("Creation Time"),
+                  &dentry->creation_time, dentry->creation_time_high);
+       print_time(T("Last Write Time"),
+                  &dentry->last_write_time, dentry->last_write_time_high);
+       print_time(T("Last Access Time"),
+                  &dentry->last_access_time, dentry->last_access_time_high);
 
 
        if (dentry->attributes & WIMLIB_FILE_ATTRIBUTE_REPARSE_POINT)
@@ -2968,7 +2981,7 @@ imagex_export(int argc, tchar **argv, int cmd)
        #endif
                dest_wimfile = NULL;
                dest_wim_fd = STDOUT_FILENO;
-               imagex_info_file = stderr;
+               imagex_output_to_stderr();
                set_fd_to_binary_mode(dest_wim_fd);
        }
        errno = ENOENT;
@@ -3182,8 +3195,7 @@ imagex_extract(int argc, tchar **argv, int cmd)
                        break;
                case IMAGEX_TO_STDOUT_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_TO_STDOUT;
-                       imagex_info_file = stderr;
-                       imagex_be_quiet = true;
+                       imagex_suppress_output();
                        set_fd_to_binary_mode(STDOUT_FILENO);
                        break;
                case IMAGEX_INCLUDE_INVALID_NAMES_OPTION:
@@ -3279,8 +3291,7 @@ imagex_extract(int argc, tchar **argv, int cmd)
        }
 
        if (ret == 0) {
-               if (!imagex_be_quiet)
-                       imagex_printf(T("Done extracting files.\n"));
+               imagex_printf(T("Done extracting files.\n"));
        } else if (ret == WIMLIB_ERR_PATH_DOES_NOT_EXIST) {
                if ((extract_flags & (WIMLIB_EXTRACT_FLAG_STRICT_GLOB |
                                      WIMLIB_EXTRACT_FLAG_GLOB_PATHS))
@@ -4385,7 +4396,8 @@ T(
 "                    [--boot] [--check] [--nocheck] [--config=FILE]\n"
 "                    [--threads=NUM_THREADS] [--no-acls] [--strict-acls]\n"
 "                    [--rpfix] [--norpfix] [--update-of=[WIMFILE:]IMAGE]\n"
-"                    [--wimboot] [--unix-data] [--dereference] [--snapshot]\n"
+"                    [--delta-from=WIMFILE] [--wimboot] [--unix-data]\n"
+"                    [--dereference] [--snapshot]\n"
 ),
 [CMD_APPLY] =
 T(
@@ -4508,9 +4520,11 @@ static const tchar *get_cmd_string(int cmd, bool only_short_form)
 static void
 version(void)
 {
-       static const tchar * const s =
+       uint32_t vers = wimlib_get_version();
+
+       static const tchar * const fmt =
        T(
-"wimlib-imagex (distributed with " PACKAGE " " PACKAGE_VERSION ")\n"
+"wimlib-imagex " PACKAGE_VERSION " (using wimlib %u.%u.%u)\n"
 "Copyright (C) 2012-2017 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"
@@ -4518,13 +4532,15 @@ version(void)
 "\n"
 "Report bugs to "PACKAGE_BUGREPORT".\n"
        );
-       tfputs(s, stdout);
+       tfprintf(stdout, fmt,
+                vers >> 20, (vers >> 10) & 0x3ff, vers & 0x3ff);
 }
 
 
 static void
-help_or_version(int argc, tchar **argv, int cmd)
+do_common_options(int *argc_p, tchar **argv, int cmd)
 {
+       int argc = *argc_p;
        int i;
        const tchar *p;
 
@@ -4541,9 +4557,18 @@ help_or_version(int argc, tchar **argv, int cmd)
                        } else if (!tstrcmp(p, T("version"))) {
                                version();
                                exit(0);
-                       }
+                       } else if (!tstrcmp(p, T("quiet"))) {
+                               imagex_suppress_output();
+                               memmove(&argv[i], &argv[i + 1],
+                                       (argc - i) * sizeof(argv[i]));
+                               argc--;
+                               i--;
+                       } else if (!*p) /* reached "--", no more options */
+                               break;
                }
        }
+
+       *argc_p = argc;
 }
 
 static void
@@ -4668,11 +4693,8 @@ main(int argc, tchar **argv)
                }
        }
 
-       /* Handle --help and --version.  --help can be either for the program as
-        * a whole (cmd == CMD_NONE) or just for a specific command (cmd !=
-        * CMD_NONE).  Note: help_or_version() will not return if a --help or
-        * --version argument was found.  */
-       help_or_version(argc, argv, cmd);
+       /* Handle common options.  May exit early (for --help or --version).  */
+       do_common_options(&argc, argv, cmd);
 
        /* Bail if a valid command was not specified.  */
        if (cmd == CMD_NONE) {