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