_archive_write_disk_close(struct archive *_a)
{
	struct archive_write_disk *a = (struct archive_write_disk *)_a;
	struct fixup_entry *next, *p;
	struct stat st;
	char *c;
	int fd, ret, openflags;

	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
	    "archive_write_disk_close");
	ret = _archive_write_disk_finish_entry(&a->archive);

	/* Sort dir list so directories are fixed up in depth-first order. */
	p = sort_dir_list(a->fixup_list);

	while (p != NULL) {
		fd = -1;
		a->pst = NULL; /* Mark stat cache as out-of-date. */

		/* We must strip trailing slashes from the path to avoid
		   dereferencing symbolic links to directories */
		c = p->name;
		while (*c != '\0')
			c++;
		while (c != p->name && *(c - 1) == '/') {
			c--;
			*c = '\0';
		}

		if (p->fixup == 0)
			goto skip_fixup_entry;
		else {
			/*
			 * We need to verify if the type of the file
			 * we are going to open matches the file type
			 * of the fixup entry.
			 */
			openflags = O_BINARY | O_NOFOLLOW | O_RDONLY
			    | O_CLOEXEC;
#if defined(O_DIRECTORY)
			if (p->filetype == AE_IFDIR)
				openflags |= O_DIRECTORY;
#endif
			fd = open(p->name, openflags);

#if defined(O_DIRECTORY)
			/*
			 * If we support O_DIRECTORY and open was
			 * successful we can skip the file type check
			 * for directories. For other file types
			 * we need to verify via fstat() or lstat()
			 */
			if (fd == -1 || p->filetype != AE_IFDIR) {
#if HAVE_FSTAT
				if (fd > 0 && (
				    fstat(fd, &st) != 0 ||
				    la_verify_filetype(st.st_mode,
				    p->filetype) == 0)) {
					goto skip_fixup_entry;
				} else
#endif
				if (lstat(p->name, &st) != 0 ||
				    la_verify_filetype(st.st_mode,
				    p->filetype) == 0) {
					goto skip_fixup_entry;
				}
			}
#else
#if HAVE_FSTAT
			if (fd > 0 && (
			    fstat(fd, &st) != 0 ||
			    la_verify_filetype(st.st_mode,
			    p->filetype) == 0)) {
				goto skip_fixup_entry;
			} else
#endif
			if (lstat(p->name, &st) != 0 ||
			    la_verify_filetype(st.st_mode,
			    p->filetype) == 0) {
				goto skip_fixup_entry;
			}
#endif
		}
		if (p->fixup & TODO_TIMES) {
			set_times(a, fd, p->mode, p->name,
			    p->atime, p->atime_nanos,
			    p->birthtime, p->birthtime_nanos,
			    p->mtime, p->mtime_nanos,
			    p->ctime, p->ctime_nanos);
		}
		if (p->fixup & TODO_MODE_BASE) {
#ifdef HAVE_FCHMOD
			if (fd >= 0)
				fchmod(fd, p->mode & 07777);
			else
#endif
#ifdef HAVE_LCHMOD
			lchmod(p->name, p->mode & 07777);
#else
			chmod(p->name, p->mode & 07777);
#endif
		}
		if (p->fixup & TODO_ACLS)
			archive_write_disk_set_acls(&a->archive, fd,
			    p->name, &p->acl, p->mode);
		if (p->fixup & TODO_FFLAGS)
			set_fflags_platform(a, fd, p->name,
			    p->mode, p->fflags_set, 0);
		if (p->fixup & TODO_MAC_METADATA)
			set_mac_metadata(a, p->name, p->mac_metadata,
					 p->mac_metadata_size);
skip_fixup_entry:
		next = p->next;
		archive_acl_clear(&p->acl);
		free(p->mac_metadata);
		free(p->name);
		if (fd >= 0)
			close(fd);
		free(p);
		p = next;
	}
	a->fixup_list = NULL;
	return (ret);
}
_archive_write_disk_close(struct archive *_a)
{
	struct archive_write_disk *a = (struct archive_write_disk *)_a;
	struct fixup_entry *next, *p;
	struct stat st;
	char *c;
	int fd, ret, openflags;

	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
	    "archive_write_disk_close");
	ret = _archive_write_disk_finish_entry(&a->archive);

	 
	p = sort_dir_list(a->fixup_list);

	while (p != NULL) {
		fd = -1;
		a->pst = NULL;  

		 
		c = p->name;
		while (*c != '\0')
			c++;
		while (c != p->name && *(c - 1) == '/') {
			c--;
			*c = '\0';
		}

		if (p->fixup == 0)
			goto skip_fixup_entry;
		else {
			 
			openflags = O_BINARY | O_NOFOLLOW | O_RDONLY
			    | O_CLOEXEC;
#if defined(O_DIRECTORY)
			if (p->filetype == AE_IFDIR)
				openflags |= O_DIRECTORY;
#endif
			fd = open(p->name, openflags);

#if defined(O_DIRECTORY)
			 
			if (fd == -1 || p->filetype != AE_IFDIR) {
#if HAVE_FSTAT
				if (fd > 0 && (
				    fstat(fd, &st) != 0 ||
				    la_verify_filetype(st.st_mode,
				    p->filetype) == 0)) {
					goto skip_fixup_entry;
				} else
#endif
				if (lstat(p->name, &st) != 0 ||
				    la_verify_filetype(st.st_mode,
				    p->filetype) == 0) {
					goto skip_fixup_entry;
				}
			}
#else
#if HAVE_FSTAT
			if (fd > 0 && (
			    fstat(fd, &st) != 0 ||
			    la_verify_filetype(st.st_mode,
			    p->filetype) == 0)) {
				goto skip_fixup_entry;
			} else
#endif
			if (lstat(p->name, &st) != 0 ||
			    la_verify_filetype(st.st_mode,
			    p->filetype) == 0) {
				goto skip_fixup_entry;
			}
#endif
		}
		if (p->fixup & TODO_TIMES) {
			set_times(a, fd, p->mode, p->name,
			    p->atime, p->atime_nanos,
			    p->birthtime, p->birthtime_nanos,
			    p->mtime, p->mtime_nanos,
			    p->ctime, p->ctime_nanos);
		}
		if (p->fixup & TODO_MODE_BASE) {
#ifdef HAVE_FCHMOD
			if (fd >= 0)
				fchmod(fd, p->mode & 07777);
			else
#endif
#ifdef HAVE_LCHMOD
			lchmod(p->name, p->mode & 07777);
#else
			chmod(p->name, p->mode & 07777);
#endif
		}
		if (p->fixup & TODO_ACLS)
			archive_write_disk_set_acls(&a->archive, fd,
			    p->name, &p->acl, p->mode);
		if (p->fixup & TODO_FFLAGS)
			set_fflags_platform(a, fd, p->name,
			    p->mode, p->fflags_set, 0);
		if (p->fixup & TODO_MAC_METADATA)
			set_mac_metadata(a, p->name, p->mac_metadata,
					 p->mac_metadata_size);
skip_fixup_entry:
		next = p->next;
		archive_acl_clear(&p->acl);
		free(p->mac_metadata);
		free(p->name);
		if (fd >= 0)
			close(fd);
		free(p);
		p = next;
	}
	a->fixup_list = NULL;
	return (ret);
}