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
17 #include <WINNT\afssw.h>
18 #include <WINNT\afsreg.h>
20 #include <afs/param.h>
22 #include <afs/cellconfig.h>
26 #include <afs/afsint.h>
29 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
38 for(tp = lineBufferp; *tp; tp++) {
47 /* comment or line end */
48 if (tc == '#' || tc == '\r' || tc == '\n')
51 /* square bracket comment -- look for closing delim */
58 if (tc == ' ' || tc == '\t')
66 /* now we have a real character, put it in the appropriate bucket */
75 /* null terminate the strings */
79 return 0; /* and return success */
83 IsWindowsModule(const char * name)
88 /* Do not perform searches for probable Windows modules */
89 for (p = name, i=0; *p; p++) {
93 p = strrchr(name, '.');
96 (!stricmp(p,".dll") ||
106 /* search for a cell, and either return an error code if we don't find it,
107 * or return 0 if we do, in which case we also fill in the addresses in
110 * new feature: we can handle abbreviations and are insensitive to case.
111 * If the caller wants the "real" cell name, it puts a non-null pointer in
112 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
113 * newCellNamep but return an error code.
115 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
116 cm_configProc_t *procp, void *rockp)
119 FILE *tfilep = NULL, *bestp, *tempp;
121 char lineBuffer[257];
124 struct sockaddr_in vlSockAddr;
128 int tracking = 1, partial = 0;
130 if ( IsWindowsModule(cellNamep) )
133 cm_GetCellServDB(wdir, sizeof(wdir));
134 tfilep = fopen(wdir, "r");
139 bestp = fopen(wdir, "r");
141 #ifdef CELLSERV_DEBUG
142 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
143 osi_LogSaveString(afsd_logp,wdir));
145 /* have we seen the cell line for the guy we're looking for? */
148 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
150 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
156 * found partial match earlier;
169 return (foundCell? 0 : -3);
174 /* turn trailing cr or lf into null */
175 tp = strchr(lineBuffer, '\r');
177 tp = strchr(lineBuffer, '\n');
180 /* skip blank lines */
181 if (lineBuffer[0] == 0) continue;
183 if (lineBuffer[0] == '>') {
184 /* trim off at white space or '#' chars */
185 tp = strchr(lineBuffer, ' ');
187 tp = strchr(lineBuffer, '\t');
189 tp = strchr(lineBuffer, '#');
192 /* now see if this is the right cell */
193 if (stricmp(lineBuffer+1, cellNamep) == 0) {
194 /* found the cell we're looking for */
196 strcpy(newCellNamep, lineBuffer+1);
197 strlwr(newCellNamep);
201 #ifdef CELLSERV_DEBUG
202 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
203 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
206 else if (strnicmp(lineBuffer+1, cellNamep,
207 strlen(cellNamep)) == 0) {
209 if (partial) { /* ambiguous */
215 strcpy(newCellNamep, lineBuffer+1);
216 strlwr(newCellNamep);
222 else inRightCell = 0;
225 valuep = strchr(lineBuffer, '#');
226 if (valuep == NULL) {
231 valuep++; /* skip the "#" */
233 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
234 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
235 * so do this just in case
237 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
238 valuep[strlen(valuep) - 1] = '\0';
241 /* add the server to the VLDB list */
243 thp = gethostbyname(valuep);
244 #ifdef CELLSERV_DEBUG
245 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
246 thp, osi_LogSaveString(afsd_logp,valuep), WSAGetLastError());
249 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
251 vlSockAddr.sin_family = AF_INET;
252 /* sin_port supplied by connection code */
254 (*procp)(rockp, &vlSockAddr, valuep);
260 char aname[241] = "";
262 /* Since there is no gethostbyname() data
263 * available we will read the IP address
264 * stored in the CellServDB file
266 code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
267 &c1, &c2, &c3, &c4, aname);
268 tp = (char *) &ip_addr;
273 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
275 vlSockAddr.sin_family = AF_INET;
276 /* sin_port supplied by connection code */
278 (*procp)(rockp, &vlSockAddr, valuep);
283 } /* while loop processing all lines */
285 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
286 return (foundCell) ? 0 : -11;
289 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
290 cm_configProc_t *procp, void *rockp)
294 int cellHostAddrs[AFSMAXCELLHOSTS];
295 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
298 struct sockaddr_in vlSockAddr;
299 #ifdef CELLSERV_DEBUG
300 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
302 if ( IsWindowsModule(cellNamep) )
304 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
305 if (rc == 0 && numServers > 0) { /* found the cell */
306 for (i = 0; i < numServers; i++) {
307 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
309 vlSockAddr.sin_family = AF_INET;
310 /* sin_port supplied by connection code */
312 (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
314 strcpy(newCellNamep,cellNamep);
315 strlwr(newCellNamep);
318 return 0; /* found cell */
321 return -1; /* not found */
323 return -1; /* not found */
324 #endif /* AFS_AFSDB_ENV */
327 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
328 * generate the fully qualified name of the CellServDB
331 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
335 cm_GetConfigDir(cellNamep, len);
337 /* add trailing backslash, if required */
338 tlen = (int)strlen(cellNamep);
339 if (cellNamep[tlen-1] != '\\') {
340 strncat(cellNamep, "\\", len);
341 cellNamep[len-1] = '\0';
344 strncat(cellNamep, AFS_CELLSERVDB, len);
345 cellNamep[len-1] = '\0';
349 /* look up the root cell's name in the Registry */
350 long cm_GetRootCellName(char *cellNamep)
352 DWORD code, dummyLen;
355 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
356 0, KEY_QUERY_VALUE, &parmKey);
357 if (code != ERROR_SUCCESS)
361 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
362 cellNamep, &dummyLen);
363 RegCloseKey (parmKey);
364 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
370 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
375 cm_GetConfigDir(wdir, sizeof(wdir));
377 strncat(wdir, namep, sizeof(wdir));
378 wdir[sizeof(wdir)-1] = '\0';
380 tfilep = fopen(wdir, rwp);
382 return ((cm_configFile_t *) tfilep);
385 long cm_WriteConfigString(char *labelp, char *valuep)
387 DWORD code, dummyDisp;
390 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
391 0, "container", 0, KEY_SET_VALUE, NULL,
392 &parmKey, &dummyDisp);
393 if (code != ERROR_SUCCESS)
396 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
397 valuep, (DWORD)strlen(valuep) + 1);
398 RegCloseKey (parmKey);
399 if (code != ERROR_SUCCESS)
405 long cm_WriteConfigInt(char *labelp, long value)
407 DWORD code, dummyDisp;
410 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
411 0, "container", 0, KEY_SET_VALUE, NULL,
412 &parmKey, &dummyDisp);
413 if (code != ERROR_SUCCESS)
416 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
417 (LPBYTE)&value, sizeof(value));
418 RegCloseKey (parmKey);
419 if (code != ERROR_SUCCESS)
425 cm_configFile_t *cm_OpenCellFile(void)
427 cm_configFile_t *cfp;
429 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
433 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
435 cm_configFile_t *tfilep; /* input file */
437 char lineBuffer[256];
442 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
448 /* have we seen the cell line for the guy we're looking for? */
451 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
453 if (feof((FILE *)tfilep)) {
455 fclose((FILE *)tfilep);
460 /* turn trailing cr or lf into null */
461 tp = strchr(lineBuffer, '\r');
463 tp = strchr(lineBuffer, '\n');
466 /* skip blank lines */
467 if (lineBuffer[0] == 0) {
468 fprintf((FILE *)ofp, "%s\n", lineBuffer);
472 if (lineBuffer[0] == '>') {
473 /* trim off at white space or '#' chars */
474 tp = strchr(lineBuffer, ' ');
476 tp = strchr(lineBuffer, '\t');
478 tp = strchr(lineBuffer, '#');
481 /* now see if this is the right cell */
482 if (strcmp(lineBuffer+1, cellNamep) == 0) {
483 /* found the cell we're looking for */
488 fprintf((FILE *)ofp, "%s\n", lineBuffer);
492 valuep = strchr(lineBuffer, '#');
493 if (valuep == NULL) return -2;
494 valuep++; /* skip the "#" */
496 fprintf((FILE *)ofp, "%s\n", lineBuffer);
499 } /* while loop processing all lines */
502 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
504 fprintf((FILE *)filep, ">%s\n", cellNamep);
508 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
510 fprintf((FILE *)filep, "%s\n", linep);
514 long cm_CloseCellFile(cm_configFile_t *filep)
520 closeCode = fclose((FILE *)filep);
522 cm_GetConfigDir(wdir, sizeof(wdir));
525 if (closeCode != 0) {
526 /* something went wrong, preserve original database */
527 strncat(wdir, AFS_CELLSERVDB ".new", sizeof(wdir));
528 wdir[sizeof(wdir)-1] = '\0';
533 strncat(wdir, AFS_CELLSERVDB, sizeof(wdir));
534 wdir[sizeof(wdir)-1] = '\0';
535 strncat(sdir, AFS_CELLSERVDB ".new", sizeof(sdir));/* new file */
536 sdir[sizeof(sdir)-1] = '\0';
538 unlink(sdir); /* delete old file */
540 code = rename(sdir, wdir); /* do the rename */
548 void cm_GetConfigDir(char *dir, afs_uint32 len)
552 if (!afssw_GetClientCellServDBDir(&dirp)) {
553 strncpy(dir, dirp, len);