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