From 133a45c109da5310add55824db21af5239951f93 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 23:30:40 +0200 Subject: Adding upstream version 3.8.1. Signed-off-by: Daniel Baumann --- doc/Makefile | 94 +++++++ doc/doxydown/.gitignore | 19 ++ doc/doxydown/LICENSE | 21 ++ doc/doxydown/README.md | 139 +++++++++++ doc/doxydown/doxydown.pl | 624 +++++++++++++++++++++++++++++++++++++++++++++++ doc/rspamadm.1 | 134 ++++++++++ doc/rspamadm.1.md | 85 +++++++ doc/rspamc.1 | 307 +++++++++++++++++++++++ doc/rspamc.1.md | 173 +++++++++++++ doc/rspamd.8 | 78 ++++++ doc/rspamd.8.md | 57 +++++ 11 files changed, 1731 insertions(+) create mode 100644 doc/Makefile create mode 100644 doc/doxydown/.gitignore create mode 100644 doc/doxydown/LICENSE create mode 100644 doc/doxydown/README.md create mode 100755 doc/doxydown/doxydown.pl create mode 100644 doc/rspamadm.1 create mode 100644 doc/rspamadm.1.md create mode 100644 doc/rspamc.1 create mode 100644 doc/rspamc.1.md create mode 100644 doc/rspamd.8 create mode 100644 doc/rspamd.8.md (limited to 'doc') diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..53ed9b6 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,94 @@ +# A simple makefile to generate documentation from .md using pandoc + +PANDOC ?= pandoc +LUADOC ?= doxydown/doxydown.pl +LLUADOC ?= ${LUADOC} -l lua -e lua + +all: man + +man: rspamd.8 rspamc.1 rspamadm.1 + +rspamd.8: rspamd.8.md + $(PANDOC) -s -f markdown -t man -o rspamd.8 rspamd.8.md +rspamc.1: rspamc.1.md + $(PANDOC) -s -f markdown -t man -o rspamc.1 rspamc.1.md +rspamadm.1: rspamadm.1.md + $(PANDOC) -s -f markdown -t man -o rspamadm.1 rspamadm.1.md + +lua-dirs: + mkdir -p markdown/lua + +lua-doc: lua-dirs rspamd_regexp rspamd_ip rspamd_config rspamd_task ucl rspamd_http rspamd_trie \ + rspamd_resolver rspamd_redis rspamd_upstream_list rspamd_expression rspamd_mimepart rspamd_logger rspamd_url \ + rspamd_tcp rspamd_mempool rspamd_html rspamd_util rspamd_sqlite3 rspamd_cryptobox rspamd_map \ + lua_redis lua_util lua_maps lua_clickhouse lua_selectors rspamd_udp rspamd_text lua_mime rspamd_parsers \ + rspamd_cdb + +lua_redis: + $(LLUADOC) < ../lualib/lua_redis.lua > markdown/lua/lua_redis.md + +lua_util: + $(LLUADOC) < ../lualib/lua_util.lua > markdown/lua/lua_util.md + +lua_maps: + $(LLUADOC) < ../lualib/lua_maps.lua > markdown/lua/lua_maps.md + +lua_clickhouse: + $(LLUADOC) < ../lualib/lua_clickhouse.lua > markdown/lua/lua_clickhouse.md + +lua_selectors: + $(LLUADOC) < ../lualib/lua_selectors/init.lua > markdown/lua/lua_selectors.md + +lua_mime: + $(LLUADOC) < ../lualib/lua_mime.lua > markdown/lua/lua_mime.md + +rspamd_regexp: ../src/lua/lua_regexp.c + $(LUADOC) < ../src/lua/lua_regexp.c > markdown/lua/rspamd_regexp.md +rspamd_ip: ../src/lua/lua_ip.c + $(LUADOC) < ../src/lua/lua_ip.c > markdown/lua/rspamd_ip.md +rspamd_config: ../src/lua/lua_config.c + $(LUADOC) < ../src/lua/lua_config.c > markdown/lua/rspamd_config.md +rspamd_task: ../src/lua/lua_task.c + $(LUADOC) < ../src/lua/lua_task.c > markdown/lua/rspamd_task.md +ucl: ../contrib/libucl/lua_ucl.c + $(LUADOC) < ../contrib/libucl/lua_ucl.c > markdown/lua/ucl.md +rspamd_http: ../src/lua/lua_http.c + $(LUADOC) < ../src/lua/lua_http.c > markdown/lua/rspamd_http.md +rspamd_trie: ../src/lua/lua_trie.c + $(LUADOC) < ../src/lua/lua_trie.c > markdown/lua/rspamd_trie.md +rspamd_resolver: ../src/lua/lua_dns_resolver.c + $(LUADOC) < ../src/lua/lua_dns_resolver.c > markdown/lua/rspamd_resolver.md +rspamd_redis: ../src/lua/lua_redis.c + $(LUADOC) < ../src/lua/lua_redis.c > markdown/lua/rspamd_redis.md +rspamd_upstream_list: ../src/lua/lua_upstream.c + $(LUADOC) < ../src/lua/lua_upstream.c > markdown/lua/rspamd_upstream.md +rspamd_expression: ../src/lua/lua_expression.c + $(LUADOC) < ../src/lua/lua_expression.c > markdown/lua/rspamd_expression.md +rspamd_mimepart: ../src/lua/lua_mimepart.c + $(LUADOC) < ../src/lua/lua_mimepart.c > markdown/lua/rspamd_mimepart.md +rspamd_logger: ../src/lua/lua_logger.c + $(LUADOC) < ../src/lua/lua_logger.c > markdown/lua/rspamd_logger.md +rspamd_url: ../src/lua/lua_url.c + $(LUADOC) < ../src/lua/lua_url.c > markdown/lua/rspamd_url.md +rspamd_tcp: ../src/lua/lua_tcp.c + $(LUADOC) < ../src/lua/lua_tcp.c > markdown/lua/rspamd_tcp.md +rspamd_mempool: ../src/lua/lua_mempool.c + $(LUADOC) < ../src/lua/lua_mempool.c > markdown/lua/rspamd_mempool.md +rspamd_html: ../src/lua/lua_html.cxx + $(LUADOC) < ../src/lua/lua_html.cxx > markdown/lua/rspamd_html.md +rspamd_util: ../src/lua/lua_util.c + $(LUADOC) < ../src/lua/lua_util.c > markdown/lua/rspamd_util.md +rspamd_sqlite3: ../src/lua/lua_sqlite3.c + $(LUADOC) < ../src/lua/lua_sqlite3.c > markdown/lua/rspamd_sqlite3.md +rspamd_cryptobox: ../src/lua/lua_cryptobox.c + $(LUADOC) < ../src/lua/lua_cryptobox.c > markdown/lua/rspamd_cryptobox.md +rspamd_map: ../src/lua/lua_map.c + $(LUADOC) < ../src/lua/lua_map.c > markdown/lua/rspamd_map.md +rspamd_udp: ../src/lua/lua_udp.c + $(LUADOC) < ../src/lua/lua_udp.c > markdown/lua/rspamd_udp.md +rspamd_text: ../src/lua/lua_text.c + $(LUADOC) < ../src/lua/lua_text.c > markdown/lua/rspamd_text.md +rspamd_parsers: ../src/lua/lua_parsers.c + $(LUADOC) < ../src/lua/lua_parsers.c > markdown/lua/rspamd_parsers.md +rspamd_cdb: ../src/lua/lua_cdb.c + $(LUADOC) < ../src/lua/lua_cdb.c > markdown/lua/rspamd_cdb.md \ No newline at end of file diff --git a/doc/doxydown/.gitignore b/doc/doxydown/.gitignore new file mode 100644 index 0000000..eaca02e --- /dev/null +++ b/doc/doxydown/.gitignore @@ -0,0 +1,19 @@ +/blib/ +/.build/ +_build/ +cover_db/ +inc/ +Build +!Build/ +Build.bat +.last_cover_stats +/Makefile +/Makefile.old +/MANIFEST.bak +/META.yml +/META.json +/MYMETA.* +nytprof.out +/pm_to_blib +*.o +*.bs diff --git a/doc/doxydown/LICENSE b/doc/doxydown/LICENSE new file mode 100644 index 0000000..d39277a --- /dev/null +++ b/doc/doxydown/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Vsevolod Stakhov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/doc/doxydown/README.md b/doc/doxydown/README.md new file mode 100644 index 0000000..86d4c30 --- /dev/null +++ b/doc/doxydown/README.md @@ -0,0 +1,139 @@ +# Doxydown - documentation utility + +## Introduction + +Doxydown is an utility to convert `doxygen`-like comments from the source code to markdown. +Unlike other documentation systems, `doxydown` is specifically designed to generate markdown output only. +At the moment, doxydown can work with C and lua comments and produce kramdown/pandoc or github +flavoured markdown. Doxydown produces output with anchors, links and table of content. +It also can highlight syntax for examples in the documentation. + +### Why markdown + +Markdown is used by many contemporary engines and can be rendered to HTML using +advanced templates, styles and scripts. Markdown provides excellent formatting +capabilities while it doesn't require authors to be web designers to create +documentation. Markdown is rendered by [`github`](https://github.com) and +doxydown can generate documentation easily viewed directly inside github. Moreover, +doxydown supports pandoc style of markdown and that means that markdown output +can be converted to all formats supported by pandoc (html, pdf, latex, +man pages and many others). + +### Why not `other documentation generator` + +Doxydown is extremely simple as it can output markdown only but it is very +convenient tool to generate nice markdown with all features required from the +documentation system. Doxydown uses input format that is very close to `doxygen` +that allows to re-use the existing documentation comments. Currently, doxydown +does not support many features but they could be easily added on demand. + +## Input format + +Doxydown extracts documentation from the comments blocks. The start of block is indicated by + + /*** + +in `C` or by + + --[[[ + +in `lua`. The end of documentation block is the normal multiline comment ending +specific for the input language. Doxydown also strips an initial comment character, +therefore the following inputs are equal: + +~~~c +/*** + * some text + * other text + * + */ +~~~ +and + +~~~c +/*** +some text +other text + +*/ +~~~ + +Note that doxydown preserves empty lines and all markdown elements. + +### Documentation blocks + +Each documentation block describes either module or function/method. Modules are +logical compounds of functions and methods. The difference between method and +function is significant for languages with methods support (e.g. by `lua` via +metatables). To define method or function you can use the following: + + /*** + @function my_awesome_function(param1[, param2]) + This function is awesome. + */ + +All text met in the current documentation block is used as function or method description. +You can also define parameters and return values for functions and methods: + + @param {type} param1 mandatory param + +Here, `{type}` is optional type description for a parameter, `param1` is parameter's name +and the rest of the string is parameter description. Currently, you cannot split +parameter description by newline character. In future versions of doxydown this might +be fixed. + +You can specify return type of your function by using of `@return` tag: + + @return {type} some cool result + +This tag is similar to `@param` and has the same limitation regarding newlines. +You can also add some example code by using of `@example` tag: + + @example + my_awesome_function('hello'); // returns 42 + +All text after `@example` tag and until documentation block end is used as an example +and is highlighted in markdown. Also you can switch the language of example by using +the extended `@example` tag: + + @example lua + +In this example, the code will be highlighted as `lua` code. + +Modules descriptions uses the same conventions, but `@param` and `@return` are +meaningless for the modules. Function and methods blocks that follows some `@module` +block are automatically attached to that module. + +Both modules and function can use links to other functions and methods by using of +`@see` tag: + + @see my_awesome_function + +This inserts a hyperlink to the specified function definition to the markdown. + +## Output format + +Doxydown can generate github flavoured markdown and pandoc/kramdown compatible +markdown. The main difference is in how anchors are organized. In kramdown and +pandoc it is possible to specify an explicit id for each header, whilst in +GH flavoured markdown we can use only implicit anchors. + +### Examples + +You can see an example of github flavoured markdown render at +[libucl github page](https://github.com/vstakhov/libucl/blob/master/doc/lua_api.md). +The same page bu rendered by kramdown engine in `jekyll` platform can be +accessed by [this address](https://rspamd.com/doc/lua/ucl.html). + +## Program invocation + + doxydown [-hg] [-l language] < input_source > markdown.md + +* `-h`: help message +* `-e`: sets default example language (default: lua) +* `-l`: sets input language (default: c) +* `-g`: use github flavoured markdown (default: kramdown/pandoc) + +## License + +Doxydown is published by terms of `MIT` license. \ No newline at end of file diff --git a/doc/doxydown/doxydown.pl b/doc/doxydown/doxydown.pl new file mode 100755 index 0000000..5002f58 --- /dev/null +++ b/doc/doxydown/doxydown.pl @@ -0,0 +1,624 @@ +#!/usr/bin/env perl + +$VERSION = "0.1.4"; + +use strict; +use warnings; +use Data::Dumper; +use Digest::MD5 qw(md5_hex); + +my @modules; +my %options = (); +my $cur_module; +my $example_language = "lua"; + +my %languages = ( + c => { + start => qr/^\s*\/\*\*\*(?:\s*|(\s+\S.+\s*))$/, + end => qr/^\s*\*+\/\s*$/, + filter => qr/^(?:\s*\*+\s?)?(\s*\S.+)\s*$/, + }, + lua => { + start => qr/^\s*\--(?:\[\[\[+|-+)\s*$/, + end => qr/^\s*--(:?\]\]+|-+)\s*$/, + filter => qr/^(?:\s*--!?\s?)?(\s*\S?.+)\s*$/, + }, + sql => { + start => qr/^\s*\--(?:\[\[+|-+)\s*$/, + end => qr/^\s*--(:?\]\]+|-+)\s*$/, + filter => qr/^(?:\s*--\s?)?(\s*\S.+)\s*$/, + }, + pl => { + start => qr/^\s*\##+\s*$/, + end => qr/^\s*##+\s*/, + filter => qr/^(?:\s*#+\s?)(\s*\S.+)\s*$/, + }, +); + +my $function_re = qr/^\s*\@(function|fn|method)\s*(\S.+)$/oi; +my $struct_re = qr/^\s*\@(table|struct)\s*(\S.+)$/oi; +my $module_re = qr/^\s*\@(?:module|file)\s*(\S.+)$/oi; +my $language; + +# /function print_module_markdown +sub print_module_markdown { + my ( $mname, $m ) = @_; + my $idline = $options{g} ? "" : " {#$m->{'id'}}"; + + print <{'data'} +EOD + if ( $m->{'example'} ) { + print <{'example_language'} +$m->{'example'} +~~~ +EOD + } + + sub print_func { + my ($f) = @_; + + my $name = $f->{'name'}; + my $id = $f->{'id'}; + + if ($f->{'brief'}) { + print "[`$name`](#$id) | ". $f->{'brief'} . "\n"; + } else { + print "[`$name`](#$id) | No description\n"; + } + } + + sub print_table { + my ($f) = @_; + + my $name = $f->{'name'}; + my $id = $f->{'id'}; + + if ($f->{'brief'}) { + print "> [`$name`](#$id): ". $f->{'brief'} . "\n\n"; + } else { + print "> [`$name`](#$id)\n\n"; + } + } + + print "\n### Brief content:\n\n"; + + if ($m->{'functions'}) { + if (scalar(@{ $m->{'functions'} }) > 0) { + print "**Functions**:\n\n"; + + print " Function | Description\n"; + print "----------|------------\n"; + foreach ( @{ $m->{'functions'} } ) { + print_func($_); + } + } + } + + if ($m->{'methods'}) { + if (scalar(@{ $m->{'methods'} }) > 0) { + print "\n\n**Methods**:\n\n"; + print " Method | Description\n"; + print "----------|------------\n"; + foreach ( @{ $m->{'methods'} } ) { + print_func($_); + } + } + } + + if ($m->{'tables'}) { + if (scalar(@{ $m->{'tables'} }) > 0) { + print "\n\n**Tables**:\n\n"; + + foreach ( @{ $m->{'tables'} } ) { + print_table($_); + } + } + } + + if ($m->{'structs'}) { + if (scalar(@{ $m->{'structs'} }) > 0) { + print "\n\n**Structs**:\n\n"; + + foreach ( @{ $m->{'structs'} } ) { + print_table($_); + } + } + } +} + +# /function print_function_markdown +sub print_function_markdown { + my ( $type, $fname, $f ) = @_; + + my $idline = $options{g} ? "" : " {#$f->{'id'}}"; + print <{'data'} +EOD + print "\n**Parameters:**\n\n"; + + if ( $f->{'params'} && scalar @{ $f->{'params'} } > 0 ) { + foreach ( @{ $f->{'params'} } ) { + if ( $_->{'type'} ) { + print + "- `$_->{'name'} \{$_->{'type'}\}`: $_->{'description'}\n"; + } else { + print "- `$_->{'name'}`: $_->{'description'}\n"; + } + } + } else { + print "No parameters\n"; + } + + print "\n**Returns:**\n\n"; + + if ( $f->{'returns'} && scalar @{ $f->{'returns'} } > 0 ) { + foreach ( @{ $f->{'returns'} } ) { + if ( $_->{'type'} ) { + print "- `\{$_->{'type'}\}`: $_->{'description'}\n"; + } else { + print "- $_->{'description'}\n"; + } + } + } else { + print "No return\n"; + } + + if ( $f->{'available'} ) { + printf "\n**Available in:** %s\n", $f->{'available'}; + } + + if ( $f->{'example'} ) { + print <{'example_language'} +$f->{'example'} +~~~ +EOD + } +} + +# /function print_struct_markdown +sub print_struct_markdown { + my ( $type, $fname, $f ) = @_; + + my $idline = $options{g} ? "" : " {#$f->{'id'}}"; + print <{'data'} +EOD + print "\n**Elements:**\n\n"; + + if ( $f->{'params'} && scalar @{ $f->{'params'} } > 0 ) { + foreach ( @{ $f->{'params'} } ) { + if ( $_->{'type'} ) { + print + "- `$_->{'name'} \{$_->{'type'}\}`: $_->{'description'}\n"; + } else { + print "- `$_->{'name'}`: $_->{'description'}\n"; + } + } + } else { + print "No elements\n"; + } + + if ( $f->{'example'} ) { + print <{'example_language'} +$f->{'example'} +~~~ +EOD + } +} + +# /function print_markdown +sub print_markdown { + for my $m (@modules) { + my $mname = $m->{name}; + + print_module_markdown( $mname, $m ); + + if ($m->{'functions'}) { + if ( scalar(@{ $m->{'functions'} }) > 0 ) { + print "\n## Functions\n\nThe module `$mname` defines the following functions.\n\n"; + + foreach ( @{ $m->{'functions'} } ) { + print_function_markdown( "Function", $_->{'name'}, $_ ); + + print "\nBack to [module description](#$m->{'id'}).\n\n"; + + } + } + } + + if ($m->{'methods'}) { + if ( scalar(@{ $m->{'methods'} }) > 0 ) { + print "\n## Methods\n\nThe module `$mname` defines the following methods.\n\n"; + + foreach ( @{ $m->{'methods'} } ) { + print_function_markdown( "Method", $_->{'name'}, $_ ); + + print "\nBack to [module description](#$m->{'id'}).\n\n"; + + } + } + } + + if ($m->{'tables'}) { + if ( scalar(@{ $m->{'tables'} }) > 0 ) { + print "\n## Tables\n\nThe module `$mname` defines the following tables.\n\n"; + + foreach ( @{ $m->{'tables'} } ) { + print_struct_markdown( "Table", $_->{'name'}, $_ ); + + print "\nBack to [module description](#$m->{'id'}).\n\n"; + + } + } + } + + if ($m->{'structs'}) { + if ( scalar(@{ $m->{'structs'} }) > 0 ) { + print "\n## Structs\n\nThe module `$mname` defines the following structs.\n\n"; + + foreach ( @{ $m->{'structs'} } ) { + print_struct_markdown( "Struct", $_->{'name'}, $_ ); + + print "\nBack to [module description](#$m->{'id'}).\n\n"; + + } + } + } + + print "\nBack to [top](#).\n\n"; + } +} + +# /function make_id +sub make_id { + my ( $name, $prefix ) = @_; + + if ( !$prefix ) { + $prefix = "f"; + } + + if ( !$options{g} ) { + + # Kramdown/pandoc version of ID's + $name =~ /^(\S+).*$/; + + return substr( substr( $prefix, 0, 1 ) . md5_hex($1), 0, 6 ); + } else { + my $input = lc $prefix . "-" . $name; + my $id = join '-', split /\s+/, $input; + + $id =~ s/[^\w_-]+//g; + + return $id; + } +} + +# /function substitute_data_keywords +sub substitute_data_keywords { + my ($line) = @_; + + if ( $line =~ /^.*\@see\s+(\S+)\s*.*$/ ) { + my $name = $1; + my $id = make_id($name); + + return $line =~ s/\@see\s+\S+/[`$name`](#$id)/r; + } + + return $line; +} + +# /function parse_function +sub parse_function { + my ( $func, @data ) = @_; + + my ( $type, $name ) = ( $func =~ $function_re ); + chomp $name; + + my $f = { + name => $name, + data => '', + example => undef, + example_language => $example_language, + id => make_id( $name, $type ), + }; + my $example = 0; + + foreach ( @data ) { + if ( /^\s*\@param\s*(?:\{([^}]+)\})?\s*(\S+)\s*(.+)?\s*$/ ) { + my $p = { + name => $2, + type => $1 || "no type", + description => $3 || "no description" + }; + + push @{ $f->{'params'} }, $p; + } elsif ( /^\s*\@return\s*(?:\{([^}]+)\})?\s*(.+)?\s*$/ ) { + my $r = { + type => $1, + description => $2 || "no description" + }; + + push @{ $f->{'returns'} }, $r; + } elsif ( /^\s*\@brief\s*(\S.+)$/ ) { + $f->{'brief'} = $1; + } elsif ( /^\s*\@available\s*(\S.+)$/ ) { + $f->{'available'} = $1; + } + elsif ( /^\s*\@example\s*(\S)?\s*$/ ) { + $example = 1; + if ( $1 ) { + $f->{'example_language'} = $1; + } + } elsif ( $_ ne $func ) { + if ( $example ) { + $f->{'example'} .= $_; + } else { + $f->{'data'} .= substitute_data_keywords($_); + } + } + } + + if ( $f->{'data'} ) { + chomp $f->{'data'}; + } elsif ($f->{'brief'}) { + chomp $f->{'brief'}; + $f->{'data'} = $f->{'brief'}; + } + + if ( $f->{'example'} ) { + chomp $f->{'example'}; + } + + if ( $f->{'available'} ) { + chomp $f->{'available'} + } + + if ( !$f->{'brief'} && $f->{'data'} ) { + + + if ( $f->{'data'} =~ /^(.*?)(?:(?:[.:]\s|$)|\n).*/ ) { + $f->{'brief'} = "$1"; + chomp $f->{'brief'}; + + if ( $f->{'brief'} !~ /\.$/) { + $f->{'brief'} .= "."; + } + } + } + + if ( $type eq "method" ) { + push @{ $cur_module->{'methods'} }, $f; + } elsif ( $type eq "function" || $type eq "fn") { + push @{ $cur_module->{'functions'} }, $f; + } +} + +# /function parse_struct +sub parse_struct { + my ( $func, @data ) = @_; + + my ( $type, $name ) = ( $func =~ $struct_re ); + chomp $name; + + my $f = { + name => $name, + data => '', + example => undef, + example_language => $example_language, + id => make_id( $name, $type ), + }; + my $example = 0; + + foreach ( @data ) { + if ( /^\s*\@param\s*(?:\{([^}]+)\})?\s*(\S+)\s*(.+)?\s*$/ ) { + my $p = { + name => $2, + type => $1, + description => $3 + }; + + push @{ $f->{'params'} }, $p; + } elsif ( /^\s*\@brief\s*(\S.+)$/ ) { + $f->{'brief'} = $1; + } elsif ( /^\s*\@example\s*(\S)?\s*$/ ) { + $example = 1; + if ( $1 ) { + $f->{'example_language'} = $1; + } + } elsif ( $_ ne $func ) { + if ( $example ) { + $f->{'example'} .= $_; + } else { + $f->{'data'} .= substitute_data_keywords($_); + } + } + } + + if ( $f->{'data'} ) { + chomp $f->{'data'}; + } elsif ($f->{'brief'}) { + chomp $f->{'brief'}; + $f->{'data'} = $f->{'brief'}; + } + + if ( $f->{'example'} ) { + chomp $f->{'example'}; + } + + if ( $type eq "table" ) { + push @{ $cur_module->{'tables'} }, $f; + } elsif ( $type eq "struct" ) { + push @{ $cur_module->{'structs'} }, $f; + } +} + +# /function parse_module +sub parse_module { + my ( $module, @data ) = @_; + my ( $name ) = ( $module =~ $module_re ); + + chomp $name; + + my $f = { + name => $name, + functions => [], + methods => [], + data => '', + example => undef, + example_language => $example_language, + id => make_id( $name, "module" ), + }; + + my $example = 0; + + foreach ( @data ) { + if ( /^\s*\@example\s*(\S)?\s*$/ ) { + $example = 1; + if ($1) { + $f->{'example_language'} = $1; + } + } elsif ( /^\s*\@brief\s*(\S.+)$/ ) { + $f->{'brief'} = $1; + } elsif ( $_ ne $module ) { + if ( $example ) { + $f->{'example'} .= $_; + } else { + $f->{'data'} .= substitute_data_keywords($_); + } + } + } + + if ( $f->{'data'} ) { + chomp $f->{'data'}; + } elsif ( $f->{'brief'} ) { + chomp $f->{'brief'}; + + $f->{'data'} = $f->{'brief'}; + } + + if ( $f->{'example'} ) { + chomp $f->{'example'}; + } + + $cur_module = $f; + push @modules, $f; +} + +# /function parse_content +sub parse_content { + # + my @func = grep /$function_re/, @_; + if ( scalar @func > 0 ) { + parse_function( $func[0], @_ ); + } + + # + my @struct = grep /$struct_re/, @_; + if ( scalar @struct > 0 ) { + parse_struct( $struct[0], @_ ); + } + + # + my @module = grep /$module_re/, @_; + if ( scalar @module > 0 ) { + parse_module( $module[0], @_ ); + } +} + +sub HELP_MESSAGE { + print STDERR < markdown.md + + -h : this (help) message + -e : sets default example language (default: lua) + -l : sets input language (default: c) + -g : use github flavoured markdown (default: kramdown/pandoc) +EOF + + exit; +} + +$Getopt::Std::STANDARD_HELP_VERSION = 1; +use Getopt::Std; + +getopts( 'he:gl:', \%options ); + +HELP_MESSAGE() if $options{h}; + +$example_language = $options{e} if $options{e}; +$language = $languages{ lc $options{l} } if $options{l}; + +if ( !$language ) { + $language = $languages{c}; +} + +## TODO: select language based on file extension +## TODO: change calling structure to allow looping through directory + +use constant { + STATE_READ_SKIP => 0, + STATE_READ_CONTENT => 1, + STATE_READ_ENUM => 2, + STATE_READ_STRUCT => 3, +}; + +my $state = STATE_READ_SKIP; +my $content; + +while ( <> ) { + if ( $state == STATE_READ_SKIP ) { + if ( $_ =~ $language->{start} ) { + $state = STATE_READ_CONTENT; + + if (defined($1)) { + chomp($content = $1); + $content =~ tr/\r//d; + $content .= "\n"; + } else { + $content = ""; + } + } + } elsif ( $state == STATE_READ_CONTENT ) { + if ( $_ =~ $language->{end} ) { + $state = STATE_READ_SKIP; + + parse_content( split /^/, $content ); + + $content = ""; + } else { + my ($line) = ( $_ =~ $language->{filter} ); + + if ( $line ) { + $line =~ tr/\r//d; + $content .= $line . "\n"; + } else { + # Preserve empty lines + $content .= "\n"; + } + } + } +} + +#print Dumper( \@modules ); +print_markdown; diff --git a/doc/rspamadm.1 b/doc/rspamadm.1 new file mode 100644 index 0000000..bd3b02a --- /dev/null +++ b/doc/rspamadm.1 @@ -0,0 +1,134 @@ +.\" Automatically generated by Pandoc 1.17.2 +.\" +.TH "RSPAMADM" "1" "" "Rspamd User Manual" "" +.hy +.SH NAME +.PP +rspamadm \- rspamd administration utility +.SH SYNOPSIS +.PP +rspamadm [\f[I]global_options\f[]] [\f[I]command\f[]] +[\f[I]command_options\f[]]... +.SH DESCRIPTION +.PP +\f[C]rspamadm\f[] is a routine to manage rspamd spam filtering system. +It is intended to perform such actions as merging databases, performing +configuration tests, encrypting passwords, signing configurations and so +on. +You can get a list of available \f[B]commands\f[] by running +.IP +.nf +\f[C] +rspamadm\ \-l +\f[] +.fi +.PP +Also for each command you can check list of available +\f[B]command_options\f[] by running +.IP +.nf +\f[C] +rspamadm\ help\ command +rspamadm\ command\ \-\-help +\f[] +.fi +.SH OPTIONS +.TP +.B \-h, \-\-help +Show help message +.RS +.RE +.TP +.B \-v, \-\-verbose +Enable verbose output +.RS +.RE +.TP +.B \-l, \-\-list\-commands +List available commands +.RS +.RE +.TP +.B \-\-version +Show version +.RS +.RE +.TP +.B \-\-var=\f[I]value\f[] +Redefine ucl variable in format \f[C]VARIABLE=VALUE\f[] +.RS +.RE +.SH RETURN VALUE +.PP +On exit \f[C]rspamadm\f[] returns \f[C]0\f[] if operation was successful +and an error code otherwise. +.SH EXAMPLES +.PP +Get help for pw command: +.IP +.nf +\f[C] +rspamadm\ help\ pw +rspamadm\ pw\ \-\-help +\f[] +.fi +.PP +Encrypt controller\[aq]s password: +.IP +.nf +\f[C] +rspamadm\ pw\ encrypt +\f[] +.fi +.PP +Merge fuzzy databases: +.IP +.nf +\f[C] +rspamadm\ fuzzy_merge\ \-s\ data1.sqlite\ \-s\ data2.sqlite\ \-t\ dest.sqlite +\f[] +.fi +.PP +Perform configuration test: +.IP +.nf +\f[C] +rspamadm\ configtest\ \-c\ rspamd.conf +\f[] +.fi +.PP +Test configuration strictly and redefine some ucl vars: +.IP +.nf +\f[C] +rspamadm\ \-\-var=DBDIR=/tmp\ configtest\ \-c\ ./rspamd.conf\ \-s +\f[] +.fi +.PP +Dump the processed configuration: +.IP +.nf +\f[C] +rspamadm\ configdump +\f[] +.fi +.PP +Dump the processed configuration as JSON string: +.IP +.nf +\f[C] +rspamadm\ configdump\ \-j +\f[] +.fi +.PP +Generate a keypair to use for HTTPCrypt encryption: +.IP +.nf +\f[C] +rspamadm\ keypair +\f[] +.fi +.SH SEE ALSO +.PP +Rspamd documentation and source codes may be downloaded from +. diff --git a/doc/rspamadm.1.md b/doc/rspamadm.1.md new file mode 100644 index 0000000..83c6c3e --- /dev/null +++ b/doc/rspamadm.1.md @@ -0,0 +1,85 @@ +% RSPAMADM(1) Rspamd User Manual + +# NAME + +rspamadm - rspamd administration utility + +# SYNOPSIS + +rspamadm [*global_options*] [*command*] [*command_options*]... + +# DESCRIPTION + +`rspamadm` is a routine to manage rspamd spam filtering system. It is intended to perform +such actions as merging databases, performing configuration tests, encrypting passwords, +signing configurations and so on. You can get a list of available **commands** by running + + rspamadm -l + +Also for each command you can check list of available **command_options** by running + + rspamadm help command + rspamadm command --help + + +# OPTIONS + +-h, \--help +: Show help message + +-v, \--verbose +: Enable verbose output + +-l, \--list-commands +: List available commands + +\--version +: Show version + +\--var=*value* +: Redefine ucl variable in format `VARIABLE=VALUE` + +# RETURN VALUE + +On exit `rspamadm` returns `0` if operation was successful and an error code otherwise. + +# EXAMPLES + +Get help for pw command: + + rspamadm help pw + rspamadm pw --help + +Encrypt controller's password: + + rspamadm pw encrypt + +Merge fuzzy databases: + + rspamadm fuzzy_merge -s data1.sqlite -s data2.sqlite -t dest.sqlite + +Perform configuration test: + + rspamadm configtest -c rspamd.conf + +Test configuration strictly and redefine some ucl vars: + + rspamadm --var=DBDIR=/tmp configtest -c ./rspamd.conf -s + + +Dump the processed configuration: + + rspamadm configdump + +Dump the processed configuration as JSON string: + + rspamadm configdump -j + +Generate a keypair to use for HTTPCrypt encryption: + + rspamadm keypair + +# SEE ALSO + +Rspamd documentation and source codes may be downloaded from +. diff --git a/doc/rspamc.1 b/doc/rspamc.1 new file mode 100644 index 0000000..0f823e6 --- /dev/null +++ b/doc/rspamc.1 @@ -0,0 +1,307 @@ +.\" Automatically generated by Pandoc 2.2.2.1 +.\" +.TH "RSPAMC" "1" "" "Rspamd User Manual" "" +.hy +.SH NAME +.PP +\f[C]rspamc\f[] \- rspamd command line client +.SH SYNOPSIS +.PP +rspamc [\f[I]options\f[]] [\f[I]command\f[]] [\f[I]input\-file\f[]]\&... +.PP +rspamc \[en]help +.SH DESCRIPTION +.PP +\f[C]rspamc\f[] is a simple rspamd client, primarily for classifying or +learning messages. +\f[C]rspamc\f[] supports the following commands: +.IP \[bu] 2 +Scan commands: +.RS 2 +.IP \[bu] 2 +\f[C]symbols\f[]: scan message and show symbols (default command) +.RE +.IP \[bu] 2 +Control commands +.RS 2 +.IP \[bu] 2 +\f[C]learn_spam\f[]: learn message as spam +.IP \[bu] 2 +\f[C]learn_ham\f[]: learn message as ham +.IP \[bu] 2 +\f[C]fuzzy_add\f[]: add message to fuzzy storage (check \f[C]\-f\f[] and +\f[C]\-w\f[] options for this command) +.IP \[bu] 2 +\f[C]fuzzy_del\f[]: delete message from fuzzy storage (check +\f[C]\-f\f[] option for this command) +.IP \[bu] 2 +\f[C]stat\f[]: show rspamd statistics +.IP \[bu] 2 +\f[C]stat_reset\f[]: show and reset rspamd statistics (useful for +graphs) +.IP \[bu] 2 +\f[C]counters\f[]: display rspamd symbols statistics +.IP \[bu] 2 +\f[C]uptime\f[]: show rspamd uptime +.IP \[bu] 2 +\f[C]add_symbol\f[]: add or modify symbol settings in rspamd +.IP \[bu] 2 +\f[C]add_action\f[]: add or modify action settings +.RE +.PP +Control commands that modify rspamd state are considered privileged and +require a password to be specified with the \f[C]\-P\f[] option (see +\f[B]OPTIONS\f[], below, for details). +.PD 0 +.P +.PD +This depends on a controller's settings and is discussed in the +\f[C]rspamd\-workers\f[] page (see \f[B]SEE ALSO\f[], below, for +details). +.PP +\f[C]Input\ files\f[] may be either regular file(s) or a directory to +scan. +If no files are specified \f[C]rspamc\f[] reads from the standard input. +Controller commands usually do not accept any input, however learn* and +fuzzy* commands requires input. +.SH OPTIONS +.TP +.B \-h \f[I]host[:port]\f[], \-\-connect=\f[I]host[:port]\f[] +Specify host and port +.RS +.RE +.TP +.B \-P \f[I]password\f[], \-\-password=\f[I]password\f[] +Specify control password +.RS +.RE +.TP +.B \-c \f[I]name\f[], \-\-classifier=\f[I]name\f[] +Classifier to learn spam or ham (bayes is used by default) +.RS +.RE +.TP +.B \-w \f[I]weight\f[], \-\-weight=\f[I]weight\f[] +Weight for fuzzy operations +.RS +.RE +.TP +.B \-f \f[I]number\f[], \-\-flag=\f[I]number\f[] +Flag for fuzzy operations +.RS +.RE +.TP +.B \-p, \-\-pass +Pass all filters +.RS +.RE +.TP +.B \-v, \-\-verbose +More verbose output +.RS +.RE +.TP +.B \-i \f[I]ip address\f[], \-\-ip=\f[I]ip address\f[] +Emulate that message was received from specified ip address +.RS +.RE +.TP +.B \-u \f[I]username\f[], \-\-user=\f[I]username\f[] +Emulate that message was received from specified authenticated user +.RS +.RE +.TP +.B \-d \f[I]user\@domain\f[], \-\-deliver=\f[I]user\@domain\f[] +Emulate that message was delivered to specified user (for +LDA/statistics) +.RS +.RE +.TP +.B \-F \f[I]user\@domain\f[], \-\-from=\f[I]user\@domain\f[] +Emulate that message has specified SMTP FROM address +.RS +.RE +.TP +.B \-r \f[I]user\@domain\f[], \-\-rcpt=\f[I]user\@domain\f[] +Emulate that message has specified SMTP RCPT address +.RS +.RE +.TP +.B \-\-helo=\f[I]helo_string\f[] +Imitate SMTP HELO passing from MTA +.RS +.RE +.TP +.B \-\-hostname=\f[I]hostname\f[] +Imitate hostname passing from MTA (rspamd assumes that it is verified by +MTA) +.RS +.RE +.TP +.B \-t \f[I]seconds\f[], \-\-timeout=\f[I]seconds\f[] +Timeout for waiting for a reply (can be floating point number, +e.g.\ 0.1) +.RS +.RE +.TP +.B \-b \f[I]host:port\f[], \-\-bind=\f[I]host:port\f[] +Bind to specified ip address +.RS +.RE +.TP +.B \-R, \-\-human +Output human readable report. +The first line of the output contains the message score and three +threshold scores, in this format: +.IP +.nf +\f[C] + score/greylist/addheader/reject,action=N:ACTION,spam=0|1,skipped=0|1 +\f[] +.fi +.RS +.RE +.TP +.B \-j, \-\-json +Output formatted JSON +.RS +.RE +.TP +.B \-\-ucl +Output UCL +.RS +.RE +.TP +.B \-\-raw +Output raw data received from rspamd (compacted JSON) +.RS +.RE +.TP +.B \-\-headers +Output HTTP headers from a reply +.RS +.RE +.TP +.B \-\-extended\-urls +Output URLs in an extended format, showing full URL, host and the part +of host that was used by surbl module (if enabled). +.RS +.RE +.TP +.B \-n \f[I]parallel_count\f[], \-\-max\-requests=\f[I]parallel_count\f[] +Maximum number of requests to rspamd executed in parallel (8 by default) +.RS +.RE +.TP +.B \-e \f[I]command\f[], \-\-execute=\f[I]command\f[] +Execute the specified command with either mime output (if \f[C]mime\f[] +option is also specified) or formatted rspamd output +.RS +.RE +.TP +.B \-\-mime +Output the full mime message instead of scanning results only +.RS +.RE +.TP +.B \-\-header=\f[I]header\f[] +Add custom HTTP header for a request. +You may specify header in format \f[C]name=value\f[] or just +\f[C]name\f[] for an empty header. +This option can be repeated multiple times. +.RS +.RE +.TP +.B \-\-sort=\f[I]type\f[] +Sort output according to a specific field. +For \f[C]counters\f[] command the allowed values for this key are +\f[C]name\f[], \f[C]weight\f[], \f[C]frequency\f[] and \f[C]hits\f[]. +Appending \f[C]:desc\f[] to any of these types inverts sorting order. +.RS +.RE +.TP +.B \-\-commands +List available commands +.RS +.RE +.SH RETURN VALUE +.PP +On exit \f[C]rspamc\f[] returns \f[C]0\f[] if operation was successful +and an error code otherwise. +.SH EXAMPLES +.PP +Check stdin: +.IP +.nf +\f[C] +rspamc\ <\ some_file +\f[] +.fi +.PP +Check files: +.IP +.nf +\f[C] +rspamc\ symbols\ file1\ file2\ file3 +\f[] +.fi +.PP +Learn files: +.IP +.nf +\f[C] +rspamc\ \-P\ pass\ learn_spam\ file1\ file2\ file3 +\f[] +.fi +.PP +Add fuzzy hash to set 2: +.IP +.nf +\f[C] +rspamc\ \-P\ pass\ \-f\ 2\ \-w\ 10\ fuzzy_add\ file1\ file2 +\f[] +.fi +.PP +Delete fuzzy hash from other server: +.IP +.nf +\f[C] +rspamc\ \-P\ pass\ \-h\ hostname:11334\ \-f\ 2\ fuzzy_del\ file1\ file2 +\f[] +.fi +.PP +Get statistics: +.IP +.nf +\f[C] +rspamc\ stat +\f[] +.fi +.PP +Get uptime: +.IP +.nf +\f[C] +rspamc\ uptime +\f[] +.fi +.PP +Add custom rule's weight: +.IP +.nf +\f[C] +rspamc\ add_symbol\ test\ 1.5 +\f[] +.fi +.PP +Add custom action's weight: +.IP +.nf +\f[C] +rspamc\ add_action\ reject\ 7.1 +\f[] +.fi +.SH SEE ALSO +.PP +Rspamd documentation and source code may be downloaded from +. diff --git a/doc/rspamc.1.md b/doc/rspamc.1.md new file mode 100644 index 0000000..335c225 --- /dev/null +++ b/doc/rspamc.1.md @@ -0,0 +1,173 @@ +% RSPAMC(1) Rspamd User Manual + +# NAME + +`rspamc` - rspamd command line client + +# SYNOPSIS + +rspamc [*options*] [*command*] [*input-file*]... + +rspamc --help + +# DESCRIPTION + +`rspamc` is a simple rspamd client, primarily for classifying or learning messages. +`rspamc` supports the following commands: + +* Scan commands: + * `symbols`: scan message and show symbols (default command) +* Control commands + * `learn_spam`: learn message as spam + * `learn_ham`: learn message as ham + * `fuzzy_add`: add message to fuzzy storage (check `-f` and `-w` options for this command) + * `fuzzy_del`: delete message from fuzzy storage (check `-f` option for this command) + * `stat`: show rspamd statistics + * `stat_reset`: show and reset rspamd statistics (useful for graphs) + * `counters`: display rspamd symbols statistics + * `uptime`: show rspamd uptime + * `add_symbol`: add or modify symbol settings in rspamd + * `add_action`: add or modify action settings + +Control commands that modify rspamd state are considered privileged and require a password to be specified with the `-P` option (see **OPTIONS**, below, for details). +This depends on a controller's settings and is discussed in the `rspamd-workers` page (see **SEE ALSO**, below, for details). + +`Input files` may be either regular file(s) or a directory to scan. If no files are specified `rspamc` reads +from the standard input. Controller commands usually do not accept any input, however learn* and fuzzy* commands +requires input. + +# OPTIONS + +-h *host[:port]*, \--connect=*host[:port]* +: Specify host and port + +-P *password*, \--password=*password* +: Specify control password + +-c *name*, \--classifier=*name* +: Classifier to learn spam or ham (bayes is used by default) + +-w *weight*, \--weight=*weight* +: Weight for fuzzy operations + +-f *number*, \--flag=*number* +: Flag for fuzzy operations + +-p, \--pass +: Pass all filters + +-v, \--verbose +: More verbose output + +-i *ip address*, \--ip=*ip address* +: Emulate that message was received from specified ip address + +-u *username*, \--user=*username* +: Emulate that message was received from specified authenticated user + +-d *user@domain*, \--deliver=*user@domain* +: Emulate that message was delivered to specified user (for LDA/statistics) + +-F *user@domain*, \--from=*user@domain* +: Emulate that message has specified SMTP FROM address + +-r *user@domain*, \--rcpt=*user@domain* +: Emulate that message has specified SMTP RCPT address + +\--helo=*helo_string* +: Imitate SMTP HELO passing from MTA + +\--hostname=*hostname* +: Imitate hostname passing from MTA (rspamd assumes that it is verified by MTA) + +-t *seconds*, \--timeout=*seconds* +: Timeout for waiting for a reply (can be floating point number, e.g. 0.1) + +-b *host:port*, \--bind=*host:port* +: Bind to specified ip address + +-R, \--human +: Output human readable report. The first line of the output contains the message score and three threshold scores, in this format: +: score/greylist/addheader/reject,action=N:ACTION,spam=0|1,skipped=0|1 + +-j, \--json +: Output formatted JSON + +\--ucl +: Output UCL + +\--raw +: Output raw data received from rspamd (compacted JSON) + +\--headers +: Output HTTP headers from a reply + +\--extended-urls +: Output URLs in an extended format, showing full URL, host and the part of host that was used by surbl module (if enabled). + +-n *parallel_count*, \--max-requests=*parallel_count* +: Maximum number of requests to rspamd executed in parallel (8 by default) + +-e *command*, \--execute=*command* +: Execute the specified command with either mime output (if `mime` option is also specified) or formatted rspamd output + +\--mime +: Output the full mime message instead of scanning results only + +\--header=*header* +: Add custom HTTP header for a request. You may specify header in format `name=value` or just `name` for an empty header. This option can be repeated multiple times. + +\--sort=*type* +: Sort output according to a specific field. For `counters` command the allowed values for this key are `name`, `weight`, `frequency` and `hits`. Appending `:asc` to any of these types inverts sorting order. + +\--commands +: List available commands + +# RETURN VALUE + +On exit `rspamc` returns `0` if operation was successful and an error code otherwise. + +# EXAMPLES + +Check stdin: + + rspamc < some_file + +Check files: + + rspamc symbols file1 file2 file3 + +Learn files: + + rspamc -P pass learn_spam file1 file2 file3 + +Add fuzzy hash to set 2: + + rspamc -P pass -f 2 -w 10 fuzzy_add file1 file2 + +Delete fuzzy hash from other server: + + rspamc -P pass -h hostname:11334 -f 2 fuzzy_del file1 file2 + +Get statistics: + + rspamc stat + +Get uptime: + + rspamc uptime + +Add custom rule's weight: + + rspamc add_symbol test 1.5 + +Add custom action's weight: + + rspamc add_action reject 7.1 + +# SEE ALSO + +Rspamd documentation and source code may be downloaded from +. + +[rspamd-workers]: https://rspamd.com/doc/workers/ diff --git a/doc/rspamd.8 b/doc/rspamd.8 new file mode 100644 index 0000000..325a507 --- /dev/null +++ b/doc/rspamd.8 @@ -0,0 +1,78 @@ +.TH "RSPAMD" "8" "" "Rspamd User Manual" "" +.SH NAME +.PP +rspamd \- main daemon for rapid spam filtering system +.SH SYNOPSIS +.PP +rspamd [\f[I]options\f[]]... +.PP +rspamd \-\-help +.SH DESCRIPTION +.PP +Rspamd filtering system is designed to be fast, modular and easily +scalable system. +Rspamd core is written in \f[C]C\f[] language using event driven +processing model. +Plugins for rspamd can be written in \f[C]Lua\f[] programming language. +Rspamd is designed to process connections completely asynchronous and do +not block anywhere in code. +.SH OPTIONS +.TP +.B \-f, \-\-no\-fork +Do not daemonize main process +.RS +.RE +.TP +.B \-c \f[I]path\f[], \-\-config=\f[I]path\f[] +Specify config file(s) +.RS +.RE +.TP +.B \-u \f[I]username\f[], \-\-user=\f[I]username\f[] +User to run rspamd as +.RS +.RE +.TP +.B \-g \f[I]groupname\f[], \-\-group=\f[I]groupname\f[] +Group to run rspamd as +.RS +.RE +.TP +.B \-p \f[I]path\f[], \-\-pid=\f[I]path\f[] +Path to pidfile +.RS +.RE +.TP +.B \-i, \-\-insecure +Ignore running workers as privileged users (insecure) +.RS +.RE +.SH EXAMPLES +.PP +Run rspamd daemon with default configuration: +.IP +.nf +\f[C] +rspamd +\f[] +.fi +.PP +Run rspamd in foreground with custom configuration: +.IP +.nf +\f[C] +rspamd\ \-f\ \-c\ ~/rspamd.conf +\f[] +.fi +.PP +Run rspamd specifying user and group: +.IP +.nf +\f[C] +rspamd\ \-u\ rspamd\ \-g\ rspamd\ \-c\ /etc/rspamd/rspamd.conf +\f[] +.fi +.SH SEE ALSO +.PP +Rspamd documentation and source codes may be downloaded from +. diff --git a/doc/rspamd.8.md b/doc/rspamd.8.md new file mode 100644 index 0000000..c7c811c --- /dev/null +++ b/doc/rspamd.8.md @@ -0,0 +1,57 @@ +% RSPAMD(8) Rspamd User Manual + +# NAME + +rspamd - main daemon for rapid spam filtering system + +# SYNOPSIS + +rspamd [*options*]... + +rspamd --help + +# DESCRIPTION + +Rspamd filtering system is designed to be fast, modular and easily scalable system. +Rspamd core is written in `C` language using event driven processing model. +Plugins for rspamd can be written in `Lua` programming language. +Rspamd is designed to process connections completely asynchronous and do not block anywhere in code. + +# OPTIONS + +-f, \--no-fork +: Do not daemonize main process + +-c *path*, \--config=*path* +: Specify config file(s) + +-u *username*, \--user=*username* +: User to run rspamd as + +-g *groupname*, \--group=*groupname* +: Group to run rspamd as + +-p *path*, \--pid=*path* +: Path to pidfile + +-i, \--insecure +: Ignore running workers as privileged users (insecure) + +# EXAMPLES + +Run rspamd daemon with default configuration: + + rspamd + +Run rspamd in foreground with custom configuration: + + rspamd -f -c ~/rspamd.conf + +Run rspamd specifying user and group: + + rspamd -u rspamd -g rspamd -c /etc/rspamd/rspamd.conf + +# SEE ALSO + +Rspamd documentation and source codes may be downloaded from +. \ No newline at end of file -- cgit v1.2.3