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
11 #include <afsconfig.h>
12 #include <afs/param.h>
23 #include <WINNT\afssw.h>
24 #include <WINNT\afsreg.h>
26 #include <afs/cellconfig.h>
29 #include <afs/afsint.h>
31 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
40 for(tp = lineBufferp; *tp; tp++) {
49 /* comment or line end */
50 if (tc == '#' || tc == '\r' || tc == '\n')
53 /* square bracket comment -- look for closing delim */
60 if (tc == ' ' || tc == '\t')
68 /* now we have a real character, put it in the appropriate bucket */
77 /* null terminate the strings */
81 return 0; /* and return success */
85 IsWindowsModule(const char * name)
90 /* Do not perform searches for probable Windows modules */
91 for (p = name, i=0; *p; p++) {
95 p = strrchr(name, '.');
97 /* as of 2009-09-04 these are not valid ICANN ccTLDs */
99 (!cm_stricmp_utf8N(p,".dll") ||
100 !cm_stricmp_utf8N(p,".exe") ||
101 !cm_stricmp_utf8N(p,".ini") ||
102 !cm_stricmp_utf8N(p,".db") ||
103 !cm_stricmp_utf8N(p,".drv")))
109 /* search for a cell, and either return an error code if we don't find it,
110 * or return 0 if we do, in which case we also fill in the addresses in
113 * new feature: we can handle abbreviations and are insensitive to case.
114 * If the caller wants the "real" cell name, it puts a non-null pointer in
115 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
116 * newCellNamep but return an error code.
118 * Linked Cells: the CellServDB format permits linked cells
119 * >cell [linked-cell] #Description
121 * newCellNamep and linkedNamep are required to be CELL_MAXNAMELEN in size.
123 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
124 cm_configProc_t *procp, void *rockp)
126 return cm_SearchCellFileEx(cellNamep, newCellNamep, NULL, procp, rockp);
129 long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
131 cm_configProc_t *procp, void *rockp)
133 char wdir[MAX_PATH]="";
134 FILE *tfilep = NULL, *bestp, *tempp;
136 char lineBuffer[257];
139 struct sockaddr_in vlSockAddr;
143 int tracking = 1, partial = 0;
146 if ( IsWindowsModule(cellNamep) )
149 cm_GetCellServDB(wdir, sizeof(wdir));
151 tfilep = fopen(wdir, "r");
156 bestp = fopen(wdir, "r");
158 #ifdef CELLSERV_DEBUG
159 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
160 osi_LogSaveString(afsd_logp,wdir));
162 /* have we seen the cell line for the guy we're looking for? */
165 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
167 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
173 * found partial match earlier;
186 return (foundCell? 0 : -3);
191 /* turn trailing cr or lf into null */
192 tp = strrchr(lineBuffer, '\r');
194 tp = strrchr(lineBuffer, '\n');
197 /* skip blank lines */
198 if (lineBuffer[0] == 0) continue;
202 * >[cell] [linked-cell] #[Description]
203 * where linked-cell and Description are optional
205 if (lineBuffer[0] == '>') {
209 return(foundCell ? 0 : -6);
213 * terminate the cellname at the first white space
214 * leaving 'tp' pointing to the next string if any
216 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
219 for (tp++ ;tp && isspace(*tp); tp++);
222 for (; tp && !isspace(*tp); tp++);
228 /* now see if this is the right cell */
229 if (stricmp(lineBuffer+1, cellNamep) == 0) {
230 /* found the cell we're looking for */
232 if (FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, lineBuffer+1))) {
237 strlwr(newCellNamep);
240 if (FAILED(StringCchCopy(linkedNamep, CELL_MAXNAMELEN, linkp ? linkp : ""))) {
249 #ifdef CELLSERV_DEBUG
250 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
251 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
254 else if (cm_stricmp_utf8(lineBuffer+1, cellNamep) == 0) {
256 if (partial) { /* ambiguous */
262 if (FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, lineBuffer+1))) {
267 strlwr(newCellNamep);
270 if (FAILED(StringCchCopy(linkedNamep, CELL_MAXNAMELEN, linkp ? linkp : ""))) {
281 else inRightCell = 0;
284 valuep = strchr(lineBuffer, '#');
285 if (valuep == NULL) {
290 valuep++; /* skip the "#" */
292 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
294 * strip spaces and tabs in the end. They should not be there according to CellServDB format
295 * so do this just in case
297 if(FAILED(StringCchLength(valuep, sizeof(lineBuffer), &len))) {
303 while(isspace(valuep[len]))
304 valuep[len--] = '\0';
305 while(isspace(*valuep))
313 isClone = (lineBuffer[0] == '[');
315 /* copy just the first word and ignore trailing white space */
316 for ( i=0; valuep[i] && !isspace(valuep[i]) && i<sizeof(hostname); i++)
317 hostname[i] = valuep[i];
320 /* add the server to the VLDB list */
322 thp = gethostbyname(hostname);
323 #ifdef CELLSERV_DEBUG
324 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
325 thp, osi_LogSaveString(afsd_logp,hostname), WSAGetLastError());
329 for (i=0 ; thp->h_addr_list[i]; i++) {
330 if (thp->h_addrtype != AF_INET)
332 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr_list[i],
334 vlSockAddr.sin_port = htons(7003);
335 vlSockAddr.sin_family = AF_INET;
336 /* sin_port supplied by connection code */
338 (*procp)(rockp, &vlSockAddr, hostname, 0);
341 /* if we didn't find a valid address, force the use of the specified one */
347 unsigned int c1, c2, c3, c4;
349 /* Since there is no gethostbyname() data
350 * available we will read the IP address
351 * stored in the CellServDB file
354 code = sscanf(lineBuffer, "[%u.%u.%u.%u]",
357 code = sscanf(lineBuffer, " %u.%u.%u.%u",
359 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
360 tp = (unsigned char *) &ip_addr;
365 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
367 vlSockAddr.sin_port = htons(7003);
368 vlSockAddr.sin_family = AF_INET;
369 /* sin_port supplied by connection code */
371 (*procp)(rockp, &vlSockAddr, hostname, 0);
377 } /* while loop processing all lines */
379 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
380 return (foundCell) ? 0 : -11;
384 cm_EnumerateCellFile(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
386 char wdir[MAX_PATH]="";
389 char lineBuffer[257];
394 cm_GetCellServDB(wdir, sizeof(wdir));
396 tfilep = fopen(wdir, "r");
401 #ifdef CELLSERV_DEBUG
402 osi_Log2(afsd_logp,"cm_enumfile fopen handle[%p], wdir[%s]", tfilep,
403 osi_LogSaveString(afsd_logp,wdir));
406 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
407 if (tp == NULL && feof(tfilep)) {
413 /* turn trailing cr or lf into null */
414 tp = strrchr(lineBuffer, '\r');
416 tp = strrchr(lineBuffer, '\n');
419 /* skip blank lines */
420 if (lineBuffer[0] == 0)
425 * >[cell] [linked-cell] #[Description]
426 * where linked-cell and Description are optional
427 * but we are only going to use the initial cell name
429 if (lineBuffer[0] == '>') {
431 * terminate the cellname at the first white space
432 * leaving 'tp' pointing to the next string if any
434 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
438 /* Now process the cell */
439 (*procp)(rockp, &lineBuffer[1]);
441 } /* while loop processing all lines */
447 * The CellServDB registry schema is as follows:
449 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\
450 * "LinkedCell" REG_SZ "[cellname]"
451 * "Description" REG_SZ "[comment]"
452 * "ForceDNS" DWORD {0,1}
454 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\[servername]\
455 * "HostName" REG_SZ "[hostname]"
456 * "IPv4Address" REG_SZ "[address]"
457 * "IPv6Address" REG_SZ "[address]" <future>
458 * "Comment" REG_SZ "[comment]"
459 * "Rank" DWORD "0..65535"
460 * "Clone" DWORD "{0,1}"
461 * "vlserver" DWORD "7003" <future>
462 * "ptserver" DWORD "7002" <future>
464 * ForceDNS is implied non-zero if there are no [servername]
465 * keys under the [cellname] key. Otherwise, ForceDNS is zero.
466 * If [servername] keys are specified and none of them evaluate
467 * to a valid server configuration, the return code is success.
468 * This prevents failover to the CellServDB file or DNS.
470 long cm_SearchCellRegistry(afs_uint32 client,
471 char *cellNamep, char *newCellNamep,
473 cm_configProc_t *procp, void *rockp)
475 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
476 DWORD dwType, dwSize;
477 DWORD dwCells, dwServers, dwForceDNS;
478 DWORD dwIndex, dwRank, dwPort;
479 unsigned short adminRank;
480 unsigned short vlPort;
482 FILETIME ftLastWriteTime;
483 char szCellName[CELL_MAXNAMELEN];
484 char szServerName[MAXHOSTCHARS];
485 char szHostName[MAXHOSTCHARS];
488 struct sockaddr_in vlSockAddr;
492 if ( IsWindowsModule(cellNamep) )
495 /* No Server CellServDB list (yet) */
497 return CM_ERROR_NOSUCHCELL;
499 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
500 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
502 KEY_READ|KEY_QUERY_VALUE,
503 &hkCellServDB) != ERROR_SUCCESS)
504 return CM_ERROR_NOSUCHCELL;
506 if (RegOpenKeyEx( hkCellServDB,
509 KEY_READ|KEY_QUERY_VALUE,
510 &hkCellName) != ERROR_SUCCESS) {
513 /* We did not find an exact match. Much search for partial matches. */
515 code = RegQueryInfoKey( hkCellServDB,
518 NULL, /* lpReserved */
519 &dwCells, /* lpcSubKeys */
520 NULL, /* lpcMaxSubKeyLen */
521 NULL, /* lpcMaxClassLen */
522 NULL, /* lpcValues */
523 NULL, /* lpcMaxValueNameLen */
524 NULL, /* lpcMaxValueLen */
525 NULL, /* lpcbSecurityDescriptor */
526 &ftLastWriteTime /* lpftLastWriteTime */
528 if (code != ERROR_SUCCESS)
532 * We search the entire list to ensure that there is only
533 * one prefix match. If there is more than one, we return none.
535 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
536 dwSize = CELL_MAXNAMELEN;
537 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
538 NULL, NULL, &ftLastWriteTime);
539 if (code != ERROR_SUCCESS)
541 szCellName[CELL_MAXNAMELEN-1] = '\0';
544 /* if not a prefix match, try the next key */
545 if (FAILED(StringCchLength(cellNamep, CELL_MAXNAMELEN, &len)))
548 if (strncmp(cellNamep, szCellName, len))
551 /* If we have a prefix match and we already found another
552 * match, return neither */
555 RegCloseKey( hkCellName);
559 if (RegOpenKeyEx( hkCellServDB,
562 KEY_READ|KEY_QUERY_VALUE,
563 &hkCellName) != ERROR_SUCCESS)
567 if (FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, cellNamep)))
574 RegCloseKey(hkCellServDB);
575 return CM_ERROR_NOSUCHCELL;
577 } else if (newCellNamep) {
578 strncpy(newCellNamep, cellNamep, CELL_MAXNAMELEN);
579 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
580 strlwr(newCellNamep);
584 dwSize = CELL_MAXNAMELEN;
585 code = RegQueryValueEx(hkCellName, "LinkedCell", NULL, &dwType,
586 (BYTE *) linkedNamep, &dwSize);
587 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
588 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
591 linkedNamep[0] = '\0';
595 /* Check to see if DNS lookups are required */
596 dwSize = sizeof(DWORD);
597 code = RegQueryValueEx(hkCellName, "ForceDNS", NULL, &dwType,
598 (BYTE *) &dwForceDNS, &dwSize);
599 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
607 * Using the defined server list. Enumerate and populate
608 * the server list for the cell.
610 code = RegQueryInfoKey( hkCellName,
613 NULL, /* lpReserved */
614 &dwServers, /* lpcSubKeys */
615 NULL, /* lpcMaxSubKeyLen */
616 NULL, /* lpcMaxClassLen */
617 NULL, /* lpcValues */
618 NULL, /* lpcMaxValueNameLen */
619 NULL, /* lpcMaxValueLen */
620 NULL, /* lpcbSecurityDescriptor */
621 &ftLastWriteTime /* lpftLastWriteTime */
623 if (code != ERROR_SUCCESS)
626 for ( dwIndex = 0; dwIndex < dwServers; dwIndex++ ) {
627 dwSize = MAXHOSTCHARS;
628 code = RegEnumKeyEx( hkCellName, dwIndex, szServerName, &dwSize, NULL,
629 NULL, NULL, &ftLastWriteTime);
630 if (code != ERROR_SUCCESS)
633 szServerName[MAXHOSTCHARS-1] = '\0';
634 if (RegOpenKeyEx( hkCellName,
637 KEY_READ|KEY_QUERY_VALUE,
638 &hkServerName) != ERROR_SUCCESS)
641 /* We have a handle to a valid server key. Now we need
642 * to add the server to the cell */
644 /* First, see if there is an alternate hostname specified */
645 dwSize = MAXHOSTCHARS;
646 code = RegQueryValueEx(hkServerName, "HostName", NULL, &dwType,
647 (BYTE *) szHostName, &dwSize);
648 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
649 szHostName[MAXHOSTCHARS-1] = '\0';
656 dwSize = sizeof(DWORD);
657 code = RegQueryValueEx(hkServerName, "Rank", NULL, &dwType,
658 (BYTE *) &dwRank, &dwSize);
659 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
660 adminRank = (unsigned short)(dwRank <= 65535 ? dwRank : 65535);
665 dwSize = sizeof(szAddr);
666 code = RegQueryValueEx(hkServerName, "IPv4Address", NULL, &dwType,
667 (BYTE *) szAddr, &dwSize);
668 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
674 dwSize = sizeof(DWORD);
675 code = RegQueryValueEx(hkServerName, "vlserver", NULL, &dwType,
676 (BYTE *) &dwPort, &dwSize);
677 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
678 vlPort = htons((unsigned short)dwPort);
680 vlPort = htons(7003);
684 thp = gethostbyname(s);
686 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr, sizeof(long));
687 vlSockAddr.sin_port = htons(7003);
688 vlSockAddr.sin_family = AF_INET;
689 /* sin_port supplied by connection code */
691 (*procp)(rockp, &vlSockAddr, s, adminRank);
692 } else if (szAddr[0]) {
694 unsigned int c1, c2, c3, c4;
696 /* Since there is no gethostbyname() data
697 * available we will read the IP address
698 * stored in the CellServDB file
700 code = sscanf(szAddr, " %u.%u.%u.%u",
702 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
703 unsigned char * tp = (unsigned char *) &ip_addr;
708 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
710 vlSockAddr.sin_port = vlPort;
711 vlSockAddr.sin_family = AF_INET;
712 /* sin_port supplied by connection code */
714 (*procp)(rockp, &vlSockAddr, s, adminRank);
718 RegCloseKey( hkServerName);
722 RegCloseKey(hkCellName);
723 RegCloseKey(hkCellServDB);
725 return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
729 * Following the registry schema listed above, cm_AddCellToRegistry
730 * will either create or update the registry configuration data for
731 * the specified cellname.
733 long cm_AddCellToRegistry( char * cellname,
734 char * linked_cellname,
735 unsigned short vlport,
736 afs_uint32 host_count,
740 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
741 DWORD dwPort, dwDisposition;
745 if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
746 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
749 REG_OPTION_NON_VOLATILE,
750 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
753 &dwDisposition) != ERROR_SUCCESS) {
754 code = CM_ERROR_NOACCESS;
758 /* Perform a recursive deletion of the cellname key */
759 SHDeleteKey( hkCellServDB, cellname);
761 if (RegCreateKeyEx( hkCellServDB,
765 REG_OPTION_NON_VOLATILE,
766 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
769 &dwDisposition) != ERROR_SUCCESS ||
770 (dwDisposition == REG_OPENED_EXISTING_KEY) ) {
771 code = CM_ERROR_NOACCESS;
775 /* If we get here, hkCellName is a handle to an empty key */
777 if (linked_cellname && linked_cellname[0]) {
778 code = RegSetValueEx( hkCellName, "LinkedCell",
780 (BYTE *) linked_cellname, CELL_MAXNAMELEN);
783 if (flags & CM_CELLFLAG_DNS) {
784 DWORD dwForceDNS = 1;
785 code = RegSetValueEx( hkCellName, "ForceDNS",
787 (BYTE *) &dwForceDNS, sizeof(DWORD));
790 for ( i = 0; i < host_count; i++ ) {
791 if (RegCreateKeyEx( hkCellName,
795 REG_OPTION_NON_VOLATILE,
796 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
799 &dwDisposition) != ERROR_SUCCESS ||
800 (dwDisposition == REG_OPENED_EXISTING_KEY)) {
801 code = CM_ERROR_NOACCESS;
805 /* We have a handle to a valid server key. Now we need
806 * to add the server to the cell */
808 /* First, see if there is an alternate hostname specified */
809 code = RegSetValueEx( hkServerName, "HostName",
811 (BYTE *) hostname[i], (DWORD)strlen(hostname[i]) + 1);
815 code = RegSetValueEx( hkServerName, "vlserver",
817 (BYTE *) &dwPort, (DWORD)sizeof(DWORD));
819 RegCloseKey( hkServerName);
825 RegCloseKey(hkServerName);
827 RegCloseKey(hkCellName);
829 RegCloseKey(hkCellServDB);
834 long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
836 HKEY hkCellServDB = 0;
841 FILETIME ftLastWriteTime;
842 char szCellName[CELL_MAXNAMELEN];
843 char * subkey = AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB";
845 /* No server CellServDB in the registry. */
846 if (!client || procp == NULL)
849 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
852 KEY_READ|KEY_QUERY_VALUE,
853 &hkCellServDB) != ERROR_SUCCESS)
856 code = RegQueryInfoKey( hkCellServDB,
859 NULL, /* lpReserved */
860 &dwCells, /* lpcSubKeys */
861 NULL, /* lpcMaxSubKeyLen */
862 NULL, /* lpcMaxClassLen */
863 NULL, /* lpcValues */
864 NULL, /* lpcMaxValueNameLen */
865 NULL, /* lpcMaxValueLen */
866 NULL, /* lpcbSecurityDescriptor */
867 &ftLastWriteTime /* lpftLastWriteTime */
869 if (code != ERROR_SUCCESS)
873 * Enumerate each Cell and
875 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
876 dwSize = CELL_MAXNAMELEN;
877 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
878 NULL, NULL, &ftLastWriteTime);
879 if (code != ERROR_SUCCESS)
881 szCellName[CELL_MAXNAMELEN-1] = '\0';
884 (*procp)(rockp, szCellName);
887 RegCloseKey(hkCellServDB);
891 /* newCellNamep is required to be CELL_MAXNAMELEN in size */
892 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
893 cm_configProc_t *procp, void *rockp)
896 int cellHostAddrs[AFSMAXCELLHOSTS];
897 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
898 unsigned short adminRanks[AFSMAXCELLHOSTS];
899 unsigned short ports[AFSMAXCELLHOSTS]; /* network byte order */
902 struct sockaddr_in vlSockAddr;
904 #ifdef CELLSERV_DEBUG
905 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
908 * Do not perform a DNS lookup if the name is
909 * either a well-known Windows DLL or directory,
910 * or if the name does not contain a top-level
911 * domain, or if the file prefix is the afs pioctl
914 if ( IsWindowsModule(cellNamep) ||
915 cm_FsStrChr(cellNamep, '.') == NULL ||
916 strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, sizeof(CM_IOCTL_FILENAME_NOSLASH)-1) == 0)
919 rc = getAFSServer("afs3-vlserver", "udp", cellNamep, htons(7003),
920 cellHostAddrs, cellHostNames, ports, adminRanks, &numServers, ttl);
921 if (rc == 0 && numServers > 0) { /* found the cell */
922 for (i = 0; i < numServers; i++) {
923 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
925 vlSockAddr.sin_port = ports[i];
926 vlSockAddr.sin_family = AF_INET;
928 (*procp)(rockp, &vlSockAddr, cellHostNames[i], adminRanks[i]);
931 if(FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, cellNamep)))
933 strlwr(newCellNamep);
935 return 0; /* found cell */
938 return -1; /* not found */
941 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
942 * generate the fully qualified name of the CellServDB
945 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
949 cm_GetConfigDir(cellNamep, len);
951 /* add trailing backslash, if required */
952 if (FAILED(StringCchLength(cellNamep, len, &tlen)))
956 if (cellNamep[tlen-1] != '\\') {
957 if (FAILED(StringCchCat(cellNamep, len, "\\")))
961 if (FAILED(StringCchCat(cellNamep, len, AFS_CELLSERVDB)))
967 /* look up the root cell's name in the Registry
968 * Input buffer must be at least CELL_MAXNAMELEN
969 * in size. (Defined in cm_cell.h)
971 long cm_GetRootCellName(char *cellNamep)
973 DWORD code, dummyLen;
976 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
977 0, KEY_QUERY_VALUE, &parmKey);
978 if (code != ERROR_SUCCESS)
981 dummyLen = CELL_MAXNAMELEN;
982 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
983 cellNamep, &dummyLen);
984 RegCloseKey (parmKey);
985 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
991 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
993 char wdir[MAX_PATH]="";
996 cm_GetConfigDir(wdir, sizeof(wdir));
998 if (FAILED(StringCchCat(wdir, MAX_PATH, namep)))
1001 tfilep = fopen(wdir, rwp);
1003 return ((cm_configFile_t *) tfilep);
1006 long cm_WriteConfigString(char *labelp, char *valuep)
1008 DWORD code, dummyDisp;
1012 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1013 0, "container", 0, KEY_SET_VALUE, NULL,
1014 &parmKey, &dummyDisp);
1015 if (code != ERROR_SUCCESS)
1018 if (FAILED(StringCchLength(valuep, CM_CONFIGDEFAULT_CELLS, &len)))
1021 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ, valuep, (DWORD)(len + 1));
1022 RegCloseKey (parmKey);
1023 if (code != ERROR_SUCCESS)
1029 long cm_WriteConfigInt(char *labelp, long value)
1031 DWORD code, dummyDisp;
1034 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1035 0, "container", 0, KEY_SET_VALUE, NULL,
1036 &parmKey, &dummyDisp);
1037 if (code != ERROR_SUCCESS)
1040 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
1041 (LPBYTE)&value, sizeof(value));
1042 RegCloseKey (parmKey);
1043 if (code != ERROR_SUCCESS)
1049 cm_configFile_t *cm_OpenCellFile(void)
1051 cm_configFile_t *cfp;
1053 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
1057 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
1059 cm_configFile_t *tfilep; /* input file */
1061 char lineBuffer[256];
1066 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
1072 /* have we seen the cell line for the guy we're looking for? */
1075 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
1077 if (feof((FILE *)tfilep)) {
1079 fclose((FILE *)tfilep);
1084 /* turn trailing cr or lf into null */
1085 tp = strchr(lineBuffer, '\r');
1087 tp = strchr(lineBuffer, '\n');
1090 /* skip blank lines */
1091 if (lineBuffer[0] == 0) {
1092 fprintf((FILE *)ofp, "%s\n", lineBuffer);
1096 if (lineBuffer[0] == '>') {
1097 /* trim off at white space or '#' chars */
1098 tp = strchr(lineBuffer, ' ');
1100 tp = strchr(lineBuffer, '\t');
1102 tp = strchr(lineBuffer, '#');
1105 /* now see if this is the right cell */
1106 if (strcmp(lineBuffer+1, cellNamep) == 0) {
1107 /* found the cell we're looking for */
1112 fprintf((FILE *)ofp, "%s\n", lineBuffer);
1116 valuep = strchr(lineBuffer, '#');
1117 if (valuep == NULL) return -2;
1118 valuep++; /* skip the "#" */
1120 fprintf((FILE *)ofp, "%s\n", lineBuffer);
1123 } /* while loop processing all lines */
1126 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
1128 fprintf((FILE *)filep, ">%s\n", cellNamep);
1132 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
1134 fprintf((FILE *)filep, "%s\n", linep);
1138 long cm_CloseCellFile(cm_configFile_t *filep)
1140 char wdir[MAX_PATH];
1141 char sdir[MAX_PATH];
1143 long closeCode = fclose((FILE *)filep);
1145 cm_GetConfigDir(wdir, sizeof(wdir));
1146 if (FAILED(StringCchCopy(sdir, sizeof(sdir), wdir)))
1149 if (closeCode != 0) {
1150 /* something went wrong, preserve original database */
1151 if (FAILED(StringCchCat(wdir, sizeof(wdir), AFS_CELLSERVDB ".new")))
1157 if (FAILED(StringCchCat(wdir, sizeof(wdir), AFS_CELLSERVDB)))
1159 if (FAILED(StringCchCat(sdir, sizeof(sdir), AFS_CELLSERVDB ".new"))) /* new file */
1162 unlink(sdir); /* delete old file */
1164 code = rename(sdir, wdir); /* do the rename */
1172 void cm_GetConfigDir(char *dir, afs_uint32 len)
1176 if (!afssw_GetClientCellServDBDir(&dirp)) {
1177 if (FAILED(StringCchCopy(dir, len, dirp)))