home *** CD-ROM | disk | FTP | other *** search
- #include <grp.h>
- #include <pwd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
-
- #include "idmap.h"
-
- struct idMap_s {
- struct idElement * byId;
- int numEntries;
- };
-
- typedef struct idMap_s * idMap;
-
- struct idElement {
- long int id;
- char * name;
- };
-
- typedef void * (*iterFn)(void);
- typedef int (*infoFn)(void * item, struct idElement * el);
-
- static idMap uidMap = NULL;
- static idMap gidMap = NULL;
-
- static int idCmp(const void * a, const void * b) {
- const struct idElement * one = a;
- const struct idElement * two = b;
-
- if (one->id < two->id)
- return -1;
- else if (one->id > two->id)
- return 1;
-
- return 0;
- }
-
- static idMap readmap(iterFn fn, infoFn info) {
- idMap map;
- int alloced;
- void * res;
- struct idElement * newEntries;
-
- map = malloc(sizeof(*map));
- if (!map) {
- return NULL;
- }
-
- alloced = 5;
- map->byId = malloc(sizeof(*map->byId) * alloced);
- if (!map->byId) {
- free(map);
- return NULL;
- }
- map->numEntries = 0;
-
- while ((res = fn())) {
- if (map->numEntries == alloced) {
- alloced += 5;
- newEntries = realloc(map->byId,
- sizeof(*map->byId) * alloced);
- if (!newEntries) {
- /* FIXME: this doesn't free the id names */
- free(map->byId);
- free(map);
- return NULL;
- }
-
- map->byId = newEntries;
- }
-
- if (info(res, map->byId + map->numEntries++)) {
- /* FIXME: this doesn't free the id names */
- free(map->byId);
- free(map);
- return NULL;
- }
- }
-
- map->byId = realloc(map->byId,
- sizeof(*map->byId) * map->numEntries);
-
- qsort(map->byId, map->numEntries, sizeof(*map->byId), idCmp);
-
- return map;
- }
-
- static int pwInfo(struct passwd * pw, struct idElement * el) {
- el->id = pw->pw_uid;
- el->name = strdup(pw->pw_name);
-
- return el->name == NULL;
- }
-
- static int grInfo(struct group * gr, struct idElement * el) {
- el->id = gr->gr_gid;
- el->name = strdup(gr->gr_name);
-
- return el->name == NULL;
- }
-
- idMap readUIDmap(void) {
- idMap result;
-
- result = readmap((void *) getpwent, (void *) pwInfo);
- endpwent();
-
- return result;
- }
-
- idMap readGIDmap(void) {
- idMap result;
-
- result = readmap((void *) getgrent, (void *) grInfo);
- endgrent();
-
- return result;
- }
-
- char * idSearchByUid(long int id) {
- struct idElement el = { id, NULL };
- struct idElement * match;
-
- match = bsearch(&el, uidMap->byId, uidMap->numEntries,
- sizeof(*uidMap->byId), idCmp);
-
- if (match) return match->name; else return NULL;
- }
-
- char * idSearchByGid(long int id) {
- struct idElement el = { id, NULL };
- struct idElement * match;
-
- match = bsearch(&el, gidMap->byId, gidMap->numEntries,
- sizeof(*gidMap->byId), idCmp);
-
- if (match) return match->name; else return NULL;
- }
-
- int idInit(void) {
- if (!(uidMap = readUIDmap())) return 1;
- if (!(gidMap = readGIDmap())) return 1;
-
- return 0;
- }
-