]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Plugson/src/Web/ventoy_http.c
Fix a bug when creating multi-mod configuration for img_list in VentoyPlugson.
[Ventoy.git] / Plugson / src / Web / ventoy_http.c
1 /******************************************************************************
2 * ventoy_http.c ---- ventoy http
3 * Copyright (c) 2021, longpanda <admin@ventoy.net>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 #include <time.h>
26
27 #if defined(_MSC_VER) || defined(WIN32)
28 #else
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <sys/types.h>
32 #include <sys/ioctl.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <sys/mount.h>
36 #include <linux/fs.h>
37 #include <linux/limits.h>
38 #include <dirent.h>
39 #include <pthread.h>
40 #endif
41
42 #include <ventoy_define.h>
43 #include <ventoy_json.h>
44 #include <ventoy_util.h>
45 #include <ventoy_disk.h>
46 #include <ventoy_http.h>
47 #include "fat_filelib.h"
48
49 static const char *g_json_title_postfix[bios_max + 1] =
50 {
51 "", "_legacy", "_uefi", "_ia32", "_aa64", "_mips", ""
52 };
53
54 static const char *g_ventoy_kbd_layout[] =
55 {
56 "QWERTY_USA", "AZERTY", "CZECH_QWERTY", "CZECH_QWERTZ", "DANISH",
57 "DVORAK_USA", "FRENCH", "GERMAN", "ITALIANO", "JAPAN_106", "LATIN_USA",
58 "PORTU_BRAZIL", "QWERTY_UK", "QWERTZ", "QWERTZ_HUN", "QWERTZ_SLOV_CROAT",
59 "SPANISH", "SWEDISH", "TURKISH_Q", "VIETNAMESE",
60 NULL
61 };
62
63 static char g_ventoy_help_lang[MAX_LANGUAGE][8];
64
65 static char g_pub_path[2 * MAX_PATH];
66 static data_control g_data_control[bios_max + 1];
67 static data_theme g_data_theme[bios_max + 1];
68 static data_alias g_data_menu_alias[bios_max + 1];
69 static data_tip g_data_menu_tip[bios_max + 1];
70 static data_class g_data_menu_class[bios_max + 1];
71 static data_image_list g_data_image_list[bios_max + 1];
72 static data_image_list *g_data_image_blacklist = g_data_image_list;
73 static data_auto_memdisk g_data_auto_memdisk[bios_max + 1];
74 static data_password g_data_password[bios_max + 1];
75 static data_conf_replace g_data_conf_replace[bios_max + 1];
76 static data_injection g_data_injection[bios_max + 1];
77 static data_auto_install g_data_auto_install[bios_max + 1];
78 static data_persistence g_data_persistence[bios_max + 1];
79 static data_dud g_data_dud[bios_max + 1];
80
81 static char *g_pub_json_buffer = NULL;
82 static char *g_pub_save_buffer = NULL;
83 #define JSON_BUFFER g_pub_json_buffer
84 #define JSON_SAVE_BUFFER g_pub_save_buffer
85
86 static pthread_mutex_t g_api_mutex;
87 static struct mg_context *g_ventoy_http_ctx = NULL;
88
89 static int ventoy_is_kbd_valid(const char *key)
90 {
91 int i = 0;
92
93 for (i = 0; g_ventoy_kbd_layout[i]; i++)
94 {
95 if (strcmp(g_ventoy_kbd_layout[i], key) == 0)
96 {
97 return 1;
98 }
99 }
100
101 return 0;
102 }
103
104 static const char * ventoy_real_path(const char *org)
105 {
106 int count = 0;
107
108 if (g_sysinfo.pathcase)
109 {
110 scnprintf(g_pub_path, MAX_PATH, "%s", org);
111 count = ventoy_path_case(g_pub_path + 1, 1);
112 if (count > 0)
113 {
114 return g_pub_path;
115 }
116 return org;
117 }
118 else
119 {
120 return org;
121 }
122 }
123
124
125 static int ventoy_json_result(struct mg_connection *conn, const char *err)
126 {
127 mg_printf(conn,
128 "HTTP/1.1 200 OK \r\n"
129 "Content-Type: application/json\r\n"
130 "Content-Length: %d\r\n"
131 "\r\n%s",
132 (int)strlen(err), err);
133
134 return 0;
135 }
136
137 static int ventoy_json_buffer(struct mg_connection *conn, const char *json_buf, int json_len)
138 {
139 mg_printf(conn,
140 "HTTP/1.1 200 OK \r\n"
141 "Content-Type: application/json\r\n"
142 "Content-Length: %d\r\n"
143 "\r\n%s",
144 json_len, json_buf);
145
146 return 0;
147 }
148
149 static void ventoy_free_path_node_list(path_node *list)
150 {
151 path_node *next = NULL;
152 path_node *node = list;
153
154 while (node)
155 {
156 next = node->next;
157 free(node);
158 node = next;
159 }
160 }
161
162 static path_node * ventoy_path_node_add_array(VTOY_JSON *array)
163 {
164 path_node *head = NULL;
165 path_node *node = NULL;
166 path_node *cur = NULL;
167 VTOY_JSON *item = NULL;
168
169 for (item = array->pstChild; item; item = item->pstNext)
170 {
171 node = zalloc(sizeof(path_node));
172 if (node)
173 {
174 scnprintf(node->path, sizeof(node->path), "%s", item->unData.pcStrVal);
175 vtoy_list_add(head, cur, node);
176 }
177 }
178
179 return head;
180 }
181
182 static int ventoy_check_fuzzy_path(char *path, int prefix)
183 {
184 int rc;
185 char c;
186 char *cur = NULL;
187 char *pos = NULL;
188
189 if (!path)
190 {
191 return 0;
192 }
193
194 pos = strchr(path, '*');
195 if (pos)
196 {
197 for (cur = pos; *cur; cur++)
198 {
199 if (*cur == '/')
200 {
201 return 0;
202 }
203 }
204
205 while (pos != path)
206 {
207 if (*pos == '/')
208 {
209 break;
210 }
211 pos--;
212 }
213
214 if (*pos == '/')
215 {
216 if (pos != path)
217 {
218 c = *pos;
219 *pos = 0;
220 if (prefix)
221 {
222 rc = ventoy_is_directory_exist("%s%s", g_cur_dir, path);
223 }
224 else
225 {
226 rc = ventoy_is_directory_exist("%s", path);
227 }
228 *pos = c;
229
230 if (rc == 0)
231 {
232 return 0;
233 }
234 }
235
236 return -1;
237 }
238 else
239 {
240 return 0;
241 }
242 }
243 else
244 {
245 if (prefix)
246 {
247 return ventoy_is_file_exist("%s%s", g_cur_dir, path);
248 }
249 else
250 {
251 return ventoy_is_file_exist("%s", path);
252 }
253 }
254 }
255
256 static int ventoy_path_list_cmp(path_node *list1, path_node *list2)
257 {
258 if (NULL == list1 && NULL == list2)
259 {
260 return 0;
261 }
262 else if (list1 && list2)
263 {
264 while (list1 && list2)
265 {
266 if (strcmp(list1->path, list2->path))
267 {
268 return 1;
269 }
270
271 list1 = list1->next;
272 list2 = list2->next;
273 }
274
275 if (list1 == NULL && list2 == NULL)
276 {
277 return 0;
278 }
279 return 1;
280 }
281 else
282 {
283 return 1;
284 }
285 }
286
287
288 static int ventoy_api_device_info(struct mg_connection *conn, VTOY_JSON *json)
289 {
290 int pos = 0;
291
292 (void)json;
293
294 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
295 VTOY_JSON_FMT_OBJ_BEGIN();
296
297 VTOY_JSON_FMT_STRN("dev_name", g_sysinfo.cur_model);
298 VTOY_JSON_FMT_STRN("dev_capacity", g_sysinfo.cur_capacity);
299 VTOY_JSON_FMT_STRN("dev_fs", g_sysinfo.cur_fsname);
300 VTOY_JSON_FMT_STRN("ventoy_ver", g_sysinfo.cur_ventoy_ver);
301 VTOY_JSON_FMT_SINT("part_style", g_sysinfo.cur_part_style);
302 VTOY_JSON_FMT_SINT("secure_boot", g_sysinfo.cur_secureboot);
303
304 VTOY_JSON_FMT_OBJ_END();
305 VTOY_JSON_FMT_END(pos);
306
307 ventoy_json_buffer(conn, JSON_BUFFER, pos);
308 return 0;
309 }
310
311 static int ventoy_api_sysinfo(struct mg_connection *conn, VTOY_JSON *json)
312 {
313 int pos = 0;
314
315 (void)json;
316
317 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
318 VTOY_JSON_FMT_OBJ_BEGIN();
319 VTOY_JSON_FMT_STRN("language", ventoy_get_os_language());
320 VTOY_JSON_FMT_STRN("curdir", g_cur_dir);
321
322 //read clear
323 VTOY_JSON_FMT_SINT("syntax_error", g_sysinfo.syntax_error);
324 g_sysinfo.syntax_error = 0;
325
326 VTOY_JSON_FMT_SINT("invalid_config", g_sysinfo.invalid_config);
327 g_sysinfo.invalid_config = 0;
328
329
330 #if defined(_MSC_VER) || defined(WIN32)
331 VTOY_JSON_FMT_STRN("os", "windows");
332 #else
333 VTOY_JSON_FMT_STRN("os", "linux");
334 #endif
335
336 VTOY_JSON_FMT_OBJ_END();
337 VTOY_JSON_FMT_END(pos);
338
339 ventoy_json_buffer(conn, JSON_BUFFER, pos);
340 return 0;
341 }
342
343 static int ventoy_api_handshake(struct mg_connection *conn, VTOY_JSON *json)
344 {
345 int pos = 0;
346
347 (void)json;
348
349 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
350 VTOY_JSON_FMT_OBJ_BEGIN();
351 VTOY_JSON_FMT_SINT("status", 0);
352 VTOY_JSON_FMT_OBJ_END();
353 VTOY_JSON_FMT_END(pos);
354
355 ventoy_json_buffer(conn, JSON_BUFFER, pos);
356 return 0;
357 }
358
359 static int ventoy_api_check_exist(struct mg_connection *conn, VTOY_JSON *json)
360 {
361 int dir = 0;
362 int pos = 0;
363 int exist = 0;
364 const char *path = NULL;
365
366 path = vtoy_json_get_string_ex(json, "path");
367 vtoy_json_get_int(json, "dir", &dir);
368
369 if (path)
370 {
371 if (dir)
372 {
373 exist = ventoy_is_directory_exist("%s", path);
374 }
375 else
376 {
377 exist = ventoy_is_file_exist("%s", path);
378 }
379 }
380
381 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
382 VTOY_JSON_FMT_OBJ_BEGIN();
383 VTOY_JSON_FMT_SINT("exist", exist);
384 VTOY_JSON_FMT_OBJ_END();
385 VTOY_JSON_FMT_END(pos);
386
387 ventoy_json_buffer(conn, JSON_BUFFER, pos);
388 return 0;
389 }
390
391 static int ventoy_api_check_exist2(struct mg_connection *conn, VTOY_JSON *json)
392 {
393 int dir1 = 0;
394 int dir2 = 0;
395 int fuzzy1 = 0;
396 int fuzzy2 = 0;
397 int pos = 0;
398 int exist1 = 0;
399 int exist2 = 0;
400 const char *path1 = NULL;
401 const char *path2 = NULL;
402
403 path1 = vtoy_json_get_string_ex(json, "path1");
404 path2 = vtoy_json_get_string_ex(json, "path2");
405 vtoy_json_get_int(json, "dir1", &dir1);
406 vtoy_json_get_int(json, "dir2", &dir2);
407 vtoy_json_get_int(json, "fuzzy1", &fuzzy1);
408 vtoy_json_get_int(json, "fuzzy2", &fuzzy2);
409
410 if (path1)
411 {
412 if (dir1)
413 {
414 exist1 = ventoy_is_directory_exist("%s", path1);
415 }
416 else
417 {
418 if (fuzzy1)
419 {
420 exist1 = ventoy_check_fuzzy_path((char *)path1, 0);
421 }
422 else
423 {
424 exist1 = ventoy_is_file_exist("%s", path1);
425 }
426 }
427 }
428
429 if (path2)
430 {
431 if (dir2)
432 {
433 exist2 = ventoy_is_directory_exist("%s", path2);
434 }
435 else
436 {
437 if (fuzzy2)
438 {
439 exist2 = ventoy_check_fuzzy_path((char *)path2, 0);
440 }
441 else
442 {
443 exist2 = ventoy_is_file_exist("%s", path2);
444 }
445 }
446 }
447
448 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
449 VTOY_JSON_FMT_OBJ_BEGIN();
450 VTOY_JSON_FMT_SINT("exist1", exist1);
451 VTOY_JSON_FMT_SINT("exist2", exist2);
452 VTOY_JSON_FMT_OBJ_END();
453 VTOY_JSON_FMT_END(pos);
454
455 ventoy_json_buffer(conn, JSON_BUFFER, pos);
456 return 0;
457 }
458
459 static int ventoy_api_check_fuzzy(struct mg_connection *conn, VTOY_JSON *json)
460 {
461 int pos = 0;
462 int exist = 0;
463 const char *path = NULL;
464
465 path = vtoy_json_get_string_ex(json, "path");
466 if (path)
467 {
468 exist = ventoy_check_fuzzy_path((char *)path, 0);
469 }
470
471 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
472 VTOY_JSON_FMT_OBJ_BEGIN();
473 VTOY_JSON_FMT_SINT("exist", exist);
474 VTOY_JSON_FMT_OBJ_END();
475 VTOY_JSON_FMT_END(pos);
476
477 ventoy_json_buffer(conn, JSON_BUFFER, pos);
478 return 0;
479 }
480
481
482 #if 0
483 #endif
484 void ventoy_data_default_control(data_control *data)
485 {
486 memset(data, 0, sizeof(data_control));
487
488 data->filter_dot_underscore = 1;
489 data->max_search_level = -1;
490 data->menu_timeout = 0;
491
492 strlcpy(data->default_kbd_layout, "QWERTY_USA");
493 strlcpy(data->help_text_language, "en_US");
494 }
495
496 int ventoy_data_cmp_control(data_control *data1, data_control *data2)
497 {
498 if (data1->default_menu_mode != data2->default_menu_mode ||
499 data1->treeview_style != data2->treeview_style ||
500 data1->filter_dot_underscore != data2->filter_dot_underscore ||
501 data1->sort_casesensitive != data2->sort_casesensitive ||
502 data1->max_search_level != data2->max_search_level ||
503 data1->vhd_no_warning != data2->vhd_no_warning ||
504 data1->filter_iso != data2->filter_iso ||
505 data1->filter_wim != data2->filter_wim ||
506 data1->filter_efi != data2->filter_efi ||
507 data1->filter_img != data2->filter_img ||
508 data1->filter_vhd != data2->filter_vhd ||
509 data1->filter_vtoy != data2->filter_vtoy ||
510 data1->win11_bypass_check != data2->win11_bypass_check ||
511 data1->linux_remount != data2->linux_remount ||
512 data1->menu_timeout != data2->menu_timeout)
513 {
514 return 1;
515 }
516
517 if (strcmp(data1->default_search_root, data2->default_search_root) ||
518 strcmp(data1->default_image, data2->default_image) ||
519 strcmp(data1->default_kbd_layout, data2->default_kbd_layout) ||
520 strcmp(data1->help_text_language, data2->help_text_language))
521 {
522 return 1;
523 }
524
525 return 0;
526 }
527
528 int ventoy_data_save_control(data_control *data, const char *title, char *buf, int buflen)
529 {
530 int pos = 0;
531 data_control *def = g_data_control + bios_max;
532
533 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
534
535 VTOY_JSON_FMT_KEY_L(L1, title);
536 VTOY_JSON_FMT_ARY_BEGIN_N();
537
538 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_DEFAULT_MENU_MODE", default_menu_mode);
539 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_TREE_VIEW_MENU_STYLE", treeview_style);
540 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILT_DOT_UNDERSCORE_FILE", filter_dot_underscore);
541 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_SORT_CASE_SENSITIVE", sort_casesensitive);
542
543 if (data->max_search_level >= 0)
544 {
545 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_MAX_SEARCH_LEVEL", max_search_level);
546 }
547
548 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_VHD_NO_WARNING", vhd_no_warning);
549 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_ISO", filter_iso);
550 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_WIM", filter_wim);
551 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_EFI", filter_efi);
552 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_IMG", filter_img);
553 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_VHD", filter_vhd);
554 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_VTOY", filter_vtoy);
555 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_WIN11_BYPASS_CHECK", win11_bypass_check);
556 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_LINUX_REMOUNT", linux_remount);
557 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_MENU_TIMEOUT", menu_timeout);
558
559 VTOY_JSON_FMT_CTRL_STRN(L2, "VTOY_DEFAULT_KBD_LAYOUT", default_kbd_layout);
560 VTOY_JSON_FMT_CTRL_STRN(L2, "VTOY_HELP_TXT_LANGUAGE", help_text_language);
561
562 if (strcmp(def->default_search_root, data->default_search_root))
563 {
564 VTOY_JSON_FMT_CTRL_STRN_STR(L2, "VTOY_DEFAULT_SEARCH_ROOT", ventoy_real_path(data->default_search_root));
565 }
566
567 if (strcmp(def->default_image, data->default_image))
568 {
569 VTOY_JSON_FMT_CTRL_STRN_STR(L2, "VTOY_DEFAULT_IMAGE", ventoy_real_path(data->default_image));
570 }
571
572 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
573 VTOY_JSON_FMT_END(pos);
574
575 return pos;
576 }
577
578 int ventoy_data_json_control(data_control *ctrl, char *buf, int buflen)
579 {
580 int i = 0;
581 int pos = 0;
582 int valid = 0;
583
584 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
585 VTOY_JSON_FMT_OBJ_BEGIN();
586
587 VTOY_JSON_FMT_SINT("default_menu_mode", ctrl->default_menu_mode);
588 VTOY_JSON_FMT_SINT("treeview_style", ctrl->treeview_style);
589 VTOY_JSON_FMT_SINT("filter_dot_underscore", ctrl->filter_dot_underscore);
590 VTOY_JSON_FMT_SINT("sort_casesensitive", ctrl->sort_casesensitive);
591 VTOY_JSON_FMT_SINT("max_search_level", ctrl->max_search_level);
592 VTOY_JSON_FMT_SINT("vhd_no_warning", ctrl->vhd_no_warning);
593
594 VTOY_JSON_FMT_SINT("filter_iso", ctrl->filter_iso);
595 VTOY_JSON_FMT_SINT("filter_wim", ctrl->filter_wim);
596 VTOY_JSON_FMT_SINT("filter_efi", ctrl->filter_efi);
597 VTOY_JSON_FMT_SINT("filter_img", ctrl->filter_img);
598 VTOY_JSON_FMT_SINT("filter_vhd", ctrl->filter_vhd);
599 VTOY_JSON_FMT_SINT("filter_vtoy", ctrl->filter_vtoy);
600 VTOY_JSON_FMT_SINT("win11_bypass_check", ctrl->win11_bypass_check);
601 VTOY_JSON_FMT_SINT("linux_remount", ctrl->linux_remount);
602 VTOY_JSON_FMT_SINT("menu_timeout", ctrl->menu_timeout);
603 VTOY_JSON_FMT_STRN("default_kbd_layout", ctrl->default_kbd_layout);
604 VTOY_JSON_FMT_STRN("help_text_language", ctrl->help_text_language);
605
606 valid = 0;
607 if (ctrl->default_search_root[0] && ventoy_is_directory_exist("%s%s", g_cur_dir, ctrl->default_search_root))
608 {
609 valid = 1;
610 }
611 VTOY_JSON_FMT_STRN("default_search_root", ctrl->default_search_root);
612 VTOY_JSON_FMT_SINT("default_search_root_valid", valid);
613
614
615 valid = 0;
616 if (ctrl->default_image[0] && ventoy_is_file_exist("%s%s", g_cur_dir, ctrl->default_image))
617 {
618 valid = 1;
619 }
620 VTOY_JSON_FMT_STRN("default_image", ctrl->default_image);
621 VTOY_JSON_FMT_SINT("default_image_valid", valid);
622
623 VTOY_JSON_FMT_KEY("help_list");
624 VTOY_JSON_FMT_ARY_BEGIN();
625
626 for (i = 0; g_ventoy_help_lang[i][0]; i++)
627 {
628 VTOY_JSON_FMT_ITEM(g_ventoy_help_lang[i]);
629 }
630 VTOY_JSON_FMT_ARY_ENDEX();
631
632
633 VTOY_JSON_FMT_OBJ_END();
634 VTOY_JSON_FMT_END(pos);
635
636 return pos;
637 }
638
639 static int ventoy_api_get_control(struct mg_connection *conn, VTOY_JSON *json)
640 {
641 api_get_func(conn, json, control);
642 return 0;
643 }
644
645 static int ventoy_api_save_control(struct mg_connection *conn, VTOY_JSON *json)
646 {
647 int ret;
648 int index = 0;
649 data_control *ctrl = NULL;
650
651 vtoy_json_get_int(json, "index", &index);
652 ctrl = g_data_control + index;
653
654 VTOY_JSON_INT("default_menu_mode", ctrl->default_menu_mode);
655 VTOY_JSON_INT("treeview_style", ctrl->treeview_style);
656 VTOY_JSON_INT("filter_dot_underscore", ctrl->filter_dot_underscore);
657 VTOY_JSON_INT("sort_casesensitive", ctrl->sort_casesensitive);
658 VTOY_JSON_INT("max_search_level", ctrl->max_search_level);
659 VTOY_JSON_INT("vhd_no_warning", ctrl->vhd_no_warning);
660 VTOY_JSON_INT("filter_iso", ctrl->filter_iso);
661 VTOY_JSON_INT("filter_wim", ctrl->filter_wim);
662 VTOY_JSON_INT("filter_efi", ctrl->filter_efi);
663 VTOY_JSON_INT("filter_img", ctrl->filter_img);
664 VTOY_JSON_INT("filter_vhd", ctrl->filter_vhd);
665 VTOY_JSON_INT("filter_vtoy", ctrl->filter_vtoy);
666 VTOY_JSON_INT("win11_bypass_check", ctrl->win11_bypass_check);
667 VTOY_JSON_INT("linux_remount", ctrl->linux_remount);
668 VTOY_JSON_INT("menu_timeout", ctrl->menu_timeout);
669
670 VTOY_JSON_STR("default_image", ctrl->default_image);
671 VTOY_JSON_STR("default_search_root", ctrl->default_search_root);
672 VTOY_JSON_STR("help_text_language", ctrl->help_text_language);
673 VTOY_JSON_STR("default_kbd_layout", ctrl->default_kbd_layout);
674
675 ret = ventoy_data_save_all();
676
677 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
678 return 0;
679 }
680
681
682 #if 0
683 #endif
684
685 void ventoy_data_default_theme(data_theme *data)
686 {
687 memset(data, 0, sizeof(data_theme));
688 strlcpy(data->gfxmode, "1024x768");
689 scnprintf(data->ventoy_left, sizeof(data->ventoy_left), "5%%");
690 scnprintf(data->ventoy_top, sizeof(data->ventoy_top), "95%%");
691 scnprintf(data->ventoy_color, sizeof(data->ventoy_color), "%s", "#0000ff");
692 }
693
694 int ventoy_data_cmp_theme(data_theme *data1, data_theme *data2)
695 {
696 if (data1->display_mode != data2->display_mode ||
697 strcmp(data1->ventoy_left, data2->ventoy_left) ||
698 strcmp(data1->ventoy_top, data2->ventoy_top) ||
699 strcmp(data1->gfxmode, data2->gfxmode) ||
700 strcmp(data1->ventoy_color, data2->ventoy_color)
701 )
702 {
703 return 1;
704 }
705
706 if (ventoy_path_list_cmp(data1->filelist, data2->filelist))
707 {
708 return 1;
709 }
710
711 if (ventoy_path_list_cmp(data1->fontslist, data2->fontslist))
712 {
713 return 1;
714 }
715
716 return 0;
717 }
718
719
720 int ventoy_data_save_theme(data_theme *data, const char *title, char *buf, int buflen)
721 {
722 int pos = 0;
723 path_node *node = NULL;
724 data_theme *def = g_data_theme + bios_max;
725
726 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
727
728 VTOY_JSON_FMT_KEY_L(L1, title);
729 VTOY_JSON_FMT_OBJ_BEGIN_N();
730
731 if (data->filelist)
732 {
733 if (data->filelist->next)
734 {
735 VTOY_JSON_FMT_KEY_L(L2, "file");
736 VTOY_JSON_FMT_ARY_BEGIN_N();
737
738 for (node = data->filelist; node; node = node->next)
739 {
740 VTOY_JSON_FMT_ITEM_PATH_LN(L3, node->path);
741 }
742
743 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
744
745 if (def->default_file != data->default_file)
746 {
747 VTOY_JSON_FMT_SINT_LN(L2, "default_file", data->default_file);
748 }
749 }
750 else
751 {
752 VTOY_JSON_FMT_STRN_PATH_LN(L2, "file", data->filelist->path);
753 }
754 }
755
756 if (data->display_mode != def->display_mode)
757 {
758 if (display_mode_cli == data->display_mode)
759 {
760 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "CLI");
761 }
762 else if (display_mode_serial == data->display_mode)
763 {
764 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "serial");
765 }
766 else if (display_mode_ser_console == data->display_mode)
767 {
768 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "serial_console");
769 }
770 else
771 {
772 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "GUI");
773 }
774 }
775
776 VTOY_JSON_FMT_DIFF_STRN(L2, "gfxmode", gfxmode);
777
778 VTOY_JSON_FMT_DIFF_STRN(L2, "ventoy_left", ventoy_left);
779 VTOY_JSON_FMT_DIFF_STRN(L2, "ventoy_top", ventoy_top);
780 VTOY_JSON_FMT_DIFF_STRN(L2, "ventoy_color", ventoy_color);
781
782 if (data->fontslist)
783 {
784 VTOY_JSON_FMT_KEY_L(L2, "fonts");
785 VTOY_JSON_FMT_ARY_BEGIN_N();
786
787 for (node = data->fontslist; node; node = node->next)
788 {
789 VTOY_JSON_FMT_ITEM_PATH_LN(L3, node->path);
790 }
791
792 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
793 }
794
795 VTOY_JSON_FMT_OBJ_ENDEX_LN(L1);
796 VTOY_JSON_FMT_END(pos);
797
798 return pos;
799 }
800
801
802 int ventoy_data_json_theme(data_theme *data, char *buf, int buflen)
803 {
804 int pos = 0;
805 path_node *node = NULL;
806
807 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
808 VTOY_JSON_FMT_OBJ_BEGIN();
809
810 VTOY_JSON_FMT_SINT("default_file", data->default_file);
811 VTOY_JSON_FMT_SINT("display_mode", data->display_mode);
812 VTOY_JSON_FMT_STRN("gfxmode", data->gfxmode);
813
814 VTOY_JSON_FMT_STRN("ventoy_color", data->ventoy_color);
815 VTOY_JSON_FMT_STRN("ventoy_left", data->ventoy_left);
816 VTOY_JSON_FMT_STRN("ventoy_top", data->ventoy_top);
817
818 VTOY_JSON_FMT_KEY("filelist");
819 VTOY_JSON_FMT_ARY_BEGIN();
820 for (node = data->filelist; node; node = node->next)
821 {
822 VTOY_JSON_FMT_OBJ_BEGIN();
823 VTOY_JSON_FMT_STRN("path", node->path);
824 VTOY_JSON_FMT_SINT("valid", ventoy_is_file_exist("%s%s", g_cur_dir, node->path));
825 VTOY_JSON_FMT_OBJ_ENDEX();
826 }
827 VTOY_JSON_FMT_ARY_ENDEX();
828
829 VTOY_JSON_FMT_KEY("fontslist");
830 VTOY_JSON_FMT_ARY_BEGIN();
831 for (node = data->fontslist; node; node = node->next)
832 {
833 VTOY_JSON_FMT_OBJ_BEGIN();
834 VTOY_JSON_FMT_STRN("path", node->path);
835 VTOY_JSON_FMT_SINT("valid", ventoy_is_file_exist("%s%s", g_cur_dir, node->path));
836 VTOY_JSON_FMT_OBJ_ENDEX();
837 }
838 VTOY_JSON_FMT_ARY_ENDEX();
839
840 VTOY_JSON_FMT_OBJ_END();
841 VTOY_JSON_FMT_END(pos);
842
843 return pos;
844 }
845
846 static int ventoy_api_get_theme(struct mg_connection *conn, VTOY_JSON *json)
847 {
848 api_get_func(conn, json, theme);
849 return 0;
850 }
851
852 static int ventoy_api_save_theme(struct mg_connection *conn, VTOY_JSON *json)
853 {
854 int ret;
855 int index = 0;
856 data_theme *data = NULL;
857
858 vtoy_json_get_int(json, "index", &index);
859 data = g_data_theme + index;
860
861 VTOY_JSON_INT("default_file", data->default_file);
862 VTOY_JSON_INT("display_mode", data->display_mode);
863 VTOY_JSON_STR("gfxmode", data->gfxmode);
864 VTOY_JSON_STR("ventoy_left", data->ventoy_left);
865 VTOY_JSON_STR("ventoy_top", data->ventoy_top);
866 VTOY_JSON_STR("ventoy_color", data->ventoy_color);
867
868 ret = ventoy_data_save_all();
869
870 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
871 return 0;
872 }
873
874 static int ventoy_api_theme_add_file(struct mg_connection *conn, VTOY_JSON *json)
875 {
876 int ret;
877 int index = 0;
878 const char *path = NULL;
879 path_node *node = NULL;
880 path_node *cur = NULL;
881 data_theme *data = NULL;
882
883 vtoy_json_get_int(json, "index", &index);
884 data = g_data_theme + index;
885
886 path = VTOY_JSON_STR_EX("path");
887 if (path)
888 {
889 node = zalloc(sizeof(path_node));
890 if (node)
891 {
892 scnprintf(node->path, sizeof(node->path), "%s", path);
893
894 vtoy_list_add(data->filelist, cur, node);
895 }
896 }
897
898 ret = ventoy_data_save_all();
899
900 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
901 return 0;
902 }
903
904 static int ventoy_api_theme_del_file(struct mg_connection *conn, VTOY_JSON *json)
905 {
906 int ret;
907 int index = 0;
908 const char *path = NULL;
909 path_node *node = NULL;
910 path_node *last = NULL;
911 data_theme *data = NULL;
912
913 vtoy_json_get_int(json, "index", &index);
914 data = g_data_theme + index;
915
916 path = VTOY_JSON_STR_EX("path");
917 if (path)
918 {
919 vtoy_list_del(last, node, data->filelist, path);
920 }
921
922 ret = ventoy_data_save_all();
923
924 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
925 return 0;
926 }
927
928
929 static int ventoy_api_theme_add_font(struct mg_connection *conn, VTOY_JSON *json)
930 {
931 int ret;
932 int index = 0;
933 const char *path = NULL;
934 path_node *node = NULL;
935 path_node *cur = NULL;
936 data_theme *data = NULL;
937
938 vtoy_json_get_int(json, "index", &index);
939 data = g_data_theme + index;
940
941 path = VTOY_JSON_STR_EX("path");
942 if (path)
943 {
944 node = zalloc(sizeof(path_node));
945 if (node)
946 {
947 scnprintf(node->path, sizeof(node->path), "%s", path);
948 vtoy_list_add(data->fontslist, cur, node);
949 }
950 }
951
952 ret = ventoy_data_save_all();
953
954 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
955 return 0;
956 }
957
958
959 static int ventoy_api_theme_del_font(struct mg_connection *conn, VTOY_JSON *json)
960 {
961 int ret;
962 int index = 0;
963 const char *path = NULL;
964 path_node *node = NULL;
965 path_node *last = NULL;
966 data_theme *data = NULL;
967
968 vtoy_json_get_int(json, "index", &index);
969 data = g_data_theme + index;
970
971 path = VTOY_JSON_STR_EX("path");
972 if (path)
973 {
974 vtoy_list_del(last, node, data->fontslist, path);
975 }
976
977 ret = ventoy_data_save_all();
978
979 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
980 return 0;
981 }
982
983 #if 0
984 #endif
985
986 void ventoy_data_default_menu_alias(data_alias *data)
987 {
988 memset(data, 0, sizeof(data_alias));
989 }
990
991 int ventoy_data_cmp_menu_alias(data_alias *data1, data_alias *data2)
992 {
993 data_alias_node *list1 = NULL;
994 data_alias_node *list2 = NULL;
995
996 if (NULL == data1->list && NULL == data2->list)
997 {
998 return 0;
999 }
1000 else if (data1->list && data2->list)
1001 {
1002 list1 = data1->list;
1003 list2 = data2->list;
1004
1005 while (list1 && list2)
1006 {
1007 if ((list1->type != list2->type) ||
1008 strcmp(list1->path, list2->path) ||
1009 strcmp(list1->alias, list2->alias))
1010 {
1011 return 1;
1012 }
1013
1014 list1 = list1->next;
1015 list2 = list2->next;
1016 }
1017
1018 if (list1 == NULL && list2 == NULL)
1019 {
1020 return 0;
1021 }
1022 return 1;
1023 }
1024 else
1025 {
1026 return 1;
1027 }
1028
1029 return 0;
1030 }
1031
1032
1033 int ventoy_data_save_menu_alias(data_alias *data, const char *title, char *buf, int buflen)
1034 {
1035 int pos = 0;
1036 data_alias_node *node = NULL;
1037
1038 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1039
1040 VTOY_JSON_FMT_KEY_L(L1, title);
1041 VTOY_JSON_FMT_ARY_BEGIN_N();
1042
1043 for (node = data->list; node; node = node->next)
1044 {
1045 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
1046
1047 if (node->type == path_type_file)
1048 {
1049 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
1050 }
1051 else
1052 {
1053 VTOY_JSON_FMT_STRN_PATH_LN(L3, "dir", node->path);
1054 }
1055
1056 VTOY_JSON_FMT_STRN_EX_LN(L3, "alias", node->alias);
1057
1058 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
1059 }
1060
1061 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1062 VTOY_JSON_FMT_END(pos);
1063
1064 return pos;
1065 }
1066
1067
1068 int ventoy_data_json_menu_alias(data_alias *data, char *buf, int buflen)
1069 {
1070 int pos = 0;
1071 int valid = 0;
1072 data_alias_node *node = NULL;
1073
1074 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1075 VTOY_JSON_FMT_ARY_BEGIN();
1076
1077 for (node = data->list; node; node = node->next)
1078 {
1079 VTOY_JSON_FMT_OBJ_BEGIN();
1080
1081 VTOY_JSON_FMT_UINT("type", node->type);
1082 VTOY_JSON_FMT_STRN("path", node->path);
1083 if (node->type == path_type_file)
1084 {
1085 valid = ventoy_check_fuzzy_path(node->path, 1);
1086 }
1087 else
1088 {
1089 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
1090 }
1091
1092 VTOY_JSON_FMT_SINT("valid", valid);
1093 VTOY_JSON_FMT_STRN("alias", node->alias);
1094
1095 VTOY_JSON_FMT_OBJ_ENDEX();
1096 }
1097
1098 VTOY_JSON_FMT_ARY_END();
1099 VTOY_JSON_FMT_END(pos);
1100
1101 return pos;
1102 }
1103
1104 static int ventoy_api_get_alias(struct mg_connection *conn, VTOY_JSON *json)
1105 {
1106 api_get_func(conn, json, menu_alias);
1107 return 0;
1108 }
1109
1110 static int ventoy_api_save_alias(struct mg_connection *conn, VTOY_JSON *json)
1111 {
1112 int ret;
1113 ret = ventoy_data_save_all();
1114
1115 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1116 return 0;
1117 }
1118
1119 static int ventoy_api_alias_add(struct mg_connection *conn, VTOY_JSON *json)
1120 {
1121 int ret;
1122 int index = 0;
1123 int type = path_type_file;
1124 const char *path = NULL;
1125 const char *alias = NULL;
1126 data_alias_node *node = NULL;
1127 data_alias_node *cur = NULL;
1128 data_alias *data = NULL;
1129
1130 vtoy_json_get_int(json, "index", &index);
1131 data = g_data_menu_alias + index;
1132
1133 vtoy_json_get_int(json, "type", &type);
1134
1135 path = VTOY_JSON_STR_EX("path");
1136 alias = VTOY_JSON_STR_EX("alias");
1137 if (path && alias)
1138 {
1139 node = zalloc(sizeof(data_alias_node));
1140 if (node)
1141 {
1142 node->type = type;
1143 scnprintf(node->path, sizeof(node->path), "%s", path);
1144 scnprintf(node->alias, sizeof(node->alias), "%s", alias);
1145
1146 vtoy_list_add(data->list, cur, node);
1147 }
1148 }
1149
1150 ret = ventoy_data_save_all();
1151
1152 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1153 return 0;
1154 }
1155
1156 static int ventoy_api_alias_del(struct mg_connection *conn, VTOY_JSON *json)
1157 {
1158 int ret;
1159 int index = 0;
1160 const char *path = NULL;
1161 data_alias_node *last = NULL;
1162 data_alias_node *node = NULL;
1163 data_alias *data = NULL;
1164
1165 vtoy_json_get_int(json, "index", &index);
1166 data = g_data_menu_alias + index;
1167
1168 path = VTOY_JSON_STR_EX("path");
1169 if (path)
1170 {
1171 vtoy_list_del(last, node, data->list, path);
1172 }
1173
1174 ret = ventoy_data_save_all();
1175
1176 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1177 return 0;
1178 }
1179
1180 #if 0
1181 #endif
1182
1183 void ventoy_data_default_menu_tip(data_tip *data)
1184 {
1185 memset(data, 0, sizeof(data_tip));
1186
1187 scnprintf(data->left, sizeof(data->left), "10%%");
1188 scnprintf(data->top, sizeof(data->top), "81%%");
1189 scnprintf(data->color, sizeof(data->color), "%s", "blue");
1190 }
1191
1192 int ventoy_data_cmp_menu_tip(data_tip *data1, data_tip *data2)
1193 {
1194 data_tip_node *list1 = NULL;
1195 data_tip_node *list2 = NULL;
1196
1197 if (strcmp(data1->left, data2->left) || strcmp(data1->top, data2->top) || strcmp(data1->color, data2->color))
1198 {
1199 return 1;
1200 }
1201
1202 if (NULL == data1->list && NULL == data2->list)
1203 {
1204 return 0;
1205 }
1206 else if (data1->list && data2->list)
1207 {
1208 list1 = data1->list;
1209 list2 = data2->list;
1210
1211 while (list1 && list2)
1212 {
1213 if ((list1->type != list2->type) ||
1214 strcmp(list1->path, list2->path) ||
1215 strcmp(list1->tip, list2->tip))
1216 {
1217 return 1;
1218 }
1219
1220 list1 = list1->next;
1221 list2 = list2->next;
1222 }
1223
1224 if (list1 == NULL && list2 == NULL)
1225 {
1226 return 0;
1227 }
1228 return 1;
1229 }
1230 else
1231 {
1232 return 1;
1233 }
1234
1235 return 0;
1236 }
1237
1238
1239 int ventoy_data_save_menu_tip(data_tip *data, const char *title, char *buf, int buflen)
1240 {
1241 int pos = 0;
1242 data_tip_node *node = NULL;
1243 data_tip *def = g_data_menu_tip + bios_max;
1244
1245 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1246 VTOY_JSON_FMT_KEY_L(L1, title);
1247 VTOY_JSON_FMT_OBJ_BEGIN_N();
1248
1249 VTOY_JSON_FMT_DIFF_STRN(L2, "left", left);
1250 VTOY_JSON_FMT_DIFF_STRN(L2, "top", top);
1251 VTOY_JSON_FMT_DIFF_STRN(L2, "color", color);
1252
1253 if (data->list)
1254 {
1255 VTOY_JSON_FMT_KEY_L(L2, "tips");
1256 VTOY_JSON_FMT_ARY_BEGIN_N();
1257
1258 for (node = data->list; node; node = node->next)
1259 {
1260 VTOY_JSON_FMT_OBJ_BEGIN_LN(L3);
1261
1262 if (node->type == path_type_file)
1263 {
1264 VTOY_JSON_FMT_STRN_PATH_LN(L4, "image", node->path);
1265 }
1266 else
1267 {
1268 VTOY_JSON_FMT_STRN_PATH_LN(L4, "dir", node->path);
1269 }
1270 VTOY_JSON_FMT_STRN_EX_LN(L4, "tip", node->tip);
1271
1272 VTOY_JSON_FMT_OBJ_ENDEX_LN(L3);
1273 }
1274
1275 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
1276 }
1277
1278 VTOY_JSON_FMT_OBJ_ENDEX_LN(L1);
1279
1280 VTOY_JSON_FMT_END(pos);
1281
1282 return pos;
1283 }
1284
1285
1286 int ventoy_data_json_menu_tip(data_tip *data, char *buf, int buflen)
1287 {
1288 int pos = 0;
1289 int valid = 0;
1290 data_tip_node *node = NULL;
1291
1292 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1293
1294 VTOY_JSON_FMT_OBJ_BEGIN();
1295
1296 VTOY_JSON_FMT_STRN("left", data->left);
1297 VTOY_JSON_FMT_STRN("top", data->top);
1298 VTOY_JSON_FMT_STRN("color", data->color);
1299
1300 VTOY_JSON_FMT_KEY("tips");
1301 VTOY_JSON_FMT_ARY_BEGIN();
1302
1303 for (node = data->list; node; node = node->next)
1304 {
1305 VTOY_JSON_FMT_OBJ_BEGIN();
1306
1307 VTOY_JSON_FMT_UINT("type", node->type);
1308 VTOY_JSON_FMT_STRN("path", node->path);
1309 if (node->type == path_type_file)
1310 {
1311 valid = ventoy_check_fuzzy_path(node->path, 1);
1312 }
1313 else
1314 {
1315 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
1316 }
1317
1318 VTOY_JSON_FMT_SINT("valid", valid);
1319 VTOY_JSON_FMT_STRN("tip", node->tip);
1320
1321 VTOY_JSON_FMT_OBJ_ENDEX();
1322 }
1323
1324 VTOY_JSON_FMT_ARY_ENDEX();
1325
1326 VTOY_JSON_FMT_OBJ_END();
1327 VTOY_JSON_FMT_END(pos);
1328
1329 return pos;
1330 }
1331
1332 static int ventoy_api_get_tip(struct mg_connection *conn, VTOY_JSON *json)
1333 {
1334 api_get_func(conn, json, menu_tip);
1335 return 0;
1336 }
1337
1338 static int ventoy_api_save_tip(struct mg_connection *conn, VTOY_JSON *json)
1339 {
1340 int ret;
1341 int index = 0;
1342 data_tip *data = NULL;
1343
1344 vtoy_json_get_int(json, "index", &index);
1345 data = g_data_menu_tip + index;
1346
1347 VTOY_JSON_STR("left", data->left);
1348 VTOY_JSON_STR("top", data->top);
1349 VTOY_JSON_STR("color", data->color);
1350
1351 ret = ventoy_data_save_all();
1352
1353 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1354 return 0;
1355 }
1356
1357 static int ventoy_api_tip_add(struct mg_connection *conn, VTOY_JSON *json)
1358 {
1359 int ret;
1360 int index = 0;
1361 int type = path_type_file;
1362 const char *path = NULL;
1363 const char *tip = NULL;
1364 data_tip_node *node = NULL;
1365 data_tip_node *cur = NULL;
1366 data_tip *data = NULL;
1367
1368 vtoy_json_get_int(json, "index", &index);
1369 data = g_data_menu_tip + index;
1370
1371 vtoy_json_get_int(json, "type", &type);
1372
1373 path = VTOY_JSON_STR_EX("path");
1374 tip = VTOY_JSON_STR_EX("tip");
1375 if (path && tip)
1376 {
1377 node = zalloc(sizeof(data_tip_node));
1378 if (node)
1379 {
1380 node->type = type;
1381 scnprintf(node->path, sizeof(node->path), "%s", path);
1382 scnprintf(node->tip, sizeof(node->tip), "%s", tip);
1383
1384 vtoy_list_add(data->list, cur, node);
1385 }
1386 }
1387
1388 ret = ventoy_data_save_all();
1389
1390 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1391 return 0;
1392 }
1393
1394 static int ventoy_api_tip_del(struct mg_connection *conn, VTOY_JSON *json)
1395 {
1396 int ret;
1397 int index = 0;
1398 const char *path = NULL;
1399 data_tip_node *last = NULL;
1400 data_tip_node *node = NULL;
1401 data_tip *data = NULL;
1402
1403 vtoy_json_get_int(json, "index", &index);
1404 data = g_data_menu_tip + index;
1405
1406 path = VTOY_JSON_STR_EX("path");
1407 if (path)
1408 {
1409 vtoy_list_del(last, node, data->list, path);
1410 }
1411
1412 ret = ventoy_data_save_all();
1413
1414 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1415 return 0;
1416 }
1417
1418 #if 0
1419 #endif
1420
1421 void ventoy_data_default_menu_class(data_class *data)
1422 {
1423 memset(data, 0, sizeof(data_class));
1424 }
1425
1426 int ventoy_data_cmp_menu_class(data_class *data1, data_class *data2)
1427 {
1428 data_class_node *list1 = NULL;
1429 data_class_node *list2 = NULL;
1430
1431 if (NULL == data1->list && NULL == data2->list)
1432 {
1433 return 0;
1434 }
1435 else if (data1->list && data2->list)
1436 {
1437 list1 = data1->list;
1438 list2 = data2->list;
1439
1440 while (list1 && list2)
1441 {
1442 if ((list1->type != list2->type) ||
1443 strcmp(list1->path, list2->path) ||
1444 strcmp(list1->class, list2->class))
1445 {
1446 return 1;
1447 }
1448
1449 list1 = list1->next;
1450 list2 = list2->next;
1451 }
1452
1453 if (list1 == NULL && list2 == NULL)
1454 {
1455 return 0;
1456 }
1457 return 1;
1458 }
1459 else
1460 {
1461 return 1;
1462 }
1463
1464 return 0;
1465 }
1466
1467
1468 int ventoy_data_save_menu_class(data_class *data, const char *title, char *buf, int buflen)
1469 {
1470 int pos = 0;
1471 data_class_node *node = NULL;
1472
1473 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1474
1475 VTOY_JSON_FMT_KEY_L(L1, title);
1476 VTOY_JSON_FMT_ARY_BEGIN_N();
1477
1478 for (node = data->list; node; node = node->next)
1479 {
1480 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
1481
1482 if (node->type == class_type_key)
1483 {
1484 VTOY_JSON_FMT_STRN_LN(L3, "key", node->path);
1485 }
1486 else if (node->type == class_type_dir)
1487 {
1488 VTOY_JSON_FMT_STRN_PATH_LN(L3, "dir", node->path);
1489 }
1490 else
1491 {
1492 VTOY_JSON_FMT_STRN_PATH_LN(L3, "parent", node->path);
1493 }
1494 VTOY_JSON_FMT_STRN_LN(L3, "class", node->class);
1495
1496 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
1497 }
1498
1499 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1500 VTOY_JSON_FMT_END(pos);
1501
1502 return pos;
1503 }
1504
1505
1506 int ventoy_data_json_menu_class(data_class *data, char *buf, int buflen)
1507 {
1508 int pos = 0;
1509 int valid = 0;
1510 data_class_node *node = NULL;
1511
1512 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1513 VTOY_JSON_FMT_ARY_BEGIN();
1514
1515 for (node = data->list; node; node = node->next)
1516 {
1517 VTOY_JSON_FMT_OBJ_BEGIN();
1518
1519 VTOY_JSON_FMT_UINT("type", node->type);
1520 VTOY_JSON_FMT_STRN("path", node->path);
1521
1522 if (node->type == class_type_key)
1523 {
1524 valid = 1;
1525 }
1526 else
1527 {
1528 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
1529 }
1530 VTOY_JSON_FMT_SINT("valid", valid);
1531
1532 VTOY_JSON_FMT_STRN("class", node->class);
1533
1534 VTOY_JSON_FMT_OBJ_ENDEX();
1535 }
1536
1537 VTOY_JSON_FMT_ARY_END();
1538 VTOY_JSON_FMT_END(pos);
1539
1540 return pos;
1541 }
1542
1543
1544 static int ventoy_api_get_class(struct mg_connection *conn, VTOY_JSON *json)
1545 {
1546 api_get_func(conn, json, menu_class);
1547 return 0;
1548 }
1549
1550 static int ventoy_api_save_class(struct mg_connection *conn, VTOY_JSON *json)
1551 {
1552 int ret;
1553 ret = ventoy_data_save_all();
1554
1555 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1556 return 0;
1557 }
1558
1559 static int ventoy_api_class_add(struct mg_connection *conn, VTOY_JSON *json)
1560 {
1561 int ret;
1562 int index = 0;
1563 int type = class_type_key;
1564 const char *path = NULL;
1565 const char *class = NULL;
1566 data_class_node *node = NULL;
1567 data_class_node *cur = NULL;
1568 data_class *data = NULL;
1569
1570 vtoy_json_get_int(json, "index", &index);
1571 data = g_data_menu_class + index;
1572
1573 vtoy_json_get_int(json, "type", &type);
1574
1575 path = VTOY_JSON_STR_EX("path");
1576 class = VTOY_JSON_STR_EX("class");
1577 if (path && class)
1578 {
1579 node = zalloc(sizeof(data_class_node));
1580 if (node)
1581 {
1582 node->type = type;
1583
1584 scnprintf(node->path, sizeof(node->path), "%s", path);
1585 scnprintf(node->class, sizeof(node->class), "%s", class);
1586
1587 vtoy_list_add(data->list, cur, node);
1588 }
1589 }
1590
1591 ret = ventoy_data_save_all();
1592
1593 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1594 return 0;
1595 }
1596
1597 static int ventoy_api_class_del(struct mg_connection *conn, VTOY_JSON *json)
1598 {
1599 int ret;
1600 int index = 0;
1601 const char *path = NULL;
1602 data_class_node *last = NULL;
1603 data_class_node *node = NULL;
1604 data_class *data = NULL;
1605
1606 vtoy_json_get_int(json, "index", &index);
1607 data = g_data_menu_class + index;
1608
1609 path = VTOY_JSON_STR_EX("path");
1610 if (path)
1611 {
1612 vtoy_list_del(last, node, data->list, path);
1613 }
1614
1615 ret = ventoy_data_save_all();
1616
1617 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1618 return 0;
1619 }
1620
1621 #if 0
1622 #endif
1623
1624 void ventoy_data_default_auto_memdisk(data_auto_memdisk *data)
1625 {
1626 memset(data, 0, sizeof(data_auto_memdisk));
1627 }
1628
1629 int ventoy_data_cmp_auto_memdisk(data_auto_memdisk *data1, data_auto_memdisk *data2)
1630 {
1631 return ventoy_path_list_cmp(data1->list, data2->list);
1632 }
1633
1634 int ventoy_data_save_auto_memdisk(data_auto_memdisk *data, const char *title, char *buf, int buflen)
1635 {
1636 int pos = 0;
1637 path_node *node = NULL;
1638
1639 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1640
1641 VTOY_JSON_FMT_KEY_L(L1, title);
1642 VTOY_JSON_FMT_ARY_BEGIN_N();
1643
1644 for (node = data->list; node; node = node->next)
1645 {
1646 VTOY_JSON_FMT_ITEM_PATH_LN(L2, node->path);
1647 }
1648
1649 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1650 VTOY_JSON_FMT_END(pos);
1651
1652 return pos;
1653 }
1654
1655 int ventoy_data_json_auto_memdisk(data_auto_memdisk *data, char *buf, int buflen)
1656 {
1657 int pos = 0;
1658 int valid = 0;
1659 path_node *node = NULL;
1660
1661 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1662 VTOY_JSON_FMT_ARY_BEGIN();
1663
1664 for (node = data->list; node; node = node->next)
1665 {
1666 VTOY_JSON_FMT_OBJ_BEGIN();
1667
1668 VTOY_JSON_FMT_STRN("path", node->path);
1669 valid = ventoy_check_fuzzy_path(node->path, 1);
1670 VTOY_JSON_FMT_SINT("valid", valid);
1671
1672 VTOY_JSON_FMT_OBJ_ENDEX();
1673 }
1674
1675 VTOY_JSON_FMT_ARY_END();
1676 VTOY_JSON_FMT_END(pos);
1677
1678 return pos;
1679 }
1680
1681 static int ventoy_api_get_auto_memdisk(struct mg_connection *conn, VTOY_JSON *json)
1682 {
1683 api_get_func(conn, json, auto_memdisk);
1684 return 0;
1685 }
1686
1687 static int ventoy_api_save_auto_memdisk(struct mg_connection *conn, VTOY_JSON *json)
1688 {
1689 int ret;
1690
1691 ret = ventoy_data_save_all();
1692
1693 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1694 return 0;
1695 }
1696
1697 static int ventoy_api_auto_memdisk_add(struct mg_connection *conn, VTOY_JSON *json)
1698 {
1699 int ret;
1700 int index = 0;
1701 const char *path = NULL;
1702 path_node *node = NULL;
1703 path_node *cur = NULL;
1704 data_auto_memdisk *data = NULL;
1705
1706 vtoy_json_get_int(json, "index", &index);
1707 data = g_data_auto_memdisk + index;
1708
1709 path = VTOY_JSON_STR_EX("path");
1710 if (path)
1711 {
1712 node = zalloc(sizeof(path_node));
1713 if (node)
1714 {
1715 scnprintf(node->path, sizeof(node->path), "%s", path);
1716 vtoy_list_add(data->list, cur, node);
1717 }
1718 }
1719
1720 ret = ventoy_data_save_all();
1721
1722 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1723 return 0;
1724 }
1725
1726 static int ventoy_api_auto_memdisk_del(struct mg_connection *conn, VTOY_JSON *json)
1727 {
1728 int ret;
1729 int index = 0;
1730 const char *path = NULL;
1731 path_node *last = NULL;
1732 path_node *node = NULL;
1733 data_auto_memdisk *data = NULL;
1734
1735 vtoy_json_get_int(json, "index", &index);
1736 data = g_data_auto_memdisk + index;
1737
1738 path = VTOY_JSON_STR_EX("path");
1739 if (path)
1740 {
1741 vtoy_list_del(last, node, data->list, path);
1742 }
1743
1744 ret = ventoy_data_save_all();
1745
1746 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1747 return 0;
1748 }
1749
1750 #if 0
1751 #endif
1752
1753 void ventoy_data_default_image_list(data_image_list *data)
1754 {
1755 memset(data, 0, sizeof(data_image_list));
1756 }
1757
1758 int ventoy_data_cmp_image_list(data_image_list *data1, data_image_list *data2)
1759 {
1760 if (data1->type != data2->type)
1761 {
1762 if (data1->list || data2->list)
1763 {
1764 return 1;
1765 }
1766 else
1767 {
1768 return 0;
1769 }
1770 }
1771
1772 return ventoy_path_list_cmp(data1->list, data2->list);
1773 }
1774
1775 int ventoy_data_save_image_list(data_image_list *data, const char *title, char *buf, int buflen)
1776 {
1777 int pos = 0;
1778 int prelen;
1779 path_node *node = NULL;
1780 char newtitle[64];
1781
1782 (void)title;
1783
1784 if (!(data->list))
1785 {
1786 return 0;
1787 }
1788
1789 prelen = (int)strlen("image_list");
1790
1791 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1792
1793 if (data->type == 0)
1794 {
1795 scnprintf(newtitle, sizeof(newtitle), "image_list%s", title + prelen);
1796 }
1797 else
1798 {
1799 scnprintf(newtitle, sizeof(newtitle), "image_blacklist%s", title + prelen);
1800 }
1801 VTOY_JSON_FMT_KEY_L(L1, newtitle);
1802
1803 VTOY_JSON_FMT_ARY_BEGIN_N();
1804
1805 for (node = data->list; node; node = node->next)
1806 {
1807 VTOY_JSON_FMT_ITEM_PATH_LN(L2, node->path);
1808 }
1809
1810 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1811 VTOY_JSON_FMT_END(pos);
1812
1813 return pos;
1814 }
1815
1816 int ventoy_data_json_image_list(data_image_list *data, char *buf, int buflen)
1817 {
1818 int pos = 0;
1819 int valid = 0;
1820 path_node *node = NULL;
1821
1822 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1823
1824 VTOY_JSON_FMT_OBJ_BEGIN();
1825 VTOY_JSON_FMT_SINT("type", data->type);
1826
1827 VTOY_JSON_FMT_KEY("list");
1828 VTOY_JSON_FMT_ARY_BEGIN();
1829
1830 for (node = data->list; node; node = node->next)
1831 {
1832 VTOY_JSON_FMT_OBJ_BEGIN();
1833
1834 VTOY_JSON_FMT_STRN("path", node->path);
1835 valid = ventoy_check_fuzzy_path(node->path, 1);
1836 VTOY_JSON_FMT_SINT("valid", valid);
1837
1838 VTOY_JSON_FMT_OBJ_ENDEX();
1839 }
1840
1841 VTOY_JSON_FMT_ARY_ENDEX();
1842 VTOY_JSON_FMT_OBJ_END();
1843
1844 VTOY_JSON_FMT_END(pos);
1845
1846 return pos;
1847 }
1848
1849 static int ventoy_api_get_image_list(struct mg_connection *conn, VTOY_JSON *json)
1850 {
1851 api_get_func(conn, json, image_list);
1852 return 0;
1853 }
1854
1855 static int ventoy_api_save_image_list(struct mg_connection *conn, VTOY_JSON *json)
1856 {
1857 int ret;
1858 int index = 0;
1859 data_image_list *data = NULL;
1860
1861 vtoy_json_get_int(json, "index", &index);
1862 data = g_data_image_list + index;
1863
1864 VTOY_JSON_INT("type", data->type);
1865
1866 ret = ventoy_data_save_all();
1867
1868 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1869 return 0;
1870 }
1871
1872 static int ventoy_api_image_list_add(struct mg_connection *conn, VTOY_JSON *json)
1873 {
1874 int ret;
1875 int index = 0;
1876 const char *path = NULL;
1877 path_node *node = NULL;
1878 path_node *cur = NULL;
1879 data_image_list *data = NULL;
1880
1881 vtoy_json_get_int(json, "index", &index);
1882 data = g_data_image_list + index;
1883
1884 path = VTOY_JSON_STR_EX("path");
1885 if (path)
1886 {
1887 node = zalloc(sizeof(path_node));
1888 if (node)
1889 {
1890 scnprintf(node->path, sizeof(node->path), "%s", path);
1891 vtoy_list_add(data->list, cur, node);
1892 }
1893 }
1894
1895 ret = ventoy_data_save_all();
1896
1897 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1898 return 0;
1899 }
1900
1901 static int ventoy_api_image_list_del(struct mg_connection *conn, VTOY_JSON *json)
1902 {
1903 int ret;
1904 int index = 0;
1905 const char *path = NULL;
1906 path_node *last = NULL;
1907 path_node *node = NULL;
1908 data_image_list *data = NULL;
1909
1910 vtoy_json_get_int(json, "index", &index);
1911 data = g_data_image_list + index;
1912
1913 path = VTOY_JSON_STR_EX("path");
1914 if (path)
1915 {
1916 vtoy_list_del(last, node, data->list, path);
1917 }
1918
1919 ret = ventoy_data_save_all();
1920
1921 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1922 return 0;
1923 }
1924
1925 #if 0
1926 #endif
1927
1928 void ventoy_data_default_password(data_password *data)
1929 {
1930 memset(data, 0, sizeof(data_password));
1931 }
1932
1933 int ventoy_data_cmp_password(data_password *data1, data_password *data2)
1934 {
1935 menu_password *list1 = NULL;
1936 menu_password *list2 = NULL;
1937
1938 if (strcmp(data1->bootpwd, data2->bootpwd) ||
1939 strcmp(data1->isopwd, data2->isopwd) ||
1940 strcmp(data1->wimpwd, data2->wimpwd) ||
1941 strcmp(data1->vhdpwd, data2->vhdpwd) ||
1942 strcmp(data1->imgpwd, data2->imgpwd) ||
1943 strcmp(data1->efipwd, data2->efipwd) ||
1944 strcmp(data1->vtoypwd, data2->vtoypwd)
1945 )
1946 {
1947 return 1;
1948 }
1949
1950 if (NULL == data1->list && NULL == data2->list)
1951 {
1952 return 0;
1953 }
1954 else if (data1->list && data2->list)
1955 {
1956 list1 = data1->list;
1957 list2 = data2->list;
1958
1959 while (list1 && list2)
1960 {
1961 if ((list1->type != list2->type) || strcmp(list1->path, list2->path))
1962 {
1963 return 1;
1964 }
1965
1966 list1 = list1->next;
1967 list2 = list2->next;
1968 }
1969
1970 if (list1 == NULL && list2 == NULL)
1971 {
1972 return 0;
1973 }
1974 return 1;
1975 }
1976 else
1977 {
1978 return 1;
1979 }
1980
1981 return 0;
1982 }
1983
1984
1985 int ventoy_data_save_password(data_password *data, const char *title, char *buf, int buflen)
1986 {
1987 int pos = 0;
1988 menu_password *node = NULL;
1989 data_password *def = g_data_password + bios_max;
1990
1991 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1992 VTOY_JSON_FMT_KEY_L(L1, title);
1993 VTOY_JSON_FMT_OBJ_BEGIN_N();
1994
1995 VTOY_JSON_FMT_DIFF_STRN(L2, "bootpwd", bootpwd);
1996 VTOY_JSON_FMT_DIFF_STRN(L2, "isopwd", isopwd);
1997 VTOY_JSON_FMT_DIFF_STRN(L2, "wimpwd", wimpwd);
1998 VTOY_JSON_FMT_DIFF_STRN(L2, "vhdpwd", vhdpwd);
1999 VTOY_JSON_FMT_DIFF_STRN(L2, "imgpwd", imgpwd);
2000 VTOY_JSON_FMT_DIFF_STRN(L2, "efipwd", efipwd);
2001 VTOY_JSON_FMT_DIFF_STRN(L2, "vtoypwd", vtoypwd);
2002
2003 if (data->list)
2004 {
2005 VTOY_JSON_FMT_KEY_L(L2, "menupwd");
2006 VTOY_JSON_FMT_ARY_BEGIN_N();
2007
2008 for (node = data->list; node; node = node->next)
2009 {
2010 VTOY_JSON_FMT_OBJ_BEGIN_LN(L3);
2011
2012 if (node->type == 0)
2013 {
2014 VTOY_JSON_FMT_STRN_PATH_LN(L4, "file", node->path);
2015 }
2016 else
2017 {
2018 VTOY_JSON_FMT_STRN_PATH_LN(L4, "parent", node->path);
2019 }
2020 VTOY_JSON_FMT_STRN_LN(L4, "pwd", node->pwd);
2021
2022 VTOY_JSON_FMT_OBJ_ENDEX_LN(L3);
2023 }
2024
2025 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
2026 }
2027
2028 VTOY_JSON_FMT_OBJ_ENDEX_LN(L1);
2029
2030 VTOY_JSON_FMT_END(pos);
2031
2032 return pos;
2033 }
2034
2035
2036 int ventoy_data_json_password(data_password *data, char *buf, int buflen)
2037 {
2038 int pos = 0;
2039 int valid = 0;
2040 menu_password *node = NULL;
2041
2042 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2043
2044 VTOY_JSON_FMT_OBJ_BEGIN();
2045
2046 VTOY_JSON_FMT_STRN("bootpwd", data->bootpwd);
2047 VTOY_JSON_FMT_STRN("isopwd", data->isopwd);
2048 VTOY_JSON_FMT_STRN("wimpwd", data->wimpwd);
2049 VTOY_JSON_FMT_STRN("vhdpwd", data->vhdpwd);
2050 VTOY_JSON_FMT_STRN("imgpwd", data->imgpwd);
2051 VTOY_JSON_FMT_STRN("efipwd", data->efipwd);
2052 VTOY_JSON_FMT_STRN("vtoypwd", data->vtoypwd);
2053
2054 VTOY_JSON_FMT_KEY("list");
2055 VTOY_JSON_FMT_ARY_BEGIN();
2056
2057 for (node = data->list; node; node = node->next)
2058 {
2059 VTOY_JSON_FMT_OBJ_BEGIN();
2060
2061 VTOY_JSON_FMT_SINT("type", node->type);
2062 VTOY_JSON_FMT_STRN("path", node->path);
2063 if (node->type == path_type_file)
2064 {
2065 valid = ventoy_check_fuzzy_path(node->path, 1);
2066 }
2067 else
2068 {
2069 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
2070 }
2071
2072 VTOY_JSON_FMT_SINT("valid", valid);
2073 VTOY_JSON_FMT_STRN("pwd", node->pwd);
2074
2075 VTOY_JSON_FMT_OBJ_ENDEX();
2076 }
2077
2078 VTOY_JSON_FMT_ARY_ENDEX();
2079
2080 VTOY_JSON_FMT_OBJ_END();
2081 VTOY_JSON_FMT_END(pos);
2082
2083 return pos;
2084 }
2085
2086 static int ventoy_api_get_password(struct mg_connection *conn, VTOY_JSON *json)
2087 {
2088 api_get_func(conn, json, password);
2089 return 0;
2090 }
2091
2092 static int ventoy_api_save_password(struct mg_connection *conn, VTOY_JSON *json)
2093 {
2094 int ret;
2095 int index = 0;
2096 data_password *data = NULL;
2097
2098 vtoy_json_get_int(json, "index", &index);
2099 data = g_data_password + index;
2100
2101 VTOY_JSON_STR("bootpwd", data->bootpwd);
2102 VTOY_JSON_STR("isopwd", data->isopwd);
2103 VTOY_JSON_STR("wimpwd", data->wimpwd);
2104 VTOY_JSON_STR("vhdpwd", data->vhdpwd);
2105 VTOY_JSON_STR("imgpwd", data->imgpwd);
2106 VTOY_JSON_STR("efipwd", data->efipwd);
2107 VTOY_JSON_STR("vtoypwd", data->vtoypwd);
2108
2109 ret = ventoy_data_save_all();
2110
2111 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2112 return 0;
2113 }
2114
2115 static int ventoy_api_password_add(struct mg_connection *conn, VTOY_JSON *json)
2116 {
2117 int ret;
2118 int index = 0;
2119 int type = 0;
2120 const char *path = NULL;
2121 const char *pwd = NULL;
2122 menu_password *node = NULL;
2123 menu_password *cur = NULL;
2124 data_password *data = NULL;
2125
2126 vtoy_json_get_int(json, "index", &index);
2127 data = g_data_password + index;
2128
2129 vtoy_json_get_int(json, "type", &type);
2130
2131 path = VTOY_JSON_STR_EX("path");
2132 pwd = VTOY_JSON_STR_EX("pwd");
2133 if (path && pwd)
2134 {
2135 node = zalloc(sizeof(menu_password));
2136 if (node)
2137 {
2138 node->type = type;
2139 scnprintf(node->path, sizeof(node->path), "%s", path);
2140 scnprintf(node->pwd, sizeof(node->pwd), "%s", pwd);
2141
2142 vtoy_list_add(data->list, cur, node);
2143 }
2144 }
2145
2146 ret = ventoy_data_save_all();
2147
2148 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2149 return 0;
2150 }
2151
2152 static int ventoy_api_password_del(struct mg_connection *conn, VTOY_JSON *json)
2153 {
2154 int ret;
2155 int index = 0;
2156 const char *path = NULL;
2157 menu_password *last = NULL;
2158 menu_password *node = NULL;
2159 data_password *data = NULL;
2160
2161 vtoy_json_get_int(json, "index", &index);
2162 data = g_data_password + index;
2163
2164 path = VTOY_JSON_STR_EX("path");
2165 if (path)
2166 {
2167 vtoy_list_del(last, node, data->list, path);
2168 }
2169
2170 ret = ventoy_data_save_all();
2171
2172 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2173 return 0;
2174 }
2175
2176 #if 0
2177 #endif
2178
2179 void ventoy_data_default_conf_replace(data_conf_replace *data)
2180 {
2181 memset(data, 0, sizeof(data_conf_replace));
2182 }
2183
2184 int ventoy_data_cmp_conf_replace(data_conf_replace *data1, data_conf_replace *data2)
2185 {
2186 conf_replace_node *list1 = NULL;
2187 conf_replace_node *list2 = NULL;
2188
2189 if (NULL == data1->list && NULL == data2->list)
2190 {
2191 return 0;
2192 }
2193 else if (data1->list && data2->list)
2194 {
2195 list1 = data1->list;
2196 list2 = data2->list;
2197
2198 while (list1 && list2)
2199 {
2200 if (list1->image != list2->image ||
2201 strcmp(list1->path, list2->path) ||
2202 strcmp(list1->org, list2->org) ||
2203 strcmp(list1->new, list2->new)
2204 )
2205 {
2206 return 1;
2207 }
2208
2209 list1 = list1->next;
2210 list2 = list2->next;
2211 }
2212
2213 if (list1 == NULL && list2 == NULL)
2214 {
2215 return 0;
2216 }
2217 return 1;
2218 }
2219 else
2220 {
2221 return 1;
2222 }
2223
2224 return 0;
2225 }
2226
2227
2228 int ventoy_data_save_conf_replace(data_conf_replace *data, const char *title, char *buf, int buflen)
2229 {
2230 int pos = 0;
2231 conf_replace_node *node = NULL;
2232
2233 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2234
2235 VTOY_JSON_FMT_KEY_L(L1, title);
2236 VTOY_JSON_FMT_ARY_BEGIN_N();
2237
2238 for (node = data->list; node; node = node->next)
2239 {
2240 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
2241
2242 VTOY_JSON_FMT_STRN_PATH_LN(L3, "iso", node->path);
2243 VTOY_JSON_FMT_STRN_LN(L3, "org", node->org);
2244 VTOY_JSON_FMT_STRN_PATH_LN(L3, "new", node->new);
2245 if (node->image)
2246 {
2247 VTOY_JSON_FMT_SINT_LN(L3, "img", node->image);
2248 }
2249
2250 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
2251 }
2252
2253 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
2254 VTOY_JSON_FMT_END(pos);
2255
2256 return pos;
2257 }
2258
2259
2260 int ventoy_data_json_conf_replace(data_conf_replace *data, char *buf, int buflen)
2261 {
2262 int pos = 0;
2263 conf_replace_node *node = NULL;
2264
2265 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2266 VTOY_JSON_FMT_ARY_BEGIN();
2267
2268 for (node = data->list; node; node = node->next)
2269 {
2270 VTOY_JSON_FMT_OBJ_BEGIN();
2271
2272 VTOY_JSON_FMT_STRN("path", node->path);
2273 VTOY_JSON_FMT_SINT("valid", ventoy_check_fuzzy_path(node->path, 1));
2274 VTOY_JSON_FMT_STRN("org", node->org);
2275 VTOY_JSON_FMT_STRN("new", node->new);
2276 VTOY_JSON_FMT_SINT("new_valid", ventoy_is_file_exist("%s%s", g_cur_dir, node->new));
2277 VTOY_JSON_FMT_SINT("img", node->image);
2278
2279 VTOY_JSON_FMT_OBJ_ENDEX();
2280 }
2281
2282 VTOY_JSON_FMT_ARY_END();
2283 VTOY_JSON_FMT_END(pos);
2284
2285 return pos;
2286 }
2287
2288 static int ventoy_api_get_conf_replace(struct mg_connection *conn, VTOY_JSON *json)
2289 {
2290 api_get_func(conn, json, conf_replace);
2291 return 0;
2292 }
2293
2294 static int ventoy_api_save_conf_replace(struct mg_connection *conn, VTOY_JSON *json)
2295 {
2296 int ret;
2297 ret = ventoy_data_save_all();
2298
2299 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2300 return 0;
2301 }
2302
2303 static int ventoy_api_conf_replace_add(struct mg_connection *conn, VTOY_JSON *json)
2304 {
2305 int ret;
2306 int image = 0;
2307 int index = 0;
2308 const char *path = NULL;
2309 const char *org = NULL;
2310 const char *new = NULL;
2311 conf_replace_node *node = NULL;
2312 conf_replace_node *cur = NULL;
2313 data_conf_replace *data = NULL;
2314
2315 vtoy_json_get_int(json, "img", &image);
2316
2317 vtoy_json_get_int(json, "index", &index);
2318 data = g_data_conf_replace + index;
2319
2320 path = VTOY_JSON_STR_EX("path");
2321 org = VTOY_JSON_STR_EX("org");
2322 new = VTOY_JSON_STR_EX("new");
2323 if (path && org && new)
2324 {
2325 node = zalloc(sizeof(conf_replace_node));
2326 if (node)
2327 {
2328 node->image = image;
2329 scnprintf(node->path, sizeof(node->path), "%s", path);
2330 scnprintf(node->org, sizeof(node->org), "%s", org);
2331 scnprintf(node->new, sizeof(node->new), "%s", new);
2332
2333 vtoy_list_add(data->list, cur, node);
2334 }
2335 }
2336
2337 ret = ventoy_data_save_all();
2338
2339 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2340 return 0;
2341 }
2342
2343 static int ventoy_api_conf_replace_del(struct mg_connection *conn, VTOY_JSON *json)
2344 {
2345 int ret;
2346 int index = 0;
2347 const char *path = NULL;
2348 conf_replace_node *last = NULL;
2349 conf_replace_node *node = NULL;
2350 data_conf_replace *data = NULL;
2351
2352 vtoy_json_get_int(json, "index", &index);
2353 data = g_data_conf_replace + index;
2354
2355 path = VTOY_JSON_STR_EX("path");
2356 if (path)
2357 {
2358 vtoy_list_del(last, node, data->list, path);
2359 }
2360
2361 ret = ventoy_data_save_all();
2362
2363 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2364 return 0;
2365 }
2366
2367
2368 #if 0
2369 #endif
2370
2371 void ventoy_data_default_dud(data_dud *data)
2372 {
2373 memset(data, 0, sizeof(data_dud));
2374 }
2375
2376 int ventoy_data_cmp_dud(data_dud *data1, data_dud *data2)
2377 {
2378 dud_node *list1 = NULL;
2379 dud_node *list2 = NULL;
2380
2381 if (NULL == data1->list && NULL == data2->list)
2382 {
2383 return 0;
2384 }
2385 else if (data1->list && data2->list)
2386 {
2387 list1 = data1->list;
2388 list2 = data2->list;
2389
2390 while (list1 && list2)
2391 {
2392 if (strcmp(list1->path, list2->path))
2393 {
2394 return 1;
2395 }
2396
2397 /* no need to compare dud list with default */
2398 list1 = list1->next;
2399 list2 = list2->next;
2400 }
2401
2402 if (list1 == NULL && list2 == NULL)
2403 {
2404 return 0;
2405 }
2406 return 1;
2407 }
2408 else
2409 {
2410 return 1;
2411 }
2412
2413 return 0;
2414 }
2415
2416
2417 int ventoy_data_save_dud(data_dud *data, const char *title, char *buf, int buflen)
2418 {
2419 int pos = 0;
2420 dud_node *node = NULL;
2421 path_node *pathnode = NULL;
2422
2423 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2424
2425 VTOY_JSON_FMT_KEY_L(L1, title);
2426 VTOY_JSON_FMT_ARY_BEGIN_N();
2427
2428 for (node = data->list; node; node = node->next)
2429 {
2430 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
2431 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
2432
2433 VTOY_JSON_FMT_KEY_L(L3, "dud");
2434 VTOY_JSON_FMT_ARY_BEGIN_N();
2435 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2436 {
2437 VTOY_JSON_FMT_ITEM_PATH_LN(L4, pathnode->path);
2438 }
2439 VTOY_JSON_FMT_ARY_ENDEX_LN(L3);
2440
2441 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
2442 }
2443
2444 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
2445 VTOY_JSON_FMT_END(pos);
2446
2447 return pos;
2448 }
2449
2450
2451 int ventoy_data_json_dud(data_dud *data, char *buf, int buflen)
2452 {
2453 int pos = 0;
2454 int valid = 0;
2455 dud_node *node = NULL;
2456 path_node *pathnode = NULL;
2457
2458 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2459 VTOY_JSON_FMT_ARY_BEGIN();
2460
2461 for (node = data->list; node; node = node->next)
2462 {
2463 VTOY_JSON_FMT_OBJ_BEGIN();
2464
2465 VTOY_JSON_FMT_STRN("path", node->path);
2466 valid = ventoy_check_fuzzy_path(node->path, 1);
2467 VTOY_JSON_FMT_SINT("valid", valid);
2468
2469
2470 VTOY_JSON_FMT_KEY("list");
2471 VTOY_JSON_FMT_ARY_BEGIN();
2472 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2473 {
2474 VTOY_JSON_FMT_OBJ_BEGIN();
2475 VTOY_JSON_FMT_STRN("path", pathnode->path);
2476
2477 valid = ventoy_is_file_exist("%s%s", g_cur_dir, pathnode->path);
2478 VTOY_JSON_FMT_SINT("valid", valid);
2479 VTOY_JSON_FMT_OBJ_ENDEX();
2480 }
2481 VTOY_JSON_FMT_ARY_ENDEX();
2482
2483
2484 VTOY_JSON_FMT_OBJ_ENDEX();
2485 }
2486
2487 VTOY_JSON_FMT_ARY_END();
2488 VTOY_JSON_FMT_END(pos);
2489
2490 return pos;
2491 }
2492
2493 static int ventoy_api_get_dud(struct mg_connection *conn, VTOY_JSON *json)
2494 {
2495 api_get_func(conn, json, dud);
2496 return 0;
2497 }
2498
2499 static int ventoy_api_save_dud(struct mg_connection *conn, VTOY_JSON *json)
2500 {
2501 int ret;
2502 ret = ventoy_data_save_all();
2503
2504 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2505 return 0;
2506 }
2507
2508
2509 static int ventoy_api_dud_add(struct mg_connection *conn, VTOY_JSON *json)
2510 {
2511 int ret;
2512 int index = 0;
2513 const char *path = NULL;
2514 dud_node *node = NULL;
2515 dud_node *cur = NULL;
2516 data_dud *data = NULL;
2517 VTOY_JSON *array = NULL;
2518
2519 vtoy_json_get_int(json, "index", &index);
2520 data = g_data_dud + index;
2521
2522 array = vtoy_json_find_item(json, JSON_TYPE_ARRAY, "dud");
2523 path = VTOY_JSON_STR_EX("path");
2524 if (path && array)
2525 {
2526 node = zalloc(sizeof(dud_node));
2527 if (node)
2528 {
2529 scnprintf(node->path, sizeof(node->path), "%s", path);
2530 node->list = ventoy_path_node_add_array(array);
2531
2532 vtoy_list_add(data->list, cur, node);
2533 }
2534 }
2535
2536 ret = ventoy_data_save_all();
2537
2538 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2539 return 0;
2540 }
2541
2542 static int ventoy_api_dud_del(struct mg_connection *conn, VTOY_JSON *json)
2543 {
2544 int ret;
2545 int index = 0;
2546 const char *path = NULL;
2547 dud_node *last = NULL;
2548 dud_node *node = NULL;
2549 data_dud *data = NULL;
2550
2551 vtoy_json_get_int(json, "index", &index);
2552 data = g_data_dud + index;
2553
2554 path = VTOY_JSON_STR_EX("path");
2555 if (path)
2556 {
2557 vtoy_list_del_ex(last, node, data->list, path, ventoy_free_path_node_list);
2558 }
2559
2560 ret = ventoy_data_save_all();
2561
2562 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2563 return 0;
2564 }
2565
2566
2567 static int ventoy_api_dud_add_inner(struct mg_connection *conn, VTOY_JSON *json)
2568 {
2569 int ret;
2570 int index = 0;
2571 const char *path = NULL;
2572 const char *outpath = NULL;
2573 path_node *pcur = NULL;
2574 path_node *pnode = NULL;
2575 dud_node *node = NULL;
2576 data_dud *data = NULL;
2577
2578 vtoy_json_get_int(json, "index", &index);
2579 data = g_data_dud + index;
2580
2581 path = VTOY_JSON_STR_EX("path");
2582 outpath = VTOY_JSON_STR_EX("outpath");
2583 if (path && outpath)
2584 {
2585 for (node = data->list; node; node = node->next)
2586 {
2587 if (strcmp(outpath, node->path) == 0)
2588 {
2589 pnode = zalloc(sizeof(path_node));
2590 if (pnode)
2591 {
2592 scnprintf(pnode->path, sizeof(pnode->path), "%s", path);
2593 vtoy_list_add(node->list, pcur, pnode);
2594 }
2595
2596 break;
2597 }
2598 }
2599 }
2600
2601 ret = ventoy_data_save_all();
2602
2603 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2604 return 0;
2605 }
2606
2607 static int ventoy_api_dud_del_inner(struct mg_connection *conn, VTOY_JSON *json)
2608 {
2609 int ret;
2610 int index = 0;
2611 const char *path = NULL;
2612 const char *outpath = NULL;
2613 path_node *plast = NULL;
2614 path_node *pnode = NULL;
2615 dud_node *node = NULL;
2616 data_dud *data = NULL;
2617
2618 vtoy_json_get_int(json, "index", &index);
2619 data = g_data_dud + index;
2620
2621 path = VTOY_JSON_STR_EX("path");
2622 outpath = VTOY_JSON_STR_EX("outpath");
2623 if (path && outpath)
2624 {
2625 for (node = data->list; node; node = node->next)
2626 {
2627 if (strcmp(outpath, node->path) == 0)
2628 {
2629 vtoy_list_del(plast, pnode, node->list, path);
2630 break;
2631 }
2632 }
2633 }
2634
2635 ret = ventoy_data_save_all();
2636
2637 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2638 return 0;
2639 }
2640
2641
2642 #if 0
2643 #endif
2644
2645 void ventoy_data_default_auto_install(data_auto_install *data)
2646 {
2647 memset(data, 0, sizeof(data_auto_install));
2648 }
2649
2650 int ventoy_data_cmp_auto_install(data_auto_install *data1, data_auto_install *data2)
2651 {
2652 auto_install_node *list1 = NULL;
2653 auto_install_node *list2 = NULL;
2654
2655 if (NULL == data1->list && NULL == data2->list)
2656 {
2657 return 0;
2658 }
2659 else if (data1->list && data2->list)
2660 {
2661 list1 = data1->list;
2662 list2 = data2->list;
2663
2664 while (list1 && list2)
2665 {
2666 if (list1->timeout != list2->timeout ||
2667 list1->autosel != list2->autosel ||
2668 strcmp(list1->path, list2->path))
2669 {
2670 return 1;
2671 }
2672
2673 /* no need to compare auto install list with default */
2674 list1 = list1->next;
2675 list2 = list2->next;
2676 }
2677
2678 if (list1 == NULL && list2 == NULL)
2679 {
2680 return 0;
2681 }
2682 return 1;
2683 }
2684 else
2685 {
2686 return 1;
2687 }
2688
2689 return 0;
2690 }
2691
2692
2693 int ventoy_data_save_auto_install(data_auto_install *data, const char *title, char *buf, int buflen)
2694 {
2695 int pos = 0;
2696 auto_install_node *node = NULL;
2697 path_node *pathnode = NULL;
2698
2699 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2700
2701 VTOY_JSON_FMT_KEY_L(L1, title);
2702 VTOY_JSON_FMT_ARY_BEGIN_N();
2703
2704 for (node = data->list; node; node = node->next)
2705 {
2706 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
2707 if (node->type == 0)
2708 {
2709 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
2710 }
2711 else
2712 {
2713 VTOY_JSON_FMT_STRN_PATH_LN(L3, "parent", node->path);
2714 }
2715
2716
2717 VTOY_JSON_FMT_KEY_L(L3, "template");
2718 VTOY_JSON_FMT_ARY_BEGIN_N();
2719 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2720 {
2721 VTOY_JSON_FMT_ITEM_PATH_LN(L4, pathnode->path);
2722 }
2723 VTOY_JSON_FMT_ARY_ENDEX_LN(L3);
2724
2725 if (node->timeouten)
2726 {
2727 VTOY_JSON_FMT_SINT_LN(L3, "timeout", node->timeout);
2728 }
2729
2730 if (node->autoselen)
2731 {
2732 VTOY_JSON_FMT_SINT_LN(L3, "autosel", node->autosel);
2733 }
2734
2735 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
2736 }
2737
2738 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
2739 VTOY_JSON_FMT_END(pos);
2740
2741 return pos;
2742 }
2743
2744
2745 int ventoy_data_json_auto_install(data_auto_install *data, char *buf, int buflen)
2746 {
2747 int pos = 0;
2748 int valid = 0;
2749 auto_install_node *node = NULL;
2750 path_node *pathnode = NULL;
2751
2752 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2753 VTOY_JSON_FMT_ARY_BEGIN();
2754
2755 for (node = data->list; node; node = node->next)
2756 {
2757 VTOY_JSON_FMT_OBJ_BEGIN();
2758
2759 VTOY_JSON_FMT_STRN("path", node->path);
2760
2761 if (node->type == 0)
2762 {
2763 valid = ventoy_check_fuzzy_path(node->path, 1);
2764 }
2765 else
2766 {
2767 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
2768 }
2769 VTOY_JSON_FMT_SINT("valid", valid);
2770 VTOY_JSON_FMT_SINT("type", node->type);
2771
2772 VTOY_JSON_FMT_BOOL("timeouten", node->timeouten);
2773 VTOY_JSON_FMT_BOOL("autoselen", node->autoselen);
2774
2775 VTOY_JSON_FMT_SINT("autosel", node->autosel);
2776 VTOY_JSON_FMT_SINT("timeout", node->timeout);
2777
2778 VTOY_JSON_FMT_KEY("list");
2779 VTOY_JSON_FMT_ARY_BEGIN();
2780 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2781 {
2782 VTOY_JSON_FMT_OBJ_BEGIN();
2783 VTOY_JSON_FMT_STRN("path", pathnode->path);
2784
2785 valid = ventoy_is_file_exist("%s%s", g_cur_dir, pathnode->path);
2786 VTOY_JSON_FMT_SINT("valid", valid);
2787 VTOY_JSON_FMT_OBJ_ENDEX();
2788 }
2789 VTOY_JSON_FMT_ARY_ENDEX();
2790
2791
2792 VTOY_JSON_FMT_OBJ_ENDEX();
2793 }
2794
2795 VTOY_JSON_FMT_ARY_END();
2796 VTOY_JSON_FMT_END(pos);
2797
2798 return pos;
2799 }
2800
2801 static int ventoy_api_get_auto_install(struct mg_connection *conn, VTOY_JSON *json)
2802 {
2803 api_get_func(conn, json, auto_install);
2804 return 0;
2805 }
2806
2807 static int ventoy_api_save_auto_install(struct mg_connection *conn, VTOY_JSON *json)
2808 {
2809 int ret;
2810 int id = -1;
2811 int cnt = 0;
2812 int index = 0;
2813 uint8_t timeouten = 0;
2814 uint8_t autoselen = 0;
2815 auto_install_node *node = NULL;
2816 data_auto_install *data = NULL;
2817
2818 vtoy_json_get_int(json, "index", &index);
2819 vtoy_json_get_int(json, "id", &id);
2820
2821 vtoy_json_get_bool(json, "timeouten", &timeouten);
2822 vtoy_json_get_bool(json, "autoselen", &autoselen);
2823
2824 data = g_data_auto_install + index;
2825
2826 if (id >= 0)
2827 {
2828 for (node = data->list; node; node = node->next)
2829 {
2830 if (cnt == id)
2831 {
2832 node->timeouten = (int)timeouten;
2833 node->autoselen = (int)autoselen;
2834 VTOY_JSON_INT("timeout", node->timeout);
2835 VTOY_JSON_INT("autosel", node->autosel);
2836 break;
2837 }
2838 }
2839 }
2840
2841 ret = ventoy_data_save_all();
2842
2843 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2844 return 0;
2845 }
2846
2847
2848 static int ventoy_api_auto_install_add(struct mg_connection *conn, VTOY_JSON *json)
2849 {
2850 int ret;
2851 int index = 0;
2852 int type = 0;
2853 const char *path = NULL;
2854 auto_install_node *node = NULL;
2855 auto_install_node *cur = NULL;
2856 data_auto_install *data = NULL;
2857 VTOY_JSON *array = NULL;
2858
2859 vtoy_json_get_int(json, "type", &type);
2860 vtoy_json_get_int(json, "index", &index);
2861 data = g_data_auto_install + index;
2862
2863 array = vtoy_json_find_item(json, JSON_TYPE_ARRAY, "template");
2864 path = VTOY_JSON_STR_EX("path");
2865 if (path && array)
2866 {
2867 node = zalloc(sizeof(auto_install_node));
2868 if (node)
2869 {
2870 node->type = type;
2871 node->timeouten = 0;
2872 node->autoselen = 0;
2873 node->autosel = 1;
2874 node->timeout = 0;
2875 scnprintf(node->path, sizeof(node->path), "%s", path);
2876 node->list = ventoy_path_node_add_array(array);
2877
2878 vtoy_list_add(data->list, cur, node);
2879 }
2880 }
2881
2882 ret = ventoy_data_save_all();
2883
2884 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2885 return 0;
2886 }
2887
2888 static int ventoy_api_auto_install_del(struct mg_connection *conn, VTOY_JSON *json)
2889 {
2890 int ret;
2891 int index = 0;
2892 const char *path = NULL;
2893 auto_install_node *last = NULL;
2894 auto_install_node *node = NULL;
2895 data_auto_install *data = NULL;
2896
2897 vtoy_json_get_int(json, "index", &index);
2898 data = g_data_auto_install + index;
2899
2900 path = VTOY_JSON_STR_EX("path");
2901 if (path)
2902 {
2903 vtoy_list_del_ex(last, node, data->list, path, ventoy_free_path_node_list);
2904 }
2905
2906 ret = ventoy_data_save_all();
2907
2908 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2909 return 0;
2910 }
2911
2912 static int ventoy_api_auto_install_add_inner(struct mg_connection *conn, VTOY_JSON *json)
2913 {
2914 int ret;
2915 int index = 0;
2916 const char *path = NULL;
2917 const char *outpath = NULL;
2918 path_node *pcur = NULL;
2919 path_node *pnode = NULL;
2920 auto_install_node *node = NULL;
2921 data_auto_install *data = NULL;
2922
2923 vtoy_json_get_int(json, "index", &index);
2924 data = g_data_auto_install + index;
2925
2926 path = VTOY_JSON_STR_EX("path");
2927 outpath = VTOY_JSON_STR_EX("outpath");
2928 if (path && outpath)
2929 {
2930 for (node = data->list; node; node = node->next)
2931 {
2932 if (strcmp(outpath, node->path) == 0)
2933 {
2934 pnode = zalloc(sizeof(path_node));
2935 if (pnode)
2936 {
2937 scnprintf(pnode->path, sizeof(pnode->path), "%s", path);
2938 vtoy_list_add(node->list, pcur, pnode);
2939 }
2940
2941 break;
2942 }
2943 }
2944 }
2945
2946 ret = ventoy_data_save_all();
2947
2948 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2949 return 0;
2950 }
2951
2952 static int ventoy_api_auto_install_del_inner(struct mg_connection *conn, VTOY_JSON *json)
2953 {
2954 int ret;
2955 int index = 0;
2956 const char *path = NULL;
2957 const char *outpath = NULL;
2958 path_node *plast = NULL;
2959 path_node *pnode = NULL;
2960 auto_install_node *node = NULL;
2961 data_auto_install *data = NULL;
2962
2963 vtoy_json_get_int(json, "index", &index);
2964 data = g_data_auto_install + index;
2965
2966 path = VTOY_JSON_STR_EX("path");
2967 outpath = VTOY_JSON_STR_EX("outpath");
2968 if (path && outpath)
2969 {
2970 for (node = data->list; node; node = node->next)
2971 {
2972 if (strcmp(outpath, node->path) == 0)
2973 {
2974 vtoy_list_del(plast, pnode, node->list, path);
2975 break;
2976 }
2977 }
2978 }
2979
2980 ret = ventoy_data_save_all();
2981
2982 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2983 return 0;
2984 }
2985
2986
2987 #if 0
2988 #endif
2989
2990
2991 void ventoy_data_default_persistence(data_persistence *data)
2992 {
2993 memset(data, 0, sizeof(data_persistence));
2994 }
2995
2996 int ventoy_data_cmp_persistence(data_persistence *data1, data_persistence *data2)
2997 {
2998 persistence_node *list1 = NULL;
2999 persistence_node *list2 = NULL;
3000
3001 if (NULL == data1->list && NULL == data2->list)
3002 {
3003 return 0;
3004 }
3005 else if (data1->list && data2->list)
3006 {
3007 list1 = data1->list;
3008 list2 = data2->list;
3009
3010 while (list1 && list2)
3011 {
3012 if (list1->timeout != list2->timeout ||
3013 list1->autosel != list2->autosel ||
3014 strcmp(list1->path, list2->path))
3015 {
3016 return 1;
3017 }
3018
3019 /* no need to compare auto install list with default */
3020 list1 = list1->next;
3021 list2 = list2->next;
3022 }
3023
3024 if (list1 == NULL && list2 == NULL)
3025 {
3026 return 0;
3027 }
3028 return 1;
3029 }
3030 else
3031 {
3032 return 1;
3033 }
3034
3035 return 0;
3036 }
3037
3038
3039 int ventoy_data_save_persistence(data_persistence *data, const char *title, char *buf, int buflen)
3040 {
3041 int pos = 0;
3042 persistence_node *node = NULL;
3043 path_node *pathnode = NULL;
3044
3045 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3046
3047 VTOY_JSON_FMT_KEY_L(L1, title);
3048 VTOY_JSON_FMT_ARY_BEGIN_N();
3049
3050 for (node = data->list; node; node = node->next)
3051 {
3052 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
3053 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
3054 VTOY_JSON_FMT_KEY_L(L3, "backend");
3055 VTOY_JSON_FMT_ARY_BEGIN_N();
3056 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
3057 {
3058 VTOY_JSON_FMT_ITEM_PATH_LN(L4, pathnode->path);
3059 }
3060 VTOY_JSON_FMT_ARY_ENDEX_LN(L3);
3061
3062 if (node->timeouten)
3063 {
3064 VTOY_JSON_FMT_SINT_LN(L3, "timeout", node->timeout);
3065 }
3066
3067 if (node->autoselen)
3068 {
3069 VTOY_JSON_FMT_SINT_LN(L3, "autosel", node->autosel);
3070 }
3071
3072 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
3073 }
3074
3075 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
3076 VTOY_JSON_FMT_END(pos);
3077
3078 return pos;
3079 }
3080
3081
3082 int ventoy_data_json_persistence(data_persistence *data, char *buf, int buflen)
3083 {
3084 int pos = 0;
3085 int valid = 0;
3086 persistence_node *node = NULL;
3087 path_node *pathnode = NULL;
3088
3089 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3090 VTOY_JSON_FMT_ARY_BEGIN();
3091
3092 for (node = data->list; node; node = node->next)
3093 {
3094 VTOY_JSON_FMT_OBJ_BEGIN();
3095
3096 VTOY_JSON_FMT_STRN("path", node->path);
3097
3098 valid = ventoy_check_fuzzy_path(node->path, 1);
3099 VTOY_JSON_FMT_SINT("valid", valid);
3100 VTOY_JSON_FMT_SINT("type", node->type);
3101
3102 VTOY_JSON_FMT_BOOL("timeouten", node->timeouten);
3103 VTOY_JSON_FMT_BOOL("autoselen", node->autoselen);
3104
3105 VTOY_JSON_FMT_SINT("autosel", node->autosel);
3106 VTOY_JSON_FMT_SINT("timeout", node->timeout);
3107
3108 VTOY_JSON_FMT_KEY("list");
3109 VTOY_JSON_FMT_ARY_BEGIN();
3110 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
3111 {
3112 VTOY_JSON_FMT_OBJ_BEGIN();
3113 VTOY_JSON_FMT_STRN("path", pathnode->path);
3114
3115 valid = ventoy_is_file_exist("%s%s", g_cur_dir, pathnode->path);
3116 VTOY_JSON_FMT_SINT("valid", valid);
3117 VTOY_JSON_FMT_OBJ_ENDEX();
3118 }
3119 VTOY_JSON_FMT_ARY_ENDEX();
3120
3121
3122 VTOY_JSON_FMT_OBJ_ENDEX();
3123 }
3124
3125 VTOY_JSON_FMT_ARY_END();
3126 VTOY_JSON_FMT_END(pos);
3127
3128 return pos;
3129 }
3130
3131 static int ventoy_api_get_persistence(struct mg_connection *conn, VTOY_JSON *json)
3132 {
3133 api_get_func(conn, json, persistence);
3134 return 0;
3135 }
3136
3137 static int ventoy_api_save_persistence(struct mg_connection *conn, VTOY_JSON *json)
3138 {
3139 int ret;
3140 int id = -1;
3141 int cnt = 0;
3142 int index = 0;
3143 uint8_t timeouten = 0;
3144 uint8_t autoselen = 0;
3145 persistence_node *node = NULL;
3146 data_persistence *data = NULL;
3147
3148 vtoy_json_get_int(json, "index", &index);
3149 vtoy_json_get_int(json, "id", &id);
3150
3151 vtoy_json_get_bool(json, "timeouten", &timeouten);
3152 vtoy_json_get_bool(json, "autoselen", &autoselen);
3153
3154 data = g_data_persistence + index;
3155
3156 if (id >= 0)
3157 {
3158 for (node = data->list; node; node = node->next)
3159 {
3160 if (cnt == id)
3161 {
3162 node->timeouten = (int)timeouten;
3163 node->autoselen = (int)autoselen;
3164 VTOY_JSON_INT("timeout", node->timeout);
3165 VTOY_JSON_INT("autosel", node->autosel);
3166 break;
3167 }
3168 }
3169 }
3170
3171 ret = ventoy_data_save_all();
3172
3173 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3174 return 0;
3175 }
3176
3177
3178 static int ventoy_api_persistence_add(struct mg_connection *conn, VTOY_JSON *json)
3179 {
3180 int ret;
3181 int index = 0;
3182 const char *path = NULL;
3183 persistence_node *node = NULL;
3184 persistence_node *cur = NULL;
3185 data_persistence *data = NULL;
3186 VTOY_JSON *array = NULL;
3187
3188 vtoy_json_get_int(json, "index", &index);
3189 data = g_data_persistence + index;
3190
3191 array = vtoy_json_find_item(json, JSON_TYPE_ARRAY, "backend");
3192 path = VTOY_JSON_STR_EX("path");
3193 if (path && array)
3194 {
3195 node = zalloc(sizeof(persistence_node));
3196 if (node)
3197 {
3198 node->timeouten = 0;
3199 node->autoselen = 0;
3200 node->autosel = 1;
3201 node->timeout = 0;
3202 scnprintf(node->path, sizeof(node->path), "%s", path);
3203 node->list = ventoy_path_node_add_array(array);
3204
3205 vtoy_list_add(data->list, cur, node);
3206 }
3207 }
3208
3209 ret = ventoy_data_save_all();
3210
3211 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3212 return 0;
3213 }
3214
3215 static int ventoy_api_persistence_del(struct mg_connection *conn, VTOY_JSON *json)
3216 {
3217 int ret;
3218 int index = 0;
3219 const char *path = NULL;
3220 persistence_node *last = NULL;
3221 persistence_node *node = NULL;
3222 data_persistence *data = NULL;
3223
3224 vtoy_json_get_int(json, "index", &index);
3225 data = g_data_persistence + index;
3226
3227 path = VTOY_JSON_STR_EX("path");
3228 if (path)
3229 {
3230 vtoy_list_del_ex(last, node, data->list, path, ventoy_free_path_node_list);
3231 }
3232
3233 ret = ventoy_data_save_all();
3234
3235 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3236 return 0;
3237 }
3238
3239 static int ventoy_api_persistence_add_inner(struct mg_connection *conn, VTOY_JSON *json)
3240 {
3241 int ret;
3242 int index = 0;
3243 const char *path = NULL;
3244 const char *outpath = NULL;
3245 path_node *pcur = NULL;
3246 path_node *pnode = NULL;
3247 persistence_node *node = NULL;
3248 data_persistence *data = NULL;
3249
3250 vtoy_json_get_int(json, "index", &index);
3251 data = g_data_persistence + index;
3252
3253 path = VTOY_JSON_STR_EX("path");
3254 outpath = VTOY_JSON_STR_EX("outpath");
3255 if (path && outpath)
3256 {
3257 for (node = data->list; node; node = node->next)
3258 {
3259 if (strcmp(outpath, node->path) == 0)
3260 {
3261 pnode = zalloc(sizeof(path_node));
3262 if (pnode)
3263 {
3264 scnprintf(pnode->path, sizeof(pnode->path), "%s", path);
3265 vtoy_list_add(node->list, pcur, pnode);
3266 }
3267
3268 break;
3269 }
3270 }
3271 }
3272
3273 ret = ventoy_data_save_all();
3274
3275 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3276 return 0;
3277 }
3278
3279 static int ventoy_api_persistence_del_inner(struct mg_connection *conn, VTOY_JSON *json)
3280 {
3281 int ret;
3282 int index = 0;
3283 const char *path = NULL;
3284 const char *outpath = NULL;
3285 path_node *plast = NULL;
3286 path_node *pnode = NULL;
3287 persistence_node *node = NULL;
3288 data_persistence *data = NULL;
3289
3290 vtoy_json_get_int(json, "index", &index);
3291 data = g_data_persistence + index;
3292
3293 path = VTOY_JSON_STR_EX("path");
3294 outpath = VTOY_JSON_STR_EX("outpath");
3295 if (path && outpath)
3296 {
3297 for (node = data->list; node; node = node->next)
3298 {
3299 if (strcmp(outpath, node->path) == 0)
3300 {
3301 vtoy_list_del(plast, pnode, node->list, path);
3302 break;
3303 }
3304 }
3305 }
3306
3307 ret = ventoy_data_save_all();
3308
3309 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3310 return 0;
3311 }
3312
3313
3314 #if 0
3315 #endif
3316
3317 void ventoy_data_default_injection(data_injection *data)
3318 {
3319 memset(data, 0, sizeof(data_injection));
3320 }
3321
3322 int ventoy_data_cmp_injection(data_injection *data1, data_injection *data2)
3323 {
3324 injection_node *list1 = NULL;
3325 injection_node *list2 = NULL;
3326
3327 if (NULL == data1->list && NULL == data2->list)
3328 {
3329 return 0;
3330 }
3331 else if (data1->list && data2->list)
3332 {
3333 list1 = data1->list;
3334 list2 = data2->list;
3335
3336 while (list1 && list2)
3337 {
3338 if ((list1->type != list2->type) ||
3339 strcmp(list1->path, list2->path) ||
3340 strcmp(list1->archive, list2->archive))
3341 {
3342 return 1;
3343 }
3344
3345 list1 = list1->next;
3346 list2 = list2->next;
3347 }
3348
3349 if (list1 == NULL && list2 == NULL)
3350 {
3351 return 0;
3352 }
3353 return 1;
3354 }
3355 else
3356 {
3357 return 1;
3358 }
3359
3360 return 0;
3361 }
3362
3363
3364 int ventoy_data_save_injection(data_injection *data, const char *title, char *buf, int buflen)
3365 {
3366 int pos = 0;
3367 injection_node *node = NULL;
3368
3369 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3370
3371 VTOY_JSON_FMT_KEY_L(L1, title);
3372 VTOY_JSON_FMT_ARY_BEGIN_N();
3373
3374 for (node = data->list; node; node = node->next)
3375 {
3376 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
3377
3378 if (node->type == 0)
3379 {
3380 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
3381 }
3382 else
3383 {
3384 VTOY_JSON_FMT_STRN_PATH_LN(L3, "parent", node->path);
3385 }
3386 VTOY_JSON_FMT_STRN_PATH_LN(L3, "archive", node->archive);
3387
3388 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
3389 }
3390
3391 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
3392 VTOY_JSON_FMT_END(pos);
3393
3394 return pos;
3395 }
3396
3397
3398 int ventoy_data_json_injection(data_injection *data, char *buf, int buflen)
3399 {
3400 int pos = 0;
3401 int valid = 0;
3402 injection_node *node = NULL;
3403
3404 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3405 VTOY_JSON_FMT_ARY_BEGIN();
3406
3407 for (node = data->list; node; node = node->next)
3408 {
3409 VTOY_JSON_FMT_OBJ_BEGIN();
3410
3411 VTOY_JSON_FMT_UINT("type", node->type);
3412 VTOY_JSON_FMT_STRN("path", node->path);
3413
3414 if (node->type == 0)
3415 {
3416 valid = ventoy_check_fuzzy_path(node->path, 1);
3417 }
3418 else
3419 {
3420 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
3421 }
3422 VTOY_JSON_FMT_SINT("valid", valid);
3423
3424 VTOY_JSON_FMT_STRN("archive", node->archive);
3425
3426 valid = ventoy_is_file_exist("%s%s", g_cur_dir, node->archive);
3427 VTOY_JSON_FMT_SINT("archive_valid", valid);
3428
3429 VTOY_JSON_FMT_OBJ_ENDEX();
3430 }
3431
3432 VTOY_JSON_FMT_ARY_END();
3433 VTOY_JSON_FMT_END(pos);
3434
3435 return pos;
3436 }
3437
3438
3439 static int ventoy_api_get_injection(struct mg_connection *conn, VTOY_JSON *json)
3440 {
3441 api_get_func(conn, json, injection);
3442 return 0;
3443 }
3444
3445 static int ventoy_api_save_injection(struct mg_connection *conn, VTOY_JSON *json)
3446 {
3447 int ret;
3448 ret = ventoy_data_save_all();
3449
3450 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3451 return 0;
3452 }
3453
3454 static int ventoy_api_injection_add(struct mg_connection *conn, VTOY_JSON *json)
3455 {
3456 int ret;
3457 int index = 0;
3458 int type = 0;
3459 const char *path = NULL;
3460 const char *archive = NULL;
3461 injection_node *node = NULL;
3462 injection_node *cur = NULL;
3463 data_injection *data = NULL;
3464
3465 vtoy_json_get_int(json, "index", &index);
3466 data = g_data_injection + index;
3467
3468 vtoy_json_get_int(json, "type", &type);
3469
3470 path = VTOY_JSON_STR_EX("path");
3471 archive = VTOY_JSON_STR_EX("archive");
3472 if (path && archive)
3473 {
3474 node = zalloc(sizeof(injection_node));
3475 if (node)
3476 {
3477 node->type = type;
3478
3479 scnprintf(node->path, sizeof(node->path), "%s", path);
3480 scnprintf(node->archive, sizeof(node->archive), "%s", archive);
3481
3482 vtoy_list_add(data->list, cur, node);
3483 }
3484 }
3485
3486 ret = ventoy_data_save_all();
3487
3488 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3489 return 0;
3490 }
3491
3492 static int ventoy_api_injection_del(struct mg_connection *conn, VTOY_JSON *json)
3493 {
3494 int ret;
3495 int index = 0;
3496 const char *path = NULL;
3497 injection_node *last = NULL;
3498 injection_node *node = NULL;
3499 data_injection *data = NULL;
3500
3501 vtoy_json_get_int(json, "index", &index);
3502 data = g_data_injection + index;
3503
3504 path = VTOY_JSON_STR_EX("path");
3505 if (path)
3506 {
3507 vtoy_list_del(last, node, data->list, path);
3508 }
3509
3510 ret = ventoy_data_save_all();
3511
3512 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3513 return 0;
3514 }
3515
3516
3517 #if 0
3518 #endif
3519
3520 int ventoy_data_save_all(void)
3521 {
3522 ventoy_set_writeback_event();
3523 return 0;
3524 }
3525
3526 int ventoy_data_real_save_all(void)
3527 {
3528 int i = 0;
3529 int pos = 0;
3530 char title[64];
3531
3532 pthread_mutex_lock(&g_api_mutex);
3533
3534 ssprintf(pos, JSON_SAVE_BUFFER, JSON_BUF_MAX, "{\n");
3535
3536 ventoy_save_plug(control);
3537 ventoy_save_plug(theme);
3538 ventoy_save_plug(menu_alias);
3539 ventoy_save_plug(menu_tip);
3540 ventoy_save_plug(menu_class);
3541 ventoy_save_plug(auto_install);
3542 ventoy_save_plug(persistence);
3543 ventoy_save_plug(injection);
3544 ventoy_save_plug(conf_replace);
3545 ventoy_save_plug(password);
3546 ventoy_save_plug(image_list);
3547 ventoy_save_plug(auto_memdisk);
3548 ventoy_save_plug(dud);
3549
3550 if (JSON_SAVE_BUFFER[pos - 1] == '\n' && JSON_SAVE_BUFFER[pos - 2] == ',')
3551 {
3552 JSON_SAVE_BUFFER[pos - 2] = '\n';
3553 pos--;
3554 }
3555 ssprintf(pos, JSON_SAVE_BUFFER, JSON_BUF_MAX, "}\n");
3556
3557 pthread_mutex_unlock(&g_api_mutex);
3558
3559 return pos;
3560 }
3561
3562 int ventoy_http_writeback(void)
3563 {
3564 int ret;
3565 int pos;
3566 char filename[128];
3567
3568 ventoy_get_json_path(filename, NULL);
3569
3570 pos = ventoy_data_real_save_all();
3571
3572 #ifdef VENTOY_SIM
3573 printf("%s", JSON_SAVE_BUFFER);
3574 #endif
3575
3576 ret = ventoy_write_buf_to_file(filename, JSON_SAVE_BUFFER, pos);
3577 if (ret)
3578 {
3579 vlog("Failed to write ventoy.json file.\n");
3580 }
3581
3582 return 0;
3583 }
3584
3585
3586 static JSON_CB g_ventoy_json_cb[] =
3587 {
3588 { "sysinfo", ventoy_api_sysinfo },
3589 { "handshake", ventoy_api_handshake },
3590 { "check_path", ventoy_api_check_exist },
3591 { "check_path2", ventoy_api_check_exist2 },
3592 { "check_fuzzy", ventoy_api_check_fuzzy },
3593
3594 { "device_info", ventoy_api_device_info },
3595
3596 { "get_control", ventoy_api_get_control },
3597 { "save_control", ventoy_api_save_control },
3598
3599 { "get_theme", ventoy_api_get_theme },
3600 { "save_theme", ventoy_api_save_theme },
3601 { "theme_add_file", ventoy_api_theme_add_file },
3602 { "theme_del_file", ventoy_api_theme_del_file },
3603 { "theme_add_font", ventoy_api_theme_add_font },
3604 { "theme_del_font", ventoy_api_theme_del_font },
3605
3606 { "get_alias", ventoy_api_get_alias },
3607 { "save_alias", ventoy_api_save_alias },
3608 { "alias_add", ventoy_api_alias_add },
3609 { "alias_del", ventoy_api_alias_del },
3610
3611 { "get_tip", ventoy_api_get_tip },
3612 { "save_tip", ventoy_api_save_tip },
3613 { "tip_add", ventoy_api_tip_add },
3614 { "tip_del", ventoy_api_tip_del },
3615
3616 { "get_class", ventoy_api_get_class },
3617 { "save_class", ventoy_api_save_class },
3618 { "class_add", ventoy_api_class_add },
3619 { "class_del", ventoy_api_class_del },
3620
3621 { "get_auto_memdisk", ventoy_api_get_auto_memdisk },
3622 { "save_auto_memdisk", ventoy_api_save_auto_memdisk },
3623 { "auto_memdisk_add", ventoy_api_auto_memdisk_add },
3624 { "auto_memdisk_del", ventoy_api_auto_memdisk_del },
3625
3626 { "get_image_list", ventoy_api_get_image_list },
3627 { "save_image_list", ventoy_api_save_image_list },
3628 { "image_list_add", ventoy_api_image_list_add },
3629 { "image_list_del", ventoy_api_image_list_del },
3630
3631 { "get_conf_replace", ventoy_api_get_conf_replace },
3632 { "save_conf_replace", ventoy_api_save_conf_replace },
3633 { "conf_replace_add", ventoy_api_conf_replace_add },
3634 { "conf_replace_del", ventoy_api_conf_replace_del },
3635
3636 { "get_dud", ventoy_api_get_dud },
3637 { "save_dud", ventoy_api_save_dud },
3638 { "dud_add", ventoy_api_dud_add },
3639 { "dud_del", ventoy_api_dud_del },
3640 { "dud_add_inner", ventoy_api_dud_add_inner },
3641 { "dud_del_inner", ventoy_api_dud_del_inner },
3642
3643 { "get_auto_install", ventoy_api_get_auto_install },
3644 { "save_auto_install", ventoy_api_save_auto_install },
3645 { "auto_install_add", ventoy_api_auto_install_add },
3646 { "auto_install_del", ventoy_api_auto_install_del },
3647 { "auto_install_add_inner", ventoy_api_auto_install_add_inner },
3648 { "auto_install_del_inner", ventoy_api_auto_install_del_inner },
3649
3650 { "get_persistence", ventoy_api_get_persistence },
3651 { "save_persistence", ventoy_api_save_persistence },
3652 { "persistence_add", ventoy_api_persistence_add },
3653 { "persistence_del", ventoy_api_persistence_del },
3654 { "persistence_add_inner", ventoy_api_persistence_add_inner },
3655 { "persistence_del_inner", ventoy_api_persistence_del_inner },
3656
3657 { "get_password", ventoy_api_get_password },
3658 { "save_password", ventoy_api_save_password },
3659 { "password_add", ventoy_api_password_add },
3660 { "password_del", ventoy_api_password_del },
3661
3662 { "get_injection", ventoy_api_get_injection },
3663 { "save_injection", ventoy_api_save_injection },
3664 { "injection_add", ventoy_api_injection_add },
3665 { "injection_del", ventoy_api_injection_del },
3666
3667
3668 };
3669
3670 static int ventoy_json_handler(struct mg_connection *conn, VTOY_JSON *json)
3671 {
3672 int i;
3673 const char *method = NULL;
3674
3675 method = vtoy_json_get_string_ex(json, "method");
3676 if (!method)
3677 {
3678 ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET);
3679 return 0;
3680 }
3681
3682 if (strcmp(method, "handshake") == 0)
3683 {
3684 ventoy_api_handshake(conn, json);
3685 return 0;
3686 }
3687
3688 for (i = 0; i < (int)(sizeof(g_ventoy_json_cb) / sizeof(g_ventoy_json_cb[0])); i++)
3689 {
3690 if (strcmp(method, g_ventoy_json_cb[i].method) == 0)
3691 {
3692 g_ventoy_json_cb[i].callback(conn, json);
3693 break;
3694 }
3695 }
3696
3697 return 0;
3698 }
3699
3700 static int ventoy_request_handler(struct mg_connection *conn)
3701 {
3702 int post_data_len;
3703 int post_buf_len;
3704 VTOY_JSON *json = NULL;
3705 char *post_data_buf = NULL;
3706 const struct mg_request_info *ri = NULL;
3707 char stack_buf[512];
3708
3709 ri = mg_get_request_info(conn);
3710
3711 if (strcmp(ri->uri, "/vtoy/json") == 0)
3712 {
3713 if (ri->content_length > 500)
3714 {
3715 post_data_buf = malloc((int)(ri->content_length + 4));
3716 post_buf_len = (int)(ri->content_length + 1);
3717 }
3718 else
3719 {
3720 post_data_buf = stack_buf;
3721 post_buf_len = sizeof(stack_buf);
3722 }
3723
3724 post_data_len = mg_read(conn, post_data_buf, post_buf_len);
3725 post_data_buf[post_data_len] = 0;
3726
3727 json = vtoy_json_create();
3728 if (JSON_SUCCESS == vtoy_json_parse(json, post_data_buf))
3729 {
3730 pthread_mutex_lock(&g_api_mutex);
3731 ventoy_json_handler(conn, json->pstChild);
3732 pthread_mutex_unlock(&g_api_mutex);
3733 }
3734 else
3735 {
3736 ventoy_json_result(conn, VTOY_JSON_INVALID_RET);
3737 }
3738
3739 vtoy_json_destroy(json);
3740
3741 if (post_data_buf != stack_buf)
3742 {
3743 free(post_data_buf);
3744 }
3745 return 1;
3746 }
3747 else
3748 {
3749 return 0;
3750 }
3751 }
3752
3753 const char *ventoy_web_openfile(const struct mg_connection *conn, const char *path, size_t *data_len)
3754 {
3755 ventoy_file *node = NULL;
3756
3757 (void)conn;
3758
3759 if (!path)
3760 {
3761 return NULL;
3762 }
3763
3764 node = ventoy_tar_find_file(path);
3765 if (node)
3766 {
3767 *data_len = node->size;
3768 return node->addr;
3769 }
3770 else
3771 {
3772 return NULL;
3773 }
3774 }
3775
3776 #if 0
3777 #endif
3778
3779 static int ventoy_parse_control(VTOY_JSON *json, void *p)
3780 {
3781 int i;
3782 VTOY_JSON *node = NULL;
3783 VTOY_JSON *child = NULL;
3784 data_control *data = (data_control *)p;
3785
3786 if (json->enDataType != JSON_TYPE_ARRAY)
3787 {
3788 return 0;
3789 }
3790
3791 for (node = json->pstChild; node; node = node->pstNext)
3792 {
3793 if (node->enDataType == JSON_TYPE_OBJECT)
3794 {
3795 child = node->pstChild;
3796
3797 if (strcmp(child->pcName, "VTOY_DEFAULT_MENU_MODE") == 0)
3798 {
3799 CONTROL_PARSE_INT(child, data->default_menu_mode);
3800 }
3801 else if (strcmp(child->pcName, "VTOY_WIN11_BYPASS_CHECK") == 0)
3802 {
3803 CONTROL_PARSE_INT(child, data->win11_bypass_check);
3804 }
3805 else if (strcmp(child->pcName, "VTOY_LINUX_REMOUNT") == 0)
3806 {
3807 CONTROL_PARSE_INT(child, data->linux_remount);
3808 }
3809 else if (strcmp(child->pcName, "VTOY_TREE_VIEW_MENU_STYLE") == 0)
3810 {
3811 CONTROL_PARSE_INT(child, data->treeview_style);
3812 }
3813 else if (strcmp(child->pcName, "VTOY_FILT_DOT_UNDERSCORE_FILE") == 0)
3814 {
3815 CONTROL_PARSE_INT(child, data->filter_dot_underscore);
3816 }
3817 else if (strcmp(child->pcName, "VTOY_SORT_CASE_SENSITIVE") == 0)
3818 {
3819 CONTROL_PARSE_INT(child, data->sort_casesensitive);
3820 }
3821 else if (strcmp(child->pcName, "VTOY_MAX_SEARCH_LEVEL") == 0)
3822 {
3823 if (strcmp(child->unData.pcStrVal, "max") == 0)
3824 {
3825 data->max_search_level = -1;
3826 }
3827 else
3828 {
3829 data->max_search_level = (int)strtol(child->unData.pcStrVal, NULL, 10);
3830 }
3831 }
3832 else if (strcmp(child->pcName, "VTOY_DEFAULT_SEARCH_ROOT") == 0)
3833 {
3834 strlcpy(data->default_search_root, child->unData.pcStrVal);
3835 }
3836 else if (strcmp(child->pcName, "VTOY_DEFAULT_IMAGE") == 0)
3837 {
3838 strlcpy(data->default_image, child->unData.pcStrVal);
3839 }
3840 else if (strcmp(child->pcName, "VTOY_DEFAULT_KBD_LAYOUT") == 0)
3841 {
3842 for (i = 0; g_ventoy_kbd_layout[i]; i++)
3843 {
3844 if (strcmp(child->unData.pcStrVal, g_ventoy_kbd_layout[i]) == 0)
3845 {
3846 strlcpy(data->default_kbd_layout, child->unData.pcStrVal);
3847 break;
3848 }
3849 }
3850 }
3851 else if (strcmp(child->pcName, "VTOY_HELP_TXT_LANGUAGE") == 0)
3852 {
3853 for (i = 0; g_ventoy_help_lang[i][0]; i++)
3854 {
3855 if (strcmp(child->unData.pcStrVal, g_ventoy_help_lang[i]) == 0)
3856 {
3857 strlcpy(data->help_text_language, child->unData.pcStrVal);
3858 break;
3859 }
3860 }
3861 }
3862 else if (strcmp(child->pcName, "VTOY_MENU_TIMEOUT") == 0)
3863 {
3864 data->menu_timeout = (int)strtol(child->unData.pcStrVal, NULL, 10);
3865 }
3866 else if (strcmp(child->pcName, "VTOY_VHD_NO_WARNING") == 0)
3867 {
3868 CONTROL_PARSE_INT(child, data->vhd_no_warning);
3869 }
3870 else if (strcmp(child->pcName, "VTOY_FILE_FLT_ISO") == 0)
3871 {
3872 CONTROL_PARSE_INT(child, data->filter_iso);
3873 }
3874 else if (strcmp(child->pcName, "VTOY_FILE_FLT_IMG") == 0)
3875 {
3876 CONTROL_PARSE_INT(child, data->filter_img);
3877 }
3878 else if (strcmp(child->pcName, "VTOY_FILE_FLT_EFI") == 0)
3879 {
3880 CONTROL_PARSE_INT(child, data->filter_efi);
3881 }
3882 else if (strcmp(child->pcName, "VTOY_FILE_FLT_WIM") == 0)
3883 {
3884 CONTROL_PARSE_INT(child, data->filter_wim);
3885 }
3886 else if (strcmp(child->pcName, "VTOY_FILE_FLT_VHD") == 0)
3887 {
3888 CONTROL_PARSE_INT(child, data->filter_vhd);
3889 }
3890 else if (strcmp(child->pcName, "VTOY_FILE_FLT_VTOY") == 0)
3891 {
3892 CONTROL_PARSE_INT(child, data->filter_vtoy);
3893 }
3894
3895 }
3896 }
3897
3898 return 0;
3899 }
3900 static int ventoy_parse_theme(VTOY_JSON *json, void *p)
3901 {
3902 const char *dismode = NULL;
3903 VTOY_JSON *child = NULL;
3904 VTOY_JSON *node = NULL;
3905 path_node *tail = NULL;
3906 path_node *pnode = NULL;
3907 data_theme *data = (data_theme *)p;
3908
3909 if (json->enDataType != JSON_TYPE_OBJECT)
3910 {
3911 return 0;
3912 }
3913
3914 child = json->pstChild;
3915
3916 dismode = vtoy_json_get_string_ex(child, "display_mode");
3917 vtoy_json_get_string(child, "ventoy_left", sizeof(data->ventoy_left), data->ventoy_left);
3918 vtoy_json_get_string(child, "ventoy_top", sizeof(data->ventoy_top), data->ventoy_top);
3919 vtoy_json_get_string(child, "ventoy_color", sizeof(data->ventoy_color), data->ventoy_color);
3920
3921 vtoy_json_get_int(child, "default_file", &(data->default_file));
3922 vtoy_json_get_string(child, "gfxmode", sizeof(data->gfxmode), data->gfxmode);
3923 vtoy_json_get_string(child, "serial_param", sizeof(data->serial_param), data->serial_param);
3924
3925 if (dismode)
3926 {
3927 if (strcmp(dismode, "CLI") == 0)
3928 {
3929 data->display_mode = display_mode_cli;
3930 }
3931 else if (strcmp(dismode, "serial") == 0)
3932 {
3933 data->display_mode = display_mode_serial;
3934 }
3935 else if (strcmp(dismode, "serial_console") == 0)
3936 {
3937 data->display_mode = display_mode_ser_console;
3938 }
3939 else
3940 {
3941 data->display_mode = display_mode_gui;
3942 }
3943 }
3944
3945 node = vtoy_json_find_item(child, JSON_TYPE_STRING, "file");
3946 if (node)
3947 {
3948 data->default_file = 0;
3949
3950 pnode = zalloc(sizeof(path_node));
3951 if (pnode)
3952 {
3953 strlcpy(pnode->path, node->unData.pcStrVal);
3954 data->filelist = pnode;
3955 }
3956 }
3957 else
3958 {
3959 node = vtoy_json_find_item(child, JSON_TYPE_ARRAY, "file");
3960 if (node)
3961 {
3962 for (node = node->pstChild; node; node = node->pstNext)
3963 {
3964 if (node->enDataType == JSON_TYPE_STRING)
3965 {
3966 pnode = zalloc(sizeof(path_node));
3967 if (pnode)
3968 {
3969 strlcpy(pnode->path, node->unData.pcStrVal);
3970 if (data->filelist)
3971 {
3972 tail->next = pnode;
3973 tail = pnode;
3974 }
3975 else
3976 {
3977 data->filelist = tail = pnode;
3978 }
3979 }
3980 }
3981 }
3982 }
3983 }
3984
3985
3986 node = vtoy_json_find_item(child, JSON_TYPE_ARRAY, "fonts");
3987 if (node)
3988 {
3989 for (node = node->pstChild; node; node = node->pstNext)
3990 {
3991 if (node->enDataType == JSON_TYPE_STRING)
3992 {
3993 pnode = zalloc(sizeof(path_node));
3994 if (pnode)
3995 {
3996 strlcpy(pnode->path, node->unData.pcStrVal);
3997 if (data->fontslist)
3998 {
3999 tail->next = pnode;
4000 tail = pnode;
4001 }
4002 else
4003 {
4004 data->fontslist = tail = pnode;
4005 }
4006 }
4007 }
4008 }
4009 }
4010
4011 return 0;
4012 }
4013 static int ventoy_parse_menu_alias(VTOY_JSON *json, void *p)
4014 {
4015 int type;
4016 const char *path = NULL;
4017 const char *alias = NULL;
4018 data_alias *data = (data_alias *)p;
4019 data_alias_node *tail = NULL;
4020 data_alias_node *pnode = NULL;
4021 VTOY_JSON *node = NULL;
4022
4023 if (json->enDataType != JSON_TYPE_ARRAY)
4024 {
4025 return 0;
4026 }
4027
4028 for (node = json->pstChild; node; node = node->pstNext)
4029 {
4030 if (node->enDataType != JSON_TYPE_OBJECT)
4031 {
4032 continue;
4033 }
4034
4035 type = path_type_file;
4036 path = vtoy_json_get_string_ex(node->pstChild, "image");
4037 if (!path)
4038 {
4039 path = vtoy_json_get_string_ex(node->pstChild, "dir");
4040 type = path_type_dir;
4041 }
4042 alias = vtoy_json_get_string_ex(node->pstChild, "alias");
4043
4044 if (path && alias)
4045 {
4046 pnode = zalloc(sizeof(data_alias_node));
4047 if (pnode)
4048 {
4049 pnode->type = type;
4050 strlcpy(pnode->path, path);
4051 strlcpy(pnode->alias, alias);
4052
4053 if (data->list)
4054 {
4055 tail->next = pnode;
4056 tail = pnode;
4057 }
4058 else
4059 {
4060 data->list = tail = pnode;
4061 }
4062 }
4063 }
4064 }
4065
4066 return 0;
4067 }
4068
4069 static int ventoy_parse_menu_tip(VTOY_JSON *json, void *p)
4070 {
4071 int type;
4072 const char *path = NULL;
4073 const char *tip = NULL;
4074 data_tip *data = (data_tip *)p;
4075 data_tip_node *tail = NULL;
4076 data_tip_node *pnode = NULL;
4077 VTOY_JSON *node = NULL;
4078 VTOY_JSON *tips = NULL;
4079
4080 if (json->enDataType != JSON_TYPE_OBJECT)
4081 {
4082 return 0;
4083 }
4084
4085 vtoy_json_get_string(json->pstChild, "left", sizeof(data->left), data->left);
4086 vtoy_json_get_string(json->pstChild, "top", sizeof(data->top), data->top);
4087 vtoy_json_get_string(json->pstChild, "color", sizeof(data->color), data->color);
4088
4089 tips = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "tips");
4090 if (!tips)
4091 {
4092 return 0;
4093 }
4094
4095 for (node = tips->pstChild; node; node = node->pstNext)
4096 {
4097 if (node->enDataType != JSON_TYPE_OBJECT)
4098 {
4099 continue;
4100 }
4101
4102 type = path_type_file;
4103 path = vtoy_json_get_string_ex(node->pstChild, "image");
4104 if (!path)
4105 {
4106 path = vtoy_json_get_string_ex(node->pstChild, "dir");
4107 type = path_type_dir;
4108 }
4109 tip = vtoy_json_get_string_ex(node->pstChild, "tip");
4110
4111 if (path && tip)
4112 {
4113 pnode = zalloc(sizeof(data_tip_node));
4114 if (pnode)
4115 {
4116 pnode->type = type;
4117 strlcpy(pnode->path, path);
4118 strlcpy(pnode->tip, tip);
4119
4120 if (data->list)
4121 {
4122 tail->next = pnode;
4123 tail = pnode;
4124 }
4125 else
4126 {
4127 data->list = tail = pnode;
4128 }
4129 }
4130 }
4131 }
4132
4133 return 0;
4134 }
4135 static int ventoy_parse_menu_class(VTOY_JSON *json, void *p)
4136 {
4137 int type;
4138 const char *path = NULL;
4139 const char *class = NULL;
4140 data_class *data = (data_class *)p;
4141 data_class_node *tail = NULL;
4142 data_class_node *pnode = NULL;
4143 VTOY_JSON *node = NULL;
4144
4145 if (json->enDataType != JSON_TYPE_ARRAY)
4146 {
4147 return 0;
4148 }
4149
4150 for (node = json->pstChild; node; node = node->pstNext)
4151 {
4152 if (node->enDataType != JSON_TYPE_OBJECT)
4153 {
4154 continue;
4155 }
4156
4157 type = class_type_key;
4158 path = vtoy_json_get_string_ex(node->pstChild, "key");
4159 if (!path)
4160 {
4161 type = class_type_dir;
4162 path = vtoy_json_get_string_ex(node->pstChild, "dir");
4163 if (!path)
4164 {
4165 type = class_type_parent;
4166 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4167 }
4168 }
4169 class = vtoy_json_get_string_ex(node->pstChild, "class");
4170
4171 if (path && class)
4172 {
4173 pnode = zalloc(sizeof(data_class_node));
4174 if (pnode)
4175 {
4176 pnode->type = type;
4177 strlcpy(pnode->path, path);
4178 strlcpy(pnode->class, class);
4179
4180 if (data->list)
4181 {
4182 tail->next = pnode;
4183 tail = pnode;
4184 }
4185 else
4186 {
4187 data->list = tail = pnode;
4188 }
4189 }
4190 }
4191 }
4192
4193 return 0;
4194 }
4195 static int ventoy_parse_auto_install(VTOY_JSON *json, void *p)
4196 {
4197 int type;
4198 int count;
4199 int timeout;
4200 int timeouten;
4201 int autosel;
4202 int autoselen;
4203 const char *path = NULL;
4204 const char *file = NULL;
4205 data_auto_install *data = (data_auto_install *)p;
4206 auto_install_node *tail = NULL;
4207 auto_install_node *pnode = NULL;
4208 path_node *pathnode = NULL;
4209 path_node *pathtail = NULL;
4210 VTOY_JSON *node = NULL;
4211 VTOY_JSON *filelist = NULL;
4212 VTOY_JSON *filenode = NULL;
4213
4214 if (json->enDataType != JSON_TYPE_ARRAY)
4215 {
4216 return 0;
4217 }
4218
4219 for (node = json->pstChild; node; node = node->pstNext)
4220 {
4221 if (node->enDataType != JSON_TYPE_OBJECT)
4222 {
4223 continue;
4224 }
4225
4226 type = 0;
4227 path = vtoy_json_get_string_ex(node->pstChild, "image");
4228 if (!path)
4229 {
4230 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4231 type = 1;
4232 }
4233 if (!path)
4234 {
4235 continue;
4236 }
4237
4238 file = vtoy_json_get_string_ex(node->pstChild, "template");
4239 if (file)
4240 {
4241 pnode = zalloc(sizeof(auto_install_node));
4242 if (pnode)
4243 {
4244 pnode->type = type;
4245 pnode->autosel = 1;
4246 strlcpy(pnode->path, path);
4247
4248 pathnode = zalloc(sizeof(path_node));
4249 if (pathnode)
4250 {
4251 strlcpy(pathnode->path, file);
4252 pnode->list = pathnode;
4253 }
4254 else
4255 {
4256 free(pnode);
4257 }
4258
4259 if (data->list)
4260 {
4261 tail->next = pnode;
4262 tail = pnode;
4263 }
4264 else
4265 {
4266 data->list = tail = pnode;
4267 }
4268 }
4269
4270 continue;
4271 }
4272
4273
4274 timeouten = autoselen = 0;
4275 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "timeout", &timeout))
4276 {
4277 timeouten = 1;
4278 }
4279 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "autosel", &autosel))
4280 {
4281 autoselen = 1;
4282 }
4283
4284 filelist = vtoy_json_find_item(node->pstChild, JSON_TYPE_ARRAY, "template");
4285 if (!filelist)
4286 {
4287 continue;
4288 }
4289
4290 pnode = zalloc(sizeof(auto_install_node));
4291 if (!pnode)
4292 {
4293 continue;
4294 }
4295
4296 pnode->type = type;
4297 pnode->autoselen = autoselen;
4298 pnode->timeouten = timeouten;
4299 pnode->timeout = timeout;
4300 pnode->autosel = autosel;
4301 strlcpy(pnode->path, path);
4302
4303 count = 0;
4304 for (filenode = filelist->pstChild; filenode; filenode = filenode->pstNext)
4305 {
4306 if (filenode->enDataType != JSON_TYPE_STRING)
4307 {
4308 continue;
4309 }
4310
4311 pathnode = zalloc(sizeof(path_node));
4312 if (pathnode)
4313 {
4314 count++;
4315 strlcpy(pathnode->path, filenode->unData.pcStrVal);
4316
4317 if (pnode->list)
4318 {
4319 pathtail->next = pathnode;
4320 pathtail = pathnode;
4321 }
4322 else
4323 {
4324 pnode->list = pathtail = pathnode;
4325 }
4326 }
4327 }
4328
4329 if (count == 0)
4330 {
4331 free(pnode);
4332 }
4333 else
4334 {
4335 if (pnode->autoselen && pnode->autosel > count)
4336 {
4337 pnode->autosel = 1;
4338 }
4339
4340 if (data->list)
4341 {
4342 tail->next = pnode;
4343 tail = pnode;
4344 }
4345 else
4346 {
4347 data->list = tail = pnode;
4348 }
4349 }
4350 }
4351
4352 return 0;
4353 }
4354 static int ventoy_parse_persistence(VTOY_JSON *json, void *p)
4355 {
4356 int count;
4357 int timeout;
4358 int timeouten;
4359 int autosel;
4360 int autoselen;
4361 const char *path = NULL;
4362 const char *file = NULL;
4363 data_persistence *data = (data_persistence *)p;
4364 persistence_node *tail = NULL;
4365 persistence_node *pnode = NULL;
4366 path_node *pathnode = NULL;
4367 path_node *pathtail = NULL;
4368 VTOY_JSON *node = NULL;
4369 VTOY_JSON *filelist = NULL;
4370 VTOY_JSON *filenode = NULL;
4371
4372 if (json->enDataType != JSON_TYPE_ARRAY)
4373 {
4374 return 0;
4375 }
4376
4377 for (node = json->pstChild; node; node = node->pstNext)
4378 {
4379 if (node->enDataType != JSON_TYPE_OBJECT)
4380 {
4381 continue;
4382 }
4383
4384 path = vtoy_json_get_string_ex(node->pstChild, "image");
4385 if (!path)
4386 {
4387 continue;
4388 }
4389
4390 file = vtoy_json_get_string_ex(node->pstChild, "backend");
4391 if (file)
4392 {
4393 pnode = zalloc(sizeof(persistence_node));
4394 if (pnode)
4395 {
4396 pnode->type = 0;
4397 pnode->autosel = 1;
4398 strlcpy(pnode->path, path);
4399
4400 pathnode = zalloc(sizeof(path_node));
4401 if (pathnode)
4402 {
4403 strlcpy(pathnode->path, file);
4404 pnode->list = pathnode;
4405 }
4406 else
4407 {
4408 free(pnode);
4409 }
4410
4411 if (data->list)
4412 {
4413 tail->next = pnode;
4414 tail = pnode;
4415 }
4416 else
4417 {
4418 data->list = tail = pnode;
4419 }
4420 }
4421
4422 continue;
4423 }
4424
4425
4426 timeouten = autoselen = 0;
4427 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "timeout", &timeout))
4428 {
4429 timeouten = 1;
4430 }
4431 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "autosel", &autosel))
4432 {
4433 autoselen = 1;
4434 }
4435
4436 filelist = vtoy_json_find_item(node->pstChild, JSON_TYPE_ARRAY, "backend");
4437 if (!filelist)
4438 {
4439 continue;
4440 }
4441
4442 pnode = zalloc(sizeof(persistence_node));
4443 if (!pnode)
4444 {
4445 continue;
4446 }
4447
4448 pnode->type = 0;
4449 pnode->autoselen = autoselen;
4450 pnode->timeouten = timeouten;
4451 pnode->timeout = timeout;
4452 pnode->autosel = autosel;
4453 strlcpy(pnode->path, path);
4454
4455 count = 0;
4456 for (filenode = filelist->pstChild; filenode; filenode = filenode->pstNext)
4457 {
4458 if (filenode->enDataType != JSON_TYPE_STRING)
4459 {
4460 continue;
4461 }
4462
4463 pathnode = zalloc(sizeof(path_node));
4464 if (pathnode)
4465 {
4466 count++;
4467 strlcpy(pathnode->path, filenode->unData.pcStrVal);
4468
4469 if (pnode->list)
4470 {
4471 pathtail->next = pathnode;
4472 pathtail = pathnode;
4473 }
4474 else
4475 {
4476 pnode->list = pathtail = pathnode;
4477 }
4478 }
4479 }
4480
4481 if (count == 0)
4482 {
4483 free(pnode);
4484 }
4485 else
4486 {
4487 if (pnode->autoselen && pnode->autosel > count)
4488 {
4489 pnode->autosel = 1;
4490 }
4491
4492 if (data->list)
4493 {
4494 tail->next = pnode;
4495 tail = pnode;
4496 }
4497 else
4498 {
4499 data->list = tail = pnode;
4500 }
4501 }
4502 }
4503
4504 return 0;
4505 }
4506 static int ventoy_parse_injection(VTOY_JSON *json, void *p)
4507 {
4508 int type;
4509 const char *path = NULL;
4510 const char *archive = NULL;
4511 data_injection *data = (data_injection *)p;
4512 injection_node *tail = NULL;
4513 injection_node *pnode = NULL;
4514 VTOY_JSON *node = NULL;
4515
4516 if (json->enDataType != JSON_TYPE_ARRAY)
4517 {
4518 return 0;
4519 }
4520
4521 for (node = json->pstChild; node; node = node->pstNext)
4522 {
4523 if (node->enDataType != JSON_TYPE_OBJECT)
4524 {
4525 continue;
4526 }
4527
4528 type = 0;
4529 path = vtoy_json_get_string_ex(node->pstChild, "image");
4530 if (!path)
4531 {
4532 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4533 type = 1;
4534 }
4535 archive = vtoy_json_get_string_ex(node->pstChild, "archive");
4536
4537 if (path && archive)
4538 {
4539 pnode = zalloc(sizeof(injection_node));
4540 if (pnode)
4541 {
4542 pnode->type = type;
4543 strlcpy(pnode->path, path);
4544 strlcpy(pnode->archive, archive);
4545
4546 if (data->list)
4547 {
4548 tail->next = pnode;
4549 tail = pnode;
4550 }
4551 else
4552 {
4553 data->list = tail = pnode;
4554 }
4555 }
4556 }
4557 }
4558
4559 return 0;
4560 }
4561 static int ventoy_parse_conf_replace(VTOY_JSON *json, void *p)
4562 {
4563 int img = 0;
4564 const char *path = NULL;
4565 const char *org = NULL;
4566 const char *new = NULL;
4567 data_conf_replace *data = (data_conf_replace *)p;
4568 conf_replace_node *tail = NULL;
4569 conf_replace_node *pnode = NULL;
4570 VTOY_JSON *node = NULL;
4571
4572 if (json->enDataType != JSON_TYPE_ARRAY)
4573 {
4574 return 0;
4575 }
4576
4577 for (node = json->pstChild; node; node = node->pstNext)
4578 {
4579 if (node->enDataType != JSON_TYPE_OBJECT)
4580 {
4581 continue;
4582 }
4583
4584 path = vtoy_json_get_string_ex(node->pstChild, "iso");
4585 org = vtoy_json_get_string_ex(node->pstChild, "org");
4586 new = vtoy_json_get_string_ex(node->pstChild, "new");
4587
4588 img = 0;
4589 vtoy_json_get_int(node->pstChild, "img", &img);
4590
4591 if (path && org && new)
4592 {
4593 pnode = zalloc(sizeof(conf_replace_node));
4594 if (pnode)
4595 {
4596 strlcpy(pnode->path, path);
4597 strlcpy(pnode->org, org);
4598 strlcpy(pnode->new, new);
4599 if (img == 1)
4600 {
4601 pnode->image = img;
4602 }
4603
4604 if (data->list)
4605 {
4606 tail->next = pnode;
4607 tail = pnode;
4608 }
4609 else
4610 {
4611 data->list = tail = pnode;
4612 }
4613 }
4614 }
4615 }
4616
4617 return 0;
4618 }
4619 static int ventoy_parse_password(VTOY_JSON *json, void *p)
4620 {
4621 int type;
4622 const char *bootpwd = NULL;
4623 const char *isopwd= NULL;
4624 const char *wimpwd= NULL;
4625 const char *imgpwd= NULL;
4626 const char *efipwd= NULL;
4627 const char *vhdpwd= NULL;
4628 const char *vtoypwd= NULL;
4629 const char *path = NULL;
4630 const char *pwd = NULL;
4631 data_password *data = (data_password *)p;
4632 menu_password *tail = NULL;
4633 menu_password *pnode = NULL;
4634 VTOY_JSON *node = NULL;
4635 VTOY_JSON *menupwd = NULL;
4636
4637 if (json->enDataType != JSON_TYPE_OBJECT)
4638 {
4639 return 0;
4640 }
4641
4642 bootpwd = vtoy_json_get_string_ex(json->pstChild, "bootpwd");
4643 isopwd = vtoy_json_get_string_ex(json->pstChild, "isopwd");
4644 wimpwd = vtoy_json_get_string_ex(json->pstChild, "wimpwd");
4645 imgpwd = vtoy_json_get_string_ex(json->pstChild, "imgpwd");
4646 efipwd = vtoy_json_get_string_ex(json->pstChild, "efipwd");
4647 vhdpwd = vtoy_json_get_string_ex(json->pstChild, "vhdpwd");
4648 vtoypwd = vtoy_json_get_string_ex(json->pstChild, "vtoypwd");
4649
4650
4651 if (bootpwd) strlcpy(data->bootpwd, bootpwd);
4652 if (isopwd) strlcpy(data->isopwd, isopwd);
4653 if (wimpwd) strlcpy(data->wimpwd, wimpwd);
4654 if (imgpwd) strlcpy(data->imgpwd, imgpwd);
4655 if (efipwd) strlcpy(data->efipwd, efipwd);
4656 if (vhdpwd) strlcpy(data->vhdpwd, vhdpwd);
4657 if (vtoypwd) strlcpy(data->vtoypwd, vtoypwd);
4658
4659
4660 menupwd = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "menupwd");
4661 if (!menupwd)
4662 {
4663 return 0;
4664 }
4665
4666 for (node = menupwd->pstChild; node; node = node->pstNext)
4667 {
4668 if (node->enDataType != JSON_TYPE_OBJECT)
4669 {
4670 continue;
4671 }
4672
4673 type = 0;
4674 path = vtoy_json_get_string_ex(node->pstChild, "file");
4675 if (!path)
4676 {
4677 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4678 type = 1;
4679 }
4680 pwd = vtoy_json_get_string_ex(node->pstChild, "pwd");
4681
4682 if (path && pwd)
4683 {
4684 pnode = zalloc(sizeof(menu_password));
4685 if (pnode)
4686 {
4687 pnode->type = type;
4688 strlcpy(pnode->path, path);
4689 strlcpy(pnode->pwd, pwd);
4690
4691 if (data->list)
4692 {
4693 tail->next = pnode;
4694 tail = pnode;
4695 }
4696 else
4697 {
4698 data->list = tail = pnode;
4699 }
4700 }
4701 }
4702 }
4703
4704 return 0;
4705 }
4706
4707 static int ventoy_parse_image_list_real(VTOY_JSON *json, int type, void *p)
4708 {
4709 VTOY_JSON *node = NULL;
4710 data_image_list *data = (data_image_list *)p;
4711 path_node *tail = NULL;
4712 path_node *pnode = NULL;
4713
4714 if (json->enDataType != JSON_TYPE_ARRAY)
4715 {
4716 return 0;
4717 }
4718
4719 data->type = type;
4720
4721 for (node = json->pstChild; node; node = node->pstNext)
4722 {
4723 if (node->enDataType == JSON_TYPE_STRING)
4724 {
4725 pnode = zalloc(sizeof(path_node));
4726 if (pnode)
4727 {
4728 strlcpy(pnode->path, node->unData.pcStrVal);
4729 if (data->list)
4730 {
4731 tail->next = pnode;
4732 tail = pnode;
4733 }
4734 else
4735 {
4736 data->list = tail = pnode;
4737 }
4738 }
4739 }
4740 }
4741
4742 return 0;
4743 }
4744 static int ventoy_parse_image_blacklist(VTOY_JSON *json, void *p)
4745 {
4746 return ventoy_parse_image_list_real(json, 1, p);
4747 }
4748 static int ventoy_parse_image_list(VTOY_JSON *json, void *p)
4749 {
4750 return ventoy_parse_image_list_real(json, 0, p);
4751 }
4752
4753 static int ventoy_parse_auto_memdisk(VTOY_JSON *json, void *p)
4754 {
4755 VTOY_JSON *node = NULL;
4756 data_auto_memdisk *data = (data_auto_memdisk *)p;
4757 path_node *tail = NULL;
4758 path_node *pnode = NULL;
4759
4760 if (json->enDataType != JSON_TYPE_ARRAY)
4761 {
4762 return 0;
4763 }
4764
4765 for (node = json->pstChild; node; node = node->pstNext)
4766 {
4767 if (node->enDataType == JSON_TYPE_STRING)
4768 {
4769 pnode = zalloc(sizeof(path_node));
4770 if (pnode)
4771 {
4772 strlcpy(pnode->path, node->unData.pcStrVal);
4773 if (data->list)
4774 {
4775 tail->next = pnode;
4776 tail = pnode;
4777 }
4778 else
4779 {
4780 data->list = tail = pnode;
4781 }
4782 }
4783 }
4784 }
4785
4786 return 0;
4787 }
4788 static int ventoy_parse_dud(VTOY_JSON *json, void *p)
4789 {
4790 int count = 0;
4791 const char *path = NULL;
4792 const char *file = NULL;
4793 data_dud *data = (data_dud *)p;
4794 dud_node *tail = NULL;
4795 dud_node *pnode = NULL;
4796 path_node *pathnode = NULL;
4797 path_node *pathtail = NULL;
4798 VTOY_JSON *node = NULL;
4799 VTOY_JSON *filelist = NULL;
4800 VTOY_JSON *filenode = NULL;
4801
4802 if (json->enDataType != JSON_TYPE_ARRAY)
4803 {
4804 return 0;
4805 }
4806
4807 for (node = json->pstChild; node; node = node->pstNext)
4808 {
4809 if (node->enDataType != JSON_TYPE_OBJECT)
4810 {
4811 continue;
4812 }
4813
4814 path = vtoy_json_get_string_ex(node->pstChild, "image");
4815 if (!path)
4816 {
4817 continue;
4818 }
4819
4820 file = vtoy_json_get_string_ex(node->pstChild, "dud");
4821 if (file)
4822 {
4823 pnode = zalloc(sizeof(dud_node));
4824 if (pnode)
4825 {
4826 strlcpy(pnode->path, path);
4827
4828 pathnode = zalloc(sizeof(path_node));
4829 if (pathnode)
4830 {
4831 strlcpy(pathnode->path, file);
4832 pnode->list = pathnode;
4833 }
4834 else
4835 {
4836 free(pnode);
4837 }
4838
4839 if (data->list)
4840 {
4841 tail->next = pnode;
4842 tail = pnode;
4843 }
4844 else
4845 {
4846 data->list = tail = pnode;
4847 }
4848 }
4849
4850 continue;
4851 }
4852
4853 filelist = vtoy_json_find_item(node->pstChild, JSON_TYPE_ARRAY, "dud");
4854 if (!filelist)
4855 {
4856 continue;
4857 }
4858
4859 pnode = zalloc(sizeof(dud_node));
4860 if (!pnode)
4861 {
4862 continue;
4863 }
4864
4865 strlcpy(pnode->path, path);
4866
4867 for (filenode = filelist->pstChild; filenode; filenode = filenode->pstNext)
4868 {
4869 if (filenode->enDataType != JSON_TYPE_STRING)
4870 {
4871 continue;
4872 }
4873
4874 pathnode = zalloc(sizeof(path_node));
4875 if (pathnode)
4876 {
4877 strlcpy(pathnode->path, filenode->unData.pcStrVal);
4878 count++;
4879
4880 if (pnode->list)
4881 {
4882 pathtail->next = pathnode;
4883 pathtail = pathnode;
4884 }
4885 else
4886 {
4887 pnode->list = pathtail = pathnode;
4888 }
4889 }
4890 }
4891
4892 if (count == 0)
4893 {
4894 free(pnode);
4895 }
4896 else
4897 {
4898 if (data->list)
4899 {
4900 tail->next = pnode;
4901 tail = pnode;
4902 }
4903 else
4904 {
4905 data->list = tail = pnode;
4906 }
4907 }
4908 }
4909
4910 return 0;
4911 }
4912
4913
4914
4915 #if 0
4916 #endif
4917
4918
4919 static int ventoy_load_old_json(const char *filename)
4920 {
4921 int ret = 0;
4922 int offset = 0;
4923 int buflen = 0;
4924 char *buffer = NULL;
4925 unsigned char *start = NULL;
4926 VTOY_JSON *json = NULL;
4927 VTOY_JSON *node = NULL;
4928 VTOY_JSON *next = NULL;
4929
4930 ret = ventoy_read_file_to_buf(filename, 4, (void **)&buffer, &buflen);
4931 if (ret)
4932 {
4933 vlog("Failed to read old ventoy.json file.\n");
4934 return 1;
4935 }
4936 buffer[buflen] = 0;
4937
4938 start = (unsigned char *)buffer;
4939
4940 if (start[0] == 0xef && start[1] == 0xbb && start[2] == 0xbf)
4941 {
4942 offset = 3;
4943 }
4944 else if ((start[0] == 0xff && start[1] == 0xfe) || (start[0] == 0xfe && start[1] == 0xff))
4945 {
4946 vlog("ventoy.json is in UCS-2 encoding, ignore it.\n");
4947 free(buffer);
4948 return 1;
4949 }
4950
4951 json = vtoy_json_create();
4952 if (!json)
4953 {
4954 free(buffer);
4955 return 1;
4956 }
4957
4958 if (vtoy_json_parse_ex(json, buffer + offset, buflen - offset) == JSON_SUCCESS)
4959 {
4960 vlog("parse ventoy.json success\n");
4961
4962 for (node = json->pstChild; node; node = node->pstNext)
4963 for (next = node->pstNext; next; next = next->pstNext)
4964 {
4965 if (node->pcName && next->pcName && strcmp(node->pcName, next->pcName) == 0)
4966 {
4967 vlog("ventoy.json contains duplicate key <%s>.\n", node->pcName);
4968 g_sysinfo.invalid_config = 1;
4969 ret = 1;
4970 goto end;
4971 }
4972 }
4973
4974 for (node = json->pstChild; node; node = node->pstNext)
4975 {
4976 ventoy_parse_json(control);
4977 ventoy_parse_json(theme);
4978 ventoy_parse_json(menu_alias);
4979 ventoy_parse_json(menu_tip);
4980 ventoy_parse_json(menu_class);
4981 ventoy_parse_json(auto_install);
4982 ventoy_parse_json(persistence);
4983 ventoy_parse_json(injection);
4984 ventoy_parse_json(conf_replace);
4985 ventoy_parse_json(password);
4986 ventoy_parse_json(image_list);
4987 ventoy_parse_json(image_blacklist);
4988 ventoy_parse_json(auto_memdisk);
4989 ventoy_parse_json(dud);
4990 }
4991 }
4992 else
4993 {
4994 vlog("ventoy.json has syntax error.\n");
4995 g_sysinfo.syntax_error = 1;
4996 ret = 1;
4997 }
4998
4999 end:
5000 vtoy_json_destroy(json);
5001
5002 free(buffer);
5003 return ret;
5004 }
5005
5006
5007 int ventoy_http_start(const char *ip, const char *port)
5008 {
5009 int i;
5010 char addr[128];
5011 char filename[128];
5012 char backupname[128];
5013 struct mg_callbacks callbacks;
5014 const char *options[] =
5015 {
5016 "listening_ports", "24681",
5017 "document_root", "www",
5018 "index_files", "index.html",
5019 "num_threads", "16",
5020 "error_log_file", LOG_FILE,
5021 "request_timeout_ms", "10000",
5022 NULL
5023 };
5024
5025 for (i = 0; i <= bios_max; i++)
5026 {
5027 ventoy_data_default_control(g_data_control + i);
5028 ventoy_data_default_theme(g_data_theme + i);
5029 ventoy_data_default_menu_alias(g_data_menu_alias + i);
5030 ventoy_data_default_menu_class(g_data_menu_class + i);
5031 ventoy_data_default_menu_tip(g_data_menu_tip + i);
5032 ventoy_data_default_auto_install(g_data_auto_install + i);
5033 ventoy_data_default_persistence(g_data_persistence + i);
5034 ventoy_data_default_injection(g_data_injection + i);
5035 ventoy_data_default_conf_replace(g_data_conf_replace + i);
5036 ventoy_data_default_password(g_data_password + i);
5037 ventoy_data_default_image_list(g_data_image_list + i);
5038 ventoy_data_default_auto_memdisk(g_data_auto_memdisk + i);
5039 ventoy_data_default_dud(g_data_dud + i);
5040 }
5041
5042 ventoy_get_json_path(filename, backupname);
5043 if (ventoy_is_file_exist("%s", filename))
5044 {
5045 ventoy_copy_file(filename, backupname);
5046 ventoy_load_old_json(filename);
5047 }
5048
5049
5050 /* option */
5051 scnprintf(addr, sizeof(addr), "%s:%s", ip, port);
5052 options[1] = addr;
5053
5054 memset(&callbacks, 0, sizeof(callbacks));
5055 callbacks.begin_request = ventoy_request_handler;
5056 #ifndef VENTOY_SIM
5057 callbacks.open_file = ventoy_web_openfile;
5058 #endif
5059 g_ventoy_http_ctx = mg_start(&callbacks, NULL, options);
5060
5061 ventoy_start_writeback_thread(ventoy_http_writeback);
5062
5063 return g_ventoy_http_ctx ? 0 : 1;
5064 }
5065
5066 int ventoy_http_stop(void)
5067 {
5068 if (g_ventoy_http_ctx)
5069 {
5070 mg_stop(g_ventoy_http_ctx);
5071 }
5072
5073 ventoy_stop_writeback_thread();
5074 return 0;
5075 }
5076
5077 int ventoy_http_init(void)
5078 {
5079 int i = 0;
5080
5081 #ifdef VENTOY_SIM
5082 char *Buffer = NULL;
5083 int BufLen = 0;
5084
5085 ventoy_read_file_to_buf("www/helplist", 4, (void **)&Buffer, &BufLen);
5086 if (Buffer)
5087 {
5088 for (i = 0; i < BufLen / 5; i++)
5089 {
5090 memcpy(g_ventoy_help_lang[i], Buffer + i * 5, 5);
5091 g_ventoy_help_lang[i][5] = 0;
5092 }
5093 free(Buffer);
5094 }
5095 #else
5096 ventoy_file *file;
5097 file = ventoy_tar_find_file("www/helplist");
5098 if (file)
5099 {
5100 for (i = 0; i < file->size / 5; i++)
5101 {
5102 memcpy(g_ventoy_help_lang[i], (char *)(file->addr) + i * 5, 5);
5103 g_ventoy_help_lang[i][5] = 0;
5104 }
5105 }
5106 #endif
5107
5108 if (!g_pub_json_buffer)
5109 {
5110 g_pub_json_buffer = malloc(JSON_BUF_MAX * 2);
5111 g_pub_save_buffer = g_pub_json_buffer + JSON_BUF_MAX;
5112 }
5113
5114
5115 pthread_mutex_init(&g_api_mutex, NULL);
5116 return 0;
5117 }
5118
5119 void ventoy_http_exit(void)
5120 {
5121 check_free(g_pub_json_buffer);
5122 g_pub_json_buffer = NULL;
5123 g_pub_save_buffer = NULL;
5124
5125 pthread_mutex_destroy(&g_api_mutex);
5126 }
5127
5128