+#ifdef ENABLE_XATTR
+/* Write an alternate data stream through the XATTR interface */
+static int wimfs_setxattr(const char *path, const char *name,
+ const char *value, size_t size, int flags)
+{
+ struct ads_entry *existing_ads_entry;
+ struct ads_entry *new_ads_entry;
+ struct lookup_table_entry *existing_lte;
+ struct lookup_table_entry *lte;
+ struct inode *inode;
+ u8 value_hash[SHA1_HASH_SIZE];
+ u16 ads_idx;
+
+ if (!(mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR))
+ return -ENOTSUP;
+
+ if (strlen(name) < 5 || memcmp(name, "user.", 5) != 0)
+ return -ENOATTR;
+ name += 5;
+
+ inode = wim_pathname_to_inode(w, path);
+ if (!inode)
+ return -ENOENT;
+
+ existing_ads_entry = inode_get_ads_entry(inode, name, &ads_idx);
+ if (existing_ads_entry) {
+ if (flags & XATTR_CREATE)
+ return -EEXIST;
+ inode_remove_ads(inode, ads_idx, w->lookup_table);
+ } else {
+ if (flags & XATTR_REPLACE)
+ return -ENOATTR;
+ }
+ new_ads_entry = inode_add_ads(inode, name);
+ if (!new_ads_entry)
+ return -ENOMEM;
+
+ sha1_buffer((const u8*)value, size, value_hash);
+
+ existing_lte = __lookup_resource(w->lookup_table, value_hash);
+
+ if (existing_lte) {
+ lte = existing_lte;
+ lte->refcnt++;
+ } else {
+ u8 *value_copy;
+ lte = new_lookup_table_entry();
+ if (!lte)
+ return -ENOMEM;
+ value_copy = MALLOC(size);
+ if (!value_copy) {
+ FREE(lte);
+ return -ENOMEM;
+ }
+ memcpy(value_copy, value, size);
+ lte->resource_location = RESOURCE_IN_ATTACHED_BUFFER;
+ lte->attached_buffer = value_copy;
+ lte->resource_entry.original_size = size;
+ lte->resource_entry.size = size;
+ lte->resource_entry.flags = 0;
+ copy_hash(lte->hash, value_hash);
+ lookup_table_insert(w->lookup_table, lte);
+ }
+ new_ads_entry->lte = lte;
+ return 0;
+}
+#endif
+