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