Skip to content

Commit 3417a94

Browse files
committed
bin/xbps-create: record file mode, owner, and group
also add a couple missing things to the xbps_create completions
1 parent 1c728bd commit 3417a94

3 files changed

Lines changed: 103 additions & 5 deletions

File tree

bin/xbps-create/main.c

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2323
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2424
*/
25+
26+
#define _DEFAULT_SOURCE
27+
2528
#include <sys/types.h>
2629
#include <sys/param.h>
2730
#include <sys/stat.h>
@@ -41,6 +44,7 @@
4144
#include <libgen.h>
4245
#include <locale.h>
4346
#include <dirent.h>
47+
#include <fnmatch.h>
4448

4549
#include <xbps.h>
4650
#include "queue.h"
@@ -66,6 +70,7 @@ struct xentry {
6670
char *file, *target;
6771
char sha256[XBPS_SHA256_SIZE];
6872
ino_t inode;
73+
mode_t mode;
6974
};
7075

7176
static TAILQ_HEAD(xentry_head, xentry) xentry_list =
@@ -109,6 +114,9 @@ usage(bool fail)
109114
" 'vi:/usr/bin/vi:/usr/bin/vim foo:/usr/bin/foo:/usr/bin/blah'\n"
110115
" --build-options A string with the used build options\n"
111116
" --compression Compression format: none, gzip, bzip2, lz4, xz, zstd (default)\n"
117+
" --chown Set the ownership of files and directories.\n"
118+
" This expects a blank-separated list of <pattern>:<user>:<group>,\n"
119+
" where '<pattern>' is an fnmatch(3) pattern.\n"
112120
" --shlib-provides List of provided shared libraries (blank separated list,\n"
113121
" e.g 'libfoo.so.1 libblah.so.2')\n"
114122
" --shlib-requires List of required shared libraries (blank separated list,\n"
@@ -245,7 +253,6 @@ process_one_alternative(const char *altgrname, const char *val)
245253
}
246254
}
247255

248-
249256
static void
250257
process_dict_of_arrays(const char *key UNUSED, const char *val)
251258
{
@@ -281,6 +288,69 @@ process_dict_of_arrays(const char *key UNUSED, const char *val)
281288
free(args);
282289
}
283290

