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';
287 isClone = (lineBuffer[0] == '[');
289 /* copy just the first word and ignore trailing white space */
290 for ( i=0; valuep[i] && !isspace(valuep[i]) && i<sizeof(hostname); i++)
291 hostname[i] = valuep[i];
294 /* add the server to the VLDB list */
296 thp = gethostbyname(hostname);
297 #ifdef CELLSERV_DEBUG
298 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
299 thp, osi_LogSaveString(afsd_logp,hostname), WSAGetLastError());
303 for (i=0 ; thp->h_addr_list[i]; i++) {
304 if (thp->h_addrtype != AF_INET)
306 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr_list[i],
308 vlSockAddr.sin_family = AF_INET;
309 /* sin_port supplied by connection code */
311 (*procp)(rockp, &vlSockAddr, hostname, 0);
314 /* if we didn't find a valid address, force the use of the specified one */
320 unsigned int c1, c2, c3, c4;
322 /* Since there is no gethostbyname() data
323 * available we will read the IP address
324 * stored in the CellServDB file
327 code = sscanf(lineBuffer, "[%u.%u.%u.%u]",
330 code = sscanf(lineBuffer, " %u.%u.%u.%u",
332 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
333 tp = (unsigned char *) &ip_addr;
338 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
340 vlSockAddr.sin_family = AF_INET;
341 /* sin_port supplied by connection code */
343 (*procp)(rockp, &vlSockAddr, hostname, 0);
349 } /* while loop processing all lines */
351 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
352 return (foundCell) ? 0 : -11;
356 * The CellServDB registry schema is as follows:
358 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\
359 * "LinkedCell" REG_SZ "[cellname]"
360 * "Description" REG_SZ "[comment]"
361 * "ForceDNS" DWORD {0,1}
363 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\[servername]\
364 * "HostName" REG_SZ "[hostname]"
365 * "IPv4Address" REG_SZ "[address]"
366 * "IPv6Address" REG_SZ "[address]" <future>
367 * "Comment" REG_SZ "[comment]"
368 * "Rank" DWORD "0..65535"
369 * "Clone" DWORD "{0,1}"
370 * "vlserver" DWORD "7003" <future>
371 * "ptserver" DWORD ... <future>
373 * ForceDNS is implied non-zero if there are no [servername]
374 * keys under the [cellname] key. Otherwise, ForceDNS is zero.
375 * If [servername] keys are specified and none of them evaluate
376 * to a valid server configuration, the return code is success.
377 * This prevents failover to the CellServDB file or DNS.
379 long cm_SearchCellRegistry(afs_uint32 client,
380 char *cellNamep, char *newCellNamep,
382 cm_configProc_t *procp, void *rockp)
384 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
385 DWORD dwType, dwSize;
386 DWORD dwCells, dwServers, dwForceDNS;
387 DWORD dwIndex, dwRank;
388 unsigned short ipRank;
390 FILETIME ftLastWriteTime;
391 char szCellName[CELL_MAXNAMELEN];
392 char szServerName[MAXHOSTCHARS];
393 char szHostName[MAXHOSTCHARS];
396 struct sockaddr_in vlSockAddr;
399 if ( IsWindowsModule(cellNamep) )
402 /* No Server CellServDB list (yet) */
404 return CM_ERROR_NOSUCHCELL;
406 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
407 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
409 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
410 &hkCellServDB) != ERROR_SUCCESS)
411 return CM_ERROR_NOSUCHCELL;
413 if (RegOpenKeyEx( hkCellServDB,
416 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
417 &hkCellName) != ERROR_SUCCESS) {
420 /* We did not find an exact match. Much search for partial matches. */
422 code = RegQueryInfoKey( hkCellServDB,
425 NULL, /* lpReserved */
426 &dwCells, /* lpcSubKeys */
427 NULL, /* lpcMaxSubKeyLen */
428 NULL, /* lpcMaxClassLen */
429 NULL, /* lpcValues */
430 NULL, /* lpcMaxValueNameLen */
431 NULL, /* lpcMaxValueLen */
432 NULL, /* lpcbSecurityDescriptor */
433 &ftLastWriteTime /* lpftLastWriteTime */
435 if (code != ERROR_SUCCESS)
439 * We search the entire list to ensure that there is only
440 * one prefix match. If there is more than one, we return none.
442 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
443 dwSize = CELL_MAXNAMELEN;
444 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
445 NULL, NULL, &ftLastWriteTime);
446 if (code != ERROR_SUCCESS)
448 szCellName[CELL_MAXNAMELEN-1] = '\0';
451 /* if not a prefix match, try the next key */
452 if (strncmp(cellNamep, szCellName, strlen(cellNamep)))
455 /* If we have a prefix match and we already found another
456 * match, return neither */
459 RegCloseKey( hkCellName);
463 if (RegOpenKeyEx( hkCellServDB,
466 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
467 &hkCellName) != ERROR_SUCCESS)
471 strncpy(newCellNamep, szCellName, CELL_MAXNAMELEN);
472 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
478 RegCloseKey(hkCellServDB);
479 return CM_ERROR_NOSUCHCELL;
481 } else if (newCellNamep) {
482 strncpy(newCellNamep, cellNamep, CELL_MAXNAMELEN);
483 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
484 strlwr(newCellNamep);
488 dwSize = CELL_MAXNAMELEN;
489 code = RegQueryValueEx(hkCellName, "LinkedCell", NULL, &dwType,
490 (BYTE *) linkedNamep, &dwSize);
491 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
492 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
495 linkedNamep[0] = '\0';
499 /* Check to see if DNS lookups are required */
500 dwSize = sizeof(DWORD);
501 code = RegQueryValueEx(hkCellName, "ForceDNS", NULL, &dwType,
502 (BYTE *) &dwForceDNS, &dwSize);
503 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
511 * Using the defined server list. Enumerate and populate
512 * the server list for the cell.
514 code = RegQueryInfoKey( hkCellName,
517 NULL, /* lpReserved */
518 &dwServers, /* lpcSubKeys */
519 NULL, /* lpcMaxSubKeyLen */
520 NULL, /* lpcMaxClassLen */
521 NULL, /* lpcValues */
522 NULL, /* lpcMaxValueNameLen */
523 NULL, /* lpcMaxValueLen */
524 NULL, /* lpcbSecurityDescriptor */
525 &ftLastWriteTime /* lpftLastWriteTime */
527 if (code != ERROR_SUCCESS)
530 for ( dwIndex = 0; dwIndex < dwServers; dwIndex++ ) {
531 dwSize = MAXHOSTCHARS;
532 code = RegEnumKeyEx( hkCellName, dwIndex, szServerName, &dwSize, NULL,
533 NULL, NULL, &ftLastWriteTime);
534 if (code != ERROR_SUCCESS)
537 szServerName[MAXHOSTCHARS-1] = '\0';
538 if (RegOpenKeyEx( hkCellName,
541 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
542 &hkServerName) != ERROR_SUCCESS)
545 /* We have a handle to a valid server key. Now we need
546 * to add the server to the cell */
548 /* First, see if there is an alternate hostname specified */
549 dwSize = MAXHOSTCHARS;
550 code = RegQueryValueEx(hkServerName, "HostName", NULL, &dwType,
551 (BYTE *) szHostName, &dwSize);
552 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
553 szHostName[MAXHOSTCHARS-1] = '\0';
560 dwSize = sizeof(DWORD);
561 code = RegQueryValueEx(hkServerName, "Rank", NULL, &dwType,
562 (BYTE *) &dwRank, &dwSize);
563 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
564 ipRank = (unsigned short)(dwRank <= 65535 ? dwRank : 65535);
569 dwSize = sizeof(szAddr);
570 code = RegQueryValueEx(hkServerName, "IPv4Address", NULL, &dwType,
571 (BYTE *) szAddr, &dwSize);
572 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
579 thp = gethostbyname(s);
581 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr, sizeof(long));
582 vlSockAddr.sin_family = AF_INET;
583 /* sin_port supplied by connection code */
585 (*procp)(rockp, &vlSockAddr, s, ipRank);
586 } else if (szAddr[0]) {
588 unsigned int c1, c2, c3, c4;
590 /* Since there is no gethostbyname() data
591 * available we will read the IP address
592 * stored in the CellServDB file
594 code = sscanf(szAddr, " %u.%u.%u.%u",
596 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
597 unsigned char * tp = (unsigned char *) &ip_addr;
602 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
604 vlSockAddr.sin_family = AF_INET;
605 /* sin_port supplied by connection code */
607 (*procp)(rockp, &vlSockAddr, s, ipRank);
611 RegCloseKey( hkServerName);
615 RegCloseKey(hkCellName);
616 RegCloseKey(hkCellServDB);
618 return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
621 long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp)
623 HKEY hkCellServDB = 0;
624 DWORD dwType, dwSize;
628 FILETIME ftLastWriteTime;
629 char szCellName[CELL_MAXNAMELEN];
631 /* No server CellServDB in the registry. */
632 if (!client || procp == NULL)
635 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
636 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
638 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
639 &hkCellServDB) != ERROR_SUCCESS)
642 code = RegQueryInfoKey( hkCellServDB,
645 NULL, /* lpReserved */
646 &dwCells, /* lpcSubKeys */
647 NULL, /* lpcMaxSubKeyLen */
648 NULL, /* lpcMaxClassLen */
649 NULL, /* lpcValues */
650 NULL, /* lpcMaxValueNameLen */
651 NULL, /* lpcMaxValueLen */
652 NULL, /* lpcbSecurityDescriptor */
653 &ftLastWriteTime /* lpftLastWriteTime */
655 if (code != ERROR_SUCCESS)
659 * Enumerate each Cell and
661 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
662 dwSize = CELL_MAXNAMELEN;
663 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
664 NULL, NULL, &ftLastWriteTime);
665 if (code != ERROR_SUCCESS)
667 szCellName[CELL_MAXNAMELEN-1] = '\0';
670 (*procp)(rockp, szCellName);
673 RegCloseKey(hkCellServDB);
677 /* newCellNamep is required to be CELL_MAXNAMELEN in size */
678 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
679 cm_configProc_t *procp, void *rockp)
683 int cellHostAddrs[AFSMAXCELLHOSTS];
684 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
685 unsigned short ipRanks[AFSMAXCELLHOSTS];
688 struct sockaddr_in vlSockAddr;
689 #ifdef CELLSERV_DEBUG
690 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
693 * Do not perform a DNS lookup if the name is
694 * either a well-known Windows DLL or directory,
695 * or if the name does not contain a top-level
698 if ( IsWindowsModule(cellNamep) ||
699 cm_FsStrChr(cellNamep, '.') == NULL)
702 rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, ipRanks, &numServers, ttl);
703 if (rc == 0 && numServers > 0) { /* found the cell */
704 for (i = 0; i < numServers; i++) {
705 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
707 vlSockAddr.sin_family = AF_INET;
708 /* sin_port supplied by connection code */
710 (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]);
713 strncpy(newCellNamep,cellNamep,CELL_MAXNAMELEN);
714 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
715 strlwr(newCellNamep);
717 return 0; /* found cell */
720 return -1; /* not found */
722 return -1; /* not found */
723 #endif /* AFS_AFSDB_ENV */
726 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
727 * generate the fully qualified name of the CellServDB
730 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
734 cm_GetConfigDir(cellNamep, len);
736 /* add trailing backslash, if required */
737 tlen = (int)strlen(cellNamep);
739 if (cellNamep[tlen-1] != '\\') {
740 strncat(cellNamep, "\\", len);
741 cellNamep[len-1] = '\0';
744 strncat(cellNamep, AFS_CELLSERVDB, len);
745 cellNamep[len-1] = '\0';
750 /* look up the root cell's name in the Registry
751 * Input buffer must be at least CELL_MAXNAMELEN
752 * in size. (Defined in cm_cell.h)
754 long cm_GetRootCellName(char *cellNamep)
756 DWORD code, dummyLen;
759 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
760 0, KEY_QUERY_VALUE, &parmKey);
761 if (code != ERROR_SUCCESS)
764 dummyLen = CELL_MAXNAMELEN;
765 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
766 cellNamep, &dummyLen);
767 RegCloseKey (parmKey);
768 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
774 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
776 char wdir[MAX_PATH]="";
779 cm_GetConfigDir(wdir, sizeof(wdir));
781 strncat(wdir, namep, sizeof(wdir));
782 wdir[sizeof(wdir)-1] = '\0';
784 tfilep = fopen(wdir, rwp);
786 return ((cm_configFile_t *) tfilep);
789 long cm_WriteConfigString(char *labelp, char *valuep)
791 DWORD code, dummyDisp;
794 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
795 0, "container", 0, KEY_SET_VALUE, NULL,
796 &parmKey, &dummyDisp);
797 if (code != ERROR_SUCCESS)
800 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
801 valuep, (DWORD)strlen(valuep) + 1);
802 RegCloseKey (parmKey);
803 if (code != ERROR_SUCCESS)
809 long cm_WriteConfigInt(char *labelp, long value)
811 DWORD code, dummyDisp;
814 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
815 0, "container", 0, KEY_SET_VALUE, NULL,
816 &parmKey, &dummyDisp);
817 if (code != ERROR_SUCCESS)
820 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
821 (LPBYTE)&value, sizeof(value));
822 RegCloseKey (parmKey);
823 if (code != ERROR_SUCCESS)
829 cm_configFile_t *cm_OpenCellFile(void)
831 cm_configFile_t *cfp;
833 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
837 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
839 cm_configFile_t *tfilep; /* input file */
841 char lineBuffer[256];
846 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
852 /* have we seen the cell line for the guy we're looking for? */
855 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
857 if (feof((FILE *)tfilep)) {
859 fclose((FILE *)tfilep);
864 /* turn trailing cr or lf into null */
865 tp = strchr(lineBuffer, '\r');
867 tp = strchr(lineBuffer, '\n');
870 /* skip blank lines */
871 if (lineBuffer[0] == 0) {
872 fprintf((FILE *)ofp, "%s\n", lineBuffer);
876 if (lineBuffer[0] == '>') {
877 /* trim off at white space or '#' chars */
878 tp = strchr(lineBuffer, ' ');
880 tp = strchr(lineBuffer, '\t');
882 tp = strchr(lineBuffer, '#');
885 /* now see if this is the right cell */
886 if (strcmp(lineBuffer+1, cellNamep) == 0) {
887 /* found the cell we're looking for */
892 fprintf((FILE *)ofp, "%s\n", lineBuffer);
896 valuep = strchr(lineBuffer, '#');
897 if (valuep == NULL) return -2;
898 valuep++; /* skip the "#" */
900 fprintf((FILE *)ofp, "%s\n", lineBuffer);
903 } /* while loop processing all lines */
906 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
908 fprintf((FILE *)filep, ">%s\n", cellNamep);
912 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
914 fprintf((FILE *)filep, "%s\n", linep);
918 long cm_CloseCellFile(cm_configFile_t *filep)
924 closeCode = fclose((FILE *)filep);
926 cm_GetConfigDir(wdir, sizeof(wdir));
929 if (closeCode != 0) {
930 /* something went wrong, preserve original database */
931 strncat(wdir, AFS_CELLSERVDB ".new", sizeof(wdir));
932 wdir[sizeof(wdir)-1] = '\0';
937 strncat(wdir, AFS_CELLSERVDB, sizeof(wdir));
938 wdir[sizeof(wdir)-1] = '\0';
939 strncat(sdir, AFS_CELLSERVDB ".new", sizeof(sdir));/* new file */
940 sdir[sizeof(sdir)-1] = '\0';
942 unlink(sdir); /* delete old file */
944 code = rename(sdir, wdir); /* do the rename */
952 void cm_GetConfigDir(char *dir, afs_uint32 len)
956 if (!afssw_GetClientCellServDBDir(&dirp)) {
957 strncpy(dir, dirp, len);