1 #define _GNU_SOURCE
2
3 #include <dirent.h>
4 #include <libgen.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12 #include <sys/mount.h>
13 #include <errno.h>
14 #include "mtdutils.h"
15 #include "rk29.h"
16
run(const char * filename,char * const argv[])17 int run(const char *filename, char *const argv[])
18 {
19 struct stat s;
20 int status;
21 pid_t pid;
22
23 if (stat(filename, &s) != 0) {
24 fprintf(stderr, "cannot find '%s'", filename);
25 return -1;
26 }
27
28 printf("executing '%s'\n", filename);
29
30 pid = fork();
31
32 if (pid == 0) {
33 setpgid(0, getpid());
34 /* execute */
35 execv(filename, argv);
36 fprintf(stderr, "can't run %s (%s)\n", filename, strerror(errno));
37 /* exit */
38 _exit(0);
39 }
40
41 if (pid < 0) {
42 fprintf(stderr, "failed to fork and start '%s'\n", filename);
43 return -1;
44 }
45
46 if (-1 == waitpid(pid, &status, WCONTINUED | WUNTRACED)) {
47 fprintf(stderr, "wait for child error\n");
48 return -1;
49 }
50
51 if (WIFEXITED(status)) {
52 printf("executed '%s' done\n", filename);
53 }
54
55 printf("executed '%s' return %d\n", filename, WEXITSTATUS(status));
56 return 0;
57 }
58
59 //int rk_make_ext4fs(const char *filename, s64 len)
60 //{
61 // const char *const mke2fs_argv[] = { "/sbin/mke2fs", "-t", "ext4", "-O", "^huge_file", "-m", "0", "-q", filename, NULL };
62 // printf("format '%s' to ext4 filesystem\n", filename);
63 // return run(mke2fs_argv[0], (char **) mke2fs_argv);
64 //}
65
rk_make_ext4fs(const char * filename,long long len,const char * mountpoint)66 int rk_make_ext4fs(const char *filename,long long len, const char *mountpoint)
67 {
68 int result;
69
70 const char *const mke2fs_argv[] = { "/usr/sbin/mke2fs", "-t", "ext4", "-b", "4096", "-O", "^huge_file", "-m", "0", "-q", "-F", filename, NULL };
71 const char *const e2fsck_argv[] = { "/usr/sbin/e2fsck", "-fy", filename, NULL };
72 printf("format '%s' to ext4 filesystem\n", filename);
73 result = run(mke2fs_argv[0], (char **) mke2fs_argv);
74 if(result) {
75 printf("format '%s' to ext4 error!\n", filename);
76 return result;
77 }
78
79 result = run(e2fsck_argv[0], (char **) e2fsck_argv);
80 if(result) {
81 printf("e2fsck check '%s' fail!\n", filename);
82 return result;
83 }
84
85 if(mountpoint != NULL) {
86 int result2 = mount(filename, mountpoint, "ext4",
87 MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
88 if(result2) {
89 printf("mount '%s' to %s fail!\n", filename, mountpoint);
90 }
91 }
92
93 return result;
94 }
95
rk_check_and_resizefs(const char * filename)96 int rk_check_and_resizefs(const char *filename) {
97 int result;
98
99 const char *const e2fsck_argv[] = { "/usr/sbin/e2fsck", "-fy", filename, NULL };
100 const char *const resizefs_argv[] = { "/usr/sbin/resize2fs", filename, NULL };
101
102 result = run(e2fsck_argv[0], (char **) e2fsck_argv);
103 if(result) {
104 printf("e2fsck check '%s' failed!\n", filename);
105 return result;
106 }
107
108 result = run(resizefs_argv[0], (char **) resizefs_argv);
109 if(result) {
110 printf("resizefs '%s' failed!\n", filename);
111 }
112
113 return result;
114 }
115
rk_check_and_resizefs_f2fs(const char * filename)116 int rk_check_and_resizefs_f2fs(const char *filename) {
117 int result;
118
119 const char *const e2fsck_argv[] = { "fsck_f2fs", filename, NULL };
120 const char *const resizefs_argv[] = { "resize.f2fs", filename, NULL };
121
122 result = run(e2fsck_argv[0], (char **) e2fsck_argv);
123 if(result) {
124 printf("fsck_f2fs check '%s' failed!\n", filename);
125 return result;
126 }
127
128 result = run(resizefs_argv[0], (char **) resizefs_argv);
129 if(result) {
130 printf("resize.f2fs '%s' failed!\n", filename);
131 }
132
133 return result;
134 }
135
136
rk_make_ext3fs(const char * filename)137 int rk_make_ext3fs(const char *filename)
138 {
139 int result;
140
141 const char *const mke2fs_argv[] = { "mke2fs", "-t", "ext3", "-b", "4096", "-O", "^huge_file", "-m", "0", "-q", filename, NULL };
142 const char *const e2fsck_argv[] = { "e2fsck", "-fy", filename, NULL };
143 printf("format '%s' to ext3 filesystem\n", filename);
144 result = run(mke2fs_argv[0], (char **) mke2fs_argv);
145 if(result) {
146 printf("format '%s' to ext3 fail!\n", filename);
147 return result;
148 }
149
150 result = run(e2fsck_argv[0], (char **) e2fsck_argv);
151 if(result) {
152 printf("e2fsck check '%s' fail!\n", filename);
153 }
154
155 return result;
156 }
157
rk_make_ext2fs(const char * filename)158 int rk_make_ext2fs(const char *filename)
159 {
160 int result;
161
162 const char *const mke2fs_argv[] = { "/sbin/mke2fs", "-t", "ext2", "-b", "4096", "-O", "^huge_file", "-m", "0", "-q", filename, NULL };
163 const char *const e2fsck_argv[] = { "/sbin/e2fsck", "-fy", filename, NULL };
164 printf("format '%s' to ext2 filesystem\n", filename);
165 result = run(mke2fs_argv[0], (char **) mke2fs_argv);
166 if(result) {
167 printf("format '%s' to ext2 fail!\n", filename);
168 return result;
169 }
170
171 result = run(e2fsck_argv[0], (char **) e2fsck_argv);
172 if(result) {
173 printf("e2fsck check '%s' fail!\n", filename);
174 }
175
176 return result;
177 }
178
make_vfat(const char * filename,const char * volumelabel)179 int make_vfat(const char *filename,const char* volumelabel)
180 {
181 printf("format '%s' to vfat filesystem\n", filename);
182 if(volumelabel == NULL){
183 const char *const mke2fs_argv[] = { "/sbin/mkdosfs", filename, NULL };
184 return run(mke2fs_argv[0], (char **) mke2fs_argv);
185 }else{
186 const char *const mke2fs_withLabel_argv[] = { "/sbin/mkdosfs", "-n", volumelabel, filename, NULL };
187 return run(mke2fs_withLabel_argv[0], (char **) mke2fs_withLabel_argv);
188 }
189 }
190
make_ntfs(const char * filename,const char * volumelabel)191 int make_ntfs(const char *filename,const char* volumelabel) {
192 printf("format '%s' to NTFS filesystem.\n", filename);
193
194 if(volumelabel == NULL){
195 const char *const mkntfs_argv[] = { "mkntfs", "-f", filename, NULL };
196 return run(mkntfs_argv[0], (char **) mkntfs_argv);
197 }else{
198 const char *const mkntfs_withLabel_argv[] = { "mkntfs", "-f", "-L", volumelabel, filename, NULL };
199 return run(mkntfs_withLabel_argv[0], (char **) mkntfs_withLabel_argv);
200 }
201 }
202
203 #ifndef min
204 #define min(a,b) ((a)<(b)?(a):(b))
205 #endif
206
rk29_fread(void * ptr,size_t size,size_t nmemb,FILE * stream)207 size_t rk29_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
208 {
209 char buf[READ_SIZE];
210 int fd;
211 long begin, end;
212 off_t offset;
213 ssize_t sz;
214 size_t count = 0, total;
215 char *p = ptr;
216
217 if (!ptr)
218 return 0;
219 if (!size || !nmemb)
220 return 0;
221 if (!stream)
222 return 0;
223 fd = fileno(stream);
224 if (fd < 0)
225 return 0;
226
227 begin = ftell(stream);
228 if (begin < 0)
229 begin = 0;
230
231 total = size * nmemb;
232 if (!total)
233 return 0;
234
235 end = begin + total;
236 offset = begin & ~READ_MASK;
237
238 if (begin & READ_MASK) {
239 sz = pread(fd, buf, READ_SIZE, offset);
240 if (sz < READ_SIZE)
241 goto out;
242 count = min(end, offset + READ_SIZE) - begin;
243 memcpy(p, buf + (begin & READ_MASK), count);
244 p += count;
245 offset += READ_SIZE;
246 }
247
248 for (; offset < (end & ~READ_MASK); offset += READ_SIZE) {
249 sz = pread(fd, buf, READ_SIZE, offset);
250 if (sz < READ_SIZE)
251 goto out;
252 count += READ_SIZE;
253 memcpy(p, buf, READ_SIZE);
254 p += READ_SIZE;
255 }
256
257 if (count < total && (end & READ_MASK)) {
258 offset = end & ~READ_MASK;
259 sz = pread(fd, buf, READ_SIZE, offset);
260 if (sz < READ_SIZE)
261 goto out;
262 memcpy(p, buf, end - offset);
263 count += end - offset;
264 }
265 out:
266 count /= size;
267 fseek(stream, begin + count * size, SEEK_SET);
268 return count;
269 }
270
rk29_fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream)271 size_t rk29_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
272 {
273 char buf[WRITE_SIZE];
274 int fd;
275 long begin, end;
276 off_t offset;
277 ssize_t sz;
278 size_t count = 0, total;
279 char *p = (char *)ptr;
280
281 if (!ptr)
282 return 0;
283 if (!size || !nmemb)
284 return 0;
285 if (!stream)
286 return 0;
287 fd = fileno(stream);
288 if (fd < 0)
289 return 0;
290
291 begin = ftell(stream);
292 if (begin < 0)
293 begin = 0;
294
295 total = size * nmemb;
296 if (!total)
297 return 0;
298
299 end = begin + total;
300 offset = begin & ~WRITE_MASK;
301
302 if (begin & WRITE_MASK) {
303 sz = pread(fd, buf, WRITE_SIZE, offset);
304 if (sz < WRITE_SIZE)
305 goto out;
306 count = min(end, offset + WRITE_SIZE) - begin;
307 memcpy(buf + (begin & WRITE_MASK), p, count);
308 sz = pwrite(fd, buf, WRITE_SIZE, offset);
309 if (sz < WRITE_SIZE)
310 goto out;
311 p += count;
312 offset += WRITE_SIZE;
313 }
314
315 for (; offset < (end & ~WRITE_MASK); offset += WRITE_SIZE) {
316 sz = pwrite(fd, p, WRITE_SIZE, offset);
317 if (sz < WRITE_SIZE)
318 goto out;
319 count += WRITE_SIZE;
320 p += WRITE_SIZE;
321 }
322
323 if (count < total && (end & WRITE_MASK)) {
324 offset = end & ~WRITE_MASK;
325 sz = pread(fd, buf, WRITE_SIZE, offset);
326 if (sz < WRITE_SIZE)
327 goto out;
328 memcpy(buf, p, end - offset);
329 sz = pwrite(fd, buf, WRITE_SIZE, offset);
330 if (sz < WRITE_SIZE)
331 goto out;
332 count += end - offset;
333 }
334 out:
335 count /= size;
336 fseek(stream, begin + count * size, SEEK_SET);
337 return count;
338 }
339
340