291+
static bool
292+
process_chown_pattern(const char *key, const char *fpat, const char *user, const char *group) {
293+
xbps_object_iterator_t iter;
294+
xbps_object_t obj;
295+
const char *fname;
296+
bool match = false;
297+
298+
if ((iter = xbps_array_iter_from_dict(pkg_filesd, key)) != NULL) {
299+
while ((obj = xbps_object_iterator_next(iter))) {
300+
xbps_dictionary_get_cstring_nocopy(obj, "file", &fname);
301+
if (fnmatch(fpat, fname, 0) == 0) {
302+
match = true;
303+
if (user != NULL)
304+
xbps_dictionary_set_cstring(obj, "user", user);
305+
if (group != NULL)
306+
xbps_dictionary_set_cstring(obj, "group", group);
307+
}
308+
}
309+
}
310+
return match;
311+
}
312+
313+
static void
314+
process_chown_patterns(const char *val) {
315+
char *raw, *itm, *fpat, *user, *group;
316+
317+
if (val == NULL)
318+
return;
319+
320+
raw = strdup(val);
321+
322+
while ((itm = strsep(&raw, " "))) {
323+
fpat = strsep(&itm, ":");
324+
if (fpat == NULL || strlen(fpat) == 0) {
325+
xbps_warn_printf("%s: skipping chown pattern `:%s': empty pattern\n", _PROGNAME, itm);
326+
continue;
327+
}
328+
329+
user = strsep(&itm, ":");
330+
if (strlen(user) == 0 || strcmp(user, "root") == 0)
331+
user = NULL;
332+
group = strsep(&itm, ":");
333+
if (strlen(group) == 0 || strcmp(group, "root") == 0)
334+
group = NULL;
335+
336+
if (itm != NULL)
337+
xbps_warn_printf("%s: chown pattern contains extra data: %s\n", _PROGNAME, itm);
338+
339+
if (user == NULL && group == NULL) {
340+
xbps_warn_printf("%s: skipping chown pattern `%s': user and group empty or root\n", _PROGNAME, fpat);
341+
continue;
342+
}
343+
344+
if (!(process_chown_pattern("dirs", fpat, user, group) ||
345+
process_chown_pattern("files", fpat, user, group) ||
346+
process_chown_pattern("links", fpat, user, group))) {
347+
xbps_warn_printf("%s: chown pattern %s matched nothing\n", _PROGNAME, fpat);
348+
}
349+
}
350+
351+
free(raw);
352+
}
353+
284354
static void
285355
process_file(const char *file, const char *key)
286356
{
@@ -396,6 +466,10 @@ ftw_cb(const char *fpath, const struct stat *sb, const struct dirent *dir UNUSED
396466
goto out;
397467
}
398468

469+
// symlinks don't have a mode on linux
470+
if (!S_ISLNK(sb->st_mode))
471+
xe->mode = sb->st_mode;
472+
399473
if (S_ISLNK(sb->st_mode)) {
400474
char buf[PATH_MAX];
401475
ssize_t len;
@@ -530,7 +604,6 @@ ftw_cb(const char *fpath, const struct stat *sb, const struct dirent *dir UNUSED
530604
xbps_dictionary_set_uint64(fileinfo, "inode", sb->st_ino);
531605
xe->inode = sb->st_ino;
532606
xe->size = (uint64_t)sb->st_size;
533-
534607
} else if (S_ISDIR(sb->st_mode)) {
535608
/* directory */
536609
xbps_dictionary_set_cstring_nocopy(fileinfo, "type", "dirs");
@@ -650,6 +723,8 @@ process_xentry(enum entry_type type, const char *mutable_files)
650723
xbps_dictionary_set_cstring(d, "sha256", xe->sha256);
651724
if (xe->size)
652725
xbps_dictionary_set_uint64(d, "size", xe->size);
726+
if (xe->mode)
727+
xbps_dictionary_set_uint32(d, "mode", xe->mode);
653728

654729
xbps_array_add(a, d);
655730
xbps_object_release(d);
@@ -832,6 +907,7 @@ main(int argc, char **argv)
832907
{ "build-options", required_argument, NULL, '2' },
833908
{ "built-with", required_argument, NULL, 'B' },
834909
{ "changelog", required_argument, NULL, 'c'},
910+
{ "chown", required_argument, NULL, '6'},
835911
{ "compression", required_argument, NULL, '3' },
836912
{ "config-files", required_argument, NULL, 'F' },
837913
{ "conflicts", required_argument, NULL, 'C' },
@@ -865,7 +941,7 @@ main(int argc, char **argv)
865941
const char *provides, *pkgver, *replaces, *reverts, *desc, *ldesc;
866942
const char *arch, *config_files, *mutable_files, *version, *changelog;
867943
const char *buildopts, *shlib_provides, *shlib_requires, *alternatives;
868-
const char *compression, *tags = NULL, *srcrevs = NULL, *sourcepkg = NULL;
944+
const char *compression, *tags = NULL, *srcrevs = NULL, *sourcepkg = NULL, *chownlst;
869945
char pkgname[XBPS_NAME_SIZE], *binpkg, *tname, *p, cwd[PATH_MAX-1];
870946
bool quiet = false, preserve = false;
871947
int c, pkg_fd;
@@ -874,7 +950,7 @@ main(int argc, char **argv)
874950
arch = conflicts = deps = homepage = license = maint = compression = NULL;
875951
provides = pkgver = replaces = reverts = desc = ldesc = bwith = NULL;
876952
buildopts = config_files = mutable_files = shlib_provides = NULL;
877-
alternatives = shlib_requires = changelog = NULL;
953+
alternatives = shlib_requires = changelog = chownlst = NULL;
878954

879955
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
880956
if (optarg && strcmp(optarg, "") == 0)
@@ -965,6 +1041,9 @@ main(int argc, char **argv)
9651041
case '5':
9661042
sourcepkg = optarg;
9671043
break;
1044+
case '6':
1045+
chownlst = optarg;
1046+
break;
9681047
case '?':
9691048
default:
9701049
usage(true);
@@ -1081,6 +1160,7 @@ main(int argc, char **argv)
10811160
die("xbps_dictionary_create");
10821161

10831162
process_destdir(mutable_files);
1163+
process_chown_patterns(chownlst);
10841164

10851165
/* Back to original cwd after file tree walk processing */
10861166
if (chdir(p) == -1)

bin/xbps-create/xbps-create.1

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@ is a relative path, the symlink will be created relative to
8181
.Em target .
8282
.It Fl -build-options Ar string
8383
A string containing the build options used in package.
84+
.It Fl -chown Ar list
85+
Set the ownership of package files and directories.
86+
This expects a whitespace-separated list of
87+
.Ar <pattern>:<user>:<group> ,
88+
where
89+
.Ar <pattern>
90+
is an
91+
.Xr fnmatch 3
92+
pattern.
93+
If
94+
.Ar <user>
95+
or
96+
.Ar <group>
97+
are empty, root is assumed.
98+
Example:
99+
.Ar '/usr/lib/foo/*:foo:foo /usr/bin/foo::foo'
84100
.It Fl -compression Ar none | gzip | bzip2 | xz | lz4 | zstd
85101
Set the binary package compression format. If unset, defaults to
86102
.Ar zstd .

data/_xbps

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,10 @@ _xbps_create() {
9696
{-s,--desc}'[Short description]:short description: ' \
9797
{-t,--tags}'[A list of tags/categories]:tags: ' \
9898
{-V,--version}'[Prints XBPS release version]' \
99+
--alternatives'[List of provided alternatives]:list of provided alternatives: ' \
99100
--build-options'[A string with the used build options]:used build options: ' \
100-
--compression'[Compression format]:compression format:(gzip bzip2 xz)' \
101+
--chown'[List of files to chown]:list of files to chown: ' \
102+
--compression'[Compression format]:compression format:(none gzip bzip2 xz lz4 zstd)' \
101103
--shlib-provides'[List of provided shared libraries]:provided shared libraries: ' \
102104
--shlib-requires'[List of required shared libraries]:required shared libraries: '
103105
}

0 commit comments

Comments
 (0)