Skip to content

Commit

Permalink
WIP: pkgdb fixups
Browse files Browse the repository at this point in the history
  • Loading branch information
classabbyamp committed Mar 14, 2023
1 parent 6ce61d7 commit a5c1700
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 11 deletions.
1 change: 1 addition & 0 deletions bin/xbps-pkgdb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ BIN = xbps-pkgdb
OBJS = main.o check.o check_pkg_files.o
OBJS += check_pkg_alternatives.o check_pkg_rundeps.o
OBJS += check_pkg_symlinks.o check_pkg_unneeded.o
OBJS += check_files.o

include $(TOPDIR)/mk/prog.mk
65 changes: 65 additions & 0 deletions bin/xbps-pkgdb/check_files.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>

#include "defs.h"



int
file_mode_check(const char *file, const mode_t mode) {
struct stat sb;

assert(file != NULL);
assert(mode);

if (lstat(file, &sb) == -1)
return -errno;

if (sb.st_mode != mode)
return ERANGE;

return 0;
}

int
file_owner_check(const char *file, const char *owner) {
struct stat sb;
struct passwd *pw;

assert(file != NULL);
assert(owner != NULL);

if (lstat(file, &sb) == -1)
return -errno;

if ((pw = getpwnam(owner)) == NULL)
return -errno;

if (sb.st_uid != pw->pw_uid)
return ERANGE;

return 0;
}

int
file_group_check(const char *file, const char *grp) {
struct stat sb;
struct group *gr;

assert(file != NULL);
assert(grp != NULL);

if (lstat(file, &sb) == -1)
return -errno;

if ((gr = getgrnam(grp)) == NULL)
return -errno;

if (sb.st_uid != gr->gr_gid)
return ERANGE;

return 0;
}
12 changes: 6 additions & 6 deletions bin/xbps-pkgdb/check_pkg_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
/* check mode */
mode = 0;
if (xbps_dictionary_get_uint32(obj, "mode", &mode)) {
rv = xbps_file_mode_check(path, mode);
rv = file_mode_check(path, mode);
switch (rv) {
case 0:
break;
Expand All @@ -122,15 +122,15 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
}
break;
default:
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
break;
}
}

/* check owner */
owner = NULL;
if (xbps_dictionary_get_cstring_nocopy(obj, "owner", &owner)) {
rv = xbps_file_owner_check(path, owner);
rv = file_owner_check(path, owner);
switch (rv) {
case 0:
break;
Expand All @@ -141,15 +141,15 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
}
break;
default:
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
break;
}
}

/* check group */
group = NULL;
if (xbps_dictionary_get_cstring_nocopy(obj, "group", &group)) {
rv = xbps_file_group_check(path, group);
rv = file_group_check(path, group);
switch (rv) {
case 0:
break;
Expand All @@ -160,7 +160,7 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
}
break;
default:
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
break;
}
}
Expand Down
8 changes: 4 additions & 4 deletions bin/xbps-pkgdb/check_pkg_symlinks.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
}

if (xbps_dictionary_get_cstring_nocopy(obj, "owner", &owner)) {
rv = xbps_file_owner_check(path, owner);
rv = file_owner_check(path, owner);
switch (rv) {
case 0:
break;
Expand All @@ -106,13 +106,13 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
test_broken = true;
break;
default:
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
break;
}
}

if (xbps_dictionary_get_cstring_nocopy(obj, "group", &group)) {
rv = xbps_file_group_check(path, group);
rv = file_group_check(path, group);
switch (rv) {
case 0:
break;
Expand All @@ -121,7 +121,7 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
test_broken = true;
break;
default:
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(-rv));
break;
}
}
Expand Down
5 changes: 5 additions & 0 deletions bin/xbps-pkgdb/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ CHECK_PKG_DECL(alternatives);
/* from convert.c */
void convert_pkgdb_format(struct xbps_handle *);

/* from check_files.c */
int file_mode_check(const char *, const mode_t);
int file_owner_check(const char *, const char *);
int file_group_check(const char *, const char *);

#endif /* !_XBPS_PKGDB_DEFS_H_ */
2 changes: 1 addition & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ LIBFETCH_INCS = fetch/common.h
LIBFETCH_GEN = fetch/ftperr.h fetch/httperr.h

# External code used by libxbps
EXTOBJS = external/dewey.o external/fexec.o external/mkpath.o
EXTOBJS = external/dewey.o external/fexec.o external/mkpath.o #external/idtree.o

# libxbps
OBJS = package_configure.o package_config_files.o package_orphans.o
Expand Down
153 changes: 153 additions & 0 deletions lib/external/idtree.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* Copyright (C) 2015-2020 Leah Neukirchen
* Parts of code derived from musl libc, which is
* Copyright (C) 2005-2014 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <sys/types.h>
#include <pwd.h>
#include <grp.h>

/* AA-tree implementation, adapted from https://github.com/ccxvii/minilibs */
struct idtree {
long id;
char *name;
struct idtree *left, *right;
int level;
};

static struct idtree idtree_sentinel = { 0, 0, &idtree_sentinel, &idtree_sentinel, 0 };

static struct idtree *
idtree_make(long id, char *name)
{
struct idtree *node = malloc(sizeof (struct idtree));
node->id = id;
node->name = name;
node->left = node->right = &idtree_sentinel;
node->level = 1;
return node;
}

char *
idtree_lookup(struct idtree *node, long id)
{
if (node) {
while (node != &idtree_sentinel) {
if (id == node->id)
return node->name;
else if (id < node->id)
node = node->left;
else
node = node->right;
}
}

return 0;
}

static struct idtree *
idtree_skew(struct idtree *node)
{
if (node->left->level == node->level) {
struct idtree *save = node;
node = node->left;
save->left = node->right;
node->right = save;
}
return node;
}

static struct idtree *
idtree_split(struct idtree *node)
{
if (node->right->right->level == node->level) {
struct idtree *save = node;
node = node->right;
save->right = node->left;
node->left = save;
node->level++;
}
return node;
}

struct idtree *
idtree_insert(struct idtree *node, long id, char *name)
{
if (node && node != &idtree_sentinel) {
if (id == node->id)
return node;
else if (id < node->id)
node->left = idtree_insert(node->left, id, name);
else
node->right = idtree_insert(node->right, id, name);
node = idtree_skew(node);
node = idtree_split(node);
return node;
}
return idtree_make(id, name);
}
/**/

static char *
strid(long id)
{
static char buf[32];
snprintf(buf, sizeof buf, "%ld", id);
return buf;
}

static char *
groupname(struct idtree *groups, gid_t gid)
{
char *name = idtree_lookup(groups, gid);

if (name)
return name;

struct group *g = getgrgid(gid);
if (g) {
char *name = strdup(g->gr_name);
groups = idtree_insert(groups, gid, name);
return name;
}

return strid(gid);
}

static char *
username(struct idtree *users, uid_t uid)
{
char *name = idtree_lookup(users, uid);

if (name)
return name;

struct passwd *p = getpwuid(uid);
if (p) {
char *name = strdup(p->pw_name);
users = idtree_insert(users, uid, name);
return name;
}

return strid(uid);
}

0 comments on commit a5c1700

Please sign in to comment.