return (ARCHIVE_OK);
archive_string_init(&tempfile);
- if (__archive_get_tempdir(&tempfile) != ARCHIVE_OK) {
- ret = ARCHIVE_WARN;
- goto cleanup;
- }
- 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");
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
/*
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,
static int
la_mktemp(struct archive_write_disk *a)
{
+ struct archive_string *tmp = &a->_tmpname_data;
int oerrno, fd;
mode_t mode;
- archive_string_empty(&a->_tmpname_data);
- archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name);
- a->tmpname = a->_tmpname_data.s;
+ archive_strcpy(tmp, a->name);
+ archive_string_dirname(tmp);
+ archive_strcat(tmp, "/tar.XXXXXXXX");
+ a->tmpname = tmp->s;
fd = __archive_mkstemp(a->tmpname);
if (fd == -1)
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");
* silly dance of writing the data to disk just so that
* copyfile() can read it back in again. */
archive_string_init(&tmp);
- archive_strcpy(&tmp, "tar.mmd.XXXXXX");
- fd = mkstemp(tmp.s);
+ archive_strcpy(&tmp, pathname);
+ archive_string_dirname(&tmp);
+ archive_strcat(&tmp, "/tar.XXXXXXXX");
+ fd = __archive_mkstemp(tmp.s);
if (fd < 0) {
archive_set_error(&a->archive, errno,
archive_string_free(&s);
}
+static void
+test_archive_string_dirname(void)
+{
+ static struct pair { const char *str, *exp; } pairs[] = {
+ { "", "." },
+ { "/", "/" },
+ { "//", "/" },
+ { "///", "/" },
+ { "./", "." },
+ { ".", "." },
+ { "..", "." },
+ { "foo", "." },
+ { "foo/", "." },
+ { "foo//", "." },
+ { "foo/bar", "foo" },
+ { "foo/bar/", "foo" },
+ { "foo/bar//", "foo" },
+ { "foo//bar", "foo" },
+ { "foo//bar/", "foo" },
+ { "foo//bar//", "foo" },
+ { "/foo", "/" },
+ { "//foo", "/" },
+ { "//foo/", "/" },
+ { "//foo//", "/" },
+ { 0 },
+ };
+ struct pair *pair;
+ struct archive_string s;
+
+ archive_string_init(&s);
+ for (pair = pairs; pair->str; pair++) {
+ archive_strcpy(&s, pair->str);
+ archive_string_dirname(&s);
+ assertEqualString(pair->exp, s.s);
+ }
+}
+
DEFINE_TEST(test_archive_string)
{
test_archive_string_ensure();
test_archive_string_concat();
test_archive_string_copy();
test_archive_string_sprintf();
+ test_archive_string_dirname();
}
static const char *strings[] =