Sanitize python object -> tag number exception handling
[platform/upstream/rpm.git] / lib / misc.c
1 /**
2  * \file lib/misc.c
3  */
4
5 #include "system.h"
6
7 /* just to put a marker in librpm.a */
8 const char * const RPMVERSION = VERSION;
9
10 #include <rpm/rpmlog.h>
11 #include <rpm/rpmstring.h>
12
13 #include "lib/misc.h"
14
15 #include "debug.h"
16
17 /* unameToUid(), uidTouname() and the group variants are really poorly
18    implemented. They really ought to use hash tables. I just made the
19    guess that most files would be owned by root or the same person/group
20    who owned the last file. Those two values are cached, everything else
21    is looked up via getpw() and getgr() functions.  If this performs
22    too poorly I'll have to implement it properly :-( */
23
24 int unameToUid(const char * thisUname, uid_t * uid)
25 {
26 static char * lastUname = NULL;
27     static size_t lastUnameLen = 0;
28     static size_t lastUnameAlloced;
29     static uid_t lastUid;
30     struct passwd * pwent;
31     size_t thisUnameLen;
32
33     if (!thisUname) {
34         lastUnameLen = 0;
35         return -1;
36     } else if (rstreq(thisUname, "root")) {
37         *uid = 0;
38         return 0;
39     }
40
41     thisUnameLen = strlen(thisUname);
42     if (lastUname == NULL || thisUnameLen != lastUnameLen ||
43         !rstreq(thisUname, lastUname))
44     {
45         if (lastUnameAlloced < thisUnameLen + 1) {
46             lastUnameAlloced = thisUnameLen + 10;
47             lastUname = xrealloc(lastUname, lastUnameAlloced);  /* XXX memory leak */
48         }
49         strcpy(lastUname, thisUname);
50
51         pwent = getpwnam(thisUname);
52         if (pwent == NULL) {
53             /* FIX: shrug */
54             endpwent();
55             pwent = getpwnam(thisUname);
56             if (pwent == NULL) return -1;
57         }
58
59         lastUid = pwent->pw_uid;
60     }
61
62     *uid = lastUid;
63
64     return 0;
65 }
66
67 int gnameToGid(const char * thisGname, gid_t * gid)
68 {
69 static char * lastGname = NULL;
70     static size_t lastGnameLen = 0;
71     static size_t lastGnameAlloced;
72     static gid_t lastGid;
73     size_t thisGnameLen;
74     struct group * grent;
75
76     if (thisGname == NULL) {
77         lastGnameLen = 0;
78         return -1;
79     } else if (rstreq(thisGname, "root")) {
80         *gid = 0;
81         return 0;
82     }
83
84     thisGnameLen = strlen(thisGname);
85     if (lastGname == NULL || thisGnameLen != lastGnameLen ||
86         !rstreq(thisGname, lastGname))
87     {
88         if (lastGnameAlloced < thisGnameLen + 1) {
89             lastGnameAlloced = thisGnameLen + 10;
90             lastGname = xrealloc(lastGname, lastGnameAlloced);  /* XXX memory leak */
91         }
92         strcpy(lastGname, thisGname);
93
94         grent = getgrnam(thisGname);
95         if (grent == NULL) {
96             /* FIX: shrug */
97             endgrent();
98             grent = getgrnam(thisGname);
99             if (grent == NULL) {
100                 /* XXX The filesystem package needs group/lock w/o getgrnam. */
101                 if (rstreq(thisGname, "lock")) {
102                     *gid = lastGid = 54;
103                     return 0;
104                 } else
105                 if (rstreq(thisGname, "mail")) {
106                     *gid = lastGid = 12;
107                     return 0;
108                 } else
109                 return -1;
110             }
111         }
112         lastGid = grent->gr_gid;
113     }
114
115     *gid = lastGid;
116
117     return 0;
118 }
119
120 const char * uidToUname(uid_t uid)
121 {
122     static uid_t lastUid = (uid_t) -1;
123 static char * lastUname = NULL;
124     static size_t lastUnameLen = 0;
125
126     if (uid == (uid_t) -1) {
127         lastUid = (uid_t) -1;
128         return NULL;
129     } else if (uid == (uid_t) 0) {
130         return "root";
131     } else if (uid == lastUid) {
132         return lastUname;
133     } else {
134         struct passwd * pwent = getpwuid(uid);
135         size_t len;
136
137         if (pwent == NULL) return NULL;
138
139         lastUid = uid;
140         len = strlen(pwent->pw_name);
141         if (lastUnameLen < len + 1) {
142             lastUnameLen = len + 20;
143             lastUname = xrealloc(lastUname, lastUnameLen);
144         }
145         strcpy(lastUname, pwent->pw_name);
146
147         return lastUname;
148     }
149 }
150
151 const char * gidToGname(gid_t gid)
152 {
153     static gid_t lastGid = (gid_t) -1;
154 static char * lastGname = NULL;
155     static size_t lastGnameLen = 0;
156
157     if (gid == (gid_t) -1) {
158         lastGid = (gid_t) -1;
159         return NULL;
160     } else if (gid == (gid_t) 0) {
161         return "root";
162     } else if (gid == lastGid) {
163         return lastGname;
164     } else {
165         struct group * grent = getgrgid(gid);
166         size_t len;
167
168         if (grent == NULL) return NULL;
169
170         lastGid = gid;
171         len = strlen(grent->gr_name);
172         if (lastGnameLen < len + 1) {
173             lastGnameLen = len + 20;
174             lastGname = xrealloc(lastGname, lastGnameLen);
175         }
176         strcpy(lastGname, grent->gr_name);
177
178         return lastGname;
179     }
180 }