]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Plugson/src/Core/ventoy_util.c
VentoyPlugson update
[Ventoy.git] / Plugson / src / Core / ventoy_util.c
1 /******************************************************************************
2 * ventoy_util.c ---- ventoy util
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 <sys/stat.h>
22 #include <ventoy_define.h>
23 #include <ventoy_util.h>
24
25
26 static int g_tar_filenum = 0;
27 static char *g_tar_buffer = NULL;
28 static ventoy_file *g_tar_filelist = NULL;
29
30 SYSINFO g_sysinfo;
31
32 unsigned char *g_unxz_buffer = NULL;
33 int g_unxz_len = 0;
34
35 void unxz_error(char *x)
36 {
37 vlog("%s\n", x);
38 }
39
40 int unxz_flush(void *src, unsigned int size)
41 {
42 memcpy(g_unxz_buffer + g_unxz_len, src, size);
43 g_unxz_len += (int)size;
44
45 return (int)size;
46 }
47
48
49 uint64_t ventoy_get_human_readable_gb(uint64_t SizeBytes)
50 {
51 int i;
52 int Pow2 = 1;
53 double Delta;
54 double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000;
55
56 if ((SizeBytes % SIZE_1GB) == 0)
57 {
58 return (uint64_t)(SizeBytes / SIZE_1GB);
59 }
60
61 for (i = 0; i < 12; i++)
62 {
63 if (Pow2 > GB)
64 {
65 Delta = (Pow2 - GB) / Pow2;
66 }
67 else
68 {
69 Delta = (GB - Pow2) / Pow2;
70 }
71
72 if (Delta < 0.05)
73 {
74 return Pow2;
75 }
76
77 Pow2 <<= 1;
78 }
79
80 return (uint64_t)GB;
81 }
82
83 int ventoy_read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen)
84 {
85 int FileSize;
86 FILE *fp = NULL;
87 void *Data = NULL;
88
89 #if defined(_MSC_VER) || defined(WIN32)
90 fopen_s(&fp, FileName, "rb");
91 #else
92 fp = fopen(FileName, "rb");
93 #endif
94 if (fp == NULL)
95 {
96 vlog("Failed to open file %s", FileName);
97 return 1;
98 }
99
100 fseek(fp, 0, SEEK_END);
101 FileSize = (int)ftell(fp);
102
103 Data = malloc(FileSize + ExtLen);
104 if (!Data)
105 {
106 fclose(fp);
107 return 1;
108 }
109
110 fseek(fp, 0, SEEK_SET);
111 fread(Data, 1, FileSize, fp);
112
113 fclose(fp);
114
115 *Bufer = Data;
116 *BufLen = FileSize;
117
118 return 0;
119 }
120
121 ventoy_file * ventoy_tar_find_file(const char *path)
122 {
123 int i;
124 int len;
125 ventoy_file *node = g_tar_filelist;
126
127 len = (int)strlen(path);
128
129 for (i = 0; i < g_tar_filenum; i++, node++)
130 {
131 if (node->pathlen == len && memcmp(node->path, path, len) == 0)
132 {
133 return node;
134 }
135
136 if (node->pathlen > len)
137 {
138 break;
139 }
140 }
141
142 return NULL;
143 }
144
145
146 int ventoy_decompress_tar(char *tarbuf, int buflen, int *tarsize)
147 {
148 int rc = 1;
149 int inused = 0;
150 int BufLen = 0;
151 unsigned char *buffer = NULL;
152 char tarxz[MAX_PATH];
153
154 #if defined(_MSC_VER) || defined(WIN32)
155 scnprintf(tarxz, sizeof(tarxz), "%s\\ventoy\\%s", g_ventoy_dir, PLUGSON_TXZ);
156 #else
157 scnprintf(tarxz, sizeof(tarxz), "%s/tool/%s", g_ventoy_dir, PLUGSON_TXZ);
158 #endif
159
160 if (ventoy_read_file_to_buf(tarxz, 0, (void **)&buffer, &BufLen))
161 {
162 vlog("Failed to read file <%s>\n", tarxz);
163 return 1;
164 }
165
166 g_unxz_buffer = (unsigned char *)tarbuf;
167 g_unxz_len = 0;
168
169 unxz(buffer, BufLen, NULL, unxz_flush, NULL, &inused, unxz_error);
170 vlog("xzlen:%u rawdata size:%d\n", BufLen, g_unxz_len);
171
172 if (inused != BufLen)
173 {
174 vlog("Failed to unxz data %d %d\n", inused, BufLen);
175 rc = 1;
176 }
177 else
178 {
179 *tarsize = g_unxz_len;
180 rc = 0;
181 }
182
183 free(buffer);
184
185 return rc;
186 }
187
188 int ventoy_www_init(void)
189 {
190 int i = 0;
191 int j = 0;
192 int size = 0;
193 int tarsize = 0;
194 int offset = 0;
195 ventoy_file *node = NULL;
196 ventoy_file *node2 = NULL;
197 VENTOY_TAR_HEAD *pHead = NULL;
198 ventoy_file tmpnode;
199
200 if (!g_tar_filelist)
201 {
202 g_tar_filelist = malloc(VENTOY_FILE_MAX * sizeof(ventoy_file));
203 g_tar_buffer = malloc(TAR_BUF_MAX);
204 g_tar_filenum = 0;
205 }
206
207 if ((!g_tar_filelist) || (!g_tar_buffer))
208 {
209 return 1;
210 }
211
212 if (ventoy_decompress_tar(g_tar_buffer, TAR_BUF_MAX, &tarsize))
213 {
214 return 1;
215 }
216
217 pHead = (VENTOY_TAR_HEAD *)g_tar_buffer;
218 node = g_tar_filelist;
219
220 while (g_tar_filenum < VENTOY_FILE_MAX && size < tarsize && memcmp(pHead->magic, TMAGIC, 5) == 0)
221 {
222 if (pHead->typeflag == REGTYPE)
223 {
224 node->size = (int)strtol(pHead->size, NULL, 8);
225 node->pathlen = (int)scnprintf(node->path, MAX_PATH, "%s", pHead->name);
226 node->addr = pHead + 1;
227
228 if (node->pathlen == 13 && strcmp(pHead->name, "www/buildtime") == 0)
229 {
230 scnprintf(g_sysinfo.buildtime, sizeof(g_sysinfo.buildtime), "%s", (char *)node->addr);
231 vlog("Plugson buildtime %s\n", g_sysinfo.buildtime);
232 }
233
234 offset = 512 + VENTOY_UP_ALIGN(node->size, 512);
235
236 node++;
237 g_tar_filenum++;
238 }
239 else
240 {
241 offset = 512;
242 }
243
244 pHead = (VENTOY_TAR_HEAD *)((char *)pHead + offset);
245 size += offset;
246 }
247
248
249 //sort
250 for (i = 0; i < g_tar_filenum; i++)
251 for (j = i + 1; j < g_tar_filenum; j++)
252 {
253 node = g_tar_filelist + i;
254 node2 = g_tar_filelist + j;
255
256 if (node->pathlen > node2->pathlen)
257 {
258 memcpy(&tmpnode, node, sizeof(ventoy_file));
259 memcpy(node, node2, sizeof(ventoy_file));
260 memcpy(node2, &tmpnode, sizeof(ventoy_file));
261 }
262 }
263
264 vlog("Total extract %d files from tar file.\n", g_tar_filenum);
265
266 return 0;
267 }
268
269 void ventoy_www_exit(void)
270 {
271 check_free(g_tar_filelist);
272 check_free(g_tar_buffer);
273 g_tar_filelist = NULL;
274 g_tar_buffer = NULL;
275 g_tar_filenum = 0;
276 }
277
278
279 void ventoy_get_json_path(char *path, char *backup)
280 {
281 #if defined(_MSC_VER) || defined(WIN32)
282 scnprintf(path, 64, "%C:\\ventoy\\ventoy.json", g_cur_dir[0]);
283 if (backup)
284 {
285 scnprintf(backup, 64, "%C:\\ventoy\\ventoy_backup.json", g_cur_dir[0]);
286 }
287 #else
288 scnprintf(path, 64, "%s/ventoy/ventoy.json", g_cur_dir);
289 if (backup)
290 {
291 scnprintf(backup, 64, "%s/ventoy/ventoy_backup.json", g_cur_dir);
292 }
293
294 #endif
295 }
296
297