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