Initial Commit

This commit is contained in:
CapCreeperGR 2024-03-25 09:41:59 +02:00
commit 7c7b6c436d
8 changed files with 303 additions and 0 deletions

1
config.go Normal file
View File

@ -0,0 +1 @@
package main

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module bpm
go 1.22

30
main.go Normal file
View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"log"
)
/* ---BPM | Bubble Package Manager--- */
/* Made By CapCreeperGR */
/* A simple-to-use package manager */
/* ---------------------------------- */
var rootDir string = "/"
func main() {
fmt.Printf("Running %s %s\n", getKernel(), getArch())
//_, err := readPackage("test_hello_package/hello.bpm")
err := installPackage("test_hello_package/hello.bpm", rootDir)
if err != nil {
log.Fatalf("Could not read package\nError: %s\n", err)
}
pkgs, err := getInstalledPackages(rootDir)
if err != nil {
log.Fatalf("Could not get installed Packages!\nError: %s\n", err)
}
for _, pkg := range pkgs {
fmt.Println(pkg)
}
fmt.Println(getPackageFiles("hello"))
}

237
package_utils.go Normal file
View File

@ -0,0 +1,237 @@
package main
import (
"archive/tar"
"bufio"
"compress/gzip"
"errors"
"io"
"os"
"path"
"slices"
"strconv"
"strings"
)
type packageInfo struct {
name string
description string
version string
depends []string
provides []string
}
func readPackage(filename string) (*packageInfo, error) {
if _, err := os.Stat(filename); os.IsNotExist(err) {
return nil, err
}
file, err := os.Open(filename)
if err != nil {
return nil, err
}
archive, err := gzip.NewReader(file)
if err != nil {
return nil, err
}
tr := tar.NewReader(archive)
for {
header, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
if header.Name == "pkg.info" {
bs, _ := io.ReadAll(tr)
err := file.Close()
if err != nil {
return nil, err
}
pkgInfo, err := readPackageInfo(string(bs))
if err != nil {
return nil, err
}
return pkgInfo, nil
}
}
return nil, errors.New("pkg.info not found in archive")
}
func readPackageInfo(contents string) (*packageInfo, error) {
pkgInfo := packageInfo{}
lines := strings.Split(contents, "\n")
for num, line := range lines {
split := strings.SplitN(line, ":", 2)
if len(split) != 2 {
return nil, errors.New("invalid pkg.info format at line " + strconv.Itoa(num))
}
split[0] = strings.Trim(split[0], " ")
split[1] = strings.Trim(split[1], " ")
switch split[0] {
case "name":
pkgInfo.name = split[1]
case "description":
pkgInfo.description = split[1]
case "version":
pkgInfo.version = split[1]
}
}
return &pkgInfo, nil
}
func createInfoFile(pkgInfo packageInfo) string {
ret := ""
ret = ret + "name: " + pkgInfo.name + "\n"
ret = ret + "description: " + pkgInfo.description + "\n"
ret = ret + "version: " + pkgInfo.version + "\n"
return ret
}
func installPackage(filename, installDir string) error {
if _, err := os.Stat(filename); os.IsNotExist(err) {
return err
}
file, err := os.Open(filename)
if err != nil {
return err
}
archive, err := gzip.NewReader(file)
if err != nil {
return err
}
tr := tar.NewReader(archive)
var files []string
var pkgInfo *packageInfo
for {
header, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
if header.Name == "pkg.info" {
bs, _ := io.ReadAll(tr)
if err != nil {
return err
}
pkgInfo, err = readPackageInfo(string(bs))
if err != nil {
return err
}
}
if strings.HasPrefix(header.Name, "files/") && header.Name != "files/" {
extractFilename := path.Join(installDir, strings.TrimPrefix(header.Name, "files/"))
switch header.Typeflag {
case tar.TypeDir:
files = append(files, strings.TrimPrefix(header.Name, "files/"))
if err := os.Mkdir(extractFilename, 0755); err != nil && !os.IsExist(err) {
return err
}
case tar.TypeReg:
outFile, err := os.Create(extractFilename)
files = append(files, strings.TrimPrefix(header.Name, "files/"))
if err != nil {
return err
}
if _, err := io.Copy(outFile, tr); err != nil {
return err
}
if err := os.Chmod(extractFilename, header.FileInfo().Mode()); err != nil {
return err
}
err = outFile.Close()
if err != nil {
return err
}
default:
return errors.New("ExtractTarGz: uknown type: " + strconv.Itoa(int(header.Typeflag)) + " in " + extractFilename)
}
}
}
if pkgInfo == nil {
return errors.New("pkg.info not found in archive")
}
slices.Sort(files)
slices.Reverse(files)
dataDir := path.Join(installDir, "var/lib/bpm/installed/")
err = os.MkdirAll(dataDir, 755)
if err != nil {
return err
}
pkgDir := path.Join(dataDir, pkgInfo.name)
err = os.RemoveAll(pkgDir)
if err != nil {
return err
}
err = os.Mkdir(pkgDir, 755)
if err != nil {
return err
}
f, err := os.Create(path.Join(pkgDir, "files"))
if err != nil {
return err
}
for _, line := range files {
_, err := f.WriteString(line + "\n")
if err != nil {
return err
}
}
f.Close()
f, err = os.Create(path.Join(pkgDir, "info"))
if err != nil {
return err
}
_, err = f.WriteString(createInfoFile(*pkgInfo))
if err != nil {
return err
}
f.Close()
archive.Close()
file.Close()
return nil
}
func getInstalledPackages(rootDir string) ([]string, error) {
dataDir := path.Join(rootDir, "var/lib/bpm/installed/")
items, err := os.ReadDir(dataDir)
if os.IsNotExist(err) {
return nil, nil
}
if err != nil {
return nil, err
}
var ret []string
for _, item := range items {
ret = append(ret, item.Name())
}
return ret, nil
}
func getPackageFiles(pkg string) []string {
var ret []string
dataDir := path.Join(rootDir, "var/lib/bpm/installed/")
pkgDir := path.Join(dataDir, pkg)
files := path.Join(pkgDir, "files")
if _, err := os.Stat(dataDir); os.IsNotExist(err) {
return nil
}
if _, err := os.Stat(pkgDir); os.IsNotExist(err) {
return nil
}
file, err := os.Open(files)
if err != nil {
return nil
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
ret = append(ret, scanner.Text())
}
return ret
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
name: hello
description: A simple hello world program
version: 1.0

29
utils.go Normal file
View File

@ -0,0 +1,29 @@
package main
import "syscall"
func getArch() string {
u := syscall.Utsname{}
err := syscall.Uname(&u)
if err != nil {
return "unknown"
}
return byteArrayToString(u.Machine[:])
}
func getKernel() string {
u := syscall.Utsname{}
err := syscall.Uname(&u)
if err != nil {
return "unknown"
}
return byteArrayToString(u.Sysname[:]) + " " + byteArrayToString(u.Release[:])
}
func byteArrayToString(bs []int8) string {
b := make([]byte, len(bs))
for i, v := range bs {
b[i] = byte(v)
}
return string(b)
}