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