/[LeafOK_CVS]/lbbs/src/main.c
ViewVC logotype

Diff of /lbbs/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.11 by sysadm, Sun Mar 20 14:37:37 2005 UTC Revision 1.91 by sysadm, Fri Dec 19 14:08:44 2025 UTC
# Line 1  Line 1 
1  /***************************************************************************  /* SPDX-License-Identifier: GPL-3.0-or-later */
2                            main.c  -  description  /*
3                               -------------------   * main
4      begin                : Mon Oct 11 2004   *   - entry of server program
5      copyright            : (C) 2004 by Leaflet   *
6      email                : leaflet@leafok.com   * Copyright (C) 2004-2025  Leaflet <leaflet@leafok.com>
7   ***************************************************************************/   */
8    
9  /***************************************************************************  #ifdef HAVE_CONFIG_H
10   *                                                                         *  #include "config.h"
11   *   This program is free software; you can redistribute it and/or modify  *  #endif
  *   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.                                   *  
  *                                                                         *  
  ***************************************************************************/  
12    
13  #include "bbs.h"  #include "bbs.h"
14    #include "bwf.h"
15  #include "common.h"  #include "common.h"
16    #include "file_loader.h"
17    #include "init.h"
18  #include "io.h"  #include "io.h"
19    #include "lml.h"
20    #include "log.h"
21  #include "menu.h"  #include "menu.h"
22    #include "net_server.h"
23    #include "section_list_loader.h"
24    #include "user_list.h"
25    #include <errno.h>
26    #include <libgen.h>
27    #include <locale.h>
28    #include <signal.h>
29    #include <stdio.h>
30    #include <stdlib.h>
31  #include <string.h>  #include <string.h>
32    #include <unistd.h>
33    #include <sys/stat.h>
34    #include <sys/types.h>
35    #include <sys/wait.h>
36    
37  void  static inline void app_help(void)
 app_help(void)  
38  {  {
39    prints (          fprintf(stderr, "Usage: bbsd [-fhv] [...]\n\n"
40      "Usage: bbsd [-fhv] [...]\n\n"                                          "-f\t--foreground\t\tForce program run in foreground\n"
41      "-f\t--foreground\t\tForce program run in foreground\n"                                          "-h\t--help\t\t\tDisplay this help message\n"
42      "-h\t--help\t\t\tDisplay this help message\n"                                          "-v\t--version\t\tDisplay version information\n"
43      "-v\t--version\t\tDisplay version information\n"                                          "\t--display-log\t\tDisplay standard log information\n"
44      "\t--display-log\t\tDisplay standard log information\n"                                          "\t--display-error-log\tDisplay error log information\n"
45      "\t--display-error-log\tDisplay error log information\n"                                          "-C\t--compile-config\tDisplay compile configuration\n"
46      "\n    If meet any bug, please report to <leaflet@leafok.com>\n\n"                                          "\n    If meet any bug, please report to <leaflet@leafok.com>\n\n");
   );  
47  }  }
48    
49  void  static inline void arg_error(void)
 arg_error(void)  
50  {  {
51    prints ("Invalid arguments\n");          fprintf(stderr, "Invalid arguments\n");
52    app_help();          app_help();
53  }  }
54    
55  int  static inline void app_compile_info(void)
 main (int argc, char *argv[])  
