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
10 #include <afs/param.h>
17 #include "cellservdb.h"
23 #include <sys/socket.h>
25 #include <WINNT\afsreg.h>
28 * PROTOTYPES _________________________________________________________________
32 #define new(_t) (_t*)malloc(sizeof(_t))
33 #define delete(_p) free((void*)(_p))
36 #define iswhite(_ch) (((_ch)==' ') || ((_ch)=='\t'))
39 #define iseol(_ch) (((_ch)=='\r') || ((_ch)=='\n'))
42 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
45 #define min(_a,_b) ((_a) < (_b) ? (_a) : (_b))
50 * STATICS ____________________________________________________________________
54 static void strzcpy (char *pszTarget, const char *pszSource, size_t cch)
56 cch = min(cch, (size_t)(1+strlen(pszSource)));
57 strncpy (pszTarget, pszSource, cch-1);
58 pszTarget[ cch-1 ] = '\0';
63 * ROUTINES ___________________________________________________________________
67 void CSDB_GetFileName (char *pszFilename)
70 /* Find the appropriate CellServDB */
76 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
77 0, KEY_QUERY_VALUE, &parmKey);
78 if (code != ERROR_SUCCESS)
81 dummyLen = MAX_CSDB_PATH;
82 code = RegQueryValueEx(parmKey, "CellServDBDir", NULL, NULL,
83 pszFilename, &dummyLen);
84 RegCloseKey (parmKey);
87 if (code != ERROR_SUCCESS || pszFilename[0] == 0) {
88 afssw_GetClientInstallDir(&clientdir);
90 strncpy(pszFilename, clientdir, MAX_CSDB_PATH);
91 pszFilename[MAX_CSDB_PATH - 1] = '\0';
94 if (pszFilename[ strlen(pszFilename)-1 ] != '\\')
95 strcat (pszFilename, "\\");
97 strcat (pszFilename, "CellServDB");
99 strcpy (pszFilename, "/usr/vice/etc/CellServDB");
104 BOOL CSDB_ReadFile (PCELLSERVDB pCellServDB, const char *pszFilename)
115 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
117 /* Open AFSDCELL.INI and read it into memory. */
120 strcpy (pCellServDB->szFilename, pszFilename);
122 CSDB_GetFileName (pCellServDB->szFilename);
124 if ((pFile = fopen (pCellServDB->szFilename, "r")) != NULL)
127 cbLength = ftell (pFile);
130 pszBuffer = (char*)malloc (sizeof(char) * (cbLength +2));
132 if ((cbRead = fread (pszBuffer, 1, cbLength, pFile)) != 0)
134 pszBuffer[ cbRead ] = '\0';
135 pszBuffer[ cbRead+1 ] = '\0';
137 /* Scan the file line-by-line... */
139 for (pszStart = pszBuffer; pszStart && *pszStart; )
141 while (iswhiteeol(*pszStart))
146 for (pszEnd = pszStart; *pszEnd && !iseol(*pszEnd); ++pszEnd)
150 /* Add this line to our chain */
152 pLine = new(CELLDBLINE);
153 memset (pLine, 0x00, sizeof(CELLDBLINE));
154 strzcpy (pLine->szLine, pszStart, cchCELLDBLINE-1);
155 pLine->szLine[ cchCELLDBLINE-1 ] = '\0';
156 if ((pLine->pPrev = pCellServDB->pLast) != NULL)
157 pLine->pPrev->pNext = pLine;
158 if ((pCellServDB->pLast = pLine)->pPrev == NULL)
159 pCellServDB->pFirst = pLine;
161 /* Process the next line in the file */
177 BOOL CSDB_WriteFile (PCELLSERVDB pCellServDB)
181 char szLine[ cchCELLDBLINE ];
184 if (pCellServDB->fChanged)
186 if ((pFile = fopen (pCellServDB->szFilename, "w")) == NULL)
192 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
195 sprintf (szLine, "%s\r\n", pLine->szLine);
197 sprintf (szLine, "%s\n", pLine->szLine);
199 fwrite (szLine, 1, strlen(szLine), pFile);
205 pCellServDB->fChanged = FALSE;
212 void CSDB_FreeFile (PCELLSERVDB pCellServDB)
216 for (pLine = pCellServDB->pFirst; pLine; pLine = pNext)
218 pNext = pLine->pNext;
221 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
225 BOOL CSDB_CrackLine (PCELLDBLINEINFO pInfo, const char *pszLine)
229 BOOL fSawHash = FALSE;
231 memset (pInfo, 0x00, sizeof(CELLDBLINEINFO));
233 if (!pszLine || !*pszLine)
236 while (iswhite(*pszLine))
241 else if (!isdigit (*pszLine))
243 else /* (isdigit (*pszLine)) */
246 for (pszOut = pInfo->szCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
247 *pszOut++ = *pszLine++;
250 while (iswhite(*pszLine) || (*pszLine == '#'))
252 fSawHash = fSawHash || (*pszLine == '#');
256 if (fIsCell && *pszLine && !fSawHash)
258 for (pszOut = pInfo->szLinkedCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
259 *pszOut++ = *pszLine++;
262 while (iswhite(*pszLine) || (*pszLine == '#'))
266 for (pszOut = pInfo->szComment; *pszLine; )
267 *pszOut++ = *pszLine++;
270 if (!pInfo->szCell[0])
275 if ((pInfo->ipServer = inet_addr (pInfo->szCell)) == 0xffffffff)
277 pInfo->szCell[0] = '\0';
284 BOOL CSDB_FormatLine (char *pszLine, const char *pszCell, const char *pszLinkedCell, const char *pszComment, BOOL fIsCell)
287 sprintf (pszLine, ">%s", pszCell);
289 strcpy (pszLine, pszCell);
291 if (fIsCell && pszLinkedCell && *pszLinkedCell)
292 sprintf (&pszLine[ strlen(pszLine) ], " %s", pszLinkedCell);
296 size_t cchSpacing = (fIsCell) ? 28 : 33;
297 strcat (pszLine, " ");
298 if ((size_t)strlen(pszLine) < cchSpacing)
300 strcat (pszLine, " ");
301 pszLine[cchSpacing] = '\0';
304 sprintf (&pszLine[ strlen(pszLine) ], ((fIsCell) ? "# %s" : "#%s"), pszComment);
311 PCELLDBLINE CSDB_FindCell (PCELLSERVDB pCellServDB, const char *pszCell)
314 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
317 if (!CSDB_CrackLine (&Info, pLine->szLine))
319 if (!strcmpi (Info.szCell, pszCell))
326 BOOL CSDB_OnRemove (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine, BOOL fRemoveCellLineToo)
332 /* Quick validation: make sure the caller specified a Cell line */
336 if (!CSDB_CrackLine (&Info, pCellLine->szLine))
341 /* Remove everything about this cell (except maybe the cell line) */
343 pLine = (fRemoveCellLineToo) ? pCellLine : pCellLine->pNext;
344 for ( ; pLine; pLine = pNext)
346 if ((pNext = CSDB_RemoveLine (pCellServDB, pLine)) != NULL)
348 if (!CSDB_CrackLine (&Info, pNext->szLine))
350 if (Info.szCell[0]) /* Hit the next cell? We're done! */
355 pCellServDB->fChanged = TRUE;
359 BOOL CSDB_RemoveCell (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine)
361 return CSDB_OnRemove (pCellServDB, pCellLine, TRUE);
364 BOOL CSDB_RemoveCellServers (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine)
366 return CSDB_OnRemove (pCellServDB, pCellLine, FALSE);
370 PCELLDBLINE CSDB_AddCell (PCELLSERVDB pCellServDB, const char *pszCell, const char *pszLinkedCell, const char *pszComment)
372 PCELLDBLINE pCellLine;
374 /* Find out if there's already an entry in CellServDB for this cell; */
375 /* add one if necessary. */
377 if ((pCellLine = CSDB_FindCell (pCellServDB, pszCell)) == NULL)
379 pCellLine = new(CELLDBLINE);
380 memset (pCellLine, 0x00, sizeof(CELLDBLINE));
381 if ((pCellLine->pPrev = pCellServDB->pLast) != NULL)
382 pCellLine->pPrev->pNext = pCellLine;
383 if ((pCellServDB->pLast = pCellLine)->pPrev == NULL)
384 pCellServDB->pFirst = pCellLine;
387 CSDB_FormatLine (pCellLine->szLine, pszCell, pszLinkedCell, pszComment, TRUE);
388 pCellServDB->fChanged = TRUE;
393 PCELLDBLINE CSDB_AddCellServer (PCELLSERVDB pCellServDB, PCELLDBLINE pAddAfter, const char *pszAddress, const char *pszComment)
395 char szLine[ cchCELLDBLINE ];
396 CSDB_FormatLine (szLine, pszAddress, NULL, pszComment, FALSE);
397 return CSDB_AddLine (pCellServDB, pAddAfter, szLine);
401 PCELLDBLINE CSDB_AddLine (PCELLSERVDB pCellServDB, PCELLDBLINE pAddAfter, const char *pszLine)
403 PCELLDBLINE pNew = new(CELLDBLINE);
404 memset (pNew, 0x00, sizeof(CELLDBLINE));
405 strcpy (pNew->szLine, pszLine);
407 if (pAddAfter == NULL)
409 if ((pNew->pNext = pCellServDB->pFirst) != NULL)
410 pNew->pNext->pPrev = pNew;
412 pCellServDB->pFirst = pNew;
413 if (pCellServDB->pLast == NULL)
414 pCellServDB->pLast = pNew;
416 else /* (pAddAfter != NULL) */
418 if ((pNew->pNext = pAddAfter->pNext) != NULL)
419 pNew->pNext->pPrev = pNew->pPrev;
420 pNew->pPrev = pAddAfter;
421 pAddAfter->pNext = pNew;
422 if (pCellServDB->pLast == pAddAfter)
423 pCellServDB->pLast = pNew;
426 pCellServDB->fChanged = TRUE;
431 PCELLDBLINE CSDB_RemoveLine (PCELLSERVDB pCellServDB, PCELLDBLINE pRemove)
438 pNext = pRemove->pNext;
441 pRemove->pPrev->pNext = pRemove->pNext;
443 pRemove->pNext->pPrev = pRemove->pPrev;
444 if (pCellServDB->pFirst == pRemove)
445 pCellServDB->pFirst = pRemove->pNext;
446 if (pCellServDB->pLast == pRemove)
447 pCellServDB->pLast = pRemove->pPrev;
451 pCellServDB->fChanged = TRUE;