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>
21 #include <WINNT\afssw.h>
22 #include <WINNT\afsreg.h>
25 #include <afs/afsint.h>
28 /* TODO: these should be pulled in from dirpath.h */
29 #define AFS_THISCELL "ThisCell"
30 #define AFS_CELLSERVDB_UNIX "CellServDB"
31 #define AFS_CELLSERVDB_NT "afsdcell.ini"
32 #ifndef AFSDIR_CLIENT_ETC_DIRPATH
33 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
35 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
37 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
46 for(tp = lineBufferp; *tp; tp++) {
55 /* comment or line end */
56 if (tc == '#' || tc == '\r' || tc == '\n')
59 /* square bracket comment -- look for closing delim */
66 if (tc == ' ' || tc == '\t')
74 /* now we have a real character, put it in the appropriate bucket */
83 /* null terminate the strings */
87 return 0; /* and return success */
91 IsWindowsModule(const char * name)
96 /* Do not perform searches for probable Windows modules */
97 for (p = name, i=0; *p; p++) {
101 p = strrchr(name, '.');
104 (!stricmp(p,".dll") ||
105 !stricmp(p,".exe") ||
106 !stricmp(p,".ini") ||
114 /* search for a cell, and either return an error code if we don't find it,
115 * or return 0 if we do, in which case we also fill in the addresses in
118 * new feature: we can handle abbreviations and are insensitive to case.
119 * If the caller wants the "real" cell name, it puts a non-null pointer in
120 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
121 * newCellNamep but return an error code.
123 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
124 cm_configProc_t *procp, void *rockp)
127 FILE *tfilep = NULL, *bestp, *tempp;
129 char lineBuffer[257];
132 struct sockaddr_in vlSockAddr;
136 int tracking = 1, partial = 0;
138 if ( IsWindowsModule(cellNamep) )
141 cm_GetCellServDB(wdir);
142 tfilep = fopen(wdir, "r");
144 /* If we are NT or higher, we don't do DJGPP, So just fail */
148 bestp = fopen(wdir, "r");
150 #ifdef CELLSERV_DEBUG
151 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
152 osi_LogSaveString(afsd_logp,wdir));
154 /* have we seen the cell line for the guy we're looking for? */
157 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
159 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
165 * found partial match earlier;
178 return (foundCell? 0 : -3);
183 /* turn trailing cr or lf into null */
184 tp = strchr(lineBuffer, '\r');
186 tp = strchr(lineBuffer, '\n');
189 /* skip blank lines */
190 if (lineBuffer[0] == 0) continue;
192 if (lineBuffer[0] == '>') {
193 /* trim off at white space or '#' chars */
194 tp = strchr(lineBuffer, ' ');
196 tp = strchr(lineBuffer, '\t');
198 tp = strchr(lineBuffer, '#');
201 /* now see if this is the right cell */
202 if (stricmp(lineBuffer+1, cellNamep) == 0) {
203 /* found the cell we're looking for */
205 strcpy(newCellNamep, lineBuffer+1);
208 #ifdef CELLSERV_DEBUG
209 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
210 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
213 else if (strnicmp(lineBuffer+1, cellNamep,
214 strlen(cellNamep)) == 0) {
216 if (partial) { /* ambiguous */
222 strcpy(newCellNamep, lineBuffer+1);
227 else inRightCell = 0;
230 valuep = strchr(lineBuffer, '#');
231 if (valuep == NULL) {
236 valuep++; /* skip the "#" */
238 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
239 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
240 * so do this just in case
242 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
243 valuep[strlen(valuep) - 1] = '\0';
246 /* add the server to the VLDB list */
248 thp = gethostbyname(valuep);
249 #ifdef CELLSERV_DEBUG
250 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
251 thp, osi_LogSaveString(afsd_logp,valuep), WSAGetLastError());
254 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
256 vlSockAddr.sin_family = AF_INET;
257 /* sin_port supplied by connection code */
259 (*procp)(rockp, &vlSockAddr, valuep);
265 char aname[241] = "";
267 /* Since there is no gethostbyname() data
268 * available we will read the IP address
269 * stored in the CellServDB file
271 code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
272 &c1, &c2, &c3, &c4, aname);
273 tp = (char *) &ip_addr;
278 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
280 vlSockAddr.sin_family = AF_INET;
281 /* sin_port supplied by connection code */
283 (*procp)(rockp, &vlSockAddr, valuep);
288 } /* while loop processing all lines */
290 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
291 return (foundCell) ? 0 : -11;
294 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
295 cm_configProc_t *procp, void *rockp)
299 int cellHostAddrs[AFSMAXCELLHOSTS];
300 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
303 struct sockaddr_in vlSockAddr;
304 #ifdef CELLSERV_DEBUG
305 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
307 if ( IsWindowsModule(cellNamep) )
309 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
310 if (rc == 0 && numServers > 0) { /* found the cell */
311 for (i = 0; i < numServers; i++) {
312 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
314 vlSockAddr.sin_family = AF_INET;
315 /* sin_port supplied by connection code */
317 (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
319 strcpy(newCellNamep,cellNamep);
321 return 0; /* found cell */
324 return -1; /* not found */
326 return -1; /* not found */
327 #endif /* AFS_AFSDB_ENV */
330 /* look up the CellServDBDir's name in the Registry
331 * or use the Client Dirpath value to produce a CellServDB
334 long cm_GetCellServDB(char *cellNamep)
336 DWORD code, dummyLen;
340 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
341 0, KEY_QUERY_VALUE, &parmKey);
342 if (code != ERROR_SUCCESS)
346 code = RegQueryValueEx(parmKey, "CellServDBDir", NULL, NULL,
347 cellNamep, &dummyLen);
348 RegCloseKey (parmKey);
351 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
352 strcpy(cellNamep, AFSDIR_CLIENT_ETC_DIRPATH);
354 /* add trailing backslash, if required */
355 tlen = (int)strlen(cellNamep);
356 if (cellNamep[tlen-1] != '\\')
357 strcat(cellNamep, "\\");
359 strcat(cellNamep, AFS_CELLSERVDB);
363 /* look up the root cell's name in the Registry */
364 long cm_GetRootCellName(char *cellNamep)
366 DWORD code, dummyLen;
369 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
370 0, KEY_QUERY_VALUE, &parmKey);
371 if (code != ERROR_SUCCESS)
375 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
376 cellNamep, &dummyLen);
377 RegCloseKey (parmKey);
378 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
384 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
390 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
392 /* add trailing backslash, if required */
393 tlen = (long)(strlen(wdir));
394 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
398 tfilep = fopen(wdir, rwp);
400 return ((cm_configFile_t *) tfilep);
403 long cm_WriteConfigString(char *labelp, char *valuep)
405 DWORD code, dummyDisp;
408 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
409 0, "container", 0, KEY_SET_VALUE, NULL,
410 &parmKey, &dummyDisp);
411 if (code != ERROR_SUCCESS)
414 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
415 valuep, (DWORD)strlen(valuep) + 1);
416 RegCloseKey (parmKey);
417 if (code != ERROR_SUCCESS)
423 long cm_WriteConfigInt(char *labelp, long value)
425 DWORD code, dummyDisp;
428 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
429 0, "container", 0, KEY_SET_VALUE, NULL,
430 &parmKey, &dummyDisp);
431 if (code != ERROR_SUCCESS)
434 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
435 (LPBYTE)&value, sizeof(value));
436 RegCloseKey (parmKey);
437 if (code != ERROR_SUCCESS)
443 cm_configFile_t *cm_OpenCellFile(void)
445 cm_configFile_t *cfp;
447 cfp = cm_CommonOpen("afsdcel2.ini", "w");
451 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
453 cm_configFile_t *tfilep; /* input file */
455 char lineBuffer[256];
460 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
461 if (!tfilep) return -1;
465 /* have we seen the cell line for the guy we're looking for? */
468 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
470 if (feof((FILE *)tfilep)) {
472 fclose((FILE *)tfilep);
477 /* turn trailing cr or lf into null */
478 tp = strchr(lineBuffer, '\r');
480 tp = strchr(lineBuffer, '\n');
483 /* skip blank lines */
484 if (lineBuffer[0] == 0) {
485 fprintf((FILE *)ofp, "%s\n", lineBuffer);
489 if (lineBuffer[0] == '>') {
490 /* trim off at white space or '#' chars */
491 tp = strchr(lineBuffer, ' ');
493 tp = strchr(lineBuffer, '\t');
495 tp = strchr(lineBuffer, '#');
498 /* now see if this is the right cell */
499 if (strcmp(lineBuffer+1, cellNamep) == 0) {
500 /* found the cell we're looking for */
505 fprintf((FILE *)ofp, "%s\n", lineBuffer);
509 valuep = strchr(lineBuffer, '#');
510 if (valuep == NULL) return -2;
511 valuep++; /* skip the "#" */
513 fprintf((FILE *)ofp, "%s\n", lineBuffer);
516 } /* while loop processing all lines */
519 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
521 fprintf((FILE *)filep, ">%s\n", cellNamep);
525 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
527 fprintf((FILE *)filep, "%s\n", linep);
531 long cm_CloseCellFile(cm_configFile_t *filep)
538 closeCode = fclose((FILE *)filep);
540 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
542 /* add trailing backslash, if required */
543 tlen = (int)strlen(wdir);
544 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
548 if (closeCode != 0) {
549 /* something went wrong, preserve original database */
550 strcat(wdir, "afsdcel2.ini");
555 strcat(wdir, AFS_CELLSERVDB);
556 strcat(sdir, "afsdcel2.ini"); /* new file */
558 unlink(wdir); /* delete old file */
560 code = rename(sdir, wdir); /* do the rename */
568 void cm_GetConfigDir(char *dir)
577 strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
579 /* add trailing backslash, if required */
580 tlen = (int)strlen(wdir);
581 if (wdir[tlen-1] != '\\') strcat(wdir, "\\");