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