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