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