void read_config()

in storm-core/src/native/worker-launcher/impl/configuration.c [118:274]


void read_config(const char* file_name) {
  FILE *conf_file;
  char *line;
  char *equaltok;
  char *temp_equaltok;
  size_t linesize = 1000;
  int size_read = 0;

  if (file_name == NULL) {
    fprintf(ERRORFILE, "ERROR: Null configuration filename passed in\n");
    exit(INVALID_CONFIG_FILE);
  }

  #ifdef DEBUG
    fprintf(LOGFILE, "read_config :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);
  if (config.confdetails == NULL) {
      fprintf(ERRORFILE, "ERROR: malloc failed while reading configuration file - 1.\n");
      exit(OUT_OF_MEMORY);
  }
  config.size = 0;
  conf_file = fopen(file_name, "r");
  if (conf_file == NULL) {
    fprintf(ERRORFILE, "ERROR: Invalid conf file provided : %s \n", file_name);
    exit(INVALID_CONFIG_FILE);
  }
  while(!feof(conf_file)) {
    line = (char *) malloc(linesize);
    if(line == NULL) {
      fprintf(ERRORFILE, "ERROR: malloc failed while reading configuration file - 2.\n");
      exit(OUT_OF_MEMORY);
    }
    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) {
      free(line);
      line = NULL;
      if(!feof(conf_file)){
        exit(INVALID_CONFIG_FILE);
      } else {
        break;
      }
    }
    int eol = strlen(line) - 1;
    if(line[eol] == '\n') {
        //trim the ending new line
        line[eol] = '\0';
    }
    //comment line
    if(line[0] == '#') {
      free(line);
      line = NULL;
      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);
      line = NULL;
      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, "read_config : Adding conf key : %s \n", equaltok);
    #endif

    memset(config.confdetails[config.size], 0, sizeof(struct confentry));
    const size_t key_tok_len = strlen(equaltok);
    config.confdetails[config.size]->key = (char *) malloc(
            sizeof(char) * (key_tok_len+1));
    if (config.confdetails[config.size]->key == NULL) {
      fprintf(LOGFILE,
          "Failed allocating memory for single configuration item\n");
      goto cleanup;
    }
    memset((void*)config.confdetails[config.size]->key, '\0', key_tok_len+1);
    strncpy((char *)config.confdetails[config.size]->key, equaltok, key_tok_len);
    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);
      line = NULL;
      free((void *)config.confdetails[config.size]->key);
      config.confdetails[config.size]->key = NULL;
      free(config.confdetails[config.size]);
      config.confdetails[config.size] = NULL;
      continue;
    }

    #ifdef DEBUG
      fprintf(LOGFILE, "read_config : Adding conf value : %s \n", equaltok);
    #endif

    const size_t val_tok_len = strlen(equaltok);
    config.confdetails[config.size]->value = (char *) malloc(
            sizeof(char) * (val_tok_len+1));
    if (config.confdetails[config.size]->value == NULL) {
      fprintf(LOGFILE,
          "Failed allocating memory for single configuration item\n");
      goto cleanup;
    }
    memset((void *)config.confdetails[config.size]->value, '\0', val_tok_len+1);
    strncpy((char *)config.confdetails[config.size]->value, equaltok, val_tok_len);
    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);
    line = NULL;
  }
 
  //close the file
  fclose(conf_file);

  if (config.size == 0) {
    fprintf(ERRORFILE, "ERROR: Invalid configuration provided in %s\n", file_name);
    exit(INVALID_CONFIG_FILE);
  }

  //clean up allocated file name
  return;
  //free spaces alloced.
  cleanup:
  if (line != NULL) {
    free(line);
    line = NULL;
  }
  fclose(conf_file);
  free_configurations();
  return;
}