Skip to content

Commit c67b024

Browse files
committed
WIP: pkgdb fixups
1 parent d2d15fe commit c67b024

File tree

7 files changed

+235
-11
lines changed

7 files changed

+235
-11
lines changed

bin/xbps-pkgdb/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ BIN = xbps-pkgdb
55
OBJS = main.o check.o check_pkg_files.o
66
OBJS += check_pkg_alternatives.o check_pkg_rundeps.o
77
OBJS += check_pkg_symlinks.o check_pkg_unneeded.o
8+
OBJS += check_files.o
89

910
include $(TOPDIR)/mk/prog.mk

bin/xbps-pkgdb/check_files.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include <assert.h>
2+
#include <errno.h>
3+
#include <sys/stat.h>
4+
#include <pwd.h>
5+
#include <grp.h>
6+
7+
#include "defs.h"
8+
9+
10+
11+
int
12+
file_mode_check(const char *file, const mode_t mode) {
13+
struct stat sb;
14+
15+
assert(file != NULL);
16+
assert(mode);
17+
18+
if (lstat(file, &sb) == -1)
19+
return -errno;
20+
21+
if (sb.st_mode != mode)
22+
return ERANGE;
23+
24+
return 0;
25+
}
26+
27+
int
28+
file_owner_check(const char *file, const char *owner) {
29+
struct stat sb;
30+
struct passwd *pw;
31+
32+
assert(file != NULL);
33+
assert(owner != NULL);
34+
35+
if (lstat(file, &sb) == -1)
36+
return -errno;
37+
38+
if ((pw = getpwnam(owner)) == NULL)
39+
return -errno;
40+
41+
if (sb.st_uid != pw->pw_uid)
42+
return ERANGE;
43+
44+
return 0;
45+
}
46+
47+
int
48+
file_group_check(const char *file, const char *grp) {
49+
struct stat sb;
50+
struct group *gr;
51+
52+
assert(file != NULL);
53+
assert(grp != NULL);
54+
55+
if (lstat(file, &sb) == -1)
56+
return -errno;
57+
58+
if ((gr = getgrnam(grp)) == NULL)
59+
return -errno;
60+
61+
if (sb.st_uid != gr->gr_gid)
62+
return ERANGE;
63+
64+
return 0;
65+
}

bin/xbps-pkgdb/check_pkg_files.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
111111
/* check mode */
112112
mode = 0;
113113
if (xbps_dictionary_get_uint32(obj, "mode", &mode)) {
114-
rv = xbps_file_mode_check(path, mode);
114+
rv = file_mode_check(path, mode);
115115
switch (rv) {
116116
case 0:
117117
break;
@@ -122,15 +122,15 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
122122
}
123123
break;
124124
default:
125-
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
125+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
126126
break;
127127
}
128128
}
129129

130130
/* check owner */
131131
owner = NULL;
132132
if (xbps_dictionary_get_cstring_nocopy(obj, "owner", &owner)) {
133-
rv = xbps_file_owner_check(path, owner);
133+
rv = file_owner_check(path, owner);
134134
switch (rv) {
135135
case 0:
136136
break;
@@ -141,15 +141,15 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
141141
}
142142
break;
143143
default:
144-
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
144+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
145145
break;
146146
}
147147
}
148148

149149
/* check group */
150150
group = NULL;
151151
if (xbps_dictionary_get_cstring_nocopy(obj, "group", &group)) {
152-
rv = xbps_file_group_check(path, group);
152+
rv = file_group_check(path, group);
153153
switch (rv) {
154154
case 0:
155155
break;
@@ -160,7 +160,7 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
160160
}
161161
break;
162162
default:
163-
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
163+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
164164
break;
165165
}
166166
}

bin/xbps-pkgdb/check_pkg_symlinks.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
9797
}
9898

9999
if (xbps_dictionary_get_cstring_nocopy(obj, "owner", &owner)) {
100-
rv = xbps_file_owner_check(path, owner);
100+
rv = file_owner_check(path, owner);
101101
switch (rv) {
102102
case 0:
103103
break;
@@ -106,13 +106,13 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
106106
test_broken = true;
107107
break;
108108
default:
109-
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
109+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
110110
break;
111111
}
112112
}
113113

114114
if (xbps_dictionary_get_cstring_nocopy(obj, "group", &group)) {
115-
rv = xbps_file_group_check(path, group);
115+
rv = file_group_check(path, group);
116116
switch (rv) {
117117
case 0:
118118
break;
@@ -121,7 +121,7 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
121121
test_broken = true;
122122
break;
123123
default:
124-
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
124+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
125125
break;
126126
}
127127
}

bin/xbps-pkgdb/defs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@ CHECK_PKG_DECL(alternatives);
4545
/* from convert.c */
4646
void convert_pkgdb_format(struct xbps_handle *);
4747

