diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0bc6c25..24f163c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,6 +8,7 @@ set(RURIMA_CORE_SOURCES
src/checkdep.c
src/dockerhub.c
src/exec.c
+ src/termux.c
src/info.c
src/lxcmirror.c
src/shared.c
@@ -32,6 +33,8 @@ set(RURIMA_CORE_SOURCES
src/ruri/src/rootless.c
src/ruri/src/mount.c
src/ruri/src/k2v.c
+ src/ruri/src/k2v3.c
+ src/ruri/src/watchdog.c
src/ruri/src/elf-magic.c
src/ruri/src/config.c
src/ruri/src/cgroup.c
diff --git a/Makefile b/Makefile
index f3c57fb..021a438 100644
--- a/Makefile
+++ b/Makefile
@@ -45,10 +45,10 @@ SRC = src/*.c src/easteregg/*.c
HEADER = src/include/*.h
# Checker.
CHECKER = clang-tidy
-CHECKER_FLAGS = --checks=*,-clang-analyzer-security.insecureAPI.strcpy,-altera-unroll-loops,-cert-err33-c,-concurrency-mt-unsafe,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-readability-function-cognitive-complexity,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-bugprone-easily-swappable-parameters,-cert-err34-c,-misc-include-cleaner,-readability-identifier-length,-bugprone-signal-handler,-cert-msc54-cpp,-cert-sig30-c,-altera-id-dependent-backward-branch,-bugprone-suspicious-realloc-usage,-hicpp-signed-bitwise,-clang-analyzer-security.insecureAPI.UncheckedReturn
+CHECKER_FLAGS = --checks=*,-altera-struct-pack-align,-google-readability-function-size,-hicpp-function-size,-readability-function-size,-clang-analyzer-security.insecureAPI.strcpy,-altera-unroll-loops,-cert-err33-c,-concurrency-mt-unsafe,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-readability-function-cognitive-complexity,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-bugprone-easily-swappable-parameters,-cert-err34-c,-misc-include-cleaner,-readability-identifier-length,-bugprone-signal-handler,-cert-msc54-cpp,-cert-sig30-c,-altera-id-dependent-backward-branch,-bugprone-suspicious-realloc-usage,-hicpp-signed-bitwise,-clang-analyzer-security.insecureAPI.UncheckedReturn
-include config.mk
# Target.
-objects = ssfx/ssfx.o easteregg/daijin.o catsh/src/catsh.o net.o checkdep.o dockerhub.o exec.o info.o lxcmirror.o shared.o signal.o archive.o subcommand.o main.o ruri/src/easteregg/action.o ruri/src/easteregg/nekofeng.o ruri/src/easteregg/layer.o ruri/src/easteregg/typewriter.o ruri/src/caplist.o ruri/src/chroot.o ruri/src/cprintf.o ruri/src/info.o ruri/src/rurienv.o ruri/src/rurifetch.o ruri/src/seccomp.o ruri/src/signal.o ruri/src/umount.o ruri/src/unshare.o ruri/src/rootless.o ruri/src/mount.o ruri/src/k2v.o ruri/src/elf-magic.o ruri/src/config.o ruri/src/cgroup.o ruri/src/passwd.o ruri/src/ps.o ruri/src/ruri.o
+objects = ssfx/ssfx.o easteregg/daijin.o catsh/src/catsh.o termux.o net.o checkdep.o dockerhub.o exec.o info.o lxcmirror.o shared.o signal.o archive.o subcommand.o main.o ruri/src/easteregg/action.o ruri/src/easteregg/nekofeng.o ruri/src/easteregg/layer.o ruri/src/easteregg/typewriter.o ruri/src/caplist.o ruri/src/chroot.o ruri/src/cprintf.o ruri/src/info.o ruri/src/rurienv.o ruri/src/rurifetch.o ruri/src/seccomp.o ruri/src/signal.o ruri/src/umount.o ruri/src/unshare.o ruri/src/rootless.o ruri/src/watchdog.o ruri/src/mount.o ruri/src/k2v.o ruri/src/k2v3.o ruri/src/elf-magic.o ruri/src/config.o ruri/src/cgroup.o ruri/src/passwd.o ruri/src/ps.o ruri/src/ruri.o
O = out
BIN_TARGET = rurima
.NOTPARALLEL:
diff --git a/README.md b/README.md
index 3408020..4c2cbe0 100644
--- a/README.md
+++ b/README.md
@@ -22,10 +22,13 @@
* This program has no Super Cow Powers.
```
This project does not follow OCI standard and can only be a `PARTIAL` replacement of docker, this project is still under development.
-For Android users, You might need to root your phone before using rurima, some container might not work properly with proot.
-# Presets:
-We are working on some presets for using rurima to build your own projects, you can find them in the [presets](presets) directory.
-The first preset is for running debian vm with avf on MTK devices, and we will add more presets in the future, PRs are welcome!
+For Android users, You might need to root your phone before using rurima, some container might not work properly with proot.
+# About:
+So, what is rurima?
+The enhanced version of ruri.
+[ruri](https://github.com/Moe-hacker/ruri) only focus on running container, but rurima can also provide the function of getting rootfs image and backup/restore.
+And it will be a more powerful container manager in the fulture.
+With the `docker` and `lxc` subcommand of rurima, you can search & get & unpack images from dockerhub or LXC mirror easily.
# Features:
- Get rootfs images from dockerhub or LXC mirror.
- Automatic parse docker image config and convert to ruri cmdline.
@@ -35,32 +38,104 @@ The first preset is for running debian vm with avf on MTK devices, and we will a
- Static binary for multiple architectures.
- Built-in OTA(upgrade) feature.
-In a word, rurima is a lightweight container implementation, it tries to get the most features of docker with the least dependencies, even when your kernel does not support cgroups or namespaces.
+In a word, rurima is a lightweight container implementation, it tries to get the most features of docker with the least dependencies, even when your kernel does not support cgroups or namespaces.
+# Demo:
+
+
+Click to expand
+
+```text
+~ $ sudo rurima pull openlistteam/openlist ./openlist
+Pulling 20158f18ba671f0b as layer-0
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-0
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling ec81343d31bcd4b6 as layer-1
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-1
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling 889dce16043c6e0b as layer-2
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-2
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling 26e754cd7c62b57e as layer-3
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-3
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling 4f4fb700ef54461c as layer-4
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-4
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling bd69fdf7a20439e0 as layer-5
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-5
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling ec5dfd7cdbbd5a97 as layer-6
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-6
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling 53c5100b64211b73 as layer-7
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-7
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Pulling 4f4fb700ef54461c as layer-8
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+Extracting layer-8
+[///////////////////////////////////////////////////////////////////////////////] 100.00%
+
+Config:
+ Workdir:
+ /opt/openlist/
+ Env:
+ PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+ UMASK = 022
+ RUN_ARIA2 = false
+ Command:
+ /entrypoint.sh
+ Entrypoint:
+ NULL
+Run with ruri:
+
+rurima r -w -W /opt/openlist/ -e "PATH" "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -e "UMASK" "022" -e "RUN_ARIA2" "false" /data/data/com.termux/files/home/openlist /entrypoint.sh
+~ $ sudo rurima r -w -W /opt/openlist/ -e "PATH" "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -e "UMASK" "022" -e "RUN_ARIA2" "false" /data/data/com.termux/files/home/openlist /entrypoint.sh
+INFO[2026-05-28 15:08:49] reading config file: /opt/openlist/data/config.json
+INFO[2026-05-28 15:08:49] config file not exists, creating default config file
+INFO[2026-05-28 15:08:49] load config from env with prefix:
+INFO[2026-05-28 15:08:49] total memory: 15371MB, available: 4204MB
+INFO[2026-05-28 15:08:49] min free memory: 1024MB
+INFO[2026-05-28 15:08:49] max block limit: 64MB
+INFO[2026-05-28 15:08:49] auto memory limit: 4MB
+INFO[2026-05-28 15:08:49] init logrus...
+Successfully created the admin user and the initial password is: LfHyicxp
+start HTTP server @ 0.0.0.0:5244
+```
+
+
+
+- Sudo is required on Android phones.
+- Enable `--privileged` option for ruri (`sudo rurima r --privileged [other options]`) might fix some compatibility issues, but it is not recommended for security reasons.
+
+# What's new:
+- We have a unified `pull` command to get images from dockerhub or LXC mirror now.
+- Some other OCI compatible registry like ghcr.io could work with `-f/--fallback` option enabled now.
+- We will automatically force enable fallback mode for ghcr.io now.
# Terms of Use:
See [TERMS_OF_USE.md](TERMS_OF_USE.md)
# Full usage doc:
For a full usage documentation,
See [USAGE.md](doc/USAGE.md).
# FAQ:
-See [FAQ.md](doc/FAQ.md).
+See [FAQ.md](doc/FAQ.md).
+# Backward compatibility:
+We promise that rurima has backward compatibility of documented parts since v0.9.x, all unstable parts will be explicitly marked as WIP or unstable, and ruri has already been backward compatible. Users can always keep `rurima ota` to get the latest build.
# Send us your feedback!
Your use case, your suggestions, anyway, we would love to hear from you!
[Discussions](https://github.com/RuriOSS/rurima/discussions/16)
And, don't forget to `rurima ota` to get the latest build!
-# What's new:
-- We have a unified `pull` command to get images from dockerhub or LXC mirror now.
-- Some other OCI compatible registry like ghcr.io could work with `-f/--fallback` option enabled now.
-- We will automatically force enable fallback mode for ghcr.io now.
-# Backward compatibility:
-We promise that rurima has backward compatibility of documented parts since v0.9.x, all unstable parts will be explicitly marked as WIP or unstable, and ruri has already been backward compatible. Users can always keep `rurima ota` to get the latest build.
-For any issue, please notify us, and we will fix it ASAP.
-# About:
-So, what is rurima?
-The enhanced version of ruri.
-[ruri](https://github.com/Moe-hacker/ruri) only focus on running container, but rurima can also provide the function of getting rootfs image and backup/restore.
-And it will be a more powerful container manager in the fulture.
-With the `docker` and `lxc` subcommand of rurima, you can search & get & unpack images from dockerhub or LXC mirror easily.
+# Presets:
+We are working on some presets for using rurima to build your own projects, you can find them in the [presets](presets) directory.
+The first preset is for running debian vm with avf on MTK devices, and we will add more presets in the future, PRs are welcome!
# Download:
You can get rurima binary (staticly linked) for arm64, armv7, armhf, riscv64, i386, loong64, s390x, ppc64le and x86_64 from the release page.
Or run the follwing command to get rurima to ./rurima and ./rurima-dbg(debug version):
@@ -84,11 +159,6 @@ For Alpine based system, run:
```
apk add wget curl jq coreutils file proot tar xz gzip
```
-# About suid or caps:
-Rurima does not allow to set any suid/sgid (with root) or capability on it, it will check it in main() and error() if detected these unsafe settings.
-So, please always use sudo instead.
-# Reporting bugs:
-Please use the debug version(rurima-dbg) in release to get debug logs, and please tell me the command you run to cause the unexpected behavior you think!
# Dependent:
rurima needs tar, xz, gzip, file, you can find these static binary for aarch64, armv7, x86_64, i386 or riscv64 in:
[tar-static](https://github.com/Moe-sushi/tar-static)
@@ -112,6 +182,11 @@ So that you download:
https://mirrors.tuna.tsinghua.edu.cn/alpine/edge/testing/aarch64/proot-static-5.4.0-r1.apk
```
and finally, tar -xvf *.apk to unpack it. So you got proot.static, rename it to proot and put it in your $PATH.
+# About suid or caps:
+Rurima does not allow to set any suid/sgid (with root) or capability on it, it will check it in main() and error() if detected these unsafe settings.
+So, please always use sudo instead.
+# Reporting bugs:
+Please use the debug version(rurima-dbg) in release to get debug logs, and please tell me the command you run to cause the unexpected behavior you think!
# TODO:
Manage ruri containers and configs.
diff --git a/build.c b/build.c
index a9db330..566e471 100644
--- a/build.c
+++ b/build.c
@@ -57,8 +57,8 @@
#if __STDC_VERSION__ < 202000L
#ifndef bool
#define bool _Bool
-#define true ((_Bool) + 1u)
-#define false ((_Bool) + 0u)
+#define true ((_Bool)1u)
+#define false ((_Bool)0u)
#endif
#endif
#define ERROR_NUM 114
@@ -837,6 +837,7 @@ int main(int argc, char **argv)
check_and_add_lib("-lpthread", false);
build();
remove_test_dot_c();
+ printf("\n\nThis program has Super Neko Powers! >w<\n");
return 0;
}
diff --git a/doc/USAGE.md b/doc/USAGE.md
index 4f2230c..6522f02 100644
--- a/doc/USAGE.md
+++ b/doc/USAGE.md
@@ -1,5 +1,8 @@
# Undocumented part:
The `load`, `run`, `sfx` and `netns` subcommand is WIP, it should not be used by users.
+# $PATH injection:
+rurima will automatically add /path/to/rurima/ to the top of $PATH.
+So you can just put required binaries like `tar/curl/jq/file` under the same dir of rurima, or do some wrapper script hacking.
# Image source:
rurima currently supports both lxc-mirror and dockerhub as container image source.
# Unified image puller:
diff --git a/src/archive.c b/src/archive.c
index 1fb8c86..785f191 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -57,13 +57,13 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
* If we are not running with root, and proot exist,
* we will use proot to extract the archive.
*/
- char **ret = malloc(sizeof(char *) * 14);
+ char **ret = (char **)malloc(sizeof(char *) * 14);
ret[0] = NULL;
char *file_command[] = { "file", "--brief", "--mime-type", file, NULL };
char *type = rurima_fork_execvp_get_stdout(file_command);
if (type == NULL) {
rurima_error("{red}Failed to get file type!\n");
- free(ret);
+ free((void *)ret);
return NULL;
}
type[strlen(type) - 1] = '\0';
@@ -77,7 +77,7 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpzf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else if (strcmp(type, "application/x-xz") == 0) {
rurima_add_argv(&ret, "proot");
rurima_add_argv(&ret, "-0");
@@ -86,7 +86,7 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpJf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else if (strcmp(type, "application/x-tar") == 0) {
rurima_add_argv(&ret, "proot");
rurima_add_argv(&ret, "-0");
@@ -95,10 +95,10 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else {
free(type);
- free(ret);
+ free((void *)ret);
return NULL;
}
} else {
@@ -109,7 +109,7 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpzf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else if (strcmp(type, "application/x-xz") == 0) {
rurima_add_argv(&ret, "proot");
rurima_add_argv(&ret, "-0");
@@ -117,7 +117,7 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpJf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else if (strcmp(type, "application/x-tar") == 0) {
rurima_add_argv(&ret, "proot");
rurima_add_argv(&ret, "-0");
@@ -125,10 +125,10 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else {
free(type);
- free(ret);
+ free((void *)ret);
return NULL;
}
}
@@ -138,22 +138,22 @@ static char **get_extract_command(char *_Nonnull file, char *_Nonnull dir)
rurima_add_argv(&ret, "-xpzf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else if (strcmp(type, "application/x-xz") == 0) {
rurima_add_argv(&ret, "tar");
rurima_add_argv(&ret, "-xpJf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else if (strcmp(type, "application/x-tar") == 0) {
rurima_add_argv(&ret, "tar");
rurima_add_argv(&ret, "-xpf");
rurima_add_argv(&ret, "-");
rurima_add_argv(&ret, "-C");
- rurima_add_argv(&ret, (char *)dir);
+ rurima_add_argv(&ret, dir);
} else {
free(type);
- free(ret);
+ free((void *)ret);
return NULL;
}
}
@@ -192,7 +192,7 @@ static void show_progress(double per)
fflush(stdout);
printf("\033[?25h");
}
-static void show_progress_with_line(float per, int line)
+static void show_progress_with_line(float per, int __attribute__((unused)) line)
{
/*
* Show progress bar.
@@ -208,7 +208,7 @@ static void show_progress_with_line(float per, int line)
struct winsize size;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
unsigned short width = size.ws_col - 10;
- unsigned short pos = (unsigned short)(width * per);
+ unsigned short pos = width * (unsigned short)per;
printf("\033[?25l");
printf("\r[\033[32m");
for (unsigned short i = 0; i < pos; i++) {
@@ -244,13 +244,13 @@ int rurima_extract_archive(char *_Nonnull file, char *_Nonnull dir)
rurima_error("{red}Unsupported file type!\n");
}
if (rurima_mkdirs(dir, 0755) == -1) {
- free(command);
+ free((void *)command);
rurima_error("{red}Failed to create directory!\n");
}
cprintf("{base}Extracting {cyan}%s\n", file);
- int fd = open(file, O_RDONLY);
+ int fd = open(file, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
- free(command);
+ free((void *)command);
rurima_error("{red}Failed to open file!\n");
}
struct cth_result *result = cth_exec_with_file_input(command, fd, true, true, show_progress_with_line, 0);
@@ -261,7 +261,7 @@ int rurima_extract_archive(char *_Nonnull file, char *_Nonnull dir)
rurima_warning("{yellow}stdout: %s\n", result->stdout_ret);
}
cth_free_result(&result);
- free(command);
+ free((void *)command);
return 0;
}
static int tar_backup__(const char *_Nonnull file, const char *_Nonnull dir)
@@ -274,10 +274,15 @@ static int tar_backup__(const char *_Nonnull file, const char *_Nonnull dir)
close(open(file, O_CLOEXEC | O_CREAT, 0755));
char *file_realpath = realpath(file, NULL);
char *dir_realpath = realpath(dir, NULL);
- int nullfd = open("/dev/null", O_RDWR);
- dup2(nullfd, STDOUT_FILENO);
- dup2(nullfd, STDERR_FILENO);
+ int nullfd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ if (nullfd >= 0) {
+ dup2(nullfd, STDOUT_FILENO);
+ dup2(nullfd, STDERR_FILENO);
+ }
int ret = 0;
+ if (!file_realpath || !dir_realpath) {
+ rurima_error("{red}Failed to get real path!\n");
+ }
if (strstr(file_realpath, dir_realpath) != NULL) {
chdir(dir);
char exclude[PATH_MAX + 12] = { '\0' };
@@ -329,15 +334,21 @@ int rurima_backup_dir(char *_Nonnull file, char *_Nonnull dir)
rurima_fork_rexec(rexec_args);
if (!du_found()) {
rurima_warning("{yellow}du not found, progress will not be shown.\n");
+ pid_t pid = fork();
+ if (pid > 0) {
+ int status = 0;
+ waitpid(pid, &status, 0);
+ return WEXITSTATUS(status);
+ }
int exstat = tar_backup__(file, dir);
- return exstat;
+ exit(exstat);
}
cprintf("{base}Getting total size to backup\n");
off_t totalsize = rurima_get_dir_file_size(dir);
cprintf("{base}Backing up to {cyan}%s\n", file);
pid_t pid = fork();
if (pid > 0) {
- int status;
+ int status = 0;
waitpid(pid, &status, WNOHANG);
off_t totalsize_bk = totalsize;
while (waitpid(pid, &status, WNOHANG) == 0) {
@@ -351,11 +362,11 @@ int rurima_backup_dir(char *_Nonnull file, char *_Nonnull dir)
usleep(100);
}
show_progress(1.0);
- return status;
- } else {
- int exstat = tar_backup__(file, dir);
- exit(exstat);
+ return WEXITSTATUS(status);
}
+ int exstat = tar_backup__(file, dir);
+ exit(exstat);
+
return 0;
}
static int download_file__(char *_Nonnull url, char *_Nonnull file, char *_Nullable token)
@@ -426,7 +437,7 @@ int rurima_download_file(char *_Nonnull url, char *_Nonnull file, char *_Nullabl
}
pid_t pid = fork();
if (pid > 0) {
- int status;
+ int status = 0;
waitpid(pid, &status, WNOHANG);
off_t size_bk = size;
while (waitpid(pid, &status, WNOHANG) == 0) {
@@ -442,10 +453,9 @@ int rurima_download_file(char *_Nonnull url, char *_Nonnull file, char *_Nullabl
show_progress(1.0);
rurima_log("{green}Download complete.\n");
return status;
- } else {
- int exstat = download_file__(url, file, token);
- rurima_log("{green}Download complete.\n");
- exit(exstat);
}
+ int exstat = download_file__(url, file, token);
+ rurima_log("{green}Download complete.\n");
+ exit(exstat);
return 0;
}
\ No newline at end of file
diff --git a/src/dockerhub.c b/src/dockerhub.c
index c4d7df2..1dbe329 100644
--- a/src/dockerhub.c
+++ b/src/dockerhub.c
@@ -60,7 +60,7 @@ static void print_export_env(struct RURIMA_DOCKER *_Nonnull config)
printf("export %s=\"%s\"\n", config->env[i], config->env[i + 1]);
}
}
-static void print_chroot_command(struct RURIMA_DOCKER *_Nonnull config, char *_Nullable savedir)
+static void print_chroot_command(struct RURIMA_DOCKER *_Nonnull config, const char *_Nullable savedir)
{
/*
* Print command to use chroot as runtime.
@@ -89,7 +89,7 @@ static void print_chroot_command(struct RURIMA_DOCKER *_Nonnull config, char *_N
}
printf("\n");
}
-static void print_proot_command(struct RURIMA_DOCKER *_Nonnull config, char *_Nullable savedir)
+static void print_proot_command(struct RURIMA_DOCKER *_Nonnull config, const char *_Nullable savedir)
{
/*
* Print command to use proot as runtime.
@@ -116,7 +116,7 @@ static void print_proot_command(struct RURIMA_DOCKER *_Nonnull config, char *_Nu
}
printf("\n");
}
-static void print_ruri_command(struct RURIMA_DOCKER *_Nonnull config, char *_Nullable savedir)
+static void print_ruri_command(struct RURIMA_DOCKER *_Nonnull config, const char *_Nullable savedir)
{
/*
* Print command to use ruri as runtime.
@@ -150,7 +150,7 @@ static void print_ruri_command(struct RURIMA_DOCKER *_Nonnull config, char *_Nul
}
printf("\n");
}
-void rurima_show_docker_config(struct RURIMA_DOCKER *_Nonnull config, char *_Nullable savedir, char *_Nullable runtime, bool quiet)
+void rurima_show_docker_config(struct RURIMA_DOCKER *_Nonnull config, const char *_Nullable savedir, char *_Nullable runtime, bool quiet)
{
/*
* Show docker config.
@@ -411,9 +411,8 @@ static char *get_token(char *_Nonnull image, char *_Nullable mirror, bool fallba
rurima_log("{red}Can not get token, using homo magic token 1145141919810\n");
// We hope the server administrator is homo.
return strdup("1145141919810");
- } else {
- rurima_error("{red}Failed to get token!");
}
+ rurima_error("{red}Failed to get token!");
}
free(token_json);
rurima_log("{base}Token: {cyan}%s{clear}\n", ret);
@@ -532,14 +531,14 @@ static struct BLOBS *get_blobs(const char *_Nonnull image, const char *_Nonnull
if (layers_orig == NULL) {
rurima_error("{red}Failed to get digest!\n");
}
- size_t len = rurima_split_lines(layers_orig, &ret->blobs);
+ rurima_split_lines(layers_orig, &ret->blobs);
char **size_char = NULL;
char *jq_cmd_2[] = { "jq", "-r", ".[] | .size", NULL };
char *layers_size = rurima_call_jq(jq_cmd_2, layers);
if (layers_size == NULL) {
rurima_error("{red}Failed to get layers size!\n");
}
- len = rurima_split_lines(layers_size, &size_char);
+ size_t len = rurima_split_lines(layers_size, &size_char);
ret->size = malloc(sizeof(size_t) * (len + 1));
for (size_t i = 0; i < len; i++) {
ret->size[i] = (size_t)strtoull(size_char[i], NULL, 10);
@@ -547,9 +546,9 @@ static struct BLOBS *get_blobs(const char *_Nonnull image, const char *_Nonnull
for (size_t i = 0; i < len; i++) {
free(size_char[i]);
}
- free(size_char);
- free(layers_size);
- free(layers_orig);
+ free((void *)size_char);
+ free((void *)layers_size);
+ free((void *)layers_orig);
if (len == 0) {
rurima_error("{red}Failed to get layers!\n");
}
@@ -842,7 +841,7 @@ static struct RURIMA_DOCKER *get_image_config(const char *_Nonnull image, const
rurima_log("{base}Env[%d]: {cyan}%s{clear}\n", i, env[i]);
free(env[i]);
}
- ret->env[len * 2] = NULL;
+ ret->env[(ptrdiff_t)(len * 2)] = NULL;
free(tmp);
free(env_from_json);
} else {
@@ -1014,9 +1013,9 @@ struct RURIMA_DOCKER *rurima_docker_pull(struct RURIMA_DOCKER_PULL *_Nonnull act
for (size_t i = 0; blobs->blobs[i] != NULL; i++) {
free(blobs->blobs[i]);
}
- free(blobs->blobs);
- free(blobs);
- free(config);
+ free((void *)blobs->blobs);
+ free((void *)blobs);
+ free((void *)config);
end_loading_animation();
return ret;
}
@@ -1117,9 +1116,9 @@ static char *docker_search__(char *_Nonnull url)
free(is_offical[i]);
}
free(results);
- free(name);
- free(description);
- free(is_offical);
+ free((void *)name);
+ free((void *)description);
+ free((void *)is_offical);
return next_url;
}
int rurima_docker_search(const char *_Nonnull image, const char *_Nonnull page_size, bool quiet, const char *_Nullable mirror)
@@ -1285,7 +1284,7 @@ static void docker_add_archlist__(char *_Nonnull arch, char ***_Nullable archlis
return;
}
if (*archlist == NULL) {
- *archlist = malloc(sizeof(char *) * 3);
+ *archlist = (char **)malloc(sizeof(char *) * 3);
(*archlist)[0] = strdup(arch);
(*archlist)[1] = NULL;
return;
@@ -1296,6 +1295,8 @@ static void docker_add_archlist__(char *_Nonnull arch, char ***_Nullable archlis
}
}
size_t j = 0;
+ // NOLINTBEGIN
+ // TODO: WTH THE WARNING?
for (; (*archlist)[j] != NULL; j++)
;
*archlist = realloc(*archlist, sizeof(char *) * (j + 3));
@@ -1306,6 +1307,7 @@ static void docker_add_archlist__(char *_Nonnull arch, char ***_Nullable archlis
break;
}
}
+ // NOLINTEND
}
static void docker_print_arch(const char *_Nonnull image, char *const *_Nonnull arch, size_t len)
{
@@ -1332,7 +1334,7 @@ static void docker_print_arch(const char *_Nonnull image, char *const *_Nonnull
for (int i = 0; archlist[i] != NULL; i++) {
free(archlist[i]);
}
- free(archlist);
+ free((void *)archlist);
}
int rurima_docker_search_arch(char *_Nonnull image, char *_Nonnull tag, char *_Nullable mirror, bool fallback)
{
@@ -1371,7 +1373,7 @@ int rurima_docker_search_arch(char *_Nonnull image, char *_Nonnull tag, char *_N
for (size_t i = 0; i < len; i++) {
free(arch[i]);
}
- free(arch);
+ free((void *)arch);
free(tmp);
return 0;
}
@@ -1382,7 +1384,7 @@ void rurima_docker_print_config_from_json(const char *_Nonnull config, const cha
* We just print the config from json string.
*/
struct RURIMA_DOCKER *ret = malloc(sizeof(struct RURIMA_DOCKER));
- char *response = config;
+ const char *response = config;
{
char *jq_command_0[] = { "jq", "-r", "-j", ".architecture", NULL };
char *architecture = rurima_call_jq(jq_command_0, response);
@@ -1404,6 +1406,8 @@ void rurima_docker_print_config_from_json(const char *_Nonnull config, const cha
}
}
{
+ // NOLINTBEGIN
+ // TODO: WTH THE WARNING?
char *jq_command_2[] = { "jq", "-r", "-j", "-c", ".config.Env", NULL };
char *env_from_json = rurima_call_jq(jq_command_2, response);
rurima_log("{base}Env: {cyan}%s{clear}\n", env_from_json == NULL ? "NULL" : env_from_json);
@@ -1424,6 +1428,7 @@ void rurima_docker_print_config_from_json(const char *_Nonnull config, const cha
} else {
ret->env[0] = NULL;
}
+ // NOLINTEND
}
{
char *jq_command_3[] = { "jq", "-r", "-j", "-c", ".config.Entrypoint", NULL };
@@ -1463,5 +1468,4 @@ void rurima_docker_print_config_from_json(const char *_Nonnull config, const cha
}
rurima_show_docker_config(ret, savedir, "ruri", false);
rurima_free_docker_config(ret);
- return;
}
\ No newline at end of file
diff --git a/src/easteregg/daijin.c b/src/easteregg/daijin.c
index 049ed53..be90d5d 100644
--- a/src/easteregg/daijin.c
+++ b/src/easteregg/daijin.c
@@ -28,7 +28,8 @@
*
*/
#include "daijin.h"
-// NOLINTNEXTLINE
+// NOLINTBEGIN
+// Never care this file bro.
static short x_win, y_win;
static size_t strlen_char32_rma(const char32_t *_Nonnull str)
{
@@ -140,4 +141,5 @@ void rurima_QwQ(void)
printf("\033[H\033[2J");
printf("\033[?1049l");
printf("\033[?25h");
-}
\ No newline at end of file
+}
+// NOLINTEND
\ No newline at end of file
diff --git a/src/exec.c b/src/exec.c
index d7a5f66..933928c 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -78,7 +78,7 @@ char *rurima_fork_execvp_get_stdout(char *_Nonnull argv[])
cth_free_result(&result);
return NULL;
}
-void rurima_add_argv(char ***_Nonnull argv, char *_Nonnull arg)
+void rurima_add_argv(char ***_Nonnull argv, const char *_Nonnull arg)
{
/*
* Add an argument to the argv array.
@@ -88,7 +88,8 @@ void rurima_add_argv(char ***_Nonnull argv, char *_Nonnull arg)
while ((*argv)[argc] != NULL) {
argc++;
}
- (*argv)[argc] = arg;
+ // TODO: when to free()?
+ (*argv)[argc] = strdup(arg);
(*argv)[argc + 1] = NULL;
}
int rurima_fork_rexec(char **_Nonnull argv)
@@ -98,7 +99,7 @@ int rurima_fork_rexec(char **_Nonnull argv)
*/
return cth_fork_rexec_self(argv);
}
-char *rurima_fork_execvp_get_stdout_with_input(char *_Nonnull argv[], char *_Nonnull input)
+char *rurima_fork_execvp_get_stdout_with_input(char *_Nonnull argv[], const char *_Nonnull input)
{
/*
* Warning: free() after use.
@@ -107,7 +108,7 @@ char *rurima_fork_execvp_get_stdout_with_input(char *_Nonnull argv[], char *_Non
* Return the stdout of the child process.
* If failed, return NULL.
*/
- struct cth_result *result = cth_exec(argv, input, true, true);
+ struct cth_result *result = cth_exec(argv, (char *)input, true, true);
rurima_log("{base}Exec {green}%s{base} result: {purple}\n%s\n", argv[0], result->stdout_ret);
rurima_log("{base}Exit code: {green}%d{base}\n", result->exit_code);
if (result->exit_code == 0) {
@@ -118,7 +119,7 @@ char *rurima_fork_execvp_get_stdout_with_input(char *_Nonnull argv[], char *_Non
cth_free_result(&result);
return NULL;
}
-char *rurima_call_jq(char *_Nonnull argv[], char *_Nonnull input)
+char *rurima_call_jq(char *_Nonnull argv[], const char *_Nonnull input)
{
/*
* Call jq with input.
diff --git a/src/include/rurima.h b/src/include/rurima.h
index 04df23e..6faba7e 100644
--- a/src/include/rurima.h
+++ b/src/include/rurima.h
@@ -49,6 +49,7 @@
#include
#include
#include
+#include
// This program need be linked with -lcap.
#include
// Bool!!!
@@ -108,9 +109,9 @@ struct RURIMA_DOCKER {
cfprintf(stderr, format, ##__VA_ARGS__); \
cfprintf(stderr, "{base}%s{clear}\n", " .^. .^."); \
cfprintf(stderr, "{base}%s{clear}\n", " /⋀\\_ノ_/⋀\\"); \
- cfprintf(stderr, "{base}%s{clear}\n", " /ノソノ\\ノソ丶)|"); \
+ cfprintf(stderr, "{base}%s{clear}\n", " /ノソノ\\ノソ丶メ"); \
cfprintf(stderr, "{base}%s{clear}\n", " ルリリ > x )リ"); \
- cfprintf(stderr, "{base}%s{clear}\n", "ノノ㇏ ^ ノ|ノ"); \
+ cfprintf(stderr, "{base}%s{clear}\n", "ノノ㇏ ^ ノノ"); \
cfprintf(stderr, "{base}%s{clear}\n", " ⠁⠁"); \
cfprintf(stderr, "{base}%s{clear}\n", "RURIMA ERROR MESSAGE"); \
cfprintf(stderr, "{base}%s{clear}\n", "Hint:"); \
@@ -169,7 +170,7 @@ void rurima_unpack(int argc, char **_Nonnull argv);
void rurima_get_input(char *_Nonnull message, char *_Nonnull buf);
void rurima_check_dep(void);
struct RURIMA_DOCKER *rurima_get_docker_config(char *_Nonnull image, char *_Nonnull tag, char *_Nullable architecture, char *_Nullable mirror, bool fallback);
-void rurima_show_docker_config(struct RURIMA_DOCKER *_Nonnull config, char *_Nullable savedir, char *_Nullable runtime, bool quiet);
+void rurima_show_docker_config(struct RURIMA_DOCKER *_Nonnull config, const char *_Nullable savedir, char *_Nullable runtime, bool quiet);
void rurima_free_docker_config(struct RURIMA_DOCKER *_Nonnull config);
void rurima_lxc_search_arch(const char *_Nullable mirror, const char *_Nonnull os);
int rurima_docker_search_arch(char *_Nonnull image, char *_Nonnull tag, char *_Nullable mirror, bool fallback);
@@ -178,7 +179,7 @@ void rurima_show_version_code(void);
void rurima_check_dir_deny_list(const char *_Nonnull dir);
char *rurima_strstr_ignore_case(const char *_Nonnull haystack, const char *_Nonnull needle);
int rurima_fork_rexec(char **_Nonnull argv);
-void rurima_add_argv(char ***_Nonnull argv, char *_Nonnull arg);
+void rurima_add_argv(char ***_Nonnull argv, const char *_Nonnull arg);
bool rurima_rootless_supported(void);
off_t rurima_get_dir_file_size(char *_Nonnull target);
int rurima_backup_dir(char *_Nonnull file, char *_Nonnull dir);
@@ -190,8 +191,8 @@ bool rurima_lxc_have_image(const char *_Nullable mirror, const char *_Nonnull os
int rurima_download_file(char *_Nonnull url, char *_Nonnull file, char *_Nullable token, ssize_t size);
bool proot_exist(void);
bool rurima_jq_exists(void);
-char *rurima_fork_execvp_get_stdout_with_input(char *_Nonnull argv[], char *_Nonnull input);
-char *rurima_call_jq(char *_Nonnull argv[], char *_Nonnull input);
+char *rurima_fork_execvp_get_stdout_with_input(char *_Nonnull argv[], const char *_Nonnull input);
+char *rurima_call_jq(char *_Nonnull argv[], const char *_Nonnull input);
size_t rurima_split_lines(const char *_Nonnull input, char ***_Nonnull lines);
size_t rurima_split_lines_allow_null(const char *_Nonnull input, char ***_Nonnull lines);
void loading_animation(char *msg);
@@ -203,4 +204,5 @@ void rurima_run(int argc, char **_Nonnull argv);
void rurima_netns_wrapper(int argc, char **argv);
void rurima_load_rootfs(int argc, char **argv);
void rurima_docker_print_config_from_json(const char *_Nonnull config, const char *_Nonnull savedir);
-void rurima_sfx(int argc, char **argv);
\ No newline at end of file
+void rurima_sfx(int argc, char **argv);
+void rurima_setup_termux_tmp(void);
\ No newline at end of file
diff --git a/src/info.c b/src/info.c
index d1fbadc..ba73735 100644
--- a/src/info.c
+++ b/src/info.c
@@ -45,24 +45,24 @@ void rurima_show_version_info(void)
cprintf("{base} \n");
cprintf("{base} Copyright (C) 2024-2025 Moe-hacker\n\n");
cprintf("{base}%s%d.%d.%d%s", "rurima version ..................: ", RURIMA_VERSION_MAJOR, RURIMA_VERSION_MINOR, RURIMA_VERSION_PATCH, "\n");
-#if defined(RURIMA_COMMIT_ID)
+#ifdef RURIMA_COMMIT_ID
cprintf("{base}%s%s%s", "rurima commit id ................: ", RURIMA_COMMIT_ID, "\n");
#endif
cprintf("{base}%s%s%s", "built-in ruri version ...........: ", RURI_VERSION, "\n");
-#if defined(RURI_COMMIT_ID)
+#ifdef RURI_COMMIT_ID
cprintf("{base}%s%s%s", "built-in ruri commit id .........: ", RURI_COMMIT_ID, "\n");
#endif
-#if defined(CTH_VERSION_STRING)
+#ifdef CTH_VERSION_STRING
cprintf("{base}%s%s%s", "built-in catsh version ..........: ", CTH_VERSION_STRING, "\n");
#endif
-#if defined(SSFX_VERSION_STRING)
+#ifdef SSFX_VERSION_STRING
cprintf("{base}%s%s%s", "built-in ssfx version ...........: ", SSFX_VERSION_STRING, "\n");
#endif
cprintf("{base}%s%s\n", "Compiler version ................: ", __VERSION__);
cprintf("{base}%s%s\n", "Build date ......................: ", __TIMESTAMP__);
cprintf("{base}\nThere is NO WARRANTY, to the extent permitted by law\n");
cprintf("{base}Docker is a registered trademark of Docker, Inc\nThis program has no relationship with it\n");
- cprintf("{base}\nThis program has Super Neko Powers!!!\n");
+ cprintf("{base}\nThis program has Super Neko Powers! >w<\n");
cprintf("{clear}\n");
}
// For `rurima -V`.
diff --git a/src/main.c b/src/main.c
index 1f60123..0ca881d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,6 +28,7 @@
*
*/
#include "include/rurima.h"
+// NOLINTBEGIN
bool disable_rurima_log = false;
// clang-format off
struct RURIMA_CONFIG rurima_global_config = {
@@ -36,6 +37,7 @@ struct RURIMA_CONFIG rurima_global_config = {
.quiet = false,
.no_progress = false,
};
+// NOLINTEND
// clang-format on
static void show_help(void)
{
@@ -183,7 +185,7 @@ static void reset_path_env(void)
return;
}
exe_path[PATH_MAX - 1] = '\0';
- for (int i = strlen(exe_path) - 1; i >= 0; i--) {
+ for (size_t i = strlen(exe_path) - 1; i >= 0; i--) {
if (exe_path[i] == '/') {
exe_path[i] = '\0';
break;
@@ -295,6 +297,7 @@ int main(int argc, char **argv)
return 0;
}
if (strcmp(argv[i], "netns") == 0) {
+ rurima_warning("{yellow}Are you Moe-hacker?\n");
rurima_netns_wrapper(argc - i - 1, &argv[i + 1]);
return 0;
}
@@ -306,6 +309,11 @@ int main(int argc, char **argv)
rurima_sfx(argc - i - 1, &argv[i + 1]);
return 0;
}
+ if (strcmp(argv[i], "tmx") == 0) {
+ rurima_warning("{yellow}Are you Moe-hacker?\n");
+ rurima_setup_termux_tmp();
+ return 0;
+ }
show_help();
rurima_error("{red}Invalid subcommand `%s`!\n", argv[i]);
return 1;
diff --git a/src/net.c b/src/net.c
index b3a251d..a48acc4 100644
--- a/src/net.c
+++ b/src/net.c
@@ -144,7 +144,7 @@ fi \n\
\n\
ip netns exec \"$NETNS_NAME\" \"$@\" \n";
// Create a memfd.
- int memfd = memfd_create("rurima_script", 0);
+ int memfd = memfd_create("rurima_script", MFD_CLOEXEC);
if (memfd == -1) {
perror("memfd_create");
exit(1);
@@ -161,7 +161,7 @@ ip netns exec \"$NETNS_NAME\" \"$@\" \n";
break;
}
}
- char **wrapper_argv = malloc(sizeof(char *) * (argc + 8));
+ char **wrapper_argv = (char **)malloc(sizeof(char *) * (argc + 8));
wrapper_argv[0] = NULL;
rurima_add_argv(&wrapper_argv, "sh");
rurima_add_argv(&wrapper_argv, script_path);
diff --git a/src/ruri b/src/ruri
index e612c43..1aec556 160000
--- a/src/ruri
+++ b/src/ruri
@@ -1 +1 @@
-Subproject commit e612c43dba5caee3832283fa3ea448b10f92538c
+Subproject commit 1aec556c462df052388585471ebe8b344914822f
diff --git a/src/shared.c b/src/shared.c
index 606b03c..b136940 100644
--- a/src/shared.c
+++ b/src/shared.c
@@ -28,12 +28,14 @@
*
*/
#include "include/rurima.h"
-void end_animation(int unused__)
+void end_animation(int __attribute((unused)) unused__)
{
printf("\r\033[K\033[0m\033[?25h");
exit(0);
}
+// NOLINTBEGIN
pid_t loading_animation_pid = 0;
+// NOLINTEND
void start_loading_animation(char *msg)
{
if (rurima_global_config.no_progress) {
@@ -49,10 +51,10 @@ void end_loading_animation(void)
{
if (loading_animation_pid > 0) {
kill(loading_animation_pid, SIGINT);
- loading_animation_pid = 0;
}
waitpid(loading_animation_pid, NULL, 0);
fflush(stdout);
+ loading_animation_pid = 0;
}
void loading_animation(char *msg)
{
@@ -65,8 +67,9 @@ void loading_animation(char *msg)
fflush(stdout);
usleep(150000);
ptr++;
- if (chr[ptr] == NULL)
+ if (chr[ptr] == NULL) {
ptr = 0;
+ }
}
}
bool proot_exist(void)
@@ -116,6 +119,7 @@ static char *get_dir_realpath(const char *_Nonnull dir)
* Warning: free() the return value after use.
*/
char *ret = malloc(PATH_MAX + strlen(dir) + 1);
+ memset(ret, 0, PATH_MAX + strlen(dir) + 1);
if (strchr(dir, '/') == dir) {
sprintf(ret, "%s", dir);
} else {
@@ -254,97 +258,97 @@ char *rurima_docker_get_host_arch(void)
* Do not free() the returned value.
*/
char *ret = NULL;
-#if defined(__aarch64__)
+#ifdef __aarch64__
ret = "arm64";
#endif
-#if defined(__alpha__)
+#ifdef __alpha__
ret = "alpha";
#endif
-#if defined(__arm__)
+#ifdef __arm__
ret = "arm";
#endif
-#if defined(__armeb__)
+#ifdef __armeb__
ret = "arm";
#endif
-#if defined(__cris__)
+#ifdef __cris__
ret = "cris";
#endif
-#if defined(__hexagon__)
+#ifdef __hexagon__
ret = "hexagon";
#endif
-#if defined(__hppa__)
+#ifdef __hppa__
ret = "hppa";
#endif
-#if defined(__i386__)
+#ifdef __i386__
ret = "386";
#endif
-#if defined(__loongarch64__)
+#ifdef __loongarch64__
ret = "loong64";
#endif
-#if defined(__m68k__)
+#ifdef __m68k__
ret = "m68k";
#endif
-#if defined(__microblaze__)
+#ifdef __microblaze__
ret = "microblaze";
#endif
-#if defined(__mips__)
+#ifdef __mips__
ret = "mips";
#endif
-#if defined(__mips64__)
+#ifdef __mips64__
ret = "mips64";
#endif
-#if defined(__mips64el__)
+#ifdef __mips64el__
ret = "mips64el";
#endif
-#if defined(__mipsel__)
+#ifdef __mipsel__
ret = "mipsel";
#endif
-#if defined(__mipsn32__)
+#ifdef __mipsn32__
ret = "mipsn32";
#endif
-#if defined(__mipsn32el__)
+#ifdef __mipsn32el__
ret = "mipsn32el";
#endif
-#if defined(__ppc__)
+#ifdef __ppc__
ret = "ppc";
#endif
-#if defined(__ppc64__)
+#ifdef __ppc64__
ret = "ppc64";
#endif
-#if defined(__ppc64le__)
+#ifdef __ppc64le__
ret = "ppc64le";
#endif
-#if defined(__riscv32__)
+#ifdef __riscv32__
ret = "riscv32";
#endif
-#if defined(__riscv64__)
+#ifdef __riscv64__
ret = "riscv64";
#endif
-#if defined(__s390x__)
+#ifdef __s390x__
ret = "s390x";
#endif
-#if defined(__sh4__)
+#ifdef __sh4__
ret = "sh4";
#endif
-#if defined(__sh4eb__)
+#ifdef __sh4eb__
ret = "sh4eb";
#endif
-#if defined(__sparc__)
+#ifdef __sparc__
ret = "sparc";
#endif
-#if defined(__sparc32plus__)
+#ifdef __sparc32plus__
ret = "sparc32plus";
#endif
-#if defined(__sparc64__)
+#ifdef __sparc64__
ret = "sparc64";
#endif
-#if defined(__x86_64__)
+#ifdef __x86_64__
ret = "amd64";
#endif
-#if defined(__xtensa__)
+#ifdef __xtensa__
ret = "xtensa";
#endif
-#if defined(__xtensaeb__)
+#ifdef __xtensaeb__
ret = "xtensaeb";
#endif
if (ret == NULL) {
@@ -361,97 +365,97 @@ char *rurima_lxc_get_host_arch(void)
* Do not free() the returned value.
*/
char *ret = NULL;
-#if defined(__aarch64__)
+#ifdef __aarch64__
ret = "arm64";
#endif
-#if defined(__alpha__)
+#ifdef __alpha__
ret = "alpha";
#endif
-#if defined(__arm__)
+#ifdef __arm__
ret = "armhf";
#endif
-#if defined(__armeb__)
+#ifdef __armeb__
ret = "armeabi";
#endif
-#if defined(__cris__)
+#ifdef __cris__
ret = "cris";
#endif
-#if defined(__hexagon__)
+#ifdef __hexagon__
ret = "hexagon";
#endif
-#if defined(__hppa__)
+#ifdef __hppa__
ret = "hppa";
#endif
-#if defined(__i386__)
+#ifdef __i386__
ret = "i386";
#endif
-#if defined(__loongarch64__)
+#ifdef __loongarch64__
ret = "loongarch64";
#endif
-#if defined(__m68k__)
+#ifdef __m68k__
ret = "m68k";
#endif
-#if defined(__microblaze__)
+#ifdef __microblaze__
ret = "microblaze";
#endif
-#if defined(__mips__)
+#ifdef __mips__
ret = "mips";
#endif
-#if defined(__mips64__)
+#ifdef __mips64__
ret = "mips64";
#endif
-#if defined(__mips64el__)
+#ifdef __mips64el__
ret = "mips64el";
#endif
-#if defined(__mipsel__)
+#ifdef __mipsel__
ret = "mipsel";
#endif
-#if defined(__mipsn32__)
+#ifdef __mipsn32__
ret = "mipsn32";
#endif
-#if defined(__mipsn32el__)
+#ifdef __mipsn32el__
ret = "mipsn32el";
#endif
-#if defined(__ppc__)
+#ifdef __ppc__
ret = "ppc";
#endif
-#if defined(__ppc64__)
+#ifdef __ppc64__
ret = "ppc64";
#endif
-#if defined(__ppc64le__)
+#ifdef __ppc64le__
ret = "ppc64le";
#endif
-#if defined(__riscv32__)
+#ifdef __riscv32__
ret = "riscv32";
#endif
-#if defined(__riscv64__)
+#ifdef __riscv64__
ret = "riscv64";
#endif
-#if defined(__s390x__)
+#ifdef __s390x__
ret = "s390x";
#endif
-#if defined(__sh4__)
+#ifdef __sh4__
ret = "sh4";
#endif
-#if defined(__sh4eb__)
+#ifdef __sh4eb__
ret = "sh4eb";
#endif
-#if defined(__sparc__)
+#ifdef __sparc__
ret = "sparc";
#endif
-#if defined(__sparc32plus__)
+#ifdef __sparc32plus__
ret = "sparc32plus";
#endif
-#if defined(__sparc64__)
+#ifdef __sparc64__
ret = "sparc64";
#endif
-#if defined(__x86_64__)
+#ifdef __x86_64__
ret = "amd64";
#endif
-#if defined(__xtensa__)
+#ifdef __xtensa__
ret = "xtensa";
#endif
-#if defined(__xtensaeb__)
+#ifdef __xtensaeb__
ret = "xtensaeb";
#endif
if (ret == NULL) {
@@ -471,7 +475,7 @@ bool rurima_rootless_supported(void)
}
exit(0);
}
- int status;
+ int status = 0;
waitpid(pid, &status, 0);
if (WEXITSTATUS(status) == 0) {
return true;
@@ -542,7 +546,7 @@ size_t rurima_split_lines(const char *_Nonnull input, char ***_Nonnull lines)
if (count == 0) {
return 0;
}
- *lines = malloc(sizeof(char *) * (count + 2));
+ *lines = (char **)malloc(sizeof(char *) * (count + 2));
input_copy = strdup(input);
line = strtok(input_copy, "\n");
size_t index = 0;
@@ -576,7 +580,8 @@ size_t rurima_split_lines_allow_null(const char *_Nonnull input, char ***_Nonnul
if (count == 0) {
return 0;
}
- *lines = malloc(sizeof(char *) * (count + 2));
+ *lines = (char **)malloc(sizeof(char *) * (count + 2));
+ memset((void *)*lines, 0, sizeof(char *) * (count + 2));
input_copy = strdup(input);
p = input_copy;
line = strsep(&p, "\n");
@@ -591,6 +596,8 @@ size_t rurima_split_lines_allow_null(const char *_Nonnull input, char ***_Nonnul
}
free(input_copy);
rurima_log("{base}lines count: {green}%zu{clear}\n", count);
+// NOLINTBEGIN
+#ifdef RURIMA_DEBUG
for (size_t i = 0; i < count; i++) {
if ((*lines)[i] != NULL) {
rurima_log("{base}lines[%zu]: {cyan}%s{clear}\n", i, (*lines)[i]);
@@ -598,6 +605,8 @@ size_t rurima_split_lines_allow_null(const char *_Nonnull input, char ***_Nonnul
rurima_log("{base}lines[%zu]: {cyan}NULL{clear}\n", i);
}
}
+#endif
+ // NOLINTEND
(*lines)[count] = NULL; // Null-terminate the array
return count;
}
\ No newline at end of file
diff --git a/src/signal.c b/src/signal.c
index 269069b..ded9db7 100644
--- a/src/signal.c
+++ b/src/signal.c
@@ -43,9 +43,9 @@ static void panic(int sig)
cfprintf(stderr, "{base}");
cfprintf(stderr, "{base}%s\n", " .^. .^.");
cfprintf(stderr, "{base}%s\n", " /⋀\\_ノ_/⋀\\");
- cfprintf(stderr, "{base}%s\n", " /ノソノ\\ノソ丶)|");
+ cfprintf(stderr, "{base}%s\n", " /ノソノ\\ノソ丶メ");
cfprintf(stderr, "{base}%s\n", " ルリリ > x )リ");
- cfprintf(stderr, "{base}%s\n", "ノノ㇏ ^ ノ|ノ");
+ cfprintf(stderr, "{base}%s\n", "ノノ㇏ ^ ノノ");
cfprintf(stderr, "{base}%s\n", " ⠁⠁");
cfprintf(stderr, "{base}%s\n", "RURIMA ERROR MESSAGE");
cfprintf(stderr, "{base}Seems that it's time to abort.\n");
diff --git a/src/subcommand.c b/src/subcommand.c
index 12be14d..27e731d 100644
--- a/src/subcommand.c
+++ b/src/subcommand.c
@@ -51,22 +51,24 @@ static void docker_pull_try_mirrors(const char *_Nonnull image, const char *_Non
/*
* Try mirrors.
*/
- char **rexec_argv = malloc(128 * sizeof(char *));
+ // NOLINTBEGIN
+ char **rexec_argv = (char **)malloc(128 * sizeof(char *));
rexec_argv[0] = NULL;
for (int i = 0; try_mirrorlist[i] != NULL; i++) {
cprintf("{base}Trying mirror: {cyan}%s\n", try_mirrorlist[i]);
+ rexec_argv[0] = NULL;
rurima_add_argv(&rexec_argv, "docker");
rurima_add_argv(&rexec_argv, "pull");
rurima_add_argv(&rexec_argv, "-i");
- rurima_add_argv(&rexec_argv, (char *)image);
+ rurima_add_argv(&rexec_argv, image);
rurima_add_argv(&rexec_argv, "-t");
- rurima_add_argv(&rexec_argv, (char *)tag);
+ rurima_add_argv(&rexec_argv, tag);
rurima_add_argv(&rexec_argv, "-a");
- rurima_add_argv(&rexec_argv, (char *)architecture);
+ rurima_add_argv(&rexec_argv, architecture);
rurima_add_argv(&rexec_argv, "-s");
- rurima_add_argv(&rexec_argv, (char *)savedir);
+ rurima_add_argv(&rexec_argv, savedir);
rurima_add_argv(&rexec_argv, "-m");
- rurima_add_argv(&rexec_argv, (char *)try_mirrorlist[i]);
+ rurima_add_argv(&rexec_argv, try_mirrorlist[i]);
if (fallback) {
rurima_add_argv(&rexec_argv, "-f");
if (rurima_fork_rexec(rexec_argv) == 0) {
@@ -85,20 +87,20 @@ static void docker_pull_try_mirrors(const char *_Nonnull image, const char *_Non
char *mirrorlist_builtin[] = { rurima_global_config.docker_mirror, "hub.xdark.top", "dockerpull.org", "hub.crdz.gq", "docker.1panel.live", "docker.unsee.tech", "docker.m.daocloud.io", "docker.kejinlion.pro", "registry.dockermirror.com", "hub.rat.dev", "dhub.kubesre.xyz", "docker.nastool.de", "docker.udayun.com", "docker.rainbond.cc", "hub.geekery.cn", "registry.hub.docker.com", NULL };
for (int i = 0; mirrorlist_builtin[i] != NULL; i++) {
cprintf("{base}Trying mirror: {cyan}%s\n", mirrorlist_builtin[i]);
- char **rexec_argv_builtin = malloc(128 * sizeof(char *));
+ char **rexec_argv_builtin = (char **)malloc(128 * sizeof(char *));
rexec_argv_builtin[0] = NULL;
rurima_add_argv(&rexec_argv_builtin, "docker");
rurima_add_argv(&rexec_argv_builtin, "pull");
rurima_add_argv(&rexec_argv_builtin, "-i");
- rurima_add_argv(&rexec_argv_builtin, (char *)image);
+ rurima_add_argv(&rexec_argv_builtin, image);
rurima_add_argv(&rexec_argv_builtin, "-t");
- rurima_add_argv(&rexec_argv_builtin, (char *)tag);
+ rurima_add_argv(&rexec_argv_builtin, tag);
rurima_add_argv(&rexec_argv_builtin, "-a");
- rurima_add_argv(&rexec_argv_builtin, (char *)architecture);
+ rurima_add_argv(&rexec_argv_builtin, architecture);
rurima_add_argv(&rexec_argv_builtin, "-s");
- rurima_add_argv(&rexec_argv_builtin, (char *)savedir);
+ rurima_add_argv(&rexec_argv_builtin, savedir);
rurima_add_argv(&rexec_argv_builtin, "-m");
- rurima_add_argv(&rexec_argv_builtin, (char *)mirrorlist_builtin[i]);
+ rurima_add_argv(&rexec_argv_builtin, mirrorlist_builtin[i]);
if (fallback) {
rurima_add_argv(&rexec_argv_builtin, "-f");
}
@@ -112,9 +114,10 @@ static void docker_pull_try_mirrors(const char *_Nonnull image, const char *_Non
} else {
cprintf("\n{yellow}Mirror {cyan}%s {yellow}is not working!\n\n", mirrorlist_builtin[i]);
}
- free(rexec_argv_builtin);
+ free((void *)rexec_argv_builtin);
}
cprintf("{red}All mirrors are not working!\n");
+ // NOLINTEND
}
/*
* Subcommand for rurima.
@@ -149,6 +152,9 @@ void rurima_docker(int argc, char **_Nonnull argv)
if (i + 1 >= argc) {
rurima_error("{red}No image specified!\n");
}
+ if (image) {
+ rurima_error("{red}Image already specified!\n");
+ }
image = strdup(argv[i + 1]);
i++;
} else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--tag") == 0) {
@@ -588,7 +594,8 @@ void rurima_pull(int argc, char **_Nonnull argv)
cprintf("{base}It will re-exec itself to call the subcommand.\n");
cprintf("{base}If -d option is not set, it will find lxc mirror first.\n");
return;
- } else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mirror") == 0) {
+ }
+ if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mirror") == 0) {
if (i + 1 >= argc) {
rurima_error("{red}No mirror specified!\n");
}
@@ -623,7 +630,7 @@ void rurima_pull(int argc, char **_Nonnull argv)
} else {
rurima_error("{red}No save directory specified!\n");
}
- char **rexec_argv = malloc(sizeof(char *) * 114);
+ char **rexec_argv = (char **)malloc(sizeof(char *) * 114);
rexec_argv[0] = NULL;
if (!docker_only && rurima_lxc_have_image(mirror, image, version, architecture, NULL)) {
if (mirror == NULL) {
@@ -635,15 +642,15 @@ void rurima_pull(int argc, char **_Nonnull argv)
rurima_add_argv(&rexec_argv, "lxc");
rurima_add_argv(&rexec_argv, "pull");
rurima_add_argv(&rexec_argv, "-m");
- rurima_add_argv(&rexec_argv, (char *)mirror);
+ rurima_add_argv(&rexec_argv, mirror);
rurima_add_argv(&rexec_argv, "-o");
- rurima_add_argv(&rexec_argv, (char *)image);
+ rurima_add_argv(&rexec_argv, image);
rurima_add_argv(&rexec_argv, "-v");
- rurima_add_argv(&rexec_argv, (char *)version);
+ rurima_add_argv(&rexec_argv, version);
rurima_add_argv(&rexec_argv, "-a");
- rurima_add_argv(&rexec_argv, (char *)architecture);
+ rurima_add_argv(&rexec_argv, architecture);
rurima_add_argv(&rexec_argv, "-s");
- rurima_add_argv(&rexec_argv, (char *)savedir);
+ rurima_add_argv(&rexec_argv, savedir);
int exit_status = rurima_fork_rexec(rexec_argv);
exit(exit_status);
} else {
@@ -659,18 +666,18 @@ void rurima_pull(int argc, char **_Nonnull argv)
rurima_add_argv(&rexec_argv, "-f");
}
rurima_add_argv(&rexec_argv, "-i");
- rurima_add_argv(&rexec_argv, (char *)image);
+ rurima_add_argv(&rexec_argv, image);
rurima_add_argv(&rexec_argv, "-t");
- rurima_add_argv(&rexec_argv, (char *)version);
+ rurima_add_argv(&rexec_argv, version);
rurima_add_argv(&rexec_argv, "-a");
- rurima_add_argv(&rexec_argv, (char *)architecture);
+ rurima_add_argv(&rexec_argv, architecture);
rurima_add_argv(&rexec_argv, "-s");
- rurima_add_argv(&rexec_argv, (char *)savedir);
+ rurima_add_argv(&rexec_argv, savedir);
rurima_add_argv(&rexec_argv, "-m");
- rurima_add_argv(&rexec_argv, (char *)mirror);
+ rurima_add_argv(&rexec_argv, mirror);
if (start_at != NULL) {
rurima_add_argv(&rexec_argv, "-S");
- rurima_add_argv(&rexec_argv, (char *)start_at);
+ rurima_add_argv(&rexec_argv, start_at);
}
int exit_status = rurima_fork_rexec(rexec_argv);
exit(exit_status);
@@ -713,14 +720,15 @@ void rurima_ota(void)
}
cprintf("{base}New version available: {cyan}%s\n{base}You are using {cyan}%s\n", commit_id_remote, commit_id_local);
char *tmpdir = getenv("TMPDIR");
- if (!tmpdir)
+ if (!tmpdir) {
tmpdir = "/tmp";
+ }
chdir(tmpdir);
// Download.
char URL[PATH_MAX];
char *hostarch = "unknown";
// Map hostarch。
-#if defined(__aarch64__)
+#ifdef __aarch64__
hostarch = "aarch64";
#elif defined(__arm__)
hostarch = "armhf";
@@ -761,7 +769,6 @@ void rurima_ota(void)
rurima_fork_execvp((char *[]){ "rm", "-f", "rurima", NULL });
rurima_fork_execvp((char *[]){ "rm", "-f", "rurima-dbg", NULL });
rurima_fork_execvp((char *[]){ "rm", "-f", "LICENSE", NULL });
- return;
}
/*
* run
@@ -811,17 +818,24 @@ void rurima_load_rootfs(int argc, char **argv)
// Read manifest.json
char manifest_path[PATH_MAX];
sprintf(manifest_path, "%s/manifest.json", tmp_dir);
- FILE *manifest_file = fopen(manifest_path, "r");
+ FILE *manifest_file = fopen(manifest_path, "re");
+ if (!manifest_file) {
+ rurima_error("{red}Failed to open manifest.json!\n");
+ }
struct stat st;
if (fstat(fileno(manifest_file), &st) != 0) {
rurima_error("{red}Failed to stat manifest.json!\n");
}
- char *manifest_content = malloc(st.st_size + 1);
- if (!manifest_file) {
- rurima_error("{red}Failed to open manifest.json!\n");
+ if (st.st_size <= 1 || st.st_size > (off_t)(1024 * 1024)) {
+ rurima_error("{red}Manifest file size is invalid: %ld bytes!\n", st.st_size);
}
+ char *manifest_content = malloc(st.st_size + 2);
fread(manifest_content, 1, st.st_size, manifest_file);
+ // NOLINTBEGIN
+ // TODO: WTH is the warning?
manifest_content[st.st_size] = 0;
+ manifest_content[st.st_size + 1] = 0;
+ // NOLINTEND
fclose(manifest_file);
char *config_file = rurima_call_jq((char *[]){ "jq", "-r", ".[].Config", NULL }, manifest_content);
if (!config_file) {
@@ -851,7 +865,7 @@ void rurima_load_rootfs(int argc, char **argv)
char config_file_path[PATH_MAX];
char *config_content = NULL;
sprintf(config_file_path, "%s/%s", tmp_dir, configs[0]);
- FILE *config_file_fp = fopen(config_file_path, "r");
+ FILE *config_file_fp = fopen(config_file_path, "re");
if (!config_file_fp) {
rurima_error("{red}Failed to open config file %s!\n", config_file_path);
}
@@ -859,9 +873,19 @@ void rurima_load_rootfs(int argc, char **argv)
if (stat(config_file_path, &config_st) != 0) {
rurima_error("{red}Failed to stat config file %s!\n", config_file_path);
}
- config_content = malloc(config_st.st_size + 1);
- fread(config_content, 1, config_st.st_size, config_file_fp);
- config_content[config_st.st_size] = 0;
+ if (config_st.st_size <= 1 || config_st.st_size > (off_t)(1024 * 1024)) {
+ rurima_error("{red}Config file size is invalid: %ld bytes!\n", config_st.st_size);
+ }
+ config_content = malloc(config_st.st_size + 2);
+ size_t bytes_read = fread(config_content, 1, config_st.st_size, config_file_fp);
+ if (bytes_read != (size_t)config_st.st_size) {
+ rurima_error("{red}Failed to read config file %s!\n", config_file_path);
+ } else {
+ // NOLINTBEGIN
+ // TODO: WTH is the warning?
+ config_content[bytes_read] = '\0';
+ // NOLINTEND
+ }
fclose(config_file_fp);
// Print config.
rurima_docker_print_config_from_json(config_content, rootfs_path);
@@ -871,17 +895,19 @@ void rurima_load_rootfs(int argc, char **argv)
for (size_t i = 0; i < layers_len; i++) {
free(layers[i]);
}
- free(layers);
+ free((void *)layers);
for (size_t i = 0; i < config_len; i++) {
free(configs[i]);
}
- free(configs);
+ free((void *)configs);
free(config_content);
rurima_check_dir_deny_list(tmp_dir);
cth_exec_command((char *[]){ "rm", "-rf", tmp_dir, NULL });
exit(0);
}
+// NOLINTBEGIN
void rurima_sfx(int argc, char **_Nonnull argv)
{
rurima_error("{red}Not implemented yet!\n");
-}
\ No newline at end of file
+}
+// NOLINTEND
\ No newline at end of file
diff --git a/src/termux.c b/src/termux.c
new file mode 100644
index 0000000..2d65b57
--- /dev/null
+++ b/src/termux.c
@@ -0,0 +1,53 @@
+#include "include/rurima.h"
+void rurima_setup_termux_tmp(void)
+{
+ /*
+ * Termux user cannot access tmpfs by default.
+ * But if we setuid() from root, it will inherit the SELinux context of root.
+ * And, using mount namespace to avoid affecting other termux processes.
+ * This is a very hacky way and only tested on SukiSU Ultra 40790.
+ */
+ if (getuid() != 0) {
+ fprintf(stderr, "This function must be run as root.\n");
+ exit(EXIT_FAILURE);
+ }
+ // get owner id of /data/data/com.termux/files/usr.
+ struct stat st;
+ if (stat("/data/data/com.termux/files/usr", &st) == -1) {
+ perror("stat");
+ printf("Termux not found.\n");
+ exit(EXIT_FAILURE);
+ }
+ int termux_uid = st.st_uid;
+ if (unshare(CLONE_NEWNS) == -1) {
+ perror("unshare");
+ exit(EXIT_FAILURE);
+ }
+ pid_t pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+ if (pid == 0) {
+ if (mount("tmpfs", "/data/data/com.termux/files/usr/tmp", "tmpfs", 0, "") == -1) {
+ perror("mount");
+ exit(EXIT_FAILURE);
+ }
+ setuid(termux_uid);
+ setenv("PATH", "/data/data/com.termux/files/usr/bin", 1);
+ setenv("HOME", "/data/data/com.termux/files/home", 1);
+ setenv("TMPDIR", "/data/data/com.termux/files/usr/tmp", 1);
+ execl("/data/data/com.termux/files/usr/bin/bash", "bash", NULL);
+ perror("execl");
+ exit(EXIT_FAILURE);
+ } else {
+ // Exit as the same state of child process.
+ int status;
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status)) {
+ exit(WEXITSTATUS(status));
+ } else {
+ exit(EXIT_FAILURE);
+ }
+ }
+}
\ No newline at end of file