blob: d65b1518317f35576be3a447c9d6da41c51339e0 [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
16
17/*******************************************************************************
18* 功能描述: copyfile
19* 参数说明:
20* (传入参数) to:目标文件
21* (传入参数) from:源文件
22* 返 回 值: 0表示成功,负值失败
23* 其它说明:
24*******************************************************************************/
25static int copyfile(const char *from, const char *to)
26{
27 int fd_to;
28 int fd_from;
29 char buf[4096];
30 ssize_t nread;
31 int ret = -1;
32
33 fd_from = open(from, O_RDONLY);
34 if (fd_from < 0)
35 return -2;
36
37 fd_to = open(to, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0640);
38 if (fd_to < 0) {
39 ret = -3;
40 goto out_error;
41 }
42
43 while (1)
44 {
45 char *out_ptr;
46 ssize_t nwritten;
47
48 nread = read(fd_from, buf, sizeof(buf));
49 if (nread == 0)
50 {
51 break; /* read file done*/
52 }
53 else
54 {
55 if (nread < 0 )
56 {
57 if (errno == EINTR || errno == EAGAIN)
58 {
59 continue;
60 }
61 else
62 {
63 ret = -4;
64 goto out_error;
65 }
66 }
67 }
68
69 out_ptr = buf;
70 do
71 {
72 nwritten = write(fd_to, out_ptr, nread);
73 if (nwritten > 0)
74 {
75 nread -= nwritten;
76 out_ptr += nwritten;
77 }
78 else
79 {
80 if (nwritten < 0)
81 {
82 if (errno == EINTR || errno == EAGAIN)
83 {
84 continue;
85 }
86 else
87 {
88 ret = -5;
89 goto out_error;
90 }
91 }
92 }
93 } while (nread > 0);
94 }
95
96 ret = fsync(fd_to);
97 if (ret < 0) {
98 printf("Sync Failed:%s, file path:%s", strerror(errno), to);
99 goto out_error;
100 }
101
102 if (close(fd_to) < 0)
103 {
104 fd_to = -1;
105 ret = -6;
106 goto out_error;
107 }
108 close(fd_from);
109
110 /* Success! */
111 return 0;
112
113out_error:
114 printf("copyfile %s to %s error:%d\n", from, to, ret);
115 close(fd_from);
116 if (fd_to >= 0)
117 close(fd_to);
118
119 return ret;
120}
121
122int nvrofs2_mount(int rw)
123{
124 if (rw)
125 return zxic_system("/bin/mount -t jffs2 -o rw,sync mtd:nvrofs2 /mnt/nvrofs2");
126 else
127 return zxic_system("/bin/mount -t jffs2 -o ro mtd:nvrofs2 /mnt/nvrofs2");
128}
129int nvrofs2_umount(void)
130{
131 return zxic_system("/bin/umount -f -l /mnt/nvrofs2");
132}
133
134unsigned char *bin2hex(const unsigned char *old, const size_t oldlen)
135{
136 unsigned char *result = (unsigned char *)malloc(oldlen * 2 + 1);
137 size_t i, j;
138 int b = 0;
139
140 for (i = j = 0; i < oldlen; i++)
141 {
142 b = old[i] >> 4;
143 result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
144 b = old[i] & 0xf;
145 result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
146 }
147 result[j] = '\0';
148 return result;
149}
150
151int calc_file_hash(const char *file_in, unsigned char *hash_value)
152{
153 MD5_CTX ctx;
154 unsigned char *buf;
155 int offset;
156 int fd;
157 ssize_t len;
158
159 fd = open(file_in, O_RDONLY);
160 if (fd < 0)
161 return -1;
162 buf = malloc(4096);
163 if (buf == NULL)
xf.li9d1a0e12023-09-20 01:43:20 -0700164 {
165 close(fd);
xf.liaa4d92f2023-09-13 00:18:58 -0700166 return -1;
xf.li9d1a0e12023-09-20 01:43:20 -0700167 }
xf.liaa4d92f2023-09-13 00:18:58 -0700168 MD5_Init(&ctx);
169 do
170 {
171 len = full_read(fd, buf, 4096);
172 MD5_Update(&ctx, buf, len);
173 if (len < 4096)
174 break;
175 } while(1);
176
177 MD5_Final(hash_value, &ctx);
178 free(buf);
xf.li9d1a0e12023-09-20 01:43:20 -0700179 close(fd);
xf.liaa4d92f2023-09-13 00:18:58 -0700180 return 0;
181}
182
183int file_hash(const char *file_in, const char *file_hash)
184{
185 unsigned char hash_value[16] = {0};
186 unsigned char *hash_str;
187 int ret;
188 ssize_t ret_s;
189
190 ret = calc_file_hash(file_in, hash_value);
191 if (ret < 0)
192 return -1;
193 hash_str = bin2hex(hash_value, 16);
194 ret_s = open_write_close(file_hash, hash_str, 32);
195 free(hash_str);
196 if (ret_s != 32)
197 return -1;
198 return 0;
199}
200int file_hash_check(const char *file_in, const char *file_hash)
201{
202 unsigned char hash_value[16] = {0};
203 unsigned char *hash_str;
204 unsigned char hash_str2[33] = {0};
205 int ret;
206 ssize_t ret_s;
207
208 ret = calc_file_hash(file_in, hash_value);
209 if (ret < 0)
210 return -1;
211 hash_str = bin2hex(hash_value, 16);
212 memset(hash_str2, 0, sizeof(hash_str2));
213 ret_s = open_read_close(file_hash, hash_str2, 32);
214 if (ret_s != 32)
215 return -1;
216 if (strcmp(hash_str, hash_str2) == 0)
217 {
218 return 0;
219 }
220 return -1;
221}
222
223unsigned int cpnv_NvroBackup(void)
224{
225 char mtd_path[MAX_PATH] = {0};
226 int ret;
227
228 ret = mtd_find("nvrofs2", mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
229 if (ret < 0)
230 {
231 printf("[error]cpnv can not find nvrofs2\n");
232 return CPNV_ERROR;
233 }
234 ret = mtd_erase_partition("nvrofs2");
235 if (ret != 0)
236 {
237 printf("[error]cpnv erase nvrofs2\n");
238 return CPNV_ERROR;
239 }
xf.li9d1a0e12023-09-20 01:43:20 -0700240
xf.liaa4d92f2023-09-13 00:18:58 -0700241 ret = nvrofs2_mount(1);
242 if (ret != 0)
243 {
xf.li9d1a0e12023-09-20 01:43:20 -0700244 nvrofs2_umount();
245 ret = nvrofs2_mount(1);
246 if (ret != 0)
247 {
248 printf("[error]cpnv nvrofs2_mount\n");
249 return CPNV_ERROR;
250 }
xf.liaa4d92f2023-09-13 00:18:58 -0700251 }
252 ret = copyfile("/mnt/nvrofs/nvroall.bin", "/mnt/nvrofs2/nvroall.bin");
253 if (ret != 0)
254 {
255 printf("[error]cpnv nvrofs2 copyfile\n");
256 goto out_err;
257 }
258 ret = file_hash("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
259 if (ret != 0)
260 {
261 printf("[error]cpnv file_hash\n");
262 goto out_err;
263 }
264 ret = nvrofs2_umount();
265 if (ret < 0)
266 {
267 printf("[error]cpnv nvrofs2_umount\n");
268 return CPNV_ERROR;
269 }
270
271 ret = flags_set_nvroflag(NVRO_BACKED_UP);
272 if (ret != 0)
273 {
274 printf("[error]cpnv NVRO_BACKED_UP\n");
275 return CPNV_ERROR;
276 }
277 return CPNV_OK;
278
279out_err:
280 nvrofs2_umount();
281
282 return CPNV_ERROR;
283}
284
285unsigned int cpnv_NvroRestore(void)
286{
287 int ret;
288 unsigned int ret_u;
289 unsigned int nvro_flag;
290
291 nvro_flag = flags_get_nvroflag();
292 if (nvro_flag != NVRO_RESTORING)
293 {
294 printf("[error]cpnv_NvroRestore nvro flag error\n");
295 return CPNV_ERROR;
296 }
297 nvrofs2_umount();
298 ret = nvrofs2_mount(0);
299 if (ret != 0)
300 {
301 printf("[error]cpnv nvrofs2_mount\n");
302 return CPNV_ERROR;
303 }
304 ret = file_hash_check("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
305 if (ret != 0)
306 {
307 printf("[error]cpnv file_hash_check\n");
308 goto out_err;
309 }
310 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 1);
311 if (ret_u != CPNV_OK)
312 {
313 printf("[error]cpnv nvrofs Attr 1\n");
314 goto out_err;
315 }
316 ret = copyfile("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs/nvroall.bin");
317 if (ret != 0)
318 {
319 printf("[error]cpnv nvrofs2 restore copyfile\n");
320 goto out_err;
321 }
322 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 0);
323 if (ret_u != CPNV_OK)
324 {
325 printf("[error]cpnv nvrofs Attr 0\n");
326 goto out_err;
327 }
328 ret = nvrofs2_umount();
329 if (ret < 0)
330 {
331 printf("[error]cpnv nvrofs2_umount\n");
332 return CPNV_ERROR;
333 }
334 ret = flags_set_nvroflag(NVRO_BACKED_UP);
335 if (ret != 0)
336 {
337 printf("[error]cpnv_NvroRestore set NVRO_BACKED_UP\n");
338 return CPNV_ERROR;
339 }
340 return CPNV_OK;
341
342out_err:
343 nvrofs2_umount();
xf.li9d1a0e12023-09-20 01:43:20 -0700344 flags_set_nvroflag(NVRO_BACKED_UP);
xf.liaa4d92f2023-09-13 00:18:58 -0700345
346 return CPNV_ERROR;
347}