modules/ca/ca_configFns.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. stringPack
  2. ca_populateDictionary
  3. opSplitsen
  4. ca_readConfig
  5. ca_getDictionary
  6. ca_get_int
  7. ca_get_dirlist
  8. ca_get_string
  9. ca_get_boolean
  10. ca_set_int
  11. ca_change_int_value
  12. testFunction
  13. ca_getDatabase
  14. ca_getSource
  15. ca_getAllSources
  16. ca_getAsource
  17. ca_set_boolean
  18. ca_set_dirlist
  19. ca_set_string
  20. ca_writeNewValue
  21. ca_getStorageLocation
  22. ca_getConfig
  23. ca_getType

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include "ca_defs.h"
#define DEBUG

void stringPack(char *dest, const char *source)
/* [<][>][^][v][top][bottom][index][help] */
{
#ifdef DEBUG
printf("\nInside stringPack function\n");
#endif  /* DEBUG */

/*----------------------------------------------------------------------*\

*  Function to rewrite a line of text with only one blankspace between  *
*  each word.
*

\*----------------------------------------------------------------------*/


/*
 * This while loop continues until the NULL character is copied into
 * the destination string.  If a tab character is copied into the 
 * destination string, it is replaced with a blank-space character.
 *
 * Multiple blank-space and/or tab characters are skipped in the source
 * string until any other character is found.
 */

        while (1)
                {
                *dest = *source;

                if (*dest == '\t')
                        (*dest = ' ');
        
                /* Exit if have copied the end of the string. */
                if (*dest == '\0')
                        return;

/*
 * If the source character was a blank-space or a tab, move to the next 
 * source character.  While the source character is a blank-space or a
 * tab, move to the next character (i.e. ignore these characters).  When
 * any other character is found in the source string, move to the next
 * element of the destination string.
 *
 * Otherwise, simultaneously, move to the next elements of the destination
 * and the source strings.
 */


                
                if ( (*source == ' ') || (*source == '\t') )
                        {
                        ++source;
                        while ( (*source == ' ') || (*source == '\t') )
                                {
                                ++source;
                                }

                        ++dest;
                        }
                else
                        {
                        ++dest;
                        ++source;
                        }
                }
}


void ca_populateDictionary(dict_t woordenboek[], int size)
/* [<][>][^][v][top][bottom][index][help] */

/*******************************************************************
 * ca_populateDictionary -- Parses dictionary file, initializes    *
 *                                                                      the dictionary structure and writes    *
 *                                                                      the file of dictionary symbols,                         *
        *                                                                       ca_dictSyms.h                                                                   *
        *                                                                                                                                                                               *
        * Parameters                                                                                                                                            *
        *               woordenboek -- the dictionary to be populated                                   *
        *               size -- the total number of variables i.e. the size of the  *
 *                                array of dict_t structures.  See D. & D., p.276               *
 *                                                                                                                                                                              *
 * Returns                                                                                                                                                      *
        *               Nothing ?  (may change this later)                                                                      *
 *                                                                                                                                                                              *
 *******************************************************************/

{
const char *blankLine = "\n";
const char *comment = "#";
char line[120];
char input[120];
char test[120];
int lineNo = 0;
int i;
int entry = 0;
FILE *dictPtr, *defnPtr;

gchar **tokens;                         /* Pointer to an array of strings. */
                
/*
        * Try to open the dictionary file for reading.  If it cannot be
 * opened, exit with an error.
 */
if ( (dictPtr = fopen("dictionary.txt", "r")) == NULL)
                {
                fprintf(stderr, "Error: Unable to open 'dictionary.txt'\n");
                exit (51);
                }
                

        /*
         *Try to open the definitions file for writing.  If it cannot be
  * opened,exit with an error
  */
if ( (defnPtr = fopen("defs.txt", "w")) == NULL)
                {
                fprintf(stderr, "Error: Unable to open 'defs.txt'\n");
                exit (51);
                }
        
                /*
                 * Read the file one line at a time;
                 * if the line begins with a comment, ignore it;
                 * otherwise, split each line into tokens;
                 * print each token.
                 * Assign each token to the appropriate member of
                 * the appropriate element of the dictionary array.
                 */
                
                fgets(input, sizeof(input), dictPtr);
        
                if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0) )

                        {
                        /*
                         * First remove the newline character.
                         * Then replace multiple tab and space
                         * characters with single space characters.
                         */

                        /* Remove the newline character, if present. 
                         * Replace the last character of the string
                         * array with with '\0'.
                         */

                        input[strlen(input) - 1] = '\0';

                        /* Now, remove the multiple space and tab
                         * characters.
                         */

                        stringPack(line, input);
                        
                        g_strchomp(line); /* Remove trailing w-space. */
#ifdef DEBUG
puts(line);
#endif  /*DEBUG */

                        tokens = g_strsplit(line, " ", 0);

#ifdef DEBUG                                            
                        for (i = 0; tokens[i] != NULL; i++)
                                printf("tokens[%d] = %s\n", i, tokens[i]);
#endif  /* DEBUG */

                        /* We no longer need a variable for scope
                         * woordenboek[entry].varScope = atoi(tokens[1]);
                         */

                        strcpy(woordenboek[entry].varName, tokens[0]);
                        strcpy(woordenboek[entry].varSym, tokens[1]);
                        strcpy(woordenboek[entry].varType, tokens[2]);
                        woordenboek[entry].varNum = entry;
                        
       /*
                         * Write the dictionary symbol and the entry number 
                         * to the definitions file.
        */
                        fprintf(defnPtr, "%s\t%d\n", tokens[1], entry);

                        ++entry; 
                        }
        /*
         * Get the 2nd and subsequent line of the file.
         */

        fgets(input, sizeof(input), dictPtr);

        while(!feof(dictPtr) )
        {
                /*
                 * Process the line if it is not a comment.
                 */

                if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0 ) )
                {
                        /*
                         * First remove the newline character.
                         * Then replace multiple tab and space
                         * characters with single space characters.
                         */

                        /* Remove the newline character, if present. 
                         * Replace the last character of the string
                         * array with with '\0'.
                         */

                        input[strlen(input) - 1] = '\0';

                        /* Now, remove the multiple space and tab
                         * characters.
                         */

                        stringPack(line, input);
                        
                        g_strchomp(line); /* Remove trailing w/space. */
#ifdef  DEBUG
puts(line);
#endif  /* DEBUG */
                        tokens = g_strsplit(line, " ", 0);
                        
#ifdef DEBUG
                        for (i = 0; tokens[i] != NULL; i++)
                                printf("tokens[%d] = %s\n", i, tokens[i]);
#endif  /* DEBUG */

                        /*
                         * We no longer need to know the scope of a variable
                         * woordenboek[entry].varScope = atoi(tokens[1]);
        */

                        strcpy(woordenboek[entry].varName, tokens[0]);
                        strcpy(woordenboek[entry].varSym, tokens[1]);
                        strcpy(woordenboek[entry].varType, tokens[2]);
                        woordenboek[entry].varNum = entry;
                        fprintf(defnPtr, "%s\t%d\n", tokens[1], entry);
                        ++entry;
                }
                fgets(input, sizeof(input), dictPtr);
        }               

fclose(dictPtr);
fclose(defnPtr);

}       /* End of ca_populateDictionary() function. */


