Source File modules/ca/ca_configFns.c

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