56  {  {
57    char log_dir[256], file_log_std[256], file_log_error[256], file_config[256];          printf("%s\n"
58    int i,j;                     "--enable-shared\t\t[%s]\n"
59    int daemon = 1, std_log_redir = 0, error_log_redir = 0;                     "--enable-systemd\t[%s]\n"
60                       "--with-debug\t\t[%s]\n"
61    //Parse args                     "--with-epoll\t\t[%s]\n"
62    for (i=1; i<argc; i++)                     "--with-mariadb\t\t[%s]\n"
63    {                     "--with-sysv\t\t[%s]\n",
64      switch (argv[i][0])                     APP_INFO,
65      {  #ifdef _ENABLE_SHARED
66        case '-':                     "yes",
67          if (argv[i][1] != '-')  #else
68          {                     "no",
69          for (j=1; j<strlen(argv[i]); j++)  #endif
70          {  #ifdef HAVE_SYSTEMD_SD_DAEMON_H
71            switch (argv[i][j])                     "yes",
72            {  #else
73              case 'f':                     "no",
74                daemon = 0;  #endif
75                break;  #ifdef _DEBUG
76              case 'h':                     "yes",
77                app_help();  #else
78                exit(0);                     "no",
79              case 'v':  #endif
80                puts (app_version);  #ifdef HAVE_SYS_EPOLL_H
81                exit(0);                     "yes",
82              default:  #else
83                arg_error();                     "no",
84                exit(1);  #endif
85            }  #ifdef HAVE_MARIADB_CLIENT
86          }                     "yes",
87          }  #else
88          else                     "no",
89          {  #endif
90            if (strcmp (argv[i]+2, "foreground") == 0)  #ifdef HAVE_SYSTEM_V
91            {                     "yes"
92                daemon = 0;  #else
93                break;                     "no"
94            }  #endif
95            if (strcmp (argv[i]+2, "help") == 0)          );
96            {  }
97              app_help();  
98              exit(0);  int main(int argc, char *argv[])
99            }  {
100            if (strcmp (argv[i]+2, "version") == 0)          char file_path_temp[FILE_PATH_LEN];
101            {          int daemon = 1;
102              puts (app_version);          int std_log_redir = 0;
103              exit(0);          int error_log_redir = 0;
104            }          FILE *fp;
105            if (strcmp (argv[i]+2, "display-log") == 0)          int ret;
106            {          int last_aid;
107              std_log_redir = 1;          struct sigaction act = {0};
108            }          int i;
109            if (strcmp (argv[i]+2, "display-error-log") == 0)          int j;
110            {          struct stat file_stat;
111              error_log_redir = 1;  
112            }          // Parse args
113          }          for (i = 1; i < argc; i++)
114          break;          {
115      }                  switch (argv[i][0])
116    }                  {
117                                case '-':
118    //Initialize daemon                          if (argv[i][1] != '-')
119    if (daemon)                          {
120      init_daemon ();                                  for (j = 1; j < strlen(argv[i]); j++)
121                                    {
122    //Initialize log                                          switch (argv[i][j])
123    strncpy (app_home_dir, argv[0], rindex(argv[0],'/')-argv[0]+1);                                          {
124    strcat (app_home_dir, "../");                                          case 'f':
125    strcpy (app_temp_dir, "/tmp/lbbs/");                                                  daemon = 0;
126    mkdir (app_temp_dir, 0700);                                                  break;
127    strcpy (log_dir, app_home_dir);                                          case 'h':
128    strcat (log_dir, "log/");                                                  app_help();
129    strcpy (file_log_std, log_dir);                                                  return 0;
130    strcpy (file_log_error, log_dir);                                          case 'v':
131    strcat (file_log_std, "bbsd.log");                                                  printf("%s\n", APP_INFO);
132    strcat (file_log_error, "error.log");                                                  printf("%s\n", COPYRIGHT_INFO);
133    mkdir (log_dir, 0700);                                                  return 0;
134    if (log_begin (file_log_std, file_log_error)<0)                                          case 'C':
135      exit(-1);                                                  app_compile_info();
136                                                    return 0;
137    if ((!daemon) && std_log_redir)                                          default:
138      log_std_redirect(2);                                                  arg_error();
139    if ((!daemon) && error_log_redir)                                                  return 1;
140      log_err_redirect(3);                                          }
141                                    }
142    //Load configuration                          }
143    strcpy (file_config, app_home_dir);                          else
144    strcat (file_config, "conf/bbsd.conf");                          {
145    if (load_conf(file_config)<0)                                  if (strcmp(argv[i] + 2, "foreground") == 0)
146      exit(-2);                                  {
147                                            daemon = 0;
148    //Load menus                                          break;
149    strcpy (file_config, app_home_dir);                                  }
150    strcat (file_config, "conf/menu.conf");                                  if (strcmp(argv[i] + 2, "help") == 0)
151    if (load_menu (&bbs_menu, file_config)<0)                                  {
152      exit(-3);                                          app_help();
153                                            return 0;
154                                    }
155                                    if (strcmp(argv[i] + 2, "version") == 0)
156                                    {
157                                            printf("%s\n", APP_INFO);
158                                            printf("%s\n", COPYRIGHT_INFO);
159                                            return 0;
160                                    }
161                                    if (strcmp(argv[i] + 2, "display-log") == 0)
162                                    {
163                                            std_log_redir = 1;
164                                    }
165                                    if (strcmp(argv[i] + 2, "display-error-log") == 0)
166                                    {
167                                            error_log_redir = 1;
168                                    }
169                                    if (strcmp(argv[i] + 2, "compile-config") == 0)
170                                    {
171                                            app_compile_info();
172                                            return 0;
173                                    }
174                            }
175                            break;
176                    }
177            }
178    
179            // Initialize daemon
180            if (daemon)
181            {
182                    init_daemon();
183            }
184    
185            // Change current dir
186            strncpy(file_path_temp, argv[0], sizeof(file_path_temp) - 1);
187            file_path_temp[sizeof(file_path_temp) - 1] = '\0';
188    
189            if (chdir(dirname(file_path_temp)) < 0)
190            {
191                    fprintf(stderr, "chdir(%s) error: %d\n", dirname(file_path_temp), errno);
192                    return -1;
193            }
194            if (chdir("..") < 0)
195            {
196                    fprintf(stderr, "chdir(..) error: %d\n", errno);
197                    return -1;
198            }
199    
200            // Apply the specified locale
201            if (setlocale(LC_ALL, "en_US.UTF-8") == NULL)
202            {
203                    fprintf(stderr, "setlocale(LC_ALL, en_US.UTF-8) error\n");
204                    return -1;
205            }
206    
207            // Initialize log
208            if (log_begin(LOG_FILE_INFO, LOG_FILE_ERROR) < 0)
209            {
210                    return -1;
211            }
212    
213            if ((!daemon) && std_log_redir)
214            {
215                    log_common_redir(STDERR_FILENO);
216            }
217            if ((!daemon) && error_log_redir)
218            {
219                    log_error_redir(STDERR_FILENO);
220            }
221    
222            log_common("Starting %s", APP_INFO);
223    
224            // Load configuration
225            if (load_conf(CONF_BBSD) < 0)
226            {
227                    return -2;
228            }
229    
230            // Load BWF config
231            if (bwf_load(CONF_BWF) < 0)
232            {
233                    return -2;
234            }
235    
236            // Get EULA modification tm
237            if (stat(DATA_EULA, &file_stat) == -1)
238            {
239                    log_error("stat(%s) error", DATA_EULA, errno);
240                    goto cleanup;
241            }
242            BBS_eula_tm = file_stat.st_mtim.tv_sec;
243    
244            // Check article cache dir
245            ret = mkdir(VAR_ARTICLE_CACHE_DIR, 0750);
246            if (ret == -1 && errno != EEXIST)
247            {
248                    log_error("mkdir(%s) error (%d)", VAR_ARTICLE_CACHE_DIR, errno);
249                    goto cleanup;
250            }
251    
252            // Check section aid location dir
253            ret = mkdir(VAR_SECTION_AID_LOC_DIR, 0750);
254            if (ret == -1 && errno != EEXIST)
255            {
256                    log_error("mkdir(%s) error (%d)", VAR_SECTION_AID_LOC_DIR, errno);
257                    goto cleanup;
258            }
259    
260            // Initialize data pools
261            if ((fp = fopen(VAR_ARTICLE_BLOCK_SHM, "w")) == NULL)
262            {
263                    log_error("fopen(%s) error", VAR_ARTICLE_BLOCK_SHM);
264                    goto cleanup;
265            }
266            fclose(fp);
267            if ((fp = fopen(VAR_SECTION_LIST_SHM, "w")) == NULL)
268            {
269                    log_error("fopen(%s) error", VAR_SECTION_LIST_SHM);
270                    goto cleanup;
271            }
272            fclose(fp);
273            if ((fp = fopen(VAR_TRIE_DICT_SHM, "w")) == NULL)
274            {
275                    log_error("fopen(%s) error", VAR_TRIE_DICT_SHM);
276                    goto cleanup;
277            }
278            fclose(fp);
279            if ((fp = fopen(VAR_USER_LIST_SHM, "w")) == NULL)
280            {
281                    log_error("fopen(%s) error", VAR_USER_LIST_SHM);
282                    goto cleanup;
283            }
284            fclose(fp);
285    
286            if (trie_dict_init(VAR_TRIE_DICT_SHM, TRIE_NODE_PER_POOL) < 0)
287            {
288                    log_error("trie_dict_init(%s, %d) error", VAR_TRIE_DICT_SHM, TRIE_NODE_PER_POOL);
289                    goto cleanup;
290            }
291            if (article_block_init(VAR_ARTICLE_BLOCK_SHM, BBS_article_limit_per_section * BBS_max_section / BBS_article_count_per_block) < 0)
292            {
293                    log_error("article_block_init(%s, %d) error", VAR_ARTICLE_BLOCK_SHM, BBS_article_limit_per_section * BBS_max_section / BBS_article_count_per_block);
294                    goto cleanup;
295            }
296            if (section_list_init(VAR_SECTION_LIST_SHM) < 0)
297            {
298                    log_error("section_list_pool_init(%s) error", VAR_SECTION_LIST_SHM);
299                    goto cleanup;
300            }
301    
302            // Init LML module
303            if (lml_init() < 0)
304            {
305                    log_error("lml_init() error");
306                    goto cleanup;
307            }
308    
309            // Load BBS cmd
310            if (load_cmd() < 0)
311            {
312                    log_error("load_cmd() error");
313                    goto cleanup;
314            }
315    
316            // Load menus
317            if (load_menu(&bbs_menu, CONF_MENU) < 0)
318            {
319                    log_error("load_menu(bbs_menu) error");
320                    goto cleanup;
321            }
322            if (load_menu(&top10_menu, CONF_TOP10_MENU) < 0)
323            {
324                    log_error("load_menu(top10_menu) error");
325                    goto cleanup;
326            }
327            top10_menu.allow_exit = 1;
328    
329            // Load data files
330            for (int i = 0; i < data_files_load_startup_count; i++)
331            {
332                    if (load_file(data_files_load_startup[i]) < 0)
333                    {
334                            log_error("load_file(%s) error", data_files_load_startup[i]);
335                    }
336            }
337    
338            // Load user_list and online_user_list
339            if (user_list_pool_init(VAR_USER_LIST_SHM) < 0)
340            {
341                    log_error("user_list_pool_init(%s) error", VAR_USER_LIST_SHM);
342                    goto cleanup;
343            }
344            if (user_list_pool_reload(0) < 0)
345            {
346                    log_error("user_list_pool_reload(all_user) error");
347                    goto cleanup;
348            }
349            if (user_list_pool_reload(1) < 0)
350            {
351                    log_error("user_list_pool_reload(online_user) error");
352                    goto cleanup;
353            }
354    
355            // Load section config and gen_ex
356            if (load_section_config_from_db(1) < 0)
357            {
358                    log_error("load_section_config_from_db(0) error");
359                    goto cleanup;
360            }
361    
362            set_last_article_op_log_from_db();
363            last_aid = 0;
364    
365            // Load section articles
366            do
367            {
368                    if ((ret = append_articles_from_db(last_aid + 1, 1, LOAD_ARTICLE_COUNT_LIMIT)) < 0)
369                    {
370                            log_error("append_articles_from_db(0, 1, %d) error", LOAD_ARTICLE_COUNT_LIMIT);
371                            goto cleanup;
372                    }
373    
374                    last_aid = article_block_last_aid();
375            } while (ret == LOAD_ARTICLE_COUNT_LIMIT);
376    
377            log_common("Initially load %d articles, last_aid = %d", article_block_article_count(), article_block_last_aid());
378    
379            if ((ret = user_stat_update()) < 0)
380            {
381                    log_error("user_stat_update() error");
382                    goto cleanup;
383            }
384    
385            // Set signal handler
386            act.sa_handler = sig_hup_handler;
387            if (sigaction(SIGHUP, &act, NULL) == -1)
388            {
389                    log_error("set signal action of SIGHUP error: %d", errno);
390                    goto cleanup;
391            }
392            act.sa_handler = sig_chld_handler;
393            if (sigaction(SIGCHLD, &act, NULL) == -1)
394            {
395                    log_error("set signal action of SIGCHLD error: %d", errno);
396                    goto cleanup;
397            }
398            act.sa_handler = sig_term_handler;
399            if (sigaction(SIGTERM, &act, NULL) == -1)
400            {
401                    log_error("set signal action of SIGTERM error: %d", errno);
402                    goto cleanup;
403            }
404            act.sa_handler = SIG_IGN;
405            if (sigaction(SIGPIPE, &act, NULL) == -1)
406            {
407                    log_error("set signal action of SIGPIPE error: %d", errno);
408                    goto cleanup;
409            }
410            act.sa_handler = SIG_IGN;
411            if (sigaction(SIGUSR1, &act, NULL) == -1)
412            {
413                    log_error("set signal action of SIGUSR1 error: %d", errno);
414                    goto cleanup;
415            }
416    
417            // Launch section_list_loader process
418            if (section_list_loader_launch() < 0)
419            {
420                    log_error("section_list_loader_launch() error");
421                    goto cleanup;
422            }
423    
424            // Initialize socket server
425            net_server(BBS_address, BBS_port);
426    
427    cleanup:
428            // Cleanup loader process if still running
429            if (SYS_child_process_count > 0)
430            {
431                    SYS_child_exit = 0;
432    
433                    if (kill(section_list_loader_pid, SIGTERM) < 0)
434                    {
435                            log_error("Send SIGTERM signal failed (%d)", errno);
436                    }
437    
438                    for (i = 0; SYS_child_exit == 0 && i < 5; i++)
439                    {
440                            sleep(1); // second
441                    }
442    
443                    if ((ret = waitpid(section_list_loader_pid, NULL, WNOHANG)) < 0)
444                    {
445                            log_error("waitpid(%d) error (%d)", section_list_loader_pid, errno);
446                    }
447                    else if (ret == 0)
448                    {
449                            log_common("Force kill section_list_loader process (%d)", section_list_loader_pid);
450                            if (kill(section_list_loader_pid, SIGKILL) < 0)
451                            {
452                                    log_error("Send SIGKILL signal failed (%d)", errno);
453                            }
454                    }
455            }
456    
457            // Cleanup loaded data files
458            for (int i = 0; i < data_files_load_startup_count; i++)
459            {
460                    if (unload_file(data_files_load_startup[i]) < 0)
461                    {
462                            log_error("unload_file(%s) error", data_files_load_startup[i]);
463                    }
464            }
465    
466            // Cleanup menu
467            unload_menu(&bbs_menu);
468            unload_menu(&top10_menu);
469    
470            // Cleanup LML module
471            lml_cleanup();
472    
473            // Cleanup data pools
474            section_list_cleanup();
475            article_block_cleanup();
476            trie_dict_cleanup();
477            user_list_pool_cleanup();
478    
479            if (unlink(VAR_ARTICLE_BLOCK_SHM) < 0)
480            {
481                    log_error("unlink(%s) error", VAR_ARTICLE_BLOCK_SHM);
482            }
483            if (unlink(VAR_SECTION_LIST_SHM) < 0)
484            {
485                    log_error("unlink(%s) error", VAR_SECTION_LIST_SHM);
486            }
487            if (unlink(VAR_TRIE_DICT_SHM) < 0)
488            {
489                    log_error("unlink(%s) error", VAR_TRIE_DICT_SHM);
490            }
491            if (unlink(VAR_USER_LIST_SHM) < 0)
492            {
493                    log_error("unlink(%s) error", VAR_SECTION_LIST_SHM);
494            }
495    
496            log_common("Main process exit normally");
497    
498    //Initialize socket server          log_end();
   net_server (BBS_address, BBS_port);  
499    
500    return 0;          return 0;
501  }  }


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1