diff --git a/cmd/packets/main.go b/cmd/packets/main.go index b050c47..6ef01fa 100644 --- a/cmd/packets/main.go +++ b/cmd/packets/main.go @@ -1,12 +1,14 @@ package main import ( + "bufio" "database/sql" "fmt" "log" "os" "packets/configs" "packets/internal/consts" + "packets/internal/utils" "path/filepath" "github.com/pelletier/go-toml/v2" @@ -17,13 +19,14 @@ import ( // init is doing some verifications func init() { + log.SetFlags(0) + _, err := os.Stat(consts.DefaultLinux_d) if os.IsNotExist(err) { - err := os.Mkdir(consts.DefaultLinux_d, 0644) + err := os.Mkdir(consts.DefaultLinux_d, 0755) if err != nil { if os.IsPermission(err) { - fmt.Println("can't create packets root directory, please run as root") - os.Exit(1) + log.Fatal("can't create packets root directory, please run as root") } else { log.Fatal(err) } @@ -34,7 +37,7 @@ func init() { if err != nil { if os.IsNotExist(err) { - fmt.Println("index.db does not exist use \"packets sync\"") + fmt.Println("index.db does not exist, try to use \"packets sync\"") } else { log.Fatal(err) } @@ -48,7 +51,7 @@ func init() { log.Fatal(db) } defer db.Close() - db.Exec("CREATE TABLE IF NOT EXISTS packages (realname TEXT NOT NULL UNIQUE PRIMARY KEY, version TEXT NOT NULL, dependencies TEXT, name TEXT, family TEXT NOT NULL, serial INTEGER, package_d TEXT NOT NULL)") + db.Exec("CREATE TABLE IF NOT EXISTS packages (name TEXT NOT NULL UNIQUE PRIMARY KEY, version TEXT NOT NULL, dependencies TEXT NOT NULL DEFAULT '', family TEXT NOT NULL, serial INTEGER, package_d TEXT NOT NULL)") } else { log.Fatal(err) } @@ -78,16 +81,117 @@ func init() { // COBRA CMDS var rootCmd = &cobra.Command{Use: "packets"} + +var syncCmd = &cobra.Command{ + Use: "sync [url]", + Args: cobra.MaximumNArgs(1), + Short: "Syncronizes with an remote index.db, and check if the data dir is changed", + Run: func(cmd *cobra.Command, args []string) { + if os.Getuid() != 0 { + fmt.Println("please, run as root") + return + } + syncUrl := consts.DefaultSyncUrl + if len(args) > 0 { + syncUrl = args[0] + } + + DBB, err := utils.GetFileHTTP(syncUrl) + if err != nil { + log.Fatal(err) + } + + if err := os.WriteFile(consts.IndexDB, DBB, 0774); err != nil { + log.Fatal(err) + } + + fmt.Println("Sucessifully sync!") + os.Exit(0) + }, +} + +type Quer1 struct { + Name string + Version string + Description string +} + var installCmd = &cobra.Command{ Use: "install {package} [packages...]", Short: "Install a package", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { + db, err := sql.Open("sqlite", consts.IndexDB) + if err != nil { + fmt.Println(err) + } + defer db.Close() + + for _, inputName := range args { + + var exist bool + err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM packages WHERE name = ?)", inputName).Scan(&exist) + if err != nil { + if err != sql.ErrNoRows { + log.Panic(err) + } + } + if exist { + + } + + rows, err := db.Query("SELECT name, version, descriptionFROM packages WHERE query_name = ?", inputName) + if err != nil { + log.Fatal(err) + + } + + defer rows.Close() + + var pkgs []Quer1 + for rows.Next() { + var q Quer1 + if err := rows.Scan(&q.Name, &q.Version, &q.Description); err != nil { + log.Panic(err) + } + pkgs = append(pkgs, q) + } + switch len(pkgs) { + case 0: + log.Fatalf("can't find any results for %s\n", inputName) + + case 1: + fmt.Printf(":: Founded 1 package for %s \n", inputName) + + fmt.Printf("Downloading %s \n", pkgs[0].Name) + goto install + + default: + + fmt.Printf(":: Founded %d packages for (%s)\n Select 1 to install\n", len(pkgs), inputName) + for i, q := range pkgs { + fmt.Printf("[%d] %s : %s\n %s\n", i, q.Name, q.Version, q.Description) + } + var choice int + optionagain: + fmt.Print(">> ") + fmt.Fscan(bufio.NewReader(os.Stdin), &choice) + if choice > len(pkgs) || choice < 0 { + fmt.Println("invalid option") + goto optionagain + } + + return + } + + install: + } }, } func main() { rootCmd.AddCommand(installCmd) + rootCmd.AddCommand(syncCmd) rootCmd.Execute() } diff --git a/doc/indexdbSchema.txt b/doc/indexdbSchema.txt index f60a141..f5bc8c3 100644 --- a/doc/indexdbSchema.txt +++ b/doc/indexdbSchema.txt @@ -13,5 +13,23 @@ CREATE TABLE packages( family TEXT NOT NULL, arch TEXT NOT NULL, os TEXT NOT NULL, + size INTEGER NOT NULL DEFAULT 0, + serial INTEGER NOT NULL +); + + +CREATE TABLE IF NOT EXISTS packages ( + query_name TEXT NOT NULL, + name TEXT NOT NULL UNIQUE PRIMARY KEY, + version TEXT NOT NULL, + dependencies TEXT NOT NULL DEFAULT '', + description TEXT NOT NULL, + family TEXT NOT NULL, + serial INTEGER NOT NULL UNIQUE, + package_d TEXT NOT NULL, + filename TEXT NOT NULL, + os TEXT NOT NULL, + arch TEXT NOT NULL, + in_cache INTEGER NOT NULL DEFAULT 1, serial INTEGER NOT NULL ); \ No newline at end of file diff --git a/go.mod b/go.mod index 700abd6..f5c8fe7 100644 --- a/go.mod +++ b/go.mod @@ -12,17 +12,43 @@ require ( ) require ( + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.11.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/spf13/pflag v1.0.10 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.42.0 // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/mod v0.27.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect golang.org/x/tools v0.36.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect modernc.org/libc v1.66.3 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect diff --git a/go.sum b/go.sum index d1f14b6..4ebf718 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,60 @@ +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 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/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 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/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -23,8 +63,25 @@ github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4 github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= @@ -36,9 +93,14 @@ golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM= modernc.org/cc/v4 v4.26.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= diff --git a/internal/consts/consts.go b/internal/consts/consts.go index 030ce6a..6bd47bb 100644 --- a/internal/consts/consts.go +++ b/internal/consts/consts.go @@ -9,4 +9,6 @@ const ( DefaultData_d = "/opt/packets" LANDeadline = 2 * time.Second IndexDB = "/etc/packets/index.db" + InstalledDB = "/etc/packets/installed.db" + DefaultSyncUrl = "https://servidordomal.fun/index.db" ) diff --git a/internal/errors/errors.go b/internal/errors/errors.go index b5ddfdb..061081a 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -5,4 +5,5 @@ import "errors" var ( ErrResponseNot200OK = errors.New("the request is not 200, download failed") ErrCantFindManifestTOML = errors.New("can't find manifest.toml when trying to read the packagefile") + ErrInvalidSignature = errors.New("the signature is invalid") ) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 6d74f54..ee646d4 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -2,11 +2,14 @@ package utils import ( "archive/tar" + "crypto/ed25519" + "database/sql" "io" "log" "net/http" "os" "packets/configs" + "packets/internal/consts" errors_packets "packets/internal/errors" "path/filepath" @@ -14,7 +17,29 @@ import ( "github.com/pelletier/go-toml/v2" ) -func GetFileHTTP(url string) (*[]byte, error) { +type Package struct { + PackageF []byte + Version string + ImageUrl string + QueryName string + Description string + Author string + AuthorVerified bool + OS string + Arch string + Filename string + Size int64 + + Signature []byte + PublicKey ed25519.PublicKey + + Manifest configs.Manifest + + Family string + Serial int +} + +func GetFileHTTP(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { @@ -30,14 +55,14 @@ func GetFileHTTP(url string) (*[]byte, error) { return nil, err } - return &fileBytes, nil + return fileBytes, nil } // ReadManifest is crucial to get package metadata it reads manifest.toml from a package file (tar.zst) -func ReadManifest(file *os.File) (*configs.Manifest, error) { +func ReadManifest(file io.Reader) (configs.Manifest, error) { zstdReader, err := zstd.NewReader(file) if err != nil { - return nil, err + return configs.Manifest{}, err } defer zstdReader.Close() @@ -48,7 +73,7 @@ func ReadManifest(file *os.File) (*configs.Manifest, error) { break } if err != nil { - return nil, err + return configs.Manifest{}, err } if filepath.Base(header.Name) == "manifest.toml" { @@ -60,13 +85,14 @@ func ReadManifest(file *os.File) (*configs.Manifest, error) { log.Fatal(err) } - return &manifest, nil + return manifest, nil } } - return nil, errors_packets.ErrCantFindManifestTOML + return configs.Manifest{}, errors_packets.ErrCantFindManifestTOML } +// CopyDir copies a directory from source to destination func CopyDir(src string, dest string) error { if stats, err := os.Stat(src); err != nil { return err @@ -114,6 +140,7 @@ func CopyDir(src string, dest string) error { return nil } +// CopyFile copies a file from source to destination func CopyFile(source string, destination string) error { src, err := os.Open(source) @@ -157,3 +184,25 @@ func CopyFile(source string, destination string) error { return nil } + +// Write writes the package file to the cache directory and returns the path to it +func (p *Package) Write() (string, error) { + + if err := os.WriteFile(filepath.Join(consts.DefaultCache_d, p.Filename), p.PackageF, 0644); err != nil { + _ = os.Remove(filepath.Join(consts.DefaultCache_d, p.Filename)) + return "", err + } + + return filepath.Join(consts.DefaultCache_d, p.Filename), nil +} + +func (p *Package) AddToInstalledDB() error { + db, err := sql.Open("sqlite", consts.InstalledDB) + if err != nil { + return err + } + defer db.Close() + + _, err = db.Exec("INSERT INTO packages (name, version, dependencies)") + return err +} diff --git a/pkg/main.go b/pkg/main.go index 7f196cd..d917d9c 100644 --- a/pkg/main.go +++ b/pkg/main.go @@ -2,19 +2,27 @@ package pkg import ( "archive/tar" + "bytes" + "crypto/ed25519" + "database/sql" + "fmt" "io" "os" "packets/configs" + "packets/internal/consts" + errors_packets "packets/internal/errors" "packets/internal/utils" utils_lua "packets/internal/utils/lua" + "path" "path/filepath" "strings" "github.com/klauspost/compress/zstd" lua "github.com/yuin/gopher-lua" + _ "modernc.org/sqlite" ) -// Install exctract and install from a package file ( tar.zst ) +// Install exctract and fully install from a package file ( tar.zst ) func InstallPackage(file *os.File) error { manifest, err := utils.ReadManifest(file) @@ -107,6 +115,7 @@ func InstallPackage(file *os.File) error { return nil } +// ExecuteRemoveScript executes the remove script from the package func ExecuteRemoveScript(path string) error { L, err := utils_lua.GetSandBox(".") @@ -124,3 +133,78 @@ func ExecuteRemoveScript(path string) error { return nil } + +// GetPackage retrieves package information from the index database and downloads the package file +func GetPackage(name string) (utils.Package, error) { + + var this utils.Package + db, err := sql.Open("sqlite", consts.IndexDB) + if err != nil { + return this, err + } + defer db.Close() + + var packageUrl string + err = db.QueryRow("SELECT query_name, version, package_url, image_url, description, author, author_verified, os, arch, signature, public_key, family, serial, size FROM packages WHERE name = ?", name). + Scan( + &this.QueryName, + &this.Version, + &packageUrl, + &this.ImageUrl, + &this.Description, + &this.Author, + &this.AuthorVerified, + &this.OS, + &this.Arch, + &this.Signature, + &this.PublicKey, + &this.Family, + &this.Serial, + &this.Size, + ) + if err != nil { + return utils.Package{}, err + } + + filename := path.Base(packageUrl) + this.Filename = filename + peers, err := utils.AskLAN(filename) + if err != nil { + return utils.Package{}, err + } + + if len(peers) > 0 { + this.PackageF, err = utils.GetFileHTTP(packageUrl) + if err != nil { + return utils.Package{}, err + } + } else { + var totalerrors int = 0 + for _, peer := range peers { + this.PackageF, err = utils.GetFileHTTP(fmt.Sprintf("http://%s:%d/%s", peer.IP, peer.Port, filename)) + if err == nil { + break + } else { + totalerrors++ + } + } + if totalerrors == len(peers) { + this.PackageF, err = utils.GetFileHTTP(packageUrl) + if err != nil { + return utils.Package{}, err + } + } + } + + reader := bytes.NewReader(this.PackageF) + this.Manifest, err = utils.ReadManifest(reader) + if err != nil { + return utils.Package{}, err + } + + if !ed25519.Verify(this.PublicKey, this.PackageF, this.Signature) { + return utils.Package{}, errors_packets.ErrInvalidSignature + } + + return this, nil +}