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