+static int file_writable(const char *path)
+{
+ int ret;
+ ret = access(path, W_OK);
+ if (ret != 0)
+ imagex_error_with_errno("Can't modify `%s'", path);
+ return ret;
+}
+
+#define TO_PERCENT(numerator, denominator) \
+ (((denominator) == 0) ? 0 : ((numerator) * 100 / (denominator)))
+
+static const char *get_data_type(int ctype)
+{
+ switch (ctype) {
+ case WIMLIB_COMPRESSION_TYPE_NONE:
+ return "uncompressed";
+ case WIMLIB_COMPRESSION_TYPE_LZX:
+ return "LZX-compressed";
+ case WIMLIB_COMPRESSION_TYPE_XPRESS:
+ return "XPRESS-compressed";
+ }
+ return NULL;
+}
+
+static int imagex_progress_func(enum wimlib_progress_msg msg,
+ const union wimlib_progress_info *info)
+{
+ unsigned percent_done;
+ switch (msg) {
+ case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
+ percent_done = TO_PERCENT(info->write_streams.completed_bytes,
+ info->write_streams.total_bytes);
+ if (info->write_streams.completed_streams == 0) {
+ const char *data_type;
+
+ data_type = get_data_type(info->write_streams.compression_type);
+ printf("Writing %s data using %u thread%s\n",
+ data_type, info->write_streams.num_threads,
+ (info->write_streams.num_threads == 1) ? "" : "s");
+ }
+ printf("\r%"PRIu64" MiB of %"PRIu64" MiB (uncompressed) "
+ "written (%u%% done)",
+ info->write_streams.completed_bytes >> 20,
+ info->write_streams.total_bytes >> 20,
+ percent_done);
+ if (info->write_streams.completed_bytes >= info->write_streams.total_bytes)
+ putchar('\n');
+ break;
+ case WIMLIB_PROGRESS_MSG_SCAN_BEGIN:
+ printf("Scanning `%s'...\n", info->scan.source);
+ break;
+ case WIMLIB_PROGRESS_MSG_SCAN_DENTRY:
+ if (info->scan.excluded)
+ printf("Excluding `%s' from capture\n", info->scan.cur_path);
+ else
+ printf("Scanning `%s'\n", info->scan.cur_path);
+ break;
+ /*case WIMLIB_PROGRESS_MSG_SCAN_END:*/
+ /*break;*/
+ case WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY:
+ percent_done = TO_PERCENT(info->integrity.completed_bytes,
+ info->integrity.total_bytes);
+ printf("\rVerifying integrity of `%s': %"PRIu64" MiB "
+ "of %"PRIu64" MiB (%u%%) done",
+ info->integrity.filename,
+ info->integrity.completed_bytes >> 20,
+ info->integrity.total_bytes >> 20,
+ percent_done);
+ if (info->integrity.completed_bytes == info->integrity.total_bytes)
+ putchar('\n');
+ break;
+ case WIMLIB_PROGRESS_MSG_CALC_INTEGRITY:
+ percent_done = TO_PERCENT(info->integrity.completed_bytes,
+ info->integrity.total_bytes);
+ printf("\rCalculating integrity table for WIM: %"PRIu64" MiB "
+ "of %"PRIu64" MiB (%u%%) done",
+ info->integrity.completed_bytes >> 20,
+ info->integrity.total_bytes >> 20,
+ percent_done);
+ if (info->integrity.completed_bytes == info->integrity.total_bytes)
+ putchar('\n');
+ break;
+ case WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN:
+ printf("Applying image %d (%s) from `%s' to %s `%s'\n",
+ info->extract.image,
+ info->extract.image_name,
+ info->extract.wimfile_name,
+ ((info->extract.extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) ?
+ "NTFS volume" : "directory"),
+ info->extract.target);
+ break;
+ /*case WIMLIB_PROGRESS_MSG_EXTRACT_DIR_STRUCTURE_BEGIN:*/
+ /*printf("Applying directory structure to %s\n",*/
+ /*info->extract.target);*/
+ /*break;*/
+ case WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS:
+ percent_done = TO_PERCENT(info->extract.completed_bytes,
+ info->extract.total_bytes);
+ printf("\rExtracting files: "
+ "%"PRIu64" MiB of %"PRIu64" MiB (%u%%) done",
+ info->extract.completed_bytes >> 20,
+ info->extract.total_bytes >> 20,
+ percent_done);
+ if (info->extract.completed_bytes >= info->extract.total_bytes)
+ putchar('\n');
+ break;
+ case WIMLIB_PROGRESS_MSG_EXTRACT_DENTRY:
+ puts(info->extract.cur_path);
+ break;
+ case WIMLIB_PROGRESS_MSG_APPLY_TIMESTAMPS:
+ printf("Setting timestamps on all extracted files...\n");
+ break;
+ case WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END:
+ if (info->extract.extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
+ printf("Unmounting NTFS volume `%s'...\n",
+ info->extract.target);
+ }
+ break;
+ case WIMLIB_PROGRESS_MSG_JOIN_STREAMS:
+ percent_done = TO_PERCENT(info->join.completed_bytes,
+ info->join.total_bytes);
+ printf("Writing resources from part %u of %u: "
+ "%"PRIu64 " MiB of %"PRIu64" MiB (%u%%) written\n",
+ (info->join.completed_parts == info->join.total_parts) ?
+ info->join.completed_parts : info->join.completed_parts + 1,
+ info->join.total_parts,
+ info->join.completed_bytes >> 20,
+ info->join.total_bytes >> 20,
+ percent_done);
+ break;
+ case WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART:
+ percent_done = TO_PERCENT(info->split.completed_bytes,
+ info->split.total_bytes);
+ printf("Writing `%s': %"PRIu64" MiB of %"PRIu64" MiB (%u%%) written\n",
+ info->split.part_name,
+ info->split.completed_bytes >> 20,
+ info->split.total_bytes >> 20,
+ percent_done);
+ break;
+ case WIMLIB_PROGRESS_MSG_SPLIT_END_PART:
+ if (info->split.completed_bytes == info->split.total_bytes) {
+ printf("Finished writing %u split WIM parts\n",
+ info->split.cur_part_number);
+ }
+ break;
+ default:
+ break;
+ }
+ fflush(stdout);
+ return 0;
+}
+
+