Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
cmail Development Information
Welcome to cmail - we're happy to have you help developing this project further!
This document will give an overview of resources and conventions we adhere to when
developing the cmail core.
If you would like to contribute additional functionality external from the core
implementation, feel free to request access to the contrib repository of the
organization, where the standards explained herein are relaxed to a great extent.
All cmail code is supplied under a 2-Clause BSD License (see LICENSE.txt).
To have your code accepted into the main repository, we ask that your contributions
be put under that same license.
Issue Tracking
One of the earliest things to familiarize yourself with, and the primary entry point
for people without a specific problem they want to solve, is our issue tracker.
We use the system provided by GitHub [0].
When reporting an issue, please be as precise as you can, to allow us to triage the
issue without having to clarify basic details. This includes information such as
whether you are using the user database feature, how an offending expression was
formatted, etc.
If you are just starting to contribute, and are unclear on where you can help,
some issues within the system are tagged "good first issue" or "help wanted".
These labels are applied to issues that are either documented very well and
show a clear path to a solution, or to those that are self-explanatory or easily
understood by looking at reference material.
Other issues may require a deeper understanding of the codebase structure.
Tools to help you gain such an understanding are given in the course of this document.
Another way to look for interesting things to do is check some left-over TODO files
within the source tree (which should be mostly migrated to the issue tracker now),
or grep the source files for "TODO" and/or "FIXME".
Development Setup
To set up your local computer for cmail development (which does not take much in terms
of preparation), please refer to SETUP.txt. For some tests, it may be useful to set
up a virtual machine running a full instance of cmail. More information on setting
up and configuring cmail can be found on the cmail website at [1].
Environment & Languages
The core daemons of cmail are, as the name implies, written in C. We use a relaxed
interpretation of the C89 standard, allowing for C++-style comments.
Our preferred compiler is GCC, though any other compliant compiler should work too,
and incompatability with any such would be considered a bug.
Memory leak and access tests are performed with valgrind and the clang AdressSanitizer.
Static analysis is performed using Coverity Scan.
Coverage tests and graphs are generated by running builds from a special branch
(daemon-repl) against afl-fuzz and generating coverage information with gcov.
Build automation is primarily implemented in GNU make, with more complex scripting
done in Bash or Python where appropriate.
Automated tests against external interfaces are implemented in Tcl/Expect, while
internal APIs and functionality is tested from minimal C implementations.
For external libraries, such as TLS support, we prefer projects also licensed under
BSD clauses. Other criteria are breadth of operating system support (ie, Linux
distribution packages), code base size (smaller is "better") and security track
Code Style
Contrary to most other big C projects, every cmail daemon presents a single translation
unit (TLU) to the compiler, resulting in quick recompile times without much build
infrastructure. This carries with it some minor problems such as make not being
used to selectively build modules and include guards being a necessity in most cases.
As for conventional code style questions
* Opening braces ({) are made on the same line as the opening statement
* Closing braces (}) are on their own line, except for do..while constructs
* Optional braces are not to be omitted under any circumstances
* Indentation is one tab character per level
* Assignments and arithmetic operations are surrounded by spaces
* Except for parentheses
* Variables used within a function are declared at the top of that function
(C89 style) if possible.
* Variable names must be "speaking" (ie, longer than two characters) if the
variable is used in more than 3 lines
* Arguments to a function are separated by ", " (that is, a comma then a space)
* Long conditional expressions may be split onto multiple lines with the
logic operator preceding the next condition and being indented one
more level than the top-level clause
We try to avoid global variables whereever possible, passing structs where necessary.
Common functionality should be factored out into the shared "lib" folder.
Functions return 0 upon success, unless otherwise noted in an appropriate comment,
either within or above the function implementation.
If you add a new functionality or parameter to an existing part of the system, please
take care to add documentation to the following places where appropriate
* The manpages
* The Homepage
* The top-level text documentation files
* The example configurations
* The generated configuration files and generators
* The administration tools
Tools & Resources
To help you understand the implementation structure of the core daemons, we utilize
tools generating a visual map of function calls throughout the execution.
These graphs can be generated using the rtl2dot tool [2] and the rtldumps target
of the main makefile. More information on generating the callgraphs can be found on
our homepage [3].