|
|
researchv10 Norman
/*
* make an ID map for the file server library
* takes a /etc/passwd-like file and an optional `exception' list
* of explicit mappings;
* returns a list of local name-ID mappings to be combined
* with those from the client to make an ID-ID map.
*/
#include <stdio.h>
#include <ctype.h>
#include "rf.h"
static Idmap *exmerge();
static int nextid();
extern char *malloc(), *realloc();
Idmap *
rfmkidmap(file, ex)
char *file;
Namemap *ex;
{
Idmap *map;
register Idmap *cur;
register int size;
register Idmap *last;
int curoff;
FILE *fp;
if ((fp = fopen(file, "r")) == NULL)
rfpanic("can't open map %s\n", file);
size = 100;
if ((map = (Idmap *)malloc(size*sizeof(Idmap))) == NULL)
rfpanic("out of mem for %s map\n", file);
last = &map[size - 1];
for (cur = map;; cur++) {
if (cur >= last) {
curoff = cur - map; /* realloc may move map */
size += 100;
if ((map = (Idmap *)realloc((char *)map, size*sizeof(Idmap))) == NULL)
rfpanic("out of mem for %s map\n", file);
last = &map[size - 1];
cur = &map[curoff];
}
if (nextid(cur, fp) == 0)
break;
}
cur->name[0] = 0;
fclose(fp);
return (exmerge(map, last, ex));
}
/*
* pick out the next name and ID from the file
* name:junk:number:junk until newline
* this matches /etc/passwd and /etc/group,
* and is simple enough to fake up
*/
static
nextid(cur, fp)
Idmap *cur;
register FILE *fp;
{
register char *p;
char buf[150]; /* assume big enough for now */
for (;;) {
if (fgets(buf, sizeof(buf), fp) == NULL)
return (0); /* EOF */
p = buf;
while (*p && *p != ':')
p++;
if (*p == 0)
continue;
*p++ = 0;
strncpy(cur->name, buf, sizeof(cur->name)-1);
cur->name[sizeof(cur->name)-1] = 0;
while (*p && *p != ':')
p++;
if (*p == 0)
continue;
p++;
if (!isdigit(*p) && *p != '-')
continue;
cur->id = atoi(p);
return (1);
}
}
static Idmap *
exmerge(map, last, ex)
Idmap *map, *last;
Namemap *ex;
{
register Idmap *lp;
register Namemap *ep;
int size, curoff;
static Namemap nilex;
if (ex == NULL)
ex = &nilex;
for (ep = ex; ep->cname[0]; ep++) {
if (ep->sname[0] == 0)
ep->sid = RFNOID;
else
ep->sid = _rflookid(map, ep->sname);
}
for (lp = map; lp->name[0]; lp++)
for (ep = ex; ep->cname[0]; ep++) {
if (ep->cname[0] != lp->name[0]) /* hash */
continue;
if (strcmp(ep->cname, lp->name) == 0) {
lp->id = ep->sid;
ep->sid = RFNOID;
}
}
/*
* add client names not in local file
* lp was left at the end of the map
*/
for (ep = ex; ep->cname[0]; ep++) {
if (ep->sid == RFNOID) /* no need to enter */
continue;
if (lp >= last) {
curoff = lp - map;
size = curoff + 10;
if ((map = (Idmap *)realloc((char *)map,
size*sizeof(Idmap))) == NULL)
rfpanic("out of mem merging except\n");
last = &map[size - 1];
lp = &map[curoff];
}
strncpy(lp->name, ep->cname, sizeof(lp->name)-1);
lp->id = ep->sid;
lp++;
}
lp->name[0] = 0;
return (map);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.