1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <pwd.h>
5 #include <grp.h>
6 #include "deco.h"
7 
8 #define NAMLEN 9
9 #define QUANT  20
10 
11 struct table {
12 	int key;
13 	char name [NAMLEN];
14 };
15 
16 static struct table *uname;
17 static struct table *grname;
18 static nuname, ngrname;
19 
20 static char root[] = "/";
21 char *home = root;
22 
compare(const void * arg1,const void * arg2)23 static int compare (const void *arg1, const void *arg2)
24 {
25 	const struct table *a = arg1;
26 	const struct table *b = arg2;
27 	register ak = a->key, bk = b->key;
28 
29 	return (ak<bk ? -1 : ak>bk ? 1 : 0);
30 }
31 
initpw()32 static void initpw ()
33 {
34 	register t, tt;
35 	register struct passwd *pw;
36 	register struct group *gr;
37 
38 	setpwent ();
39 	for (t=0; (pw=getpwent()); ) {
40 		mcheck (uname, struct table *, nuname, QUANT, t);
41 		if (pw->pw_uid == uid) {
42 			if (home != root)
43 				free (home);
44 			home = malloc (strlen (pw->pw_dir) + 1);
45 			strcpy (home, pw->pw_dir);
46 		}
47 		for (tt=0; tt<t; ++tt)
48 			if (uname[tt].key == pw->pw_uid)
49 				break;
50 		if (tt < t)
51 			continue;	/* ignore entry with same uid */
52 		uname[t].key = pw->pw_uid;
53 		strncpy (uname[t].name, pw->pw_name, NAMLEN-1);
54 		uname[t].name[NAMLEN-1] = 0;
55 		++t;
56 	}
57 	endpwent ();
58 	nuname = t;
59 	if (nuname)
60 		qsort ((char *) uname, (unsigned) nuname, sizeof (struct table), compare);
61 	setgrent ();
62 	for (t=0; (gr=getgrent()); ) {
63 		mcheck (grname, struct table *, ngrname, QUANT, t);
64 		for (tt=0; tt<t; ++tt)
65 			if (grname[tt].key == gr->gr_gid)
66 				break;
67 		if (tt < t)
68 			continue;       /* ignore entry with same gid */
69 		grname[t].key = gr->gr_gid;
70 		strncpy (grname[t].name, gr->gr_name, NAMLEN-1);
71 		grname[t].name[NAMLEN-1] = 0;
72 		++t;
73 	}
74 	endgrent ();
75 	ngrname = t;
76 	if (ngrname) {
77 		qsort ((char *) grname, (unsigned) ngrname, sizeof (struct table), compare);
78 	}
79 }
80 
tabsearch(int key,struct table * base,int nel)81 static struct table *tabsearch (int key, struct table *base, int nel)
82 {
83 	struct table *last;     /* Last element in table */
84 	register struct table *p;
85 
86 	if (! nel)
87 		return ((struct table *) 0);
88 	last = base + (nel - 1);
89 	while (last >= base) {
90 		p = base + ((last - base)/2);
91 		if (p->key == key)
92 			return (p);	/* Key found */
93 		if (p->key > key)
94 			last = p - 1;
95 		else
96 			base = p + 1;
97 	}
98 	return ((struct table *) 0);    /* Key not found */
99 }
100 
username(int u)101 char *username (int u)
102 {
103 	register struct table *t;
104 	static char buf [NAMLEN];
105 
106 	if (! nuname)
107 		initpw ();
108 	if ((t = tabsearch (u, uname, nuname)))
109 		return (t->name);
110 	sprintf (buf, "%d", u);
111 	return (buf);
112 }
113 
groupname(int g)114 char *groupname (int g)
115 {
116 	register struct table *t;
117 	static char buf [NAMLEN];
118 
119 	if (! ngrname)
120 		initpw ();
121 	if ((t = tabsearch (g, grname, ngrname)))
122 		return (t->name);
123 	sprintf (buf, "%d", g);
124 	return (buf);
125 }
126