void opSplitsen (FILE *filePtr, gchar **tokenArray)
/* [<][>][^][v][top][bottom][index][help] */
{
/*
 * Declaring character constants is safer than using #define.
 * See Oualline's book, p.145.
 *
 */

const char *blankLine = "\n";           /* Declared as a string, not a character. */
const char *comment = "#";                      /* Declared as a string. */
char line[99];
char input[99];
int lineNo = 0;
int j;


        fgets(input, sizeof(input), filePtr); /* Get the (first) line from the */
                                         /* file to which filePtr points. */
        
#ifdef DEBUG
        printf("\nFIRST INPUT >>> %s\n", input);
#endif  /* DEBUG */

        /* Compare the first character of the input */
        /* to the comment and the newline strings. */

        if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0) )
                                        
                                

                {
                /* Remove the newline character, if present. */
                /* Replace the last character */
                /* of the string array with '\0'. */

                input[strlen(input) - 1] = '\0';        
#ifdef DEBUG
printf("First Input >>> %s\n", input);
#endif /* DEBUG */

                strcpy(line, input);
#ifdef DEBUG
printf("First Line after copy >>> %s\n", line);
#endif  /* DEBUG */

                stringPack(line, input);     
#ifdef DEBUG
printf("Line: %s\n", line);
#endif  /* DEBUG */

                g_strchomp(line);
/*              g_strdelimit(line, " ", ':');
 *              g_strdelimit(line, "\t", '*');
*/

                printf("%3d> %s\n", ++lineNo, line);

                /*
                 * g_strsplit() is a GLib function;
                 * it returns an array of strings.
                 * 
                 * Here, we split on two spaces, "  ".
                 * We set max_tokenArray to be 0.  We want the 
                 * first token to be the name of the variable
                 * and the other tokens to be the value of the variable,
                 * qualifiers, etc.
                 */

                tokenArray = g_strsplit(line, " ", 0);  

                for (j = 0; tokenArray[j] != NULL; j++)
                        printf("token[%d] = %s\n", j, tokenArray[j]);
                } /* End of processing the first line, if not commented. */

                /* End of getting the first line. */


        /*Get the 2nd line of the file. */
        fgets(input, sizeof(input), filePtr);

        while(!feof(filePtr) )
                {
                        
                        /* Process the line if it is not commented. */
                        if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) != 0 ) )
                        {
                /* Remove the newline character, if present. */ 
                        input[strlen(input) -1] = '\0';
#ifdef DEBUG
printf("Subsequent Input >>> %s\n", input);
#endif  /* DEBUG */

                        strcpy(line, input);
#ifdef DEBUG
printf("Subsequent Line after copy >>> %s\n", line);
#endif  /* DEBUG */

                        stringPack(line, input);
#ifdef DEBUG
printf("Line: %s\n", line);
#endif  /* DEBUG */

                        g_strchomp(line);
/*                      g_strdelimit(line, " ", ':');
 *                      g_strdelimit(line, "\t", '*');
 */
                        printf("%3d> %s\n", ++lineNo, line);

                        /*
                         * See the comment above about the maximum 
                         * number of tokens being set to 0.
                         */

                        tokenArray = g_strsplit(line, " ", 0);
                        for (j = 0; tokenArray[j] != NULL; j++)
                                {       
                                printf("token[%d] = %s\n", j, tokenArray[j]);
                                /* Can also use puts(tokenArray[j]) here. */
                                }
                        } /* Processed uncommented lines. */

                fgets(input, sizeof(input), filePtr);
                } /* Processed the 2nd & subsequent lines of the file. */

} /* End of processing the opened file. */


void ca_readConfig(const char *configFile, values_t confVars[], int size)
/* [<][>][^][v][top][bottom][index][help] */
/*******************************************************************
 *                                                                                                                                                                              *
 * ca_readConfig -- parses the config file and writes the values   *
 *                                               into memory.                                                                                           *
 *                                                                                                                                                                              *
 * Parameters                                                                                                                                           *
 *              configFile -- the configuration file
        *               confVars[] -- the array of values structures                                            *
        *               size -- the number of configuration variables                                   *
 *                                                                                                                                                                              *
 * Returns                                                                                                                                                      *
 *              Nothing -- perhaps make this return 0 on successful exit ?      *
 *                                                                                                                                                                              *
 * Note:        Should we make the name of the config file a global             *
        *                       variable ?                                                                                                                              *       
 *******************************************************************/
{
FILE *confPtr;                  /* Pointer to config file. */
char name[STRLENGTH];           /* The name of the config variable */
char value[STRLENGTH];                  /* The value of the variable */
int location;                   /* Storage Location of the variable's value. */
int type;        /* Data type of the variable, represented by an integer. */


const char *blankLine = "\n";  /* Declared as a string, not a character. */
const char *comment = "#";              /* Declared as a string. */

char source[16];                                                                        /* The name of a source. */
char database[STRLENGTH];               /* The elements of a database. */

gchar **dbcomps;        /* Pointer to an array of strings that represents */
                                                        /* the components of a db. */

int i;                                  /* A counting variable. */

ca_database_t *newDbPtr;        /* A pointer to a new instance of */
                                                                                /* ca_database_t.                                                */

ca_database_list_t *newSrc;     /* A pointer to a new instance of */
                                                                                /* ca_database_list_t.                           */

/* 
 * Function Prototype for ca_getStorageLocation()
 * We put it here; thus it can only be called from 
 * within ca_readConfig()
 *
 * This function finds the location in the values_t array
 * where we store pointers to the string value and the actual
 * value of the variable.  It returns this location as an 
 * integer.
 *
 */
int ca_getStorageLocation(char [], dict_t [], int);

/*
        * Function Prototype for ca_getType()
        * We put it here so that it can only be called from
        * within ca_readConfig()
 *
 * This function returns the type of the configuration
 * variable.  It returns it as a string.
 *
 */
int ca_getType(char [], dict_t [], int);


#ifdef  DEBUG
printf("\nInside readConfig() function.\n");
printf("Configuration file is: %s\n", configFile);
#endif  /* DEBUG */

/*
        * Open the configuration file for reading .....
 */
if ( (confPtr = fopen(configFile, "r")) == NULL)
                {
                printf("Error: file %s could not be opened.\n", configFile);
                exit (51);
                }

/*
        * Read the first record in the configuration file .....
 * We read the _name_ of the variable using fscanf into a
 * string array.  We read the _value_ of the variable
 * using fgets into an array; thus, we can handle values of
 * variables with qualifiers (e.g. SPLIT after DBLIST) and
 * values with blank characters (e.g. REPLYBANNER).
 */
fscanf(confPtr, "%s", name);
fgets(value, sizeof(value), confPtr);


/* 
        *               While there are records to be read in the config file.
        *               write the current record into memory,
 *     read the next record in the config file
 */


while (!feof(confPtr) )
        {

/*
        * From the variable name, find the dictionary number.
 * The dictionary number is defined as the place in the 
 * values array in which to store the value of the variable.
 * 
 */

                /*
                 * Process the line only when/if it is not a comment or 
                 * a blankline.
     */
                if ( (strncmp(name, comment, 1) != 0) && (strncmp(name, blankLine, 1) != 0) )
                        {
                        /*
                 * If the last character of "value" is '\n',
        * replace it with '\0'.
        */
                        if ( value[strlen(value) - 1] == '\n')
                                {
                                value[strlen(value) - 1] = '\0';
                                }

                        /*
                         * From the variable name, find the element of the values
                         * array in which to store the value of the variable.
        *
                         */
                        location = ca_getStorageLocation(name, dictionary, VARS);
                        printf("The location is: %d\n", location);

                        /*
                         * Store a pointer to the string that contains the value
                         * This is not necessarily the actual value itself.
                         * First, we must allocate some memory.
                         */
                        confVars[location].strPtr = (char *)malloc(STRLENGTH);
                        /*
                         * We check the return value of the malloc function .....
        */      
                        if (confVars[location].strPtr == NULL)
                                {
                                fprintf(stderr, "Cannot allocate memory for confVars[location].strPtr\n");
                                exit (8);
                                }

                        strcpy(confVars[location].strPtr, value);

                        /*
                         * Now, store a pointer to the _value_ of the variable.  
                         * Do this as follows:
                         * (a) get the _type_ of the variable
                         * (b) store a pointer to the value of the variable in 
                         *     a way that depends on the _type_ of the variable.
        */
#ifdef DEBUG
printf("Variable \"%s\" is data-type \"%d\"\n", name, ca_getType(name, dictionary, VARS) );
#endif /* DEBUG */


type = ca_getType(name, dictionary, VARS);

                        /*
                         * Given the _type_ of the variable, store the value of the
                 * variable in the appropriate way.
                         */              
                        switch(type)    
                                {
                                case 11:
                                puts("Data type is Integer");
                                confVars[location].valPtr = malloc(sizeof(int) );
                                if (confVars[location].valPtr == NULL)
                                        {
                                        fprintf(stderr, "Cannot allocate memory !!!\n");
                                        exit (8);
                                        }
                                sscanf(value, "%d", (int *) confVars[location].valPtr);
                                break;

                                case 12:
                                puts("Data type is String");
                                confVars[location].valPtr = (char *)malloc(STRLENGTH);
                                if (confVars[location].valPtr == NULL)
                                        {
                                        fprintf(stderr, "Cannot allocate memory !!!\n");
                                        exit (8);
                                        }
                                 strcpy(confVars[location].valPtr, value);
                                break;

                                case 13:
                                puts("Data type is Dirlist");
                                confVars[location].valPtr = (char *)malloc(STRLENGTH);
                                if (confVars[location].valPtr == NULL)
                                        {
                                        fprintf(stderr, "Cannot allocate memory !!!\n");
                                        exit (8);
                                        }
                                 strcpy(confVars[location].valPtr, value);
                                break;

                                case 15:
                                puts("Data type is Source !!!");
                                /*
                                 * Split the value into "source" and "database"
           * Use blankspace as the delimiter between the
                                 * "source" and "database".
                                 */
                                sscanf(value, "%s %s", source, database);
#ifdef DEBUG
puts(source);
puts(database);
#endif  /* DEBUG */

                                /*
                                 * Using the values in "database".
                                 * populate a ca_database_t structure.
                                 * Give this variable a name.
                                 *
                                 */

                        /* First, separate the values in "database", using "," as 
                                         * as a delimiting  character.
                                         */
                                dbcomps = g_strsplit(database, ",", 0);

#ifdef DEBUG                                            
for (i = 0; dbcomps[i] != NULL; i++)
                printf("dbcomps[%d] = %s\n", i, dbcomps[i]);
#endif  /* DEBUG */


                                        /*
                                         * Create a structure for this database.
                                         */
                                newDbPtr = malloc(sizeof(ca_database_t));
                                if (newDbPtr == NULL)
                                        {
                                        fprintf(stderr, "Cannot allocate memory to new db structure\n");
                                        exit (8);
                                        }

                                strcpy(newDbPtr->host, dbcomps[0]);
                                strcpy(newDbPtr->port, dbcomps[1]);
                                strcpy(newDbPtr->user, dbcomps[2]);
                                strcpy(newDbPtr->password, dbcomps[3]);
                                strcpy(newDbPtr->dbName, dbcomps[4]);
#ifdef DEBUG
puts("Testing the population of the db structure:");
printf("\n%s::%s::%s::%s::%s\n", newDbPtr->host, newDbPtr->port, newDbPtr->user, newDbPtr->password, newDbPtr->dbName);
#endif /* DEBUG */

                                /*
                                 * Using the above ca_database_t structure
                                 * and the "source" value, 
                                 * populate the ca_src_t structure.
                                 */
                        
                                        /*
                                         * Create a new structure for this source.
                                         */
                                newSrc = malloc(sizeof(ca_database_list_t));

                                if (newSrc == NULL)
                                        {
                                        fprintf(stderr, "Cannot allocate memory to new source structure\n");
                                        exit (8);
                                        }

                                strcpy(newSrc->name, source);
                                newSrc->db = *newDbPtr;

#ifdef DEBUG
puts("Testing the population of the ca_database_list_t structure:");
printf("\n%s::%s::%s::%s::%s::%s\n", newSrc->name, (newSrc->db).host, (newSrc->db).port, (newSrc->db).user, (newSrc->db).password, (newSrc->db).dbName);
#endif /* DEBUG */

                                /*
                                 * Append this ca_src_t structure to the sourceList,
                                 * which is a singly-linked list if type GSList.
                                 */

sourceList = g_slist_append(sourceList, newSrc);

                                break;

                                default:
                                printf("Data type not found for variable \"%s\".\n", name);
                                break;
                                }
                        }

fscanf(confPtr, "%s", name);
fgets(value, sizeof(value), confPtr);

        }       /* End of processing the config file. */

}       /* End of readConfig() function */


