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>
12 #include <afs/cellconfig.h>
18 #include <sys/socket.h>
25 #include "cm_config.h"
26 #include <WINNT\afssw.h>
29 #include <afs/afsint.h>
32 char AFSConfigKeyName[] =
33 "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
35 /* TODO: these should be pulled in from dirpath.h */
36 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
37 #define AFS_THISCELL "ThisCell"
39 #define AFS_CELLSERVDB_UNIX "CellServDB"
40 #define AFS_CELLSERVDB_NT "afsdcell.ini"
41 #ifndef AFSDIR_CLIENT_ETC_DIRPATH
42 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
44 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
45 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
47 extern char cm_confDir[];
51 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
52 #endif /* DJGPP || WIN95 */
57 #define TRACE_OPTION_EVENT 1
58 #define ISLOGONTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
60 void DebugEvent0_local(char *a)
62 HANDLE h; char *ptbuf[1];
63 if (!ISLOGONTRACE(TraceOption))
65 h = RegisterEventSource(NULL, a);
67 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
68 DeregisterEventSource(h);
73 void DebugEvent_local(char *a,char *b,...)
75 HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
77 if (!ISLOGONTRACE(TraceOption))
79 h = RegisterEventSource(NULL, a);
81 _vsnprintf(buf,MAXBUF_,b,marker);
83 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
84 DeregisterEventSource(h);
89 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
98 for(tp = lineBufferp; *tp; tp++) {
107 /* comment or line end */
108 if (tc == '#' || tc == '\r' || tc == '\n')
111 /* square bracket comment -- look for closing delim */
118 if (tc == ' ' || tc == '\t')
126 /* now we have a real character, put it in the appropriate bucket */
127 if (sawEquals == 0) {
135 /* null terminate the strings */
139 return 0; /* and return success */
142 /* search for a cell, and either return an error code if we don't find it,
143 * or return 0 if we do, in which case we also fill in the addresses in
146 * new feature: we can handle abbreviations and are insensitive to case.
147 * If the caller wants the "real" cell name, it puts a non-null pointer in
148 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
149 * newCellNamep but return an error code.
151 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
152 cm_configProc_t *procp, void *rockp)
156 FILE *tfilep = NULL, *bestp, *tempp;
158 char lineBuffer[257];
161 struct sockaddr_in vlSockAddr;
165 int tracking = 1, partial = 0;
166 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
171 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
173 /* add trailing backslash, if required */
175 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
177 strcpy(wdir, cm_confDir);
181 strcat(wdir, AFS_CELLSERVDB);
182 tfilep = fopen(wdir, "r");
184 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
186 /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
187 /* If we are in Win95 here, we are linking with klog etc. and are
188 using DJGPP client even though DJGPP is not defined. So we still
189 need to check AFSCONF for location. */
190 afsconf_path = getenv("AFSCONF");
192 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
194 strcpy(wdir, afsconf_path);
196 strcat(wdir, AFS_CELLSERVDB);
197 /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
198 tfilep = fopen(wdir, "r");
199 if (!tfilep) return -2;
202 /* If we are NT or higher, we don't do DJGPP, So just fail */
207 bestp = fopen(wdir, "r");
210 DebugEvent_local("AFS- cm_searchfile fopen", "Handle[%x], wdir[%s]", bestp, wdir);
213 /* have we seen the cell line for the guy we're looking for? */
216 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
218 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
224 * found partial match earlier;
237 return (foundCell? 0 : -3);
242 /* turn trailing cr or lf into null */
243 tp = strchr(lineBuffer, '\r');
245 tp = strchr(lineBuffer, '\n');
248 /* skip blank lines */
249 if (lineBuffer[0] == 0) continue;
251 if (lineBuffer[0] == '>') {
252 /* trim off at white space or '#' chars */
253 tp = strchr(lineBuffer, ' ');
255 tp = strchr(lineBuffer, '\t');
257 tp = strchr(lineBuffer, '#');
260 /* now see if this is the right cell */
261 if (stricmp(lineBuffer+1, cellNamep) == 0) {
262 /* found the cell we're looking for */
264 strcpy(newCellNamep, lineBuffer+1);
268 DebugEvent_local("AFS- cm_searchfile is cell", "inRightCell[%x], linebuffer[%s]",
269 inRightCell, lineBuffer);
272 else if (strnicmp(lineBuffer+1, cellNamep,
273 strlen(cellNamep)) == 0) {
275 if (partial) { /* ambiguous */
281 strcpy(newCellNamep, lineBuffer+1);
286 else inRightCell = 0;
289 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
290 valuep = strchr(lineBuffer, '#');
291 if (valuep == NULL) {
296 valuep++; /* skip the "#" */
298 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
299 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
300 so do this just in case */
301 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
302 valuep[strlen(valuep) - 1] = '\0';
306 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
307 /* add the server to the VLDB list */
309 thp = gethostbyname(valuep);
312 int iErr = WSAGetLastError();
313 DebugEvent_local("AFS- cm_searchfile inRightCell",
314 "thp[%x], valuep[%s], WSAGetLastError[%d]",
319 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
321 vlSockAddr.sin_family = AF_INET;
322 /* sin_port supplied by connection code */
324 (*procp)(rockp, &vlSockAddr, valuep);
333 char aname[241] = "";
335 /* Since there is no gethostbyname() data
336 * available we will read the IP address
337 * stored in the CellServDB file
339 code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
340 &c1, &c2, &c3, &c4, aname);
341 tp = (char *) &ip_addr;
346 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
348 vlSockAddr.sin_family = AF_INET;
349 /* sin_port supplied by connection code */
351 (*procp)(rockp, &vlSockAddr, valuep);
356 } /* while loop processing all lines */
358 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
359 return (foundCell) ? 0 : -11;
362 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
363 cm_configProc_t *procp, void *rockp)
367 int cellHostAddrs[AFSMAXCELLHOSTS];
368 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
371 struct sockaddr_in vlSockAddr;
374 DebugEvent_local("AFS SearchCellDNS-","Doing search for [%s]", cellNamep);
376 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
377 if (rc == 0 && numServers > 0) { /* found the cell */
378 for (i = 0; i < numServers; i++) {
379 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
381 vlSockAddr.sin_family = AF_INET;
382 /* sin_port supplied by connection code */
384 (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
386 strcpy(newCellNamep,cellNamep);
388 return 0; /* found cell */
391 return -1; /* not found */
393 return -1; /* not found */
394 #endif /* AFS_AFSDB_ENV */
397 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
398 /* look up the root cell's name in the Registry */
399 long cm_GetRootCellName(char *cellNamep)
401 DWORD code, dummyLen;
404 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
405 0, KEY_QUERY_VALUE, &parmKey);
406 if (code != ERROR_SUCCESS)
410 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
411 cellNamep, &dummyLen);
412 RegCloseKey (parmKey);
413 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
419 /* look up the root cell's name in the THISCELL file */
420 long cm_GetRootCellName(char *cellNamep)
423 char thisCellPath[256];
427 strcpy(thisCellPath, cm_confDir);
431 afsconf_path = getenv("AFSCONF");
433 strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
435 strcpy(thisCellPath, afsconf_path);
437 strcat(thisCellPath,"/");
439 strcat(thisCellPath, AFS_THISCELL);
440 thisCell = fopen(thisCellPath, "r");
441 if (thisCell == NULL)
444 fgets(cellNamep, 256, thisCell);
447 newline = strrchr(cellNamep,'\n');
448 if (newline) *newline = '\0';
449 newline = strrchr(cellNamep,'\r');
450 if (newline) *newline = '\0';
456 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
463 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
464 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
466 /* add trailing backslash, if required */
468 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
471 strcpy(wdir,cm_confDir);
473 char *afsconf_path = getenv("AFSCONF");
475 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
477 strcpy(wdir, afsconf_path);
480 #endif /* DJGPP || WIN95 */
484 tfilep = fopen(wdir, rwp);
486 return ((cm_configFile_t *) tfilep);
490 long cm_WriteConfigString(char *labelp, char *valuep)
492 DWORD code, dummyDisp;
495 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
496 0, "container", 0, KEY_SET_VALUE, NULL,
497 &parmKey, &dummyDisp);
498 if (code != ERROR_SUCCESS)
501 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
502 valuep, strlen(valuep) + 1);
503 RegCloseKey (parmKey);
504 if (code != ERROR_SUCCESS)
512 long cm_WriteConfigInt(char *labelp, long value)
514 DWORD code, dummyDisp;
517 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
518 0, "container", 0, KEY_SET_VALUE, NULL,
519 &parmKey, &dummyDisp);
520 if (code != ERROR_SUCCESS)
523 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
524 (LPBYTE)&value, sizeof(value));
525 RegCloseKey (parmKey);
526 if (code != ERROR_SUCCESS)
533 cm_configFile_t *cm_OpenCellFile(void)
535 cm_configFile_t *cfp;
537 cfp = cm_CommonOpen("afsdcel2.ini", "w");
541 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
543 cm_configFile_t *tfilep; /* input file */
545 char lineBuffer[256];
550 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
551 if (!tfilep) return -1;
555 /* have we seen the cell line for the guy we're looking for? */
558 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
560 if (feof((FILE *)tfilep)) {
562 fclose((FILE *)tfilep);
567 /* turn trailing cr or lf into null */
568 tp = strchr(lineBuffer, '\r');
570 tp = strchr(lineBuffer, '\n');
573 /* skip blank lines */
574 if (lineBuffer[0] == 0) {
575 fprintf((FILE *)ofp, "%s\n", lineBuffer);
579 if (lineBuffer[0] == '>') {
580 /* trim off at white space or '#' chars */
581 tp = strchr(lineBuffer, ' ');
583 tp = strchr(lineBuffer, '\t');
585 tp = strchr(lineBuffer, '#');
588 /* now see if this is the right cell */
589 if (strcmp(lineBuffer+1, cellNamep) == 0) {
590 /* found the cell we're looking for */
595 fprintf((FILE *)ofp, "%s\n", lineBuffer);
599 valuep = strchr(lineBuffer, '#');
600 if (valuep == NULL) return -2;
601 valuep++; /* skip the "#" */
603 fprintf((FILE *)ofp, "%s\n", lineBuffer);
606 } /* while loop processing all lines */
609 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
611 fprintf((FILE *)filep, ">%s\n", cellNamep);
615 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
617 fprintf((FILE *)filep, "%s\n", linep);
621 long cm_CloseCellFile(cm_configFile_t *filep)
631 closeCode = fclose((FILE *)filep);
633 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
634 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
636 /* add trailing backslash, if required */
638 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
641 strcpy(wdir,cm_confDir);
643 afsconf_path = getenv("AFSCONF");
645 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
647 strcpy(wdir, afsconf_path);
650 #endif /* DJGPP || WIN95 */
654 if (closeCode != 0) {
655 /* something went wrong, preserve original database */
656 strcat(wdir, "afsdcel2.ini");
661 strcat(wdir, AFS_CELLSERVDB);
662 strcat(sdir, "afsdcel2.ini"); /* new file */
664 unlink(wdir); /* delete old file */
666 code = rename(sdir, wdir); /* do the rename */
674 void cm_GetConfigDir(char *dir)
683 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
684 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
686 /* add trailing backslash, if required */
688 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
691 strcpy(wdir,cm_confDir);
693 afsconf_path = getenv("AFSCONF");
695 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
697 strcpy(wdir, afsconf_path);
700 #endif /* DJGPP || WIN95 */