python312Packages.prosemirror: 0.5.0 -> 0.5.1 (#365256)
[NixPkgs.git] / pkgs / misc / cups / drivers / mfcj6510dwlpr / default.nix
blobb63b297a17aaab6e4b6bd2d0d3685083cfc2fe5a
2   lib,
3   stdenv,
4   fetchurl,
5   pkgsi686Linux,
6   dpkg,
7   makeWrapper,
8   coreutils,
9   gnused,
10   gawk,
11   file,
12   cups,
13   util-linux,
14   xxd,
15   runtimeShell,
16   ghostscript,
17   a2ps,
20 # Why:
21 # The executable "brprintconf_mfcj6510dw" binary is looking for "/opt/brother/Printers/%s/inf/br%sfunc" and "/opt/brother/Printers/%s/inf/br%src".
22 # 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.
23 # e.g. Say the filename is "0123456789ABCDE", the runtime will be looking for /opt/brother/Printers/ABCDE/inf/brABCDEfunc.
24 # Presumably, the binary was designed to be deployed under the filename "printconf_mfcj6510dw", whereby it will search for "/opt/brother/Printers/mfcj6510dw/inf/brmfcj6510dwfunc".
25 # For NixOS, we want to change the string to the store path of brmfcj6510dwfunc and brmfcj6510dwrc but we're faced with two complications:
26 # 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.
27 # 2. The binary needs the directory it's running from to be r/w.
28 # What:
29 # As such, we strip the path and substitution altogether, leaving only "brmfcj6510dwfunc" and "brmfcj6510dwrc", while filling the leftovers with nulls.
30 # Fully null terminating the cstrings is necessary to keep the array the same size and preventing overflows.
31 # We then use a shell script to link and execute the binary, func and rc files in a temporary directory.
32 # How:
33 # 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.
34 # 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.
35 # Result:
36 # The user can run brprintconf_mfcj6510dw in the shell.
38 stdenv.mkDerivation rec {
39   pname = "mfcj6510dwlpr";
40   version = "3.0.0-1";
42   src = fetchurl {
43     url = "https://download.brother.com/welcome/dlf006614/mfcj6510dwlpr-${version}.i386.deb";
44     sha256 = "1ccvx393pqavsgzd8igrzlin5jrsf01d3acyvwqd1d0yz5jgqy6d";
45   };
47   nativeBuildInputs = [ makeWrapper ];
48   buildInputs = [
49     cups
50     ghostscript
51     dpkg
52     a2ps
53   ];
55   dontUnpack = true;
57   brprintconf_mfcj6510dw_script = ''
58     #!${runtimeShell}
59     cd $(mktemp -d)
60     ln -s @out@/usr/bin/brprintconf_mfcj6510dw_patched brprintconf_mfcj6510dw_patched
61     ln -s @out@/opt/brother/Printers/mfcj6510dw/inf/brmfcj6510dwfunc brmfcj6510dwfunc
62     ln -s @out@/opt/brother/Printers/mfcj6510dw/inf/brmfcj6510dwrc brmfcj6510dwrc
63     ./brprintconf_mfcj6510dw_patched "$@"
64   '';
66   installPhase = ''
67     dpkg-deb -x $src $out
68     substituteInPlace $out/opt/brother/Printers/mfcj6510dw/lpd/filtermfcj6510dw \
69       --replace /opt "$out/opt"
70     substituteInPlace $out/opt/brother/Printers/mfcj6510dw/lpd/psconvertij2 \
71       --replace "GHOST_SCRIPT=`which gs`" "GHOST_SCRIPT=${ghostscript}/bin/gs"
72     substituteInPlace $out/opt/brother/Printers/mfcj6510dw/inf/setupPrintcapij \
73       --replace "/opt/brother/Printers" "$out/opt/brother/Printers" \
74       --replace "printcap.local" "printcap"
76     patchelf --set-interpreter ${pkgsi686Linux.stdenv.cc.libc.out}/lib/ld-linux.so.2 \
77       --set-rpath $out/opt/brother/Printers/mfcj6510dw/inf:$out/opt/brother/Printers/mfcj6510dw/lpd \
78       $out/opt/brother/Printers/mfcj6510dw/lpd/brmfcj6510dwfilter
79     patchelf --set-interpreter ${pkgsi686Linux.stdenv.cc.libc.out}/lib/ld-linux.so.2 $out/usr/bin/brprintconf_mfcj6510dw
81     #stripping the hardcoded path.
82     ${util-linux}/bin/hexdump -ve '1/1 "%.2X"' $out/usr/bin/brprintconf_mfcj6510dw | \
83     sed 's.2F6F70742F62726F746865722F5072696E746572732F25732F696E662F6272257366756E63.62726d66636a36353130647766756e63000000000000000000000000000000000000000000.' | \
84     sed 's.2F6F70742F62726F746865722F5072696E746572732F25732F696E662F627225737263.62726D66636A3635313064777263000000000000000000000000000000000000000000.' | \
85     ${xxd}/bin/xxd -r -p > $out/usr/bin/brprintconf_mfcj6510dw_patched
86     chmod +x $out/usr/bin/brprintconf_mfcj6510dw_patched
87     #executing from current dir. segfaults if it's not r\w.
88     mkdir -p $out/bin
89     echo -n "$brprintconf_mfcj6510dw_script" > $out/bin/brprintconf_mfcj6510dw
90     chmod +x $out/bin/brprintconf_mfcj6510dw
91     substituteInPlace $out/bin/brprintconf_mfcj6510dw --replace @out@ $out
93     mkdir -p $out/lib/cups/filter/
94     ln -s $out/opt/brother/Printers/mfcj6510dw/lpd/filtermfcj6510dw $out/lib/cups/filter/brother_lpdwrapper_mfcj6510dw
96     wrapProgram $out/opt/brother/Printers/mfcj6510dw/lpd/psconvertij2 \
97       --prefix PATH ":" ${
98         lib.makeBinPath [
99           coreutils
100           gnused
101           gawk
102         ]
103       }
104     wrapProgram $out/opt/brother/Printers/mfcj6510dw/lpd/filtermfcj6510dw \
105       --prefix PATH ":" ${
106         lib.makeBinPath [
107           coreutils
108           gnused
109           file
110           ghostscript
111           a2ps
112         ]
113       }
114   '';
116   meta = with lib; {
117     description = "Brother MFC-J6510DW LPR driver";
118     downloadPage = "http://support.brother.com/g/b/downloadlist.aspx?c=us&lang=en&prod=mfcj6510dw_all&os=128";
119     homepage = "http://www.brother.com/";
120     sourceProvenance = with sourceTypes; [ binaryNativeCode ];
121     license = with licenses; unfree;
122     maintainers = with maintainers; [ ramkromberg ];
123     platforms = with platforms; linux;
124   };