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