Improve handling of invalid filenames
[wimlib] / src / unix_apply.c
index 0b96055d8142afe916d35eb9eaab6cc75f2e615e..b1d914827beec90c9ac3f6e69067cd19161eaaa9 100644 (file)
  * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
  * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
-#include "config.h"
+#ifndef __WIN32__
 
 
-#ifdef HAVE_UTIME_H
-#  include <utime.h>
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
 #endif
 #endif
+
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <unistd.h>
+#ifdef HAVE_UTIME_H
+#  include <utime.h>
+#endif
 
 
-#include "timestamp.h"
-#include "wimlib_internal.h"
-#include "lookup_table.h"
+#include "wimlib/apply.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/reparse.h"
+#include "wimlib/timestamp.h"
 
 /* Returns the number of components of @path.  */
 static unsigned
 
 /* Returns the number of components of @path.  */
 static unsigned
@@ -89,8 +95,13 @@ unix_extract_regular_file_linked(struct wim_dentry *dentry,
                char *p;
                const char *p2;
                size_t i;
                char *p;
                const char *p2;
                size_t i;
+               const struct wim_dentry *d;
 
 
-               num_path_components = get_num_path_components(dentry->_full_path) - 1;
+               num_path_components = 0;
+               for (d = dentry; d != args->extract_root; d = d->parent)
+                       num_path_components++;
+               wimlib_assert(num_path_components > 0);
+               num_path_components--;
                num_output_dir_path_components = get_num_path_components(args->target);
 
                if (args->extract_flags & WIMLIB_EXTRACT_FLAG_MULTI_IMAGE) {
                num_output_dir_path_components = get_num_path_components(args->target);
 
                if (args->extract_flags & WIMLIB_EXTRACT_FLAG_MULTI_IMAGE) {
@@ -333,7 +344,7 @@ unix_extract_symlink(struct wim_dentry *dentry,
 
        if (ret <= 0) {
                ERROR("Could not read the symbolic link from dentry `%s'",
 
        if (ret <= 0) {
                ERROR("Could not read the symbolic link from dentry `%s'",
-                     dentry->_full_path);
+                     dentry_full_path(dentry));
                return WIMLIB_ERR_INVALID_DENTRY;
        }
        target[args->target_realpath_len + ret] = '\0';
                return WIMLIB_ERR_INVALID_DENTRY;
        }
        target[args->target_realpath_len + ret] = '\0';
@@ -374,37 +385,33 @@ unix_extract_symlink(struct wim_dentry *dentry,
 }
 
 static int
 }
 
 static int
-unix_extract_directory(struct wim_dentry *dentry, const tchar *output_path,
+unix_extract_directory(struct wim_dentry *dentry, const char *output_path,
                       int extract_flags)
 {
        int ret;
        struct stat stbuf;
 
                       int extract_flags)
 {
        int ret;
        struct stat stbuf;
 
-       ret = tstat(output_path, &stbuf);
+       ret = stat(output_path, &stbuf);
        if (ret == 0) {
                if (S_ISDIR(stbuf.st_mode)) {
        if (ret == 0) {
                if (S_ISDIR(stbuf.st_mode)) {
-                       /*if (!is_root)*/
-                               /*WARNING("`%s' already exists", output_path);*/
                        goto dir_exists;
                } else {
                        goto dir_exists;
                } else {
-                       ERROR("`%"TS"' is not a directory", output_path);
+                       ERROR("\"%s\" is not a directory", output_path);
                        return WIMLIB_ERR_MKDIR;
                }
        } else {
                if (errno != ENOENT) {
                        return WIMLIB_ERR_MKDIR;
                }
        } else {
                if (errno != ENOENT) {
-                       ERROR_WITH_ERRNO("Failed to stat `%"TS"'", output_path);
+                       ERROR_WITH_ERRNO("Failed to stat \"%s\"", output_path);
                        return WIMLIB_ERR_STAT;
                }
        }
 
                        return WIMLIB_ERR_STAT;
                }
        }
 
-       if (tmkdir(output_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
-       {
-               ERROR_WITH_ERRNO("Cannot create directory `%"TS"'", output_path);
+       if (mkdir(output_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
+               ERROR_WITH_ERRNO("Cannot create directory \"%s\"", output_path);
                return WIMLIB_ERR_MKDIR;
        }
 dir_exists:
        ret = 0;
                return WIMLIB_ERR_MKDIR;
        }
 dir_exists:
        ret = 0;
-#ifndef __WIN32__
        if (extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) {
                struct wimlib_unix_data unix_data;
                ret = inode_get_unix_data(dentry->d_inode, &unix_data, NULL);
        if (extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) {
                struct wimlib_unix_data unix_data;
                ret = inode_get_unix_data(dentry->d_inode, &unix_data, NULL);
@@ -416,7 +423,6 @@ dir_exists:
                        ret = dir_apply_unix_data(output_path, &unix_data,
                                                  extract_flags);
        }
                        ret = dir_apply_unix_data(output_path, &unix_data,
                                                  extract_flags);
        }
-#endif
        return ret;
 }
 
        return ret;
 }
 
@@ -493,3 +499,5 @@ unix_do_apply_dentry_timestamps(const char *output_path,
        }
        return 0;
 }
        }
        return 0;
 }
+
+#endif /* !__WIN32__ */