Compare commits

8 Commits

Author SHA1 Message Date
3b6a582937 added a package in newer format 2025-10-25 22:43:24 -03:00
9b15d014c1 package dependency test 2025-10-11 19:14:37 -03:00
39d315c09e removing old package format 2025-10-05 11:24:41 -03:00
3f5a0e3898 new package format 2025-10-05 11:23:56 -03:00
e556b4c982 removing source code from test branch 2025-08-20 15:35:33 -03:00
bd63bf8b1f test package compiling 2025-08-20 15:30:04 -03:00
f75808b8c4 removed files from test branch 2025-08-20 15:29:25 -03:00
2abcec6384 test package 2025-08-20 14:45:11 -03:00
11 changed files with 0 additions and 2809 deletions

163
README.md
View File

@@ -1,163 +0,0 @@
# 📦 Packets Custom Package Manager for Linux
> A fast and minimal package manager written in Go with Lua hooks, local network discovery, and SQLite-based indexing.
---
## 📘 Overview
**Packets** is a lightweight package manager for Linux, written in Go. It supports:
- Installation and removal of packages
- Dependency resolution and upgrading
- `.tar.zst` compressed packages with `manifest.toml` metadata
- Lua-based install/remove hooks
- Local cache with SHA-256 validation
- Peer-to-peer discovery over LAN
- Remote package syncing via HTTP
- SQLite-based local database
---
## 📁 Directory Structure
| Path | Description |
|-----------------------|----------------------------------|
| `/etc/packets/` | Configuration files |
| `/opt/packets/` | Installed package data |
| `/var/cache/packets/` | Cached `.tar.zst` package files |
(This can be changed in `/etc/packets/config.toml`)
---
# Available Commands
| Command | Description |
|---------------------------|----------------------------------------------------------------------------|
|`packets install <name>` | Install a package (resolves dependencies, executes Lua install hook) |
|`packets remove <name>` | Remove a package (executes Lua remove hook) |
|`packets upgrade <name>` | Upgrade a package by checking family and serial in the manifest |
|`packets sync [url]` | Synchronize index.db from remote HTTP source |
|`packets serve init/stop` | Starts and stop the LAN service daemon |
|`packets list` | List all installed packages |
|`packets info` | Get technical package information |
|`packets search` | List all packages in index.db |
# 📦 Package Format
Packages must be compressed as .tar.zst and include:
- ├── manifest.toml # Package metadata
- ├── data/ # Files to install
- ├── install.lua # Lua install hook
- └── remove.lua # Lua remove hook
## Example manifest.toml
[Info]
name = "packets"
version = "1.0.0"
description = "offline and online packetmanager"
dependencies = []
author = "robo"
family = "1f84ca15-5077-4f1d-a370-0ec860766eb2"
serial = 0
[Hooks]
install = "install.lua"
remove = "remove.lua"
--
# 🔄 Installation Process
- Check if package is already cached and validated via SHA-256.
- If not, search the package:
Via LAN: Sends UDP broadcast (Q:filename) to peers.
Via HTTP: Downloads from configured mirrors.
Decompress .tar.zst, install files.
Execute Lua install hook.
# 🧩 Core Features
✅ Dependency Resolution
Installs required dependencies listed in the manifest.
## 🌐 LAN Discovery
Broadcasts package request to devices in the same network via UDP.
## 📡 Remote Download
Downloads package via HTTP if not found on LAN.
## 🔒 Security
SHA-256 checksum validation
Path validation to avoid exploits (..)
Safe, sandboxed Lua runtime with limited API
# 🌍 Global Variables Available in Lua Scripts
During the execution of install.lua and remove.lua hooks, some global variables are automatically provided to the Lua environment. These help simplify file path handling and access to package-specific directories.
## Available variables:
|Name |Type | Description
|--------------------|--------|--------------------------------------------------------------------------|
|packets_package_dir | string| Absolute path to the package's data directory (e.g., /opt/packets/...) |
| packets_bin_dir | string| Path where executables should be installed (e.g., /usr/bin) |
|script | string| Path to the currently executing script (e.g., "install.lua") |
|data_dir | string| Path to the /data folder of the current package |
### Example usage in Lua:
print("Installing into: " .. packets_bin_dir)
print("Package data in: " .. data_dir)
-- Copy a binary to /usr/bin
os.copy(path_join(data_dir, "htop"), path_join(packets_bin_dir, "htop"))
These variables are preloaded in the Lua environment—no need to manually declare or initialize them.
## 🛠️ Allowed Lua API (install/remove hooks)
To ensure security, only a limited set of safe functions are exposed in Lua hooks:
os.remove(path)
os.rename(old, new)
os.copy(source, target)
os.symlink(source, target)
io.open(path, mode)
os.mkdir(path, filemode)
path_join(...)
### Note: Dangerous functions like os.execute, os.getenv, etc. are removed.
## 🗃️ Databases
index.db: Available packages (after sync)
installed.db: Packages currently installed
# ⚠️ Restrictions & Notes
Linux only (//go:build linux)
Root permissions required for most commands
Changing dataDir triggers prompt to migrate installed packages
Binaries in binDir are not automatically moved if path changes
Do not manually edit lastDataDir
# TODO
- Auto-compile packages
- An web page to upload packages

View File

@@ -1,37 +0,0 @@
package main
import (
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"packets/internal"
"github.com/BurntSushi/toml"
)
type ConfigTOML struct {
Config struct {
DefaultHttpPort int `toml:"httpPort"`
DefaultCacheDir string `toml:"cacheDir"`
} `toml:"Config"`
}
func main() {
internal.PacketsPackageDir()
var cfg ConfigTOML
toml.Decode(filepath.Join(internal.PacketsPackageDir(), "config.toml"), &cfg)
pid := os.Getpid()
if err := os.WriteFile(filepath.Join(internal.PacketsPackageDir(), "http.pid"), []byte(fmt.Sprint(pid)), 0644); err != nil {
fmt.Println("error saving subprocess pid", err)
}
fs := http.FileServer(http.Dir(cfg.Config.DefaultCacheDir))
http.Handle("/", fs)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", cfg.Config.DefaultHttpPort), nil))
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,65 +0,0 @@
package main
import (
"fmt"
"log"
"net"
"os"
"packets/internal"
"path/filepath"
"strings"
"github.com/BurntSushi/toml"
)
type ConfigTOML struct {
Config struct {
HttpPort int `toml:"httpPort"`
CacheDir string `toml:"cacheDir"`
} `toml:"Config"`
}
var cfg ConfigTOML
func CheckDownloaded(filename string) bool {
_, err := os.Stat(filepath.Join(cfg.Config.CacheDir))
if os.IsNotExist(err) {
return false
} else {
return true
}
}
func main() {
pid := os.Getpid()
if err := os.WriteFile(filepath.Join(internal.PacketsPackageDir(), "udp.pid"), []byte(fmt.Sprint(pid)), 0644); err != nil {
fmt.Println("error saving subprocess pid", err)
}
toml.Decode(filepath.Join(internal.PacketsPackageDir(), "config.toml"), &cfg)
addr := net.UDPAddr{IP: net.IPv4zero, Port: 1333}
conn, err := net.ListenUDP("udp", &addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
buf := make([]byte, 1500)
for {
n, remote, err := conn.ReadFromUDP(buf)
if err != nil {
log.Println("error creating udp socket", err)
}
msg := string(buf[:n])
if !strings.HasPrefix(msg, "Q:") {
continue
}
filename := strings.TrimPrefix(msg, "Q:")
if CheckDownloaded(filename) {
reply := fmt.Sprintf("H:%s:%d", filename, cfg.Config.HttpPort)
conn.WriteToUDP([]byte(reply), remote)
}
}
}

View File

@@ -1 +0,0 @@
-- PACKETS SCRIPTS EXAMPLES

31
go.mod
View File

@@ -1,31 +0,0 @@
module packets
go 1.24.4
require (
github.com/BurntSushi/toml v1.5.0
github.com/klauspost/compress v1.18.0
github.com/schollz/progressbar/v3 v3.18.0
github.com/spf13/cobra v1.9.1
github.com/yuin/gopher-lua v1.1.1
golang.org/x/net v0.41.0
modernc.org/sqlite v1.38.0
)
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.7 // indirect
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
modernc.org/libc v1.65.10 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)

85
go.sum
View File

@@ -1,85 +0,0 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA=
modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc=
modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI=
modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=

View File

@@ -1,557 +0,0 @@
package internal
import (
"archive/tar"
"fmt"
"io"
"io/fs"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/BurntSushi/toml"
"github.com/klauspost/compress/zstd"
lua "github.com/yuin/gopher-lua"
)
var AllowedCmds = map[string]string{
"go": "go", // "Go code compiler"
"gcc": "gcc", // "C"
"g++": "g++", // "C++"
"rustc": "rustc", // "Rust"
"javac": "javac", // "Java"
"luac": "luac", // "Lua"
"pyinstaller": "pyinstaller", // "Python"
"kotlinc": "kotlinc", // "Kotlin"
"mcs": "mcs", // "C# compiler"
"swiftc": "swiftc", // "Swift compiler"
"ts": "tsc", // "TypeScript compiler"
"ruby": "rubyc", // "Ruby compiler"
}
type ConfigTOML struct {
Config struct {
HttpPort int `toml:"httpPort"`
CacheDir string `toml:"cacheDir"`
AutoDeleteCacheDir bool `toml:"dayToDeleteCacheDir"`
DaysToDelete int `toml:"daysToDelete"`
DataDir string `toml:"dataDir"`
BinDir string `toml:"binDir"`
LastDataDir string `toml:"lastDataDir"`
} `toml:"Config"`
}
type Manifest struct {
Info struct {
Name string `toml:"name"`
Version string `toml:"version"`
Description string `toml:"description"`
Dependencies []string `toml:"dependencies"`
Author string `toml:"author"`
Family string `toml:"family"`
Serial uint `toml:"serial"`
} `toml:"Info"`
Hooks struct {
Install string `toml:"install"`
Remove string `toml:"remove"`
} `toml:"Hooks"`
}
var SandboxDir string
func PacketsPackageDir() string {
out, _ := exec.Command("uname", "-s").Output()
if uname := strings.TrimSpace(string(out)); uname == "J2ME" {
_, err := os.Stat("packets.help")
if os.IsNotExist(err) {
err = nil
var thedirectory string
err := filepath.WalkDir("/mnt", func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
thedirectory = filepath.Join(path, "packets")
if err := os.Mkdir(thedirectory, 0644); err != nil {
return err
}
if err := os.WriteFile("packets.help", []byte(thedirectory), 0644); err != nil {
return err
}
if err := os.Mkdir(filepath.Join(filepath.Join(thedirectory, "cache")), 0644); err != nil {
return err
}
if err := os.Mkdir(filepath.Join(filepath.Join(thedirectory, "packages")), 0644); err != nil {
return err
}
if err := os.Mkdir(filepath.Join(filepath.Join(thedirectory, "bin")), 0644); err != nil {
return err
}
return nil
}
return nil
})
if err != nil {
log.Fatal(err)
}
return thedirectory
}
byt, err := os.ReadFile("packets.help")
if err != nil {
log.Fatal(err)
}
return string(byt)
} else {
return "/etc/packets"
}
}
func ManifestReadXZ(path string) (*Manifest, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
zr, err := zstd.NewReader(f)
if err != nil {
return nil, err
}
defer zr.Close()
tarReader := tar.NewReader(zr)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
if filepath.Base(header.Name) == "manifest.toml" {
decoder := toml.NewDecoder(tarReader)
var manifest Manifest
if _, err := decoder.Decode(&manifest); err != nil {
log.Fatal(err)
}
return &manifest, nil
}
}
return nil, fmt.Errorf("can't find manifest.toml")
}
func DefaultConfigTOML() *ConfigTOML {
var cfg ConfigTOML
out, _ := exec.Command("uname", "-s").Output()
if uname := strings.TrimSpace(string(out)); uname == "J2ME" {
cfg.Config.HttpPort = 9123
cfg.Config.AutoDeleteCacheDir = false
cfg.Config.CacheDir = filepath.Join(PacketsPackageDir(), "cache")
cfg.Config.DataDir = filepath.Join(PacketsPackageDir(), "data")
cfg.Config.DaysToDelete = -1
cfg.Config.BinDir = filepath.Join(PacketsPackageDir(), "bin")
cfg.Config.LastDataDir = filepath.Join(PacketsPackageDir(), "data")
return &cfg
} else {
cfg.Config.HttpPort = 9123
cfg.Config.AutoDeleteCacheDir = false
cfg.Config.CacheDir = "/var/cache/packets"
cfg.Config.DataDir = "/opt/packets"
cfg.Config.DaysToDelete = -1
cfg.Config.BinDir = "/usr/bin"
cfg.Config.LastDataDir = "/opt/packets"
return &cfg
}
}
func IsSafe(str string) bool {
s, err := filepath.EvalSymlinks(filepath.Clean(str))
if err != nil {
s = filepath.Clean(str)
}
var cfg ConfigTOML
toml.DecodeFile(filepath.Join(PacketsPackageDir(), "config.toml"), &cfg)
if strings.HasPrefix(s, cfg.Config.DataDir) || strings.HasPrefix(s, cfg.Config.BinDir) {
return true
} else if strings.Contains(s, ".ssh") {
return false
} else if strings.HasPrefix(s, "/etc") {
return false
} else if strings.HasPrefix(s, "/usr") || strings.HasPrefix(s, "/bin") {
fmt.Println(s, "está dentro de usr")
return strings.HasPrefix(s, "/usr/share")
} else if strings.HasPrefix(s, "/var/mail") {
return false
} else if strings.HasPrefix(s, "/proc") {
return false
} else if strings.HasPrefix(s, "/sys") {
return false
} else if strings.HasPrefix(s, "/var/run") || strings.HasPrefix(s, "/run") {
return false
} else if strings.HasPrefix(s, "/tmp") {
return false
} else if strings.HasPrefix(s, "/dev") {
return false
} else if strings.HasPrefix(s, "/boot") {
return false
} else if strings.HasPrefix(s, "/home") {
if strings.Contains(s, "/Pictures") || strings.Contains(s, "/Videos") || strings.Contains(s, "/Documents") || strings.Contains(s, "/Downloads") {
return false
}
} else if strings.HasPrefix(s, "/lib") || strings.HasPrefix(s, "/lib64") || strings.HasPrefix(s, "/var/lib64") || strings.HasPrefix(s, "/lib") {
return false
} else if strings.HasPrefix(s, "/sbin") {
return false
} else if strings.HasPrefix(s, "/srv") {
return false
} else if strings.HasPrefix(s, "/mnt") {
return false
} else if strings.HasPrefix(s, "/media") {
return false
} else if strings.HasPrefix(s, "/snap") {
return false
}
return true
}
func SafeRemove(L *lua.LState) int {
filename := L.CheckString(1)
if !IsSafe(filename) {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
err := os.RemoveAll(filename)
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] remove failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
L.Push(lua.LNil)
return 2
}
func SafeRename(L *lua.LState) int {
oldname := L.CheckString(1)
newname := L.CheckString(2)
if !IsSafe(oldname) || !IsSafe(newname) {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
if err := os.Rename(oldname, newname); err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] rename failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
return 1
}
func SafeCopy(L *lua.LState) int {
oldname := L.CheckString(1)
newname := L.CheckString(2)
if !IsSafe(oldname) || !IsSafe(newname) {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
src, err := os.Open(oldname)
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
defer src.Close()
status, err := src.Stat()
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
err = os.MkdirAll(filepath.Dir(newname), 0755)
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
dst, err := os.Create(newname)
if err != nil {
if !os.IsExist(err) {
dst, err = os.Open(newname)
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
} else {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
}
defer dst.Close()
if err := dst.Chmod(status.Mode()); err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
_, err = io.Copy(dst, src)
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] copy failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
L.Push(lua.LNil)
return 2
}
func SymbolicLua(L *lua.LState) int {
fileName := L.CheckString(1)
destination := L.CheckString(2)
if !IsSafe(fileName) || !IsSafe(destination) {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
_ = os.RemoveAll(destination)
if err := os.Symlink(fileName, destination); err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] symlink failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
L.Push(lua.LNil)
return 2
}
func modeFlags(mode string) int {
switch mode {
case "r", "rb":
return os.O_RDONLY
case "w", "wb":
return os.O_CREATE | os.O_WRONLY | os.O_TRUNC
case "a", "ab":
return os.O_CREATE | os.O_WRONLY | os.O_APPEND
case "r+", "r+b", "rb+", "br+":
return os.O_RDWR
case "w+", "w+b", "wb+", "bw+":
return os.O_CREATE | os.O_RDWR | os.O_TRUNC
case "a+", "a+b", "ab+", "ba+":
return os.O_CREATE | os.O_RDWR | os.O_APPEND
default:
return os.O_RDONLY
}
}
func SafeOpen(L *lua.LState) int {
path := L.CheckString(1)
mode := L.OptString(2, "r")
if !IsSafe(path) {
L.Push(lua.LNil)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
file, err := os.OpenFile(path, modeFlags(mode), 0644)
if err != nil {
L.Push(lua.LNil)
L.Push(lua.LString("[packets] open failed\n" + err.Error()))
return 2
}
ud := L.NewUserData()
ud.Value = file
L.SetMetatable(ud, L.GetTypeMetatable("file"))
L.Push(ud)
L.Push(lua.LNil)
return 2
}
func Ljoin(L *lua.LState) int {
n := L.GetTop()
parts := make([]string, 0, n)
for i := 1; i <= n; i++ {
val := L.Get(i)
parts = append(parts, val.String())
}
result := filepath.Join(parts...)
L.Push(lua.LString(result))
return 1
}
func LMkdir(L *lua.LState) int {
path := L.CheckString(1)
perm := L.CheckInt(2)
if !IsSafe(path) {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath\n"))
return 2
}
if err := os.MkdirAll(path, os.FileMode(perm)); err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] mkdir failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
L.Push(lua.LNil)
return 2
}
func LuaCompile(L *lua.LState) int {
lang := L.CheckString(1)
args := []string{}
for i := 2; i <= L.GetTop(); i++ {
if strings.Contains(L.CheckString(i), "/") {
tryintoacess, err := filepath.Abs(filepath.Clean(filepath.Join(SandboxDir, L.CheckString(i))))
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] invalid filepath\n" + err.Error()))
return 2
}
fmt.Printf("sandboxdir: (%s) acessto: (%s)\n", SandboxDir, tryintoacess)
rel, err := filepath.Rel(SandboxDir, tryintoacess)
if err != nil || strings.HasPrefix(rel, "..") {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
}
args = append(args, L.CheckString(i))
}
bin, suc := AllowedCmds[lang]
if !suc {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsupported language"))
return 2
}
cmd := exec.Command(bin, args...)
cmd.Dir = SandboxDir
out, err := cmd.CombinedOutput()
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] compile failed\n" + err.Error() + "\n" + string(out)))
return 2
}
if err := cmd.Run(); err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] compile failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
L.Push(lua.LString(string(out)))
return 2
}
func CompileRequirements(L *lua.LState) int {
cmdLang := L.CheckString(1)
if strings.Contains(L.CheckString(2), "/") {
tryintoacess, err := filepath.Abs(filepath.Clean(L.CheckString(2)))
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] invalid filepath\n" + err.Error()))
return 2
}
if !strings.HasPrefix(tryintoacess, SandboxDir) {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] unsafe filepath"))
return 2
}
}
var err error
switch cmdLang {
case "python":
cmd := exec.Command("pip", "install", "--target", filepath.Join(SandboxDir, "tmp/build"), "-r", L.CheckString(2))
cmd.Dir = filepath.Join(SandboxDir, "data")
err = cmd.Run()
case "java":
cmd := exec.Command("mvn", "dependency:copy-dependencies", "-DoutputDirectory="+filepath.Join(SandboxDir, "tmp/build"))
cmd.Dir = L.CheckString(2)
err = cmd.Run()
case "ruby":
cmd := exec.Command("bundle", "install", "--path", filepath.Join(SandboxDir, "tmp/build"))
cmd.Dir = L.CheckString(2)
err = cmd.Run()
}
if err != nil {
L.Push(lua.LFalse)
L.Push(lua.LString("[packets] requirements install failed\n" + err.Error()))
return 2
}
L.Push(lua.LTrue)
L.Push(lua.LNil)
return 2
}

BIN
ola@3000.pkt.tar.zst Normal file

Binary file not shown.

BIN
realtime@1.25.0.pkt.tar.zst Normal file

Binary file not shown.

BIN
teste@1.0.pkt.tar.zst Normal file

Binary file not shown.