1// Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com
2// Note: most likely none of his code remains
3//
4// Copyright 2002, Albert Cahalan
5//
6// This file is placed under the conditions of the GNU Library
7// General Public License, version 2, or any later version.
8// See file COPYING for information on distribution conditions.
9
10#include <stdio.h>
11#include <sys/types.h>
12#include <stdlib.h>
13#include <pwd.h>
14#include "alloc.h"
15#include "pwcache.h"
16#include <grp.h>
17
18// might as well fill cache lines... else we waste memory anyway
19
20#define	HASHSIZE	64	/* power of 2 */
21#define	HASH(x)		((x) & (HASHSIZE - 1))
22
23#define NAMESIZE	20
24#define NAMELENGTH	"19"
25
26static struct pwbuf {
27	struct pwbuf *next;
28	uid_t uid;
29	char name[NAMESIZE];
30} *pwhash[HASHSIZE];
31
32char *user_from_uid(uid_t uid)
33{
34	struct pwbuf **p;
35	struct passwd *pw;
36
37	p = &pwhash[HASH(uid)];
38	while (*p) {
39		if ((*p)->uid == uid)
40			return ((*p)->name);
41		p = &(*p)->next;
42	}
43	*p = (struct pwbuf *)xmalloc(sizeof(struct pwbuf));
44	(*p)->uid = uid;
45	if ((pw = getpwuid(uid)) == NULL)
46		sprintf((*p)->name, "#%d", uid);
47	else
48		sprintf((*p)->name, "%-." NAMELENGTH "s", pw->pw_name);
49	(*p)->next = NULL;
50	return ((*p)->name);
51}
52
53static struct grpbuf {
54	struct grpbuf *next;
55	gid_t gid;
56	char name[NAMESIZE];
57} *grphash[HASHSIZE];
58
59char *group_from_gid(gid_t gid)
60{
61	struct grpbuf **g;
62	struct group *gr;
63
64	g = &grphash[HASH(gid)];
65	while (*g) {
66		if ((*g)->gid == gid)
67			return ((*g)->name);
68		g = &(*g)->next;
69	}
70	*g = (struct grpbuf *)malloc(sizeof(struct grpbuf));
71	(*g)->gid = gid;
72	if ((gr = getgrgid(gid)) == NULL)
73		sprintf((*g)->name, "#%d", gid);
74	else
75		sprintf((*g)->name, "%-." NAMELENGTH "s", gr->gr_name);
76	(*g)->next = NULL;
77	return ((*g)->name);
78}
79