2024-08-13 00:01:00 +00:00
|
|
|
package lib
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/tar"
|
|
|
|
"bufio"
|
|
|
|
"compress/gzip"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"path"
|
2024-08-25 21:51:20 +00:00
|
|
|
"strings"
|
|
|
|
"unicode"
|
2024-08-13 00:01:00 +00:00
|
|
|
|
|
|
|
"github.com/bigkevmcd/go-configparser"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Pool struct {
|
|
|
|
Maintainer string `json:"-"`
|
|
|
|
Pubkey string `json:"-"`
|
|
|
|
Size string `json:"-"`
|
|
|
|
|
|
|
|
Display string `json:"display"`
|
|
|
|
Branch string `json:"branch"`
|
|
|
|
Source string `json:"source"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
Dir string `json:"dir"`
|
|
|
|
}
|
|
|
|
|
2024-08-25 21:51:20 +00:00
|
|
|
func (p *Pool) ID() string {
|
|
|
|
var res string = ""
|
|
|
|
|
|
|
|
for _, c := range p.Display {
|
|
|
|
if unicode.IsDigit(c) || unicode.IsLetter(c) {
|
|
|
|
res += string(c)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
res += "-"
|
|
|
|
}
|
|
|
|
|
|
|
|
return strings.TrimSuffix(res, "-")
|
|
|
|
}
|
|
|
|
|
2024-08-13 00:01:00 +00:00
|
|
|
func (p *Pool) Load(list *[]Package) error {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if p.Dir == "" {
|
|
|
|
return fmt.Errorf("pool directory is not specified")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = p.LoadInfo(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = p.LoadList(list); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Pool) LoadList(list *[]Package) error {
|
|
|
|
var (
|
|
|
|
list_path string
|
|
|
|
list_file *os.File
|
|
|
|
gzip_reader io.Reader
|
|
|
|
header *tar.Header
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
|
|
|
|
list_path = path.Join(p.Dir, "LIST")
|
|
|
|
|
|
|
|
if list_file, err = os.Open(list_path); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer list_file.Close()
|
|
|
|
|
|
|
|
if gzip_reader, err = gzip.NewReader(bufio.NewReader(list_file)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
reader := tar.NewReader(gzip_reader)
|
|
|
|
|
|
|
|
for header, err = reader.Next(); err == nil; header, err = reader.Next() {
|
|
|
|
if header.Typeflag != tar.TypeReg {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if path.Base(header.Name) != "DATA" {
|
|
|
|
return fmt.Errorf("LIST archive contains an unknown file")
|
|
|
|
}
|
|
|
|
|
|
|
|
var pkg Package
|
|
|
|
|
|
|
|
if err = pkg.Load(reader); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-08-13 19:12:27 +00:00
|
|
|
pkg.Archive = path.Join(p.Dir, fmt.Sprintf("%s_%s.mpf", pkg.Name, pkg.Version))
|
|
|
|
pkg.Pool = p
|
|
|
|
|
2024-08-13 00:01:00 +00:00
|
|
|
*list = append(*list, pkg)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Pool) LoadInfo() error {
|
|
|
|
var (
|
|
|
|
info_path string
|
|
|
|
info_file *os.File
|
|
|
|
section string
|
|
|
|
size int64
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
|
|
|
|
info_path = path.Join(p.Dir, "INFO")
|
|
|
|
|
|
|
|
if info_file, err = os.Open(info_path); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
parser := configparser.New()
|
|
|
|
|
|
|
|
if err = parser.ParseReader(bufio.NewReader(info_file)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
section = "DEFAULT"
|
|
|
|
|
|
|
|
for _, s := range parser.Sections() {
|
|
|
|
if s == "DEFAULT" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
section = s
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if section == "DEFAULT" {
|
|
|
|
return fmt.Errorf("DATA does not contain any sections")
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.Name != section {
|
|
|
|
return fmt.Errorf("pool name (\"%s\") doesn't match with \"%s\"", p.Name, section)
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.Maintainer, err = parser.Get(p.Name, "maintainer"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if size, err = parser.GetInt64(section, "size"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
p.Size = SizeFromBytes(size)
|
|
|
|
|
|
|
|
if p.Pubkey, err = parser.Get(section, "pubkey"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|