summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'eclass/qmail.eclass')
-rw-r--r--eclass/qmail.eclass536
1 files changed, 536 insertions, 0 deletions
diff --git a/eclass/qmail.eclass b/eclass/qmail.eclass
new file mode 100644
index 000000000000..eb6e0122998f
--- /dev/null
+++ b/eclass/qmail.eclass
@@ -0,0 +1,536 @@
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+# @ECLASS: qmail.eclass
+# @MAINTAINER:
+# qmail-bugs@gentoo.org
+# @BLURB: common qmail functions
+
+inherit flag-o-matic toolchain-funcs fixheadtails user
+
+# hardcoded paths
+QMAIL_HOME="/var/qmail"
+TCPRULES_DIR="/etc/tcprules.d"
+SUPERVISE_DIR="/var/qmail/supervise"
+
+# source files and directories
+GENQMAIL_F=genqmail-${GENQMAIL_PV}.tar.bz2
+GENQMAIL_S="${WORKDIR}"/genqmail-${GENQMAIL_PV}
+
+QMAIL_SPP_F=qmail-spp-${QMAIL_SPP_PV}.tar.gz
+QMAIL_SPP_S="${WORKDIR}"/qmail-spp-${QMAIL_SPP_PV}
+
+# @FUNCTION: primes
+# @USAGE: <min> <max>
+# @DESCRIPTION:
+# Prints a list of primes between min and max inclusive
+# Note: this functions gets very slow when used with large numbers.
+primes() {
+ local min=${1} max=${2}
+ local result= primelist=2 i p
+
+ [[ ${min} -le 2 ]] && result="${result} 2"
+
+ for ((i = 3; i <= max; i += 2))
+ do
+ for p in ${primelist}
+ do
+ [[ $[i % p] == 0 || $[p * p] -gt ${i} ]] && \
+ break
+ done
+ if [[ $[i % p] != 0 ]]
+ then
+ primelist="${primelist} ${i}"
+ [[ ${i} -ge ${min} ]] && \
+ result="${result} ${i}"
+ fi
+ done
+
+ echo ${result}
+}
+
+# @FUNCTION: is_prima
+# @USAGE: <number>
+# @DESCRIPTION:
+# Checks wether a number is a prime number
+is_prime() {
+ local number=${1} i
+ for i in $(primes ${number} ${number})
+ do
+ [[ ${i} == ${number} ]] && return 0
+ done
+ return 1
+}
+
+dospp() {
+ insinto "${QMAIL_HOME}"/plugins/
+ insopts -o root -g "$GROUP_ROOT" -m 0755
+ newins $1 ${2:-$(basename $1)}
+}
+
+# @FUNCTION: dosupervise
+# @USAGE: dosupervise <service> [<runfile> <logfile>]
+# @DESCRIPTION:
+# Install runfiles for services and logging to supervise directory
+dosupervise() {
+ local service=$1
+ local runfile=${2:-${service}} logfile=${3:-${service}-log}
+ [[ -z "${service}" ]] && die "no service given"
+
+ insopts -o root -g "$GROUP_ROOT" -m 0755
+ diropts -o root -g "$GROUP_ROOT" -m 0755
+
+ dodir ${SUPERVISE_DIR}/${service}{,/log}
+ fperms +t ${SUPERVISE_DIR}/${service}{,/log}
+
+ insinto ${SUPERVISE_DIR}/${service}
+ newins ${runfile} run
+
+ insinto ${SUPERVISE_DIR}/${service}/log
+ newins ${logfile} run
+}
+
+# @FUNCTION: qmail_set_cc
+# @DESCRIPTION:
+# The following commands patch the conf-{cc,ld} files to use the user's
+# specified CFLAGS and LDFLAGS. These rather complex commands are needed
+# because a user supplied patch might apply changes to these files, too.
+# See bug #165981.
+qmail_set_cc() {
+ local cc=$(head -n 1 ./conf-cc | sed -e "s#^g\?cc\s\+\(-O2\)\?#$(tc-getCC) #")
+ local ld=$(head -n 1 ./conf-ld | sed -e "s#^g\?cc\s\+\(-s\)\?#$(tc-getCC) #")
+
+ echo "${cc} ${CFLAGS} ${CPPFLAGS}" > ./conf-cc || die 'Patching conf-cc failed.'
+ echo "${ld} ${LDFLAGS}" > ./conf-ld || die 'Patching conf-ld failed.'
+}
+
+# @FUNCTION: qmail_create_groups
+# @DESCRIPTION:
+# Keep qmail groups in sync across ebuilds
+qmail_create_groups() {
+ einfo "Creating qmail groups"
+ enewgroup nofiles 200
+ enewgroup qmail 201
+}
+
+# @FUNCTION: qmail_create_users
+# @DESCRIPTION:
+# Keep qmail users in sync across ebuilds
+qmail_create_users() {
+ qmail_create_groups
+
+ einfo "Creating qmail users"
+ enewuser alias 200 -1 "${QMAIL_HOME}"/alias 200
+ enewuser qmaild 201 -1 "${QMAIL_HOME}" 200
+ enewuser qmaill 202 -1 "${QMAIL_HOME}" 200
+ enewuser qmailp 203 -1 "${QMAIL_HOME}" 200
+ enewuser qmailq 204 -1 "${QMAIL_HOME}" 201
+ enewuser qmailr 205 -1 "${QMAIL_HOME}" 201
+ enewuser qmails 206 -1 "${QMAIL_HOME}" 201
+}
+
+genqmail_src_unpack() {
+ cd "${WORKDIR}"
+ [[ -n ${GENQMAIL_PV} ]] && unpack "${GENQMAIL_F}"
+}
+
+qmail_spp_src_unpack() {
+ cd "${WORKDIR}"
+ [[ -n ${QMAIL_SPP_PV} ]] && unpack "${QMAIL_SPP_F}"
+}
+
+# @FUNCTION: qmail_src_postunpack
+# @DESCRIPTION:
+# Unpack common config files, apply custom patches if supplied and
+# set built configuration (CFLAGS, LDFLAGS, etc)
+qmail_src_postunpack() {
+ cd "${S}"
+
+ qmail_set_cc
+
+ mysplit=${QMAIL_CONF_SPLIT:-23}
+ is_prime ${mysplit} || die "QMAIL_CONF_SPLIT is not a prime number."
+ einfo "Using conf-split value of ${mysplit}."
+ echo -n ${mysplit} > "${S}"/conf-split
+}
+
+qmail_src_compile() {
+ cd "${S}"
+ emake it man "$@" || die "make failed"
+}
+
+qmail_spp_src_compile() {
+ cd "${GENQMAIL_S}"/spp/
+ emake || die "make spp failed"
+}
+
+qmail_base_install() {
+ einfo "Setting up basic directory hierarchy"
+ diropts -o root -g qmail -m 755
+ keepdir "${QMAIL_HOME}"/{,bin,control}
+
+ einfo "Installing basic qmail software"
+ insinto "${QMAIL_HOME}"/bin
+
+ insopts -o root -g qmail -m 755
+ doins datemail elq forward maildir2mbox maildirmake \
+ maildirwatch mailsubj pinq predate qail \
+ qmail-{inject,qmqpc,showctl} sendmail
+
+ einfo "Adding env.d entry for qmail"
+ doenvd "${GENQMAIL_S}"/conf/99qmail
+
+ declare -F qmail_base_install_hook >/dev/null && \
+ qmail_base_install_hook
+}
+
+qmail_full_install() {
+ einfo "Setting up full directory hierarchy"
+ keepdir "${QMAIL_HOME}"/users
+ diropts -o alias -g qmail -m 755
+ keepdir "${QMAIL_HOME}"/alias
+
+ einfo "Installing all qmail software"
+ insopts -o root -g qmail -m 755
+ doins bouncesaying condredirect config-fast except preline qbiff \
+ qmail-{pop3d,qmqpd,qmtpd,qread,qstat,smtpd,tcpok,tcpto} \
+ qreceipt qsmhook tcp-env
+
+ insopts -o root -g qmail -m 711
+ doins qmail-{clean,getpw,local,popup,pw2u,remote,rspawn,send} splogger
+
+ insopts -o root -g qmail -m 700
+ doins qmail-{lspawn,newmrh,newu,start}
+
+ insopts -o qmailq -g qmail -m 4711
+ doins qmail-queue
+
+ declare -F qmail_full_install_hook >/dev/null && \
+ qmail_full_install_hook
+}
+
+qmail_config_install() {
+ einfo "Installing stock configuration files"
+ insinto "${QMAIL_HOME}"/control
+ insopts -o root -g "$GROUP_ROOT" -m 644
+ doins "${GENQMAIL_S}"/control/{conf-*,defaultdelivery}
+
+ einfo "Installing configuration sanity checker and launcher"
+ insinto "${QMAIL_HOME}"/bin
+ insopts -o root -g "$GROUP_ROOT" -m 644
+ doins "${GENQMAIL_S}"/control/qmail-config-system
+
+ declare -F qmail_config_install_hook >/dev/null && \
+ qmail_config_install_hook
+}
+
+qmail_man_install() {
+ einfo "Installing manpages and documentation"
+
+ # those are tagged for section 8 but named for
+ # section 9 (which does not exist anyway)
+ for i in *.9; do
+ mv ${i} ${i/.9/.8}
+ done
+
+ into /usr
+ doman *.[1578]
+ dodoc BLURB* CHANGES FAQ INSTALL* PIC* README* REMOVE* SECURITY \
+ SENDMAIL SYSDEPS TEST* THANKS* THOUGHTS TODO* \
+ UPGRADE VERSION*
+
+ declare -F qmail_man_install_hook >/dev/null && \
+ qmail_man_install_hook
+}
+
+qmail_sendmail_install() {
+ einfo "Installing sendmail replacement"
+ diropts -m 755
+ dodir /usr/sbin /usr/lib
+
+ dosym "${QMAIL_HOME}"/bin/sendmail /usr/sbin/sendmail
+ dosym "${QMAIL_HOME}"/bin/sendmail /usr/lib/sendmail
+
+ declare -F qmail_sendmail_install_hook >/dev/null && \
+ qmail_sendmail_install_hook
+}
+
+qmail_maildir_install() {
+ # use the correct maildirmake
+ # the courier-imap one has some extensions that are nicer
+ MAILDIRMAKE="${D}${QMAIL_HOME}/bin/maildirmake"
+ [[ -e /usr/bin/maildirmake ]] && \
+ MAILDIRMAKE="/usr/bin/maildirmake"
+
+ einfo "Setting up the default aliases"
+ diropts -o alias -g qmail -m 700
+ "${MAILDIRMAKE}" "${D}${QMAIL_HOME}"/alias/.maildir
+ keepdir "${QMAIL_HOME}"/alias/.maildir/{cur,new,tmp}
+
+ for i in "${QMAIL_HOME}"/alias/.qmail-{mailer-daemon,postmaster,root}; do
+ if [[ ! -f "${ROOT}${i}" ]]; then
+ touch "${D}${i}"
+ fowners alias:qmail "${i}"
+ fi
+ done
+
+ einfo "Setting up default maildirs in the account skeleton"
+ diropts -o root -g "$GROUP_ROOT" -m 755
+ insinto /etc/skel
+ insopts -o root -g "$GROUP_ROOT" -m 644
+ newins "${GENQMAIL_S}"/control/defaultdelivery .qmail.sample
+ "${MAILDIRMAKE}" "${D}"/etc/skel/.maildir
+ keepdir /etc/skel/.maildir/{cur,new,tmp}
+
+ declare -F qmail_maildir_install_hook >/dev/null && \
+ qmail_maildir_install_hook
+}
+
+qmail_tcprules_install() {
+ dodir "${TCPRULES_DIR}"
+ insinto "${TCPRULES_DIR}"
+ insopts -o root -g "$GROUP_ROOT" -m 0644
+ doins "${GENQMAIL_S}"/tcprules/Makefile.qmail
+ doins "${GENQMAIL_S}"/tcprules/tcp.qmail-*
+ use ssl || rm -f "${D}${TCPRULES_DIR}"/tcp.qmail-pop3sd
+}
+
+qmail_supervise_install() {
+ einfo "Installing supervise scripts"
+
+ cd "${GENQMAIL_S}"/supervise
+
+ for i in qmail-{send,smtpd,qmtpd,qmqpd,pop3d}; do
+ dosupervise ${i}
+ diropts -o qmaill -g "$GROUP_ROOT" -m 755
+ keepdir /var/log/qmail/${i}
+ done
+
+ if use ssl; then
+ dosupervise qmail-pop3sd
+ diropts -o qmaill -g "$GROUP_ROOT" -m 755
+ keepdir /var/log/qmail/qmail-pop3sd
+ fi
+
+ declare -F qmail_supervise_install_hook >/dev/null && \
+ qmail_supervise_install_hook
+}
+
+qmail_spp_install() {
+ einfo "Installing qmail-spp configuration files"
+ insinto "${QMAIL_HOME}"/control/
+ insopts -o root -g "$GROUP_ROOT" -m 0644
+ doins "${GENQMAIL_S}"/spp/smtpplugins
+
+ einfo "Installing qmail-spp plugins"
+ keepdir "${QMAIL_HOME}"/plugins/
+ for i in authlog mfdnscheck ifauthnext tarpit; do
+ dospp "${GENQMAIL_S}"/spp/${i}
+ done
+
+ declare -F qmail_spp_install_hook >/dev/null && \
+ qmail_spp_install_hook
+}
+
+qmail_ssl_install() {
+ use gencertdaily && \
+ CRON_FOLDER=cron.daily || \
+ CRON_FOLDER=cron.hourly
+
+ einfo "Installing SSL Certificate creation script"
+ insinto "${QMAIL_HOME}"/control
+ insopts -o root -g "$GROUP_ROOT" -m 0644
+ doins "${GENQMAIL_S}"/ssl/servercert.cnf
+
+ insinto "${QMAIL_HOME}"/bin
+ insopts -o root -g "$GROUP_ROOT" -m 0755
+ doins "${GENQMAIL_S}"/ssl/mkservercert
+
+ einfo "Installing RSA key generation cronjob"
+ insinto /etc/${CRON_FOLDER}
+ insopts -o root -g "$GROUP_ROOT" -m 0755
+ doins "${GENQMAIL_S}"/ssl/qmail-genrsacert.sh
+
+ keepdir "${QMAIL_HOME}"/control/tlshosts
+
+ declare -F qmail_ssl_install_hook >/dev/null && \
+ qmail_ssl_install_hook
+}
+
+qmail_src_install() {
+ export GROUP_ROOT="$(id -gn root)"
+ qmail_base_install
+ qmail_full_install
+ qmail_config_install
+ qmail_man_install
+ qmail_sendmail_install
+ qmail_maildir_install
+ qmail_tcprules_install
+ qmail_supervise_install
+
+ use qmail-spp && qmail_spp_install
+ use ssl && qmail_ssl_install
+}
+
+qmail_queue_setup() {
+ if use highvolume; then
+ myconf="--bigtodo"
+ else
+ myconf="--no-bigtodo"
+ fi
+
+ mysplit=${QMAIL_CONF_SPLIT:-23}
+ is_prime ${mysplit} || die "QMAIL_CONF_SPLIT is not a prime number."
+
+ einfo "Setting up the message queue hierarchy"
+ /usr/bin/queue-repair.py --create ${myconf} \
+ --split ${mysplit} \
+ "${ROOT}${QMAIL_HOME}" >/dev/null || \
+ die 'queue-repair failed'
+}
+
+qmail_rootmail_fixup() {
+ local TMPCMD="ln -sf ${QMAIL_HOME}/alias/.maildir/ ${ROOT}/root/.maildir"
+
+ if [[ -d "${ROOT}"/root/.maildir && ! -L "${ROOT}"/root/.maildir ]] ; then
+ elog "Previously the qmail ebuilds created /root/.maildir/ but not"
+ elog "every mail was delivered there. If the directory does not"
+ elog "contain any mail, please delete it and run:"
+ elog "${TMPCMD}"
+ else
+ ${TMPCMD}
+ fi
+
+ chown -R alias:qmail "${ROOT}${QMAIL_HOME}"/alias/.maildir 2>/dev/null
+}
+
+qmail_tcprules_fixup() {
+ mkdir -p "${TCPRULES_DIR}"
+ for f in {smtp,qmtp,qmqp,pop3}{,.cdb}; do
+ old="/etc/tcp.${f}"
+ new="${TCPRULES_DIR}/tcp.qmail-${f}"
+ fail=0
+ if [[ -f "${old}" && ! -f "${new}" ]]; then
+ einfo "Moving ${old} to ${new}"
+ cp "${old}" "${new}" || fail=1
+ else
+ fail=1
+ fi
+ if [[ "${fail}" = 1 && -f "${old}" ]]; then
+ eerror "Error moving ${old} to ${new}, be sure to check the"
+ eerror "configuration! You may have already moved the files,"
+ eerror "in which case you can delete ${old}"
+ fi
+ done
+}
+
+qmail_tcprules_build() {
+ for f in tcp.qmail-{smtp,qmtp,qmqp,pop3,pop3s}; do
+ # please note that we don't check if it exists
+ # as we want it to make the cdb files anyway!
+ src="${ROOT}${TCPRULES_DIR}/${f}"
+ cdb="${ROOT}${TCPRULES_DIR}/${f}.cdb"
+ tmp="${ROOT}${TCPRULES_DIR}/.${f}.tmp"
+ [[ -e "${src}" ]] && tcprules "${cdb}" "${tmp}" < "${src}"
+ done
+}
+
+qmail_config_notice() {
+ elog
+ elog "To setup ${PN} to run out-of-the-box on your system, run:"
+ elog "emerge --config =${CATEGORY}/${PF}"
+}
+
+qmail_supervise_config_notice() {
+ elog
+ elog "To start qmail at boot you have to add svscan to your startup"
+ elog "and create the following links:"
+ elog "ln -s ${SUPERVISE_DIR}/qmail-send /service/qmail-send"
+ elog "ln -s ${SUPERVISE_DIR}/qmail-smtpd /service/qmail-smtpd"
+ elog
+ elog "To start the pop3 server as well, create the following link:"
+ elog "ln -s ${SUPERVISE_DIR}/qmail-pop3d /service/qmail-pop3d"
+ elog
+ if use ssl; then
+ elog "To start the pop3s server as well, create the following link:"
+ elog "ln -s ${SUPERVISE_DIR}/qmail-pop3sd /service/qmail-pop3sd"
+ elog
+ fi
+ elog "Additionally, the QMTP and QMQP protocols are supported, "
+ elog "and can be started as:"
+ elog "ln -s ${SUPERVISE_DIR}/qmail-qmtpd /service/qmail-qmtpd"
+ elog "ln -s ${SUPERVISE_DIR}/qmail-qmqpd /service/qmail-qmqpd"
+ elog
+ elog "Additionally, if you wish to run qmail right now, you should "
+ elog "run this before anything else:"
+ elog "source /etc/profile"
+}
+
+qmail_config_fast() {
+ if [[ ${ROOT} = / ]]; then
+ local host=$(hostname --fqdn)
+
+ if [[ -z "${host}" ]]; then
+ eerror
+ eerror "Cannot determine your fully-qualified hostname"
+ eerror "Please setup your /etc/hosts as described in"
+ eerror "http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&chap=8#doc_chap2_sect4"
+ eerror
+ die "cannot determine FQDN"
+ fi
+
+ if [[ ! -f "${ROOT}${QMAIL_HOME}"/control/me ]]; then
+ "${ROOT}${QMAIL_HOME}"/bin/config-fast ${host}
+ fi
+ else
+ ewarn "Skipping some configuration as it MUST be run on the final host"
+ fi
+}
+
+qmail_tcprules_config() {
+ local localips ip tcpstring line proto f
+
+ einfo "Accepting relaying by default from all ips configured on this machine."
+
+ # Start with iproute2 as ifconfig is deprecated, and ifconfig does not handle
+ # additional addresses added via iproute2.
+ # Note: We have to strip off the packed netmask w/e.g. 192.168.0.2/24
+ localips=$(ip address show 2>/dev/null | awk '$1 == "inet" {print $2}' | sed 's:/.*::')
+ if [[ -z ${localips} ]] ; then
+ # Hello old friend. Maybe you can tell us at least something.
+ localips=$(ifconfig | awk '$1 == "inet" {print $2}')
+ fi
+
+ tcpstring=':allow,RELAYCLIENT="",RBLSMTPD=""'
+
+ for ip in ${localips}; do
+ line="${ip}${tcpstring}"
+ for proto in smtp qmtp qmqp; do
+ f="${EROOT}${TCPRULES_DIR}/tcp.qmail-${proto}"
+ egrep -qs "${line}" "${f}" || echo "${line}" >> "${f}"
+ done
+ done
+}
+
+qmail_ssl_generate() {
+ CRON_FOLDER=cron.hourly
+ use gencertdaily && CRON_FOLDER=cron.daily
+
+ ebegin "Generating RSA keys for SSL/TLS, this can take some time"
+ "${ROOT}"/etc/${CRON_FOLDER}/qmail-genrsacert.sh
+ eend $?
+
+ einfo "Creating a self-signed ssl-certificate:"
+ "${ROOT}${QMAIL_HOME}"/bin/mkservercert
+
+ einfo "If you want to have a properly signed certificate "
+ einfo "instead, do the following:"
+ # space at the end of the string because of the current implementation
+ # of einfo
+ einfo "openssl req -new -nodes -out req.pem \\ "
+ einfo " -config ${QMAIL_HOME}/control/servercert.cnf \\ "
+ einfo " -keyout ${QMAIL_HOME}/control/servercert.pem"
+ einfo "Send req.pem to your CA to obtain signed_req.pem, and do:"
+ einfo "cat signed_req.pem >> ${QMAIL_HOME}/control/servercert.pem"
+}