/*
 * void ca_populateDictionary(dictionary_t woordenboek[], int size, FILE *fiPtr)
 * {
 * int j;
 * char input[99];
 * 
 * for (j=0; (j < size) && !feof(fiPtr); j++)
 *      j = 0;
 *      while ((j < size) && !feof(fiPtr) )
 *      {
 *      printf("\n%d\n", j);
 *      
 *      fgets(input, sizeof(input), filePtr);
 * 
 *      if ( (strncmp(input, comment, 1) != 0) && (strncmp(input, blankLine, 1) 
 * != 0) )
 *      {
 *      fscanf(fiPtr, "%s %s %s %s", woordenboek[j].varName, woordenboek[j].varScope, woordenboek[j].varSym, woordenboek[j].varType);
 *      }
 * 
 *      fgets(input, sizeof(input), filePtr);
 *      printf("%s\n", woordenboek[j].varName);
 *      }
 * }
 * 
 */


void ca_getDictionary(dict_t woordenboek[], int size)
/* [<][>][^][v][top][bottom][index][help] */
{
int k;

for (k = 0; k <= size; k++)
        {
        printf("\nj = %d\n", k);
 /*
         * printf("%s\t%d\t%s\n", woordenboek[k].varName, woordenboek[k].varScope, woordenboek[k].varType);
         */
         printf("%s\t%s\t%s\t%d\n", woordenboek[k].varName, woordenboek[k].varSym, woordenboek[k].varType, woordenboek[k].varNum);

        }
}


int ca_get_int(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
int *xPtr;

                /*
                 * First print a message saying that the ca_get_int()
                 * function is being called.
                 */
#ifdef DEBUG
        printf("\nDEBUG: ca_get_int() function is called .....\n");
printf("DEBUG: New value of StringPtr: %s\n", globals[symbol].strPtr);
#endif  /* DEBUG */

                /*
                 * Look at the appropriate place in the dictionary;
                 * e.g. C_BINDPORT => the first element, index = 0.
                 *
                 * if the varType is not an integer, exit with an error;
                 *
                 * otherwise, 
                 *              if the varScope is global, look for the value in the
                 *              appropriate place in memory in the global values array;
                 *    otherwise, look for the value in the appropriate place in 
                 *      memory in the local values array;
                 *
                 *
                 */

                /* Look at the appropriate place in the dictionary. */

#ifdef DEBUG
                printf("\nDEBUG: Variable type: %s\n", dictionary[symbol].varType);
#endif  /* DEBUG */

                /* If the variable type is not an integer, exit with an error. */
                if ( strcmp(dictionary[symbol].varType, "CA_INT") != 0)
                        {
                        fprintf(stderr, "Error: unexpected variable type.\n");
                        exit (51);
                        }
                else
                        {
                        /*
                         * If the variable has global scope, look for it in 
                         * the globals array.  Otherwise, look for it in the
                         * locals array.
                         *
                         */
                        
                        /*
                         * Lock the value of the variable before reading it.
                         */

                        mutex_lock(&Lock);

                                switch(dictionary[symbol].varScope)
                                        {
                                        case 1:
#ifdef  DEBUG
                                        printf("\nThis variable has global scope.\n");
                                        printf("The string is: %s\n", globals[symbol].strPtr);
                                        printf("String2Value: %d\n", atoi(globals[symbol].strPtr));
#endif  /* DEBUG */

                                        xPtr = globals[symbol].valPtr;
                                        printf("Value: %d\n", *xPtr);
                                        return(*xPtr);
                                        break;

                                        case 99:
#ifdef  DEBUG
                                        printf("\nThis variable has local scope.\n");
                                        printf("The string is %s\n", locals[symbol].strPtr);
                                        printf("String2Value: %d\n", atoi(locals[symbol].strPtr));
#endif  /* DEBUG */
                                        xPtr = locals[symbol].valPtr;
                                        printf("Value: %d\n", *xPtr);
                                        return(*xPtr);
                                        break;

                                        default:
                                        printf("\nAaaargh !!!  This variable has unwelcome scope.\n");                  
                                        break;
                                        }
                        /* 
                         * Unlock the value of the variable after reading it.
                         */
                        mutex_unlock(&Lock);
                        
                        }
        
}

char *ca_get_dirlist(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
/*
 * This function returns a pointer to a character array.  Thus,
 * we need to declare such a pointer.
 *
 */

char *xPtr;
#ifdef  DEBUG
        printf("\nca_get_dirlist() function is called .....\n");
#endif  /* DEBUG */


                /*
                 * Look at the appropriate place in the dictionary;
                 * e.g. CA_HELP => the second element, index = 1.
                 *
                 * if the varType is not CA_DIRLIST, exit with an error;
                 *
                 * otherwise, 
                 *              if the varScope is global, look for the value in the
                 *              appropriate place in memory in the global values array;
                 *    otherwise, look for the value in the appropriate place in 
                 *      memory in the local values array;
                 *
                 *
                 */

                /* Look at the appropriate place in the dictionary. */
                
                printf("\nVariable type: %s\n", dictionary[symbol].varType);
        
                /* If the variable type is not CA_DIRLIST, exit with an error. */
                if ( strcmp(dictionary[symbol].varType, "CA_DIRLIST") != 0)
                        {
                        fprintf(stderr, "Error: unexpected variable type.\n");
                        exit (51);
                        }
                else
                        {
                        /*
                         * If the variable has global scope, look for it in 
                         * the globals array.  Otherwise, look for it in the
                         * locals array.
                         *
                         */

                                switch(dictionary[symbol].varScope)
                                        {
                                        case 1:
                                        printf("\nThis variable has global scope.\n");
                                        printf("The string is: %s\n", globals[symbol].strPtr);
                                        xPtr = globals[symbol].valPtr;
                                        printf("Value: %s\n", xPtr);
                                        return(xPtr);
                                        break;

                                        case 99:
                                        printf("\nThis variable has local scope.\n");
                                        printf("The string is %s\n", locals[symbol].strPtr);
                                        xPtr = locals[symbol].valPtr;
                                        printf("Value: %s\n", xPtr);
                                        return(xPtr);
                                        break;

                                        default:
                                        printf("\nAaaargh !!!  This variable has unwelcome scope.\n");                  
                                        break;
                                        }
                        
                        }
        
}


