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