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 CellServDB */
72 afssw_GetClientInstallDir(&clientdir);
74 strncpy(pszFilename, clientdir, MAX_CSDB_PATH);
75 pszFilename[MAX_CSDB_PATH - 1] = '\0';
77 if (pszFilename[ strlen(pszFilename)-1 ] != '\\')
78 strcat (pszFilename, "\\");
80 strcat (pszFilename, "CellServDB");
82 strcpy (pszFilename, "/usr/vice/etc/CellServDB");
87 BOOL CSDB_ReadFile (PCELLSERVDB pCellServDB, const char *pszFilename)
98 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
100 /* Open AFSDCELL.INI and read it into memory. */
103 strcpy (pCellServDB->szFilename, pszFilename);
105 CSDB_GetFileName (pCellServDB->szFilename);
107 if ((pFile = fopen (pCellServDB->szFilename, "r")) != NULL)
110 cbLength = ftell (pFile);
113 pszBuffer = (char*)malloc (sizeof(char) * (cbLength +2));
115 if ((cbRead = fread (pszBuffer, 1, cbLength, pFile)) != 0)
117 pszBuffer[ cbRead ] = '\0';
118 pszBuffer[ cbRead+1 ] = '\0';
120 /* Scan the file line-by-line... */
122 for (pszStart = pszBuffer; pszStart && *pszStart; )
124 while (iswhiteeol(*pszStart))
129 for (pszEnd = pszStart; *pszEnd && !iseol(*pszEnd); ++pszEnd)
133 /* Add this line to our chain */
135 pLine = new(CELLDBLINE);
136 memset (pLine, 0x00, sizeof(CELLDBLINE));
137 strzcpy (pLine->szLine, pszStart, cchCELLDBLINE-1);
138 pLine->szLine[ cchCELLDBLINE-1 ] = '\0';
139 if ((pLine->pPrev = pCellServDB->pLast) != NULL)
140 pLine->pPrev->pNext = pLine;
141 if ((pCellServDB->pLast = pLine)->pPrev == NULL)
142 pCellServDB->pFirst = pLine;
144 /* Process the next line in the file */
160 BOOL CSDB_WriteFile (PCELLSERVDB pCellServDB)
164 char szLine[ cchCELLDBLINE ];
167 if (pCellServDB->fChanged)
169 if ((pFile = fopen (pCellServDB->szFilename, "w")) == NULL)
175 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
178 sprintf (szLine, "%s\r\n", pLine->szLine);
180 sprintf (szLine, "%s\n", pLine->szLine);
182 fwrite (szLine, 1, strlen(szLine), pFile);
188 pCellServDB->fChanged = FALSE;
195 void CSDB_FreeFile (PCELLSERVDB pCellServDB)
199 for (pLine = pCellServDB->pFirst; pLine; pLine = pNext)
201 pNext = pLine->pNext;
204 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
208 BOOL CSDB_CrackLine (PCELLDBLINEINFO pInfo, const char *pszLine)
212 BOOL fSawHash = FALSE;
214 memset (pInfo, 0x00, sizeof(CELLDBLINEINFO));
216 if (!pszLine || !*pszLine)
219 while (iswhite(*pszLine))
224 else if (!isdigit (*pszLine))
226 else /* (isdigit (*pszLine)) */
229 for (pszOut = pInfo->szCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
230 *pszOut++ = *pszLine++;
233 while (iswhite(*pszLine) || (*pszLine == '#'))
235 fSawHash = fSawHash || (*pszLine == '#');
239 if (fIsCell && *pszLine && !fSawHash)
241 for (pszOut = pInfo->szLinkedCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
242 *pszOut++ = *pszLine++;
245 while (iswhite(*pszLine) || (*pszLine == '#'))
249 for (pszOut = pInfo->szComment; *pszLine; )
250 *pszOut++ = *pszLine++;
253 if (!pInfo->szCell[0])
258 if ((pInfo->ipServer = inet_addr (pInfo->szCell)) == 0xffffffff)
260 pInfo->szCell[0] = '\0';
267 BOOL CSDB_FormatLine (char *pszLine, const char *pszCell, const char *pszLinkedCell, const char *pszComment, BOOL fIsCell)
270 sprintf (pszLine, ">%s", pszCell);
272 strcpy (pszLine, pszCell);
274 if (fIsCell && pszLinkedCell && *pszLinkedCell)
275 sprintf (&pszLine[ strlen(pszLine) ], " %s", pszLinkedCell);
279 size_t cchSpacing = (fIsCell) ? 28 : 33;
280 strcat (pszLine, " ");
281 if ((size_t)strlen(pszLine) < cchSpacing)
283 strcat (pszLine, " ");
284 pszLine[cchSpacing] = '\0';
287 sprintf (&pszLine[ strlen(pszLine) ], ((fIsCell) ? "# %s" : "#%s"), pszComment);
294 PCELLDBLINE CSDB_FindCell (PCELLSERVDB pCellServDB, const char *pszCell)
297 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
300 if (!CSDB_CrackLine (&Info, pLine->szLine))
302 if (!strcmpi (Info.szCell, pszCell))
309 BOOL CSDB_OnRemove (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine, BOOL fRemoveCellLineToo)
315 /* Quick validation: make sure the caller specified a Cell line */
319 if (!CSDB_CrackLine (&Info, pCellLine->szLine))
324 /* Remove everything about this cell (except maybe the cell line) */
326 pLine = (fRemoveCellLineToo) ? pCellLine : pCellLine->pNext;
327 for ( ; pLine; pLine = pNext)
329 if ((pNext = CSDB_RemoveLine (pCellServDB, pLine)) != NULL)
331 if (!CSDB_CrackLine (&Info, pNext->szLine))
333 if (Info.szCell[0]) /* Hit the next cell? We're done! */
338 pCellServDB->fChanged = TRUE;
342 BOOL CSDB_RemoveCell (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine)
344 return CSDB_OnRemove (pCellServDB, pCellLine, TRUE);
347 BOOL CSDB_RemoveCellServers (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine)
349 return CSDB_OnRemove (pCellServDB, pCellLine, FALSE);
353 PCELLDBLINE CSDB_AddCell (PCELLSERVDB pCellServDB, const char *pszCell, const char *pszLinkedCell, const char *pszComment)
355 PCELLDBLINE pCellLine;
357 /* Find out if there's already an entry in CellServDB for this cell; */
358 /* add one if necessary. */
360 if ((pCellLine = CSDB_FindCell (pCellServDB, pszCell)) == NULL)
362 pCellLine = new(CELLDBLINE);
363 memset (pCellLine, 0x00, sizeof(CELLDBLINE));
364 if ((pCellLine->pPrev = pCellServDB->pLast) != NULL)
365 pCellLine->pPrev->pNext = pCellLine;
366 if ((pCellServDB->pLast = pCellLine)->pPrev == NULL)
367 pCellServDB->pFirst = pCellLine;
370 CSDB_FormatLine (pCellLine->szLine, pszCell, pszLinkedCell, pszComment, TRUE);
371 pCellServDB->fChanged = TRUE;
376 PCELLDBLINE CSDB_AddCellServer (PCELLSERVDB pCellServDB, PCELLDBLINE pAddAfter, const char *pszAddress, const char *pszComment)
378 char szLine[ cchCELLDBLINE ];
379 CSDB_FormatLine (szLine, pszAddress, NULL, pszComment, FALSE);
380 return CSDB_AddLine (pCellServDB, pAddAfter, szLine);
384 PCELLDBLINE CSDB_AddLine (PCELLSERVDB pCellServDB, PCELLDBLINE pAddAfter, const char *pszLine)
386 PCELLDBLINE pNew = new(CELLDBLINE);
387 memset (pNew, 0x00, sizeof(CELLDBLINE));
388 strcpy (pNew->szLine, pszLine);
390 if (pAddAfter == NULL)
392 if ((pNew->pNext = pCellServDB->pFirst) != NULL)
393 pNew->pNext->pPrev = pNew;
395 pCellServDB->pFirst = pNew;
396 if (pCellServDB->pLast == NULL)
397 pCellServDB->pLast = pNew;
399 else /* (pAddAfter != NULL) */
401 if ((pNew->pNext = pAddAfter->pNext) != NULL)
402 pNew->pNext->pPrev = pNew->pPrev;
403 pNew->pPrev = pAddAfter;
404 pAddAfter->pNext = pNew;
405 if (pCellServDB->pLast == pAddAfter)
406 pCellServDB->pLast = pNew;
409 pCellServDB->fChanged = TRUE;
414 PCELLDBLINE CSDB_RemoveLine (PCELLSERVDB pCellServDB, PCELLDBLINE pRemove)
421 pNext = pRemove->pNext;
424 pRemove->pPrev->pNext = pRemove->pNext;
426 pRemove->pNext->pPrev = pRemove->pPrev;
427 if (pCellServDB->pFirst == pRemove)
428 pCellServDB->pFirst = pRemove->pNext;
429 if (pCellServDB->pLast == pRemove)
430 pCellServDB->pLast = pRemove->pPrev;
434 pCellServDB->fChanged = TRUE;