char *ca_get_string(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
/*
 * This function returns a pointer to a character array.  Thus,
 * we need to declare such a pointer.
 *
 */

char *xPtr;
#ifdef  DEBUG
        printf("\nca_get_text() function is called .....\n");
#endif  /* DEBUG */


                /*
                 * Look at the appropriate place in the dictionary;
                 * e.g. CA_REPLYBANNER => the third element, index = 2.
                 *
                 * if the varType is not CA_STRING, exit with an error;
                 *
                 * otherwise, 
                 *              if the varScope is global, look for the value in the
                 *              appropriate place in memory in the global values array;
                 *    otherwise, look for the value in the appropriate place in 
                 *      memory in the local values array;
                 *
                 *
                 */

                /* Look at the appropriate place in the dictionary. */
                
                printf("\nVariable type: %s\n", dictionary[symbol].varType);
        
                /* If the variable type is not CA_STRING, exit with an error. */
                if ( strcmp(dictionary[symbol].varType, "CA_STRING") != 0)
                        {
                        fprintf(stderr, "Error: unexpected variable type.\n");
                        exit (51);
                        }
                else
                        {
                        /*
                         * If the variable has global scope, look for it in 
                         * the globals array.  Otherwise, look for it in the
                         * locals array.
                         *
                         */

                                switch(dictionary[symbol].varScope)
                                        {
                                        case 1:
                                        printf("\nThis variable has global scope.\n");
                                        printf("The string is: %s\n", globals[symbol].strPtr);
                                        xPtr = globals[symbol].valPtr;
                                        printf("Value: %s\n", xPtr);
                                        return(xPtr);
                                        break;

                                        case 99:
                                        printf("\nThis variable has local scope.\n");
                                        printf("The string is %s\n", locals[symbol].strPtr);
                                        xPtr = locals[symbol].valPtr;
                                        printf("Value: %s\n", xPtr);
                                        return(xPtr);
                                        break;

                                        default:
                                        printf("\nAaaargh !!!  This variable has unwelcome scope.\n");                  
                                        break;
                                        }
                        
                        }
}


int ca_get_boolean(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
/**********************************************
 * ca_get_boolean()                                                                     *
        *                                                                                                                       *
        *                                                                                                                       *
        * Parameters                                                                                    *
        *                                                                                                                       *
        *       symbol -- the symbol for the variable           *
 *                                                                                                                      *
        *                                                                                                                       *
        * Returns                                                                                               *
        *                                                                                                                       *
        *       1 if true, 0 if false.                                                  *
 *                                                                                                                      *
 * Remarks                                                                                              *
        *                                                                                                                       *
 *   Is there a better way to implement                 *
        *   Boolean values in C ?                                                       *
 *                                                                                                                      *
        *********************************************/

int *xPtr;

/*
 * Print this message if in debug mode.
 *
 */
#ifdef DEBUG
        printf("\nca_get_boolean() function is called .....\n");
printf("DEBUG 5: New value of StringPtr: %s\n", globals[symbol].strPtr);
#endif  /* DEBUG        */

/**********************************************\
 *                                                                                                                      *
        * Here is how this works:                                                       *
 *                                                                                                                      *
 * (a) Check that the type of variable whose    *
 *     value is being read is CA_BOOLEAN.               *
 *                                                                                                                      *
 * (b) Lock the value of the variable before    *
 *              reading it.                                                                             *
 *                                                                                                                      *
 * (c) Depending on the scope of the variable   *
 *     look for it in the appropriate array.    *
 *                                                                                                                      *
        * (d) Read the value of the variable.                   *
 *                                                                                                                      *
        * (e) Unlock the value of the variable after *
 *              reading it.                                                                             *
        *                                                                                                                       *
 *                                                                                                                      *
 * Returns                                                                                              *
        *
        *       an integer value as follows:                                    *
        *               1 if the db is in testmode (true),                                                      *
        *               0 if the db is not in testmode (false).                                 *
\*********************************************/


/*
        * Look at the appropriate place in the dictionary; 
        * e.g. CA_BOOLEAN = the fifth element of the dict_t array,
 * => index = 4.
 *
 * If the varType is not Boolean, exit with an error
        * 
 * Otherwise,
        *       if the varScope is global, look for the value in the
        *       appropriate place in the global values array;
        *
        *       otherwise, look for the value in the appropriate place in the
        *       locals array.
        *
 */

#ifdef DEBUG
/* Look in the appropriate place in the dictionary. */
printf("\nVariable type: %s\n", dictionary[symbol].varType);
#endif  /* DEBUG */

/* If the variable type is not Boolean, exit with an error. */

        if ( strcmp(dictionary[symbol].varType, "CA_BOOLEAN") != 0)
                {
                fprintf(stderr, "Error: Boolean type expected.\n");
                exit (51);
                }

        else
                {
                /*
                 * Lock the value of the variable before reading it.
                 *
                 */
                
                mutex_lock(&Lock);
                
                /*
                 * If the variable has global scope, look for it in the globals
                 * array.  Otherwise, look for it in the locals array.
                 *
     */

                switch(dictionary[symbol].varScope)
                        {
                        case 1:
                        printf("\nThis variable has global scope.\n");
                        printf("The string is: %s\n", globals[symbol].strPtr);
                        printf("String2Value: %d\n", atoi(globals[symbol].strPtr) );
                        xPtr = globals[symbol].valPtr;
                        printf("Value: %d\n", *xPtr);
                        return (*xPtr);
                        break;

                        case 99:
                        printf("\nThis variable has local scope.\n");
                        printf("The string is %s\n", locals[symbol].strPtr);
                        printf("String2Value: %d\n", atoi(locals[symbol].strPtr) );
                        xPtr = locals[symbol].valPtr;
                        printf("Value: %d\n", *xPtr);
                        return(*xPtr);
                        break;

                        default:
                        printf("\nError: This variable has unknown scope.\n");
                        break;
                        }

                /*
                 * Unlock the value of the variable after reading it.
                 */
                mutex_unlock(&Lock);
                
                }       

}



