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";
34 char AFSLocalMachineKeyName[] = "SOFTWARE\\OpenAFS\\Client";
36 /* TODO: these should be pulled in from dirpath.h */
37 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
38 #define AFS_THISCELL "ThisCell"
40 #define AFS_CELLSERVDB_UNIX "CellServDB"
41 #define AFS_CELLSERVDB_NT "afsdcell.ini"
42 #ifndef AFSDIR_CLIENT_ETC_DIRPATH
43 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
45 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
46 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
48 extern char cm_confDir[];
52 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
53 #endif /* DJGPP || WIN95 */
55 static DWORD TraceOption = 0;
57 /* This really needs to be initialized at DLL Init */
58 #define TRACE_OPTION_EVENT 4
60 #define ISCONFIGTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
62 void DebugEvent0_local(char *a)
64 HANDLE h; char *ptbuf[1];
65 if (!ISCONFIGTRACE(TraceOption))
67 h = RegisterEventSource(NULL, a);
69 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
70 DeregisterEventSource(h);
75 void DebugEvent_local(char *a,char *b,...)
77 HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
79 if (!ISCONFIGTRACE(TraceOption))
81 h = RegisterEventSource(NULL, a);
83 _vsnprintf(buf,MAXBUF_,b,marker);
85 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
86 DeregisterEventSource(h);
90 #define REG_CLIENT_PARMS_KEY TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters")
91 #define REG_CLIENT_TRACE_OPTION_PARM TEXT("TraceOption")
94 BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
98 case DLL_PROCESS_ATTACH: {
99 DWORD LSPtype, LSPsize;
102 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY,
103 0, KEY_QUERY_VALUE, &NPKey);
104 LSPsize=sizeof(TraceOption);
105 RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
106 &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
112 case DLL_THREAD_ATTACH:
115 case DLL_THREAD_DETACH:
118 case DLL_PROCESS_DETACH:
125 return TRUE; // successful DLL_PROCESS_ATTACH
129 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
138 for(tp = lineBufferp; *tp; tp++) {
147 /* comment or line end */
148 if (tc == '#' || tc == '\r' || tc == '\n')
151 /* square bracket comment -- look for closing delim */
158 if (tc == ' ' || tc == '\t')
166 /* now we have a real character, put it in the appropriate bucket */
167 if (sawEquals == 0) {
175 /* null terminate the strings */
179 return 0; /* and return success */
182 /* search for a cell, and either return an error code if we don't find it,
183 * or return 0 if we do, in which case we also fill in the addresses in
186 * new feature: we can handle abbreviations and are insensitive to case.
187 * If the caller wants the "real" cell name, it puts a non-null pointer in
188 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
189 * newCellNamep but return an error code.
191 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
192 cm_configProc_t *procp, void *rockp)
195 FILE *tfilep = NULL, *bestp, *tempp;
197 char lineBuffer[257];
200 struct sockaddr_in vlSockAddr;
204 int tracking = 1, partial = 0;
205 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
209 cm_GetCellServDB(wdir);
210 tfilep = fopen(wdir, "r");
212 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
214 /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
215 /* If we are in Win95 here, we are linking with klog etc. and are
216 using DJGPP client even though DJGPP is not defined. So we still
217 need to check AFSCONF for location. */
218 afsconf_path = getenv("AFSCONF");
220 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
222 strcpy(wdir, afsconf_path);
224 strcat(wdir, AFS_CELLSERVDB);
225 /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
226 tfilep = fopen(wdir, "r");
227 if (!tfilep) return -2;
230 /* If we are NT or higher, we don't do DJGPP, So just fail */
235 bestp = fopen(wdir, "r");
238 DebugEvent_local("AFS- cm_searchfile fopen", "Handle[%x], wdir[%s]", bestp, wdir);
241 /* have we seen the cell line for the guy we're looking for? */
244 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
246 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
252 * found partial match earlier;
265 return (foundCell? 0 : -3);
270 /* turn trailing cr or lf into null */
271 tp = strchr(lineBuffer, '\r');
273 tp = strchr(lineBuffer, '\n');
276 /* skip blank lines */
277 if (lineBuffer[0] == 0) continue;
279 if (lineBuffer[0] == '>') {
280 /* trim off at white space or '#' chars */
281 tp = strchr(lineBuffer, ' ');
283 tp = strchr(lineBuffer, '\t');
285 tp = strchr(lineBuffer, '#');
288 /* now see if this is the right cell */
289 if (stricmp(lineBuffer+1, cellNamep) == 0) {
290 /* found the cell we're looking for */
292 strcpy(newCellNamep, lineBuffer+1);
296 DebugEvent_local("AFS- cm_searchfile is cell", "inRightCell[%x], linebuffer[%s]",
297 inRightCell, lineBuffer);
300 else if (strnicmp(lineBuffer+1, cellNamep,
301 strlen(cellNamep)) == 0) {
303 if (partial) { /* ambiguous */
309 strcpy(newCellNamep, lineBuffer+1);
314 else inRightCell = 0;
317 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
318 valuep = strchr(lineBuffer, '#');
319 if (valuep == NULL) {
324 valuep++; /* skip the "#" */
326 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
327 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
328 so do this just in case */
329 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
330 valuep[strlen(valuep) - 1] = '\0';
334 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
335 /* add the server to the VLDB list */
337 thp = gethostbyname(valuep);
340 int iErr = WSAGetLastError();
341 DebugEvent_local("AFS- cm_searchfile inRightCell",
342 "thp[%x], valuep[%s], WSAGetLastError[%d]",
347 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
349 vlSockAddr.sin_family = AF_INET;
350 /* sin_port supplied by connection code */
352 (*procp)(rockp, &vlSockAddr, valuep);
361 char aname[241] = "";
363 /* Since there is no gethostbyname() data
364 * available we will read the IP address
365 * stored in the CellServDB file
367 code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
368 &c1, &c2, &c3, &c4, aname);
369 tp = (char *) &ip_addr;
374 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
376 vlSockAddr.sin_family = AF_INET;
377 /* sin_port supplied by connection code */
379 (*procp)(rockp, &vlSockAddr, valuep);
384 } /* while loop processing all lines */
386 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
387 return (foundCell) ? 0 : -11;
390 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
391 cm_configProc_t *procp, void *rockp)
395 int cellHostAddrs[AFSMAXCELLHOSTS];
396 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
399 struct sockaddr_in vlSockAddr;
402 DebugEvent_local("AFS SearchCellDNS-","Doing search for [%s]", cellNamep);
404 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
405 if (rc == 0 && numServers > 0) { /* found the cell */
406 for (i = 0; i < numServers; i++) {
407 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
409 vlSockAddr.sin_family = AF_INET;
410 /* sin_port supplied by connection code */
412 (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
414 strcpy(newCellNamep,cellNamep);
416 return 0; /* found cell */
419 return -1; /* not found */
421 return -1; /* not found */
422 #endif /* AFS_AFSDB_ENV */
425 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
426 /* look up the CellServDBDir's name in the Registry
427 * or use the Client Dirpath value to produce a CellServDB
430 long cm_GetCellServDB(char *cellNamep)
433 DWORD code, dummyLen;
437 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLocalMachineKeyName,
438 0, KEY_QUERY_VALUE, &parmKey);
439 if (code != ERROR_SUCCESS)
443 code = RegQueryValueEx(parmKey, "CellServDBDir", NULL, NULL,
444 cellNamep, &dummyLen);
445 RegCloseKey (parmKey);
448 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
449 strcpy(cellNamep, AFSDIR_CLIENT_ETC_DIRPATH);
451 /* add trailing backslash, if required */
452 tlen = strlen(cellNamep);
453 if (cellNamep[tlen-1] != '\\')
454 strcat(cellNamep, "\\");
456 strcpy(cellNamep, cm_confDir);
457 strcat(cellNamep,"/");
460 strcat(cellNamep, AFS_CELLSERVDB);
464 /* look up the root cell's name in the Registry */
465 long cm_GetRootCellName(char *cellNamep)
467 DWORD code, dummyLen;
470 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
471 0, KEY_QUERY_VALUE, &parmKey);
472 if (code != ERROR_SUCCESS)
476 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
477 cellNamep, &dummyLen);
478 RegCloseKey (parmKey);
479 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
485 /* look up the root cell's name in the THISCELL file */
486 long cm_GetRootCellName(char *cellNamep)
489 char thisCellPath[256];
493 strcpy(thisCellPath, cm_confDir);
497 afsconf_path = getenv("AFSCONF");
499 strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
501 strcpy(thisCellPath, afsconf_path);
503 strcat(thisCellPath,"/");
505 strcat(thisCellPath, AFS_THISCELL);
506 thisCell = fopen(thisCellPath, "r");
507 if (thisCell == NULL)
510 fgets(cellNamep, 256, thisCell);
513 newline = strrchr(cellNamep,'\n');
514 if (newline) *newline = '\0';
515 newline = strrchr(cellNamep,'\r');
516 if (newline) *newline = '\0';
522 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
528 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
529 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
531 /* add trailing backslash, if required */
533 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
536 strcpy(wdir,cm_confDir);
538 char *afsconf_path = getenv("AFSCONF");
540 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
542 strcpy(wdir, afsconf_path);
545 #endif /* DJGPP || WIN95 */
549 tfilep = fopen(wdir, rwp);
551 return ((cm_configFile_t *) tfilep);
555 long cm_WriteConfigString(char *labelp, char *valuep)
557 DWORD code, dummyDisp;
560 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
561 0, "container", 0, KEY_SET_VALUE, NULL,
562 &parmKey, &dummyDisp);
563 if (code != ERROR_SUCCESS)
566 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
567 valuep, strlen(valuep) + 1);
568 RegCloseKey (parmKey);
569 if (code != ERROR_SUCCESS)
577 long cm_WriteConfigInt(char *labelp, long value)
579 DWORD code, dummyDisp;
582 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
583 0, "container", 0, KEY_SET_VALUE, NULL,
584 &parmKey, &dummyDisp);
585 if (code != ERROR_SUCCESS)
588 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
589 (LPBYTE)&value, sizeof(value));
590 RegCloseKey (parmKey);
591 if (code != ERROR_SUCCESS)
598 cm_configFile_t *cm_OpenCellFile(void)
600 cm_configFile_t *cfp;
602 cfp = cm_CommonOpen("afsdcel2.ini", "w");
606 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
608 cm_configFile_t *tfilep; /* input file */
610 char lineBuffer[256];
615 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
616 if (!tfilep) return -1;
620 /* have we seen the cell line for the guy we're looking for? */
623 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
625 if (feof((FILE *)tfilep)) {
627 fclose((FILE *)tfilep);
632 /* turn trailing cr or lf into null */
633 tp = strchr(lineBuffer, '\r');
635 tp = strchr(lineBuffer, '\n');
638 /* skip blank lines */
639 if (lineBuffer[0] == 0) {
640 fprintf((FILE *)ofp, "%s\n", lineBuffer);
644 if (lineBuffer[0] == '>') {
645 /* trim off at white space or '#' chars */
646 tp = strchr(lineBuffer, ' ');
648 tp = strchr(lineBuffer, '\t');
650 tp = strchr(lineBuffer, '#');
653 /* now see if this is the right cell */
654 if (strcmp(lineBuffer+1, cellNamep) == 0) {
655 /* found the cell we're looking for */
660 fprintf((FILE *)ofp, "%s\n", lineBuffer);
664 valuep = strchr(lineBuffer, '#');
665 if (valuep == NULL) return -2;
666 valuep++; /* skip the "#" */
668 fprintf((FILE *)ofp, "%s\n", lineBuffer);
671 } /* while loop processing all lines */
674 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
676 fprintf((FILE *)filep, ">%s\n", cellNamep);
680 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
682 fprintf((FILE *)filep, "%s\n", linep);
686 long cm_CloseCellFile(cm_configFile_t *filep)
696 closeCode = fclose((FILE *)filep);
698 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
699 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
701 /* add trailing backslash, if required */
703 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
706 strcpy(wdir,cm_confDir);
708 afsconf_path = getenv("AFSCONF");
710 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
712 strcpy(wdir, afsconf_path);
715 #endif /* DJGPP || WIN95 */
719 if (closeCode != 0) {
720 /* something went wrong, preserve original database */
721 strcat(wdir, "afsdcel2.ini");
726 strcat(wdir, AFS_CELLSERVDB);
727 strcat(sdir, "afsdcel2.ini"); /* new file */
729 unlink(wdir); /* delete old file */
731 code = rename(sdir, wdir); /* do the rename */
739 void cm_GetConfigDir(char *dir)
747 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
748 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
750 /* add trailing backslash, if required */
752 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
755 strcpy(wdir,cm_confDir);
757 afsconf_path = getenv("AFSCONF");
759 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
761 strcpy(wdir, afsconf_path);
764 #endif /* DJGPP || WIN95 */