{ config, lib, pkgs, ... }: with lib; let portSpec = name: '' port ${name} type pipe protocol e reliable true command ${pkgs.openssh}/bin/ssh -x -o batchmode=yes ${name} ''; sysSpec = name: '' system ${name} time Any port ${name} chat "" protocol e ''; in { options = { services.uucp = { enable = mkOption { type = types.bool; default = false; description = '' If enabled we set up an account accesible via uucp over ssh ''; }; nodeName = mkOption { type = types.str; default = "nixos"; description = "uucp node name"; }; sshUser = mkOption { type = types.attrs; default = {}; description = "Overrides for the local uucp linux-user"; }; sshConfig = mkOption { type = types.str; default = ""; description = "~uucp/.ssh/config"; }; remoteNodes = mkOption { type = types.listOf types.str; default = []; description = "List of ports to set up. You will probably need to configure these in sshConfig"; }; spoolDir = mkOption { type = types.path; default = "/var/spool/uucp"; description = "Spool directory"; }; lockDir = mkOption { type = types.path; default = "/var/spool/uucp"; description = "Lock directory"; }; pubDir = mkOption { type = types.path; default = "/var/spool/uucppublic"; description = "Public directory"; }; logFile = mkOption { type = types.path; default = "/var/log/uucp"; description = "Log file"; }; statFile = mkOption { type = types.path; default = "/var/log/uucp.stat"; description = "Statistics file"; }; debugFile = mkOption { type = types.path; default = "/var/log/uucp.debug"; description = "Debug file"; }; extraConfig = mkOption { type = types.string; default = ""; description = "Extra configuration to append verbatim to `/etc/uucp/config'"; }; }; }; config = mkIf config.services.uucp.enable { environment.etc."uucp/config" = { text = '' hostname ${config.services.uucp.nodeName} spool ${config.services.uucp.spoolDir} lockdir ${config.services.uucp.lockDir} pubdir ${config.services.uucp.pubDir} logfile ${config.services.uucp.logFile} statfile ${config.services.uucp.statFile} debugfile ${config.services.uucp.debugFile} ${config.services.uucp.extraConfig} ''; }; users.users."uucp" = { name = "uucp"; isSystemUser = true; isNormalUser = false; createHome = true; home = config.services.uucp.spoolDir; description = "User for uucp over ssh"; } // config.services.uucp.sshUser; system.activationScripts."uucp-sshconfig" = '' mkdir -p ${config.users.users."uucp".home}/.ssh chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.users.users."uucp".home}/.ssh chmod 700 ${config.users.users."uucp".home}/.ssh ln -fs ${builtins.toFile "ssh-config" config.services.uucp.sshConfig} ${config.users.users."uucp".home}/.ssh/config ''; system.activationScripts."uucp-logs" = '' touch ${config.services.uucp.logFile} chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.services.uucp.logFile} chmod 644 ${config.services.uucp.logFile} touch ${config.services.uucp.statFile} chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.services.uucp.statFile} chmod 644 ${config.services.uucp.statFile} touch ${config.services.uucp.debugFile} chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.services.uucp.debugFile} chmod 644 ${config.services.uucp.debugFile} ''; environment.etc."uucp/port" = { text = '' port ssh type stdin protocol e '' + concatStringsSep "\n" (map portSpec config.services.uucp.remoteNodes); }; environment.etc."uucp/sys" = { text = concatStringsSep "\n" (map sysSpec config.services.uucp.remoteNodes); }; security.setuidOwners = map (p: {program = p; owner = "root"; group = "root"; setuid = true; setgid = false;}) ["uucico" "uuxqt" "cu" "uucp" "uuname" "uustat" "uux"]; nixpkgs.config.packageOverrides = pkgs: with pkgs; { uucp = stdenv.lib.overrideDerivation uucp (oldAttrs: { configureFlags = "--with-newconfigdir=/etc/uucp"; }); }; environment.systemPackages = with pkgs; [uucp]; }; }