void ca_set_int(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
        /*********************************************
         * ca_set_int()                                                                         *
  *                                                                                                             *
         * Parameters                                                                                   *
         *              symbol -- the symbol for the variable.  *
         *                                                                                                                      *
         * Returns                                                                                              *
         *              1 if successful 0 if not ?                                      *
         *                                                                                                                      *
         * Remarks                                                                                              *
         *      Needs a better way to check for valid  *
  *    values from the keyboard.                                        *
         *                                                                                                                      *
         *********************************************/

        void *tempPtr;          /* Temp pointer to point to the value pointer
                                                                in the appropriate values array. */
 char newPort[16];
 int invalid;
 int portNr;

 /* Function to change the value in a given values array.
  * This function can only be called from within ca_set_int().
         */
 int *ca_change_int_value(char []); 
 void testFunction(values_t values[]);

        /*
  * Using the symbol, look at the appropriate place in the
         * dictionary.
         */
#ifdef DEBUG
 printf("\nca_set_int() function called .....\n");
        printf("Variable type: %s\n", dictionary[symbol].varType);
#endif  /* DEBUG */


/*
 * Make sure that a reasonable, sensible value of bind-port has
 * been read from the keyboard.
 */

do      {

                /*
                 * First, flush input stream.
     */
                fflush(stdin);

                /*
                 * Prompt for the new value of the bind-port.
                 */
                
                printf("\nNew value of bind-port (non-zero positive integer) >>> ");
                scanf("%s", newPort);
                /*
                 * gets(newPort);                                  
                 */
#ifdef DEBUG
                printf("\nDEBUG: Value of newPort variable: %s\n", newPort);
#endif  /* DEBUG */

                sscanf(newPort, "%d", &portNr);

#ifdef DEBUG
                printf("\nDEBUG: Value of integer variable, portNr: %d\n", portNr);
#endif  /* DEBUG */
                
                        if (portNr < 0)
                                {
                                invalid = 1;
                                puts("Only non-zero positive integer values accepted for bind-port");
                                }
                        else
                                {
                                invalid = 0;
                                }

                } while(invalid);

 /*
         * Check that the function is attempting to set the correct type
         * of value.  If not, do not set the value and exit.
         */

        if (strcmp(dictionary[symbol].varType, "CA_INT") != 0)
                {
                fprintf(stderr, "Error: unexpected variable type.\n");
                exit (51);
                }

        /*
         * Choose the appropriate values array.  
         */
        switch(dictionary[symbol].varScope)
                {
                /* If the variable has global scope, 
                 * write it into the globals array.
                 * If it has local scope,
                 * write it into the local array.
                 * If the scope cannot be found, then report an error.
                 */
                case 1:
                globals[symbol].valPtr = ca_change_int_value(newPort);
                globals[symbol].strPtr = newPort;
                
                globals[symbol].strPtr = (char *)malloc(sizeof(newPort) );
                
                /* Check the return value of malloc() to make sure that we 
                 * actually got the memory.
                 */
                if (globals[symbol].strPtr == NULL)
                        {       
                        fprintf(stderr, "Cannot allocate memory for globals[symbol].strPtr.\n");
                        exit (8);
                        }
#ifdef DEBUG
                printf("DEBUG: New value of StringPtr: %s\n", globals[symbol].strPtr);
#endif  /* DEBUG */

                strcpy(globals[symbol].strPtr, newPort);

#ifdef DEBUG
                printf("DEBUG 2: New value of StringPtr: %s\n", globals[symbol].strPtr);
#endif  /* DEBUG */
                break;

                case 99:
                locals[symbol].valPtr = ca_change_int_value(newPort);
                /*
                 * First allocate some memory and then copy the value of the new 
                 * Port into it.
     */
                locals[symbol].strPtr = (char *)malloc(sizeof(newPort) );
                /* 
                 * Now, check that the memory was actually allocated.
                 */
                if (locals[symbol].strPtr == NULL)
                        {
                        fprintf(stderr, "Cannot allocate memory for locals[symbol].strPtr\n");
                        exit(8);
                        }
                
                strcpy(locals[symbol].strPtr, newPort);
                /*
                 * locals[symbol].strPtr = newPort;
                 */     
                break;

                default:
                fprintf(stderr, "Error; unknown scope: %d\n", dictionary[symbol].varScope);
                break;
                }

 /*
  * Write the new value of the variable to the correct place in 
  * this array.  (First, set a mutex lock ???).
         */

 /*
         * Write the new value of this variable back to the config. file
         */

ca_writeNewValue(symbol, newPort);

                printf("DEBUG 3: New value of StringPtr: %s\n", globals[symbol].strPtr);

}

int *ca_change_int_value(char value[])
/* [<][>][^][v][top][bottom][index][help] */
{
void *tempPtr;

/*
 * Check the return value of malloc() in case we did not actually get
 * the memory.
 */
tempPtr = malloc(sizeof(int) );
if (tempPtr == NULL)
                {
                fprintf(stderr, "Cannot allocate memory for tempPtr\n");
                exit (8);
                }

sscanf(value, "%d", (int *) tempPtr);
return(tempPtr);
}



void testFunction(values_t array[])
/* [<][>][^][v][top][bottom][index][help] */
{
        printf("\nInside the Test function.\n");
        }


void ca_getDatabase(ca_database_t db)
/* [<][>][^][v][top][bottom][index][help] */
{
printf("\n%s\t%s\t%s\t%s\t%s\n", db.host, db.port, db.user, db.password, db.dbName);
}

void ca_getSource(ca_database_list_t src)
/* [<][>][^][v][top][bottom][index][help] */
{
printf("\n%s\t%s\t%s\t%s\t%s\t%s\n", src.name, (src.db).host, (src.db).port, (src.db).user, (src.db).password, (src.db).dbName);
}


void ca_getAllSources(GSList *sources)
/* [<][>][^][v][top][bottom][index][help] */
{
/*
 * Function Prototype of getSource().
 * getSource can only be called from within getAllSources().
 */
void ca_getAsource(ca_database_list_t *);
         
GSList *currentPtr;     /* Pointer to the structure at which we look. */

/*
 * Look at the first member of the linked-list of sources.
 */
currentPtr = sources;

/*
 * Look at each data component of the source list,
 * untill we reach the end of the list.
 */
while(currentPtr != NULL)
        {
 ca_database_list_t *srcPtr = currentPtr->data;
printf("\n%s\t%s\t%s\t%s\t%s\t%s\n", srcPtr->name, (srcPtr->db).host, (srcPtr->db).port, (srcPtr->db).user, (srcPtr->db).password, (srcPtr->db).dbName);
 currentPtr = currentPtr->next; 
        }
}

void ca_getAsource(ca_database_list_t *srcPtr)
/* [<][>][^][v][top][bottom][index][help] */
{
printf("\n%s\t%s\t%s\t%s\t%s\t%s\n", srcPtr->name, (srcPtr->db).host, (srcPtr->db).port, (srcPtr->db).user, (srcPtr->db).password, (srcPtr->db).dbName);
}


