Printer config for old laser printer

I trying to make a config of my printer, following the description on the wiki.

I have a tar file Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar contaning the driver and I
trying to install it.

It contains:

usr
├── lib
│   └── cups
│       └── filter
│           ├── FXM_ALC
│           ├── FXM_CC
│           ├── FXM_HBPL
│           ├── FXM_MF
│           ├── FXM_PF
│           ├── FXM_PM2FXR
│           ├── FXM_PR
│           ├── FXM_PS2PM
│           └── FXM_SBP
└── share
    └── cups
        ├── FujiXerox
        │   └── dlut
        │       └── FX_DocuPrint_C525_A_AP.dlut
        └── model
            └── FujiXerox
                └── en
                    └── FX_DocuPrint_C525_A_AP.ppd

10 directories, 11 files

I have tried to make a Nix file for my printer.

# cat Xerox_Phaser_6125N.nix 
{ stdenv }:
stdenv.mkDerivation rec {
  name = "Xerox-Phaser-6125N-${version}";
  version = "1.0";

  src = ./.;

  installPhase = ''
    # mkdir -p $out/share/cups/model/
    # cp myprinter.ppd $out/share/cups/model/
    tar -C /tmp/ -xf Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar
    cp -r /tmp/usr/. $out/
    # If you need to patch the path to files outside the nix store, you can do it this way
    # (if the ppd also comes with executables you may need to also patch the executables)
    # substituteInPlace $out/share/cups/model/myprinter.ppd \
  '';
}

I load it in the configuration.nix like this:

  services.printing.drivers = [ 
    (pkgs.callPackage ./Xerox_Phaser_6125N.nix {})
  ];

Yes, the printer is different then the driver, but it is not an error but a hack. This is a driver
that work for this printer on Linux. :slight_smile:

But when I try to make the system, I get this error:

no Makefile or custom buildPhase, doing nothing
installing
tar: .: Cannot utime: Operation not permitted
tar: .: Cannot change mode to rwxr-xr-t: Operation not permitted
tar: Exiting with failure status due to previous errors
error: builder for '/nix/store/xzlvpiqcmxc585db6iak5hh22m47mkpp-Xerox-Phaser-6125N-1.0.drv' failed with exit code 2
error: 1 dependencies of derivation '/nix/store/pqq048xiwl70h41gzhmbj6l9b71h88pp-X-Restart-Triggers.drv' failed to build
error: 1 dependencies of derivation '/nix/store/1hmmdq3hn7x72bvzhgn66wdzh5ilxaw2-cups-progs.drv' failed to build
error: 1 dependencies of derivation '/nix/store/5wlcyawpvgsyvsdi1lgmldsrh2aidwnf-hwdb.bin.drv' failed to build
error: 1 dependencies of derivation '/nix/store/38sdfkmgvavxxhw5smcx17vm5iiypdl5-etc.drv' failed to build
error: 1 dependencies of derivation '/nix/store/6hzvvdca09qcp0c300mwxinq9w14a4rm-nixos-system-cynix-23.05pre487203.7084250df3d.drv' failed to build

Looks like I make some error in unpacking the tar file.

But what is the proper way to unpack a tar file, and installing something like this?

Try

src = requireFile {
    name = "Fuji_Xerox-DocuPrint_C525_A_AP-${version}-1.i386.tar";
    url = "https://www.xerox.com"; # this in only printed if src is no in the store
    sha256 = "...";
};
dontBuild = true;

add the tarball to the store with nix-store --add-fixed Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar

and in your install phase use

tar -xf $src
mkdir -p $out
cp -r usr $out/.

I get this error!

