LINUX: afs_create infinite fetchStatus loop
[pkg-k5-afs_openafs.git] / src / WINNT / client_config / cellservdb.c
blob74bbee2fddbe452404d341b0bcb8619e7a86f4c4
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
10 #include <afs/param.h>
11 #include <afs/stds.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <memory.h>
16 #include <malloc.h>
17 #include "cellservdb.h"
18 #include <afs/cm_config.h>
20 #include <windows.h>
21 #include <winsock2.h>
24 * PROTOTYPES _________________________________________________________________
28 #define new(_t) (_t*)malloc(sizeof(_t))
29 #define delete(_p) free((void*)(_p))
31 #ifndef iswhite
32 #define iswhite(_ch) (((_ch)==' ') || ((_ch)=='\t'))
33 #endif
34 #ifndef iseol
35 #define iseol(_ch) (((_ch)=='\r') || ((_ch)=='\n'))
36 #endif
37 #ifndef iswhiteeol
38 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
39 #endif
40 #ifndef min
41 #define min(_a,_b) ((_a) < (_b) ? (_a) : (_b))
42 #endif
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)
71 BOOL rc = FALSE;
72 FILE *pFile;
73 size_t cbLength;
74 size_t cbRead;
75 char *pszBuffer;
76 char *pszStart;
77 char *pszEnd;
78 PCELLDBLINE pLine;
80 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
82 /* Open AFSDCELL.INI and read it into memory. */
84 if (pszFilename)
85 strcpy (pCellServDB->szFilename, pszFilename);
86 else
87 CSDB_GetFileName (pCellServDB->szFilename);
89 if ((pFile = fopen (pCellServDB->szFilename, "r")) != NULL)
91 fseek (pFile, 0, 2);
92 cbLength = ftell (pFile);
93 fseek (pFile, 0, 0);
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))
107 ++pszStart;
108 if (!*pszStart)
109 break;
111 for (pszEnd = pszStart; *pszEnd && !iseol(*pszEnd); ++pszEnd)
113 *pszEnd++ = '\0';
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 */
128 pszStart = pszEnd;
131 rc = TRUE;
134 free (pszBuffer);
135 fclose (pFile);
138 return rc;
142 BOOL CSDB_WriteFile (PCELLSERVDB pCellServDB)
144 BOOL rc = TRUE;
145 FILE *pFile;
146 char szLine[ cchCELLDBLINE ];
147 PCELLDBLINE pLine;
149 if (pCellServDB->fChanged)
151 if ((pFile = fopen (pCellServDB->szFilename, "w")) == NULL)
153 rc = FALSE;
155 else
157 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
159 sprintf (szLine, "%s\r\n", pLine->szLine);
160 fwrite (szLine, 1, strlen(szLine), pFile);
163 fclose (pFile);
166 pCellServDB->fChanged = FALSE;
169 return rc;
173 void CSDB_FreeFile (PCELLSERVDB pCellServDB)
175 PCELLDBLINE pNext;
176 PCELLDBLINE pLine;
177 for (pLine = pCellServDB->pFirst; pLine; pLine = pNext)
179 pNext = pLine->pNext;
180 delete(pLine);
182 memset (pCellServDB, 0x00, sizeof(CELLSERVDB));
186 BOOL CSDB_CrackLine (PCELLDBLINEINFO pInfo, const char *pszLine)
188 char *pszOut;
189 BOOL fIsCell = TRUE;
190 BOOL fSawHash = FALSE;
192 memset (pInfo, 0x00, sizeof(CELLDBLINEINFO));
194 if (!pszLine || !*pszLine)
195 return FALSE;
197 while (iswhite(*pszLine))
198 ++pszLine;
200 if (*pszLine == '>')
201 ++pszLine;
202 else if (!isdigit (*pszLine))
203 return FALSE;
204 else /* (isdigit (*pszLine)) */
205 fIsCell = FALSE;
207 for (pszOut = pInfo->szCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
208 *pszOut++ = *pszLine++;
209 *pszOut = '\0';
211 while (iswhite(*pszLine) || (*pszLine == '#'))
213 fSawHash = fSawHash || (*pszLine == '#');
214 ++pszLine;
217 if (fIsCell && *pszLine && !fSawHash)
219 for (pszOut = pInfo->szLinkedCell; *pszLine && (!iswhite(*pszLine)) && (*pszLine != '#'); )
220 *pszOut++ = *pszLine++;
221 *pszOut = '\0';
223 while (iswhite(*pszLine) || (*pszLine == '#'))
224 ++pszLine;
227 for (pszOut = pInfo->szComment; *pszLine; )
228 *pszOut++ = *pszLine++;
229 *pszOut = '\0';
231 if (!pInfo->szCell[0])
232 return FALSE;
234 if (!fIsCell)
236 if ((pInfo->ipServer = inet_addr (pInfo->szCell)) == 0xffffffff)
237 return FALSE;
238 pInfo->szCell[0] = '\0';
241 return TRUE;
245 BOOL CSDB_FormatLine (char *pszLine, const char *pszCell, const char *pszLinkedCell, const char *pszComment, BOOL fIsCell)
247 if (fIsCell)
248 sprintf (pszLine, ">%s", pszCell);
249 else
250 strcpy (pszLine, pszCell);
252 if (fIsCell && pszLinkedCell && *pszLinkedCell)
253 sprintf (&pszLine[ strlen(pszLine) ], " %s", pszLinkedCell);
255 if (pszComment)
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);
268 return TRUE;
272 PCELLDBLINE CSDB_FindCell (PCELLSERVDB pCellServDB, const char *pszCell)
274 PCELLDBLINE pLine;
275 for (pLine = pCellServDB->pFirst; pLine; pLine = pLine->pNext)
277 CELLDBLINEINFO Info;
278 if (!CSDB_CrackLine (&Info, pLine->szLine))
279 continue;
280 if (!_stricmp (Info.szCell, pszCell))
281 return pLine;
283 return NULL;
287 BOOL CSDB_OnRemove (PCELLSERVDB pCellServDB, PCELLDBLINE pCellLine, BOOL fRemoveCellLineToo)
289 CELLDBLINEINFO Info;
290 PCELLDBLINE pNext;
291 PCELLDBLINE pLine;
293 /* Quick validation: make sure the caller specified a Cell line */
295 if (!pCellLine)
296 return FALSE;
297 if (!CSDB_CrackLine (&Info, pCellLine->szLine))
298 return FALSE;
299 if (!Info.szCell[0])
300 return FALSE;
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))
310 break;
311 if (Info.szCell[0]) /* Hit the next cell? We're done! */
312 break;
316 pCellServDB->fChanged = TRUE;
317 return 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;
350 return pCellLine;
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;
372 pNew->pPrev = NULL;
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;
388 return pNew;
392 PCELLDBLINE CSDB_RemoveLine (PCELLSERVDB pCellServDB, PCELLDBLINE pRemove)
394 PCELLDBLINE pNext;
396 if (!pRemove)
397 return NULL;
399 pNext = pRemove->pNext;
401 if (pRemove->pPrev)
402 pRemove->pPrev->pNext = pRemove->pNext;
403 if (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;
410 delete(pRemove);
412 pCellServDB->fChanged = TRUE;
413 return pNext;