void ca_set_boolean(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
/*************************************************************
 *                                                                                                                                                              *
 * ca_set_boolean()                                                                                                             *
 *                                                                                                                                                              *
        *                                                                                                                                                               *
 * Parameters                                                                                                                           *
 *                                                                                                                                                              *
        *       symbol -- the symbol for the variable.                                                  *
 *                                                                                                                                                              *
        *                                                                                                                                                               *
        * Returns                                                                                                                                       *
        *                                                                                                                                                               *
        *               nothing                                                                                                                         *
 *                                                                                                                                                              *
        *                                                                                                                                                               *
 * Remarks                                                                                                                                      *
        *                                                                                                                                                               *
        *       Must check that a sensible value is given as input.             *
        *                                                                                                                                                               *
        *                                                                                                                                                               *
        *************************************************************/


char newTestmodeStr[2];
int newTestmodeVal;     /* The new value of the testmode variable. */
int invalid;                            /* Flag to indicate an invalid new value.  */

FILE *testPtr, *tempPtr;                        /* The pointer to the files. */
char name[STRLENGTH];                           /* The name of the variable. */
char value[STRLENGTH];                  /* The value of the variable. */

/*
 * Function to change the value in a given values array.
 * This function can only be called from within ca_set_boolean().
 */
int *ca_change_int_value(char []);


/*
        * Using the symbol, look at the appropriate place in the 
 * dictionary.
        */
#ifdef DEBUG
printf("\nca_set_int() function called .....\n");
printf("Variable type: %s\n", dictionary[symbol].varType);
#endif          /* DEBUG */

/*
 * Check that the function is attempting to set the correct type of 
 * value.  If not, do not set the value, but exit instead.
 */

if (strcmp(dictionary[symbol].varType, "CA_BOOLEAN") != 0)
                {
                fprintf(stderr, "Error: CA_BOOLEAN data type expected.\n");
                exit (51);
                }

/*
 * First, flush the input stream.
 */
fflush(stdin);


/*
 * Make sure that a reasonable, sensible value of bind-port has
 * been read from the keyboard.
 */

do      {
                        /*
                         * Prompt for the new value of the testmode.
                         */

                        printf("\nNew value of testmode (0 or 1) >>> ");
                        scanf("%s", newTestmodeStr);

                        /*
                         * We scanf() the value as a string, but we want it to be an
                         * integer.  Thus, we use sscanf() to scanf the value from the
         * string-variable and store it as an integer in an integer
                         * variable.
                         */ 
                        sscanf(newTestmodeStr, "%d", &newTestmodeVal);

                        /*
        * We only change the testmode when the user is absolutely sure
                         * that they want to change.  Thus, we only accept two possible
                         * values for testmode.
                         */

                        if ( (newTestmodeVal < 0) || (newTestmodeVal > 1) )
                                {
                                invalid = 1;
                                puts("Only '0' or '1' accepted as value for testmode.");
                                }
                        else
                                {
                                invalid = 0;
                                }       
                } while(invalid);
        

/*
        * Lock the value of the variable before changing it.
 */

mutex_lock(&Lock);


/*
 * Choose the appropriate values array.
 */

switch(dictionary[symbol].varScope)
                {
                /*
                 * If the variable has global scope, 
                 * write it into the globals array.
                 * If it has local scope, 
                 * write it into the local array.
                 * If the scope cannot be found, then report an error.
     */
                case 1:
                globals[symbol].valPtr = ca_change_int_value(newTestmodeStr);
                globals[symbol].strPtr = newTestmodeStr;
                break;

                case 99:
                locals[symbol].valPtr = ca_change_int_value(newTestmodeStr);
                locals[symbol].strPtr = newTestmodeStr;
                break;

                default:
                fprintf(stderr, "Error: unknown scope: %d\n", dictionary[symbol].varScope);
                break;
                }

/*
        * Write the new value of this variable back to the config file.
 *
 * To be implemented.
 */

/*
 * Find the actual name of the variable from the dictionary
 * structure (use the variable symbol as an index into the
 * array of dictionary structures.
 */
 
        printf("Name of variable to be changed: %s\n", dictionary[symbol].varName);
        printf("Type of variable to be changed: %s\n", dictionary[symbol].varType);

/*
        * Open the test config file for reading .....
 */
if ( (testPtr = fopen(testFile, "r")) == NULL)
        {
        printf("File \"%s\" could not be opened.\n", testFile);
        exit (51);
        }

/*
        * Open the temporary file for writing .....
 */
if ((tempPtr = fopen(tempFile, "w")) == NULL)
        {
        printf("File \"%s\" could not be opened.\n", tempFile);
 exit (51);
 }

/*
 * Read the first record in the test config file.
 */
 
 fscanf(testPtr, "%s", name);
 fgets(value, sizeof(value), testPtr);
 
 /*
  * If the last character of "value" is '\n',
  * replace it with '\0'.
  */
        if (value[strlen(value) - 1] == '\n')
                {
                printf("The value string is %s", value);
                printf("Replacing last character of \"%s\" with the NULL character\n", name);
                value[strlen(value) - 1] = '\0';
                printf("The new value string is %s", value);
                }


/*
        * While there are records to be read in the test config file:
        *               Write the current record into the temporary file.
 *              Read the next record in the config file.
 * Repeat untill the EOF has been reached.
 */
        
while(!feof(testPtr) )
        {
 fprintf(tempPtr, "%s %s\n", name, value);
 fscanf(testPtr, "%s", name);
        fgets(value, sizeof(value), testPtr);

 /*
  * If the last character of "value" is '\n',
  * replace it with '\0'.
  */
        if (value[strlen(value) - 1] == '\n')
                {
                printf("The last character of the value string is %c", value[strlen(value) - 1]);
                printf("The value string is %s", value);
                printf("Replacing last character of \"%s\" with the NULL character\n",name);
                value[strlen(value) - 1] = '\0';
                printf("The new value string is %s", value);
                }

 
 /*
  * if we read the variable that we want to change,
  * stop reading this file and print only the name
  * of this variable to the temporary file.
  */

        /*
         * If we read the variable that we want to change,
  * replace the value of this variable in the config
  * file with the value supplied from the keyboard.
  *
  */
        if ( strcmp(name, dictionary[symbol].varName) == 0)
                {
                strcpy(value, newTestmodeStr);
                printf("The replacement string is %s", value);
                }
        /*
         * Flush the pointer to the test config file.
         */
        fflush(testPtr);

        }                               
 /* 
         * Here ends the loop that writes the config file, with the
  * new variable, to the temporary file.
         */

/*
 *
 * While !(the record to be updated)
        *       BEGIN
        *  Write the record to the temporary file
 *  Read the next record in the config file
 *      END
 *
 * Write the new value to the temporary file
 * Read the next record in the config file
 * COMMENT: this is the record to be updated.
 * COMMENT: discard this record.
 * 
 * Read the next record in the config file
        *
 * While !(EOF)
        *       BEGIN
        *  write the record to the temporary file
 *  read the next record in the config file
 *  END
 *
 * Close Config file
 * Close Temporary file
 *
 * Open Temporary file for reading
 * Open Config file for writing
 *
 * Read the next record of the Temporary file
 *
 * While (!EOF of Temporary file)
        *       BEGIN
        *  write the record into the Config file
        *  read the next record of the Temporary file
 *  END
 * 
        *       Close Temporary file
 *  Close Config file
 *
 */

fclose(testPtr);
fclose(tempPtr);

/*
        * Now, flush the file pointers
 */
        fflush(testPtr);
        fflush(tempPtr);

/*
 * Open the temporary file for reading.
        * Open the config file for writing.
 * Write the contents of the temporary file
 * into the config file.
 */

/*
        * Open the temporary file for reading .....
 */
if ((tempPtr = fopen(tempFile, "r")) == NULL)
        {
        printf("File \"%s\" could not be opened for reading.\n", tempFile);
 exit (51);
 }

/*
        * Open the config file for writing .....
 */
if ((testPtr = fopen(testFile, "w")) == NULL)
        {
        printf("File \"%s\" could not be opened for writing.\n", testFile);
 exit (51);
 }

/*
 * Read the first record in the temporary file.
 */
 
 fscanf(tempPtr, "%s", name);
 fgets(value, sizeof(value), tempPtr);
        printf("\nFIRST LINE: %s %s", name, value);
 
 
/*
        * While there are records to be read in the temporary file:
        *               Write the current record into the test config file.
 *              Read the next record in the temporary file.
 * Repeat untill the EOF has been reached.
 */
        
while(!feof(tempPtr) )
        {
 fprintf(testPtr, "%s %s", name, value);
 fscanf(tempPtr, "%s", name);
        fgets(value, sizeof(value), tempPtr);
 }

fclose(testPtr);
fclose(tempPtr);

/*
        * Unlock the value of the variable after setting it and writing the
 * new value back to the configuration (and the dictionary) file.
        *
 */
        mutex_unlock(&Lock);

}


