home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / idmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-07  |  2.8 KB  |  147 lines

  1. #include <grp.h>
  2. #include <pwd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6.  
  7. #include "idmap.h"
  8.  
  9. struct idMap_s {
  10.     struct idElement * byId;
  11.     int numEntries;
  12. };
  13.  
  14. typedef struct idMap_s * idMap;
  15.  
  16. struct idElement {
  17.     long int id;
  18.     char * name;
  19. };
  20.  
  21. typedef void * (*iterFn)(void);
  22. typedef int (*infoFn)(void * item, struct idElement * el);
  23.  
  24. static idMap uidMap = NULL;
  25. static idMap gidMap = NULL;
  26.  
  27. static int idCmp(const void * a, const void * b) {
  28.     const struct idElement * one = a;
  29.     const struct idElement * two = b;
  30.  
  31.     if (one->id < two->id)
  32.     return -1;
  33.     else if (one->id > two->id)
  34.     return 1;
  35.  
  36.     return 0;
  37. }
  38.  
  39. static idMap readmap(iterFn fn, infoFn info) {
  40.     idMap map;
  41.     int alloced;
  42.     void * res;
  43.     struct idElement * newEntries;
  44.  
  45.     map = malloc(sizeof(*map));
  46.     if (!map) {
  47.     return NULL;
  48.     }
  49.  
  50.     alloced = 5;
  51.     map->byId = malloc(sizeof(*map->byId) * alloced);
  52.     if (!map->byId) {
  53.     free(map);
  54.     return NULL;
  55.     }
  56.     map->numEntries = 0;
  57.  
  58.     while ((res = fn())) {
  59.     if (map->numEntries == alloced) {
  60.         alloced += 5;
  61.         newEntries = realloc(map->byId, 
  62.                     sizeof(*map->byId) * alloced);
  63.         if (!newEntries) {
  64.         /* FIXME: this doesn't free the id names */
  65.         free(map->byId);
  66.         free(map);
  67.         return NULL;
  68.         }
  69.  
  70.         map->byId = newEntries;
  71.     }
  72.  
  73.     if (info(res, map->byId + map->numEntries++)) {
  74.         /* FIXME: this doesn't free the id names */
  75.         free(map->byId);
  76.         free(map);
  77.         return NULL;
  78.     }
  79.     }
  80.  
  81.     map->byId = realloc(map->byId, 
  82.                 sizeof(*map->byId) * map->numEntries);
  83.  
  84.     qsort(map->byId, map->numEntries, sizeof(*map->byId), idCmp);
  85.  
  86.     return map;
  87. }
  88.  
  89. static int pwInfo(struct passwd * pw, struct idElement * el) {
  90.     el->id = pw->pw_uid;
  91.     el->name = strdup(pw->pw_name);
  92.  
  93.     return el->name == NULL;
  94. }
  95.  
  96. static int grInfo(struct group * gr, struct idElement * el) {
  97.     el->id = gr->gr_gid;
  98.     el->name = strdup(gr->gr_name);
  99.  
  100.     return el->name == NULL;
  101. }
  102.  
  103. idMap readUIDmap(void) {
  104.     idMap result;
  105.  
  106.     result = readmap((void *) getpwent, (void *) pwInfo);
  107.     endpwent();
  108.  
  109.     return result;
  110. }
  111.  
  112. idMap readGIDmap(void) {
  113.     idMap result;
  114.  
  115.     result = readmap((void *) getgrent, (void *) grInfo);
  116.     endgrent();
  117.  
  118.     return result;
  119. }
  120.  
  121. char * idSearchByUid(long int id) {
  122.     struct idElement el = { id, NULL };
  123.     struct idElement * match;
  124.  
  125.     match = bsearch(&el, uidMap->byId, uidMap->numEntries, 
  126.            sizeof(*uidMap->byId), idCmp);
  127.  
  128.     if (match) return match->name; else return NULL;
  129. }
  130.  
  131. char * idSearchByGid(long int id) {
  132.     struct idElement el = { id, NULL };
  133.     struct idElement * match;
  134.  
  135.     match = bsearch(&el, gidMap->byId, gidMap->numEntries, 
  136.            sizeof(*gidMap->byId), idCmp);
  137.  
  138.     if (match) return match->name; else return NULL;
  139. }
  140.  
  141. int idInit(void) {
  142.     if (!(uidMap = readUIDmap())) return 1;
  143.     if (!(gidMap = readGIDmap())) return 1;
  144.  
  145.     return 0;
  146. }
  147.