]> 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 ventoy_file * ventoy_tar_find_file(const char *path)
84 {
85 int i;
86 int len;
87 ventoy_file *node = g_tar_filelist;
88
89 len = (int)strlen(path);
90
91 for (i = 0; i < g_tar_filenum; i++, node++)
92 {
93 if (node->pathlen == len && memcmp(node->path, path, len) == 0)
94 {
95 return node;
96 }
97
98 if (node->pathlen > len)
99 {
100 break;
101 }
102 }
103
104 return NULL;
105 }
106
107
108 int ventoy_decompress_tar(char *tarbuf, int buflen, int *tarsize)
109 {
110 int rc = 1;
111 int inused = 0;
112 int BufLen = 0;
113 unsigned char *buffer = NULL;
114 char tarxz[MAX_PATH];
115
116 #if defined(_MSC_VER) || defined(WIN32)
117 scnprintf(tarxz, sizeof(tarxz), "%s\\ventoy\\%s", g_ventoy_dir, PLUGSON_TXZ);
118 #else
119 scnprintf(tarxz, sizeof(tarxz), "%s/tool/%s", g_ventoy_dir, PLUGSON_TXZ);
120 #endif
121
122 if (ventoy_read_file_to_buf(tarxz, 0, (void **)&buffer, &BufLen))
123 {
124 vlog("Failed to read file <%s>\n", tarxz);
125 return 1;
126 }
127
128 g_unxz_buffer = (unsigned char *)tarbuf;
129 g_unxz_len = 0;
130
131 unxz(buffer, BufLen, NULL, unxz_flush, NULL, &inused, unxz_error);
132 vlog("xzlen:%u rawdata size:%d\n", BufLen, g_unxz_len);
133
134 if (inused != BufLen)
135 {
136 vlog("Failed to unxz data %d %d\n", inused, BufLen);
137 rc = 1;
138 }
139 else
140 {
141 *tarsize = g_unxz_len;
142 rc = 0;
143 }
144
145 free(buffer);
146
147 return rc;
148 }
149
150 int ventoy_www_init(void)
151 {
152 int i = 0;
153 int j = 0;
154 int size = 0;
155 int tarsize = 0;
156 int offset = 0;
157 ventoy_file *node = NULL;
158 ventoy_file *node2 = NULL;
159 VENTOY_TAR_HEAD *pHead = NULL;
160 ventoy_file tmpnode;
161
162 if (!g_tar_filelist)
163 {
164 g_tar_filelist = malloc(VENTOY_FILE_MAX * sizeof(ventoy_file));
165 g_tar_buffer = malloc(TAR_BUF_MAX);
166 g_tar_filenum = 0;
167 }
168
169 if ((!g_tar_filelist) || (!g_tar_buffer))
170 {
171 return 1;
172 }
173
174 if (ventoy_decompress_tar(g_tar_buffer, TAR_BUF_MAX, &tarsize))
175 {
176 vlog("Failed to decompress tar\n");
177 return 1;
178 }
179
180 pHead = (VENTOY_TAR_HEAD *)g_tar_buffer;
181 node = g_tar_filelist;
182
183 while (g_tar_filenum < VENTOY_FILE_MAX && size < tarsize && memcmp(pHead->magic, TMAGIC, 5) == 0)
184 {
185 if (pHead->typeflag == REGTYPE)
186 {
187 node->size = (int)strtol(pHead->size, NULL, 8);
188 node->pathlen = (int)scnprintf(node->path, MAX_PATH, "%s", pHead->name);
189 node->addr = pHead + 1;
190
191 if (node->pathlen == 13 && strcmp(pHead->name, "www/buildtime") == 0)
192 {
193 scnprintf(g_sysinfo.buildtime, sizeof(g_sysinfo.buildtime), "%s", (char *)node->addr);
194 vlog("Plugson buildtime %s\n", g_sysinfo.buildtime);
195 }
196
197 offset = 512 + VENTOY_UP_ALIGN(node->size, 512);
198
199 node++;
200 g_tar_filenum++;
201 }
202 else
203 {
204 offset = 512;
205 }
206
207 pHead = (VENTOY_TAR_HEAD *)((char *)pHead + offset);
208 size += offset;
209 }
210
211
212 //sort
213 for (i = 0; i < g_tar_filenum; i++)
214 for (j = i + 1; j < g_tar_filenum; j++)
215 {
216 node = g_tar_filelist + i;
217 node2 = g_tar_filelist + j;
218
219 if (node->pathlen > node2->pathlen)
220 {
221 memcpy(&tmpnode, node, sizeof(ventoy_file));
222 memcpy(node, node2, sizeof(ventoy_file));
223 memcpy(node2, &tmpnode, sizeof(ventoy_file));
224 }
225 }
226
227 vlog("Total extract %d files from tar file.\n", g_tar_filenum);
228
229 return 0;
230 }
231
232 void ventoy_www_exit(void)
233 {
234 check_free(g_tar_filelist);
235 check_free(g_tar_buffer);
236 g_tar_filelist = NULL;
237 g_tar_buffer = NULL;
238 g_tar_filenum = 0;
239 }
240
241
242 void ventoy_get_json_path(char *path, char *backup)
243 {
244 #if defined(_MSC_VER) || defined(WIN32)
245 scnprintf(path, 64, "%C:\\ventoy\\ventoy.json", g_cur_dir[0]);
246 if (backup)
247 {
248 scnprintf(backup, 64, "%C:\\ventoy\\ventoy_backup.json", g_cur_dir[0]);
249 }
250 #else
251 scnprintf(path, 64, "%s/ventoy/ventoy.json", g_cur_dir);
252 if (backup)
253 {
254 scnprintf(backup, 64, "%s/ventoy/ventoy_backup.json", g_cur_dir);
255 }
256
257 #endif
258 }
259
260 static const char g_encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
261 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
262 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
263 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
264 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
265 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
266 'w', 'x', 'y', 'z', '0', '1', '2', '3',
267 '4', '5', '6', '7', '8', '9', '+', '/'};
268
269 char * ventoy_base64_encode(const char *data, int input_length, int *output_length)
270 {
271 int i = 0;
272 int j = 0;
273 char *encoded_data = NULL;
274 int mod_table[] = {0, 2, 1};
275
276 *output_length = 4 * ((input_length + 2) / 3);
277 encoded_data = malloc(*output_length + 4);
278 if (!encoded_data)
279 {
280 return NULL;
281 }
282
283 while (i < input_length)
284 {
285 unsigned int octet_a = i < input_length ? (unsigned char)data[i++] : 0;
286 unsigned int octet_b = i < input_length ? (unsigned char)data[i++] : 0;
287 unsigned int octet_c = i < input_length ? (unsigned char)data[i++] : 0;
288
289 unsigned int triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
290
291 encoded_data[j++] = g_encoding_table[(triple >> 3 * 6) & 0x3F];
292 encoded_data[j++] = g_encoding_table[(triple >> 2 * 6) & 0x3F];
293 encoded_data[j++] = g_encoding_table[(triple >> 1 * 6) & 0x3F];
294 encoded_data[j++] = g_encoding_table[(triple >> 0 * 6) & 0x3F];
295 }
296
297 for (i = 0; i < mod_table[input_length % 3]; i++)
298 {
299 encoded_data[*output_length - 1 - i] = '=';
300 }
301
302 return encoded_data;
303 }
304