]>
Dogcows Code - chaz/tar/blob - src/xattrs.c
e813d5388ad5c2048d8567eca198995a8e4fdbf8
1 /* Support for extended attributes.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
6 Written by James Antill, on 2006-07-27.
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any later
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
31 struct xattrs_mask_map
38 /* list of fnmatch patterns */
41 /* lists of fnmatch patterns */
42 struct xattrs_mask_map incl
;
43 struct xattrs_mask_map excl
;
46 static void mask_map_realloc (struct xattrs_mask_map
*map
)
51 map
->masks
= xmalloc (16 * sizeof (char *));
55 if (map
->size
<= map
->used
)
58 map
->masks
= xrealloc (map
->masks
, map
->size
* sizeof (char *));
63 void xattrs_mask_add (const char *mask
, bool incl
)
65 struct xattrs_mask_map
*mask_map
= incl
? &xattrs_setup
.incl
67 /* ensure there is enough space */
68 mask_map_realloc (mask_map
);
69 /* just assign pointers -- we silently expect that pointer "mask" is valid
70 through the whole program (pointer to argv array) */
71 mask_map
->masks
[mask_map
->used
++] = mask
;
74 static void clear_mask_map (struct xattrs_mask_map
*mask_map
)
77 free (mask_map
->masks
);
80 void xattrs_clear_setup ()
82 clear_mask_map (&xattrs_setup
.incl
);
83 clear_mask_map (&xattrs_setup
.excl
);
86 /* get all xattrs from file given by FILE_NAME or FD (when non-zero). This
87 includes all the user.*, security.*, system.*, etc. available domains */
88 void xattrs_xattrs_get (int parentfd
, char const *file_name
,
89 struct tar_stat_info
*st
, int fd
)
91 if (xattrs_option
> 0)
96 WARN ((0, 0, _("XATTR support is not available")));
99 static ssize_t xsz
= 1024;
100 static char *xatrs
= NULL
;
103 if (!xatrs
) xatrs
= xmalloc (xsz
);
106 ((xret
= llistxattrat (parentfd
, file_name
, xatrs
, xsz
)) == -1) :
107 ((xret
= flistxattr (fd
, xatrs
, xsz
)) == -1)) &&
111 xatrs
= xrealloc (xatrs
, xsz
);
115 call_arg_warn ((fd
== 0) ? "llistxattrat" : "flistxattr", file_name
);
118 const char *attr
= xatrs
;
119 static ssize_t asz
= 1024;
120 static char *val
= NULL
;
122 if (!val
) val
= xmalloc (asz
);
126 size_t len
= strlen (attr
);
129 /* Archive all xattrs during creation, decide at extraction time
130 * which ones are of interest/use for the target filesystem. */
132 ? ((aret
= lgetxattrat (parentfd
, file_name
, attr
,
134 : ((aret
= fgetxattr (fd
, attr
, val
, asz
)) == -1))
135 && (errno
== ERANGE
))
138 val
= xrealloc (val
, asz
);
142 xheader_xattr_add (st
, attr
, val
, aret
);
143 else if (errno
!= ENOATTR
)
144 call_arg_warn ((fd
== 0) ? "lgetxattrat"
145 : "fgetxattr", file_name
);
155 static void xattrs__fd_set (struct tar_stat_info
const *st
,
156 char const *file_name
, char typeflag
,
158 const char *ptr
, size_t len
)
162 const char *sysname
= "setxattrat";
165 if (typeflag
!= SYMTYPE
)
166 ret
= setxattrat (chdir_fd
, file_name
, attr
, ptr
, len
, 0);
169 sysname
= "lsetxattr";
170 ret
= lsetxattrat (chdir_fd
, file_name
, attr
, ptr
, len
, 0);
174 WARNOPT (WARN_XATTR_WRITE
, (0, errno
,
175 _("%s: Cannot set '%s' extended attribute for file '%s'"),
176 sysname
, attr
, file_name
));
180 static bool xattrs_matches_mask (const char *kw
, struct xattrs_mask_map
*mm
)
187 for (i
= 0; i
< mm
->used
; i
++)
188 if (fnmatch (mm
->masks
[i
], kw
, 0) == 0)
194 static bool xattrs_kw_included (const char *kw
, bool archiving
)
196 if (xattrs_setup
.incl
.size
)
197 return xattrs_matches_mask (kw
, &xattrs_setup
.incl
);
203 return strncmp (kw
, "user.", strlen ("user.")) == 0;
207 static bool xattrs_kw_excluded (const char *kw
, bool archiving
)
209 if (!xattrs_setup
.excl
.size
)
212 return xattrs_matches_mask (kw
, &xattrs_setup
.excl
);
215 /* Check whether the xattr with keyword KW should be discarded from list of
216 attributes that are going to be archived/excluded (set ARCHIVING=true for
217 archiving, false for excluding) */
218 static bool xattrs_masked_out (const char *kw
, bool archiving
)
220 if (!xattrs_kw_included (kw
, archiving
))
223 return xattrs_kw_excluded (kw
, archiving
);
226 void xattrs_xattrs_set (struct tar_stat_info
const *st
,
227 char const *file_name
, char typeflag
,
230 if (xattrs_option
> 0)
235 WARN ((0, 0, _("XATTR support is not available")));
240 if (!st
->xattr_map_size
)
243 for (; scan
< st
->xattr_map_size
; ++scan
)
245 char *keyword
= st
->xattr_map
[scan
].xkey
;
246 keyword
+= strlen ("SCHILY.xattr.");
248 /* TODO: this 'later_run' workaround is temporary solution -> once
249 capabilities should become fully supported by it's API and there
250 should exist something like xattrs_capabilities_set() call.
251 For a regular files: all extended attributes are restored during
252 the first run except 'security.capability' which is restored in
254 if (typeflag
== REGTYPE
255 && later_run
== !!strcmp (keyword
, "security.capability"))
258 if (xattrs_masked_out (keyword
, false /* extracting */ ))
259 /* we don't want to restore this keyword */
262 xattrs__fd_set (st
, file_name
, typeflag
, keyword
,
263 st
->xattr_map
[scan
].xval_ptr
,
264 st
->xattr_map
[scan
].xval_len
);
270 void xattrs_print_char (struct tar_stat_info
const *st
, char *output
)
273 if (verbose_option
< 2)
279 if (xattrs_option
> 0)
286 if (xattrs_option
> 0 && st
->xattr_map_size
)
287 for (i
= 0; i
< st
->xattr_map_size
; ++i
)
289 char *keyword
= st
->xattr_map
[i
].xkey
+ strlen ("SCHILY.xattr.");
290 if (xattrs_masked_out (keyword
, false /* like extracting */ ))
297 void xattrs_print (struct tar_stat_info
const *st
)
299 if (verbose_option
< 3)
303 if (xattrs_option
&& st
->xattr_map_size
)
306 for (i
= 0; i
< st
->xattr_map_size
; ++i
)
308 char *keyword
= st
->xattr_map
[i
].xkey
+ strlen ("SCHILY.xattr.");
309 if (xattrs_masked_out (keyword
, false /* like extracting */ ))
311 fprintf (stdlis
, " x: %lu %s\n",
312 (unsigned long) st
->xattr_map
[i
].xval_len
, keyword
);
This page took 0.051205 seconds and 3 git commands to generate.