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>
26 #include <WINNT\afssw.h>
27 #include <WINNT\afsreg.h>
30 #include <afs/afsint.h>
33 /* TODO: these should be pulled in from dirpath.h */
34 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
35 #define AFS_THISCELL "ThisCell"
37 #define AFS_CELLSERVDB_UNIX "CellServDB"
38 #define AFS_CELLSERVDB_NT "afsdcell.ini"
39 #ifndef AFSDIR_CLIENT_ETC_DIRPATH
40 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
42 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
43 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
45 extern char cm_confDir[];
49 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
50 #endif /* DJGPP || WIN95 */
52 static DWORD TraceOption = 0;
54 /* This really needs to be initialized at DLL Init */
55 #define TRACE_OPTION_EVENT 4
57 #define ISCONFIGTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
59 void DebugEvent0_local(char *a)
61 HANDLE h; char *ptbuf[1];
62 if (!ISCONFIGTRACE(TraceOption))
64 h = RegisterEventSource(NULL, a);
66 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
67 DeregisterEventSource(h);
72 void DebugEvent_local(char *a,char *b,...)
74 HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
76 if (!ISCONFIGTRACE(TraceOption))
78 h = RegisterEventSource(NULL, a);
80 _vsnprintf(buf,MAXBUF_,b,marker);
82 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
83 DeregisterEventSource(h);
87 #define REG_CLIENT_PARMS_KEY TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters")
88 #define REG_CLIENT_TRACE_OPTION_PARM TEXT("TraceOption")
91 BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
95 case DLL_PROCESS_ATTACH: {
96 DWORD LSPtype, LSPsize;
99 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
100 0, KEY_QUERY_VALUE, &NPKey);
101 LSPsize=sizeof(TraceOption);
102 RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
103 &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
109 case DLL_THREAD_ATTACH:
112 case DLL_THREAD_DETACH:
115 case DLL_PROCESS_DETACH:
122 return TRUE; // successful DLL_PROCESS_ATTACH
126 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
135 for(tp = lineBufferp; *tp; tp++) {
144 /* comment or line end */
145 if (tc == '#' || tc == '\r' || tc == '\n')
148 /* square bracket comment -- look for closing delim */
155 if (tc == ' ' || tc == '\t')
163 /* now we have a real character, put it in the appropriate bucket */
164 if (sawEquals == 0) {
172 /* null terminate the strings */
176 return 0; /* and return success */
179 /* search for a cell, and either return an error code if we don't find it,
180 * or return 0 if we do, in which case we also fill in the addresses in
183 * new feature: we can handle abbreviations and are insensitive to case.
184 * If the caller wants the "real" cell name, it puts a non-null pointer in
185 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
186 * newCellNamep but return an error code.
188 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
189 cm_configProc_t *procp, void *rockp)
192 FILE *tfilep = NULL, *bestp, *tempp;
194 char lineBuffer[257];
197 struct sockaddr_in vlSockAddr;
201 int tracking = 1, partial = 0;
202 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
207 cm_GetCellServDB(wdir);
208 tfilep = fopen(wdir, "r");
210 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
212 /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
213 /* If we are in Win95 here, we are linking with klog etc. and are
214 using DJGPP client even though DJGPP is not defined. So we still
215 need to check AFSCONF for location. */
216 dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
217 afsconf_path = malloc(dwSize);
218 dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
220 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
222 strcpy(wdir, afsconf_path);
226 strcat(wdir, AFS_CELLSERVDB);
227 /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
228 tfilep = fopen(wdir, "r");
229 if (!tfilep) return -2;
232 /* If we are NT or higher, we don't do DJGPP, So just fail */
237 bestp = fopen(wdir, "r");
240 DebugEvent_local("AFS- cm_searchfile fopen", "Handle[%x], wdir[%s]", bestp, wdir);
243 /* have we seen the cell line for the guy we're looking for? */
246 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
248 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
254 * found partial match earlier;
267 return (foundCell? 0 : -3);
272 /* turn trailing cr or lf into null */
273 tp = strchr(lineBuffer, '\r');
275 tp = strchr(lineBuffer, '\n');
278 /* skip blank lines */
279 if (lineBuffer[0] == 0) continue;
281 if (lineBuffer[0] == '>') {
282 /* trim off at white space or '#' chars */
283 tp = strchr(lineBuffer, ' ');
285 tp = strchr(lineBuffer, '\t');
287 tp = strchr(lineBuffer, '#');
290 /* now see if this is the right cell */
291 if (stricmp(lineBuffer+1, cellNamep) == 0) {
292 /* found the cell we're looking for */
294 strcpy(newCellNamep, lineBuffer+1);
298 DebugEvent_local("AFS- cm_searchfile is cell", "inRightCell[%x], linebuffer[%s]",
299 inRightCell, lineBuffer);
302 else if (strnicmp(lineBuffer+1, cellNamep,
303 strlen(cellNamep)) == 0) {
305 if (partial) { /* ambiguous */
311 strcpy(newCellNamep, lineBuffer+1);
316 else inRightCell = 0;
319 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
320 valuep = strchr(lineBuffer, '#');
321 if (valuep == NULL) {
326 valuep++; /* skip the "#" */
328 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
329 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
330 so do this just in case */
331 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
332 valuep[strlen(valuep) - 1] = '\0';
336 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
337 /* add the server to the VLDB list */
339 thp = gethostbyname(valuep);
342 int iErr = WSAGetLastError();
343 DebugEvent_local("AFS- cm_searchfile inRightCell",
344 "thp[%x], valuep[%s], WSAGetLastError[%d]",
349 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
351 vlSockAddr.sin_family = AF_INET;
352 /* sin_port supplied by connection code */
354 (*procp)(rockp, &vlSockAddr, valuep);
363 char aname[241] = "";
365 /* Since there is no gethostbyname() data
366 * available we will read the IP address
367 * stored in the CellServDB file
369 code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
370 &c1, &c2, &c3, &c4, aname);
371 tp = (char *) &ip_addr;
376 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
378 vlSockAddr.sin_family = AF_INET;
379 /* sin_port supplied by connection code */
381 (*procp)(rockp, &vlSockAddr, valuep);
386 } /* while loop processing all lines */
388 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
389 return (foundCell) ? 0 : -11;
392 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
393 cm_configProc_t *procp, void *rockp)
397 int cellHostAddrs[AFSMAXCELLHOSTS];
398 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
401 struct sockaddr_in vlSockAddr;
404 DebugEvent_local("AFS SearchCellDNS-","Doing search for [%s]", cellNamep);
406 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
407 if (rc == 0 && numServers > 0) { /* found the cell */
408 for (i = 0; i < numServers; i++) {
409 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
411 vlSockAddr.sin_family = AF_INET;
412 /* sin_port supplied by connection code */
414 (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
416 strcpy(newCellNamep,cellNamep);
418 return 0; /* found cell */
421 return -1; /* not found */
423 return -1; /* not found */
424 #endif /* AFS_AFSDB_ENV */
427 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
428 /* look up the CellServDBDir's name in the Registry
429 * or use the Client Dirpath value to produce a CellServDB
432 long cm_GetCellServDB(char *cellNamep)
435 DWORD code, dummyLen;
439 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
440 0, KEY_QUERY_VALUE, &parmKey);
441 if (code != ERROR_SUCCESS)
445 code = RegQueryValueEx(parmKey, "CellServDBDir", NULL, NULL,
446 cellNamep, &dummyLen);
447 RegCloseKey (parmKey);
450 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
451 strcpy(cellNamep, AFSDIR_CLIENT_ETC_DIRPATH);
453 /* add trailing backslash, if required */
454 tlen = strlen(cellNamep);
455 if (cellNamep[tlen-1] != '\\')
456 strcat(cellNamep, "\\");
458 strcpy(cellNamep, cm_confDir);
459 strcat(cellNamep,"/");
462 strcat(cellNamep, AFS_CELLSERVDB);
466 /* look up the root cell's name in the Registry */
467 long cm_GetRootCellName(char *cellNamep)
469 DWORD code, dummyLen;
472 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
473 0, KEY_QUERY_VALUE, &parmKey);
474 if (code != ERROR_SUCCESS)
478 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
479 cellNamep, &dummyLen);
480 RegCloseKey (parmKey);
481 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
487 /* look up the root cell's name in the THISCELL file */
488 long cm_GetRootCellName(char *cellNamep)
491 char thisCellPath[256];
496 strcpy(thisCellPath, cm_confDir);
500 dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
501 afsconf_path = malloc(dwSize);
502 dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
504 strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
506 strcpy(thisCellPath, afsconf_path);
510 strcat(thisCellPath,"/");
512 strcat(thisCellPath, AFS_THISCELL);
513 thisCell = fopen(thisCellPath, "r");
514 if (thisCell == NULL)
517 fgets(cellNamep, 256, thisCell);
520 newline = strrchr(cellNamep,'\n');
521 if (newline) *newline = '\0';
522 newline = strrchr(cellNamep,'\r');
523 if (newline) *newline = '\0';
529 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
535 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
536 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
538 /* add trailing backslash, if required */
540 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
543 strcpy(wdir,cm_confDir);
548 dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
549 afsconf_path = malloc(dwSize);
550 dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
553 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
555 strcpy(wdir, afsconf_path);
560 #endif /* DJGPP || WIN95 */
564 tfilep = fopen(wdir, rwp);
566 return ((cm_configFile_t *) tfilep);
570 long cm_WriteConfigString(char *labelp, char *valuep)
572 DWORD code, dummyDisp;
575 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
576 0, "container", 0, KEY_SET_VALUE, NULL,
577 &parmKey, &dummyDisp);
578 if (code != ERROR_SUCCESS)
581 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
582 valuep, strlen(valuep) + 1);
583 RegCloseKey (parmKey);
584 if (code != ERROR_SUCCESS)
592 long cm_WriteConfigInt(char *labelp, long value)
594 DWORD code, dummyDisp;
597 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
598 0, "container", 0, KEY_SET_VALUE, NULL,
599 &parmKey, &dummyDisp);
600 if (code != ERROR_SUCCESS)
603 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
604 (LPBYTE)&value, sizeof(value));
605 RegCloseKey (parmKey);
606 if (code != ERROR_SUCCESS)
613 cm_configFile_t *cm_OpenCellFile(void)
615 cm_configFile_t *cfp;
617 cfp = cm_CommonOpen("afsdcel2.ini", "w");
621 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
623 cm_configFile_t *tfilep; /* input file */
625 char lineBuffer[256];
630 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
631 if (!tfilep) return -1;
635 /* have we seen the cell line for the guy we're looking for? */
638 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
640 if (feof((FILE *)tfilep)) {
642 fclose((FILE *)tfilep);
647 /* turn trailing cr or lf into null */
648 tp = strchr(lineBuffer, '\r');
650 tp = strchr(lineBuffer, '\n');
653 /* skip blank lines */
654 if (lineBuffer[0] == 0) {
655 fprintf((FILE *)ofp, "%s\n", lineBuffer);
659 if (lineBuffer[0] == '>') {
660 /* trim off at white space or '#' chars */
661 tp = strchr(lineBuffer, ' ');
663 tp = strchr(lineBuffer, '\t');
665 tp = strchr(lineBuffer, '#');
668 /* now see if this is the right cell */
669 if (strcmp(lineBuffer+1, cellNamep) == 0) {
670 /* found the cell we're looking for */
675 fprintf((FILE *)ofp, "%s\n", lineBuffer);
679 valuep = strchr(lineBuffer, '#');
680 if (valuep == NULL) return -2;
681 valuep++; /* skip the "#" */
683 fprintf((FILE *)ofp, "%s\n", lineBuffer);
686 } /* while loop processing all lines */
689 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
691 fprintf((FILE *)filep, ">%s\n", cellNamep);
695 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
697 fprintf((FILE *)filep, "%s\n", linep);
701 long cm_CloseCellFile(cm_configFile_t *filep)
712 closeCode = fclose((FILE *)filep);
714 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
715 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
717 /* add trailing backslash, if required */
719 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
722 strcpy(wdir,cm_confDir);
724 dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
725 afsconf_path = malloc(dwSize);
726 dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
728 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
730 strcpy(wdir, afsconf_path);
735 #endif /* DJGPP || WIN95 */
739 if (closeCode != 0) {
740 /* something went wrong, preserve original database */
741 strcat(wdir, "afsdcel2.ini");
746 strcat(wdir, AFS_CELLSERVDB);
747 strcat(sdir, "afsdcel2.ini"); /* new file */
749 unlink(wdir); /* delete old file */
751 code = rename(sdir, wdir); /* do the rename */
759 void cm_GetConfigDir(char *dir)
768 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
769 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
771 /* add trailing backslash, if required */
773 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
776 strcpy(wdir,cm_confDir);
778 dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
779 afsconf_path = malloc(dwSize);
780 dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
782 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
784 strcpy(wdir, afsconf_path);
789 #endif /* DJGPP || WIN95 */