called from outside of this module.
SVN-Revision: 3943
libarchive/test/test_write_disk.c \
libarchive/test/test_write_disk_failures.c \
libarchive/test/test_write_disk_hardlink.c \
+ libarchive/test/test_write_disk_lookup.c \
libarchive/test/test_write_disk_perms.c \
libarchive/test/test_write_disk_secure.c \
libarchive/test/test_write_disk_sparse.c \
void * /* private_data */,
__LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
void (* /* cleanup */)(void *));
+__LA_DECL __LA_INT64_T archive_write_disk_gid(struct archive *, const char *, __LA_INT64_T);
+__LA_DECL __LA_INT64_T archive_write_disk_uid(struct archive *, const char *, __LA_INT64_T);
/*
* ARCHIVE_READ_DISK API
time_t, long, time_t, long, time_t, long, time_t, long);
static int set_times_from_entry(struct archive_write_disk *);
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
-static int64_t trivial_lookup_gid(void *, const char *, int64_t);
-static int64_t trivial_lookup_uid(void *, const char *, int64_t);
static ssize_t write_data_block(struct archive_write_disk *,
const char *, size_t);
* TODO: the TODO_SGID condition can be dropped here, can't it?
*/
if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
- a->uid = a->lookup_uid(a->lookup_uid_data,
+ a->uid = archive_write_disk_uid(&a->archive,
archive_entry_uname(a->entry),
archive_entry_uid(a->entry));
}
/* Look up the "real" GID only if we're going to need it. */
/* TODO: the TODO_SUID condition can be dropped here, can't it? */
if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
- a->gid = a->lookup_gid(a->lookup_gid_data,
+ a->gid = archive_write_disk_gid(&a->archive,
archive_entry_gname(a->entry),
archive_entry_gid(a->entry));
}
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+ if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+ (a->cleanup_gid)(a->lookup_gid_data);
+
a->lookup_gid = lookup_gid;
a->cleanup_gid = cleanup_gid;
a->lookup_gid_data = private_data;
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+ if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+ (a->cleanup_uid)(a->lookup_uid_data);
+
a->lookup_uid = lookup_uid;
a->cleanup_uid = cleanup_uid;
a->lookup_uid_data = private_data;
return (ARCHIVE_OK);
}
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+ if (a->lookup_gid)
+ return (a->lookup_gid)(a->lookup_gid_data, name, id);
+ return (id);
+}
+
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+ if (a->lookup_uid)
+ return (a->lookup_uid)(a->lookup_uid_data, name, id);
+ return (id);
+}
/*
* Create a new archive_write_disk object and initialize it with global state.
/* We're ready to write a header immediately. */
a->archive.state = ARCHIVE_STATE_HEADER;
a->archive.vtable = archive_write_disk_vtable();
- a->lookup_uid = trivial_lookup_uid;
- a->lookup_gid = trivial_lookup_gid;
a->start_time = time(NULL);
/* Query and restore the umask. */
umask(a->user_umask = umask(0));
ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
a = (struct archive_write_disk *)_a;
ret = _archive_write_disk_close(&a->archive);
- if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
- (a->cleanup_gid)(a->lookup_gid_data);
- if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
- (a->cleanup_uid)(a->lookup_uid_data);
+ archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+ archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
if (a->entry)
archive_entry_free(a->entry);
archive_string_free(&a->_name_data);
switch (ae_tag) {
case ARCHIVE_ENTRY_ACL_USER:
acl_set_tag_type(acl_entry, ACL_USER);
- ae_uid = a->lookup_uid(a->lookup_uid_data,
+ ae_uid = archive_write_disk_uid(&a->archive,
ae_name, ae_id);
acl_set_qualifier(acl_entry, &ae_uid);
break;
case ARCHIVE_ENTRY_ACL_GROUP:
acl_set_tag_type(acl_entry, ACL_GROUP);
- ae_gid = a->lookup_gid(a->lookup_gid_data,
+ ae_gid = archive_write_disk_gid(&a->archive,
ae_name, ae_id);
acl_set_qualifier(acl_entry, &ae_gid);
break;
}
#endif
-
-/*
- * Trivial implementations of gid/uid lookup functions.
- * These are normally overridden by the client, but these stub
- * versions ensure that we always have something that works.
- */
-static int64_t
-trivial_lookup_gid(void *private_data, const char *gname, int64_t gid)
-{
- (void)private_data; /* UNUSED */
- (void)gname; /* UNUSED */
- return (gid);
-}
-
-static int64_t
-trivial_lookup_uid(void *private_data, const char *uname, int64_t uid)
-{
- (void)private_data; /* UNUSED */
- (void)uname; /* UNUSED */
- return (uid);
-}
-
/*
* Test if file on disk is older than entry.
*/
time_t, long, time_t, long, time_t, long, time_t, long);
static int set_times_from_entry(struct archive_write_disk *);
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
-static int64_t trivial_lookup_gid(void *, const char *, int64_t);
-static int64_t trivial_lookup_uid(void *, const char *, int64_t);
static ssize_t write_data_block(struct archive_write_disk *,
const char *, size_t);
* TODO: the TODO_SGID condition can be dropped here, can't it?
*/
if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
- a->uid = a->lookup_uid(a->lookup_uid_data,
+ a->uid = archive_write_disk_uid(&a->archive,
archive_entry_uname(a->entry),
archive_entry_uid(a->entry));
}
/* Look up the "real" GID only if we're going to need it. */
/* TODO: the TODO_SUID condition can be dropped here, can't it? */
if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
- a->gid = a->lookup_gid(a->lookup_gid_data,
+ a->gid = archive_write_disk_gid(&a->archive,
archive_entry_gname(a->entry),
archive_entry_gid(a->entry));
}
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+ if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+ (a->cleanup_gid)(a->lookup_gid_data);
+
a->lookup_gid = lookup_gid;
a->cleanup_gid = cleanup_gid;
a->lookup_gid_data = private_data;
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+ if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+ (a->cleanup_uid)(a->lookup_uid_data);
+
a->lookup_uid = lookup_uid;
a->cleanup_uid = cleanup_uid;
a->lookup_uid_data = private_data;
return (ARCHIVE_OK);
}
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+ if (a->lookup_gid)
+ return (a->lookup_gid)(a->lookup_gid_data, name, id);
+ return (id);
+}
+
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+ if (a->lookup_uid)
+ return (a->lookup_uid)(a->lookup_uid_data, name, id);
+ return (id);
+}
/*
* Create a new archive_write_disk object and initialize it with global state.
/* We're ready to write a header immediately. */
a->archive.state = ARCHIVE_STATE_HEADER;
a->archive.vtable = archive_write_disk_vtable();
- a->lookup_uid = trivial_lookup_uid;
- a->lookup_gid = trivial_lookup_gid;
a->start_time = time(NULL);
/* Query and restore the umask. */
umask(a->user_umask = umask(0));
ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
a = (struct archive_write_disk *)_a;
ret = _archive_write_disk_close(&a->archive);
- if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
- (a->cleanup_gid)(a->lookup_gid_data);
- if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
- (a->cleanup_uid)(a->lookup_uid_data);
+ archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+ archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
if (a->entry)
archive_entry_free(a->entry);
archive_wstring_free(&a->_name_data);
return (ARCHIVE_OK);
}
-
-/*
- * Trivial implementations of gid/uid lookup functions.
- * These are normally overridden by the client, but these stub
- * versions ensure that we always have something that works.
- */
-static int64_t
-trivial_lookup_gid(void *private_data, const char *gname, int64_t gid)
-{
- (void)private_data; /* UNUSED */
- (void)gname; /* UNUSED */
- return (gid);
-}
-
-static int64_t
-trivial_lookup_uid(void *private_data, const char *uname, int64_t uid)
-{
- (void)private_data; /* UNUSED */
- (void)uname; /* UNUSED */
- return (uid);
-}
-
static void
fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
{
test_write_disk.c
test_write_disk_failures.c
test_write_disk_hardlink.c
+ test_write_disk_lookup.c
test_write_disk_perms.c
test_write_disk_secure.c
test_write_disk_sparse.c
--- /dev/null
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+group_cleanup(void *d)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x13579);
+ *mp = 0x2468;
+}
+
+static int64_t
+group_lookup(void *d, const char *name, int64_t g)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x13579);
+ if (strcmp(name, "FOOGROUP"))
+ return (1);
+ return (73);
+}
+
+static void
+user_cleanup(void *d)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x1234);
+ *mp = 0x2345;
+}
+
+static int64_t
+user_lookup(void *d, const char *name, int64_t u)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x1234);
+ if (strcmp("FOO", name) == 0)
+ return (2);
+ return (74);
+}
+
+DEFINE_TEST(test_write_disk_lookup)
+{
+ struct archive *a;
+ int gmagic = 0x13579, umagic = 0x1234;
+ int64_t id;
+
+ assert((a = archive_write_disk_new()) != NULL);
+
+ /* Default uname/gname lookups always return ID. */
+ assertEqualInt(0, archive_write_disk_gid(a, "", 0));
+ assertEqualInt(12, archive_write_disk_gid(a, "root", 12));
+ assertEqualInt(12, archive_write_disk_gid(a, "wheel", 12));
+ assertEqualInt(0, archive_write_disk_uid(a, "", 0));
+ assertEqualInt(18, archive_write_disk_uid(a, "root", 18));
+
+ /* Register some weird lookup functions. */
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_group_lookup(a,
+ &gmagic, &group_lookup, &group_cleanup));
+ /* Verify that our new function got called. */
+ assertEqualInt(73, archive_write_disk_gid(a, "FOOGROUP", 8));
+ assertEqualInt(1, archive_write_disk_gid(a, "NOTFOOGROUP", 8));
+
+ /* De-register. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_group_lookup(a, NULL, NULL, NULL));
+ /* Ensure our cleanup function got called. */
+ assertEqualInt(gmagic, 0x2468);
+
+ /* Same thing with uname lookup.... */
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_user_lookup(a,
+ &umagic, &user_lookup, &user_cleanup));
+ assertEqualInt(2, archive_write_disk_uid(a, "FOO", 0));
+ assertEqualInt(74, archive_write_disk_uid(a, "NOTFOO", 1));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_user_lookup(a, NULL, NULL, NULL));
+ assertEqualInt(umagic, 0x2345);
+
+ /* Try the standard lookup functions. */
+ if (archive_write_disk_set_standard_lookup(a) != ARCHIVE_OK) {
+ skipping("standard uname/gname lookup");
+ } else {
+ /* Try a few common names for group #0. */
+ id = archive_write_disk_gid(a, "wheel", 8);
+ if (id != 0)
+ id = archive_write_disk_gid(a, "root", 8);
+ failure("Unable to verify lookup of group #0");
+ assertEqualInt(0, id);
+
+ /* Try a few common names for user #0. */
+ id = archive_write_disk_uid(a, "root", 8);
+ failure("Unable to verify lookup of user #0");
+ assertEqualInt(0, id);
+ }
+
+ /* Deregister again and verify the default lookups again. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_group_lookup(a, NULL, NULL, NULL));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_user_lookup(a, NULL, NULL, NULL));
+ assertEqualInt(0, archive_write_disk_gid(a, "", 0));
+ assertEqualInt(0, archive_write_disk_uid(a, "", 0));
+
+ /* Re-register our custom handlers. */
+ gmagic = 0x13579;
+ umagic = 0x1234;
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_group_lookup(a,
+ &gmagic, &group_lookup, &group_cleanup));
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_user_lookup(a,
+ &umagic, &user_lookup, &user_cleanup));
+
+ /* Destroy the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* Verify our cleanup functions got called. */
+ assertEqualInt(gmagic, 0x2468);
+ assertEqualInt(umagic, 0x2345);
+}