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