<pre style='margin:0'>
Renee Otten (reneeotten) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/26262610dcc8f35b4b17d80471157574eee3ed77">https://github.com/macports/macports-ports/commit/26262610dcc8f35b4b17d80471157574eee3ed77</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new 26262610dcc dovecot: Deprecate apns variant because Apple no longer supports APNS certificates for Mail
</span>26262610dcc is described below
<span style='display:block; white-space:pre;color:#808000;'>commit 26262610dcc8f35b4b17d80471157574eee3ed77
</span>Author: Steven Thomas Smith <s.t.smith@ieee.org>
AuthorDate: Mon Mar 24 21:00:41 2025 -0400
<span style='display:block; white-space:pre;color:#404040;'> dovecot: Deprecate apns variant because Apple no longer supports APNS certificates for Mail
</span>---
mail/dovecot/Portfile | 151 +-----
mail/dovecot/files/dovecot-core-pushnotify.patch | 585 ---------------------
mail/dovecot/files/org.macports.dovecot-apns.plist | 21 -
mail/dovecot/files/pushnotify.pl | 130 -----
4 files changed, 9 insertions(+), 878 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/mail/dovecot/Portfile b/mail/dovecot/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index e8d4d40dbfa..fcc7b4acfa4 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/mail/dovecot/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/mail/dovecot/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -9,7 +9,7 @@ set core_version ${core_branch}.${minor_version}
</span> github.setup dovecot core ${core_version}
github.tarball_from releases
name dovecot
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision 1
</span> epoch 20060722
categories mail
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -176,115 +176,13 @@ if {${name} eq ${subport}} {
</span> configure.args-append --with-libstemmer
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ # remove after 2026-01-01
</span> variant apns \
<span style='display:block; white-space:pre;background:#ffe0e0;'>- description "Enable Apple Push Notification Service (APNS)" {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # 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
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- patchfiles-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- dovecot-core-pushnotify.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- post-patch {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- reinplace "s|@PREFIX@|${prefix}|g" \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${worksrcpath}/src/imap/cmd-x-apple-push-service.c \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${worksrcpath}/src/plugins/push-notify/push-notify-plugin.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- depends_run-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- port:perl${perl5.major} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- port:p${perl5.major}-json \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- port:p${perl5.major}-moo \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- port:p${perl5.major}-privileges-drop \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- port:p${perl5.major}-protocol-http2
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # The patch modifies configure.ac and Makefile.am.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- use_autoreconf yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- autoreconf.args -fvi
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # error: possibly undefined macro: AM_ICONV
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- depends_build-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- port:gettext
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # https://trac.macports.org/wiki/WimplicitFunctionDeclaration#strchr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- configure.checks.implicit_function_declaration.whitelist-append strchr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pre-destroot {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- xinstall -m 0750 -d \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- -o ${default_internal_user} -g ${default_login_user} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/etc/${name}-apns \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/var/db/${name}-apns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- xinstall -m 0755 -d \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/lib/pushnotify/Net/APNS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- touch ${destroot}${prefix}/var/db/${name}-apns/devices
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- file attributes \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/var/db/${name}-apns/devices \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- -permissions 0750 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- -owner ${default_internal_user} -group ${default_login_user}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- destroot.keepdirs-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/etc/${name}-apns \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/var/db/${name}-apns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- xinstall -m 0755 ${filespath}/pushnotify.pl \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/sbin
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- xinstall -m 0755 ${filespath}/Net/APNS/SimpleCert.pm \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/lib/pushnotify/Net/APNS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- foreach cmd [list \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- "s|@PREFIX@|${prefix}|g" \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- "s|@PERL5_MAJOR_VERSION@|${perl5.major}|g" \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- "s|@DEFAULT_INTERNAL_USER@|${default_internal_user}|g" \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ] {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- reinplace ${cmd} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${destroot}${prefix}/sbin/pushnotify.pl
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # References:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # * https://github.com/matthewpowell/pushnotify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # * https://www.c0ffee.net/blog/dovecot-push-notifications/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ description "Enable Apple Push Notification Service (APNS) \[deprecated]" {
</span> notes-append \
<span style='display:block; white-space:pre;background:#ffe0e0;'>- "Dovecot is configured with the Apple Push Notification Service (APNS)\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- plugin. APNS use requires these steps:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 1. Acquire APNS Mail certificates from a (virtual) macOS\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- High Sierra 10.13 and Server.app version 5.6. Export\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- the APNS certificates and keys from the Keychain into the\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- files com.apple.servermgrd.apns.mail.cer and\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- com.apple.servermgrd.apns.mail.key.p12. APNS certificates appear\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- separately with names APSP:<UUID> that correspond to the\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- certificate's User ID field, com.apple.mail.XServer.<UUID>.\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- APNS keys are simply named com.apple.servermgrd.apns.mail.\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- *Note*: APNS Mail certificate creation is deprecated on\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Server.app version 5.7+.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 2. Convert the APNS Mail certificates to PEM files:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- openssl x509 -inform der -in com.apple.servermgrd.apns.mail.cer \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- | sed '/BEGIN CERTIFICATE/,\$!d' \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- > com.apple.mail.cert.pem
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- openssl pkcs12 -in com.apple.servermgrd.apns.mail.key.p12 \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- -nodes -nocerts | sed '/BEGIN PRIVATE KEY/,\$!d' \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- > com.apple.mail.key.pem
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # verify that the certificate and key match:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- openssl x509 -noout -modulus -in com.apple.mail.cert.pem \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- | openssl sha1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- openssl rsa -noout -modulus -in com.apple.mail.key.pem \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- | openssl sha1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- sudo install -m 0640 -o ${default_internal_user} -g ${default_login_user} \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- com.apple.mail.cert.pem com.apple.mail.key.pem \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${prefix}/etc/dovecot-apns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 3. Configure dovecot for APNS:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${prefix}/etc/${name}/conf.d/15-lda.conf:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- protocol lda { mail_plugins = \$mail_plugins push_notify }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${prefix}/etc/${name}/conf.d/90-apns.conf:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- aps_topic = com.apple.mail.XServer.<UUID>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- where the certificate's UUID is obtained from the command:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- openssl x509 -text -noout \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- -in ${prefix}/etc/dovecot-apns/com.apple.mail.cert.pem \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- | grep -E -o 'com\.apple\.mail\.XServer\.\[0-9a-f-\]+'
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 4. Launch the APNS daemon:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- sudo launchctl load -w \\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /Library/LaunchDaemons/org.macports.dovecot-apns.plist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "Apple no longer supports APNS certificates for Mail.\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ This variant will be removed in a future update. See:\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ https://discussions.apple.com/thread/255898876"
</span> }
variant postgresql11 \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -427,40 +325,9 @@ if {${name} eq ${subport}} {
</span> variant mariadb10.2 requires mariadb10.5 description "Legacy compatibility variant" {}
variant postgresql10 requires postgresql13 description "Legacy compatibility variant" {}
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if {[variant_isset "apns"]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- set daemon_uniquename \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- org.macports.${name}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- set pushnotify_uniquename \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- org.macports.${name}-apns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- startupitem.type launchd
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- startupitem.create no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Inject our own launchd plists to include pushnotify.pl
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- startupitems \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- name ${name} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- location LaunchDaemons \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- uniquename ${daemon_uniquename} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- plist ${daemon_uniquename}.plist \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- custom_file ${workpath}/plists/${daemon_uniquename}.plist \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- name ${name}-apns \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- location LaunchDaemons \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- uniquename ${pushnotify_uniquename} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- plist ${pushnotify_uniquename}.plist \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- custom_file ${workpath}/plists/${pushnotify_uniquename}.plist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- post-extract {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- xinstall -d ${workpath}/plists
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- foreach uniquename [list ${daemon_uniquename} ${pushnotify_uniquename}] {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- xinstall -m 644 -W ${filespath} ${uniquename}.plist \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${workpath}/plists
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- reinplace "s|@PREFIX@|${prefix}|g" \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ${workpath}/plists/${uniquename}.plist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- startupitem.create yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- startupitem.executable ${prefix}/sbin/${name}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- startupitem.pidfile auto ${prefix}/var/run/${name}/master.pid
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ startupitem.create yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ startupitem.executable ${prefix}/sbin/${name}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ startupitem.pidfile auto ${prefix}/var/run/${name}/master.pid
</span>
destroot.keepdirs \
${destroot}${prefix}/etc/${name}
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/mail/dovecot/files/dovecot-core-pushnotify.patch b/mail/dovecot/files/dovecot-core-pushnotify.patch
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index c7d121e7b7e..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/mail/dovecot/files/dovecot-core-pushnotify.patch
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,585 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./README.md
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./README.md
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,3 +1,53 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Apple Push Notification Service (APNS) Plugin
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+=============================================
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+This branch of [dovecot/core](https://github.com/dovecot/core)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+includes a plugin for APNS. This is based on
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[matthewpowell/pushnotify](https://github.com/matthewpowell/pushnotify),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[cullum/freebsd-ports](https://github.com/cullum/freebsd-ports/tree/master/mail),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+and this [post](https://www.c0ffee.net/blog/dovecot-push-notifications/).
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+APNS use requires these steps:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+1. Acquire APNS Mail certificates from a (virtual) macOS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ High Sierra 10.13 and Server.app version 5.7. Export
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ the certificates from the Keychain into the file
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ com.apple.servermgrd.apns.mail.p12 . **Note**: APNS Mail
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ certificate creation is deprecated on Server.app version 5.8+.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+2. Convert the APNS Mail certificates to PEM files:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ openssl pkcs12 -in com.apple.servermgrd.apns.mail.p12 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -clcerts -nokeys | sed '/BEGIN CERTIFICATE/,$!d' \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ > mail.crt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ sudo install -m 0644 -o _dovecot -g _dovenull \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ mail.crt /opt/local/etc/dovecot-apns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ openssl pkcs12 -in com.apple.servermgrd.apns.mail.p12 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -nodes -nocerts | sed '/BEGIN PRIVATE KEY/,$!d' \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ > mail.key
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ sudo install -m 0640 -o _dovecot -g _dovenull \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ mail.key /opt/local/etc/dovecot-apns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+3. Configure dovecot for APNS:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /opt/local/etc/dovecot/conf.d/15-lda.conf:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ protocol lda { mail_plugins = $mail_plugins push_notify }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /opt/local/etc/dovecot/conf.d/90-apns.conf:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ aps_topic = com.apple.mail.XServer.<UUID>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ where the certificate's UUID is obtained from the command:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ openssl x509 -text -noout \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -in /opt/local/etc/dovecot-apns/mail.crt \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ | grep -E -o 'com.apple.mail.XServer.[0-9a-f-]+'
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+4. Launch the APNS daemon (macOS):
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ sudo launchctl load -w \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /Library/LaunchDaemons/org.macports.dovecot-apns.plist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+```
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Installation
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ============
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./configure.ac
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./configure.ac
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -906,6 +906,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- src/plugins/notify/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- src/plugins/notify-status/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- src/plugins/push-notification/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+src/plugins/push-notify/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- src/plugins/pop3-migration/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- src/plugins/quota/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- src/plugins/quota-clone/Makefile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/auth/auth-settings.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/auth/auth-settings.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -271,6 +271,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEFLIST(passdbs, "passdb", &auth_passdb_setting_parser_info),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEFLIST(userdbs, "userdb", &auth_userdb_setting_parser_info),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ DEF_NOPREFIX(STR, aps_topic),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF_NOPREFIX(STR, base_dir),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF_NOPREFIX(BOOL, verbose_proctitle),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF_NOPREFIX(UINT, first_valid_uid),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -333,6 +334,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .passdbs = ARRAY_INIT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .userdbs = ARRAY_INIT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ .aps_topic = "",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .base_dir = PKG_RUNDIR,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .verbose_proctitle = FALSE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .first_valid_uid = 500,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/auth/auth-settings.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/auth/auth-settings.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -82,6 +82,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ARRAY(struct auth_passdb_settings *) passdbs;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ARRAY(struct auth_userdb_settings *) userdbs;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_topic;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *base_dir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *ssl_client_ca_dir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *ssl_client_ca_file;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/Makefile.am
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/Makefile.am
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -65,6 +65,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cmd-unselect.c \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cmd-unsubscribe.c \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cmd-urlfetch.c \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ cmd-x-apple-push-service.c \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cmd-x-cancel.c \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cmd-x-state.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/cmd-x-apple-push-service.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/cmd-x-apple-push-service.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,173 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2010-2011 Apple Inc. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * are met:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 2. Redistributions in binary form must reproduce the above
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * copyright notice, this list of conditions and the following
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * disclaimer in the documentation and/or other materials provided
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * with the distribution.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * contributors may be used to endorse or promote products derived
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * from this software without specific prior written permission.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "imap-common.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "imap-id.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "str.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "home-expand.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "mail-user.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "imap-quote.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <fcntl.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/un.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/stat.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define APS_VERSION "1"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef struct msg_data_s {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ unsigned long msg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ unsigned long pid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d1[128];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d2[512];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d3[512];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d4[512];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+} msg_data_t;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ tag1 XAPPLEPUSHSERVICE "aps-version" "1"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ "aps-account-id" "E8CD34AD-98D3-4489-A6BB-86B1D082FECE"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ "aps-device-token" "a66216ad1683d48b9933cdcc3b98a833ee1a968143f41ea494187da54715da66"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ "aps-subtopic" "com.apple.mobilemail"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void do_notify(const char *username, const char *aps_acct_id,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_dev_token, const char *aps_sub_topic)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *push_notify_path = "@PREFIX@/var/run/dovecot/push_notify";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ msg_data_t msg_data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ memset(&msg_data, 0, sizeof(struct msg_data_s));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ msg_data.msg = 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy(msg_data.d1, username, sizeof(msg_data.d1));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy(msg_data.d2, aps_acct_id, sizeof(msg_data.d2));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy(msg_data.d3, aps_dev_token, sizeof(msg_data.d3));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy(msg_data.d4, aps_sub_topic, sizeof(msg_data.d4));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ int soc = socket( AF_UNIX, SOCK_DGRAM, 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( soc < 0 ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_warning( "open notify socket failed(%d): %m", soc );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ struct sockaddr_un sock_addr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ memset( &sock_addr, 0, sizeof(struct sockaddr_un));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ sock_addr.sun_family = AF_UNIX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy( sock_addr.sun_path, push_notify_path, sizeof(sock_addr.sun_path) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ socklen_t sock_len = sizeof(sock_addr.sun_family) + strlen(sock_addr.sun_path) + 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ int rc = connect(soc, (struct sockaddr *) &sock_addr, sock_len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( rc < 0 ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_warning("connect to notify socket %s failed: %m",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ push_notify_path);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ close(soc);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ rc = send(soc, (void *)&msg_data, sizeof(msg_data), 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( rc < 0 )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_warning("send to notify socket %s failed: %m",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ push_notify_path);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ close(soc);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const char *aps_reply_generate (struct client_command_context *cmd,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const struct imap_arg *args)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_topic = cmd->client->set->aps_topic;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_ver=NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_acct_id=NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_dev_token=NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_sub_topic=NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *key, *value;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* must have a topic */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (aps_topic == NULL || *aps_topic == '\0')
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* scarf off the aps keys/values */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ while (imap_arg_get_astring(&args[0], &key) &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ imap_arg_get_astring(&args[1], &value)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (strcasecmp(key, "aps-version") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ aps_ver = t_strdup(value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ else if (strcasecmp(key, "aps-account-id") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ aps_acct_id = t_strdup(value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ else if (strcasecmp(key, "aps-device-token") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ aps_dev_token = t_strdup(value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ else if (strcasecmp(key, "aps-subtopic") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ aps_sub_topic = t_strdup(value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ args += 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* save notification settings */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( aps_ver && aps_acct_id && aps_dev_token && aps_sub_topic ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* subscribe to notification node */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ do_notify(cmd->client->user->username, aps_acct_id,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ aps_dev_token, aps_sub_topic);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* generate aps response */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ string_t *str = t_str_new(256);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ imap_append_quoted( str, "aps-version" );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ str_append_c(str, ' ');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ imap_append_quoted( str, APS_VERSION );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ str_append_c(str, ' ');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ imap_append_quoted( str, "aps-topic" );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ str_append_c(str, ' ');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ imap_append_quoted( str, aps_topic );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return str_c(str);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool cmd_x_apple_push_service(struct client_command_context *cmd)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const struct imap_arg *args;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (!client_read_args(cmd, 0, 0, &args))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return FALSE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *reply = aps_reply_generate(cmd, args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (reply != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ client_send_line(cmd->client,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ t_strdup_printf("* XAPPLEPUSHSERVICE %s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ reply));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ client_send_tagline(cmd, "OK XAPPLEPUSHSERVICE completed.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return TRUE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/imap-client.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/imap-client.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -178,6 +178,8 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- a chance of working */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- client_add_capability(client, "SEARCH=FUZZY");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (set->aps_topic != NULL && *set->aps_topic)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ str_append(client->capability_string, " XAPPLEPUSHSERVICE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail_set = mail_user_set_get_storage_set(user);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (mail_set->mailbox_list_index) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/imap-commands.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/imap-commands.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -76,6 +76,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- { "UID SORT", cmd_sort, COMMAND_FLAG_BREAKS_SEQS },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- { "UID THREAD", cmd_thread, COMMAND_FLAG_BREAKS_SEQS },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- { "UNSELECT", cmd_unselect, COMMAND_FLAG_BREAKS_MAILBOX },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ { "XAPPLEPUSHSERVICE", cmd_x_apple_push_service, 0},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- { "X-CANCEL", cmd_x_cancel, 0 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- { "X-STATE", cmd_x_state, COMMAND_FLAG_REQUIRES_SYNC },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- { "XLIST", cmd_list, 0 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/imap-commands.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/imap-commands.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -121,6 +121,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool cmd_uid_expunge(struct client_command_context *cmd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool cmd_move(struct client_command_context *cmd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool cmd_unselect(struct client_command_context *cmd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool cmd_x_apple_push_service(struct client_command_context *cmd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool cmd_x_cancel(struct client_command_context *cmd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool cmd_x_state(struct client_command_context *cmd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/imap-settings.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/imap-settings.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -75,6 +75,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(STR, imap_logout_format),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(STR, imap_id_send),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(STR, imap_id_log),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ DEF(STR, aps_topic),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(ENUM, imap_fetch_failure),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(BOOL, imap_metadata),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(BOOL, imap_literal_minus),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -103,6 +104,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- "body_count=%{fetch_body_count} body_bytes=%{fetch_body_bytes}",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_id_send = "name *",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_id_log = "",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ .aps_topic = "",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_fetch_failure = "disconnect-immediately:disconnect-after:no-after",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_metadata = FALSE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_literal_minus = FALSE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap/imap-settings.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap/imap-settings.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -31,6 +31,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_logout_format;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_id_send;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_id_log;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_topic;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_fetch_failure;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool imap_metadata;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool imap_literal_minus;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap-login/imap-login-client.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap-login/imap-login-client.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -116,6 +116,8 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- str_append(cap_str, " STARTTLS");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (is_login_cmd_disabled(client))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- str_append(cap_str, " LOGINDISABLED");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (*imap_client->set->aps_topic)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ str_append(cap_str, " XAPPLEPUSHSERVICE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- client_authenticate_get_capabilities(client, cap_str);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- return str_c(cap_str);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap-login/imap-login-settings.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap-login/imap-login-settings.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -57,6 +57,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(STR, imap_capability),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(STR, imap_id_send),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(STR, imap_id_log),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ DEF(STR, aps_topic),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(BOOL, imap_literal_minus),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DEF(BOOL, imap_id_retain),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -67,6 +68,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_capability = "",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_id_send = "name *",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_id_log = "",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ .aps_topic = "",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_literal_minus = FALSE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .imap_id_retain = FALSE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/imap-login/imap-login-settings.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/imap-login/imap-login-settings.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -5,6 +5,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_capability;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_id_send;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *imap_id_log;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *aps_topic;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool imap_literal_minus;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- bool imap_id_retain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/lib-lda/mail-deliver.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/lib-lda/mail-deliver.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -35,6 +35,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- deliver_mail_func_t *deliver_mail = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+deliver_hook_func_t *deliver_hook = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct mail_deliver_mailbox {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- union mailbox_module_context module_ctx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -461,6 +462,9 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pool_unref(&changes.pool);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (deliver_hook != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ deliver_hook(ctx, mailbox);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail_storage_get_last_internal_error(*storage_r, &error));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -549,6 +553,8 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* success. message may or may not have been saved. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ret = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (!ret && deliver_hook)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ deliver_hook(ctx, ctx->rcpt_default_mailbox);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail_duplicate_db_deinit(&ctx->dup_db);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- return -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/lib-lda/mail-deliver.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/lib-lda/mail-deliver.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -140,6 +140,9 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct mail_storage **storage_r);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern deliver_mail_func_t *deliver_mail;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef void deliver_hook_func_t(struct mail_deliver_context *ctx,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *mailbox);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern deliver_hook_func_t *deliver_hook;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const struct var_expand_table *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail_deliver_ctx_get_log_var_expand_table(struct mail_deliver_context *ctx,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/plugins/Makefile.am
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/plugins/Makefile.am
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -29,6 +29,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- notify \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- notify-status \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- push-notification \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ push-notify \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mail-log \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $(MAIL_LUA) \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mailbox-alias \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/plugins/push-notify/Makefile.am
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/plugins/push-notify/Makefile.am
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,25 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+AM_CPPFLAGS = \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -I$(top_srcdir)/src/lib \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -I$(top_srcdir)/src/lib-lda \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -I$(top_srcdir)/src/lib-mail \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -I$(top_srcdir)/src/lib-smtp \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ -I$(top_srcdir)/src/lib-storage
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+NOPLUGIN_LDFLAGS =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+lib20_push_notify_plugin_la_LDFLAGS = -module -avoid-version
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+module_LTLIBRARIES = \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ lib20_push_notify_plugin.la
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+if DOVECOT_PLUGIN_DEPS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+notify_deps = ../notify/lib15_notify_plugin.la
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+lib20_push_notify_plugin_la_SOURCES = \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ push-notify-plugin.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+headers = \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ push-notify-plugin.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pkginc_libdir = $(pkgincludedir)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pkginc_lib_HEADERS = $(headers)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/plugins/push-notify/push-notify-plugin.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/plugins/push-notify/push-notify-plugin.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,102 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Copyright (c) 2008-2011 Apple, inc. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "lib.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "mail-deliver.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "mail-namespace.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "message-address.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "push-notify-plugin.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/un.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/stat.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/unistd.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+const char *push_notify_plugin_version = DOVECOT_ABI_VERSION;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static deliver_hook_func_t *next_deliver_mail;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct et_list *_et_list = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct message_info {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *from;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *subj;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+// -----------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+// push_notification ()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+push_notification(struct mail_deliver_context *ctx, const char *mailbox)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ int debug = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ int notify_sock = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *sock_path = "@PREFIX@/var/run/dovecot/push_notify";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ ssize_t rc = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ socklen_t sock_len = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ struct sockaddr_un sock_addr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ struct msg_data_s msg_data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (ctx->rcpt_user->mail_debug) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ debug = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_info( "push-notify: push notification enabled" );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( strcasecmp(mailbox, "INBOX") != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_info( "push-notify: message saved to mailbox: %s, no notification sent", mailbox );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ notify_sock = socket( AF_UNIX, SOCK_DGRAM, 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( notify_sock < 0 ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* warn that connect failed but do not fail the plugin or message will not get delivered */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_warning( "push-notify: open socket: \"%s\" failed", sock_path );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ sock_addr.sun_family = AF_UNIX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy( sock_addr.sun_path, "@PREFIX@/var/run/dovecot/push_notify", sizeof(sock_addr.sun_path) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ sock_len = sizeof(sock_addr.sun_family) + strlen(sock_addr.sun_path) + 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ rc = connect(notify_sock, (struct sockaddr *) &sock_addr, sock_len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( rc < 0 ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* warn that connect failed but do not fail the plugin or message will not get delivered */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_warning( "push-notify: connect() to socket: \"%s\" failed: %m", sock_path );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ memset( &msg_data, 0, sizeof( msg_data ) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ msg_data.msg = 3;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ /* set user/account id */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( ctx->rcpt_user->username != NULL ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ strncpy( msg_data.d1, ctx->rcpt_user->username, sizeof(msg_data.d1) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (debug)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_info( "push-notify: notify: %s", msg_data.d1 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ rc = send(notify_sock, (void *)&msg_data, sizeof(struct msg_data_s), 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if ( rc < 0 )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_warning( "push-notify: send() to socket: \"%s\" failed: %m", sock_path );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (debug)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ i_info("push-notify: data sent: %lu", rc);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ close(notify_sock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+} // push_notification
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void push_notify_deliver(struct mail_deliver_context *ctx,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ const char *mailbox)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ push_notification(ctx, mailbox);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ if (next_deliver_mail != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ next_deliver_mail(ctx, mailbox);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void push_notify_plugin_init (struct module *module ATTR_UNUSED)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ next_deliver_mail = deliver_hook;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ deliver_hook = push_notify_deliver;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void push_notify_plugin_deinit (void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ deliver_hook = next_deliver_mail;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- ./src/plugins/push-notify/push-notify-plugin.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ ./src/plugins/push-notify/push-notify-plugin.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,20 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Copyright (c) 2008-2011 Apple, inc. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifndef __NOTIFY_PLUGIN_H__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define __NOTIFY_PLUGIN_H__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct module;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void push_notify_plugin_init(struct module *module);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void push_notify_plugin_deinit(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef struct msg_data_s {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ unsigned long msg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ unsigned long pid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d1[128];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d2[512];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d3[512];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ char d4[512];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+} msg_data_t;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/mail/dovecot/files/org.macports.dovecot-apns.plist b/mail/dovecot/files/org.macports.dovecot-apns.plist
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 8c63e2080cd..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/mail/dovecot/files/org.macports.dovecot-apns.plist
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,21 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<?xml version='1.0' encoding='UTF-8'?>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<plist version='1.0'>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<dict>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<key>Label</key><string>org.macports.dovecot-apns</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<key>ProgramArguments</key>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<array>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>@PREFIX@/bin/daemondo</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>--label=dovecot-apns</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>--start-cmd</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>@PREFIX@/sbin/pushnotify.pl</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>;</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>--pid=exec</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>--pidfile</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- <string>@PREFIX@/var/run/dovecot/pushnotify.pid</string>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-</array>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<key>Disabled</key><true/>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-<key>KeepAlive</key><true/>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-</dict>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-</plist>
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/mail/dovecot/files/pushnotify.pl b/mail/dovecot/files/pushnotify.pl
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 862e329fa23..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/mail/dovecot/files/pushnotify.pl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,130 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#!@PREFIX@/bin/perl@PERL5_MAJOR_VERSION@ -w -T
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# Based on https://github.com/matthewpowell/pushnotify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# LGPLv2.1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-use strict;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-use lib '@PREFIX@/lib/pushnotify';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-use Privileges::Drop;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-use IO::Socket::UNIX qw( SOCK_DGRAM SOMAXCONN );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-use Sys::Syslog qw( openlog syslog LOG_INFO );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-use Net::APNS::SimpleCert;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-sub save_devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# Dovecot's push notification socket
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $sockpath = '@PREFIX@/var/run/dovecot/push_notify';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# user to drop privileges to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $user = '@DEFAULT_INTERNAL_USER@';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# A file containing registration information
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $devicepath = '@PREFIX@/var/db/dovecot-apns/devices';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# APNS certificate
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $apns_cert = '@PREFIX@/etc/dovecot-apns/com.apple.mail.cert.pem';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# APNS key (might be the same as $apns_cert)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $apns_key = '@PREFIX@/etc/dovecot-apns/com.apple.mail.key.pem';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# Read in the list of registered devices.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my %devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-if (open DEVICES, $devicepath) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- while (<DEVICES>) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- chomp;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- my ($username, $devicedata) = split /:/;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- push @{$devices{$username}}, $devicedata;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- close DEVICES;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# Open the socket to Dovecot
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-unlink $sockpath;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-umask (0111);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $socket = IO::Socket::UNIX->new(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Type => SOCK_DGRAM,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Local => $sockpath,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Listen => SOMAXCONN,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-) or die("Can't create server socket: $!\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-drop_privileges($user);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-openlog ('pushnotify', 'ndelay', 'mail');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# We'll defer connecting to APNS until our first notification, but define $apns here
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-my $apns;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-syslog (LOG_INFO, 'Atomnet push notify service running');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-while(1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- my $data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $socket->recv($data, 2048);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- my ($junk, $username, $aps_acct_id, $aps_dev_token, $aps_sub_topic) = split /\0+/, $data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if ($aps_acct_id) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $aps_dev_token = lc($aps_dev_token);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- my $devicedata = join ',', $aps_acct_id, $aps_dev_token, $aps_sub_topic, time;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- syslog (LOG_INFO, "Register device $aps_dev_token for $username");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Cancel any duplicate registration
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- @{$devices{$username}} = grep {!/$aps_dev_token/} @{$devices{$username}};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Register new device
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- push @{$devices{$username}}, $devicedata;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- save_devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (defined $devices{$username}) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # User has at least one device registered
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Do the push notification
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- foreach (@{$devices{$username}}) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- my ($aps_acct_id, $aps_dev_token, $aps_sub_topic, $time) = split /,/;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- syslog(LOG_INFO, "Send notification to $aps_dev_token for $username");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- eval {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $apns->prepare (
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $aps_dev_token,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- aps => {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 'account-id' => $aps_acct_id
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $apns->notify;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } or do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Failed; connect to APNS and try again
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- syslog(LOG_INFO, 'Connect to APNS push gateway');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- eval { $apns->disconnect };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $apns = Net::APNS::SimpleCert->new({
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- development => 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cert => $apns_cert,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- key => $apns_key
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $apns->prepare (
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $aps_dev_token,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- aps => {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 'account-id' => $aps_acct_id
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- $apns->notify;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-sub save_devices {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Save our registration data
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- umask (0077);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- open DEVICES, ">$devicepath";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- foreach my $username (keys %devices) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- foreach my $devicedata (@{$devices{$username}}) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- print DEVICES "$username:$devicedata\n";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- close DEVICES;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span></pre><pre style='margin:0'>
</pre>