#endif
#ifndef __WIN32__
+
+/* Returns the number of components of @path. */
+static unsigned
+get_num_path_components(const char *path)
+{
+ unsigned num_components = 0;
+ while (*path) {
+ while (*path == '/')
+ path++;
+ if (*path)
+ num_components++;
+ while (*path && *path != '/')
+ path++;
+ }
+ return num_components;
+}
+
+static const char *
+path_next_part(const char *path)
+{
+ while (*path && *path != '/')
+ path++;
+ while (*path && *path == '/')
+ path++;
+ return path;
+}
+
static int
extract_regular_file_linked(struct wim_dentry *dentry,
- const mbchar *output_path,
+ const char *output_path,
struct apply_args *args,
struct wim_lookup_table_entry *lte)
{
int num_path_components;
int num_output_dir_path_components;
size_t extracted_file_len;
- mbchar *p;
- const mbchar *p2;
+ char *p;
+ const char *p2;
size_t i;
num_path_components =
}
extracted_file_len = strlen(lte->extracted_file);
- mbchar buf[extracted_file_len + 3 * num_path_components + 1];
+ char buf[extracted_file_len + 3 * num_path_components + 1];
p = &buf[0];
for (i = 0; i < num_path_components; i++) {
p2 = lte->extracted_file;
while (*p2 == '/')
p2++;
- while (num_output_dir_path_components--)
- p2 = path_next_part(p2, NULL);
+ while (num_output_dir_path_components > 0) {
+ p2 = path_next_part(p2);
+ num_output_dir_path_components--;
+ }
strcpy(p, p2);
if (symlink(buf, output_path) != 0) {
ERROR_WITH_ERRNO("Failed to symlink `%s' to `%s'",
}
static int
-symlink_apply_unix_data(const mbchar *link,
+symlink_apply_unix_data(const char *link,
const struct wimlib_unix_data *unix_data)
{
if (lchown(link, unix_data->uid, unix_data->gid)) {
}
static int
-dir_apply_unix_data(const mbchar *dir, const struct wimlib_unix_data *unix_data)
+dir_apply_unix_data(const char *dir, const struct wimlib_unix_data *unix_data)
{
int dfd = open(dir, O_RDONLY);
int ret;
static int
extract_regular_file_unlinked(struct wim_dentry *dentry,
struct apply_args *args,
- const mbchar *output_path,
+ const char *output_path,
struct wim_lookup_table_entry *lte)
{
/* Normal mode of extraction. Regular files and hard links are
static int
extract_regular_file(struct wim_dentry *dentry,
struct apply_args *args,
- const mbchar *output_path)
+ const char *output_path)
{
struct wim_lookup_table_entry *lte;
const struct wim_inode *inode = dentry->d_inode;
static int
extract_symlink(struct wim_dentry *dentry,
struct apply_args *args,
- const mbchar *output_path)
+ const char *output_path)
{
- mbchar target[4096];
+ char target[4096];
ssize_t ret = inode_readlink(dentry->d_inode, target,
sizeof(target), args->w, 0);
struct wim_lookup_table_entry *lte;
static int
extract_directory(struct wim_dentry *dentry,
- const mbchar *output_path, bool is_root)
+ const tchar *output_path, bool is_root)
{
int ret;
struct stat stbuf;
- ret = stat(output_path, &stbuf);
+ ret = tstat(output_path, &stbuf);
if (ret == 0) {
if (S_ISDIR(stbuf.st_mode)) {
/*if (!is_root)*/
/*WARNING("`%s' already exists", output_path);*/
goto dir_exists;
} else {
- ERROR("`%s' is not a directory", output_path);
+ ERROR("`%"TS"' is not a directory", output_path);
return WIMLIB_ERR_MKDIR;
}
} else {
if (errno != ENOENT) {
- ERROR_WITH_ERRNO("Failed to stat `%s'", output_path);
+ ERROR_WITH_ERRNO("Failed to stat `%"TS"'", output_path);
return WIMLIB_ERR_STAT;
}
}
- if (mkdir(output_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
+ if (tmkdir(output_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
{
- ERROR_WITH_ERRNO("Cannot create directory `%s'", output_path);
+ ERROR_WITH_ERRNO("Cannot create directory `%"TS"'", output_path);
return WIMLIB_ERR_MKDIR;
}
dir_exists:
}
#ifndef __WIN32__
-static int unix_do_apply_dentry(const mbchar *output_path,
+static int unix_do_apply_dentry(const char *output_path,
size_t output_path_len,
struct wim_dentry *dentry,
struct apply_args *args)
}
static int
-unix_do_apply_dentry_timestamps(const mbchar *output_path,
+unix_do_apply_dentry_timestamps(const char *output_path,
size_t output_path_len,
const struct wim_dentry *dentry,
struct apply_args *args)
apply_dentry_normal(struct wim_dentry *dentry, void *arg)
{
struct apply_args *args = arg;
+ tchar *output_path;
size_t len;
- mbchar *output_path;
- len = strlen(args->target);
+ len = tstrlen(args->target);
if (dentry_is_root(dentry)) {
- output_path = (mbchar*)args->target;
+ output_path = (tchar*)args->target;
} else {
- output_path = alloca(len + dentry->full_path_nbytes + 1);
- memcpy(output_path, args->target, len);
+ output_path = alloca(len * sizeof(tchar) + dentry->full_path_nbytes +
+ sizeof(tchar));
+ memcpy(output_path, args->target, len * sizeof(tchar));
memcpy(output_path + len, dentry->full_path, dentry->full_path_nbytes);
- output_path[len + dentry->full_path_nbytes] = '\0';
- len += dentry->full_path_nbytes;
+ len += dentry->full_path_nbytes / sizeof(tchar);
+ output_path[len] = T('\0');
}
#ifdef __WIN32__
return win32_do_apply_dentry(output_path, len, dentry, args);
{
struct apply_args *args = arg;
size_t len;
- mbchar *output_path;
+ tchar *output_path;
- len = strlen(args->target);
+ len = tstrlen(args->target);
if (dentry_is_root(dentry)) {
- output_path = (mbchar*)args->target;
+ output_path = (tchar*)args->target;
} else {
- output_path = alloca(len + dentry->full_path_nbytes + 1);
- memcpy(output_path, args->target, len);
+ output_path = alloca(len * sizeof(tchar) + dentry->full_path_nbytes +
+ sizeof(tchar));
+ memcpy(output_path, args->target, len * sizeof(tchar));
memcpy(output_path + len, dentry->full_path, dentry->full_path_nbytes);
- output_path[len + dentry->full_path_nbytes] = '\0';
- len += dentry->full_path_nbytes;
+ len += dentry->full_path_nbytes / sizeof(tchar);
+ output_path[len] = T('\0');
}
+
#ifdef __WIN32__
return win32_do_apply_dentry_timestamps(output_path, len, dentry, args);
#else
* @target. */
static int
extract_single_image(WIMStruct *w, int image,
- const mbchar *target, int extract_flags,
+ const tchar *target, int extract_flags,
wimlib_progress_func_t progress_func)
{
int ret;
if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
args.vol = ntfs_mount(target, 0);
if (!args.vol) {
- ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s'", target);
+ ERROR_WITH_ERRNO("Failed to mount NTFS volume `%"TS"'",
+ target);
return WIMLIB_ERR_NTFS_3G;
}
ops = &ntfs_apply_operations;
/* Unmount the NTFS volume */
if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
if (ntfs_umount(args.vol, FALSE) != 0) {
- ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%s'", args.target);
+ ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%"TS"'",
+ args.target);
if (ret == 0)
ret = WIMLIB_ERR_NTFS_3G;
}
return ret;
}
+static const tchar *filename_forbidden_chars =
+T(
+#ifdef __WIN32__
+"<>:\"/\\|?*"
+#else
+"/"
+#endif
+);
+
+/* This function checks if it is okay to use a WIM image's name as a directory
+ * name. */
+static bool
+image_name_ok_as_dir(const tchar *image_name)
+{
+ return image_name && *image_name &&
+ !tstrpbrk(image_name, filename_forbidden_chars);
+}
/* Extracts all images from the WIM to the directory @target, with the images
* placed in subdirectories named by their image names. */
static int
-extract_all_images(WIMStruct *w, const mbchar *target,
+extract_all_images(WIMStruct *w,
+ const tchar *target,
int extract_flags,
wimlib_progress_func_t progress_func)
{
size_t image_name_max_len = max(xml_get_max_image_name_len(w), 20);
- size_t output_path_len = strlen(target);
- mbchar buf[output_path_len + 1 + image_name_max_len + 1];
+ size_t output_path_len = tstrlen(target);
+ tchar buf[output_path_len + 1 + image_name_max_len + 1];
int ret;
int image;
- const utf8char *image_name;
+ const tchar *image_name;
ret = extract_directory(NULL, target, true);
- if (ret != 0)
+ if (ret)
return ret;
- memcpy(buf, target, output_path_len);
- buf[output_path_len] = '/';
+ tmemcpy(buf, target, output_path_len);
+ buf[output_path_len] = T('/');
for (image = 1; image <= w->hdr.image_count; image++) {
image_name = wimlib_get_image_name(w, image);
- if (image_name && *image_name &&
- (wimlib_mbs_is_utf8 || !utf8_str_contains_nonascii_chars(image_name))
- && strchr(image_name, '/') == NULL)
- {
- strcpy(buf + output_path_len + 1, image_name);
+ if (image_name_ok_as_dir(image_name)) {
+ tstrcpy(buf + output_path_len + 1, image_name);
} else {
- /* Image name is empty, or may not be representable in
- * the current locale, or contains path separators. Use
- * the image number instead. */
- sprintf(buf + output_path_len + 1, "%d", image);
+ /* Image name is empty, or contains forbidden
+ * characters. */
+ tsprintf(buf + output_path_len + 1, T("%d"), image);
}
ret = extract_single_image(w, image, buf, extract_flags,
progress_func);
/* Extracts a single image or all images from a WIM file to a directory or NTFS
* volume. */
-WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
- int image,
- const char *target,
- int extract_flags,
- WIMStruct **additional_swms,
- unsigned num_additional_swms,
- wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_extract_image(WIMStruct *w,
+ int image,
+ const tchar *target,
+ int extract_flags,
+ WIMStruct **additional_swms,
+ unsigned num_additional_swms,
+ wimlib_progress_func_t progress_func)
{
struct wim_lookup_table *joined_tab, *w_tab_save;
int ret;