10 inherit (lib.options) literalExpression mkEnableOption mkOption;
23 inherit (lib.modules) mkDefault mkIf mkMerge;
26 Values can be either strings or integers
27 (which will be added to the config file verbatimly)
29 (which will be translated to multiple
30 lines with the same configuration key).
31 Boolean values are translated to "Yes" or "No".
32 The default contains some reasonable
33 configuration to yield an operational system.
37 # Options in HylaFAX configuration files can be
38 # booleans, strings, integers, or list thereof
39 # representing multiple config directives with the same key.
40 # This type definition resolves all
41 # those types into a list of strings.
49 innerType = coercedTo bool (x: if x then "Yes" else "No") (coercedTo int (toString) str);
51 attrsOf (coercedTo innerType lib.singleton (listOf innerType));
53 cfg = config.services.hylafax;
56 { name, config, ... }:
64 will be searched for in {file}`/dev`.
71 Name of modem configuration file,
72 will be searched for in {file}`config`
73 in the spooling area directory.
77 type = configAttrType;
82 LocalIdentifier = "LostInBerlin";
85 Attribute set of values for the given modem.
87 Options defined here override options in
88 {option}`commonModemConfig` for this modem.
92 config.name = mkDefault name;
93 config.config.Include = [ "config/${config.type}" ];
98 inherit (config.security) wrapperDir;
99 inherit (config.services.mail.sendmailSetuidWrapper) program;
100 mkIfDefault = cond: value: mkIf cond (mkDefault value);
101 noWrapper = config.services.mail.sendmailSetuidWrapper == null;
102 # If a sendmail setuid wrapper exists,
103 # we add the path to the default configuration file.
104 # Otherwise, we use `false` to provoke
105 # an error if hylafax tries to use it.
106 c.sendmailPath = mkMerge [
107 (mkIfDefault noWrapper "${pkgs.coreutils}/bin/false")
108 (mkIfDefault (!noWrapper) "${wrapperDir}/${program}")
110 importDefaultConfig =
111 file: lib.attrsets.mapAttrs (lib.trivial.const mkDefault) (import file { inherit pkgs; });
112 c.commonModemConfig = importDefaultConfig ./modem-default.nix;
113 c.faxqConfig = importDefaultConfig ./faxq-default.nix;
114 c.hfaxdConfig = importDefaultConfig ./hfaxd-default.nix;
120 c.hfaxdConfig.UserAccessFile = cfg.userAccessFile;
121 c.faxqConfig = lib.attrsets.mapAttrs (lib.trivial.const (v: mkIf (v != null) v)) {
122 AreaCode = cfg.areaCode;
123 CountryCode = cfg.countryCode;
124 LongDistancePrefix = cfg.longDistancePrefix;
125 InternationalPrefix = cfg.internationalPrefix;
127 c.commonModemConfig = c.faxqConfig;
135 options.services.hylafax = {
137 enable = mkEnableOption "HylaFAX server";
139 autostart = mkOption {
144 Autostart the HylaFAX queue manager at system start.
145 If this is `false`, the queue manager
146 will still be started if there are pending
147 jobs or if a user tries to connect to it.
151 countryCode = mkOption {
152 type = nullOr nonEmptyStr;
155 description = "Country code for server and all modems.";
158 areaCode = mkOption {
159 type = nullOr nonEmptyStr;
162 description = "Area code for server and all modems.";
165 longDistancePrefix = mkOption {
169 description = "Long distance prefix for server and all modems.";
172 internationalPrefix = mkOption {
176 description = "International prefix for server and all modems.";
179 spoolAreaPath = mkOption {
181 default = "/var/spool/fax";
183 The spooling area will be created/maintained
184 at the location given here.
188 userAccessFile = mkOption {
190 default = "/etc/hosts.hfaxd";
192 The {file}`hosts.hfaxd`
193 file entry in the spooling area
194 will be symlinked to the location given here.
195 This file must exist and be
196 readable only by the `uucp` user.
197 See hosts.hfaxd(5) for details.
198 This configuration permits access for all users:
200 environment.etc."hosts.hfaxd" = {
206 Note that host-based access can be controlled with
207 {option}`config.systemd.sockets.hylafax-hfaxd.listenStreams`;
208 by default, only 127.0.0.1 is permitted to connect.
212 sendmailPath = mkOption {
214 example = literalExpression ''"''${pkgs.postfix}/bin/sendmail"'';
217 Path to {file}`sendmail` program.
218 The default uses the local sendmail wrapper
219 (see {option}`config.services.mail.sendmailSetuidWrapper`),
220 otherwise the {file}`false`
221 binary to cause an error if used.
225 hfaxdConfig = mkOption {
226 type = configAttrType;
227 example.RecvqProtection = "0400";
229 Attribute set of lines for the global
230 hfaxd config file {file}`etc/hfaxd.conf`.
235 faxqConfig = mkOption {
236 type = configAttrType;
238 InternationalPrefix = "00";
239 LongDistancePrefix = "0";
242 Attribute set of lines for the global
243 faxq config file {file}`etc/config`.
248 commonModemConfig = mkOption {
249 type = configAttrType;
251 InternationalPrefix = "00";
252 LongDistancePrefix = "0";
255 Attribute set of default values for
256 modem config files {file}`etc/config.*`.
258 Think twice before changing
259 paths of fax-processing scripts.
264 type = attrsOf (submodule [ modemConfigOptions ]);
269 FAXNumber = "123456";
270 LocalIdentifier = "Smith";
274 Description of installed modems.
275 At least on modem must be defined
276 to enable the HylaFAX server.
280 spoolExtraInit = mkOption {
283 example = "chmod 0755 . # everyone may read my faxes";
285 Additional shell code that is executed within the
286 spooling area directory right after its setup.
290 faxcron.enable.spoolInit = mkEnableOption ''
291 purging old files from the spooling area with
293 each time the spooling area is initialized
295 faxcron.enable.frequency = mkOption {
296 type = nullOr nonEmptyStr;
300 purging old files from the spooling area with
301 {file}`faxcron` with the given frequency
302 (see systemd.time(7))
305 faxcron.infoDays = mkOption {
306 type = ints.positive;
309 Set the expiration time for data in the
310 remote machine information directory in days.
313 faxcron.logDays = mkOption {
314 type = ints.positive;
317 Set the expiration time for
318 session trace log files in days.
321 faxcron.rcvDays = mkOption {
322 type = ints.positive;
325 Set the expiration time for files in
326 the received facsimile queue in days.
330 faxqclean.enable.spoolInit = mkEnableOption ''
331 purging old files from the spooling area with
333 each time the spooling area is initialized
335 faxqclean.enable.frequency = mkOption {
336 type = nullOr nonEmptyStr;
340 Purge old files from the spooling area with
341 {file}`faxcron` with the given frequency
342 (see systemd.time(7)).
345 faxqclean.archiving = mkOption {
351 default = "as-flagged";
354 Enable or suppress job archiving:
355 `never` disables job archiving,
356 `as-flagged` archives jobs that
357 have been flagged for archiving by sendfax,
358 `always` forces archiving of all jobs.
359 See also sendfax(1) and faxqclean(8).
362 faxqclean.doneqMinutes = mkOption {
363 type = ints.positive;
365 example = literalExpression "24*60";
368 age threshold (in minutes) that controls how long
369 jobs may reside in the doneq directory.
372 faxqclean.docqMinutes = mkOption {
373 type = ints.positive;
375 example = literalExpression "24*60";
378 age threshold (in minutes) that controls how long
379 unreferenced files may reside in the docq directory.
385 config.services.hylafax = mkIf (config.services.hylafax.enable) (mkMerge [