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>
25 #include <afs/afsint.h>
27 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
36 for(tp = lineBufferp; *tp; tp++) {
45 /* comment or line end */
46 if (tc == '#' || tc == '\r' || tc == '\n')
49 /* square bracket comment -- look for closing delim */
56 if (tc == ' ' || tc == '\t')
64 /* now we have a real character, put it in the appropriate bucket */
73 /* null terminate the strings */
77 return 0; /* and return success */
81 IsWindowsModule(const char * name)
86 /* Do not perform searches for probable Windows modules */
87 for (p = name, i=0; *p; p++) {
91 p = strrchr(name, '.');
93 /* as of 2009-09-04 these are not valid ICANN ccTLDs */
95 (!cm_stricmp_utf8N(p,".dll") ||
96 !cm_stricmp_utf8N(p,".exe") ||
97 !cm_stricmp_utf8N(p,".ini") ||
98 !cm_stricmp_utf8N(p,".db") ||
99 !cm_stricmp_utf8N(p,".drv")))
105 /* search for a cell, and either return an error code if we don't find it,
106 * or return 0 if we do, in which case we also fill in the addresses in
109 * new feature: we can handle abbreviations and are insensitive to case.
110 * If the caller wants the "real" cell name, it puts a non-null pointer in
111 * newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
112 * newCellNamep but return an error code.
114 * Linked Cells: the CellServDB format permits linked cells
115 * >cell [linked-cell] #Description
117 * newCellNamep and linkedNamep are required to be CELL_MAXNAMELEN in size.
119 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
120 cm_configProc_t *procp, void *rockp)
122 return cm_SearchCellFileEx(cellNamep, newCellNamep, NULL, procp, rockp);
125 long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
127 cm_configProc_t *procp, void *rockp)
129 char wdir[MAX_PATH]="";
130 FILE *tfilep = NULL, *bestp, *tempp;
132 char lineBuffer[257];
135 struct sockaddr_in vlSockAddr;
139 int tracking = 1, partial = 0;
141 if ( IsWindowsModule(cellNamep) )
144 cm_GetCellServDB(wdir, sizeof(wdir));
146 tfilep = fopen(wdir, "r");
151 bestp = fopen(wdir, "r");
153 #ifdef CELLSERV_DEBUG
154 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
155 osi_LogSaveString(afsd_logp,wdir));
157 /* have we seen the cell line for the guy we're looking for? */
160 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
162 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
168 * found partial match earlier;
181 return (foundCell? 0 : -3);
186 /* turn trailing cr or lf into null */
187 tp = strrchr(lineBuffer, '\r');
189 tp = strrchr(lineBuffer, '\n');
192 /* skip blank lines */
193 if (lineBuffer[0] == 0) continue;
197 * >[cell] [linked-cell] #[Description]
198 * where linked-cell and Description are optional
200 if (lineBuffer[0] == '>') {
204 return(foundCell ? 0 : -6);
208 * terminate the cellname at the first white space
209 * leaving 'tp' pointing to the next string if any
211 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
214 for (tp++ ;tp && isspace(*tp); tp++);
217 for (; tp && !isspace(*tp); tp++);
223 /* now see if this is the right cell */
224 if (stricmp(lineBuffer+1, cellNamep) == 0) {
225 /* found the cell we're looking for */
227 strncpy(newCellNamep, lineBuffer+1,CELL_MAXNAMELEN);
228 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
229 strlwr(newCellNamep);
232 strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
233 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
238 #ifdef CELLSERV_DEBUG
239 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
240 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
243 else if (cm_stricmp_utf8(lineBuffer+1, cellNamep) == 0) {
245 if (partial) { /* ambiguous */
251 strncpy(newCellNamep, lineBuffer+1,CELL_MAXNAMELEN);
252 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
253 strlwr(newCellNamep);
256 strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
257 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
264 else inRightCell = 0;
267 valuep = strchr(lineBuffer, '#');
268 if (valuep == NULL) {
273 valuep++; /* skip the "#" */
275 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
276 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
277 * so do this just in case
279 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
280 valuep[strlen(valuep) - 1] = '\0';
286 isClone = (lineBuffer[0] == '[');
288 /* copy just the first word and ignore trailing white space */
289 for ( i=0; valuep[i] && !isspace(valuep[i]) && i<sizeof(hostname); i++)
290 hostname[i] = valuep[i];
293 /* add the server to the VLDB list */
295 thp = gethostbyname(hostname);
296 #ifdef CELLSERV_DEBUG
297 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
298 thp, osi_LogSaveString(afsd_logp,hostname), WSAGetLastError());
302 for (i=0 ; thp->h_addr_list[i]; i++) {
303 if (thp->h_addrtype != AF_INET)
305 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr_list[i],
307 vlSockAddr.sin_port = htons(7003);
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_port = htons(7003);
341 vlSockAddr.sin_family = AF_INET;
342 /* sin_port supplied by connection code */
344 (*procp)(rockp, &vlSockAddr, hostname, 0);
350 } /* while loop processing all lines */
352 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
353 return (foundCell) ? 0 : -11;
357 * The CellServDB registry schema is as follows:
359 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\
360 * "LinkedCell" REG_SZ "[cellname]"
361 * "Description" REG_SZ "[comment]"
362 * "ForceDNS" DWORD {0,1}
364 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\[servername]\
365 * "HostName" REG_SZ "[hostname]"
366 * "IPv4Address" REG_SZ "[address]"
367 * "IPv6Address" REG_SZ "[address]" <future>
368 * "Comment" REG_SZ "[comment]"
369 * "Rank" DWORD "0..65535"
370 * "Clone" DWORD "{0,1}"
371 * "vlserver" DWORD "7003" <future>
372 * "ptserver" DWORD "7002" <future>
374 * ForceDNS is implied non-zero if there are no [servername]
375 * keys under the [cellname] key. Otherwise, ForceDNS is zero.
376 * If [servername] keys are specified and none of them evaluate
377 * to a valid server configuration, the return code is success.
378 * This prevents failover to the CellServDB file or DNS.
380 long cm_SearchCellRegistry(afs_uint32 client,
381 char *cellNamep, char *newCellNamep,
383 cm_configProc_t *procp, void *rockp)
385 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
386 DWORD dwType, dwSize;
387 DWORD dwCells, dwServers, dwForceDNS;
388 DWORD dwIndex, dwRank, dwPort;
389 unsigned short ipRank;
390 unsigned short vlPort;
392 FILETIME ftLastWriteTime;
393 char szCellName[CELL_MAXNAMELEN];
394 char szServerName[MAXHOSTCHARS];
395 char szHostName[MAXHOSTCHARS];
398 struct sockaddr_in vlSockAddr;
401 if ( IsWindowsModule(cellNamep) )
404 /* No Server CellServDB list (yet) */
406 return CM_ERROR_NOSUCHCELL;
408 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
409 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
411 KEY_READ|KEY_QUERY_VALUE,
412 &hkCellServDB) != ERROR_SUCCESS)
413 return CM_ERROR_NOSUCHCELL;
415 if (RegOpenKeyEx( hkCellServDB,
418 KEY_READ|KEY_QUERY_VALUE,
419 &hkCellName) != ERROR_SUCCESS) {
422 /* We did not find an exact match. Much search for partial matches. */
424 code = RegQueryInfoKey( hkCellServDB,
427 NULL, /* lpReserved */
428 &dwCells, /* lpcSubKeys */
429 NULL, /* lpcMaxSubKeyLen */
430 NULL, /* lpcMaxClassLen */
431 NULL, /* lpcValues */
432 NULL, /* lpcMaxValueNameLen */
433 NULL, /* lpcMaxValueLen */
434 NULL, /* lpcbSecurityDescriptor */
435 &ftLastWriteTime /* lpftLastWriteTime */
437 if (code != ERROR_SUCCESS)
441 * We search the entire list to ensure that there is only
442 * one prefix match. If there is more than one, we return none.
444 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
445 dwSize = CELL_MAXNAMELEN;
446 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
447 NULL, NULL, &ftLastWriteTime);
448 if (code != ERROR_SUCCESS)
450 szCellName[CELL_MAXNAMELEN-1] = '\0';
453 /* if not a prefix match, try the next key */
454 if (strncmp(cellNamep, szCellName, strlen(cellNamep)))
457 /* If we have a prefix match and we already found another
458 * match, return neither */
461 RegCloseKey( hkCellName);
465 if (RegOpenKeyEx( hkCellServDB,
468 KEY_READ|KEY_QUERY_VALUE,
469 &hkCellName) != ERROR_SUCCESS)
473 strncpy(newCellNamep, szCellName, CELL_MAXNAMELEN);
474 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
480 RegCloseKey(hkCellServDB);
481 return CM_ERROR_NOSUCHCELL;
483 } else if (newCellNamep) {
484 strncpy(newCellNamep, cellNamep, CELL_MAXNAMELEN);
485 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
486 strlwr(newCellNamep);
490 dwSize = CELL_MAXNAMELEN;
491 code = RegQueryValueEx(hkCellName, "LinkedCell", NULL, &dwType,
492 (BYTE *) linkedNamep, &dwSize);
493 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
494 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
497 linkedNamep[0] = '\0';
501 /* Check to see if DNS lookups are required */
502 dwSize = sizeof(DWORD);
503 code = RegQueryValueEx(hkCellName, "ForceDNS", NULL, &dwType,
504 (BYTE *) &dwForceDNS, &dwSize);
505 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
513 * Using the defined server list. Enumerate and populate
514 * the server list for the cell.
516 code = RegQueryInfoKey( hkCellName,
519 NULL, /* lpReserved */
520 &dwServers, /* lpcSubKeys */
521 NULL, /* lpcMaxSubKeyLen */
522 NULL, /* lpcMaxClassLen */
523 NULL, /* lpcValues */
524 NULL, /* lpcMaxValueNameLen */
525 NULL, /* lpcMaxValueLen */
526 NULL, /* lpcbSecurityDescriptor */
527 &ftLastWriteTime /* lpftLastWriteTime */
529 if (code != ERROR_SUCCESS)
532 for ( dwIndex = 0; dwIndex < dwServers; dwIndex++ ) {
533 dwSize = MAXHOSTCHARS;
534 code = RegEnumKeyEx( hkCellName, dwIndex, szServerName, &dwSize, NULL,
535 NULL, NULL, &ftLastWriteTime);
536 if (code != ERROR_SUCCESS)
539 szServerName[MAXHOSTCHARS-1] = '\0';
540 if (RegOpenKeyEx( hkCellName,
543 KEY_READ|KEY_QUERY_VALUE,
544 &hkServerName) != ERROR_SUCCESS)
547 /* We have a handle to a valid server key. Now we need
548 * to add the server to the cell */
550 /* First, see if there is an alternate hostname specified */
551 dwSize = MAXHOSTCHARS;
552 code = RegQueryValueEx(hkServerName, "HostName", NULL, &dwType,
553 (BYTE *) szHostName, &dwSize);
554 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
555 szHostName[MAXHOSTCHARS-1] = '\0';
562 dwSize = sizeof(DWORD);
563 code = RegQueryValueEx(hkServerName, "Rank", NULL, &dwType,
564 (BYTE *) &dwRank, &dwSize);
565 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
566 ipRank = (unsigned short)(dwRank <= 65535 ? dwRank : 65535);
571 dwSize = sizeof(szAddr);
572 code = RegQueryValueEx(hkServerName, "IPv4Address", NULL, &dwType,
573 (BYTE *) szAddr, &dwSize);
574 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
580 dwSize = sizeof(DWORD);
581 code = RegQueryValueEx(hkServerName, "vlserver", NULL, &dwType,
582 (BYTE *) &dwPort, &dwSize);
583 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
584 vlPort = htons((unsigned short)dwPort);
586 vlPort = htons(7003);
590 thp = gethostbyname(s);
592 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr, sizeof(long));
593 vlSockAddr.sin_port = htons(7003);
594 vlSockAddr.sin_family = AF_INET;
595 /* sin_port supplied by connection code */
597 (*procp)(rockp, &vlSockAddr, s, ipRank);
598 } else if (szAddr[0]) {
600 unsigned int c1, c2, c3, c4;
602 /* Since there is no gethostbyname() data
603 * available we will read the IP address
604 * stored in the CellServDB file
606 code = sscanf(szAddr, " %u.%u.%u.%u",
608 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
609 unsigned char * tp = (unsigned char *) &ip_addr;
614 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
616 vlSockAddr.sin_port = vlPort;
617 vlSockAddr.sin_family = AF_INET;
618 /* sin_port supplied by connection code */
620 (*procp)(rockp, &vlSockAddr, s, ipRank);
624 RegCloseKey( hkServerName);
628 RegCloseKey(hkCellName);
629 RegCloseKey(hkCellServDB);
631 return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
634 long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp)
636 HKEY hkCellServDB = 0;
641 FILETIME ftLastWriteTime;
642 char szCellName[CELL_MAXNAMELEN];
644 /* No server CellServDB in the registry. */
645 if (!client || procp == NULL)
648 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
649 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
651 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
652 &hkCellServDB) != ERROR_SUCCESS)
655 code = RegQueryInfoKey( hkCellServDB,
658 NULL, /* lpReserved */
659 &dwCells, /* lpcSubKeys */
660 NULL, /* lpcMaxSubKeyLen */
661 NULL, /* lpcMaxClassLen */
662 NULL, /* lpcValues */
663 NULL, /* lpcMaxValueNameLen */
664 NULL, /* lpcMaxValueLen */
665 NULL, /* lpcbSecurityDescriptor */
666 &ftLastWriteTime /* lpftLastWriteTime */
668 if (code != ERROR_SUCCESS)
672 * Enumerate each Cell and
674 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
675 dwSize = CELL_MAXNAMELEN;
676 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
677 NULL, NULL, &ftLastWriteTime);
678 if (code != ERROR_SUCCESS)
680 szCellName[CELL_MAXNAMELEN-1] = '\0';
683 (*procp)(rockp, szCellName);
686 RegCloseKey(hkCellServDB);
690 /* newCellNamep is required to be CELL_MAXNAMELEN in size */
691 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
692 cm_configProc_t *procp, void *rockp)
695 int cellHostAddrs[AFSMAXCELLHOSTS];
696 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
697 unsigned short ipRanks[AFSMAXCELLHOSTS];
698 unsigned short ports[AFSMAXCELLHOSTS]; /* network byte order */
701 struct sockaddr_in vlSockAddr;
702 #ifdef CELLSERV_DEBUG
703 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
706 * Do not perform a DNS lookup if the name is
707 * either a well-known Windows DLL or directory,
708 * or if the name does not contain a top-level
709 * domain, or if the file prefix is the afs pioctl
712 if ( IsWindowsModule(cellNamep) ||
713 cm_FsStrChr(cellNamep, '.') == NULL ||
714 strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, strlen(CM_IOCTL_FILENAME_NOSLASH)) == 0)
717 rc = getAFSServer("afs3-vlserver", "udp", cellNamep, htons(7003),
718 cellHostAddrs, cellHostNames, ports, ipRanks, &numServers, ttl);
719 if (rc == 0 && numServers > 0) { /* found the cell */
720 for (i = 0; i < numServers; i++) {
721 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
723 vlSockAddr.sin_port = ports[i];
724 vlSockAddr.sin_family = AF_INET;
726 (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]);
729 strncpy(newCellNamep,cellNamep,CELL_MAXNAMELEN);
730 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
731 strlwr(newCellNamep);
733 return 0; /* found cell */
736 return -1; /* not found */
739 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
740 * generate the fully qualified name of the CellServDB
743 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
747 cm_GetConfigDir(cellNamep, len);
749 /* add trailing backslash, if required */
750 tlen = (int)strlen(cellNamep);
752 if (cellNamep[tlen-1] != '\\') {
753 strncat(cellNamep, "\\", len);
754 cellNamep[len-1] = '\0';
757 strncat(cellNamep, AFS_CELLSERVDB, len);
758 cellNamep[len-1] = '\0';
763 /* look up the root cell's name in the Registry
764 * Input buffer must be at least CELL_MAXNAMELEN
765 * in size. (Defined in cm_cell.h)
767 long cm_GetRootCellName(char *cellNamep)
769 DWORD code, dummyLen;
772 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
773 0, KEY_QUERY_VALUE, &parmKey);
774 if (code != ERROR_SUCCESS)
777 dummyLen = CELL_MAXNAMELEN;
778 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
779 cellNamep, &dummyLen);
780 RegCloseKey (parmKey);
781 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
787 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
789 char wdir[MAX_PATH]="";
792 cm_GetConfigDir(wdir, sizeof(wdir));
794 strncat(wdir, namep, sizeof(wdir));
795 wdir[sizeof(wdir)-1] = '\0';
797 tfilep = fopen(wdir, rwp);
799 return ((cm_configFile_t *) tfilep);
802 long cm_WriteConfigString(char *labelp, char *valuep)
804 DWORD code, dummyDisp;
807 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
808 0, "container", 0, KEY_SET_VALUE, NULL,
809 &parmKey, &dummyDisp);
810 if (code != ERROR_SUCCESS)
813 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
814 valuep, (DWORD)strlen(valuep) + 1);
815 RegCloseKey (parmKey);
816 if (code != ERROR_SUCCESS)
822 long cm_WriteConfigInt(char *labelp, long value)
824 DWORD code, dummyDisp;
827 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
828 0, "container", 0, KEY_SET_VALUE, NULL,
829 &parmKey, &dummyDisp);
830 if (code != ERROR_SUCCESS)
833 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
834 (LPBYTE)&value, sizeof(value));
835 RegCloseKey (parmKey);
836 if (code != ERROR_SUCCESS)
842 cm_configFile_t *cm_OpenCellFile(void)
844 cm_configFile_t *cfp;
846 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
850 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
852 cm_configFile_t *tfilep; /* input file */
854 char lineBuffer[256];
859 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
865 /* have we seen the cell line for the guy we're looking for? */
868 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
870 if (feof((FILE *)tfilep)) {
872 fclose((FILE *)tfilep);
877 /* turn trailing cr or lf into null */
878 tp = strchr(lineBuffer, '\r');
880 tp = strchr(lineBuffer, '\n');
883 /* skip blank lines */
884 if (lineBuffer[0] == 0) {
885 fprintf((FILE *)ofp, "%s\n", lineBuffer);
889 if (lineBuffer[0] == '>') {
890 /* trim off at white space or '#' chars */
891 tp = strchr(lineBuffer, ' ');
893 tp = strchr(lineBuffer, '\t');
895 tp = strchr(lineBuffer, '#');
898 /* now see if this is the right cell */
899 if (strcmp(lineBuffer+1, cellNamep) == 0) {
900 /* found the cell we're looking for */
905 fprintf((FILE *)ofp, "%s\n", lineBuffer);
909 valuep = strchr(lineBuffer, '#');
910 if (valuep == NULL) return -2;
911 valuep++; /* skip the "#" */
913 fprintf((FILE *)ofp, "%s\n", lineBuffer);
916 } /* while loop processing all lines */
919 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
921 fprintf((FILE *)filep, ">%s\n", cellNamep);
925 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
927 fprintf((FILE *)filep, "%s\n", linep);
931 long cm_CloseCellFile(cm_configFile_t *filep)
937 closeCode = fclose((FILE *)filep);
939 cm_GetConfigDir(wdir, sizeof(wdir));
942 if (closeCode != 0) {
943 /* something went wrong, preserve original database */
944 strncat(wdir, AFS_CELLSERVDB ".new", sizeof(wdir));
945 wdir[sizeof(wdir)-1] = '\0';
950 strncat(wdir, AFS_CELLSERVDB, sizeof(wdir));
951 wdir[sizeof(wdir)-1] = '\0';
952 strncat(sdir, AFS_CELLSERVDB ".new", sizeof(sdir));/* new file */
953 sdir[sizeof(sdir)-1] = '\0';
955 unlink(sdir); /* delete old file */
957 code = rename(sdir, wdir); /* do the rename */
965 void cm_GetConfigDir(char *dir, afs_uint32 len)
969 if (!afssw_GetClientCellServDBDir(&dirp)) {
970 strncpy(dir, dirp, len);