2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afs/param.h>
17 #include <sys/socket.h>
24 #include "cm_config.h"
27 #include <afs/afsint.h>
30 char AFSConfigKeyName[] =
31 "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
33 #define AFS_THISCELL "ThisCell"
34 #define AFS_CELLSERVDB_UNIX "CellServDB"
35 #define AFS_CELLSERVDB_NT "afsdcell.ini"
36 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
37 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
38 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
40 extern char cm_confDir[];
44 #define AFS_CELLSERVDB AFS_CELLSERVDB_NT
45 #endif /* DJGPP || WIN95 */
48 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
57 for(tp = lineBufferp; *tp; tp++) {
66 /* comment or line end */
67 if (tc == '#' || tc == '\r' || tc == '\n') break;
69 /* square bracket comment -- look for closing delim
70 if (tc == '[') {sawBracket = 1; continue;}
73 if (tc == ' ' || tc == '\t') continue;
80 /* now we have a real character, put it in the appropriate bucket */
89 /* null terminate the strings */
93 return 0; /* and return success */
96 /* search for a cell, and either return an error code if we don't find it,
97 * or return 0 if we do, in which case we also fill in the addresses in
100 * new feature: we can handle abbreviations and are insensitive to case.
101 * If the caller wants the "real" cell name, it puts a non-null pointer in
102 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
103 * newCellNamep but return an error code.
105 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
106 cm_configProc_t *procp, void *rockp)
110 FILE *tfilep, *bestp, *tempp;
112 char lineBuffer[256];
115 struct sockaddr_in vlSockAddr;
119 int tracking = 1, partial = 0;
120 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
130 code = GetWindowsDirectory(wdir, sizeof(wdir));
131 if (code == 0 || code > sizeof(wdir)) return -1;
133 /* add trailing backslash, if required */
135 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
137 strcpy(wdir, cm_confDir);
141 strcat(wdir, AFS_CELLSERVDB);
143 tfilep = fopen(wdir, "r");
146 /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
147 /* If we are in Win95 here, we are linking with klog etc. and are
148 using DJGPP client even though DJGPP is not defined. So we still
149 need to check AFSCONF for location. */
150 afsconf_path = getenv("AFSCONF");
152 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
154 strcpy(wdir, afsconf_path);
156 strcat(wdir, AFS_CELLSERVDB_UNIX);
157 /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
158 tfilep = fopen(wdir, "r");
159 if (!tfilep) return -2;
162 bestp = fopen(wdir, "r");
164 /* have we seen the cell line for the guy we're looking for? */
167 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
169 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
175 * found partial match earlier;
188 return (foundCell? 0 : -3);
193 /* turn trailing cr or lf into null */
194 tp = strchr(lineBuffer, '\r');
196 tp = strchr(lineBuffer, '\n');
199 /* skip blank lines */
200 if (lineBuffer[0] == 0) continue;
202 if (lineBuffer[0] == '>') {
203 /* trim off at white space or '#' chars */
204 tp = strchr(lineBuffer, ' ');
206 tp = strchr(lineBuffer, '\t');
208 tp = strchr(lineBuffer, '#');
211 /* now see if this is the right cell */
212 if (stricmp(lineBuffer+1, cellNamep) == 0) {
213 /* found the cell we're looking for */
215 strcpy(newCellNamep, lineBuffer+1);
219 else if (strnicmp(lineBuffer+1, cellNamep,
220 strlen(cellNamep)) == 0) {
222 if (partial) { /* ambiguous */
228 strcpy(newCellNamep, lineBuffer+1);
233 else inRightCell = 0;
236 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
237 valuep = strchr(lineBuffer, '#');
238 if (valuep == NULL) {
243 valuep++; /* skip the "#" */
245 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
246 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
247 so do this just in case */
248 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t') valuep[strlen(valuep) - 1] = '\0';
252 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
253 /* add the server to the VLDB list */
254 thp = gethostbyname(valuep);
256 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
258 vlSockAddr.sin_family = AF_INET;
259 /* sin_port supplied by connection code */
261 (*procp)(rockp, &vlSockAddr, valuep);
265 /* For DJGPP, we will read IP address instead
266 of name/comment field */
267 code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
268 &c1, &c2, &c3, &c4, aname);
269 tp = (char *) &ip_addr;
274 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
276 vlSockAddr.sin_family = AF_INET;
277 /* sin_port supplied by connection code */
279 (*procp)(rockp, &vlSockAddr, valuep);
284 } /* while loop processing all lines */
287 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
288 cm_configProc_t *procp, void *rockp)
292 int cellHosts[AFSMAXCELLHOSTS];
295 struct sockaddr_in vlSockAddr;
297 rc = getAFSServer(cellNamep, cellHosts, &numServers, ttl);
298 if (rc == 0 && numServers > 0) { /* found the cell */
299 for (i = 0; i < numServers; i++) {
300 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHosts[i],
302 vlSockAddr.sin_family = AF_INET;
303 /* sin_port supplied by connection code */
305 (*procp)(rockp, &vlSockAddr, NULL);
307 strcpy(newCellNamep,cellNamep);
309 return 0; /* found cell */
312 #endif /* AFS_AFSDB_ENV */
313 return -1; /* not found */
316 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
317 /* look up the root cell's name in the Registry */
318 long cm_GetRootCellName(char *cellNamep)
320 DWORD code, dummyLen;
323 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
324 0, KEY_QUERY_VALUE, &parmKey);
325 if (code != ERROR_SUCCESS)
329 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
330 cellNamep, &dummyLen);
331 RegCloseKey (parmKey);
332 if (code != ERROR_SUCCESS)
338 /* look up the root cell's name in the THISCELL file */
339 long cm_GetRootCellName(char *cellNamep)
342 char thisCellPath[256];
347 strcpy(thisCellPath, cm_confDir);
350 afsconf_path = getenv("AFSCONF");
352 strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
354 strcpy(thisCellPath, afsconf_path);
356 strcat(thisCellPath,"/");
358 strcat(thisCellPath, AFS_THISCELL);
359 thisCell = fopen(thisCellPath, "r");
360 if (thisCell == NULL)
363 fgets(cellNamep, 256, thisCell);
366 newline = strrchr(cellNamep,'\n');
367 if (newline) *newline = '\0';
368 newline = strrchr(cellNamep,'\r');
369 if (newline) *newline = '\0';
375 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
383 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
384 code = GetWindowsDirectory(wdir, sizeof(wdir));
385 if (code == 0 || code > sizeof(wdir)) return NULL;
387 /* add trailing backslash, if required */
389 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
392 strcpy(wdir,cm_confDir);
394 afsconf_path = getenv("AFSCONF");
396 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
398 strcpy(wdir, afsconf_path);
401 #endif /* DJGPP || WIN95 */
405 tfilep = fopen(wdir, rwp);
407 return ((cm_configFile_t *) tfilep);
411 long cm_WriteConfigString(char *labelp, char *valuep)
413 DWORD code, dummyDisp;
416 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
417 0, "container", 0, KEY_SET_VALUE, NULL,
418 &parmKey, &dummyDisp);
419 if (code != ERROR_SUCCESS)
422 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
423 valuep, strlen(valuep) + 1);
424 RegCloseKey (parmKey);
425 if (code != ERROR_SUCCESS)
433 long cm_WriteConfigInt(char *labelp, long value)
435 DWORD code, dummyDisp;
438 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
439 0, "container", 0, KEY_SET_VALUE, NULL,
440 &parmKey, &dummyDisp);
441 if (code != ERROR_SUCCESS)
444 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
445 (LPBYTE)&value, sizeof(value));
446 RegCloseKey (parmKey);
447 if (code != ERROR_SUCCESS)
454 cm_configFile_t *cm_OpenCellFile(void)
456 cm_configFile_t *cfp;
458 cfp = cm_CommonOpen("afsdcel2.ini", "w");
462 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
464 cm_configFile_t *tfilep; /* input file */
466 char lineBuffer[256];
471 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
472 if (!tfilep) return -1;
476 /* have we seen the cell line for the guy we're looking for? */
479 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
481 if (feof((FILE *)tfilep)) {
483 fclose((FILE *)tfilep);
488 /* turn trailing cr or lf into null */
489 tp = strchr(lineBuffer, '\r');
491 tp = strchr(lineBuffer, '\n');
494 /* skip blank lines */
495 if (lineBuffer[0] == 0) {
496 fprintf((FILE *)ofp, "%s\n", lineBuffer);
500 if (lineBuffer[0] == '>') {
501 /* trim off at white space or '#' chars */
502 tp = strchr(lineBuffer, ' ');
504 tp = strchr(lineBuffer, '\t');
506 tp = strchr(lineBuffer, '#');
509 /* now see if this is the right cell */
510 if (strcmp(lineBuffer+1, cellNamep) == 0) {
511 /* found the cell we're looking for */
516 fprintf((FILE *)ofp, "%s\n", lineBuffer);
520 valuep = strchr(lineBuffer, '#');
521 if (valuep == NULL) return -2;
522 valuep++; /* skip the "#" */
524 fprintf((FILE *)ofp, "%s\n", lineBuffer);
527 } /* while loop processing all lines */
530 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
532 fprintf((FILE *)filep, ">%s\n", cellNamep);
536 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
538 fprintf((FILE *)filep, "%s\n", linep);
542 long cm_CloseCellFile(cm_configFile_t *filep)
551 closeCode = fclose((FILE *)filep);
553 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
554 code = GetWindowsDirectory(wdir, sizeof(wdir));
555 if (code == 0 || code > sizeof(wdir)) return NULL;
557 /* add trailing backslash, if required */
559 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
562 strcpy(wdir,cm_confDir);
564 afsconf_path = getenv("AFSCONF");
566 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
568 strcpy(wdir, afsconf_path);
571 #endif /* DJGPP || WIN95 */
575 if (closeCode != 0) {
576 /* something went wrong, preserve original database */
577 strcat(wdir, "afsdcel2.ini");
582 strcat(wdir, AFS_CELLSERVDB);
583 strcat(sdir, "afsdcel2.ini"); /* new file */
585 unlink(wdir); /* delete old file */
587 code = rename(sdir, wdir); /* do the rename */
589 if (code) code = errno;
594 void cm_GetConfigDir(char *dir)
601 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
602 code = GetWindowsDirectory(wdir, sizeof(wdir));
603 if (code == 0 || code > sizeof(wdir)) wdir[0] = 0;
605 /* add trailing backslash, if required */
607 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
610 strcpy(wdir,cm_confDir);
612 afsconf_path = getenv("AFSCONF");
614 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
616 strcpy(wdir, afsconf_path);
619 #endif /* DJGPP || WIN95 */