1    | #include <stdio.h>
2    | #include <stdlib.h>
3    | #include <glib.h>
4    | #include <string.h>
5    | #include <stubs.h>
6    | #include "ca_defs.h"
7    | /* #define DEBUG */
8    | 
9    | /**********************************************
10   |  * This file contains the definitions of all	*
11   |  * the functions.										*
12   | 	**********************************************/
13   | 
14   | 
15   | void stringPack(char *dest, const char *source)
16   | {
17   | #ifdef DEBUG
18   | printf("\nInside stringPack function\n");
19   | #endif 	/* DEBUG */
20   | 
21   | /*----------------------------------------------------------------------*\
22   | 
23   | *  Function to rewrite a line of text with only one blankspace between  *
24   | *  each word.
25   | *
26   | 
27   | \*----------------------------------------------------------------------*/
28   | 
29   | 
30   | /*
31   |  * This while loop continues until the NULL character is copied into
32   |  * the destination string.  If a tab character is copied into the 
33   |  * destination string, it is replaced with a blank-space character.
34   |  *
35   |  * Multiple blank-space and/or tab characters are skipped in the source
36   |  * string until any other character is found.
37   |  */
38   | 
39   | 	while (1)
40   | 		{
41   | 		*dest = *source;
42   | 
43   | 		if (*dest == '\t')
44   | 			(*dest = ' ');
45   | 	
46   | 		/* Exit if have copied the end of the string. */
47   | 		if (*dest == '\0')
48   | 			return;
49   | 
50   | /*
51   |  * If the source character was a blank-space or a tab, move to the next 
52   |  * source character.  While the source character is a blank-space or a
53   |  * tab, move to the next character (i.e. ignore these characters).  When
54   |  * any other character is found in the source string, move to the next
55   |  * element of the destination string.
56   |  *
57   |  * Otherwise, simultaneously, move to the next elements of the destination
58   |  * and the source strings.
59   |  */
60   | 
61   | 
62   | 		
63   | 		if ( (*source == ' ') || (*source == '\t') )
64   | 			{
65   | 			++source;
66   | 			while ( (*source == ' ') || (*source == '\t') )
67   | 				{
68   | 				++source;
69   | 				}
70   | 
71   | 			++dest;
72   | 			}
73   | 		else
74   | 			{
75   | 			++dest;
76   | 			++source;
77   | 			}
78   | 		}
79   | }
80   | 
81   | 
82   | void ca_populateDictionary(dict_t woordenboek[], int size)
83   | 
84   | /*******************************************************************
85   |  * ca_populateDictionary -- Parses dictionary file, initializes    *
86   |  *									the dictionary structure and writes    *
87   |  *									the file of dictionary symbols, 			*
88   | 	*									ca_dictSyms.h									*
89   | 	*																						*
90   | 	* Parameters																		*
91   | 	*		woordenboek -- the dictionary to be populated					*
92   | 	*		size -- the total number of variables i.e. the size of the  *
93   |  *	 			  array of dict_t structures.  See D. & D., p.276		*
94   |  *																						*
95   |  * Returns																			*
96   | 	*		Nothing ?  (may change this later)									*
97   |  *																						*
98   |  *******************************************************************/
99   | 
100  | {
101  | const char *blankLine = "\n";
102  | const char *comment = "#";
103  | char line[120];
104  | char input[120];
105  | char test[120];
106  | int lineNo = 0;
107  | int i;
108  | int entry = 0;
109  | FILE *dictPtr, *defnPtr;
110  | 
111  | gchar **tokens;                         /* Pointer to an array of strings. */
112  | 		
113  | /*
114  | 	* Try to open the dictionary file for reading.  If it cannot be
115  |  * opened, exit with an error.
116  |  */
117  | if ( (dictPtr = fopen("dictionary.txt", "r")) == NULL)
118  | 		{
119  | 		fprintf(stderr, "Error: Unable to open 'dictionary.txt'\n");
120  | 		die;
121  | 		}
122  | 		
123  | 
124  | 	/*
125  | 	 *Try to open the definitions file for writing.  If it cannot be
126  |   * opened,exit with an error
127  |   */
128  | if ( (defnPtr = fopen("defs.txt", "w")) == NULL)
129  | 		{
130  | 		fprintf(stderr, "Error: Unable to open 'defs.txt'\n");
131  | 		die;
132  | 		}
133  | 	
134  | 		/*
135  | 		 * Read the file one line at a time;
136  | 		 * if the line begins with a comment, ignore it;
137  | 		 * otherwise, split each line into tokens;
138  | 		 * print each token.
139  | 		 * Assign each token to the appropriate member of
140  | 		 * the appropriate element of the dictionary array.
141  | 		 */
142  | 		
143  | 		fgets(input, sizeof(input), dictPtr);
144  | 	
145  | 		if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0) )
146  | 
147  | 			{
148  | 			/*
149  | 			 * First remove the newline character.
150  | 			 * Then replace multiple tab and space
151  | 			 * characters with single space characters.
152  | 			 */
153  | 
154  | 			/* Remove the newline character, if present. 
155  | 			 * Replace the last character of the string
156  | 			 * array with with '\0'.
157  | 			 */
158  | 
159  | 			input[strlen(input) - 1] = '\0';
160  | 
161  | 			/* Now, remove the multiple space and tab
162  | 			 * characters.
163  | 			 */
164  | 
165  | 			stringPack(line, input);
166  | 			
167  | 			g_strchomp(line); /* Remove trailing w-space. */
168  | #ifdef DEBUG
169  | puts(line);
170  | #endif	/*DEBUG */
171  | 
172  | 			tokens = g_strsplit(line, " ", 0);
173  | 
174  | #ifdef DEBUG						
175  | 			for (i = 0; tokens[i] != NULL; i++)
176  | 				printf("tokens[%d] = %s\n", i, tokens[i]);
177  | #endif	/* DEBUG */
178  | 
179  | 			/* We no longer need a variable for scope
180  | 			 * woordenboek[entry].varScope = atoi(tokens[1]);
181  | 			 */
182  | 
183  | 			strcpy(woordenboek[entry].varName, tokens[0]);
184  | 			strcpy(woordenboek[entry].varSym, tokens[1]);
185  | 			strcpy(woordenboek[entry].varType, tokens[2]);
186  | 			woordenboek[entry].varNum = entry;
187  | 			
188  |        /*
189  | 			 * Write the dictionary symbol and the entry number 
190  | 			 * to the definitions file.
191  |         */
192  | 			fprintf(defnPtr, "%s\t%d\n", tokens[1], entry);
193  | 
194  | 			++entry;
195  | 			g_strfreev( tokens ); 
196  | 			}
197  | 	/*
198  | 	 * Get the 2nd and subsequent line of the file.
199  | 	 */
200  | 
201  | 	fgets(input, sizeof(input), dictPtr);
202  | 
203  | 	while(!feof(dictPtr) )
204  | 	{
205  | 		/*
206  | 		 * Process the line if it is not a comment.
207  | 		 */
208  | 
209  | 		if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0 ) )
210  | 		{
211  | 			/*
212  | 			 * First remove the newline character.
213  | 			 * Then replace multiple tab and space
214  | 			 * characters with single space characters.
215  | 			 */
216  | 
217  | 			/* Remove the newline character, if present. 
218  | 			 * Replace the last character of the string
219  | 			 * array with with '\0'.
220  | 			 */
221  | 
222  | 			input[strlen(input) - 1] = '\0';
223  | 
224  | 			/* Now, remove the multiple space and tab
225  | 			 * characters.
226  | 			 */
227  | 
228  | 			stringPack(line, input);
229  | 			
230  | 			g_strchomp(line); /* Remove trailing w/space. */
231  | #ifdef	DEBUG
232  | puts(line);
233  | #endif	/* DEBUG */
234  | 			tokens = g_strsplit(line, " ", 0);
235  | 			
236  | #ifdef DEBUG
237  | 			for (i = 0; tokens[i] != NULL; i++)
238  | 				printf("tokens[%d] = %s\n", i, tokens[i]);
239  | #endif	/* DEBUG */
240  | 
241  | 			/*
242  | 			 * We no longer need to know the scope of a variable
243  | 			 * woordenboek[entry].varScope = atoi(tokens[1]);
244  |         */
245  | 
246  | 			strcpy(woordenboek[entry].varName, tokens[0]);
247  | 			strcpy(woordenboek[entry].varSym, tokens[1]);
248  | 			strcpy(woordenboek[entry].varType, tokens[2]);
249  | 			woordenboek[entry].varNum = entry;
250  | 			fprintf(defnPtr, "%s\t%d\n", tokens[1], entry);
251  | 			++entry;
252  | 
253  | 			g_strfreev( tokens );
254  | 		}
255  | 		fgets(input, sizeof(input), dictPtr);
256  | 	}		
257  | 
258  | fclose(dictPtr);
259  | fclose(defnPtr);
260  | 
261  | }	/* End of ca_populateDictionary() function. */
262  | 
263  | 
264  | void opSplitsen (FILE *filePtr, gchar **tokenArray)
265  | {
266  | /*
267  |  * Declaring character constants is safer than using #define.
268  |  * See Oualline's book, p.145.
269  |  *
270  |  */
271  | 
272  | const char *blankLine = "\n";		/* Declared as a string, not a character. */
273  | const char *comment = "#";			/* Declared as a string. */
274  | char line[99];
275  | char input[99];
276  | int lineNo = 0;
277  | int j;
278  | 
279  | 
280  | 	fgets(input, sizeof(input), filePtr); /* Get the (first) line from the */
281  | 					 /* file to which filePtr points. */
282  | 	
283  | #ifdef DEBUG
284  | 	printf("\nFIRST INPUT >>> %s\n", input);
285  | #endif	/* DEBUG */
286  | 
287  | 	/* Compare the first character of the input */
288  | 	/* to the comment and the newline strings. */
289  | 
290  | 	if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0) )
291  | 					
292  | 				
293  | 
294  | 		{
295  | 		/* Remove the newline character, if present. */
296  | 		/* Replace the last character */
297  | 		/* of the string array with '\0'. */
298  | 
299  | 		input[strlen(input) - 1] = '\0';	
300  | #ifdef DEBUG
301  | printf("First Input >>> %s\n", input);
302  | #endif /* DEBUG */
303  | 
304  | 		strcpy(line, input);
305  | #ifdef DEBUG
306  | printf("First Line after copy >>> %s\n", line);
307  | #endif 	/* DEBUG */
308  | 
309  | 		stringPack(line, input);     
310  | #ifdef DEBUG
311  | printf("Line: %s\n", line);
312  | #endif	/* DEBUG */
313  | 
314  | 		g_strchomp(line);
315  | /*		g_strdelimit(line, " ", ':');
316  |  *		g_strdelimit(line, "\t", '*');
317  | */
318  | 
319  | #ifdef DEBUG
320  | 		printf("%3d> %s\n", ++lineNo, line);
321  | #endif	/* DEBUG */
322  | 
323  | 		/*
324  | 		 * g_strsplit() is a GLib function;
325  | 		 * it returns an array of strings.
326  | 		 * 
327  | 		 * Here, we split on two spaces, "  ".
328  | 		 * We set max_tokenArray to be 0.  We want the 
329  | 		 * first token to be the name of the variable
330  | 		 * and the other tokens to be the value of the variable,
331  | 		 * qualifiers, etc.
332  | 		 */
333  | 
334  | 		tokenArray = g_strsplit(line, " ", 0);	
335  | 
336  | #ifdef DEBUG
337  | 		for (j = 0; tokenArray[j] != NULL; j++)
338  | 			printf("token[%d] = %s\n", j, tokenArray[j]);
339  | #endif	/* DEBUG */
340  | 
341  | 		} /* End of processing the first line, if not commented. */
342  | 
343  | 		/* End of getting the first line. */
344  | 
345  | 
346  | 	/*Get the 2nd line of the file. */
347  | 	fgets(input, sizeof(input), filePtr);
348  | 
349  | 	while(!feof(filePtr) )
350  | 		{
351  | 			
352  | 			/* Process the line if it is not commented. */
353  | 			if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0 ) )
354  | 			{
355  | 	   	/* Remove the newline character, if present. */ 
356  | 			input[strlen(input) -1] = '\0';
357  | #ifdef DEBUG
358  | printf("Subsequent Input >>> %s\n", input);
359  | #endif	/* DEBUG */
360  | 
361  | 			strcpy(line, input);
362  | #ifdef DEBUG
363  | printf("Subsequent Line after copy >>> %s\n", line);
364  | #endif	/* DEBUG */
365  | 
366  | 			stringPack(line, input);
367  | #ifdef DEBUG
368  | printf("Line: %s\n", line);
369  | #endif	/* DEBUG */
370  | 
371  | 			g_strchomp(line);
372  | /*			g_strdelimit(line, " ", ':');
373  |  *			g_strdelimit(line, "\t", '*');
374  |  */
375  | 
376  | #ifdef DEBUG
377  | 			printf("%3d> %s\n", ++lineNo, line);
378  | #endif	/* DEBUG */
379  | 
380  | 			/*
381  | 			 * See the comment above about the maximum 
382  | 			 * number of tokens being set to 0.
383  | 			 */
384  | 
385  | 			tokenArray = g_strsplit(line, " ", 0);
386  | 
387  | #ifdef DEBUG
388  | 			for (j = 0; tokenArray[j] != NULL; j++)
389  | 				{	
390  | 				printf("token[%d] = %s\n", j, tokenArray[j]);
391  | 				/* Can also use puts(tokenArray[j]) here. */
392  | 				}
393  | #endif /* DEBUG */
394  | 			} /* Processed uncommented lines. */
395  | 
396  | 		fgets(input, sizeof(input), filePtr);
397  | 		} /* Processed the 2nd & subsequent lines of the file. */
398  | 
399  | } /* End of processing the opened file. */
400  | 
401  | 
402  | void ca_readConfig(const char *configFile, values_t confVars[], int size)
403  | /*******************************************************************
404  |  *																						*
405  |  * ca_readConfig -- parses the config file and writes the values   *
406  |  * 						 into memory.												*
407  |  *																						*
408  |  * Parameters																		*
409  |  *		configFile -- the configuration file
410  | 	*		confVars[] -- the array of values structures						*
411  | 	*		size -- the number of configuration variables					*
412  |  * 																						*
413  |  * Returns																			*
414  |  *		Nothing -- perhaps make this return 0 on successful exit ?	*
415  |  *																						*
416  |  * Note: 	Should we make the name of the config file a global		*
417  | 	*			variable ?																*	
418  |  *******************************************************************/
419  | {
420  | FILE *confPtr;			/* Pointer to config file. */
421  | char name[STRLENGTH_M];		/* The name of the config variable */
422  | 										/* 80 characters */
423  | char value[STRLENGTH_XXL];			/* The value of the variable */
424  | 												/* 640 characters */
425  | int location;			/* Storage Location of the variable's value. */
426  | int type;	 /* Data type of the variable, represented by an integer. */
427  | 
428  | 
429  | const char *blankLine = "\n";  /* Declared as a string, not a character. */
430  | const char *comment = "#"; 		/* Declared as a string. */
431  | 
432  | char source[16];									/* The name of a source. */
433  | char database[STRLENGTH_M]; 		/* The elements of a database. */
434  | 												/* 80 characters */
435  | int mode;								/* The mode of operation of the src */
436  | char srcOptions[16];				/* The options of a source. */
437  | char nrtMirror[STRLENGTH_M];			/* The elements of a NRTM */
438  | int updatePort;						/* The update port of the source */
439  | 
440  | gchar **dbcomps;	/* Pointer to an array of strings that represents */
441  | 							/* the components of a db. */
442  | 
443  | gchar **nrtmcomps; /* Pointer to an array of strings that represents */
444  | 							/* the components of a nrtm. */
445  | 
446  | gchar **optcomps;	/* Pointer to an array of strings that represents */
447  | 							/* the components of the options of a source. */
448  | 
449  | int i;					/* A counting variable. */
450  | 
451  | ca_database_t *newDbPtr; 	/* A pointer to a new instance of */
452  | 										/* ca_database_t.						 */
453  | 
454  | ca_mirror_t *newMirrPtr;		/* A pointer to a new instance of */
455  | 										/* ca_mirror_t.						 */
456  | 
457  | ca_database_list_t *newSrc;	/* A pointer to a new instance of */
458  | 										/* ca_database_list_t.				 */
459  | 
460  | ca_ripadmin_t	 *newAdminPtr;	/* A pointer to a new instance of */
461  | 											/* a ca_ripadmin_t variable. 	*/
462  | 
463  | /* 
464  |  * Function Prototype for ca_getStorageLocation()
465  |  * We put it here; thus it can only be called from 
466  |  * within ca_readConfig()
467  |  *
468  |  * This function finds the location in the values_t array
469  |  * where we store pointers to the string value and the actual
470  |  * value of the variable.  It returns this location as an 
471  |  * integer.
472  |  *
473  |  */
474  | int ca_getStorageLocation(char [], dict_t [], int);
475  | 
476  | /*
477  | 	* Function Prototype for ca_getType()
478  | 	* We put it here so that it can only be called from
479  | 	* within ca_readConfig()
480  |  *
481  |  * This function returns the type of the configuration
482  |  * variable.  It returns it as a string.
483  |  *
484  |  */
485  | int ca_getType(char [], dict_t [], int);
486  | 
487  | 
488  | #ifdef	DEBUG
489  | printf("\nInside readConfig() function.\n");
490  | printf("Configuration file is: %s\n", configFile);
491  | #endif	/* DEBUG */
492  | 
493  | /*
494  | 	* Open the configuration file for reading .....
495  |  */
496  | if ( (confPtr = fopen(configFile, "r")) == NULL)
497  | 		{
498  | 		printf("Error: file %s could not be opened.\n", configFile);
499  | 		die;
500  | 		}
501  | 
502  | /*
503  | 	* Read the first record in the configuration file .....
504  |  * We read the _name_ of the variable using fscanf into a
505  |  * string array.  We read the _value_ of the variable
506  |  * using fgets into an array; thus, we can handle values of
507  |  * variables with qualifiers (e.g. SPLIT after DBLIST) and
508  |  * values with blank characters (e.g. REPLYBANNER).
509  |  */
510  | fscanf(confPtr, "%s", name);
511  | fgets(value, sizeof(value), confPtr);
512  | 
513  | 
514  | /* 
515  | 	* 		While there are records to be read in the config file.
516  | 	*		write the current record into memory,
517  |  *     read the next record in the config file
518  |  */
519  | 
520  | 
521  | while (!feof(confPtr) )
522  | 	{
523  | 
524  | /*
525  | 	* From the variable name, find the dictionary number.
526  |  * The dictionary number is defined as the place in the 
527  |  * values array in which to store the value of the variable.
528  |  * 
529  |  */
530  | 
531  | 		/*
532  | 		 * Process the line only when/if it is not a comment or 
533  | 		 * a blankline.
534  |      */
535  | 		if ( (strncmp(name, comment, 1) != 0) && (strncmp(name, blankLine, 1) != 0) )
536  | 			{
537  | 			/*
538  |  		 * If the last character of "value" is '\n',
539  |         * replace it with '\0'.
540  |         */
541  | 			if ( value[strlen(value) - 1] == '\n')
542  | 				{
543  | 				value[strlen(value) - 1] = '\0';
544  | 				}
545  | 
546  | 			/*
547  | 			 * From the variable name, find the element of the values
548  | 			 * array in which to store the value of the variable.
549  |         *
550  | 			 */
551  | 			location = ca_getStorageLocation(name, dictionary, VARS);
552  | 
553  | #ifdef DEBUG
554  | 			printf("The location is: %d\n", location);
555  | #endif	/* DEBUG */
556  | 
557  | 			/*
558  | 			 * See if the string value has already been stored;
559  | 			 * if it has, then concatenate the new value to it;
560  | 			 * if not, then allocate some memory and copy the
561  | 			 * string into it.
562  | 			 */
563  | 
564  | 			/*
565  | 			 * If this variable already exists, it has a non-zero
566  |         * value and this 'if' statement returns a "true" value.
567  | 			 * Otherwise, it returns a "zero" or "false" value.
568  | 			 */
569  | 			if (confVars[location].strPtr)
570  | 				{
571  | 				strcat(confVars[location].strPtr, "\n");
572  | 				strcat(confVars[location].strPtr, value);
573  | 				}
574  | 			else
575  | 				{
576  | 			/*
577  | 			 * Store a pointer to the string that contains the value
578  | 			 * This is not necessarily the actual value itself.
579  | 			 * First, we must allocate some memory.
580  | 			 */
581  | 			confVars[location].strPtr = (char *)malloc(STRLENGTH_XXL);
582  | 			/*
583  | 			 * We check the return value of the malloc function .....
584  |         */	
585  | 			if (confVars[location].strPtr == NULL)
586  | 				{
587  | 				fprintf(stderr, "Cannot allocate memory for confVars[location].strPtr\n");
588  | 				die;
589  | 				}
590  | 			strcpy(confVars[location].strPtr, value);
591  | 				}
592  | 
593  | 			/*
594  | 			 * Now, store a pointer to the _value_ of the variable.  
595  | 			 * Do this as follows:
596  | 			 * (a) get the _type_ of the variable
597  | 			 * (b) store a pointer to the value of the variable in 
598  | 			 *     a way that depends on the _type_ of the variable.
599  |         */
600  | #ifdef DEBUG
601  | printf("Variable \"%s\" is data-type \"%d\"\n", name, ca_getType(name, dictionary, VARS) );
602  | #endif /* DEBUG */
603  | 
604  | 
605  | type = ca_getType(name, dictionary, VARS);
606  | 
607  | 			/*
608  | 			 * Given the _type_ of the variable, store the value of the
609  |   		 * variable in the appropriate way.
610  | 			 */		 
611  | 			switch(type)	
612  | 				{
613  | 				case 11:
614  | 
615  | #ifdef DEBUG
616  | 				puts("Data type is Integer");
617  | #endif	/* DEBUG */
618  | 
619  | 				confVars[location].valPtr = malloc(sizeof(int) );
620  | 				if (confVars[location].valPtr == NULL)
621  | 					{
622  | 					fprintf(stderr, "Cannot allocate memory !!!\n");
623  | 					die;
624  | 					}
625  | 				sscanf(value, "%d", (int *) confVars[location].valPtr);
626  | 				break;
627  | 
628  | 				case 12:
629  | 
630  | #ifdef DEBUG
631  | 				puts("Data type is String !!! *** !!!");
632  | #endif	/* DEBUG */
633  | 
634  | 
635  | 				/*
636  | 				 * Test if this variable has already been created.
637  | 				 * Look for a non-zero i.e. true value.
638  | 				 *
639  | 				 * First put a '\n' character at the end of the existing 
640  |            * string.
641  | 				 * Then, concatenate the additional string.
642  | 				 */
643  | 				if (confVars[location].valPtr) 
644  | 					{
645  | #ifdef DEBUG
646  | 					printf("\n%s variable already exists\n", name);
647  | #endif /* DEBUG */
648  | 					strcat(confVars[location].valPtr, "\n");
649  | 					strcat(confVars[location].valPtr, value);
650  | 					}	
651  | 				else
652  | 					{
653  | 					/*
654  | 					 * If the variable has not already been created,
655  | 					 * then create it.
656  | 					 */
657  | #ifdef DEBUG
658  | 					printf("\n%s variable does not exist\n", name);
659  | #endif	/* DEBUG */
660  | 				
661  | 					confVars[location].valPtr = (char *)malloc(STRLENGTH_XXL);
662  | 					if (confVars[location].valPtr == NULL)
663  | 						{
664  | 						fprintf(stderr, "Cannot allocate memory !!!\n");
665  | 						die;
666  | 						}
667  | 					 strcpy(confVars[location].valPtr, value);
668  | 					}
669  | 
670  | 				break;
671  | 
672  | 				case 13:
673  | #ifdef DEBUG
674  | 				puts("Data type is Dirlist");
675  | #endif	/* DEBUG */
676  | 				confVars[location].valPtr = (char *)malloc(STRLENGTH);
677  | 				if (confVars[location].valPtr == NULL)
678  | 					{
679  | 					fprintf(stderr, "Cannot allocate memory !!!\n");
680  | 					die;
681  | 					}
682  | 				 strcpy(confVars[location].valPtr, value);
683  | 				break;
684  | 
685  | 				case 14:
686  | #ifdef DEBUG
687  | 				puts("Data type is Boolean");
688  | #endif	/* DEBUG */
689  | 				confVars[location].valPtr = (char *)malloc(2);
690  | 				if (confVars[location].valPtr == NULL)
691  | 					{
692  | 					fprintf(stderr, "Cannot allocate memory !!!\n");
693  | 					die;
694  | 					}
695  | 				 strcpy(confVars[location].valPtr, value);
696  | 				break;
697  | 
698  | 				case 15:
699  | #ifdef DEBUG
700  | 				puts("Data type is Source !!!");
701  | #endif	/* DEBUG */
702  | 
703  | #ifdef DEBUG
704  | puts(name);
705  | puts(value);
706  | #endif	/* DEBUG */
707  | 				/*
708  | 				 * Split the value into "source" and "database"
709  |            * Use blankspace as the delimiter between the
710  | 				 * "source" and "database".
711  | 				 */
712  | 				sscanf(value, "%s %s %d %s %d %s", source, database, &mode, nrtMirror, &updatePort, srcOptions);
713  | #ifdef DEBUG
714  | puts(source);
715  | puts(database);
716  | printf("%d\n", mode);
717  | puts(nrtMirror);
718  | printf("%d\n", updatePort);
719  | puts(srcOptions);
720  | #endif	/* DEBUG */
721  | 
722  | 				/*
723  | 				 * Using the values in "database".
724  | 				 * populate a ca_database_t structure.
725  | 				 * Give this variable a name.
726  | 				 *
727  | 				 */
728  | 
729  | 	          	/* First, separate the values in "database", using "," as 
730  | 					 * as a delimiting  character.
731  | 					 */
732  | 				dbcomps = g_strsplit(database, ",", 0);
733  | 
734  | #ifdef DEBUG                                            
735  | for (i = 0; dbcomps[i] != NULL; i++)
736  | 		printf("dbcomps[%d] = %s\n", i, dbcomps[i]);
737  | #endif  /* DEBUG */
738  | 
739  | 
740  | 					/*
741  | 					 * Create a structure for this database.
742  | 					 */
743  | 				newDbPtr = calloc(1,sizeof(ca_database_t));
744  | 				if (newDbPtr == NULL)
745  | 					{
746  | 					fprintf(stderr, "Cannot allocate memory to new db structure\n");
747  | 					die;
748  | 					}
749  | 
750  | 				strcpy(newDbPtr->host, dbcomps[0]);
751  | 				newDbPtr->port = atoi(dbcomps[1]);
752  | 				strcpy(newDbPtr->user, dbcomps[2]);
753  | 				strcpy(newDbPtr->password, dbcomps[3]);
754  | 				strcpy(newDbPtr->dbName, dbcomps[4]);
755  | 				
756  | 				g_strfreev(dbcomps);
757  | #ifdef DEBUG
758  | puts("Testing the population of the db structure:");
759  | printf("\n%s::%d::%s::%s::%s\n", newDbPtr->host, newDbPtr->port, newDbPtr->user, newDbPtr->password,  newDbPtr->dbName);
760  | #endif /* DEBUG */
761  |  
762  | 
763  | 
764  | 				/*
765  | 				 * The mode of operation of the source has already been 
766  | 				 * set in the sscanf statement above.
767  | 				 */
768  | 
769  | 				/*
770  | 				 * Using the values in "nrtMirror".
771  | 				 * populate a ca_mrrror_t structure.
772  | 				 * Give this variable a name.
773  | 				 *
774  | 				 */
775  | 
776  | 	          	/* First, separate the values in "nrtMirror", using "," as 
777  | 					 * as a delimiting  character.
778  | 					 */
779  | 				nrtmcomps = g_strsplit(nrtMirror, ",", 0);
780  | 
781  | #ifdef DEBUG                                            
782  | for (i = 0; nrtmcomps[i] != NULL; i++)
783  | 		printf("nrtmcomps[%d] = %s\n", i, nrtmcomps[i]);
784  | #endif  /* DEBUG */
785  | 
786  | 
787  | 					/*
788  | 					 * Create a structure for this near-real-time mirror.
789  | 					 */
790  | 				newMirrPtr = calloc(1,sizeof(ca_mirror_t));
791  | 				if (newMirrPtr == NULL)
792  | 					{
793  | 					fprintf(stderr, "Cannot allocate memory to new nrtm structure\n");
794  | 					die;
795  | 					}
796  | 
797  | 				strcpy(newMirrPtr->host, nrtmcomps[0]);
798  | 				newMirrPtr->port = atoi(nrtmcomps[1]);
799  | 				strcpy(newMirrPtr->log, nrtmcomps[2]);
800  | 				newMirrPtr->delay = atoi(nrtmcomps[3]);
801  | 				newMirrPtr->protocolVer = atoi(nrtmcomps[4]);
802  | #ifdef DEBUG
803  | puts("Testing the population of the nrtm structure:");
804  | printf("\n%s::%d::%s::%d::%d\n", newMirrPtr->host, newMirrPtr->port, newMirrPtr->log, newMirrPtr->delay, newMirrPtr->protocolVer);
805  | #endif /* DEBUG */
806  | 
807  |                                 g_strfreev(nrtmcomps);
808  | 				/*
809  | 				 * The update port was already set by the sscanf 
810  | 				 * statement above.
811  | 				 */
812  | 
813  | 				/*
814  | 				 * Using the values in "srcOptions"
815  | 				 * get the values for the canupd and deflook 
816  | 				 * components od the ca_dbSource_t structure.
817  | 				 *
818  | 				 */
819  | 
820  | 	          	/* First, separate the values in "srcOptions", using "," 
821  | 					 * as a delimiting  character.
822  | 					 */
823  | 				optcomps = g_strsplit(srcOptions, ",", 0);
824  | 
825  | #ifdef DEBUG                                            
826  | for (i = 0; optcomps[i] != NULL; i++)
827  | 		printf("optcomps[%d] = %s\n", i, optcomps[i]);
828  | #endif  /* DEBUG */
829  | 
830  | 
831  | 				/*
832  | 				 * Using the above ca_database_t structure
833  | 				 * and the "source" value, 
834  | 				 * populate the ca_dbSource_t structure.
835  | 				 */
836  | 			
837  | 					/*
838  | 					 * Create a new structure for this source.
839  | 					 */
840  | 				newSrc = calloc(1,sizeof(ca_dbSource_t));
841  | 
842  | 				if (newSrc == NULL)
843  | 					{
844  | 					fprintf(stderr, "Cannot allocate memory to new source structure\n");
845  | 					die;
846  | 					}
847  | 
848  | 				strcpy(newSrc->name, source);
849  | 				newSrc->db = *newDbPtr;
850  | 				newSrc->opMode = mode;
851  | 				newSrc->nrtm = *newMirrPtr;
852  | 				newSrc->updPort = updatePort;
853  | 				strcpy(newSrc->canupd, optcomps[0]);
854  | 				strcpy(newSrc->deflook, optcomps[1]);
855  | 
856  | 				free(newMirrPtr); /* was copied */
857  | 				free(newDbPtr); /* was copied */
858  | 				g_strfreev(optcomps);
859  | 
860  | #ifdef DEBUG
861  | puts("Testing the population of the ca_dbSource_t structure:");
862  | printf("Source name: %s\n", newSrc->name);
863  | printf("\nDB == %s::%d::%s::%s::%s\n", (newSrc->db).host, (newSrc->db).port, (newSrc->db).user, (newSrc->db).password, (newSrc->db).dbName);
864  | printf("Mode: %d\n", newSrc->opMode);
865  | printf("NRTM == %s::%d::%s::%d:%d\n", (newSrc->nrtm).host, (newSrc->nrtm).port, (newSrc->nrtm).log, (newSrc->nrtm).delay, (newSrc->nrtm).protocolVer);
866  | printf("UpdPort: %d\n", newSrc->updPort);
867  | printf("Src Options == %s::%s\n", newSrc->canupd, newSrc->deflook);
868  | #endif /* DEBUG */
869  | 
870  | 				/*
871  | 				 * Append this ca_src_t structure to the sourceList,
872  | 				 * which is a singly-linked list if type GSList.
873  | 				 */
874  | 
875  | sourceList = g_slist_append(sourceList, newSrc);
876  | 
877  | /*
878  |  * 20000609
879  | 	* Experiment:
880  | 	* Add the newSrc to the other variable describing the list of sources,
881  |  * mySrcList
882  |  * 
883  |  * mySrcList = g_slist_append(mySrcList, newSrc);
884  |  */
885  | 
886  | 				break;
887  | 
888  | 				case 16:
889  | #ifdef DEBUG
890  | puts("Found the CA_ADMIN stuff !!!");
891  | #endif	/* DEBUG */
892  | 				/* The elements of the Admin-DB have already been read in. */
893  | 				/* Now, split up the elements and assign them to the */
894  |  			/* components of the Admin-DB structure. */
895  | 				/* First, separate the values in "value", using ',' as a */
896  | 				/* delimiting character.	*/
897  | 				dbcomps = g_strsplit(value, ",", 0);
898  | 
899  | #ifdef DEBUG				
900  | for (i = 0; dbcomps[i] != NULL; i++)
901  |                 printf("dbcomps[%d] = %s\n", i, dbcomps[i]);
902  | #endif  /* DEBUG */
903  | 
904  | 				/*
905  | 				 * Now, allocate some memory to the newAdminPtr.
906  | 				 */
907  | 			   newAdminPtr = calloc(1, sizeof(ca_ripadmin_t) );
908  | 
909  | 				/*
910  | 				 * Check that we actually got the memory.
911  | 				 */
912  | 				if (newAdminPtr ==NULL)
913  | 					{	
914  | 					fprintf(stderr, "Cannot allocate memory to new admin-db structure\n");
915  | 					die;
916  | 					}
917  | 					
918  | 				/*
919  | 				 * Now, assign the elements of the dbcomps array to the 
920  | 				 * appropriate components of the structure to which 
921  | 				 * newAdminPtr points.
922  | 				 */
923  | 				
924  | 				strcpy(newAdminPtr->host, dbcomps[0]);
925  | 				newAdminPtr->port = atoi(dbcomps[1]);
926  | 				strcpy(newAdminPtr->user, dbcomps[2]);
927  | 				strcpy(newAdminPtr->password, dbcomps[3]);
928  | 				strcpy(newAdminPtr->tableName, dbcomps[4]);
929  | 
930  | 				g_strfreev(dbcomps);
931  | 
932  | #ifdef DEBUG
933  | puts("Testing the population of the rip-admin db structure:");
934  | printf("\n%s::%d::%s::%s::%s\n", newAdminPtr->host, newAdminPtr->port, newAdminPtr->user, newAdminPtr->password, newAdminPtr->tableName);
935  | #endif /* DEBUG */
936  | 
937  | 				/*
938  | 				 * Now, assign these values into the correct long-term
939  | 				 * storage.
940  | 				 */
941  | 
942  | 
943  | 				confVars[location].valPtr = (ca_ripadmin_t *)calloc(1, sizeof(ca_ripadmin_t) );
944  | 
945  | 
946  | 				/*
947  | 				 * Check that we actually got the memory.
948  | 				 */
949  | 				if (confVars[location].valPtr == NULL)
950  | 					{	
951  | 					fprintf(stderr, "Cannot allocate memory to new admin-db structure\n");
952  | 					die;
953  | 					}
954  | 				
955  | 				memcpy(confVars[location].valPtr, newAdminPtr, sizeof(ca_ripadmin_t));
956  | 				/*
957  | 				strcpy( ((ca_ripadmin_t *)confVars[location].valPtr)->host, newAdminPtr->host);
958  | 				(confVars[location].valPtr)->port = newAdminPtr->port; 
959  | 			 	strcpy( (confVars[location].valPtr)->user, newAdminPtr->user);
960  | 			 	strcpy( (confVars[location].valPtr)->password, newAdminPtr->password);
961  | 			 	strcpy( (confVars[location].valPtr)->tableName, newAdminPtr->tableName);
962  | 				*/
963  | 			
964  |           free(newAdminPtr);
965  | #ifdef DEBUG
966  | 				printf("The ripadmin machine is: %s\n", ((ca_ripadmin_t *)confVars[location].valPtr)->host);
967  | #endif	/* DEBUG */
968  | 
969  | 				break;
970  | 
971  | 				default:
972  | 				fprintf(stderr, "Data type not found for variable \"%s\".\n", name);
973  | 				die;
974  | 				break;
975  | 				}
976  | 	 		}
977  | 
978  | fscanf(confPtr, "%s", name);
979  | fgets(value, sizeof(value), confPtr);
980  | 
981  | 	}	/* End of processing the config file. */
982  | 
983  | }	/* End of readConfig() function */
984  | 
985  | 
986  | /*
987  |  * void ca_populateDictionary(dictionary_t woordenboek[], int size, FILE *fiPtr)
988  |  * {
989  |  * int j;
990  |  * char input[99];
991  |  * 
992  |  * for (j=0; (j < size) && !feof(fiPtr); j++)
993  |  * 	j = 0;
994  |  * 	while ((j < size) && !feof(fiPtr) )
995  |  * 	{
996  |  * 	printf("\n%d\n", j);
997  |  * 	
998  |  * 	fgets(input, sizeof(input), filePtr);
999  |  * 
1000 |  * 	if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) 
1001 |  * != 0) )
1002 |  * 	{
1003 |  * 	fscanf(fiPtr, "%s %s %s %s", woordenboek[j].varName, woordenboek[j].varScope, woordenboek[j].varSym, woordenboek[j].varType);
1004 |  * 	}
1005 |  * 
1006 |  * 	fgets(input, sizeof(input), filePtr);
1007 |  * 	printf("%s\n", woordenboek[j].varName);
1008 |  * 	}
1009 |  * }
1010 |  * 
1011 |  */
1012 | 
1013 | 
1014 | void ca_getDictionary(dict_t woordenboek[], int size)
1015 | {
1016 | int k;
1017 | 
1018 | for (k = 0; k <= size; k++)
1019 | 	{
1020 | 	printf("\nj = %d\n", k);
1021 |  /*
1022 | 	 * printf("%s\t%d\t%s\n", woordenboek[k].varName, woordenboek[k].varScope, woordenboek[k].varType);
1023 | 	 */
1024 | 	 printf("%s\t%s\t%s\t%d\n", woordenboek[k].varName, woordenboek[k].varSym, woordenboek[k].varType, woordenboek[k].varNum);
1025 | 
1026 | 	}
1027 | }
1028 | 
1029 | 
1030 | int ca_get_int(int symbol)
1031 | {
1032 | int *xPtr;
1033 | 
1034 | 		/*
1035 | 		 * First print a message saying that the ca_get_int()
1036 | 		 * function is being called.
1037 | 		 */
1038 | #ifdef DEBUG
1039 | 	printf("\nDEBUG: ca_get_int() function is called .....\n");
1040 | printf("DEBUG: New value of StringPtr: %s\n", confVars[symbol].strPtr);
1041 | #endif 	/* DEBUG */
1042 | 
1043 | 		/*
1044 | 		 * Look at the appropriate place in the dictionary;
1045 | 		 * e.g. C_BINDPORT => the first element, index = 0.
1046 | 		 *
1047 | 		 * if the varType is not an integer, exit with an error;
1048 | 		 *
1049 | 		 * otherwise, 
1050 | 		 *		if the varScope is global, look for the value in the
1051 | 		 *		appropriate place in memory in the global values array;
1052 | 		 *    otherwise, look for the value in the appropriate place in 
1053 | 		 * 	memory in the local values array;
1054 | 		 *
1055 | 		 *
1056 | 		 */
1057 | 
1058 | 		/* Look at the appropriate place in the dictionary. */
1059 | 
1060 | #ifdef DEBUG
1061 | 		printf("\nDEBUG: Variable type: %s\n", dictionary[symbol].varType);
1062 | #endif	/* DEBUG */
1063 | 
1064 | 		/* If the variable type is not an integer, exit with an error. */
1065 | 		if ( strcmp(dictionary[symbol].varType, "CA_INT") != 0)
1066 | 			{
1067 | 			fprintf(stderr, "Error: unexpected variable type.\n");
1068 | 			die;
1069 | 			}
1070 | 		else
1071 | 			{
1072 | 			/*
1073 | 			 * If the variable has global scope, look for it in 
1074 | 			 * the globals array.  Otherwise, look for it in the
1075 | 			 * locals array.
1076 | 			 *
1077 | 			 */
1078 | 			
1079 | 
1080 | /*
1081 |  *				switch(dictionary[symbol].varScope)
1082 |  *					{
1083 |  *					case 1:
1084 |  *					printf("\nThis variable has global scope.\n");
1085 |  *					printf("The string is: %s\n", globals[symbol].strPtr);
1086 |  *					printf("String2Value: %d\n", atoi(globals[symbol].strPtr));
1087 |  *
1088 |  *					xPtr = globals[symbol].valPtr;
1089 |  *					printf("Value: %d\n", *xPtr);
1090 |  *					return(*xPtr);
1091 |  *					break;
1092 |  *
1093 |  *					case 99:
1094 |  *					printf("\nThis variable has local scope.\n");
1095 |  *					printf("The string is %s\n", locals[symbol].strPtr);
1096 |  *					printf("String2Value: %d\n", atoi(locals[symbol].strPtr));
1097 |  *					xPtr = locals[symbol].valPtr;
1098 |  *					printf("Value: %d\n", *xPtr);
1099 |  *					return(*xPtr);
1100 |  *					break;
1101 |  *
1102 |  *					default:
1103 |  *					printf("\nAaaargh !!!  This variable has unwelcome scope.\n");			
1104 |  *					break;
1105 |  *					}
1106 |  */
1107 | 
1108 | 			/*
1109 | 			 * Lock the value of the variable before reading it.
1110 | 		 	 */
1111 | 
1112 | 			mutex_lock(&Lock);
1113 | 
1114 | 			xPtr = confVars[symbol].valPtr;
1115 | 			/* 
1116 | 			 * Unlock the value of the variable after reading it.
1117 | 			 */
1118 | 			mutex_unlock(&Lock);
1119 | 			return(*xPtr);
1120 | 			}
1121 | 	
1122 | }
1123 | 
1124 | char *ca_get_dirlist(int symbol)
1125 | {
1126 | /*
1127 |  * This function returns a pointer to a character array.  Thus,
1128 |  * we need to declare such a pointer.
1129 |  *
1130 |  */
1131 | 
1132 | char *xPtr;
1133 | #ifdef	DEBUG
1134 | 	printf("\nca_get_dirlist() function is called .....\n");
1135 | #endif	/* DEBUG */
1136 | 
1137 | 
1138 | 		/*
1139 | 		 * Look at the appropriate place in the dictionary;
1140 | 		 * e.g. CA_HELP => the second element, index = 1.
1141 | 		 *
1142 | 		 * if the varType is not CA_DIRLIST, exit with an error;
1143 | 		 *
1144 | 		 * otherwise, 
1145 | 		 *		if the varScope is global, look for the value in the
1146 | 		 *		appropriate place in memory in the global values array;
1147 | 		 *    otherwise, look for the value in the appropriate place in 
1148 | 		 * 	memory in the local values array;
1149 | 		 *
1150 | 		 *
1151 | 		 */
1152 | 
1153 | 		/* Look at the appropriate place in the dictionary. */
1154 | 		#ifdef DEBUG	
1155 | 		printf("\nVariable type: %s\n", dictionary[symbol].varType);
1156 | 		#endif	/* DEBUG */	
1157 | 
1158 | 		/* If the variable type is not CA_DIRLIST, exit with an error. */
1159 | 		if ( strcmp(dictionary[symbol].varType, "CA_DIRLIST") != 0)
1160 | 			{
1161 | 			fprintf(stderr, "Error: unexpected variable type.\n");
1162 | 			die;
1163 | 			}
1164 | 		else
1165 | 			{
1166 | 			/*
1167 | 			 * If the variable has global scope, look for it in 
1168 | 			 * the globals array.  Otherwise, look for it in the
1169 | 			 * locals array.
1170 | 			 *
1171 | 			 */
1172 | 
1173 | /*
1174 | 	* This next piece of code (switch statements, etc.) is not
1175 |  * needed.  We do not have global or local variables anymore.
1176 |  */			
1177 | 
1178 | /*
1179 |  * 				switch(dictionary[symbol].varScope)
1180 |  * 					{
1181 |  * 					case 1:
1182 |  * 					printf("\nThis variable has global scope.\n");
1183 |  * 					printf("The string is: %s\n", globals[symbol].strPtr);
1184 |  * 					xPtr = strdup(globals[symbol].valPtr);
1185 |  * 					printf("Value: %s\n", xPtr);
1186 |  * 					return(xPtr);
1187 |  * 					break;
1188 |  * 
1189 |  * 					case 99:
1190 |  * 				
1191 |  * 					printf("\nThis variable has local scope.\n");
1192 |  * 					printf("The string is %s\n", locals[symbol].strPtr);
1193 |  * 					xPtr = locals[symbol].valPtr;
1194 |  * 					printf("Value: %s\n", xPtr);
1195 |  * 					return(xPtr);
1196 |  * 					break;
1197 |  * 
1198 |  * 					default:
1199 |  * 					printf("\nAaaargh !!!  This variable has unwelcome scope.\n");			
1200 |  * 					break;
1201 |  * 					}
1202 |  */
1203 |  
1204 | 				mutex_lock(&Lock);
1205 | 				xPtr = (strdup(confVars[symbol].valPtr));
1206 | 				#ifdef DEBUG
1207 | 				printf("Value: %s\n", xPtr);
1208 | 				#endif	/* DEBUG */
1209 | 				mutex_unlock(&Lock);	
1210 | 				return(xPtr);
1211 | 			}
1212 | 	
1213 | }
1214 | 
1215 | 
1216 | char *ca_get_string(int symbol)
1217 | {
1218 | /*
1219 |  * This function returns a pointer to a character array.  Thus,
1220 |  * we need to declare such a pointer.
1221 |  *
1222 |  */
1223 | 
1224 | char *xPtr;
1225 | #ifdef	DEBUG
1226 | 	printf("\nca_get_text() function is called .....\n");
1227 | #endif	/* DEBUG */
1228 | 
1229 | 
1230 | 		/*
1231 | 		 * Look at the appropriate place in the dictionary;
1232 | 		 * e.g. CA_REPLYBANNER => the third element, index = 2.
1233 | 		 *
1234 | 		 * if the varType is not CA_STRING, exit with an error;
1235 | 		 *
1236 | 		 * otherwise, 
1237 | 		 *		if the varScope is global, look for the value in the
1238 | 		 *		appropriate place in memory in the global values array;
1239 | 		 *    otherwise, look for the value in the appropriate place in 
1240 | 		 * 	memory in the local values array;
1241 | 		 *
1242 | 		 *
1243 | 		 */
1244 | 
1245 | 		/* Look at the appropriate place in the dictionary. */
1246 | 		
1247 | #ifdef DEBUG
1248 | 		printf("\nVariable type: %s\n", dictionary[symbol].varType);
1249 | #endif	/* DEBUG */
1250 | 	
1251 | 		/* If the variable type is not CA_STRING, exit with an error. */
1252 | 		if ( strcmp(dictionary[symbol].varType, "CA_STRING") != 0)
1253 | 			{
1254 | 			fprintf(stderr, "Error: unexpected variable type.\n");
1255 | 			die;
1256 | 			}
1257 | 		else
1258 | 			{
1259 | 			/*
1260 | 			 * If the variable has global scope, look for it in 
1261 | 			 * the globals array.  Otherwise, look for it in the
1262 | 			 * locals array.
1263 | 			 *
1264 | 			 */
1265 | 
1266 | /*
1267 |  * We do not need this code any longer.  We do not use
1268 |  * global or local variables or the associated arrays,
1269 |  * 'globals' and 'locals'.
1270 |  *
1271 |  *				switch(dictionary[symbol].varScope)
1272 |  *					{
1273 |  *					case 1:
1274 |  *					printf("\nThis variable has global scope.\n");
1275 |  *					printf("The string is: %s\n", globals[symbol].strPtr);
1276 |  *					xPtr = globals[symbol].valPtr;
1277 |  *					printf("Value: %s\n", xPtr);
1278 |  *					return(xPtr);
1279 |  *					break;
1280 |  *
1281 |  *					case 99:
1282 |  *					printf("\nThis variable has local scope.\n");
1283 |  *					printf("The string is %s\n", locals[symbol].strPtr);
1284 |  *					xPtr = locals[symbol].valPtr;
1285 |  *					printf("Value: %s\n", xPtr);
1286 |  *					return(xPtr);
1287 |  *					break;
1288 |  *
1289 |  *					default:
1290 |  *					printf("\nAaaargh !!!  This variable has unwelcome scope.\n");			
1291 |  *					break;
1292 |  *				}
1293 |  */
1294 | 				mutex_lock(&Lock);
1295 | 				xPtr = (strdup(confVars[symbol].valPtr));
1296 | 				#ifdef DEBUG
1297 | 				printf("Value: %s\n", xPtr);
1298 | 				#endif	/* DEBUG */
1299 | 				mutex_unlock(&Lock);
1300 | 				return(xPtr);
1301 | 			
1302 | 			}
1303 | }
1304 | 
1305 | 
1306 | int ca_get_boolean(int symbol)
1307 | {
1308 | /**********************************************
1309 |  * ca_get_boolean()									*
1310 | 	* 															*
1311 | 	*															*
1312 | 	* Parameters											*
1313 | 	*															*
1314 | 	*	symbol -- the symbol for the variable		*
1315 |  *															*
1316 | 	*															*
1317 | 	* Returns												*
1318 | 	*															*
1319 | 	*	1 if true, 0 if false.							*
1320 |  *															*
1321 |  * Remarks												*
1322 | 	*															*
1323 |  *   Is there a better way to implement 		*
1324 | 	*   Boolean values in C ?							*
1325 |  *															*
1326 | 	*********************************************/
1327 | 
1328 | int *xPtr;
1329 | 
1330 | /*
1331 |  * Print this message if in debug mode.
1332 |  *
1333 |  */
1334 | #ifdef DEBUG
1335 | 	printf("\nca_get_boolean() function is called .....\n");
1336 | printf("DEBUG 5: New value of StringPtr: %s\n", globals[symbol].strPtr);
1337 | #endif	/* DEBUG	*/
1338 | 
1339 | /**********************************************\
1340 |  *															*
1341 | 	* Here is how this works:							*
1342 |  * 															*
1343 |  * (a) Check that the type of variable whose 	*
1344 |  *     value is being read is CA_BOOLEAN.		*
1345 |  *															*
1346 |  * (b) Lock the value of the variable before	*
1347 |  * 		reading it.										*
1348 |  *															*
1349 |  * (c) Depending on the scope of the variable	*
1350 |  *     look for it in the appropriate array.	*
1351 |  *															*
1352 | 	* (d) Read the value of the variable.			*
1353 |  *															*
1354 | 	* (e) Unlock the value of the variable after *
1355 |  *		reading it.										*
1356 | 	*															*
1357 |  *															*
1358 |  * Returns												*
1359 | 	*
1360 | 	*	an integer value as follows:					*
1361 | 	*		1 if the db is in testmode (true),							*
1362 | 	*		0 if the db is not in testmode (false).					*
1363 | \*********************************************/
1364 | 
1365 | 
1366 | /*
1367 | 	* Look at the appropriate place in the dictionary; 
1368 | 	* e.g. CA_BOOLEAN = the fifth element of the dict_t array,
1369 |  * => index = 4.
1370 |  *
1371 |  * If the varType is not Boolean, exit with an error
1372 | 	* 
1373 |  * Otherwise,
1374 | 	*	if the varScope is global, look for the value in the
1375 | 	* 	appropriate place in the global values array;
1376 | 	*
1377 | 	*	otherwise, look for the value in the appropriate place in the
1378 | 	*	locals array.
1379 | 	*
1380 |  */
1381 | 
1382 | #ifdef DEBUG
1383 | /* Look in the appropriate place in the dictionary. */
1384 | printf("\nVariable type: %s\n", dictionary[symbol].varType);
1385 | #endif	/* DEBUG */
1386 | 
1387 | /* If the variable type is not Boolean, exit with an error. */
1388 | 
1389 | 	if ( strcmp(dictionary[symbol].varType, "CA_BOOLEAN") != 0)
1390 | 		{
1391 | 		fprintf(stderr, "Error: Boolean type expected.\n");
1392 | 		die;
1393 | 		}
1394 | 
1395 | 	else
1396 | 		{
1397 | 		
1398 | 		/*
1399 | 		 * If the variable has global scope, look for it in the globals
1400 | 		 * array.  Otherwise, look for it in the locals array.
1401 | 		 *
1402 |      */
1403 | /* 
1404 |  * We do not need this code (switch statements, etc.) anymore.
1405 |  */
1406 | 
1407 | /*
1408 |  *		switch(dictionary[symbol].varScope)
1409 |  *			{
1410 |  *			case 1:
1411 |  *			printf("\nThis variable has global scope.\n");
1412 |  *			printf("The string is: %s\n", globals[symbol].strPtr);
1413 |  *			printf("String2Value: %d\n", atoi(globals[symbol].strPtr) );
1414 |  *			xPtr = globals[symbol].valPtr;
1415 |  *			printf("Value: %d\n", *xPtr);
1416 |  *			return (*xPtr);
1417 |  *			break;
1418 |  *
1419 |  *			case 99:
1420 |  *			printf("\nThis variable has local scope.\n");
1421 |  *			printf("The string is %s\n", locals[symbol].strPtr);
1422 |  *			printf("String2Value: %d\n", atoi(locals[symbol].strPtr) );
1423 |  *			xPtr = locals[symbol].valPtr;
1424 |  *			printf("Value: %d\n", *xPtr);
1425 |  *			return(*xPtr);
1426 |  *			break;
1427 |  *
1428 |  *			default:
1429 |  *			printf("\nError: This variable has unknown scope.\n");
1430 |  *			break;
1431 |  *
1432 |  *			}
1433 |  */
1434 | 
1435 | 		/*
1436 | 		 * Lock the value of the variable before reading it.
1437 | 		 *
1438 | 		 */
1439 | 		
1440 | 		mutex_lock(&Lock);
1441 | 		xPtr = confVars[symbol].valPtr;
1442 | 		/*
1443 | 		 * Unlock the value of the variable after reading it.
1444 | 		 */
1445 | 		mutex_unlock(&Lock);
1446 | 		
1447 | 		return(*xPtr);
1448 | 	}	
1449 | }
1450 | 
1451 | 
1452 | 
1453 | void ca_set_int(int symbol)
1454 | {
1455 | 	/*********************************************
1456 | 	 * ca_set_int()										*
1457 |   *  														*
1458 | 	 * Parameters											*
1459 | 	 *		symbol -- the symbol for the variable.	*
1460 | 	 *															*
1461 | 	 * Returns												*
1462 | 	 *		1 if successful 0 if not ?					*
1463 | 	 *															*
1464 | 	 * Remarks												*
1465 | 	 * 	Needs a better way to check for valid  *
1466 |   *    values from the keyboard.					*
1467 | 	 *															*
1468 | 	 *********************************************/
1469 | 
1470 | 	void *tempPtr;		/* Temp pointer to point to the value pointer
1471 | 								in the appropriate values array. */
1472 |  char newPort[16];
1473 |  int invalid;
1474 |  int portNr;
1475 | 
1476 |  /* Function to change the value in a given values array.
1477 |   * This function can only be called from within ca_set_int().
1478 | 	 */
1479 |  int *ca_change_int_value(char []); 
1480 |  void testFunction(values_t values[]);
1481 | 
1482 | 	/*
1483 |   * Using the symbol, look at the appropriate place in the
1484 | 	 * dictionary.
1485 | 	 */
1486 | #ifdef DEBUG
1487 |  printf("\nca_set_int() function called .....\n");
1488 | 	printf("Variable type: %s\n", dictionary[symbol].varType);
1489 | #endif	/* DEBUG */
1490 | 
1491 | 
1492 | /*
1493 |  * Make sure that a reasonable, sensible value of bind-port has
1494 |  * been read from the keyboard.
1495 |  */
1496 | 
1497 | do	{
1498 | 
1499 | 		/*
1500 | 		 * First, flush input stream.
1501 |      */
1502 | 		fflush(stdin);
1503 | 
1504 | 		/*
1505 | 		 * Prompt for the new value of the bind-port.
1506 | 		 */
1507 | 		
1508 | 		printf("\nNew value of bind-port (non-zero positive integer) >>> ");
1509 | 		scanf("%s", newPort);
1510 | 		/*
1511 | 		 * gets(newPort);                                  
1512 | 		 */
1513 | #ifdef DEBUG
1514 | 		printf("\nDEBUG: Value of newPort variable: %s\n", newPort);
1515 | #endif	/* DEBUG */
1516 | 
1517 | 		sscanf(newPort, "%d", &portNr);
1518 | 
1519 | #ifdef DEBUG
1520 | 		printf("\nDEBUG: Value of integer variable, portNr: %d\n", portNr);
1521 | #endif	/* DEBUG */
1522 | 		
1523 | 			if (portNr < 0)
1524 | 				{
1525 | 				invalid = 1;
1526 | 				puts("Only non-zero positive integer values accepted for bind-port");
1527 | 				}
1528 | 			else
1529 | 				{
1530 | 				invalid = 0;
1531 | 				}
1532 | 
1533 | 		} while(invalid);
1534 | 
1535 |  /*
1536 | 	 * Check that the function is attempting to set the correct type
1537 | 	 * of value.  If not, do not set the value and exit.
1538 | 	 */
1539 | 
1540 | 	if (strcmp(dictionary[symbol].varType, "CA_INT") != 0)
1541 | 		{
1542 | 		fprintf(stderr, "Error: unexpected variable type.\n");
1543 | 		die;
1544 | 		}
1545 | 
1546 | 	/*
1547 | 	 * Choose the appropriate values array.  
1548 | 	 */
1549 | 	switch(dictionary[symbol].varScope)
1550 | 		{
1551 | 		/* If the variable has global scope, 
1552 | 		 * write it into the globals array.
1553 | 		 * If it has local scope,
1554 | 		 * write it into the local array.
1555 | 		 * If the scope cannot be found, then report an error.
1556 | 		 */
1557 | 		case 1:
1558 | 		globals[symbol].valPtr = ca_change_int_value(newPort);
1559 | 		globals[symbol].strPtr = newPort;
1560 | 		
1561 | 		globals[symbol].strPtr = (char *)calloc(1,sizeof(newPort) );
1562 | 		
1563 | 		/* Check the return value of malloc() to make sure that we 
1564 | 		 * actually got the memory.
1565 | 		 */
1566 | 		if (globals[symbol].strPtr == NULL)
1567 | 			{	
1568 | 			fprintf(stderr, "Cannot allocate memory for globals[symbol].strPtr.\n");
1569 | 			die;
1570 | 			}
1571 | #ifdef DEBUG
1572 | 		printf("DEBUG: New value of StringPtr: %s\n", globals[symbol].strPtr);
1573 | #endif	/* DEBUG */
1574 | 
1575 | 		strcpy(globals[symbol].strPtr, newPort);
1576 | 
1577 | #ifdef DEBUG
1578 | 		printf("DEBUG 2: New value of StringPtr: %s\n", globals[symbol].strPtr);
1579 | #endif	/* DEBUG */
1580 | 		break;
1581 | 
1582 | 		case 99:
1583 | 		locals[symbol].valPtr = ca_change_int_value(newPort);
1584 | 		/*
1585 | 		 * First allocate some memory and then copy the value of the new 
1586 | 		 * Port into it.
1587 |      */
1588 | 		locals[symbol].strPtr = (char *)calloc(1,sizeof(newPort) );
1589 | 		/* 
1590 | 		 * Now, check that the memory was actually allocated.
1591 | 		 */
1592 | 		if (locals[symbol].strPtr == NULL)
1593 | 			{
1594 | 			fprintf(stderr, "Cannot allocate memory for locals[symbol].strPtr\n");
1595 | 			exit(8);
1596 | 			}
1597 | 		
1598 | 		strcpy(locals[symbol].strPtr, newPort);
1599 | 		/*
1600 | 		 * locals[symbol].strPtr = newPort;
1601 | 		 */	
1602 | 		break;
1603 | 
1604 | 		default:
1605 | 		fprintf(stderr, "Error; unknown scope: %d\n", dictionary[symbol].varScope);
1606 | 		break;
1607 | 		}
1608 | 
1609 |  /*
1610 |   * Write the new value of the variable to the correct place in 
1611 |   * this array.  (First, set a mutex lock ???).
1612 | 	 */
1613 | 
1614 |  /*
1615 | 	 * Write the new value of this variable back to the config. file
1616 | 	 */
1617 | 
1618 | ca_writeNewValue(symbol, newPort);
1619 | 
1620 | 		printf("DEBUG 3: New value of StringPtr: %s\n", globals[symbol].strPtr);
1621 | 
1622 | }
1623 | 
1624 | int *ca_change_int_value(char value[])
1625 | {
1626 | void *tempPtr;
1627 | 
1628 | /*
1629 |  * Check the return value of malloc() in case we did not actually get
1630 |  * the memory.
1631 |  */
1632 | tempPtr = malloc(sizeof(int) );
1633 | if (tempPtr == NULL)
1634 | 		{
1635 | 		fprintf(stderr, "Cannot allocate memory for tempPtr\n");
1636 | 		die;
1637 | 		}
1638 | 
1639 | sscanf(value, "%d", (int *) tempPtr);
1640 | return(tempPtr);
1641 | }
1642 | 
1643 | 
1644 | 
1645 | void testFunction(values_t array[])
1646 | {
1647 | 	printf("\nInside the Test function.\n");
1648 | 	}
1649 | 
1650 | 
1651 | void ca_getDatabase(ca_database_t db)
1652 | {
1653 | printf("\n%s\t%s\t%s\t%s\t%s\n", db.host, db.port, db.user, db.password, db.dbName);
1654 | }
1655 | 
1656 | void ca_getSource(ca_database_list_t src)
1657 | {
1658 | printf("\n%s\t%s\t%s\t%s\t%s\t%s\n", src.name, (src.db).host, (src.db).port, (src.db).user, (src.db).password, (src.db).dbName);
1659 | }
1660 | 
1661 | 
1662 | void ca_getAllSources(GSList *sources)
1663 | {
1664 | 	 
1665 | GSList *currentPtr;	/* Pointer to the structure at which we look. */
1666 | 
1667 | /*
1668 |  * Look at the first member of the linked-list of sources.
1669 |  */
1670 | currentPtr = sources;
1671 | 
1672 | /*
1673 |  * Look at each data component of the source list,
1674 |  * untill we reach the end of the list.
1675 |  */
1676 | while(currentPtr != NULL)
1677 | 	{
1678 |  ca_database_list_t *srcPtr = currentPtr->data;
1679 | printf("\n%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\n", srcPtr->name, (srcPtr->db).host, (srcPtr->db).port, (srcPtr->db).user, (srcPtr->db).password, (srcPtr->db).dbName);
1680 |  currentPtr = currentPtr->next;	
1681 | 	}
1682 | }
1683 | 
1684 | void ca_getAsource(char *sourceName, GSList *sources)
1685 | /*******************************************************************
1686 |  * ca_getAsource -- looks for a source in the linked list				*
1687 |  *																						*
1688 |  * Parameters																		*
1689 | 	*	sourceName -- the name of a source for which to look 				*
1690 | 	*  sources -- the list of sources in which to look						*
1691 |  *																						*
1692 |  * Returns																			*
1693 |  *  nothing, so far.																*
1694 |  *																						*
1695 |  *******************************************************************/
1696 | {
1697 | 	 
1698 | GSList *currentPtr = sources; 
1699 | 
1700 | #ifdef DEBUG
1701 | printf("\nLooking for source: %s\n", sourceName);
1702 | #endif	/* DEBUG */
1703 | 
1704 | /*
1705 |  * Look at each data component of the source list,
1706 | 	* compare the name of the source with the sourceName
1707 |  * untill we find the source o we reach the end of the list 
1708 |  */
1709 | {	/* Begin special block 
1710 | 		 * I got a syntax error when I defined 
1711 | 		 * "ca_database_list_t *srcPtr = currentPtr->data;"
1712 | 		 * in the usual way, with all the other local variables.
1713 | 		 *
1714 |      * However, if I define it inside this block, I do not
1715 | 		 * get any syntax errors.
1716 | 	    *
1717 |  	 */
1718 | 		
1719 | 
1720 | ca_database_list_t *srcPtr = currentPtr->data;
1721 | #ifdef DEBUG
1722 | printf("FirstSource is: %s\n", srcPtr->name);
1723 | #endif	/* DEBUG */
1724 | while( (currentPtr != NULL) && ( strcmp(srcPtr->name, sourceName) != 0 ) )
1725 | 	{
1726 | #ifdef DEBUG
1727 |  puts("Now printing the current source .....");
1728 |  printf("CurrentSource is: %s\n", srcPtr->name);
1729 |  printf("%d\n", strcmp(srcPtr->name, sourceName) );
1730 |  if ( strcmp(srcPtr->name, sourceName) == 0 ) 
1731 | 		{
1732 | 		printf("Found it !!! Source: %s\n", srcPtr->name);
1733 | 		}
1734 | #endif	/* DEBUG */
1735 |  currentPtr = currentPtr->next;	
1736 | 	puts("currentPtr = currentPtr->next");
1737 | 	if (currentPtr != NULL)
1738 | 	{
1739 |  	srcPtr = currentPtr->data;
1740 |  	puts("srcPtr = currentPtr->data");
1741 |  }
1742 |  #ifdef DEBUG
1743 | 		puts("At the end of the while loop inside ca_getAsource function .....");
1744 |  	printf("The NewSource is: %s\n", srcPtr->name);
1745 |  #endif	/* DEBUG */
1746 | 	}
1747 | #ifdef DEBUG
1748 | puts("Exited from while loop in ca_getAsource function .....");
1749 | #endif /* DEBUG */
1750 | 
1751 | if (currentPtr != NULL)
1752 | 	{
1753 |  printf("\nFound the source: %s\n", srcPtr->name); 
1754 | /* printf("\n%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", srcPtr->name, (srcPtr->db).host, (srcPtr->db).port, (srcPtr->db).user, (srcPtr->db).password, (srcPtr->db).canupd, (srcPtr->db).deflook, (srcPtr->db).dbName);
1755 | */
1756 |  }
1757 | else
1758 | 	{
1759 | 	printf("\nCould not find source: %s\n", sourceName);
1760 | 	}
1761 | }	/* End special block */
1762 | 
1763 | }
1764 | 
1765 | 
1766 | ca_dbSource_t *ca_getSourceDetails(char *sourceName, GSList *sources)
1767 | /*******************************************************************
1768 |  * ca_getSourceDetails															*
1769 |  * 	-- A function that compares each 'name' component of every 		*
1770 |  *		ca_database_list_t element in the linked-list of sources		*
1771 | 	*		(the first element of which is a parameter of this function)*
1772 |  *		with the name of the source to be found.  If the required	*
1773 | 	*		source is found, a pointer to the structure representing 	*
1774 |  * 		this source is returned.												*
1775 | 	*																						*
1776 | 	*	Parameters																		*
1777 | 	*	--	sourceName - the name of the required source						*
1778 | 	*	--	sources	- the list of sources in which to look					*
1779 | 	*																						*
1780 |  * 	Returns																			*
1781 | 	*	-- srcPtr - a pointer to the structure representing the source	*
1782 | 	*            - or a pointer to NULL, if we cannot find the source *
1783 |  *																						*
1784 |  *******************************************************************/
1785 | {
1786 | /* 
1787 | 	* Define a pointer to the current element in the linked list.
1788 |  * Initialise it to the start of the list;
1789 |  */
1790 | GSList *currentPtr = sources; 	
1791 | 
1792 | 	/*
1793 | 		* Define and initialise a pointer that points to the 'data'
1794 | 	 * component of the GSList struct; i.e. a pointer to a 
1795 | 	 * variable of type ca_dbSource_t.
1796 | 	 */
1797 | ca_dbSource_t *srcPtr = currentPtr->data;								 
1798 | 	
1799 | 	
1800 | 	/*
1801 | 		* Look at each data component of list of sources;
1802 | 		* (each data component is a structure of type ca_dbSource_t
1803 | 		* i.e. ca_database_list_t).  Compare the 'name' component of
1804 | 	 * of each ca_dbSource_t structure with the value of sourceName 
1805 | 	 * untill we get a match or we reach the end of the list.
1806 | 		*/
1807 | 	/*
1808 | 	 * We first check if currentPtr is pointing to NULL;
1809 | 	 *		if yes, we exit the while loop;
1810 | 	 * 	if no, we make srcPtr point to the data component
1811 | 	 *    of the current dbSource structure;
1812 | 	 *			then, we check if this is the source name that we want;
1813 | 	 *			if yes, we _break_ from the while loop.
1814 |  */
1815 | 	while (currentPtr != NULL)
1816 | 		{
1817 | 	  	srcPtr = currentPtr->data;
1818 |  	if (strcmp(srcPtr->name, sourceName) == 0 ) 
1819 | 			break;
1820 | 		currentPtr = currentPtr->next;
1821 | 		}
1822 | 	
1823 | 	/*
1824 | 		* We return a pointer.  If we found the source, this pointer points
1825 | 	 * to the ca_dbSource_t structure which represents the source.
1826 | 	 * If we did not find the source, we return a pointer to NULL.
1827 | 	 */
1828 | 	if (currentPtr == NULL)
1829 | 		{	
1830 | 		srcPtr = NULL;
1831 | 		return(srcPtr);
1832 | 		}
1833 |  else
1834 | 		{
1835 | 		return(srcPtr);
1836 | 		}
1837 | 	
1838 | }	/* End of ca_getSourceDetails function */
1839 |  
1840 | 
1841 | ca_SrcHdl_t *ca_get_SourceHandleByPosition(int position)
1842 | /*******************************************************************
1843 |  * ca_get_SourceHandleByPosition												*
1844 |  *	-- retrieves the a handle to a Source									*
1845 |  *																						*
1846 |  * Parameters																		*
1847 |  *	-- the position in the linked list of sources						*
1848 |  *																						*
1849 |  *																						*
1850 | 	* Returns																			*
1851 | 	*	-- a pointer to the source or NULL										*
1852 |  *		i.e. a pointer to the data component of the appropriate		*
1853 |  *		element in the linked list of sources.								*
1854 |  *******************************************************************/
1855 | {
1856 | ca_dbSource_t * mySource;
1857 | 
1858 | mySource = g_slist_nth_data(sourceList, position);
1859 | return(mySource);
1860 | }
1861 | 
1862 | ca_SrcHdl_t *ca_get_SourceHandleByName(char *srcName)
1863 | /*******************************************************************
1864 |  * ca_get_SourceHandleByName													*
1865 |  *	-- retrieves the a handle to a source									*
1866 |  *																						*
1867 |  * Parameters																		*
1868 |  *	-- the name of the required source
1869 |  *																						*
1870 |  *																						*
1871 | 	* Returns																			*
1872 | 	*	-- a pointer to the source or NULL										*
1873 |  *		i.e. a pointer to the data component of the appropriate		*
1874 |  *		element in the linked list of sources.								*
1875 |  *******************************************************************/
1876 | 
1877 | {
1878 | ca_dbSource_t * mySource;
1879 | 
1880 | mySource = ca_getSourceDetails(srcName, sourceList);
1881 | return(mySource);
1882 | }
1883 | 
1884 | char *ca_srchandle2Strelement(ca_SrcHdl_t *ah, int srcAttrib)
1885 | /*******************************************************************
1886 | 	* ca_srchandle2Strelement															*
1887 | 	*	-- returns a string which represents the attribute of a source *
1888 | 	*		e.g. returns the name of a source									*
1889 | 	*		It allocates the required memory;									*
1890 | 	*		but it returns NULL if the required memory cannot be 			*
1891 | 	*		allocated.
1892 |  *																						*
1893 | 	* Parameters								 										*
1894 | 	*	--  source name - the name of the source
1895 | 	*		 ca_get_SourceHandleByName or ca_get_SourceHandleByPosition *
1896 | 	*																						*
1897 | 	*	-- srcAttrib - an integer which represents the required 			*
1898 | 	*		attribute of the source.  We use #define statments to make	*
1899 | 	*		a mapping between the attributes and the integers.				*
1900 |  *																						*
1901 | 	* Returns																			*
1902 | 	* -- a string or NULL															*
1903 |  *******************************************************************/
1904 | {
1905 | char *myStr;
1906 | void ca_malloc(char *, int);
1907 | 
1908 | if(ah == NULL)
1909 | 		{
1910 | 		fprintf(stderr, "ca_srchandle2Strelement(): Cannot dereference NULL pointer\n");
1911 | 		die;
1912 | 		}
1913 | 
1914 | switch(srcAttrib)
1915 | 		{
1916 | 		case 0:
1917 | 		/* source name */
1918 | 		myStr = strdup(ah->name);
1919 | 		break;
1920 | 
1921 | 		case 1:
1922 | 		/* canupd */
1923 | 		myStr =  strdup(ah->canupd);
1924 | 		break;
1925 | 
1926 | 		case 2:
1927 | 		/* deflook */
1928 | 		/*
1929 | 		 * ca_malloc(myStr, 2);
1930 | 		 * strcpy(myStr, (ah->db).deflook);
1931 | 		 */
1932 | 		myStr = strdup(ah->deflook);
1933 | 		break;
1934 | 
1935 | 		case 3:
1936 | 		/* machine */
1937 | 		myStr = strdup((ah->db).host);
1938 | 		break;
1939 | 
1940 | 		case 5:
1941 | 		/* user */
1942 | 		myStr = strdup((ah->db).user);
1943 | 		break;
1944 | 
1945 | 		case 6:
1946 | 		/* password */
1947 | 		myStr = strdup((ah->db).password);
1948 | 		break;
1949 | 
1950 | 		case 7:
1951 | 		/* dbName */
1952 | 		myStr = strdup((ah->db).dbName);
1953 | 		break;
1954 | 
1955 | 		case 9:
1956 | 		/* Near-Real-Time Mirror host */
1957 | 		myStr = strdup((ah->nrtm).host);
1958 | 		break;
1959 | 
1960 | 		case 11:
1961 | 		/* NRTM Log */
1962 | 		myStr = strdup((ah->nrtm).log);
1963 | 		break;
1964 | 
1965 | 		default:
1966 | 		puts("Cannot find this source attribute");
1967 | 		break;
1968 | 		}
1969 | 
1970 | return(myStr);
1971 | }
1972 | 
1973 | int ca_srchandle2Intelement(ca_SrcHdl_t *ah, int srcAttrib)
1974 | /*******************************************************************
1975 | 	* ca_srchandle2Intelement														*
1976 |  * 	-- a function that returns the integer value of the requested	*
1977 |  *     attribute of the given source.										*
1978 |  *																						*
1979 |  * Parameters																		*
1980 | 	*	--  source name - the name of the source
1981 | 	*		 ca_get_SourceHandleByName or ca_get_SourceHandleByPosition *
1982 | 	*																						*
1983 | 	*	-- srcAttrib - an integer which represents the required 			*
1984 | 	*		attribute of the source.  We use #define statments to make	*
1985 | 	*		a mapping between the attributes and the integers.				*
1986 |  *																						*
1987 |  * Returns																			*
1988 | 	*  -- an integer.
1989 | 	*******************************************************************/
1990 | {
1991 | int myInt;	/* The value of this integer is returned. */
1992 | 
1993 | if(ah == NULL)
1994 | 		{
1995 | 		fprintf(stderr, "ca_srchandle2Intelement(): Cannot dereference NULL pointer\n");
1996 | 		die;
1997 | 		}
1998 | 
1999 | 	switch(srcAttrib)
2000 | 		{
2001 | 		
2002 | 		case 4:
2003 | 		/* DB Port */
2004 | 		myInt = (ah->db).port;
2005 | 		break;
2006 | 
2007 | 		case 8:
2008 | 		/* Mode of Operation of the Source. */
2009 | 		myInt = ah->opMode;
2010 | 		break;
2011 | 
2012 | 		case 10:
2013 | 		/* Near-Real-Time Mirror port */
2014 | 		myInt = (ah->nrtm).port;
2015 | 		break;
2016 | 
2017 | 		case 12:
2018 | 		/* NRTM Delay */
2019 | 		myInt = (ah->nrtm).delay;
2020 | 		break;
2021 | 
2022 | 		case 13:
2023 | 		/* NRTM Protocol Version. */
2024 | 		myInt = (ah->nrtm).protocolVer;
2025 | 		break;
2026 | 
2027 | 		case 14:
2028 | 		/* Source Update Port */
2029 | 		myInt = ah->updPort;
2030 | 		break;
2031 | 
2032 | 		default:
2033 | 		fprintf(stderr, "Could not find source-attribute %d\n", srcAttrib);
2034 | 		die;
2035 |     break;  
2036 | 		}
2037 | 
2038 | return (myInt);
2039 | }
2040 | 
2041 | 
2042 | char *ca_get_adminStrElement(int symbol, int adminAttrib)
2043 | /*******************************************************************
2044 | 	* ca_adminStrElement
2045 | 	*	-- returns a string which represents the attribute of a admin  *
2046 |  *     db
2047 | 	*		e.g. returns the name of a host machine.						   *
2048 | 	*		It allocates the required memory;									*
2049 | 	*		but it returns NULL if the required memory cannot be 			*
2050 | 	*		allocated.
2051 |  *																						*
2052 | 	* Parameters								 										*
2053 | 	*  -- symbol - the symbol of the variable
2054 | 	*																						*
2055 | 	*	-- adminAttrib - an integer which represents the required 			*
2056 | 	*		attribute of the Admin db.  We use #define statements to 	*
2057 | 	*		make a mapping between the attributes and the integers.		*
2058 |  *																						*
2059 | 	* Returns																			*
2060 | 	* -- a string or NULL															*
2061 |  *******************************************************************/
2062 | {
2063 | char *myStr;
2064 | void ca_malloc(char *, int);
2065 | 
2066 | /*
2067 | 	* Make sure that we are calling the correct function.
2068 |  */
2069 | if ( strcmp(dictionary[symbol].varType, "CA_ADMIN") != 0)
2070 | 		{
2071 | 		fprintf(stderr, "Error: unexpected variable type.\n");
2072 | 		die;
2073 | 		}
2074 | else
2075 | 		{
2076 |  mutex_lock(&Lock);
2077 |  switch(adminAttrib)
2078 | 		{
2079 | 		case 0:
2080 | 		/* admin host */
2081 | 		myStr = strdup( ((ca_ripadmin_t *)confVars[symbol].valPtr)->host);
2082 | 		break;
2083 | 
2084 | 		case 2:
2085 | 		/* User */
2086 | 		myStr =  strdup( ((ca_ripadmin_t *)confVars[symbol].valPtr)->user);
2087 | 		break;
2088 | 
2089 | 		case 3:
2090 | 		/* password */
2091 | 		myStr = strdup( ((ca_ripadmin_t *)confVars[symbol].valPtr)->password);
2092 | 		break;
2093 | 
2094 | 		case 4:
2095 | 		/* tableName */
2096 | 		myStr = strdup( ((ca_ripadmin_t *)confVars[symbol].valPtr)->tableName);
2097 | 		break;
2098 | 
2099 | 		default:
2100 | 		puts("Cannot find this admin attribute");
2101 | 		die;
2102 | 		break;
2103 | 		}
2104 |  mutex_unlock(&Lock);
2105 | 
2106 |  return(myStr);
2107 |  }
2108 | }
2109 | 
2110 | int ca_get_adminIntElement(int symbol, int adminAttrib)
2111 | /*
2112 | 	* Returns an int element of the admin db structure.
2113 |  */
2114 | {
2115 | int myInt;	/* The value of this integer is returned. */
2116 |  
2117 | mutex_lock(&Lock);
2118 | switch(adminAttrib)
2119 | 	{
2120 | 	case 1:
2121 | 	/* Port number */
2122 | 	myInt = ((ca_ripadmin_t *)confVars[symbol].valPtr)->port;
2123 | 	break;
2124 | 
2125 |  default:
2126 | 	puts("Cannot find this admin attribute");
2127 | 	die;
2128 | 	break;
2129 | 	}
2130 | mutex_unlock(&Lock);
2131 | 
2132 | return(myInt);
2133 | }
2134 | 
2135 | void ca_malloc(char *someStr, int memSize)
2136 | /*******************************************************************
2137 | 	* ca_malloc																			*
2138 | 	*	-- a function that allocates memory for a string					*
2139 | 	*																						*
2140 |  * Parameters																		*
2141 | 	* --someStr	- the string that is to be created							*
2142 | 	*	 memSize- required amount of memory in bytes							*
2143 | 	*																						*
2144 | 	* Returns																			*
2145 | 	* -- nothing; it assigns the allocated memory to the pointer 		*
2146 |  *   that was passed to it.														*
2147 | 	*																						*
2148 | 	*******************************************************************/
2149 | {
2150 | 	someStr = malloc(memSize);
2151 | 	
2152 | 	/*
2153 | 	 * Check that we actually did get the memory ....
2154 |   */
2155 | 	if (someStr == NULL)
2156 | 		{
2157 | 		fprintf(stderr, "ca_malloc(): cannot allocate memory !!!\n");
2158 | 		exit(8);
2159 | 		}
2160 | }
2161 | 
2162 | void ca_set_boolean(int symbol)
2163 | {
2164 | /*************************************************************
2165 |  *																				*
2166 |  * ca_set_boolean()														*
2167 |  * 																				*
2168 | 	*																				*
2169 |  * Parameters																*
2170 |  *																				*
2171 | 	* 	symbol -- the symbol for the variable.							*
2172 |  *																				*
2173 | 	*																				*
2174 | 	* Returns																	*
2175 | 	*																				*
2176 | 	* 		nothing																*
2177 |  *																				*
2178 | 	*																				*
2179 |  * Remarks																	*
2180 | 	*																				*
2181 | 	* 	Must check that a sensible value is given as input.		*
2182 | 	*																				*
2183 | 	*																				*
2184 | 	*************************************************************/
2185 | 
2186 | 
2187 | char newTestmodeStr[2];
2188 | int newTestmodeVal;	/* The new value of the testmode variable. */
2189 | int invalid;				/* Flag to indicate an invalid new value.  */
2190 | 
2191 | FILE *testPtr, *tempPtr;			/* The pointer to the files. */
2192 | char name[STRLENGTH];				/* The name of the variable. */
2193 | char value[STRLENGTH];			/* The value of the variable. */
2194 | 
2195 | /*
2196 |  * Function to change the value in a given values array.
2197 |  * This function can only be called from within ca_set_boolean().
2198 |  */
2199 | int *ca_change_int_value(char []);
2200 | 
2201 | 
2202 | /*
2203 | 	* Using the symbol, look at the appropriate place in the 
2204 |  * dictionary.
2205 | 	*/
2206 | #ifdef DEBUG
2207 | printf("\nca_set_int() function called .....\n");
2208 | printf("Variable type: %s\n", dictionary[symbol].varType);
2209 | #endif		/* DEBUG */
2210 | 
2211 | /*
2212 |  * Check that the function is attempting to set the correct type of 
2213 |  * value.  If not, do not set the value, but exit instead.
2214 |  */
2215 | 
2216 | if (strcmp(dictionary[symbol].varType, "CA_BOOLEAN") != 0)
2217 | 		{
2218 | 		fprintf(stderr, "Error: CA_BOOLEAN data type expected.\n");
2219 | 		die;
2220 | 		}
2221 | 
2222 | /*
2223 |  * First, flush the input stream.
2224 |  */
2225 | fflush(stdin);
2226 | 
2227 | 
2228 | /*
2229 |  * Make sure that a reasonable, sensible value of bind-port has
2230 |  * been read from the keyboard.
2231 |  */
2232 | 
2233 | do	{
2234 | 			/*
2235 | 			 * Prompt for the new value of the testmode.
2236 | 			 */
2237 | 
2238 | 			printf("\nNew value of testmode (0 or 1) >>> ");
2239 | 			scanf("%s", newTestmodeStr);
2240 | 
2241 | 			/*
2242 | 			 * We scanf() the value as a string, but we want it to be an
2243 | 			 * integer.  Thus, we use sscanf() to scanf the value from the
2244 |     	 * string-variable and store it as an integer in an integer
2245 | 			 * variable.
2246 | 			 */ 
2247 | 			sscanf(newTestmodeStr, "%d", &newTestmodeVal);
2248 | 
2249 | 			/*
2250 |         * We only change the testmode when the user is absolutely sure
2251 | 			 * that they want to change.  Thus, we only accept two possible
2252 | 			 * values for testmode.
2253 | 			 */
2254 | 
2255 | 			if ( (newTestmodeVal < 0) || (newTestmodeVal > 1) )
2256 | 				{
2257 | 				invalid = 1;
2258 | 				puts("Only '0' or '1' accepted as value for testmode.");
2259 | 				}
2260 | 			else
2261 | 				{
2262 | 				invalid = 0;
2263 | 				}	
2264 | 		} while(invalid);
2265 | 	
2266 | 
2267 | /*
2268 | 	* Lock the value of the variable before changing it.
2269 |  */
2270 | 
2271 | mutex_lock(&Lock);
2272 | 
2273 | 
2274 | /*
2275 |  * Choose the appropriate values array.
2276 |  */
2277 | 
2278 | switch(dictionary[symbol].varScope)
2279 | 		{
2280 | 		/*
2281 | 		 * If the variable has global scope, 
2282 | 		 * write it into the globals array.
2283 | 		 * If it has local scope, 
2284 | 		 * write it into the local array.
2285 | 		 * If the scope cannot be found, then report an error.
2286 |      */
2287 | 		case 1:
2288 | 		globals[symbol].valPtr = ca_change_int_value(newTestmodeStr);
2289 | 		globals[symbol].strPtr = newTestmodeStr;
2290 | 		break;
2291 | 
2292 | 		case 99:
2293 | 		locals[symbol].valPtr = ca_change_int_value(newTestmodeStr);
2294 | 		locals[symbol].strPtr = newTestmodeStr;
2295 | 		break;
2296 | 
2297 | 		default:
2298 | 		fprintf(stderr, "Error: unknown scope: %d\n", dictionary[symbol].varScope);
2299 | 		break;
2300 | 		}
2301 | 
2302 | /*
2303 | 	* Write the new value of this variable back to the config file.
2304 |  *
2305 |  * To be implemented.
2306 |  */
2307 | 
2308 | /*
2309 |  * Find the actual name of the variable from the dictionary
2310 |  * structure (use the variable symbol as an index into the
2311 |  * array of dictionary structures.
2312 |  */
2313 |  
2314 | 	printf("Name of variable to be changed: %s\n", dictionary[symbol].varName);
2315 | 	printf("Type of variable to be changed: %s\n", dictionary[symbol].varType);
2316 | 
2317 | /*
2318 | 	* Open the test config file for reading .....
2319 |  */
2320 | if ( (testPtr = fopen(testFile, "r")) == NULL)
2321 | 	{
2322 | 	printf("File \"%s\" could not be opened.\n", testFile);
2323 | 	die;
2324 | 	}
2325 | 
2326 | /*
2327 | 	* Open the temporary file for writing .....
2328 |  */
2329 | if ((tempPtr = fopen(tempFile, "w")) == NULL)
2330 | 	{
2331 | 	printf("File \"%s\" could not be opened.\n", tempFile);
2332 |  die;
2333 |  }
2334 | 
2335 | /*
2336 |  * Read the first record in the test config file.
2337 |  */
2338 |  
2339 |  fscanf(testPtr, "%s", name);
2340 |  fgets(value, sizeof(value), testPtr);
2341 |  
2342 |  /*
2343 |   * If the last character of "value" is '\n',
2344 |   * replace it with '\0'.
2345 |   */
2346 | 	if (value[strlen(value) - 1] == '\n')
2347 | 		{
2348 | 		printf("The value string is %s", value);
2349 | 		printf("Replacing last character of \"%s\" with the NULL character\n", name);
2350 | 		value[strlen(value) - 1] = '\0';
2351 | 		printf("The new value string is %s", value);
2352 | 		}
2353 | 
2354 | 
2355 | /*
2356 | 	* While there are records to be read in the test config file:
2357 | 	* 		Write the current record into the temporary file.
2358 |  * 		Read the next record in the config file.
2359 |  * Repeat untill the EOF has been reached.
2360 |  */
2361 | 	
2362 | while(!feof(testPtr) )
2363 | 	{
2364 |  fprintf(tempPtr, "%s %s\n", name, value);
2365 |  fscanf(testPtr, "%s", name);
2366 | 	fgets(value, sizeof(value), testPtr);
2367 | 
2368 |  /*
2369 |   * If the last character of "value" is '\n',
2370 |   * replace it with '\0'.
2371 |   */
2372 | 	if (value[strlen(value) - 1] == '\n')
2373 | 		{
2374 | 		printf("The last character of the value string is %c", value[strlen(value) - 1]);
2375 | 		printf("The value string is %s", value);
2376 | 		printf("Replacing last character of \"%s\" with the NULL character\n",name);
2377 | 		value[strlen(value) - 1] = '\0';
2378 | 		printf("The new value string is %s", value);
2379 | 		}
2380 | 
2381 |  
2382 |  /*
2383 |   * if we read the variable that we want to change,
2384 |   * stop reading this file and print only the name
2385 |   * of this variable to the temporary file.
2386 |   */
2387 | 
2388 | 	/*
2389 | 	 * If we read the variable that we want to change,
2390 |   * replace the value of this variable in the config
2391 |   * file with the value supplied from the keyboard.
2392 |   *
2393 |   */
2394 | 	if ( strcmp(name, dictionary[symbol].varName) == 0)
2395 | 		{
2396 | 		strcpy(value, newTestmodeStr);
2397 | 		printf("The replacement string is %s", value);
2398 | 		}
2399 | 	/*
2400 | 	 * Flush the pointer to the test config file.
2401 | 	 */
2402 | 	fflush(testPtr);
2403 | 
2404 | 	}				
2405 |  /* 
2406 | 	 * Here ends the loop that writes the config file, with the
2407 |   * new variable, to the temporary file.
2408 | 	 */
2409 | 
2410 | /*
2411 |  *
2412 |  * While !(the record to be updated)
2413 | 	*	BEGIN
2414 | 	*  Write the record to the temporary file
2415 |  *  Read the next record in the config file
2416 |  *	END
2417 |  *
2418 |  * Write the new value to the temporary file
2419 |  * Read the next record in the config file
2420 |  * COMMENT: this is the record to be updated.
2421 |  * COMMENT: discard this record.
2422 |  * 
2423 |  * Read the next record in the config file
2424 | 	*
2425 |  * While !(EOF)
2426 | 	*	BEGIN
2427 | 	*  write the record to the temporary file
2428 |  *  read the next record in the config file
2429 |  *  END
2430 |  *
2431 |  * Close Config file
2432 |  * Close Temporary file
2433 |  *
2434 |  * Open Temporary file for reading
2435 |  * Open Config file for writing
2436 |  *
2437 |  * Read the next record of the Temporary file
2438 |  *
2439 |  * While (!EOF of Temporary file)
2440 | 	*	BEGIN
2441 | 	*  write the record into the Config file
2442 | 	*  read the next record of the Temporary file
2443 |  *  END
2444 |  * 
2445 | 	*	Close Temporary file
2446 |  *  Close Config file
2447 |  *
2448 |  */
2449 | 
2450 | fclose(testPtr);
2451 | fclose(tempPtr);
2452 | 
2453 | /*
2454 | 	* Now, flush the file pointers
2455 |  */
2456 | 	fflush(testPtr);
2457 | 	fflush(tempPtr);
2458 | 
2459 | /*
2460 |  * Open the temporary file for reading.
2461 | 	* Open the config file for writing.
2462 |  * Write the contents of the temporary file
2463 |  * into the config file.
2464 |  */
2465 | 
2466 | /*
2467 | 	* Open the temporary file for reading .....
2468 |  */
2469 | if ((tempPtr = fopen(tempFile, "r")) == NULL)
2470 | 	{
2471 | 	printf("File \"%s\" could not be opened for reading.\n", tempFile);
2472 |  die;
2473 |  }
2474 | 
2475 | /*
2476 | 	* Open the config file for writing .....
2477 |  */
2478 | if ((testPtr = fopen(testFile, "w")) == NULL)
2479 | 	{
2480 | 	printf("File \"%s\" could not be opened for writing.\n", testFile);
2481 |  die;
2482 |  }
2483 | 
2484 | /*
2485 |  * Read the first record in the temporary file.
2486 |  */
2487 |  
2488 |  fscanf(tempPtr, "%s", name);
2489 |  fgets(value, sizeof(value), tempPtr);
2490 | 	printf("\nFIRST LINE: %s %s", name, value);
2491 |  
2492 |  
2493 | /*
2494 | 	* While there are records to be read in the temporary file:
2495 | 	* 		Write the current record into the test config file.
2496 |  * 		Read the next record in the temporary file.
2497 |  * Repeat untill the EOF has been reached.
2498 |  */
2499 | 	
2500 | while(!feof(tempPtr) )
2501 | 	{
2502 |  fprintf(testPtr, "%s %s", name, value);
2503 |  fscanf(tempPtr, "%s", name);
2504 | 	fgets(value, sizeof(value), tempPtr);
2505 |  }
2506 | 
2507 | fclose(testPtr);
2508 | fclose(tempPtr);
2509 | 
2510 | /*
2511 | 	* Unlock the value of the variable after setting it and writing the
2512 |  * new value back to the configuration (and the dictionary) file.
2513 | 	*
2514 |  */
2515 | 	mutex_unlock(&Lock);
2516 | 
2517 | }
2518 | 
2519 | 
2520 | void ca_set_dirlist(int symbol)
2521 | {
2522 | /****************************************************************
2523 | 	* ca_set_dirlist()															*
2524 |  *																					*
2525 |  * Parameters																  	*
2526 | 	*		symbol -- the symbol of the variable.							*
2527 |  *																					*
2528 |  * Returns																		*
2529 | 	*		1 if successful, 0 if not successful.							*
2530 | 	*																					*
2531 | 	* Remarks																		*
2532 |  *		Writing the new value back to the config file has yet to *
2533 | 	*		be implemented.														*
2534 |  *																					*
2535 | 	****************************************************************/
2536 | 
2537 |  char newDir[80];
2538 |  /*
2539 |   * Declare a pointer to a values_t variable.
2540 | 	 * Later, we shall assign this pointer to the first element
2541 |   * of either the globals or the locals array, as appropriate.
2542 |   */
2543 |  values_t *hereValues;
2544 | 
2545 | 	/*
2546 | 	 * Using the symbol, look in the appropriate place in the dictionary.
2547 | 	 */
2548 | #ifdef DEBUG
2549 | 	printf("\nca_set_dirlist() function called ..... \n");
2550 |  printf("Variable type: %s\n", dictionary[symbol].varType);
2551 | #endif
2552 | 
2553 | 	/*
2554 | 	 * First, flush the input stream.
2555 | 	 */
2556 | 	fflush(stdin);
2557 | 
2558 | 	/* 
2559 | 	 * Prompt for the new value of the directory.
2560 | 	 */
2561 | 	printf("\nNew value of %s [80 characters, maximum] >>> ", dictionary[symbol].varName);
2562 |  scanf("%s", newDir);
2563 | 	
2564 | /*
2565 |  * Make sure that a reasonable, sensible value of the directory 
2566 |  * value has been read from the keyboard.
2567 |  *
2568 |  * How do we implement this ???
2569 |  *
2570 |  */
2571 | 
2572 | 
2573 |  /*
2574 |   * Make sure that the function is attempting to set the correct type
2575 |   * of value.  If not, do not set the value - and exit.
2576 |   */
2577 | 
2578 | if (strcmp(dictionary[symbol].varType, "CA_DIRLIST") != 0)
2579 | 		{
2580 | 		fprintf(stderr, "Error: unexpected variable type.\n");
2581 | 		exit(51);
2582 | 		}	
2583 | 
2584 | 	/*
2585 |   * Choose the appropriate values array.
2586 | 	 * Assign a temporary pointer to this array.
2587 | 	 */
2588 | 
2589 | 	switch(dictionary[symbol].varScope)
2590 | 		{
2591 | 		/* If the variable has global scope,
2592 | 		 * write it into the globals array.
2593 | 		 * If it has local scope, 
2594 | 		 * write it into the locals array.
2595 |  	 * If the scope cannot be found, report an error.
2596 | 		 */
2597 | 		case 1:
2598 | 		hereValues = globals;
2599 | 		break;
2600 | 
2601 | 		case 99:
2602 | 		hereValues = locals;
2603 | 		break;
2604 | 
2605 | 		default:
2606 | 		fprintf(stderr, "Error: Unknown scope: %d\n", dictionary[symbol].varScope);
2607 | 		break;
2608 | 		}
2609 | 
2610 | 
2611 | 	/*
2612 |   * Check for the presence of the mutex lock:
2613 | 	 *		if present,
2614 | 	 * 		wait until it is available;
2615 | 	 *		else
2616 |   *			get the lock and proceed with the change of value.
2617 | 	 */
2618 | 	
2619 | 	/*
2620 |   * Write the new value of the variable to the correct place
2621 | 	 * in the [appropriate] values array.
2622 | 	 *
2623 |   * Note that there is a check to see if malloc() actually worked .....
2624 | 	 */
2625 | 
2626 | 		hereValues[symbol].valPtr = (char *)malloc(80);
2627 | 		if (hereValues[symbol].valPtr == NULL)
2628 | 			{
2629 | 			fprintf(stderr, "Cannot alllocate memory for hereValuesvlPtr\n");
2630 | 			die;
2631 | 			}
2632 | 		strcpy(hereValues[symbol].valPtr,newDir); 
2633 | 
2634 | 
2635 | 		hereValues[symbol].strPtr = (char *)malloc(sizeof(newDir) );
2636 | 		if (hereValues[symbol].strPtr == NULL)
2637 | 			{
2638 | 			fprintf(stderr, "Cannot alllocate memory for hereValuestPtr\n");
2639 | 			die;
2640 | 			}
2641 | 		strcpy(hereValues[symbol].strPtr, newDir);
2642 | 
2643 | 	/*
2644 | 	 * Free the temporary pointer, hereValues.
2645 |   *
2646 |   */
2647 | 	free(hereValues);
2648 | 	hereValues = NULL;
2649 | 		
2650 | 	/*
2651 | 	 * Release the mutex lock.
2652 | 	 */
2653 | 
2654 | 	/*
2655 | 	 * Write the new value of this variable back to the config file.
2656 | 	 */
2657 | 
2658 | }
2659 | 
2660 | 
2661 | void ca_set_string(int symbol)
2662 | {
2663 | 
2664 | /****************************************************************
2665 | 	* ca_set_string()															*
2666 |  *																					*
2667 |  * Parameters																  	*
2668 | 	*		symbol -- the symbol of the variable.							*
2669 |  *																					*
2670 |  * Returns																		*
2671 | 	*		1 if successful, 0 if not successful ?							*
2672 | 	*																					*
2673 | 	* Remarks																		*
2674 |  *		Writing the new value back to the config file has yet to *
2675 | 	*		be implemented.														*
2676 |  *																					*
2677 | 	****************************************************************/
2678 | 
2679 |  char newString[80];	/* May need to make this bigger. */
2680 | 
2681 |  /*
2682 |   * Declare a pointer to a values_t variable.
2683 | 	 * Later, we shall assign this pointer to the first element
2684 |   * of either the globals or the locals array, as appropriate.
2685 |   */
2686 |  values_t *hereValues;
2687 | 
2688 | 	/*
2689 | 	 * Using the symbol, look in the appropriate place in the dictionary.
2690 | 	 */
2691 | #ifdef DEBUG
2692 | 	printf("\nca_set_string() function called ..... \n");
2693 |  printf("Variable type: %s\n", dictionary[symbol].varType);
2694 | #endif
2695 | 
2696 | 	/*
2697 | 	 * First, flush the input stream.
2698 | 	 */
2699 | 	fflush(stdin);
2700 | 
2701 | 	/* 
2702 | 	 * Prompt for the new value of the string.
2703 | 	 */
2704 | 	printf("\nNew value of %s [80 characters, maximum] >>> ", dictionary[symbol].varName);
2705 | gets(newString);
2706 | 	
2707 | /*
2708 |  * Make sure that a reasonable, sensible value of the string
2709 |  * value has been read from the keyboard.
2710 |  *
2711 |  * How do we implement this ???
2712 |  *
2713 |  */
2714 | 
2715 | 
2716 |  /*
2717 |   * Make sure that the function is attempting to set the correct type
2718 |   * of value.  If not, do not set the value - and exit.
2719 |   */
2720 | 
2721 | if (strcmp(dictionary[symbol].varType, "CA_STRING") != 0)
2722 | 		{
2723 | 		fprintf(stderr, "Error: unexpected variable type.\n");
2724 | 		exit(51);
2725 | 		}	
2726 | 
2727 | 	/*
2728 |   * Choose the appropriate values array.
2729 | 	 * Assign a temporary pointer to this array.
2730 | 	 */
2731 | 
2732 | 	switch(dictionary[symbol].varScope)
2733 | 		{
2734 | 		/* If the variable has global scope,
2735 | 		 * write it into the globals array.
2736 | 		 * If it has local scope, 
2737 | 		 * write it into the locals array.
2738 |  	 * If the scope cannot be found, report an error.
2739 | 		 */
2740 | 		case 1:
2741 | 		hereValues = globals;
2742 | 		break;
2743 | 
2744 | 		case 99:
2745 | 		hereValues = locals;
2746 | 		break;
2747 | 
2748 | 		default:
2749 | 		fprintf(stderr, "Error: Unknown scope: %d\n", dictionary[symbol].varScope);
2750 | 		break;
2751 | 		}
2752 | 
2753 | 
2754 | 	/*
2755 |   * Check for the presence of the mutex lock:
2756 | 	 *		if present,
2757 | 	 * 		wait until it is available;
2758 | 	 *		else
2759 |   *			get the lock and proceed with the change of value.
2760 | 	 */
2761 | 	mutex_lock(&Lock);
2762 | 	
2763 | 	/*
2764 |   * Write the new value of the variable to the correct place
2765 | 	 * in the [appropriate] values array.
2766 |   * Note the check to the return value of malloc() to see if the
2767 | 	 * memory was actually obtained.
2768 | 	 */
2769 | 
2770 | 		hereValues[symbol].valPtr = (char *)malloc(80);
2771 | 		if (hereValues[symbol].valPtr == NULL)
2772 | 			{
2773 | 			fprintf(stderr, "Cannot allocate memory for hereValues[symbol].valPtr\n");
2774 | 			die;
2775 | 			}
2776 | 		strcpy(hereValues[symbol].valPtr, newString); 
2777 | 
2778 | 
2779 | 		hereValues[symbol].strPtr = (char *)malloc(sizeof(newString) );
2780 | 		if (hereValues[symbol].strPtr == NULL)
2781 | 			{
2782 | 			fprintf(stderr, "Cannot allocate memory for hereValues[symbol].strPtr\n");
2783 | 			die;
2784 | 			}
2785 | 		strcpy(hereValues[symbol].strPtr, newString);
2786 | 
2787 | 	/*
2788 | 	 * Free the temporary pointer, hereValues.
2789 | 	 *
2790 |   */
2791 | 	free(hereValues);
2792 |  hereValues = NULL;
2793 | 
2794 | 	/*
2795 | 	 * Release the mutex lock.
2796 | 	 */
2797 | 	mutex_unlock(&Lock);
2798 | 
2799 | 	/*
2800 | 	 * Write the new value of this variable back to the config file.
2801 | 	 * Implement this later ?
2802 | 	 */
2803 | 
2804 | }
2805 | 
2806 | 
2807 | int ca_writeNewValue(int dictSymbol, char *newValue)
2808 | {
2809 | 
2810 | FILE *confPtr;						/* Pointer to config file */
2811 | FILE *tempPtr;						/* The pointer to temp file. */
2812 | char name[STRLENGTH];				/* The name of the variable. */
2813 | char value[STRLENGTH];			/* The value of the variable. */
2814 | 
2815 | 
2816 | /*
2817 |  * Find the actual name of the variable from the dictionary
2818 |  * structure (use the variable symbol as an index into the
2819 |  * array of dictionary structures.
2820 |  */
2821 | #ifdef DEBUG 
2822 | 	printf("Name of variable to be changed: %s\n", dictionary[dictSymbol].varName);
2823 | 	printf("Type of variable to be changed: %s\n", dictionary[dictSymbol].varType);
2824 | #endif	/* DEBUG */
2825 | 
2826 | /*
2827 | 	* Open the test config file for reading .....
2828 |  */
2829 | if ( (confPtr = fopen(testFile, "r")) == NULL)
2830 | 	{
2831 | 	printf("File \"%s\" could not be opened.\n", testFile);
2832 | 	die;
2833 | 	}
2834 | 
2835 | /*
2836 | 	* Open the temporary file for writing .....
2837 |  */
2838 | if ((tempPtr = fopen(tempFile, "w")) == NULL)
2839 | 	{
2840 | 	printf("File \"%s\" could not be opened.\n", tempFile);
2841 |  die;
2842 |  }
2843 | 
2844 | /*
2845 |  * Read the first record in the test config file.
2846 |  */
2847 |  
2848 |  fscanf(confPtr, "%s", name);
2849 |  fgets(value, sizeof(value), confPtr);
2850 |  
2851 |  /*
2852 |   * If the last character of "value" is '\n',
2853 |   * replace it with '\0'.
2854 |   */
2855 | 	if (value[strlen(value) - 1] == '\n')
2856 | 		{
2857 | #ifdef DEBUG
2858 | 		printf("The value string is %s", value);
2859 | 		printf("Replacing last character of \"%s\" with the NULL character\n", name);
2860 | #endif	/* DEBUG */
2861 | 
2862 | 		value[strlen(value) - 1] = '\0';
2863 | 
2864 | #ifdef DEBUG
2865 | 		printf("The new value string is %s", value);
2866 | #endif	/* DEBUG */
2867 | 		}
2868 | 
2869 | 	/*
2870 | 	 * If we read the variable that we want to change,
2871 |   * replace the value of this variable in the config
2872 |   * file with the value supplied from the keyboard.
2873 |   *
2874 |   */
2875 | 	if ( strcmp(name, dictionary[dictSymbol].varName) == 0)
2876 | 		{
2877 | 		strcpy(value, newValue);
2878 | 
2879 | #ifdef DEBUG
2880 | 		printf("The replacement string is %s", value);
2881 | #endif	/* DEBUG */
2882 | }
2883 | 
2884 | /*
2885 | 	* While there are records to be read in the test config file:
2886 | 	* 		Write the current record into the temporary file.
2887 |  * 		Read the next record in the config file.
2888 |  * Repeat untill the EOF has been reached.
2889 |  */
2890 | 	
2891 | while(!feof(confPtr) )
2892 | 	{
2893 |  fprintf(tempPtr, "%s %s\n", name, value);
2894 |  fscanf(confPtr, "%s", name);
2895 | 	fgets(value, sizeof(value), confPtr);
2896 | 
2897 |  /*
2898 |   * If the last character of "value" is '\n',
2899 |   * replace it with '\0'.
2900 |   */
2901 | 	if (value[strlen(value) - 1] == '\n')
2902 | 		{
2903 | #ifdef DEBUG
2904 | 		printf("The last character of the value string is %c", value[strlen(value) - 1]);
2905 | 		printf("The value string is %s", value);
2906 | 		printf("Replacing last character of \"%s\" with the NULL character\n",name);
2907 | #endif	/* DEBUG */
2908 | 
2909 | 		value[strlen(value) - 1] = '\0';
2910 | #ifdef DEBUG
2911 | 		printf("The new value string is %s", value);
2912 | #endif	/* DEBUG */
2913 | 		}
2914 | 
2915 | 
2916 | 	/*
2917 | 	 * If we read the variable that we want to change,
2918 |   * replace the value of this variable in the config
2919 |   * file with the value supplied from the keyboard.
2920 |   *
2921 |   */
2922 | 	if ( strcmp(name, dictionary[dictSymbol].varName) == 0)
2923 | 		{
2924 | 		strcpy(value, newValue);
2925 | 
2926 | #ifdef DEBUG
2927 | 		printf("The replacement string is %s", value);
2928 | #endif	/* DEBUG */
2929 | 		}
2930 | 
2931 | 	/*
2932 | 	 * Flush the pointer to the test config file.
2933 | 	 */
2934 | 	fflush(confPtr);
2935 | 
2936 | 	}				
2937 |  /* 
2938 | 	 * Here ends the loop that writes the config file, with the
2939 |   * new variable, to the temporary file.
2940 | 	 */
2941 | 
2942 | /*
2943 |  *
2944 |  * While !(the record to be updated)
2945 | 	*	BEGIN
2946 | 	*  Write the record to the temporary file
2947 |  *  Read the next record in the config file
2948 |  *	END
2949 |  *
2950 |  * Write the new value to the temporary file
2951 |  * Read the next record in the config file
2952 |  * COMMENT: this is the record to be updated.
2953 |  * COMMENT: discard this record.
2954 |  * 
2955 |  * Read the next record in the config file
2956 | 	*
2957 |  * While !(EOF)
2958 | 	*	BEGIN
2959 | 	*  write the record to the temporary file
2960 |  *  read the next record in the config file
2961 |  *  END
2962 |  *
2963 |  * Close Config file
2964 |  * Close Temporary file
2965 |  *
2966 |  * Open Temporary file for reading
2967 |  * Open Config file for writing
2968 |  *
2969 |  * Read the next record of the Temporary file
2970 |  *
2971 |  * While (!EOF of Temporary file)
2972 | 	*	BEGIN
2973 | 	*  write the record into the Config file
2974 | 	*  read the next record of the Temporary file
2975 |  *  END
2976 |  * 
2977 | 	*	Close Temporary file
2978 |  *  Close Config file
2979 |  *
2980 |  */
2981 | 
2982 | fclose(confPtr);
2983 | fclose(tempPtr);
2984 | 
2985 | /*
2986 | 	* Now, flush the file pointers
2987 |  */
2988 | 	fflush(confPtr);
2989 | 	fflush(tempPtr);
2990 | 
2991 | /*
2992 |  * Open the temporary file for reading.
2993 | 	* Open the config file for writing.
2994 |  * Write the contents of the temporary file
2995 |  * into the config file.
2996 |  */
2997 | 
2998 | /*
2999 | 	* Open the temporary file for reading .....
3000 |  */
3001 | if ((tempPtr = fopen(tempFile, "r")) == NULL)
3002 | 	{
3003 | 	printf("File \"%s\" could not be opened for reading.\n", tempFile);
3004 |  die;
3005 |  }
3006 | 
3007 | /*
3008 | 	* Open the config file for writing .....
3009 |  */
3010 | if ((confPtr = fopen(testFile, "w")) == NULL)
3011 | 	{
3012 | 	printf("File \"%s\" could not be opened for writing.\n", testFile);
3013 |  die;
3014 |  }
3015 | 
3016 | /*
3017 |  * Read the first record in the temporary file.
3018 |  */
3019 |  
3020 |  fscanf(tempPtr, "%s", name);
3021 |  fgets(value, sizeof(value), tempPtr);
3022 | #ifdef DEBUG
3023 | 	printf("\nFIRST LINE: %s %s", name, value);
3024 | #endif /* DEBUG */
3025 |  
3026 | /*
3027 | 	* While there are records to be read in the temporary file:
3028 | 	* 		Write the current record into the test config file.
3029 |  * 		Read the next record in the temporary file.
3030 |  * Repeat untill the EOF has been reached.
3031 |  */
3032 | 	
3033 | while(!feof(tempPtr) )
3034 | 	{
3035 |  fprintf(confPtr, "%s %s", name, value);
3036 |  fscanf(tempPtr, "%s", name);
3037 | 	fgets(value, sizeof(value), tempPtr);
3038 |  }
3039 | 
3040 | fclose(confPtr);
3041 | fclose(tempPtr);
3042 | unlink(tempFile);
3043 | 
3044 | return(0);
3045 | }
3046 | 
3047 | 
3048 | int ca_getStorageLocation(char *confVar, dict_t woordenboek[], int size)
3049 | /*************************************************************
3050 |  * ca_getStorageLocation()												*
3051 | 	*	- takes the name of a config variable and searches the  	*
3052 |  *    dictionary structure for the storage location for this *
3053 |  * 	  variable.																*
3054 |  *																				*
3055 |  * Parameters																*
3056 | 	*	confVar -- the string variable that contains the name    *
3057 |  *        	  of the variable.										*	
3058 |  *  woordenboek -- the dictionary structure to be searched	*
3059 | 	*	size			-- the size of the dictionary structure to	*
3060 |  *                 searched.											*
3061 |  *																				*
3062 |  * Returns																	*
3063 | 	*	the location (integer) in the values array.					*
3064 |  *																				*
3065 | 	*************************************************************/
3066 | {
3067 | int i, 
3068 | where,
3069 | found = 0	;		/* Whether or not the symbol has been found. */
3070 | 
3071 | 
3072 | #ifdef DEBUG
3073 | printf("The variable name in ca_getStorageLocation is: %s\n", confVar);
3074 | #endif /* DEBUG */
3075 | 
3076 | /*
3077 |  * Compares each name in the dictionary with the one for which
3078 |  * we are looking.
3079 |  */
3080 | i = 0;
3081 | while (!found && i <= size)
3082 | 	{
3083 | 	if (strcmp(woordenboek[i].varName, confVar) == 0)
3084 | 		{
3085 | 		found = 1;
3086 | 		}
3087 | 	else
3088 | 		{
3089 | 		++i;
3090 | 		}
3091 | 	}
3092 | 
3093 | /*
3094 | 	* Returns the storage location for the given variable name
3095 |  * or else returns NOT_FOUND
3096 |  */
3097 | if (found)
3098 | 		{
3099 | 		/*	mySymbol = atoi(woordenboek[i].varSym);	*/
3100 | #ifdef DEBUG
3101 |     printf("Symbol is %s\n", woordenboek[i].varSym);
3102 | 		printf("Storage Location is: %d\n", woordenboek[i].varNum);
3103 | #endif	/* DEBUG */
3104 | 	   where = woordenboek[i].varNum; 
3105 | 		}
3106 | else
3107 | 		{
3108 | 		fprintf(stderr, "Error: cannot find storage location for variable %s\n", confVar);	
3109 | 		where = NOT_FOUND;
3110 | 		}
3111 | 	return (where);
3112 | 
3113 | }
3114 | 
3115 | 
3116 | void ca_getConfig(values_t confVars[], int size)
3117 | /*************************************************************
3118 |  * ca_getConfig -- prints the strings representing the 		*
3119 |  * 					   values of the configuration variables		*
3120 |  *																				*
3121 |  * Parameters																*
3122 | 	*		confVars -- the values_t array which stores the 		*
3123 | 	*						values of the configuration variables.	   *
3124 | 	*		size -- the number of configuration variables,			*
3125 | 	*		        the number of elements in the confVars array  *
3126 |  *																				*
3127 |  *																				*
3128 |  *************************************************************/
3129 | {
3130 | int i = 0; 	/* A counting variable. */
3131 | 
3132 | puts("A dump of the strings of the values of the Config Vars:");
3133 | puts("Number\t\tString");
3134 | puts("----------");
3135 | 
3136 | while (i < size)
3137 | 	{
3138 | 	printf("%d\t\t%s\n", i, confVars[i].strPtr);
3139 |  ++i;
3140 | 	}
3141 | 
3142 | }
3143 | 
3144 | 
3145 | int ca_getType(char *confVar, dict_t woordenboek[], int size)
3146 | /****************************************************************
3147 | 	* ca_getType -- returns the data type of the variable.			*
3148 |  *																					*
3149 |  * Parameters																	*
3150 |  *		confVar -- the name of the configuration variable.			*
3151 | 	*		woordenboek -- the array of dict_t structures.				*
3152 | 	*		size -- the number of configuration variables.				*
3153 |  *																					*
3154 |  * Returns																		*
3155 |  *		an integer representing the data type of the variable		*
3156 |  *																					*
3157 |  ****************************************************************/
3158 | {
3159 | int i = 0,		/* Counter variable. */
3160 | 		found = 0;	/* Set this == 1 when we find the variable.  */
3161 | int myType;	/* Integer representing the type of the config variable. */
3162 | 
3163 | /*
3164 |  * Compare each name in the dictionary with the one for which we
3165 |  * are looking.
3166 |  */
3167 |  
3168 | myType = 0;
3169 | 
3170 | #ifdef DEBUG
3171 | printf("ca_getType function called for variable: %s\n", confVar);
3172 | #endif	/* DEBUG */
3173 | 
3174 | while (!found && i <= size)
3175 | 		{
3176 | 		if (strcmp(woordenboek[i].varName, confVar) == 0)
3177 | 			{
3178 | 			found = 1;
3179 | #ifdef DEBUG	
3180 | printf("ca_getType function: %s, %s matched.\n", woordenboek[i].varName, confVar);
3181 | #endif	/* DEBUG */
3182 | 			}
3183 | 		else
3184 | 			{
3185 | 			++i;
3186 | 			}
3187 | 		}			
3188 | 
3189 | /*
3190 | 	* Return the type of the config variable or
3191 | 	* else return "NOT FOUND".
3192 |  */
3193 | if (found)
3194 | 		{
3195 | 			if(strcmp(woordenboek[i].varType, "CA_INT") == 0)
3196 | 				{
3197 | #ifdef DEBUG
3198 | printf("ca_getType function: %s variable of type %s is Integer type\n", woordenboek[i].varName, woordenboek[i].varType);
3199 | 
3200 | printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
3201 | #endif /* DEBUG */
3202 | 				myType = 11;
3203 | #ifdef DEBUG
3204 | 				printf("For type CA_INT, myType is %d\n", myType);
3205 | printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
3206 | #endif /* DEBUG */
3207 | 				}
3208 | 			else
3209 | 				{
3210 | 					if(strcmp(woordenboek[i].varType, "CA_STRING") == 0)
3211 | 						{
3212 | #ifdef DEBUG
3213 | printf("ca_getType function: %s variable of type %s is String type\n", woordenboek[i].varName, woordenboek[i].varType);
3214 | printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
3215 | #endif /* DEBUG */
3216 | 						myType = 12;
3217 | #ifdef DEBUG
3218 | printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
3219 | #endif /* DEBUG */
3220 | 						}
3221 | 					else
3222 | 						{
3223 | 						if (strcmp(woordenboek[i].varType, "CA_DIRLIST") == 0 )
3224 | 							{
3225 | #ifdef DEBUG
3226 | printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
3227 | #endif /* DEBUG */
3228 | 							myType = 13;
3229 | #ifdef DEBUG
3230 | printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
3231 | #endif /* DEBUG */
3232 | 							}
3233 | 						else
3234 | 							{
3235 | 							if (strcmp(woordenboek[i].varType, "CA_BOOLEAN") == 0)
3236 | 								{
3237 | #ifdef DEBUG
3238 | printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
3239 | #endif /* DEBUG */
3240 | 								myType = 14;
3241 | #ifdef DEBUG
3242 | printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
3243 | #endif /* DEBUG */
3244 | 								}
3245 | 							else
3246 | 								{
3247 | 								if (strcmp(woordenboek[i].varType, "CA_SOURCETYPE") == 0)
3248 | 									{	
3249 | #ifdef DEBUG
3250 | printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
3251 | #endif /* DEBUG */
3252 | 									myType = 15;
3253 | #ifdef DEBUG
3254 | printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
3255 | #endif /* DEBUG */
3256 | 									}
3257 | 								else
3258 | 									{
3259 | 									if (strcmp(woordenboek[i].varType, "CA_ADMIN") == 0)
3260 | 										{	
3261 | #ifdef DEBUG
3262 | printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
3263 | #endif /* DEBUG */
3264 | 									myType = 16;
3265 | #ifdef DEBUG
3266 | printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
3267 | #endif /* DEBUG */
3268 | 										
3269 | 										}
3270 | 									}
3271 | 								}
3272 | 							}
3273 | 						}
3274 | 				}
3275 | 		}
3276 | 	else
3277 | 		{
3278 | 		myType = NOT_FOUND;
3279 | 		}
3280 | 	return(myType);
3281 |  }