1 /* $Copyright: $
2  * Copyright (c) 1996 - 2018 by Steve Baker (ice@mama.indstate.edu)
3  * All Rights reserved
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "tree.h"
20 
21 /* Faster uid/gid -> name lookup with hash(tm)(r)(c) tables! */
22 #define HASH(x)		((x)&255)
23 struct xtable *gtable[256], *utable[256];
24 
25 #define inohash(x)	((x)&255)
26 struct inotable *itable[256];
27 
uidtoname(uid_t uid)28 char *uidtoname(uid_t uid)
29 {
30   struct xtable *o, *p, *t;
31   struct passwd *ent;
32   char ubuf[32];
33   int uent = HASH(uid);
34 
35   for(o = p = utable[uent]; p ; p=p->nxt) {
36     if (uid == p->xid) return p->name;
37     else if (uid < p->xid) break;
38     o = p;
39   }
40   /* Not found, do a real lookup and add to table */
41   t = xmalloc(sizeof(struct xtable));
42   if ((ent = getpwuid(uid)) != NULL) t->name = scopy(ent->pw_name);
43   else {
44     snprintf(ubuf,30,"%d",uid);
45     ubuf[31] = 0;
46     t->name = scopy(ubuf);
47   }
48   t->xid = uid;
49   t->nxt = p;
50   if (p == utable[uent]) utable[uent] = t;
51   else o->nxt = t;
52   return t->name;
53 }
54 
gidtoname(gid_t gid)55 char *gidtoname(gid_t gid)
56 {
57   struct xtable *o, *p, *t;
58   struct group *ent;
59   char gbuf[32];
60   int gent = HASH(gid);
61 
62   for(o = p = gtable[gent]; p ; p=p->nxt) {
63     if (gid == p->xid) return p->name;
64     else if (gid < p->xid) break;
65     o = p;
66   }
67   /* Not found, do a real lookup and add to table */
68   t = xmalloc(sizeof(struct xtable));
69   if ((ent = getgrgid(gid)) != NULL) t->name = scopy(ent->gr_name);
70   else {
71     snprintf(gbuf,30,"%d",gid);
72     gbuf[31] = 0;
73     t->name = scopy(gbuf);
74   }
75   t->xid = gid;
76   t->nxt = p;
77   if (p == gtable[gent]) gtable[gent] = t;
78   else o->nxt = t;
79   return t->name;
80 }
81 
82 /* Record inode numbers of followed sym-links to avoid refollowing them */
saveino(ino_t inode,dev_t device)83 void saveino(ino_t inode, dev_t device)
84 {
85   struct inotable *it, *ip, *pp;
86   int hp = inohash(inode);
87 
88   for(pp = ip = itable[hp];ip;ip = ip->nxt) {
89     if (ip->inode > inode) break;
90     if (ip->inode == inode && ip->device >= device) break;
91     pp = ip;
92   }
93 
94   if (ip && ip->inode == inode && ip->device == device) return;
95 
96   it = xmalloc(sizeof(struct inotable));
97   it->inode = inode;
98   it->device = device;
99   it->nxt = ip;
100   if (ip == itable[hp]) itable[hp] = it;
101   else pp->nxt = it;
102 }
103 
findino(ino_t inode,dev_t device)104 int findino(ino_t inode, dev_t device)
105 {
106   struct inotable *it;
107 
108   for(it=itable[inohash(inode)]; it; it=it->nxt) {
109     if (it->inode > inode) break;
110     if (it->inode == inode && it->device >= device) break;
111   }
112 
113   if (it && it->inode == inode && it->device == device) return TRUE;
114   return FALSE;
115 }
116