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