diff --git a/src/asgen/backends/freebsd/fbsdpkg.d b/src/asgen/backends/freebsd/fbsdpkg.d new file mode 100644 index 0000000..a5552e1 --- /dev/null +++ b/src/asgen/backends/freebsd/fbsdpkg.d @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2023 Serenity Cyber Security, LLC + * Author: Gleb Popov + * + * Licensed under the GNU Lesser General Public License Version 3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the license, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +module asgen.backends.freebsd.fbsdpkg; + +import std.stdio; +import std.json; +import std.path; +import std.string; +import std.array : empty; +import asgen.backends.interfaces; +import asgen.logging; +import asgen.zarchive; + + +final class FreeBSDPackage : Package +{ +private: + JSONValue pkgjson; + + string pkgFname; + PackageKind _kind; + + ArchiveDecompressor pkgArchive; + string[] contentsL = null; + +public: + this (string pkgRoot, JSONValue[string] j) + { + pkgjson = j; + pkgFname = buildPath (pkgRoot, pkgjson["repopath"].str()); + _kind = PackageKind.PHYSICAL; + } + + @property override string name () const { return pkgjson["name"].str(); } + @property override string ver () const { return pkgjson["version"].str(); } + @property override string arch () const { return pkgjson["arch"].str(); } + @property override string maintainer () const { return pkgjson["maintainer"].str(); } + @property override string getFilename () const { return pkgFname; } + + + @property override const(string[string]) summary () const + { + string[string] sums; + sums["en"] = pkgjson["comment"].str(); + return sums; + } + + @property override const(string[string]) description () const + { + string[string] descs; + descs["en"] = pkgjson["desc"].str(); + return descs; + } + + override + const(ubyte[]) getFileData (string fname) + { + if (!pkgArchive.isOpen) + pkgArchive.open (this.getFilename); + + return pkgArchive.readData(fname); + } + + @property override + string[] contents () + { + if (!this.contentsL.empty) + return this.contentsL; + + if (!pkgArchive.isOpen) + pkgArchive.open (this.getFilename); + + this.contentsL = pkgArchive.readContents (); + return this.contentsL; + } + + override + void finish () + { + } + + @property override + PackageKind kind () @safe pure + { + return this._kind; + } +} diff --git a/src/asgen/backends/freebsd/fbsdpkgindex.d b/src/asgen/backends/freebsd/fbsdpkgindex.d new file mode 100644 index 0000000..03f49b5 --- /dev/null +++ b/src/asgen/backends/freebsd/fbsdpkgindex.d @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2023 Serenity Cyber Security, LLC + * Author: Gleb Popov + * + * Licensed under the GNU Lesser General Public License Version 3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the license, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +module asgen.backends.freebsd.fbsdpkgindex; + +import std.json; +import std.stdio; +import std.path; +import std.string; +import std.conv : to; +import std.array : appender; +import std.algorithm : remove; +static import std.file; + +import asgen.logging; +import asgen.zarchive; +import asgen.backends.interfaces; +import asgen.backends.freebsd.fbsdpkg; + + +final class FreeBSDPackageIndex : PackageIndex +{ + +private: + string rootDir; + Package[][string] pkgCache; + +public: + + this (string dir) + { + this.rootDir = dir; + if (!std.file.exists (dir)) + throw new Exception ("Directory '%s' does not exist.", dir); + } + + void release () + { + pkgCache = null; + } + + private Package[] loadPackages (string suite, string section, string arch) + { + auto pkgRoot = buildPath (rootDir, suite); + auto listsTarFname = buildPath (pkgRoot, "packagesite.pkg"); + if (!std.file.exists (listsTarFname)) { + logWarning ("Package lists file '%s' does not exist.", listsTarFname); + return []; + } + + ArchiveDecompressor ad; + ad.open (listsTarFname); + logDebug ("Opened: %s", listsTarFname); + + auto d = ad.readData("packagesite.yaml"); + auto pkgs = appender!(Package[]); + + foreach(entry; d.split('\n')) { + auto j = parseJSON(assumeUTF(entry)); + if (j.type == JSONType.object) + pkgs ~= to!Package(new FreeBSDPackage(pkgRoot, j.object)); + } + + return pkgs.data; + } + + Package[] packagesFor (string suite, string section, string arch, bool withLongDescs = true) + { + immutable id = "%s-%s-%s".format (suite, section, arch); + if (id !in pkgCache) { + auto pkgs = loadPackages (suite, section, arch); + synchronized (this) pkgCache[id] = pkgs; + } + + return pkgCache[id]; + } + + Package packageForFile (string fname, string suite = null, string section = null) + { + return null; // FIXME: not implemented + } + + bool hasChanges (DataStore dstore, string suite, string section, string arch) + { + return true; + } +} diff --git a/src/asgen/backends/freebsd/package.d b/src/asgen/backends/freebsd/package.d new file mode 100644 index 0000000..e7961ee --- /dev/null +++ b/src/asgen/backends/freebsd/package.d @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 Serenity Cyber Security, LLC + * Author: Gleb Popov + * + * Licensed under the GNU Lesser General Public License Version 3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the license, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +module asgen.backends.freebsd; + +public import asgen.backends.freebsd.fbsdpkg; +public import asgen.backends.freebsd.fbsdpkgindex; diff --git a/src/asgen/config.d b/src/asgen/config.d index b2cbd3e..6f95a22 100644 --- a/src/asgen/config.d +++ b/src/asgen/config.d @@ -68,7 +68,8 @@ enum Backend { Ubuntu, Archlinux, RpmMd, - Alpinelinux + Alpinelinux, + FreeBSD } /** @@ -408,6 +409,11 @@ public: this.backend = Backend.Alpinelinux; this.metadataType = DataType.XML; break; + case "freebsd": + this.backendName = "FreeBSD"; + this.backend = Backend.FreeBSD; + this.metadataType = DataType.XML; + break; default: break; } diff --git a/src/asgen/engine.d b/src/asgen/engine.d index 9e7f216..67526d1 100644 --- a/src/asgen/engine.d +++ b/src/asgen/engine.d @@ -49,6 +49,7 @@ import asgen.backends.debian; import asgen.backends.ubuntu; import asgen.backends.archlinux; import asgen.backends.alpinelinux; +import asgen.backends.freebsd; static if (HAVE_RPMMD) import asgen.backends.rpmmd; @@ -99,6 +100,9 @@ public: case Backend.Alpinelinux: pkgIndex = new AlpinePackageIndex(conf.archiveRoot); break; + case Backend.FreeBSD: + pkgIndex = new FreeBSDPackageIndex (conf.archiveRoot); + break; default: throw new Exception("No backend specified, can not continue!"); } diff --git a/src/asgen/meson.build b/src/asgen/meson.build index 5252f14..1d69af1 100644 --- a/src/asgen/meson.build +++ b/src/asgen/meson.build @@ -64,6 +64,10 @@ backend_sources = [ 'backends/ubuntu/package.d', 'backends/ubuntu/ubupkg.d', 'backends/ubuntu/ubupkgindex.d', + + 'backends/freebsd/package.d', + 'backends/freebsd/fbsdpkg.d', + 'backends/freebsd/fbsdpkgindex.d', ] if get_option('rpmmd')