android13/bootable/recovery/mtdutils/rk29.c

320 lines
8.3 KiB
C

#define _GNU_SOURCE
#include <dirent.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <errno.h>
#include "mtdutils/mtdutils.h"
#include "mtdutils/rk29.h"
int run(const char *filename, char *const argv[])
{
struct stat s;
int status;
pid_t pid;
if (stat(filename, &s) != 0) {
fprintf(stderr, "cannot find '%s'", filename);
return -1;
}
printf("executing '%s'\n", filename);
pid = fork();
if (pid == 0) {
setpgid(0, getpid());
/* execute */
execv(filename, argv);
fprintf(stderr, "can't run %s (%s)\n", filename, strerror(errno));
/* exit */
_exit(0);
}
if (pid < 0) {
fprintf(stderr, "failed to fork and start '%s'\n", filename);
return -1;
}
if (-1 == waitpid(pid, &status, WCONTINUED | WUNTRACED)) {
fprintf(stderr, "wait for child error\n");
return -1;
}
if (WIFEXITED(status)) {
printf("executed '%s' done\n", filename);
}
printf("executed '%s' return %d\n", filename, WEXITSTATUS(status));
return 0;
}
//int rk_make_ext4fs(const char *filename, s64 len)
//{
// const char *const mke2fs_argv[] = { "/sbin/mke2fs", "-t", "ext4", "-O", "^huge_file", "-m", "0", "-q", filename, NULL };
// printf("format '%s' to ext4 filesystem\n", filename);
// return run(mke2fs_argv[0], (char **) mke2fs_argv);
//}
int rk_make_ext4fs(const char *filename,long long len, const char *mountpoint)
{
int result;
(void)len;
const char *const mke2fs_argv[] = { "/sbin/mke2fs", "-t", "ext4", "-b", "4096", "-O", "^huge_file", "-m", "0", "-q", filename, NULL };
const char *const e2fsck_argv[] = { "/sbin/e2fsck", "-fy", filename, NULL };
printf("format '%s' to ext4 filesystem\n", filename);
result = run(mke2fs_argv[0], (char **) mke2fs_argv);
if(result) {
printf("format '%s' to ext4 error!\n", filename);
return result;
}
result = run(e2fsck_argv[0], (char **) e2fsck_argv);
if(result) {
printf("e2fsck check '%s' fail!\n", filename);
return result;
}
if(mountpoint != NULL) {
int result2 = mount(filename, mountpoint, "ext4",
MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
if(result2) {
printf("mount '%s' to %s fail!\n", filename, mountpoint);
}
}
return result;
}
int rk_check_and_resizefs(const char *filename) {
int result;
const char *const e2fsck_argv[] = { "/sbin/e2fsck", "-fy", filename, NULL };
const char *const resizefs_argv[] = { "/sbin/resize2fs", filename, NULL };
result = run(e2fsck_argv[0], (char **) e2fsck_argv);
if(result) {
printf("e2fsck check '%s' failed!\n", filename);
return result;
}
result = run(resizefs_argv[0], (char **) resizefs_argv);
if(result) {
printf("resizefs '%s' failed!\n", filename);
}
return result;
}
int rk_check_and_resizefs_f2fs(const char *filename) {
int result;
const char *const e2fsck_argv[] = { "/system/bin/fsck.f2fs", filename, NULL };
const char *const resizefs_argv[] = { "/system/bin/resize.f2fs", filename, NULL };
printf("fsck_f2fs check '%s' 11111111111111!\n", filename);
result = run(e2fsck_argv[0], (char **) e2fsck_argv);
if(result) {
printf("fsck_f2fs check '%s' failed!\n", filename);
return result;
}
result = run(resizefs_argv[0], (char **) resizefs_argv);
if(result) {
printf("resize.f2fs '%s' failed!\n", filename);
}
return result;
}
int rk_make_ext3fs(const char *filename)
{
int result;
const char *const mke2fs_argv[] = { "/sbin/mke2fs", "-t", "ext3", "-b", "4096", "-O", "^huge_file", "-m", "0", "-q", filename, NULL };
const char *const e2fsck_argv[] = { "/sbin/e2fsck", "-fy", filename, NULL };
printf("format '%s' to ext3 filesystem\n", filename);
result = run(mke2fs_argv[0], (char **) mke2fs_argv);
if(result) {
printf("format '%s' to ext3 fail!\n", filename);
return result;
}
result = run(e2fsck_argv[0], (char **) e2fsck_argv);
if(result) {
printf("e2fsck check '%s' fail!\n", filename);
}
return result;
}
int make_vfat(const char *filename,const char* volumelabel)
{
printf("format '%s' to vfat filesystem\n", filename);
if(volumelabel == NULL){
const char *const mke2fs_argv[] = { "/sbin/mkdosfs", filename, NULL };
return run(mke2fs_argv[0], (char **) mke2fs_argv);
}else{
const char *const mke2fs_withLabel_argv[] = { "/sbin/mkdosfs", "-L", volumelabel, filename, NULL };
return run(mke2fs_withLabel_argv[0], (char **) mke2fs_withLabel_argv);
}
}
int make_ntfs(const char *filename,const char* volumelabel) {
printf("format '%s' to NTFS filesystem.\n", filename);
if(volumelabel == NULL){
const char *const mkntfs_argv[] = { "/system/bin/mkntfs", "-f", filename, NULL };
return run(mkntfs_argv[0], (char **) mkntfs_argv);
}else{
const char *const mkntfs_withLabel_argv[] = { "/system/bin/mkntfs", "-f", "-L", volumelabel, filename, NULL };
return run(mkntfs_withLabel_argv[0], (char **) mkntfs_withLabel_argv);
}
}
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif
size_t rk29_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
char buf[READ_SIZE];
int fd;
long begin, end;
off_t offset;
ssize_t sz;
size_t count = 0, total;
char *p = ptr;
if (!ptr)
return 0;
if (!size || !nmemb)
return 0;
if (!stream)
return 0;
fd = fileno(stream);
if (fd < 0)
return 0;
begin = ftell(stream);
if (begin < 0)
begin = 0;
total = size * nmemb;
if (!total)
return 0;
end = begin + total;
offset = begin & ~READ_MASK;
if (begin & READ_MASK) {
sz = pread(fd, buf, READ_SIZE, offset);
if (sz < READ_SIZE)
goto out;
count = min(end, offset + READ_SIZE) - begin;
memcpy(p, buf + (begin & READ_MASK), count);
p += count;
offset += READ_SIZE;
}
for (; offset < (end & ~READ_MASK); offset += READ_SIZE) {
sz = pread(fd, buf, READ_SIZE, offset);
if (sz < READ_SIZE)
goto out;
count += READ_SIZE;
memcpy(p, buf, READ_SIZE);
p += READ_SIZE;
}
if (count < total && (end & READ_MASK)) {
offset = end & ~READ_MASK;
sz = pread(fd, buf, READ_SIZE, offset);
if (sz < READ_SIZE)
goto out;
memcpy(p, buf, end - offset);
count += end - offset;
}
out:
count /= size;
fseek(stream, begin + count * size, SEEK_SET);
return count;
}
size_t rk29_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
char buf[WRITE_SIZE];
int fd;
long begin, end;
off_t offset;
ssize_t sz;
size_t count = 0, total;
char *p = (char *)ptr;
if (!ptr)
return 0;
if (!size || !nmemb)
return 0;
if (!stream)
return 0;
fd = fileno(stream);
if (fd < 0)
return 0;
begin = ftell(stream);
if (begin < 0)
begin = 0;
total = size * nmemb;
if (!total)
return 0;
end = begin + total;
offset = begin & ~WRITE_MASK;
if (begin & WRITE_MASK) {
sz = pread(fd, buf, WRITE_SIZE, offset);
if (sz < WRITE_SIZE)
goto out;
count = min(end, offset + WRITE_SIZE) - begin;
memcpy(buf + (begin & WRITE_MASK), p, count);
sz = pwrite(fd, buf, WRITE_SIZE, offset);
if (sz < WRITE_SIZE)
goto out;
p += count;
offset += WRITE_SIZE;
}
for (; offset < (end & ~WRITE_MASK); offset += WRITE_SIZE) {
sz = pwrite(fd, p, WRITE_SIZE, offset);
if (sz < WRITE_SIZE)
goto out;
count += WRITE_SIZE;
p += WRITE_SIZE;
}
if (count < total && (end & WRITE_MASK)) {
offset = end & ~WRITE_MASK;
sz = pread(fd, buf, WRITE_SIZE, offset);
if (sz < WRITE_SIZE)
goto out;
memcpy(buf, p, end - offset);
sz = pwrite(fd, buf, WRITE_SIZE, offset);
if (sz < WRITE_SIZE)
goto out;
count += end - offset;
}
out:
count /= size;
fseek(stream, begin + count * size, SEEK_SET);
return count;
}