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, '.');
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;
143 if ( IsWindowsModule(cellNamep) )
146 cm_GetCellServDB(wdir, sizeof(wdir));
148 tfilep = fopen(wdir, "r");
153 bestp = fopen(wdir, "r");
155 #ifdef CELLSERV_DEBUG
156 osi_Log2(afsd_logp,"cm_searchfile fopen handle[%p], wdir[%s]", bestp,
157 osi_LogSaveString(afsd_logp,wdir));
159 /* have we seen the cell line for the guy we're looking for? */
162 tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
164 (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
170 * found partial match earlier;
183 return (foundCell? 0 : -3);
188 /* turn trailing cr or lf into null */
189 tp = strrchr(lineBuffer, '\r');
191 tp = strrchr(lineBuffer, '\n');
194 /* skip blank lines */
195 if (lineBuffer[0] == 0) continue;
199 * >[cell] [linked-cell] #[Description]
200 * where linked-cell and Description are optional
202 if (lineBuffer[0] == '>') {
206 return(foundCell ? 0 : -6);
210 * terminate the cellname at the first white space
211 * leaving 'tp' pointing to the next string if any
213 for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
216 for (tp++ ;tp && isspace(*tp); tp++);
219 for (; tp && !isspace(*tp); tp++);
225 /* now see if this is the right cell */
226 if (stricmp(lineBuffer+1, cellNamep) == 0) {
227 /* found the cell we're looking for */
229 strncpy(newCellNamep, lineBuffer+1,CELL_MAXNAMELEN);
230 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
231 strlwr(newCellNamep);
234 strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
235 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
240 #ifdef CELLSERV_DEBUG
241 osi_Log2(afsd_logp, "cm_searchfile is cell inRightCell[%p], linebuffer[%s]",
242 inRightCell, osi_LogSaveString(afsd_logp,lineBuffer));
245 else if (cm_stricmp_utf8(lineBuffer+1, cellNamep) == 0) {
247 if (partial) { /* ambiguous */
253 strncpy(newCellNamep, lineBuffer+1,CELL_MAXNAMELEN);
254 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
255 strlwr(newCellNamep);
258 strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
259 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
266 else inRightCell = 0;
269 valuep = strchr(lineBuffer, '#');
270 if (valuep == NULL) {
275 valuep++; /* skip the "#" */
277 valuep += strspn(valuep, " \t"); /* skip SP & TAB */
278 /* strip spaces and tabs in the end. They should not be there according to CellServDB format
279 * so do this just in case
281 while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t')
282 valuep[strlen(valuep) - 1] = '\0';
288 isClone = (lineBuffer[0] == '[');
290 /* copy just the first word and ignore trailing white space */
291 for ( i=0; valuep[i] && !isspace(valuep[i]) && i<sizeof(hostname); i++)
292 hostname[i] = valuep[i];
295 /* add the server to the VLDB list */
297 thp = gethostbyname(hostname);
298 #ifdef CELLSERV_DEBUG
299 osi_Log3(afsd_logp,"cm_searchfile inRightCell thp[%p], valuep[%s], WSAGetLastError[%d]",
300 thp, osi_LogSaveString(afsd_logp,hostname), WSAGetLastError());
304 for (i=0 ; thp->h_addr_list[i]; i++) {
305 if (thp->h_addrtype != AF_INET)
307 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr_list[i],
309 vlSockAddr.sin_port = htons(7003);
310 vlSockAddr.sin_family = AF_INET;
311 /* sin_port supplied by connection code */
313 (*procp)(rockp, &vlSockAddr, hostname, 0);
316 /* if we didn't find a valid address, force the use of the specified one */
322 unsigned int c1, c2, c3, c4;
324 /* Since there is no gethostbyname() data
325 * available we will read the IP address
326 * stored in the CellServDB file
329 code = sscanf(lineBuffer, "[%u.%u.%u.%u]",
332 code = sscanf(lineBuffer, " %u.%u.%u.%u",
334 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
335 tp = (unsigned char *) &ip_addr;
340 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
342 vlSockAddr.sin_port = htons(7003);
343 vlSockAddr.sin_family = AF_INET;
344 /* sin_port supplied by connection code */
346 (*procp)(rockp, &vlSockAddr, hostname, 0);
352 } /* while loop processing all lines */
354 /* if for some unknown reason cell is not found, return negative code (-11) ??? */
355 return (foundCell) ? 0 : -11;
359 * The CellServDB registry schema is as follows:
361 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\
362 * "LinkedCell" REG_SZ "[cellname]"
363 * "Description" REG_SZ "[comment]"
364 * "ForceDNS" DWORD {0,1}
366 * HKLM\SOFTWARE\OpenAFS\Client\CellServDB\[cellname]\[servername]\
367 * "HostName" REG_SZ "[hostname]"
368 * "IPv4Address" REG_SZ "[address]"
369 * "IPv6Address" REG_SZ "[address]" <future>
370 * "Comment" REG_SZ "[comment]"
371 * "Rank" DWORD "0..65535"
372 * "Clone" DWORD "{0,1}"
373 * "vlserver" DWORD "7003" <future>
374 * "ptserver" DWORD "7002" <future>
376 * ForceDNS is implied non-zero if there are no [servername]
377 * keys under the [cellname] key. Otherwise, ForceDNS is zero.
378 * If [servername] keys are specified and none of them evaluate
379 * to a valid server configuration, the return code is success.
380 * This prevents failover to the CellServDB file or DNS.
382 long cm_SearchCellRegistry(afs_uint32 client,
383 char *cellNamep, char *newCellNamep,
385 cm_configProc_t *procp, void *rockp)
387 HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
388 DWORD dwType, dwSize;
389 DWORD dwCells, dwServers, dwForceDNS;
390 DWORD dwIndex, dwRank, dwPort;
391 unsigned short ipRank;
392 unsigned short vlPort;
394 FILETIME ftLastWriteTime;
395 char szCellName[CELL_MAXNAMELEN];
396 char szServerName[MAXHOSTCHARS];
397 char szHostName[MAXHOSTCHARS];
400 struct sockaddr_in vlSockAddr;
403 if ( IsWindowsModule(cellNamep) )
406 /* No Server CellServDB list (yet) */
408 return CM_ERROR_NOSUCHCELL;
410 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
411 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
413 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
414 &hkCellServDB) != ERROR_SUCCESS)
415 return CM_ERROR_NOSUCHCELL;
417 if (RegOpenKeyEx( hkCellServDB,
420 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
421 &hkCellName) != ERROR_SUCCESS) {
424 /* We did not find an exact match. Much search for partial matches. */
426 code = RegQueryInfoKey( hkCellServDB,
429 NULL, /* lpReserved */
430 &dwCells, /* lpcSubKeys */
431 NULL, /* lpcMaxSubKeyLen */
432 NULL, /* lpcMaxClassLen */
433 NULL, /* lpcValues */
434 NULL, /* lpcMaxValueNameLen */
435 NULL, /* lpcMaxValueLen */
436 NULL, /* lpcbSecurityDescriptor */
437 &ftLastWriteTime /* lpftLastWriteTime */
439 if (code != ERROR_SUCCESS)
443 * We search the entire list to ensure that there is only
444 * one prefix match. If there is more than one, we return none.
446 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
447 dwSize = CELL_MAXNAMELEN;
448 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
449 NULL, NULL, &ftLastWriteTime);
450 if (code != ERROR_SUCCESS)
452 szCellName[CELL_MAXNAMELEN-1] = '\0';
455 /* if not a prefix match, try the next key */
456 if (strncmp(cellNamep, szCellName, strlen(cellNamep)))
459 /* If we have a prefix match and we already found another
460 * match, return neither */
463 RegCloseKey( hkCellName);
467 if (RegOpenKeyEx( hkCellServDB,
470 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
471 &hkCellName) != ERROR_SUCCESS)
475 strncpy(newCellNamep, szCellName, CELL_MAXNAMELEN);
476 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
482 RegCloseKey(hkCellServDB);
483 return CM_ERROR_NOSUCHCELL;
485 } else if (newCellNamep) {
486 strncpy(newCellNamep, cellNamep, CELL_MAXNAMELEN);
487 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
488 strlwr(newCellNamep);
492 dwSize = CELL_MAXNAMELEN;
493 code = RegQueryValueEx(hkCellName, "LinkedCell", NULL, &dwType,
494 (BYTE *) linkedNamep, &dwSize);
495 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
496 linkedNamep[CELL_MAXNAMELEN-1] = '\0';
499 linkedNamep[0] = '\0';
503 /* Check to see if DNS lookups are required */
504 dwSize = sizeof(DWORD);
505 code = RegQueryValueEx(hkCellName, "ForceDNS", NULL, &dwType,
506 (BYTE *) &dwForceDNS, &dwSize);
507 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
515 * Using the defined server list. Enumerate and populate
516 * the server list for the cell.
518 code = RegQueryInfoKey( hkCellName,
521 NULL, /* lpReserved */
522 &dwServers, /* lpcSubKeys */
523 NULL, /* lpcMaxSubKeyLen */
524 NULL, /* lpcMaxClassLen */
525 NULL, /* lpcValues */
526 NULL, /* lpcMaxValueNameLen */
527 NULL, /* lpcMaxValueLen */
528 NULL, /* lpcbSecurityDescriptor */
529 &ftLastWriteTime /* lpftLastWriteTime */
531 if (code != ERROR_SUCCESS)
534 for ( dwIndex = 0; dwIndex < dwServers; dwIndex++ ) {
535 dwSize = MAXHOSTCHARS;
536 code = RegEnumKeyEx( hkCellName, dwIndex, szServerName, &dwSize, NULL,
537 NULL, NULL, &ftLastWriteTime);
538 if (code != ERROR_SUCCESS)
541 szServerName[MAXHOSTCHARS-1] = '\0';
542 if (RegOpenKeyEx( hkCellName,
545 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
546 &hkServerName) != ERROR_SUCCESS)
549 /* We have a handle to a valid server key. Now we need
550 * to add the server to the cell */
552 /* First, see if there is an alternate hostname specified */
553 dwSize = MAXHOSTCHARS;
554 code = RegQueryValueEx(hkServerName, "HostName", NULL, &dwType,
555 (BYTE *) szHostName, &dwSize);
556 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
557 szHostName[MAXHOSTCHARS-1] = '\0';
564 dwSize = sizeof(DWORD);
565 code = RegQueryValueEx(hkServerName, "Rank", NULL, &dwType,
566 (BYTE *) &dwRank, &dwSize);
567 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
568 ipRank = (unsigned short)(dwRank <= 65535 ? dwRank : 65535);
573 dwSize = sizeof(szAddr);
574 code = RegQueryValueEx(hkServerName, "IPv4Address", NULL, &dwType,
575 (BYTE *) szAddr, &dwSize);
576 if (code == ERROR_SUCCESS && dwType == REG_SZ) {
582 dwSize = sizeof(DWORD);
583 code = RegQueryValueEx(hkServerName, "vlserver", NULL, &dwType,
584 (BYTE *) &dwPort, &dwSize);
585 if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
586 vlPort = htons((unsigned short)dwPort);
588 vlPort = htons(7003);
592 thp = gethostbyname(s);
594 memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr, sizeof(long));
595 vlSockAddr.sin_port = htons(7003);
596 vlSockAddr.sin_family = AF_INET;
597 /* sin_port supplied by connection code */
599 (*procp)(rockp, &vlSockAddr, s, ipRank);
600 } else if (szAddr[0]) {
602 unsigned int c1, c2, c3, c4;
604 /* Since there is no gethostbyname() data
605 * available we will read the IP address
606 * stored in the CellServDB file
608 code = sscanf(szAddr, " %u.%u.%u.%u",
610 if (code == 4 && c1<256 && c2<256 && c3<256 && c4<256) {
611 unsigned char * tp = (unsigned char *) &ip_addr;
616 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
618 vlSockAddr.sin_port = vlPort;
619 vlSockAddr.sin_family = AF_INET;
620 /* sin_port supplied by connection code */
622 (*procp)(rockp, &vlSockAddr, s, ipRank);
626 RegCloseKey( hkServerName);
630 RegCloseKey(hkCellName);
631 RegCloseKey(hkCellServDB);
633 return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
636 long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp)
638 HKEY hkCellServDB = 0;
643 FILETIME ftLastWriteTime;
644 char szCellName[CELL_MAXNAMELEN];
646 /* No server CellServDB in the registry. */
647 if (!client || procp == NULL)
650 if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
651 AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
653 KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
654 &hkCellServDB) != ERROR_SUCCESS)
657 code = RegQueryInfoKey( hkCellServDB,
660 NULL, /* lpReserved */
661 &dwCells, /* lpcSubKeys */
662 NULL, /* lpcMaxSubKeyLen */
663 NULL, /* lpcMaxClassLen */
664 NULL, /* lpcValues */
665 NULL, /* lpcMaxValueNameLen */
666 NULL, /* lpcMaxValueLen */
667 NULL, /* lpcbSecurityDescriptor */
668 &ftLastWriteTime /* lpftLastWriteTime */
670 if (code != ERROR_SUCCESS)
674 * Enumerate each Cell and
676 for ( dwIndex = 0; dwIndex < dwCells; dwIndex++ ) {
677 dwSize = CELL_MAXNAMELEN;
678 code = RegEnumKeyEx( hkCellServDB, dwIndex, szCellName, &dwSize, NULL,
679 NULL, NULL, &ftLastWriteTime);
680 if (code != ERROR_SUCCESS)
682 szCellName[CELL_MAXNAMELEN-1] = '\0';
685 (*procp)(rockp, szCellName);
688 RegCloseKey(hkCellServDB);
692 /* newCellNamep is required to be CELL_MAXNAMELEN in size */
693 long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
694 cm_configProc_t *procp, void *rockp)
698 int cellHostAddrs[AFSMAXCELLHOSTS];
699 char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
700 unsigned short ipRanks[AFSMAXCELLHOSTS];
701 unsigned short ports[AFSMAXCELLHOSTS];
704 struct sockaddr_in vlSockAddr;
705 #ifdef CELLSERV_DEBUG
706 osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
709 * Do not perform a DNS lookup if the name is
710 * either a well-known Windows DLL or directory,
711 * or if the name does not contain a top-level
712 * domain, or if the file prefix is the afs pioctl
715 if ( IsWindowsModule(cellNamep) ||
716 cm_FsStrChr(cellNamep, '.') == NULL ||
717 strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, strlen(CM_IOCTL_FILENAME_NOSLASH)) == 0)
720 rc = getAFSServer("afs3-vlserver", "udp", cellNamep, 7003,
721 cellHostAddrs, cellHostNames, ports, ipRanks, &numServers, ttl);
722 if (rc == 0 && numServers > 0) { /* found the cell */
723 for (i = 0; i < numServers; i++) {
724 memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
726 vlSockAddr.sin_port = ports[i];
727 vlSockAddr.sin_family = AF_INET;
729 (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]);
732 strncpy(newCellNamep,cellNamep,CELL_MAXNAMELEN);
733 newCellNamep[CELL_MAXNAMELEN-1] = '\0';
734 strlwr(newCellNamep);
736 return 0; /* found cell */
739 return -1; /* not found */
741 return -1; /* not found */
742 #endif /* AFS_AFSDB_ENV */
745 /* use cm_GetConfigDir() plus AFS_CELLSERVDB to
746 * generate the fully qualified name of the CellServDB
749 long cm_GetCellServDB(char *cellNamep, afs_uint32 len)
753 cm_GetConfigDir(cellNamep, len);
755 /* add trailing backslash, if required */
756 tlen = (int)strlen(cellNamep);
758 if (cellNamep[tlen-1] != '\\') {
759 strncat(cellNamep, "\\", len);
760 cellNamep[len-1] = '\0';
763 strncat(cellNamep, AFS_CELLSERVDB, len);
764 cellNamep[len-1] = '\0';
769 /* look up the root cell's name in the Registry
770 * Input buffer must be at least CELL_MAXNAMELEN
771 * in size. (Defined in cm_cell.h)
773 long cm_GetRootCellName(char *cellNamep)
775 DWORD code, dummyLen;
778 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
779 0, KEY_QUERY_VALUE, &parmKey);
780 if (code != ERROR_SUCCESS)
783 dummyLen = CELL_MAXNAMELEN;
784 code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
785 cellNamep, &dummyLen);
786 RegCloseKey (parmKey);
787 if (code != ERROR_SUCCESS || cellNamep[0] == 0)
793 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
795 char wdir[MAX_PATH]="";
798 cm_GetConfigDir(wdir, sizeof(wdir));
800 strncat(wdir, namep, sizeof(wdir));
801 wdir[sizeof(wdir)-1] = '\0';
803 tfilep = fopen(wdir, rwp);
805 return ((cm_configFile_t *) tfilep);
808 long cm_WriteConfigString(char *labelp, char *valuep)
810 DWORD code, dummyDisp;
813 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
814 0, "container", 0, KEY_SET_VALUE, NULL,
815 &parmKey, &dummyDisp);
816 if (code != ERROR_SUCCESS)
819 code = RegSetValueEx(parmKey, labelp, 0, REG_SZ,
820 valuep, (DWORD)strlen(valuep) + 1);
821 RegCloseKey (parmKey);
822 if (code != ERROR_SUCCESS)
828 long cm_WriteConfigInt(char *labelp, long value)
830 DWORD code, dummyDisp;
833 code = RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
834 0, "container", 0, KEY_SET_VALUE, NULL,
835 &parmKey, &dummyDisp);
836 if (code != ERROR_SUCCESS)
839 code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
840 (LPBYTE)&value, sizeof(value));
841 RegCloseKey (parmKey);
842 if (code != ERROR_SUCCESS)
848 cm_configFile_t *cm_OpenCellFile(void)
850 cm_configFile_t *cfp;
852 cfp = cm_CommonOpen(AFS_CELLSERVDB ".new", "w");
856 long cm_AppendPrunedCellList(cm_configFile_t *ofp, char *cellNamep)
858 cm_configFile_t *tfilep; /* input file */
860 char lineBuffer[256];
865 tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
871 /* have we seen the cell line for the guy we're looking for? */
874 tp = fgets(lineBuffer, sizeof(lineBuffer), (FILE *)tfilep);
876 if (feof((FILE *)tfilep)) {
878 fclose((FILE *)tfilep);
883 /* turn trailing cr or lf into null */
884 tp = strchr(lineBuffer, '\r');
886 tp = strchr(lineBuffer, '\n');
889 /* skip blank lines */
890 if (lineBuffer[0] == 0) {
891 fprintf((FILE *)ofp, "%s\n", lineBuffer);
895 if (lineBuffer[0] == '>') {
896 /* trim off at white space or '#' chars */
897 tp = strchr(lineBuffer, ' ');
899 tp = strchr(lineBuffer, '\t');
901 tp = strchr(lineBuffer, '#');
904 /* now see if this is the right cell */
905 if (strcmp(lineBuffer+1, cellNamep) == 0) {
906 /* found the cell we're looking for */
911 fprintf((FILE *)ofp, "%s\n", lineBuffer);
915 valuep = strchr(lineBuffer, '#');
916 if (valuep == NULL) return -2;
917 valuep++; /* skip the "#" */
919 fprintf((FILE *)ofp, "%s\n", lineBuffer);
922 } /* while loop processing all lines */
925 long cm_AppendNewCell(cm_configFile_t *filep, char *cellNamep)
927 fprintf((FILE *)filep, ">%s\n", cellNamep);
931 long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
933 fprintf((FILE *)filep, "%s\n", linep);
937 long cm_CloseCellFile(cm_configFile_t *filep)
943 closeCode = fclose((FILE *)filep);
945 cm_GetConfigDir(wdir, sizeof(wdir));
948 if (closeCode != 0) {
949 /* something went wrong, preserve original database */
950 strncat(wdir, AFS_CELLSERVDB ".new", sizeof(wdir));
951 wdir[sizeof(wdir)-1] = '\0';
956 strncat(wdir, AFS_CELLSERVDB, sizeof(wdir));
957 wdir[sizeof(wdir)-1] = '\0';
958 strncat(sdir, AFS_CELLSERVDB ".new", sizeof(sdir));/* new file */
959 sdir[sizeof(sdir)-1] = '\0';
961 unlink(sdir); /* delete old file */
963 code = rename(sdir, wdir); /* do the rename */
971 void cm_GetConfigDir(char *dir, afs_uint32 len)
975 if (!afssw_GetClientCellServDBDir(&dirp)) {
976 strncpy(dir, dirp, len);