Example #1
0
/*
 * Note: if text was provided, this just returns that text.  If you
 * really need the text to be rebuilt in a canonical form, set the
 * text, ask for the bitmaps, then set the bitmaps.  (Setting the
 * bitmaps clears any stored text.)  This design is deliberate: if
 * we're editing archives, we don't want to discard flags just because
 * they aren't supported on the current system.  The bitmap<->text
 * conversions are platform-specific (see below).
 */
const char *
archive_entry_fflags_text(struct archive_entry *entry)
{
	const char *f;
	char *p;

	if (archive_mstring_get_mbs(entry->archive,
	    &entry->ae_fflags_text, &f) == 0) {
		if (f != NULL)
			return (f);
	} else if (errno == ENOMEM)
		__archive_errx(1, "No memory");

	if (entry->ae_fflags_set == 0  &&  entry->ae_fflags_clear == 0)
		return (NULL);

	p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear);
	if (p == NULL)
		return (NULL);

	archive_mstring_copy_mbs(&entry->ae_fflags_text, p);
	free(p);
	if (archive_mstring_get_mbs(entry->archive,
	    &entry->ae_fflags_text, &f) == 0)
		return (f);
	if (errno == ENOMEM)
		__archive_errx(1, "No memory");
	return (NULL);
}
Example #2
0
/*
 * Again, mimic gtar:  inclusions are always anchored (have to match
 * the beginning of the path) even though exclusions are not anchored.
 */
static int
match_path_inclusion(struct archive_match *a, struct match *m,
    int mbs, const void *pn)
{
	/* Recursive operation requires only a prefix match. */
	int flag = a->recursive_include ?
		PATHMATCH_NO_ANCHOR_END :
		0;
	int r;

	if (mbs) {
		const char *p;
		r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
		if (r == 0)
			return (archive_pathmatch(p, (const char *)pn, flag));
	} else {
		const wchar_t *p;
		r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
		if (r == 0)
			return (archive_pathmatch_w(p, (const wchar_t *)pn,
				flag));
	}
	if (errno == ENOMEM)
		return (error_nomem(a));
	return (0);
}
Example #3
0
/*
 * Call back functions for archive_rb.
 */
static int
cmp_node_mbs(const struct archive_rb_node *n1,
    const struct archive_rb_node *n2)
{
	struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
	struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
	const char *p1, *p2;

	archive_mstring_get_mbs(NULL, &(f1->pathname), &p1);
	archive_mstring_get_mbs(NULL, &(f2->pathname), &p2);
	if (p1 == NULL)
		return (1);
	if (p2 == NULL)
		return (-1);
	return (strcmp(p1, p2));
}
Example #4
0
const char *
archive_entry_uname(struct archive_entry *entry)
{
	const char *p;
	if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0)
		return (p);
	return (NULL);
}
Example #5
0
const char *
archive_entry_symlink(struct archive_entry *entry)
{
	const char *p;
	if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_mbs(
	    entry->archive, &entry->ae_symlink, &p) == 0)
		return (p);
	return (NULL);
}
Example #6
0
const char *
archive_entry_sourcepath(struct archive_entry *entry)
{
	const char *p;
	if (archive_mstring_get_mbs(
	    entry->archive, &entry->ae_sourcepath, &p) == 0)
		return (p);
	return (NULL);
}
Example #7
0
const char *
archive_entry_uname(struct archive_entry *entry)
{
	const char *p;
	if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0)
		return (p);
	if (errno == ENOMEM)
		__archive_errx(1, "No memory");
	return (NULL);
}
Example #8
0
static int
cmp_key_mbs(const struct archive_rb_node *n, const void *key)
{
	struct match_file *f = (struct match_file *)(uintptr_t)n;
	const char *p;

	archive_mstring_get_mbs(NULL, &(f->pathname), &p);
	if (p == NULL)
		return (-1);
	return (strcmp(p, (const char *)key));
}
Example #9
0
const char *
archive_entry_symlink(struct archive_entry *entry)
{
	const char *p;
	if ((entry->ae_set & AE_SET_SYMLINK) == 0)
		return (NULL);
	if (archive_mstring_get_mbs(
	    entry->archive, &entry->ae_symlink, &p) == 0)
		return (p);
	if (errno == ENOMEM)
		__archive_errx(1, "No memory");
	return (NULL);
}
Example #10
0
static int
match_list_unmatched_inclusions_next(struct archive_match *a,
    struct match_list *list, int mbs, const void **vp)
{
	struct match *m;

	*vp = NULL;
	if (list->unmatched_eof) {
		list->unmatched_eof = 0;
		return (ARCHIVE_EOF);
	}
	if (list->unmatched_next == NULL) {
		if (list->unmatched_count == 0)
			return (ARCHIVE_EOF);
		list->unmatched_next = list->first;
	}

	for (m = list->unmatched_next; m != NULL; m = m->next) {
		int r;

		if (m->matches)
			continue;
		if (mbs) {
			const char *p;
			r = archive_mstring_get_mbs(&(a->archive),
				&(m->pattern), &p);
			if (r < 0 && errno == ENOMEM)
				return (error_nomem(a));
			if (p == NULL)
				p = "";
			*vp = p;
		} else {
			const wchar_t *p;
			r = archive_mstring_get_wcs(&(a->archive),
				&(m->pattern), &p);
			if (r < 0 && errno == ENOMEM)
				return (error_nomem(a));
			if (p == NULL)
				p = L"";
			*vp = p;
		}
		list->unmatched_next = m->next;
		if (list->unmatched_next == NULL)
			/* To return EOF next time. */
			list->unmatched_eof = 1;
		return (ARCHIVE_OK);
	}
	list->unmatched_next = NULL;
	return (ARCHIVE_EOF);
}
Example #11
0
/*
 * Note: if text was provided, this just returns that text.  If you
 * really need the text to be rebuilt in a canonical form, set the
 * text, ask for the bitmaps, then set the bitmaps.  (Setting the
 * bitmaps clears any stored text.)  This design is deliberate: if
 * we're editing archives, we don't want to discard flags just because
 * they aren't supported on the current system.  The bitmap<->text
 * conversions are platform-specific (see below).
 */
