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,2001,2002                    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 "rip.h"
38   | 
39   | #include <stdio.h>
40   | #include <stdlib.h>
41   | #include <glib.h>
42   | #include <string.h>
43   | #include <unistd.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  | int no_source_defd;
116  | /* At least one source _must_ be defined.		*/
117  | /* If one or more sources are defined, then	*/
118  | /* this variable is set to 0.  Otherwise, 		*/
119  | /* this is 1.											*/
120  | 
121  | 	/*
122  | 	 * Function prototypes of ca_parseDbLine(), ca_parseNrtmLine() and
123  | 	 * ca_parseSrcLine().  We put them here so that it can only be called
124  | 	 * from within the ca_readSources() function.
125  | 	 */
126  | 	void ca_parseDbLine(char *, ca_database_t *);
127  | 	void ca_parseNrtmLine(char *, ca_mirror_t *);
128  | 	void ca_parseSrcLine(char *, ca_dbSource_t *);
129  | 
130  | 
131  | #ifdef DEBUG
132  | 	printf("\nInside ca_readSources() function.\n");
133  | 	printf("Sources file is: %s\n", sourcesDefFile);
134  | #endif	/* DEBUG */
135  | 
136  | 	/*
137  | 	 * Open the sources file for reading .....
138  | 	 */
139  | 	if ((sourcesFilePtr = fopen(sourcesDefFile, "r")) == NULL) {
140  | 		printf("Error: the file %s could not be opened.\n", sourcesDefFile);
141  | 		die;
142  | 	}
143  | 
144  | 	/* Before reading the file, we initialise all flags to 0. */
145  | 	in_DATABASE_def = 0;
146  | 	in_NRTM_def = 0;
147  | 	in_SOURCE_def = 0;
148  | 	no_source_defd = 1;
149  | 
150  | 	/*
151  | 	 * Read the first line of the file. Remove leading and trailing
152  | 	 * blank-space characters. if the first character of the line is a
153  | 	 * comment or if it is a blank-line, continue.
154  | 	 * 
155  | 	 */
156  | 
157  | 	fgets(line, sizeof(line), sourcesFilePtr);
158  | 	g_strstrip(line);
159  | 
160  | 	/*
161  | 	 * While there are lines to be read in the sources file, process the
162  | 	 * current line and read the next line.
163  | 	 */
164  | 
165  | 	while (!feof(sourcesFilePtr)) {
166  | #ifdef DEBUG
167  | 		printf("line:%s:End of line\n", line);
168  | 		printf("Length of line: %d\n", strlen(line));
169  | #endif	/* DEBUG */
170  | 
171  | 		/*
172  | 		 * Ignore comments and empty lines.
173  | 		 */
174  | 		if ((strncmp(line, comment, 1) == 0) || (strlen(line) == 0)) {
175  | #ifdef DEBUG
176  | 			printf("We are reading a comment or an empty line ..... \n");
177  | #endif	/* DEBUG */
178  | 			fgets(line, sizeof(line), sourcesFilePtr);
179  | 			g_strstrip(line);
180  | 			continue;
181  | 		}
182  | 
183  | 		/* Testing */
184  | #ifdef DEBUG
185  | 		printf("LINE >>>%sEND_OF_LINE\n", line);
186  | #endif	/* DEBUG */
187  | 
188  | 		/*
189  | 		 * if we are in a DATABASE definition then have we read all
190  | 		 * of the definition ? if yes, then commit the definition,
191  | 		 * reset the 'Database' flag and read the next line.
192  | 		 * Otherwise parse the line and store the details in
193  | 		 * temporary variables.
194  | 		 */
195  | 
196  | 		/* If we are in a DATABASE definition */
197  | 		if (in_DATABASE_def) {
198  | 			/*
199  | 			 * If we have reached the end of a DATABASE
200  | 			 * definition, commit the definition.
201  | 			 */
202  | 
203  | 			if (strcmp(line, "/DATABASE") == 0) {
204  | 				/* Commit the definition */
205  | 				/* Some code. */
206  | #ifdef DEBUG
207  | 				puts("We have reached the end of a DATABASE definition");
208  | 				puts("Testing the population of the db structure:");
209  | 				printf("\n%s::%d::%s::%s::%s\n", newDbPtr->host, newDbPtr->port, newDbPtr->user, newDbPtr->password, newDbPtr->dbName);
210  | #endif	/* DEBUG */
211  | 
212  | 			/*
213  | 			 * Check that the definition of the DATABASE is complete.
214  | 			 */
215  | 			 if ( !(newDbPtr->host && newDbPtr->port && newDbPtr->user && newDbPtr->password && newDbPtr->dbName) )
216  | 				{
217  | 				fprintf(stderr, "Error: definition of database is incomplete.\n");
218  | 				die;
219  | 				}
220  | 
221  | 				/*
222  | 				 * Commit the definition to the linked list
223  | 				 * of Databases.
224  | 				 */
225  | 
226  | 				dbList = g_slist_append(dbList, newDbPtr);
227  | 
228  | 				/*
229  | 				 * We have reached the end of the DATABASE
230  | 				 * definition
231  | 				 */
232  | 				/* Thus, reset the flag and free some memory. */
233  | 				in_DATABASE_def = 0;
234  | 
235  | 
236  | 				/*
237  | 				 * Read the next line and do the conditional
238  | 				 * test.
239  | 				 */
240  | 				fgets(line, sizeof(line), sourcesFilePtr);
241  | 				g_strstrip(line);
242  | 				continue;
243  | 			}
244  | 
245  | 			/*
246  | 			 * Otherwise, parse the line and fill in the
247  | 			 * structure of the Database.
248  | 			 */
249  | 			ca_parseDbLine(line, newDbPtr);
250  | 
251  | 		}
252  | 
253  | 		/*
254  | 		 * If we have found the _beginning_ of a Database definition,
255  | 		 * then set the in_DATABASE_def flag and allocate space, etc.
256  | 		 * for the database.
257  | 		 */
258  | 
259  | 		if ((!in_DATABASE_def) && (strncmp(line, DATABASE_KEY, strlen(DATABASE_KEY)) == 0)) {
260  | 			in_DATABASE_def = 1;
261  | 
262  | 			/* Allocate space for the database */
263  | 			/* Current_db = fscanf etc.) */
264  | 			/* Fill in the defaults. */
265  | #ifdef DEBUG
266  | 			puts("Beginning of a database defintion ..... ");
267  | #endif	/* DEBUG */
268  | 
269  | 			sscanf(line, "%s %s", varName, database);
270  | 			g_strstrip(database);
271  | 
272  | #ifdef DEBUG
273  | 			printf("Database name is: %s\n", database);
274  | #endif	/* DEBUG */
275  | 
276  | 			/*
277  | 			 * Create a structure for the database.
278  | 			 */
279  | 			newDbPtr = UT_calloc(1, sizeof(ca_database_t));
280  | 			/*
281  | 			 *	if (newDbPtr == NULL) {
282  | 		    *		fprintf(stderr, "Cannot allocate memory to new db structure\n");
283  | 		    *		die;
284  | 					}
285  | 			 */
286  | 
287  | 			/* Assign the name of the database */
288  | 			strcpy(newDbPtr->dbName, database);
289  | 
290  | 		}
291  | 
292  | 
293  | 		/********************
294  | 	               * NRTM definition  *
295  | 	               ********************/
296  | 
297  | 		/*
298  | 		 * if we are in a NRTM definition then have we read all of
299  | 		 * the definition ? if yes, then commit the definition and
300  | 		 * read the next line. otherwise parse the line and store the
301  | 		 * details in temporary variables.
302  | 		 */
303  | 
304  | 		/* If we are in a NRTM definition */
305  | 		if (in_NRTM_def) {
306  | 			/*
307  | 			 * If we have reached the end of a NRTM definition,
308  | 			 * commit the definition.
309  | 			 */
310  | 			if (strcmp(line, "/NRTM") == 0) {
311  | 				/* Commit the definition */
312  | 				/* Some code. */
313  | #ifdef DEBUG
314  | 				puts("We have reached the end of a NRTM definition");
315  | 				puts("Testing the population of the mirror structure:");
316  | 				printf("\n%s::%d::%d::%d\n", newMirrPtr->host, newMirrPtr->port, newMirrPtr->delay, newMirrPtr->protocolVer);
317  | #endif	/* DEBUG */
318  | 
319  | 
320  | 			/*
321  | 			 * Check that the definition of the NRTM is complete.
322  | 			 */
323  | 			 if ( !( newMirrPtr->host && newMirrPtr->port && newMirrPtr->protocolVer) && (newMirrPtr->delay < 0) )
324  | 				{
325  | 				fprintf(stderr, "Error: definition of near-real-time-mirror is incomplete.\n");
326  | 				die;
327  | 				}
328  | 				/*
329  | 				 * Commit the definition to the linked list
330  | 				 * of nrt-mirrors.
331  | 				 */
332  | 
333  | 				nrtmList = g_slist_append(nrtmList, newMirrPtr);
334  | 
335  | 				/*
336  | 				 * We have reached the end of the NRTM
337  | 				 * definition
338  | 				 */
339  | 				/* Thus, reset the NRTM flag. */
340  | 				in_NRTM_def = 0;
341  | 
342  | 				/*
343  | 				 * Read the next line and do the conditional
344  | 				 * test.
345  | 				 */
346  | 				fgets(line, sizeof(line), sourcesFilePtr);
347  | 				g_strstrip(line);
348  | 				continue;
349  | 			}
350  | 
351  | 			/*
352  | 			 * Otherwise, parse the line and fill in the
353  | 			 * structure of the NRMT.
354  | 			 */
355  | 
356  | 			ca_parseNrtmLine(line, newMirrPtr);
357  | 		}
358  | 
359  | 		/*
360  | 		 * If we have found the beginning of a Near-Real-Time-Mirror
361  | 		 * definition, then set the in_NRTM_def flag and allocate
362  | 		 * space, etc. for the Near-Real-Time-Mirror.
363  | 		 */
364  | 
365  | 		if ((!in_NRTM_def) && (strncmp(line, NRTM_KEY, strlen(NRTM_KEY)) == 0)) {
366  | 			in_NRTM_def = 1;
367  | 			/* Allocate space for the Near-Real-Time-Mirror. */
368  | 			/* Current_db = fscanf etc.) */
369  | 			/* Fill in the defaults. */
370  | #ifdef DEBUG
371  | 			puts("Beginning of a Near-Real-Time-Mirror defintion ..... ");
372  | #endif	/* DEBUG */
373  | 
374  | 			sscanf(line, "%s %s", varName, mirror);
375  | 
376  | 			/*
377  | 			 * Create a structure for the mirror.
378  | 			 */
379  | 			newMirrPtr = UT_calloc(1, sizeof(ca_mirror_t));
380  | /*
381  |  * No need to verify that NULL has not been returned.
382  |  *
383  |  *		if (newMirrPtr == NULL) {
384  |  *				fprintf(stderr, "Cannot allocate memory to new nrtm structure\n");
385  | 	*			die;
386  |  *			}
387  |  */
388  | 
389  | 			/* Assign the name of the mirror ? */
390  | 			strcpy(newMirrPtr->mrName, mirror);
391  | 
392  | 		}
393  | 
394  | 		/*********************
395  | 	               * SOURCE Definition *
396  | 	               *********************/
397  | 
398  | 		/*
399  | 		 * if we are in a SOURCE definition then have we read all of
400  | 		 * the definition ? if yes, then commit the definition, reset
401  | 		 * the 'Database' flag and read the next line. Otherwise
402  | 		 * parse the line and store the details in temporary
403  | 		 * variables.
404  | 		 */
405  | 
406  | 		/* If we are in a SOURCE definition */
407  | 		if (in_SOURCE_def) {
408  | 			/*
409  | 			 * If we have reached the end of a SOURCE definition,
410  | 			 * commit the definition.
411  | 			 */
412  | 
413  | 			if (strcmp(line, "/SOURCE") == 0) {
414  | 				/* Commit the definition */
415  | 				/* Some code. */
416  | #ifdef DEBUG
417  | 				puts("We have reached the end of a SOURCE definition");
418  | 				puts("Testing the population of the new Source structure:");
419  | 				printf("Source name: %s\n", newSrcPtr->name);
420  | 				printf("\nDB == %s::%d::%s::%s::%s\n", (newSrcPtr->db).host, (newSrcPtr->db).port, (newSrcPtr->db).user, (newSrcPtr->db).password, (newSrcPtr->db).dbName);
421  | 				printf("Mode: %d\n", newSrcPtr->opMode);
422  | 				printf("NRTM == %s::%d::%d:%d\n", (newSrcPtr->nrtm).host, (newSrcPtr->nrtm).port, (newSrcPtr->nrtm).delay, (newSrcPtr->nrtm).protocolVer);
423  | 				printf("UpdPort: %d\n", newSrcPtr->updPort);
424  | 				printf("New Source Options == %s::%s\n", newSrcPtr->canupd, newSrcPtr->deflook);
425  | #endif	/* DEBUG */
426  | 
427  | 
428  | 			/*
429  | 			 * Check that the definition of the SOURCE is complete.
430  | 			 */
431  | 			 if ( !(newSrcPtr->name && newSrcPtr->updPort && newSrcPtr->canupd && newSrcPtr->deflook) && (newSrcPtr->opMode < 0) )
432  | 				{
433  | 				fprintf(stderr, "Error: definition of source is incomplete.\n");
434  | 				die;
435  | 				}
436  | 				/*
437  | 				 * Commit the definition to the linked list
438  | 				 * of Sources.
439  | 				 */
440  | 
441  | 				sourceList = g_slist_append(sourceList, newSrcPtr);
442  | 
443  | 				/*
444  | 				 * We have reached the end of the SOURCE
445  | 				 * definition
446  | 				 */
447  | 				/* Thus, reset the flag and free some memory. */
448  | 				in_SOURCE_def = 0;
449  | 
450  | 
451  | 				/*
452  | 				 * Read the next line and do the conditional
453  | 				 * test.
454  | 				 */
455  | 				fgets(line, sizeof(line), sourcesFilePtr);
456  | 				g_strstrip(line);
457  | 				continue;
458  | 			}
459  | 
460  | 			/*
461  | 			 * Otherwise, parse the line and fill in the
462  | 			 * structure of the Database.
463  | 			 */
464  | 			ca_parseSrcLine(line, newSrcPtr);
465  | 
466  | 		}
467  | 
468  | 		/*
469  | 		 * If we have found the _beginning_ of a SOURCE definition,
470  | 		 * then set the in_SOURCE_def flag and allocate space, etc.
471  | 		 * for the database.
472  | 		 * We also set the no_source_defd flag.
473  | 		 */
474  | 
475  | 		if ((!in_SOURCE_def) && (strncmp(line, SOURCE_KEY, strlen(SOURCE_KEY)) == 0)) {
476  | 			in_SOURCE_def = 1;
477  | 			no_source_defd = 0;
478  | 
479  | 			/* Allocate space for the Source */
480  | 			/* Current_source = fscanf etc.) */
481  | 			/* Fill in the defaults. */
482  | #ifdef DEBUG
483  | 			puts("Beginning of a Source defintion ..... ");
484  | #endif	/* DEBUG */
485  | 
486  | 			sscanf(line, "%s %s", varName, source);
487  | 			g_strstrip(source);
488  | 
489  | #ifdef DEBUG
490  | 			printf("Source name is: %s\n", source);
491  | #endif	/* DEBUG */
492  | 
493  | 			/*
494  | 			 * Create a structure for the source.
495  | 			 * 
496  | 			 */
497  | 			newSrcPtr = UT_calloc(1, sizeof(ca_dbSource_t));
498  | 
499  | 			/*
500  | 			 * No need to check that NULL has not been returned.
501  | 			 *
502  | 			 * if (newSrcPtr == NULL) {
503  | 		    *		fprintf(stderr, "Cannot allocate memory to new Source structure\n");
504  | 		    *		die;
505  | 			 * }
506  | 			 */
507  | 
508  | 			/* Assign the name of the Source */
509  | 			strcpy(newSrcPtr->name, source);
510  | 
511  | 		}
512  | 
513  | 		/* Read the next line. */
514  | 		fgets(line, sizeof(line), sourcesFilePtr);
515  | 		g_strstrip(line);
516  | 
517  | 		/* End of while loop; i.e. end of processing a line. */
518  | 	}
519  | 
520  | 	/* Close the sources definition file. */
521  | 	fclose(sourcesFilePtr);
522  | 
523  | 	/* End of ca_readSources() function */
524  | 
525  | if (no_source_defd != 0)
526  | 		{
527  | 		fprintf(stderr, "Error: No source defined !!!\n");
528  | 		die;
529  | 		}
530  | }
531  | 
532  | void
533  | ca_getAllDatabases(GSList * databases)
534  | {
535  | 	GSList *currentPtr;	/* Pointer to the structure at which we look. */
536  | 
537  | 	/*
538  | 	 * Look at the first member of the linked-list of sources.
539  | 	 */
540  | 	currentPtr = databases;
541  | 
542  | 	/*
543  | 	 * Look at each data component of the source list, untill we reach
544  | 	 * the end of the list.
545  | 	 */
546  | 	while (currentPtr != NULL) {
547  | 		ca_database_t *dbPtr = currentPtr->data;
548  | 		printf("\n%s,%d,%s,%s,%s\n", dbPtr->host, dbPtr->port, dbPtr->user, dbPtr->password, dbPtr->dbName);
549  | 		currentPtr = currentPtr->next;
550  | 	}
551  | }
552  | 
553  | 
554  | void
555  | ca_getAllMirrors(GSList * mirrors)
556  | {
557  | 	GSList *currentPtr;	/* Pointer to the structure at which we look. */
558  | 
559  | 	/*
560  | 	 * Look at the first member of the linked-list of sources.
561  | 	 */
562  | 	currentPtr = mirrors;
563  | 
564  | 	/*
565  | 	 * Look at each data component of the source list, untill we reach
566  | 	 * the end of the list.
567  | 	 */
568  | 	while (currentPtr != NULL) {
569  | 		ca_mirror_t *nrtmPtr = currentPtr->data;
570  | 		printf("\n%s,%d,%d,%d, %s\n", nrtmPtr->host, nrtmPtr->port, nrtmPtr->delay, nrtmPtr->protocolVer, nrtmPtr->mrName);
571  | 		currentPtr = currentPtr->next;
572  | 	}
573  | }
574  | 
575  | void
576  | ca_parseDbLine(char *lineStr, ca_database_t * dbStructPtr)
577  | /*******************************************************************
578  |  *                                             *
579  |  * ca_parseLine  -- parses the a line in the Sources file and     *
580  |  *             writes the values into temporary variables.    *
581  |  *                                            *
582  |  * Parameters                                    *
583  |   *    lineStr     -- the current line of the Sources file       *
584  |  *               -- a NULL terminated string            *
585  |   *    dbStructPtr  -- the db we are filling                 *
586  |   *              -- a pointer to a ca_database_t structure.  *
587  |  *                                            *
588  |  * Returns                                      *
589  |   *    Nothing -- perhaps make this return 0 on successful exit ?  *
590  |  *                                            *
591  |  *******************************************************************/
592  | {
593  | 	char dbComp[64];	/* Component of a database. */
594  | 	char varName[16];	/* The name of the variable. */
595  | 
596  | 	gchar **tokens;	/* Pointer to an array of strings. */
597  | 
598  | #ifdef DEBUG
599  | 	int i;	/* A counting variable. */
600  | #endif	/* DEBUG */
601  | 
602  | 	/*
603  | 	 * Split the line on the ':' character. Then, for both the name of
604  | 	 * the variable and its value, remove leading and trailing
605  | 	 * blank-space characters.
606  | 	 * We set max_tokens to be 1 to allow ':' in the password.
607  | 	 */
608  | 	tokens = g_strsplit(lineStr, ":", 1);
609  | 
610  | #ifdef DEBUG
611  | 	for (i = 0; tokens[i] != NULL; i++)
612  | 		printf("tokens[%d] = %s\n", i, tokens[i]);
613  | #endif	/* DEBUG */
614  | 
615  | 	strcpy(varName, tokens[0]);
616  | 	strcpy(dbComp, tokens[1]);
617  | 
618  | 	/* Free the memory used by the tokens array. */
619  | 	g_strfreev(tokens);
620  | 
621  | 	/* Remove leading and trailing blank-space characters. */
622  | 	g_strstrip(varName);
623  | 	g_strstrip(dbComp);
624  | 
625  | #ifdef DEBUG
626  | 	printf("VarName: %s; dbComp: %s\n", varName, dbComp);
627  | #endif	/* DEBUG */
628  | 
629  | 	if (strcmp(varName, "host") == 0) {
630  | 		strcpy(dbStructPtr->host, dbComp);
631  | 	}
632  | 	else {
633  | 		if (strcmp(varName, "port") == 0) {
634  | 			dbStructPtr->port = atoi(dbComp);
635  | 		}
636  | 		else {
637  | 			if (strcmp(varName, "user") == 0) {
638  | 				strcpy(dbStructPtr->user, dbComp);
639  | 			}
640  | 			else {
641  | 				if (strcmp(varName, "password") == 0) {
642  | 					strcpy(dbStructPtr->password, dbComp);
643  | 				}
644  | 				else {
645  | 					fprintf(stderr, "Unknown database component \"%s\".\n", dbComp);
646  | 					die;
647  | 				}
648  | 			}
649  | 		}
650  | 	}
651  | }
652  | 
653  | 
654  | 
655  | void
656  | ca_parseNrtmLine(char *lineStr, ca_mirror_t * mrStructPtr)
657  | /*
658  |  * */
659  | {
660  | 	char nrtmComp[64];	/* Component of a NRTM. */
661  | 	char varName[16];	/* The name of the variable. */
662  | 
663  | 	gchar **tokens;	/* Pointer to an array of strings. */
664  | 
665  | #ifdef DEBUG
666  | 	int i;	/* A counting variable. */
667  | #endif	/* DEBUG */
668  | 
669  | 	/*
670  | 	 * Split the line on the ':' character. Then, for both the name of
671  | 	 * the variable and its value, remove leading and trailing
672  | 	 * blank-space characters.
673  |   * We set max_tokens to be 1; thus the line is split after the first
674  |   * ':'.
675  | 	 */
676  | 	tokens = g_strsplit(lineStr, ":", 1);
677  | 
678  | #ifdef DEBUG
679  | 	for (i = 0; tokens[i] != NULL; i++)
680  | 		printf("tokens[%d] = %s\n", i, tokens[i]);
681  | #endif	/* DEBUG */
682  | 
683  | 	strcpy(varName, tokens[0]);
684  | 	strcpy(nrtmComp, tokens[1]);
685  | 
686  | 	/* Free the memory used by the tokens array. */
687  | 	g_strfreev(tokens);
688  | 
689  | 	/* Remove leading and trailing blank-space characters. */
690  | 	g_strstrip(varName);
691  | 	g_strstrip(nrtmComp);
692  | 
693  | #ifdef DEBUG
694  | 	printf("VarName: %s; nrtmComp: %s\n", varName, nrtmComp);
695  | #endif	/* DEBUG */
696  | 
697  | 
698  | 	if (strcmp(varName, "host") == 0) {
699  | 		strcpy(mrStructPtr->host, nrtmComp);
700  | 	}
701  | 	else {
702  | 		if (strcmp(varName, "port") == 0) {
703  | 			mrStructPtr->port = atoi(nrtmComp);
704  | 		}
705  | 		else {
706  | 			if (strcmp(varName, "delay") == 0) {
707  | 				mrStructPtr->delay = atoi(nrtmComp);
708  | 			}
709  | 			else {
710  | 				if (strcmp(varName, "protocolVersion") == 0) {
711  | 					mrStructPtr->protocolVer = atoi(nrtmComp);
712  | 				}
713  | 				else {
714  | 					fprintf(stderr, "Unknown mirror component \"%s\".\n", nrtmComp);
715  | 					die;
716  | 				}
717  | 			}
718  | 	 }
719  |  }
720  | }
721  | 
722  | 
723  | 
724  | 
725  | void
726  | ca_parseSrcLine(char *lineStr, ca_dbSource_t * srcStructPtr)
727  | /*
728  |  * ca_parseSrcLine() function.
729  |  */
730  | {
731  | 	char srcComp[64];	/* Component of a database. */
732  | 	char varName[16];	/* The name of the variable. */
733  | 
734  | 	gchar **tokens;	/* Pointer to an array of strings. */
735  | 
736  | #ifdef DEBUG
737  | 	int i;	/* A counting variable. */
738  | #endif	/* DEBUG */
739  | 
740  | 	/*
741  | 	 * Split the line on the ':' character. Then, for both the name of
742  | 	 * the variable and its value, remove leading and trailing
743  | 	 * blank-space characters.
744  | 	 * We set the value of max_tokens to be 1; thus, the line is split at
745  | 	 * the first ':' character.
746  | 	 */
747  | 	tokens = g_strsplit(lineStr, ":", 1);
748  | 
749  | 
750  | #ifdef DEBUG
751  | 	for (i = 0; tokens[i] != NULL; i++)
752  | 		printf("tokens[%d] = %s\n", i, tokens[i]);
753  | #endif	/* DEBUG */
754  | 
755  | 	strcpy(varName, tokens[0]);
756  | 	strcpy(srcComp, tokens[1]);
757  | 
758  | 	/* Free the memory used by the tokens array. */
759  | 	g_strfreev(tokens);
760  | 
761  | 	/* Remove leading and trailing blank-space characters. */
762  | 	g_strstrip(varName);
763  | 	g_strstrip(srcComp);
764  | 
765  | #ifdef DEBUG
766  | 	printf("VarName: %s; srcComp: %s\n", varName, srcComp);
767  | #endif	/* DEBUG */
768  | 
769  | 	/*
770  | 	 * Parse each line of the SOURCE definition. If we find a database or
771  | 	 * a mirror, search for it in the appropriate linked list and make
772  | 	 * this source point to it.
773  | 	 */
774  | 
775  | 	if (strcmp(varName, "database") == 0) {
776  | 		/* Search for the appropriate database. */
777  | 		/* Make this source point to it. */
778  | 		/* Use ca_getDbHandleByName(). */
779  | 
780  | 		/* Check that we did not get a NULL pointer.		*/
781  | 		/* If we did, then print an error message and	*/
782  | 		/* die.														*/
783  | 
784  | 		if ( ca_getDbHandleByName(srcComp) == NULL)
785  | 			{
786  | 			fprintf(stderr, "Error: Non-existent database \"%s\" referenced !!!\n", srcComp);
787  | 			die;
788  | 			}
789  | 		else
790  | 			{
791  | 			srcStructPtr->db = *ca_getDbHandleByName(srcComp);
792  | 			}
793  | 
794  | 	}
795  | 	else {
796  | 		if (strcmp(varName, "opMode") == 0) {
797  | 			srcStructPtr->opMode = atoi(srcComp);
798  | 		}
799  | 		else {
800  | 			if (strcmp(varName, "updPort") == 0) {
801  | 				srcStructPtr->updPort = atoi(srcComp);
802  | 			}
803  | 			else {
804  | 				if (strcmp(varName, "canupd") == 0) {
805  | 					strcpy(srcStructPtr->canupd, srcComp);
806  | 				}
807  | 				else {
808  | 					if (strcmp(varName, "deflook") == 0) {
809  | 						strcpy(srcStructPtr->deflook, srcComp);
810  | 					}
811  | 					else {
812  | 						if (strcmp(varName, "nrtm") == 0) {
813  | 							/*
814  | 							 * Get Mirror Handle
815  | 							 * by Name
816  | 							 */
817  | 							/*
818  | 							 * Assign this mirror
819  | 							 * to
820  | 							 */
821  | 							/*
822  | 							 * 
823  | 							 * srcStructPtr->nrtm.
824  | 							 * 
825  | 							 */
826  | 
827  | 							 /* We check that the mirror is defined.		*/
828  | 
829  | 							 if ( ca_getNrtmHandleByName(srcComp) == NULL)
830  | 								{
831  | 								fprintf(stderr, "Error: non-existent mirror \"%s\" referenced !!!\n", srcComp);
832  | 								die;
833  | 								}
834  | 							 else
835  | 								{
836  | 								srcStructPtr->nrtm = *ca_getNrtmHandleByName(srcComp);
837  | 								}
838  | 						}
839  | 						else {
840  | 							fprintf(stderr, "Unknown SOURCE component \"%s\".\n", srcComp);
841  | 							die;
842  | 						}
843  | 					}
844  | 				}
845  | 			}
846  | 		}
847  | 	}
848  | }
849  | 
850  | 
851  | ca_database_t *
852  | ca_getDbHandleByName(char *databaseNameStr)
853  | /*******************************************************************
854  |  * ca_getDbHandleByName                              *
855  |  *   -- A function that compares each 'name' component of every     *
856  |  *    element in the linked-list of databases with the name of   *
857  |  *    the database to be found.  If the required database is     *
858  |  *    found, a pointer to the structure representing this       *
859  |  *     database is  returned.                          *
860  |  *                                            *
861  |  *   Parameters                                    *
862  |  *  -- databaseNameStr - the name of the required database        *
863  |  *                                            *
864  |  *  Returns                                      *
865  |   *  -- dbasePtr  - a pointer to the structure representing the     *
866  |   *            database or a pointer to NULL, if we cannot     *
867  |  *            find the database.                      *
868  |  *                                            *
869  |  *******************************************************************/
870  | {
871  | 	/*
872  | 	 * Define a pointer to the current element in the linked list.
873  | 	 * Later, initialise it to the start of the list.
874  | 	 */
875  | 	GSList *currentPtr; 
876  | 
877  | 	/*
878  | 	 * Define and later initialise a pointer that points to the 'data'
879  | 	 * component of the GSList struct; i.e. a pointer to a variable of
880  | 	 * type ca_database_t.
881  | 	 */
882  | 	ca_database_t *dbasePtr; 
883  | 
884  |  /*
885  |   * Before we search the linked-list, we must first check that it is
886  |   * not empty.  If it is, then print a error message and exit.
887  |   */
888  | 
889  |  if (dbList == NULL)
890  | 		{
891  | 		fprintf(stderr, "Error: no database is defined in SOURCEFILE.\n");
892  | 		die;
893  | 		}
894  | 
895  |  currentPtr = dbList;
896  |  dbasePtr = currentPtr->data;
897  | 
898  | 	/*
899  | 	 * Look at each data component of the list of databases; (each data
900  | 	 * component is a structure of type ca_database_t). Compare the
901  | 	 * 'name' component of each ca_database_t structure with the value of
902  | 	 * databaseName untill we get a match or we reach the end of the
903  | 	 * list.
904  | 	 */
905  | 
906  | 	/*
907  | 	 * We first check if currentPtr is pointing to NULL; if yes, we exit
908  | 	 * the while loop; if no, we make dbasePtr point to the data
909  | 	 * component of the current ca_database_t structure; then, we check
910  | 	 * if this is the database name that we want; if yes, we _break_ from
911  | 	 * the while loop.
912  | 	 */
913  | 	while (currentPtr != NULL) {
914  | 		dbasePtr = currentPtr->data;
915  | 		if (strcmp(dbasePtr->dbName, databaseNameStr) == 0)
916  | 			break;
917  | 		currentPtr = currentPtr->next;
918  | 	}
919  | 
920  | 	/*
921  | 	 * We return a pointer.  If we found the database, this pointer
922  | 	 * points to the ca_database_t structure which represents the
923  | 	 * database. If we did not find the database, we return a pointer to
924  | 	 * NULL.
925  | 	 */
926  | 	if (currentPtr == NULL) {
927  | 		dbasePtr = NULL;
928  | 		return (dbasePtr);
929  | 	}
930  | 	else {
931  | 		return (dbasePtr);
932  | 	}
933  | 
934  | }
935  | 
936  | 
937  | 
938  | ca_mirror_t *
939  | ca_getNrtmHandleByName(char *nrtmNameStr)
940  | /*******************************************************************
941  |  * ca_NrtmHandleByName                              *
942  |  *   -- A function that compares each 'name' component of every     *
943  |  *    element in the linked-list of databases with the name of   *
944  |  *    the database to be found.  If the required database is     *
945  |  *    found, a pointer to the structure representing this       *
946  |  *     database is  returned.                          *
947  |  *                                            *
948  |  *   Parameters                                    *
949  |  *  -- nrtmNameStr - the name of the required database        *
950  |  *                                            *
951  |  *  Returns                                      *
952  |   *  -- nrtmPtr  - a pointer to the structure representing the     *
953  |   *            database or a pointer to NULL, if we cannot     *
954  |  *            find the database.                      *
955  |  *                                            *
956  |  *******************************************************************/
957  | {
958  | 	/*
959  | 	 * Define a pointer to the current element in the linked list.
960  | 	 * Later, initialise it to the start of the list.
961  | 	 */
962  | 	GSList *currentPtr; 
963  | 
964  | 	/*
965  | 	 * Define and initialise a pointer that points to the 'data'
966  | 	 * component of the GSList struct; i.e. a pointer to a variable of
967  | 	 * type ca_database_t.
968  | 	 */
969  | 	ca_mirror_t *nrtmPtr; 
970  | 
971  | 	/*
972  | 	 * First check that the linked list of mirrors is not empty.  If it
973  | 	 * is, print an error and exit.
974  | 	 */
975  | 	 if (nrtmList == NULL)
976  | 		{
977  | 		fprintf(stderr, "Error: no near-real-time mirror defined in SOURCEFILE.\n");
978  | 		die;
979  | 		}
980  | 
981  |  currentPtr = nrtmList; 
982  |  nrtmPtr = currentPtr->data;
983  | 
984  | 	/*
985  | 	 * Look at each data component of the list of databases; (each data
986  | 	 * component is a structure of type ca_database_t). Compare the
987  | 	 * 'name' component of each ca_database_t structure with the value of
988  | 	 * databaseName untill we get a match or we reach the end of the
989  | 	 * list.
990  | 	 */
991  | 
992  | 
993  | 	/*
994  | 	 * We first check if currentPtr is pointing to NULL; if yes, we exit
995  | 	 * the while loop; if no, we make nrtmPtr point to the data component
996  | 	 * of the current ca_database_t structure; then, we check if this is
997  | 	 * the database name that we want; if yes, we _break_ from the while
998  | 	 * loop.
999  | 	 */
1000 | 	while (currentPtr != NULL) {
1001 | 		nrtmPtr = currentPtr->data;
1002 | 		if (strcmp(nrtmPtr->mrName, nrtmNameStr) == 0)
1003 | 			break;
1004 | 		currentPtr = currentPtr->next;
1005 | 	}
1006 | 
1007 | 	/*
1008 | 	 * We return a pointer.  If we found the mirror, this pointer
1009 | 	 * points to the ca_mirror_t structure which represents the
1010 | 	 * mirror. If we did not find the database, we return a pointer to
1011 | 	 * NULL.
1012 | 	 */
1013 | 	if (currentPtr == NULL) {
1014 | 		nrtmPtr = NULL;
1015 | 		return (nrtmPtr);
1016 | 	}
1017 | 	else {
1018 | 		return (nrtmPtr);
1019 | 	}
1020 | 
1021 | }