Настройка DBMail под Mac OS X

Оказалось, что установка DBMail под Mac OS X — задачка не из тривиальных! Пришлось накропать по крайней мере строк пятьдесят всяко-разного кода! В частности, это было связано с тем, что в коде DBMail‘а сброс привилегий до пользователя, указанного в /opt/local/etc/dbmail.conf, производился раньше, чем открывался доступ к shm (Shared Memory) Отсюда и проблемы с невозможностью открыть сокет и разделяемую память при работе под пользователем, отличного от root‘а. Что же до версий 2.0.x и 2.2.x, то их установить оказалось настолько непросто, что и браться за это не стал. Одни жёсткие требования к версии xmlto чего стоили! Короче, читайте, кому интересно.-)


Как пропатчить KDE под FreeBSD? (видимо, вопрос смысла жизни системных администраторов)
Apache Software Foundation

Настройка DBMail под Mac OS X

Предисловие, как всегда

Как это ни странно, но настройка DBMail‘а порой превращается не в саму простую из задач, какую может себе поставить системный администратор. Быть может дело в том, что пока инструментарий установки и настройки DBMail пока не очень совершенен. Не даром, некоторые дистрибутивы Linux, да и Macports пока не включили в свой состав этот довольно часто используемый программный продукт. Он и впрямь удобен: возможность хранить почту в БД, использовать всю мощность языка SQL при сортировке, поиске и фильтрации — это довольно большое достоинство во многих случаях. Особенно, последнее свойство будет удобно при создании какого-нибудь корпоративного интерфейса для почтового обмена.
Однако, определённая скудность документации и определённый ряд неудобств, возникащих при установке и настройке DBMail часто отвращают администраторов от попытки его использования. Особенно неприятная картина возникает под Mac OS X:
Во-первых, версии, младше 2.3.x вообще ставиться под этой операционкой не хотят, находя тому массу отговорок и неувязок.
Во-вторых, невозможно уговорить инсталлятор (./configure) устанавливать исполняемые файлы, куда-нибудь, кроме /bin или /sbin. Про /opt/local/bin или /opt/local/sbin мы и слышать не хотим. Даже несмотря на тщательнейшим образом втыкаемые аргументы, типа —prefix=/opt/local/, —exec-prefix=/opt/local и так далее. Вполне вменяемо «подхватываются» аргументы —with-logdir=${LOGDIR}, —sysconfdir=${SYSCONFDIR}, а с префиксом дела плохи. Куда бинарники влепили, туда влепили, как паспорт — на вечную носку. Куда-там, системная безопасность…
Представляю себе, до какой степени должны раздражать делателей портов, портежей, пакаджей, инсталляционных пакетов (и т.д.) такие вот мелкие «неувязочки». Даром ли, видел на каком-то сайте предложение приобрести соответствующий порт за $10. Это, конечно, не дорого, но покупать что-то для открытого ПО… не спортивно! Хотя, признаюсь… соблазн сэкономить время был. Увы мне — десять долларов в наличии были, но ссылка никуда не вела. Порт оказался «дутым»! Значит, придётся всё делать ручками, ручками…
Думаю, версии ниже 2.3 отметаются, как неприличные. Во-первых, в 2.3.x «прикрепы» (аттачи) хранятся отдельно. Во-вторых, судя по отдельным отзывам, с MySQL эта ветка работает лучше и стабильнее. В-третьих (ох уж мне это «в-третьих»!) — ветви 2.0.x и 2.2.x для своей установки, скажем требуют совершенно определённой версии xmlto и asciidoc. Сие, милостивые государи, ужасно и для моей (несоменно нежной) админской души, соершенно непереносимо!

Шаг за шагом…

