From 04beb1b0838a644c2199677e2d6cefa41ad404a3 Mon Sep 17 00:00:00 2001 From: notify Date: Wed, 8 Mar 2023 15:00:39 +0800 Subject: [PATCH 1/3] init struct conf_opt --- a/.gitignore | 1 + a/CMakeLists.txt | 10 +++++++++ a/conf.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ a/conf.h | 29 +++++++++++++++++++++++++ a/main.c | 6 ++++++ a/parse_args.c | 0 a/read_conf.c | 0 7 files changed, 102 insertions(+) create mode 100644 a/.gitignore create mode 100644 a/CMakeLists.txt create mode 100644 a/conf.c create mode 100644 a/conf.h create mode 100644 a/parse_args.c create mode 100644 a/read_conf.c diff --git a/a/.gitignore b/a/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/a/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/a/CMakeLists.txt b/a/CMakeLists.txt new file mode 100644 index 0000000..85ad535 --- /dev/null +++ b/a/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.16) + +add_definitions(-D_GNU_SOURCE) + +add_executable(conf_demo + main.c + conf.c + parse_args.c + read_conf.c +) diff --git a/a/conf.c b/a/conf.c new file mode 100644 index 0000000..658ed69 --- /dev/null +++ b/a/conf.c @@ -0,0 +1,56 @@ +#include "conf.h" +#include +#include + +conf_opts *Config = NULL; + +conf_opts *create_conf() { + conf_opts *ret = malloc(sizeof(conf_opts)); + // set default config here + set_config(ret, CONF_CGI_ROOT, "/usr/local/var/www/cgi-bin"); + set_config(ret, CONF_DEFAULT_FILE, "*"); + set_config(ret, CONF_DOCUMENT_ROOT, "/usr/local/var/www"); + set_config(ret, CONF_CONFIG_FILE, "/etc/SHTTPD.conf"); + set_config(ret, CONF_LISTEN_PORT, "8080"); + set_config(ret, CONF_MAX_CLIENT, "4"); + set_config(ret, CONF_TIMEOUT, "3"); + return ret; +} + +void set_config(conf_opts *conf, conf_type key, const char *value) { + switch (key) { + case CONF_CGI_ROOT: + free(conf->cgi_root); + conf->cgi_root = strdup(value); + break; + case CONF_DEFAULT_FILE: + free(conf->default_file); + conf->default_file = strdup(value); + break; + case CONF_DOCUMENT_ROOT: + free(conf->document_root); + conf->document_root = strdup(value); + break; + case CONF_CONFIG_FILE: + free(conf->config_file); + conf->config_file = strdup(value); + break; + case CONF_LISTEN_PORT: + conf->listen_port = atoi(value); + break; + case CONF_MAX_CLIENT: + conf->max_client = atoi(value); + break; + case CONF_TIMEOUT: + conf->timeout = atoi(value); + break; + } +} + +void free_conf(conf_opts *conf) { + free(conf->config_file); + free(conf->cgi_root); + free(conf->default_file); + free(conf->document_root); + free(conf); +} diff --git a/a/conf.h b/a/conf.h new file mode 100644 index 0000000..cc1d4de --- /dev/null +++ b/a/conf.h @@ -0,0 +1,29 @@ +#pragma once + +struct conf_opts { + char *cgi_root; + char *default_file; + char *document_root; + char *config_file; + int listen_port; + int max_client; + int timeout; +}; + +typedef struct conf_opts conf_opts; + +typedef enum { + CONF_CGI_ROOT, + CONF_DEFAULT_FILE, + CONF_DOCUMENT_ROOT, + CONF_CONFIG_FILE, + CONF_LISTEN_PORT, + CONF_MAX_CLIENT, + CONF_TIMEOUT, +} conf_type; + +conf_opts *create_conf(); +void set_config(conf_opts *conf, conf_type key, const char *value); +void free_conf(conf_opts *conf); + +extern conf_opts *Config; diff --git a/a/main.c b/a/main.c index 6c0e70d..89a89d7 100644 --- a/a/main.c +++ b/a/main.c @@ -1,6 +1,12 @@ +#include "conf.h" #include #include +extern void parse_arg(int argc, char **argv); + int main(int argc, char **argv) { + Config = create_conf(); + parse_arg(argc, argv); + free_conf(Config); return 0; } diff --git a/a/parse_args.c b/a/parse_args.c new file mode 100644 index 0000000..e69de29 diff --git a/a/read_conf.c b/a/read_conf.c new file mode 100644 index 0000000..e69de29 -- Gitee From fe4a38516615d06d0452c0227020852e4c87dabb Mon Sep 17 00:00:00 2001 From: notify Date: Wed, 8 Mar 2023 15:26:57 +0800 Subject: [PATCH 2/3] parse args --- a/conf.c | 11 ++++++++ a/conf.h | 1 + a/main.c | 3 +++ a/parse_args.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/a/conf.c b/a/conf.c index 658ed69..457394f 100644 --- a/a/conf.c +++ b/a/conf.c @@ -1,4 +1,5 @@ #include "conf.h" +#include #include #include @@ -47,6 +48,16 @@ void set_config(conf_opts *conf, conf_type key, const char *value) { } } +void print_config(conf_opts *conf) { + printf("CGIRoot=%s\n", conf->cgi_root); + printf("DefaultFile=%s\n", conf->default_file); + printf("ConfigFile=%s\n", conf->config_file); + printf("DocumentRoot=%s\n", conf->document_root); + printf("ListenPort=%d\n", conf->listen_port); + printf("MaxClient=%d\n", conf->max_client); + printf("TimeOut=%d\n", conf->timeout); +} + void free_conf(conf_opts *conf) { free(conf->config_file); free(conf->cgi_root); diff --git a/a/conf.h b/a/conf.h index cc1d4de..598a887 100644 --- a/a/conf.h +++ b/a/conf.h @@ -24,6 +24,7 @@ typedef enum { conf_opts *create_conf(); void set_config(conf_opts *conf, conf_type key, const char *value); +void print_config(conf_opts *conf); void free_conf(conf_opts *conf); extern conf_opts *Config; diff --git a/a/main.c b/a/main.c index 89a89d7..4f28a35 100644 --- a/a/main.c +++ b/a/main.c @@ -6,7 +6,10 @@ extern void parse_arg(int argc, char **argv); int main(int argc, char **argv) { Config = create_conf(); + print_config(Config); + puts("\nParsing args\n"); parse_arg(argc, argv); + print_config(Config); free_conf(Config); return 0; } diff --git a/a/parse_args.c b/a/parse_args.c index e69de29..bd148f2 100644 --- a/a/parse_args.c +++ b/a/parse_args.c @@ -0,0 +1,69 @@ +#include +#include + +#include "conf.h" + +static const char *help_msg = "This is help message."; + +void parse_arg(int argc, char **argv) { + int c; + int digit_optind = 0; + + while (1) { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"CGIRoot", required_argument, NULL, 'c'}, + {"DefaultFile", required_argument, NULL, 'd'}, + {"ConfigFile", required_argument, NULL, 'f'}, + {"DocumentRoot", required_argument, NULL, 'o'}, + {"ListenPort", required_argument, NULL, 'l'}, + {"MaxClient", required_argument, NULL, 'm'}, + {"TimeOut", required_argument, NULL, 't'}, + {"Help", no_argument, NULL, 'h'}, + {0, 0, 0, 0}}; + + c = getopt_long(argc, argv, "c:d:f:o:l:m:t:h", long_options, &option_index); + if (c == -1) break; + + switch (c) { + case 'c': + set_config(Config, CONF_CGI_ROOT, optarg); + break; + + case 'd': + set_config(Config, CONF_DEFAULT_FILE, optarg); + break; + + case 'f': + set_config(Config, CONF_CONFIG_FILE, optarg); + break; + + case 'o': + set_config(Config, CONF_DOCUMENT_ROOT, optarg); + break; + + case 'l': + set_config(Config, CONF_LISTEN_PORT, optarg); + break; + + case 'm': + set_config(Config, CONF_MAX_CLIENT, optarg); + break; + + case 't': + set_config(Config, CONF_TIMEOUT, optarg); + break; + + case 'h': + puts(help_msg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } +} -- Gitee From 74b9281a3e26679d4c2958b6c8a7122a19b11c27 Mon Sep 17 00:00:00 2001 From: notify Date: Wed, 8 Mar 2023 16:05:40 +0800 Subject: [PATCH 3/3] read from config file --- a/main.c | 8 ++++++++ a/read_conf.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/a/main.c b/a/main.c index 4f28a35..f0b4759 100644 --- a/a/main.c +++ b/a/main.c @@ -2,14 +2,22 @@ #include #include +extern void read_conf(const char *conf_file); extern void parse_arg(int argc, char **argv); int main(int argc, char **argv) { Config = create_conf(); print_config(Config); + + static const char *conf_file = "./conf.ini"; + printf("\nRead Config from %s\n\n", conf_file); + read_conf(conf_file); + print_config(Config); + puts("\nParsing args\n"); parse_arg(argc, argv); print_config(Config); + free_conf(Config); return 0; } diff --git a/a/read_conf.c b/a/read_conf.c index e69de29..c34275d 100644 --- a/a/read_conf.c +++ b/a/read_conf.c @@ -0,0 +1,56 @@ +#include "conf.h" +#include +#include +#include + +void read_conf(const char *conf_file) { + char *line = NULL; + size_t length; + FILE *f = fopen(conf_file, "r"); + if (!f) return; + + while (1) { + int l = getline(&line, &length, f); + if (l <= 0) { + free(line); + break; + } + + if (line[0] == '#') { + free(line); + continue; + } + + char *p = NULL; + line[strlen(line) - 1] = 0; + + for (int i = 0; i < strlen(line); i++) { + if (line[i] == '=') { + line[i] = 0; + p = line + i + 1; + break; + } + } + + if (p) { + if (!strcmp(line, "CGIRoot")) { + set_config(Config, CONF_CGI_ROOT, p); + } else if (!strcmp(line, "DefaultFile")) { + set_config(Config, CONF_DEFAULT_FILE, p); + } else if (!strcmp(line, "ConfigFile")) { + set_config(Config, CONF_CONFIG_FILE, p); + } else if (!strcmp(line, "DocumentRoot")) { + set_config(Config, CONF_DOCUMENT_ROOT, p); + } else if (!strcmp(line, "ListenPort")) { + set_config(Config, CONF_LISTEN_PORT, p); + } else if (!strcmp(line, "MaxClient")) { + set_config(Config, CONF_MAX_CLIENT, p); + } else if (!strcmp(line, "TimeOut")) { + set_config(Config, CONF_TIMEOUT, p); + } + } + + free(line); + line = NULL; + } +} -- Gitee