···93939494- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
95959696+- [armagetronad](https://wiki.armagetronad.org), a mid-2000s 3D lightcycle game widely played at iD Tech Camps. You can define multiple servers using `services.armagetronad.<server>.enable`.
9797+9698- [TuxClocker](https://github.com/Lurkki14/tuxclocker), a hardware control and monitoring program. Available as [programs.tuxclocker](#opt-programs.tuxclocker.enable).
979998100- [ALVR](https://github.com/alvr-org/alvr), a VR desktop streamer. Available as [programs.alvr](#opt-programs.alvr.enable)
···11+{ lib, stdenv, fetchurl, pkgsi686Linux, dpkg, makeWrapper, coreutils, gnused, gawk, file, cups, util-linux, xxd, runtimeShell
22+, ghostscript, a2ps, bash }:
33+44+# Why:
55+# The executable "brprintconf_mfcj880dw" binary is looking for "/opt/brother/Printers/%s/inf/br%sfunc" and "/opt/brother/Printers/%s/inf/br%src".
66+# Whereby, %s is printf(3) string substitution for stdin's arg0 (the command's own filename) from the 10th char forwards, as a runtime dependency.
77+# e.g. Say the filename is "0123456789ABCDE", the runtime will be looking for /opt/brother/Printers/ABCDE/inf/brABCDEfunc.
88+# Presumably, the binary was designed to be deployed under the filename "printconf_mfcj880dw", whereby it will search for "/opt/brother/Printers/mfcj880dw/inf/brmfcj880dwfunc".
99+# For NixOS, we want to change the string to the store path of brmfcj880dwfunc and brmfcj880dwrc but we're faced with two complications:
1010+# 1. Too little room to specify the nix store path. We can't even take advantage of %s by renaming the file to the store path hash since the variable is too short and can't contain the whole hash.
1111+# 2. The binary needs the directory it's running from to be r/w.
1212+# What:
1313+# As such, we strip the path and substitution altogether, leaving only "brmfcj880dwfunc" and "brmfcj880dwrc", while filling the leftovers with nulls.
1414+# Fully null terminating the cstrings is necessary to keep the array the same size and preventing overflows.
1515+# We then use a shell script to link and execute the binary, func and rc files in a temporary directory.
1616+# How:
1717+# In the package, we dump the raw binary as a string of search-able hex values using hexdump. We execute the substitution with sed. We then convert the hex values back to binary form using xxd.
1818+# We also write a shell script that invoked "mktemp -d" to produce a r/w temporary directory and link what we need in the temporary directory.
1919+# Result:
2020+# The user can run brprintconf_mfcj880dw in the shell.
2121+2222+stdenv.mkDerivation rec {
2323+ pname = "mfcj880dwlpr";
2424+ version = "1.0.0-0";
2525+2626+ src = fetchurl {
2727+ url = "https://download.brother.com/welcome/dlf102038/mfcj880dwlpr-${version}.i386.deb";
2828+ sha256 = "1680b301f660a407fe0b69f5de59c7473d2d66dc472a1589b0cd9f51736bfea7";
2929+ };
3030+3131+ nativeBuildInputs = [ makeWrapper ];
3232+ buildInputs = [ cups ghostscript dpkg a2ps ];
3333+3434+ dontUnpack = true;
3535+3636+ brprintconf_mfcj880dw_script = ''
3737+ #!${runtimeShell}
3838+ cd $(mktemp -d)
3939+ ln -s @out@/usr/bin/brprintconf_mfcj880dw_patched brprintconf_mfcj880dw_patched
4040+ ln -s @out@/opt/brother/Printers/mfcj880dw/inf/brmfcj880dwfunc brmfcj880dwfunc
4141+ ln -s @out@/opt/brother/Printers/mfcj880dw/inf/brmfcj880dwrc brmfcj880dwrc
4242+ ./brprintconf_mfcj880dw_patched "$@"
4343+ '';
4444+4545+ installPhase = ''
4646+ dpkg-deb -x $src $out
4747+ substituteInPlace $out/opt/brother/Printers/mfcj880dw/lpd/filtermfcj880dw \
4848+ --replace-fail /opt "$out/opt"
4949+ substituteInPlace $out/opt/brother/Printers/mfcj880dw/lpd/psconvertij2 \
5050+ --replace-fail "GHOST_SCRIPT=`which gs`" "GHOST_SCRIPT=${ghostscript}/bin/gs"
5151+ substituteInPlace $out/opt/brother/Printers/mfcj880dw/inf/setupPrintcapij \
5252+ --replace-fail "/opt/brother/Printers" "$out/opt/brother/Printers" \
5353+ --replace-fail "printcap.local" "printcap"
5454+5555+ patchelf --set-interpreter ${pkgsi686Linux.stdenv.cc.libc.out}/lib/ld-linux.so.2 \
5656+ --set-rpath $out/opt/brother/Printers/mfcj880dw/inf:$out/opt/brother/Printers/mfcj880dw/lpd \
5757+ $out/opt/brother/Printers/mfcj880dw/lpd/brmfcj880dwfilter
5858+ patchelf --set-interpreter ${pkgsi686Linux.stdenv.cc.libc.out}/lib/ld-linux.so.2 $out/usr/bin/brprintconf_mfcj880dw
5959+6060+ #stripping the hardcoded path.
6161+ # /opt/brother/Printers/%s/inf/br%sfunc -> brmfcj880dwfunc
6262+ # /opt/brother/Printers/%s/inf/br%src -> brmfcj880dwrc
6363+ ${util-linux}/bin/hexdump -ve '1/1 "%.2X"' $out/usr/bin/brprintconf_mfcj880dw | \
6464+ sed 's.2F6F70742F62726F746865722F5072696E746572732F25732F696E662F6272257366756E63.62726d66636a383830647766756e6300000000000000000000000000000000000000000000.' | \
6565+ sed 's.2F6F70742F62726F746865722F5072696E746572732F25732F696E662F627225737263.62726d66636a3838306477726300000000000000000000000000000000000000000000.' | \
6666+ ${xxd}/bin/xxd -r -p > $out/usr/bin/brprintconf_mfcj880dw_patched
6767+ chmod +x $out/usr/bin/brprintconf_mfcj880dw_patched
6868+ #executing from current dir. segfaults if it's not r\w.
6969+ mkdir -p $out/bin
7070+ echo -n "$brprintconf_mfcj880dw_script" > $out/bin/brprintconf_mfcj880dw
7171+ chmod +x $out/bin/brprintconf_mfcj880dw
7272+ substituteInPlace $out/bin/brprintconf_mfcj880dw --replace-fail @out@ $out
7373+7474+ # NOTE: opt/brother/Printers/mfcj880dw/lpd/brmfcj880dwfilter also has cardcoded paths, but we can not simply replace them
7575+7676+ mkdir -p $out/lib/cups/filter/
7777+ ln -s $out/opt/brother/Printers/mfcj880dw/lpd/filtermfcj880dw $out/lib/cups/filter/brother_lpdwrapper_mfcj880dw
7878+7979+ wrapProgram $out/opt/brother/Printers/mfcj880dw/lpd/psconvertij2 \
8080+ --prefix PATH ":" ${ lib.makeBinPath [ coreutils gnused gawk ] }
8181+ wrapProgram $out/opt/brother/Printers/mfcj880dw/lpd/filtermfcj880dw \
8282+ --prefix PATH ":" ${ lib.makeBinPath [ coreutils gnused file ghostscript a2ps ] }
8383+ '';
8484+8585+ meta = with lib; {
8686+ description = "Brother MFC-J880DW LPR driver";
8787+ downloadPage = "https://support.brother.com/g/b/downloadlist.aspx?c=us&lang=en&prod=mfcj880dw_us_eu_as&os=128";
8888+ homepage = "http://www.brother.com/";
8989+ sourceProvenance = with sourceTypes; [ binaryNativeCode ];
9090+ license = with licenses; unfree;
9191+ maintainers = with maintainers; [ _6543 ];
9292+ platforms = with platforms; linux;
9393+ };
9494+}
···88 magma-hip,
99 magma-cuda-static,
1010 # Use the system NCCL as long as we're targeting CUDA on a supported platform.
1111- useSystemNccl ? (cudaSupport && !cudaPackages.nccl.meta.unsupported),
1111+ useSystemNccl ? (cudaSupport && !cudaPackages.nccl.meta.unsupported || rocmSupport),
1212 MPISupport ? false, mpi,
1313 buildDocs ? false,
1414