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>
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 AFSDCELL.INI */
71 GetWindowsDirectory (pszFilename, MAX_CSDB_PATH);
73 if (pszFilename[ strlen(pszFilename)-1 ] != '\\')
74 strcat (pszFilename, "\\");
76 strcat (pszFilename, "AFSDCELL.INI");
78 strcpy (pszFilename, "/usr/vice/etc/CellServDB");
83 BOOL CSDB_ReadFile (PCELLSERVDB pCellServDB, const char *pszFilename)
94 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
96 /* Open AFSDCELL.INI and read it into memory. */
99 strcpy (pCellServDB->szFilename, pszFilename);
101 CSDB_GetFileName (pCellServDB->szFilename);
103 if ((pFile = fopen (pCellServDB->szFilename, "r")) != NULL)
106 cbLength = ftell (pFile);
109 pszBuffer = (char*)malloc (sizeof(char) * (cbLength +2));
111 if ((cbRead = fread (pszBuffer, 1, cbLength, pFile)) != 0)
113 pszBuffer[ cbRead ] = '\0';
114 pszBuffer[ cbRead+1 ] = '\0';
116 /* Scan the file line-by-line... */
118 for (pszStart = pszBuffer; pszStart && *pszStart; )
120 while (iswhiteeol(*pszStart))
125 for (pszEnd = pszStart; *pszEnd && !iseol(*pszEnd); ++pszEnd)
129 /* Add this line to our chain */
131 pLine = new(CELLDBLINE);
132 memset (pLine, 0x00, sizeof(CELLDBLINE));
133 strzcpy (pLine->szLine, pszStart, cchCELLDBLINE-1);
134 pLine->szLine[ cchCELLDBLINE-1 ] = '\0';
135 if ((pLine->pPrev = pCellServDB->pLast) != NULL)
136 pLine->pPrev->pNext = pLine;
137 if ((pCellServDB->pLast = pLine)->pPrev == NULL)
138 pCellServDB->pFirst = pLine;
140 /* Process the next line in the file */
156 BOOL CSDB_WriteFile (PCELLSERVDB pCellServDB)
160 char szLine[ cchCELLDBLINE ];
163 if (pCellServDB->fChanged)
165 if ((pFile = fopen (pCellServDB->szFilename, "w")) == NULL)
171 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
174 sprintf (szLine, "%s\r\n", pLine->szLine);
176 sprintf (szLine, "%s\n", pLine->szLine);
178 fwrite (szLine, 1, strlen(szLine), pFile);
184 pCellServDB->fChanged = FALSE;
191 void CSDB_FreeFile (PCELLSERVDB pCellServDB)
195 for (pLine = pCellServDB->pFirst; pLine; pLine = pNext)
197 pNext = pLine->pNext;
200 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
204 BOOL CSDB_CrackLine (PCELLDBLINEINFO pInfo, const char *pszLine)
208 BOOL fSawHash = FALSE;
210 memset (pInfo, 0x00, sizeof(CELLDBLINEINFO));
212 if (!pszLine || !*pszLine)
215 while (iswhite(*pszLine))
220 else if (!isdigit (*pszLine))
222 else /* (isdigit (*pszLine)) */
225 for (pszOut = pInfo->szCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
226 *pszOut++ = *pszLine++;
229 while (iswhite(*pszLine) || (*pszLine == '#'))
231 fSawHash = fSawHash || (*pszLine == '#');
235 if (fIsCell && *pszLine && !fSawHash)
237 for (pszOut = pInfo->szLinkedCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
238 *pszOut++ = *pszLine++;
241 while (iswhite(*pszLine) || (*pszLine == '#'))
245 for (pszOut = pInfo->szComment; *pszLine; )
246 *pszOut++ = *pszLine++;
249 if (!pInfo->szCell[0])
254 if ((pInfo->ipServer = inet_addr (pInfo->szCell)) == 0xffffffff)
256 pInfo->szCell[0] = '\0';
263 BOOL CSDB_FormatLine (char *pszLine, const char *pszCell, const char *pszLinkedCell, const char *pszComment, BOOL fIsCell)
266 sprintf (pszLine, ">%s", pszCell);
268 strcpy (pszLine, pszCell);
270 if (fIsCell && pszLinkedCell && *pszLinkedCell)
271 sprintf (&pszLine[ strlen(pszLine) ], " %s", pszLinkedCell);
275 size_t cchSpacing = (fIsCell) ? 28 : 33;
276 strcat (pszLine, " ");
277 if ((size_t)strlen(pszLine) < cchSpacing)
279 strcat (pszLine, " ");
280 pszLine[cchSpacing] = '\0';
283 sprintf (&pszLine[ strlen(pszLine) ], ((fIsCell) ? "# %s" : "#%s"), pszComment);
290 PCELLDBLINE CSDB_FindCell (PCELLSERVDB pCellServDB, const char *pszCell)
293 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
296 if (!CSDB_CrackLine (&Info, pLine->szLine))
298 if (!strcmpi (Info.szCell, pszCell))
305 BOOL CSDB_OnRemove (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine, BOOL fRemoveCellLineToo)
311 /* Quick validation: make sure the caller specified a Cell line */
315 if (!CSDB_CrackLine (&Info, pCellLine->szLine))
320 /* Remove everything about this cell (except maybe the cell line) */
322 pLine = (fRemoveCellLineToo) ? pCellLine : pCellLine->pNext;
323 for ( ; pLine; pLine = pNext)
325 if ((pNext = CSDB_RemoveLine (pCellServDB, pLine)) != NULL)
327 if (!CSDB_CrackLine (&Info, pNext->szLine))
329 if (Info.szCell[0]) /* Hit the next cell? We're done! */
334 pCellServDB->fChanged = TRUE;
338 BOOL CSDB_RemoveCell (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine)
340 return CSDB_OnRemove (pCellServDB, pCellLine, TRUE);
343 BOOL CSDB_RemoveCellServers (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine)
345 return CSDB_OnRemove (pCellServDB, pCellLine, FALSE);
349 PCELLDBLINE CSDB_AddCell (PCELLSERVDB pCellServDB, const char *pszCell, const char *pszLinkedCell, const char *pszComment)
351 PCELLDBLINE pCellLine;
353 /* Find out if there's already an entry in CellServDB for this cell; */
354 /* add one if necessary. */
356 if ((pCellLine = CSDB_FindCell (pCellServDB, pszCell)) == NULL)
358 pCellLine = new(CELLDBLINE);
359 memset (pCellLine, 0x00, sizeof(CELLDBLINE));
360 if ((pCellLine->pPrev = pCellServDB->pLast) != NULL)
361 pCellLine->pPrev->pNext = pCellLine;
362 if ((pCellServDB->pLast = pCellLine)->pPrev == NULL)
363 pCellServDB->pFirst = pCellLine;
366 CSDB_FormatLine (pCellLine->szLine, pszCell, pszLinkedCell, pszComment, TRUE);
367 pCellServDB->fChanged = TRUE;
372 PCELLDBLINE CSDB_AddCellServer (PCELLSERVDB pCellServDB, PCELLDBLINE pAddAfter, const char *pszAddress, const char *pszComment)
374 char szLine[ cchCELLDBLINE ];
375 CSDB_FormatLine (szLine, pszAddress, NULL, pszComment, FALSE);
376 return CSDB_AddLine (pCellServDB, pAddAfter, szLine);
380 PCELLDBLINE CSDB_AddLine (PCELLSERVDB pCellServDB, PCELLDBLINE pAddAfter, const char *pszLine)
382 PCELLDBLINE pNew = new(CELLDBLINE);
383 memset (pNew, 0x00, sizeof(CELLDBLINE));
384 strcpy (pNew->szLine, pszLine);
386 if (pAddAfter == NULL)
388 if ((pNew->pNext = pCellServDB->pFirst) != NULL)
389 pNew->pNext->pPrev = pNew;
391 pCellServDB->pFirst = pNew;
392 if (pCellServDB->pLast == NULL)
393 pCellServDB->pLast = pNew;
395 else /* (pAddAfter != NULL) */
397 if ((pNew->pNext = pAddAfter->pNext) != NULL)
398 pNew->pNext->pPrev = pNew->pPrev;
399 pNew->pPrev = pAddAfter;
400 pAddAfter->pNext = pNew;
401 if (pCellServDB->pLast == pAddAfter)
402 pCellServDB->pLast = pNew;
405 pCellServDB->fChanged = TRUE;
410 PCELLDBLINE CSDB_RemoveLine (PCELLSERVDB pCellServDB, PCELLDBLINE pRemove)
417 pNext = pRemove->pNext;
420 pRemove->pPrev->pNext = pRemove->pNext;
422 pRemove->pNext->pPrev = pRemove->pPrev;
423 if (pCellServDB->pFirst == pRemove)
424 pCellServDB->pFirst = pRemove->pNext;
425 if (pCellServDB->pLast == pRemove)
426 pCellServDB->pLast = pRemove->pPrev;
430 pCellServDB->fChanged = TRUE;