From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp11.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id MC+mCZ4PxWKw4AAAbAwnHQ (envelope-from ) for ; Wed, 06 Jul 2022 06:29:18 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp11.migadu.com with LMTPS id 6KaUCZ4PxWJCfAAA9RJhRA (envelope-from ) for ; Wed, 06 Jul 2022 06:29:18 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 8CD3CE201 for ; Wed, 6 Jul 2022 06:29:17 +0200 (CEST) Received: from localhost ([::1]:37996 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o8wf6-0001T7-8h for larch@yhetil.org; Wed, 06 Jul 2022 00:29:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54600) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o8wet-0001Sx-59 for guix-patches@gnu.org; Wed, 06 Jul 2022 00:29:06 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:58130) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o8wes-0005UG-P8 for guix-patches@gnu.org; Wed, 06 Jul 2022 00:29:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1o8wes-0005BM-Hv for guix-patches@gnu.org; Wed, 06 Jul 2022 00:29:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#56046] [PATCH] services: mail: add opensmtpd records to enhance opensmtpd-configuration. Version 2 Resent-From: Liliana Marie Prikler Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 06 Jul 2022 04:29:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 56046 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Joshua Branson , 56046@debbugs.gnu.org Received: via spool by 56046-submit@debbugs.gnu.org id=B56046.165708168619850 (code B ref 56046); Wed, 06 Jul 2022 04:29:02 +0000 Received: (at 56046) by debbugs.gnu.org; 6 Jul 2022 04:28:06 +0000 Received: from localhost ([127.0.0.1]:52027 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o8wdr-00059i-JP for submit@debbugs.gnu.org; Wed, 06 Jul 2022 00:28:05 -0400 Received: from mail-ej1-f67.google.com ([209.85.218.67]:45709) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o8wdk-00059N-9k for 56046@debbugs.gnu.org; Wed, 06 Jul 2022 00:27:57 -0400 Received: by mail-ej1-f67.google.com with SMTP id h23so24894321ejj.12 for <56046@debbugs.gnu.org>; Tue, 05 Jul 2022 21:27:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:subject:from:to:date:in-reply-to:references:user-agent :mime-version:content-transfer-encoding; bh=gduwxLChwEnV1zfeROMWD2TTCf0U4GW0foAab/DvmkU=; b=oxmmwhTY0a52Gu7tfJuEwO5mSJtnLJ4fipIuDcoOBfOCZ/n6WGuxeyvh9toEhlEWuc fB8FLK6MOZkNVz/tRWpaAJf3/Z6GVOuX3PXCTmGuxXMvFaZdXRRoyPILnYLjG3eY1zgr DtAnRLzVfKCl5JRNNPz5+C72Bkh0xPxsiad/2r4RMTehN7I8ndKdHLNgoFCCRsf6ZFYP c31GoqHB6AwFVc2EbYSiAG/eCdyxjmuOqLJixoReNQktwl1gGxqfPk9xlX+czEibkLP1 ivXgGloWWsphUecQE1f7zJfHzfXMfPot8KByDl0waalylog3UL7S3ohlBxHUMPCK5OQr eZug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:subject:from:to:date:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=gduwxLChwEnV1zfeROMWD2TTCf0U4GW0foAab/DvmkU=; b=sIIPPHdE/M+ksaUzSZ2tIFVu2bCGJHejBV/Z7omXpUqvmyIzRC7IZKeRqo6Kzl8KsT wqjchszdzRcfWpDpfEHc7muV4W4vH47MVGQFljhPJjfPUNZjzg6GrPbAAS65WqlMYxmk 1b+FjxUEAZxjRORBcIH/jEi3Q6SrMlp7BZyWaQSqFcn9ofyjndo89Dsz0WIkCFaIpTVo kRv85l8krtCBxI3OQgF+KrttCvdqxNUREDSmIPhdrNSPTnppQ+SmMC7OQ9/nQ3eU4KTw 8RwZaIrkolk4CeU1tgDjR8Mb0aroFLB7qZG5ohImwP6pksZKZ+gVIe9jtvm78D7LG5UD PPBw== X-Gm-Message-State: AJIora/kzBdTYFvEMNw7SSbV5H3akwnHOFAUZYYwJdNS2v0wQZ7YK5r6 H69eckl1egv4hJBUJ0nOjeE= X-Google-Smtp-Source: AGRyM1vL3MyLJNnnhI1sURiM+IfbomW3JmT0piu+RCjNOwtDjLGAw7xqvoiimcCn4wHvNiXDfnMGCg== X-Received: by 2002:a17:906:2da:b0:712:14b:62da with SMTP id 26-20020a17090602da00b00712014b62damr36743944ejk.351.1657081665857; Tue, 05 Jul 2022 21:27:45 -0700 (PDT) Received: from nijino.fritz.box (85-127-52-93.dsl.dynamic.surfer.at. [85.127.52.93]) by smtp.gmail.com with ESMTPSA id la21-20020a170907781500b0072aeda86ac3sm1358592ejc.149.2022.07.05.21.27.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Jul 2022 21:27:45 -0700 (PDT) Message-ID: <756a905107d7783bab238091d668fddbc1e712ab.camel@gmail.com> From: Liliana Marie Prikler Date: Wed, 06 Jul 2022 06:27:44 +0200 In-Reply-To: <20220704211759.8314-1-jbranso@dismail.de> References: <20220704211759.8314-1-jbranso@dismail.de> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.42.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1657081757; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:resent-cc: resent-from:resent-sender:resent-message-id:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=gduwxLChwEnV1zfeROMWD2TTCf0U4GW0foAab/DvmkU=; b=d9WVvQi6ldPZIQfgxBCKm6RjWv+sZRbX+pJcdFH4aBTuoaXvv8gaCtyd7tpLEBrtH/Fd3h 2izo2VP4mwPvavkXQPPXLNOG25nfJiuXu+JMkmVjxUlw0bdsc+pjGt6inqYscQLIj/PtWd 5Mn+kyD9KTBSwtOEzdt9kfQB5ZxWDbWErNWaMHd9GdJGISEOQl6tp+Nc/IF5XUKShGAtlW SrU868/2juj9R9++KGKK9fd0fHrfEcsUzHmGfCuCohtICJc/Fim9xvuINu0kslSjBqBVQ9 v1jvtDKrX+zx8s68zZA3TJiyOjUw1AlOxuxj5RXmPly54zb4Xtbomkghab4sDQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1657081757; a=rsa-sha256; cv=none; b=u3ebpBSG71eJlWy/nGKr/vcLRH83rKg+AnLwQipPkLaOPJErhYLQtL9lO2rPzB3oqXpAoR 0haqgOBpe9dL88Q8gV6GHJrUcxdSHqAlvYXAwfp8c5TfUgb4q3IB38h8k41NPsRRUYmu6H Mr7AV1liSs1YCXqL3kwzviLM90g2XAx6OnBOqEzqZELj0XJJLur4Ac+WMrqboWiatjbCyf IcBJmOrL9OfwV25zAK3q2V3vBMI/FBc2VNKuzytmRMa7XkZkJXL4e49f0E7bTBs7HTKyBK tk+MQJtiP4yjrDOWQa2ki6+vnNrkcqeso6YsJNMwjkKRHsqYPkMsX8q4M1KLkA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gmail.com header.s=20210112 header.b=oxmmwhTY; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: 6.05 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gmail.com header.s=20210112 header.b=oxmmwhTY; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 8CD3CE201 X-Spam-Score: 6.05 X-Migadu-Scanner: scn1.migadu.com X-TUID: FgD1YyDOEAjT Am Montag, dem 04.07.2022 um 17:17 -0400 schrieb Joshua Branson: > Openmstpd-configuration may only be configured by a config-file.  > This > patch, enables one to configure opensmtpd by using some guile record > types (defined via define-record-type*). > > * gnu/services/mail.scm:  New records (opensmtpd-table- > configuration), > (opensmtpd-ca-configuration), > (opensmtpd-pki-configuration), > (opensmtpd-action-local-delivery-configuration), > (opensmtpd-maildir-configuration), > (opensmtpd-mda-configuration), > (opensmtpd-action-relay-configuration), > (opensmtpd-option-configuration), > (opensmtpd-filter-phase-configuration), > (opensmtpd-filter-configuration), > (opensmtpd-listen-on-configuration), > (opensmtpd-listen-on-socket-configuration), > (opensmtpd-match-configuration), > (opensmtpd-smtp-configuration), > (opensmtpd-srs-configuration), > (opensmtpd-queue-configuration), and > (opensmtpd-configuration). Not a ChangeLog. > New procedures: false?, is-value-right-type, add-comma-or-string, > file-exists?, list-of-procedures->string, string-in-list?, my- > sanitize, > opensmtpd-filter-chain?, throw-error-duplicate-option, > sanitize-list-of-options-for-match-configuration, sanitize-filters, > list-has-duplicates-or-non-filters?, > filter-phase-has-message-and-value?, > filter-phase-decision-lacks-proper-message?, > filter-phase-lacks-proper-value?, > filter-phase-has-incorrect-junk-or-bypass?, > filter-phase-junks-after-commit?, > list-of-unique-filter-or-filter-phase?, throw-error, > contains-duplicate?, list-of-type?, list-of-strings?, > list-of-unique-opensmtpd-option-configuration?, > list-of-opensmtpd-ca-configuration?, > list-of-opensmtpd-pki-configuration?, > list-of-opensmtpd-listen-on-configuration?, > list-of-unique-opensmtpd-match-configuration?, list-of-strings- > >string, > assoc-list? assoc-list, variable->string, > table-whose-data-are-assoc-list?, > table-whose-data-are-a-list-of-strings?, assoc-list->string, > opensmtpd-table-configuration->string, > opensmtpd-listen-on-configuration->string, > opensmtpd-listen-on-socket-configuration->string, > opensmtpd-action-relay-configuration->string, > opensmtpd-lmtp-configuration->string, > opensmtpd-mda-configuration->string, > opensmtpd-maildir-configuration->string, > opensmtpd-action-local-delivery-configuration->string, > opensmtpd-action->string, opensmtpd-option-configuration->string, > opensmtpd-match-configuration->string, > opensmtpd-ca-configuration->string, opensmtpd-pki-configuration- > >string, > generate-filter-chain-name, opensmtpd-filter-chain->string, > opensmtpd-filter-phase-configuration->string, opensmtpd-filters- > >string, > opensmtpd-configuration-listen->string, > opensmtpd-configuration-srs->string, > opensmtpd-smtp-configuration->string, > opensmtpd-configuration-queue->string, get-opensmtpd-actions, > get-opensmtpd-pki-configurations, get-opensmtpd-filters, flatten, > get-opensmtpd-tables, opensmtpd-configuration-fieldname->string, > list-of-records->string, opensmtpd-configuration->mixed-text-file. Neither is this. > * doc/guix.texi added documentation for the new records for > opensmtpd. Or this. > --- >  doc/guix.texi         | 1051 ++++++++++++++++++++- >  gnu/services/mail.scm | 2016 > ++++++++++++++++++++++++++++++++++++++++- >  2 files changed, 3056 insertions(+), 11 deletions(-) > > diff --git a/doc/guix.texi b/doc/guix.texi > index eda0956260..e8564240d1 100644 > --- a/doc/guix.texi > +++ b/doc/guix.texi > @@ -24849,14 +24849,59 @@ could instantiate a dovecot service like > this: >  @subsubheading OpenSMTPD Service >   >  @deffn {Scheme Variable} opensmtpd-service-type > -This is the type of the @uref{https://www.opensmtpd.org, OpenSMTPD} > -service, whose value should be an @code{opensmtpd-configuration} > object > -as in this example: > - > -@lisp > -(service opensmtpd-service-type > -         (opensmtpd-configuration > -           (config-file (local-file "./my-smtpd.conf")))) > +OpenSMTPD is an easy-to-use mail transfer agent (MTA). Its > configuration file is > +throughly documented in @code{man 5 smtpd.conf}. OpenSMTPD > @strong{listens} for incoming > +mail and @strong{matches} the mail to @strong{actions}. The > following records represent those > +stages: > + > +@multitable {aaaaaaaaa} > {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} I suggest using fractions here. > [...] > +This is a string of one of these options: > + > +@multitable {aaaaaaaaaaaaaaaaaaaa} > {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} Same here. Btw. I did not actually check all the doc in between, so I might be missing something. > +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaa} > {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} Likewise. > +@multitable {aaaaaaaaaa} > {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} You get the drill. > [more doc with strange multitables] > diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm > index d99743ac31..2a344e303e 100644 > --- a/gnu/services/mail.scm > +++ b/gnu/services/mail.scm > @@ -57,8 +57,143 @@ (define-module (gnu services mail) >              mailbox-configuration >              namespace-configuration >   > +            opensmtpd-table-configuration > +            opensmtpd-table-configuration? > +            opensmtpd-table-configuration-name > +            opensmtpd-table-configuration-file-db > +            opensmtpd-table-configuration-data > + > +            opensmtpd-ca-configuration > +            opensmtpd-ca-configuration? > +            opensmtpd-ca-configuration-name > +            opensmtpd-ca-configuration-file > + > +            opensmtpd-pki-configuration > +            opensmtpd-pki-configuration? > +            opensmtpd-pki-configuration-domain > +            opensmtpd-pki-configuration-cert > +            opensmtpd-pki-configuration-key > +            opensmtpd-pki-configuration-dhe > + > +            opensmtpd-action-local-delivery-configuration > +            opensmtpd-action-local-delivery-configuration? > +            opensmtpd-action-local-delivery-configuration-method > +            opensmtpd-action-local-delivery-configuration-alias > +            opensmtpd-action-local-delivery-configuration-ttl > +            opensmtpd-action-local-delivery-configuration-user > +            opensmtpd-action-local-delivery-configuration-userbase > +            opensmtpd-action-local-delivery-configuration-virtual > +            opensmtpd-action-local-delivery-configuration-wrapper > + > +            opensmtpd-maildir-configuration > +            opensmtpd-maildir-configuration? > +            opensmtpd-maildir-configuration-pathname > +            opensmtpd-maildir-configuration-junk > + > +            opensmtpd-mda-configuration > +            opensmtpd-mda-configuration-name > +            opensmtpd-mda-configuration-command > + > +            opensmtpd-action-relay-configuration > +            opensmtpd-action-relay-configuration? > +            opensmtpd-action-relay-configuration-backup > +            opensmtpd-action-relay-configuration-backup-mx > +            opensmtpd-action-relay-configuration-helo > +            opensmtpd-action-relay-configuration-domain > +            opensmtpd-action-relay-configuration-host > +            opensmtpd-action-relay-configuration-pki > +            opensmtpd-action-relay-configuration-srs > +            opensmtpd-action-relay-configuration-tls > +            opensmtpd-action-relay-configuration-auth > +            opensmtpd-action-relay-configuration-mail-from > +            opensmtpd-action-relay-configuration-src > + > +            opensmtpd-option-configuration > +            opensmtpd-option-configuration? > +            opensmtpd-option-configuration-option > +            opensmtpd-option-configuration-not > +            opensmtpd-option-configuration-regex > +            opensmtpd-option-configuration-data > + > +            opensmtpd-filter-phase-configuration > +            opensmtpd-filter-phase-configuration? > +            opensmtpd-filter-phase-configuration-name > +            opensmtpd-filter-phase-configuration-phase-name > +            opensmtpd-filter-phase-configuration-options > +            opensmtpd-filter-phase-configuration-decision > +            opensmtpd-filter-phase-configuration-message > +            opensmtpd-filter-phase-configuration-value > + > +            opensmtpd-filter-configuration > +            opensmtpd-filter-configuration? > +            opensmtpd-filter-configuration-name > +            opensmtpd-filter-configuration-proc > + > +            opensmtpd-listen-on-configuration > +            opensmtpd-listen-on-configuration? > +            opensmtpd-listen-on-configuration-interface > +            opensmtpd-listen-on-configuration-family > +            opensmtpd-listen-on-configuration-auth > +            opensmtpd-listen-on-configuration-auth-optional > +            opensmtpd-listen-on-configuration-filters > +            opensmtpd-listen-on-configuration-hostname > +            opensmtpd-listen-on-configuration-hostnames > +            opensmtpd-listen-on-configuration-mask-src > +            opensmtpd-listen-on-configuration-disable-dsn > +            opensmtpd-listen-on-configuration-pki > +            opensmtpd-listen-on-configuration-port > +            opensmtpd-listen-on-configuration-proxy-v2 > +            opensmtpd-listen-on-configuration-received-auth > +            opensmtpd-listen-on-configuration-senders > +            opensmtpd-listen-on-configuration-secure-connection > +            opensmtpd-listen-on-configuration-tag > + > +            opensmtpd-listen-on-socket-configuration > +            opensmtpd-listen-on-socket-configuration? > +            opensmtpd-listen-on-socket-configuration-filters > +            opensmtpd-listen-on-socket-configuration-mask-src > +            opensmtpd-listen-on-socket-configuration-tag > + > +            opensmtpd-match-configuration > +            opensmtpd-match-configuration? > +            opensmtpd-match-configuration-action > +            opensmtpd-match-configuration-options > + > +            opensmtpd-smtp-configuration > +            opensmtpd-smtp-configuration? > +            opensmtpd-smtp-configuration-ciphers > +            opensmtpd-smtp-configuration-limit-max-mails > +            opensmtpd-smtp-configuration-limit-max-rcpt > +            opensmtpd-smtp-configuration-max-message-size > +            opensmtpd-smtp-configuration-sub-addr-delim character > + > +            opensmtpd-srs-configuration > +            opensmtpd-srs-configuration? > +            opensmtpd-srs-configuration-key > +            opensmtpd-srs-configuration-backup-key > +            opensmtpd-srs-configuration-ttl-delay > + > +            opensmtpd-queue-configuration > +            opensmtpd-queue-configuration? > +            opensmtpd-queue-configuration-compression > +            opensmtpd-queue-configuration-encryption > +            opensmtpd-queue-configuration-ttl-delay > + >              opensmtpd-configuration >              opensmtpd-configuration? > +            opensmtpd-package > +            opensmtpd-config-file > +            opensmtpd-configuration-bounce > +            opensmtpd-configuration-listen-ons > +            opensmtpd-configuration-listen-on-socket > +            opensmtpd-configuration-includes > +            opensmtpd-configuration-matches > +            opensmtpd-configuration-mda-wrappers > +            opensmtpd-configuration-mta-max-deferred > +            opensmtpd-configuration-srs > +            opensmtpd-configuration-smtp > +            opensmtpd-configuration-queue > + >              opensmtpd-service-type >              %default-opensmtpd-config-file >   > @@ -1651,13 +1786,1888 @@ (define (generate-dovecot-documentation) >  ;;; OpenSMTPD. >  ;;; >   > +;; some fieldnames have a default value of #f, which is ok.  They > cannot have a value of #t. > +;; for example opensmtpd-table-configuration-data can be #f, BUT NOT > true. > +;; my/sanitize procedure tests values to see if they are of the > right kind. > +;; procedure false? is needed to allow fields like 'values' to be > blank, (empty), or #f BUT also > +;; have a value like a list of strings. > +(define (false? var) > +  (eq? #f var)) I'm pretty sure it'd be fine to use not in lieu of false?, even at the risk of matching nil. > +;; this procedure takes in a var and a list of procedures.  It loops > through list of procedures passing in var to each. > +;; if one procedure returns #t, the function returns true.  > Otherwise #f. > +;; TODO for fun rewrite this using map > +;; If I rewrote it in map, then it may help with sanitizing. > +;; eg: I could then potentially easily sanitize vars with lambda > procedures. > +(define (is-value-right-type? var list-of-procedures record > fieldname) > +  (if (null? list-of-procedures) > +        #f > +        (cond [(procedure? (car list-of-procedures)) > +               (if ((car list-of-procedures) var) > +                   #t > +                   (is-value-right-type? var (cdr list-of- > procedures) record fieldname))] > +              [(and (sanitize-configuration? (car list-of- > procedures)) > +                    (sanitize-configuration-error-if-proc-fails (car > list-of-procedures)) > +                    (if ((sanitize-configuration-proc (car list-of- > procedures)) var) > +                        #t > +                        (begin > +                          (apply string-append > +                                 (sanitize-configuration-error- > message (car list-of-procedures))) > +                          (throw 'bad! var))))] > +              [else (if ((sanitize-configuration-proc (car list-of- > procedures)) var) > +                        #t > +                        (is-value-right-type? var (cdr list-of- > procedures) record fieldname))]))) Don't we have field sanitizers already that make this obsolete? > +;; converts strings like this: > +;; "apple, ham, cherry" -> "apple, ham, or cherry" > +;; "pineapple" -> "pinneapple". > +;; "cheese, grapefruit, or jam" -> "cheese, grapefruit, or jam" > +(define (add-comma-or string) > +  (define last-comma-location (string-rindex string #\,)) > +  (if last-comma-location > +      (if (string-contains string ", or" last-comma-location) > +          string > +          (string-replace string ", or" last-comma-location > +                          (+ 1 last-comma-location))) > +      string)) > + > +;; I could test for read-ability of a file, but then I would have to > +;; test the program as root everytime instead of as a normal user... > +(define (file-exists? file) > +(if (string? file) > +    (access? file F_OK) > +    #f)) Is this not part of the Guile standard library? > +(define (list-of-procedures->string procedures) > +  (define string > +    (let loop ([procedures procedures]) > +      (if (null? procedures) > +          "" > +          (begin > +            (string-append > +             (cond [(eq? false? (car procedures)) > +                    "#f , "] > +                   [(eq? boolean? (car procedures)) > +                    "boolean, "] > +                   [(eq? string? (car procedures)) > +                    "string, "] > +                   [(eq? integer? (car procedures)) > +                    "integer, "] > +                   [(eq? list-of-strings? (car procedures)) > +                    "list of strings, "] > +                   [(eq? assoc-list? (car procedures)) > +                    "an association list, "] > +                   [(eq? opensmtpd-pki-configuration? (car > procedures)) > +                    "an record, "] > +                   [(eq? opensmtpd-table-configuration? (car > procedures)) > +                    "an record, "] > +                   [(eq? list-of-unique-opensmtpd-match- > configuration? (car procedures)) > +                    "a list of unique configuration> records, "] > +                   [(eq? table-whose-data-are-assoc-list? (car > procedures)) > +                    (string-append > +                    "an record whose > fieldname 'values' are an assoc-list \n" > +                    "(eg: (opensmtpd-table-configuration (name > \"table\") (data '(\"joshua\" . \"$encrypted$password\")))), ")] > +                   [(eq? file-exists? (car procedures)) > +                    "file, "] > +                   [else "has an incorrect value, "]) > +             (loop (cdr procedures))))))) > +  (add-comma-or (string-append (string-drop-right string 2) ".\n"))) Using a table, map and string-join might be wiser. If this is the only place add-comma-or is used, you can replace it by  (string-append (string-join (butlast strings) ",") ", or " (last strings)) where you only need to define butlast. > +;; TODO can I M-x raise-sexp (string=? string var) in this > procedure? and get rid of checking > +;; if the var is a string?  The previous string-in-list? had that > check. > +;; (string-in-list? '("hello" 5 "cat")) currently works.  If I M-x > raise-sexp (string=? string var) > +;; then it will no longer work. > +(define (string-in-list? string list) > +  (primitive-eval (cons 'or (map (lambda (var) (and (string? var) > (string=? string var))) list)))) Ever heard of member? > +(define (my/sanitize var record fieldname list-of-procedures) > +  (if (is-value-right-type? var list-of-procedures record fieldname) > +      var > +      (begin > +        (display (string-append "<" record "> fieldname: '" > fieldname "' is of type " > +                                (list-of-procedures->string list-of- > procedures) "\n")) > +        (throw 'bad! var)))) > + > +;; Some example opensmtpd-table-configurations: > +;; > +;;  (opensmtpd-table-configuration (name "root accounts") (data > '(("joshua" . "root@dismail.de") ("joshua" . > "postmaster@dismail.de")))) > +;;  (opensmtpd-table-configuration (name "root accounts") (data > (list "mysite.me" "your-site.com"))) > +;;  TODO should support have a > fieldname 'file'? > +;;  Or should I change name to name-or-file ? > +(define-record-type* > +  opensmtpd-table-configuration make-opensmtpd-table-configuration > +  opensmtpd-table-configuration? > +  this-record > +  (name opensmtpd-table-configuration-name ;; string > +        (default #f) > +        (sanitize (lambda (var) > +                    (my/sanitize var "opensmtpd-table-configuration" > "name" (list string?))))) > +  (file-db opensmtpd-table-configuration-file-db > +           (default #f) > +           (sanitize (lambda (var) > +                       (my/sanitize var "opensmtpd-table- > configuration" "file-db" > +                                    (list boolean?))))) > +  ;; FIXME support an aliasing table as described here: > +  ;; https://man.openbsd.org/table.5 > +  ;; One may have to use the record file for this.  I don't think > tables support a table like this: > +  ;; table "name" { joshua = > joshua@gnucode.me,joshua@gnu-hurd.com,joshua@propernaming.org, root = > root@gnucode.me } > +  ;; If values is an absolute filename, then it will use said > filename to house the table info. > +  ;; filename must be an absolute filename. > +  (data opensmtpd-table-configuration-data > +          (default #f) > +          (sanitize (lambda (var) > +                      (my/sanitize var "opensmtpd-table- > configuration" "values" > +                                   (list file-exists? list-of- > strings? assoc-list?))))) > +  ;; is a list of values or key values > +  ;; eg: (list "mysite.me" "your-site.com") > +  ;; eg: (list ("joshua" . "joshua@gnu.org") ("james" . > "james@gnu.org")) > +  ;; I am currently making these values be as assocation list of > strings only. > +  ;; FIXME should I allow a var like this? > +  ;; (list (cons "gnucode.me" 234.949.392.23)) > +  ;; can be of type: (quote list-of-strings) or (quote assoc-list) > +  ;; (opensmtpd-table-configuration-type record) returns the values' > type.  The user SHOULD NEVER set the type. > +  ;; TODO jpoiret: on irc reccomends that I just use an outside > function to determine fieldname 'values', type. > +  ;; it would be "simpler" and possibly easier for the next person > working on this code to understand what is happening. > +  (type opensmtpd-table-configuration-type > +        (default #f) > +        (thunked) > +        (sanitize (lambda (var) > +                    (cond [(opensmtpd-table-configuration-data this- > record) > +                           (if (list-of-strings? (opensmtpd-table- > configuration-data this-record)) > +                               (quote list-of-strings) > +                               (quote assoc-list))] Just a quick side note, we don't usually intermix [ and (. It's all (. > [skipping a bit of stuff, may check later...] > +(define-record-type* > +  opensmtpd-option-configuration make-opensmtpd-option-configuration > +  opensmtpd-option-configuration? > +  (option opensmtpd-option-configuration-option > +          (default #f) > +          (sanitize (lambda (var) > +                      (if (and (string? var) > +                               (or (string-in-list? var (list > "fcrdns" "rdns" > +                                                          "src" > "helo" > +                                                          "auth" > "mail-from" > +                                                          "rcpt-to" > +                                                          "for" > +                                                          "for any" > "for local" > +                                                          "for > domain" "for rcpt-to" > +                                                          "from any" > "from auth" > +                                                          "from > local" "from mail-from" > +                                                          "from > rdns" "from socket" > +                                                          "from src" > "auth" > +                                                          "helo" > "mail-from" > +                                                          "rcpt-to" > "tag" "tls" > +                                                          )))) > +                          var > +                          (begin > +                            (display (string-append " option-configuration> fieldname: 'option' is of type \n" > +                                                    "string.  The > string can be either 'fcrdns', \n" > +                                                    " 'rdns', 'src', > 'helo', 'auth', 'mail-from', or 'rcpt-to', \n" > +                                                    "'for', 'for > any', 'for local', 'for domain', 'for rcpt-to', \n" > +                                                    "'from any', > 'from auth', 'from local', 'from mail-from', 'from rdns', 'from > socket', \n" > +                                                    "'from src', > 'auth helo', 'mail-from', 'rcpt-to', 'tag', or 'tls' \n" > +                                                    )) > +                            (throw 'bad! var)))))) This is a little verbose for what it does. > +(define-record-type* What is a "listen-on"? > +(define-record-type* configuration> Again, could this just be ? >  (define-record-type* >    opensmtpd-configuration make-opensmtpd-configuration >    opensmtpd-configuration? > -  (package     opensmtpd-configuration-package > -               (default opensmtpd)) > +  (package opensmtpd-configuration-package > +           (default opensmtpd)) >    (config-file opensmtpd-configuration-config-file > -               (default %default-opensmtpd-config-file))) > +               (default #f)) > +  ;; FIXME/TODO should I include a admd authservid entry? > + > +  ;; TODO sanitize this properly with perhaps a configuration>. > +  (bounce opensmtpd-configuration-bounce > +          (default #f) > +          (sanitize (lambda (var) > +                      (my/sanitize var "opensmtpd-configuration" > "bounce" > +                                   (list false? list?))))) > +  (cas opensmtpd-configuration-cas > +       (default #f) > +       (sanitize (lambda (var) > +                   (my/sanitize var "opensmtpd-configuration" "cas" > +                                (list false? list-of-opensmtpd-ca- > configuration?))))) > +  ;; list of many records of type opensmtpd-listen-on-configuration > +  (listen-ons opensmtpd-configuration-listen-ons What does opensmtpd acutally listen on? > [...] Too much to check, too little time. Maybe return later.