| /** |
| * 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; |
| } |
| |