blob: 3b8b89d3fbe359520635c685e3e73346bd500053 [file] [log] [blame]
#include <ctype.h>
/*
* Simple ini file parser
*
* This should be copied from somewhere but, unfortunately is reinvented.
*
* Copyright (C) 2019 James.Bottomley@HansenPartnership.com
*
* SPDX-License-Identifier: LGPL-2.1-only
*/
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "openssl-pkcs11.h"
#define BUF_SIZE 4096
static char *conf_buf = NULL;
static ssize_t conf_size;
static char *read_pos;
static char *trim(char *line)
{
int len;
while (isspace(*line))
line++;
len = strlen(line);
if (len == 0)
return line;
for (--len; isspace(line[len]); --len)
;
line[len + 1] = '\0';
return line;
}
static char *read_line(void)
{
char *eol;
char *ret;
eol = strchr(read_pos, '\n');
ret = read_pos;
if (!eol)
return NULL;
*eol = '\0';
read_pos = eol + 1;
return ret;
}
static void parse_mem(void)
{
char *line, *delim;
char *section = GLOBAL_SECTION, *key, *value;
read_pos = conf_buf;
while ((line = read_line()) != NULL) {
int end;
line = trim(line);
end = strlen(line) - 1;
if (line[0] == '#' || line[0] == '\0')
continue;
if (line[0] == '[' && line[end] == ']') {
line[end] = '\0';
section = ++line;
continue;
}
delim = strchr(line, '=');
if (!delim) {
fprintf(stderr, "illegal line in config file '%s'\n",
line);
continue;
}
*delim = '\0';
key = trim(line);
value = trim(delim + 1);
cache_add(section, key, value, 0);
}
}
int parse_ini_file(void)
{
char *home = getenv("HOME");
char *conf = getenv(ENV_CONFIG);
char *end;
char config[PATH_MAX];
int fd,len;
struct stat st;
config[0] = '\0';
if (conf) {
strncpy(config, conf, sizeof(config) - 1);
} else {
strncpy(config, home, sizeof(config) - 1);
strcat(config, "/");
strcat(config, CONFIG_FILE);
}
fd = open(config, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "failed to open config file %s: %s\n",
config, strerror(errno));
return 0;
}
if (fstat(fd, &st)) {
fprintf(stderr, "failed to stat config file %s: %s\n",
config, strerror(errno));
return 0;
}
conf_size = st.st_size;
if (conf_size == 0) {
fprintf(stderr, "conf file %s is empty\n", config);
return 0;
}
conf_buf = malloc(conf_size + 2);
if (!conf_buf) {
fprintf(stderr, "failed to allocate %d bytes for con file %s\n",
(int)conf_size, config);
return 0;
}
len = read(fd, conf_buf, conf_size);
if (len < 0) {
fprintf(stderr, "failed to read config file %s: %s\n",
config, strerror(errno));
return 0;
}
if (len != conf_size) {
fprintf(stderr, "Config file %s changed while being read\n",
config);
free(conf_buf);
return 0;
}
close(fd);
/* the parser requires the file end with a newline,
* so add one if needed */
end = &conf_buf[conf_size - 1];
if (*end++ != '\n')
*end++ = '\n';
*end = '\0';
parse_mem();
cache_load_crypto_keys();
return 1;
}
void free_ini_file(void)
{
free(conf_buf);
}