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