# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem          1.0
PortGroup           github 1.0

set core_branch     2.3
set minor_version   21.1
set core_version    ${core_branch}.${minor_version}
github.setup        dovecot core ${core_version}
name                dovecot
revision            0
epoch               20060722

categories          mail
maintainers         {jberry @jdberry} openmaintainer
license             LGPL-2.1
homepage            https://www.dovecot.org

description         Secure, fast imap and pop3 server

long_description    Dovecot is an IMAP and POP3 server for \
                    Linux/UNIX-like systems, written with security \
                    primarily in mind. Although it is written in C, it \
                    uses several coding techniques to avoid most of \
                    the common pitfalls.

subport dovecot-sieve {
    github.setup    dovecot pigeonhole 0.5.${minor_version}
    revision        0

    description     Pigeonhole sieve and managesieve plugins for dovecot
    long_description \
                    Pigeonhole is the name of the project that adds \
                    support for the Sieve language (RFC 5228) and the \
                    ManageSieve protocol (RFC 5804) to the Dovecot \
                    Secure IMAP Server. The Sieve language is used to \
                    specify how e-mail needs to be processed. By \
                    writing Sieve scripts, users can customize how \
                    messages are delivered, e.g. whether they are \
                    forwarded or stored in special folders. Unwanted \
                    messages can be discarded or rejected, and, when \
                    the user is not available, the Sieve interpreter \
                    can send an automated reply. Above all, the Sieve \
                    language is meant to be simple, extensible and \
                    system independent. And, unlike most other mail \
                    filtering script languages, it does not allow \
                    users to execute arbitrary programs. This is \
                    particularly useful to prevent virtual users from \
                    having full access to the mail store. The \
                    intention of the language is to make it impossible \
                    for users to do anything more complex (and \
                    dangerous) than write simple mail filters.  Using \
                    the ManageSieve protocol, users can upload their \
                    Sieve scripts remotely, without needing direct \
                    filesystem access through FTP or \
                    SCP. Additionally, a ManageSieve server always \
                    makes sure that uploaded scripts are valid, \
                    preventing compile failures at mail delivery. The \
                    Pigeonhole project provides Sieve support as a \
                    plugin to Dovecot's Local Delivery Agent \
                    (LDA). The ManageSieve protocol is provided is an \
                    additional service, next to Dovecot's own POP3 and \
                    IMAP services.

    homepage        https://pigeonhole.dovecot.org/

    distname        dovecot-${core_branch}-pigeonhole-${version}
    master_sites    ${homepage}releases/${core_branch}/

    checksums       rmd160 4936e99b2e3ca573acc600b2b060a26b5ee67775 \
                    sha256 0377db284b620723de060431115fb2e7791e1df4321411af718201d6925c4692 \
                    size   1956404

    depends_lib-append \
                    port:dovecot

    patchfiles      dynamic_lookup-11-sieve.patch

    configure.ldflags-append \
                    -L${prefix}/lib/dovecot
    configure.args  --with-managesieve=yes \
                    --disable-dependency-tracking
}

set perl5.major     5.34

