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
19 #include <WINNT\afssw.h>
20 #include <WINNT\afsreg.h>
22 #include <afs/param.h>
24 #include <afs/cellconfig.h>
27 #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, '.');
95 /* as of 2009-09-04 these are not valid ICANN ccTLDs */
97 (!cm_stricmp_utf8N(p,".dll") ||
98 !cm_stricmp_utf8N(p,".exe") ||
99 !cm_stricmp_utf8N(p,".ini") ||
100 !cm_stricmp_utf8N(p,".db") ||
101 !cm_stricmp_utf8N(p,".drv")))
107 /* search for a cell, and either return an error code if we don't find it,
108 * or return 0 if we do, in which case we also fill in the addresses in
111 * new feature: we can handle abbreviations and are insensitive to case.
112 * If the caller wants the "real" cell name, it puts a non-null pointer in
113 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
114 * newCellNamep but return an error code.
116 * Linked Cells: the CellServDB format permits linked cells
117 * >cell [linked-cell] #Description
119 * newCellNamep and linkedNamep are required to be CELL_MAXNAMELEN in size.
121 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
122 cm_configProc_t *procp, void *rockp)
124 return cm_SearchCellFileEx(cellNamep, newCellNamep, NULL, procp, rockp);
127 long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
129 cm_configProc_t *procp, void *rockp)
131 char wdir[MAX_PATH]="";
132 FILE *tfilep = NULL, *bestp, *tempp;
134 char lineBuffer[257];
137 struct sockaddr_in vlSockAddr;
141 int tracking = 1, partial = 0;
144 if ( IsWindowsModule(cellNamep) )
147 cm_GetCellServDB(wdir, sizeof(wdir));
149 tfilep = fopen(wdir, "r");
154 bestp = fopen(wdir, "r");
156 #ifdef CELLSERV_DEBUG
157 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
158 osi_LogSaveString(afsd_logp,wdir));
160 /* have we seen the cell line for the guy we're looking for? */
163 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
165 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
171 * found partial match earlier;
184 return (foundCell? 0 : -3);
189 /* turn trailing cr or lf into null */
190 tp = strrchr(lineBuffer, '\r');
192 tp = strrchr(lineBuffer, '\n');
195 /* skip blank lines */
196 if (lineBuffer[0] == 0) continue;
200 * >[cell] [linked-cell] #[Description]
201 * where linked-cell and Description are optional
203 if (lineBuffer[0] == '>') {
207 return(foundCell ? 0 : -6);
211 * terminate the cellname at the first white space
212 * leaving 'tp' pointing to the next string if any
214 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
217 for (tp++ ;tp && isspace(*tp); tp++);
220 for (; tp && !isspace(*tp); tp++);
226 /* now see if this is the right cell */
227 if (stricmp(lineBuffer+1, cellNamep) == 0) {
228 /* found the cell we're looking for */
230 if (FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, lineBuffer+1))) {
235 strlwr(newCellNamep);
238 if (FAILED(StringCchCopy(linkedNamep, CELL_MAXNAMELEN, linkp ? linkp : ""))) {
247 #ifdef CELLSERV_DEBUG
248 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
249 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
252 else if (cm_stricmp_utf8(lineBuffer+1, cellNamep) == 0) {
254 if (partial) { /* ambiguous */
260 if (FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, lineBuffer+1))) {
265 strlwr(newCellNamep);
268 if (FAILED(StringCchCopy(linkedNamep, CELL_MAXNAMELEN, linkp ? linkp : ""))) {
279 else inRightCell = 0;
282 valuep = strchr(lineBuffer, '#');
283 if (valuep == NULL) {
288 valuep++; /* skip the "#" */
290 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
292 * strip spaces and tabs in the end. They should not be there according to CellServDB format
293 * so do this just in case
295 if(FAILED(StringCchLength(valuep, sizeof(lineBuffer), &len))) {
301 while(isspace(valuep[len]))
302 valuep[len--] = '\0';
303 while(isspace(*valuep))
311 isClone = (lineBuffer[0] == '[');
313 /* copy just the first word and ignore trailing white space */
314 for ( i=0; valuep[i] && !isspace(valuep[i]) && i<sizeof(hostname); i++)
315 hostname[i] = valuep[i];
318 /* add the server to the VLDB list */
320 thp = gethostbyname(hostname);
321 #ifdef CELLSERV_DEBUG
322 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
323 thp, osi_LogSaveString(afsd_logp,hostname), WSAGetLastError());
327 for (i=0 ; thp->h_addr_list[i]; i++) {
328 if (thp->h_addrtype != AF_INET)
330 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr_list[i],
332 vlSockAddr.sin_port = htons(7003);
333 vlSockAddr.sin_family = AF_INET;
334 /* sin_port supplied by connection code */
336 (*procp)(rockp, &vlSockAddr, hostname, 0);
339 /* if we didn't find a valid address, force the use of the specified one */
345 unsigned int c1, c2, c3, c4;
347 /* Since there is no gethostbyname() data
348 * available we will read the IP address
349 * stored in the CellServDB file
352 code = sscanf(lineBuffer, "[%u.%u.%u.%u]",
355 code = sscanf(lineBuffer, " %u.%u.%u.%u",
357 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
358 tp = (unsigned char *) &ip_addr;
363 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
365 vlSockAddr.sin_port = htons(7003);
366 vlSockAddr.sin_family = AF_INET;
367 /* sin_port supplied by connection code */
369 (*procp)(rockp, &vlSockAddr, hostname, 0);
375 } /* while loop processing all lines */
377 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
378 return (foundCell) ? 0 : -11;
382 cm_EnumerateCellFile(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
384 char wdir[MAX_PATH]="";
387 char lineBuffer[257];
392 cm_GetCellServDB(wdir, sizeof(wdir));
394 tfilep = fopen(wdir, "r");
399 #ifdef CELLSERV_DEBUG
400 osi_Log2(afsd_logp,"cm_enumfile fopen handle[%p], wdir[%s]", tfilep,
401 osi_LogSaveString(afsd_logp,wdir));
404 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
405 if (tp == NULL && feof(tfilep)) {
411 /* turn trailing cr or lf into null */
412 tp = strrchr(lineBuffer, '\r');
414 tp = strrchr(lineBuffer, '\n');
417 /* skip blank lines */
418 if (lineBuffer[0] == 0)
423 * >[cell] [linked-cell] #[Description]
424 * where linked-cell and Description are optional
425 * but we are only going to use the initial cell name
427 if (lineBuffer[0] == '>') {
429 * terminate the cellname at the first white space
430 * leaving 'tp' pointing to the next string if any
432 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
436 /* Now process the cell */
437 (*procp)(rockp, &lineBuffer[1]);
439 } /* while loop processing all lines */
445 * The CellServDB registry schema is as follows:
447 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\
448 * "LinkedCell" REG_SZ "[cellname]"
449 * "Description" REG_SZ "[comment]"
450 * "ForceDNS" DWORD {0,1}
452 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\[servername]\
453 * "HostName" REG_SZ "[hostname]"
454 * "IPv4Address" REG_SZ "[address]"
455 * "IPv6Address" REG_SZ "[address]" <future>
456 * "Comment" REG_SZ "[comment]"
457 * "Rank" DWORD "0..65535"
458 * "Clone" DWORD "{0,1}"
459 * "vlserver" DWORD "7003" <future>
460 * "ptserver" DWORD "7002" <future>
462 * ForceDNS is implied non-zero if there are no [servername]
463 * keys under the [cellname] key. Otherwise, ForceDNS is zero.
464 * If [servername] keys are specified and none of them evaluate
465 * to a valid server configuration, the return code is success.
466 * This prevents failover to the CellServDB file or DNS.
468 long cm_SearchCellRegistry(afs_uint32 client,
469 char *cellNamep, char *newCellNamep,
471 cm_configProc_t *procp, void *rockp)
473 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
474 DWORD dwType, dwSize;
475 DWORD dwCells, dwServers, dwForceDNS;
476 DWORD dwIndex, dwRank, dwPort;
477 unsigned short ipRank;
478 unsigned short vlPort;
480 FILETIME ftLastWriteTime;
481 char szCellName[CELL_MAXNAMELEN];
482 char szServerName[MAXHOSTCHARS];
483 char szHostName[MAXHOSTCHARS];
486 struct sockaddr_in vlSockAddr;
490 if ( IsWindowsModule(cellNamep) )
493 /* No Server CellServDB list (yet) */
495 return CM_ERROR_NOSUCHCELL;
497 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
498 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
500 KEY_READ|KEY_QUERY_VALUE,
501 &hkCellServDB) != ERROR_SUCCESS)
502 return CM_ERROR_NOSUCHCELL;
504 if (RegOpenKeyEx( hkCellServDB,
507 KEY_READ|KEY_QUERY_VALUE,
508 &hkCellName) != ERROR_SUCCESS) {
511 /* We did not find an exact match. Much search for partial matches. */
513 code = RegQueryInfoKey( hkCellServDB,
516 NULL, /* lpReserved */
517 &dwCells, /* lpcSubKeys */
518 NULL, /* lpcMaxSubKeyLen */
519 NULL, /* lpcMaxClassLen */
520 NULL, /* lpcValues */
521 NULL, /* lpcMaxValueNameLen */
522 NULL, /* lpcMaxValueLen */
523 NULL, /* lpcbSecurityDescriptor */
524 &ftLastWriteTime /* lpftLastWriteTime */
526 if (code != ERROR_SUCCESS)
530 * We search the entire list to ensure that there is only
531 * one prefix match. If there is more than one, we return none.
533 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
534 dwSize = CELL_MAXNAMELEN;
535 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
536 NULL, NULL, &ftLastWriteTime);
537 if (code != ERROR_SUCCESS)
539 szCellName[CELL_MAXNAMELEN-1] = '\0';
542 /* if not a prefix match, try the next key */
543 if (FAILED(StringCchLength(cellNamep, CELL_MAXNAMELEN, &len)))
546 if (strncmp(cellNamep, szCellName, len))
549 /* If we have a prefix match and we already found another
550 * match, return neither */
553 RegCloseKey( hkCellName);
557 if (RegOpenKeyEx( hkCellServDB,
560 KEY_READ|KEY_QUERY_VALUE,
561 &hkCellName) != ERROR_SUCCESS)
565 if (FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, cellNamep)))
572 RegCloseKey(hkCellServDB);
573 return CM_ERROR_NOSUCHCELL;
575 } else if (newCellNamep) {
576 strncpy(newCellNamep, cellNamep, CELL_MAXNAMELEN);
577 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
578 strlwr(newCellNamep);
582 dwSize = CELL_MAXNAMELEN;
583 code = RegQueryValueEx(hkCellName, "LinkedCell", NULL, &dwType,
584 (BYTE *) linkedNamep, &dwSize);
585 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
586 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
589 linkedNamep[0] = '\0';
593 /* Check to see if DNS lookups are required */
594 dwSize = sizeof(DWORD);
595 code = RegQueryValueEx(hkCellName, "ForceDNS", NULL, &dwType,
596 (BYTE *) &dwForceDNS, &dwSize);
597 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
605 * Using the defined server list. Enumerate and populate
606 * the server list for the cell.
608 code = RegQueryInfoKey( hkCellName,
611 NULL, /* lpReserved */
612 &dwServers, /* lpcSubKeys */
613 NULL, /* lpcMaxSubKeyLen */
614 NULL, /* lpcMaxClassLen */
615 NULL, /* lpcValues */
616 NULL, /* lpcMaxValueNameLen */
617 NULL, /* lpcMaxValueLen */
618 NULL, /* lpcbSecurityDescriptor */
619 &ftLastWriteTime /* lpftLastWriteTime */
621 if (code != ERROR_SUCCESS)
624 for ( dwIndex = 0; dwIndex < dwServers; dwIndex++ ) {
625 dwSize = MAXHOSTCHARS;
626 code = RegEnumKeyEx( hkCellName, dwIndex, szServerName, &dwSize, NULL,
627 NULL, NULL, &ftLastWriteTime);
628 if (code != ERROR_SUCCESS)
631 szServerName[MAXHOSTCHARS-1] = '\0';
632 if (RegOpenKeyEx( hkCellName,
635 KEY_READ|KEY_QUERY_VALUE,
636 &hkServerName) != ERROR_SUCCESS)
639 /* We have a handle to a valid server key. Now we need
640 * to add the server to the cell */
642 /* First, see if there is an alternate hostname specified */
643 dwSize = MAXHOSTCHARS;
644 code = RegQueryValueEx(hkServerName, "HostName", NULL, &dwType,
645 (BYTE *) szHostName, &dwSize);
646 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
647 szHostName[MAXHOSTCHARS-1] = '\0';
654 dwSize = sizeof(DWORD);
655 code = RegQueryValueEx(hkServerName, "Rank", NULL, &dwType,
656 (BYTE *) &dwRank, &dwSize);
657 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
658 ipRank = (unsigned short)(dwRank <= 65535 ? dwRank : 65535);
663 dwSize = sizeof(szAddr);
664 code = RegQueryValueEx(hkServerName, "IPv4Address", NULL, &dwType,
665 (BYTE *) szAddr, &dwSize);
666 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
672 dwSize = sizeof(DWORD);
673 code = RegQueryValueEx(hkServerName, "vlserver", NULL, &dwType,
674 (BYTE *) &dwPort, &dwSize);
675 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
676 vlPort = htons((unsigned short)dwPort);
678 vlPort = htons(7003);
682 thp = gethostbyname(s);
684 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr, sizeof(long));
685 vlSockAddr.sin_port = htons(7003);
686 vlSockAddr.sin_family = AF_INET;
687 /* sin_port supplied by connection code */
689 (*procp)(rockp, &vlSockAddr, s, ipRank);
690 } else if (szAddr[0]) {
692 unsigned int c1, c2, c3, c4;
694 /* Since there is no gethostbyname() data
695 * available we will read the IP address
696 * stored in the CellServDB file
698 code = sscanf(szAddr, " %u.%u.%u.%u",
700 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
701 unsigned char * tp = (unsigned char *) &ip_addr;
706 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
708 vlSockAddr.sin_port = vlPort;
709 vlSockAddr.sin_family = AF_INET;
710 /* sin_port supplied by connection code */
712 (*procp)(rockp, &vlSockAddr, s, ipRank);
716 RegCloseKey( hkServerName);
720 RegCloseKey(hkCellName);
721 RegCloseKey(hkCellServDB);
723 return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
727 * Following the registry schema listed above, cm_AddCellToRegistry
728 * will either create or update the registry configuration data for
729 * the specified cellname.
731 long cm_AddCellToRegistry( char * cellname,
732 char * linked_cellname,
733 unsigned short vlport,
734 afs_uint32 host_count,
738 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
739 DWORD dwPort, dwDisposition;
743 if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
744 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
747 REG_OPTION_NON_VOLATILE,
748 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
751 &dwDisposition) != ERROR_SUCCESS) {
752 code = CM_ERROR_NOACCESS;
756 /* Perform a recursive deletion of the cellname key */
757 SHDeleteKey( hkCellServDB, cellname);
759 if (RegCreateKeyEx( hkCellServDB,
763 REG_OPTION_NON_VOLATILE,
764 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
767 &dwDisposition) != ERROR_SUCCESS ||
768 (dwDisposition == REG_OPENED_EXISTING_KEY) ) {
769 code = CM_ERROR_NOACCESS;
773 /* If we get here, hkCellName is a handle to an empty key */
775 if (linked_cellname && linked_cellname[0]) {
776 code = RegSetValueEx( hkCellName, "LinkedCell",
778 (BYTE *) linked_cellname, CELL_MAXNAMELEN);
781 if (flags & CM_CELLFLAG_DNS) {
782 DWORD dwForceDNS = 1;
783 code = RegSetValueEx( hkCellName, "ForceDNS",
785 (BYTE *) &dwForceDNS, sizeof(DWORD));
788 for ( i = 0; i < host_count; i++ ) {
789 if (RegCreateKeyEx( hkCellName,
793 REG_OPTION_NON_VOLATILE,
794 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
797 &dwDisposition) != ERROR_SUCCESS ||
798 (dwDisposition == REG_OPENED_EXISTING_KEY)) {
799 code = CM_ERROR_NOACCESS;
803 /* We have a handle to a valid server key. Now we need
804 * to add the server to the cell */
806 /* First, see if there is an alternate hostname specified */
807 code = RegSetValueEx( hkServerName, "HostName",
809 (BYTE *) hostname[i], (DWORD)strlen(hostname[i]) + 1);
813 code = RegSetValueEx( hkServerName, "vlserver",
815 (BYTE *) &dwPort, (DWORD)sizeof(DWORD));
817 RegCloseKey( hkServerName);
823 RegCloseKey(hkServerName);
825 RegCloseKey(hkCellName);
827 RegCloseKey(hkCellServDB);
832 long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
834 HKEY hkCellServDB = 0;
839 FILETIME ftLastWriteTime;
840 char szCellName[CELL_MAXNAMELEN];
842 /* No server CellServDB in the registry. */
843 if (!client || procp == NULL)
846 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
847 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
849 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
850 &hkCellServDB) != ERROR_SUCCESS)
853 code = RegQueryInfoKey( hkCellServDB,
856 NULL, /* lpReserved */
857 &dwCells, /* lpcSubKeys */
858 NULL, /* lpcMaxSubKeyLen */
859 NULL, /* lpcMaxClassLen */
860 NULL, /* lpcValues */
861 NULL, /* lpcMaxValueNameLen */
862 NULL, /* lpcMaxValueLen */
863 NULL, /* lpcbSecurityDescriptor */
864 &ftLastWriteTime /* lpftLastWriteTime */
866 if (code != ERROR_SUCCESS)
870 * Enumerate each Cell and
872 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
873 dwSize = CELL_MAXNAMELEN;
874 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
875 NULL, NULL, &ftLastWriteTime);
876 if (code != ERROR_SUCCESS)
878 szCellName[CELL_MAXNAMELEN-1] = '\0';
881 (*procp)(rockp, szCellName);
884 RegCloseKey(hkCellServDB);
888 /* newCellNamep is required to be CELL_MAXNAMELEN in size */
889 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
890 cm_configProc_t *procp, void *rockp)
893 int cellHostAddrs[AFSMAXCELLHOSTS];
894 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
895 unsigned short ipRanks[AFSMAXCELLHOSTS];
896 unsigned short ports[AFSMAXCELLHOSTS]; /* network byte order */
899 struct sockaddr_in vlSockAddr;
901 #ifdef CELLSERV_DEBUG
902 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
905 * Do not perform a DNS lookup if the name is
906 * either a well-known Windows DLL or directory,
907 * or if the name does not contain a top-level
908 * domain, or if the file prefix is the afs pioctl
911 if ( IsWindowsModule(cellNamep) ||
912 cm_FsStrChr(cellNamep, '.') == NULL ||
913 strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, sizeof(CM_IOCTL_FILENAME_NOSLASH)-1) == 0)
916 rc = getAFSServer("afs3-vlserver", "udp", cellNamep, htons(7003),
917 cellHostAddrs, cellHostNames, ports, ipRanks, &numServers, ttl);
918 if (rc == 0 && numServers > 0) { /* found the cell */
919 for (i = 0; i < numServers; i++) {
920 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
922 vlSockAddr.sin_port = ports[i];
923 vlSockAddr.sin_family = AF_INET;
925 (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]);
928 if(FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, cellNamep)))
930 strlwr(newCellNamep);
932 return 0; /* found cell */
935 return -1; /* not found */
938 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
939 * generate the fully qualified name of the CellServDB
942 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
946 cm_GetConfigDir(cellNamep, len);
948 /* add trailing backslash, if required */
949 if (FAILED(StringCchLength(cellNamep, len, &tlen)))
953 if (cellNamep[tlen-1] != '\\') {
954 if (FAILED(StringCchCat(cellNamep, len, "\\")))
958 if (FAILED(StringCchCat(cellNamep, len, AFS_CELLSERVDB)))
964 /* look up the root cell's name in the Registry
965 * Input buffer must be at least CELL_MAXNAMELEN
966 * in size. (Defined in cm_cell.h)
968 long cm_GetRootCellName(char *cellNamep)
970 DWORD code, dummyLen;
973 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
974 0, KEY_QUERY_VALUE, &parmKey);
975 if (code != ERROR_SUCCESS)
978 dummyLen = CELL_MAXNAMELEN;
979 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
980 cellNamep, &dummyLen);
981 RegCloseKey (parmKey);
982 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
988 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
990 char wdir[MAX_PATH]="";
993 cm_GetConfigDir(wdir, sizeof(wdir));
995 if (FAILED(StringCchCat(wdir, MAX_PATH, namep)))
998 tfilep = fopen(wdir, rwp);
1000 return ((cm_configFile_t *) tfilep);
1003 long cm_WriteConfigString(char *labelp, char *valuep)
1005 DWORD code, dummyDisp;
1009 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1010 0, "container", 0, KEY_SET_VALUE, NULL,
1011 &parmKey, &dummyDisp);
1012 if (code != ERROR_SUCCESS)
1015 if (FAILED(StringCchLength(valuep, CM_CONFIGDEFAULT_CELLS, &len)))
1018 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ, valuep, (DWORD)(len + 1));
1019 RegCloseKey (parmKey);
1020 if (code != ERROR_SUCCESS)
1026 long cm_WriteConfigInt(char *labelp, long value)
1028 DWORD code, dummyDisp;
1031 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1032 0, "container", 0, KEY_SET_VALUE, NULL,
1033 &parmKey, &dummyDisp);
1034 if (code != ERROR_SUCCESS)
1037 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
1038 (LPBYTE)&value, sizeof(value));
1039 RegCloseKey (parmKey);
1040 if (code != ERROR_SUCCESS)
1046 cm_configFile_t *cm_OpenCellFile(void)
1048 cm_configFile_t *cfp;
1050 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
1054 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
1056 cm_configFile_t *tfilep; /* input file */
1058 char lineBuffer[256];
1063 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
1069 /* have we seen the cell line for the guy we're looking for? */
1072 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
1074 if (feof((FILE *)tfilep)) {
1076 fclose((FILE *)tfilep);
1081 /* turn trailing cr or lf into null */
1082 tp = strchr(lineBuffer, '\r');
1084 tp = strchr(lineBuffer, '\n');
1087 /* skip blank lines */
1088 if (lineBuffer[0] == 0) {
1089 fprintf((FILE *)ofp, "%s\n", lineBuffer);
1093 if (lineBuffer[0] == '>') {
1094 /* trim off at white space or '#' chars */
1095 tp = strchr(lineBuffer, ' ');
1097 tp = strchr(lineBuffer, '\t');
1099 tp = strchr(lineBuffer, '#');
1102 /* now see if this is the right cell */
1103 if (strcmp(lineBuffer+1, cellNamep) == 0) {
1104 /* found the cell we're looking for */
1109 fprintf((FILE *)ofp, "%s\n", lineBuffer);
1113 valuep = strchr(lineBuffer, '#');
1114 if (valuep == NULL) return -2;
1115 valuep++; /* skip the "#" */
1117 fprintf((FILE *)ofp, "%s\n", lineBuffer);
1120 } /* while loop processing all lines */
1123 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
1125 fprintf((FILE *)filep, ">%s\n", cellNamep);
1129 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
1131 fprintf((FILE *)filep, "%s\n", linep);
1135 long cm_CloseCellFile(cm_configFile_t *filep)
1137 char wdir[MAX_PATH];
1138 char sdir[MAX_PATH];
1140 long closeCode = fclose((FILE *)filep);
1142 cm_GetConfigDir(wdir, sizeof(wdir));
1143 if (FAILED(StringCchCopy(sdir, sizeof(sdir), wdir)))
1146 if (closeCode != 0) {
1147 /* something went wrong, preserve original database */
1148 if (FAILED(StringCchCat(wdir, sizeof(wdir), AFS_CELLSERVDB ".new")))
1154 if (FAILED(StringCchCat(wdir, sizeof(wdir), AFS_CELLSERVDB)))
1156 if (FAILED(StringCchCat(sdir, sizeof(sdir), AFS_CELLSERVDB ".new"))) /* new file */
1159 unlink(sdir); /* delete old file */
1161 code = rename(sdir, wdir); /* do the rename */
1169 void cm_GetConfigDir(char *dir, afs_uint32 len)
1173 if (!afssw_GetClientCellServDBDir(&dirp)) {
1174 if (FAILED(StringCchCopy(dir, len, dirp)))