#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min)))
#endif
-#include <grp.h>
-#include <pwd.h>
-
/* Play games to come up with a suitable makedev() definition. */
#ifdef __QNXNTO__
/* QNX. <sigh> */
}
void
-archive_entry_set_gid(struct archive_entry *entry, int g)
+archive_entry_set_gid(struct archive_entry *entry, gid_t g)
{
entry->stat_valid = 0;
entry->ae_stat.aest_gid = g;
- if(entry->ae_stat.aest_gid != g) {
- static int warned = 0;
- static struct group *nobodygroup;
- gid_t truncgroup;
- if(!nobodygroup)
- nobodygroup = getgrnam("nobody");
- if(nobodygroup)
- truncgroup = nobodygroup->gr_gid;
- else
- truncgroup = 99;
- if(!warned) {
- fprintf(stderr, "libarchive: gid %d out of range; will be extracted as %d\n",
- g, truncgroup);
- warned = 1;
- }
- entry->ae_stat.aest_gid = truncgroup;
- }
}
void
}
void
-archive_entry_set_uid(struct archive_entry *entry, int u)
+archive_entry_set_uid(struct archive_entry *entry, uid_t u)
{
entry->stat_valid = 0;
entry->ae_stat.aest_uid = u;
-
- if(entry->ae_stat.aest_uid != u) {
- static int warned = 0;
- static struct passwd *nobodyuser;
- uid_t truncuser;
- if(!nobodyuser)
- nobodyuser = getpwnam("nobody");
- if(nobodyuser)
- truncuser = nobodyuser->pw_uid;
- else
- truncuser = 99;
- if(!warned) {
- fprintf(stderr, "libarchive: uid %d out of range; will be extracted as %d\n",
- u, truncuser);
- warned = 1;
- }
- entry->ae_stat.aest_uid = truncuser;
- }
}
void
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
-__LA_DECL void archive_entry_set_gid(struct archive_entry *, int);
+__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_GID_T);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_uid(struct archive_entry *, int);
+__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_UID_T);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161 2009-12-29 05:44:39Z kientzle $");
+#include <grp.h>
+#include <pwd.h>
+
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
header_common(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
+ int err = ARCHIVE_OK;
const struct archive_entry_header_ustar *header;
char tartype;
+ uid_t uid;
+ gid_t gid;
(void)a; /* UNUSED */
/* Parse out the numeric fields (all are octal) */
archive_entry_set_mode(entry, tar_atol(header->mode, sizeof(header->mode)));
- archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
- archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
+
+ uid = (uid_t) tar_atol(header->uid, sizeof(header->uid));
+
+ /* Sanity check: uid overflow. Some systems have a limited uid_t.
+ * For example, Minix 3.2.0 has 16-bit uids.
+ */
+ if (uid != tar_atol(header->uid, sizeof(header->uid))) {
+
+ /* This isn't a fatal error, so we try to set the uid to
+ * the uid of the "nobody" user or 99.
+ */
+
+ static int warned = 0;
+ static struct passwd *nobodyuser = NULL;
+
+ if (nobodyuser == NULL) {
+ nobodyuser = getpwnam("nobody");
+ }
+
+ if (nobodyuser != NULL) {
+ uid = nobodyuser->pw_uid;
+ } else {
+ uid = (uid_t) 99;
+ }
+
+ if (warned == 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "uid %ld out of range; will be extracted as %d.",
+ tar_atol(header->uid, sizeof(header->uid)),
+ uid);
+
+ warned = 1; /* only warn once about invalid uid */
+ err = ARCHIVE_WARN;
+ }
+ }
+
+ archive_entry_set_uid(entry, uid);
+
+ gid = (gid_t) tar_atol(header->gid, sizeof(header->gid));
+
+ /* Sanity check: gid overflow. Some systems have a limited gid_t.
+ * For example, Minix 3.2.0 has 8-bit gids.
+ */
+ if (gid != tar_atol(header->gid, sizeof(header->gid))) {
+
+ /* This isn't a fatal error, so we try to set the gid to
+ * the gid of the "nobody" or "nogroup" group or 99.
+ */
+
+ static int warned = 0;
+ static struct group *nobodygroup = NULL;
+
+ if (nobodygroup == NULL) {
+
+ nobodygroup = getgrnam("nobody");
+ if (nobodygroup == NULL) {
+ nobodygroup = getgrnam("nogroup");
+ }
+ }
+
+ if (nobodygroup != NULL) {
+ gid = nobodygroup->gr_gid;
+ } else {
+ gid = (gid_t) 99;
+ }
+
+ if (warned == 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "gid %ld out of range; will be extracted as %d",
+ tar_atol(header->gid, sizeof(header->gid)),
+ gid);
+
+ warned = 1; /* only warn once about invalid gid */
+ err = ARCHIVE_WARN;
+ }
+ }
+
+ archive_entry_set_gid(entry, gid);
+
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
tar->realsize = tar->entry_bytes_remaining;
archive_entry_set_size(entry, tar->entry_bytes_remaining);
archive_entry_set_filetype(entry, AE_IFREG);
break;
}
- return (0);
+
+ return err;
}
/*
header_old_tar(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
+ int err;
const struct archive_entry_header_ustar *header;
/* Copy filename over (to ensure null termination). */
archive_entry_copy_pathname(entry, tar->entry_pathname.s);
/* Grab rest of common fields */
- header_common(a, tar, entry, h);
+ err = header_common(a, tar, entry, h);
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (0);
+ return err;
}
/*
header_ustar(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
+ int err;
const struct archive_entry_header_ustar *header;
struct archive_string *as;
archive_entry_copy_pathname(entry, as->s);
/* Handle rest of common fields. */
- header_common(a, tar, entry, h);
+ err = header_common(a, tar, entry, h);
/* Handle POSIX ustar fields. */
archive_strncpy(&(tar->entry_uname), header->uname,
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (0);
+ return err;
}
header_gnutar(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
+ int err;
const struct archive_entry_header_gnutar *header;
(void)a;
*/
/* Grab fields common to all tar variants. */
- header_common(a, tar, entry, h);
+ err = header_common(a, tar, entry, h);
/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_gnutar *)h;
}
}
- return (0);
+ return err;
}
static void