+ root->d_inode->lte = lte;
+ } else if (S_ISDIR(root_stbuf.st_mode)) { /* Archiving a directory */
+
+ inode->attributes = FILE_ATTRIBUTE_DIRECTORY;
+
+ DIR *dir;
+ struct dirent entry, *result;
+ struct dentry *child;
+
+ dir = opendir(root_disk_path);
+ if (!dir) {
+ ERROR_WITH_ERRNO("Failed to open the directory `%s'",
+ root_disk_path);
+ ret = WIMLIB_ERR_OPEN;
+ goto out;
+ }
+
+ /* Buffer for names of files in directory. */
+ size_t len = strlen(root_disk_path);
+ char name[len + 1 + FILENAME_MAX + 1];
+ memcpy(name, root_disk_path, len);
+ name[len] = '/';
+
+ /* Create a dentry for each entry in the directory on disk, and recurse
+ * to any subdirectories. */
+ while (1) {
+ errno = 0;
+ ret = readdir_r(dir, &entry, &result);
+ if (ret != 0) {
+ ret = WIMLIB_ERR_READ;
+ ERROR_WITH_ERRNO("Error reading the "
+ "directory `%s'",
+ root_disk_path);
+ break;
+ }
+ if (result == NULL)
+ break;
+ if (result->d_name[0] == '.' && (result->d_name[1] == '\0'
+ || (result->d_name[1] == '.' && result->d_name[2] == '\0')))
+ continue;
+ strcpy(name + len + 1, result->d_name);
+ ret = build_dentry_tree(&child, name, lookup_table,
+ NULL, config, add_image_flags,
+ progress_func, NULL);
+ if (ret != 0)
+ break;
+ if (child)
+ dentry_add_child(root, child);
+ }
+ closedir(dir);
+ } else { /* Archiving a symbolic link */
+ inode->attributes = FILE_ATTRIBUTE_REPARSE_POINT;
+ inode->reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK;
+
+ /* The idea here is to call readlink() to get the UNIX target of
+ * the symbolic link, then turn the target into a reparse point
+ * data buffer that contains a relative or absolute symbolic
+ * link (NOT a junction point or *full* path symbolic link with
+ * drive letter).
+ */
+
+ char deref_name_buf[4096];
+ ssize_t deref_name_len;
+
+ deref_name_len = readlink(root_disk_path, deref_name_buf,
+ sizeof(deref_name_buf) - 1);
+ if (deref_name_len >= 0) {
+ deref_name_buf[deref_name_len] = '\0';
+ DEBUG("Read symlink `%s'", deref_name_buf);
+ ret = inode_set_symlink(root->d_inode, deref_name_buf,
+ lookup_table, NULL);
+ if (ret == 0) {
+ /*
+ * Unfortunately, Windows seems to have the
+ * concept of "file" symbolic links as being
+ * different from "directory" symbolic links...
+ * so FILE_ATTRIBUTE_DIRECTORY needs to be set
+ * on the symbolic link if the *target* of the
+ * symbolic link is a directory.
+ */
+ struct stat stbuf;
+ if (stat(root_disk_path, &stbuf) == 0 &&
+ S_ISDIR(stbuf.st_mode))
+ {
+ inode->attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ }
+ }
+ } else {
+ ERROR_WITH_ERRNO("Failed to read target of "
+ "symbolic link `%s'", root_disk_path);
+ ret = WIMLIB_ERR_READLINK;
+ }