static int GetCellNT(struct afsconf_dir *adir);
#endif
static int GetCellUnix(struct afsconf_dir *adir);
-static int afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
- char clones[]);
+static int afsconf_OpenInternal(struct afsconf_dir *adir);
static int ParseHostLine(char *aline, struct sockaddr_in *addr,
- char *aname, char *aclone);
+ char *aname, char *aclone /* boolean */);
static int ParseCellLine(char *aline, char *aname,
char *alname);
static int afsconf_CloseInternal(struct afsconf_dir *adir);
if (aname == NULL || aname[0] == '\0')
return -1;
-#if defined(AFS_OSF_ENV)
- ts = getservbyname(aname, "");
-#else
ts = (struct servent *) getservbyname(aname, NULL);
-#endif
if (ts) {
/* we found it in /etc/services, so we use this value */
return ts->s_port; /* already in network byte order */
/* NT client CellServDB has different file name than NT server or Unix */
if (_afsconf_IsClientConfigDirectory(adir->name)) {
if (!afssw_GetClientCellServDBDir(&p)) {
- asprintf(path, "%s/%s", p, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
+ if (asprintf(path, "%s/%s", p, AFSDIR_CELLSERVDB_FILE_NTCLIENT) < 0)
+ *path = NULL;
free(p);
} else {
- asprintf(path, "%s/%s", adir->name, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
+ if (asprintf(path, "%s/%s", adir->name,
+ AFSDIR_CELLSERVDB_FILE_NTCLIENT) < 0)
+ *path = NULL;
}
} else {
- asprintf(path, "%s/%s", adir->name, AFSDIR_CELLSERVDB_FILE);
+ if (asprintf(path, "%s/%s", adir->name, AFSDIR_CELLSERVDB_FILE) < 0)
+ *path = NULL;
}
return;
}
static void
_afsconf_CellServDBPath(struct afsconf_dir *adir, char **path)
{
- asprintf(path, "%s/%s", adir->name, AFSDIR_CELLSERVDB_FILE);
+ if (asprintf(path, "%s/%s", adir->name, AFSDIR_CELLSERVDB_FILE) < 0)
+ *path = NULL;
}
#endif /* AFS_NT40_ENV */
int
_afsconf_UpToDate(struct afsconf_dir *adir)
{
- char *cellservDB;
struct stat tstat;
int code;
time_t now = time(0);
- if (adir->timeCheck == now) {
+ if (adir->timeRead && (adir->timeCheck == now)) {
return 1; /* stat no more than once a second */
}
adir->timeCheck = now;
- _afsconf_CellServDBPath(adir, &cellservDB);
- if (cellservDB == NULL)
+ if (adir->cellservDB == NULL)
return 0;
- code = stat(cellservDB, &tstat);
- free(cellservDB);
+ code = stat(adir->cellservDB, &tstat);
if (code < 0)
return 0; /* Can't throw the error, so just say we're not up to date */
int
_afsconf_Touch(struct afsconf_dir *adir)
{
- char *cellservDB;
int code;
#ifndef AFS_NT40_ENV
struct timeval tvp[2];
adir->timeRead = 0; /* just in case */
adir->timeCheck = 0;
- _afsconf_CellServDBPath(adir, &cellservDB);
- if (cellservDB == NULL)
+ if (adir->cellservDB == NULL)
return ENOMEM;
#ifdef AFS_NT40_ENV
- code = _utime(cellservDB, NULL);
+ code = _utime(adir->cellservDB, NULL);
#else
gettimeofday(&tvp[0], NULL);
tvp[1] = tvp[0];
- code = utimes(cellservDB, tvp);
+ code = utimes(adir->cellservDB, tvp);
#endif /* AFS_NT40_ENV */
- free(cellservDB);
return code;
}
tdir = calloc(1, sizeof(struct afsconf_dir));
tdir->name = strdup(adir);
- code = afsconf_OpenInternal(tdir, 0, 0);
+ code = afsconf_OpenInternal(tdir);
if (code) {
char *afsconf_path, afs_confdir[128];
/* The "AFSCONF" environment (or contents of "/.AFSCONF") will be typically set to something like "/afs/<cell>/common/etc" where, by convention, the default files for "ThisCell" and "CellServDB" will reside; note that a major drawback is that a given afs client on that cell may NOT contain the same contents... */
char *home_dir;
afsconf_FILE *fp;
- size_t len;
+ size_t len = 0;
+ int r;
if (!(home_dir = getenv("HOME"))) {
/* Our last chance is the "/.AFSCONF" file */
if (fp == 0)
goto fail;
- fgets(afs_confdir, 128, fp);
- fclose(fp);
} else {
char *pathname = NULL;
- asprintf(&pathname, "%s/%s", home_dir, ".AFSCONF");
- if (pathname == NULL)
+ r = asprintf(&pathname, "%s/%s", home_dir, ".AFSCONF");
+ if (r < 0 || pathname == NULL)
goto fail;
fp = fopen(pathname, "r");
if (fp == 0)
goto fail;
}
- fgets(afs_confdir, 128, fp);
- fclose(fp);
}
- len = strlen(afs_confdir);
+ if (fgets(afs_confdir, 128, fp) != NULL)
+ len = strlen(afs_confdir);
+ fclose(fp);
if (len == 0)
goto fail;
afsconf_path = afs_confdir;
}
tdir->name = strdup(afsconf_path);
- code = afsconf_OpenInternal(tdir, 0, 0);
+ code = afsconf_OpenInternal(tdir);
if (code) {
free(tdir->name);
goto fail;
static int
-afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
- char clones[])
+afsconf_OpenInternal(struct afsconf_dir *adir)
{
afsconf_FILE *tf;
char *tp, *bp;
afs_int32 i;
char tbuffer[256];
struct stat tstat;
- char *cellservDB;
#ifdef AFS_NT40_ENV
cm_enumCellRegistry_t enumCellRegistry = {0, 0};
#endif /* AFS_NT40_ENV */
+ /* init the keys queue before any call to afsconf_CloseInternal() */
+ _afsconf_InitKeys(adir);
+
/* figure out the local cell name */
#ifdef AFS_NT40_ENV
i = GetCellNT(adir);
/* now parse the individual lines */
curEntry = 0;
- _afsconf_CellServDBPath(adir, &cellservDB);
+ _afsconf_CellServDBPath(adir, &adir->cellservDB);
#ifdef AFS_NT40_ENV
if (_afsconf_IsClientConfigDirectory(adir->name))
enumCellRegistry.client = 1;
#endif /* AFS_NT40_ENV */
- if (!stat(cellservDB, &tstat)) {
+ if (!stat(adir->cellservDB, &tstat)) {
adir->timeRead = tstat.st_mtime;
} else {
adir->timeRead = 0;
}
- tf = fopen(cellservDB, "r");
+ tf = fopen(adir->cellservDB, "r");
if (!tf) {
return -1;
}
- /* init the keys queue before any call to afsconf_CloseInternal() */
- _afsconf_InitKeys(adir);
-
/* The CellServDB file is now open.
* The following code parses the contents of the
* file and creates a list with the first cell entry
}
i = curEntry->cellInfo.numServers;
if (i < MAXHOSTSPERCELL) {
- if (cell && !strcmp(cell, curEntry->cellInfo.name))
- code =
- ParseHostLine(tbuffer,
- &curEntry->cellInfo.hostAddr[i],
- curEntry->cellInfo.hostName[i],
- &clones[i]);
- else
- code =
- ParseHostLine(tbuffer,
- &curEntry->cellInfo.hostAddr[i],
- curEntry->cellInfo.hostName[i], 0);
-
+ code = ParseHostLine(tbuffer,
+ &curEntry->cellInfo.hostAddr[i],
+ curEntry->cellInfo.hostName[i],
+ &curEntry->cellInfo.clone[i]);
if (code) {
if (code == AFSCONF_SYNTAX) {
for (bp = tbuffer; *bp != '\n'; bp++) { /* Take out the <cr> from the buffer */
*bp = '\0';
fprintf(stderr,
"Can't properly parse host line \"%s\" in configuration file %s\n",
- tbuffer, cellservDB);
+ tbuffer, adir->cellservDB);
}
free(curEntry);
fclose(tf);
} else {
fprintf(stderr,
"Too many hosts for cell %s in configuration file %s\n",
- curEntry->cellInfo.name, cellservDB);
+ curEntry->cellInfo.name, adir->cellservDB);
}
}
}
fclose(tf); /* close the file now */
- free(cellservDB);
/* end the last partially-completed cell */
if (curEntry) {
*/
static int
ParseHostLine(char *aline, struct sockaddr_in *addr, char *aname,
- char *aclone)
+ char *aclone /* boolean */)
{
- int c1, c2, c3, c4;
+ int i;
+ int c[4];
afs_int32 code;
char *tp;
if (aclone)
*aclone = 1;
/* FIXME: length of aname unknown here */
- code = sscanf(aline, "[%d.%d.%d.%d] #%s", &c1, &c2, &c3, &c4, aname);
+ code = sscanf(aline, "[%d.%d.%d.%d] #%s", &c[0], &c[1], &c[2], &c[3],
+ aname);
} else {
if (aclone)
*aclone = 0;
/* FIXME: length of aname unknown here */
- code = sscanf(aline, "%d.%d.%d.%d #%s", &c1, &c2, &c3, &c4, aname);
+ code = sscanf(aline, "%d.%d.%d.%d #%s", &c[0], &c[1], &c[2], &c[3],
+ aname);
}
if (code != 5)
return AFSCONF_SYNTAX;
+ for(i = 0; i < 4; ++i) {
+ if (c[i] < 0 || c[i] > 255) {
+ fprintf(stderr, "Illegal IP address %d.%d.%d.%d\n", c[0], c[1],
+ c[2], c[3]);
+ return AFSCONF_SYNTAX;
+ }
+ }
addr->sin_family = AF_INET;
addr->sin_port = 0;
#ifdef STRUCT_SOCKADDR_HAS_SA_LEN
addr->sin_len = sizeof(struct sockaddr_in);
#endif
tp = (char *)&addr->sin_addr;
- *tp++ = c1;
- *tp++ = c2;
- *tp++ = c3;
- *tp++ = c4;
+ *tp++ = c[0];
+ *tp++ = c[1];
+ *tp++ = c[2];
+ *tp++ = c[3];
return 0;
}
char clones[])
{
afs_int32 code;
- char *cell;
+ int i;
code = afsconf_GetCellInfo(adir, acellName, aservice, acellInfo);
if (code)
return code;
- if (acellName)
- cell = acellName;
- else
- cell = (char *)&acellInfo->name;
-
- code = afsconf_OpenInternal(adir, cell, clones);
+ for (i = 0; i < acellInfo->numServers; i++) {
+ clones[i] = acellInfo->clone[i];
+ }
return code;
}
int
afsconf_LookupServer(const char *service, const char *protocol,
const char *cellName, unsigned short afsdbPort,
- int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
+ afs_uint32 *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
unsigned short ports[], unsigned short ipRanks[],
int *numServers, int *ttl, char **arealCellName)
{
int code = 0;
+ int r;
int len;
unsigned char answer[4096];
unsigned char *p;
#endif
retryafsdb:
+ r = -1;
switch (pass) {
case 0:
dnstype = T_SRV;
- asprintf(&dotcellname, "_%s._%s.%s.", IANAname, protocol, cellName);
+ r = asprintf(&dotcellname, "_%s._%s.%s.", IANAname, protocol, cellName);
break;
case 1:
dnstype = T_AFSDB;
- asprintf(&dotcellname, "%s.", cellName);
+ r = asprintf(&dotcellname, "%s.", cellName);
break;
case 2:
dnstype = T_SRV;
- asprintf(&dotcellname, "_%s._%s.%s", IANAname, protocol, cellName);
+ r = asprintf(&dotcellname, "_%s._%s.%s", IANAname, protocol, cellName);
break;
case 3:
dnstype = T_AFSDB;
- asprintf(&dotcellname, "%s", cellName);
+ r = asprintf(&dotcellname, "%s", cellName);
break;
}
- if (dotcellname == NULL)
+ if (r < 0 || dotcellname == NULL)
goto findservererror;
LOCK_GLOBAL_MUTEX;
/* Do we want to get TTL data for the A record as well? */
(he = gethostbyname(host))) {
if (he->h_addrtype == AF_INET) {
- afs_int32 ipaddr;
+ afs_uint32 ipaddr;
memcpy(&ipaddr, he->h_addr, sizeof(ipaddr));
cellHostAddrs[server_num] = ipaddr;
ports[server_num] = afsdbPort;
/* Do we want to get TTL data for the A record as well? */
(he = gethostbyname(host))) {
if (he->h_addrtype == AF_INET) {
- afs_int32 ipaddr;
+ afs_uint32 ipaddr;
memcpy(&ipaddr, he->h_addr, sizeof(ipaddr));
cellHostAddrs[server_num] = ipaddr;
afsconf_GetAfsdbInfo(char *acellName, char *aservice,
struct afsconf_cell *acellInfo)
{
- afs_int32 cellHostAddrs[AFSMAXCELLHOSTS];
+ afs_uint32 cellHostAddrs[AFSMAXCELLHOSTS];
char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
unsigned short ipRanks[AFSMAXCELLHOSTS];
unsigned short ports[AFSMAXCELLHOSTS];
int tservice = afsconf_FindService(aservice); /* network byte order */
const char *ianaName = afsconf_FindIANAName(aservice);
struct afsconf_entry DNSce;
- afs_int32 cellHostAddrs[AFSMAXCELLHOSTS];
+ afs_uint32 cellHostAddrs[AFSMAXCELLHOSTS];
char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
unsigned short ipRanks[AFSMAXCELLHOSTS];
unsigned short ports[AFSMAXCELLHOSTS]; /* network byte order */
for (i = 0; i < numServers; i++) {
memcpy(&acellInfo->hostAddr[i].sin_addr.s_addr, &cellHostAddrs[i],
- sizeof(long));
+ sizeof(afs_uint32));
memcpy(acellInfo->hostName[i], cellHostNames[i], MAXHOSTCHARS);
acellInfo->hostAddr[i].sin_family = AF_INET;
if (aservice)
short numServers=0; /*Num active servers for the cell */
struct sockaddr_in hostAddr[MAXHOSTSPERCELL]; /*IP addresses for cell's servers */
char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS]; /*Names for cell's servers */
+ char clone[MAXHOSTSPERCELL]; /*Indicates which ones are clones. */
memset(&hostAddr, 0, sizeof(hostAddr));
memset(&hostName, 0, sizeof(hostName));
+ memset(&clone, 0, sizeof(clone));
for ( j=0; j<acellInfo->numServers && numServers < MAXHOSTSPERCELL; j++ ) {
struct hostent *he = gethostbyname(acellInfo->hostName[j]);
for (i=0 ; he->h_addr_list[i] && numServers < MAXHOSTSPERCELL; i++) {
/* check to see if this is a new address; if so insert it into the list */
int k, dup;
+ afs_uint32 addr;
+ memcpy(&addr, he->h_addr_list[i], sizeof(addr));
for (k=0, dup=0; !dup && k < numServers; k++) {
- if (hostAddr[k].sin_addr.s_addr == *(u_long *)he->h_addr_list[i])
+ if (hostAddr[k].sin_addr.s_addr == addr) {
dup = 1;
+ }
}
if (dup)
continue;
#ifdef STRUCT_SOCKADDR_HAS_SA_LEN
hostAddr[numServers].sin_len = sizeof(struct sockaddr_in);
#endif
- memcpy(&hostAddr[numServers].sin_addr.s_addr, he->h_addr_list[i], sizeof(long));
+ memcpy(&hostAddr[numServers].sin_addr.s_addr, he->h_addr_list[i], sizeof(afs_uint32));
strcpy(hostName[numServers], acellInfo->hostName[j]);
+ clone[numServers] = acellInfo->clone[j];
foundAddr = 1;
numServers++;
}
if (!foundAddr) {
hostAddr[numServers] = acellInfo->hostAddr[j];
strcpy(hostName[numServers], acellInfo->hostName[j]);
+ clone[numServers] = acellInfo->clone[j];
numServers++;
}
}
for (i=0; i<numServers; i++) {
acellInfo->hostAddr[i] = hostAddr[i];
strcpy(acellInfo->hostName[i], hostName[i]);
+ acellInfo->clone[i] = clone[i];
}
acellInfo->numServers = numServers;
acellInfo->flags |= AFSCONF_CELL_FLAG_DNS_QUERIED;
*
* @return status
* @retval 0 success
- * @retval AFSCONF_UNKNOWN failed to get cellname
+ * @retval AFSCONF_NOCELLNAME cannot determine local cell name
*
* @internal
*/
if (adir->cellName) {
*pname = adir->cellName;
} else
- code = AFSCONF_UNKNOWN;
+ code = AFSCONF_NOCELLNAME;
}
return code;
}
int
afsconf_Close(struct afsconf_dir *adir)
{
+ if (adir == NULL) {
+ return 0;
+ }
+
LOCK_GLOBAL_MUTEX;
afsconf_CloseInternal(adir);
if (adir->name)
struct afsconf_aliasentry *ta, *na;
char *tname;
+ if (adir == NULL) {
+ return 0;
+ }
+
tname = adir->name; /* remember name, since that's all we preserve */
/* free everything we can find */
if (adir->cellName)
free(adir->cellName);
+ if (adir->cellservDB)
+ free(adir->cellservDB);
for (td = adir->entries; td; td = nd) {
nd = td->next;
if (td->cellInfo.linkedCell)
code = afsconf_CloseInternal(adir);
if (code)
return code;
- code = afsconf_OpenInternal(adir, 0, 0);
+ code = afsconf_OpenInternal(adir);
return code;
}