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

Contents of /lbbs/src/data_file_mgr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Sun Nov 9 11:07:35 2025 UTC (4 months 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 /* 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 {"敏感词表", CONF_BWF},
46 {"穿梭配置", CONF_BBSNET},
47 };
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 if (SYS_server_exit) // Do not save data on shutdown
198 {
199 goto cleanup;
200 }
201
202 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 // 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 {
230 log_error("write(len=%ld) error (%d)\n", len_data_new, errno);
231 goto cleanup;
232 }
233
234 if (close(fd) < 0)
235 {
236 log_error("close(fd) error (%d)\n", errno);
237 fd = -1;
238 goto cleanup;
239 }
240 fd = -1;
241
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