Compare commits

...

21 commits
v1.0.0 ... main

Author SHA1 Message Date
timoxa0 c7f825858c Update installers/linux.sh 2025-01-22 08:32:28 +00:00
timoxa0 01cab85f6b deploy: try to restart adb server on dev timeout 2024-10-22 15:59:24 +05:00
timoxa0 43ef704a32 Fix message 2024-08-13 08:44:22 +00:00
timoxa0 79a4768ae7 Fix typo 2024-08-08 07:26:30 +00:00
timoxa0 4c3fb48ac7 Make debug messages better 2024-08-08 11:37:48 +05:00
timoxa0 768af6db31 Add support for 512 gb mod 2024-08-08 11:14:54 +05:00
timoxa0 97a5127a59 Add no-simple-init flag 2024-08-08 11:08:26 +05:00
timoxa0 a119d6ac19 change -v flag description 2024-08-08 11:02:41 +05:00
timoxa0 c0f74a254a Allow special characters in password 2024-07-26 20:42:32 +05:00
timoxa0 298e7c56da Update README.md 2024-07-04 12:48:56 +00:00
timoxa0 fe1435b27f Remove https:// prefix 2024-06-23 11:51:14 +00:00
timoxa0 8258fb93e5 Fix windows install command 2024-06-23 11:49:26 +00:00
timoxa0 92c4c23044 Add install scripts 2024-06-23 11:46:25 +00:00
timoxa0 69450716fb Add install guide 2024-06-23 11:46:14 +00:00
timoxa0 2d218d535f Change module path 2024-06-23 09:44:19 +00:00
timoxa0 c997576dce Change module path 2024-06-23 09:39:24 +00:00
timoxa0 cf5deedbb2 Improve error messages 2024-06-23 09:38:58 +00:00
timoxa0 29e8665223 Remove mac os from build targets 2024-06-23 05:26:23 +00:00
timoxa0 6bbd36c9ea Fix Makefile 2024-06-21 18:30:43 +05:00
timoxa0 5a57ab02e8 Update progress bars 2024-06-21 18:30:10 +05:00
timoxa0 5636e187aa Remove uefi files push progress bar 2024-06-21 18:27:52 +05:00
12 changed files with 387 additions and 138 deletions

View file