48+
/* from check_files.c */
49+
int file_mode_check(const char *, const mode_t);
50+
int file_owner_check(const char *, const char *);
51+
int file_group_check(const char *, const char *);
52+
4853
#endif /* !_XBPS_PKGDB_DEFS_H_ */

lib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ LIBFETCH_INCS = fetch/common.h
3232
LIBFETCH_GEN = fetch/ftperr.h fetch/httperr.h
3333

3434
# External code used by libxbps
35-
EXTOBJS = external/dewey.o external/fexec.o external/mkpath.o
35+
EXTOBJS = external/dewey.o external/fexec.o external/mkpath.o #external/idtree.o
3636

3737
# libxbps
3838
OBJS = package_configure.o package_config_files.o package_orphans.o

lib/external/idtree.c

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* Copyright (C) 2015-2020 Leah Neukirchen
3+
* Parts of code derived from musl libc, which is
4+
* Copyright (C) 2005-2014 Rich Felker, et al.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining
7+
* a copy of this software and associated documentation files (the
8+
* "Software"), to deal in the Software without restriction, including
9+
* without limitation the rights to use, copy, modify, merge, publish,
10+
* distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to
12+
* the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be
15+
* included in all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
#include <sys/types.h>
27+
#include <pwd.h>
28+
#include <grp.h>
29+
30+
/* AA-tree implementation, adapted from https://github.com/ccxvii/minilibs */
31+
struct idtree {
32+
long id;
33+
char *name;
34+
struct idtree *left, *right;
35+
int level;
36+
};
37+
38+
static struct idtree idtree_sentinel = { 0, 0, &idtree_sentinel, &idtree_sentinel, 0 };
39+
40+
static struct idtree *
41+
idtree_make(long id, char *name)
42+
{
43+
struct idtree *node = malloc(sizeof (struct idtree));
44+
node->id = id;
45+
node->name = name;
46+
node->left = node->right = &idtree_sentinel;
47+
node->level = 1;
48+
return node;
49+
}
50+
51+
char *
52+
idtree_lookup(struct idtree *node, long id)
53+
{
54+
if (node) {
55+
while (node != &idtree_sentinel) {
56+
if (id == node->id)
57+
return node->name;
58+
else if (id < node->id)
59+
node = node->left;
60+
else
61+
node = node->right;
62+
}
63+
}
64+
65+
return 0;
66+
}
67+
68+
static struct idtree *
69+
idtree_skew(struct idtree *node)
70+
{
71+
if (node->left->level == node->level) {
72+
struct idtree *save = node;
73+
node = node->left;
74+
save->left = node->right;
75+
node->right = save;
76+
}
77+
return node;
78+
}
79+
80+
static struct idtree *
81+
idtree_split(struct idtree *node)
82+
{
83+
if (node->right->right->level == node->level) {
84+
struct idtree *save = node;
85+
node = node->right;
86+
save->right = node->left;
87+
node->left = save;
88+
node->level++;
89+
}
90+
return node;
91+
}
92+
93+
struct idtree *
94+
idtree_insert(struct idtree *node, long id, char *name)
95+
{
96+
if (node && node != &idtree_sentinel) {
97+
if (id == node->id)
98+
return node;
99+
else if (id < node->id)
100+
node->left = idtree_insert(node->left, id, name);
101+
else
102+
node->right = idtree_insert(node->right, id, name);
103+
node = idtree_skew(node);
104+
node = idtree_split(node);
105+
return node;
106+
}
107+
return idtree_make(id, name);
108+
}
109+
/**/
110+
111+
static char *
112+
strid(long id)
113+
{
114+
static char buf[32];
115+
snprintf(buf, sizeof buf, "%ld", id);
116+
return buf;
117+
}
118+
119+
static char *
120+
groupname(struct idtree *groups, gid_t gid)
121+
{
122+
char *name = idtree_lookup(groups, gid);
123+
124+
if (name)
125+
return name;
126+
127+
struct group *g = getgrgid(gid);
128+
if (g) {
129+
char *name = strdup(g->gr_name);
130+
groups = idtree_insert(groups, gid, name);
131+
return name;
132+
}
133+
134+
return strid(gid);
135+
}
136+
137+
static char *
138+
username(struct idtree *users, uid_t uid)
139+
{
140+
char *name = idtree_lookup(users, uid);
141+
142+
if (name)
143+
return name;
144+
145+
struct passwd *p = getpwuid(uid);
146+
if (p) {
147+
char *name = strdup(p->pw_name);
148+
users = idtree_insert(users, uid, name);
149+
return name;
150+
}
151+
152+
return strid(uid);
153+
}

0 commit comments

Comments
 (0)