]> wimlib.net Git - wimlib/blobdiff - src/util.c
Code to handle some weird siutations and bad WIMs
[wimlib] / src / util.c
index bdd0a294dc7655ab28a571e2e92f47928d9bd6fd..985d11b875c90352233d73ecbd9f1bdcc918bdd0 100644 (file)
@@ -25,6 +25,8 @@
 #include "wimlib_internal.h"
 #include "endianness.h"
 #include "sha1.h"
+#include "timestamp.h"
+#include <sys/time.h>
 
 
 #include <iconv.h>
@@ -35,8 +37,8 @@
 #include <unistd.h>
 #include <errno.h>
 
-/* True if WIMLIB is to print an informational message when an error occurs.
- * This can be turned off by calling wimlib_set_error_messages(false). */
+/* True if wimlib is to print an informational message when an error occurs.
+ * This can be turned off by calling wimlib_set_print_errors(false). */
 #ifdef ENABLE_ERROR_MESSAGES
 #include <stdarg.h>
 bool __wimlib_print_errors = false;
@@ -49,8 +51,25 @@ void wimlib_error(const char *format, ...)
 
                va_start(va, format);
                errno_save = errno;
-               fputs("ERROR: ", stderr);
+               fputs("[ERROR] ", stderr);
                vfprintf(stderr, format, va);
+               putc('\n', stderr);
+               errno = errno_save;
+               va_end(va);
+       }
+}
+
+void wimlib_error_with_errno(const char *format, ...)
+{
+       if (__wimlib_print_errors) {
+               va_list va;
+               int errno_save;
+
+               va_start(va, format);
+               errno_save = errno;
+               fputs("[ERROR] ", stderr);
+               vfprintf(stderr, format, va);
+               fprintf(stderr, ": %s\n", strerror(errno_save));
                errno = errno_save;
                va_end(va);
        }
@@ -64,8 +83,9 @@ void wimlib_warning(const char *format, ...)
 
                va_start(va, format);
                errno_save = errno;
-               fputs("WARNING: ", stderr);
+               fputs("[WARNING] ", stderr);
                vfprintf(stderr, format, va);
+               putc('\n', stderr);
                errno = errno_save;
                va_end(va);
        }
@@ -121,8 +141,12 @@ static const char *error_strings[] = {
                = "Tried to select an image that does not exist in the WIM",
        [WIMLIB_ERR_INVALID_INTEGRITY_TABLE] 
                = "The WIM's integrity table is invalid",
+       [WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY]
+               = "An entry in the WIM's lookup table is invalid",
        [WIMLIB_ERR_INVALID_PARAM] 
                = "An invalid parameter was given",
+       [WIMLIB_ERR_INVALID_RESOURCE_HASH]
+               = "The SHA1 message digest of a WIM resource did not match the expected value",
        [WIMLIB_ERR_INVALID_RESOURCE_SIZE] 
                = "A resource entry in the WIM is invalid",
        [WIMLIB_ERR_LINK] 
@@ -141,14 +165,22 @@ static const char *error_strings[] = {
                        "identify a WIM file",
        [WIMLIB_ERR_NO_FILENAME] 
                = "The WIM is not identified with a filename",
+       [WIMLIB_ERR_NOT_ROOT]
+               = "Root privileges are required for this operation",
+       [WIMLIB_ERR_NTFS_3G]
+               = "NTFS-3g encountered an error (check errno)",
        [WIMLIB_ERR_OPEN] 
                = "Failed to open a file",
        [WIMLIB_ERR_OPENDIR] 
                = "Failed to open a directory",
        [WIMLIB_ERR_READ] 
                = "Could not read data from a file",
+       [WIMLIB_ERR_READLINK]
+               = "Could not read the target of a symbolic link",
        [WIMLIB_ERR_RENAME] 
                = "Could not rename a file",
+       [WIMLIB_ERR_SPECIAL_FILE]
+               = "Encountered a special file that cannot be archived",
        [WIMLIB_ERR_SPLIT_INVALID] 
                = "The WIM is part of an invalid split WIM",
        [WIMLIB_ERR_SPLIT_UNSUPPORTED] 
@@ -178,8 +210,8 @@ WIMLIBAPI const char *wimlib_get_error_string(enum wimlib_error_code code)
 
 
 #ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
-void *(*wimlib_malloc_func)(size_t) = malloc;
-void (*wimlib_free_func)(void *) = free;
+void *(*wimlib_malloc_func) (size_t)        = malloc;
+void  (*wimlib_free_func)   (void *)        = free;
 void *(*wimlib_realloc_func)(void *, size_t) = realloc;
 
 void *wimlib_calloc(size_t nmemb, size_t size)
@@ -221,9 +253,9 @@ WIMLIBAPI int wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
                                 wimlib_realloc_func);
        return 0;
 #else
-       ERROR("Cannot set custom memory allocator functions:\n");
-       ERROR("wimlib was compiled with the "
-                       "--without-custom-memory-allocator flag\n");
+       ERROR("Cannot set custom memory allocator functions:");
+       ERROR("wimlib was compiled with the --without-custom-memory-allocator "
+             "flag");
        return WIMLIB_ERR_UNSUPPORTED;
 #endif
 }
