blob: bbacbf7efcf0e09ecbd24e7be18148352f5b7a14 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "configuration.h"
char * hadoop_conf_dir;
struct configuration config={.size=0, .confdetails=NULL};
//clean up method for freeing configuration
void free_configurations() {
int i = 0;
for (i = 0; i < config.size; i++) {
if (config.confdetails[i]->key != NULL) {
free((void *)config.confdetails[i]->key);
}
if (config.confdetails[i]->value != NULL) {
free((void *)config.confdetails[i]->value);
}
free(config.confdetails[i]);
}
if (config.size > 0) {
free(config.confdetails);
}
config.size = 0;
}
//function used to load the configurations present in the secure config
void get_configs() {
FILE *conf_file;
char *line;
char *equaltok;
char *temp_equaltok;
size_t linesize = 1000;
int size_read = 0;
int str_len = 0;
char *file_name = NULL;
#ifndef HADOOP_CONF_DIR
str_len = strlen(CONF_FILE_PATTERN) + strlen(hadoop_conf_dir);
file_name = (char *) malloc(sizeof(char) * (str_len + 1));
#else
str_len = strlen(CONF_FILE_PATTERN) + strlen(HADOOP_CONF_DIR);
file_name = (char *) malloc(sizeof(char) * (str_len + 1));
#endif
if (file_name == NULL) {
fprintf(LOGFILE, "Malloc failed :Out of memory \n");
return;
}
memset(file_name,'\0',str_len +1);
#ifndef HADOOP_CONF_DIR
snprintf(file_name,str_len, CONF_FILE_PATTERN, hadoop_conf_dir);
#else
snprintf(file_name, str_len, CONF_FILE_PATTERN, HADOOP_CONF_DIR);
#endif
#ifdef DEBUG
fprintf(LOGFILE, "get_configs :Conf file name is : %s \n", file_name);
#endif
//allocate space for ten configuration items.
config.confdetails = (struct confentry **) malloc(sizeof(struct confentry *)
* MAX_SIZE);
config.size = 0;
conf_file = fopen(file_name, "r");
if (conf_file == NULL) {
fprintf(LOGFILE, "Invalid conf file provided : %s \n", file_name);
free(file_name);
return;
}
while(!feof(conf_file)) {
line = (char *) malloc(linesize);
if(line == NULL) {
fprintf(LOGFILE, "malloc failed while reading configuration file.\n");
goto cleanup;
}
size_read = getline(&line,&linesize,conf_file);
//feof returns true only after we read past EOF.
//so a file with no new line, at last can reach this place
//if size_read returns negative check for eof condition
if (size_read == -1) {
if(!feof(conf_file)){
fprintf(LOGFILE, "getline returned error.\n");
goto cleanup;
}else {
break;
}
}
//trim the ending new line
line[strlen(line)-1] = '\0';
//comment line
if(line[0] == '#') {
free(line);
continue;
}
//tokenize first to get key and list of values.
//if no equals is found ignore this line, can be an empty line also
equaltok = strtok_r(line, "=", &temp_equaltok);
if(equaltok == NULL) {
free(line);
continue;
}
config.confdetails[config.size] = (struct confentry *) malloc(
sizeof(struct confentry));
if(config.confdetails[config.size] == NULL) {
fprintf(LOGFILE,
"Failed allocating memory for single configuration item\n");
goto cleanup;
}
#ifdef DEBUG
fprintf(LOGFILE, "get_configs : Adding conf key : %s \n", equaltok);
#endif
memset(config.confdetails[config.size], 0, sizeof(struct confentry));
config.confdetails[config.size]->key = (char *) malloc(
sizeof(char) * (strlen(equaltok)+1));
strcpy((char *)config.confdetails[config.size]->key, equaltok);
equaltok = strtok_r(NULL, "=", &temp_equaltok);
if (equaltok == NULL) {
fprintf(LOGFILE, "configuration tokenization failed \n");
goto cleanup;
}
//means value is commented so don't store the key
if(equaltok[0] == '#') {
free(line);
free((void *)config.confdetails[config.size]->key);
free(config.confdetails[config.size]);
continue;
}
#ifdef DEBUG
fprintf(LOGFILE, "get_configs : Adding conf value : %s \n", equaltok);
#endif
config.confdetails[config.size]->value = (char *) malloc(
sizeof(char) * (strlen(equaltok)+1));
strcpy((char *)config.confdetails[config.size]->value, equaltok);
if((config.size + 1) % MAX_SIZE == 0) {
config.confdetails = (struct confentry **) realloc(config.confdetails,
sizeof(struct confentry **) * (MAX_SIZE + config.size));
if (config.confdetails == NULL) {
fprintf(LOGFILE,
"Failed re-allocating memory for configuration items\n");
goto cleanup;
}
}
if(config.confdetails[config.size] )
config.size++;
free(line);
}
//close the file
fclose(conf_file);
//clean up allocated file name
free(file_name);
return;
//free spaces alloced.
cleanup:
if (line != NULL) {
free(line);
}
fclose(conf_file);
free(file_name);
free_configurations();
return;
}
/*
* function used to get a configuration value.
* The function for the first time populates the configuration details into
* array, next time onwards used the populated array.
*
*/
const char * get_value(const char* key) {
int count;
if (config.size == 0) {
get_configs();
}
if (config.size == 0) {
fprintf(LOGFILE, "Invalid configuration provided\n");
return NULL;
}
for (count = 0; count < config.size; count++) {
if (strcmp(config.confdetails[count]->key, key) == 0) {
return strdup(config.confdetails[count]->value);
}
}
return NULL;
}
/**
* Function to return an array of values for a key.
* Value delimiter is assumed to be a comma.
*/
const char ** get_values(const char * key) {
const char ** toPass = NULL;
const char *value = get_value(key);
char *tempTok = NULL;
char *tempstr = NULL;
int size = 0;
int len;
//first allocate any array of 10
if(value != NULL) {
toPass = (const char **) malloc(sizeof(char *) * MAX_SIZE);
tempTok = strtok_r((char *)value, ",", &tempstr);
if (tempTok != NULL) {
while (1) {
toPass[size++] = tempTok;
tempTok = strtok_r(NULL, ",", &tempstr);
if(tempTok == NULL){
break;
}
if((size % MAX_SIZE) == 0) {
toPass = (const char **) realloc(toPass,(sizeof(char *) *
(MAX_SIZE * ((size/MAX_SIZE) +1))));
}
}
} else {
toPass[size] = (char *)value;
}
}
if(size > 0) {
toPass[size] = NULL;
}
return toPass;
}