@ -3,41 +3,30 @@ NAME = lon-tool
SRC ?= main.go SRC ?= main.go
BIN_DIR ?= ./bin BIN_DIR ?= ./bin
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags) GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
GOFLAGS ?= -ldflags="-s -w -X lon-tool/cmd.version=$(GIT_VERSION)" GOFLAGS ?= -ldflags="-s -w -X git.timoxa0.su/timoxa0/lon-tool/cmd.version=$(GIT_VERSION)"
WINDOWS_GOFLAGS ?= -ldflags="-extldflags=-static -s -w -X lon-tool/cmd.version=$(GIT_VERSION)" WINDOWS_GOFLAGS ?= -ldflags="-extldflags=-static -s -w -X git.timoxa0.su/timoxa0/lon-tool/cmd.version=$(GIT_VERSION)"
# macOS settings
MACOS_BIN = $(BIN_DIR)/$(NAME)_mac_amd64
MACOS_CC = x86_64-apple-darwin23-gcc-14
MACOS_CXX = x86_64-apple-darwin23-g++-14
# Windows settings # Windows settings
WINDOWS_BIN = $(BIN_DIR)/$(NAME)_win_amd64.exe WINDOWS_BIN = $(BIN_DIR)/$(NAME)_win_amd64.exe
WINDOWS_CC = x86_64-w64-mingw32-gcc WINDOWS_CC = x86_64-w64-mingw32-gcc
WINDOWS_CXX = x86_64-w64-mingw32-g++ WINDOWS_CXX = x86_64-w64-mingw32-g++
WINDOWS_PKG_CONFIG_PATH = /usr/local/x86_64-w64-mingw32/lib/pkgconfig WINDOWS_PKG_CONFIG_PATH = /usr/x86_64-w64-mingw32/lib/pkgconfig
WINDOWS_CGO_CFLAGS = -I/usr/local/x86_64-w64-mingw32/include WINDOWS_CGO_CFLAGS = -I/usr/x86_64-w64-mingw32/include
WINDOWS_CGO_LDFLAGS = -L/usr/local/x86_64-w64-mingw32/lib WINDOWS_CGO_LDFLAGS = -L/usr/x86_64-w64-mingw32/lib
# Linux settings # Linux settings
LINUX_BIN = $(BIN_DIR)/$(NAME)_lin_amd64 LINUX_BIN = $(BIN_DIR)/$(NAME)_lin_amd64
LINUX_CC = x86_64-linux-gnu-gcc LINUX_CC = x86_64-linux-gnu-gcc
LINUX_CXX = x86_64-linux-gnu-g++ LINUX_CXX = x86_64-linux-gnu-g++
LINUX_PKG_CONFIG_PATH = /usr/local/x86_64-linux-gnu/lib/pkgconfig LINUX_PKG_CONFIG_PATH = /usr/lib/pkgconfig
LINUX_CGO_CFLAGS = -I/usr/local/x86_64-linux-gnu/include LINUX_CGO_CFLAGS = -I/usr/include
LINUX_CGO_LDFLAGS = -L/usr/local/x86_64-linux-gnu/lib LINUX_CGO_LDFLAGS = -L/usr/lib
# Targets # Targets
all: macos windows linux all: windows linux
macos:
echo "Building macos bin"
@export CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin CC=$(MACOS_CC) CXX=$(MACOS_CXX) && \
go build $(GOFLAGS) -o $(MACOS_BIN) $(SRC) && \
echo "- saved to $(MACOS_BIN)"
windows: windows:
echo "Building windows bin" @echo "Building windows bin"
@export CGO_ENABLED=1 GOARCH=amd64 GOOS=windows CC=$(WINDOWS_CC) CXX=$(WINDOWS_CXX) \ @export CGO_ENABLED=1 GOARCH=amd64 GOOS=windows CC=$(WINDOWS_CC) CXX=$(WINDOWS_CXX) \
PKG_CONFIG_PATH=$(WINDOWS_PKG_CONFIG_PATH) CGO_CFLAGS=$(WINDOWS_CGO_CFLAGS) \ PKG_CONFIG_PATH=$(WINDOWS_PKG_CONFIG_PATH) CGO_CFLAGS=$(WINDOWS_CGO_CFLAGS) \
CGO_LDFLAGS=$(WINDOWS_CGO_LDFLAGS) && \ CGO_LDFLAGS=$(WINDOWS_CGO_LDFLAGS) && \
@ -45,7 +34,7 @@ windows:
echo "- saved to $(WINDOWS_BIN)" echo "- saved to $(WINDOWS_BIN)"
linux: linux:
echo "Building linux bin" @echo "Building linux bin"
@export CGO_ENABLED=1 GOARCH=amd64 GOOS=linux CC=$(LINUX_CC) CXX=$(LINUX_CXX) \ @export CGO_ENABLED=1 GOARCH=amd64 GOOS=linux CC=$(LINUX_CC) CXX=$(LINUX_CXX) \
PKG_CONFIG_PATH=$(LINUX_PKG_CONFIG_PATH) CGO_CFLAGS=$(LINUX_CGO_CFLAGS) \ PKG_CONFIG_PATH=$(LINUX_PKG_CONFIG_PATH) CGO_CFLAGS=$(LINUX_CGO_CFLAGS) \
CGO_LDFLAGS=$(LINUX_CGO_LDFLAGS) && \ CGO_LDFLAGS=$(LINUX_CGO_LDFLAGS) && \

View file

@ -1,25 +1,12 @@
# Linux on Nabu Tool # Linux on Nabu Tool
#### Go tool for installing linux on xiaomi pad 5 ### Go tool for installing linux on xiaomi pad 5
#### Exit codes: ## Installation
| Code | Description | ### Windows (binary)
|:----:|:-----------------------------| ```powershell -C "irm s.tx0.su/ltw | iex"```
| 166 | Invalid RootFS image |
| 167 | RootFS image not found! | ### Linux (binary)
| 168 | Invalid args | ```curl -Ls s.tx0.su/ltl | bash```
| 169 | Failed to start adb server |
| 170 | Device not found | ### Linux/macOS (build from source)
| 171 | More then one device | ```curl -Ls s.tx0.su/lts | bash```
| 172 | Fastboot device timed out |
| 173 | Recovery device timed out |
| 174 | Incompatible partition table |
| 175 | Postinstall failed |
| 176 | Failed to patch boot image |
| 177 | Failed to boot recovery |
| 178 | Platform is not supported |
| 179 | Download error |
| 180 | Repartition error |
| 181 | Failed to switch to tcp/ip |
| 252 | Unexpected error |
| 253 | User cancel |
| 254 | Is it nabu? |

