*/
/*
- * Copyright (C) 2015-2016 Eric Biggers
+ * Copyright (C) 2015-2017 Eric Biggers
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
size_t entries_size;
struct wimlib_unix_data unix_data;
const char *prefix = "user.";
+ static const char capability_name[] = "security.capability";
+ bool generated_capability_xattr = false;
/*
* On Linux, xattrs in the "user" namespace are only permitted on
}
for (int i = 0; i < num_xattrs; i++) {
- int name_len = 1 + rand32() % 64;
int value_len = rand32() % 64;
u8 *p;
- entry->name_len = cpu_to_le16(strlen(prefix) + name_len);
entry->reserved = 0;
entry->value_len = cpu_to_le32(value_len);
- p = mempcpy(entry->name, prefix, strlen(prefix));
- *p++ = 'a' + i;
- for (int j = 1; j < name_len; j++) {
- do {
- *p = rand8();
- } while (*p == '\0');
- p++;
+
+ if (rand32() % 16 == 0 && am_root() &&
+ !generated_capability_xattr) {
+ int name_len = sizeof(capability_name) - 1;
+ entry->name_len = cpu_to_le16(name_len);
+ p = mempcpy(entry->name, capability_name, name_len);
+ generated_capability_xattr = true;
+ } else {
+ int name_len = 1 + rand32() % 64;
+
+ entry->name_len = cpu_to_le16(strlen(prefix) + name_len);
+ p = mempcpy(entry->name, prefix, strlen(prefix));
+ *p++ = 'a' + i;
+ for (int j = 1; j < name_len; j++) {
+ do {
+ *p = rand8();
+ } while (*p == '\0');
+ p++;
+ }
}
for (int j = 0; j < value_len; j++)
*p++ = rand8();
}
}
+static int
+cmp_timestamps(const struct wim_inode *inode1, const struct wim_inode *inode2,
+ int cmp_flags)
+{
+ if (inode1->i_creation_time != inode2->i_creation_time &&
+ !(cmp_flags & WIMLIB_CMP_FLAG_UNIX_MODE)) {
+ ERROR("Creation time of %"TS" differs",
+ inode_any_full_path(inode1));
+ return WIMLIB_ERR_IMAGES_ARE_DIFFERENT;
+ }
+
+ if (inode1->i_last_write_time != inode2->i_last_write_time) {
+ ERROR("Last write time of %"TS" differs",
+ inode_any_full_path(inode1));
+ return WIMLIB_ERR_IMAGES_ARE_DIFFERENT;
+ }
+
+ if (inode1->i_last_access_time != inode2->i_last_access_time) {
+ ERROR("Last access time of %"TS" differs",
+ inode_any_full_path(inode1));
+ return WIMLIB_ERR_IMAGES_ARE_DIFFERENT;
+ }
+
+ return 0;
+}
+
static int
cmp_inodes(const struct wim_inode *inode1, const struct wim_inode *inode2,
const struct wim_image_metadata *imd1,
if (ret)
return ret;
+ /* Compare timestamps */
+ ret = cmp_timestamps(inode1, inode2, cmp_flags);
+ if (ret)
+ return ret;
+
/* Compare standard UNIX metadata */
ret = cmp_unix_metadata(inode1, inode2, cmp_flags);
if (ret)