namei: move icache to lib/
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
8a2045620e
commit
04a5cb58b6
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef UTIL_LINUX_IDCACHE_H
|
||||||
|
#define UTIL_LINUX_IDCACHE_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#define IDCACHE_FLAGS_NAMELEN (1 << 1)
|
||||||
|
|
||||||
|
struct identry {
|
||||||
|
unsigned long int id;
|
||||||
|
char *name;
|
||||||
|
struct identry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct idcache {
|
||||||
|
struct identry *ent; /* first entry */
|
||||||
|
int width; /* name width */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern struct idcache *new_idcache(void);
|
||||||
|
extern void add_gid(struct idcache *cache, unsigned long int id);
|
||||||
|
extern void add_uid(struct idcache *cache, unsigned long int id);
|
||||||
|
|
||||||
|
extern void free_idcache(struct idcache *ic);
|
||||||
|
extern struct identry *get_id(struct idcache *ic, unsigned long int id);
|
||||||
|
|
||||||
|
#endif /* UTIL_LINUX_IDCACHE_H */
|
|
@ -8,6 +8,7 @@ libcommon_la_SOURCES = \
|
||||||
lib/crc32.c \
|
lib/crc32.c \
|
||||||
lib/crc64.c \
|
lib/crc64.c \
|
||||||
lib/env.c \
|
lib/env.c \
|
||||||
|
lib/idcache.c \
|
||||||
lib/fileutils.c \
|
lib/fileutils.c \
|
||||||
lib/ismounted.c \
|
lib/ismounted.c \
|
||||||
lib/color-names.c \
|
lib/color-names.c \
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "c.h"
|
||||||
|
#include "idcache.h"
|
||||||
|
|
||||||
|
struct identry *get_id(struct idcache *ic, unsigned long int id)
|
||||||
|
{
|
||||||
|
struct identry *ent;
|
||||||
|
|
||||||
|
if (!ic)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (ent = ic->ent; ent; ent = ent->next) {
|
||||||
|
if (ent->id == id)
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct idcache *new_idcache()
|
||||||
|
{
|
||||||
|
return calloc(1, sizeof(struct idcache));
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_idcache(struct idcache *ic)
|
||||||
|
{
|
||||||
|
struct identry *ent = ic->ent;
|
||||||
|
|
||||||
|
while (ent) {
|
||||||
|
struct identry *next = ent->next;
|
||||||
|
free(ent->name);
|
||||||
|
free(ent);
|
||||||
|
ent = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_id(struct idcache *ic, char *name, unsigned long int id)
|
||||||
|
{
|
||||||
|
struct identry *ent, *x;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
ent = calloc(1, sizeof(struct identry));
|
||||||
|
if (!ent)
|
||||||
|
return;
|
||||||
|
ent->id = id;
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
#ifdef HAVE_WIDECHAR
|
||||||
|
wchar_t wc[LOGIN_NAME_MAX + 1];
|
||||||
|
|
||||||
|
if (mbstowcs(wc, name, LOGIN_NAME_MAX) > 0) {
|
||||||
|
wc[LOGIN_NAME_MAX] = '\0';
|
||||||
|
w = wcswidth(wc, LOGIN_NAME_MAX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
w = strlen(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* note, we ignore names with non-printable widechars */
|
||||||
|
if (w > 0) {
|
||||||
|
ent->name = strdup(name);
|
||||||
|
if (!ent->name) {
|
||||||
|
free(ent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (asprintf(&ent->name, "%lu", id) < 0) {
|
||||||
|
free(ent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = ic->ent; x && x->next; x = x->next);
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
x->next = ent;
|
||||||
|
else
|
||||||
|
ic->ent = ent;
|
||||||
|
|
||||||
|
if (w <= 0)
|
||||||
|
w = ent->name ? strlen(ent->name) : 0;
|
||||||
|
ic->width = ic->width < w ? w : ic->width;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_uid(struct idcache *cache, unsigned long int id)
|
||||||
|
{
|
||||||
|
struct identry *ent= get_id(cache, id);
|
||||||
|
|
||||||
|
if (!ent) {
|
||||||
|
struct passwd *pw = getpwuid((uid_t) id);
|
||||||
|
add_id(cache, pw ? pw->pw_name : NULL, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_gid(struct idcache *cache, unsigned long int id)
|
||||||
|
{
|
||||||
|
struct identry *ent = get_id(cache, id);
|
||||||
|
|
||||||
|
if (!ent) {
|
||||||
|
struct group *gr = getgrgid((gid_t) id);
|
||||||
|
add_id(cache, gr ? gr->gr_name : NULL, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ endif
|
||||||
if BUILD_NAMEI
|
if BUILD_NAMEI
|
||||||
usrbin_exec_PROGRAMS += namei
|
usrbin_exec_PROGRAMS += namei
|
||||||
dist_man_MANS += misc-utils/namei.1
|
dist_man_MANS += misc-utils/namei.1
|
||||||
namei_SOURCES = misc-utils/namei.c lib/strutils.c
|
namei_SOURCES = misc-utils/namei.c lib/strutils.c lib/idcache.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_WHEREIS
|
if BUILD_WHEREIS
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "widechar.h"
|
#include "widechar.h"
|
||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
#include "closestream.h"
|
#include "closestream.h"
|
||||||
|
#include "idcache.h"
|
||||||
|
|
||||||
#ifndef MAXSYMLINKS
|
#ifndef MAXSYMLINKS
|
||||||
#define MAXSYMLINKS 256
|
#define MAXSYMLINKS 256
|
||||||
|
@ -65,103 +66,10 @@ struct namei {
|
||||||
int noent; /* is this item not existing */
|
int noent; /* is this item not existing */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct idcache {
|
|
||||||
unsigned long int id;
|
|
||||||
char *name;
|
|
||||||
struct idcache *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int flags;
|
static int flags;
|
||||||
static int uwidth; /* maximal width of username */
|
|
||||||
static int gwidth; /* maximal width of groupname */
|
|
||||||
static struct idcache *gcache; /* groupnames */
|
static struct idcache *gcache; /* groupnames */
|
||||||
static struct idcache *ucache; /* usernames */
|
static struct idcache *ucache; /* usernames */
|
||||||
|
|
||||||
static struct idcache *
|
|
||||||
get_id(struct idcache *ic, unsigned long int id)
|
|
||||||
{
|
|
||||||
while(ic) {
|
|
||||||
if (ic->id == id)
|
|
||||||
return ic;
|
|
||||||
ic = ic->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_idcache(struct idcache *ic)
|
|
||||||
{
|
|
||||||
while(ic) {
|
|
||||||
struct idcache *next = ic->next;
|
|
||||||
free(ic->name);
|
|
||||||
free(ic);
|
|
||||||
ic = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_id(struct idcache **ic, char *name, unsigned long int id, int *width)
|
|
||||||
{
|
|
||||||
struct idcache *nc, *x;
|
|
||||||
int w = 0;
|
|
||||||
|
|
||||||
nc = xcalloc(1, sizeof(*nc));
|
|
||||||
nc->id = id;
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
#ifdef HAVE_WIDECHAR
|
|
||||||
wchar_t wc[LOGIN_NAME_MAX + 1];
|
|
||||||
|
|
||||||
if (mbstowcs(wc, name, LOGIN_NAME_MAX) > 0) {
|
|
||||||
wc[LOGIN_NAME_MAX] = '\0';
|
|
||||||
w = wcswidth(wc, LOGIN_NAME_MAX);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
w = strlen(name);
|
|
||||||
}
|
|
||||||
/* note, we ignore names with non-printable widechars */
|
|
||||||
if (w > 0)
|
|
||||||
nc->name = xstrdup(name);
|
|
||||||
else
|
|
||||||
xasprintf(&nc->name, "%lu", id);
|
|
||||||
|
|
||||||
for (x = *ic; x && x->next; x = x->next);
|
|
||||||
|
|
||||||
/* add 'nc' at end of the 'ic' list */
|
|
||||||
if (x)
|
|
||||||
x->next = nc;
|
|
||||||
else
|
|
||||||
*ic = nc;
|
|
||||||
if (w <= 0)
|
|
||||||
w = nc->name ? strlen(nc->name) : 0;
|
|
||||||
|
|
||||||
*width = *width < w ? w : *width;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_uid(unsigned long int id)
|
|
||||||
{
|
|
||||||
struct idcache *ic = get_id(ucache, id);
|
|
||||||
|
|
||||||
if (!ic) {
|
|
||||||
struct passwd *pw = getpwuid((uid_t) id);
|
|
||||||
add_id(&ucache, pw ? pw->pw_name : NULL, id, &uwidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_gid(unsigned long int id)
|
|
||||||
{
|
|
||||||
struct idcache *ic = get_id(gcache, id);
|
|
||||||
|
|
||||||
if (!ic) {
|
|
||||||
struct group *gr = getgrgid((gid_t) id);
|
|
||||||
add_id(&gcache, gr ? gr->gr_name : NULL, id, &gwidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_namei(struct namei *nm)
|
free_namei(struct namei *nm)
|
||||||
{
|
{
|
||||||
|
@ -254,8 +162,8 @@ new_namei(struct namei *parent, const char *path, const char *fname, int lev)
|
||||||
if (S_ISLNK(nm->st.st_mode))
|
if (S_ISLNK(nm->st.st_mode))
|
||||||
readlink_to_namei(nm, path);
|
readlink_to_namei(nm, path);
|
||||||
if (flags & NAMEI_OWNERS) {
|
if (flags & NAMEI_OWNERS) {
|
||||||
add_uid(nm->st.st_uid);
|
add_uid(ucache, nm->st.st_uid);
|
||||||
add_gid(nm->st.st_gid);
|
add_gid(gcache, nm->st.st_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & NAMEI_MNTS) && S_ISDIR(nm->st.st_mode)) {
|
if ((flags & NAMEI_MNTS) && S_ISDIR(nm->st.st_mode)) {
|
||||||
|
@ -371,7 +279,7 @@ print_namei(struct namei *nm, char *path)
|
||||||
if (flags & NAMEI_MODES)
|
if (flags & NAMEI_MODES)
|
||||||
blanks += 9;
|
blanks += 9;
|
||||||
if (flags & NAMEI_OWNERS)
|
if (flags & NAMEI_OWNERS)
|
||||||
blanks += uwidth + gwidth + 2;
|
blanks += ucache->width + gcache->width + 2;
|
||||||
if (!(flags & NAMEI_VERTICAL))
|
if (!(flags & NAMEI_VERTICAL))
|
||||||
blanks += 1;
|
blanks += 1;
|
||||||
blanks += nm->level * 2;
|
blanks += nm->level * 2;
|
||||||
|
@ -397,9 +305,9 @@ print_namei(struct namei *nm, char *path)
|
||||||
printf("%c", md[0]);
|
printf("%c", md[0]);
|
||||||
|
|
||||||
if (flags & NAMEI_OWNERS) {
|
if (flags & NAMEI_OWNERS) {
|
||||||
printf(" %-*s", uwidth,
|
printf(" %-*s", ucache->width,
|
||||||
get_id(ucache, nm->st.st_uid)->name);
|
get_id(ucache, nm->st.st_uid)->name);
|
||||||
printf(" %-*s", gwidth,
|
printf(" %-*s", gcache->width,
|
||||||
get_id(gcache, nm->st.st_gid)->name);
|
get_id(gcache, nm->st.st_gid)->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,6 +413,13 @@ main(int argc, char **argv)
|
||||||
usage(EXIT_FAILURE);
|
usage(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ucache = new_idcache();
|
||||||
|
if (!ucache)
|
||||||
|
err(EXIT_FAILURE, _("failed to allocate UID cache"));
|
||||||
|
gcache = new_idcache();
|
||||||
|
if (!gcache)
|
||||||
|
err(EXIT_FAILURE, _("failed to allocate GID cache"));
|
||||||
|
|
||||||
for(; optind < argc; optind++) {
|
for(; optind < argc; optind++) {
|
||||||
char *path = argv[optind];
|
char *path = argv[optind];
|
||||||
struct namei *nm = NULL;
|
struct namei *nm = NULL;
|
||||||
|
|
Loading…
Reference in New Issue