void ca_set_dirlist(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{
/****************************************************************
        * ca_set_dirlist()                                                                                                                      *
 *                                                                                                                                                                      *
 * Parameters                                                                                                                                   *
        *               symbol -- the symbol of the variable.                                                   *
 *                                                                                                                                                                      *
 * Returns                                                                                                                                              *
        *               1 if successful, 0 if not successful.                                                   *
        *                                                                                                                                                                       *
        * Remarks                                                                                                                                               *
 *              Writing the new value back to the config file has yet to *
        *               be implemented.                                                                                                         *
 *                                                                                                                                                                      *
        ****************************************************************/

 char newDir[80];
 /*
  * Declare a pointer to a values_t variable.
         * Later, we shall assign this pointer to the first element
  * of either the globals or the locals array, as appropriate.
  */
 values_t *hereValues;

        /*
         * Using the symbol, look in the appropriate place in the dictionary.
         */
#ifdef DEBUG
        printf("\nca_set_dirlist() function called ..... \n");
 printf("Variable type: %s\n", dictionary[symbol].varType);
#endif

        /*
         * First, flush the input stream.
         */
        fflush(stdin);

        /* 
         * Prompt for the new value of the directory.
         */
        printf("\nNew value of %s [80 characters, maximum] >>> ", dictionary[symbol].varName);
 scanf("%s", newDir);
        
/*
 * Make sure that a reasonable, sensible value of the directory 
 * value has been read from the keyboard.
 *
 * How do we implement this ???
 *
 */


 /*
  * Make sure that the function is attempting to set the correct type
  * of value.  If not, do not set the value - and exit.
  */

if (strcmp(dictionary[symbol].varType, "CA_DIRLIST") != 0)
                {
                fprintf(stderr, "Error: unexpected variable type.\n");
                exit(51);
                }       

        /*
  * Choose the appropriate values array.
         * Assign a temporary pointer to this array.
         */

        switch(dictionary[symbol].varScope)
                {
                /* If the variable has global scope,
                 * write it into the globals array.
                 * If it has local scope, 
                 * write it into the locals array.
         * If the scope cannot be found, report an error.
                 */
                case 1:
                hereValues = globals;
                break;

                case 99:
                hereValues = locals;
                break;

                default:
                fprintf(stderr, "Error: Unknown scope: %d\n", dictionary[symbol].varScope);
                break;
                }


        /*
  * Check for the presence of the mutex lock:
         *              if present,
         *              wait until it is available;
         *              else
  *                     get the lock and proceed with the change of value.
         */
        
        /*
  * Write the new value of the variable to the correct place
         * in the [appropriate] values array.
         *
  * Note that there is a check to see if malloc() actually worked .....
         */

                hereValues[symbol].valPtr = (char *)malloc(80);
                if (hereValues[symbol].valPtr == NULL)
                        {
                        fprintf(stderr, "Cannot alllocate memory for hereValuesvlPtr\n");
                        exit (8);
                        }
                strcpy(hereValues[symbol].valPtr,newDir); 


                hereValues[symbol].strPtr = (char *)malloc(sizeof(newDir) );
                if (hereValues[symbol].strPtr == NULL)
                        {
                        fprintf(stderr, "Cannot alllocate memory for hereValuestPtr\n");
                        exit (8);
                        }
                strcpy(hereValues[symbol].strPtr, newDir);

        /*
         * Free the temporary pointer, hereValues.
  *
  */
        free(hereValues);
        hereValues = NULL;
                
        /*
         * Release the mutex lock.
         */

        /*
         * Write the new value of this variable back to the config file.
         */

}


void ca_set_string(int symbol)
/* [<][>][^][v][top][bottom][index][help] */
{

/****************************************************************
        * ca_set_string()                                                                                                                       *
 *                                                                                                                                                                      *
 * Parameters                                                                                                                                   *
        *               symbol -- the symbol of the variable.                                                   *
 *                                                                                                                                                                      *
 * Returns                                                                                                                                              *
        *               1 if successful, 0 if not successful ?                                                  *
        *                                                                                                                                                                       *
        * Remarks                                                                                                                                               *
 *              Writing the new value back to the config file has yet to *
        *               be implemented.                                                                                                         *
 *                                                                                                                                                                      *
        ****************************************************************/

 char newString[80];    /* May need to make this bigger. */

 /*
  * Declare a pointer to a values_t variable.
         * Later, we shall assign this pointer to the first element
  * of either the globals or the locals array, as appropriate.
  */
 values_t *hereValues;

        /*
         * Using the symbol, look in the appropriate place in the dictionary.
         */
#ifdef DEBUG
        printf("\nca_set_string() function called ..... \n");
 printf("Variable type: %s\n", dictionary[symbol].varType);
#endif

        /*
         * First, flush the input stream.
         */
        fflush(stdin);

        /* 
         * Prompt for the new value of the string.
         */
        printf("\nNew value of %s [80 characters, maximum] >>> ", dictionary[symbol].varName);
gets(newString);
        
/*
 * Make sure that a reasonable, sensible value of the string
 * value has been read from the keyboard.
 *
 * How do we implement this ???
 *
 */


 /*
  * Make sure that the function is attempting to set the correct type
  * of value.  If not, do not set the value - and exit.
  */

if (strcmp(dictionary[symbol].varType, "CA_STRING") != 0)
                {
                fprintf(stderr, "Error: unexpected variable type.\n");
                exit(51);
                }       

        /*
  * Choose the appropriate values array.
         * Assign a temporary pointer to this array.
         */

        switch(dictionary[symbol].varScope)
                {
                /* If the variable has global scope,
                 * write it into the globals array.
                 * If it has local scope, 
                 * write it into the locals array.
         * If the scope cannot be found, report an error.
                 */
                case 1:
                hereValues = globals;
                break;

                case 99:
                hereValues = locals;
                break;

                default:
                fprintf(stderr, "Error: Unknown scope: %d\n", dictionary[symbol].varScope);
                break;
                }


        /*
  * Check for the presence of the mutex lock:
         *              if present,
         *              wait until it is available;
         *              else
  *                     get the lock and proceed with the change of value.
         */
        mutex_lock(&Lock);
        
        /*
  * Write the new value of the variable to the correct place
         * in the [appropriate] values array.
  * Note the check to the return value of malloc() to see if the
         * memory was actually obtained.
         */

                hereValues[symbol].valPtr = (char *)malloc(80);
                if (hereValues[symbol].valPtr == NULL)
                        {
                        fprintf(stderr, "Cannot allocate memory for hereValues[symbol].valPtr\n");
                        exit (8);
                        }
                strcpy(hereValues[symbol].valPtr, newString); 


                hereValues[symbol].strPtr = (char *)malloc(sizeof(newString) );
                if (hereValues[symbol].strPtr == NULL)
                        {
                        fprintf(stderr, "Cannot allocate memory for hereValues[symbol].strPtr\n");
                        exit (8);
                        }
                strcpy(hereValues[symbol].strPtr, newString);

        /*
         * Free the temporary pointer, hereValues.
         *
  */
        free(hereValues);
 hereValues = NULL;

        /*
         * Release the mutex lock.
         */
        mutex_unlock(&Lock);

        /*
         * Write the new value of this variable back to the config file.
         * Implement this later ?
         */

}


int ca_writeNewValue(int dictSymbol, char *newValue)
/* [<][>][^][v][top][bottom][index][help] */
{

FILE *confPtr;                                          /* Pointer to config file */
FILE *tempPtr;                                          /* The pointer to temp file. */
char name[STRLENGTH];                           /* The name of the variable. */
char value[STRLENGTH];                  /* The value of the variable. */


/*
 * Find the actual name of the variable from the dictionary
 * structure (use the variable symbol as an index into the
 * array of dictionary structures.
 */
#ifdef DEBUG 
        printf("Name of variable to be changed: %s\n", dictionary[dictSymbol].varName);
        printf("Type of variable to be changed: %s\n", dictionary[dictSymbol].varType);
#endif  /* DEBUG */

/*
        * Open the test config file for reading .....
 */
if ( (confPtr = fopen(testFile, "r")) == NULL)
        {
        printf("File \"%s\" could not be opened.\n", testFile);
        exit (51);
        }

/*
        * Open the temporary file for writing .....
 */
if ((tempPtr = fopen(tempFile, "w")) == NULL)
        {
        printf("File \"%s\" could not be opened.\n", tempFile);
 exit (51);
 }

/*
 * Read the first record in the test config file.
 */
 
 fscanf(confPtr, "%s", name);
 fgets(value, sizeof(value), confPtr);
 
 /*
  * If the last character of "value" is '\n',
  * replace it with '\0'.
  */
        if (value[strlen(value) - 1] == '\n')
                {
#ifdef DEBUG
                printf("The value string is %s", value);
                printf("Replacing last character of \"%s\" with the NULL character\n", name);
#endif  /* DEBUG */

                value[strlen(value) - 1] = '\0';

#ifdef DEBUG
                printf("The new value string is %s", value);
#endif  /* DEBUG */
                }

        /*
         * If we read the variable that we want to change,
  * replace the value of this variable in the config
  * file with the value supplied from the keyboard.
  *
  */
        if ( strcmp(name, dictionary[dictSymbol].varName) == 0)
                {
                strcpy(value, newValue);

#ifdef DEBUG
                printf("The replacement string is %s", value);
#endif  /* DEBUG */
}

/*
        * While there are records to be read in the test config file:
        *               Write the current record into the temporary file.
 *              Read the next record in the config file.
 * Repeat untill the EOF has been reached.
 */
        
while(!feof(confPtr) )
        {
 fprintf(tempPtr, "%s %s\n", name, value);
 fscanf(confPtr, "%s", name);
        fgets(value, sizeof(value), confPtr);

 /*
  * If the last character of "value" is '\n',
  * replace it with '\0'.
  */
        if (value[strlen(value) - 1] == '\n')
                {
#ifdef DEBUG
                printf("The last character of the value string is %c", value[strlen(value) - 1]);
                printf("The value string is %s", value);
                printf("Replacing last character of \"%s\" with the NULL character\n",name);
#endif  /* DEBUG */

                value[strlen(value) - 1] = '\0';
#ifdef DEBUG
                printf("The new value string is %s", value);
#endif  /* DEBUG */
                }


        /*
         * If we read the variable that we want to change,
  * replace the value of this variable in the config
  * file with the value supplied from the keyboard.
  *
  */
        if ( strcmp(name, dictionary[dictSymbol].varName) == 0)
                {
                strcpy(value, newValue);

#ifdef DEBUG
                printf("The replacement string is %s", value);
#endif  /* DEBUG */
                }

        /*
         * Flush the pointer to the test config file.
         */
        fflush(confPtr);

        }                               
 /* 
         * Here ends the loop that writes the config file, with the
  * new variable, to the temporary file.
         */

/*
 *
 * While !(the record to be updated)
        *       BEGIN
        *  Write the record to the temporary file
 *  Read the next record in the config file
 *      END
 *
 * Write the new value to the temporary file
 * Read the next record in the config file
 * COMMENT: this is the record to be updated.
 * COMMENT: discard this record.
 * 
 * Read the next record in the config file
        *
 * While !(EOF)
        *       BEGIN
        *  write the record to the temporary file
 *  read the next record in the config file
 *  END
 *
 * Close Config file
 * Close Temporary file
 *
 * Open Temporary file for reading
 * Open Config file for writing
 *
 * Read the next record of the Temporary file
 *
 * While (!EOF of Temporary file)
        *       BEGIN
        *  write the record into the Config file
        *  read the next record of the Temporary file
 *  END
 * 
        *       Close Temporary file
 *  Close Config file
 *
 */

fclose(confPtr);
fclose(tempPtr);

/*
        * Now, flush the file pointers
 */
        fflush(confPtr);
        fflush(tempPtr);

/*
 * Open the temporary file for reading.
        * Open the config file for writing.
 * Write the contents of the temporary file
 * into the config file.
 */

/*
        * Open the temporary file for reading .....
 */
if ((tempPtr = fopen(tempFile, "r")) == NULL)
        {
        printf("File \"%s\" could not be opened for reading.\n", tempFile);
 exit (51);
 }

/*
        * Open the config file for writing .....
 */
if ((confPtr = fopen(testFile, "w")) == NULL)
        {
        printf("File \"%s\" could not be opened for writing.\n", testFile);
 exit (51);
 }

/*
 * Read the first record in the temporary file.
 */
 
 fscanf(tempPtr, "%s", name);
 fgets(value, sizeof(value), tempPtr);
#ifdef DEBUG
        printf("\nFIRST LINE: %s %s", name, value);
#endif /* DEBUG */
 
/*
        * While there are records to be read in the temporary file:
        *               Write the current record into the test config file.
 *              Read the next record in the temporary file.
 * Repeat untill the EOF has been reached.
 */
        
while(!feof(tempPtr) )
        {
 fprintf(confPtr, "%s %s", name, value);
 fscanf(tempPtr, "%s", name);
        fgets(value, sizeof(value), tempPtr);
 }

fclose(confPtr);
fclose(tempPtr);
unlink(tempFile);

return(0);
}


int ca_getStorageLocation(char *confVar, dict_t woordenboek[], int size)
/* [<][>][^][v][top][bottom][index][help] */
/*************************************************************
 * ca_getStorageLocation()                                                                                              *
        *       - takes the name of a config variable and searches the          *
 *    dictionary structure for the storage location for this *
 *        variable.                                                                                                                             *
 *                                                                                                                                                              *
 * Parameters                                                                                                                           *
        *       confVar -- the string variable that contains the name    *
 *                of the variable.                                                                              *       
 *  woordenboek -- the dictionary structure to be searched      *
        *       size                    -- the size of the dictionary structure to      *
 *                 searched.                                                                                    *
 *                                                                                                                                                              *
 * Returns                                                                                                                                      *
        *       the location (integer) in the values array.                                     *
 *                                                                                                                                                              *
        *************************************************************/
{
int i, 
where,
found = 0       ;               /* Whether or not the symbol has been found. */


#ifdef DEBUG
printf("The variable name in ca_getStorageLocation is: %s\n", confVar);
#endif /* DEBUG */

/*
 * Compares each name in the dictionary with the one for which
 * we are looking.
 */
i = 0;
while (!found && i <= size)
        {
        if (strcmp(woordenboek[i].varName, confVar) == 0)
                {
                found = 1;
                }
        else
                {
                ++i;
                }
        }

/*
        * Returns the storage location for the given variable name
 * or else returns NOT_FOUND
 */
if (found)
                {
                /*      mySymbol = atoi(woordenboek[i].varSym); */
    printf("Symbol is %s\n", woordenboek[i].varSym);
                printf("Storage Location is: %d\n", woordenboek[i].varNum);
           where = woordenboek[i].varNum; 
                }
else
                {
                fprintf(stderr, "Error: cannot find storage location for variable %s\n", confVar);      
                where = NOT_FOUND;
                }
        return (where);

}


void ca_getConfig(values_t confVars[], int size)
/* [<][>][^][v][top][bottom][index][help] */
/*************************************************************
 * ca_getConfig -- prints the strings representing the          *
 *                                         values of the configuration variables                *
 *                                                                                                                                                              *
 * Parameters                                                                                                                           *
        *               confVars -- the values_t array which stores the                 *
        *                                               values of the configuration variables.     *
        *               size -- the number of configuration variables,                  *
        *                       the number of elements in the confVars array  *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *************************************************************/
{
int i = 0;      /* A counting variable. */

puts("A dump of the strings of the values of the Config Vars:");
puts("Number\t\tString");
puts("----------");

while (i < size)
        {
        printf("%d\t\t%s\n", i, confVars[i].strPtr);
 ++i;
        }

}


int ca_getType(char *confVar, dict_t woordenboek[], int size)
/* [<][>][^][v][top][bottom][index][help] */
/****************************************************************
        * ca_getType -- returns the data type of the variable.                  *
 *                                                                                                                                                                      *
 * Parameters                                                                                                                                   *
 *              confVar -- the name of the configuration variable.                      *
        *               woordenboek -- the array of dict_t structures.                          *
        *               size -- the number of configuration variables.                          *
 *                                                                                                                                                                      *
 * Returns                                                                                                                                              *
 *              an integer representing the data type of the variable           *
 *                                                                                                                                                                      *
 ****************************************************************/
{
int i = 0,              /* Counter variable. */
                found = 0;      /* Set this == 1 when we find the variable.  */
int myType;     /* Integer representing the type of the config variable. */

/*
 * Compare each name in the dictionary with the one for which we
 * are looking.
 */
 
myType = 0;

#ifdef DEBUG
printf("ca_getType function called for variable: %s\n", confVar);
#endif  /* DEBUG */

while (!found && i <= size)
                {
                if (strcmp(woordenboek[i].varName, confVar) == 0)
                        {
                        found = 1;
#ifdef DEBUG    
printf("ca_getType function: %s, %s matched.\n", woordenboek[i].varName, confVar);
#endif  /* DEBUG */
                        }
                else
                        {
                        ++i;
                        }
                }                       

/*
        * Return the type of the config variable or
        * else return "NOT FOUND".
 */
if (found)
                {
                        if(strcmp(woordenboek[i].varType, "CA_INT") == 0)
                                {
#ifdef DEBUG
printf("ca_getType function: %s variable of type %s is Integer type\n", woordenboek[i].varName, woordenboek[i].varType);

printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
#endif /* DEBUG */
                                myType = 11;
                                printf("For type CA_INT, myType is %d\n", myType);
#ifdef DEBUG
printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
#endif /* DEBUG */
                                }
                        else
                                {
                                        if(strcmp(woordenboek[i].varType, "CA_STRING") == 0)
                                                {
#ifdef DEBUG
printf("ca_getType function: %s variable of type %s is String type\n", woordenboek[i].varName, woordenboek[i].varType);
printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
#endif /* DEBUG */
                                                myType = 12;
#ifdef DEBUG
printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
#endif /* DEBUG */
                                                }
                                        else
                                                {
                                                if (strcmp(woordenboek[i].varType, "CA_DIRLIST") == 0 )
                                                        {
#ifdef DEBUG
printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
#endif /* DEBUG */
                                                        myType = 13;
#ifdef DEBUG
printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
#endif /* DEBUG */
                                                        }
                                                else
                                                        {
                                                        if (strcmp(woordenboek[i].varType, "CA_BOOLEAN") == 0)
                                                                {
#ifdef DEBUG
printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
#endif /* DEBUG */
                                                                myType = 14;
#ifdef DEBUG
printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
#endif /* DEBUG */
                                                                }
                                                        else
                                                                {
                                                                if (strcmp(woordenboek[i].varType, "CA_SOURCETYPE") == 0)
                                                                        {       
#ifdef DEBUG
printf("ca_getType function: %s, %s\n", woordenboek[i].varName, woordenboek[i].varType);
#endif /* DEBUG */
                                                                        myType = 15;
#ifdef DEBUG
printf("ca_getType function: %s, %s, %d\n", woordenboek[i].varName, woordenboek[i].varType, myType);
#endif /* DEBUG */
                                                                        }
                                                                }
                                                        }
                                                }
                                }
                }
        else
                {
                myType = NOT_FOUND;
                }
        return(myType);
 }

/* [<][>][^][v][top][bottom][index][help] */