1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
# SBo SlackBuilds Repository
SlackBuild scripts for which danix is the **official SBo maintainer** on
[SlackBuilds.org (SBo)](https://slackbuilds.org).
**Maintainer workspace:** if this repo is checked out inside the maintainer
workspace (a parent directory holding `AGENTS.md`, `sweep.sh` and `hooks/`),
read `../AGENTS.md` first. It holds the operational workflow: git hooks, the
upstream sweep, test builds, and delivery to SBo.
## Purpose: tracking, not development
This repo is a **maintenance mirror of already-published SBo packages**. No new
packages are developed here. Its job is the ongoing upkeep of packages already
on SBo:
1. Track upstream version changes (via nvchecker).
2. Reflect a new upstream version in the package's `.SlackBuild` / `.info`.
3. Test-build the bump on both Slackware 15.0 and -current.
4. Deliver the update to SBo (GitHub PR or submission tarball).
New-package development happens in **other** repos, not here:
- [my-slackbuilds](https://github.com/danixland/my-slackbuilds): regular
packages, plus SBo packages whose upstream moves faster than SBo review
(worked ahead of the SBo copy).
- [Slackware-Pentesting-Suite](https://github.com/danixland/Slackware-Pentesting-Suite):
cybersecurity packages.
When a new package is uploaded to SBo and approved, it **moves here** and this
repo takes over its maintenance.
---
## Repo Structure
Packages live under their SBo category, mirroring the layout of the SBo repo
itself (`<category>/<package-name>/`):
```
<category>/<package-name>/
├── <package-name>.SlackBuild # Main build script
├── <package-name>.info # Metadata (version, checksums, URLs)
├── README # Description and usage notes
├── slack-desc # Package description (11-line format)
├── <package-name>.desktop # (optional) Desktop entry for GUI apps
└── [...] # other optional files
```
The category is not recorded anywhere else: the directory *is* the category.
It is authoritative in the synced SBo tree, so to find where a package
belongs:
```bash
find /var/lib/sbopkg/SBo-stable -maxdepth 2 -mindepth 2 -type d -name '<pkg>'
```
Current categories: `misc` (SecLists, exploitdb, nuclei), `games`
(UrbanTerror), `network` (feroxbuster, ffuf, gobuster,
metasploit-framework-bin, r8125).
Matching SBo's layout means a package directory exports to the SBo repo at
the identical relative path, with no mapping step. Tooling that locates a
build must walk up to the directory holding the `.SlackBuild` rather than
assume a fixed depth.
Version tracking is handled by a single file:
```
.extras/nvchecker.toml # nvchecker config listing all packages
```
### `.extras/` holds all non-package repo files
Anything that is not a SlackBuild package must live under `.extras/`, never at
the repo root. Currently: `nvchecker.toml` (version tracking), `assets/`.
Maintainer tooling (git hooks, the upstream sweep, test builds, the SBo PR
export) is kept outside this repo, in the maintainer's private workspace.
---
## Build Strategies
Packages fall into several categories; the SlackBuild style differs
accordingly.
### Source builds (Go)
Packages such as `ffuf`, `gobuster`, `nuclei` are built from upstream source
tarballs using `go build`. Key points:
- Set `GOPATH`, `GOPROXY`, `GOFLAGS` before building
- Use `-buildmode=pie -trimpath -mod=readonly -modcacherw`
- Strip ELF binaries after build
- Clean up `$GOPATH` / Go module cache before packaging
- `REQUIRES="google-go-lang"` in the `.info` file
### Source builds (Rust)
Packages such as `feroxbuster` build from a vendored crates tarball
(`<pkg>-<version>-vendor.tar.gz`) declared as a second source in `.info`,
alongside the upstream tarball. The SlackBuild unpacks it, points cargo at it
via `.cargo/config.toml`, and builds fully offline (`cargo build --offline
--locked`). The vendor tarball is generated once per version with
`cargo-vendor-filterer`, with `SOURCE_DATE_EPOCH` pinned to the release tag's
commit date for a byte-for-byte reproducible archive. The exact command is
recorded in the package's own `README`.
### Binary repacks — Debian `.deb`
Packages such as `metasploit-framework-bin` are repacked from upstream `.deb`
archives (SBo convention: `.deb`/binary repacks take a `-bin` suffix):
- Extract with: `ar p <file>.deb data.tar.gz | tar xzv`
- Set `DOWNLOAD="UNSUPPORTED"` and use `DOWNLOAD_x86_64` / `MD5SUM_x86_64`
(plus the i386 pair when the package is multi-arch)
- Strip ELF binaries after extraction
#### `metasploit-framework-bin`: msfvenom bash-completion
The shipped `msfvenom.bash-completion` is a **pre-generated snapshot**, not a
static file. Upstream (kali) no longer ships it; they generate it at build
time with a ruby script that loads the framework and dumps the live
payload/encoder/arch/platform/format lists. We ship a snapshot instead of
running ruby at build time (hermetic build, no build-time dep).
**Regenerate it on every version bump.** No host install needed: `test-build
--keep` produces a `.txz`; extract it to a scratchpad dir and run the
generator against the *extracted* framework's bundled ruby. This avoids `sudo
installpkg` and is fully in the agent's hands.
**The `GEM_HOME`/`GEM_PATH`/`BUNDLE_GEMFILE` vars below are mandatory.** The
embedded ruby has `/opt/metasploit-framework` baked in as its prefix, so
bundler resolves gem paths there no matter where the tree was extracted, and
the run dies with:
```
Could not find metasploit-payloads-X, rex-socket-X, ... in locally installed
gems (Bundler::GemNotFound)
```
Pointing the gem vars at the extracted tree fixes it. Note `3.4.0` in that
path is the embedded **ruby version** and moves when upstream bumps ruby;
check `$FW/embedded/lib/ruby/gems/` if the path is wrong.
```bash
KEPT=/data/sbo-test-build/kept/metasploit-framework-bin-$VERSION-x86_64-*.tgz
tar xf $KEPT -C $SCRATCH/msf-extract
FW=$SCRATCH/msf-extract/opt/metasploit-framework
curl -o $SCRATCH/gen.rb \
https://gitlab.com/kalilinux/packages/metasploit-framework/-/raw/kali/master/debian/generate-msfvenom-bash-completion.rb
cd $FW/embedded/framework
GEM_HOME=$FW/embedded/lib/ruby/gems/3.4.0 \
GEM_PATH=$FW/embedded/lib/ruby/gems/3.4.0 \
BUNDLE_GEMFILE=$FW/embedded/framework/Gemfile \
$FW/embedded/bin/ruby \
-I$FW/embedded/framework/lib $SCRATCH/gen.rb \
> network/metasploit-framework-bin/msfvenom.bash-completion
```
**Do not fall back to running the generator against a live
`/opt/metasploit-framework`.** Without the gem vars the extracted-tree run
only appears to work when a host install happens to sit at that path, and it
then reads the *installed* version, silently emitting completion data for
whatever is on the host rather than the version being packaged. That is how
the 2026-07-30 "byte-identical, no host install needed" claim was reached; it
was actually reading a host install. Corrected 2026-08-07 during the 6.5.1
bump, where the host `/opt` still held 6.4.147.
Verify the output is non-empty and the `%s` slots were filled (grep for real
payload names like `windows/meterpreter`), then commit it with the bump.
#### `metasploit-framework-bin`: man pages
The .deb ships **no** metasploit man pages (its `share/man` tree is only for
bundled deps like postgres/ruby). We ship `msfconsole.1` and `msfvenom.1`
from kali, who maintain them by hand (no generator script). The SlackBuild
gzips them into `/usr/man/man1`. **Refresh them on version bumps** in case
kali has updated them:
```bash
for p in msfconsole msfvenom ; do
curl -o network/metasploit-framework-bin/$p.1 \
https://gitlab.com/kalilinux/packages/metasploit-framework/-/raw/kali/master/debian/extra/$p.1
done
```
For metasploit bumps, `PRGNAM=metasploit-framework-bin` with
`SRCNAM=metasploit-framework` drives the `.deb` glob and `/opt` path; pull
both-arch filenames and MD5s from the apt Packages indexes (`binary-amd64`
and `binary-i386`).
### Data / archive packages
Packages such as `SecLists`, `exploitdb` install data files rather than
compiled binaries. No stripping needed.
`exploitdb` fails `sbopkglint` test 15-noarch ("package claims to be
noarch, but contains ELF binaries") on both trees. The ELF files are
exploit payloads from the pinned `exploitdb-bin-sploits` 2022-11-22
archive, data to the package, not binaries it runs. False positive: keep
`ARCH=noarch` and note the finding in the PR body instead of claiming lint
clean. (Found: 2026-10-02, seen again 2026-10-23.)
### Out-of-tree kernel modules — `r8125`
Builds against installed kernel headers, so the package is kernel-specific:
`PKGVER` embeds the kernel version and the name comes out as
`r8125-<version>_<kernel>-<arch>-<build>_SBo.tgz`. `KERNEL` defaults to the
running `uname -r`; override it to build for a kernel that is installed but
not booted (e.g. right after a kernel upgrade, before rebooting):
```bash
KERNEL=6.1.0 ./r8125.SlackBuild # target a specific kernel
PRINT_PACKAGE_NAME=1 ./r8125.SlackBuild # check output name, no root needed
```
`doinst.sh` ships an `@KERNEL@` placeholder that `sed` replaces at build
time, so the packaged copy carries a literal kernel version and its `depmod`
runs against the right tree. When verifying a build, confirm the placeholder
is gone from the packaged `doinst.sh`.
**DASH must stay disabled.** The make invocation passes
`ENABLE_DASH_SUPPORT=n`, and it is load-bearing, not cosmetic. Upstream's
Makefile defaults it to `y` and adds `-DENABLE_DASH_SUPPORT` through
`EXTRA_CFLAGS +=`, but the SlackBuild passes `EXTRA_CFLAGS="$SLKCFLAGS"` on
the make command line, which *overrides* the Makefile's value rather than
appending to it. The define is lost while `r8125_dash.o` is still built, and
`r8125_dash.c` then fails to compile against a struct whose members are
`#ifdef`'d out. Dropping the flag on a version bump brings the failure
straight back. The r8168 SBo package uses the same `EXTRA_CFLAGS` override
and builds only because its Makefile happens to default DASH off. DASH is
out-of-band management hardware, unused here.
Upstream is tracked against Realtek's download API, not a git forge, so the
`.info` `DOWNLOAD` points at a mirror of the tarball rather than Realtek
directly (their download endpoint is an interstitial page, not a file).
Realtek edits the listing's description text in place without re-rolling the
tarball, so a changed blurb is not a new release: compare `Version`,
`UpdateTime` and the MD5 before concluding anything changed.
---
## SlackBuild Scripting Guidelines
### Templates (local clone)
A clone of the SBo templates lives at `~/Templates/SlackBuilds/sbo/` (refreshed
by `~/Templates/SlackBuilds/update-templates.sh`). **Start from the matching
file there** rather than from memory:
- Per-build-type SlackBuilds: `autotools-`, `cmake-`, `meson-`, `python-`,
`perl-`, `rubygem-`, `haskell-template.SlackBuild`.
- Shared support files: `slack-desc`, `template.info`, `doinst.sh`,
`douninst.sh`.
The [online SBo template](https://slackbuilds.org/templates/) remains the
authority; the local clone mirrors it. Refresh the clone if it looks stale
before relying on it.
### General
- Follow the SBo template (local clone above) as the base for all scripts
- Use `set -e` to abort on errors
- Honor `$TMP`, `$BUILD`, `$TAG`, `$OUTPUT` variables; default values must be set if unset
- Use `$ARCH` detection with proper `SLKCFLAGS` and `LIBDIRSUFFIX`
- Strip binaries and libraries unless upstream explicitly discourages it
- Install docs to `/usr/doc/$PRGNAM-$VERSION/`
- Always include `find -L` + `chown`/`chmod` cleanup block before packaging
- Copy repo files into `$PKG` with `cat src > dest`, never `cp`. `cat` writes
through a fresh destination so the build's umask/root ownership sets the
perms; `cp` bleeds the git working-tree mode/ownership into the package.
Applies to `slack-desc`, `doinst.sh`, and any file staged from `$CWD`
(SlackBuild, README, `.nvchecker`) into `$PKG`.
- Use `makepkg -l y -c n` to create the final package
### `.info` file
Must contain:
```
PRGNAM, VERSION, HOMEPAGE, DOWNLOAD, MD5SUM (or SHA256SUM), REQUIRES, MAINTAINER, EMAIL
```
- Checksums must match the exact source archive
- MAINTAINER/EMAIL are danix's, since this repo is his SBo-official packages
- Use `REQUIRES=""` if no SBo dependencies; list space-separated SBo package names otherwise
### `slack-desc`
- Exactly 11 lines in the `package-name: description` format
- First line: `package-name: package-name (short one-liner)`
- Lines 2–11: description, leave blank lines as `package-name:`
- Handy ruler line must be included (but not shipped)
---
## Version Tracking: nvchecker
A single `.extras/nvchecker.toml` tracks upstream versions for all packages.
**Every package in this repo must have a stanza there.**
The file has no `[__config__]`. Do not run it as-is against GitHub: the
anonymous API budget (60 req/h) runs out and later stanzas 403. Run it from a
throwaway copy with a `[__config__]` that adds a GitHub token keyfile, and
probe single stanzas with `nvchecker -c <cfg> -e <name>`.
For github stanzas prefer `use_latest_release` (hits `releases/latest`,
lenient) over `use_max_tag` (hits `git/refs/tags`, tightly rate-limited); use
`use_max_tag` only for repos that tag but don't cut Releases (a
`use_latest_release` probe 404s on those).
When a new version is detected, update `VERSION` in both `.SlackBuild` and
`.info`, then fix the checksum with `sbodl` (see below).
---
## Tooling: sbo-maintainer-tools
Source: https://slackware.uk/~urchlay/repos/sbo-maintainer-tools
| Tool | Purpose |
|------|---------|
| `sbolint` | Lint `.SlackBuild`, `README`, `.info`, `slack-desc` |
| `sbopkglint` | Lint the built package |
| `sbofixinfo` | Auto-fix common `.info` file issues |
| `sbodl` | Download sources and verify `MD5SUM`/`SHA256SUM` from `.info` |
Run `sbolint` on every changed package before committing. A `pre-commit`
wrapper that does it automatically is available from
https://slackware.uk/~urchlay/repos/sbostuff.
### Checksums and source symlinks
`sbodl` verifies checksums, `sbofixinfo` only normalizes `.info` formatting
and does not touch checksums. After a version bump: run `sbodl`, it
downloads and prints `WARN: md5sum doesn't match ... got: <new>`; put the
`got:` value in `MD5SUM`; run `sbodl` again until `md5sum matches OK`.
`sbodl` creates symlinks in the package directory pointing to downloaded
sources. Remove them before staging; they must never be committed. Run it
from the repo root so no package is missed:
```bash
find . -type l -not -path './.git/*' -print -delete
```
### File modes: 0644
SBo requires 0644 for files and 0755 for directories, and the upload form
rejects otherwise. Git tracks the exec bit, so a `.SlackBuild` that was ever
`chmod +x` carries 0755 into the repo. `sbolint` catches it
(`must have mode 0644, not 0755`), which is one reason to run it before every
commit. To fix, both on disk and in the index:
```bash
chmod 644 <category>/<pkg>/<file>
git add --chmod=-x <category>/<pkg>/<file>
```
Audit the whole repo:
```bash
git ls-files --stage | awk '$1!="100644" && $4 !~ /^\.extras/ {print $1, $4}'
```
---
## SBo Submission Guidelines
Before submitting or updating a package on SlackBuilds.org:
1. **Pass all lint checks** — `sbolint` and `sbopkglint` must report no errors
2. **Test the build** on a clean Slackware installation (or VM snapshot)
3. **Verify checksums** via `sbodl` before committing
4. **Check `README`** includes all non-SBo dependencies and any special build notes
5. **Follow the SBo submission guidelines**: https://slackbuilds.org/guidelines/
6. **Bump `VERSION`** in both `.SlackBuild` and `.info` when updating
7. **Run `sbodl`** after every version bump to verify the checksum, and
`sbofixinfo` to normalize the `.info`
---
## Commit Conventions
Local commits in this repo:
- One commit per package add/update
- Commit message format: `<package-name>: add version X.Y.Z` or `<package-name>: update to X.Y.Z`
- For fixes: `<package-name>: fix <short description>`
- Repo-level changes (AGENTS.md, nvchecker config) take no package
prefix and are never exported
The **exported PR commit uses SBo's wording instead**, generated from the path
and `.info` VERSION at export time: `<category>/<package>: Updated for version
X.Y.Z.` The two histories are independent by design, so local commits need not adopt SBo's format.
---
## Maintainer
danix
|