if {${name} eq ${subport}} {
    master_sites    https://dovecot.org/releases/${core_branch}/
    distname        ${name}-${version}
    checksums       rmd160 a1dc152dc823680fd5675f982347251a47b6c8d3 \
                    sha256 2d90a178c4297611088bf7daae5492a3bc3d5ab6328c3a032eb425d2c249097e \
                    size 7842044

    depends_build-append \
                    port:bison \
                    port:flex \
                    path:bin/pkg-config:pkgconfig

    depends_lib-append \
                    port:bzip2 \
                    path:lib/pkgconfig/icu-uc.pc:icu \
                    port:libiconv \
                    path:lib/libssl.dylib:openssl \
                    port:lz4 \
                    port:xz \
                    port:zlib

    set default_internal_user   _dovecot
    set default_login_user      _dovenull
    add_users ${default_internal_user} group=${default_internal_user} realname=Dovecot \
              ${default_login_user}    group=${default_login_user}    realname=Dovenull

    patch.pre_args-replace  -p0 -p1
    patchfiles      patch-doc-example-config-conf.d-10-master.conf.diff \
                    patch-src-master-master-settings.c.diff \
                    dynamic_lookup-11.patch \
                    dbox-storage.c.patch

    post-patch {
        reinplace "s|@@default_internal_user@@|${default_internal_user}|g" \
            ${worksrcpath}/doc/example-config/conf.d/10-master.conf
        reinplace "s|@@default_login_user@@|${default_login_user}|g" \
            ${worksrcpath}/doc/example-config/conf.d/10-master.conf
    }

    configure.args  --sysconfdir=${prefix}/etc \
                    --localstatedir=${prefix}/var \
                    --with-ssl=openssl \
                    --with-zlib \
                    --with-bzlib \
                    --with-ssldir=${prefix}/etc/openssl \
                    --with-shared-libs \
                    --with-pam \
                    --with-gssapi=yes

    configure.cppflags  -I${prefix}/include/openssl
    configure.env-append \
                    PANDOC=false

    # Remove next release
    # https://github.com/dovecot/core/commit/1ccd5b54a408d12fce0c94ab0bbaedbb5ef69830
    configure.env-append \
                    LIBICU_LIBS=-licui18n\ -licuuc

    # check if dovecot-sieve must be upgraded
    post-activate {
        if { ![catch {set result [registry_active dovecot-sieve]}]
             && [lrange [split [lindex [lindex ${result} 0] 1] .] 2 end] ne
                   [split ${minor_version} .] } {
            ui_msg "dovecot-sieve @[lindex [lindex ${result} 0] 1] and dovecot @${core_version} versions are incompatible. Please run:

\tsudo port upgrade dovecot-sieve
"
        }
    }

    variant ldap description {Enable LDAP support} {
        depends_lib-append          path:lib/libldap.dylib:openldap
        configure.args-append       --with-ldap=yes
    }

    variant solr requires lucene description {Enable apache-solr support} {
        depends_lib-append          port:curl port:expat
        depends_run-append          port:apache-solr8
        configure.args-append       --with-solr
    }

    variant lucene description {Enable lucene support} {
        depends_lib-append          port:clucene
        configure.args-append       --with-lucene
    }

    variant libstemmer description {Use libstemmer for full-text search} {
        depends_lib-append          port:libstemmer
        configure.args-append       --with-libstemmer
    }

    variant apns \
        description "Enable Apple Push Notification Service (APNS)" {
        # diff -Naur core-2.3.7.1 core-2.3.7.1-pushnotify | sed -E -e 's/core-([[:digit:]]+\.?)+(-pushnotify)?\//.\//g' > dovecot-core-pushnotify.patch
        patchfiles-append \
            dovecot-core-pushnotify.patch
        post-patch {
            reinplace "s|@PREFIX@|${prefix}|g" \
                ${worksrcpath}/src/imap/cmd-x-apple-push-service.c \
                ${worksrcpath}/src/plugins/push-notify/push-notify-plugin.c
        }
        depends_run-append \
                        port:perl${perl5.major} \
                        port:p${perl5.major}-json \
                        port:p${perl5.major}-moo \
                        port:p${perl5.major}-privileges-drop \
                        port:p${perl5.major}-protocol-http2

        # The patch modifies configure.ac and Makefile.am.
        use_autoreconf  yes
        autoreconf.args -fvi
        # error: possibly undefined macro: AM_ICONV
        depends_build-append \
                        port:gettext
        # https://trac.macports.org/wiki/WimplicitFunctionDeclaration#strchr
        configure.checks.implicit_function_declaration.whitelist-append strchr

        pre-destroot {
            xinstall -m 0750 -d \
                -o ${default_internal_user} -g ${default_login_user} \
                ${destroot}${prefix}/etc/${name}-apns \
                ${destroot}${prefix}/var/db/${name}-apns
            xinstall -m 0755 -d \
                ${destroot}${prefix}/lib/pushnotify/Net/APNS
            touch ${destroot}${prefix}/var/db/${name}-apns/devices
            file attributes \
                ${destroot}${prefix}/var/db/${name}-apns/devices \
                -permissions 0750 \
                -owner ${default_internal_user} -group ${default_login_user}
            destroot.keepdirs-append \
                ${destroot}${prefix}/etc/${name}-apns \
                ${destroot}${prefix}/var/db/${name}-apns
            xinstall -m 0755 ${filespath}/pushnotify.pl \
                ${destroot}${prefix}/sbin
            xinstall -m 0755 ${filespath}/Net/APNS/SimpleCert.pm \
                ${destroot}${prefix}/lib/pushnotify/Net/APNS
            foreach cmd [list \
                "s|@PREFIX@|${prefix}|g" \
                "s|@PERL5_MAJOR_VERSION@|${perl5.major}|g" \
                "s|@DEFAULT_INTERNAL_USER@|${default_internal_user}|g" \
                ] {
                reinplace ${cmd} \
                    ${destroot}${prefix}/sbin/pushnotify.pl
            }
        }

        # References:
        #   * https://github.com/matthewpowell/pushnotify
        #   * https://www.c0ffee.net/blog/dovecot-push-notifications/
        notes-append \
            "Dovecot is configured with the Apple Push Notification Service (APNS)\
            plugin. APNS use requires these steps:

         1. Acquire APNS Mail certificates from a (virtual) macOS\
            High Sierra 10.13 and Server.app version 5.6. Export\
            the APNS certificates and keys from the Keychain into the\
            files com.apple.servermgrd.apns.mail.cer and\
            com.apple.servermgrd.apns.mail.key.p12. APNS certificates appear\
            separately with names APSP:<UUID> that correspond to the\
            certificate's User ID field, com.apple.mail.XServer.<UUID>.\
            APNS keys are simply named com.apple.servermgrd.apns.mail.\
            *Note*: APNS Mail certificate creation is deprecated on\
            Server.app version 5.7+.

         2. Convert the APNS Mail certificates to PEM files:

                openssl x509 -inform der -in com.apple.servermgrd.apns.mail.cer  \\
                    | sed '/BEGIN CERTIFICATE/,\$!d'   \\
                > com.apple.mail.cert.pem
                openssl pkcs12 -in com.apple.servermgrd.apns.mail.key.p12  \\
                    -nodes -nocerts | sed '/BEGIN PRIVATE KEY/,\$!d'    \\
                > com.apple.mail.key.pem
                # verify that the certificate and key match:
                openssl x509 -noout -modulus -in com.apple.mail.cert.pem \\
                | openssl sha1
                openssl rsa -noout -modulus -in com.apple.mail.key.pem \\
                | openssl sha1
                sudo install -m 0640 -o ${default_internal_user} -g ${default_login_user} \\
                    com.apple.mail.cert.pem com.apple.mail.key.pem \\
                    ${prefix}/etc/dovecot-apns

         3. Configure dovecot for APNS:

            ${prefix}/etc/${name}/conf.d/15-lda.conf:
            protocol lda { mail_plugins = \$mail_plugins push_notify }

            ${prefix}/etc/${name}/conf.d/90-apns.conf:
            aps_topic = com.apple.mail.XServer.<UUID>

            where the certificate's UUID is obtained from the command:

                openssl x509 -text -noout                                   \\
                    -in ${prefix}/etc/dovecot-apns/com.apple.mail.cert.pem \\
                | grep -E -o 'com\.apple\.mail\.XServer\.\[0-9a-f-\]+'

         4. Launch the APNS daemon:

                sudo launchctl load -w \\
                    /Library/LaunchDaemons/org.macports.dovecot-apns.plist
    "
    }

    variant postgresql10 \
        conflicts postgresql11 postgresql12 postgresql13 postgresql14 postgresql15 \
        description "Enable PostgreSQL 10 support" {
        depends_lib-append          port:postgresql10
        configure.env-append        PG_CONFIG=${prefix}/lib/postgresql10/bin/pg_config
        configure.args-append       --with-pgsql
    }

    variant postgresql11 \
        conflicts postgresql10 postgresql12 postgresql13 postgresql14 postgresql15 \
        description "Enable PostgreSQL 11 support" {
        depends_lib-append          port:postgresql11
        configure.env-append        PG_CONFIG=${prefix}/lib/postgresql11/bin/pg_config
        configure.args-append       --with-pgsql
    }

    variant postgresql12 \
        conflicts postgresql10 postgresql11 postgresql13 postgresql14 postgresql15 \
        description "Enable PostgreSQL 12 support" {
        depends_lib-append          port:postgresql12
        configure.env-append        PG_CONFIG=${prefix}/lib/postgresql12/bin/pg_config
        configure.args-append       --with-pgsql
    }

    variant postgresql13 \
        conflicts postgresql10 postgresql11 postgresql12 postgresql14 postgresql15 \
        description "Enable PostgreSQL 13 support" {
        depends_lib-append          port:postgresql13
        configure.env-append        PG_CONFIG=${prefix}/lib/postgresql13/bin/pg_config
        configure.args-append       --with-pgsql
    }

    variant postgresql14 \
        conflicts postgresql10 postgresql11 postgresql12 postgresql13 postgresql15 \
        description "Enable PostgreSQL 14 support" {
        depends_lib-append          port:postgresql14
        configure.env-append        PG_CONFIG=${prefix}/lib/postgresql14/bin/pg_config
        configure.args-append       --with-pgsql
    }

    variant postgresql15 \
        conflicts postgresql10 postgresql11 postgresql12 postgresql13 postgresql14 \
        description "Enable PostgreSQL 15 support" {
        depends_lib-append          port:postgresql15
        configure.env-append        PG_CONFIG=${prefix}/lib/postgresql15/bin/pg_config
        configure.args-append       --with-pgsql
    }

    variant percona \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.7 mariadb10.8 mysql57 mysql8 \
        description "Enable Percona (MySQL) support" {
            depends_lib-append          port:percona
            configure.env-append        MYSQL_CONFIG=${prefix}/lib/percona/bin/mysql_config
            configure.args-append       --with-mysql
    }

    variant mariadb10.2 \
        conflicts mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.7 mariadb10.8 mysql57 mysql8 percona \
        description "Enable MariaDB 10.2 (MySQL) support" {
        depends_lib-append          port:mariadb-10.2
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.2/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mariadb10.3 \
        conflicts mariadb10.2 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.7 mariadb10.8 mysql57 mysql8 percona \
        description "Enable MariaDB 10.3 (MySQL) support" {
        depends_lib-append          port:mariadb-10.3
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.3/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mariadb10.4 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.5 mariadb10.6 mariadb10.7 mariadb10.8 mysql57 mysql8 percona \
        description "Enable MariaDB 10.4 (MySQL) support" {
        depends_lib-append          port:mariadb-10.4
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.4/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mariadb10.5 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.6 mariadb10.7 mariadb10.8 mysql57 mysql8 percona \
        description "Enable MariaDB 10.5 (MySQL) support" {
        depends_lib-append          port:mariadb-10.5
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.5/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mariadb10.6 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.7 mariadb10.8 mysql57 mysql8 percona \
        description "Enable MariaDB 10.6 (MySQL) support" {
        depends_lib-append          port:mariadb-10.6
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.6/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mariadb10.7 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.8 mysql57 mysql8 percona \
        description "Enable MariaDB 10.7 (MySQL) support" {
        depends_lib-append          port:mariadb-10.7
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.7/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mariadb10.8 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.7 mysql57 mysql8 percona \
        description "Enable MariaDB 10.8 (MySQL) support" {
        depends_lib-append          port:mariadb-10.8
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mariadb-10.8/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mysql57 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.7 mariadb10.8 mysql8 percona \
        description "Enable MySQL 5.7 support" {
        depends_lib-append          port:mysql57
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mysql57/bin/mysql_config
        configure.args-append       --with-mysql
    }

    variant mysql8 \
        conflicts mariadb10.2 mariadb10.3 mariadb10.4 mariadb10.5 mariadb10.6 mariadb10.7 mariadb10.8 mysql57 percona \
        description "Enable MySQL 8 support" {
        depends_lib-append          port:mysql8
        configure.env-append        MYSQL_CONFIG=${prefix}/lib/mysql8/bin/mysql_config
        configure.args-append       --with-mysql
    }

    # remove after 2023-08-20
    variant mariadb10.1 requires mariadb10.7 description "Legacy compatibility variant" {}
    variant mariadb requires mariadb10.7 description "Legacy compatibility variant" {}

    # remove after 2024-04-04
    variant postgresql96 requires postgresql14 description "Legacy compatibility variant" {}

    if {[variant_isset "apns"]} {
        set daemon_uniquename   \
                                org.macports.${name}
        set pushnotify_uniquename \
                                org.macports.${name}-apns
        startupitem.type        launchd
        startupitem.create      no
        # Inject our own launchd plists to include pushnotify.pl
        startupitems \
            name                ${name} \
            location            LaunchDaemons \
            uniquename          ${daemon_uniquename} \
            plist               ${daemon_uniquename}.plist \
            custom_file         ${workpath}/plists/${daemon_uniquename}.plist \
            name                ${name}-apns \
            location            LaunchDaemons \
            uniquename          ${pushnotify_uniquename} \
            plist               ${pushnotify_uniquename}.plist \
            custom_file         ${workpath}/plists/${pushnotify_uniquename}.plist

        post-extract {
            xinstall -d ${workpath}/plists
            foreach uniquename [list ${daemon_uniquename} ${pushnotify_uniquename}] {
                xinstall -m 644 -W ${filespath} ${uniquename}.plist \
                    ${workpath}/plists
                reinplace "s|@PREFIX@|${prefix}|g" \
                    ${workpath}/plists/${uniquename}.plist
            }
        }
    } else {
        startupitem.create      yes
        startupitem.executable  ${prefix}/sbin/${name}
        startupitem.pidfile     auto ${prefix}/var/run/${name}/master.pid
    }

    destroot.keepdirs \
        ${destroot}${prefix}/etc/${name}
}
