├── .gitignore ├── _setup_c ├── .gitignore ├── include │ ├── sigint.h │ ├── callable.h │ ├── colors.h │ ├── curl.h │ ├── shell_io.h │ ├── tasks.h │ ├── read_int.h │ ├── ask_input.h │ └── file_io.h ├── README.MD ├── Makefile ├── src │ ├── sigint.c │ ├── tasks.c │ ├── read_int.c │ ├── shell_io.c │ ├── curl.c │ ├── ask_input.c │ ├── file_io.c │ └── main.c └── .clang-format ├── configs ├── pip.conf ├── alacritty.toml ├── ruff.toml ├── .bashrc └── aria2.conf ├── .termux ├── MesloLGS_NF_Bold.ttf ├── colors.properties.dark_blue └── colors.properties.light_blue ├── scripts ├── k.sh ├── gui.sh └── debian.sh ├── bin ├── arc ├── termux-url-opener ├── rxfetch └── apm ├── LICENSE ├── README.md └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.o 3 | -------------------------------------------------------------------------------- /_setup_c/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.o 3 | setup 4 | -------------------------------------------------------------------------------- /configs/pip.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | extra-index-url = https://termux-user-repository.github.io/pypi/ 3 | -------------------------------------------------------------------------------- /.termux/MesloLGS_NF_Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anonymousx97/termux-setup/HEAD/.termux/MesloLGS_NF_Bold.ttf -------------------------------------------------------------------------------- /configs/alacritty.toml: -------------------------------------------------------------------------------- 1 | [window] 2 | opacity = 0.5 3 | 4 | [font] 5 | normal = { family = "Monospace", style = "Regular" } 6 | size = 22.0 7 | -------------------------------------------------------------------------------- /_setup_c/include/sigint.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGINT_H 2 | #define SIGINT_H 3 | 4 | void sigint_handler(int sig); 5 | void exit_if_sigint(); 6 | 7 | #endif //sigint.h 8 | -------------------------------------------------------------------------------- /_setup_c/include/callable.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLABLE_H 2 | #define CALLABLE_H 3 | 4 | typedef void (*Callable)(); 5 | 6 | typedef void (*MenuCallable)(int); 7 | 8 | #endif //callable.h 9 | -------------------------------------------------------------------------------- /_setup_c/include/colors.h: -------------------------------------------------------------------------------- 1 | #ifndef COLORS_H 2 | #define COLORS_H 3 | 4 | #define RED "\x1b[1;31m" 5 | #define GREEN "\x1b[1;32m" 6 | #define RESET "\x1b[0m" 7 | 8 | #endif // COLORS_H 9 | -------------------------------------------------------------------------------- /_setup_c/include/curl.h: -------------------------------------------------------------------------------- 1 | #ifndef CURL_D_H 2 | #define CURL_D_H 3 | 4 | int download_file(const char* url, const char* filename, const char* dir, const char *file_mode); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /_setup_c/include/shell_io.h: -------------------------------------------------------------------------------- 1 | #ifndef SHELL_IO_H 2 | #define SHELL_IO_H 3 | 4 | #define MAX_OUTPUT_SIZE 8192 // 8mb max output 5 | 6 | typedef struct ShellResult { 7 | int exit_code; 8 | char output[MAX_OUTPUT_SIZE]; 9 | } ShellResult; 10 | 11 | void clear_term(void); 12 | 13 | #endif // !SHELL_IO_H 14 | -------------------------------------------------------------------------------- /scripts/k.sh: -------------------------------------------------------------------------------- 1 | # Kali nethunter arm64 2 | DISTRO_NAME="kali Nethunter (arm64)" 3 | DISTRO_COMMENT="Kali nethunter arm64 (official version)" 4 | TARBALL_URL['aarch64']="https://kali.download/nethunter-images/current/rootfs/kalifs-arm64-minimal.tar.xz" 5 | TARBALL_SHA256['aarch64']="b35534aa0dca0fdf4940836124efdb2faae2cb2e850182e82a8789da5b60b164" 6 | -------------------------------------------------------------------------------- /_setup_c/README.MD: -------------------------------------------------------------------------------- 1 | ### Why? 2 | Because Ryuk used eval in bash version for 3 years and it just didnt sit right with him. 3 | BUT the day before he was ready to push the C version he found a way to make bash version work without eval. 4 | So now this exists as a project that he used to learn C [Was challenged by [THIS PERSON](https://github.com/likeadragonmaid)] 5 | -------------------------------------------------------------------------------- /_setup_c/include/tasks.h: -------------------------------------------------------------------------------- 1 | #ifndef TASKS_H 2 | #define TASKS_H 3 | #include "callable.h" 4 | 5 | #define MAX_TASKS 100 6 | 7 | typedef enum TaskType {INIT_TASK, EXIT_TASK} TaskType; 8 | 9 | void register_init_task(Callable t); 10 | 11 | void register_exit_task(Callable t); 12 | 13 | void run_tasks(const TaskType type); 14 | 15 | #endif //tasks.h 16 | -------------------------------------------------------------------------------- /_setup_c/include/read_int.h: -------------------------------------------------------------------------------- 1 | #ifndef READ_INT_H 2 | #define READ_INT_H 3 | 4 | typedef enum InputStatus{ 5 | SUCCESS, 6 | ERR_EMPTY_INPUT, 7 | ERR_INVALID_INPUT, 8 | NOT_SET 9 | } InputStatus; 10 | 11 | typedef struct ReadResult{ 12 | InputStatus status; 13 | int num; 14 | } ReadResult; 15 | 16 | ReadResult read_int(); 17 | 18 | #endif //read_int.h -------------------------------------------------------------------------------- /configs/ruff.toml: -------------------------------------------------------------------------------- 1 | line-length = 100 2 | target-version = "py312" 3 | extend-exclude = ["**__init__.py"] 4 | 5 | [format] 6 | quote-style = "double" 7 | indent-style = "space" 8 | skip-magic-trailing-comma = false 9 | line-ending = "auto" 10 | 11 | [lint] 12 | extend-select = ["B", "E", "F", "I", "UP", "N", "C90"] 13 | ignore = ["E501"] 14 | 15 | [lint.isort] 16 | relative-imports-order = "closest-to-furthest" -------------------------------------------------------------------------------- /.termux/colors.properties.dark_blue: -------------------------------------------------------------------------------- 1 | background=#090D13 2 | foreground=#FEFEFE 3 | cursor=#E96B72 4 | color0=#00050D 5 | color1=#E96B72 6 | color2=#90B261 7 | color3=#F8AE4E 8 | color4=#52BCF9 9 | color5=#F9E893 10 | color6=#8FE0C5 11 | color7=#C6C6C6 12 | color8=#676767 13 | color9=#EF7077 14 | color10=#C1D84B 15 | color11=#FEB353 16 | color12=#58C1FE 17 | color13=#FEED98 18 | color14=#94E5CA 19 | color15=#FEFEFE 20 | -------------------------------------------------------------------------------- /bin/arc: -------------------------------------------------------------------------------- 1 | #!/data/data/com.termux/files/usr/bin/bash 2 | 3 | # Auto Resume Downloading Last URL 4 | if [[ "${1}" == "-r" ]]; then 5 | url=$(tail -n 2 "${HOME}/.arc_history") 6 | 7 | else 8 | echo -e 'Link or Magnet' 9 | read -r -p "> " url 10 | 11 | # Save the URL 12 | echo -e "${url}\n" >>"${HOME}/.arc_history" 13 | fi 14 | 15 | [[ "${1}" == "-d" ]] && dir="${2}" || dir="/sdcard/Download" 16 | 17 | # Start Aria2 18 | aria2c -d "${dir}" "${url}" 19 | -------------------------------------------------------------------------------- /.termux/colors.properties.light_blue: -------------------------------------------------------------------------------- 1 | # Credits: https://github.com/mayTermux/mytermux 2 | 3 | color0=#2f343f 4 | color1=#fd6b85 5 | color2=#63e0be 6 | color3=#fed270 7 | color4=#67d4f2 8 | color5=#ff8167 9 | color6=#63e0be 10 | color7=#eeeeee 11 | color8=#4f4f5b 12 | color9=#fd6b85 13 | color10=#63e0be 14 | color11=#fed270 15 | color12=#67d4f2 16 | color13=#ff8167 17 | color14=#63e0be 18 | color15=#eeeeee 19 | background=#2a2c3a 20 | foreground=#eeeeee 21 | cursor=#fd6b85 22 | -------------------------------------------------------------------------------- /_setup_c/include/ask_input.h: -------------------------------------------------------------------------------- 1 | #ifndef ASK_INPUT_H 2 | #define ASK_INPUT_H 3 | #include "callable.h" 4 | 5 | typedef struct ArrayResult{ 6 | int code; 7 | MenuCallable func; 8 | } ArrayResult; 9 | 10 | 11 | typedef struct AskArray{ 12 | int capacity; 13 | MenuCallable values[20]; 14 | } AskArray; 15 | 16 | 17 | ArrayResult get_result(struct AskArray *array, int idx); 18 | int ask_and_run(struct AskArray *array, char *menu, char *options); 19 | 20 | #endif //ask_input.h 21 | -------------------------------------------------------------------------------- /_setup_c/Makefile: -------------------------------------------------------------------------------- 1 | CC ?= clang 2 | CFLAGS = -std=c23 -Wall -Wextra -O2 -Iinclude 3 | LDFLAGS = -lcurl 4 | 5 | SRC = $(wildcard src/*.c) 6 | OBJ = $(patsubst src/%.c,build/%.o,$(SRC)) 7 | TARGET ?= setup 8 | 9 | # Gets set in github actions env. 10 | ifdef TARGET_ARCH 11 | OUT = $(TARGET)-$(TARGET_ARCH) 12 | else 13 | OUT = $(TARGET) 14 | endif 15 | 16 | all: $(OUT) 17 | 18 | $(OUT): $(OBJ) 19 | $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) 20 | 21 | build/%.o: src/%.c 22 | @mkdir -p $(dir $@) 23 | $(CC) $(CFLAGS) -c $< -o $@ 24 | 25 | clean: 26 | rm -rf build -------------------------------------------------------------------------------- /_setup_c/include/file_io.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE_IO_H 2 | #define FILE_IO_H 3 | #include 4 | 5 | char* build_filepath(const char* dir, const char* filename); 6 | 7 | int create_dir_recursive(const char* path); 8 | 9 | size_t write_to_file_stream(void* ptr, size_t size, size_t buffer_len, void* stream); 10 | 11 | int write_to_file(const char *filename, const char *text, const char *operation_mode); 12 | 13 | int check_write_access(const char *path); 14 | 15 | int check_exec_access(const char *path); 16 | 17 | int is_file(const char *filepath); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /_setup_c/src/sigint.c: -------------------------------------------------------------------------------- 1 | #include "../include/sigint.h" 2 | #include 3 | #include 4 | #include 5 | #include "../include/colors.h" 6 | #include "../include/tasks.h" 7 | 8 | volatile sig_atomic_t sigint_received = 0; 9 | 10 | void sigint_handler(int _) { 11 | sigint_received = 1; 12 | } 13 | 14 | void exit_if_sigint() { 15 | if (sigint_received) { 16 | printf(GREEN "Ctrl+c received. Exiting...\n" RESET); 17 | exit(1); 18 | } 19 | } 20 | 21 | static void _register_handler(void) { 22 | signal(SIGINT, sigint_handler); 23 | } 24 | 25 | __attribute__((constructor)) void register_handler(void) { 26 | register_init_task(_register_handler); 27 | } 28 | -------------------------------------------------------------------------------- /_setup_c/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Chromium 2 | IndentWidth: 4 3 | ContinuationIndentWidth: 4 4 | ColumnLimit: 120 5 | AllowShortIfStatementsOnASingleLine: false 6 | AllowShortBlocksOnASingleLine: false 7 | AllowShortEnumsOnASingleLine: false 8 | 9 | BreakBeforeBraces: Custom 10 | BraceWrapping: 11 | AfterClass: false 12 | AfterControlStatement: false 13 | AfterEnum: false 14 | AfterFunction: false 15 | AfterNamespace: false 16 | AfterStruct: false 17 | AfterUnion: false 18 | BeforeCatch: false 19 | BeforeElse: false 20 | SplitEmptyFunction: false 21 | SplitEmptyRecord: false 22 | SplitEmptyNamespace: false 23 | #BreakBeforeCloseBracketFunction: true 24 | #BreakBeforeCloseBracketBracedList: true 25 | -------------------------------------------------------------------------------- /scripts/gui.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | function KillRedundantProcess(){ 5 | for i in "dbus" "com.termux.x11" "Xwayland" "pulseaudio" "virgl_test_server_android"; 6 | do pkill -eif "${i}*"; 7 | done 8 | } 9 | 10 | 11 | function supress_output(){ 12 | "${@}" >/dev/null 2>&1 13 | } 14 | 15 | 16 | function _exit(){ 17 | termux-wake-unlock 18 | KillRedundantProcess 19 | } 20 | 21 | 22 | function _start(){ 23 | export DISPLAY=:0 XDG_RUNTIME_DIR=${TMPDIR} 24 | KillRedundantProcess 25 | termux-wake-lock && echo "WakeLock Acquired" 26 | echo "X11 is Listening for incoming connections" 27 | supress_output termux-x11 :0 -ac -xstartup "am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity ; i3" 28 | } 29 | 30 | 31 | trap _exit SIGINT 32 | 33 | _start 34 | _exit 35 | -------------------------------------------------------------------------------- /bin/termux-url-opener: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function yt_dl() { 4 | echo -e "1. Audio : 160kbps Opus\n2. Best Video + Best Audio (Max Resolution)\n3. Download with custom args." 5 | 6 | while true; do 7 | read -r -p "> " x 8 | 9 | case "$x" in 10 | "") echo -e "Choose an option" ;; 11 | 12 | 1) 13 | echo -e "Downloading Audio" 14 | yt-dlp -o /sdcard/Download/YT_DLP/"%(title)s.%(ext)s" -x --audio-format opus --audio-quality 0 --embed-thumbnail "$1" 15 | break 16 | ;; 17 | 18 | 2) 19 | yt-dlp -o /sdcard/Download/YT_DLP/"%(title)s.%(ext)s" -f "bv+ba/b" "$1" 20 | break 21 | ;; 22 | 23 | 3) 24 | echo -e "yt-dlp args:" 25 | read -rp "> " -a args 26 | yt-dlp "${args[@]}" "$1" 27 | break 28 | ;; 29 | 30 | *) echo -e "Invalid Input: ${x}" ;; 31 | 32 | esac 33 | done 34 | sleep 5 35 | } 36 | 37 | if grep -qE "^magnet:" <<<"$1"; then 38 | arc <<<"$1" 39 | else 40 | yt_dl "$1" 41 | fi 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Ryuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /_setup_c/src/tasks.c: -------------------------------------------------------------------------------- 1 | #include "../include/tasks.h" 2 | #include 3 | #include 4 | #include "../include/callable.h" 5 | 6 | static Callable INIT_TASKS[MAX_TASKS]; 7 | static int init_task_count = 0; 8 | 9 | static Callable EXIT_TASKS[MAX_TASKS]; 10 | static int exit_task_count = 0; 11 | 12 | void register_init_task(Callable t) { 13 | if (init_task_count >= MAX_TASKS) { 14 | fprintf(stderr, "Init tasks limit reached.\n"); 15 | return; 16 | } 17 | INIT_TASKS[init_task_count++] = t; 18 | } 19 | 20 | void register_exit_task(Callable t) { 21 | if (exit_task_count >= MAX_TASKS) { 22 | fprintf(stderr, "Exit tasks limit reached.\n"); 23 | return; 24 | } 25 | EXIT_TASKS[exit_task_count++] = t; 26 | } 27 | 28 | void run_tasks(const TaskType type) { 29 | Callable* tasks = NULL; 30 | int length = 0; 31 | 32 | switch (type) { 33 | case INIT_TASK: 34 | tasks = INIT_TASKS; 35 | length = init_task_count; 36 | break; 37 | case EXIT_TASK: 38 | tasks = EXIT_TASKS; 39 | length = exit_task_count; 40 | break; 41 | default: 42 | fprintf(stderr, "Unknown task type!\n"); 43 | return; 44 | } 45 | 46 | for (int i = 0; i < length; i++) { 47 | tasks[i](); 48 | } 49 | } -------------------------------------------------------------------------------- /scripts/debian.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export DISPLAY=:0 XDG_RUNTIME_DIR=${TMPDIR} 4 | 5 | 6 | function KillRedundantProcess(){ 7 | for i in "dbus" "com.termux.x11" "Xwayland" "pulseaudio" "virgl_test_server_android"; 8 | do pkill -qif "${i}*"; 9 | done 10 | } 11 | 12 | 13 | KillRedundantProcess 14 | 15 | 16 | function supress_output(){ 17 | "$@" >/dev/null 2>&1 18 | } 19 | 20 | 21 | termux-wake-lock && echo "WakeLock Acquired" 22 | 23 | 24 | echo "X11 is Listening for incoming connections" 25 | 26 | 27 | supress_output \ 28 | termux-x11 :0 -ac & 29 | 30 | 31 | sleep 3 32 | 33 | 34 | echo "Starting XFCE4" 35 | 36 | 37 | supress_output \ 38 | am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity 39 | 40 | supress_output \ 41 | pulseaudio \ 42 | --start \ 43 | --load="module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1" \ 44 | --exit-idle-time=-1 45 | 46 | 47 | supress_output \ 48 | pacmd \ 49 | load-module \ 50 | module-native-protocol-tcp \ 51 | auth-ip-acl=127.0.0.1 \ 52 | auth-anonymous=1 53 | 54 | supress_output \ 55 | virgl_test_server_android & 56 | 57 | supress_output \ 58 | proot-distro login debian \ 59 | --termux-home \ 60 | --shared-tmp \ 61 | -- bash -c " 62 | export DISPLAY=:0 PULSE_SERVER=tcp:127.0.0.1 63 | dbus-launch --exit-with-session wm_start_cmd" 64 | 65 | 66 | termux-wake-unlock 67 | 68 | 69 | KillRedundantProcess 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Termux Setup 2 | 3 | ### A script to auto-install few packages and customise termux. 4 | ![image](https://github.com/anonymousx97/termux-setup/assets/88324835/424eafa8-d0bb-4b6b-a033-b45b5d878dcc) 5 | 6 | 7 | >It was made because Ryuk was ~~LAZY~~ tired of setting up termux again and again. XD 8 | 9 | ### Previews 10 |
11 | termux-url-opener: 12 | 13 | https://github.com/anonymousx97/termux-setup/assets/88324835/9ba12b6a-e53c-47df-88b8-51585666cd5e 14 | 15 |
16 |
17 | arc: 18 | 19 | https://github.com/anonymousx97/termux-setup/assets/88324835/a1067ff9-9c31-40d8-82bf-c2c10dbc11f3 20 | 21 |
22 | 23 | ### Installation 24 | Download Termux: [**GitHub**](https://github.com/termux/termux-app/releases/download/v0.118.0/termux-app_v0.118.0+github-debug_universal.apk) 25 | 26 | Run: 27 | 28 | ```bash 29 | bash -c "$(curl -fsSL https://raw.githubusercontent.com/anonymousx97/termux-setup/main/setup.sh)" 30 | ``` 31 | ### Credits 32 | * By: Ryuk [ [TG](https://t.me/anonymousx97) | [GitHub](https://github.com/anonymousx97) ] 33 | * [mayTrmux](https://github.com/mayTermux) for _color.properties_ 34 | * Packages Used: 35 | * APT : 36 | aria2 37 | curl 38 | diff-so-fancy 39 | ffmpeg 40 | git 41 | gh 42 | openssh 43 | python 44 | python-pip 45 | python-pillow 46 | ruff 47 | tmux 48 | tsu 49 | wget 50 | root-repo 51 | tur-repo 52 | x11-repo 53 | 54 | * PIP : 55 | yt-dlp 56 | 57 | -------------------------------------------------------------------------------- /_setup_c/src/read_int.c: -------------------------------------------------------------------------------- 1 | #include "../include/read_int.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../include/sigint.h" 9 | 10 | #define MAX_INPUT_SIZE 10 11 | 12 | void remove_char_inplace(char* str, char to_rm) { 13 | char* src = str; 14 | char* dest = str; 15 | while (*src) { 16 | if (*src != to_rm) { 17 | *dest = *src; 18 | dest++; 19 | } 20 | src++; 21 | } 22 | *dest = '\0'; 23 | } 24 | 25 | ReadResult read_int() { 26 | ReadResult result = {.status = NOT_SET}; 27 | char input_line[MAX_INPUT_SIZE]; 28 | char* endptr; 29 | 30 | if (fgets(input_line, MAX_INPUT_SIZE, stdin) == NULL) { 31 | exit_if_sigint(); 32 | result.status = ERR_EMPTY_INPUT; 33 | return result; 34 | } 35 | 36 | exit_if_sigint(); 37 | 38 | remove_char_inplace(input_line, ' '); 39 | 40 | exit_if_sigint(); 41 | 42 | if (input_line[0] == '\0' || input_line[0] == '\n') { 43 | result.status = ERR_EMPTY_INPUT; 44 | return result; 45 | } 46 | 47 | errno = 0; 48 | long num; 49 | num = strtol(input_line, &endptr, 10); 50 | 51 | if (errno == ERANGE) { 52 | result.status = ERR_INVALID_INPUT; 53 | return result; 54 | } 55 | 56 | if (!isspace((unsigned char)*endptr) && *endptr != '\0') { 57 | result.status = ERR_INVALID_INPUT; 58 | return result; 59 | } 60 | 61 | result.num = num; 62 | result.status = SUCCESS; 63 | return result; 64 | } 65 | -------------------------------------------------------------------------------- /configs/.bashrc: -------------------------------------------------------------------------------- 1 | shopt -s cdspell # cd with spelling mistakes ex: cd xzy will cd to xyz if dir exists 2 | shopt -s autocd # just typing xyz will cd to it automatically [if exists] [is spelling sensitive] [supports globbing] 3 | shopt -s globstar # turn on recursive globbing ex **/*.txt will find txt files recursively 4 | shopt -s nullglob # globbing expands to empty string when it fails to match things. 5 | shopt -s extglob # enables regex based globbing pattern support. 6 | shopt -s checkwinsize # checks window sizes (lines, columns) on resize/launch. 7 | 8 | # Useful aliases 9 | alias cds="cd /sdcard" 10 | alias cdd="cd /sdcard/Download" 11 | 12 | alias q="exit" 13 | alias clr="clear && rxfetch" 14 | alias la="ls -a" 15 | 16 | alias apti="apt install" 17 | alias aptu="apt update -y && apt upgrade" 18 | alias aptr="apt remove" 19 | 20 | alias pipi="pip install" 21 | alias pipu="pip install -U" 22 | alias pipr="pip uninstall -y" 23 | 24 | alias py="python" 25 | alias pym="python -m" 26 | 27 | alias gc="git clone" 28 | alias gp="git push" 29 | alias ga="git add --all" 30 | alias gcm="git commit -m" 31 | alias gs="git status" 32 | alias gd="git diff --diff-filter=ACMRTUXB" 33 | alias gl='git log --all --graph --oneline --pretty=format:"%C(magenta)%h %C(white) %an %ar%C(blue) %D%n%s%n"' 34 | 35 | function cd() { 36 | # auto runs ls after cd'ing to a dir. 37 | builtin cd "$@" && ls 38 | } 39 | 40 | function prt() { 41 | # runs ruff tool on given file/dir 42 | ruff check --fix "$@" 43 | ruff format "$@" 44 | } 45 | 46 | function shh() { 47 | # Quietly run a command 48 | "$@" >/dev/null 2>&1 49 | } 50 | -------------------------------------------------------------------------------- /_setup_c/src/shell_io.c: -------------------------------------------------------------------------------- 1 | #include "../include/shell_io.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define MAX_CMD_LEN 1024 7 | 8 | ShellResult run_cmd(const char* cmd) { 9 | ShellResult result = {.exit_code = 0}; 10 | 11 | char stdout_redirected_cmd[MAX_CMD_LEN] = {0}; 12 | 13 | strncpy(stdout_redirected_cmd, cmd, MAX_CMD_LEN - 1); 14 | stdout_redirected_cmd[MAX_CMD_LEN - 1] = '\0'; 15 | 16 | if ((strlen(stdout_redirected_cmd) + strlen(" 2>&1")) < MAX_CMD_LEN) { 17 | strcat(stdout_redirected_cmd, " 2>&1"); 18 | } 19 | 20 | FILE* fp = popen(cmd, "r"); 21 | 22 | if (!fp) { 23 | perror("subprocess popen failed"); 24 | strncpy(result.output, "subprocess popen failed.\n", MAX_OUTPUT_SIZE - 1); 25 | result.output[MAX_OUTPUT_SIZE - 1] = '\0'; 26 | return result; 27 | } 28 | 29 | size_t output_buffer_total = 0; 30 | 31 | char buffer[256]; // read in chunks 32 | 33 | while (fgets(buffer, sizeof(buffer), fp) != NULL) { 34 | size_t current_len = strlen(buffer); 35 | // check if there's space in output for new data. 36 | if (output_buffer_total + current_len < MAX_OUTPUT_SIZE - 1) { 37 | // append the new data 38 | strcpy(result.output + output_buffer_total, buffer); 39 | // increase output index 40 | output_buffer_total += current_len; 41 | continue; 42 | } 43 | 44 | // write EOF 45 | result.output[output_buffer_total] = '\0'; 46 | break; 47 | } 48 | 49 | int process_status = pclose(fp); 50 | result.exit_code = WIFEXITED(process_status) ? WEXITSTATUS(process_status) : -1; 51 | return result; 52 | } 53 | 54 | void clear_term(void) { 55 | printf("\x1b[2J\x1b[H"); 56 | } 57 | -------------------------------------------------------------------------------- /_setup_c/src/curl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../include/file_io.h" 6 | #include "../include/tasks.h" 7 | 8 | static int curl_initialised = 0; 9 | 10 | void init_curl(void) { 11 | CURLcode res = curl_global_init(CURL_GLOBAL_ALL); 12 | if (res != CURLE_OK) { 13 | fprintf(stderr, "curl_global_init failed: %s\n", curl_easy_strerror(res)); 14 | return; 15 | } 16 | curl_initialised++; 17 | } 18 | 19 | __attribute__((constructor)) void _curl_init(void) { 20 | register_init_task(init_curl); 21 | } 22 | 23 | void cleanup_curl(void) { 24 | curl_global_cleanup(); 25 | curl_initialised--; 26 | } 27 | 28 | __attribute__((constructor)) void _curl_de_init(void) { 29 | register_exit_task(cleanup_curl); 30 | } 31 | 32 | int download_file(const char* url, const char* filename, const char* dir, const char* file_mode) { 33 | if (create_dir_recursive(dir)) { 34 | return 1; 35 | } 36 | 37 | char* path = build_filepath(dir, filename); 38 | 39 | if (path == NULL) { 40 | return 1; 41 | } 42 | 43 | CURL* curl = curl_easy_init(); 44 | 45 | if (!curl) { 46 | return 1; 47 | } 48 | 49 | FILE* fp = fopen(path, file_mode); 50 | 51 | if (!fp) { 52 | free(path); 53 | return 1; 54 | } 55 | 56 | curl_easy_setopt(curl, CURLOPT_URL, url); 57 | 58 | curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 59 | 60 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_file_stream); 61 | 62 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 63 | 64 | curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); 65 | 66 | curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); 67 | 68 | curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); 69 | 70 | CURLcode res = curl_easy_perform(curl); 71 | 72 | fclose(fp); 73 | curl_easy_cleanup(curl); 74 | 75 | if (res != CURLE_OK) { 76 | return 1; 77 | } else { 78 | return 0; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /_setup_c/src/ask_input.c: -------------------------------------------------------------------------------- 1 | #include "../include/ask_input.h" 2 | #include 3 | #include "../include/colors.h" 4 | #include "../include/read_int.h" 5 | #include "../include/shell_io.h" 6 | #include "../include/sigint.h" 7 | 8 | ArrayResult get_result(AskArray* array, int idx) { 9 | idx--; 10 | ArrayResult result = {.code = -1, .func = NULL}; 11 | 12 | if (idx < 0 || idx > array->capacity || array->values[idx] == NULL) { 13 | return result; 14 | } 15 | 16 | result.func = array->values[idx]; 17 | result.code = 0; 18 | return result; 19 | } 20 | 21 | int ask_and_run(AskArray* array, char* menu, char* options) { 22 | clear_term(); 23 | 24 | char header[27] = "What would you like to do?"; 25 | 26 | printf("%s%s:%s\n%s\n%s\n> ", GREEN, menu, RESET, header, options); 27 | 28 | int max_retries = 3; 29 | 30 | int retries = 0; 31 | 32 | while (retries < max_retries) { 33 | ReadResult choice; 34 | choice = read_int(); 35 | switch (choice.status) { 36 | case ERR_EMPTY_INPUT: 37 | case NOT_SET: 38 | clear_term(); 39 | printf("%s%s:%s\n%s\n%s\n%sEnter a num.%s\n> ", GREEN, menu, RESET, header, options, RED, RESET); 40 | break; 41 | 42 | case ERR_INVALID_INPUT: 43 | clear_term(); 44 | printf("%s%s:%s\n%s\n%s\n%sInvalid input.%s\n> ", GREEN, menu, RESET, header, options, RED, RESET); 45 | break; 46 | 47 | case SUCCESS: 48 | ArrayResult result = get_result(array, choice.num); 49 | 50 | if (result.code == -1) { 51 | // printf("%s", result.func); 52 | clear_term(); 53 | printf("%s%s:%s\n%s\n%s\n%sInvalid choice.%s\n> ", GREEN, menu, RESET, header, options, RED, RESET); 54 | break; 55 | } 56 | 57 | result.func(choice.num); 58 | return 0; 59 | } 60 | exit_if_sigint(); 61 | retries++; 62 | } 63 | if (retries >= max_retries) { 64 | printf(RED "\nMax retry limit reached.\n" RESET); 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /_setup_c/src/file_io.c: -------------------------------------------------------------------------------- 1 | #include "../include/file_io.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int create_dir_recursive(const char* path) { 10 | // creates all dirs in a path 11 | // /abc/xyz/123/mno.txt 12 | 13 | char pathbuffer[1024]; 14 | 15 | snprintf(pathbuffer, sizeof(pathbuffer), "%s", path); 16 | 17 | size_t len = strlen(pathbuffer); 18 | 19 | // Empty string 20 | if (len == 0) { 21 | printf("mkdir: empty path"); 22 | return -1; 23 | } 24 | 25 | // remove trailing slash ex: abc/ -> abc 26 | if (pathbuffer[len - 1] == '/') { 27 | pathbuffer[len - 1] = '\0'; 28 | } 29 | 30 | char* p = pathbuffer + 1; // skip leading slash 31 | 32 | while (*p) { 33 | // loop over the chars till you find / 34 | if (*p == '/') { 35 | *p = '\0'; // fake the end of the string here 36 | 37 | // call mkdir with whole string till the fake end 38 | if (mkdir(pathbuffer, 0755) == -1 && errno != EEXIST) { 39 | perror("mkdir"); 40 | return -1; 41 | } 42 | 43 | // dir created/exists, continue to sub dir 44 | *p = '/'; // restore slash 45 | } 46 | 47 | p++; // continues to next char 48 | } 49 | 50 | // create the last directory 51 | if (mkdir(pathbuffer, 0755) == -1 && errno != EEXIST) { 52 | perror("mkdir"); 53 | return -1; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | char* build_filepath(const char* dir, const char* filename) { 60 | if (!dir || !filename || filename[0] == '\0') { 61 | perror("empty parameters."); 62 | return NULL; // error on empty filename. 63 | } 64 | 65 | if (create_dir_recursive(dir) == -1) { 66 | return NULL; // error creating dir 67 | } 68 | 69 | size_t dir_len = strlen(dir); 70 | 71 | int should_join_with_slash = 0; 72 | 73 | if (dir_len > 0 && dir[dir_len - 1] != '/') { 74 | should_join_with_slash = 1; 75 | } 76 | 77 | size_t full_path_len = dir_len + strlen(filename) + should_join_with_slash + 1; 78 | 79 | char* path = malloc(full_path_len); 80 | 81 | if (dir_len == 0) { 82 | snprintf(path, full_path_len, "%s", filename); 83 | } 84 | 85 | else if (should_join_with_slash) { 86 | snprintf(path, full_path_len, "%s/%s", dir, filename); 87 | } 88 | 89 | else { 90 | snprintf(path, full_path_len, "%s%s", dir, filename); 91 | } 92 | 93 | return path; 94 | } 95 | 96 | size_t write_to_file_stream(void* ptr, size_t size, size_t buffer_len, void* stream) { 97 | FILE* fp = (FILE*)stream; 98 | return fwrite(ptr, size, buffer_len, fp); 99 | } 100 | 101 | int write_to_file(const char* filename, const char* text, const char* operation_mode) { 102 | FILE* fp = fopen(filename, operation_mode); 103 | 104 | if (!fp) { 105 | perror("Failed to open file"); 106 | return -1; 107 | } 108 | 109 | if (fputs(text, fp) == EOF) { // it writes here in fputs 110 | perror("Failed to write to file"); 111 | fclose(fp); 112 | return -1; 113 | } 114 | 115 | fclose(fp); 116 | return 0; 117 | } 118 | 119 | int check_write_access(const char* path) { 120 | return (path && (access(path, W_OK) == 0)) ? 0 : -1; 121 | } 122 | 123 | int check_exec_access(const char* path) { 124 | return (path && (access(path, X_OK) == 0)) ? 0 : -1; 125 | } 126 | 127 | int is_file(const char* filename) { 128 | return (filename && (access(filename, F_OK) == 0)) ? 0 : -1; 129 | } 130 | -------------------------------------------------------------------------------- /configs/aria2.conf: -------------------------------------------------------------------------------- 1 | console-log-level=notice 2 | summary-interval=0 3 | 4 | file-allocation=none 5 | continue=true 6 | 7 | max-concurrent-downloads=5 8 | max-overall-download-limit=0 9 | max-download-limit=0 10 | # max-connection-per-server=16 11 | 12 | # min-split-size=8M 13 | # split=5 14 | 15 | allow-piece-length-change=true 16 | always-resume=true 17 | seed-time=0 18 | 19 | content-disposition-default-utf8=true 20 | 21 | bt-tracker=udp://tracker.coppersurfer.tk:6969/announce,udp://tracker.leechers-paradise.org:6969/announce,udp://tracker.opentrackr.org:1337/announce,udp://9.rarbg.to:2710/announce,udp://exodus.desync.com:6969/announce,udp://tracker.openbittorrent.com:80/announce,udp://tracker.tiny-vps.com:6969/announce,udp://retracker.lanta-net.ru:2710/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.cyberia.is:6969/announce,udp://torrentclub.tech:6969/announce,udp://open.stealth.si:80/announce,udp://denis.stalker.upeer.me:6969/announce,udp://tracker.moeking.me:6969/announce,udp://open.demonii.si:1337/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://tracker3.itzmx.com:6961/announce,udp://explodie.org:6969/announce,udp://valakas.rollo.dnsabr.com:2710/announce,udp://tracker.nyaa.uk:6969/announce,udp://tracker.iamhansen.xyz:2000/announce,udp://tracker.filepit.to:6969/announce,udp://tracker-udp.gbitt.info:80/announce,udp://retracker.netbynet.ru:2710/announce,udp://retracker.akado-ural.ru:80/announce,udp://opentor.org:2710/announce,udp://tracker.yoshi210.com:6969/announce,udp://tracker.filemail.com:6969/announce,udp://tracker.ds.is:6969/announce,udp://newtoncity.org:6969/announce,udp://bt2.archive.org:6969/announce,udp://bt1.archive.org:6969/announce,https://tracker.fastdownload.xyz:443/announce,https://opentracker.xyz:443/announce,https://opentracker.co:443/announce,http://tracker.bt4g.com:2095/announce,http://opentracker.xyz:80/announce,http://open.trackerlist.xyz:80/announce,http://h4.trakx.nibba.trade:80/announce,udp://xxxtor.com:2710/announce,udp://tracker.uw0.xyz:6969/announce,udp://tracker.tvunderground.org.ru:3218/announce,udp://tracker.nextrp.ru:6969/announce,udp://tracker.msm8916.com:6969/announce,udp://tracker.lelux.fi:6969/announce,udp://retracker.sevstar.net:2710/announce,udp://npserver.intranet.pw:4201/announce,https://tracker.nanoha.org:443/announce,https://tracker.hama3.net:443/announce,http://www.proxmox.com:6969/announce,http://tracker.tvunderground.org.ru:3218/announce,http://tracker.opentrackr.org:1337/announce,http://tracker.bz:80/announce,http://torrentclub.tech:6969/announce,http://t.nyaatracker.com:80/announce,http://retracker.sevstar.net:2710/announce,http://open.acgtracker.com:1096/announce,http://explodie.org:6969/announce,udp://tracker4.itzmx.com:2710/announce,udp://tracker2.itzmx.com:6961/announce,udp://tracker.swateam.org.uk:2710/announce,udp://tr.bangumi.moe:6969/announce,udp://qg.lorzl.gq:2710/announce,udp://chihaya.toss.li:9696/announce,https://tracker.vectahosting.eu:2053/announce,https://tracker.lelux.fi:443/announce,https://tracker.gbitt.info:443/announce,https://opentracker.acgnx.se:443/announce,http://www.loushao.net:8080/announce,http://vps02.net.orel.ru:80/announce,http://tracker4.itzmx.com:2710/announce,http://tracker3.itzmx.com:6961/announce,http://tracker2.itzmx.com:6961/announce,http://tracker1.itzmx.com:8080/announce,http://tracker01.loveapp.com:6789/announce,http://tracker.yoshi210.com:6969/announce,http://tracker.torrentyorg.pl:80/announce,http://tracker.lelux.fi:80/announce,http://tracker.gbitt.info:80/announce,http://tracker.frozen-layer.net:6969/announce,http://sukebei.tracker.wf:8888/announce,http://pow7.com:80/announce,http://opentracker.acgnx.se:80/announce,http://open.acgnxtracker.com:80/announce,http://newtoncity.org:6969/announce,http://mail2.zelenaya.net:80/announce,http://bt-tracker.gamexp.ru:2710/announce,http://acg.rip:6699/announce 22 | -------------------------------------------------------------------------------- /bin/rxfetch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # By Anonymousx97 3 | 4 | # Colors quoted with $ to work with EOF 5 | magenta=$'\033[1;35m' 6 | green=$'\033[1;32m' 7 | white=$'\033[1;37m' 8 | blue=$'\033[1;34m' 9 | red=$'\033[1;31m' 10 | black=$'\033[1;40;30m' 11 | yellow=$'\033[1;33m' 12 | cyan=$'\033[1;36m' 13 | reset=$'\033[0m' 14 | bgyellow=$'\033[1;43;33m' 15 | bgwhite=$'\033[1;47;37m' 16 | 17 | # Termux 18 | if [[ $HOME == "/data/data/com.termux/files/home" ]]; then 19 | 20 | distro_string=" Android 🧡 Termux" 21 | 22 | function getCodeName() { 23 | echo "$(getprop ro.product.board)${red}@${reset}$(getprop ro.com.google.clientidbase)" 24 | } 25 | 26 | function getModel() { 27 | echo "${magenta}phone${reset} $(getprop ro.product.vendor.model)" 28 | } 29 | 30 | function getDistro() { 31 | echo "${green}os${reset} $(uname -o) $(uname -m)" 32 | } 33 | 34 | else 35 | # Desktop 36 | 37 | distro_string=" Linux 🧡 Desktop " 38 | 39 | function getCodeName() { 40 | echo "$(grep -oP '^[Model|Hardware].*: \K.*' /proc/cpuinfo)" 41 | } 42 | 43 | function getModel() { 44 | echo "${magenta}host${reset} $(hostname)" 45 | } 46 | 47 | function getDistro() { 48 | echo "${green}os${reset} $(grep -oP '^NAME="\K[^"]+' /etc/os-release)" 49 | } 50 | 51 | fi 52 | 53 | function getKernel() { 54 | echo "${cyan}ker${reset} $(uname -r)" 55 | } 56 | 57 | function getTotalPackages() { 58 | echo "${blue}pkgs${reset} $(apt list --installed 2>/dev/null | wc -l)" 59 | } 60 | 61 | function getShell() { 62 | local shell="$(basename "$SHELL")" 63 | 64 | if [[ $shell == "login" ]]; then 65 | local custom_shell="/data/data/com.termux/files/home/.termux/shell" 66 | 67 | if [[ -f $custom_shell && -x $custom_shell ]]; then 68 | shell="$($custom_shell -c 'basename "$0"')" 69 | else 70 | shell="bash" 71 | fi 72 | 73 | fi 74 | 75 | echo "${red}sh${reset} $shell" 76 | } 77 | 78 | function getUptime() { 79 | echo "${yellow}up${reset} $(uptime --pretty | sed 's/up//')" 80 | } 81 | 82 | function getMemoryUsage() { 83 | read -r used total <<<"$(free --mega | awk '/Mem:/ {print $3, $2}')" 84 | echo "${magenta}ram${reset} ${used}MB ${red}/${reset} ${total}MB" 85 | } 86 | 87 | function getDiskUsage() { 88 | read -r size used available percent <<<"$(df -h . | awk 'NR==2 {print $2, $3, $4, $5}')" 89 | local mem_color 90 | awk '{if ($1+0 < 10) exit 0; else exit 1}' <<<"$available" && mem_color=$red || mem_color=$green 91 | echo "${green}disk${reset} ${used}B ${red}/${reset} ${size}B = ${mem_color}${available}B${reset} (${percent})" 92 | } 93 | 94 | print_rxfetch() { 95 | cat <<-EOF 96 | 97 | 98 | ┏━━━━━━━━━━━━━━━━━━━━━━━┓ 99 | ┃ ${magenta}r${green}x${cyan}f${blue}e${red}t${yellow}${cyan}c${magenta}h${reset} ${red}${reset} ${yellow}${reset} ${cyan}${reset} ┃ $(getCodeName) 100 | ┣━━━━━━━━━━━━━━━━━━━━━━━┫ 101 | ┃ ┃ $(getModel) 102 | ┃ ${white}•${black}_${white}•${reset} ┃ $(getDistro) 103 | ┃ ${black}${reset}${bgyellow}oo${reset}${black}|${reset} ┃ $(getKernel) 104 | ┃ ${black}/${reset}${bgwhite} ${reset}${black}'\'${reset} ┃ $(getTotalPackages) 105 | ┃ ${bgyellow}(${reset}${black}\_;/${reset}${bgyellow})${reset} ┃ $(getShell) 106 | ┃ ┃ $(getUptime) 107 | ┃ ${distro_string} ┃ $(getMemoryUsage) 108 | ┃ ┃ $(getDiskUsage) 109 | ┗━━━━━━━━━━━━━━━━━━━━━━━┛ ${magenta}━━━${green}━━━${white}━━━${blue}━━━${red}━━━${yellow}━━━${cyan}━━━${reset} 110 | 111 | 112 | EOF 113 | 114 | } 115 | 116 | print_stdout() { 117 | cat <<-EOF 118 | $(getModel) 119 | $(getDistro) 120 | $(getKernel) 121 | $(getTotalPackages) 122 | $(getShell) 123 | $(getUptime) 124 | $(getMemoryUsage) 125 | $(getDiskUsage) 126 | EOF 127 | } 128 | 129 | [[ "$1" =~ ^(--stdout|-s)$ ]] && print_stdout || print_rxfetch 130 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # By Ryuk Github | TG : [ anonymousx97 ] 4 | 5 | red="\033[1;31m" 6 | reset="\033[0m" 7 | green="\033[1;32m" 8 | defaults=0 9 | 10 | download() { 11 | local dir="$1" 12 | local file="$2" 13 | local url="$3" 14 | 15 | mkdir -p "$dir" 16 | curl -sL -o "${dir%%/}/${file}" "$url" 17 | } 18 | 19 | print() { 20 | builtin echo -e "$@" 21 | } 22 | 23 | print_green() { 24 | print "${green}${*}${reset}" 25 | } 26 | 27 | graceful_exit() { 28 | print_green "Exiting..." 29 | exit 30 | } 31 | 32 | index_options_str() { 33 | local options_str="" 34 | 35 | idx=0 36 | for i in "$@"; do 37 | # Index with idx+1 38 | ((idx++)) 39 | options_str+=" ${idx}. ${i}" 40 | # add newline only if theres more data 41 | ((idx << $#)) && options_str+=$'\n' 42 | 43 | done 44 | 45 | printf '%s' "$options_str" 46 | } 47 | 48 | ask() { 49 | clear 50 | 51 | local header="What do you want to do?" 52 | local menu="$1" 53 | local option_text="$2" 54 | local -n arg_array="$3" 55 | 56 | local text_to_print="${green}${menu}:${reset}\n${header}\n${option_text}" 57 | 58 | print "$text_to_print" 59 | 60 | while true; do 61 | 62 | read -r -p "> " choice 63 | 64 | if [[ -z "${choice}" || ! "$choice" =~ ^[0-9]+$ || $choice -le 0 || ! -v arg_array[$((--choice))] ]]; then 65 | clear 66 | print "${text_to_print}${red}\n Invalid input.${reset}" 67 | continue 68 | 69 | fi 70 | 71 | "${arg_array[$choice]}" "$choice" 72 | break 73 | 74 | done 75 | } 76 | 77 | run_all() { 78 | export defaults=1 79 | package_setup 80 | customize_all 81 | } 82 | 83 | start() { 84 | # Setup Storage Permissions 85 | ! [[ -w /sdcard && -r /sdcard ]] && termux-setup-storage 86 | 87 | local options=( 88 | "Install Essential packages." 89 | "Customize Termux." 90 | "Both 1 & 2 (Uses Presets for customisation)" 91 | "Setup Debian in Termux." 92 | "Exit" 93 | ) 94 | 95 | export start_options_arr=( 96 | package_setup 97 | customize 98 | run_all 99 | setup_debian 100 | graceful_exit 101 | ) 102 | 103 | ask "Main Menu" "$(index_options_str "${options[@]}")" "start_options_arr" 104 | } 105 | 106 | customize_all() { 107 | print_green "Customising All." 108 | export defaults=1 109 | setup_apm 110 | setup_aria2 111 | setup_ytdlp 112 | setup_prettify 113 | setup_rxfetch 114 | change_cursor 115 | change_ui 116 | sleep 2 117 | clear 118 | rxfetch 119 | } 120 | 121 | customize() { 122 | 123 | export option_dict=( 124 | setup_apm 125 | setup_aria2 126 | setup_ytdlp 127 | setup_rxfetch 128 | change_cursor 129 | change_ui 130 | customize_all 131 | start 132 | graceful_exit 133 | ) 134 | 135 | local options=( 136 | "Setup Android Package Manager by Ryuk." 137 | "Setup Aria2 Shortcut." 138 | "Enable Downloading Magnets or YT-DLP supported links by sharing to termux." 139 | "Setup Rxfetch." 140 | "Change Cursor Style." 141 | "Change Colour and Font." 142 | "All of the above. ( Uses Presets )" 143 | "Go back to previous menu." 144 | "Exit" 145 | ) 146 | ask "Customisation Menu" "$(index_options_str "${options[@]}")" "option_dict" 147 | 148 | } 149 | 150 | package_setup() { 151 | # Update Termux Package Repository 152 | termux-change-repo 153 | 154 | yes | pkg upgrade 155 | apt update -y && apt upgrade -y 156 | 157 | # Install necessary packages 158 | apt install -y \ 159 | aria2 \ 160 | curl \ 161 | ffmpeg \ 162 | git \ 163 | gh \ 164 | openssh \ 165 | python \ 166 | python-pip \ 167 | tmux \ 168 | tsu \ 169 | wget \ 170 | root-repo \ 171 | x11-repo \ 172 | tur-repo 173 | 174 | # Sets up Termux's PIP Index repo 175 | download "${HOME}/.config/pip/" "pip.conf" \ 176 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/configs/pip.conf" 177 | 178 | # Setup .bashrc 179 | cat <<-EOF >>"${HOME}/.bashrc" 180 | $(curl -fsSL https://raw.githubusercontent.com/anonymousx97/termux-setup/main/configs/.bashrc) 181 | EOF 182 | 183 | # Update and Install pip packages 184 | pip install -U \ 185 | wheel \ 186 | setuptools \ 187 | yt-dlp 188 | } 189 | 190 | setup_debian() { 191 | apt update 192 | apt install -y 193 | apt install -y \ 194 | proot \ 195 | proot-distro \ 196 | termux-x11-nightly \ 197 | pulseaudio 198 | 199 | proot-distro install debian 200 | 201 | clear 202 | 203 | local options=("Install xfce4" "Install KDE" "Exit") 204 | 205 | wm="" 206 | wm_cmd="" 207 | 208 | export wm_dict=( 209 | "export wm=xfce4 wm_cmd=startxfce4" 210 | "export wm=kde-standard wm_cmd=startplasma-x11" 211 | "graceful_exit" 212 | ) 213 | 214 | ask "Window Manager Menu" "$(index_options_str "${options[@]}")" "wm_dict" 215 | 216 | proot-distro login debian --termux-home --shared-tmp -- bash -c <<-EOF 217 | apt update -y 218 | 219 | apt install -y \ 220 | firefox-esr \ 221 | ${wm} \ 222 | xfce4-goodies \ 223 | locales \ 224 | fonts-noto-cjk 225 | 226 | ln -sf /usr/share/zoneinfo/Asia/Calcutta /etc/localtime 227 | 228 | echo en_US.UTF-8 UTF-8 >> /etc/locale.gen 229 | 230 | locale-gen 231 | 232 | echo 'LANG=en_US.UTF-8' > /etc/locale.conf 233 | EOF 234 | 235 | download "${HOME}" "debian.sh" \ 236 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/scripts/debian.sh" 237 | 238 | sed -i "s/wm_start_cmd/${wm_cmd}/" "${HOME}/debian.sh" 239 | 240 | cat <<-EOF >>"${HOME}/.bashrc" 241 | alias dcli="proot-distro login debian --termux-home --shared-tmp -- bash" 242 | alias dgui="bash debian.sh" 243 | 244 | [[ "$(whoami)" == "root" ]] && export HISTFILE=~/.debian_history 245 | 246 | EOF 247 | 248 | print_green "Done." 249 | 250 | print "You can now use '${green}dcli${reset}' for debian cli and '${green}dgui${reset}' for GUI (Termux x11 app required)." 251 | 252 | } 253 | 254 | setup_native_gui() { 255 | apt update -y && apt install -y i3 rofi feh alacritty proot 256 | 257 | download ".config/i3" "config" \ 258 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/configs/i3" 259 | 260 | download ".config/alacritty" "alacritty.toml" \ 261 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/configs/alacritty.toml" 262 | 263 | download "$HOME" "gui.sh" \ 264 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/scripts/gui.sh" 265 | 266 | chmod +x "${HOME}/gui.sh" 267 | 268 | echo "alias gui='~/gui.sh'" 269 | 270 | } 271 | 272 | setup_apm() { 273 | print "\n1. Downloading Android Package Manager By Ryuk." 274 | 275 | download "${PATH}" "apm" \ 276 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/bin/apm" 277 | 278 | chmod +x "${PATH}/apm" 279 | 280 | print "${green}Done.${reset} use 'apm' to call it." 281 | } 282 | 283 | setup_aria2() { 284 | print "\n2. Downloading Aria2 shortcut and config." 285 | 286 | download "${PATH}" "arc" \ 287 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/bin/arc" 288 | 289 | chmod +x "${PATH}/arc" 290 | 291 | download "${HOME}/.aria2/" "aria2.conf" \ 292 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/config/aria2.conf" 293 | 294 | print_green "Done." 295 | } 296 | 297 | setup_ytdlp() { 298 | print "\n3. Downloading files and Setting Up Magent & YT-DLP link share Trigger." 299 | 300 | download "${HOME}/bin" "termux-url-opener" \ 301 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/bin/termux-url-opener" 302 | 303 | print_green "Done." 304 | } 305 | 306 | setup_rxfetch() { 307 | print "\n5. Downloading and Setting up Rxfetch" 308 | 309 | download "${PATH}" "rxfetch" \ 310 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/bin/rxfetch" 311 | 312 | chmod +x "${PATH}/rxfetch" 313 | 314 | local motd="#!${SHELL}\nbash rxfetch" 315 | 316 | if [[ -f ~/.termux/motd.sh && $defaults -eq 0 ]]; then 317 | print "${red}A custom start script exists in the path ${HOME}/.termux/motd.sh${reset}" 318 | print " Enter 1 to overwrite the current file.\n Press Enter to skip." 319 | 320 | read -r -p "> " prompt 321 | 322 | if [[ ! "${prompt}" || ! "${prompt}" == 1 ]]; then 323 | print_green "Skipping motd modification." 324 | 325 | else 326 | print "${red}Overwriting motd.${reset}" 327 | print "${motd}" >~/.termux/motd.sh 328 | fi 329 | 330 | else 331 | print "${motd}" >~/.termux/motd.sh 332 | fi 333 | 334 | print_green "Done." 335 | } 336 | 337 | apply_cursor_change() { 338 | local choice="${1:-0}" 339 | local style 340 | local style_ansi 341 | 342 | case "$choice" in 343 | 0) 344 | style="bar" 345 | style_ansi='\e[6 q' 346 | ;; 347 | 1) 348 | style="underline" 349 | style_ansi='\e[4 q' 350 | ;; 351 | 2) 352 | style="block" 353 | style_ansi='\e[1 q' 354 | ;; 355 | esac 356 | 357 | printf "%b" "$style_ansi" 358 | 359 | # Set the style in termux properties 360 | sed -i "s/.*terminal-cursor-style.*/terminal-cursor-style = ${style}/" "${HOME}/.termux/termux.properties" 361 | 362 | # Change Blink Rate 363 | sed -i "s/.*terminal-cursor-blink-rate.*/terminal-cursor-blink-rate = 600/" "${HOME}/.termux/termux.properties" 364 | 365 | print_green "Done." 366 | } 367 | 368 | change_cursor() { 369 | print "\n6. Changing Cursor" 370 | 371 | [[ "$defaults" -ne 0 ]] && apply_cursor_change && return 372 | 373 | local options=( 374 | "Change to ${green}|${reset} (bar)" 375 | "Change to ${green}_${reset} (underscore)" 376 | "Change to Default Block style." 377 | "Exit" 378 | ) 379 | 380 | export cursor_dict=( 381 | apply_cursor_change 382 | apply_cursor_change 383 | apply_cursor_change 384 | graceful_exit 385 | ) 386 | 387 | ask "Cursor Menu" "$(index_options_str "${options[@]}")" "cursor_dict" 388 | 389 | } 390 | 391 | apply_ui_change() { 392 | local choice="${1:-0}" 393 | local url 394 | 395 | if [[ "$choice" -eq 0 ]]; then 396 | url="https://raw.githubusercontent.com/anonymousx97/termux-setup/main/.termux/colors.properties.dark_blue" 397 | 398 | else 399 | url="https://raw.githubusercontent.com/anonymousx97/termux-setup/main/.termux/colors.properties.light_blue" 400 | 401 | fi 402 | 403 | download "${HOME}/.termux" "colors.properties" url 404 | 405 | download "${HOME}/.termux/" "font.ttf" \ 406 | "https://raw.githubusercontent.com/anonymousx97/termux-setup/main/.termux/MesloLGS_NF_Bold.ttf" 407 | 408 | print_green "\nApplying Changes." 409 | 410 | termux-reload-settings 411 | 412 | print_green "Done." 413 | } 414 | 415 | change_ui() { 416 | print "\n7. Changing Colour and Font." 417 | 418 | [[ "$defaults" -ne 0 ]] && apply_ui_change && return 419 | 420 | local options=("Set Dark Blue" "Set Light Blue") 421 | 422 | export ui_dict=( 423 | apply_ui_change 424 | apply_ui_change 425 | ) 426 | ask "UI Menu" "$(index_options_str "${options[@]}")" "ui_dict" 427 | 428 | } 429 | 430 | save_setup_sh() { 431 | [[ -f "${PATH}/setup-termux" ]] && return 0 432 | 433 | print "\nSaving setup.sh for future use." 434 | 435 | cat <<-EOF >"${PATH}/setup-termux" 436 | #!/usr/bin/env bash 437 | bash -c "$(curl -fsSL https://raw.githubusercontent.com/anonymousx97/termux-setup/main/setup.sh)" 438 | EOF 439 | 440 | chmod +x "${PATH}/setup-termux" 441 | 442 | print "${green}Done\n${reset}You can now use ${green}'setup-termux'${reset} to get back to this menu." 443 | 444 | } 445 | 446 | trap 'print_green "\nCtrl+c received exiting..." && exit 1' SIGINT 447 | start 448 | save_setup_sh 449 | -------------------------------------------------------------------------------- /_setup_c/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../include/ask_input.h" 4 | #include "../include/colors.h" 5 | #include "../include/curl.h" 6 | #include "../include/file_io.h" 7 | #include "../include/read_int.h" 8 | #include "../include/sigint.h" 9 | #include "../include/tasks.h" 10 | 11 | #define HOME "/data/data/com.termux/files/home" 12 | #define BIN "/data/data/com.termux/files/usr/bin" 13 | #define TMPDIR "/data/data/com.termux/files/usr/tmp" 14 | #define SHELL "/data/data/com.termux/files/usr/bin/bash" 15 | 16 | static int DEFAULTS = 0; 17 | 18 | static void __exit(int _) { 19 | run_tasks(EXIT_TASK); 20 | printf(GREEN "Exiting...\n" RESET); 21 | } 22 | 23 | void packages_setup(int _) { 24 | system("termux-change-repo; yes | pkg upgrade ; apt update"); 25 | 26 | system( 27 | "apt install -y " 28 | " aria2" 29 | " curl" 30 | " ffmpeg" 31 | " git" 32 | " gh" 33 | " openssh" 34 | " python" 35 | " python-pip" 36 | " tmux" 37 | " tsu" 38 | " wget" 39 | " root-repo" 40 | " x11-repo" 41 | " tur-repo"); 42 | 43 | // Save Termux pip iindex url 44 | download_file( 45 | "https://raw.githubusercontent.com/anonymousx97/" 46 | "termux-setup/main/configs/pip.conf", 47 | "pip.conf", HOME "/.config/pip/", "a+"); 48 | 49 | system( 50 | "pip install -U " 51 | " wheel" 52 | " setuptools" 53 | " yt-dlp"); 54 | 55 | download_file( 56 | "https://raw.githubusercontent.com/anonymousx97/" 57 | "termux-setup/main/configs/.bashrc", 58 | ".bashrc", HOME, "a+"); 59 | } 60 | 61 | void setup_native_gui(int _) { 62 | system( 63 | "apt update -y && apt install -y i3 rofi feh alacritty " 64 | "proot"); 65 | exit_if_sigint(); 66 | // Save i3 WM config 67 | download_file( 68 | "https://raw.githubusercontent.com/anonymousx97/" 69 | "termux-setup/main/configs/i3", 70 | "config", HOME "/.config/i3", "w+"); 71 | // save gui start sscript 72 | download_file( 73 | "https://raw.githubusercontent.com/anonymousx97/" 74 | "termux-setup/main/scripts/gui.sh", 75 | "gui.sh", HOME, "w+"); 76 | // create executable 77 | system("chmod +x " HOME "/gui.sh"); 78 | // setup alias 79 | write_to_file(HOME "/.bashrc", "\nalias gui=~/gui.sh", "a+"); 80 | 81 | printf(GREEN "\nDone.\n" RESET "\nRestart Termux and type:" RED "gui\n" RESET); 82 | } 83 | 84 | void setup_apm(int choice) { 85 | printf("\n%d. Downloading Android Package Manager By Ryuk.\n", choice); 86 | 87 | download_file( 88 | "https://raw.githubusercontent.com/anonymousx97/" 89 | "termux-setup/main/bin/apm", 90 | "apm", BIN, "w+"); 91 | 92 | system("chmod +x " BIN "/apm"); 93 | 94 | printf(GREEN "Done\n." RESET "use 'apm' to call it."); 95 | } 96 | 97 | void setup_aria2(int choice) { 98 | printf("\n%d. Downloading Aria2 shortcut and config.\n", choice); 99 | 100 | download_file( 101 | "https://raw.githubusercontent.com/anonymousx97/" 102 | "termux-setup/main/bin/arc", 103 | "arc", BIN, "w+"); 104 | 105 | system("chmod +x " BIN "/arc"); 106 | 107 | download_file( 108 | "https://raw.githubusercontent.com/anonymousx97/" 109 | "termux-setup/main/config/aria2.conf", 110 | "aria2.conf", HOME ".aria2/", "w+"); 111 | 112 | printf(GREEN "Done.\n" RESET "Usage: " RED "arc\n" RESET); 113 | } 114 | 115 | void setup_ytdlp(int choice) { 116 | printf( 117 | "\n%d. Downloading files and Setting Up Magent & YT-DLP " 118 | "link share Trigger.\n", 119 | choice); 120 | 121 | download_file( 122 | "https://raw.githubusercontent.com/anonymousx97/" 123 | "termux-setup/main/bin/" 124 | "termux-url-opener", 125 | "termux-url-opner", HOME "/bin", "w+"); 126 | 127 | printf(GREEN "Done\n." RESET); 128 | } 129 | 130 | void setup_rxfetch(int choice) { 131 | printf("\n%d. Downloading and Setting up Rxfetch\n", choice); 132 | 133 | download_file( 134 | "https://raw.githubusercontent.com/anonymousx97/" 135 | "termux-setup/main/bin/rxfetch", 136 | "rxfetch", BIN, "w+"); 137 | 138 | printf(GREEN "Downloaded...\n" RESET); 139 | 140 | system("chmod +x " BIN "/rxfetch"); 141 | 142 | const char motd[] = "#!" SHELL "\nbash rxfetch"; 143 | 144 | if (is_file(HOME "/.termux/motd,sh") && DEFAULTS == 0) { 145 | printf(RED "A custom start script exists in the path " HOME "/.termux/motd.sh\n" RESET 146 | " Enter 1 to overwrite the current file\n Press " 147 | "any other key to skip.\n>"); 148 | 149 | ReadResult result = read_int(); 150 | 151 | if (result.num == 1) { 152 | printf(RED "Overwriting motd." RESET); 153 | } else { 154 | printf(GREEN "Skipping motd modification.\n" RESET); 155 | return; 156 | } 157 | } 158 | 159 | write_to_file(HOME "/.termux/motd.sh", motd, "w+"); 160 | printf(GREEN "Done\n." RESET); 161 | } 162 | 163 | static void apply_cursor(int choice) { 164 | char* style; 165 | char* style_ansi; 166 | 167 | switch (choice - 1) { 168 | case 0: 169 | style = "bar"; 170 | style_ansi = "\e[6 q"; 171 | break; 172 | case 1: 173 | style = "underline"; 174 | style_ansi = "\e[4 q"; 175 | break; 176 | case 2: 177 | style = "block"; 178 | style_ansi = "\e[1 q"; 179 | break; 180 | } 181 | printf("%s", style_ansi); // apply in current term 182 | 183 | char sed_str[500]; 184 | snprintf(sed_str, sizeof(sed_str), 185 | "sed -i " 186 | "\"s/.*terminal-cursor-style.*/terminal-cursor-style = " 187 | "%s/\" " 188 | "%s/.termux/termux.properties", 189 | style, HOME); 190 | 191 | // change in config gile 192 | system(sed_str); 193 | 194 | // change blinkrate 195 | system( 196 | "sed -i " 197 | "\"s/.*terminal-cursor-blink-rate.*/" 198 | "terminal-cursor-blink-rate = 600/\" \"" HOME "/.termux/termux.properties\""); 199 | } 200 | 201 | void change_cursor(int choice) { 202 | printf("\n%d. Changing Cursor\n", choice); 203 | if (DEFAULTS != 0) { 204 | apply_cursor(1); 205 | } 206 | AskArray array = {.capacity = 3, .values = {apply_cursor, apply_cursor, apply_cursor}}; 207 | char options[] = " 1. Change to " GREEN "|" RESET 208 | " (bar)\n" 209 | " 2. Change to " GREEN "_" RESET 210 | " (underscore)\n" 211 | " 3. Change to Default Block style.\n"; 212 | ask_and_run(&array, "Cursor Menu", options); 213 | printf(GREEN "Done\n." RESET); 214 | } 215 | 216 | static void apply_ui_change(int choice) { 217 | char* url; 218 | 219 | if ((choice - 1) == 0) { 220 | url = 221 | "https://raw.githubusercontent.com/anonymousx97/" 222 | "termux-setup/main/.termux/" 223 | "colors.properties.dark_blue"; 224 | } else { 225 | url = 226 | "https://raw.githubusercontent.com/anonymousx97/" 227 | "termux-setup/main/.termux/" 228 | "colors.properties.light_blue"; 229 | } 230 | 231 | download_file(url, "colors.properties", HOME "/.termux", "w+"); 232 | download_file( 233 | "https://raw.githubusercontent.com/anonymousx97/" 234 | "termux-setup/main/.termux/" 235 | "MesloLGS_NF_Bold.ttf", 236 | "font.ttf", HOME "/.termux", "w+"); 237 | } 238 | 239 | void change_ui(int choice) { 240 | printf("%d. Changing Colour and Font.\n", choice); 241 | if (DEFAULTS != 0) { 242 | apply_ui_change(1); 243 | } else { 244 | AskArray array = {.capacity = 2, .values = {apply_ui_change, apply_ui_change}}; 245 | ask_and_run(&array, "UI Menu", " 1. Set Dark Blue\n 2. Set Light Blue"); 246 | } 247 | 248 | printf(GREEN "Applying Changes.\n" RESET); 249 | 250 | system("termux-reload-settings"); 251 | 252 | printf(GREEN "Done\n." RESET); 253 | } 254 | 255 | void save_setup_sh(void) { 256 | if (is_file(BIN "/setup-termux") == 0) { 257 | return; 258 | } 259 | 260 | printf("\nSaving setup.sh for future use.\n"); 261 | 262 | write_to_file(BIN "/setup-termux", 263 | "#!/usr/bin/env bash" 264 | "\nexecutable=" TMPDIR 265 | "/setup" 266 | "\ncurl -fsSL " 267 | "https://raw.githubusercontent.com/anonymousx97/" 268 | "termux-setup/main/setup_src/" 269 | "setup > $executable" 270 | "\n$executable", 271 | "w+"); 272 | 273 | system("chmod +x " BIN "/setup-termux"); 274 | 275 | printf(GREEN "\nDone\n" RESET "You can now use " GREEN "'setup-termux'" RESET " to get back to this menu.\n"); 276 | } 277 | 278 | void customize_all(int choice) { 279 | MenuCallable array[] = { 280 | setup_apm, setup_aria2, setup_ytdlp, setup_rxfetch, change_cursor, change_ui, 281 | }; 282 | 283 | int size = sizeof(array) / sizeof(array[0]); 284 | 285 | for (int i = 0; i < size; i++) { 286 | array[i](choice); 287 | } 288 | } 289 | 290 | void start(int _); 291 | void customize(int _); 292 | 293 | void run_all(int choice) { 294 | DEFAULTS++; 295 | packages_setup(choice); 296 | customize_all(choice); 297 | } 298 | 299 | void start(int _) { 300 | AskArray menu_array = {.capacity = 5, .values = {packages_setup, customize, run_all, setup_native_gui, __exit}}; 301 | 302 | char options[] = 303 | " 1. Install Essential Packages.\n" 304 | " 2. Customize Termux.\n" 305 | " 3. Both 1 & 2 (Uses Presets)\n" 306 | " 4. Setup Native i3 Gui in termux (needs termux-x11 " 307 | "app)\n" 308 | " 5. Exit"; 309 | 310 | ask_and_run(&menu_array, "Main Menu", options); 311 | } 312 | 313 | void customize(int _) { 314 | AskArray array = {.capacity = 10, 315 | .values = { 316 | setup_apm, 317 | setup_aria2, 318 | setup_ytdlp, 319 | setup_rxfetch, 320 | change_cursor, 321 | change_ui, 322 | customize_all, 323 | start, 324 | __exit, 325 | }}; 326 | char options[] = 327 | " 1. Setup Android Package Manager by Ryuk." 328 | "\n 2. Setup Aria2 Shortcut." 329 | "\n 3. Enable Downloading Magnets or YT-DLP supported " 330 | "links by sharing to termux." 331 | "\n 4. Setup Rxfetch." 332 | "\n 5. Change Cursor Style. " 333 | "\n 6. Change Colour and Font." 334 | "\n 7. All of the above. ( Uses Presets )" 335 | "\n 8. Go back to previous menu." 336 | "\n 9. Exit"; 337 | 338 | ask_and_run(&array, "Customisation Menu", options); 339 | } 340 | 341 | int main(void) { 342 | // check if termux has storage perm. 343 | if (check_write_access("/sdcard") != 0) { 344 | system("termux-setup-storage"); 345 | } 346 | run_tasks(INIT_TASK); 347 | start(0); 348 | run_tasks(EXIT_TASK); 349 | save_setup_sh(); 350 | } 351 | -------------------------------------------------------------------------------- /bin/apm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # By Ryuk [anonymousx97] 3 | 4 | import datetime 5 | import inspect 6 | import os 7 | import shutil 8 | import subprocess 9 | import sys 10 | import termios 11 | import time 12 | import tty 13 | from logging import DEBUG, INFO 14 | 15 | LOG_LEVEL = DEBUG if "-d" in sys.argv else INFO 16 | 17 | 18 | class Colors: 19 | CYAN = "\x1b[1;36m" 20 | RED = "\x1b[1;38;5;162m" 21 | GREEN = "\x1b[1;32m" 22 | WHITE = "\x1b[38;2;225;225;225m" 23 | RESET = "\x1b[0m" 24 | 25 | 26 | class Buttons: 27 | ESCAPE_CHAR = "\x1b" 28 | UP = "\x1b[A" 29 | DOWN = "\x1b[B" 30 | LEFT = "\x1b[D" 31 | BACKSPACE = "\x7f" 32 | CTRL_C = "\x03" 33 | CTRL_Z = "\x1a" 34 | 35 | 36 | def write_log(text, levelno): 37 | if levelno < LOG_LEVEL: 38 | return 39 | with open(f"{os.getenv('HOME')}/.apm_log.txt", "w+") as f: 40 | f.write( 41 | f"[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]" 42 | f" | {inspect.stack()[1].function}:" 43 | f"\n {text}\n\n" 44 | ) 45 | 46 | 47 | class Terminal: 48 | def __init__(self): 49 | self._stdin = sys.stdin 50 | self._stdout = sys.stdout 51 | # Save term settings before change it's settings. 52 | self._old_terminal_settings = termios.tcgetattr(self._stdin.fileno()) 53 | # Save length of last displayed text 54 | self._last_displayed_line_count = 0 55 | 56 | def _enable_raw_input_mode(self): 57 | """ 58 | Set terminal to touch to type 59 | so users don't need to press enter while interacting. 60 | """ 61 | tty.setcbreak(self._stdin.fileno()) 62 | write_log("Terminal set to touch to type/raw mode.", DEBUG) 63 | 64 | def _restore_terminal_mode(self): 65 | """Undo Live-Input and restore old settings""" 66 | self.show_cursor() 67 | self.reset_color() 68 | termios.tcsetattr( 69 | self._stdin.fileno(), termios.TCSADRAIN, self._old_terminal_settings 70 | ) 71 | write_log("Terminal set to normal mode.", DEBUG) 72 | 73 | def send_csi(self, code: str): 74 | self._stdout.write(f"\x1b[{code}") 75 | self._stdout.flush() 76 | 77 | def save_cursor_position(self): 78 | self.send_csi("s") 79 | write_log("Saving cursor position.", DEBUG) 80 | 81 | def reset_color(self): 82 | self.send_csi("0m") 83 | write_log("Resetting colors.", DEBUG) 84 | 85 | def hide_cursor(self): 86 | self.send_csi("?25l") 87 | write_log("Cursor hidden.", DEBUG) 88 | 89 | def show_cursor(self): 90 | self.send_csi("?25h") 91 | write_log("Cursor un-hidden.", DEBUG) 92 | 93 | def move_cursor_up(self, n: int = 1): 94 | self.send_csi(f"{n}A") 95 | write_log(f"Cursor moved up by {n} lines", DEBUG) 96 | 97 | def move_cursor_down(self, n: int = 1): 98 | self.send_csi(f"{n}B") 99 | write_log(f"Cursor moved down by {n} lines.", DEBUG) 100 | 101 | def clear_line(self): 102 | self.send_csi("2K") 103 | 104 | def clear_lines(self, n: int = 0): 105 | write_log(f"Clearing {n or self._last_displayed_line_count} lines.", DEBUG) 106 | for _ in range(0, n or self._last_displayed_line_count): 107 | self.move_cursor_up() 108 | self.clear_line() 109 | self._last_displayed_line_count = 0 110 | 111 | def print_lines(self, lines: list[str], clear_old_lines: bool = False): 112 | """ 113 | Write lines on terminal and save no of lines printed. 114 | """ 115 | if clear_old_lines: 116 | self.clear_lines() 117 | 118 | write_log(f"Printing {'\n'.join(lines)}.", DEBUG) 119 | 120 | for line in lines: 121 | self._stdout.write(line + "\n") 122 | self._stdout.flush() 123 | self._last_displayed_line_count = len(lines) 124 | 125 | def read_input(self, length: int = 1): 126 | _input = "" 127 | while len(_input) < length: 128 | _input += self._stdin.read(1) 129 | return _input 130 | 131 | 132 | class PackageManager(Terminal): 133 | def __init__(self): 134 | super().__init__() 135 | # User to perform action for. 136 | self.user = "0" 137 | # su -c OR adb shell 138 | self.executable_args = [] 139 | # Operation Mode [disable | enable | uninstall] 140 | self.operation_mode = None 141 | # Continuously keep performing operation selected in the start. 142 | self._continuous_operation_mode = "-c" in sys.argv 143 | 144 | # Full package list 145 | self._packages: list[str] = [] 146 | write_log("Package Manager Initialised.", INFO) 147 | 148 | def __enter__(self) -> "PackageManager": 149 | self._post_init_setup() 150 | write_log("__enter__ done", DEBUG) 151 | return self 152 | 153 | def __exit__(self, exc_type, exc_val, exc_tb): 154 | write_log(f"{exc_type} {exc_val}", DEBUG) 155 | 156 | self.clear_lines() 157 | exit_code = 0 158 | if exc_type and not issubclass(exc_type, KeyboardInterrupt | SystemExit): 159 | exit_code = 1 160 | write_log(text=f"{exc_type} {exc_val}", levelno=INFO) 161 | 162 | if issubclass(exc_type, SystemExit): 163 | sys.exit(exit_code) 164 | 165 | self._cleanup_and_exit(exit_code) 166 | 167 | def _post_init_setup(self): 168 | # Check for su/adb and exit if it's not available 169 | if "--adb" in sys.argv: 170 | self._check_adb() 171 | else: 172 | self._check_super_user_access() 173 | 174 | self._set_user() 175 | # Save Cursor Position 176 | self.save_cursor_position() 177 | # Enable Live input 178 | self._enable_raw_input_mode() 179 | # Remove Cursor 180 | self.hide_cursor() 181 | 182 | write_log(text="Post-Init setup done.", levelno=INFO) 183 | 184 | def _cleanup_and_exit(self, exit_code): 185 | self._restore_terminal_mode() 186 | write_log(f"Exiting with code: {exit_code}", INFO) 187 | sys.exit(exit_code) 188 | 189 | def _exit_with_err(self, err: str): 190 | write_log(f"Exiting with err: {err}", DEBUG) 191 | print(f"{Colors.RED}{err}{Colors.RESET}") 192 | self._cleanup_and_exit(1) 193 | 194 | def _check_super_user_access(self) -> None: 195 | """ 196 | Go through known SU Binary locations and check for executable access 197 | Set the binary as default or exit with error. 198 | """ 199 | su_paths = [ 200 | "/sbin/su", 201 | "/system/sbin/su", 202 | "/system/bin/su", 203 | "/system/xbin/su", 204 | "/su/bin/su", 205 | "/magisk/.core/bin/su", 206 | ] 207 | for path in su_paths: 208 | if os.access(path, os.X_OK): 209 | self.executable_args.extend([path, "-c"]) 210 | write_log(text=f"Found su binary in path: {path}", levelno=INFO) 211 | break 212 | else: 213 | write_log(text="SU binary not found. Exiting.", levelno=INFO) 214 | self._exit_with_err("SU Binary not found\nAre you Rooted?") 215 | 216 | def _check_adb(self) -> None: 217 | adb_binary = shutil.which("adb") 218 | 219 | if not adb_binary: 220 | self._exit_with_err("adb not found.") 221 | print( 222 | f"adb server running in bg kill it with {Colors.GREEN}'pkill -efn adb'{Colors.RESET}" 223 | ) 224 | devices = self._run_shell_cmd([adb_binary, "get-state"]) 225 | if "error" in devices: 226 | self._exit_with_err("No devices connected to adb") 227 | self.executable_args = [adb_binary, "shell"] 228 | 229 | def _set_user(self): 230 | if "--user" not in sys.argv: 231 | return 232 | user_arg_index = sys.argv.index("--user") 233 | try: 234 | self.user = sys.argv[user_arg_index + 1] 235 | if not self.user.isdigit(): 236 | self._exit_with_err("--user requires an integer argument") 237 | except IndexError: 238 | self._exit_with_err("--user requires an integer argument") 239 | 240 | def create_operation_command(self, package_name: str) -> list[str]: 241 | return [ 242 | *self.executable_args, 243 | "pm", 244 | self.operation_mode, 245 | f"--user {self.user}", 246 | package_name, 247 | ] 248 | 249 | @staticmethod 250 | def _run_shell_cmd(args: list): 251 | write_log(text=f"Running {' '.join(args)}", levelno=INFO) 252 | return subprocess.run( 253 | args, 254 | text=True, 255 | stdout=subprocess.PIPE, 256 | stderr=subprocess.STDOUT, 257 | ).stdout.strip() 258 | 259 | def _cache_packages(self, disabled: bool = False): 260 | args = [*self.executable_args, "pm", "list", "packages"] 261 | if disabled: 262 | args.append("-d") 263 | args.extend(["--user", self.user]) 264 | raw_packages = self._run_shell_cmd(args) 265 | self._packages = [pkg.removeprefix("package:") for pkg in raw_packages.split()] 266 | 267 | def search_cache(self, search_term: str, size: int = 5): 268 | matches = [] 269 | for pkg in self._packages: 270 | if search_term.lower() in pkg: 271 | matches.append(pkg) 272 | if len(matches) == size: 273 | break 274 | return matches 275 | 276 | def _prompt_for_operation_mode(self): 277 | """ 278 | Show main menu and set operation mode. 279 | """ 280 | opts = {"1": "enable", "2": "disable", "3": "uninstall", "4": "exit"} 281 | menu = [ 282 | "What would you like to do?", 283 | *[ 284 | f"{Colors.GREEN}{k}{Colors.WHITE}. {v.capitalize()}" 285 | for k, v in opts.items() 286 | ], 287 | ] 288 | while True: 289 | self.print_lines(menu, clear_old_lines=True) 290 | choice = self.read_input() 291 | if choice in opts.keys(): 292 | self.clear_lines() 293 | break 294 | 295 | if choice == "4": 296 | write_log(text="Exit chosen in main menu.", levelno=INFO) 297 | self._cleanup_and_exit(0) 298 | 299 | self.operation_mode = opts[choice] 300 | # adb compatibility 301 | # just pm disable doesn't work it needs disable-user 302 | if self.operation_mode == "disable": 303 | self.operation_mode += "-user" 304 | 305 | write_log(text=f"Set {self.operation_mode} as operation mode.", levelno=INFO) 306 | 307 | # fmt: off 308 | def _package_selection(self): 309 | search_term = "" 310 | pkg_index = 0 311 | selected_package = None 312 | while True: 313 | packages = self.search_cache(search_term) 314 | 315 | if packages: 316 | try: 317 | # noinspection PyStatementEffect 318 | packages[pkg_index] 319 | write_log(text=f"Selected {selected_package}", levelno=DEBUG) 320 | except IndexError: 321 | write_log(text=f"IndexError on index {pkg_index}.", levelno=DEBUG) 322 | pkg_index = 0 323 | 324 | selected_package = packages[pkg_index] 325 | packages[pkg_index] = ( 326 | f"{Colors.RED}>{Colors.WHITE} " 327 | f"{Colors.CYAN}{packages[pkg_index]}{Colors.WHITE}" 328 | ) 329 | 330 | self.print_lines( 331 | lines=[ 332 | f"{Colors.RED}app name:{Colors.WHITE} {search_term}", 333 | *packages, 334 | "-" * 32, 335 | f"Press {Colors.RED}<{Colors.WHITE} to go back " 336 | f"and {Colors.RED}!{Colors.WHITE} to quit", 337 | ], 338 | clear_old_lines=True, 339 | ) 340 | 341 | stdin = self.read_input() 342 | 343 | match stdin: 344 | case Buttons.CTRL_C | Buttons.CTRL_Z: 345 | write_log(text="Keyboard Interrupt received", levelno=INFO) 346 | self._cleanup_and_exit(0) 347 | 348 | case " ": 349 | write_log(text="Ignoring Spaces", levelno=DEBUG) 350 | continue 351 | 352 | case "!": 353 | write_log(text="Exit symbol ! pressed.", levelno=DEBUG) 354 | self._cleanup_and_exit(0) 355 | 356 | case "<": 357 | write_log(text="Main menu symbol pressed.", levelno=DEBUG) 358 | self.clear_lines() 359 | return 1 360 | 361 | case Buttons.ESCAPE_CHAR: 362 | button = stdin + self.read_input(2) 363 | write_log(text=f"{button} pressed.", levelno=DEBUG) 364 | 365 | match button: 366 | case Buttons.UP: 367 | pkg_index -= 1 368 | case Buttons.DOWN: 369 | pkg_index += 1 370 | case Buttons.LEFT: 371 | write_log("Main menu symbol pressed.", DEBUG) 372 | self.clear_lines() 373 | return 1 374 | 375 | case Buttons.BACKSPACE: 376 | search_term = search_term[:-1] 377 | write_log(text=f"Backspace: {search_term}.", levelno=DEBUG) 378 | 379 | case "\n": 380 | if packages: 381 | write_log(f"Enter Pressed on {selected_package}", INFO) 382 | self._run_shell_cmd( 383 | self.create_operation_command(selected_package) 384 | ) 385 | self.print_lines( 386 | lines=[ 387 | f"{Colors.RED}{self.operation_mode.capitalize()}{Colors.WHITE}: " 388 | f"{selected_package}" 389 | ], 390 | clear_old_lines=True, 391 | ) 392 | time.sleep(1) 393 | return 0 394 | write_log(text="Enter pressed on empty packages.", levelno=DEBUG) 395 | 396 | case _ if stdin.isalnum(): 397 | search_term += stdin 398 | write_log(text=f"Search term: {search_term}", levelno=DEBUG) 399 | 400 | case _: 401 | write_log(text=f"Ignoring {stdin} input.", levelno=DEBUG) 402 | # fmt: on 403 | 404 | def run(self): 405 | ret_code = 0 406 | is_first_run = True 407 | while 1: 408 | if any((is_first_run, ret_code == 1, not self._continuous_operation_mode)): 409 | self._prompt_for_operation_mode() 410 | self._cache_packages(self.operation_mode == "enable") 411 | ret_code = self._package_selection() 412 | is_first_run = False 413 | 414 | 415 | if __name__ == "__main__": 416 | if "-h" in sys.argv: 417 | print( 418 | f"""{Colors.RED}Interactive package manager by Ryuk.{Colors.WHITE} 419 | 420 | Usage: apm [options...] [--adb] [-c] [--user 0] 421 | {Colors.GREEN}-h{Colors.RESET}: show help 422 | {Colors.GREEN}-d{Colors.RESET}: enable debug logging 423 | {Colors.GREEN}-c{Colors.RESET}: continuous mode (doesn't return to main menu after performing action.) 424 | 425 | {Colors.GREEN}--adb{Colors.RESET}: uses adb instead of root. 426 | {Colors.GREEN}--user{Colors.RESET}: user to perform action for. (defaults to 0) 427 | """ 428 | ) 429 | sys.exit(0) 430 | 431 | with PackageManager() as pm: 432 | pm.run() 433 | --------------------------------------------------------------------------------