const char *
archive_entry_fflags_text(struct archive_entry *entry)
{
	const char *f;
	char *p;

	if (archive_mstring_get_mbs(entry->archive,
	    &entry->ae_fflags_text, &f) == 0 && f != NULL)
		return (f);

	if (entry->ae_fflags_set == 0  &&  entry->ae_fflags_clear == 0)
		return (NULL);

	p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear);
	if (p == NULL)
		return (NULL);

	archive_mstring_copy_mbs(&entry->ae_fflags_text, p);
	free(p);
	if (archive_mstring_get_mbs(entry->archive,
	    &entry->ae_fflags_text, &f) == 0)
		return (f);
	return (NULL);
}
Example #12
0
static int
match_owner_name_mbs(struct archive_match *a, struct match_list *list,
    const char *name)
{
	struct match *m;
	const char *p;

	if (name == NULL || *name == '\0')
		return (0);
	for (m = list->first; m; m = m->next) {
		if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p)
		    < 0 && errno == ENOMEM)
			return (error_nomem(a));
		if (p != NULL && strcmp(p, name) == 0) {
			m->matches++;
			return (1);
		}
	}
	return (0);
}
Example #13
0
/*
 * This is a little odd, but it matches the default behavior of
 * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
 *
 */
static int
match_path_exclusion(struct archive_match *a, struct match *m,
    int mbs, const void *pn)
{
	int flag = PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END;
	int r;

	if (mbs) {
		const char *p;
		r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
		if (r == 0)
			return (archive_pathmatch(p, (const char *)pn, flag));
	} else {
		const wchar_t *p;
		r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
		if (r == 0)
			return (archive_pathmatch_w(p, (const wchar_t *)pn,
				flag));
	}
	if (errno == ENOMEM)
		return (error_nomem(a));
	return (0);
}
Example #14
0
static int
file_open(struct archive *a, void *client_data)
{
	int flags;
	struct write_file_data *mine;
	struct stat st;
#if defined(_WIN32) && !defined(__CYGWIN__)
	wchar_t *fullpath;
#endif
	const wchar_t *wcs;
	const char *mbs;

	mine = (struct write_file_data *)client_data;
	flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC;

	/*
	 * Open the file.
	 */
	mbs = NULL; wcs = NULL;
#if defined(_WIN32) && !defined(__CYGWIN__)
	if (archive_mstring_get_wcs(a, &mine->filename, &wcs) != 0) {
		if (errno == ENOMEM)
			archive_set_error(a, errno, "No memory");
		else {
			archive_mstring_get_mbs(a, &mine->filename, &mbs);
			archive_set_error(a, errno,
			    "Can't convert '%s' to WCS", mbs);
		}
		return (ARCHIVE_FATAL);
	}
	fullpath = __la_win_permissive_name_w(wcs);
	if (fullpath != NULL) {
		mine->fd = _wopen(fullpath, flags, 0666);
		free(fullpath);
	} else
		mine->fd = _wopen(wcs, flags, 0666);
#else
	if (archive_mstring_get_mbs(a, &mine->filename, &mbs) != 0) {
		if (errno == ENOMEM)
			archive_set_error(a, errno, "No memory");
		else {
			archive_mstring_get_wcs(a, &mine->filename, &wcs);
			archive_set_error(a, errno,
			    "Can't convert '%S' to MBS", wcs);
		}
		return (ARCHIVE_FATAL);
	}
	mine->fd = open(mbs, flags, 0666);
	__archive_ensure_cloexec_flag(mine->fd);
#endif
	if (mine->fd < 0) {
		if (mbs != NULL)
			archive_set_error(a, errno, "Failed to open '%s'", mbs);
		else
			archive_set_error(a, errno, "Failed to open '%S'", wcs);
		return (ARCHIVE_FATAL);
	}

	if (fstat(mine->fd, &st) != 0) {
		if (mbs != NULL)
			archive_set_error(a, errno, "Couldn't stat '%s'", mbs);
		else
			archive_set_error(a, errno, "Couldn't stat '%S'", wcs);
		return (ARCHIVE_FATAL);
	}

	/*
	 * Set up default last block handling.
	 */
	if (archive_write_get_bytes_in_last_block(a) < 0) {
		if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
		    S_ISFIFO(st.st_mode))
			/* Pad last block when writing to device or FIFO. */
			archive_write_set_bytes_in_last_block(a, 0);
		else
			/* Don't pad last block otherwise. */
			archive_write_set_bytes_in_last_block(a, 1);
	}

	/*
	 * If the output file is a regular file, don't add it to
	 * itself.  If it's a device file, it's okay to add the device
	 * entry to the output archive.
	 */
	if (S_ISREG(st.st_mode))
		archive_write_set_skip_file(a, st.st_dev, st.st_ino);

	return (ARCHIVE_OK);
}