#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <nb30.h>
#include <winsock2.h>
+#endif /* !DJGPP */
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
{
cm_server_t *tsp;
cm_serverRef_t *tsrp;
- cm_cell_t *cellp;
+ cm_cell_t *cellp;
cellp = rockp;
/* load up a cell structure from the cell database, afsdcell.ini */
cm_cell_t *cm_GetCell(char *namep, long flags)
{
+ return cm_GetCell_Gen(namep, NULL, flags);
+}
+
+cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
+{
cm_cell_t *cp;
- long code;
- static cellCounter = 1; /* locked by cm_cellLock */
+ long code;
+ static cellCounter = 1; /* locked by cm_cellLock */
+ int ttl;
+ char fullname[200]="";
lock_ObtainWrite(&cm_cellLock);
for(cp = cm_allCellsp; cp; cp=cp->nextp) {
- if (strcmp(namep, cp->namep) == 0) break;
+ if (strcmp(namep, cp->namep) == 0) {
+ strcpy(fullname, cp->namep);
+ break;
+ }
+ }
+
+ if ((!cp && (flags & CM_FLAG_CREATE))
+#ifdef AFS_AFSDB_ENV
+ /* if it's from DNS, see if it has expired */
+ || (cp && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout))
+#endif
+ ) {
+ int dns_expired = 0;
+ if (!cp) {
+ cp = malloc(sizeof(*cp));
+ memset(cp, 0, sizeof(*cp));
+ }
+ else {
+ dns_expired = 1;
+ /* must empty cp->vlServersp */
+ cm_FreeServerList(&cp->vlServersp);
+ cp->vlServersp = NULL;
}
- if (!cp && (flags & CM_FLAG_CREATE)) {
- cp = malloc(sizeof(*cp));
- memset(cp, 0, sizeof(*cp));
- code = cm_SearchCellFile(namep, NULL, cm_AddCellProc, cp);
- if (code) {
- free(cp);
- cp = NULL;
- goto done;
+
+ code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
+ if (code) {
+ afsi_log("in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s",
+ namep, code, fullname);
+
+#ifdef AFS_AFSDB_ENV
+ if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/) {
+ code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
+ if ( code ) {
+ afsi_log("in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
+ namep, code, fullname);
+ if (dns_expired) {
+ if ( cm_allCellsp == cp )
+ cm_allCellsp = cp->nextp;
+ else {
+ cm_cell_t *tcp;
+
+ for(tcp = cm_allCellsp; tcp->nextp; tcp=tcp->nextp) {
+ if ( tcp->nextp == cp ) {
+ tcp->nextp = cp->nextp;
+ break;
+ }
+ }
+ }
+
+ lock_FinalizeMutex(&cp->mx);
+ free(cp->namep);
+ }
+ }
+ else { /* got cell from DNS */
+ cp->flags |= CM_CELLFLAG_DNS;
+ cp->timeout = time(0) + ttl;
}
+ }
+#endif
+ if (code) {
+ free(cp);
+ cp = NULL;
+ goto done;
+ }
+ }
/* randomise among those vlservers having the same rank*/
cm_RandomizeServer(&cp->vlServersp);
- /* otherwise we found the cell, and so we're nearly done */
- lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
+#ifdef AFS_AFSDB_ENV
+ if (dns_expired) {
+ /* we want to preserve the full name and mutex.
+ * also, cp is already in the cm_allCellsp list
+ */
+ goto done;
+ }
+#endif /* AFS_AFSDB_ENV */
+
+ /* otherwise we found the cell, and so we're nearly done */
+ lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
/* copy in name */
- cp->namep = malloc(strlen(namep)+1);
- strcpy(cp->namep, namep);
+ cp->namep = malloc(strlen(fullname)+1);
+ strcpy(cp->namep, fullname);
/* thread on global list */
- cp->nextp = cm_allCellsp;
- cm_allCellsp = cp;
+ cp->nextp = cm_allCellsp;
+ cm_allCellsp = cp;
- cp->cellID = cellCounter++;
- }
+ cp->cellID = cellCounter++;
+ }
-done:
+ done:
+ /* fullname is not valid if cp == NULL */
+ if (cp && newnamep)
+ strcpy(newnamep, fullname);
lock_ReleaseWrite(&cm_cellLock);
- return cp;
+ return cp;
}
cm_cell_t *cm_FindCellByID(long cellID)
{
cm_cell_t *cp;
+ int ttl;
+ int code;
lock_ObtainWrite(&cm_cellLock);
for(cp = cm_allCellsp; cp; cp=cp->nextp) {
- if (cellID == cp->cellID) break;
- }
+ if (cellID == cp->cellID)
+ break;
+ }
+
+#ifdef AFS_AFSDB_ENV
+ /* if it's from DNS, see if it has expired */
+ if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout)) {
+ code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
+ if (code == 0) { /* got cell from DNS */
+ cp->flags |= CM_CELLFLAG_DNS;
+#ifdef DEBUG
+ fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
+#endif
+ cp->timeout = time(0) + ttl;
+ }
+ /* if we fail to find it this time, we'll just do nothing and leave the
+ current entry alone */
+ }
+#endif /* AFS_AFSDB_ENV */
+
lock_ReleaseWrite(&cm_cellLock);
-
- return cp;
+ return cp;
}
void cm_InitCell(void)
osi_EndOnce(&once);
}
}
-void cm_ChangeRankCellVLServer(cm_server_t *tsp)
+void cm_ChangeRankCellVLServer(cm_server_t *tsp)
{
cm_cell_t *cp;
int code;