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"
18 #include <afs/cm_config.h>
24 * PROTOTYPES _________________________________________________________________
28 #define new(_t) (_t*)malloc(sizeof(_t))
29 #define delete(_p) free((void*)(_p))
32 #define iswhite(_ch) (((_ch)==' ') || ((_ch)=='\t'))
35 #define iseol(_ch) (((_ch)=='\r') || ((_ch)=='\n'))
38 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
41 #define min(_a,_b) ((_a) < (_b) ? (_a) : (_b))
46 * STATICS ____________________________________________________________________
50 static void strzcpy (char *pszTarget
, const char *pszSource
, size_t cch
)
52 cch
= min(cch
, (size_t)(1+strlen(pszSource
)));
53 strncpy (pszTarget
, pszSource
, cch
-1);
54 pszTarget
[ cch
-1 ] = '\0';
59 * ROUTINES ___________________________________________________________________
63 void CSDB_GetFileName (char *pszFilename
)
65 cm_GetCellServDB(pszFilename
, MAX_CSDB_PATH
);
69 BOOL
CSDB_ReadFile (PCELLSERVDB pCellServDB
, const char *pszFilename
)
80 memset (pCellServDB
, 0x00, sizeof(CELLSERVDB
));
82 /* Open AFSDCELL.INI and read it into memory. */
85 strcpy (pCellServDB
->szFilename
, pszFilename
);
87 CSDB_GetFileName (pCellServDB
->szFilename
);
89 if ((pFile
= fopen (pCellServDB
->szFilename
, "r")) != NULL
)
92 cbLength
= ftell (pFile
);
95 pszBuffer
= (char*)malloc (sizeof(char) * (cbLength
+2));
97 if ((cbRead
= fread (pszBuffer
, 1, cbLength
, pFile
)) != 0)
99 pszBuffer
[ cbRead
] = '\0';
100 pszBuffer
[ cbRead
+1 ] = '\0';
102 /* Scan the file line-by-line... */
104 for (pszStart
= pszBuffer
; pszStart
&& *pszStart
; )
106 while (iswhiteeol(*pszStart
))
111 for (pszEnd
= pszStart
; *pszEnd
&& !iseol(*pszEnd
); ++pszEnd
)
115 /* Add this line to our chain */
117 pLine
= new(CELLDBLINE
);
118 memset (pLine
, 0x00, sizeof(CELLDBLINE
));
119 strzcpy (pLine
->szLine
, pszStart
, cchCELLDBLINE
-1);
120 pLine
->szLine
[ cchCELLDBLINE
-1 ] = '\0';
121 if ((pLine
->pPrev
= pCellServDB
->pLast
) != NULL
)
122 pLine
->pPrev
->pNext
= pLine
;
123 if ((pCellServDB
->pLast
= pLine
)->pPrev
== NULL
)
124 pCellServDB
->pFirst
= pLine
;
126 /* Process the next line in the file */
142 BOOL
CSDB_WriteFile (PCELLSERVDB pCellServDB
)
146 char szLine
[ cchCELLDBLINE
];
149 if (pCellServDB
->fChanged
)
151 if ((pFile
= fopen (pCellServDB
->szFilename
, "w")) == NULL
)
157 for (pLine
= pCellServDB
->pFirst
; pLine
; pLine
= pLine
->pNext
)
159 sprintf (szLine
, "%s\r\n", pLine
->szLine
);
160 fwrite (szLine
, 1, strlen(szLine
), pFile
);
166 pCellServDB
->fChanged
= FALSE
;
173 void CSDB_FreeFile (PCELLSERVDB pCellServDB
)
177 for (pLine
= pCellServDB
->pFirst
; pLine
; pLine
= pNext
)
179 pNext
= pLine
->pNext
;
182 memset (pCellServDB
, 0x00, sizeof(CELLSERVDB
));
186 BOOL
CSDB_CrackLine (PCELLDBLINEINFO pInfo
, const char *pszLine
)
190 BOOL fSawHash
= FALSE
;
192 memset (pInfo
, 0x00, sizeof(CELLDBLINEINFO
));
194 if (!pszLine
|| !*pszLine
)
197 while (iswhite(*pszLine
))
202 else if (!isdigit (*pszLine
))
204 else /* (isdigit (*pszLine)) */
207 for (pszOut
= pInfo
->szCell
; *pszLine
&& (!iswhite(*pszLine
)) && (*pszLine
!= '#'); )
208 *pszOut
++ = *pszLine
++;
211 while (iswhite(*pszLine
) || (*pszLine
== '#'))
213 fSawHash
= fSawHash
|| (*pszLine
== '#');
217 if (fIsCell
&& *pszLine
&& !fSawHash
)
219 for (pszOut
= pInfo
->szLinkedCell
; *pszLine
&& (!iswhite(*pszLine
)) && (*pszLine
!= '#'); )
220 *pszOut
++ = *pszLine
++;
223 while (iswhite(*pszLine
) || (*pszLine
== '#'))
227 for (pszOut
= pInfo
->szComment
; *pszLine
; )
228 *pszOut
++ = *pszLine
++;
231 if (!pInfo
->szCell
[0])
236 if ((pInfo
->ipServer
= inet_addr (pInfo
->szCell
)) == 0xffffffff)
238 pInfo
->szCell
[0] = '\0';
245 BOOL
CSDB_FormatLine (char *pszLine
, const char *pszCell
, const char *pszLinkedCell
, const char *pszComment
, BOOL fIsCell
)
248 sprintf (pszLine
, ">%s", pszCell
);
250 strcpy (pszLine
, pszCell
);
252 if (fIsCell
&& pszLinkedCell
&& *pszLinkedCell
)
253 sprintf (&pszLine
[ strlen(pszLine
) ], " %s", pszLinkedCell
);
257 size_t cchSpacing
= (fIsCell
) ? 28 : 33;
258 strcat (pszLine
, " ");
259 if ((size_t)strlen(pszLine
) < cchSpacing
)
261 strcat (pszLine
, " ");
262 pszLine
[cchSpacing
] = '\0';
265 sprintf (&pszLine
[ strlen(pszLine
) ], ((fIsCell
) ? "# %s" : "#%s"), pszComment
);
272 PCELLDBLINE
CSDB_FindCell (PCELLSERVDB pCellServDB
, const char *pszCell
)
275 for (pLine
= pCellServDB
->pFirst
; pLine
; pLine
= pLine
->pNext
)
278 if (!CSDB_CrackLine (&Info
, pLine
->szLine
))
280 if (!_stricmp (Info
.szCell
, pszCell
))
287 BOOL
CSDB_OnRemove (PCELLSERVDB pCellServDB
, PCELLDBLINE pCellLine
, BOOL fRemoveCellLineToo
)
293 /* Quick validation: make sure the caller specified a Cell line */
297 if (!CSDB_CrackLine (&Info
, pCellLine
->szLine
))
302 /* Remove everything about this cell (except maybe the cell line) */
304 pLine
= (fRemoveCellLineToo
) ? pCellLine
: pCellLine
->pNext
;
305 for ( ; pLine
; pLine
= pNext
)
307 if ((pNext
= CSDB_RemoveLine (pCellServDB
, pLine
)) != NULL
)
309 if (!CSDB_CrackLine (&Info
, pNext
->szLine
))
311 if (Info
.szCell
[0]) /* Hit the next cell? We're done! */
316 pCellServDB
->fChanged
= TRUE
;
320 BOOL
CSDB_RemoveCell (PCELLSERVDB pCellServDB
, PCELLDBLINE pCellLine
)
322 return CSDB_OnRemove (pCellServDB
, pCellLine
, TRUE
);
325 BOOL
CSDB_RemoveCellServers (PCELLSERVDB pCellServDB
, PCELLDBLINE pCellLine
)
327 return CSDB_OnRemove (pCellServDB
, pCellLine
, FALSE
);
331 PCELLDBLINE
CSDB_AddCell (PCELLSERVDB pCellServDB
, const char *pszCell
, const char *pszLinkedCell
, const char *pszComment
)
333 PCELLDBLINE pCellLine
;
335 /* Find out if there's already an entry in CellServDB for this cell; */
336 /* add one if necessary. */
338 if ((pCellLine
= CSDB_FindCell (pCellServDB
, pszCell
)) == NULL
)
340 pCellLine
= new(CELLDBLINE
);
341 memset (pCellLine
, 0x00, sizeof(CELLDBLINE
));
342 if ((pCellLine
->pPrev
= pCellServDB
->pLast
) != NULL
)
343 pCellLine
->pPrev
->pNext
= pCellLine
;
344 if ((pCellServDB
->pLast
= pCellLine
)->pPrev
== NULL
)
345 pCellServDB
->pFirst
= pCellLine
;
348 CSDB_FormatLine (pCellLine
->szLine
, pszCell
, pszLinkedCell
, pszComment
, TRUE
);
349 pCellServDB
->fChanged
= TRUE
;
354 PCELLDBLINE
CSDB_AddCellServer (PCELLSERVDB pCellServDB
, PCELLDBLINE pAddAfter
, const char *pszAddress
, const char *pszComment
)
356 char szLine
[ cchCELLDBLINE
];
357 CSDB_FormatLine (szLine
, pszAddress
, NULL
, pszComment
, FALSE
);
358 return CSDB_AddLine (pCellServDB
, pAddAfter
, szLine
);
362 PCELLDBLINE
CSDB_AddLine (PCELLSERVDB pCellServDB
, PCELLDBLINE pAddAfter
, const char *pszLine
)
364 PCELLDBLINE pNew
= new(CELLDBLINE
);
365 memset (pNew
, 0x00, sizeof(CELLDBLINE
));
366 strcpy (pNew
->szLine
, pszLine
);
368 if (pAddAfter
== NULL
)
370 if ((pNew
->pNext
= pCellServDB
->pFirst
) != NULL
)
371 pNew
->pNext
->pPrev
= pNew
;
373 pCellServDB
->pFirst
= pNew
;
374 if (pCellServDB
->pLast
== NULL
)
375 pCellServDB
->pLast
= pNew
;
377 else /* (pAddAfter != NULL) */
379 if ((pNew
->pNext
= pAddAfter
->pNext
) != NULL
)
380 pNew
->pNext
->pPrev
= pNew
->pPrev
;
381 pNew
->pPrev
= pAddAfter
;
382 pAddAfter
->pNext
= pNew
;
383 if (pCellServDB
->pLast
== pAddAfter
)
384 pCellServDB
->pLast
= pNew
;
387 pCellServDB
->fChanged
= TRUE
;
392 PCELLDBLINE
CSDB_RemoveLine (PCELLSERVDB pCellServDB
, PCELLDBLINE pRemove
)
399 pNext
= pRemove
->pNext
;
402 pRemove
->pPrev
->pNext
= pRemove
->pNext
;
404 pRemove
->pNext
->pPrev
= pRemove
->pPrev
;
405 if (pCellServDB
->pFirst
== pRemove
)
406 pCellServDB
->pFirst
= pRemove
->pNext
;
407 if (pCellServDB
->pLast
== pRemove
)
408 pCellServDB
->pLast
= pRemove
->pPrev
;
412 pCellServDB
->fChanged
= TRUE
;