@@ -240,8 +272,8 @@ char *utf16_to_utf8(const char *utf16_str, size_t utf16_len,
        if (cd_utf16_to_utf8 == (iconv_t)(-1)) {
                cd_utf16_to_utf8 = iconv_open("UTF-8", "UTF-16LE");
                if (cd_utf16_to_utf8 == (iconv_t)-1) {
-                       ERROR("Failed to get conversion descriptor for "
-                                       "converting UTF-16LE to UTF-8: %m\n");
+                       ERROR_WITH_ERRNO("Failed to get conversion descriptor "
+                                        "for converting UTF-16LE to UTF-8");
                        return NULL;
                }
        }
@@ -258,8 +290,8 @@ char *utf16_to_utf8(const char *utf16_str, size_t utf16_len,
                        &utf16_bytes_left, &utf8_str, &utf8_bytes_left);
 
        if (num_chars_converted == (size_t)(-1)) {
-               ERROR("Failed to convert UTF-16LE string to UTF-8 string: "
-                               "%m\n");
+               ERROR_WITH_ERRNO("Failed to convert UTF-16LE string to UTF-8 "
+                                "string");
                FREE(orig_utf8_str);
                return NULL;
        }
@@ -275,14 +307,14 @@ static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1);
 
 /* Converts a string in the UTF-8 encoding to a newly allocated string in the
  * UTF-16 encoding.  */
-char *utf8_to_utf16(const char *utf8_str, size_t utf8_len, 
-                                               size_t *utf16_len_ret)
+char *utf8_to_utf16(const char *utf8_str, size_t utf8_len,
+                   size_t *utf16_len_ret)
 {
        if (cd_utf8_to_utf16 == (iconv_t)(-1)) {
                cd_utf8_to_utf16 = iconv_open("UTF-16LE", "UTF-8");
                if (cd_utf8_to_utf16 == (iconv_t)-1) {
-                       ERROR("Failed to get conversion descriptor for "
-                                       "converting UTF-8 to UTF-16LE: %m\n");
+                       ERROR_WITH_ERRNO("Failed to get conversion descriptor "
+                                        "for converting UTF-8 to UTF-16LE");
                        return NULL;
                }
        }
@@ -301,11 +333,8 @@ char *utf8_to_utf16(const char *utf8_str, size_t utf8_len,
                        &utf8_bytes_left, &utf16_str, &utf16_bytes_left);
 
        if (num_chars_converted == (size_t)(-1)) {
-               ERROR("Failed to convert UTF-8 string to UTF-16LE string: "
-                               "%s\n", 
-                               (errno == E2BIG) ? 
-                                       "Not enough room in output buffer" : 
-                                       strerror(errno));
+               ERROR_WITH_ERRNO("Failed to convert UTF-8 string to UTF-16LE "
+                                "string");
                FREE(orig_utf16_str);
                return NULL;
        }
@@ -366,10 +395,8 @@ void randomize_char_array_with_alnum(char p[], size_t n)
 }
 
 /* Fills @n bytes pointer to by @p with random numbers. */
-void randomize_byte_array(void *__p, size_t n)
+void randomize_byte_array(u8 *p, size_t n)
 {
-       u8 *p = __p;
-
        if (!seeded) {
                srand(time(NULL));
                seeded = true;
@@ -411,6 +438,20 @@ const char *path_basename(const char *path)
        return p + 1;
 }
 
+/* 
+ * Returns a pointer to the part of @path following the first colon in the last
+ * path component, or NULL if the last path component does not contain a colon.
+ */
+const char *path_stream_name(const char *path)
+{
+       const char *base = path_basename(path);
+       const char *stream_name = strchr(base, ':');
+       if (!stream_name)
+               return NULL;
+       else
+               return stream_name + 1;
+}
+
 /* 
  * Splits a file path into the part before the first '/', or the entire name if
  * there is no '/', and the part after the first sequence of '/' characters.
@@ -471,3 +512,11 @@ void print_string(const void *string, size_t len)
        }
 }
 
+u64 get_wim_timestamp()
+{
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return timeval_to_wim_timestamp(&tv);
+}
+
+