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 (!cm_stricmp_utf8N(p,".dll") ||
97 !cm_stricmp_utf8N(p,".exe") ||
98 !cm_stricmp_utf8N(p,".ini") ||
99 !cm_stricmp_utf8N(p,".db") ||
100 !cm_stricmp_utf8N(p,".drv")))
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 * Linked Cells: the CellServDB format permits linked cells
116 * >cell [linked-cell] #Description
118 * newCellNamep and linkedNamep are required to be CELL_MAXNAMELEN in size.
120 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
121 cm_configProc_t *procp, void *rockp)
123 return cm_SearchCellFileEx(cellNamep, newCellNamep, NULL, procp, rockp);
126 long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
128 cm_configProc_t *procp, void *rockp)
130 char wdir[MAX_PATH]="";
131 FILE *tfilep = NULL, *bestp, *tempp;
133 char lineBuffer[257];
136 struct sockaddr_in vlSockAddr;
140 int tracking = 1, partial = 0;
142 if ( IsWindowsModule(cellNamep) )
145 cm_GetCellServDB(wdir, sizeof(wdir));
147 tfilep = fopen(wdir, "r");
152 bestp = fopen(wdir, "r");
154 #ifdef CELLSERV_DEBUG
155 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
156 osi_LogSaveString(afsd_logp,wdir));
158 /* have we seen the cell line for the guy we're looking for? */
161 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
163 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
169 * found partial match earlier;
182 return (foundCell? 0 : -3);
187 /* turn trailing cr or lf into null */
188 tp = strrchr(lineBuffer, '\r');
190 tp = strrchr(lineBuffer, '\n');
193 /* skip blank lines */
194 if (lineBuffer[0] == 0) continue;
198 * >[cell] [linked-cell] #[Description]
199 * where linked-cell and Description are optional
201 if (lineBuffer[0] == '>') {
205 return(foundCell ? 0 : -6);
209 * terminate the cellname at the first white space
210 * leaving 'tp' pointing to the next string if any
212 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
215 for (tp++ ;tp && isspace(*tp); tp++);
218 for (; tp && !isspace(*tp); tp++);
224 /* now see if this is the right cell */
225 if (stricmp(lineBuffer+1, cellNamep) == 0) {
226 /* found the cell we're looking for */
228 strncpy(newCellNamep, lineBuffer+1,CELL_MAXNAMELEN);
229 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
230 strlwr(newCellNamep);
233 strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
234 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
239 #ifdef CELLSERV_DEBUG
240 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
241 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
244 else if (cm_stricmp_utf8(lineBuffer+1, cellNamep) == 0) {
246 if (partial) { /* ambiguous */
252 strncpy(newCellNamep, lineBuffer+1,CELL_MAXNAMELEN);
253 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
254 strlwr(newCellNamep);
257 strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
258 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
265 else inRightCell = 0;
268 valuep = strchr(lineBuffer, '#');
269 if (valuep == NULL) {
274 valuep++; /* skip the "#" */
276 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
277 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
278 * so do this just in case
280 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
281 valuep[strlen(valuep) - 1] = '\0';
284 /* add the server to the VLDB list */
286 thp = gethostbyname(valuep);
287 #ifdef CELLSERV_DEBUG
288 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
289 thp, osi_LogSaveString(afsd_logp,valuep), WSAGetLastError());
292 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
294 vlSockAddr.sin_family = AF_INET;
295 /* sin_port supplied by connection code */
297 (*procp)(rockp, &vlSockAddr, valuep);
302 unsigned int c1, c2, c3, c4;
304 /* Since there is no gethostbyname() data
305 * available we will read the IP address
306 * stored in the CellServDB file
308 code = sscanf(lineBuffer, " %u.%u.%u.%u",
310 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
311 tp = (unsigned char *) &ip_addr;
316 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
318 vlSockAddr.sin_family = AF_INET;
319 /* sin_port supplied by connection code */
321 (*procp)(rockp, &vlSockAddr, valuep);
327 } /* while loop processing all lines */
329 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
330 return (foundCell) ? 0 : -11;
333 /* newCellNamep is required to be CELL_MAXNAMELEN in size */
334 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
335 cm_configProc_t *procp, void *rockp)
339 int cellHostAddrs[AFSMAXCELLHOSTS];
340 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
343 struct sockaddr_in vlSockAddr;
344 #ifdef CELLSERV_DEBUG
345 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
347 if ( IsWindowsModule(cellNamep) )
349 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
350 if (rc == 0 && numServers > 0) { /* found the cell */
351 for (i = 0; i < numServers; i++) {
352 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
354 vlSockAddr.sin_family = AF_INET;
355 /* sin_port supplied by connection code */
357 (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
359 strncpy(newCellNamep,cellNamep,CELL_MAXNAMELEN);
360 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
361 strlwr(newCellNamep);
364 return 0; /* found cell */
367 return -1; /* not found */
369 return -1; /* not found */
370 #endif /* AFS_AFSDB_ENV */
373 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
374 * generate the fully qualified name of the CellServDB
377 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
381 cm_GetConfigDir(cellNamep, len);
383 /* add trailing backslash, if required */
384 tlen = (int)strlen(cellNamep);
386 if (cellNamep[tlen-1] != '\\') {
387 strncat(cellNamep, "\\", len);
388 cellNamep[len-1] = '\0';
391 strncat(cellNamep, AFS_CELLSERVDB, len);
392 cellNamep[len-1] = '\0';
397 /* look up the root cell's name in the Registry
398 * Input buffer must be at least CELL_MAXNAMELEN
399 * in size. (Defined in cm_cell.h)
401 long cm_GetRootCellName(char *cellNamep)
403 DWORD code, dummyLen;
406 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
407 0, KEY_QUERY_VALUE, &parmKey);
408 if (code != ERROR_SUCCESS)
411 dummyLen = CELL_MAXNAMELEN;
412 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
413 cellNamep, &dummyLen);
414 RegCloseKey (parmKey);
415 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
421 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
423 char wdir[MAX_PATH]="";
426 cm_GetConfigDir(wdir, sizeof(wdir));
428 strncat(wdir, namep, sizeof(wdir));
429 wdir[sizeof(wdir)-1] = '\0';
431 tfilep = fopen(wdir, rwp);
433 return ((cm_configFile_t *) tfilep);
436 long cm_WriteConfigString(char *labelp, char *valuep)
438 DWORD code, dummyDisp;
441 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
442 0, "container", 0, KEY_SET_VALUE, NULL,
443 &parmKey, &dummyDisp);
444 if (code != ERROR_SUCCESS)
447 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
448 valuep, (DWORD)strlen(valuep) + 1);
449 RegCloseKey (parmKey);
450 if (code != ERROR_SUCCESS)
456 long cm_WriteConfigInt(char *labelp, long value)
458 DWORD code, dummyDisp;
461 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
462 0, "container", 0, KEY_SET_VALUE, NULL,
463 &parmKey, &dummyDisp);
464 if (code != ERROR_SUCCESS)
467 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
468 (LPBYTE)&value, sizeof(value));
469 RegCloseKey (parmKey);
470 if (code != ERROR_SUCCESS)
476 cm_configFile_t *cm_OpenCellFile(void)
478 cm_configFile_t *cfp;
480 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
484 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
486 cm_configFile_t *tfilep; /* input file */
488 char lineBuffer[256];
493 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
499 /* have we seen the cell line for the guy we're looking for? */
502 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
504 if (feof((FILE *)tfilep)) {
506 fclose((FILE *)tfilep);
511 /* turn trailing cr or lf into null */
512 tp = strchr(lineBuffer, '\r');
514 tp = strchr(lineBuffer, '\n');
517 /* skip blank lines */
518 if (lineBuffer[0] == 0) {
519 fprintf((FILE *)ofp, "%s\n", lineBuffer);
523 if (lineBuffer[0] == '>') {
524 /* trim off at white space or '#' chars */
525 tp = strchr(lineBuffer, ' ');
527 tp = strchr(lineBuffer, '\t');
529 tp = strchr(lineBuffer, '#');
532 /* now see if this is the right cell */
533 if (strcmp(lineBuffer+1, cellNamep) == 0) {
534 /* found the cell we're looking for */
539 fprintf((FILE *)ofp, "%s\n", lineBuffer);
543 valuep = strchr(lineBuffer, '#');
544 if (valuep == NULL) return -2;
545 valuep++; /* skip the "#" */
547 fprintf((FILE *)ofp, "%s\n", lineBuffer);
550 } /* while loop processing all lines */
553 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
555 fprintf((FILE *)filep, ">%s\n", cellNamep);
559 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
561 fprintf((FILE *)filep, "%s\n", linep);
565 long cm_CloseCellFile(cm_configFile_t *filep)
571 closeCode = fclose((FILE *)filep);
573 cm_GetConfigDir(wdir, sizeof(wdir));
576 if (closeCode != 0) {
577 /* something went wrong, preserve original database */
578 strncat(wdir, AFS_CELLSERVDB ".new", sizeof(wdir));
579 wdir[sizeof(wdir)-1] = '\0';
584 strncat(wdir, AFS_CELLSERVDB, sizeof(wdir));
585 wdir[sizeof(wdir)-1] = '\0';
586 strncat(sdir, AFS_CELLSERVDB ".new", sizeof(sdir));/* new file */
587 sdir[sizeof(sdir)-1] = '\0';
589 unlink(sdir); /* delete old file */
591 code = rename(sdir, wdir); /* do the rename */
599 void cm_GetConfigDir(char *dir, afs_uint32 len)
603 if (!afssw_GetClientCellServDBDir(&dirp)) {
604 strncpy(dir, dirp, len);