error: undefined variable 'requireFile'

       at /etc/nixos/Xerox_Phaser_6125N.nix:6:9:

            5|
            6|   src = requireFile {
             |         ^
            7|       name = "Fuji_Xerox-DocuPrint_C525_A_AP-${version}-1.i386.tar";

You also need to change { stdenv }: to { stdenv, requireFile }: at the beginning of Xerox_Phaser_6125N.nix.

This version can build.

# cat Xerox_Phaser_6125N.nix
{ stdenv, requireFile }:
stdenv.mkDerivation rec {
  name = "Xerox-Phaser-6125N-${version}";
  version = "1.0";

  src = requireFile {
      name = "Fuji_Xerox-DocuPrint_C525_A_AP-${version}-1.i386.tar";
      # add the file to the store, like this.
      # nix-store --add-fixed sha256 ./Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar
      url = "https://www.xerox.com"; # this in only printed if src is no in the store
      # found sha256 with nix-hash --flat --base32 --type sha256 Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar 
      sha256 = "14hw5wmmv7xzyz7j2liljlrkprppj68ks7r1lrlyjrrix345pkrf";
  };
  dontBuild = true;

  installPhase = ''
    # mkdir -p $out/share/cups/model/
    # cp myprinter.ppd $out/share/cups/model/
    tar -xf $src
    mkdir -p $out
    cp -r usr/. $out/
    # If you need to patch the path to files outside the nix store, you can do it this way
    # (if the ppd also comes with executables you may need to also patch the executables)
    # substituteInPlace $out/share/cups/model/FujiXerox/en/FX_DocuPrint_C525_A_AP.ppd --replace "/usr" $out
    # substituteInPlace $out/ --replace "/usr" $out
    # substituteInPlace $out/  --replace "/usr/" ""
  '';
}

But I still need to substitute the path out.

Is is possible to run substituteInPlace recursively on all files in a directory structure?

Where do I lookup information about substituteInPlace and other build in functions?

Is is possible to run substituteInPlace recursively on all files in a directory structure?

find . -type f -print0 | xargs -0 .....

Or

find . -type f -exec ...

Where do I lookup information about substituteInPlace and other build in functions?

I always just check the source (it’s very convenient having ixpkgs checked out). All the various build helpers are in here: https://github.com/NixOS/nixpkgs/tree/master/pkgs/build-support

And substituteInPlace and friends : https://github.com/NixOS/nixpkgs/tree/master/pkgs/build-support/substitute

I am getting this error:

installing
xargs: substituteInPlace: No such file or directory
error: builder for '/nix/store/308dhrpvmq5vxny0cbxrqdyjv3vdgphf-Xerox-Phaser-6125N-1.0.drv' failed with exit code 127
error: 1 dependencies of derivation '/nix/store/2qcw3dlhggx7ddf814w4qv4y352vagx1-X-Restart-Triggers.drv' failed to build

From this code:

  installPhase = ''
    # mkdir -p $out/share/cups/model/
    # cp myprinter.ppd $out/share/cups/model/
    tar -xf $src
    mkdir -p $out
    cp -r usr/. $out/
    # If you need to patch the path to files outside the nix store, you can do it this way
    # (if the ppd also comes with executables you may need to also patch the executables)
    # substituteInPlace $out/share/cups/model/FujiXerox/en/FX_DocuPrint_C525_A_AP.ppd --replace "/usr" $out
    
    ## find files with refs to filters? 
    grep -lrUH "/usr/lib/cups/filter" $out/ | xargs -I xfile substituteInPlace xfile --replace "/usr/lib/cups/filter" "$out/lib/cups/filter"
    ## find files with refs to driver (dlut and ppd)
    grep -lrUH  "/usr/share/cups/" $out/ | xargs -I xfile substituteInPlace xfile --replace "/usr/share/cups/" "$out/share/cups/"
    # substituteInPlace $out/  --replace "/usr/" ""
  '';

xargs creates subprocesses, substituteInPlace is a shell function; export -f substituteInPlace right before doing grep .. | xargs .. might help (not tested)

export -f … did not work.

maybe try sed -i instead of substituteInPlace

Next problem.

$ strings FXM_MF | head
/lib/ld-linux.so.2
SuSE
libcups.so.2
_DYNAMIC
ppdFindMarkedChoice
_init
_fini
_GLOBAL_OFFSET_TABLE_
_Jv_RegisterClasses
__gmon_start__

as I understand it “/lib/ld-linux.so.2” need to be exchanged with a /nix/store path. How do I use patchelf to do that?

The current version looks like this.

# cat Xerox_Phaser_6125N.nix
{ stdenv, requireFile, ghostscript, autoPatchelfHook, lib, glibc, cups}:
stdenv.mkDerivation rec {
  name = "Xerox-Phaser-6125N-${version}";
  version = "1.0";

  src = requireFile {
      name = "Fuji_Xerox-DocuPrint_C525_A_AP-${version}-1.i386.tar";
      # add the file to the store, like this.
      # nix-store --add-fixed sha256 ./Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar
      url = "https://www.xerox.com"; # this in only printed if src is no in the store
      # found sha256 with nix-hash --flat --base32 --type sha256 Fuji_Xerox-DocuPrint_C525_A_AP-1.0-1.i386.tar 
      sha256 = "14hw5wmmv7xzyz7j2liljlrkprppj68ks7r1lrlyjrrix345pkrf";
  };
  dontConfigure = true;
  dontBuild = true;
  meta = {
    architectures = [ "x86" ];
   };

   nativeBuildInputs = [
    autoPatchelfHook
   ];
  
  buildInputs = [
    cups
    ];

  installPhase = ''
    # mkdir -p $out/share/cups/model/
    # cp myprinter.ppd $out/share/cups/model/
    tar -xf $src
    mkdir -p $out
    cp -r usr/. $out/
    # If you need to patch the path to files outside the nix store, you can do it this way
    # (if the ppd also comes with executables you may need to also patch the executables)
    # substituteInPlace $out/share/cups/model/FujiXerox/en/FX_DocuPrint_C525_A_AP.ppd --replace "/usr" $out
    
    ## find files with refs to filters? 
    substituteInPlace $out/share/cups/model/FujiXerox/en/FX_DocuPrint_C525_A_AP.ppd --replace "/usr/lib/cups/filter" $out/lib/cups/filter
    # find . -type f -print0 | xargs -I xfile substituteInPlace xfile --replace "/usr/lib/cups/filter" "$out/lib/cups/filter"
    ## find files with refs to driver (dlut and ppd)
    substituteInPlace $out/share/cups/model/FujiXerox/en/FX_DocuPrint_C525_A_AP.ppd --replace "/usr/share/cups" $out/share/cups
    substituteInPlace $out/lib/cups/filter/FXM_PS2PM --replace "/usr" "${ghostscript}"
    # grep -r dlut /nix/store/*Xerox-Phaser-6125N-1.0 2>/dev/null | grep "FX_DocuPrint_C525_A_AP.ppd"
  '';

#  preFixup = let
#    # we prepare our library path in the let clause to avoid it become part of the input of mkDerivation
#    libPath = lib.makeLibraryPath [
#      # cups-2.4.2-lib    # /lib/libcups.so.2
#      glibc              # libc.so.6
#    ];
#  in ''
#    patchelf \
#      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
#      --set-rpath "${libPath}" \
#      $out/lib/cups/filter/FXM_ALC
#  '';
}

Getting this log file.

          PosixPath('/nix/store/nf1lkdrhapsx5lr6diyxyjr7pb7r20gr-patch-shebangs.sh/lib'),
          PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'),
          PosixPath('/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh/lib'),
          PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'),
          PosixPath('/nix/store/a9ndjg0b1ivi0av9m93vfkrndp7fqbw1-strip.sh/lib'),
          PosixPath('/nix/store/c22pksfcw1nnkcxlf5xm7ljxhngg3n65-gcc-wrapper-12.2.0/lib'),
          PosixPath('/nix/store/fsx3pqfpp3n41y0x467v9xl7gd8zx4qa-binutils-wrapper-2.40/lib'),
          PosixPath('/nix/store/kl64bhhcnrqd9pqqcn21qx7xxv7v3khi-cups-2.4.2-dev/lib'),
          PosixPath('/nix/store/xh8bxi7d2b9s84pn4z5pzxm5ii0cpc46-gmp-with-cxx-6.2.1-dev/lib'),
          PosixPath('/nix/store/h2pqqpgkfjh0q3rf9ya44p8swmiwa4bs-gmp-with-cxx-6.2.1/lib'),
          PosixPath('/nix/store/da3j6kzrh193crhsx5nj8vkvj7z96ppp-cups-2.4.2-lib/lib'),
          PosixPath('/nix/store/2bqi93aplq25y63mliby0krqlvzn5h2h-cups-2.4.2/lib')],
 'paths': [PosixPath('/nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0')],
 'recursive': True,
 'runtime_dependencies': []}
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_CC because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_ALC because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_PF because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_PR because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_MF because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_PM2FXR because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_SBP because its architecture (x86) differs from target (x64)
skipping /nix/store/6p0cai94ipy5ibag1ddlvdp8hsg16d17-Xerox-Phaser-6125N-1.0/lib/cups/filter/FXM_HBPL because its architecture (x86) differs from target (x64)
auto-patchelf: 0 dependencies could not be satisfied

Next problem an architecture problem? Is this solvable?

I tried to connect to the printer via ftp, but the data-transfer did not work.
I did a port scan to figure out the problem. And discovers that there was a web server
on the printer with status information and more.

completely undocumented in the Printer Settings print out.

Anyone with access to a Mac? That can help me extract the ppd file in this Mac printer diver ?

As described here?