blob: a457ab12dfc4f438e5d263b5bd832443689da97b [file] [log] [blame]
xf.liaa4d92f2023-09-13 00:18:58 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <errno.h>
9#include "openssl/md5.h"
10#include "mtd.h"
11#include "libcpnv.h"
12#include "cfg_api.h"
13#include "flags_api.h"
14#include "zxicbasic_api.h"
15
xf.lie31de8b2023-12-26 23:38:58 -080016static int file_is_exist(const char *filename)
17{
18 FILE *file = fopen(filename, "r");
19
20 if (file)
21 {
22 fclose(file);
23 return 1;
24 }
25 else
26 {
27 return 0;
28 }
29}
xf.liaa4d92f2023-09-13 00:18:58 -070030
31/*******************************************************************************
32* 功能描述: copyfile
33* 参数说明:
34* (传入参数) to:目标文件
35* (传入参数) from:源文件
36* 返 回 值: 0表示成功,负值失败
37* 其它说明:
38*******************************************************************************/
39static int copyfile(const char *from, const char *to)
40{
41 int fd_to;
42 int fd_from;
43 char buf[4096];
44 ssize_t nread;
45 int ret = -1;
46
47 fd_from = open(from, O_RDONLY);
48 if (fd_from < 0)
49 return -2;
50
51 fd_to = open(to, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0640);
52 if (fd_to < 0) {
53 ret = -3;
54 goto out_error;
55 }
56
57 while (1)
58 {
59 char *out_ptr;
60 ssize_t nwritten;
61
62 nread = read(fd_from, buf, sizeof(buf));
63 if (nread == 0)
64 {
65 break; /* read file done*/
66 }
67 else
68 {
69 if (nread < 0 )
70 {
71 if (errno == EINTR || errno == EAGAIN)
72 {
73 continue;
74 }
75 else
76 {
77 ret = -4;
78 goto out_error;
79 }
80 }
81 }
82
83 out_ptr = buf;
84 do
85 {
86 nwritten = write(fd_to, out_ptr, nread);
87 if (nwritten > 0)
88 {
89 nread -= nwritten;
90 out_ptr += nwritten;
91 }
92 else
93 {
94 if (nwritten < 0)
95 {
96 if (errno == EINTR || errno == EAGAIN)
97 {
98 continue;
99 }
100 else
101 {
102 ret = -5;
103 goto out_error;
104 }
105 }
106 }
107 } while (nread > 0);
108 }
109
110 ret = fsync(fd_to);
111 if (ret < 0) {
112 printf("Sync Failed:%s, file path:%s", strerror(errno), to);
113 goto out_error;
114 }
115
116 if (close(fd_to) < 0)
117 {
118 fd_to = -1;
119 ret = -6;
120 goto out_error;
121 }
122 close(fd_from);
123
124 /* Success! */
125 return 0;
126
127out_error:
128 printf("copyfile %s to %s error:%d\n", from, to, ret);
129 close(fd_from);
130 if (fd_to >= 0)
131 close(fd_to);
132
133 return ret;
134}
135
xf.lie31de8b2023-12-26 23:38:58 -0800136/*******************************************************************************
137* 功能描述: nvrofs2挂载
138* 参数说明:
139* (传入参数) rw,传入0进行只读挂载,传入非0进行可写挂载
140* 返 回 值: 0表示成功,非0表示失败
141* 其它说明:
142*******************************************************************************/
xf.liaa4d92f2023-09-13 00:18:58 -0700143int nvrofs2_mount(int rw)
144{
145 if (rw)
146 return zxic_system("/bin/mount -t jffs2 -o rw,sync mtd:nvrofs2 /mnt/nvrofs2");
147 else
148 return zxic_system("/bin/mount -t jffs2 -o ro mtd:nvrofs2 /mnt/nvrofs2");
149}
150int nvrofs2_umount(void)
151{
152 return zxic_system("/bin/umount -f -l /mnt/nvrofs2");
153}
154
155unsigned char *bin2hex(const unsigned char *old, const size_t oldlen)
156{
157 unsigned char *result = (unsigned char *)malloc(oldlen * 2 + 1);
158 size_t i, j;
159 int b = 0;
160
161 for (i = j = 0; i < oldlen; i++)
162 {
163 b = old[i] >> 4;
164 result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
165 b = old[i] & 0xf;
166 result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
167 }
168 result[j] = '\0';
169 return result;
170}
171
xf.lie31de8b2023-12-26 23:38:58 -0800172/*******************************************************************************
173* 功能描述: 计算文件md5
174* 参数说明:
175* (传入参数) file_in文件名
176* (传出参数) hash_value保存文件的md5(二进制),md5需要至少16个字节
177* 返 回 值: 0表示成功,非0表示失败
178* 其它说明:
179*******************************************************************************/
xf.liaa4d92f2023-09-13 00:18:58 -0700180int calc_file_hash(const char *file_in, unsigned char *hash_value)
181{
182 MD5_CTX ctx;
183 unsigned char *buf;
184 int offset;
185 int fd;
186 ssize_t len;
187
188 fd = open(file_in, O_RDONLY);
189 if (fd < 0)
190 return -1;
191 buf = malloc(4096);
192 if (buf == NULL)
xf.li9d1a0e12023-09-20 01:43:20 -0700193 {
194 close(fd);
xf.liaa4d92f2023-09-13 00:18:58 -0700195 return -1;
xf.li9d1a0e12023-09-20 01:43:20 -0700196 }
xf.liaa4d92f2023-09-13 00:18:58 -0700197 MD5_Init(&ctx);
198 do
199 {
200 len = full_read(fd, buf, 4096);
201 MD5_Update(&ctx, buf, len);
202 if (len < 4096)
203 break;
204 } while(1);
205
206 MD5_Final(hash_value, &ctx);
207 free(buf);
xf.li9d1a0e12023-09-20 01:43:20 -0700208 close(fd);
xf.liaa4d92f2023-09-13 00:18:58 -0700209 return 0;
210}
211
xf.lie31de8b2023-12-26 23:38:58 -0800212/*******************************************************************************
213* 功能描述: 计算文件md5,并保存到文件
214* 参数说明:
215* (传入参数) file_in文件名
216* (传入参数) file_hash保存md5的文件
217* 返 回 值: 0表示成功,非0表示失败
218* 其它说明:
219*******************************************************************************/
xf.liaa4d92f2023-09-13 00:18:58 -0700220int file_hash(const char *file_in, const char *file_hash)
221{
222 unsigned char hash_value[16] = {0};
223 unsigned char *hash_str;
224 int ret;
225 ssize_t ret_s;
226
227 ret = calc_file_hash(file_in, hash_value);
228 if (ret < 0)
229 return -1;
230 hash_str = bin2hex(hash_value, 16);
231 ret_s = open_write_close(file_hash, hash_str, 32);
232 free(hash_str);
233 if (ret_s != 32)
234 return -1;
235 return 0;
236}
xf.lie31de8b2023-12-26 23:38:58 -0800237
238/*******************************************************************************
239* 功能描述: 检验文件md5是否一致
240* 参数说明:
241* (传入参数) file_in文件名
242* (传入参数) file_hash md5文件
243* 返 回 值: 0表示校验一致,非0表示校验不一致
244* 其它说明:
245*******************************************************************************/
xf.liaa4d92f2023-09-13 00:18:58 -0700246int file_hash_check(const char *file_in, const char *file_hash)
247{
248 unsigned char hash_value[16] = {0};
249 unsigned char *hash_str;
xf.lie31de8b2023-12-26 23:38:58 -0800250 unsigned char hash_str2[36] = {0};
251 int ret = -1;
xf.liaa4d92f2023-09-13 00:18:58 -0700252 ssize_t ret_s;
253
254 ret = calc_file_hash(file_in, hash_value);
255 if (ret < 0)
256 return -1;
257 hash_str = bin2hex(hash_value, 16);
258 memset(hash_str2, 0, sizeof(hash_str2));
259 ret_s = open_read_close(file_hash, hash_str2, 32);
260 if (ret_s != 32)
xf.liaa4d92f2023-09-13 00:18:58 -0700261 {
xf.lie31de8b2023-12-26 23:38:58 -0800262 ret = -1;
263 goto out;
xf.liaa4d92f2023-09-13 00:18:58 -0700264 }
xf.lie31de8b2023-12-26 23:38:58 -0800265 if (strcmp(hash_str, hash_str2) == 0)
266 ret = 0; /* md5数据一致 */
267 else
268 ret = -1; /* md5数据不一致 */
269out:
270 free(hash_str);
271 return ret;
xf.liaa4d92f2023-09-13 00:18:58 -0700272}
273
274unsigned int cpnv_NvroBackup(void)
275{
276 char mtd_path[MAX_PATH] = {0};
277 int ret;
xf.lie31de8b2023-12-26 23:38:58 -0800278 unsigned int ret_u;
xf.liaa4d92f2023-09-13 00:18:58 -0700279
280 ret = mtd_find("nvrofs2", mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
281 if (ret < 0)
282 {
283 printf("[error]cpnv can not find nvrofs2\n");
284 return CPNV_ERROR;
285 }
286 ret = mtd_erase_partition("nvrofs2");
287 if (ret != 0)
288 {
289 printf("[error]cpnv erase nvrofs2\n");
290 return CPNV_ERROR;
291 }
xf.li9d1a0e12023-09-20 01:43:20 -0700292
xf.liaa4d92f2023-09-13 00:18:58 -0700293 ret = nvrofs2_mount(1);
294 if (ret != 0)
295 {
xf.li9d1a0e12023-09-20 01:43:20 -0700296 nvrofs2_umount();
297 ret = nvrofs2_mount(1);
298 if (ret != 0)
299 {
300 printf("[error]cpnv nvrofs2_mount\n");
301 return CPNV_ERROR;
302 }
xf.liaa4d92f2023-09-13 00:18:58 -0700303 }
304 ret = copyfile("/mnt/nvrofs/nvroall.bin", "/mnt/nvrofs2/nvroall.bin");
305 if (ret != 0)
306 {
307 printf("[error]cpnv nvrofs2 copyfile\n");
308 goto out_err;
309 }
310 ret = file_hash("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
311 if (ret != 0)
312 {
313 printf("[error]cpnv file_hash\n");
314 goto out_err;
315 }
xf.lie31de8b2023-12-26 23:38:58 -0800316 ret = copyfile("/mnt/nvrofs/nvroc0wall.bin", "/mnt/nvrofs2/nvroc0wall.bin");
317 if (ret != 0)
318 {
319 printf("[error]cpnv nvrofs2 copyfile\n");
320 goto out_err;
321 }
322 ret = file_hash("/mnt/nvrofs2/nvroc0wall.bin", "/mnt/nvrofs2/nvroc0wall.bin.hash");
323 if (ret != 0)
324 {
325 printf("[error]cpnv file_hash\n");
326 goto out_err;
327 }
328 ret = nvrofs2_umount();
329 if (ret < 0)
330 {
331 printf("[error]cpnv nvrofs2_umount\n");
332 goto out_err;
333 }
334 ret = flags_set_nvroflag(NVRO_BACKED_UP);
335 if (ret != 0)
336 {
337 printf("[error]cpnv NVRO_BACKED_UP\n");
338 return CPNV_ERROR;
339 }
340 ret = nvrofs2_mount(0);
341 if (ret != 0)
342 {
343 printf("[error]cpnv nvrofs2_mount ro\n");
344 goto out_err;
345 }
346 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 1);
347 if (ret_u != CPNV_OK)
348 {
349 printf("[error]cpnv nvrofs Attr 1\n");
350 goto out_err;
351 }
352 ret = copyfile("/mnt/nvrofs2/nvroall.bin.hash", "/mnt/nvrofs/nvroall.bin.hash");
353 if (ret != 0)
354 {
355 printf("[error]cpnv nvroall.bin.hash copyfile\n");
356 goto out_err;
357 }
358 ret = copyfile("/mnt/nvrofs2/nvroc0wall.bin.hash", "/mnt/nvrofs/nvroc0wall.bin.hash");
359 if (ret != 0)
360 {
361 printf("[error]cpnv nvroc0wall.bin.hash copyfile\n");
362 goto out_err;
363 }
364 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 0);
365 if (ret_u != CPNV_OK)
366 {
367 printf("[error]cpnv nvrofs Attr 0\n");
368 goto out_err;
369 }
370
xf.liaa4d92f2023-09-13 00:18:58 -0700371 ret = nvrofs2_umount();
372 if (ret < 0)
373 {
374 printf("[error]cpnv nvrofs2_umount\n");
375 return CPNV_ERROR;
376 }
377
xf.liaa4d92f2023-09-13 00:18:58 -0700378 return CPNV_OK;
379
380out_err:
381 nvrofs2_umount();
382
383 return CPNV_ERROR;
384}
385
xf.lie31de8b2023-12-26 23:38:58 -0800386unsigned int cpnv_nvro_check(int flag)
387{
388 int ret;
389
390 if (!file_is_exist("/mnt/nvrofs/nvroall.bin.hash"))
391 {
392 printf("[error]cpnv nvro nvroall.bin.hash not found\n");
393 return CPNV_ERROR;
394 }
395 ret = file_hash_check("/mnt/nvrofs/nvroall.bin", "/mnt/nvrofs/nvroall.bin.hash");
396 if (ret != 0)
397 {
398 printf("[error]cpnv nvro hash check\n");
399 return CPNV_ERROR;
400 }
401 if (flag == 2)
402 {
403 ret = file_hash_check("/mnt/nvrofs/nvroc0wall.bin", "/mnt/nvrofs/nvroc0wall.bin.hash");
404 if (ret != 0)
405 {
406 printf("[error]cpnv nvro hash check\n");
407 return CPNV_ERROR;
408 }
409 }
410 return CPNV_OK;
411}
412
xf.liaa4d92f2023-09-13 00:18:58 -0700413unsigned int cpnv_NvroRestore(void)
414{
415 int ret;
416 unsigned int ret_u;
417 unsigned int nvro_flag;
418
419 nvro_flag = flags_get_nvroflag();
420 if (nvro_flag != NVRO_RESTORING)
421 {
422 printf("[error]cpnv_NvroRestore nvro flag error\n");
423 return CPNV_ERROR;
424 }
xf.liaa4d92f2023-09-13 00:18:58 -0700425 ret = nvrofs2_mount(0);
426 if (ret != 0)
427 {
xf.lie31de8b2023-12-26 23:38:58 -0800428 nvrofs2_umount();
429 ret = nvrofs2_mount(0);
430 if (ret != 0)
431 {
432 printf("[error]cpnv nvrofs2_mount\n");
433 return CPNV_ERROR;
434 }
xf.liaa4d92f2023-09-13 00:18:58 -0700435 }
436 ret = file_hash_check("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
437 if (ret != 0)
438 {
439 printf("[error]cpnv file_hash_check\n");
440 goto out_err;
441 }
xf.lie31de8b2023-12-26 23:38:58 -0800442 ret = file_hash_check("/mnt/nvrofs2/nvroc0wall.bin", "/mnt/nvrofs2/nvroc0wall.bin.hash");
443 if (ret != 0)
444 {
445 printf("[error]cpnv file_hash_check\n");
446 goto out_err;
447 }
xf.liaa4d92f2023-09-13 00:18:58 -0700448 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 1);
449 if (ret_u != CPNV_OK)
450 {
451 printf("[error]cpnv nvrofs Attr 1\n");
452 goto out_err;
453 }
454 ret = copyfile("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs/nvroall.bin");
455 if (ret != 0)
456 {
457 printf("[error]cpnv nvrofs2 restore copyfile\n");
458 goto out_err;
459 }
xf.lie31de8b2023-12-26 23:38:58 -0800460 ret = copyfile("/mnt/nvrofs2/nvroall.bin.hash", "/mnt/nvrofs/nvroall.bin.hash");
461 if (ret != 0)
462 {
463 printf("[error]cpnv nvrofs2 restore hash copyfile\n");
464 goto out_err;
465 }
466 ret = copyfile("/mnt/nvrofs2/nvroc0wall.bin", "/mnt/nvrofs/nvroc0wall.bin");
467 if (ret != 0)
468 {
469 printf("[error]cpnv nvrofs2 restore copyfile\n");
470 goto out_err;
471 }
472 ret = copyfile("/mnt/nvrofs2/nvroc0wall.bin.hash", "/mnt/nvrofs/nvroc0wall.bin.hash");
473 if (ret != 0)
474 {
475 printf("[error]cpnv nvrofs2 restore hash copyfile\n");
476 goto out_err;
477 }
478 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 0);
xf.liaa4d92f2023-09-13 00:18:58 -0700479 if (ret_u != CPNV_OK)
480 {
481 printf("[error]cpnv nvrofs Attr 0\n");
482 goto out_err;
483 }
484 ret = nvrofs2_umount();
485 if (ret < 0)
486 {
487 printf("[error]cpnv nvrofs2_umount\n");
488 return CPNV_ERROR;
489 }
490 ret = flags_set_nvroflag(NVRO_BACKED_UP);
491 if (ret != 0)
492 {
493 printf("[error]cpnv_NvroRestore set NVRO_BACKED_UP\n");
494 return CPNV_ERROR;
495 }
496 return CPNV_OK;
497
498out_err:
499 nvrofs2_umount();
xf.li9d1a0e12023-09-20 01:43:20 -0700500 flags_set_nvroflag(NVRO_BACKED_UP);
xf.liaa4d92f2023-09-13 00:18:58 -0700501
502 return CPNV_ERROR;
503}