Coding standards
DBMail is a high performance collection of C programs to manage and deliver a highly scalable email storage system backed by a SQL database.
This coding standard article is aimed at developers, contributors, port maintainers and anyone wishing to build dbmail themselves.
Services
- dbmail-deliver a command line interface to insert emails;
- dbmail-imapd provides IMAP for end users to manage their email;
- dbmail-sievecmd a command line utility to manage sieve scripts;
- dbmail-util a command line utility to manage routine maintenance;
- dbmail-export command line utility to export a DBMail mailbox to an mbox formatted mailbox;
- dbmail-lmtpd provides LMTP to receive emails from an MTA;
- dbmail-sieved provides a manage sieve daemon for end users to manage their own filters;
- dbmail-httpd provides a REST API to dbmail;
- dbmail-pop3d Post Office Protocol POP3;
- dbmail-users command line utility to manage users.
Libraries
Thanks to Open Source, dbmail delivers reliable high performance thanks to many external libraries including:
Wondered about the value of Open Source software? See this report by Harvard Business Review.
Building DBMail
Building dbmail is straightforward thanks to GNU Autotools. The usual configure followed by make then make install should get you a working system. If you're new to dbmail then perhaps configure and try it out with sqlite, when you're ready to evaluate it then PostgreSQL, MySQL and Oracle are good choices. DBMail is included in most distributions so there is rarely any need to build it yourself.
For those interested in finding out more, delving into how dbmail works, developing local modifications or proposing patches you might find the following flags useful: -O0 -g -std=c17 -Wall -Wextra -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -Wno-format-pedantic.
Building with debug symbols, all and extra warnings are highly recommended, all main C compilers have great user feedback helping improve software quality. As of 2024-10-22 there are only two -Wdeprecated-declarations compile warnings.
Layout
Layout is straightforward as are the files they contain, most of the directories follow:
/contrib/
User contributions.
/debian/
Debian contributed files to help build dbmail.
/docker/
An experimental docker image is available with files and documentation here showing how to use it with docker-compose.
/man/
Man pages for the dbmail-* apps and config, they are largely auto generated.
/sql/[database]/upgrades
All four supported databases MySQL, Oracle, PostgreSQL and SQLite have their own directory and contain everything needed to create and upgrade a dbmail database. Creation and upgrades are automatic for dbmail version 3.5 and later though databases large enough to have their own dba will probably want to upgrade manually.
/src/
All core code is here, with sieve filtering, ldap and sql authentication in /src/modules.
/test/
Tests live here, alas there aren't enough of them.
Files
The files are well structured though for historic reasons their names may not be intuitive.
Utility | main() | Description |
---|---|---|
dbmail-deliver | main.c | Command line utility to deliver an email |
dbmail-export | export.c | Command line utility to export emails |
dbmail-httpd | httpd.c | HTTP daemon |
dbmail-imapd | imapd.c | IMAP daemon |
dbmail-lmtpd | lmtpd.c | LMTP daemon |
dbmail-pop3d | pop3d.c | POP3 daemon |
dbmail-sievecmd | sievecmd.c | Command line utility to manage sieve scripts |
dbmail-sieved | sieved.c | SIEVED daemon |
dbmail-users | user.c | Command line utility to manage users |
dbmail-util | maintenance.c | Command line maintenance utility |
There is the usual combination of example.h for headers and example.c for C code.
Notable files are dbmail.h.in for includes and dbmailtypes.h for the majority of core data types and definitions.
Each dm_* file encapsulates various functions, for example dm_config.c manages access to dbmail.conf and dm_db.c manages communications with the database.
Classes and functions could be better documented, nevertheless they're usually well named and relatively obvious once you start using them. Where documentation is helpful it should be added both at the class, function, definition, structure and inline as necessary. Doxygen understands class and function comments so commands such as \brief are unnecessary, unhelpful for humans, distracting and will be removed on an ad-hoc basis.
Much of dbmail is about implementing standards, these should be documented in the relevant class. For example dm_dsn.c relates to Delivery User Functions and there is a comment mentioning "Enhanced Status Codes from RFC 1893 and should be updated to include its successor, RFC 3463".
As GMime and GTK are core libraries, most strings tend to be GString objects, GList objects for doubly-linked lists using g_* macros and functions.
There's little need for duplication as almost everything is compiled into libdbmail.so and where necessary variables are also shared, for example loudness is an 'extern int verbose';
Quality control
All software has bugs and dbmail is no exception. Nevertheless in addition to compiling with warnings as described above and using tests to check functionality, maintaining consistent high quality is essential for dbmail so valgrind is an integral part of development as is testing with additional warnings.
The main trunk in GitHub is for the majority of activity, for each officially released version there is a version branch created for bug fixes. Where there are significant new features or changes a feature branch will be created to better support testing and development.
Happy coding ;)