static int GetCellNT(struct afsconf_dir *adir) { if (_afsconf_IsClientConfigDirectory(adir->name)) { /* NT client config dir; ThisCell is in registry (no file). */ return afssw_GetClientCellName(&adir->cellName); } else { /* NT server config dir; works just like Unix */ return GetCellUnix(adir); } }
/** * Load the cell configuration into memory. * * Read the cell configuration into a newly allocated or cleared afsconf_dir * structure. Reads the CellServDB file, and if present, the cell alias file, * the key files, and kerberos related files. * * If the configuration cannot be loaded for any reason, any partial changes * are freed. The name member is preserved. * * @param[in,out] adir pointer to the cell configuration * the name member must be set to the pathname of the * cell configuration to be loaded. All other members * must be unassigned. * * @returns 0 on success */ static int LoadConfig(struct afsconf_dir *adir) { afsconf_FILE *tf; char *tp, *bp; struct afsconf_entry *curEntry; struct afsconf_aliasentry *curAlias; afs_int32 code; afs_int32 i; char tbuffer[256]; struct stat tstat; #ifdef AFS_NT40_ENV cm_enumCellRegistry_t enumCellRegistry = {0, 0}; #endif /* AFS_NT40_ENV */ /* init the keys queue before any call to UnloadConfig() */ _afsconf_InitKeys(adir); /* figure out the local cell name */ #ifdef AFS_NT40_ENV i = GetCellNT(adir); enumCellRegistry.adir = adir; #else i = GetCellUnix(adir); #endif #ifndef AFS_FREELANCE_CLIENT /* no local cell not fatal in freelance */ if (i) { return i; } #endif /* now parse the individual lines */ curEntry = 0; _afsconf_CellServDBPath(adir, &adir->cellservDB); #ifdef AFS_NT40_ENV if (_afsconf_IsClientConfigDirectory(adir->name)) enumCellRegistry.client = 1; #endif /* AFS_NT40_ENV */ if (!stat(adir->cellservDB, &tstat)) { adir->timeRead = tstat.st_mtime; } else { adir->timeRead = 0; } tf = fopen(adir->cellservDB, "r"); if (!tf) { return -1; } /* The CellServDB file is now open. * The following code parses the contents of the * file and creates a list with the first cell entry * in the CellServDB file at the end of the list. * * No checking is performed for duplicates. * The side effects of this process are that duplicate * entries appended to the end of the CellServDB file * take precedence and are found in a shorter period * of time. */ while (1) { tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == 0 || tbuffer[0] == '\n') continue; /* empty line */ if (tbuffer[0] == '>') { char linkedcell[MAXCELLCHARS]; /* start new cell item */ if (curEntry) { /* thread this guy on the list */ curEntry->next = adir->entries; adir->entries = curEntry; curEntry = 0; } curEntry = calloc(1, sizeof(struct afsconf_entry)); code = ParseCellLine(tbuffer, curEntry->cellInfo.name, linkedcell); if (code) { UnloadConfig(adir); fclose(tf); free(curEntry); return -1; } if (linkedcell[0] != '\0') curEntry->cellInfo.linkedCell = strdup(linkedcell); } else { /* new host in the current cell */ if (!curEntry) { UnloadConfig(adir); fclose(tf); return -1; } i = curEntry->cellInfo.numServers; if (i < MAXHOSTSPERCELL) { 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 */ if (!*bp) break; } *bp = '\0'; fprintf(stderr, "Can't properly parse host line \"%s\" in configuration file %s\n", tbuffer, adir->cellservDB); } free(curEntry); fclose(tf); UnloadConfig(adir); return -1; } curEntry->cellInfo.numServers = ++i; } else { fprintf(stderr, "Too many hosts for cell %s in configuration file %s\n", curEntry->cellInfo.name, adir->cellservDB); } } } fclose(tf); /* close the file now */ /* end the last partially-completed cell */ if (curEntry) { curEntry->next = adir->entries; adir->entries = curEntry; } #ifdef AFS_NT40_ENV /* * Windows maintains a CellServDB list in the Registry * that supercedes the contents of the CellServDB file. * Prepending these entries to the head of the list * is sufficient to enforce the precedence. */ cm_EnumerateCellRegistry( enumCellRegistry.client, cm_enumCellRegistryProc, &enumCellRegistry); #endif /* AFS_NT40_ENV */ /* Read in the alias list */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, (char *)NULL); tf = fopen(tbuffer, "r"); while (tf) { char *aliasPtr; tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == '\0' || tbuffer[0] == '\n' || tbuffer[0] == '#') continue; /* empty line */ tp = tbuffer; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t') tp++; if (tp[0] == '\0') continue; /* invalid line */ while (tp[0] != '\0' && (tp[0] == ' ' || tp[0] == '\t')) 0[tp++] = '\0'; if (tp[0] == '\0') continue; /* invalid line */ aliasPtr = tp; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t' && tp[0] != '\r' && tp[0] != '\n') tp++; tp[0] = '\0'; curAlias = calloc(1, sizeof(*curAlias)); strlcpy(curAlias->aliasInfo.aliasName, aliasPtr, sizeof curAlias->aliasInfo.aliasName); strlcpy(curAlias->aliasInfo.realName, tbuffer, sizeof curAlias->aliasInfo.realName); curAlias->next = adir->alias_entries; adir->alias_entries = curAlias; } if (tf != NULL) fclose(tf); /* now read the fs keys, if possible */ code = _afsconf_LoadKeys(adir); if (code) { return code; } code = _afsconf_LoadRealms(adir); return code; }
static int afsconf_OpenInternal(struct afsconf_dir *adir, char *cell, char clones[]) { afsconf_FILE *tf; char *tp, *bp; struct afsconf_entry *curEntry; struct afsconf_aliasentry *curAlias; afs_int32 code; afs_int32 i; char tbuffer[256], tbuf1[256]; struct stat tstat; #ifdef AFS_NT40_ENV cm_enumCellRegistry_t enumCellRegistry = {0, 0}; #endif /* AFS_NT40_ENV */ /* figure out the local cell name */ #ifdef AFS_NT40_ENV i = GetCellNT(adir); enumCellRegistry.adir = adir; #else i = GetCellUnix(adir); #endif #ifndef AFS_FREELANCE_CLIENT /* no local cell not fatal in freelance */ if (i) { return i; } #endif /* now parse the individual lines */ curEntry = 0; #ifdef AFS_NT40_ENV /* NT client/server have a CellServDB that is the same format as Unix. * However, the NT client uses a different file name */ if (IsClientConfigDirectory(adir->name)) { /* NT client config dir */ char *p; enumCellRegistry.client = 1; if (!afssw_GetClientCellServDBDir(&p)) { strcompose(tbuffer, sizeof(tbuffer), p, "/", AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL); free(p); } else { int len; strncpy(tbuffer, adir->name, sizeof(tbuffer)); len = (int)strlen(tbuffer); if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') { strncat(tbuffer, "\\", sizeof(tbuffer)); } strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT, sizeof(tbuffer)); tbuffer[sizeof(tbuffer) - 1] = '\0'; } } else { /* NT server config dir */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); } #else strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); #endif /* AFS_NT40_ENV */ if (!stat(tbuffer, &tstat)) { adir->timeRead = tstat.st_mtime; } else { adir->timeRead = 0; } strlcpy(tbuf1, tbuffer, sizeof tbuf1); tf = fopen(tbuffer, "r"); if (!tf) { return -1; } /* The CellServDB file is now open. * The following code parses the contents of the * file and creates a list with the first cell entry * in the CellServDB file at the end of the list. * * No checking is performed for duplicates. * The side effects of this process are that duplicate * entries appended to the end of the CellServDB file * take precedence and are found in a shorter period * of time. */ while (1) { tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == 0 || tbuffer[0] == '\n') continue; /* empty line */ if (tbuffer[0] == '>') { char linkedcell[MAXCELLCHARS]; /* start new cell item */ if (curEntry) { /* thread this guy on the list */ curEntry->next = adir->entries; adir->entries = curEntry; curEntry = 0; } curEntry = (struct afsconf_entry *)malloc(sizeof(struct afsconf_entry)); memset(curEntry, 0, sizeof(struct afsconf_entry)); code = ParseCellLine(tbuffer, curEntry->cellInfo.name, linkedcell); if (code) { afsconf_CloseInternal(adir); fclose(tf); free(curEntry); return -1; } if (linkedcell[0] != '\0') curEntry->cellInfo.linkedCell = strdup(linkedcell); } else { /* new host in the current cell */ if (!curEntry) { afsconf_CloseInternal(adir); fclose(tf); return -1; } 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); if (code) { if (code == AFSCONF_SYNTAX) { for (bp = tbuffer; *bp != '\n'; bp++) { /* Take out the <cr> from the buffer */ if (!*bp) break; } *bp = '\0'; fprintf(stderr, "Can't properly parse host line \"%s\" in configuration file %s\n", tbuffer, tbuf1); } free(curEntry); fclose(tf); afsconf_CloseInternal(adir); return -1; } curEntry->cellInfo.numServers = ++i; } else { fprintf(stderr, "Too many hosts for cell %s in configuration file %s\n", curEntry->cellInfo.name, tbuf1); } } } fclose(tf); /* close the file now */ /* end the last partially-completed cell */ if (curEntry) { curEntry->next = adir->entries; adir->entries = curEntry; } #ifdef AFS_NT40_ENV /* * Windows maintains a CellServDB list in the Registry * that supercedes the contents of the CellServDB file. * Prepending these entries to the head of the list * is sufficient to enforce the precedence. */ cm_EnumerateCellRegistry( enumCellRegistry.client, cm_enumCellRegistryProc, &enumCellRegistry); #endif /* AFS_NT40_ENV */ /* Read in the alias list */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, NULL); tf = fopen(tbuffer, "r"); while (tf) { char *aliasPtr; tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == '\0' || tbuffer[0] == '\n' || tbuffer[0] == '#') continue; /* empty line */ tp = tbuffer; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t') tp++; if (tp[0] == '\0') continue; /* invalid line */ while (tp[0] != '\0' && (tp[0] == ' ' || tp[0] == '\t')) 0[tp++] = '\0'; if (tp[0] == '\0') continue; /* invalid line */ aliasPtr = tp; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t' && tp[0] != '\r' && tp[0] != '\n') tp++; tp[0] = '\0'; curAlias = malloc(sizeof(*curAlias)); memset(curAlias, 0, sizeof(*curAlias)); strlcpy(curAlias->aliasInfo.aliasName, aliasPtr, sizeof curAlias->aliasInfo.aliasName); strlcpy(curAlias->aliasInfo.realName, tbuffer, sizeof curAlias->aliasInfo.realName); curAlias->next = adir->alias_entries; adir->alias_entries = curAlias; } if (tf != NULL) fclose(tf); /* now read the fs keys, if possible */ adir->keystr = (struct afsconf_keys *)0; afsconf_IntGetKeys(adir); return 0; }