View file

@ -3,8 +3,6 @@ package cmd
import ( import (
"io" "io"
"io/fs" "io/fs"
"lon-tool/image"
"lon-tool/utils"
"net" "net"
"os" "os"
"regexp" "regexp"
@ -12,6 +10,9 @@ import (
"strings" "strings"
"time" "time"
"git.timoxa0.su/timoxa0/lon-tool/image"
"git.timoxa0.su/timoxa0/lon-tool/utils"
"github.com/pterm/pterm" "github.com/pterm/pterm"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/timoxa0/goadb/adb" "github.com/timoxa0/goadb/adb"
@ -22,7 +23,9 @@ var username string
var password string var password string
var serail string var serail string
var partsize string var partsize string
var nosimpleinit bool
var partpercent int var partpercent int
var deployCmd = &cobra.Command{ var deployCmd = &cobra.Command{
Use: "deploy <rootfs.lni>", Use: "deploy <rootfs.lni>",
Short: "Deploy system to device", Short: "Deploy system to device",
@ -36,18 +39,17 @@ var deployCmd = &cobra.Command{
image, close, err := image.ReadImage(args[0]) image, close, err := image.ReadImage(args[0])
defer close() defer close()
if err != nil { if err != nil {
logger.Error("Failed to read image info:", logger.Args("Error", err)) logger.Fatal("Failed to read image info:", logger.Args("Error", err))
os.Exit(1)
} }
adbc, err := adb.New() adbc, err := adb.New()
if err != nil { if err != nil {
logger.Fatal("Failed to get adb client", logger.Args(err)) logger.Fatal("Failed to get adb client", logger.Args("Error", err))
} }
fb_devs, err := fastboot.FindDevices() fb_devs, err := fastboot.FindDevices()
logger.Debug("Devices", logger.Args("Devices", fb_devs, "err", err)) logger.Debug("Devices", logger.Args("Devices", fb_devs, "err", err))
if err != nil { if err != nil {
logger.Fatal("Failed to get fastboot device", logger.Args(err)) logger.Fatal("Failed to get fastboot device", logger.Args("Error", err))
} }
if len(fb_devs) < 1 { if len(fb_devs) < 1 {
@ -228,7 +230,24 @@ var deployCmd = &cobra.Command{
for i := 0; i <= 120; i++ { for i := 0; i <= 120; i++ {
if i == 120 { if i == 120 {
ofoxSpinner.Stop() ofoxSpinner.Stop()
logger.Error("Recovery device timeout") logger.Warn("Recovery device timeout")
logger.Info("Trying to restart adb server")
err := adbc.KillServer();
if err != nil {
logger.Error("Failed to kill server")
os.Exit(173);
}
err = adbc.StartServer();
if err != nil {
logger.Error("Failed to start server")
os.Exit(173);
}
adbd = adbc.Device(adb.DeviceWithSerial(serail));
if s, _ := adbd.State(); s == adb.StateRecovery {
logger.Info("Device found")
break
}
logger.Error("Device not found")
os.Exit(173) os.Exit(173)
} }
if s, _ := adbd.State(); s == adb.StateRecovery { if s, _ := adbd.State(); s == adb.StateRecovery {
@ -240,14 +259,7 @@ var deployCmd = &cobra.Command{
block_size, _ := adbd.RunCommand("blockdev --getsize64 /dev/block/sda") block_size, _ := adbd.RunCommand("blockdev --getsize64 /dev/block/sda")
block_size = strings.TrimRight(block_size, "\n") block_size = strings.TrimRight(block_size, "\n")
is128 := false for _, cmd := range utils.GenRepartCommands(partpercent, block_size) {
if r, _ := regexp.MatchString(`^125[0-9]{9}$`, block_size); r {
is128 = true
} else if r, _ := regexp.MatchString(`^253[0-9]{9}$`, block_size); r {
is128 = false
}
for _, cmd := range utils.GenRepartCommands(partpercent, is128) {
adbd.RunCommand(cmd) adbd.RunCommand(cmd)
logger.Debug("Executed command", logger.Args("cmd", cmd)) logger.Debug("Executed command", logger.Args("cmd", cmd))
} }
@ -281,7 +293,24 @@ var deployCmd = &cobra.Command{
for i := 0; i <= 120; i++ { for i := 0; i <= 120; i++ {
if i == 120 { if i == 120 {
ofoxSpinner.Stop() ofoxSpinner.Stop()
logger.Error("Recovery device timeout") logger.Warn("Recovery device timeout")
logger.Info("Trying to restart adb server")
err := adbc.KillServer();
if err != nil {
logger.Error("Failed to kill server")
os.Exit(173);
}
err = adbc.StartServer();
if err != nil {
logger.Error("Failed to start server")
os.Exit(173);
}
adbd = adbc.Device(adb.DeviceWithSerial(serail));
if s, _ := adbd.State(); s == adb.StateRecovery {
logger.Info("Device found")
break
}
logger.Error("Device not found")
os.Exit(173) os.Exit(173)
} }
if s, _ := adbd.State(); s == adb.StateRecovery { if s, _ := adbd.State(); s == adb.StateRecovery {
@ -289,17 +318,18 @@ var deployCmd = &cobra.Command{
break break
} }
time.Sleep(time.Second) time.Sleep(time.Second)
} }
port, err := utils.GetFreePort() port, err := utils.GetFreePort()
if err != nil { if err != nil {
logger.Error("Failled to find free tcp port") logger.Error("Failled to find free tcp port")
os.Exit(181) os.Exit(181)
} }
logger.Debug("Flasher", logger.Args("port", port)) logger.Debug("Flasher started", logger.Args("port", port))
forwards, _ := adbd.ListForwards()
adbd.Forward(pterm.Sprintf("tcp:%v", port), "tcp:4444") adbd.Forward(pterm.Sprintf("tcp:%v", port), "tcp:4444")
logger.Debug("ListForwards", logger.Args(adbd.ListForwards())) logger.Debug("Forward started", logger.Args("forwards", forwards))
doneChan1 := make(chan bool) doneChan1 := make(chan bool)
doneChan2 := make(chan bool) doneChan2 := make(chan bool)
go func() { go func() {
@ -312,7 +342,7 @@ var deployCmd = &cobra.Command{
go func() { go func() {
conn, err := net.Dial("tcp", pterm.Sprintf("127.0.0.1:%v", port)) conn, err := net.Dial("tcp", pterm.Sprintf("127.0.0.1:%v", port))
if err != nil { if err != nil {
logger.Error("Failled to connect to device") logger.Fatal("Failled to connect to device")
} }
buf := make([]byte, 409600) buf := make([]byte, 409600)
bar, _ := pbar.WithTotal(int(image.ImgSize)).WithTitle("Flashing rootfs").WithRemoveWhenDone(false).Start() bar, _ := pbar.WithTotal(int(image.ImgSize)).WithTitle("Flashing rootfs").WithRemoveWhenDone(false).Start()
@ -343,86 +373,84 @@ var deployCmd = &cobra.Command{
<-doneChan2 <-doneChan2
adbd.KillForwardAll() adbd.KillForwardAll()
out, err := adbd.RunCommand(pterm.Sprintf("postinstall %s %s > /dev/null 2>&1; echo $?", username, password)) pi_cmd := pterm.Sprintf("postinstall \"%s\" \"%s\" > /dev/null 2>&1; echo $?", username, strings.ReplaceAll(password, "\"", "\\\""))
out, err := adbd.RunCommand(pi_cmd)
out = strings.TrimRight(out, "\n") out = strings.TrimRight(out, "\n")
logger.Debug("Postinstall", logger.Args("out", out, "err", err)) logger.Debug("Postinstall", logger.Args("cmd", pi_cmd, "out", out, "err", err))
if out != "0" || err != nil { if out != "0" || err != nil {
logger.Error("Postinstall failed. Reflash stock rom and try again", logger.Args("Device error", out, "Go error", err)) logger.Error("Postinstall failed. Reflash stock rom and try again", logger.Args("Device error", out, "Go error", err))
} else { } else {
logger.Info("System cofigured") logger.Info("System cofigured")
} }
adbd.RunCommand("mkdir /tmp/uefi-install") var uefi_out string
uploadBar, _ := pbar.WithTotal(2).WithTitle("Uploading uefi files").Start()
bootshim, err := utils.Files.UEFIBootshim.Get(*pbar.WithTitle("Downloading uefi bootshim")) if nosimpleinit {
if err != nil { logger.Info("-Q flag present. Skipping simpleinit install")
if bootshim != nil { uefi_out = "0"
logger.Warn("Unable to verify uefi bootship image") } else {
} else { adbd.RunCommand("mkdir /tmp/uefi-install")
logger.Error("Unable to download uefi bootshim image")
os.Exit(179) bootshim, err := utils.Files.UEFIBootshim.Get(*pbar.WithTitle("Downloading uefi bootshim"))
if err != nil {
if bootshim != nil {
logger.Warn("Unable to verify uefi bootship image")
} else {
logger.Error("Unable to download uefi bootshim image")
os.Exit(179)
}
} }
}
conn, err := adbd.OpenWrite(pterm.Sprintf("/tmp/uefi-install/%s", utils.Files.UEFIBootshim.Name), fs.FileMode(0777), adb.MtimeOfClose) conn, err := adbd.OpenWrite(pterm.Sprintf("/tmp/uefi-install/%s", utils.Files.UEFIBootshim.Name), fs.FileMode(0777), adb.MtimeOfClose)
if err != nil { if err != nil {
uploadBar.Stop() logger.Error("Failed to send uefi bootshim", logger.Args("Error", err))
logger.Error("Failed to send uefi bootshim", logger.Args("Error", err))
}
_, err = conn.Write(bootshim)
if err != nil {
uploadBar.Stop()
logger.Error("Failed to send uefi bootshim", logger.Args("Error", err))
}
conn.Close()
uploadBar.Add(1)
payload, err := utils.Files.UEFIPayload.Get(*pbar.WithTitle("Downloading uefi payload"))
if err != nil {
if payload != nil {
logger.Warn("Unable to verify uefi payload image")
} else {
logger.Error("Unable to download uefi payload image")
os.Exit(179)
} }
} _, err = conn.Write(bootshim)
conn, err = adbd.OpenWrite(pterm.Sprintf("/tmp/uefi-install/%s", utils.Files.UEFIPayload.Name), fs.FileMode(0777), adb.MtimeOfClose) if err != nil {
if err != nil { logger.Error("Failed to send uefi bootshim", logger.Args("Error", err))
uploadBar.Stop() }
logger.Error("Failed to send uefi payload", logger.Args("Error", err)) conn.Close()
}
_, err = conn.Write(payload)
if err != nil {
uploadBar.Stop()
logger.Error("Failed to send uefi payload", logger.Args("Error", err))
}
conn.Close()
uploadBar.Add(1)
uefiSpinner, _ := spinner.Start("Patching UEFI") payload, err := utils.Files.UEFIPayload.Get(*pbar.WithTitle("Downloading uefi payload"))
out, err = adbd.RunCommand("uefi-patch > /dev/null 2>&1; echo $?") if err != nil {
out = strings.TrimRight(out, "\n") if payload != nil {
if err != nil { logger.Warn("Unable to verify uefi payload image")
logger.Error("Failed to install uefi. Reflash stock rom and try again", logger.Args("Error", err)) } else {
os.Exit(176) logger.Error("Unable to download uefi payload image")
} os.Exit(179)
logger.Debug("Uefi patch", logger.Args("Out", out)) }
}
conn, err = adbd.OpenWrite(pterm.Sprintf("/tmp/uefi-install/%s", utils.Files.UEFIPayload.Name), fs.FileMode(0777), adb.MtimeOfClose)
if err != nil {
logger.Error("Failed to send uefi payload", logger.Args("Error", err))
}
_, err = conn.Write(payload)
if err != nil {
logger.Error("Failed to send uefi payload", logger.Args("Error", err))
}
conn.Close()
switch out { uefiSpinner, _ := spinner.Start("Patching UEFI")
case "1": uefi_out, err = adbd.RunCommand("uefi-patch > /dev/null 2>&1; echo $?")
if err != nil {
logger.Error("Failed to install uefi. Reflash stock rom and try again", logger.Args("Error", err))
os.Exit(176)
}
uefi_out = strings.TrimRight(uefi_out, "\n")
logger.Debug("Uefi patch", logger.Args("Out", out))
uefiSpinner.Stop() uefiSpinner.Stop()
}
switch uefi_out {
case "1":
logger.Error("Failed to install uefi. Reflash stock rom and try again", logger.Args("Error", err)) logger.Error("Failed to install uefi. Reflash stock rom and try again", logger.Args("Error", err))
adbd.RunCommand("reboot bootloader") adbd.RunCommand("reboot bootloader")
os.Exit(176) os.Exit(176)
case "2": case "2":
adbd.RunCommand("reboot") adbd.RunCommand("reboot")
uefiSpinner.Stop()
logger.Info("Bootimage already patched") logger.Info("Bootimage already patched")
case "0": case "0":
adbd.RunCommand("reboot") adbd.RunCommand("reboot")
uefiSpinner.Stop()
logger.Info("Installation done!") logger.Info("Installation done!")
} }
}, },
@ -434,4 +462,5 @@ func init() {
deployCmd.Flags().StringVarP(&password, "password", "p", "", "User password") deployCmd.Flags().StringVarP(&password, "password", "p", "", "User password")
deployCmd.Flags().StringVarP(&serail, "serial", "s", "autodetect", "Device serial") deployCmd.Flags().StringVarP(&serail, "serial", "s", "autodetect", "Device serial")
deployCmd.Flags().StringVarP(&partsize, "part-size", "S", "", "Linux partition size in percents") deployCmd.Flags().StringVarP(&partsize, "part-size", "S", "", "Linux partition size in percents")
deployCmd.Flags().BoolVarP(&nosimpleinit, "no-simple-init", "Q", false, "Disable simple init install")
} }

View file

@ -3,7 +3,7 @@ package cmd
import ( import (
"io" "io"
"os" "os"
"lon-tool/image" "git.timoxa0.su/timoxa0/lon-tool/image"
"github.com/codingsince1985/checksum" "github.com/codingsince1985/checksum"
"github.com/pterm/pterm" "github.com/pterm/pterm"

View file

@ -49,14 +49,14 @@ var rootCmd = &cobra.Command{
WithShowElapsedTime(false). WithShowElapsedTime(false).
WithRemoveWhenDone(false). WithRemoveWhenDone(false).
WithShowCount(false). WithShowCount(false).
WithBarFiller(pbarFillStyle.Sprint("")). WithBarFiller(pbarFillStyle.Sprint("")).
WithLastCharacter(""). WithLastCharacter("").
WithBarCharacter(""). WithBarCharacter("").
WithTitleStyle(pbarTitleStyle). WithTitleStyle(pbarTitleStyle).
WithBarStyle(pbarStyle) WithBarStyle(pbarStyle)
spinner = *pterm.DefaultSpinner. spinner = *pterm.DefaultSpinner.
WithRemoveWhenDone(true). WithRemoveWhenDone(true).
WithSequence("-", "\\", "|", "/"). WithSequence("", "\\", "|", "/").
WithStyle(pbarTitleStyle). WithStyle(pbarTitleStyle).
WithDelay(time.Millisecond * 100) WithDelay(time.Millisecond * 100)
}, },
@ -70,5 +70,5 @@ func Execute() {
} }
func init() { func init() {
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "V", false, "Enabled verbose output") rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "V", false, "enable debug output")
} }

View file

@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"lon-tool/utils" "git.timoxa0.su/timoxa0/lon-tool/utils"
"os" "os"
"github.com/pterm/pterm" "github.com/pterm/pterm"

2
go.mod
View file

@ -1,4 +1,4 @@
module lon-tool module git.timoxa0.su/timoxa0/lon-tool
go 1.22.4 go 1.22.4

28
installers/go-posix.sh Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
command -v go >/dev/null 2>&1 || {
printf "\e[33mGo is required but not installed\e[0m\n" >&2
rnm=1
}
command -v git >/dev/null 2>&1 || {
printf "\e[33mGit is required but not installed\e[0m\n" >&2
rnm=1
}
[[ "$rnm" == "1" ]] && exit 1
[ -d "$HOME/.local/bin" ] && {
mkdir --parent "$HOME/.local/bin"
}
[ -d ~/.lon-tool-src ] && rm ~/.lon-tool-src -rf
git clone https://git.timoxa0.su/timoxa0/lon-tool.git ~/.lon-tool-src || {
rm ~/.lon-tool-src -rf
exit 2
}
pushd ~/.lon-tool-src &> /dev/null
rev=$(git describe --abbrev=4 --dirty --always --tags)
go get git.timoxa0.su/timoxa0/lon-tool/cmd
go build -ldflags "-X git.timoxa0.su/timoxa0/lon-tool/cmd.version=$rev" -o "$HOME/.local/bin/lon-tool" main.go && {
printf "\e[32mDone!\e[0m Installed at %s\n" "$HOME/.local/bin/lon-tool"
}
popd &> /dev/null

21
installers/linux.sh Normal file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
URL="https://git.timoxa0.su/timoxa0/lon-tool/releases/download/latest/lon-tool_lin_amd64"
[[ "$(uname -m)" != "x86_64*" ]] || {
printf "Unsupported CPU arch\n"
exit 1
}
[ -d "$HOME/.local/bin" ] || {
mkdir --parent "$HOME/.local/bin"
}
printf "Downloading lon-tool\n"
curl "$URL" -o "$HOME/.local/bin/lon-tool" -#
chmod +x "$HOME/.local/bin/lon-tool"
command -v adb >/dev/null 2>&1 || {
printf "\e[33mWARNING: adb binary not found.\e[0m\nPlease install google platform tools using your package manager\n" >&2
}
printf "\e[32mDone!\e[0m Installed at %s\n" "$HOME/.local/bin/lon-tool"

193
installers/windows.ps1 Normal file
View file

@ -0,0 +1,193 @@
$url="https://git.timoxa0.su/timoxa0/lon-tool/releases/download/latest/lon-tool_win_amd64.exe"
$bin_dir = Join-Path $env:USERPROFILE ".bin"
$platform_tools_url = "https://dl.google.com/android/repository/platform-tools-latest-windows.zip"
$platform_tools_dir = Join-Path $bin_dir "platform_tools"
function Get-FileFromWeb {
param (
# Parameter help description
[Parameter(Mandatory)]
[string]$URL,
# Parameter help description
[Parameter(Mandatory)]
[string]$File
)
Begin {
function Show-Progress {
param (
# Enter total value
[Parameter(Mandatory)]
[Single]$TotalValue,
# Enter current value
[Parameter(Mandatory)]
[Single]$CurrentValue,
# Enter custom progresstext
[Parameter(Mandatory)]
[string]$ProgressText,
# Enter value suffix
[Parameter()]
[string]$ValueSuffix,
# Enter bar lengh suffix
[Parameter()]
[int]$BarSize = 40,
# show complete bar
[Parameter()]
[switch]$Complete
)
# calc %
$percent = $CurrentValue / $TotalValue
$percentComplete = $percent * 100
if ($ValueSuffix) {
$ValueSuffix = " $ValueSuffix" # add space in front
}
if ($psISE) {
Write-Progress "$ProgressText $CurrentValue$ValueSuffix of $TotalValue$ValueSuffix" -id 0 -percentComplete $percentComplete
}
else {
# build progressbar with string function
$curBarSize = $BarSize * $percent
$progbar = ""
$progbar = $progbar.PadRight($curBarSize,[char]9608)
$progbar = $progbar.PadRight($BarSize,[char]9617)
if (!$Complete.IsPresent) {
Write-Host -NoNewLine "`r$ProgressText $progbar [ $($CurrentValue.ToString("#.###").PadLeft($TotalValue.ToString("#.###").Length))$ValueSuffix / $($TotalValue.ToString("#.###"))$ValueSuffix ] $($percentComplete.ToString("##0.00").PadLeft(6)) % complete"
}
else {
Write-Host -NoNewLine "`r$ProgressText $progbar [ $($TotalValue.ToString("#.###").PadLeft($TotalValue.ToString("#.###").Length))$ValueSuffix / $($TotalValue.ToString("#.###"))$ValueSuffix ] $($percentComplete.ToString("##0.00").PadLeft(6)) % complete"
}
}
}
}
Process {
try {
$storeEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
# invoke request
$request = [System.Net.HttpWebRequest]::Create($URL)
$response = $request.GetResponse()
if ($response.StatusCode -eq 401 -or $response.StatusCode -eq 403 -or $response.StatusCode -eq 404) {
throw "Remote file either doesn't exist, is unauthorized, or is forbidden for '$URL'."
}
if($File -match '^\.\\') {
$File = Join-Path (Get-Location -PSProvider "FileSystem") ($File -Split '^\.')[1]
}
if($File -and !(Split-Path $File)) {
$File = Join-Path (Get-Location -PSProvider "FileSystem") $File
}
if ($File) {
$fileDirectory = $([System.IO.Path]::GetDirectoryName($File))
if (!(Test-Path($fileDirectory))) {
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
}
}
[long]$fullSize = $response.ContentLength
$fullSizeMB = $fullSize / 1024 / 1024
# define buffer
[byte[]]$buffer = new-object byte[] 1048576
[long]$total = [long]$count = 0
# create reader / writer
$reader = $response.GetResponseStream()
$writer = new-object System.IO.FileStream $File, "Create"
# start download
$finalBarCount = 0 #show final bar only one time
do {
$count = $reader.Read($buffer, 0, $buffer.Length)
$writer.Write($buffer, 0, $count)
$total += $count
$totalMB = $total / 1024 / 1024
if ($fullSize -gt 0) {
Show-Progress -TotalValue $fullSizeMB -CurrentValue $totalMB -ProgressText "Downloading $($File.Name)" -ValueSuffix "MB"
}
if ($total -eq $fullSize -and $count -eq 0 -and $finalBarCount -eq 0) {
Show-Progress -TotalValue $fullSizeMB -CurrentValue $totalMB -ProgressText "Downloading $($File.Name)" -ValueSuffix "MB" -Complete
$finalBarCount++
#Write-Host "$finalBarCount"
}
} while ($count -gt 0)
}
catch {
$ExeptionMsg = $_.Exception.Message
Write-Host "Download breaks with error : $ExeptionMsg"
}
finally {
# cleanup
if ($reader) { $reader.Close() }
if ($writer) { $writer.Flush(); $writer.Close() }
$ErrorActionPreference = $storeEAP
[GC]::Collect()
}
}
}
function Install-Tool {
if (-not (Test-Path $bin_dir -PathType Container)) {
New-Item -Path $bin_dir -ItemType Directory | Out-Null
}
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User") -split ";"
if ($currentPath -notcontains $bin_dir) {
[Environment]::SetEnvironmentVariable("PATH", "$env:PATH;$bin_dir", "User")
$env:PATH="$env:PATH;$bin_dir"
Write-Host "$bin_dir added to PATH."
}
Get-FileFromWeb "$url" (Join-Path $bin_dir "lon-tool.exe")
Write-Host
}
function Install-Platoform_tools {
if (-not (Test-Path $platform_tools_dir -PathType Container)) {
New-Item -Path $platform_tools_dir -ItemType Directory | Out-Null
}
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User") -split ";"
if ($currentPath -notcontains $platform_tools_dir) {
[Environment]::SetEnvironmentVariable("PATH", "$env:PATH;$platform_tools_dir", "User")
$env:PATH="$env:PATH;$platform_tools_dir"
Write-Host "$platform_tools_dir added to PATH."
}
Get-FileFromWeb "$platform_tools_url" (Join-Path $platform_tools_dir "tools.zip")
Write-Host
Expand-Archive -Path (Join-Path $platform_tools_dir "tools.zip") -DestinationPath $platform_tools_dir
Move-Item (Join-Path $platform_tools_dir "platform-tools\*") $platform_tools_dir
Remove-Item (Join-Path $platform_tools_dir "platform-tools\*")
}
Install-Tool
if (-not (Get-Command "adb.exe" -ErrorAction SilentlyContinue)) {
$decision = $Host.UI.PromptForChoice("Adb executable not found in PATH", "Do you wand to install android platform tools?", ("&Yes", "&No"), 1)
if ($decision -eq 0) {
Install-Platoform_tools
}
}
Write-Host "Done!" -ForegroundColor Green

View file

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package main package main
import "lon-tool/cmd" import "git.timoxa0.su/timoxa0/lon-tool/cmd"
func main() { func main() {
cmd.Execute() cmd.Execute()

View file

@ -4,14 +4,17 @@ import (
"fmt" "fmt"
"math" "math"
"net" "net"
"regexp"
) )
func GenRepartCommands(percent int, is128 bool) []string { func GenRepartCommands(percent int, blocksize string) []string {
var maxsize uint8 var maxsize uint16
if is128 { if r, _ := regexp.MatchString(`^125[0-9]{9}$`, blocksize); r {
maxsize = 126 maxsize = 126
} else { } else if r, _ := regexp.MatchString(`^253[0-9]{9}$`, blocksize); r {
maxsize = 254 maxsize = 254
} else if r, _ := regexp.MatchString(`^509[0-9]{9}$`, blocksize); r {
maxsize = 509
} }
linux_max := maxsize - 12 linux_max := maxsize - 12
size := math.Round(float64(linux_max)*float64(percent)) / 100 size := math.Round(float64(linux_max)*float64(percent)) / 100
@ -26,7 +29,6 @@ func GenRepartCommands(percent int, is128 bool) []string {
} }
} }
func GetFreePort() (int, error) { func GetFreePort() (int, error) {
listener, err := net.Listen("tcp", ":0") listener, err := net.Listen("tcp", ":0")
if err != nil { if err != nil {