blob: 0e5880c6e2ced4efe9e2cdd90df39ba4ec6b5364 [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)
164 return -1;
165 MD5_Init(&ctx);
166 do
167 {
168 len = full_read(fd, buf, 4096);
169 MD5_Update(&ctx, buf, len);
170 if (len < 4096)
171 break;
172 } while(1);
173
174 MD5_Final(hash_value, &ctx);
175 free(buf);
176 return 0;
177}
178
179int file_hash(const char *file_in, const char *file_hash)
180{
181 unsigned char hash_value[16] = {0};
182 unsigned char *hash_str;
183 int ret;
184 ssize_t ret_s;
185
186 ret = calc_file_hash(file_in, hash_value);
187 if (ret < 0)
188 return -1;
189 hash_str = bin2hex(hash_value, 16);
190 ret_s = open_write_close(file_hash, hash_str, 32);
191 free(hash_str);
192 if (ret_s != 32)
193 return -1;
194 return 0;
195}
196int file_hash_check(const char *file_in, const char *file_hash)
197{
198 unsigned char hash_value[16] = {0};
199 unsigned char *hash_str;
200 unsigned char hash_str2[33] = {0};
201 int ret;
202 ssize_t ret_s;
203
204 ret = calc_file_hash(file_in, hash_value);
205 if (ret < 0)
206 return -1;
207 hash_str = bin2hex(hash_value, 16);
208 memset(hash_str2, 0, sizeof(hash_str2));
209 ret_s = open_read_close(file_hash, hash_str2, 32);
210 if (ret_s != 32)
211 return -1;
212 if (strcmp(hash_str, hash_str2) == 0)
213 {
214 return 0;
215 }
216 return -1;
217}
218
219unsigned int cpnv_NvroBackup(void)
220{
221 char mtd_path[MAX_PATH] = {0};
222 int ret;
223
224 ret = mtd_find("nvrofs2", mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
225 if (ret < 0)
226 {
227 printf("[error]cpnv can not find nvrofs2\n");
228 return CPNV_ERROR;
229 }
230 ret = mtd_erase_partition("nvrofs2");
231 if (ret != 0)
232 {
233 printf("[error]cpnv erase nvrofs2\n");
234 return CPNV_ERROR;
235 }
236
237 nvrofs2_umount();
238 ret = nvrofs2_mount(1);
239 if (ret != 0)
240 {
241 printf("[error]cpnv nvrofs2_mount\n");
242 return CPNV_ERROR;
243 }
244 ret = copyfile("/mnt/nvrofs/nvroall.bin", "/mnt/nvrofs2/nvroall.bin");
245 if (ret != 0)
246 {
247 printf("[error]cpnv nvrofs2 copyfile\n");
248 goto out_err;
249 }
250 ret = file_hash("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
251 if (ret != 0)
252 {
253 printf("[error]cpnv file_hash\n");
254 goto out_err;
255 }
256 ret = nvrofs2_umount();
257 if (ret < 0)
258 {
259 printf("[error]cpnv nvrofs2_umount\n");
260 return CPNV_ERROR;
261 }
262
263 ret = flags_set_nvroflag(NVRO_BACKED_UP);
264 if (ret != 0)
265 {
266 printf("[error]cpnv NVRO_BACKED_UP\n");
267 return CPNV_ERROR;
268 }
269 return CPNV_OK;
270
271out_err:
272 nvrofs2_umount();
273
274 return CPNV_ERROR;
275}
276
277unsigned int cpnv_NvroRestore(void)
278{
279 int ret;
280 unsigned int ret_u;
281 unsigned int nvro_flag;
282
283 nvro_flag = flags_get_nvroflag();
284 if (nvro_flag != NVRO_RESTORING)
285 {
286 printf("[error]cpnv_NvroRestore nvro flag error\n");
287 return CPNV_ERROR;
288 }
289 nvrofs2_umount();
290 ret = nvrofs2_mount(0);
291 if (ret != 0)
292 {
293 printf("[error]cpnv nvrofs2_mount\n");
294 return CPNV_ERROR;
295 }
296 ret = file_hash_check("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
297 if (ret != 0)
298 {
299 printf("[error]cpnv file_hash_check\n");
300 goto out_err;
301 }
302 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 1);
303 if (ret_u != CPNV_OK)
304 {
305 printf("[error]cpnv nvrofs Attr 1\n");
306 goto out_err;
307 }
308 ret = copyfile("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs/nvroall.bin");
309 if (ret != 0)
310 {
311 printf("[error]cpnv nvrofs2 restore copyfile\n");
312 goto out_err;
313 }
314 ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 0);
315 if (ret_u != CPNV_OK)
316 {
317 printf("[error]cpnv nvrofs Attr 0\n");
318 goto out_err;
319 }
320 ret = nvrofs2_umount();
321 if (ret < 0)
322 {
323 printf("[error]cpnv nvrofs2_umount\n");
324 return CPNV_ERROR;
325 }
326 ret = flags_set_nvroflag(NVRO_BACKED_UP);
327 if (ret != 0)
328 {
329 printf("[error]cpnv_NvroRestore set NVRO_BACKED_UP\n");
330 return CPNV_ERROR;
331 }
332 return CPNV_OK;
333
334out_err:
335 nvrofs2_umount();
336
337 return CPNV_ERROR;
338}