1    | /***************************************
2    |   $Revision:
3    | 
4    |   CA module: definitions of functions that read a file of databases and
5    |              sources.
6    | 
7    |   Status: NOT REVIEWED, NOT TESTED
8    | 
9    |   Author(s):       Ambrose Magee
10   | 
11   | ******************//******************
12   | Modification History:
13   | 
14   | ******************/
15   | 
16   | /************************************
17   | Copyright (c) 2000                              RIPE NCC
18   | 
19   | All Rights Reserved
20   | 
21   | Permission to use, copy, modify, and distribute this software and its
22   | documentation for any purpose and without fee is hereby granted,
23   | provided that the above copyright notice appear in all copies and that
24   | both that copyright notice and this permission notice appear in
25   | supporting documentation, and that the name of the author not be
26   | used in advertising or publicity pertaining to distribution of the
27   | software without specific, written prior permission.
28   | 
29   | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
30   | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
31   | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
32   | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
33   | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
34   | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35   | ***************************************/
36   | 
37   | #include <stdio.h>
38   | #include <stdlib.h>
39   | #include <glib.h>
40   | #include <string.h>
41   | #include <stubs.h>
42   | #include <unistd.h>
43   | #include "ca_configFns.h"
44   | 
45   | /* #define DEBUG *//* Swich OFF Debugging. */
46   | 
47   | /*******************************************************
48   |   * This file contains the definitions of functions     *
49   |  * that read a file of databases and sources.        *
50   |  *******************************************************/
51   | 
52   | 
53   | void
54   | ca_readSources(const char *sourcesDefFile, values_t confVars[])
55   | /*******************************************************************
56   |  *                                             *
57   |  * ca_readSources -- parses the Sources file and writes the values  *
58   |  *              into memory.                        *
59   |  *                                            *
60   |  * Parameters                                    *
61   |   *    sourcesFile  -- the file of databases, mirrors, sources    *
62   |   *    confVars[]  --  the array of values structures          *
63   |  *                                            *
64   |  * Returns                                      *
65   |   *    Nothing -- perhaps make this return 0 on successful exit ?  *
66   |  *                                            *
67   |  *******************************************************************/
68   | {
69   | 	FILE *sourcesFilePtr;	/* Pointer to Source file. */
70   | 	char line[80];	/* The current line of input. */
71   | 	const char *comment = "#";	/* Declared as a string. */
72   | #ifdef DEBUG
73   | 	char name[STRLENGTH_M];	/* The name of the config variable */
74   | 	char value[STRLENGTH_XXL];	/* The value of the variable */
75   | 	/* 640 characters */
76   | 
77   | 	int location;	/* Storage Location of the variable's value. */
78   | 	int type;	/* Data type of the variable, represented by an
79   | 			 * integer. */
80   | 
81   | 	const char *blankLine = "\n";	/* Declared as a string, not a
82   | 					 * character. */
83   | 
84   | 	char dbcomp[16];	/* Component of a databse. */
85   | 	char nrtmcomp[16];	/* Component of an nrtm. */
86   | 	int mode;	/* The mode of operation of the src */
87   | 	char srcOptions[16];	/* The options of a source. */
88   | 	char nrtMirror[STRLENGTH_M];	/* The elements of a NRTM */
89   | 	int updatePort;	/* The update port of the source */
90   | 	/* N. B.  This is not the same as the */
91   | 	/* updPort in the UPDSOURCE variables. */
92   | #endif	/* DEBUG */
93   | 	char source[16];	/* The name of a source. */
94   | 	char database[16];	/* The name of a database. */
95   | 	char mirror[16];	/* The name of a mirror. */
96   | 	char varName[16];	/* Temporary variable */
97   | 
98   | 
99   | 
100  | 	ca_database_t *newDbPtr;	/* A pointer to a new instance of */
101  | 	/* ca_database_t.                 */
102  | 
103  | 	ca_mirror_t *newMirrPtr;	/* A pointer to a new instance of */
104  | 	/* ca_mirror_t.                   */
105  | 
106  | 	ca_dbSource_t *newSrcPtr;	/* A pointer to a new instance of */
107  | 	/* ca_database_list_t.            */
108  | 
109  | 	int in_DATABASE_def, in_NRTM_def, in_SOURCE_def;
110  | 	/* When we are reading the definition */
111  | 	/* of a database, nrtm, source, etc.  */
112  | 	/* this is set to 1.  Otherwise, it */
113  | 	/* is 0. */
114  | 
115  | 	/*
116  | 	 * Function prototypes of ca_parseDbLine(), ca_parseNrtmLine() and
117  | 	 * ca_parseSrcLine().  We put them here so that it can only be called
118  | 	 * from within the ca_readSources() function.
119  | 	 */
120  | 	void ca_parseDbLine(char *, ca_database_t *);
121  | 	void ca_parseNrtmLine(char *, ca_mirror_t *);
122  | 	void ca_parseSrcLine(char *, ca_dbSource_t *);
123  | 
124  | 
125  | #ifdef DEBUG
126  | 	printf("\nInside ca_readSources() function.\n");
127  | 	printf("Sources file is: %s\n", sourcesDefFile);
128  | #endif	/* DEBUG */
129  | 
130  | 	/*
131  | 	 * Open the sources file for reading .....
132  | 	 */
133  | 	if ((sourcesFilePtr = fopen(sourcesDefFile, "r")) == NULL) {
134  | 		printf("Error: the file %s could not be opened.\n", sourcesDefFile);
135  | 		die;
136  | 	}
137  | 
138  | 	/* Before reading the file, we initialise all flags to 0. */
139  | 	in_DATABASE_def = 0;
140  | 	in_NRTM_def = 0;
141  | 	in_SOURCE_def = 0;
142  | 
143  | 	/*
144  | 	 * Read the first line of the file. Remove leading and trailing
145  | 	 * blank-space characters. if the first character of the line is a
146  | 	 * comment or if it is a blank-line, continue.
147  | 	 * 
148  | 	 */
149  | 
150  | 	fgets(line, sizeof(line), sourcesFilePtr);
151  | 	g_strstrip(line);
152  | 
153  | 	/*
154  | 	 * While there are lines to be read in the sources file, process the
155  | 	 * current line and read the next line.
156  | 	 */
157  | 
158  | 	while (!feof(sourcesFilePtr)) {
159  | #ifdef DEBUG
160  | 		printf("line:%s:End of line\n", line);
161  | 		printf("Length of line: %d\n", strlen(line));
162  | #endif	/* DEBUG */
163  | 
164  | 		/*
165  | 		 * Ignore comments and empty lines.
166  | 		 */
167  | 		if ((strncmp(line, comment, 1) == 0) || (strlen(line) == 0)) {
168  | #ifdef DEBUG
169  | 			printf("We are reading a comment or an empty line ..... \n");
170  | #endif	/* DEBUG */
171  | 			fgets(line, sizeof(line), sourcesFilePtr);
172  | 			g_strstrip(line);
173  | 			continue;
174  | 		}
175  | 
176  | 		/* Testing */
177  | #ifdef DEBUG
178  | 		printf("LINE >>>%sEND_OF_LINE\n", line);
179  | #endif	/* DEBUG */
180  | 
181  | 		/*
182  | 		 * if we are in a DATABASE definition then have we read all
183  | 		 * of the definition ? if yes, then commit the definition,
184  | 		 * reset the 'Database' flag and read the next line.
185  | 		 * Otherwise parse the line and store the details in
186  | 		 * temporary variables.
187  | 		 */
188  | 
189  | 		/* If we are in a DATABASE definition */
190  | 		if (in_DATABASE_def) {
191  | 			/*
192  | 			 * If we have reached the end of a DATABASE
193  | 			 * definition, commit the definition.
194  | 			 */
195  | 
196  | 			if (strcmp(line, "/DATABASE") == 0) {
197  | 				/* Commit the definition */
198  | 				/* Some code. */
199  | #ifdef DEBUG
200  | 				puts("We have reached the end of a DATABASE definition");
201  | 				puts("Testing the population of the db structure:");
202  | 				printf("\n%s::%d::%s::%s::%s\n", newDbPtr->host, newDbPtr->port, newDbPtr->user, newDbPtr->password, newDbPtr->dbName);
203  | #endif	/* DEBUG */
204  | 
205  | 				/*
206  | 				 * Commit the definition to the linked list
207  | 				 * of Databases.
208  | 				 */
209  | 
210  | 				dbList = g_slist_append(dbList, newDbPtr);
211  | 
212  | 				/*
213  | 				 * We have reached the end of the DATABASE
214  | 				 * definition
215  | 				 */
216  | 				/* Thus, reset the flag and free some memory. */
217  | 				in_DATABASE_def = 0;
218  | 
219  | 
220  | 				/*
221  | 				 * Read the next line and do the conditional
222  | 				 * test.
223  | 				 */
224  | 				fgets(line, sizeof(line), sourcesFilePtr);
225  | 				g_strstrip(line);
226  | 				continue;
227  | 			}
228  | 
229  | 			/*
230  | 			 * Otherwise, parse the line and fill in the
231  | 			 * structure of the Database.
232  | 			 */
233  | 			ca_parseDbLine(line, newDbPtr);
234  | 
235  | 		}
236  | 
237  | 		/*
238  | 		 * If we have found the _beginning_ of a Database definition,
239  | 		 * then set the in_DATABASE_def flag and allocate space, etc.
240  | 		 * for the database.
241  | 		 */
242  | 
243  | 		if ((!in_DATABASE_def) && (strncmp(line, DATABASE_KEY, strlen(DATABASE_KEY)) == 0)) {
244  | 			in_DATABASE_def = 1;
245  | 
246  | 			/* Allocate space for the database */
247  | 			/* Current_db = fscanf etc.) */
248  | 			/* Fill in the defaults. */
249  | #ifdef DEBUG
250  | 			puts("Beginning of a database defintion ..... ");
251  | #endif	/* DEBUG */
252  | 
253  | 			sscanf(line, "%s %s", varName, database);
254  | 			g_strstrip(database);
255  | 
256  | #ifdef DEBUG
257  | 			printf("Database name is: %s\n", database);
258  | #endif	/* DEBUG */
259  | 
260  | 			/*
261  | 			 * Create a structure for the database.
262  | 			 */
263  | 			newDbPtr = calloc(1, sizeof(ca_database_t));
264  | 			if (newDbPtr == NULL) {
265  | 				fprintf(stderr, "Cannot allocate memory to new db structure\n");
266  | 				die;
267  | 			}
268  | 
269  | 			/* Assign the name of the database */
270  | 			strcpy(newDbPtr->dbName, database);
271  | 
272  | 		}
273  | 
274  | 
275  | 		/********************
276  | 	               * NRTM definition  *
277  | 	               ********************/
278  | 
279  | 		/*
280  | 		 * if we are in a NRTM definition then have we read all of
281  | 		 * the definition ? if yes, then commit the definition and
282  | 		 * read the next line. otherwise parse the line and store the
283  | 		 * details in temporary variables.
284  | 		 */
285  | 
286  | 		/* If we are in a NRTM definition */
287  | 		if (in_NRTM_def) {
288  | 			/*
289  | 			 * If we have reached the end of a NRTM definition,
290  | 			 * commit the definition.
291  | 			 */
292  | 			if (strcmp(line, "/NRTM") == 0) {
293  | 				/* Commit the definition */
294  | 				/* Some code. */
295  | #ifdef DEBUG
296  | 				puts("We have reached the end of a NRTM definition");
297  | 				puts("Testing the population of the mirror structure:");
298  | 				printf("\n%s::%d::%d::%d\n", newMirrPtr->host, newMirrPtr->port, newMirrPtr->delay, newMirrPtr->protocolVer);
299  | #endif	/* DEBUG */
300  | 
301  | 				/*
302  | 				 * Commit the definition to the linked list
303  | 				 * of nrt-mirrors.
304  | 				 */
305  | 
306  | 				nrtmList = g_slist_append(nrtmList, newMirrPtr);
307  | 
308  | 				/*
309  | 				 * We have reached the end of the NRTM
310  | 				 * definition
311  | 				 */
312  | 				/* Thus, reset the NRTM flag. */
313  | 				in_NRTM_def = 0;
314  | 
315  | 				/*
316  | 				 * Read the next line and do the conditional
317  | 				 * test.
318  | 				 */
319  | 				fgets(line, sizeof(line), sourcesFilePtr);
320  | 				g_strstrip(line);
321  | 				continue;
322  | 			}
323  | 
324  | 			/*
325  | 			 * Otherwise, parse the line and fill in the
326  | 			 * structure of the NRMT.
327  | 			 */
328  | 
329  | 			ca_parseNrtmLine(line, newMirrPtr);
330  | 		}
331  | 
332  | 		/*
333  | 		 * If we have found the beginning of a Near-Real-Time-Mirror
334  | 		 * definition, then set the in_NRTM_def flag and allocate
335  | 		 * space, etc. for the Near-Real-Time-Mirror.
336  | 		 */
337  | 
338  | 		if ((!in_NRTM_def) && (strncmp(line, NRTM_KEY, strlen(NRTM_KEY)) == 0)) {
339  | 			in_NRTM_def = 1;
340  | 			/* Allocate space for the Near-Real-Time-Mirror. */
341  | 			/* Current_db = fscanf etc.) */
342  | 			/* Fill in the defaults. */
343  | #ifdef DEBUG
344  | 			puts("Beginning of a Near-Real-Time-Mirror defintion ..... ");
345  | #endif	/* DEBUG */
346  | 
347  | 			sscanf(line, "%s %s", varName, mirror);
348  | 
349  | 			/*
350  | 			 * Create a structure for the mirror.
351  | 			 */
352  | 			newMirrPtr = calloc(1, sizeof(ca_mirror_t));
353  | 			if (newMirrPtr == NULL) {
354  | 				fprintf(stderr, "Cannot allocate memory to new nrtm structure\n");
355  | 				die;
356  | 			}
357  | 			/* Assign the name of the mirror ? */
358  | 			strcpy(newMirrPtr->mrName, mirror);
359  | 
360  | 		}
361  | 
362  | 		/*********************
363  | 	               * SOURCE Definition *
364  | 	               *********************/
365  | 
366  | 		/*
367  | 		 * if we are in a SOURCE definition then have we read all of
368  | 		 * the definition ? if yes, then commit the definition, reset
369  | 		 * the 'Database' flag and read the next line. Otherwise
370  | 		 * parse the line and store the details in temporary
371  | 		 * variables.
372  | 		 */
373  | 
374  | 		/* If we are in a SOURCE definition */
375  | 		if (in_SOURCE_def) {
376  | 			/*
377  | 			 * If we have reached the end of a SOURCE definition,
378  | 			 * commit the definition.
379  | 			 */
380  | 
381  | 			if (strcmp(line, "/SOURCE") == 0) {
382  | 				/* Commit the definition */
383  | 				/* Some code. */
384  | #ifdef DEBUG
385  | 				puts("We have reached the end of a SOURCE definition");
386  | 				puts("Testing the population of the new Source structure:");
387  | 				printf("Source name: %s\n", newSrcPtr->name);
388  | 				printf("\nDB == %s::%d::%s::%s::%s\n", (newSrcPtr->db).host, (newSrcPtr->db).port, (newSrcPtr->db).user, (newSrcPtr->db).password, (newSrcPtr->db).dbName);
389  | 				printf("Mode: %d\n", newSrcPtr->opMode);
390  | 				printf("NRTM == %s::%d::%d:%d\n", (newSrcPtr->nrtm).host, (newSrcPtr->nrtm).port, (newSrcPtr->nrtm).delay, (newSrcPtr->nrtm).protocolVer);
391  | 				printf("UpdPort: %d\n", newSrcPtr->updPort);
392  | 				printf("New Source Options == %s::%s\n", newSrcPtr->canupd, newSrcPtr->deflook);
393  | #endif	/* DEBUG */
394  | 
395  | 				/*
396  | 				 * Commit the definition to the linked list
397  | 				 * of Databases.
398  | 				 */
399  | 
400  | 				sourceList = g_slist_append(sourceList, newSrcPtr);
401  | 
402  | 				/*
403  | 				 * We have reached the end of the DATABASE
404  | 				 * definition
405  | 				 */
406  | 				/* Thus, reset the flag and free some memory. */
407  | 				in_SOURCE_def = 0;
408  | 
409  | 
410  | 				/*
411  | 				 * Read the next line and do the conditional
412  | 				 * test.
413  | 				 */
414  | 				fgets(line, sizeof(line), sourcesFilePtr);
415  | 				g_strstrip(line);
416  | 				continue;
417  | 			}
418  | 
419  | 			/*
420  | 			 * Otherwise, parse the line and fill in the
421  | 			 * structure of the Database.
422  | 			 */
423  | 			ca_parseSrcLine(line, newSrcPtr);
424  | 
425  | 		}
426  | 
427  | 		/*
428  | 		 * If we have found the _beginning_ of a SOURCE definition,
429  | 		 * then set the in_SOURCE_def flag and allocate space, etc.
430  | 		 * for the database.
431  | 		 */
432  | 
433  | 		if ((!in_SOURCE_def) && (strncmp(line, SOURCE_KEY, strlen(SOURCE_KEY)) == 0)) {
434  | 			in_SOURCE_def = 1;
435  | 
436  | 			/* Allocate space for the Source */
437  | 			/* Current_source = fscanf etc.) */
438  | 			/* Fill in the defaults. */
439  | #ifdef DEBUG
440  | 			puts("Beginning of a Source defintion ..... ");
441  | #endif	/* DEBUG */
442  | 
443  | 			sscanf(line, "%s %s", varName, source);
444  | 			g_strstrip(source);
445  | 
446  | #ifdef DEBUG
447  | 			printf("Source name is: %s\n", source);
448  | #endif	/* DEBUG */
449  | 
450  | 			/*
451  | 			 * Create a structure for the source.
452  | 			 * 
453  | 			 */
454  | 			newSrcPtr = calloc(1, sizeof(ca_dbSource_t));
455  | 			if (newSrcPtr == NULL) {
456  | 				fprintf(stderr, "Cannot allocate memory to new Source structure\n");
457  | 				die;
458  | 			}
459  | 
460  | 			/* Assign the name of the Source */
461  | 			strcpy(newSrcPtr->name, source);
462  | 
463  | 		}
464  | 
465  | 		/* Read the next line. */
466  | 		fgets(line, sizeof(line), sourcesFilePtr);
467  | 		g_strstrip(line);
468  | 
469  | 		/* End of while loop; i.e. end of processing a line. */
470  | 	}
471  | 
472  | 	/* Close the sources definition file. */
473  | 	fclose(sourcesFilePtr);
474  | 
475  | 	/* End of ca_readSources() function */
476  | 
477  | }
478  | 
479  | void
480  | ca_getAllDatabases(GSList * databases)
481  | {
482  | 	GSList *currentPtr;	/* Pointer to the structure at which we look. */
483  | 
484  | 	/*
485  | 	 * Look at the first member of the linked-list of sources.
486  | 	 */
487  | 	currentPtr = databases;
488  | 
489  | 	/*
490  | 	 * Look at each data component of the source list, untill we reach
491  | 	 * the end of the list.
492  | 	 */
493  | 	while (currentPtr != NULL) {
494  | 		ca_database_t *dbPtr = currentPtr->data;
495  | 		printf("\n%s,%d,%s,%s,%s\n", dbPtr->host, dbPtr->port, dbPtr->user, dbPtr->password, dbPtr->dbName);
496  | 		currentPtr = currentPtr->next;
497  | 	}
498  | }
499  | 
500  | 
501  | void
502  | ca_getAllMirrors(GSList * mirrors)
503  | {
504  | 	GSList *currentPtr;	/* Pointer to the structure at which we look. */
505  | 
506  | 	/*
507  | 	 * Look at the first member of the linked-list of sources.
508  | 	 */
509  | 	currentPtr = mirrors;
510  | 
511  | 	/*
512  | 	 * Look at each data component of the source list, untill we reach
513  | 	 * the end of the list.
514  | 	 */
515  | 	while (currentPtr != NULL) {
516  | 		ca_mirror_t *nrtmPtr = currentPtr->data;
517  | 		printf("\n%s,%d,%d,%d, %s\n", nrtmPtr->host, nrtmPtr->port, nrtmPtr->delay, nrtmPtr->protocolVer, nrtmPtr->mrName);
518  | 		currentPtr = currentPtr->next;
519  | 	}
520  | }
521  | 
522  | void
523  | ca_parseDbLine(char *lineStr, ca_database_t * dbStructPtr)
524  | /*******************************************************************
525  |  *                                             *
526  |  * ca_parseLine  -- parses the a line in the Sources file and     *
527  |  *             writes the values into temporary variables.    *
528  |  *                                            *
529  |  * Parameters                                    *
530  |   *    lineStr     -- the current line of the Sources file       *
531  |  *               -- a NULL terminated string            *
532  |   *    dbStructPtr  -- the db we are filling                 *
533  |   *              -- a pointer to a ca_database_t structure.  *
534  |  *                                            *
535  |  * Returns                                      *
536  |   *    Nothing -- perhaps make this return 0 on successful exit ?  *
537  |  *                                            *
538  |  *******************************************************************/
539  | {
540  | 	char dbComp[64];	/* Component of a database. */
541  | 	char varName[16];	/* The name of the variable. */
542  | 
543  | 	gchar **tokens;	/* Pointer to an array of strings. */
544  | 
545  | #ifdef DEBUG
546  | 	int i;	/* A counting variable. */
547  | #endif	/* DEBUG */
548  | 
549  | 	/*
550  | 	 * Split the line on the ':' character. Then, for both the name of
551  | 	 * the variable and its value, remove leading and trailing
552  | 	 * blank-space characters.
553  | 	 */
554  | 	tokens = g_strsplit(lineStr, ":", 0);
555  | 
556  | #ifdef DEBUG
557  | 	for (i = 0; tokens[i] != NULL; i++)
558  | 		printf("tokens[%d] = %s\n", i, tokens[i]);
559  | #endif	/* DEBUG */
560  | 
561  | 	strcpy(varName, tokens[0]);
562  | 	strcpy(dbComp, tokens[1]);
563  | 
564  | 	/* Free the memory used by the tokens array. */
565  | 	g_strfreev(tokens);
566  | 
567  | 	/* Remove leading and trailing blank-space characters. */
568  | 	g_strstrip(varName);
569  | 	g_strstrip(dbComp);
570  | 
571  | #ifdef DEBUG
572  | 	printf("VarName: %s; dbComp: %s\n", varName, dbComp);
573  | #endif	/* DEBUG */
574  | 
575  | 	if (strcmp(varName, "host") == 0) {
576  | 		strcpy(dbStructPtr->host, dbComp);
577  | 	}
578  | 	else {
579  | 		if (strcmp(varName, "port") == 0) {
580  | 			dbStructPtr->port = atoi(dbComp);
581  | 		}
582  | 		else {
583  | 			if (strcmp(varName, "user") == 0) {
584  | 				strcpy(dbStructPtr->user, dbComp);
585  | 			}
586  | 			else {
587  | 				if (strcmp(varName, "password") == 0) {
588  | 					strcpy(dbStructPtr->password, dbComp);
589  | 				}
590  | 				else {
591  | 					fprintf(stderr, "Unknown database component \"%s\".\n", dbComp);
592  | 					die;
593  | 				}
594  | 			}
595  | 		}
596  | 	}
597  | }
598  | 
599  | 
600  | 
601  | void
602  | ca_parseNrtmLine(char *lineStr, ca_mirror_t * mrStructPtr)
603  | /*
604  |  * */
605  | {
606  | 	char nrtmComp[64];	/* Component of a NRTM. */
607  | 	char varName[16];	/* The name of the variable. */
608  | 
609  | 	gchar **tokens;	/* Pointer to an array of strings. */
610  | 
611  | #ifdef DEBUG
612  | 	int i;	/* A counting variable. */
613  | #endif	/* DEBUG */
614  | 
615  | 	/*
616  | 	 * Split the line on the ':' character. Then, for both the name of
617  | 	 * the variable and its value, remove leading and trailing
618  | 	 * blank-space characters.
619  | 	 */
620  | 	tokens = g_strsplit(lineStr, ":", 0);
621  | 
622  | #ifdef DEBUG
623  | 	for (i = 0; tokens[i] != NULL; i++)
624  | 		printf("tokens[%d] = %s\n", i, tokens[i]);
625  | #endif	/* DEBUG */
626  | 
627  | 	strcpy(varName, tokens[0]);
628  | 	strcpy(nrtmComp, tokens[1]);
629  | 
630  | 	/* Free the memory used by the tokens array. */
631  | 	g_strfreev(tokens);
632  | 
633  | 	/* Remove leading and trailing blank-space characters. */
634  | 	g_strstrip(varName);
635  | 	g_strstrip(nrtmComp);
636  | 
637  | #ifdef DEBUG
638  | 	printf("VarName: %s; nrtmComp: %s\n", varName, nrtmComp);
639  | #endif	/* DEBUG */
640  | 
641  | 
642  | 	if (strcmp(varName, "host") == 0) {
643  | 		strcpy(mrStructPtr->host, nrtmComp);
644  | 	}
645  | 	else {
646  | 		if (strcmp(varName, "port") == 0) {
647  | 			mrStructPtr->port = atoi(nrtmComp);
648  | 		}
649  | 		else {
650  | 			if (strcmp(varName, "delay") == 0) {
651  | 				mrStructPtr->delay = atoi(nrtmComp);
652  | 			}
653  | 			else {
654  | 				if (strcmp(varName, "protocolVersion") == 0) {
655  | 					mrStructPtr->protocolVer = atoi(nrtmComp);
656  | 				}
657  | 				else {
658  | 					fprintf(stderr, "Unknown mirror component \"%s\".\n", nrtmComp);
659  | 					die;
660  | 				}
661  | 			}
662  | 		}
663  | 	}
664  | }
665  | 
666  | 
667  | 
668  | 
669  | void
670  | ca_parseSrcLine(char *lineStr, ca_dbSource_t * srcStructPtr)
671  | /*
672  |  * ca_parseSrcLine() function.
673  |  */
674  | {
675  | 	char srcComp[64];	/* Component of a database. */
676  | 	char varName[16];	/* The name of the variable. */
677  | 
678  | 	gchar **tokens;	/* Pointer to an array of strings. */
679  | 
680  | #ifdef DEBUG
681  | 	int i;	/* A counting variable. */
682  | #endif	/* DEBUG */
683  | 
684  | 	/*
685  | 	 * Split the line on the ':' character. Then, for both the name of
686  | 	 * the variable and its value, remove leading and trailing
687  | 	 * blank-space characters.
688  | 	 */
689  | 	tokens = g_strsplit(lineStr, ":", 0);
690  | 
691  | #ifdef DEBUG
692  | 	for (i = 0; tokens[i] != NULL; i++)
693  | 		printf("tokens[%d] = %s\n", i, tokens[i]);
694  | #endif	/* DEBUG */
695  | 
696  | 	strcpy(varName, tokens[0]);
697  | 	strcpy(srcComp, tokens[1]);
698  | 
699  | 	/* Free the memory used by the tokens array. */
700  | 	g_strfreev(tokens);
701  | 
702  | 	/* Remove leading and trailing blank-space characters. */
703  | 	g_strstrip(varName);
704  | 	g_strstrip(srcComp);
705  | 
706  | #ifdef DEBUG
707  | 	printf("VarName: %s; srcComp: %s\n", varName, srcComp);
708  | #endif	/* DEBUG */
709  | 
710  | 	/*
711  | 	 * Parse each line of the SOURCE definition. If we find a database or
712  | 	 * a mirror, search for it in the appropriate linked list and make
713  | 	 * this source point to it.
714  | 	 */
715  | 	if (strcmp(varName, "database") == 0) {
716  | 		/* Search for the appropriate database. */
717  | 		/* Make this source point to it. */
718  | 		/* Use ca_getDbHandleByName(). */
719  | 		srcStructPtr->db = *ca_getDbHandleByName(srcComp);
720  | 	}
721  | 	else {
722  | 		if (strcmp(varName, "opMode") == 0) {
723  | 			srcStructPtr->opMode = atoi(srcComp);
724  | 		}
725  | 		else {
726  | 			if (strcmp(varName, "updPort") == 0) {
727  | 				srcStructPtr->updPort = atoi(srcComp);
728  | 			}
729  | 			else {
730  | 				if (strcmp(varName, "canupd") == 0) {
731  | 					strcpy(srcStructPtr->canupd, srcComp);
732  | 				}
733  | 				else {
734  | 					if (strcmp(varName, "deflook") == 0) {
735  | 						strcpy(srcStructPtr->deflook, srcComp);
736  | 					}
737  | 					else {
738  | 						if (strcmp(varName, "nrtm") == 0) {
739  | 							/*
740  | 							 * Get Mirror Handle
741  | 							 * by Name
742  | 							 */
743  | 							/*
744  | 							 * Assign this mirror
745  | 							 * to
746  | 							 */
747  | 							/*
748  | 							 * 
749  | 							 * srcStructPtr->nrtm.
750  | 							 * 
751  | 							 */
752  | 							srcStructPtr->nrtm = *ca_getNrtmHandleByName(srcComp);
753  | 						}
754  | 						else {
755  | 							fprintf(stderr, "Unknown SOURCE component \"%s\".\n", srcComp);
756  | 							die;
757  | 						}
758  | 					}
759  | 				}
760  | 			}
761  | 		}
762  | 	}
763  | }
764  | 
765  | 
766  | ca_database_t *
767  | ca_getDbHandleByName(char *databaseNameStr)
768  | /*******************************************************************
769  |  * ca_getDbHandleByName                              *
770  |  *   -- A function that compares each 'name' component of every     *
771  |  *    element in the linked-list of databases with the name of   *
772  |  *    the database to be found.  If the required database is     *
773  |  *    found, a pointer to the structure representing this       *
774  |  *     database is  returned.                          *
775  |  *                                            *
776  |  *   Parameters                                    *
777  |  *  -- databaseNameStr - the name of the required database        *
778  |  *                                            *
779  |  *  Returns                                      *
780  |   *  -- dbasePtr  - a pointer to the structure representing the     *
781  |   *            database or a pointer to NULL, if we cannot     *
782  |  *            find the database.                      *
783  |  *                                            *
784  |  *******************************************************************/
785  | {
786  | 	/*
787  | 	 * Define a pointer to the current element in the linked list.
788  | 	 * Initialise it to the start of the list.
789  | 	 */
790  | 	GSList *currentPtr = dbList;
791  | 
792  | 	/*
793  | 	 * Define and initialise a pointer that points to the 'data'
794  | 	 * component of the GSList struct; i.e. a pointer to a variable of
795  | 	 * type ca_database_t.
796  | 	 */
797  | 	ca_database_t *dbasePtr = currentPtr->data;
798  | 
799  | 	/*
800  | 	 * Look at each data component of the list of databases; (each data
801  | 	 * component is a structure of type ca_database_t). Compare the
802  | 	 * 'name' component of each ca_database_t structure with the value of
803  | 	 * databaseName untill we get a match or we reach the end of the
804  | 	 * list.
805  | 	 */
806  | 
807  | 	/*
808  | 	 * We first check if currentPtr is pointing to NULL; if yes, we exit
809  | 	 * the while loop; if no, we make dbasePtr point to the data
810  | 	 * component of the current ca_database_t structure; then, we check
811  | 	 * if this is the database name that we want; if yes, we _break_ from
812  | 	 * the while loop.
813  | 	 */
814  | 	while (currentPtr != NULL) {
815  | 		dbasePtr = currentPtr->data;
816  | 		if (strcmp(dbasePtr->dbName, databaseNameStr) == 0)
817  | 			break;
818  | 		currentPtr = currentPtr->next;
819  | 	}
820  | 
821  | 	/*
822  | 	 * We return a pointer.  If we found the database, this pointer
823  | 	 * points to the ca_database_t structure which represents the
824  | 	 * database. If we did not find the database, we return a pointer to
825  | 	 * NULL.
826  | 	 */
827  | 	if (currentPtr == NULL) {
828  | 		dbasePtr = NULL;
829  | 		return (dbasePtr);
830  | 	}
831  | 	else {
832  | 		return (dbasePtr);
833  | 	}
834  | 
835  | }
836  | 
837  | 
838  | 
839  | ca_mirror_t *
840  | ca_getNrtmHandleByName(char *nrtmNameStr)
841  | /*******************************************************************
842  |  * ca_NrtmHandleByName                              *
843  |  *   -- A function that compares each 'name' component of every     *
844  |  *    element in the linked-list of databases with the name of   *
845  |  *    the database to be found.  If the required database is     *
846  |  *    found, a pointer to the structure representing this       *
847  |  *     database is  returned.                          *
848  |  *                                            *
849  |  *   Parameters                                    *
850  |  *  -- nrtmNameStr - the name of the required database        *
851  |  *                                            *
852  |  *  Returns                                      *
853  |   *  -- nrtmPtr  - a pointer to the structure representing the     *
854  |   *            database or a pointer to NULL, if we cannot     *
855  |  *            find the database.                      *
856  |  *                                            *
857  |  *******************************************************************/
858  | {
859  | 	/*
860  | 	 * Define a pointer to the current element in the linked list.
861  | 	 * Initialise it to the start of the list.
862  | 	 */
863  | 	GSList *currentPtr = nrtmList;
864  | 
865  | 	/*
866  | 	 * Define and initialise a pointer that points to the 'data'
867  | 	 * component of the GSList struct; i.e. a pointer to a variable of
868  | 	 * type ca_database_t.
869  | 	 */
870  | 	ca_mirror_t *nrtmPtr = currentPtr->data;
871  | 
872  | 	/*
873  | 	 * Look at each data component of the list of databases; (each data
874  | 	 * component is a structure of type ca_database_t). Compare the
875  | 	 * 'name' component of each ca_database_t structure with the value of
876  | 	 * databaseName untill we get a match or we reach the end of the
877  | 	 * list.
878  | 	 */
879  | 
880  | 	/*
881  | 	 * We first check if currentPtr is pointing to NULL; if yes, we exit
882  | 	 * the while loop; if no, we make nrtmPtr point to the data component
883  | 	 * of the current ca_database_t structure; then, we check if this is
884  | 	 * the database name that we want; if yes, we _break_ from the while
885  | 	 * loop.
886  | 	 */
887  | 	while (currentPtr != NULL) {
888  | 		nrtmPtr = currentPtr->data;
889  | 		if (strcmp(nrtmPtr->mrName, nrtmNameStr) == 0)
890  | 			break;
891  | 		currentPtr = currentPtr->next;
892  | 	}
893  | 
894  | 	/*
895  | 	 * We return a pointer.  If we found the database, this pointer
896  | 	 * points to the ca_database_t structure which represents the
897  | 	 * database. If we did not find the database, we return a pointer to
898  | 	 * NULL.
899  | 	 */
900  | 	if (currentPtr == NULL) {
901  | 		nrtmPtr = NULL;
902  | 		return (nrtmPtr);
903  | 	}
904  | 	else {
905  | 		return (nrtmPtr);
906  | 	}
907  | 
908  | }