Backport of upstream commits d0f69b3 + 1c08abc (bsc#1254340)
"Create temporary files in the target directory" adapted to libarchive 3.6.2.
Adds archive_string_dirname() and makes AppleDouble/mac-metadata and
extraction temporary files be created in the target file's directory
instead of the current working directory / TMPDIR.

diff -ru a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c
--- a/libarchive/archive_read_disk_entry_from_file.c
+++ b/libarchive/archive_read_disk_entry_from_file.c
@@ -339,7 +339,7 @@
 	int ret = ARCHIVE_OK;
 	void *buff = NULL;
 	int have_attrs;
-	const char *name, *tempdir;
+	const char *name;
 	struct archive_string tempfile;
 
 	(void)fd; /* UNUSED */
@@ -358,15 +358,11 @@
 	if (have_attrs == 0)
 		return (ARCHIVE_OK);
 
-	tempdir = NULL;
-	if (issetugid() == 0)
-		tempdir = getenv("TMPDIR");
-	if (tempdir == NULL)
-		tempdir = _PATH_TMP;
 	archive_string_init(&tempfile);
-	archive_strcpy(&tempfile, tempdir);
-	archive_strcat(&tempfile, "tar.md.XXXXXX");
-	tempfd = mkstemp(tempfile.s);
+	archive_strcpy(&tempfile, name);
+	archive_string_dirname(&tempfile);
+	archive_strcat(&tempfile, "/tar.XXXXXXXX");
+	tempfd = __archive_mkstemp(tempfile.s);
 	if (tempfd < 0) {
 		archive_set_error(&a->archive, errno,
 		    "Could not open extended attribute file");
diff -ru a/libarchive/archive_string.c b/libarchive/archive_string.c
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -2012,6 +2012,26 @@
 	return (r);
 }
 
+struct archive_string *
+archive_string_dirname(struct archive_string *as)
+{
+	/* strip trailing separators */
+	while (as->length > 1 && as->s[as->length - 1] == '/')
+		as->length--;
+	/* strip final component */
+	while (as->length > 0 && as->s[as->length - 1] != '/')
+		as->length--;
+	/* empty path -> cwd */
+	if (as->length == 0)
+		return (archive_strcat(as, "."));
+	/* strip separator(s) */
+	while (as->length > 1 && as->s[as->length - 1] == '/')
+		as->length--;
+	/* terminate */
+	as->s[as->length] = '\0';
+	return (as);
+}
+
 #if HAVE_ICONV
 
 /*
diff -ru a/libarchive/archive_string.h b/libarchive/archive_string.h
--- a/libarchive/archive_string.h
+++ b/libarchive/archive_string.h
@@ -195,6 +195,10 @@
 void	archive_string_sprintf(struct archive_string *, const char *, ...)
 	    __LA_PRINTF(2, 3);
 
+/* Equivalent to dirname(3) */
+struct archive_string *
+archive_string_dirname(struct archive_string *);
+
 /* Translates from MBS to Unicode. */
 /* Returns non-zero if conversion failed in any way. */
 int archive_wstring_append_from_mbs(struct archive_wstring *dest,
diff -ru a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -415,8 +415,9 @@
 	int oerrno, fd;
 	mode_t mode;
 
-	archive_string_empty(&a->_tmpname_data);
-	archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name);
+	archive_strcpy(&a->_tmpname_data, a->name);
+	archive_string_dirname(&a->_tmpname_data);
+	archive_strcat(&a->_tmpname_data, "/tar.XXXXXXXX");
 	a->tmpname = a->_tmpname_data.s;
 
 	fd = __archive_mkstemp(a->tmpname);
@@ -4251,8 +4252,10 @@
 	int tmpfd;
 
 	archive_string_init(&tmpdatafork);
-	archive_strcpy(&tmpdatafork, "tar.md.XXXXXX");
-	tmpfd = mkstemp(tmpdatafork.s);
+	archive_strcpy(&tmpdatafork, pathname);
+	archive_string_dirname(&tmpdatafork);
+	archive_strcat(&tmpdatafork, "/tar.XXXXXXXX");
+	tmpfd = __archive_mkstemp(tmpdatafork.s);
 	if (tmpfd < 0) {
 		archive_set_error(&a->archive, errno,
 		    "Failed to mkstemp");
@@ -4332,8 +4335,9 @@
 	 * copyfile() can read it back in again. */
 	archive_string_init(&tmp);
 	archive_strcpy(&tmp, pathname);
-	archive_strcat(&tmp, ".XXXXXX");
-	fd = mkstemp(tmp.s);
+	archive_string_dirname(&tmp);
+	archive_strcat(&tmp, "/tar.XXXXXXXX");
+	fd = __archive_mkstemp(tmp.s);
 
 	if (fd < 0) {
 		archive_set_error(&a->archive, errno,
