/* "system.posix_acl_default" */ static void xattrs__acls_get_d (int parentfd, char const *file_name, struct tar_stat_info *st, char **ret_ptr, size_t * ret_len) { char *val = NULL; ssize_t len; acl_t acl; if (!(acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_DEFAULT))) { if (errno != ENOTSUP) call_arg_warn ("acl_get_file_at", file_name); return; } val = acl_to_text (acl, &len); acl_free (acl); if (!val) { call_arg_warn ("acl_to_text", file_name); return; } *ret_ptr = xstrdup (val); *ret_len = len; acl_free (val); }
void xattrs_acls_get (int parentfd, char const *file_name, struct tar_stat_info *st, int fd, int xisfile) { if (acls_option > 0) { #ifndef HAVE_POSIX_ACLS static int done = 0; if (!done) WARN ((0, 0, _("POSIX ACL support is not available"))); done = 1; #else int err = file_has_acl_at (parentfd, file_name, &st->stat); if (err == 0) return; if (err == -1) { call_arg_warn ("file_has_acl_at", file_name); return; } xattrs__acls_get_a (parentfd, file_name, st, &st->acls_a_ptr, &st->acls_a_len); if (!xisfile) xattrs__acls_get_d (parentfd, file_name, st, &st->acls_d_ptr, &st->acls_d_len); #endif } }
/* Set the "system.posix_acl_access/system.posix_acl_default" extended attribute. Called only when acls_option > 0. */ static void xattrs__acls_set (struct tar_stat_info const *st, char const *file_name, int type, char *ptr, size_t len, bool def) { acl_t acl; if (ptr) { /* assert (strlen (ptr) == len); */ ptr = fixup_extra_acl_fields (ptr); acl = acl_from_text (ptr); } else if (def) { /* No "default" IEEE 1003.1e ACL set for directory. At this moment, FILE_NAME may already have inherited default acls from parent directory; clean them up. */ if (acl_delete_def_file_at (chdir_fd, file_name)) WARNOPT (WARN_XATTR_WRITE, (0, errno, _("acl_delete_def_file_at: Cannot drop default POSIX ACLs " "for file '%s'"), file_name)); return; } else acl = perms2acl (st->stat.st_mode); if (!acl) { call_arg_warn ("acl_from_text", file_name); return; } if (acl_set_file_at (chdir_fd, file_name, type, acl) == -1) /* warn even if filesystem does not support acls */ WARNOPT (WARN_XATTR_WRITE, (0, errno, _ ("acl_set_file_at: Cannot set POSIX ACLs for file '%s'"), file_name)); acl_free (acl); }
/* lgetfileconat is called against FILE_NAME iff the FD parameter is set to zero, otherwise the fgetfileconat is used against correct file descriptor */ void xattrs_selinux_get (int parentfd, char const *file_name, struct tar_stat_info *st, int fd) { if (selinux_context_option > 0) { #if HAVE_SELINUX_SELINUX_H != 1 static int done = 0; if (!done) WARN ((0, 0, _("SELinux support is not available"))); done = 1; #else int result = fd ? fgetfilecon (fd, &st->cntx_name) : lgetfileconat (parentfd, file_name, &st->cntx_name); if (result == -1 && errno != ENODATA && errno != ENOTSUP) call_arg_warn (fd ? "fgetfilecon" : "lgetfileconat", file_name); #endif } }
/* get all xattrs from file given by FILE_NAME or FD (when non-zero). This includes all the user.*, security.*, system.*, etc. available domains */ void xattrs_xattrs_get (int parentfd, char const *file_name, struct tar_stat_info *st, int fd) { if (xattrs_option > 0) { #ifndef HAVE_XATTRS static int done = 0; if (!done) WARN ((0, 0, _("XATTR support is not available"))); done = 1; #else static size_t xsz = 1024; static char *xatrs = NULL; ssize_t xret = -1; if (!xatrs) xatrs = x2nrealloc (xatrs, &xsz, 1); while (((fd == 0) ? ((xret = llistxattrat (parentfd, file_name, xatrs, xsz)) == -1) : ((xret = flistxattr (fd, xatrs, xsz)) == -1)) && (errno == ERANGE)) { xatrs = x2nrealloc (xatrs, &xsz, 1); } if (xret == -1) call_arg_warn ((fd == 0) ? "llistxattrat" : "flistxattr", file_name); else { const char *attr = xatrs; static size_t asz = 1024; static char *val = NULL; if (!val) val = x2nrealloc (val, &asz, 1); while (xret > 0) { size_t len = strlen (attr); ssize_t aret = 0; /* Archive all xattrs during creation, decide at extraction time * which ones are of interest/use for the target filesystem. */ while (((fd == 0) ? ((aret = lgetxattrat (parentfd, file_name, attr, val, asz)) == -1) : ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && (errno == ERANGE)) { val = x2nrealloc (val, &asz, 1); } if (aret != -1) xheader_xattr_add (st, attr, val, aret); else if (errno != ENOATTR) call_arg_warn ((fd == 0) ? "lgetxattrat" : "fgetxattr", file_name); attr += len + 1; xret -= len + 1; } } #endif } }
void stat_warn (char const *name) { call_arg_warn ("stat", name); }
void truncate_warn (char const *name) { call_arg_warn ("truncate", name); }
void seek_warn (char const *name) { call_arg_warn ("seek", name); }
void savedir_warn (char const *name) { call_arg_warn ("savedir", name); }
void readlink_warn (char const *name) { call_arg_warn ("readlink", name); }
void open_warn (char const *name) { call_arg_warn ("open", name); }
void close_warn (char const *name) { call_arg_warn ("close", name); }