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

Annotation of /lbbs/src/data_file_mgr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations)
Sun Nov 9 11:07:35 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.2: +2 -0 lines
Content type: text/x-csrc
Add BBSNET configuration and BWF configuration into data file manager

1 sysadm 1.1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2     /*
3     * data_file_mgr
4     * - Edit / Preview data files
5     *
6     * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7     */
8    
9     #include "bbs.h"
10     #include "bbs_cmd.h"
11     #include "common.h"
12     #include "data_file_mgr.h"
13     #include "editor.h"
14     #include "log.h"
15     #include "screen.h"
16     #include "str_process.h"
17     #include <ctype.h>
18     #include <errno.h>
19     #include <fcntl.h>
20     #include <stdio.h>
21     #include <stdlib.h>
22     #include <unistd.h>
23     #include <sys/mman.h>
24     #include <sys/stat.h>
25    
26     enum _data_file_mgr_constant_t
27     {
28     DATA_FILE_MAX_LEN = 1024 * 1024 * 4, // 4MB
29     };
30    
31     struct data_file_item_t
32     {
33     const char *const name;
34     const char *const path;
35     };
36     typedef struct data_file_item_t DATA_FILE_ITEM;
37    
38     static const DATA_FILE_ITEM data_file_list[] = {
39     {"进站欢迎", DATA_WELCOME},
40     {"离站告别", DATA_GOODBYE},
41     {"登陆错误", DATA_LOGIN_ERROR},
42     {"活动看板", DATA_ACTIVE_BOARD},
43     {"浏览帮助", DATA_READ_HELP},
44     {"编辑帮助", DATA_EDITOR_HELP},
45 sysadm 1.3 {"敏感词表", CONF_BWF},
46     {"穿梭配置", CONF_BBSNET},
47 sysadm 1.1 };
48    
49     static const int data_file_cnt = sizeof(data_file_list) / sizeof(DATA_FILE_ITEM);
50    
51     int data_file_mgr(void *param)
52     {
53     char path[FILE_PATH_LEN];
54     int fd = -1;
55     struct stat sb;
56     void *p_data = NULL;
57     size_t len_data = 0;
58     EDITOR_DATA *p_editor_data = NULL;
59     long len_data_new = 0;
60     char *p_data_new = NULL;
61     long line_total;
62     long line_offsets[MAX_SPLIT_FILE_LINES];
63     char buf[3] = "";
64     int ch = 0;
65     int previewed = 0;
66     int i;
67    
68     clearscr();
69     moveto(1, 1);
70     prints("数据文件列表: ");
71    
72     for (i = 0; i < data_file_cnt; i++)
73     {
74     moveto(3 + i, 4);
75     prints("%2d. %s", i + 1, data_file_list[i].name);
76     }
77    
78     get_data(SCREEN_ROWS, 1, "请输入需要编辑的文件编号: ", buf, sizeof(buf), 2);
79     i = atoi(buf) - 1;
80     if (i < 0 || i >= data_file_cnt)
81     {
82     return REDRAW;
83     }
84    
85     snprintf(path, sizeof(path), "%s.user", data_file_list[i].path);
86     if ((fd = open(path, O_RDONLY)) < 0 &&
87     (fd = open(data_file_list[i].path, O_RDONLY)) < 0)
88     {
89     log_error("open(%s) error (%d)\n", data_file_list[i].path, errno);
90     return REDRAW;
91     }
92    
93     if (fstat(fd, &sb) < 0)
94     {
95     log_error("fstat(fd) error (%d)\n", errno);
96     goto cleanup;
97     }
98    
99     len_data = (size_t)sb.st_size;
100     p_data = mmap(NULL, len_data, PROT_READ, MAP_SHARED, fd, 0L);
101     if (p_data == MAP_FAILED)
102     {
103     log_error("mmap() error (%d)\n", errno);
104     goto cleanup;
105     }
106    
107     if (close(fd) < 0)
108     {
109     log_error("close(fd) error (%d)\n", errno);
110     fd = -1;
111     goto cleanup;
112     }
113     fd = -1;
114    
115     p_editor_data = editor_data_load(p_data);
116     if (p_editor_data == NULL)
117     {
118     log_error("editor_data_load(data) error\n");
119     goto cleanup;
120     }
121    
122     if (munmap(p_data, len_data) < 0)
123     {
124     log_error("munmap() error (%d)\n", errno);
125     p_data = NULL;
126     goto cleanup;
127     }
128     p_data = NULL;
129    
130     p_data_new = malloc(DATA_FILE_MAX_LEN);
131     if (p_data_new == NULL)
132     {
133     log_error("malloc(content) error: OOM\n");
134     goto cleanup;
135     }
136    
137     for (ch = 'E'; !SYS_server_exit;)
138     {
139     if (ch == 'E')
140     {
141     editor_display(p_editor_data);
142     previewed = 0;
143     }
144    
145     clearscr();
146     moveto(1, 1);
147     if (previewed)
148     {
149     prints("(S)保存, (P)预览, (C)取消 or (E)再编辑? [P]: ");
150     }
151     else
152     {
153     prints("(P)预览, (C)取消 or (E)再编辑? [P]: ");
154     }
155     iflush();
156    
157     ch = igetch_t(BBS_max_user_idle_time);
158     switch (toupper(ch))
159     {
160     case KEY_NULL:
161     case KEY_TIMEOUT:
162     goto cleanup;
163     case CR:
164     case 'P':
165     len_data_new = editor_data_save(p_editor_data, p_data_new, DATA_FILE_MAX_LEN);
166     if (len_data_new < 0)
167     {
168     log_error("editor_data_save() error\n");
169     goto cleanup;
170     }
171     line_total = split_data_lines(p_data_new, SCREEN_COLS, line_offsets, MAX_SPLIT_FILE_LINES, 1, NULL);
172     display_data(p_data_new, line_total, line_offsets, 1, display_file_key_handler, DATA_READ_HELP);
173     previewed = 1;
174     continue;
175     case 'S':
176     if (!previewed)
177     {
178     continue;
179     }
180     break;
181     case 'C':
182     clearscr();
183     moveto(1, 1);
184     prints("取消更改...");
185     press_any_key();
186     goto cleanup;
187     case 'E':
188     ch = 'E';
189     continue;
190     default: // Invalid selection
191     continue;
192     }
193    
194     break;
195     }
196    
197 sysadm 1.2 if (SYS_server_exit) // Do not save data on shutdown
198     {
199     goto cleanup;
200     }
201    
202 sysadm 1.1 if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640)) < 0)
203     {
204     log_error("open(%s) error (%d)\n", path, errno);
205     goto cleanup;
206     }
207    
208     if (write(fd, p_data_new, (size_t)len_data_new) < 0)
209     {
210     log_error("write(len=%ld) error (%d)\n", len_data_new, errno);
211     goto cleanup;
212     }
213    
214     if (close(fd) < 0)
215     {
216     log_error("close(fd) error (%d)\n", errno);
217     fd = -1;
218     goto cleanup;
219     }
220    
221 sysadm 1.2 // Make another copy of the data file so that the user editored copy will be kept after upgrade / reinstall
222     if ((fd = open(data_file_list[i].path, O_WRONLY | O_CREAT | O_TRUNC, 0640)) < 0)
223     {
224     log_error("open(%s) error (%d)\n", data_file_list[i].path, errno);
225     goto cleanup;
226     }
227    
228     if (write(fd, p_data_new, (size_t)len_data_new) < 0)
229 sysadm 1.1 {
230 sysadm 1.2 log_error("write(len=%ld) error (%d)\n", len_data_new, errno);
231 sysadm 1.1 goto cleanup;
232     }
233    
234 sysadm 1.2 if (close(fd) < 0)
235 sysadm 1.1 {
236 sysadm 1.2 log_error("close(fd) error (%d)\n", errno);
237     fd = -1;
238 sysadm 1.1 goto cleanup;
239     }
240 sysadm 1.2 fd = -1;
241 sysadm 1.1
242     clearscr();
243     moveto(1, 1);
244     prints("修改已完成,需要重新加载配置后才会生效...");
245     press_any_key();
246    
247     cleanup:
248     if (p_editor_data != NULL)
249     {
250     editor_data_cleanup(p_editor_data);
251     }
252    
253     if (p_data_new != NULL)
254     {
255     free(p_data_new);
256     }
257    
258     if (p_data != NULL && munmap(p_data, len_data) < 0)
259     {
260     log_error("munmap() error (%d)\n", errno);
261     }
262    
263     if (fd >= 0 && close(fd) < 0)
264     {
265     log_error("close(fd) error (%d)\n", errno);
266     }
267    
268     return REDRAW;
269     }

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