…перед сборкой обработать напильником © народная инструкция
Итак, дабы не ввергнуться в искушение диавольское и несомненно, посрамить нечистого, следует избегая беззрассудной траты вечности, начать с ветви 2.3.x (на сей день доступна последняя версия этой ветви dbmail-2.3.1.tar.gz). Для начала просмотрим что и как здесь можно настраивать (листинг ./configure —help):
`configure' configures dbmail dbmail@dbmail.org to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR           user executables [EPREFIX/bin]
  --sbindir=DIR          system admin executables [EPREFIX/sbin]
  --libexecdir=DIR       program executables [EPREFIX/libexec]
  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
  --libdir=DIR           object code libraries [EPREFIX/lib]
  --includedir=DIR       C header files [PREFIX/include]
  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR          info documentation [DATAROOTDIR/info]
  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR           man documentation [DATAROOTDIR/man]
  --docdir=DIR           documentation root [DATAROOTDIR/doc/dbmail]
  --htmldir=DIR          html documentation [DOCDIR]
  --dvidir=DIR           dvi documentation [DOCDIR]
  --pdfdir=DIR           pdf documentation [DOCDIR]
  --psdir=DIR            ps documentation [DOCDIR]

Program names:
  --program-prefix=PREFIX            prepend PREFIX to installed program names
  --program-suffix=SUFFIX            append SUFFIX to installed program names
  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]

Optional Features:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-maintainer-mode  enable make rules and dependencies not useful
                          (and sometimes confusing) to the casual installer
  --enable-shared[=PKGS]  build shared libraries [default=no]
  --enable-static[=PKGS]  build static libraries [default=no]
  --disable-dependency-tracking  speeds up one-time build
  --enable-dependency-tracking   do not reject slow dependency extractors
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-logdir           use logdir for logfiles
  --with-mysql            use MySQL as database.
                Uses mysql_config for finding includes and libraries
  --with-pgsql            use PostgreSQL as database.
                Uses pg_config for finding includes and libraries
  --with-sqlite           use SQLite3 as database.
            Uses pkg-config for finding includes and libraries
  --with-ingres           use Ingres as database.
            Specify the II_SYSTEM location
  --with-ldap=PATH        path to LDAP base directory (e.g. /usr/local or /usr)
  --with-sieve=PATH       path to libSieve base directory (e.g. /usr/local or /usr)
  --with-gc=PREFIX        libgc PREFIX
  --with-check=PATH       prefix where check is installed default=auto
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
  --with-pic              try to use only PIC/non-PIC objects [default=use
                          both]
  --with-tags[=TAGS]      include additional configurations [automatic]

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  CXX         C++ compiler command
  CXXFLAGS    C++ compiler flags
  CXXCPP      C++ preprocessor
  F77         Fortran 77 compiler command
  FFLAGS      Fortran 77 compiler flags

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Надо сказать, что со всеми тремя заявленными БД-серверами (С сервером БД Ingres пока так и не познакомился) работает вполне нормально. Этот факт я проверил бегло, наскоро, но в сети отрицательных отзывов не нашёл. Да и с драйверами MySQL, PostgreSQL, SQLite, всё прекрасно собралось и с серверами вменяемо общалось (да да, вот именно: жадность — не порок, а мутировавшая запасливость)
Ну и ещё одна дань жадности — —with-sieve=/opt/local. В конце-концов — это шанс изучить язык фильтрации e-mail-сообщений sieve… правда, обойдётся это в дополнительную строчку в командной строке: sudo port install libsieve. Ну и ещё придётся нам поставить xmlto + asciidoc, чтобы документация по проекту собралась. Процедура та же: sudo port install ….
Итак, предварительно распаковав файлы в директорию, создал себе следующий инициализирующий скрипт:
#!/bin/sh
#
PREFIX=/opt/local
PREFIX=/opt/local/bin
LOGDIR=/var/log
LOCALSTATEDIR=/opt/local/var/run
SYSCONFDIR=/opt/local/etc
DATAROOTDIR=/opt/local/lib/
PATH=${PATH}:/opt/local/lib/mysql5/bin/:/opt/local/lib/postgresql83/bin/
./configure 
--datarootdir=${DATAROOTDIR} 
--localstatedir=${LOCALSTATEDIR} 
--sysconfdir=${SYSCONFDIR} 
--prefix=${PREFIX} 
--exec-prefix=${EPREFIX} 
--with-logdir=${LOGDIR} 
--with-mysql 
--with-pgsql 
--with-sqlite 
--with-ldap 
--enable-shared 
--with-sieve=/opt/local
Итак, запустим этот конфигурационный скрипт:
./myinstall.sh 

This is 's GNU configure script.

checking for a BSD-compatible install... /opt/local/bin/ginstall -c
checking whether build environment is sane... yeschecking for gawk... gawk
checking whether make sets $(MAKE)... yeschecking whether to enable maintainer-specific portions of Makefiles... nochecking for mysql_config... /opt/local/lib/mysql5/bin//mysql_config
checking MySQL headers... -I/opt/local/include/mysql5/mysql
checking MySQL libraries... -L/opt/local/lib -L/opt/local/lib/mysql5/mysql -lmysqlclient -L/opt/local/lib -lz -lm  -L/opt/local/lib -lssl -lcrypto
checking for pg_config... /opt/local/lib/postgresql83/bin//pg_config
checking PostgreSQL headers... -I/opt/local/include/postgresql83
checking PostgreSQL libraries... -L/opt/local/lib/postgresql83 -lpq
checking for pkg-config... /opt/local/bin/pkg-config
checking SQLite3 headers... -I/opt/local/include  
checking SQLite libraries... -L/opt/local/lib -lsqlite3 -lpthread  
checking for style of include used by make... GNU
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yeschecking whether we are cross compiling... nochecking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yeschecking whether gcc accepts -g... yeschecking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for LDAP headers... 
checking for LDAP libraries... -lldap
checking for library containing ldap_initialize... -lldap
checking for libSieve headers... -I/opt/local/include
checking for libSieve libraries... -L/opt/local/lib -lsieve
checking for pkg-config... /opt/local/bin/pkg-config
checking GLib headers... -I/opt/local/include/glib-2.0 -I/opt/local/lib/glib-2.0/include -I/opt/local/include  
checking Glib libraries... -L/opt/local/lib -lglib-2.0 -lintl -liconv  
checking for pkg-config... /opt/local/bin/pkg-config
checking GMime headers... -I/opt/local/include/gmime-2.0 -I/opt/local/include/glib-2.0 -I/opt/local/lib/glib-2.0/include -I/opt/local/include  
checking GMime libraries... -L/opt/local/lib -lgmime-2.0 -lz -lgobject-2.0 -lglib-2.0 -lintl -liconv  
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yeschecking for sys/types.h... yeschecking for sys/stat.h... yeschecking for stdlib.h... yeschecking for string.h... yeschecking for memory.h... yeschecking for strings.h... yeschecking for inttypes.h... yeschecking for stdint.h... yeschecking for unistd.h... yeschecking for --with-gc... nochecking getopt.h usability... yeschecking getopt.h presence... yeschecking for getopt.h... yeschecking for getopt_long_only... yeschecking whether optreset is declared... yeschecking for connect... yeschecking for res_search... yeschecking for dn_expand... yeschecking for dns_lookup... nochecking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yeschecking whether gcc accepts -g... (cached) yeschecking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking maximum warning verbosity option...  -W -Wall -Wpointer-arith -Wstrict-prototypes for C
checking for an ANSI C-conforming const... yeschecking for inline... inline
checking whether byte ordering is bigendian... nochecking endian.h usability... nochecking endian.h presence... nochecking for endian.h... nochecking crypt.h usability... nochecking crypt.h presence... nochecking for crypt.h... nochecking for crypt in -lcrypt... nochecking build system type... i386-apple-darwin8.11.1
checking host system type... i386-apple-darwin8.11.1
checking for a sed that does not truncate output... /usr/bin/sed
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... nochecking for /usr/bin/ld option to reload object files... -r
checking for BSD-compatible nm... /usr/bin/nm -p
checking whether ln -s works... yeschecking how to recognise dependent libraries... pass_all
checking dlfcn.h usability... yeschecking dlfcn.h presence... yeschecking for dlfcn.h... yeschecking for g++... g++
checking whether we are using the GNU C++ compiler... yeschecking whether g++ accepts -g... yeschecking dependency style of g++... gcc3
checking how to run the C++ preprocessor... g++ -E
checking for g77... nochecking for xlf... nochecking for f77... nochecking for frt... nochecking for pgf77... nochecking for cf77... nochecking for fort77... nochecking for fl32... nochecking for af77... nochecking for xlf90... nochecking for f90... nochecking for pgf90... nochecking for pghpf... nochecking for epcf90... nochecking for gfortran... nochecking for g95... nochecking for xlf95... nochecking for f95... nochecking for fort... nochecking for ifort... nochecking for ifc... nochecking for efc... nochecking for pgf95... nochecking for lf95... nochecking for ftn... nochecking whether we are using the GNU Fortran 77 compiler... nochecking whether  accepts -g... nochecking the maximum length of command line arguments... 196608
checking command to parse /usr/bin/nm -p output from gcc object... ok
checking for objdir... .libs
checking for ar... ar
checking for ranlib... ranlib
checking for strip... strip
checking if gcc supports -fno-rtti -fno-exceptions... nochecking for gcc option to produce PIC... -fno-common
checking if gcc PIC flag -fno-common works... yeschecking if gcc static flag -static works... nochecking if gcc supports -c -o file.o... yeschecking whether the gcc linker (/usr/bin/ld) supports shared libraries... yeschecking dynamic linker characteristics... darwin8.11.1 dyld
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yeschecking if libtool supports shared libraries... yeschecking whether to build shared libraries... yeschecking whether to build static libraries... noconfigure: creating libtool
appending configuration tag "CXX" to libtool
checking for ld used by g++... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... nochecking whether the g++ linker (/usr/bin/ld) supports shared libraries... yeschecking for g++ option to produce PIC... -fno-common
checking if g++ PIC flag -fno-common works... yeschecking if g++ static flag -static works... nochecking if g++ supports -c -o file.o... yeschecking whether the g++ linker (/usr/bin/ld) supports shared libraries... yeschecking dynamic linker characteristics... darwin8.11.1 dyld
checking how to hardcode library paths into programs... immediate
appending configuration tag "F77" to libtool
configure: creating ./config.status
config.status: creating src/.h
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating src/modules/Makefile
config.status: creating man/Makefile
config.status: creating test/Makefile
config.status: creating config.h
config.status: executing depfiles commands


 DM_LOGDIR:                 /var/log
 DM_CONFDIR:                /opt/local/etc
 DM_STATEDIR:               /opt/local/var/run
 USE_DM_GETOPT:             1
 CFLAGS:                    -g -O2 -I/opt/local/include/glib-2.0 -I/opt/local/lib/glib-2.0/include -I/opt/local/include   -I/opt/local/include/gmime-2.0 -I/opt/local/include/glib-2.0 -I/opt/local/lib/glib-2.0/include -I/opt/local/include   -W -Wall -Wpointer-arith -Wstrict-prototypes
 GLIB:                      -L/opt/local/lib -lglib-2.0 -lintl -liconv  
 GMIME:                     -L/opt/local/lib -lgmime-2.0 -lz -lgobject-2.0 -lglib-2.0 -lintl -liconv  
 MYSQL:                     -L/opt/local/lib -L/opt/local/lib/mysql5/mysql -lmysqlclient -L/opt/local/lib -lz -lm  -L/opt/local/lib -lssl -lcrypto
 PGSQL:                     -L/opt/local/lib/postgresql83 -lpq
 SQLITE:                    -L/opt/local/lib -lsqlite3 -lpthread  
 INGRES:                    
 SIEVE:                     -I/opt/local/include-L/opt/local/lib -lsieve
 LDAP:                      -lldap
 SHARED:                    yesSTATIC:                    noCHECK:                     noSOCKETS:                   
Здесь настораживает одна вещь: поле SOCKET — пустое. Впрочем, далее по тексту, читатель узнает, что здесь-то и обнаружится одна маленькая проблемка.
Unix live free or die!
BSD
FreeBSD
Также, позже выяснилось, —prefix и —exec-prefix силы никакой не возымели. Увы… —sysconfigdir — прекрасно отработала. Так, что после инсталляции царит полный, с позволения сказать, раскардаш: исполняемые файлы (-export, -lmtpd, -sievecmd, -timsieved, -users, -imapd, -pop3d, -smtp, -top, -util) обитают в /sbin, а все настройки и библиотеки, в /opt/local/[etc/][lib/] (где им, с точки зрения номарльного BSD-шника и положено обитать).
Однако, попытка собрать дистрибутив командой вроде sudo make install потерпит почти наверняка полный провал:
server.c: In function 'create_unix_socket':
server.c:417: error: 'AF_LOCAL' undeclared (first use in this function)
server.c:417: error: (Each undeclared identifier is reported only once
server.c:417: error: for each function it appears in.)
server.c: In function 'create_inet_socket':
server.c:461: warning: implicit declaration of function 'inet_aton'
make[3]: *** [lib_la-server.lo] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
Что уж руководило «аффтарами» при использовании AF_LOCAL даже и не знаю. Быть может, приверженность, к заветам бессмертного Уильяма Стевенса? Не иначе… дело, однако, более, чем поправимое: надо прописать в начале файла <_src_dir>/src/server.c (всего-то!) #define AF_LOCAL AF_UNIX Что характерно, рецепт, предложенный авторами DBMail, в данной ситуации не помог, хотя в /usr/include/sys/socket.h написано следующее:
#ifndef _POSIX_C_SOURCE
#define AF_LOCAL        AF_UNIX         /* backward compatibility */
#endif  /* !_POSIX_C_SOURCE */
Итак, sudo make install. (Не знаю, как Вас, почтеннейшие граждане Публика, а последняя пара предупреждений меня малость покоробила:
OpenBSD
NetBSD
Linux
KDE
serverpool.c:365: warning: passing argument 1 of 'strncpy' discards qualifiers from pointer target type
serverpool.c:367: warning: passing argument 1 of 'strncpy' discards qualifiers from pointer target type
— надо будет на досуге с ними разобраться)
После радующей душу команды make install, так и тянет кинуть пальцы на клавиатуру и бойко отстучать: sudo dbmail-imap (нет, ну чем демоны (и прочие покровители unix‘a) не шутят, а вдруг запустится?!) Ну может получится, а может и нет. Можно словить и такую странную ошибку, связанную с невозможностью доступа к разделяемой памяти. На это великий Paul J. Stevens справедливо отмечает, что нефиг запускать процесс из под суперпользователя. (Уж не родственник ли… ну того, великого и неповторимого?) Чтож замечание вполне справедливое. Ещё замечу, что установочный скрипт нифига нужных директорий не создал:
/opt/local/var/run/dbmail
/var/log/dbmail
отсутствуют как класс! Значит, mkdir /opt/local/var/run/dbmail && mkdir /var/log/dbmail и chown …… стоп, а кому chown, собственно? Непонятно! Придётся добавить пользователя и группу dbmail:dbmail, а то… небезопасно как-то. Да.
Вот тут-то и подстерегает нас безапеляционная подкрадуха в лице утилиты dscl (видела я, знаете ли котов без улыбок, но улыбка без кота… © Льюис Кэрол) Мануал по этой утилите не то, чтобы невнятен, он просто не для простых людей писан. Даже не для админов (видимо, сказываются издержки коммерциализации UniX, а может я такой малосообразительный…) Посему, настоятельно рекомендую почитать статью «Open Directory and the dscl Tool» с сайта developer.apple.com, або «Command Line, Make Mac Work»
Неплохо бы сразу соорудить скриптик для сооружения uid и gid. Обратите внимание на то, что PrimaryGroupID Вы, почтеннейшие граждане Публика, создаёте сами! И он должен присутствовать, как в uid, так и в gid, иначе группа при переназначении пользователя демона в момента запуска, не будет найдена!
#!/bin/sh
# (© yevstigneyevda@mail.ru)
# PrimaryGroupID выбран, честно сказать от "балды". Ну, скажем,
# у PostgreSQL -- 503, а у нас будет 703.
PrimaryGroupID=703

dscl / -delete /Users/dbmail
dscl / -delete /Groups/dbmail

dscl / -create /Groups/dbmail PrimaryGroupID 703
dscl / -append /Groups/dbmail RealName dbmail
dscl / -create /Users/dbmail UniqueID 703
dscl / -append /Users/dbmail PrimaryGroupID 703
dscl / -append /Users/dbmail RealName dbmail

dscl / -read /Users/dbmail
dscl / -read /Groups/dbmail
Почти порядок. Осталось сообразить конфигурационный файл и инициировать базы данных, как это указанно в штатной инструкции к настоящему приложению:
# mysqladmin5 create dbmail -u root -p
# mysql -u root -p
$ GRANT ALL ON dbmail.* to dbmail@localhost identified by '<pass>';
$ exit
SendMail
Exim
Postfix
Почтеннейшие граждане Публика, обратите внимание на вот это mysqladmin5 — это, если угодно, одна из «национальных» особенностей MacPorts. Впрочем, не так уж это и страшно. Просто руки не сразу привыкают после привычного mysql, набирать mysql5. Ну да ничего, ко-всему привыкнуть можно… однако, кажется я отвлёкся.
Теперь мы торжественно подхватываем штатные таблицы из дистрибутива (они обитают в <dbmail_src_dir>/sql/mysql/… (или что Вы там у себя поставили?)
# mysql -u root -p dbmail <dbmail_src_dir>/sql/mysql/create_tables.mysql

И всё-таки оно настраивается!

16:00. Война с Англией. © распорядок дня Б. Мюнхгаузена.
Думаете всё, да? О нет, веселье только началось: теперь начнём разборки с dbmail.conf. Согласно заданным параметрам, обитать он должен в /opt/local/etc/dbmail.conf.
Fetchmail
# sudo cp <dbmail_src_dir>/dbmail.conf /opt/local/etc/
# sudo vim /opt/local/etc/dbmail.conf
(ну или какой-там редактор Вы предпочитаете в это время суток?)
GNU
GTK
# (c) 2000-2006 IC&S, The Netherlands 
# (сурдоперевод - © yevstigneyevda@mail.ru)
# Конфигурационный файл DBMAIL 

[DBMAIL] 
# 
# Настройки БД
#

# 
# Общий драйвер БД. Поддерживаемые драйвера: mysql, pgsql, sqlite.
#
driver               = mysql

# 
# Драйвера БД авторизации. Поддерживаемые драйвера sql, ldap.
#
authdriver           = sql

# Хост БД. Установите localhost, если сервер БД находится
# на том же компьютере, что и dbmail и вы хотите использовать
# сокет для подлючения
#
host                 = localhost          

# Если вы хотите использовать TCP/IP для подключения к БД,
# и ваш Сервер БД отвечает по нестандартному порту (стандартный
# порт MySQL -- 3306, PostgreSQL -- 5432, SQLite... SQLite, вообще
# не сервер, а процесс, взаимодейстующий непосредствено с клиентом
# и порта ему не положено.
#
sqlport              = 3306  

#
# эта настройка, когда подключение к серверу БД локальное,
# через файл сокета. Например, /var/run/mysql.sock и т.д.
#
sqlsocket            = /opt/local/var/run/mysql5/mysqld.sock       

# 
# логин пользователя БД.
#
user                 = dbmail

# 
# пароль пользователя БД.
#
pass                 = MyPassword

# 
# название БД.
#
db                   = dbmail

# 
# Префиксы таблиц БД. По умолчанию префикс dbmail_ не определён!
#
table_prefix         = dbmail_   

#
# кодировка должна соответствовать кодировке БД/таблицы
#
encoding             = utf8

#
# что делать с сообщениями с неизвестной кодировкой, если таковые
# встретятся. Т.е. определить кодировку по умолчанию, как iso8859-1 или utf-8...
#
default_msg_encoding = utf8

#
# почтовый адрес постмастера -- для перенаправления отброшенных
# сообщений.
#
#
#postmaster           = DBMAIL-MAILER       

# 
# Sendmail executable for forwards, replies, notifies, vacations.
# You may use pipes (|) in this command, for example:
# dos2unix|/usr/sbin/sendmail  works well with Qmail.
# You may use quotes (") for executables with unusual names.
#
# местонахождение исполняемого файла для перенаправления, ответов,
# уведомлений, реализации механизма «отпускных сообщений» (т.е. на сообщение приходит ответ «уехал, вернусь не скоро, приеду — отвечу — »<a href="http://wiki.cs.huji.ac.il/wiki/Mail_Vacation_Messages" class="out" target="_blank">Mail Vacation Mechanizm</a>) и т.д.
# Вы можете использовать pipe (|) в команде, например:
# dos2unix|/usr/sbin/sendmail (при работе с <a href="http://www.qmail.org" class="out" target="_blank">QMail</a>
#
sendmail              = /usr/sbin/sendmail     

#
#
# Слеующие строки позволяют переопределить service-specific разделы 
#

#
# Отладочный режим ( тот самый загадочный «debug level», возникающий
# при какой-нибудь неопределимой ошибке) По умолчанию стоит 2 -- (сообщения, ошибки
# фатальные ошибки)
#
TRACE_SYSLOG          = 3

#
# Уровень трассировки перенаправялемый в stderr. По умолчанию - 0
# (только фатальные ошибки)
#
TRACE_STDERR          = 1          

# 
# root-права используются для открытия порта, затем
# они сбрасываются до определённых ниже пользователя/группы
#
# 
#
#
EFFECTIVE_USER        = dbmail
EFFECTIVE_GROUP       = dbmail

# 
# IP-адрес сервиса, с которым надо связыаться.
# Используйте * для определения всех локальных интерфейсов.
# Используйте 127.0.0.1 для того, чтобы определить только localhost
# Множественные значения разделяйте пробелами ( ) или запятыми (,)
#
BINDIP                = *               

# 
# номер запускаемого дочернего процесса по умолчанию
#
NCHILDREN             = 2             

# 
# Максимально допустимое число дочерних процессов
#
MAXCHILDREN           = 10          

# 
# Число всегда доступных неиспользованных процессов
#
MINSPARECHILDREN      = 2      

# 
# Максимальное число неиспользованных активных дочерних процессов
#
MAXSPARECHILDREN      = 4      

# 
# Дочерний процесс будет перезапущен после обработки данного количества подключений
#
MAXCONNECTS           = 10000       

# 
# Дочерний процесс будет перезапущен после данного количества ошибочных подключений
#
MAX_ERRORS            = 500          

# 
# Допустимое время ожидания после выключения подключения
#
TIMEOUT               = 300             

# 
# Допустимое время ожидания после того как подключение будет выключено, если вы всё ещё залогинились
#
login_timeout         = 60

# 
# Если "да", то разрешает IP-адрес в DNS-имя при залогинивании
#
RESOLVE_IP            = no
# Файл журнала для stdout-сообщений
#
logfile               = /var/log/dbmail/dbmail.log

# 
# файл журнала для stderr-сообщений
#
errorlog              = /var/log/dbmail/dbmail.err

# 
# директория для сохранения PID (Process ID) файлов
#
pid_directory         = /opt/local/var/run/dbmail

#
# папка для сохранения файлов состояний демонов
#
state_directory       = /opt/local/var/run/dbmail

#
# место, где сохранены библиотеки (лучше будет их прикомпилировать статически)
#
library_directory       = /opt/local/lib/dbmail

[SMTP]
# Фактически, здесь по умолчанию ничего нет...
                        

[LMTP]
# 
# Порт привязки
#
PORT                  = 24                 

[POP]
# 
# Порт привязки
#
PORT                  = 110                

# 
# Если да, то SMTP разрешён доступ с указанных IP подключающихся по POP3
# Эта опция необходима для расширения возможностей конфигурирования ваших MTA
# (Mail Transfer Agent)
#
POP_BEFORE_SMTP       = no[IMAP]

# 
# Соответственно, порт привязки
#
PORT                  = 143                

# 
# Для нормальной работы IMAP предпочтительно выделить таймаут побольше, чем для остальных сервисов
#
TIMEOUT               = 4000            

# 
# 
# Если этот параметр определён, как "yes", то будет разрешёт SMTP доступ
# со стороны IP адресов, подключающихся по IMAP.
# Эта настройка необходима для дополнительных настроек MTA.
#
IMAP_BEFORE_SMTP      = no
# период ожидания в секундах при проверке почтового ящика (по умолчанию -- 30 секунд)
# 
# idle_timeout          = 30

#
# Поддержка возможности переопределить значения по умолчанию
#
# capability 		= IMAP4 IMAP4rev1 AUTH=LOGIN ACL NAMESPACE CHILDREN SORT QUOTA THREAD=ORDEREDSUBJECT UNSELECT IDLE

#
# Посылать статус отправки почтового ящика '*.STATUS' (MESSAGES x RECENT x UNSEEN x NEXTUID x)
# для всех отправляемых сообщений в течение времени ожидания (по умолчанию - 'no')
# ЗАМЕЧАНИЕ: эта настройка экспериментальная
# 
# idle_status           = yes[SIEVE]
# 
# Порт привязки
#
PORT                  = 2000               

[LDAP]
PORT                  = 389
VERSION               = 3
HOSTNAME              = ldap
BASE_DN               = ou=People,dc=mydomain,dc=com

# 
# Если вы включили поддержку библиотеки LDAP (ldap_initialize()) вы можете 
# использовать альтернативный LDAP-сервер, примерно таким способом:
#
# URI                = ldap://127.0.0.1:389
# URI                = ldapi://%2fvar%2frun%2fopenldap%2fldapi/

# 

# Оставьте это поле пустым, если хотите сделать привязку анонимной
# или можете заполнить это поле так: cn=admin, dc=mydomain, dc=com
# 
BIND_DN               = 

# 
# Оставьте эти поля пустыми, если хотите сделать привязку анонимной
#
BIND_PW               = 
SCOPE                 = SubTree
USER_OBJECTCLASS      = top,account,dbmailUser
FORW_OBJECTCLASS      = top,account,dbmailForwardingAddress
CN_STRING             = uid
FIELD_PASSWD          = userPassword
FIELD_UID             = uid
FIELD_NID             = uidNumber
MIN_NID               = 10000
MAX_NID               = 15000
FIELD_CID             = gidNumber
MIN_CID               = 10000
MAX_CID               = 15000
FIELD_MAIL            = mail
FIELD_QUOTA           = mailQuota
FIELD_FWDTARGET       = mailForwardingAddress

[DELIVERY]
# 
# Запуск Sieve-скриптов при получении сообщения
# 
SIEVE                 = yes
# Если используем формат 'user+mailbox@domain' для отправки в почтовый ящик
#
SUBADDRESS            = yes
# Включить или выключить отпускное Sieve-расширение (Sieve Vacation extension)
#
SIEVE_VACATION        = yes
# Вклюить или выключить Sieve-расширение уведомление
#
SIEVE_NOTIFY          = yes
# Включить или выключить дополнительную отладку Sieve-скриптов
#
SIEVE_DEBUG           = no
# Использовать таблицу автоуведомлений для отправки почтовых уведомлений
#
AUTO_NOTIFY           = no
# Использовать таблицу автоответов для дальнейшей переправки сообщений
#
AUTO_REPLY            = no
# По умолчанию "NEW MAIL NOTIFICATION"
#
#AUTO_NOTIFY_SUBJECT        =    

# 
# По умолчанию отправить POSTMASTER'у из раздела DBMAIL
#
#AUTO_NOTIFY_SENDER        =   

# 
# Если вы установите значение 'yes', dbmail будет проверять
# дублированные сообщения в соответствующих почтовых ящиках
# в течение отправки сообщения. Проверка осуществляется по
# Message ID Header.
#
suppress_duplicates	= noend of configuration file

Думаю, особое внимание здесь надо обратить на расположение mysqld.sock/opt/local/var/run/mysql5/mysqld.sock. Остальное, вполне тривиально.
Вообще говоря, ещё до попыток запуска демона dbmail-imapd, надо было бы подумать об установке базы данных. У меня стоит MySQL, чего и Вам, почтеннейшие граждане Публика, желаю. Посему и идём в директорию <DBMail-2.3.1_src>/sql/mysql, берём файл create_tables.mysql и «напускаем» на него mysql5:
$ mysqladmin5 create dbmail
$ mysql5 dbmail < [DBMail-2.3.1_src]/sql/mysql/create_tables.mysql
Про Mac OS X‘овскую «пятёрочку» (ну или «четвёрочку», неожиданно возникающую после имени команд, наинающихся на mysql) не забыли? Хорошо. Кстати, не забудьте, что если сервер «живёт» на другом хосте или доступ за семью паролями, то надо модифицировать вызовы комманд до mysql<…>5 —user <user> —host -p. Во-избежание.
Ingres - Busines Open Source
MacPorts
Теперь можно честно подумать о добавлении пользователей системы:
$ dbmail-users -a admin@localhost -p
$ dbmail-users -c admin@localhost -g 1
(вторая команда делает пользователя admin@localhost — суперпользователем)
Как это пишется порой в мелодраматических романах, хотел бы я сказать, что история эта продолжится хорошо, но увы. Добавлять пользователей, несомненно было бы удобнее при помощи NetVulture Cunsulting (NVC) Toolbox. Ну, там надо (будте бдительны!) было скачать два архива: собственно, сам ToolBox и nvc — модуль для работы с БД. Но, увы, для DBMail-2.3.1 эти пакеты не подходят. Так, что командная строка и утилита dbmail-user, почтеннейшие граждане Публика, вам в помощь.

От сохи и от root’а

Держивал ли ты соху? умеешь ли пахать? © В. И. Даль. «Толковый словарь живого великорусского языка»
А теперь о грустном. В нашем с Вами случае мы вынуждены писать user=root, group=wheel. Нарушение безопасности — вопиющее. Однако, почти без вариантов: попытайся мы запустить всё своё хозяйство из под пользователя dbmail, сразу получим ответ:
Dec 28 16:03:51 denis-yevstigney dbmail-imapd[389]: FATAL:[server] server.c,create_inet_socket(+470): Fatal error, could not bind to [*:143] Permission denied
Очевидно, что пользователю dbmail просто недостаточно прав для «бинденья» (связывания) сокета.
QMail
MySQL
PostgreSQL
Если же мы запустим, скажем dbmail-imapd из под «root», то получим сообщение другого рода:
Dec 28 22:45:16 denis-yevstigney dbmail-imapd[16561]: FATAL:[server] serverpool.c, scoreboard_new(+92): shmget failed [nospace left on device]
На самом деле, сообщение крайне неприятное, потому что увеличение объёма shm (Shared Memory — Разделяемой Памяти) может неприятным образом сказаться на производительности системы. Неприятным и почти мистическим, потому что, скажем, 120 мегабайт вряд-ли сделают погоду при восьми гигабайтах оперативной памяти.
Итак, нарастить разделяемую память несложно (почти также, как и во FreeBSD):
$sudo /Applications/vim70/gvim /etc/rc
(ну или кто у Вас там ходит в любимых редакторах? Во всяком случае, редактировать надо именно /etc/rc — другие файлы просто не дадут желаемого эффекта.)
Apple (Mac OS X)
Open Solaris
Ищем строчки, связанные с shm и изменяем значения на примерно такие: sysctl -w kern.sysv.shmmax=167772160 kern.sysv.shmmin=1 kern.sysv.shmmni=64 kern.sysv .shmseg=16 kern.sysv.shmall=65536. Теперь можно перезагрузиться: всё равно изменения, даже если мы их передадим напрямую из командной строки эффекта без перезагрузки иметь не будут. Ведь это же параметры, передаваемые ядру Mac OS X при загрузке.
После перезагрузки можем проверить, изменились ли параметры системы, связанные с shm:
$ sudo sysctl -a | grep shm
Password:
kern.exec: unknown type returned
kern.sysv.shmmax: 167772160
kern.sysv.shmmin: 1
kern.sysv.shmmni: 64
kern.sysv.shmseg: 16
kern.sysv.shmall: 65536
Есть! Ура! Сработало! (Кстати, эти параметры будут полезными и для работы PostgreSQL–сервера. Ведь он тоже использует разделяемую память для связи между процессами!) Подробнее о любимой всеми FreeBSD-шниками команде sysctl

и настройках shm, можете посмотреть в статье «Shared Memory Configuration», ну и, конечно же в любимом народе man sysctl.

Ещё раз попытаемся запустить sudo /sbin/dbmail-imapd -v и…
Dec 28 10:41:42 denis-yevstigney dbmail-imapd[416]: FATAL:[server] serverpool.c,scoreboard_new(+98): scoreboard init failed [Permission denied]
Слушайте, а Вы точно поменяли пользователя в конфигурационном файле на root‘a? А группу на wheel‘a? Точно ну-ну…
Есть, заработало (если, конечно, добавлены пользователи, как это описано ниже)

Космический крейсер своими руками? Это просто!

Да просыпется файловая система Windows™ на головы программистов Linux, не учивших стандарты ©Мегахакерское проклятие.
Но, вообще-то говоря, «заработало» — это с бааальшой натяжкой. Во-первых, как говорится, «от root‘a» (почти что «от винта!»), а во-вторых, с использованием shm, применение которой в Mac OS X, категорически не рекомендовано. О чём весьма убедительно сообщается в Technical Note TN2071. Там настоятельно рекомендуется использовать вместо getshm(), mmap(). В коде DBMail разделяемый ресурс используется именно, как место хранения структуры Scoreboard_t. Это неудобно, так как mmap() отображает в память файлы.
Во-вторых, использование как getshm(), так и mmap()с точки зрения безопасности весьма «червиво последствиями». В принципе, лучше, но сложнее всего использовать многопоточную модель для программирования связи между отдельными процессами (вот хорошо бы мост построить да мужиков бы на нём с семечками поставить) Хорошо, конечно Apache: у него какую хочешь модель включаешь — хоть IPC во всех его прелестях, хоть мультипоточность.
О многопоточной модели Mac OS X подробно можно почитать в статьях Carbon Multiprocess Service, «Multithreaded Cocoa Programs», «Porting Multithreaded Application from win32 to Mac OS X». Понятно, что Posix Threads Library (pthread) будет как-то более переносимой… (читать «PTHREADs Programming Guide».) Ооох… опять меня в дебри понесло. Как-минимум, было бы не плохо. А ещё Macport соответствующий сделать. Ну да ладно, раскатал губень…
В третьих, есть догадка, что DBMail переключается на пользователя, указанного в конфигурационном файле до того, как открывает сокет и отводит место в разделяемой памяти (В отличие, скажем, от PostgreSQL.) Отсюда и проблемы. Надо бы этот момент разъяснить будет. Во-всяком случае, все беды (в DBMail v 2.3.1) происходят в файле <DBMail-2.3.1_src>/src/serverpool.c, в группе функций scoreboard_/new/lock_get/lock_new/setup…. А «срыв кода» происходит непосредственно в ф-ии scoreboard_new:
void scoreboard_new(serverConfig_t * conf)
{
	int serr;
	if ((shmid = shmget(IPC_PRIVATE,
			(sizeof(child_state_t) * HARD_MAX_CHILDREN),
			/* 0644 | IPC_CREAT */IPC_CREAT | IPC_EXCL)) == -1) {
		serr = errno;
		TRACE(TRACE_FATAL, "shmget failed [%s]",
				strerror(serr));
	}
	scoreboard = shmat(shmid, (void *) 0, 0);
	serr=errno;
	if (scoreboard == (Scoreboard_t *) (-1)) {
		TRACE(TRACE_FATAL, "scoreboard init failed [%s] (size = %d)",
		      strerror(serr), sizeof(child_state_t) * HARD_MAX_CHILDREN);
		scoreboard_delete();
	}
	scoreboard_lock_new();
	scoreboard->conf = conf;
	scoreboard_setup();
	scoreboard_conf_check();

	/* Make sure that we clean up our shared memory segments when we exit
	 * normally (i.e. not by kill -9, if you do that, you get to clean this
	 * up yourself!)
	 * */
	atexit(scoreboard_delete);
}
Чтож, проверим догадку о слишком раннем вызове функции (т.е., пользователь, указанный в dbmail.conf устанавливается раньше, чем открыт доступ к разлеяемой памяти. Итак, для смены пользователя, вызывается функция drop_privileges (char *newuser, char *newgroup) в файле [DBMail-2.3.1_src]/src/dm_misc.c:
int drop_privileges(char *newuser, char *newgroup)
{
	/* will drop running program's priviledges to newuser and newgroup */
	struct passwd *pwd;
	struct group *grp;

	grp = getgrnam(newgroup);

	if (grp == NULL) {
		TRACE(TRACE_ERROR, "could not find group %s
", newgroup);
		return -1;
	}

	pwd = getpwnam(newuser);
	if (pwd == NULL) {
		TRACE(TRACE_ERROR, "could not find user %s
", newuser);
		return -1;
	}

	if (setgid(grp->gr_gid) != 0) {
		TRACE(TRACE_ERROR, "could not set gid to %s
", newgroup);
		return -1;
	}

	if (setuid(pwd->pw_uid) != 0) {
		TRACE(TRACE_ERROR, "could not set uid to %s
", newuser);
		return -1;
	}
	return 0;
}
Функция StartServer(serverConfig_t *conf), в свою очередь вызывает scoreboard_new(serverConfig_t *config) (для открытия в памяти разделяемого ресурса) в файле [DBMail-2.3.1_src]/src/server.c. Осталось найти, кто вызывает функцию StartServer(). Ага, вот оно: функция server_run(serverConfig_t * conf), 254-й строки файла [DBMail-2.3.1_src]/src/server.c. А именно:
	case 0:
		/* child process */
		if (drop_privileges(conf->serverUser, conf->serverGroup) < 0) {
			mainStop = 1;
			TRACE(TRACE_ERROR,"unable to drop privileges");
			return 0;
		}
		isChildProcess = 1;
		result = StartServer(conf);
		TRACE(TRACE_INFO, "server done, restart = [%d]",
				result);
		exit(result);
		break;
Ну так и есть! В Linux‘е (и даже быть может, во FreeBSD с невысоким предустановелнным уровнем сетевой безопасности) такой номер проходит, а здесь — нет. Бо Mac OS X.
Ну чтож, попробуем поменять местами вызовы StartServer(…) и drop_privileges (char * newuser, char *newgroup):
case 0:
	/* child process */
	/* (© yevstigneyevda@mail.ru) */
	isChildProcess = 1;
	result = StartServer(conf);
	TRACE(TRACE_INFO, "server done, restart = [%d]",
			result);
	if (drop_privileges(conf->serverUser, conf->serverGroup) < 0) {
		mainStop = 1;
		TRACE(TRACE_ERROR,"unable to drop privileges");
		return 0;
	}
	exit(result);
	break;
Пересоберём DBMail-2.3.1 и установим в файле /opt/local/etc/dbmail.conf снова пользователя и группу в dbmail:
user = dbmail
group = dbmail
Понятно, что запускаем демона «штатно», т.е. «от root‘а»:
$ sudo dbmail-imapd -v -n
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+262): server will create  [2] children
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+275): children will make max. [10000] connections
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+288): timeout [4000] seconds
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+300): login_timeout [60] seconds
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+305): no value for SOCKET in config file
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+308): socket []
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+320): binding to PORT [143]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+341): binding to IP [*]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+348): no value for BACKLOG in config file. Using default value [16]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+362): not resolving client IP
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+376): Disabling IMAP-before-SMTP
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+388): effective user shall be [dbmail]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+400): effective group shall be [dbmail]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+412): will maintain minimum of [2] spare children in reserve
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+424): will maintain maximum of [4] spare children in reserve
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverparent] serverparent.c,LoadServerConfig(+436): will allow maximum of [10] children
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[db] dbmodule.c,db_load_driver(+59): library_directory is [/opt/local/lib/dbmail]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[db] dbmodule.c,db_load_driver(+72): looking for mysql as /opt/local/lib/dbmail/libmysql.so
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[sql] dbmysql.c,db_query(+297): query [SET NAMES utf8]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[sql] dbmysql.c,db_query(+297): query [SHOW VARIABLES LIKE 'collation_%']
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[sql] dbmysql.c,db_mysql_check_collations(+127): does [collation_database:utf8_general_ci] match [collation_connection:utf8_general_ci]?
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[auth] authmodule.c,auth_load_driver(+51): library_directory is [/opt/local/lib/dbmail]
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[auth] authmodule.c,auth_load_driver(+64): looking for auth_sql as /opt/local/lib/dbmail/libauth_sql.so
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[serverchild] serverchild.c,manage_start_cli_server(+446): client info init complete, calling client handler
* OK dbmail imap (protocol version 4r1) server dbmail@dbmail.org ready to run
Jan 20 20:30:04 denis-yevstigney dbmail-imapd[15229]: Debug:[imapsession] dbmail-imapsession.c,dbmail_imap_session_printf(+1647): RESPONSE: [* OK dbmail imap (protocol version 4r1) server dbmail@dbmail.org ready to run
]
Урааа! Зарработало! Правда, патчик писать пока не буду. Хотите — правьте сами.

«Демонизация» процесса

Кругло точно © искажённая надпись «Круглосуточно» на по-всей видимости, круглосуточном ларьке
Теперь надо настроить автозапуск демона. Управляет этим процессом управляет утилита daemondo из пакета MacPorts. Эта утилита была встроена в него, начиная с версии 1.6. К ней пока нет соответствующего мануала, зато весьма подробный help:
$ daemondo --help
daemondo, version 1.1

usage: daemondo [-hv] [--version]
                     --start-cmd prog args... ;
                     [--stop-cmd prog arg... ;]
                     [--restart-cmd prog arg... ;]
                     [--restart-wakeup]
                     [--restart-netchange]

daemondo is a wrapper program that runs daemons. It starts the specified
daemon on launch, stops it when given SIGTERM, and restarts it on SIGHUP.
It can also watch for transitions in system state, such as a change in
network availability or system power state, and restart the daemon on such
an event.

daemondo works well as an adapter between darwin 8's launchd, and daemons
that are normally started via traditional rc.d style scripts or parameters.

Parameters:

  -h, --help                      Provide this help.
  -v                              Increase verbosity.
      --verbosity=n               Set verbosity to n.
  -V, --version                   Display program version information.
  -l, --label=desc                Label used to describe the daemon.

  -s, --start-cmd args... ;       Required: command that will start the daemon.
  -k, --stop-cmd args... ;        Command that will stop the daemon.
  -r, --restart-cmd args... ;     Command that will restart the daemon.

      --pid=none|exec|fileauto|fileclean
                                  Whether to use/how to treat pid file.
      --pidfile=         A pidfile from which to scavenge the target pid.

      --restart-wakeup            Restart daemon on wake from sleep.
      --restart-netchange         Restart daemon on a network change.
      --restart-config regex... ; SC patterns on which to restart the daemon.
      --restart-dist-notify names... ;
                                  Distributed Notification Center notifications
                                  on which to restart the daemon.
      --restart-darwin-notify names... ;
                                  Darwin Notification Center notifications
                                  on which to restart the daemon.
      --restart-config regex... ; SC patterns on which to restart the daemon.

daemondo responds to SIGHUP by restarting the daemon, and to SIGTERM by
stopping it. daemondo exits on receipt of SIGTERM, or when it detects
that the daemon process has died.

The arguments start-cmd, stop-cmd, restart-cmd, restart-config,
restart-dist-notify, and restart-darwin-notify, if present,
must each be followed by arguments terminated by a ';'. You may need to
escape or quote the ';' to protect it from special handling by your shell.

daemondo runs in one of two modes: (1) If no stop-cmd is given, daemondo
executes start-cmd asyncronously, and tracks the process id; that process id
is used to signal the daemon for later stop and/or restart. (2) If stop-cmd
is given, then both start-cmd and stop-cmd are issued syncronously, and are
assumed to do all the work of controlling the daemon. In such cases there is
no process id to track. In either mode, restart-cmd, if present, is used to
restart the daemon. If in mode 1, restart-cmd must not disrupt the process id.
If restart-cmd is not provided, the daemon is restarted via a stop/start
sequence.

The argument restart-config specifies a set of regex patterns corresponding
to system configuration keys, on notification of change for which the daemon
will be restarted

The arguments restart-dist-notify and restart-darwin-notify specify a set of
notification names from the distributed and darwin notification centers,
respectively, on receipt of which the daemon will be restarted.

The argument restart-wakeup will cause the daemon to be restarted when the
computer wakes from sleep.

The argument restart-netchange will cause the daemon to be restarted when
the network configuration changes. This is a shortcut for the more
verbose --restart-darwin-notify com.apple.system.config.network_change.

In mode 1 only, daemondo will exit when it detects that the daemon being
monitored has exited.
Впрочем, в подробном чтении этого документа нет необходимости. Достаточно просто скопировать какой-нибудь из *.wrapper-файлов и изменить его в соответствии с нашими требованиями.
Создадим директорию /opt/local/etc/LaunchDaemons/dbmail:
$ sudo mkdir /opt/local/etc/LaunchDaemons/dbmail
К примеру, возьмём за образец файл /opt/local/etc/LaunchDaemons/org.macports.apache2, скопируем его в директорию /opt/local/etc/LaunchDaemons/dbmail/dbmail.wrapper и приведём его в надлежащий вид:
#!/bin/sh
#
# daemondo support script (© yevstigneyevda@mail.ru)
#

#
# Init
#
prefix=/opt/local

#
# Start
#
Start()
{
	/sbin/dbmail-imapd > /dev/null
}

#
# Stop
#
Stop()
{
	if [ -r /opt/local/var/run/dbmail.pid ] 
	then
		read PID `echo /opt/local/var/run/dbmail.pid`
		kill -TERM ${PID}
	fi
}

#
# Restart
#
Restart()
{
	Stop
	Start	
}

#
# Run
#
Run()
{
case $1 in
  start  ) Start   ;;
  stop   ) Stop    ;;
  restart) Restart ;;
  *      ) echo "$0: unknown argument: $1";;
esac
}

Run $1
Теперь настала очередь файла /opt/local/etc/LaunchDaemons/dbmail/dbmail.plist. Это XML файл. Опять же, можно взять за основу какой-нибудь *.plist файл и изменить его. Получим примерно следующее:
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<!-- (© yevstigneyevda@mail.ru) -->
<plist version="1.0">
<dict>
	<key>Debug</key>
	<false/>
	<key>Label</key>
	<string>dbmail</string>
	<key>OnDemand</key>
	<false/>
	<key>ProgramArguments</key>
	<array>
		<string>/opt/local/bin/daemondo</string>
		<string>--label=dbmail</string>
		<string>--start-cmd</string>
		<string>/opt/local/etc/LaunchDaemons/dbmail/dbmail.wrapper</string>
		<string>start</string>
		<string>;</string>
		<string>--stop-cmd</string>
		<string>/opt/local/etc/LaunchDaemons/dbmail/dbmail.wrapper</string>
		<string>stop</string>
		<string>;</string>
		<string>--restart-cmd</string>
		<string>/opt/local/etc/LaunchDaemons/dbmail/dbmail.wrapper</string>
		<string>restart</string>
		<string>;</string>
		<string>--pid=none</string>
	</array>
	<key>RunAtLoad</key>
	<false/>
</dict>
</plist>
Нетрудно проверить себя:
$ sudo /opt/local/etc/LaunchDaemon/dbmail/dbmail.wrapper start
Если в логе /var/log/dbmail/dbmail.err не видим ничего интересного, значит затея удалась. Порядок!
Копируем /opt/local/etc/LaunchDaemon/dbmail/dbmail.plist в /Library/LaunchDaemon/dbmail.plist и добавляем его в автозапуск при помощи команды
$ sudo launchctl load -w /Library/LaunchDaemons/dbmail.plist
После перезагрузки проверим себя:
ps ax | grep dbmail
   33  ??  Ss     0:00.02 /opt/local/bin/daemondo --label=dbmail --start-cmd /opt/lo
  362  p1  S+     0:00.00 grep dbmail
Право слово, сердце радуется! Как ни странно, но это — всё. Пааачтеннейшие граждане Публика, всем радоваться!

Related posts

Leave a Comment