Move low level support routines to librpmio.
[tools/librpm-tizen.git] / rpmio / ugid.c
1 #include "system.h"
2
3 #include "ugid.h"
4
5 /* unameToUid(), uidTouname() and the group variants are really poorly
6    implemented. They really ought to use hash tables. I just made the
7    guess that most files would be owned by root or the same person/group
8    who owned the last file. Those two values are cached, everything else
9    is looked up via getpw() and getgr() functions.  If this performs
10    too poorly I'll have to implement it properly :-( */
11
12 int unameToUid(const char * thisUname, uid_t * uid)
13 {
14     /*@only@*/ static char * lastUname = NULL;
15     static int lastUnameLen = 0;
16     static int lastUnameAlloced;
17     static uid_t lastUid;
18     struct passwd * pwent;
19     int thisUnameLen;
20
21     if (!thisUname) {
22         lastUnameLen = 0;
23         return -1;
24     } else if (!strcmp(thisUname, "root")) {
25         *uid = 0;
26         return 0;
27     }
28
29     thisUnameLen = strlen(thisUname);
30     if (!lastUname || thisUnameLen != lastUnameLen ||
31         strcmp(thisUname, lastUname)) {
32         if (lastUnameAlloced < thisUnameLen + 1) {
33             lastUnameAlloced = thisUnameLen + 10;
34             lastUname = xrealloc(lastUname, lastUnameAlloced);  /* XXX memory leak */
35         }
36         strcpy(lastUname, thisUname);
37
38         pwent = getpwnam(thisUname);
39         if (!pwent) {
40             endpwent();
41             pwent = getpwnam(thisUname);
42             if (!pwent) return -1;
43         }
44
45         lastUid = pwent->pw_uid;
46     }
47
48     *uid = lastUid;
49
50     return 0;
51 }
52
53 int gnameToGid(const char * thisGname, gid_t * gid)
54 {
55     /*@only@*/ static char * lastGname = NULL;
56     static int lastGnameLen = 0;
57     static int lastGnameAlloced;
58     static uid_t lastGid;
59     int thisGnameLen;
60     struct group * grent;
61
62     if (!thisGname) {
63         lastGnameLen = 0;
64         return -1;
65     } else if (!strcmp(thisGname, "root")) {
66         *gid = 0;
67         return 0;
68     }
69
70     thisGnameLen = strlen(thisGname);
71     if (!lastGname || thisGnameLen != lastGnameLen ||
72         strcmp(thisGname, lastGname)) {
73         if (lastGnameAlloced < thisGnameLen + 1) {
74             lastGnameAlloced = thisGnameLen + 10;
75             lastGname = xrealloc(lastGname, lastGnameAlloced);  /* XXX memory leak */
76         }
77         strcpy(lastGname, thisGname);
78
79         grent = getgrnam(thisGname);
80         if (!grent) {
81             endgrent();
82             grent = getgrnam(thisGname);
83             if (!grent) return -1;
84         }
85         lastGid = grent->gr_gid;
86     }
87
88     *gid = lastGid;
89
90     return 0;
91 }
92
93 char * uidToUname(uid_t uid)
94 {
95     static int lastUid = -1;
96     /*@only@*/ static char * lastUname = NULL;
97     static int lastUnameLen = 0;
98     struct passwd * pwent;
99     int len;
100
101     if (uid == (uid_t) -1) {
102         lastUid = -1;
103         return NULL;
104     } else if (!uid) {
105         return "root";
106     } else if (uid == lastUid) {
107         return lastUname;
108     } else {
109         pwent = getpwuid(uid);
110         if (!pwent) return NULL;
111
112         lastUid = uid;
113         len = strlen(pwent->pw_name);
114         if (lastUnameLen < len + 1) {
115             lastUnameLen = len + 20;
116             lastUname = xrealloc(lastUname, lastUnameLen);
117         }
118         strcpy(lastUname, pwent->pw_name);
119
120         return lastUname;
121     }
122 }
123
124 char * gidToGname(gid_t gid)
125 {
126     static int lastGid = -1;
127     /*@only@*/ static char * lastGname = NULL;
128     static int lastGnameLen = 0;
129     struct group * grent;
130     int len;
131
132     if (gid == (gid_t) -1) {
133         lastGid = -1;
134         return NULL;
135     } else if (!gid) {
136         return "root";
137     } else if (gid == lastGid) {
138         return lastGname;
139     } else {
140         grent = getgrgid(gid);
141         if (!grent) return NULL;
142
143         lastGid = gid;
144         len = strlen(grent->gr_name);
145         if (lastGnameLen < len + 1) {
146             lastGnameLen = len + 20;
147             lastGname = xrealloc(lastGname, lastGnameLen);
148         }
149         strcpy(lastGname, grent->gr_name);
150
151         return lastGname;
152     }
153 }