1 # Copyright 1999-2012 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: qmail.eclass
6 # qmail-bugs@gentoo.org
7 # @BLURB: common qmail functions
9 inherit flag-o-matic toolchain-funcs fixheadtails user
12 QMAIL_HOME="/var/qmail"
13 TCPRULES_DIR="/etc/tcprules.d"
14 SUPERVISE_DIR="/var/qmail/supervise"
16 # source files and directories
17 GENQMAIL_F=genqmail-${GENQMAIL_PV}.tar.bz2
18 GENQMAIL_S="${WORKDIR}"/genqmail-${GENQMAIL_PV}
20 QMAIL_SPP_F=qmail-spp-${QMAIL_SPP_PV}.tar.gz
21 QMAIL_SPP_S="${WORKDIR}"/qmail-spp-${QMAIL_SPP_PV}
26 # Prints a list of primes between min and max inclusive
27 # Note: this functions gets very slow when used with large numbers.
29 local min=${1} max=${2}
30 local result= primelist=2 i p
32 [[ ${min} -le 2 ]] && result="${result} 2"
34 for ((i = 3; i <= max; i += 2))
38 [[ $[i % p] == 0 || $[p * p] -gt ${i} ]] && \
41 if [[ $[i % p] != 0 ]]
43 primelist="${primelist} ${i}"
44 [[ ${i} -ge ${min} ]] && \
45 result="${result} ${i}"
55 # Checks wether a number is a prime number
58 for i in $(primes ${number} ${number})
60 [[ ${i} == ${number} ]] && return 0
66 insinto "${QMAIL_HOME}"/plugins/
67 insopts -o root -g "$GROUP_ROOT" -m 0755
68 newins $1 ${2:-$(basename $1)}
71 # @FUNCTION: dosupervise
72 # @USAGE: dosupervise <service> [<runfile> <logfile>]
74 # Install runfiles for services and logging to supervise directory
77 local runfile=${2:-${service}} logfile=${3:-${service}-log}
78 [[ -z "${service}" ]] && die "no service given"
80 insopts -o root -g "$GROUP_ROOT" -m 0755
81 diropts -o root -g "$GROUP_ROOT" -m 0755
83 dodir ${SUPERVISE_DIR}/${service}{,/log}
84 fperms +t ${SUPERVISE_DIR}/${service}{,/log}
86 insinto ${SUPERVISE_DIR}/${service}
89 insinto ${SUPERVISE_DIR}/${service}/log
93 # @FUNCTION: qmail_set_cc
95 # The following commands patch the conf-{cc,ld} files to use the user's
96 # specified CFLAGS and LDFLAGS. These rather complex commands are needed
97 # because a user supplied patch might apply changes to these files, too.
100 local cc=$(head -n 1 ./conf-cc | sed -e "s#^g\?cc\s\+\(-O2\)\?#$(tc-getCC) #")
101 local ld=$(head -n 1 ./conf-ld | sed -e "s#^g\?cc\s\+\(-s\)\?#$(tc-getCC) #")
103 echo "${cc} ${CFLAGS} ${CPPFLAGS}" > ./conf-cc || die 'Patching conf-cc failed.'
104 echo "${ld} ${LDFLAGS}" > ./conf-ld || die 'Patching conf-ld failed.'
107 # @FUNCTION: qmail_create_groups
109 # Keep qmail groups in sync across ebuilds
110 qmail_create_groups() {
111 einfo "Creating qmail groups"
112 enewgroup nofiles 200
116 # @FUNCTION: qmail_create_users
118 # Keep qmail users in sync across ebuilds
119 qmail_create_users() {
122 einfo "Creating qmail users"
123 enewuser alias 200 -1 "${QMAIL_HOME}"/alias 200
124 enewuser qmaild 201 -1 "${QMAIL_HOME}" 200
125 enewuser qmaill 202 -1 "${QMAIL_HOME}" 200
126 enewuser qmailp 203 -1 "${QMAIL_HOME}" 200
127 enewuser qmailq 204 -1 "${QMAIL_HOME}" 201
128 enewuser qmailr 205 -1 "${QMAIL_HOME}" 201
129 enewuser qmails 206 -1 "${QMAIL_HOME}" 201
132 genqmail_src_unpack() {
134 [[ -n ${GENQMAIL_PV} ]] && unpack "${GENQMAIL_F}"
137 qmail_spp_src_unpack() {
139 [[ -n ${QMAIL_SPP_PV} ]] && unpack "${QMAIL_SPP_F}"
142 # @FUNCTION: qmail_src_postunpack
144 # Unpack common config files, apply custom patches if supplied and
145 # set built configuration (CFLAGS, LDFLAGS, etc)
146 qmail_src_postunpack() {
151 mysplit=${QMAIL_CONF_SPLIT:-23}
152 is_prime ${mysplit} || die "QMAIL_CONF_SPLIT is not a prime number."
153 einfo "Using conf-split value of ${mysplit}."
154 echo -n ${mysplit} > "${S}"/conf-split
157 qmail_src_compile() {
159 emake it man "$@" || die "make failed"
162 qmail_spp_src_compile() {
163 cd "${GENQMAIL_S}"/spp/
164 emake || die "make spp failed"
167 qmail_base_install() {
168 einfo "Setting up basic directory hierarchy"
169 diropts -o root -g qmail -m 755
170 keepdir "${QMAIL_HOME}"/{,bin,control}
172 einfo "Installing basic qmail software"
173 insinto "${QMAIL_HOME}"/bin
175 insopts -o root -g qmail -m 755
176 doins datemail elq forward maildir2mbox maildirmake \
177 maildirwatch mailsubj pinq predate qail \
178 qmail-{inject,qmqpc,showctl} sendmail
180 einfo "Adding env.d entry for qmail"
181 doenvd "${GENQMAIL_S}"/conf/99qmail
183 declare -F qmail_base_install_hook >/dev/null && \
184 qmail_base_install_hook
187 qmail_full_install() {
188 einfo "Setting up full directory hierarchy"
189 keepdir "${QMAIL_HOME}"/users
190 diropts -o alias -g qmail -m 755
191 keepdir "${QMAIL_HOME}"/alias
193 einfo "Installing all qmail software"
194 insopts -o root -g qmail -m 755
195 doins bouncesaying condredirect config-fast except preline qbiff \
196 qmail-{pop3d,qmqpd,qmtpd,qread,qstat,smtpd,tcpok,tcpto} \
197 qreceipt qsmhook tcp-env
199 insopts -o root -g qmail -m 711
200 doins qmail-{clean,getpw,local,popup,pw2u,remote,rspawn,send} splogger
202 insopts -o root -g qmail -m 700
203 doins qmail-{lspawn,newmrh,newu,start}
205 insopts -o qmailq -g qmail -m 4711
208 declare -F qmail_full_install_hook >/dev/null && \
209 qmail_full_install_hook
212 qmail_config_install() {
213 einfo "Installing stock configuration files"
214 insinto "${QMAIL_HOME}"/control
215 insopts -o root -g "$GROUP_ROOT" -m 644
216 doins "${GENQMAIL_S}"/control/{conf-*,defaultdelivery}
218 einfo "Installing configuration sanity checker and launcher"
219 insinto "${QMAIL_HOME}"/bin
220 insopts -o root -g "$GROUP_ROOT" -m 644
221 doins "${GENQMAIL_S}"/control/qmail-config-system
223 declare -F qmail_config_install_hook >/dev/null && \
224 qmail_config_install_hook
227 qmail_man_install() {
228 einfo "Installing manpages and documentation"
230 # those are tagged for section 8 but named for
231 # section 9 (which does not exist anyway)
238 dodoc BLURB* CHANGES FAQ INSTALL* PIC* README* REMOVE* SECURITY \
239 SENDMAIL SYSDEPS TEST* THANKS* THOUGHTS TODO* \
242 declare -F qmail_man_install_hook >/dev/null && \
243 qmail_man_install_hook
246 qmail_sendmail_install() {
247 einfo "Installing sendmail replacement"
249 dodir /usr/sbin /usr/lib
251 dosym "${QMAIL_HOME}"/bin/sendmail /usr/sbin/sendmail
252 dosym "${QMAIL_HOME}"/bin/sendmail /usr/lib/sendmail
254 declare -F qmail_sendmail_install_hook >/dev/null && \
255 qmail_sendmail_install_hook
258 qmail_maildir_install() {
259 # use the correct maildirmake
260 # the courier-imap one has some extensions that are nicer
261 MAILDIRMAKE="${D}${QMAIL_HOME}/bin/maildirmake"
262 [[ -e /usr/bin/maildirmake ]] && \
263 MAILDIRMAKE="/usr/bin/maildirmake"
265 einfo "Setting up the default aliases"
266 diropts -o alias -g qmail -m 700
267 "${MAILDIRMAKE}" "${D}${QMAIL_HOME}"/alias/.maildir
268 keepdir "${QMAIL_HOME}"/alias/.maildir/{cur,new,tmp}
270 for i in "${QMAIL_HOME}"/alias/.qmail-{mailer-daemon,postmaster,root}; do
271 if [[ ! -f "${ROOT}${i}" ]]; then
273 fowners alias:qmail "${i}"
277 einfo "Setting up default maildirs in the account skeleton"
278 diropts -o root -g "$GROUP_ROOT" -m 755
280 insopts -o root -g "$GROUP_ROOT" -m 644
281 newins "${GENQMAIL_S}"/control/defaultdelivery .qmail.sample
282 "${MAILDIRMAKE}" "${D}"/etc/skel/.maildir
283 keepdir /etc/skel/.maildir/{cur,new,tmp}
285 declare -F qmail_maildir_install_hook >/dev/null && \
286 qmail_maildir_install_hook
289 qmail_tcprules_install() {
290 dodir "${TCPRULES_DIR}"
291 insinto "${TCPRULES_DIR}"
292 insopts -o root -g "$GROUP_ROOT" -m 0644
293 doins "${GENQMAIL_S}"/tcprules/Makefile.qmail
294 doins "${GENQMAIL_S}"/tcprules/tcp.qmail-*
295 use ssl || rm -f "${D}${TCPRULES_DIR}"/tcp.qmail-pop3sd
298 qmail_supervise_install() {
299 einfo "Installing supervise scripts"
301 cd "${GENQMAIL_S}"/supervise
303 for i in qmail-{send,smtpd,qmtpd,qmqpd,pop3d}; do
305 diropts -o qmaill -g "$GROUP_ROOT" -m 755
306 keepdir /var/log/qmail/${i}
310 dosupervise qmail-pop3sd
311 diropts -o qmaill -g "$GROUP_ROOT" -m 755
312 keepdir /var/log/qmail/qmail-pop3sd
315 declare -F qmail_supervise_install_hook >/dev/null && \
316 qmail_supervise_install_hook
319 qmail_spp_install() {
320 einfo "Installing qmail-spp configuration files"
321 insinto "${QMAIL_HOME}"/control/
322 insopts -o root -g "$GROUP_ROOT" -m 0644
323 doins "${GENQMAIL_S}"/spp/smtpplugins
325 einfo "Installing qmail-spp plugins"
326 keepdir "${QMAIL_HOME}"/plugins/
327 for i in authlog mfdnscheck ifauthnext tarpit; do
328 dospp "${GENQMAIL_S}"/spp/${i}
331 declare -F qmail_spp_install_hook >/dev/null && \
332 qmail_spp_install_hook
335 qmail_ssl_install() {
336 use gencertdaily && \
337 CRON_FOLDER=cron.daily || \
338 CRON_FOLDER=cron.hourly
340 einfo "Installing SSL Certificate creation script"
341 insinto "${QMAIL_HOME}"/control
342 insopts -o root -g "$GROUP_ROOT" -m 0644
343 doins "${GENQMAIL_S}"/ssl/servercert.cnf
345 insinto "${QMAIL_HOME}"/bin
346 insopts -o root -g "$GROUP_ROOT" -m 0755
347 doins "${GENQMAIL_S}"/ssl/mkservercert
349 einfo "Installing RSA key generation cronjob"
350 insinto /etc/${CRON_FOLDER}
351 insopts -o root -g "$GROUP_ROOT" -m 0755
352 doins "${GENQMAIL_S}"/ssl/qmail-genrsacert.sh
354 keepdir "${QMAIL_HOME}"/control/tlshosts
356 declare -F qmail_ssl_install_hook >/dev/null && \
357 qmail_ssl_install_hook
360 qmail_src_install() {
361 export GROUP_ROOT="$(id -gn root)"
366 qmail_sendmail_install
367 qmail_maildir_install
368 qmail_tcprules_install
369 qmail_supervise_install
371 use qmail-spp && qmail_spp_install
372 use ssl && qmail_ssl_install
375 qmail_queue_setup() {
376 if use highvolume; then
379 myconf="--no-bigtodo"
382 mysplit=${QMAIL_CONF_SPLIT:-23}
383 is_prime ${mysplit} || die "QMAIL_CONF_SPLIT is not a prime number."
385 einfo "Setting up the message queue hierarchy"
386 /usr/bin/queue-repair.py --create ${myconf} \
388 "${ROOT}${QMAIL_HOME}" >/dev/null || \
389 die 'queue-repair failed'
392 qmail_rootmail_fixup() {
393 local TMPCMD="ln -sf ${QMAIL_HOME}/alias/.maildir/ ${ROOT}/root/.maildir"
395 if [[ -d "${ROOT}"/root/.maildir && ! -L "${ROOT}"/root/.maildir ]] ; then
396 elog "Previously the qmail ebuilds created /root/.maildir/ but not"
397 elog "every mail was delivered there. If the directory does not"
398 elog "contain any mail, please delete it and run:"
404 chown -R alias:qmail "${ROOT}${QMAIL_HOME}"/alias/.maildir 2>/dev/null
407 qmail_tcprules_fixup() {
408 mkdir -p "${TCPRULES_DIR}"
409 for f in {smtp,qmtp,qmqp,pop3}{,.cdb}; do
411 new="${TCPRULES_DIR}/tcp.qmail-${f}"
413 if [[ -f "${old}" && ! -f "${new}" ]]; then
414 einfo "Moving ${old} to ${new}"
415 cp "${old}" "${new}" || fail=1
419 if [[ "${fail}" = 1 && -f "${old}" ]]; then
420 eerror "Error moving ${old} to ${new}, be sure to check the"
421 eerror "configuration! You may have already moved the files,"
422 eerror "in which case you can delete ${old}"
427 qmail_tcprules_build() {
428 for f in tcp.qmail-{smtp,qmtp,qmqp,pop3,pop3s}; do
429 # please note that we don't check if it exists
430 # as we want it to make the cdb files anyway!
431 src="${ROOT}${TCPRULES_DIR}/${f}"
432 cdb="${ROOT}${TCPRULES_DIR}/${f}.cdb"
433 tmp="${ROOT}${TCPRULES_DIR}/.${f}.tmp"
434 [[ -e "${src}" ]] && tcprules "${cdb}" "${tmp}" < "${src}"
438 qmail_config_notice() {
440 elog "To setup ${PN} to run out-of-the-box on your system, run:"
441 elog "emerge --config =${CATEGORY}/${PF}"
444 qmail_supervise_config_notice() {
446 elog "To start qmail at boot you have to add svscan to your startup"
447 elog "and create the following links:"
448 elog "ln -s ${SUPERVISE_DIR}/qmail-send /service/qmail-send"
449 elog "ln -s ${SUPERVISE_DIR}/qmail-smtpd /service/qmail-smtpd"
451 elog "To start the pop3 server as well, create the following link:"
452 elog "ln -s ${SUPERVISE_DIR}/qmail-pop3d /service/qmail-pop3d"
455 elog "To start the pop3s server as well, create the following link:"
456 elog "ln -s ${SUPERVISE_DIR}/qmail-pop3sd /service/qmail-pop3sd"
459 elog "Additionally, the QMTP and QMQP protocols are supported, "
460 elog "and can be started as:"
461 elog "ln -s ${SUPERVISE_DIR}/qmail-qmtpd /service/qmail-qmtpd"
462 elog "ln -s ${SUPERVISE_DIR}/qmail-qmqpd /service/qmail-qmqpd"
464 elog "Additionally, if you wish to run qmail right now, you should "
465 elog "run this before anything else:"
466 elog "source /etc/profile"
469 qmail_config_fast() {
470 if [[ ${ROOT} = / ]]; then
471 local host=$(hostname --fqdn)
473 if [[ -z "${host}" ]]; then
475 eerror "Cannot determine your fully-qualified hostname"
476 eerror "Please setup your /etc/hosts as described in"
477 eerror "https://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&chap=8#doc_chap2_sect4"
479 die "cannot determine FQDN"
482 if [[ ! -f "${ROOT}${QMAIL_HOME}"/control/me ]]; then
483 "${ROOT}${QMAIL_HOME}"/bin/config-fast ${host}
486 ewarn "Skipping some configuration as it MUST be run on the final host"
490 qmail_tcprules_config() {
491 local localips ip tcpstring line proto f
493 einfo "Accepting relaying by default from all ips configured on this machine."
495 # Start with iproute2 as ifconfig is deprecated, and ifconfig does not handle
496 # additional addresses added via iproute2.
497 # Note: We have to strip off the packed netmask w/e.g. 192.168.0.2/24
498 localips=$(ip address show 2>/dev/null | awk '$1 == "inet" {print $2}' | sed 's:/.*::')
499 if [[ -z ${localips} ]] ; then
500 # Hello old friend. Maybe you can tell us at least something.
501 localips=$(ifconfig | awk '$1 == "inet" {print $2}')
504 tcpstring=':allow,RELAYCLIENT="",RBLSMTPD=""'
506 for ip in ${localips}; do
507 line="${ip}${tcpstring}"
508 for proto in smtp qmtp qmqp; do
509 f="${EROOT}${TCPRULES_DIR}/tcp.qmail-${proto}"
510 egrep -qs "${line}" "${f}" || echo "${line}" >> "${f}"
515 qmail_ssl_generate() {
516 CRON_FOLDER=cron.hourly
517 use gencertdaily && CRON_FOLDER=cron.daily
519 ebegin "Generating RSA keys for SSL/TLS, this can take some time"
520 "${ROOT}"/etc/${CRON_FOLDER}/qmail-genrsacert.sh
523 einfo "Creating a self-signed ssl-certificate:"
524 "${ROOT}${QMAIL_HOME}"/bin/mkservercert
526 einfo "If you want to have a properly signed certificate "
527 einfo "instead, do the following:"
528 # space at the end of the string because of the current implementation
530 einfo "openssl req -new -nodes -out req.pem \\ "
531 einfo " -config ${QMAIL_HOME}/control/servercert.cnf \\ "
532 einfo " -keyout ${QMAIL_HOME}/control/servercert.pem"
533 einfo "Send req.pem to your CA to obtain signed_req.pem, and do:"
534 einfo "cat signed_req.pem >> ${QMAIL_HOME}/control/servercert.pem"