--- lbbs/src/init.c 2004/10/20 07:46:32 1.5 +++ lbbs/src/init.c 2025/11/04 14:58:56 1.33 @@ -1,127 +1,207 @@ -/*************************************************************************** - init.c - description - ------------------- - begin : Mon Oct 18 2004 - copyright : (C) 2004 by Leaflet - email : leaflet@leafok.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * init + * - initializer of server daemon + * + * Copyright (C) 2004-2025 Leaflet + */ #include "bbs.h" #include "common.h" +#include "database.h" +#include "init.h" +#include "io.h" +#include "log.h" +#include +#include +#include +#include +#include +#include +#include -void -init_daemon (void) -{ - int pid; - int i; - - if (pid = fork ()) - exit (0); - else if (pid < 0) - exit (1); - - setsid (); - - if (pid = fork ()) - exit (0); - else if (pid < 0) - exit (1); - - for (i = 0; i < NOFILE; ++i) - close (i); - chdir (app_home_dir); - umask (0); +#define CONF_DELIM_WITH_SPACE " \t\r\n" - signal (SIGCHLD, SIG_IGN); - - return; -} - -int -load_conf (const char *conf_file) +int init_daemon(void) { - char temp[256]; - - // Load configuration - char c_name[256]; - FILE *fin; + int pid; - if ((fin = fopen (conf_file, "r")) == NULL) - { - log_error ("Open bbsd.conf failed"); - return -1; - } + pid = fork(); - while (fscanf (fin, "%s", c_name) != EOF) - { - if (c_name[0] == '#') - { - fgets(temp, 256, fin); - continue; - } - fscanf (fin, "%*c"); - if (strcmp (c_name, "bbs_id") == 0) - { - fscanf (fin, "%s", BBS_id); - } - if (strcmp (c_name, "bbs_name") == 0) - { - fscanf (fin, "%s", BBS_name); - } - if (strcmp (c_name, "bbs_server") == 0) - { - fscanf (fin, "%s", BBS_server); - } - if (strcmp (c_name, "bbs_address") == 0) - { - fscanf (fin, "%s", BBS_address); - } - if (strcmp (c_name, "bbs_port") == 0) + if (pid > 0) // Parent process { - fscanf (fin, "%ud", &BBS_port); + _exit(0); } - if (strcmp (c_name, "bbs_max_client") == 0) + else if (pid < 0) // error { - fscanf (fin, "%d", &BBS_max_client); + _exit(pid); } - if (strcmp (c_name, "bbs_max_user") == 0) - { - fscanf (fin, "%d", &BBS_max_user); - } - if (strcmp (c_name, "bbs_start_dt") == 0) - { - int y = 0, m = 0, d = 0; - fscanf (fin, "%d-%d-%d", &y, &m, &d); - sprintf (BBS_start_dt, "%4dÄê%2dÔÂ%2dÈÕ",y,m,d); - } - if (strcmp (c_name, "db_host") == 0) - { - fscanf (fin, "%s", DB_host); - } - if (strcmp (c_name, "db_username") == 0) + + // Child process + setsid(); + + pid = fork(); + + if (pid > 0) // Parent process { - fscanf (fin, "%s", DB_username); + _exit(0); } - if (strcmp (c_name, "db_password") == 0) + else if (pid < 0) // error { - fscanf (fin, "%s", DB_password); + _exit(pid); } - if (strcmp (c_name, "db_database") == 0) - { - fscanf (fin, "%s", DB_database); + + // Child process + umask(022); + + return 0; +} + +int load_conf(const char *conf_file) +{ + char buffer[LINE_BUFFER_LEN]; + char *saveptr = NULL; + char *p, *q, *r; + char *y, *m, *d; + int v; + FILE *fin; + + // Load configuration + if ((fin = fopen(conf_file, "r")) == NULL) + { + log_error("Open %s failed", conf_file); + return -1; + } + + while (fgets(buffer, sizeof(buffer), fin) != NULL) + { + p = strtok_r(buffer, CONF_DELIM_WITH_SPACE, &saveptr); + if (p == NULL) // Blank line + { + continue; + } + + if (*p == '#' || *p == '\r' || *p == '\n') // Comment or blank line + { + continue; + } + + q = strtok_r(NULL, CONF_DELIM_WITH_SPACE, &saveptr); + if (q == NULL) // Empty value + { + log_error("Skip empty value of config item: %s\n", p); + continue; + } + + // Check syntax + r = strtok_r(NULL, CONF_DELIM_WITH_SPACE, &saveptr); + if (r != NULL && r[0] != '#') + { + log_error("Skip config line with extra value %s = %s %s\n", p, q, r); + continue; + } + + if (strcasecmp(p, "bbs_id") == 0) + { + strncpy(BBS_id, q, sizeof(BBS_id) - 1); + BBS_id[sizeof(BBS_id) - 1] = '\0'; + } + else if (strcasecmp(p, "bbs_name") == 0) + { + strncpy(BBS_name, q, sizeof(BBS_name) - 1); + BBS_name[sizeof(BBS_name) - 1] = '\0'; + } + else if (strcasecmp(p, "bbs_server") == 0) + { + strncpy(BBS_server, q, sizeof(BBS_server) - 1); + BBS_server[sizeof(BBS_server) - 1] = '\0'; + } + else if (strcasecmp(p, "bbs_address") == 0) + { + strncpy(BBS_address, q, sizeof(BBS_address) - 1); + BBS_address[sizeof(BBS_address) - 1] = '\0'; + } + else if (strcasecmp(p, "bbs_port") == 0) + { + BBS_port[0] = (in_port_t)atoi(q); + } + else if (strcasecmp(p, "bbs_ssh_port") == 0) + { + BBS_port[1] = (in_port_t)atoi(q); + } + else if (strcasecmp(p, "bbs_max_client") == 0) + { + BBS_max_client = atoi(q); + if (BBS_max_client <= 0 || BBS_max_client > MAX_CLIENT_LIMIT) + { + log_error("Ignore config bbs_max_client with incorrect value %d\n", BBS_max_client); + BBS_max_client = MAX_CLIENT_LIMIT; + } + } + else if (strcasecmp(p, "bbs_max_client_per_ip") == 0) + { + BBS_max_client_per_ip = atoi(q); + if (BBS_max_client_per_ip <= 0 || BBS_max_client_per_ip > MAX_CLIENT_PER_IP_LIMIT) + { + log_error("Ignore config bbs_max_client with incorrect value %d\n", BBS_max_client_per_ip); + BBS_max_client_per_ip = MAX_CLIENT_PER_IP_LIMIT; + } + } + else if (strcasecmp(p, "bbs_start_dt") == 0) + { + y = strtok_r(q, "-", &saveptr); + m = strtok_r(NULL, "-", &saveptr); + d = strtok_r(NULL, "-", &saveptr); + + if (y == NULL || m == NULL || d == NULL) + { + log_error("Ignore config bbs_start_dt with incorrect value\n"); + continue; + } + snprintf(BBS_start_dt, sizeof(BBS_start_dt), "%4så¹´%2s月%2sæ—¥", y, m, d); + } + else if (strcasecmp(p, "bbs_sys_id") == 0) + { + v = atoi(q); + if (v <= 0) + { + log_error("Ignore config bbs_sys_id with incorrect value %d\n", v); + continue; + } + BBS_sys_id = v; + } + else if (strcasecmp(p, "db_host") == 0) + { + strncpy(DB_host, q, sizeof(DB_host) - 1); + DB_host[sizeof(DB_host) - 1] = '\0'; + } + else if (strcasecmp(p, "db_username") == 0) + { + strncpy(DB_username, q, sizeof(DB_username) - 1); + DB_username[sizeof(DB_username) - 1] = '\0'; + } + else if (strcasecmp(p, "db_password") == 0) + { + strncpy(DB_password, q, sizeof(DB_password) - 1); + DB_password[sizeof(DB_password) - 1] = '\0'; + } + else if (strcasecmp(p, "db_database") == 0) + { + strncpy(DB_database, q, sizeof(DB_database) - 1); + DB_database[sizeof(DB_database) - 1] = '\0'; + } + else if (strcasecmp(p, "db_timezone") == 0) + { + strncpy(DB_timezone, q, sizeof(DB_timezone) - 1); + DB_timezone[sizeof(DB_timezone) - 1] = '\0'; + } + else + { + log_error("Unknown config %s = %s\n", p, q); + } } - } - fclose (fin); - - return 0; + fclose(fin); + + return 0; }