Only the most important changes more recent than version 0.6 are noted here.
+Version 1.0.1:
+ Fixed problem when exporting images from XPRESS to LZX compressed WIM or
+ vice versa
+
Version 1.0.0:
Enough changes to call it version 1.0.0!
WIMLIB
-This is wimlib version 1.0.0 (September 2012). wimlib can be used to read,
+This is wimlib version 1.0.1 (September 2012). wimlib can be used to read,
write, and mount files in the Windows Imaging Format (WIM files). These
files are normally created by using the `imagex.exe' utility on Windows,
but this library provides a free implementation of imagex for UNIX-based
It has been tested on x86 (32-bit) GNU/Linux occasionally.
-I have tested a previous version of wimlib on FreeBSD and it worked, but this is
-not well tested, especially with the more recent versions of this software.
+wimlib may work on FreeBSD. However, this not well tested. If you do not have
+libntfs-3g 2011-4-12 or later available, you may have to configure with
+--without-ntfs-3g. Also, GNU coreutils is needed to run the test suite. Before
+mounting a WIM you need to load the POSIX message queue module (run `kldload
+mqueuefs'). There is no `fusermount' command on FreeBSD, so you must use
+`umount' rather than `imagex unmount' to unmount a mounted WIM, but this won't
+allow you to commit changes to a read-write mounted WIM...
wimlib should work on big endian machines but it has not been tested.
- Fix bugs
- Add more test cases
- Implement LZX block splitting to improve compression ratio
+- Improve performance of large directories in mounted WIMs.
/* Define to 1 if using the xattr interface to WIM alternate data streams */
#undef ENABLE_XATTR
+/* Define to 1 if you have the <alloca.h> header file. */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#undef HAVE_BYTESWAP_H
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the <endian.h> header file. */
+#undef HAVE_ENDIAN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
/* Define if you have the iconv() function and it works. */
#undef HAVE_ICONV
/* Define to 1 if you have the `ntfs-3g' library (-lntfs-3g). */
#undef HAVE_LIBNTFS_3G
+/* Define to 1 if you have the <machine/endian.h> header file. */
+#undef HAVE_MACHINE_ENDIAN_H
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
+/* Define to 1 if you have the <sys/byteorder.h> header file. */
+#undef HAVE_SYS_BYTEORDER_H
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#undef HAVE_SYS_ENDIAN_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the `utimensat' function. */
+#undef HAVE_UTIMENSAT
+
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST
-AC_INIT([wimlib], [1.0.0], [ebiggers3@gmail.com])
+AC_INIT([wimlib], [1.0.1], [ebiggers3@gmail.com])
AC_CONFIG_SRCDIR([src/wim.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_PROG_CC
AM_PROG_CC_C_O
+AC_CHECK_FUNCS([utimensat])
+AC_CHECK_HEADERS([endian.h byteswap.h sys/byteorder.h sys/endian.h \
+ sys/param.h machine/endian.h alloca.h stdlib.h stdarg.h \
+ errno.h])
+
AM_ICONV
if test "x$am_cv_func_iconv" != "xyes"; then
libraries.])
fi
+
AC_ARG_WITH(pkgconfigdir,
[ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@],
[pkgconfigdir=$withval],
#include "config.h"
#include <inttypes.h>
-/* Changes the endianness of a 32-bit value. */
+#ifdef WORDS_BIGENDIAN
+
+#ifndef bswap16
+static inline uint16_t bswap16(uint16_t n)
+{
+ return (n << 8) | (n >> 8);
+}
+#endif
+
+#ifndef bswap32
static inline uint32_t bswap32(uint32_t n)
{
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
(n >> 24);
#endif
}
-
-#ifdef WORDS_BIGENDIAN
-
-/* Big endian. */
-
-/* Changes the endianness of a 16-bit value. */
-static inline uint16_t bswap16(uint16_t n)
-{
- return (n << 8) | (n >> 8);
-}
+#endif
-/* Changes the endianness of a 64-bit value. */
+#ifndef bswap64
static inline uint64_t bswap64(uint64_t n)
{
#ifdef __GNUC__
((n & 0xff000000000000) >> 40) | (n >> 56);
#endif
}
+#endif
/* Not in place */
#define to_le16(n) bswap16(n)
#define to_le32(n) bswap32(n)
#define to_le64(n) bswap64(n)
-#define to_be16(n) (n)
-#define to_be32(n) (n)
-#define to_be64(n) (n)
+#ifndef _NTFS_ENDIANS_H
#define le16_to_cpu(n) bswap16(n)
#define le32_to_cpu(n) bswap32(n)
#define le64_to_cpu(n) bswap64(n)
+#endif
/* In place */
#define TO_LE16(n) ((n) = to_le16(n))
#define to_le32(n) (n)
#define to_le64(n) (n)
+#ifndef _NTFS_ENDIANS_H
#define le16_to_cpu(n) (n)
#define le32_to_cpu(n) (n)
#define le64_to_cpu(n) (n)
-
-#define to_be16(n) (bswap16(n))
-#define to_be32(n) (bswap32(n))
-#define to_be64(n) (bswap64(n))
+#endif
/* In place */
#define TO_LE16(n)
#include <fuse.h>
#include <ftw.h>
#include <mqueue.h>
+#include <utime.h>
#ifdef ENABLE_XATTR
#include <attr/xattr.h>
* commands */
static char *unmount_to_daemon_mq_name;
static char *daemon_to_unmount_mq_name;
-static int unmount_to_daemon_mq;
-static int daemon_to_unmount_mq;
+static mqd_t unmount_to_daemon_mq;
+static mqd_t daemon_to_unmount_mq;
/* Simple function that returns the concatenation of 4 strings. */
static char *strcat_dup(const char *s1, const char *s2, const char *s3,
unmount_to_daemon_mq = mq_open(unmount_to_daemon_mq_name, flags,
0700, NULL);
- if (unmount_to_daemon_mq == -1) {
+ if (unmount_to_daemon_mq == (mqd_t)-1) {
ERROR_WITH_ERRNO("mq_open()");
ret = WIMLIB_ERR_MQUEUE;
goto err2;
daemon_to_unmount_mq = mq_open(daemon_to_unmount_mq_name, flags,
0700, NULL);
- if (daemon_to_unmount_mq == -1) {
+ if (daemon_to_unmount_mq == (mqd_t)-1) {
ERROR_WITH_ERRNO("mq_open()");
ret = WIMLIB_ERR_MQUEUE;
goto err3;
struct dentry *cur = dentry;
do {
if (times[0])
- dentry->creation_time = times[0];
+ cur->creation_time = times[0];
if (times[1])
- dentry->last_write_time = times[1];
+ cur->last_write_time = times[1];
if (times[2])
- dentry->last_access_time = times[2];
+ cur->last_access_time = times[2];
} while ((cur = container_of(dentry->link_group_list.next,
struct dentry,
link_group_list)) != dentry);
return 0;
}
+#ifdef HAVE_UTIMENSAT
/*
* Change the timestamp on a file dentry.
*
dentry_link_group_set_times(dentry, times);
return 0;
}
+#else
+static int wimfs_utime(const char *path, struct utimbuf *times)
+{
+ struct dentry *dentry = get_dentry(w, path);
+ if (!dentry)
+ return -ENOENT;
+ u64 wim_times[3];
+ wim_times[0] = 0;
+ wim_times[1] = unix_timestamp_to_wim(times->modtime);
+ wim_times[2] = unix_timestamp_to_wim(times->actime);
+ dentry_link_group_set_times(dentry, wim_times);
+ return 0;
+}
+#endif
/* Writes to a file in the WIM filesystem.
* It may be an alternate data stream, but here we don't even notice because we
.symlink = wimfs_symlink,
.truncate = wimfs_truncate,
.unlink = wimfs_unlink,
+#ifdef HAVE_UTIMENSAT
.utimens = wimfs_utimens,
+#else
+ .utime = wimfs_utime,
+#endif
.write = wimfs_write,
};
*/
mount_dir = dir;
+
pid = fork();
if (pid == -1) {
ERROR_WITH_ERRNO("Failed to fork()");
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
+
#include "config.h"
+
+#ifdef WITH_NTFS_3G
+#include <ntfs-3g/endians.h>
+#include <ntfs-3g/types.h>
+#endif
+
#include "wimlib_internal.h"
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
+
#include "config.h"
+
+#ifdef WITH_NTFS_3G
+#include <ntfs-3g/endians.h>
+#include <ntfs-3g/types.h>
+#endif
+
#include "wimlib_internal.h"
if (ret != 0)
return ret;
} else {
+ #ifdef ENODATA
if (errno != ENODATA) {
ERROR_WITH_ERRNO("Error getting DOS name "
"of `%s'", path);
return WIMLIB_ERR_NTFS_3G;
}
+ #endif
}
}
* wimlib; if not, see http://www.gnu.org/licenses/.
*/
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef WITH_NTFS_3G
+#include <ntfs-3g/attrib.h>
+#include <ntfs-3g/inode.h>
+#include <ntfs-3g/dir.h>
+#endif
+
#include "wimlib_internal.h"
#include "lookup_table.h"
#include "io.h"
#include "xpress.h"
#include "sha1.h"
#include "dentry.h"
-#include "config.h"
#include <unistd.h>
#include <errno.h>
+#ifdef HAVE_ALLOCA_H
#include <alloca.h>
-
-#ifdef WITH_NTFS_3G
-#include <ntfs-3g/attrib.h>
-#include <ntfs-3g/inode.h>
-#include <ntfs-3g/dir.h>
#endif
+
/*
* Reads all or part of a compressed resource into an in-memory buffer.
*
# define HOT
#endif /* __GNUC__ */
+#ifndef _NTFS_TYPES_H
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
+#endif
typedef unsigned uint;
+#ifndef min
#define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
(__a < __b) ? __a : __b; })
+#endif
+
+#ifndef max
#define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
(__a > __b) ? __a : __b; })
+#endif
+
+#ifndef swap
#define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
+#endif
#define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "io.h"
-#include "lookup_table.h"
-#include "xml.h"
+#include "config.h"
#include <stdlib.h>
+#include <stdarg.h>
#ifdef WITH_NTFS_3G
#include <ntfs-3g/volume.h>
#endif
+#include "wimlib_internal.h"
+#include "io.h"
+#include "lookup_table.h"
+#include "xml.h"
+
+
static int print_metadata(WIMStruct *w)
{
print_security_data(wim_security_data(w));
#define WIM_HDR_FLAG_COMPRESS_LZX 0x00040000
#ifdef WITH_NTFS_3G
-typedef struct _ntfs_volume ntfs_volume;
+struct _ntfs_volume;
#endif
/* Structure for security data. Each image in the WIM file has its own security
bool write_metadata;
};
#ifdef WITH_NTFS_3G
- ntfs_volume *ntfs_vol;
+ struct _ntfs_volume *ntfs_vol;
#endif
/* The currently selected image, indexed starting at 1. If not 0,