├── .gitignore ├── Makefile ├── README.md ├── docs ├── images │ └── dyneorg.svg ├── index.md └── stylesheets │ └── extra.css ├── man-to-md.pl └── src ├── cjit ├── docs │ ├── faq.md │ ├── filesystem.md │ ├── graphics.md │ ├── images │ │ ├── cjit_donut_race.gif │ │ ├── cjit_life_c.gif │ │ ├── cjit_nuklear.gif │ │ ├── cjit_opengl.gif │ │ ├── cjit_sdl2_noise.gif │ │ ├── dyneorg.svg │ │ └── favicon.png │ ├── index.md │ ├── manpage.md │ ├── sound.md │ └── tui.md ├── import-manpage.sh └── mkdocs.yml ├── dynebolic ├── README.md ├── docs │ ├── appendix.md │ ├── bootingonusb.md │ ├── developers.md │ ├── disclaimer.md │ ├── getting_started.md │ ├── images │ │ ├── OpenSnitchFalkonExample.png │ │ ├── OpenSnitchMain.png │ │ ├── browse.webp │ │ ├── choose.webp │ │ ├── diskspace.webp │ │ ├── dyneorg.svg │ │ ├── grub.webp │ │ ├── name-vm.webp │ │ ├── pick.webp │ │ ├── resources.webp │ │ └── vm-running.webp │ ├── index.md │ └── stylesheets │ │ └── extra.css └── mkdocs.yml ├── jaromail ├── docs │ ├── images │ │ ├── dyneorg.svg │ │ └── jaromail-shot.jpg │ ├── index.md │ └── stylesheets │ │ └── extra.css └── mkdocs.yml └── tomb ├── README.md ├── docs ├── Makefile ├── images │ ├── awesome-shot.webp │ ├── cryptounderstaker.webp │ ├── dyneorg.svg │ ├── github_tomb.webp │ ├── monmort1.webp │ ├── nerdonthestreet.webp │ ├── tomb_crew_hkm11.webp │ ├── tomb_n_bats.webp │ └── tomb_songs.webp ├── index.md ├── manpage.md └── stylesheets │ └── extra.css └── mkdocs.yml /.gitignore: -------------------------------------------------------------------------------- 1 | site 2 | env 3 | venv 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | projects ?= $(shell ls src) 2 | tmp := $(shell mktemp) 3 | 4 | all: 5 | @echo "List of documented projects in src:" 6 | @echo "${projects}" 7 | @echo 8 | @echo "Use 'make deploy' to publish modifications" 9 | 10 | deploy: 11 | -@for i in ${projects}; do git checkout master && \ 12 | cd src/$$i && mkdocs build && tar cf ${tmp} -C site . \ 13 | && cd - && git checkout gh-pages && mkdir -p $$i && tar xf ${tmp} -C $$i \ 14 | && grep -v '^Build\ Date' $$i/index.html > ${tmp} && mv ${tmp} $$i/index.html \ 15 | && rm -f $$i/sitemap.xml.gz \ 16 | && git add $$i && git commit -m "update $$i" && git push && git checkout master \ 17 | ; done 18 | @git checkout master 19 | 20 | deploy-root: 21 | -@mkdocs build && tar cf ${tmp} -C site . \ 22 | && git checkout gh-pages && tar xf ${tmp} -C . \ 23 | && grep -v '^Build\ Date' index.html > ${tmp} && mv ${tmp} index.html \ 24 | && rm -f sitemap.xml.gz 25 | @echo "ready to review, then commit and push to gh-pages" 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Documentation and Manauls at Dyne.org 2 | 3 | ## Install dependencies 4 | 5 | You need to have mkdocs and the material plugin installed: 6 | ``` 7 | apt-get install mkdocs 8 | pip install mkdocs-material 9 | ``` 10 | 11 | If your system is complaining that mkdocs-material is an externally-managed-environment, you can use `venv` instead: 12 | 13 | Create the virtual environment 14 | ``` 15 | python -m venv path/to/venv 16 | ``` 17 | Install mkdocs-material to the environment 18 | ``` 19 | path/to/venv/bin/pip install mkdocs-material 20 | ``` 21 | 22 | Activate the virtual environement 23 | ``` 24 | source path/to/venv/bin/activate 25 | ``` 26 | 27 | 28 | ## Create a new project 29 | 30 | Go inside the `src/` folder and use `mkdocs new name_of_project`. 31 | 32 | Beware the name you chose will also be in the url `https://dyne.org/docs/name_of_project`. 33 | 34 | Go inside the freshly created project folder and use mkdocs as usual 35 | 36 | 👁️ preview using `mkdocs serve` directly in each src/ folder. 37 | 38 | ⚠️⚠️ never do `mkdocs deploy`! But instead... 39 | 40 | ## Publish changes 41 | 42 | Go in the root of this repository and do `make deploy`. 43 | 44 | If there are no changes in the src files then an error will be returned and no commit created. 45 | 46 | Read carefully the errors returned because some warnings contain useful information. 47 | 48 | 49 | ## Further questions 50 | 51 | Ask Jaromil or Settoshi 52 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ECF8F7 !important; 3 | } 4 | .md-header { 5 | background-color: #36968C !important; 6 | } 7 | -------------------------------------------------------------------------------- /man-to-md.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # man-to-md -- Converts nroff man pages to Markdown. 4 | # Copyright © 2016-2020 Maximilian Eul 5 | # 6 | # This file is part of man-to-md. 7 | # 8 | # man-to-md is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # man-to-md is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with man-to-md. If not, see . 20 | 21 | use strict; 22 | use warnings; 23 | use utf8; 24 | use Getopt::Long qw(:config no_getopt_compat bundling); 25 | use File::Basename qw(dirname basename); 26 | chdir dirname($0); 27 | 28 | use constant { 29 | PROGNAME => basename($0), 30 | PROGVER => '0.17.0', 31 | PROGDATE => '2020-12-18', 32 | 33 | DEFAULT_COMMENT => "This file was autogenerated from the man page with 'make README.md'", 34 | }; 35 | 36 | my ($section, $subsection, $prev_section); 37 | my ($is_synopsis, $in_list, $start_list_item, $is_desclist, $in_rawblock, $in_preblock); 38 | my ($in_urltitle, $in_mailtitle); 39 | my ($progname, $mansection, $version, $is_bare_version, $verdate, $description); 40 | my ($lineopt, $line_did_set_options); 41 | my $headline_prefix = '# '; 42 | my $section_prefix = '# '; 43 | my $subsection_prefix = '### '; 44 | 45 | my $re_token = qr/(?:"(?:\.|[^"])*+"|(?:\\.|[^\s"])(?:\\.|\S)*+)/; # matches one token, with or without "enclosure". 46 | my $re_urlprefix = qr/(?:https?:|s?ftp:|www)/; 47 | my $re_url = qr/${re_urlprefix}.+?/; 48 | my $re_email = qr/(?:\w[\w\-_\.\+]*@[\w\-_\+\.]+?\.[\w\-]+)/; 49 | my $re_punctuation = qr/[\s,;\.\?!]/; 50 | 51 | my $replacement_token = "\001kXXfQ6Yd" . int(10000 * rand); 52 | 53 | my %paste_after_section = ( ); # ('section' => ['filename'...], ...) 54 | my %paste_before_section = ( ); 55 | my $plain_dashes = 1; 56 | my $code_formatting = 0; 57 | my $add_comment; 58 | 59 | my %strings = ( ); 60 | my %words = ( ); 61 | my %stopwords = map { $_ => 1 } (qw( 62 | a an the 63 | as at and but by for from nor or so yet while if on of off to it its it's 64 | on in onto into with within unless while after before once since until when since 65 | )); 66 | 67 | sub Syntax (;$) { 68 | printf STDERR < output.md 70 | Converts nroff man pages to Markdown. 71 | Options: 72 | -p, --paste-section-after SECTION:FILENAME 73 | Pastes the contents of FILENAME after the input SECTION 74 | and adds the filename as section title. 75 | -P, --paste-section-before SECTION:FILENAME 76 | Pastes the contents of FILENAME right before the input SECTION 77 | and adds the filename as section title. 78 | --paste-after SECTION:FILENAME Like -p, but does not add a section title. 79 | --paste-before SECTION:FILENAME Like -P, but does not add a section title. 80 | -c, --comment [COMMENT] Adds an invisible comment as first line. 81 | Uses a default comment without its argument. 82 | --escaped-dashes Don't remove the backslash from escaped dashes (\\-). 83 | -w, --word WORD Adds a word to the list of words 84 | not to be titlecased in chapter titles. 85 | -f, --formatted-code Allow formatting in nf/fi code blocks and Synopsis line. 86 | -h, --help Show program help 87 | -V, --version Show program version 88 | 89 | EOT 90 | exit ($_[0] // 0); 91 | } 92 | 93 | sub Version () { 94 | printf <, %s. 97 | License GPLv3+: GNU GPL Version 3 or later 98 | 99 | EOT 100 | exit; 101 | } 102 | 103 | GetOptions( 104 | 'paste-after=s@' => sub{ add_paste_file('after', split /:/, $_[1]) }, 105 | 'paste-before=s@' => sub{ add_paste_file('before', split /:/, $_[1]) }, 106 | 'p|paste-section-after=s@' => sub{ add_paste_file('after', split(/:/, $_[1]), 1) }, 107 | 'P|paste-section-before=s@' => sub{ add_paste_file('before', split(/:/, $_[1]), 1) }, 108 | 'escaped-dashes' => sub{ $plain_dashes = 0 }, 109 | 'c|comment:s' => sub{ $add_comment = (length $_[1]) ? $_[1] : DEFAULT_COMMENT }, 110 | 'f|formatted-code' => sub{ $code_formatting = 1 }, 111 | 'w|word=s' => sub{ $words{ lc $_[1] } = $_[1] }, 112 | 'h|help' => sub{ Syntax 0 }, 113 | 'V|version' => sub{ Version }, 114 | ); 115 | 116 | sub add_paste_file ($$$) { 117 | my ($op, $section, $filename, $add_section_title) = @_; 118 | die "file not readable: $filename" unless (-f $filename && -r $filename); 119 | my $addto = ($op eq 'after') 120 | ? \%paste_after_section 121 | : \%paste_before_section; 122 | push @{ $addto->{$section} }, {file => $filename, add_section_title => $add_section_title}; 123 | } 124 | 125 | # Install postprocessing function for all output: 126 | sub { 127 | my $pid = open(STDOUT, '|-'); 128 | return if $pid > 0; 129 | die "cannot fork: $!" unless defined $pid; 130 | 131 | # process entire output at once: 132 | local $/; 133 | local $_ = ; 134 | utf8::decode($_); 135 | 136 | # merge code blocks: 137 | s#(?:\n```\n```\n|\n
|\n\n?)# #g;
138 | 	s#(?:|
)##g;
139 | 	s#(?:\n\n\n|\n\n\n)# #g;
140 | 
141 | 	# ensure correct synposis format:
142 | 	s#(<(synopsis(?:Formatted)?)>.*)#postprocess_synopsis($1)#se;
143 | 
144 | 	# URLs:
145 | 	s/(\[[^\]]+) (?=\]\((?:$re_urlprefix|mailto:))/$1/g;  # remove trailing spaces in link titles
146 | 	s/^(.+)(?)(?:$)\n^(?:[\[\(]\*{0,2}($re_url)\*{0,2}[\]\)])($re_punctuation*)$/[$1]($2)$3/gm;
147 | 
148 | 	# Line breaks;
149 | 	s/\n *${replacement_token}#BRK#/  \n/g;
150 | 
151 | 	# Internal links:
152 | 	s=${replacement_token}#INTERNAL-LINK#\n? *(?:((?!<|<)[^\n]+)\n)? *(?:<|<)([^\n]+?)(?:>|>)($re_punctuation*)$=
153 | 		'[' . ($1 // $2) . '](' . $2 . ')' . $3
154 | 		=gme;
155 | 	s=${replacement_token}#LINK-TO#([^#]+)#\n? *(<|<|“|‘|")?([^\n]+?)((?:>|>|”|’|")?$re_punctuation*)?$=
156 | 		($2 // '') . '[' . $3 . '](#' . section_slug($1) . ')' . ($4 // '')
157 | 		=gme;
158 | 		# 1 target
159 | 		# 2 prefix
160 | 		# 3 link text
161 | 		# 4 suffix
162 | 
163 | 	# Clean up remaining markers:
164 | 	s/${replacement_token}#[\w\-]+#\n?//g;
165 | 
166 | 	# There should never be a linebreak after a NBSP, it defeats the entire purpose.
167 | 	s/(?<= )\n//g;
168 | 
169 | 	utf8::encode($_);
170 | 	print;
171 | 	exit;
172 | }->();
173 | 
174 | # nextline(keep_blanklines=false)
175 | #  Fetch next input line into $_.
176 | #  Returns true if there was an input line, false if EOF.
177 | #  If the first argument (keep_blanklines) is true,
178 | #  blank lines will be returned;
179 | #  by default, blank lines will be skipped.
180 | #  This function also removes all line comments (\")
181 | #  and block comments (.ig).
182 | sub nextline {
183 | 	my $keep_blanklines = $_[0] // 0;
184 | 	my $in_comment;
185 | 	do {{
186 | 		$_ = <>;
187 | 		return 0 unless defined;
188 | 
189 | 		# options for following line(s):
190 | 		$line_did_set_options = 0;
191 | 		if (s/^\.?\s*\\"\s*(PLAIN)\s*$//) {
192 | 			$line_did_set_options = 1;
193 | 			add_lineopt($1);
194 | 		}
195 | 
196 | 		# special markers in comments:
197 | 		s/^\.?\s*\\"\s*INTERNAL-LINK.*$/${replacement_token}#INTERNAL-LINK#/s  or
198 | 		s/^\.?\s*\\"\s*LINK-TO\s+([^\s#][^#\r\n]*)\s*$/${replacement_token}#LINK-TO#$1#/s  or
199 | 
200 | 		s/^\.\\".*$//  # remove line comment commands
201 | 		or
202 | 		s/^((?:\\[^"]|[^\\])++)\\".*$/$1/;  # remove line comments
203 | 
204 | 		if (m/^\.ig/ || $in_comment) {
205 | 			# block comment
206 | 			$in_comment = ! m/^\.\./;
207 | 			redo;
208 | 		}
209 | 
210 | 		# Keep reading if line ends with “\”, it's not truly finished yet:
211 | 		while (!eof && s/((?:\\{2})*)\\[\r\n]+$/$1/) {
212 | 			$_ .= <>;
213 | 		}
214 | 
215 | 	}} while (line_empty() && !$keep_blanklines);
216 | 	utf8::decode($_);
217 | 	1
218 | }
219 | 
220 | sub line_empty { m/^\s*$/ }
221 | 
222 | sub has_lineopt ($) { defined($lineopt) && $lineopt =~ m/\b$_[0]\b/ }
223 | sub add_lineopt ($) { $lineopt .= " $_[0] " }
224 | sub clr_lineopt ()  { undef $lineopt }
225 | 
226 | sub strip_highlighting {
227 | 	# remove remaining highlighting:
228 | 	s/(?:^\.[BIR] |\\f[BIRP1234])//g  unless $_[0];
229 | 	# get rid of .BR formatting, but correctly unquote its arguments:
230 | 	s/^\.[BIR]{2} *(.+)/alternating_highlighting('R', 'R', $1)/ge  unless $_[0];
231 | 
232 | 	# paragraphs:
233 | 	if (m/^\.br/i) {
234 | 		$_ = "${replacement_token}#BRK#";
235 | 		return
236 | 	} elsif (m/^\.(LP|P|PP|sp)\b/) {
237 | 		$_ = "\n";  # one blank line
238 | 		$in_list = 0;
239 | 	}
240 | 
241 | 	# known special characters:
242 | 	s/\\\(lq/“/g;
243 | 	s/\\\(rq/”/g;
244 | 	s/\\\(oq/‘/g;
245 | 	s/\\\(cq/’/g;
246 | 	s/\\\(ga/`/g;
247 | 	s/\\\(aq/'/g;
248 | 	s/\\\(dq/"/g;
249 | 	s/\\\(fm/′/g;
250 | 	s/\\\(sd/″/g;
251 | 	s/\\\(Fo/«/g;
252 | 	s/\\\(Fc/»/g;
253 | 	s/\\\(fo/‹/g;
254 | 	s/\\\(fc/›/g;
255 | 	s/\\\(hy/-/g;
256 | 	s/\\\(en/–/g;
257 | 	s/\\\(em/—/g;
258 | 	s/\\\(ha/^/g;
259 | 	s/\\\(lh/☜/g;
260 | 	s/\\\(rh/☞/g;
261 | 
262 | 	s/\\\(at/@/g;
263 | 	s/\\\(bu/·/g;
264 | 	s/\\\(ci/○/g;
265 | 	s/\\\(CR/↵/g;
266 | 	s/\\\(de/°/g;
267 | 	s/\\\(dg/†/g;
268 | 	s/\\\(dd/‡/g;
269 | 	s/\\\(lz/◊/g;
270 | 	s/\\\(mc/µ/g;
271 | 	s/\\\(OK/✓/g;
272 | 	s/\\\(ps/¶/g;
273 | 	s/\\\(ru/_/g;
274 | 	s/\\\(sc/§/g;
275 | 	s/\\\(sh/#/g;
276 | 	s/\\\(sq/□/g;
277 | 	s/\\\(ti/~/g;
278 | 
279 | 	s/\\\(ct/¢/g;
280 | 	s/\\\(Do/\$/;
281 | 	s/\\\([Ee]u/€/g;
282 | 	s/\\\(Ye/¥/g;
283 | 	s/\\\(Po/£/g;
284 | 	s/\\\(Cs/¤/g;
285 | 
286 | 	s/\\\(co/©/g;
287 | 	s/\\\(rg/®/g;
288 | 	s/\\\(tm/™/g;
289 | 
290 | 	s/\\\(ff/ff/g;
291 | 	s/\\\(fi/fi/g;
292 | 	s/\\\(Fi/ffi/g;
293 | 	s/\\\(fl/fl/g;
294 | 	s/\\\(Fl/ffl/g;
295 | 	s/\\\(12/½/g;
296 | 	s/\\\(14/¼/g;
297 | 	s/\\\(34/¾/g;
298 | 	s/\\\(38/⅜/g;
299 | 	s/\\\(58/⅝/g;
300 | 	s/\\\(78/⅞/g;
301 | 	s/\\\(S1/¹/g;
302 | 	s/\\\(S2/²/g;
303 | 	s/\\\(S3/³/g;
304 | 
305 | 	# unicode characters:
306 | 	s/\\\[u0*?([0-9a-fA-F]+)\]/ chr hex $1 /ge;
307 | 
308 | 	s/\\[ ~]/ /g;  # non-breakable space
309 | #	s/\\-/‑/g;  # non-breakable hyphen
310 | 	s/\\%//g;  # hyphenation command
311 | 
312 | 	# other special characters, except "\\":
313 | 	s/`/\\`/g;
314 | 	s/\\ / /g;
315 | 	s/\\-/-/g  if $plain_dashes;
316 | #	s/\\(.)/$1/g;
317 | 
318 | 	# non-printing zero-width characters, used to mask strings that are not commands:
319 | 	s/\\[&\)]//g;
320 | 	s/\\:/​/g;  # ZWSP
321 | 	# other unprintables and control characters:
322 | 	s/\\[\/,]//g;
323 | 
324 | 	# unknown \*X or \*(XX string usages not previously defined with .ds:
325 | 	s/^(?:\\[^\*]|[^\\])*?\K\\\*[^\s\(]//g;
326 | 	s/^(?:\\[^\*]|[^\\])*?\K\\\*\([^\s]{2}//g;
327 | 	# These regexes look a bit weird.
328 | 	# They prevent removal of non-string-sequence input like ...**\\\\**...
329 | 	# but excluding there patterns with a negative look-behind
330 | 	# won't work because it's not a fixed-length match.
331 | 	# TODO: Apply similar exclusions to all other backslash-escaped replacements in this sub?
332 | 
333 | 	utf8::encode($_);
334 | }
335 | 
336 | sub strip_html {
337 | 	# avoid accidental html output:
338 | 	my @result = map{
339 | 			s//>/g;
341 | 		$_ }
342 | 		($#_ >= 0 ? @_ : ($_));
343 | 	wantarray ? @result : $result[0]
344 | }
345 | 
346 | sub section_title {
347 | 	# If the current line contains a section title,
348 | 	# this function sets $section, $prev_section, and the $is_... flags accordingly
349 | 	# and returns true.
350 | 	return 0 unless m/^\.SH +(.+)$/m;
351 | 
352 | 	$in_list = 0;
353 | 	$prev_section = $section // '';
354 | 	$section = qtok($1);
355 | 	undef $subsection;
356 | 
357 | 	$is_synopsis = ($section eq 'SYNTAX' || $section eq 'SYNOPSIS');
358 | 	1
359 | }
360 | 
361 | sub subsection_title {
362 | 	return 0 unless m/^\.SS +(.+)$/m;
363 | 
364 | 	$in_list = 0;
365 | 	$subsection = qtok($1);
366 | 	1
367 | }
368 | 
369 | sub postprocess_synopsis {
370 | 	local $_ = $_[0];
371 | 
372 | 	# Turn fake block tags into correct markup:
373 | 	s#(.*)#```$1```#s ||
374 | 	s#^\n(.*)\n#
$1
#s; 375 | 376 | # Synopsis blocks are processed line-by-line, then merged by the global output postprocessing function. 377 | # This may cause spaces to be inserted at unexpected places. Remove them: 378 | s/ *${replacement_token}#BRK# */\n/gs; 379 | 380 | $_ 381 | } 382 | 383 | sub reformat_syntax { 384 | # commands to be ignored: 385 | if (m/^\.(?:PD|hy|ad|ft|fi|\s|$)/) { 386 | $_ = ''; 387 | return 388 | } 389 | 390 | # replace .ds strings: 391 | for my $sname (keys %strings) { 392 | if (length $sname == 1) { s/\\\*$sname/$strings{$sname}/g; } 393 | elsif (length $sname == 2) { s/\\\*\($sname/$strings{$sname}/g; } 394 | } 395 | 396 | # raw block markers: 397 | if (m/^\.(?:nf|co|cm)/) { 398 | if (has_lineopt('PLAIN')) { 399 | $in_preblock = 2; 400 | } else { 401 | $in_rawblock = 2; 402 | } 403 | if (m/^\.cm(?:\s+($re_token))?/) { 404 | chomp; 405 | $_ = qtok($1); 406 | strip_highlighting(); 407 | $_ = "\n**\`$_\`**\n\n" 408 | } elsif (m/^\.co/) { 409 | $_ = "\n" 410 | } else { 411 | $_ = '' 412 | } 413 | return 414 | } 415 | 416 | # command invocation in Synopsis section: 417 | if ($is_synopsis && !line_empty()) { 418 | # only code here 419 | chomp; 420 | if ($code_formatting) { 421 | # synopsis content with formatting 422 | $_ = strip_html($_); 423 | reformat_html(); 424 | strip_highlighting(); 425 | s/\\(.)/$1/g; # in md
 blocks, backslashes are not special!
426 | 			$_ = "\n$_\n\n"
427 | 		} else {
428 | 			strip_highlighting();
429 | 			$_ = "\n$_\n\n";
430 | 		}
431 | 		return
432 | 	}
433 | 
434 | 	# Usually we can get away with unescaped underscores.
435 | 	# But they'll lead to problems inside words that use \fI font changes.
436 | 	# So escape just these occurrences:
437 | 	s/(?=\S*\\f[IRP12]\S*)_/\\_/g;
438 | 
439 | 	# bold and italics:
440 | 	# (The special cases * and * are handled after the strip_html() call.)
441 | 	s/(?:\\f[B3])+([^\*_]|.{2,}?)(?:\\f[RP1])+/**$1**/g;
442 | 	s/(?:\\f[I2])+([^\*_]|.{2,}?)(?:\\f[RP1])+/_$1_/g;
443 | 	s/(?:\\f4)+([^\*_]|.{2,}?)(?:\\f[RP1])+/**_$1_**/g;
444 | 
445 | 	# groff concatenates tokens in .B and .I lines with spaces.
446 | 	# We still have to tokenize and re-join the line
447 | 	# to get rid of the token doublequote enclosures.
448 | 	s/^\.B +([^\*].*)/'**' . join(' ', tokenize($1)) . '**'/ge;
449 | 	s/^\.I +([^\*].*)/'_' . join(' ', tokenize($1)) . '_'/ge;
450 | 
451 | 	s/^\.([BIR])([BIR]) *(.+)/alternating_highlighting($1, $2, $3)/ge;
452 | 
453 | 	# other formatting:
454 | 	strip_highlighting(1);
455 | 
456 | 	# escape html tags:
457 | 	$_ = strip_html($_);
458 | 
459 | 	# process highlighting special cases:
460 | 	s#(?:\\f[B3])+(\*|_)(?:\\f[RP1])+#\\$1#g;
461 | 	s#(?:\\f[I2])+(\*|_)(?:\\f[RP1])+#\\$1#g;
462 | 	s#(?:\\f4)+(\*|_)(?:\\f[RP1])+#\\$1#g;
463 | 	s#^\.B +(\*.*)#'' . join(' ', tokenize($1)) . ''#ge;
464 | 	s#^\.I +(\*.*)#'' . join(' ', tokenize($1)) . ''#ge;
465 | 
466 | 	# remove remaining highlighting:
467 | 	s/(?:^\.[BIR]{1,2} |\\f[BIRP1234])//g;
468 | 
469 | 	if ($section eq 'AUTHOR' || $section eq 'AUTHORS') {
470 | 		# convert e-mail address to link:
471 | 		s/\b($re_email)\b/[$1](mailto:$1)/u;
472 | 	}
473 | 
474 | 	# item lists and description lists:
475 | 	if (m/^\.IP(?: +($re_token))?/ || m/^\.TP/) {
476 | 		my $tok = defined($1) ? qtok($1) : undef;
477 | 		my $is_bullet = (!defined($tok) || $tok eq '' || $tok eq '-' || $tok eq 'o');
478 | 		$is_desclist = !$is_bullet || (m/^\.TP/ && ($section ne 'EXIT CODES' && $section ne 'EXIT STATUS'));
479 | 		my $indent = ($in_list > 1)
480 | 			? '    ' x ($in_list - 1)
481 | 			: '';
482 | 		$_ = $indent . '* ';  # no trailing break here
483 | 		if ($is_bullet) {
484 | 			$start_list_item = 1;
485 | 		} else {
486 | 			$_ .= $tok . "  \n";
487 | 		}
488 | 		if (!$in_list) {
489 | 			$_ = "\n$_";
490 | 			$in_list = 1;
491 | 		}
492 | 	} elsif ($in_list && m/^\.RS/) {
493 | 		$in_list++;
494 | 		$_ = ''
495 | 	} elsif ($in_list && m/^\.RE/) {
496 | 		$in_list--;
497 | 		$_ = ''
498 | 	} elsif (m/^\.(?:RS|RE)/) {
499 | 		# ignore
500 | 		$_ = ''
501 | 	} elsif ($in_list) {
502 | 		if ($start_list_item) {
503 | 			$start_list_item = 0;
504 | 
505 | 			# In description list (probably some CLI options).
506 | 			# Add extra line break after option name:
507 | 			s/$/  /  if $is_desclist;
508 | 		} else {
509 | 			my $indent = ' ' x (2 + (4 * ($in_list - 1)));
510 | 			s/^/$indent/;
511 | 		}
512 | 	} elsif (m/\.UR ($re_url)\s*$/) {
513 | 		$in_urltitle = $1;
514 | 		$_ = '['
515 | 	} elsif (m/\.MT ($re_email)\s*$/) {
516 | 		$in_mailtitle = $1;
517 | 		$_ = '['
518 | 	} elsif (defined $in_urltitle && m/\.UE(?: (\S*)\s*)?$/) {
519 | 		$_ = "]($in_urltitle)" . ($1 // '') . "\n";
520 | 		undef $in_urltitle
521 | 	} elsif (defined $in_mailtitle && m/\.ME(?: (\S*)\s*)?$/) {
522 | 		$_ = "](mailto:$in_mailtitle)" . ($1 // '') . "\n";
523 | 		undef $in_mailtitle
524 | 	} elsif (defined $in_urltitle || defined $in_mailtitle) {
525 | 		s/[\r\n]+/ /g
526 | 	}
527 | 
528 | 	s/$/  /  if has_lineopt('BRK');
529 | 	clr_lineopt()  unless $line_did_set_options;
530 | }
531 | 
532 | sub reformat_html {
533 | 	s#\\f[B3](.+?)\\f[RP1]#$1#g;
534 | 	s#\\f[I2](.+?)\\f[RP1]#$1#g;
535 | 	s#\\f4(.+?)\\f[RP1]#$1#g;
536 | 	s#^\.B +(.+)#$1#g;
537 | 	s#^\.I +(.+)#$1#g;
538 | 	s/^\.([BIR])([BIR]) *(.+)/alternating_highlighting($1, $2, $3, 1)/ge;
539 | }
540 | 
541 | # Strips doublequote enclosure from string tokens, if present.
542 | sub qtok {
543 | 	my @result = map{ defined && m/^"(.+)"$/ ? $1 : $_ } @_;
544 | 	wantarray ? @result : $result[0]
545 | }
546 | 
547 | # Extracts all tokens from the input string and returns them in a list.
548 | # Tokens are things enclosed in unescaped doublequotes or any strings without spaces.
549 | sub tokenize { qtok($_[0] =~ m/$re_token/g) }
550 | 
551 | 
552 | sub section_slug ($) {
553 | 	local $_ = lc shift;
554 | 	s/[^\w\d\-_ ]//g;
555 | 	s/[ \-]+/-/g;
556 | 	$_
557 | }
558 | 
559 | sub section_anchor ($) { "" }
560 | 
561 | sub print_section_title    ($) {
562 | 	my $title = strip_html($_[0]);
563 | 	my $output = sprintf "\n%s\n\n%s%s\n\n", section_anchor($title), $section_prefix, $title;
564 | 	utf8::encode($output);
565 | 	print $output
566 | }
567 | 
568 | sub print_subsection_title ($) {
569 | 	my $title = strip_html($_[0]);
570 | 	my $output = sprintf "\n%s\n\n%s%s\n\n", section_anchor($title), $subsection_prefix, $title;
571 | 	utf8::encode($output);
572 | 	print $output
573 | }
574 | 
575 | sub paste_file (%) {
576 | 	my %args = @_;
577 | 	return 0 unless -r $args{'file'};
578 | 
579 | 	if ($args{'add_section_title'} && $args{'file'} =~ m/^(?:[a-zA-Z0-9_\-]+\/)*(.+)\.md$/) {
580 | 		my $section_title = $1;
581 | 		print_section_title $section_title;
582 | 	}
583 | 
584 | 	open FH, "< $args{'file'}";
585 | 	local $/;
586 | 	my $content = ;
587 | 	close FH;
588 | 
589 | #	$content =~ s/\s+$//;
590 | 	print "$content\n";
591 | 
592 | 	1
593 | }
594 | 
595 | sub alternating_highlighting {
596 | 	my @hl = @_[0, 1];
597 | 	my @tokens = tokenize($_[2]);
598 | 	my $do_html = $_[3] // 0;
599 | 	my $h = 0;
600 | 
601 | 	# groff concatenates tokens in .B and .I lines with spaces,
602 | 	# but tokens in .[BIR][BIR] lines are concatenated WITHOUT spaces.
603 | 	# Therefore we have to join('') the tokens here:
604 | 
605 | 	return join '', map {
606 | 		my $highlightkey = $hl[$h++ % 2];
607 | 
608 | 		if ($highlightkey eq 'R') {
609 | 			$_
610 | 		} elsif ($highlightkey eq 'I') {
611 | 			($do_html)
612 | 				? '' . $_ . ''
613 | 				: '_' . $_ . '_'
614 | 		} elsif ($highlightkey eq 'B') {
615 | 			($do_html)
616 | 				? '' . $_ . ''
617 | 				: '**' . $_ . '**'
618 | 		}
619 | 	} @tokens
620 | }
621 | 
622 | sub titlecase {
623 | 	local $_ = $_[0];
624 | 	my $re_word = '(\pL[\pL\d\'_]*)';
625 | 
626 | 	# lowercase stop words, keep casing of known words, else titlecase
627 | 	s!$re_word!$stopwords{lc $1} ? lc($1) : ($words{lc $1} // ucfirst(lc($1)))!ge;
628 | 	# capitalize first word following colon or semicolon
629 | 	s/ ( [:;] \s+ ) $re_word /$1\u$2/x;
630 | 	# titlecase first word (even a stopword), except if it's a known word
631 | 	s!^\s*$re_word!$words{lc $1} // ucfirst(lc($1))!e;
632 | 
633 | 	$_
634 | }
635 | 
636 | sub read_version {
637 | 	if ($_[0] eq '') {
638 | 		# no version string found
639 | 		$version = '';
640 | 		return 1
641 | 	}
642 | 
643 | 	if ($_[0] =~ m/^(?:$progname(?: \(\d\))?\s+)(?:v|ver\.?|version)? ?(\d[\w\.\-\+]*)$/i) {
644 | 		# found explicit version following known progname
645 | 		$is_bare_version = 1;
646 | 		$version = $1;
647 | 		return 1
648 | 	}
649 | 
650 | 	# found something else
651 | 	$version = $_[0];
652 | 	return 1
653 | }
654 | 
655 | ##############################
656 | 
657 | # eat first line, extract progname, version, and man section
658 | nextline()  or die "could not read first line";
659 | m/^.(?:Dd|Dt)\b/  and die "man page is in mdoc format which is not supported";
660 | m/^\.TH\b/  or die "first line does not contain '.TH' macro";
661 | m/^\.TH ($re_token)(?:\s|$)/  or die ".TH line doesn't contain page title";
662 | m/^\.TH ($re_token) ($re_token)(?: ($re_token)(?: ($re_token))?)?/  or die ".TH line doesn't contain man section";
663 | 
664 | ($progname, $mansection, $verdate) = (lc(qtok($1)), qtok($2), qtok($3));
665 | read_version(qtok($4 // ''));
666 | 
667 | # skip NAME headline, extract description
668 | if (nextline() && section_title() && $section eq 'NAME') {
669 | 	if (nextline() && m/ \\?(?:-|\\\(em|\\\(en) +(.+)$/) {
670 | 		$description = $1;
671 | 		nextline();
672 | 	}
673 | }
674 | 
675 | print "[//]: # ($add_comment)\n\n"  if defined $add_comment;
676 | printf "%s%s(%s)", $headline_prefix, strip_html($progname), $mansection;
677 | printf " - %s", strip_html($description)  if defined $description;
678 | print "\n\n";
679 | 
680 | # Fake section name 'HEADLINE' can be used
681 | # to paste additional content right after the headline
682 | # (but not before)
683 | if (defined $paste_after_section{'HEADLINE'}) {
684 | 	paste_file(%$_)  foreach (@{ $paste_after_section{'HEADLINE'} });
685 | 	undef $paste_after_section{'HEADLINE'};
686 | }
687 | 
688 | if ($version || $verdate) {
689 | 	if ($version) {
690 | 		print "Version "  if $is_bare_version;
691 | 		print $version;
692 | 	}
693 | 	if ($version && $verdate) {
694 | 		print ", ";
695 | 	}
696 | 	if ($verdate) {
697 | 		print $verdate;
698 | 	}
699 | 	print "\n\n";
700 | }
701 | 
702 | # skip SYNOPSIS headline
703 | nextline() if (section_title && $is_synopsis);
704 | 
705 | 
706 | do {{
707 | 	PARSELINE:
708 | 
709 | 	if ($in_rawblock) {
710 | 		if (m/^\.(?:fi|SH|cx)/) {
711 | 			# code block ends
712 | 			$in_rawblock = 0;
713 | 			print "
\n" if $code_formatting; 714 | print "\n" if m/^\.cx/; 715 | redo if m/^\.SH/; # .nf sections can be ended with .SH, but we still need to print the new section title too 716 | } elsif ($code_formatting) { 717 | # inside code block with limited html formatting 718 | if ($in_rawblock == 2) { 719 | $in_rawblock = 1; 720 | print "
";
721 | 			}
722 | 			$_ = strip_html($_);
723 | 			reformat_html;
724 | 			strip_highlighting;
725 | 			s/\\(.)/$1/g;  # in md 
 blocks, backslashes are not special!
726 | 			print
727 | 		} else {
728 | 			# inside code block without formatting
729 | 			strip_highlighting;
730 | 			s/\\(.)/$1/g;  # in md raw blocks, backslashes are not special!
731 | 			print "    $_"
732 | 		}
733 | 
734 | 	} elsif ($in_preblock) {
735 | 		if (m/^\.fi/) {
736 | 			# preformatted block ends
737 | 			$in_preblock = 0;
738 | 			$_ = '';
739 | 		} else {
740 | 			# Add two spaces at EOL to force visible linebreak:
741 | 			add_lineopt('BRK');
742 | 		}
743 | 		reformat_syntax;
744 | 		print
745 | 
746 | 	} elsif (section_title) {
747 | 		# new section begins
748 | 		if (defined $paste_after_section{$prev_section}) {
749 | 			paste_file(%$_)  foreach (@{ $paste_after_section{$prev_section} });
750 | 			undef $paste_after_section{$prev_section};
751 | 		}
752 | 		if (defined $paste_before_section{$section}) {
753 | 			paste_file(%$_)  foreach (@{ $paste_before_section{$section} });
754 | 			undef $paste_before_section{$section};
755 | 		}
756 | 		print_section_title titlecase($section)
757 | 
758 | 	} elsif (subsection_title) {
759 | 		# new subsection begins
760 | 		print_subsection_title $subsection
761 | 
762 | 	} elsif (m/^\.ds +(\S{1,2}) +"?(.+)$/) {
763 | 		$strings{ $1 } = $2
764 | 
765 | 	} elsif (m/^\.de\b/) {
766 | 		# macro definition -- skip completely
767 | 		1 while (nextline(1) && ! m/^\.\./);
768 | 
769 | 	} else {
770 | 		reformat_syntax;
771 | 		print
772 | 	}
773 | 
774 | }} while (nextline(1));
775 | 
776 | 
777 | # Paste section which haven't matched anything yet:
778 | # TODO: print warnings -- they probably should have gone somewhere else
779 | foreach (values %paste_before_section)
780 | 	{ paste_file(%$_)  foreach (@$_) }
781 | foreach (values %paste_after_section)
782 | 	{ paste_file(%$_)  foreach (@$_) }
783 | 
784 | 


--------------------------------------------------------------------------------
/src/cjit/docs/faq.md:
--------------------------------------------------------------------------------
 1 | # Frequently Asked Questions about CJIT
 2 | 
 3 | Here we try to answer the most asked questions.
 4 | 
 5 | ## What's different between `tcc -run` and CJIT?
 6 | 
 7 | The main difference is in usability.
 8 | 
 9 | CJIT improves three main UX aspects for now:
10 | 
11 | 1. It works as a single executable file which embeds the TinyCC
12 |    compiler, all its headers and its standard library. This way there
13 |    is no need to install anything system wide, check paths and setup
14 |    build folders.
15 | 
16 | 2. It supports adding multiple files into one execution: can accept
17 |    wildcards to ingest anything that is a C source, a pre-compiled
18 |    object or a shared library. The symbols exported by each file will
19 |    be visible to all during the same execution.
20 | 
21 | 3. It finds automatically common system libraries for each target
22 |    platform, avoiding the need to repeat these settings and look for
23 |    the right paths.
24 | 
25 | We are happy to further the improve developer experience with CJIT,
26 | and your advice is welcome: [open an issue](https://github.com/dyne/cjit/issues)!
27 | 
28 | ## What's different between `libgccjit` and CJIT?
29 | 
30 | CJIT is built as an command-line interpreter using the TinyCC backend
31 | for in-memory compilation. In the future it may also offer `libgccjit`
32 | as backend, as long as it will be possible to embed it all inside a
33 | single executable file, which is a core feature of CJIT's vision for
34 | developer experience.
35 | 
36 | ## Which parts of CJIT are licensed, under what?
37 | 
38 | Detailed licensing information for CJIT is in the [REUSE metadata
39 | file](https://github.com/dyne/cjit/blob/main/REUSE.toml). We check
40 | correctness of these attributions at every single commit.
41 | 
42 | All CJIT's original code is licensed using GNU GPL v3 and will be
43 | updated to use future versions of this license published by the Free
44 | Software Foundation. All included licenses are compatible with this.
45 | 
46 | We grant to everyone the freedome to use, study, modify, and
47 | redistribute modifications of CJIT as long as such modifications are
48 | licensed with one of the licenses already present: MIT, GPL or LGPL.
49 | 
50 | More information about CJIT's licensing is also found in its [manpage section on LICENSING](https://dyne.org/docs/cjit/manpage/#licensing).
51 | 
52 | ## Where to I send my corrections to this documentation?
53 | 
54 | You are welcome to [open an issue or a PR to the dyne/docs project](https://github.com/dyne/docs).
55 | 
56 | The source of the CJIT manual is in the markdown formatted files in `src/cjit/docs` inside the repository.
57 | 
58 | ## I have a new question, whom can I ask?
59 | 
60 | You are welcome to interact in public with Dyne.org hackers over any
61 | of [our channels and social network acconts](https://dyne.org/contact).
62 | 
63 | If you prefer to interact privately, write a mail to
64 | [info@dyne.org](mailto:info@dyne.org).
65 | 


--------------------------------------------------------------------------------
/src/cjit/docs/filesystem.md:
--------------------------------------------------------------------------------
 1 | 
 2 | # Filesystem operations
 3 | 
 4 | The [dmon](https://github.com/septag/dmon/) header is designed for
 5 | monitoring changes in the filesystem: simplifies the process of
 6 | tracking file modifications, deletions, and creations, allowing you to
 7 | respond to these events in real time within your C scripts.
 8 | 
 9 | Here is
10 | [examples/dmon.c](https://github.com/dyne/cjit/blob/main/examples/dmon.c)
11 | wich is tested to run on all CJIT platforms:
12 | 
13 | ```c
14 | #include 
15 | #include 
16 | 
17 | static void watch_callback(dmon_watch_id watch_id,
18 |                            dmon_action action,
19 |                            const char* rootdir,
20 |                            const char* filepath,
21 |                            const char* oldfilepath,
22 |                            void* user) {
23 |     (void)(user);
24 |     (void)(watch_id);
25 |     switch (action) {
26 |     case DMON_ACTION_CREATE:
27 |         fprintf(stderr,"CREATE: [%s]%s\n", rootdir, filepath);
28 |         break;
29 |     case DMON_ACTION_DELETE:
30 |         fprintf(stderr,"DELETE: [%s]%s\n", rootdir, filepath);
31 |         break;
32 |     case DMON_ACTION_MODIFY:
33 |         fprintf(stderr,"MODIFY: [%s]%s\n", rootdir, filepath);
34 |         break;
35 |     case DMON_ACTION_MOVE:
36 |         fprintf(stderr,"MOVE: [%s]%s -> [%s]%s\n",
37 |           rootdir, oldfilepath, rootdir, filepath);
38 |         break;
39 |     }
40 | }
41 | 
42 | int main(int argc, char* argv[]) {
43 |     if (argc > 1) {
44 |         dmon_init();
45 |         puts("waiting for changes ..");
46 |         dmon_watch(argv[1], watch_callback,
47 |           DMON_WATCHFLAGS_RECURSIVE, NULL);
48 |         getchar();
49 |         dmon_deinit();
50 |     } else {
51 |         puts("usage: test dirname");
52 |     }
53 |     return 0;
54 | }
55 | ```
56 | 
57 | # ⏩ [Next: Terminal User Interface](tui.md)
58 | 
59 | Go to the next chapter of this tutorial.
60 | 


--------------------------------------------------------------------------------
/src/cjit/docs/graphics.md:
--------------------------------------------------------------------------------
  1 | 
  2 | # CJIT for graphical applications
  3 | 
  4 | Be welcome to the exciting world of graphical C applications using SDL
  5 | ([Simple DirectMedia Layer](https://sdl.org)). SDL, originally
  6 | developed by Sam Lantinga in 1998, is a powerful, cross-platform
  7 | library designed to provide low-level access to audio, keyboard,
  8 | mouse, and graphics hardware via OpenGL and Direct3D.
  9 | 
 10 | !!! warn
 11 |     This part of the tutorial may be incomplete for Apple/OSX, please help testing and refining it!
 12 | 
 13 | ## Download the cjit-demo package
 14 | 
 15 | From now on this tutorial will guide you to launch more complex
 16 | applications, showing how to use libraries that are installed on your
 17 | system and shipped along with the source code.
 18 | 
 19 | To setup the demo environment you can simply run the command below:
 20 | 
 21 | === "MS/Windows"
 22 | 
 23 |     ```
 24 |     iex ((New-Object System.Net.WebClient).DownloadString('https://dyne.org/cjit/demo'))
 25 |     ```
 26 | 
 27 | === "Apple/OSX"
 28 | 
 29 |     ```
 30 |     curl -sL https://dyne.org/cjit/demo.sh | bash
 31 |     ```
 32 | 
 33 | === "GNU/Linux"
 34 | 
 35 |     ```
 36 |     curl -sL https://dyne.org/cjit/demo.sh | bash
 37 |     ```
 38 | 
 39 | 
 40 | ## The Beauty of Random
 41 | 
 42 | Execute [sdl2_noise.c](https://github.com/dyne/cjit/blob/main/examples/sdl2_noise.c) passing the source file as argument to CJIT, and since we are also using the SDL2 library we also need an extra parameter:
 43 | 
 44 | === "MS/Windows"
 45 | 
 46 |     ```
 47 |     .\cjit.exe examples/sdl2_noise.c SDL2.dll
 48 |     ```
 49 | 
 50 | === "Apple/OSX"
 51 | 
 52 |     ```
 53 |     ./cjit examples/sdl2_noise.c -lSDL2
 54 |     ```
 55 | 
 56 | === "GNU/Linux"
 57 | 
 58 |     ```
 59 |     ./cjit examples/sdl2_noise.c -lSDL2
 60 |     ```
 61 | 
 62 | 
 63 | ![A lousy rendering quality of random pixels](images/cjit_sdl2_noise.gif)
 64 | 
 65 | !!! info
 66 |     This preview looks blurred because video compression cannot deal well with randomness.
 67 | 
 68 | Have a look inside [sdl2_noise.c](https://github.com/dyne/cjit/blob/main/examples/sdl2_noise.c), and see the first line of code:
 69 | 
 70 | ### The "hashbang"
 71 | ```sh
 72 | #!/usr/bin/env cjit
 73 | ```
 74 | 
 75 | The source file can be launched as a script, when the CJIT interpreter is found in PATH.
 76 | 
 77 | !!! warning
 78 |     The hashbang works only on Apple/OSX and GNU/Linux, where scripts can be made executable with `chmod +x`
 79 | 
 80 | ### The pragma lib
 81 | 
 82 | Also see this pre-processor directive:
 83 | ```c
 84 | #pragma comment(lib, "SDL2")
 85 | ```
 86 | 
 87 | This line tells CJIT to link the `SDL2` shared library. It is the equivaled of `SDL2.dll` on the commandline, with the only difference that it can be specified inside the source code.
 88 | 
 89 | !!! info
 90 |     On Windows the DLL files need to be in the same directory of execution, or installed system-wide.
 91 | 
 92 | ## Three Dimensions
 93 | 
 94 | To draw accelerated graphics and 3D objects we'll use OpenGL libraries, which need to be installed on the system.
 95 | 
 96 | === "MS/Windows"
 97 |     [Install the Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/) which is distributed gratis by Microsoft.
 98 | 
 99 | === "Apple/OSX"
100 |     Not sure (help testing this please!)
101 | 
102 | === "GNU/Linux"
103 |     ```
104 |     sudo apt-get install libopengl-dev
105 |     ```
106 | 
107 | Then run CJIT passing the file [examples/opengl.c]((https://github.com/dyne/cjit/blob/main/examples/opengl.c) as argument, along with the same parameter to link SDL2.
108 | 
109 | ![Smoothly rotating red square](images/cjit_opengl.gif)
110 | 
111 | For more details on using OpenGL and SDL2 in C with shaders, read the
112 | [multi-platform-modern-opengl-demo-with-sdl2
113 | tutorial](https://shallowbrooksoftware.com/posts/a-multi-platform-modern-opengl-demo-with-sdl2/)
114 | on which our example code is based.
115 | 
116 | ## Nuklear widgets
117 | 
118 | Nuklear is a minimal, immediate-mode graphical user interface toolkit
119 | written in ANSI C and licensed under public domain. It is designed to
120 | be lightweight and highly customizable, and provides a wide range of
121 | components, including buttons, sliders, text input fields, and more,
122 | all of which can be integrated seamlessly with CJIT.
123 | 
124 | This time the code of our example is distributed across multiple files, this is a quick overview of what is found inside the `example` folder:
125 | ```
126 | .
127 | ├── nuklear
128 | │   ├── calculator.c
129 | │   ├── canvas.c
130 | │   ├── node_editor.c
131 | │   ├── overview.c
132 | │   └── style.c
133 | ├── nuklear.c
134 | └── nuklear.h
135 | ```
136 | 
137 | The main code of our example
138 | is
139 | [examples/nuklear.c](https://github.com/dyne/cjit/blob/main/examples/nuklear.c) and by default it will just start all modules.
140 | 
141 | Fire it up as usual with `./cjit.exe examples/nuklear.c` or equivalent commands on GNU/Linux and Apple/OSX.
142 | 
143 | And 💥Boom! enjoy Nuklear!
144 | 
145 | ![Pretty advanced GUI widgets shown](images/cjit_nuklear.gif)
146 | 
147 | # ⏩ [Next: sound with CJIT](sound.md)
148 | 
149 | Go to the next chapter of this tutorial.
150 | 


--------------------------------------------------------------------------------
/src/cjit/docs/images/cjit_donut_race.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/cjit/docs/images/cjit_donut_race.gif


--------------------------------------------------------------------------------
/src/cjit/docs/images/cjit_life_c.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/cjit/docs/images/cjit_life_c.gif


--------------------------------------------------------------------------------
/src/cjit/docs/images/cjit_nuklear.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/cjit/docs/images/cjit_nuklear.gif


--------------------------------------------------------------------------------
/src/cjit/docs/images/cjit_opengl.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/cjit/docs/images/cjit_opengl.gif


--------------------------------------------------------------------------------
/src/cjit/docs/images/cjit_sdl2_noise.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/cjit/docs/images/cjit_sdl2_noise.gif


--------------------------------------------------------------------------------
/src/cjit/docs/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/cjit/docs/images/favicon.png


--------------------------------------------------------------------------------
/src/cjit/docs/index.md:
--------------------------------------------------------------------------------
  1 | 
  2 | # Welcome to the CJIT Tutorial
  3 | 
  4 | CJIT is a versatile C interpreter based on TinyCC, designed to compile
  5 | C code in-memory and execute it live. This manual serves as a guide to
  6 | the full potential of CJIT, empowering you to efficiently develop and
  7 | test C programs in real-time.
  8 | 
  9 | This tutorial will guide you through practical usage examples, helping
 10 | you to swiftly integrate CJIT into your workflow. 📚🔧
 11 | 
 12 | ## Download CJIT
 13 | 
 14 | If you have already downloaded the CJIT executable for your running
 15 | system them you can skip this section.
 16 | 
 17 | If you like to download it by hand, go to the [CJIT release page](https://github.com/dyne/cjit/releases).
 18 | 
 19 | If you prefer to cut & paste a terminal script, pick one below for your running system:
 20 | 
 21 | === "MS/Windows"
 22 | 
 23 |     ```
 24 |     Invoke-WebRequest -OutFile "cjit.exe" -Uri "https://github.com/dyne/cjit/releases/latest/download/cjit.exe"
 25 |     ```
 26 | 
 27 | === "Apple/OSX"
 28 | 
 29 |     ```
 30 |     curl -sLo cjit https://github.com/dyne/cjit/releases/latest/download/cjit-$(uname)-$(uname -m)
 31 |     chmod +x cjit
 32 |     ```
 33 | 
 34 | === "GNU/Linux"
 35 | 
 36 |     ```
 37 |     source /etc/os-release
 38 |     curl -sLo cjit "https://github.com/dyne/cjit/releases/latest/download/cjit-$(uname -m)-${NAME,,}-${VERSION_ID}"
 39 |     chmod +x cjit
 40 |     ```
 41 | 
 42 | 
 43 | !!! info
 44 |     All Windows examples are made for PowerShell, on WSL then pick GNU/Linux.
 45 | 
 46 | ## Hello World!
 47 | 
 48 | This classic example will make you create a `hello.c` file and execute
 49 | it with CJIT to print the string "Hello World!" in the terminal.
 50 | 
 51 | Create hello.c by pasting these lines in the terminal:
 52 | 
 53 | === "MS/Windows"
 54 | 
 55 |     ```c
 56 |     @"
 57 |     #include 
 58 |     #include 
 59 |     int main(int argc, char **argv) {
 60 |       fprintf(stderr,"Hello, World!\n");
 61 |       exit(0);
 62 |     }
 63 |     "@| Out-File -FilePath "hello.c" -Encoding ASCII
 64 |     ```
 65 | 
 66 | === "Apple/OSX"
 67 | 
 68 |     ```bash
 69 |     cat << EOF > hello.c
 70 |     #!/usr/bin/env cjit
 71 |     #include 
 72 |     #include 
 73 |     int main(int argc, char **argv) {
 74 |       fprintf(stderr,"Hello, World!\n");
 75 |       exit(0);
 76 |     }
 77 |     EOF
 78 |     ```
 79 | 
 80 | === "GNU/Linux"
 81 | 
 82 |     ```bash
 83 |     cat << EOF > hello.c
 84 |     #!/usr/bin/env cjit
 85 |     #include 
 86 |     #include 
 87 |     int main(int argc, char **argv) {
 88 |       fprintf(stderr,"Hello, World!\n");
 89 |       exit(0);
 90 |     }
 91 |     EOF
 92 |     ```
 93 | 
 94 | Finally execute hello.c with CJIT:
 95 | 
 96 | === "MS/Windows"
 97 |     ```
 98 |     .\cjit.exe .\hello.c
 99 |     ```
100 | === "Apple/OSX"
101 |     ```
102 |     ./cjit hello.c
103 |     ```
104 | === "GNU/Linux"
105 |     ```
106 |     ./cjit hello.c
107 |     ```
108 | 
109 | 
110 | As a result you will see CJIT starting and printing "Hello World!"
111 | 
112 | ```
113 | CJIT v0.16.2 by Dyne.org
114 | Hello World!
115 | ```
116 | 
117 | You can play with `hello.c`, change what you want and run it again!
118 | 
119 | ## Flying Donuts
120 | 
121 | This example will print an animated donut on the terminal!
122 | 
123 | Create the `donut.c` file using the artful code below:
124 | 
125 | === "MS/Windows"
126 | 
127 |     ```c
128 |     @"
129 |                  i,j,k,x,y,o,N;
130 |              main(){float z[1760],a
131 |           #define R(t,x,y) f=x;x-=t*y\
132 |        ;y+=t*f;f=(3-x*x-y*y)/2;x*=f;y*=f;
133 |        =0,e=1,c=1,d=0,f,g,h,G,H,A,t,D;char
134 |      b[1760];for(;;){memset(b,32,1760);g=0,
135 |     h=1;memset(z,0,7040);for(j=0;j<90;j++){
136 |     G=0,H=1;for(i=0;i<314;i++){A=h+2,D=1/(G*
137 |     A*a+g*e+5);t=G*A        *e-g*a;x=40+30*D
138 |     *(H*A*d-t*c);y=          12+15*D*(H*A*c+
139 |     t*d);o=x+80*y;N          =8*((g*a-G*h*e)
140 |     *d-G*h*a-g*e-H*h        *c);if(22>y&&y>
141 |      0&&x>0&&80>x&&D>z[o]){z[o]=D;b[o]=(N>0
142 |       ?N:0)[".,-~:;=!*#$@"];}R(.02,H,G);}R(
143 |       .07,h,g);}for(k=0;1761>k;k++)putchar
144 |        (k%80?b[k]:10);R(.04,e,a);R(.02,d,
145 |          c);usleep(15000);printf('\n'+(
146 |             " donut.c! \x1b[23A"));}}
147 |               /*no math lib needed
148 |                  .@a1k0n 2021.*/
149 |     "@| Out-File -FilePath "donut.c" -Encoding ASCII
150 |     ```
151 | 
152 | === "Apple/OSX"
153 | 
154 | 
155 |     ```c
156 |     cat << EOF > donut.c
157 |                  i,j,k,x,y,o,N;
158 |              main(){float z[1760],a
159 |           #define R(t,x,y) f=x;x-=t*y\
160 |        ;y+=t*f;f=(3-x*x-y*y)/2;x*=f;y*=f;
161 |        =0,e=1,c=1,d=0,f,g,h,G,H,A,t,D;char
162 |      b[1760];for(;;){memset(b,32,1760);g=0,
163 |     h=1;memset(z,0,7040);for(j=0;j<90;j++){
164 |     G=0,H=1;for(i=0;i<314;i++){A=h+2,D=1/(G*
165 |     A*a+g*e+5);t=G*A        *e-g*a;x=40+30*D
166 |     *(H*A*d-t*c);y=          12+15*D*(H*A*c+
167 |     t*d);o=x+80*y;N          =8*((g*a-G*h*e)
168 |     *d-G*h*a-g*e-H*h        *c);if(22>y&&y>
169 |      0&&x>0&&80>x&&D>z[o]){z[o]=D;b[o]=(N>0
170 |       ?N:0)[".,-~:;=!*#$@"];}R(.02,H,G);}R(
171 |       .07,h,g);}for(k=0;1761>k;k++)putchar
172 |        (k%80?b[k]:10);R(.04,e,a);R(.02,d,
173 |          c);usleep(15000);printf('\n'+(
174 |             " donut.c! \x1b[23A"));}}
175 |               /*no math lib needed
176 |                  .@a1k0n 2021.*/
177 |     EOF
178 |     ```
179 | 
180 | === "GNU/Linux"
181 | 
182 |     ```c
183 |     cat << EOF > donut.c
184 |                  i,j,k,x,y,o,N;
185 |              main(){float z[1760],a
186 |           #define R(t,x,y) f=x;x-=t*y\
187 |        ;y+=t*f;f=(3-x*x-y*y)/2;x*=f;y*=f;
188 |        =0,e=1,c=1,d=0,f,g,h,G,H,A,t,D;char
189 |      b[1760];for(;;){memset(b,32,1760);g=0,
190 |     h=1;memset(z,0,7040);for(j=0;j<90;j++){
191 |     G=0,H=1;for(i=0;i<314;i++){A=h+2,D=1/(G*
192 |     A*a+g*e+5);t=G*A        *e-g*a;x=40+30*D
193 |     *(H*A*d-t*c);y=          12+15*D*(H*A*c+
194 |     t*d);o=x+80*y;N          =8*((g*a-G*h*e)
195 |     *d-G*h*a-g*e-H*h        *c);if(22>y&&y>
196 |      0&&x>0&&80>x&&D>z[o]){z[o]=D;b[o]=(N>0
197 |       ?N:0)[".,-~:;=!*#$@"];}R(.02,H,G);}R(
198 |       .07,h,g);}for(k=0;1761>k;k++)putchar
199 |        (k%80?b[k]:10);R(.04,e,a);R(.02,d,
200 |          c);usleep(15000);printf('\n'+(
201 |             " donut.c! \x1b[23A"));}}
202 |               /*no math lib needed
203 |                  .@a1k0n 2021.*/
204 |     EOF
205 |     ```
206 | 
207 | Then make the donut fly with CJIT!
208 | 
209 | === "MS/Windows"
210 |     ```
211 |     .\cjit.exe .\donut.c
212 |     ```
213 | === "Apple/OSX"
214 |     ```
215 |     ./cjit donut.c
216 |     ```
217 | === "GNU/Linux"
218 |     ```
219 |     ./cjit donut.c
220 |     ```
221 | 
222 | !!! warning
223 |     With this example and other programs, just hit **CTRL+C** to quit.
224 | 
225 | The state of affairs in CJIT is well demonstrated by this example: right now the terminal is much slower on windows (rightmost donut).
226 | 
227 | ![Two flying donuts, one running on GNU/Linux to the left and one on MS/Windows to the right](images/cjit_donut_race.gif)
228 | 
229 | ## Game of Life
230 | 
231 | Another fascinating example is the "Game of Life," a cellular
232 | automaton devised by the British mathematician John Horton Conway
233 | in 1970.
234 | 
235 | Our `life.c` example is part of the [cjit-demo.tar.gz](https://github.com/dyne/cjit/releases/latest/download/cjit-demo.tar.gz) package you should download to enjoy this and other demos in this tutorial. Download, extract and **copy the cjit executable inside the cjit-demo folder**. Below are quick sequence of commands to do that:
236 | 
237 | === "MS/Windows"
238 | 
239 |     ```
240 |     Invoke-WebRequest -OutFile "life.c" -Uri "https://github.com/dyne/cjit/raw/refs/heads/main/examples/life.c"
241 |     ```
242 | 
243 | === "Apple/OSX"
244 | 
245 |     ```
246 |     curl -sLo life.c https://github.com/dyne/cjit/raw/refs/heads/main/examples/life.c
247 |     ```
248 | 
249 | === "GNU/Linux"
250 | 
251 |     ```
252 |     curl -sLo life.c https://github.com/dyne/cjit/raw/refs/heads/main/examples/life.c
253 |     ```
254 | 
255 | Then execute the `life.c` source file passing it as argument to `cjit`, the same way it was done for the flying donut.
256 | 
257 | === "MS/Windows"
258 | 
259 |     ```
260 |     .\cjit.exe life.c
261 |     ```
262 | 
263 | === "Apple/OSX"
264 | 
265 |     ```
266 |     ./cjit life.c
267 |     ```
268 | 
269 | === "GNU/Linux"
270 | 
271 |     ```
272 |     ./cjit life.c
273 |     ```
274 | 
275 | Have a look around the `life.c` file with your favorite text editor and
276 | feel free to change things and see what happens.
277 | 
278 | ![Game of Life in ASCII animation](images/cjit_life_c.gif)
279 | 
280 | 
281 | # ⏩ [Next: graphics with CJIT](graphics.md)
282 | 
283 | Go to the next chapter of this tutorial.
284 | 


--------------------------------------------------------------------------------
/src/cjit/docs/manpage.md:
--------------------------------------------------------------------------------
  1 | # cjit(1) - Just-In-Time interpreter for C
  2 | 
  3 | CJIT, January 2025
  4 | 
  5 | 
cjit [options] <files> [-- app arguments]
  6 | 
  7 | 
  8 | 
  9 | [options] are prefixed by single or double dash and may require an argument
 10 | 
 11 | 
 12 | 
 13 | <files> can be one or more paths to any source (.c), object (.o) or libs (dll, dylib, .so)
 14 | 
 15 | 
 16 | 
 17 | [-- app args] all arguments following a double dash are passed as-is to the running application
18 | 19 | 20 | 21 | 22 | # Description 23 | 24 | **CJIT** 25 | is a lightweight C interpreter that lets you run C code 26 | instantly, without needing to build it first. In addition to 27 | just-in-time execution, it can do everything a C compiler does, 28 | including call functions from any installed library, and generate 29 | executables. It is also designed to be a drop-in replacement for gcc(1) 30 | and clang(1) for instance using CC=cjit as environment setting. 31 | 32 | 33 | 34 | 35 | # Options 36 | 37 | 38 | 39 | * -h 40 | Displays a summary of the command-line options available with \`cjit\`. It is useful for users who need a quick reference on how to use the tool. This manual is meant to complete that knowledge with more in-depth information. 41 | 42 | * -v 43 | Prints the version number of \`cjit\`. It's helpful for verifying the specific version you're working with, especially when troubleshooting or reporting issues: always include the version output. It can also be quickly added to any commandline combination to show the internal state of cjit, for instance include and library paths configured, cflags and libraries linked. 44 | 45 | * -q 46 | Suppresses all non-essential output, providing a quieter operation. Only critical errors are displayed. This option is turned on by default when CJIT is launched inside a script (no tty). 47 | 48 | * -C _<--various -C --flags>_ 49 | Use this option to specify custom flags for the interpreter or compiler. If not set, \`cjit\` uses the flags defined in the environment variable \`CFLAGS\`. 50 | 51 | * -c 52 | Only compiles a single provided source file, without executing it, to produce an object file. This option will generate a new pre-compiled object file named like the given source, changing its extension from .c to .o, unless a new name is specified using _-o_. 53 | 54 | * -o _<filename>_ 55 | Specifies a filename output. When included in a command-line it switches CJIT to _BUILD_ mode (see section below) and compiles all the source files into an executable but does not run the resulting program. You must provide the path for the output executable. 56 | 57 | * -D _key[=value]_ 58 | Defines a "macro" key (and optionally its value) for the preprocessor, just like a _#define_ directive would do when included inside the source. You can specify a simple symbol or use \`key=value\` to define a macro with a specific value. 59 | 60 | * -I _<path>_ 61 | Adds a directory path to the list of paths searched for header files. This is particularly useful if your project includes headers that are not in the standard system directories, for more information see the _PATHS_ section. 62 | 63 | * -l _<name>_> 64 | Links a specific shared library. On Windows the name is that of a .DLL file without its extension. On UNIX systems (GNU/Linux and BSD) one needs to provide the name of the library without the \`lib\` prefix (e.g., use \`-lssl\` for \`libssl.so\`). 65 | 66 | * -L _<path>_ 67 | Add a directory path to the library search paths. This is helpful when your project depends on libraries that are located in non-standard directories, for more information see the _PATHS_ section. 68 | 69 | * -e _<function>_ 70 | Specifies a different entry function than the default \`main\` function. It is useful if your program has multiple potential entry points, of you want to try a different one ... at your own risk. 71 | 72 | * -p _<path>_ 73 | Writes the process ID of the executing program to the specified file. This is useful for managing and monitoring the running process. 74 | 75 | * --verb 76 | Enables verbose logging, which provides more detailed information about the actions CJIT is performing. It's useful for debugging and understanding the compilation and execution process. 77 | 78 | * --xass _[path]_ 79 | Extract runtime assets required by CJIT to run you program. If a path is specified, the assets are extracted to that location; otherwise, they are extracted to the default directory, which is located in _AppData\\Local\\Temp\\CJIT-vN.N.N_ on Windows and in _/tmp/cjit-vN.N.N_ on POSIX systems. 80 | 81 | * --xtgz _<path>_ 82 | Extracts all files from a specified _USTAR_ format tar.gz archive. This is useful for setting up project dependencies or resources packaged in an archive, for instance is used to setup the _cjit-demo.tar.gz_ tutorial assets by the script found on _https://dyne.org/cjit/demo_. 83 | 84 | 85 | 86 | 87 | # Author 88 | 89 | 90 | This manual is Copyright (c) 2025 by the Dyne.org foundation 91 | 92 | Written by Denis Roio <_https://jaromil.dyne.org_> 93 | 94 | 95 | 96 | 97 | # Licensing 98 | 99 | 100 | **CJIT** 101 | is licensed under the GNU General Public License version 3 (GPLv3) or any later version published by the Free Software Foundation. 102 | **The GPLv3 grants you 4 freedoms:** 103 | **- Use:** 104 | Just like anyone else, you may use this software for any purpose. 105 | **- Study and Modify:** 106 | You may study how CJIT works, and modify it to make it do what you wish. 107 | **- Distribute:** 108 | You may redistribute copies of CJIT so that others can benefit from it. 109 | **- Distribute Modified Versions:** 110 | You may distribute your modifications if you grant others the same freedom. 111 | 112 | This is a human-readable summary of (and not a substitute for) the license. For the full text of the GPLv3 visit _https://www.gnu.org/licenses/gpl-3.0.html_. Components included in CJIT are copyright and licensed by their respective vendors, and all are compatible with the GPLv3: a list of component licenses is provided in CJIT's sourcecode inside the LICENSES/ folder and detailed by the REUSE.toml file. 113 | 114 | This manpage is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0) or any later version. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/. 115 | 116 | 117 | 118 | 119 | # Availability 120 | 121 | 122 | The most recent version of CJIT sourcecode and up to date 123 | documentation is made available from its website on 124 | _https://dyne.org/cjit_. 125 | 126 | 127 | 128 | 129 | # See Also 130 | 131 | **tcc**(1), 132 | 133 | -------------------------------------------------------------------------------- /src/cjit/docs/sound.md: -------------------------------------------------------------------------------- 1 | # Sound operations: play and record 2 | 3 | The [miniaudio](https://miniaud.io) header handles audio playback and 4 | capture with ease: you can seamlessly integrate audio functionality 5 | into your C code, creating immersive and interactive experiences for 6 | your users. 7 | 8 | Miniaudio provides two main sources of documentation 9 | 10 | - [The miniaudio Programmer's manual](https://miniaud.io/docs/manual/index.html) 11 | - [Various miniaudio examples](https://miniaud.io/docs/examples/index.html) 12 | 13 | Miniaudio includes both low level and high level APIs. The low level 14 | API is good for those who want to do all of their mixing themselves 15 | and only require a light weight interface to the underlying audio 16 | device. The high level API is good for those who have complex mixing 17 | and effect requirements. 18 | 19 | In miniaudio, objects are transparent structures. Unlike many other 20 | libraries, there are no handles to opaque objects which means you need 21 | to allocate memory for objects yourself. 22 | 23 | A config/init pattern is used throughout the entire library. The idea 24 | is that you set up a config object and pass that into the 25 | initialization routine. The advantage to this system is that the 26 | config object can be initialized with logical defaults and new 27 | properties added to it without breaking the API. 28 | 29 | Below and in 30 | [examples/miniaudio.c](https://github.com/dyne/cjit/blob/main/examples/miniaudio.c) 31 | is an example of sin wave synthesis that runs smoothly in CJIT: 32 | 33 | ```c 34 | #define MA_NO_DECODING 35 | #define MA_NO_ENCODING 36 | #define MINIAUDIO_IMPLEMENTATION 37 | #include 38 | #include 39 | #define DEVICE_FORMAT ma_format_f32 40 | #define DEVICE_CHANNELS 2 41 | #define DEVICE_SAMPLE_RATE 48000 42 | 43 | void data_callback(ma_device* pDevice, 44 | void* pOutput, 45 | const void* pInput, 46 | ma_uint32 frameCount) { 47 | ma_waveform* pSineWave; 48 | MA_ASSERT(pDevice->playback.channels == DEVICE_CHANNELS); 49 | pSineWave = (ma_waveform*)pDevice->pUserData; 50 | MA_ASSERT(pSineWave != NULL); 51 | ma_waveform_read_pcm_frames(pSineWave, pOutput, frameCount, NULL); 52 | (void)pInput; /* Unused in this example. */ 53 | } 54 | 55 | int main(int argc, char** argv) { 56 | ma_waveform sineWave; 57 | ma_device_config deviceConfig; 58 | ma_device device; 59 | ma_waveform_config sineWaveConfig; 60 | deviceConfig = ma_device_config_init(ma_device_type_playback); 61 | deviceConfig.playback.format = DEVICE_FORMAT; 62 | deviceConfig.playback.channels = DEVICE_CHANNELS; 63 | deviceConfig.sampleRate = DEVICE_SAMPLE_RATE; 64 | deviceConfig.dataCallback = data_callback; 65 | deviceConfig.pUserData = &sineWave; 66 | if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) { 67 | printf("Failed to open playback device.\n"); 68 | return -4; 69 | } 70 | printf("Device Name: %s\n", device.playback.name); 71 | sineWaveConfig = ma_waveform_config_init(device.playback.format, 72 | device.playback.channels, 73 | device.sampleRate, 74 | ma_waveform_type_sine, 75 | 0.2, 220); 76 | ma_waveform_init(&sineWaveConfig, &sineWave); 77 | if (ma_device_start(&device) != MA_SUCCESS) { 78 | printf("Failed to start playback device.\n"); 79 | ma_device_uninit(&device); 80 | return -5; 81 | } 82 | printf("Press Enter to quit...\n"); 83 | getchar(); 84 | ma_device_uninit(&device); 85 | (void)argc; 86 | (void)argv; 87 | return 0; 88 | } 89 | ``` 90 | 91 | # ⏩ [Next: filesystem operations](filesystem.md) 92 | 93 | Go to the next chapter of this tutorial. 94 | -------------------------------------------------------------------------------- /src/cjit/docs/tui.md: -------------------------------------------------------------------------------- 1 | # Terminal User Interface 2 | 3 | Believe it or not, one can draw a beautiful terminal user interface 4 | (also called TUI) on a text console, with colors and blinking lights 5 | too. Our choice is to use [termbox2](https://github.com/termbox/termbox2) 6 | whose API that improves a lot on old approaches as ncurses 7 | or slang, by [sucking much less](https://suckless.org) `:^)` 8 | 9 | Here is a quick synopsis: 10 | 11 | ```c 12 | #define TB_IMPL 13 | #include "termbox2.h" 14 | 15 | int main(int argc, char **argv) { 16 | struct tb_event ev; 17 | int y = 0; 18 | 19 | tb_init(); 20 | 21 | tb_printf(0, y++, TB_GREEN, 0, "hello from termbox"); 22 | tb_printf(0, y++, 0, 0, "width=%d height=%d", 23 | tb_width(), tb_height()); 24 | tb_printf(0, y++, 0, 0, "press any key..."); 25 | tb_present(); 26 | 27 | tb_poll_event(&ev); 28 | 29 | y++; 30 | tb_printf(0, y++, 0, 0, "event type=%d key=%d ch=%c", 31 | ev.type, ev.key, ev.ch); 32 | tb_printf(0, y++, 0, 0, "press any key to quit..."); 33 | tb_present(); 34 | 35 | tb_poll_event(&ev); 36 | tb_shutdown(); 37 | 38 | return 0; 39 | } 40 | ``` 41 | 42 | The termbox2 basic API is self explanatory: 43 | 44 | ```c 45 | int tb_init(); 46 | int tb_shutdown(); 47 | 48 | int tb_width(); 49 | int tb_height(); 50 | 51 | int tb_clear(); 52 | int tb_present(); 53 | 54 | int tb_set_cursor(int cx, int cy); 55 | int tb_hide_cursor(); 56 | 57 | int tb_set_cell(int x, int y, uint32_t ch, 58 | uintattr_t fg, uintattr_t bg); 59 | 60 | int tb_peek_event(struct tb_event *event, 61 | int timeout_ms); 62 | int tb_poll_event(struct tb_event *event); 63 | 64 | int tb_print(int x, int y, 65 | uintattr_t fg, uintattr_t bg, 66 | const char *str); 67 | int tb_printf(int x, int y, 68 | uintattr_t fg, uintattr_t bg, 69 | const char *fmt, ...); 70 | ``` 71 | 72 | To see a demo of what it can do, see the 73 | [examples/termbox.c](https://github.com/dyne/cjit/blob/main/examples/termbox2.c) 74 | example which will draw a keyboard on your terminal and show the keys 75 | you are pressing in real-time. Its code is a great source of knowledge 76 | about what termbox2 can do! 77 | -------------------------------------------------------------------------------- /src/cjit/import-manpage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | [ -r "$1" ] || { 5 | >&2 echo "cjit.1 manpage not found, pass path as argument, i.e:" 6 | >&2 echo "~/devel/cjit/docs/cjit.1" 7 | exit 1 8 | } 9 | res=0 10 | out=docs/manpage.md 11 | #tmp=`mktemp` 12 | #pandoc --to asciidoc $1 > ${tmp} || res=1 13 | #asciidoctor -b manpage ${1} -o docs/manpage.md || res=1 14 | #cat "$1" | groff -mandoc -Thtml > ${tmp} 15 | #pandoc --to markdown ${tmp} > ${out} 16 | #rm -f ${tmp} 17 | perl ../../man-to-md.pl -f "$1" > "$out" 18 | [ "$res" = "0" ] && { 19 | >&2 echo "Manpage written to: $out" 20 | } 21 | exit $res 22 | -------------------------------------------------------------------------------- /src/cjit/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: CJIT Tutorial 2 | site_url: https://dyne.org/docs/cjit 3 | copyright: CJIT Tutorial written by Jaromil, Copyright © 2024-2025 Dyne.org Foundation 4 | 5 | theme: 6 | name: material 7 | logo: images/dyneorg.svg 8 | favicon: images/favicon.png 9 | features: 10 | - content.tabs.link 11 | 12 | extra: 13 | social: 14 | - icon: fontawesome/brands/github 15 | link: https://github.com/dyne/cjit 16 | - icon: fontawesome/brands/linkedin 17 | link: https://www.linkedin.com/company/dyne-org/ 18 | generator: false 19 | 20 | #extra_css: 21 | # - stylesheets/extra.css 22 | 23 | nav: 24 | - Introduction: index.md 25 | - Graphics: graphics.md 26 | - Sound: sound.md 27 | - Filesystem: filesystem.md 28 | - Text UI: tui.md 29 | - Manpage: manpage.md 30 | - FAQ: faq.md 31 | 32 | markdown_extensions: 33 | - attr_list 34 | - md_in_html 35 | - admonition 36 | - pymdownx.details 37 | - pymdownx.superfences 38 | - pymdownx.tabbed: 39 | alternate_style: true 40 | slugify: !!python/object/apply:pymdownx.slugs.slugify 41 | kwds: 42 | case: lower 43 | -------------------------------------------------------------------------------- /src/dynebolic/README.md: -------------------------------------------------------------------------------- 1 | # Dynebolic documentation source 2 | 3 | This docuementation is built with mkdocs using the Material template. 4 | 5 | Test locally: 6 | - Clone the repo: `git clone https://git.devuan.org/sakrecoer/dynebolic-documentation.git` 7 | - Install mkdocs-material: `pip install mkdocs-material` 8 | - `cd` into your local clone of the repo and run `mkdocs serve `. The prompt will inform you of the URL where you can test your changes. 9 | 10 | -------------------------------------------------------------------------------- /src/dynebolic/docs/appendix.md: -------------------------------------------------------------------------------- 1 | # Appendix II: The Dyne Foundation 2 | 3 | *Dynebolic* is brought to you by the [Dyne Foundation](https://dyne.org). The Dyne Foundation is a *think & do tank*, born as an on-line community in 1999 by uniting artists, activists and hackers of mixed backgrounds. It is also a young research organization working on a growing number of succesful projects for the European Commission. These are its three guiding principles: 4 | 5 | - **Diversity**: We love to mix: methods, disciplines, knowledge, 6 | culture and languages. We love our Bastard Culture! 7 | - **Open-source**: Code is our literature: we build software to 8 | communicate, interact and inspire. Dyne.org is where art, science 9 | and technology meet open source. 10 | - **Ecology**: We recycle old technology rather than create needs for 11 | new one: this is our way to respect the environment and optimize 12 | resources. 13 | 14 | The Dyne Foundation develops and promotes projects focused on free software and free culture, and hosts the development of [a large selection of free software](https://dyne.org/software/). Notably, the Dyne Foundation hosts and supports the development of the [Devuan](https://www.devuan.org/) "init freedom" Linux Distribution, which *dynebolic* is based on. 15 | 16 | ## Appendix III: Links and other sources of information 17 | 18 | ## Further info 19 | 20 | ## Other Documentation sources 21 | 22 | ## Online Communities 23 | 24 | - [Fediverse (Lemmy)](https://fed.dyne.org/c/dynebolic) 25 | - Bridged chats: 26 | - [Matrix](https://socials.dyne.org/matrix-dynebolic) 27 | - [IRC](https://irc.dyne.org/?channels=dynebolic) 28 | 29 | ## License 30 | 31 | GFDL, I believe. 32 | -------------------------------------------------------------------------------- /src/dynebolic/docs/bootingonusb.md: -------------------------------------------------------------------------------- 1 | # Booting dynebolic 2 | 3 | There are many ways to boot dynebolic on your computer. First, you need to [download the ISO](https://dyne.org/dynebolic/download/) file and verify the checksum. 4 | 5 | ## Booting from usb 6 | 7 | ### On windows 8 | 9 | On Windows you can use an application called [Rufus](https://rufus.ie/) to flash the ISO file to a USB drive. 10 | The interface is very intuitive, plug the usb stick, select the volume to install on and the ISO image you just downloaded to install. After pressing start it will recognize the image and will ask you to either install normally or in `dd mode`, **please select `dd mode`**. 11 | 12 | ### On GNU+Linux 13 | 14 | On GNU+Linux, find the device name of your USB stick, with this command: 15 | 16 | ``` 17 | lsblk -o NAME,SIZE,RO,TYPE,VENDOR,HOTPLUG 18 | ``` 19 | 20 | The name you are looking for should be something like `/dev/sdX` (where "X" is a letter defined by your system). Read the information carefully, because it will include de `sdX` name of the main drive of your computer. Once you've determined the name of your USB stick, run this command as root: 21 | 22 | ``` 23 | dd bs=4M if=path/to/dynebolicIV.iso of=/dev/sdX status=progress && sync 24 | ``` 25 | 26 | !!! note 27 | 28 | You *have* to adapt this line so that "X" represents its actual value in your system. 29 | 30 | Once this command has completed, the USB stick will be ready to boot. 31 | 32 | **Be sure to know the hotkey to press at boot for boot selection, or bios interface to configure USB boot**. 33 | 34 | --- 35 | 36 | ## Booting in a Virtual Machine 37 | 38 | A virutal machine allows you to run an Operative System within your running Operative system. This way you can leverage all that dynebolic has to offer without the need to install it on your machine. 39 | 40 | #### Virtual Machine Manager 41 | 42 | One of the most user-friendly ways to run dynebolic in a virutal machine on GNU+Linux is by using [Virtual Machine Manager](https://virt-manager.org/). This tool will provide you with a GUI and take care of many complicated parts such as the routing of your physical audio and network devices more or less seemlessly. It also sets everything up to have copy+paste working from your physical machine's desktop to dynebolic within its virtual machine. 43 | 44 | To install Virtual Machine Manager, follow the [instructions on their website](https://virt-manager.org/) 45 | 46 | Once installed you can run it an add a virtual machine. To do this follow these intstructions: 47 | 48 | Hit the "+" button in the upper left corner of the GUI. You will be presented with a prompt asking you to choose how you would like to install the operative system. 49 | 50 |
51 | ![Chose "Local install media"](images/choose.webp) 52 |
Chose "Local install media"
53 |
54 | 55 | In the next panel, you are asked to pick the file you want to use. 56 | 57 |
58 | ![Pick the isofile](images/pick.webp) 59 |
Chose ISO
60 |
61 | 62 | This will open a prompt that allows you browse your file system. Click "Browse Local" and locate the ISO file you downloaded from dynebolic.org 63 | 64 |
65 | ![Pick the isofile](images/browse.webp) 66 |
Pick the ISO file you downloaded
67 |
68 | 69 | After this you will come back to the previous window and get to chose an operating system. Since Devuan is based on Debian chose, "Debian 12" and click "Forward". 70 | 71 | In the next prompt, you are invited to allocate resources to the virtual machines in terms of CPU cores and RAM. You can safely allocate half of your resouces for both. In this example the machine has 4 cores and 4GB (4096 bytes) ram. So we allocate 2 cores and 2Gb (2048 bytes) RAM. 72 | 73 |
74 | ![Alocate resources](images/resources.webp) 75 |
Alocate resources
76 |
77 | 78 | In the next prompt, you can allocate disk space to your virtual machine. This is a file that will be mounted as if it was a drive. It will contain all the data you create, so you might want to choose a good location for it. The extention for the file is `.qcow2`. In the screenshot bellow, we gave it 10Gb and stored the file in `~/Documents/dynebolic.qcow2` 79 | 80 |
81 | ![Alocate diskspace](images/diskspace.webp) 82 |
Alocate diskspace
83 |
84 | 85 | We then get a chance to review the settings and name the Virtual Machine. Let's name it "dynebolic" and click "Finish". 86 | 87 |
88 | ![Name the Virtual Machine](images/name-vm.webp) 89 |
Name the Virtual Machine
90 |
91 | 92 | This will initiate the virtual machine and you should now see a window displaying a virtual screen with a boot slection. Pick the first entry by hiting the Enter key on your keyboard. 93 | 94 |
95 | ![Run the Virtual Machine](images/vm-running.webp) 96 |
Run the Virtual Machine
97 |
98 | 99 | **Voilà! Give a few moments, and dynebolic will boot inside your computer.** 100 | 101 | --- 102 | 103 | #### QEMU (TODO) 104 | [QEMU](https://www.qemu.org/) is a generic and open source machine emulator and virtualizer. 105 | 106 | 107 | 108 | 109 | 110 | ### On windows (todo) 111 | -------------------------------------------------------------------------------- /src/dynebolic/docs/developers.md: -------------------------------------------------------------------------------- 1 | # For Developers 2 | 3 | **Greetings, fellow devel!** 🖖🏽 4 | 5 | *dynebolic* welcomes contributions, big and small. You are here by invited to [clone the repository](https://git.devuan.org/jaromil/dynebolic) localy and [get yourself an account on the Devuan Gitea](https://git.devuan.org/user/sign_up). For your convenience the repository is mirrored on [GitHub](https://github.com/dyne/dynebolic/). However, due to the ownership model of GitHub we encourage you to stick to the Devuan Gitea. From the Gitea interface you will be able to fork the repository and [send Pull Requests](https://docs.gitea.com/next/usage/pull-request). But you are welcome to ask for write permission in the bridged chat. 6 | 7 | ## Source code 8 | 9 | **[https://git.devuan.org/jaromil/dynebolic](https://git.devuan.org/jaromil/dynebolic)** 10 | 11 | ## Come talk to us 12 | 13 | - [IRC](https://irc.dyne.org/?channels=dynebolic) 14 | - [Matrix](https://socials.dyne.org/matrix-dynebolic) 15 | 16 | These channels are all bridge, meaning it doesn't matter whether you are using one or the other, you will be able to communicate with everyone. 17 | 18 | ## The dynebolic SDK 19 | 20 | ## Dynebolic Modules 21 | 22 | ## System Development 23 | 24 | ## Developing For The Desktop 25 | 26 | The *dynebolic* SDK offers various workflows. To get the full list of targets, `cd` into your cloned repository and run `make`. This will present you with a list of Make targets that will help you contribute to the project. 27 | 28 | ### Getting dynebolic development up and running 29 | 30 | The two workflows Desktop devleopers are interested in are "Quick start": 31 | 32 | ``` 33 | ---- __ Quick start: 34 | deps 🛠 Install development dependencies 35 | setup 📥 Download the latest development ROOT modules 36 | system 🗿 Build the root system: dyneIV-root 37 | iso 🏁 Create the current ISO image 38 | qemu 🖥 Emulate UEFI USB boot using qemu 39 | burn 🔥 Write the ISO to a removable USB=/dev/sd? 40 | ``` 41 | 42 | and "Snapshot testing" 43 | 44 | ``` 45 | ----- __ Snapshot testing functions: 46 | snap-iso 🧨 Test a squashed snapshot as ISO FILE=path 47 | snap-mount 👀 Explore the contents of a snapshot FILE=path 48 | snap-umount 🔌 Stop exploring and unplug the snapshot 49 | test-changes 🍳 Test current changes in home and static 50 | 51 | ``` 52 | Most of these `make` commands need to be run as root. This can be achieved in different ways depending on your operating system. 53 | 54 | To bootstrap your Desktop development environement, follow this sequence: 55 | 56 | 1. `make deps` (requires root) 57 | 2. `make setup` (requires root) 58 | 3. `make system` (requires root) 59 | 4. `make iso` (requires root) 60 | 61 | Each command will take a moment to complete and be quite verbose. Don't fear it. It might look scary, but your computer is talking to you, so listen! 62 | 63 | Once you have ran all of the four commands, there will be a new file in your local repository called `dynebolic.iso`. This is an image of the dynebolic install disk. 64 | 65 | You can now test it by running: 66 | 67 | 5. `make qemu` 68 | 69 | This will start a virtual environement in which dynebolic will boot. If everything was made correctly, you will see the grub menu. Pick the first entry. 70 | 71 |
72 | ![Image title](./images/grub.webp) 73 |
grub menu
74 |
75 | 76 | Soon see the desktop appear. Once it does, you can proceed and make changes to the desktop and then export them. Even though it is slightly more time consuming, it is advisable to make one change and export at the time. 77 | 78 | ### Export changes 79 | Once you have made the desired changes, from within the virutal d:b dekstop, start a terminal and become root. To do this type: `su`. The system will ask you for a password. **The password is `dyne`**. It will look like this: 80 | 81 | ``` 82 | dyne@dynebolic ~ ❯ su 83 | Password: 84 | root@dynebolic:/home/dyne# 85 | ``` 86 | 87 | The user changed to root, and you may now export your changes. To do this, type: 88 | 89 | `dyne-snapshot` 90 | 91 | Accept the identity of the remote server, by typing `yes` and hitting enter. 92 | 93 | This will fetch any modified file, package them into a single file and upload them to the snapshot server. You will be presented with a URL. Using this method, you won't be able to copy it from your virtual machine to your machine. To fetch this snapshot, either use the QR code with your phone to transfer it to yourself. Or head over to the [snapshot server](https://zorro.zenr.io/snapshots/) and sort the files by "Last Modified". 94 | 95 | ### Inspecting changes to commit them. 96 | 97 | Terminate the virutal machine for now. To inspect your snapshot, download your snapshot to the root of your cloned repository and mount it. 98 | 99 | - `sudo su` (become root) 100 | - `make snap-mount FILE=/path/to/your-snapshot-file` 101 | 102 | This will create a folder in the root of your cloned repository called "snap-mount" containing all the modified files. Navigate into it and run `ncdu`. 103 | 104 | ``` 105 | cd snap-mount 106 | ncdu 107 | ``` 108 | 109 | This will show you a browser like view where you can browse through the modified files. **To close it, hit the "Q" key on your keyboard** 110 | 111 | Still as root, copy the files you are interested in to a different folder: 112 | 113 | - `mkdir ../snap-export` create folder. 114 | - `cp -ra . ../snap-export` copy all files recursively 115 | - `chown -R 1000:1000 ../snap-export` transfer ownership of the copied file to your own user. 116 | - `make snap-umount` unmount the snapshot from the file system ⚠️ 117 | 118 | In the root of your cloned repository, there is a folder called `static`. This is where the configuration files for the desktop and system are residing. Copy over the files to this folder following the same structure. If your file is `snap-export/home/dyne/.config/my-amazing-settings.conf`, move it to `static/home/dyne/.config/my-amazing-settings.conf` 119 | 120 | Once you have done this, you need to make sure that your changes are going to give the desired effect. This because, maybe you forgot something? Maybe there are more files responsible for the changes you want? 121 | 122 | - `make test-changes` 123 | 124 | This will launch a virtual machine taking into account your changes. When the desktop appears, you should be able to see your changes. If you do, commit them to the repository: 125 | 126 | - `git add path/to/changed.file` 127 | - `git commit -m "write a description of your changes in present tense here"` 128 | - `git push` 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ## Appendices 138 | 139 | ### Appendix I: A Brief History of dynebolic 140 | 141 | 142 | 143 | 144 | 145 | - Context (technological, social, political) of first release of *dynebolic* 146 | - Evolution of *dynebolic* 147 | - *Dynebolic* now. 148 | 149 | The first edition of *dynebolic* was released 150 | -------------------------------------------------------------------------------- /src/dynebolic/docs/disclaimer.md: -------------------------------------------------------------------------------- 1 | ## Disclaimer 2 | 3 | ***Dynebolic GNU/Linux* is copyright (C) 2001 - 2024 Denis Jaromil Roio** 4 | 5 | *Dynebolic* is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | -------------------------------------------------------------------------------- /src/dynebolic/docs/getting_started.md: -------------------------------------------------------------------------------- 1 | # Getting Started with dynebolic 2 | 3 | ## Your Desktop Environment 4 | 5 | *Dynebolic* doesn’t require you to install anything on your disks, which can be left untouched while the system is used. Still, depending on your preferred way to operate, it can boot from harddisks, CD, USB or network (explained in the following chapters) and it can store data in a single file that can be transported across different media. 6 | 7 | The default desktop environment is KDE Plasma 6, which offer you multiple desktops (try ctrl+F2, F3, ecc) and a menu that can be recall by clicking the right mouse button on the background. On the upper right corner you have your storage devices which you can access with a click. 8 | 9 | Inside the application menu organized in tasks you'll find the software available, so you can easily explore the variety of multimedia production tools and much more. 10 | 11 | KDE Plasma offers *Activities*, which are a practical way to organize your workflows depending on the task at hand, whether you're editing video, recording and mixing audio, processing digital photographs, or running a live media stream. 12 | When you start your *dynebolic* desktop session, there will be a number of pre-configured Activities: *Audio*, *Video*, *Streaming*, etc. You can think of these Activities as workplaces dedicated to a particular line of work. They are, of course, not exclusive: nothing stops you from pulling out *Inkscape* to work on an album cover for a track you're currently mastering in the Audio Activity. 13 | 14 | In the following chapters we will look at what is available to you in each Activity. 15 | 16 | #### Installing dynebolic on a disk 17 | 18 | Open the file manager konqueror and click on the disk on the left where you want to install *dynebolic*, on the terminal in the lower part of the window become root with `sudo su`, by default the password is **dyne**, then run `dyne-install`, on next reboot you will be using a persistent storage and your modifications will be saved. 19 | 20 | Now you can also activate *Flatpak* and *GUIX* with `dyne-install flatpak` and `dyne-install guix` from the very same terminal. On next reboot you will also have the *flatpak* and *GUIX* package managers. 21 | 22 | ### Package Management 23 | 24 | To widen the pool of software available *Dynebolic* ships the default package manager for [Devuan](https://www.devuan.org/), the [Flatpak](https://flatpak.org) manager and the [GUIX](https://guix.gnu.org) package manger. 25 | 26 | 27 | 28 | #### Tried and True, and now systemd-free thanks to Devuan. 29 | 30 | *Dynebolic* is based on [Devuan](https://www.devuan.org), a fork of *Debian* with a wider choice of init systems than systemd, not only that, we have replaced the *Pulseaudio suite*, manager of the whole desktop audio stack, with [Pipewire](https://www.pipewire.org)! A new and emergent audio and video subsystem to manage all your needs. 31 | 32 | #### OpenSnitch - network protection 33 | 34 | *Dynebolic* ships with *OpenSnitch* a GUI firewall program. By default it will block all traffic in and outcoming. 35 | 36 | ![OpenSnitch](/docs/dynebolic/images/OpenSnitchMain.png "OpenSnitch main screen") 37 | 38 | In this example we see what happens when we open the internet browser *Falkon* for the first time, by default the action is to allow the traffic after 30 seconds. 39 | 40 | ![OpenSnitch](/docs/dynebolic/images/OpenSnitchFalkonExample.png "OpenSnitch traffic detection example") 41 | 42 | In each tab you can see, configure and act on various levels, ip level, application level, ecc. 43 | 44 | Among GUI firewalls OpenSnitch is the most intuitive and user friendly. 45 | 46 | 47 | 48 | 49 | 50 | 51 | ## Working with Video 52 | 53 | ### Introduction 54 | 55 | The GNU/Linux platform nowadays offers an interesting range of tools for video production, editing and manipulation; you can play all kind of video files, but also encode them for distribution and switch between formats. Furthermore, you’ll find software for recording, veejaying and streaming, non-linear editing and subtitling. 56 | 57 | However, you should consider that most of the video tools running on GNU/Linux platform are in development: indeed you can help much in testing and reporting the bugs you encounter, that’s how anyone can help free software to grow better and better, as it does. 58 | 59 | Now let's proceed on how to configure an available video device and then browse thru the video software included in dynebolic, following a subdivision in task categories. 60 | 61 | ### Configure your video devices 62 | 63 | There are various devices that can be used on PC computers in order to have video input: USB webcams and capture cards, PCI TV cards, Firewire and even parallel port. They all have different chipsets and manufacturers and need different Linux device drivers. 64 | 65 | *Dynebolic* is capable of automatically recognizing most PCI (internal) TV cards at boot time (WinTV, BTTV) and now also USB webcams as well as Firewire controllers: they will all be initialized at boot and can be accessed from the video device `/dev/video0` or subsequent numbers (`video1`, `video2` ….) in case you have more than one. [FIXME: double-check that] 66 | 67 | If your video device is not recognized automatically (the `/dev/video` doesn’t exist) then you need to configure it by hand. 68 | 69 | If the online documentation says your device is supported by a particular kernel driver, you can try to load it using the command `modprobe modulename` and see if everything went well by looking in the last lines of the messages printed out by the `dmesg` command. Many modules are already present in *dynebolic*, but some might require to be compiled using the kernel sources, which is a more complicated process that can’t be explained here: you’ll need to find more instructions online about how to do it and download the Linux kernel sources. If you’ll even do it, keep in mind that once you have compiled your own kernel you have moved your very first step into becoming a hacker ;). 70 | 71 | ### Video tools and programs 72 | #### KDEnlive 73 | 74 | *KDEnlive* (the KDE Non-Linear Video Editor) is one of the best free and open-source video editing programs. It is based on the MLT Framework, which allows it to integrate many plugin effects for video and sound processing or creation. Furthermore *KDEnlive* brings a powerful titling tool, a DVD authoring solution, and can be used as a complete studio for video creation. 75 | 76 | #### Frei0r 77 | 78 | *Frei0r* is a free and open source plugin collection for video effects. Applications can use its API to embed more than 100 video filters, sources and mixers. 79 | 80 | *Frei0r* is a minimalistic plugin API for video effects. The main emphasis is on simplicity for an API that will round up the most common video effects into simple filters, sources and mixers that can be controlled by parameters. It’s our hope that this way these simple effects can be shared between many applications, avoiding their reimplementation by different projects. 81 | 82 | *Frei0r* is not meant as a competing standard to more ambitious efforts that try to satisfy the needs of many different applications and more complex effects. It is not meant as a generic API for all kinds of video applications, as it doesn’t provides things like an extensive parameter mechanism or event handling. Eventually the frei0r API can be wrapped by higher level APIs expanding its functionalities (for instance as GStreamer, MLT, FFmpeg and others do). 83 | 84 | *Frei0r* has been developed with production video software in mind, not video players or desktop toys of sorts. For instance it can be used like GStreamer, but its different as it aims to be lighter, for instance allowing host application developers to avoid memcpy and other buffering operations. Also it doesn’t enforces dependency from GNOME and such desktop frameworks. 85 | 86 | #### Etc. 87 | 88 | ## Working with Audio 89 | 90 | This distribution is full with audio software to do all kind of things: electronic music, sound processing, voice effects, interviews and more. And there is one important thing that makes this system superior to any other commercial solution: there is no competition :) 91 | 92 | Most of the audio applications in dynebolic can be connected together, input to output, in order to form a chain of tools processing the sound: this is done thanks to a technologies like Pipewire, JACK and the Advanced Linux Sound Architecture (ALSA). Instead of keeping separated the tasks of every single application, now it is possible to take advantage of the great variety of approaches that a GNU/Linux system like *dynebolic* has to offer. 93 | 94 | *TIP: it happens often that line-out and headphones are inverted, so while Line-out could be selected it's actually outputting on the headphones, if there's no sound always double check this. 95 | 96 | ### Audio tools and programs 97 | 98 | #### Audacity 99 | 100 | *Audacity* is a user-friendly audio editing program suitable to manipulate your audio files, interviews and recordings, separating or mixing them, applying effects and encoding in various formats. It can also be used to record audio straight away via its intuitive interface, which can be commonly found also on other operating systems since it is a cross-platform free application. A perfect choice to start manipulating audio. 101 | 102 | #### Ardour 103 | 104 | *Ardour* is the fully featured multitrack studio that offers the most advanced interface for your music recording studio. Combined together with other applications when necessary (it also uses Jack) it can really solve all your needs for audio mastering and music production. Check the online documentation for this valuable software on the [Ardour homepage](https://ardour.org): if you are a musician, the patience needed to learn it’s usage and hotkeys is definitely worth the effort. 105 | 106 | #### Mixxx 107 | 108 | *Mixxx* is currenly the most popular libre DJ Automation and digital DJ performance application. It includes many features common to digital DJ solutions as well as some unique ones: it natively supports advanced MIDI and HID DJ controllers, is licensed under the GPL-2.0-or-later and runs on all major desktop operating systems. The project was started in early 2001 for a doctoral thesis as one of the first digital DJing systems 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | ### Some technicalities 119 | 120 | - The low-latency question 121 | 122 | ### Audio servers 123 | 124 | The zoo of Linux audio servers. 125 | 126 | (Obligatory [XKCD 927](https://xkcd.com/927/) here.) 127 | 128 | 1. The ALSA audio back-end. 129 | 130 | 2. The JACK audio server 131 | 132 | Still going strong. 133 | 134 | 3. Pulseaudio 135 | 136 | Explain why *Pulseaudio* is a Crime against Nature, and why "Poettering" is a gerund. 137 | 138 | (I honestly hope we won't have to deal with PA here.) 139 | 140 | 4. The Pipewire audio server 141 | 142 | One media server to rule them all. 143 | 144 | ### Pipewire 145 | 146 | Pipewire is the new sound and video layer in between the graphical desktop/the applications and the devices, offer so much more than pulseaudio beside an integration with libcam for all that has to do with webcams, video streaming, desktop sharing, ecc. 147 | Pipewire also offer a simple utility called *pw-jack* that allows for jackd-only applications to run natively on top of pipewire. For example, lets open up a software called qpwgraph, and after that let's open Ardour in a terminal with the command *pw-jack ardour*, all ardour inputs and outputs will show in pipewire patchbay without a jackd daemon running. 148 | 149 | ## Streaming Media 150 | 151 | Now that you have worked hard on your media, be it a podcast, experimental video, music, or sound art, you might feel the need to get it out there in the world. As far as streaming media goes, *dynebolic*'s Streaming Activity has you covered. 152 | 153 | ### OBS Studio 154 | 155 | *OBS Studio* (the Open Broadcaster's Software Studio) is a free and open-source, cross-platform app for screencasting screencasting and live streaming. It is available for Linux and BSD distributions, as well as other operating systems. *OBS Studio* provides real-time capture, scene composition, recording, encoding, and broadcasting via Real-Time Messaging Protocol (RTMP), HLS, SRT, RIST or WebRTC. It can stream videos to any RTMP-supporting destination, including YouTube, Twitch, Instagram and Facebook 156 | 157 | In recent years (and especially in the wake of the COVID-19 crisis), *OBS Studio* has become the most popular tool for countless podcasts, live streaming sessions, news broadcasts, or live coding. It can use any number of cameras and sound sources, and can be comfortably configured to stream any computer screen or program window we choose. 158 | 159 | The first you'll start OBS it will guide you through some basic settings and wheter you want to record locally, stream online or both. 160 | You will be greeted by a popup with the news of the latest updates, being a very active software, and the interface composed by the preview, the scene editor and selector, the sources editor and selector, the audio mixer, the transition selector and the controls. 161 | 162 | In the scene selector we can create new scenes to wich add new sources, make it a background image, another audio source, a webcam, ecc, a live streamer for example would want and intro scene, with microfones shutoff, some news rolling, a count down and a shiny background animation, with a transparency transition of 3 second while switching to the second scene, in wich there could be a different setup of sources, the capturing of a program window or a game, a webcam, ecc; OBS also has full hotkeys support, so for activating and deactivating sources like microfones or camera without leaving your keyboard or using external usb deck devices. Once an optimal setup is found scene and sources can be locked and even copied/cloned. 163 | In the case of live streaming you will have to tweak the bitrate based on your upload speed. 164 | 165 | OBS has also an advanced interface with two preview screens that can be enabled in the preferences. 166 | 167 | ### BUTT 168 | 169 | If our streaming project doesn't need all the power and features of OBS Studio, or we need to join a broadcast using an Icecast server, the ideal tool for the job is *BUTT*. 170 | 171 | *Broadcast Using This Tool* (charmingly contracted to *BUTT*) is an easy to use, multi-OS streaming tool. 172 | It supports SHOUTcast and Icecast and runs on Linux and other operating systems. The main purpose of BUTT is to stream live audio data from your computers mic or line input to a Shoutcast 173 | or Icecast server. It also has facilities for recording our session. 174 | 175 | One peculiarity of *BUTT* is that it is focused on live audio - that is, it will broadcast a microphone, instrument, or software synth source to the Icecast server's mount point, but it will not stream recorded media files. (But nothing stops you from using it to stream your DJ session with [Mixxx](#mixxx), for example.) 176 | 177 | ## Working With Graphic Design 178 | 179 | ### Inkscape 180 | 181 | *Inkscape* is a free and open source vector graphics editor for GNU/Linux and other operating systems. It offers a rich set of features and is widely used for both artistic and technical illustrations such as cartoons, clip art, logos, typography, diagramming and flowcharting. It uses vector graphics to allow for sharp printouts and renderings at unlimited resolution and is not bound to a fixed number of pixels like raster graphics. *Inkscape* uses the standardized SVG file format as its main format, which is supported by many other applications including web browsers. It is an ideal tool for flyers, high-resolution prints and pre-flight DTP work. 182 | 183 | ### Krita 184 | 185 | *Krita* is a free and open source cross-platform application that offers an end-to-end solution for creating digital art files from scratch. It is made by artists that want to see affordable art tools for everyone. *Krita* is optimized for frequent, prolonged and focused use. Explicitly supported fields of painting are illustrations, concept art, matte painting, textures, comics and animations. *Krita* supports open standards and interoperates with other applications. 186 | 187 | Krita’s tools are developed keeping the above vision in mind. Although it has features that overlap with other raster editors its intended purpose is to provide robust tool for digital painting and creating artworks from scratch. 188 | 189 | ### Blender 190 | 191 | *Blender* is the free and open source 3D creation suite. It supports the entirety of the 3D pipeline—modeling, rigging, animation, simulation, rendering, compositing and motion tracking, even video editing and game creation. Advanced users employ *Blender*’s API for Python scripting to customize the application and write specialized tools; often these are included in *Blender*’s future releases. *Blender* is well suited to individuals and small studios who benefit from its unified pipeline and responsive development process. Examples from many Blender-based projects are available in the showcase. 192 | 193 | *Blender* is cross-platform and runs equally well on Linux and other operating systems. Its interface uses OpenGL to provide a consistent experience. To confirm specific compatibility, the list of supported platforms indicates those regularly tested by the development team. 194 | 195 | Indeed, *Blender* is such a powerful and complex multimedia tool, that it fits equally well in the [Video](#working-with-video) and here in the [Graphic Design](#graphic-design) Activities of *dynebolic*. 196 | 197 | ## Working With Photography 198 | 199 | Whether you just need to crop or apply an effect on a bitmap image, or you need to establish a good RAW development workflow, the Photography Activity has the tools for you. 200 | 201 | ### Gwenview 202 | 203 | *Gwenview*, the KDE Plasma default image viewer, is a fast and lean tool for viewing images and browsing and annotating picture collections. It even offers some basic editing operations, such as image resizing and cropping, which make it very handy for moments when a heavier tool would be overkill. 204 | 205 | ### The GNU Image Manipulation Program 206 | 207 | The *GNU Image Manipulation Program* is a well mature application capable to create and edit bitmap images, offers a perfect environment for web graphics as well a powerful script engine to automatize its operations and even generate automatically stylish logos. 208 | 209 | ### Darktable 210 | 211 | *Darktable* is an open source photography workflow application and RAW developer. A virtual lighttable and darkroom for photographers. It manages your digital negatives in a database, lets you view them through a zoomable lighttable and enables you to develop RAW images and enhance them. 212 | 213 | ### digiKam 214 | 215 | *digiKam* is an advanced open-source digital photo management application that runs on Linux and other operating systems. The application provides a comprehensive set of tools for importing, managing, editing, and sharing photos and raw files. While *digiKam* also has RAW development capabilities, its strong point is in library management and cataloging. It also has a useful set of plugins which enable direct publishing to online sites such as Flickr and others. 216 | 217 | ### The `lensfun` database 218 | 219 | 220 | *Dynebolic* comes with enough powerful tools for digital photography to satisfy a photographer's needs. Nevertheless, an important step in setting up our digital photography workflow is updating the `lensfun` database. `lensfun` is an open, collaborative database of camera and lens profile, which are essential for RAW development operations, such as lens correction. If *Darktable* can't find the profile of your camera model or lens (or at least the closest possible one), chances are your `lensfun` database hasn't been updated. 221 | 222 | To do this, we open *Konsole*, and do the following: 223 | 224 | > lensfun-update-data 225 | 226 | And that's it. You won't need to do anything else - *Darktable* or other RAW processing tools will use the updated `lensfun` database in the background. 227 | 228 | ### Learn more 229 | 230 | - [The Darktable website](https://www.darktable.org/), and its [resources section](https://www.darktable.org/resources/) 231 | - [The digiKam website](https://www.digikam.org) 232 | - The `lensfun` [website](https://lensfun.github.io/), especially its [FAQ](https://lensfun.github.io/faq/) 233 | - [dstyle.net](https://dtstyle.net/), a huge collaborative collection of *Darktable* styles 234 | - [Pixls.us](https://pixls.us/), one of the greatest resources for libre digital photography. In particular, check out its [forums](https://discuss.pixls.us/) 235 | 236 | ## Publishing 237 | 238 | Although nowadays most of what we call "publishing" happens online, we shouldn't underestimate the importance of print media for local grassroots organizations and activism. That flyer you posted on a local community cork board or left at your neighborhood coffee house might reach people your social media updates won't! 239 | 240 | While flyers, brochures and leaflets can be produced with [Inkscape](#inkscape), *dynebolic* also provides [Scribus](#scribus), a full-fledged Desktop Publishing (DTP) environment. 241 | 242 | ### Writing Implements 243 | 244 | Whatever you intend to publish, chances are that you'll need to write some copy. No matter what you intend to do with it, there's no avoiding some banging on a keyboard for a while. 245 | 246 | For text- and document writing and editing, *dynebolic* includes *LibreOffice*, so you have the full feature set of an office suite. 247 | 248 | If you prefer leaner writing tools, *dynebolic* also includes the *Kate* advanced text editor. And, if you're feeling particularly *1337*, at the command line you will find a recent version of the venerable *Vim* editor. 249 | 250 | ### Scribus 251 | 252 | *Scribus* is a desktop publishing program to compose vectorial formats like PDF and Postscript, it is useful to paginate text in a professional printable form to produce magazines, flyers and most publications that need to mix text and images in pages following customizable schemes. 253 | 254 | -------------------------------------------------------------------------------- /src/dynebolic/docs/images/OpenSnitchFalkonExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/OpenSnitchFalkonExample.png -------------------------------------------------------------------------------- /src/dynebolic/docs/images/OpenSnitchMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/OpenSnitchMain.png -------------------------------------------------------------------------------- /src/dynebolic/docs/images/browse.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/browse.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/choose.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/choose.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/diskspace.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/diskspace.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/grub.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/grub.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/name-vm.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/name-vm.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/pick.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/pick.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/resources.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/resources.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/images/vm-running.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/dynebolic/docs/images/vm-running.webp -------------------------------------------------------------------------------- /src/dynebolic/docs/index.md: -------------------------------------------------------------------------------- 1 | # Dynebolic IV GNU/Linux User's Guide 2 | 3 | *2024 Denis Jaromil Rojo & The dynebolic Documentation Team* 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ## What Is dynebolic? 12 | 13 | *Dynebolic* is a 100% Free Software Operating System for multimedia production, recommended by the Free Software Foundation. It is a live ISO that can run from a CD or Drive, without the need to install. 14 | 15 | ## Be Welcome to a GNU+Linux World! 16 | 17 | For culture and information to circulate freely and unbiased, media activists, artists and creatives need to be independent from corporate alienation. *Dynebolic* is an Operating System and a practical tool for multimedia production: it enables the manipulation and broadcasting of both audio and video with tools to record, edit, encode, stream, and publish. Dyne:bolic automatically recognizes most device and peripherals: audio, video, TV, network cards, firewire, usb and more; all using only free software! 18 | 19 | ## 100% Free, As In Speech 20 | 21 | *Dynebolic* is a GNU+Linux distribution recommended by the Free Software Foundation: no proprietary software is inside, no closed source firmware, no hockus pockus. Everything is transparent and can be peer reviewed. All of this without ever compromising with the expression creatives rely on. 22 | 23 | You are free to study, modify, redistribute and even sell this Operating System, as long you grant the same freedom to your peers. 24 | 25 | ## Friendly To The Environment 26 | 27 | *Dynebolic* is designed to run on computers with extremly low ressources (*dynebolic III* was benchmarked at Pentium2 processors with 256MB RAM). It can even run in ram: not even a harddisk is required. 28 | 29 | Unleash the full potential of computers, including second hand machines. Let’s put an end to consumerism and use what already exists to its full potential. 30 | 31 | ## Digital Resistance 32 | 33 | The *dynebolic* Operating System is about resilience and digital resistance. In a reality where governments and corporation are exercising control by monitoring the way people communicate, hackers, creatives and citizens of the digital era have a common interest in keeping their computing sovereign. To accomplish this, sharing knowledge is paramount. 34 | 35 | Liberate yourself from mental slavery. Embrace sovereign communication. Free your mind, open the source! 36 | 37 | ## Freedom Needs Privacy 38 | 39 | *Dynebolic* Operating System does not include any cloud-service and does not establish background communications without the consent of the user. 40 | 41 | *Dynebolic* also includes support for strong encryption of private data, thanks to Dyne.org's [Tomb](https://dyne.org/software/tomb). 42 | 43 | ## Freedom of Expression 44 | 45 | More than the means of media playback, *dynebolic* includes free software for the production of professional grade multimedia. 46 | 47 | For everything you can see and play, *dynebolic* includes the software to create it. This Operating System lets you express yourself, without the need to rent a license or install additional components. *dynebolic* was built to make it possible for people to be the independent producers of their own story. Not just content creators for corporate platforms or consumers of information. 48 | 49 | ## Appreciated Worldwide 50 | 51 | Since its birth in 2000, *dynebolic* has been redistributed by several magazines and adopted by universities, community initiatives, medialabs and public institutions around the World. 52 | 53 | ## How is dynebolic different from other live distros? 54 | 55 | True to the original desire to put digital power in the hands of the people, we craft dynebolic to fill the gap between expression and technology. Our legacy stretches over decades. 56 | 57 | Free Software is the idea that, operating-, using-, modifying- and sharing- means of digital production, is the only way for humans to create and communicate safely in the digital realm. With *dynebolic* we apply this idea, to a carefully curated list of applications and utilities, in ways that align perfectly with the principles of Free Software. More than a distribution, dynebolic is a human centric community, facilitating professional grade multimedia tools to the masses. 58 | 59 | *dynebolic* is a nomadic system, meaning it is ready to move in to your device with a minimum of material friction. But it shall also follow you on the road, where the conditions may be unpredicatble. For many dynes, it is a gateway to the freedom to compute and a reaching hand for travelers looking to onboard the liberty of expression. 60 | -------------------------------------------------------------------------------- /src/dynebolic/docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ECF8F7 !important; 3 | } 4 | .md-header { 5 | background-color: #36968C !important; 6 | } 7 | -------------------------------------------------------------------------------- /src/dynebolic/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Dynebolic Manual 2 | site_url: https://dyne.org/docs/dynebolic/ 3 | 4 | theme: 5 | name: material 6 | logo: images/dyneorg.svg 7 | favicon: images/favicon.png 8 | 9 | extra_css: 10 | - stylesheets/extra.css 11 | 12 | nav: 13 | - Home: index.md 14 | - Booting Dynebolic: bootingonusb.md 15 | - Getting Started: getting_started.md 16 | - 'Contribute to d:b': developers.md 17 | - Source code: https://git.devuan.org/jaromil/dynebolic 18 | - Appendix: appendix.md 19 | - Disclaimer: disclaimer.md 20 | 21 | markdown_extensions: 22 | - attr_list 23 | - md_in_html 24 | - admonition 25 | - pymdownx.details 26 | - pymdownx.superfences 27 | -------------------------------------------------------------------------------- /src/jaromail/docs/images/jaromail-shot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/jaromail/docs/images/jaromail-shot.jpg -------------------------------------------------------------------------------- /src/jaromail/docs/index.md: -------------------------------------------------------------------------------- 1 | jaromail(1) -- self-sovereign e-mail management 2 | =============================================== 3 | 4 | Jaro Mail is an integrated suite of interoperable tools to manage e-mail 5 | communication in a private and efficient way, without relying too much 6 | on on-line services, in fact encouraging users to store their email 7 | locally. 8 | 9 | Rather than reinventing the wheel, this suite reuses existing free and 10 | open source tools and protocols and is mainly targeted for GNU/Linux/BSD 11 | desktop usage. 12 | 13 | This manual illustrates the usage of Jaro Mail. The newest version of 14 | this manual is made available on 15 | 16 | 17 | ### Features 18 | 19 | ![](images/jaromail-shot.jpg) 20 | 21 | - Minimalistic and efficient interface with message threading 22 | - Targets intensive usage of e-mails and mailinglists 23 | - Stores e-mails locally in a reliable format (maildir) 24 | - Integrates whitelisting and blacklisting, local and remote 25 | - Can do search and backup by advanced expressions 26 | - Automatically generates filter rules (sieve) 27 | - Imports and exports VCard contacts to addressbook 28 | - Computes and shows statistics on mail traffic 29 | - Facilitates sending anonymous emails (Mixmaster) 30 | - Encrypted password storage using OS native keyrings 31 | - Advanced maildir tools (merge, backup, address extraction) 32 | - Defers connections for off-line operations 33 | - Checks SSL/TLS certificates when fetching and sending mails 34 | - Supports strong encryption messaging (GnuPG) 35 | - Multi platform: GNU/Linux/BSD, Apple/OSX 36 | - Old school, used by its author for the past 10 years 37 | 38 | ### Vision 39 | 40 | The internet offers plenty of free services, on the wave of the Web2.0 41 | fuzz and the community boom, while all private informations are hosted 42 | on servers owned by global corporations and monopolies. 43 | 44 | It is important to keep in mind that no-one else better than you can 45 | ensure the privacy of your personal data. Server hosted services and web 46 | integrated technologies gather all data into huge information pools that 47 | are made available to established economical and cultural regimes. 48 | 49 | The vision behind this software is that of sharing a simple and 50 | consistent way to operate e-mail communication with tools that are 51 | available on most platforms and can be as well used remotely over a 52 | secure shell connection. 53 | 54 | Jaro Mail aims to facilitate the task of downloading and storing e-mail 55 | archives off-line in a way that they can be still accessible in more 56 | than 10 years time and independently of any software. Nowadays many 57 | users have the habit of keeping all their e-mails on servers, accessing 58 | them through an often clumsy web interface, while downloading them can 59 | free space and improve their privacy. 60 | 61 | ## Architecture 62 | 63 | JaroMail is a usable terminal interface that easily sets up and 64 | integrates the following components to manage large e-mail folders 65 | locally: 66 | 67 | | Acronym | Function | Software | 68 | |---------|-----------------------|-----------------------------------------------------------------------| 69 | | MUA | Mail User Agent | [Mutt](http://www.mutt.org) | 70 | | MTA | Mail Transport Agent | [Fetchmail](http://www.fetchmail.info) | 71 | | LDA | Local Delivery Agent | [Mblaze](https://github.com/leahneukirchen/mblaze) | 72 | | MDA | Remote Delivery Agent | [Sieve](http://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)) | 73 | | SMTP | Mail delivery agent | [MSmtp](http://msmtp.sourceforge.net) | 74 | | ANON | Anonymous delivery | [MixMaster](http://mixmaster.sourceforge.net/) | 75 | | SEARCH | Mail Search engine | [Notmuch](http://notmuchmail.org/) | 76 | | ABOOK | Contacts Addressbook | [ABook](http://abook.sf.net) | 77 | | GPG | Cryptographic Agent | [GnuPG](http://www.gnupg.org) | 78 | | STORE | Cryptographic Storage | [Tomb](http://www.dyne.org/software/Tomb) | 79 | 80 | ## Setup 81 | 82 | ### Build 83 | 84 | Some dependencies are needed in order to build this software. The 85 | Makefile for GNU/Linux configures the build environment automatically on 86 | Debian and Fedora systems, using their packaging to install all needed 87 | packages. 88 | 89 | The dependencies to be installed on the system for JaroMail are: 90 | 91 | ``` 92 | gcc bison flex make autoconf automake sqlite3 libglib2.0-dev libgnome-keyring-dev 93 | ``` 94 | 95 | ### Install 96 | To install the following programs need to be installed: 97 | 98 | ``` 99 | fetchmail msmtp neomutt direnv mblaze pinentry abook wipe notmuch alot 100 | ``` 101 | 102 | Then `make install` will put all jaromail files in `/usr/local/share/jaromail`. 103 | 104 | ### Apple/OSX 105 | 106 | Apple/OSX users that have no experience in building software can obtain 107 | a pre-built universal binary from our download zone on 108 | 109 | 110 | One can simply drag JaroMail into Applications. When started JaroMail 111 | opens a Terminal window preconfigured with its environment, to activate 112 | it for any terminal add this to \`\~/.profile\`: 113 | 114 | `export PATH=/Applications/JaroMail.app/Contents/Resources/jaro/bin:$PATH` 115 | 116 | ### Use 117 | 118 | Make a directory where all the emails and settings needs to be, change 119 | to the directory and init the environment: 120 | 121 | `mkdir $HOME/gmail-alternative` 122 | 123 | `cd $HOME/gmail-alternative` 124 | 125 | `jaro init` 126 | 127 | Every installation of Jaro Mail is fully reentrant, meaning the 128 | directory where it gets initialised contains all maildirs, 129 | configurations, filters, whitelist, addressbooks and other necessary 130 | files. 131 | 132 | A single user can have multiple Jaro Mail folders on the same system 133 | to permit the complete separation of E-Mail identities. 134 | 135 | If called from outside the installation directory, the **jaro** command 136 | will use the environmental variable **\$JAROMAILDIR** to find out the 137 | active installation being in use. If one is using a different 138 | installation path then should first change that, i.e: 139 | 140 | `export JAROMAILDIR=$HOME/OtherIdentities/Luther/Mail` 141 | 142 | ## Configuration 143 | 144 | The place where Jaro Mail is initialized, its folder contains all 145 | configuration files. 146 | 147 | From now own, we will call this place the **MAILDIR**. 148 | 149 | Configurations are in readable plain text files that can be edited 150 | using any editor. Inside them there are comments to explain the 151 | settings: all comment lines start by \'#\' and will be ignored by 152 | JaroMail. 153 | 154 | The most important files to start configuring are: 155 | 156 | - `Accounts/default.txt` : main account configuration (there can be more than one file in the `Accounts/` folder) 157 | - `Aliases.txt` : more email addresses one may receive on the configured accounts 158 | - `Filters.txt` : Full set of mailinglist sorting rules 159 | - `Applications.txt` : mime type associations to programs used to open attachments 160 | - `Mutt.txt` : mutt specific custom configurations 161 | 162 | ### Accounts 163 | 164 | Inside the Mail directory is found the folder **Accounts** with brief 165 | instructions and default templates to fill with Imap and Smtp account 166 | configurations to fetch mail. A default template will be found in fresh 167 | installations: **Accounts/default.txt**. The configuration can be edited 168 | with one\'s favourite text editor, the format of the file is pretty 169 | self-explanatory. 170 | 171 | It is possible to have more than one account (simply as a new file in 172 | the Accounts/ directory) and refer to it using the `-a` commandline 173 | option. For instance when we configure `Accounts/gamer.txt` as an 174 | alternative mailbox then we can connect it using `jaro peek -a gamer` 175 | 176 | Config files in `Accounts` can also contain `my_hdr` that will 177 | configure custom header lines (for instance GPG-ID or X-Organisation) 178 | that will be added to the mails sent. For more information about the 179 | vast amount of configurations supported please refer to the Mutt 180 | documentation[^1]. 181 | 182 | ### Organization 183 | 184 | One of the main goals for Jaro Mail is to organize the e-mail workflow 185 | so that one\'s attention is dedicated to important communications, 186 | rather than being constantly distracted by various degrees of spam and 187 | the need to weed it out of the mailbox. This ambitious task is pursued 188 | by realizing an integrated approach consisting of flexible whitelisting 189 | and the distinction between mails from known people and the rest. 190 | 191 | ### Folders 192 | 193 | First lets start with a categorization of the standard maildirs and a 194 | brief description for each. This information is **very important** to 195 | understand how Jaro Mail works: these maildirs are standard in Jaro 196 | Mail, here they are listed in order of priority 197 | 198 | Folder What goes in there 199 | ------------------ -------------------------------------------------- 200 | **known** Mails whose sender is known (Whitelist) 201 | **priv** Unknown sender, we are among explicit recipients 202 | **unsorted** Unknown sender, we are not among recipients 203 | **zz.blacklist** Mails whose sender is not desired (Blacklist) 204 | **zz.spam** Mails that are tagged as spam (server-side) 205 | **zz.bounces** Mail bounces like mailman and similar 206 | 207 | The advantage using such a folder organization is that every time we 208 | open up the mail reader we will be presented with something we are 209 | likely to be most interested in (known people replying our mails) and 210 | progressively, as we will have the time to scroll through, mails from 211 | \"new people\" or mass mailings of sort. 212 | 213 | This setup is handy especially considering it produces **sieve** filters 214 | that can be uploaded to mail servers and processed server-side. Imagine 215 | having your email on a fixed computer, but occasionally checking it from 216 | a mobile phone: server-side filtering will save you time by presenting a 217 | clean INBOX of whitelisted contacts for the mobile phone use. 218 | 219 | Please note this organization does not includes spam, which is 220 | supposedly weeded out on the server via spamlists: White/Blacklisting 221 | has more to do with our own selection of content sources than with the 222 | generic protection from random pieces of information. 223 | 224 | At last, anything that is matched by filters configured in 225 | **Filters.txt** will be saved into the named maildir, whose name can be 226 | freely choosen. 227 | 228 | ### Whitelist 229 | 230 | The way whitelisting works if quite crucial to this setup and, at the 231 | same time, is fairly simple since it does not include any automatic 232 | detection, learning filters, Markov chains or Bayesian A/I. We believe 233 | the user should be in full control of prioritizing communication 234 | channels and at the same time constantly able to tweak the setup in an 235 | easy way. 236 | 237 | To whitelist an address is sufficient to send it an e-mail: at the 238 | moment the message is sent Jaro Mail will remember the destination 239 | address and prioritize all messages coming back from it. This we call 240 | implicit whitelisting. 241 | 242 | To explicitly whitelist an address from inside the mail reader index 243 | press \[ **a** \] while selecting an email, this will add in the 244 | whitelist the sender address (From: header). If you want to add all 245 | addresses reached by the mail (From: To: and Cc: fields) use the same 246 | letter capitalized pressing shift \[ **A** \]. 247 | 248 | All addresses selected this way will have the privilege of ending up in 249 | your **known/** folder, plus their name and e-mail will be completed 250 | automatically when composing a new email, pressing the **Tab** key while 251 | indicating them among the recipients. 252 | 253 | ### Blacklist 254 | 255 | To blacklist an address instead one can use the \[ **z** \] key while an 256 | e-mail is selected on the index: the sender indicated in the From: field 257 | will be downgraded to the very bottom of your priorities, closes to spam 258 | than the rest, the most infamous **zz.blacklist/** folder. 259 | 260 | ### Organization In Brief 261 | 262 | Below a recapitulation of keys related to the white and blacklisting 263 | functionality, to be used in the e-mail index or when an e-mail is open 264 | inside the mail user agent: 265 | 266 | List Key Function Fields 267 | ------- --------------- ------------------------- --------------- 268 | White **a** Add the sender address From: 269 | White **A** (shift) Add all addresses From: To: Cc: 270 | Black **z** Blacklist the sender From: 271 | Black **Z** (shift) Blacklist all addresses From: To: Cc: 272 | 273 | 274 | 275 | ## Workflow 276 | 277 | This section goes through a scenario of simple usage for Jaro Mail 278 | 279 | ### Fetch and read your mail at home 280 | 281 | As you acces your computer where Jaro Mail has been configured, you can 282 | open a Terminal and type: 283 | 284 | ``` example 285 | jaro fetch 286 | ``` 287 | 288 | This will download all new mails. 289 | 290 | If you have configured **fetchall** among the imap account options, then 291 | will delete them from the server, freeing online space. 292 | 293 | If you have configured the **keep** option, which is the default, Jaro 294 | Mail will only download the email that you have not yet read and in any 295 | case it won\'t delete anything from the server. Remove the **keep** 296 | option to delete on the server all emails that are downloaded. 297 | 298 | ``` example 299 | jaro 300 | ``` 301 | 302 | This will launch mutt on the first folder containing unread emails, 303 | starting from the **known** folder, then **priv**, then all the 304 | destinations specified by **Filters.txt** exactly in the ascending order 305 | they are listed in that configuration file.. 306 | 307 | From there on, pressing **=** or **c** you can change to other folders 308 | and your **unsorted** mails. 309 | 310 | ### Write a new mail 311 | 312 | If you like to write a mail to someone, hit **m** and write the 313 | recipient address, you will be then asked about any additional Cc: 314 | recipients. 315 | 316 | If you don\'t remember the emails of the recipients, you can just type 317 | their name or parts of the email you remember, then press the \[ **Tab** 318 | \] key for completion. A list of addresses may popup with matches found 319 | in your whitelist addressbook to help remind who are you looking for. 320 | 321 | The email is composed using a special [Vim](http://www.vim.org/) 322 | configuration that facilitates justifying text to 72 columns using \[ 323 | **ctrl-j** \]. After composing the email you will be able to review it 324 | and change: 325 | 326 | - the From: field using \[ **ESC f** \] 327 | - the recipient in the To: field using \[ **t** \] 328 | - the recipients in the Cc: field using \[ **c** \] 329 | - the subject string using \[ **s** \] 330 | 331 | You\'ll also be able to add more attachments by pressing **a** and use 332 | the arrow keys to move over the existing ones and delete them using \[ 333 | **D** \] (please note that is a uppercase D, because lowercase d will 334 | just add a description for the attachment). 335 | 336 | At last, when ready, pressing **y** will queue the email into the 337 | outbox, ready for sending. 338 | 339 | One can review at any time the sending queue, which is just another 340 | maildir named **outbox** 341 | 342 | ``` example 343 | jaro outbox 344 | ``` 345 | 346 | Mails can be deleted from this view using \[ **d** \] or edited using \[ 347 | **e** \] which will allow tweaking of both the header and body of the 348 | email. 349 | 350 | Once sure the outbox contains all what needs to be sent, make sure the 351 | computer is connected to the Internet and issue the **send** command: 352 | 353 | ``` example 354 | jaro send 355 | ``` 356 | 357 | Jaro Mail will send all emails in outbox, one by one, listing their 358 | recipients and size while doing so. If successful, mails will be removed 359 | from the outbox and put into the **sent** folder, which can be accessed 360 | from inside mutt or with the command **jaro open sent**. 361 | 362 | ### Write a new email from the commandline 363 | 364 | Jaro Mail supports a lot of commandline operations based on stdin/stdout 365 | pipes, which makes it pretty easy to use in scripts that send emails and 366 | attachments. 367 | 368 | If you have written a plain-text email using your favorite editor, you 369 | can send it quickly using the commandline: save the email into a txt 370 | file and then pipe it into **jaro compose** followed by a list of 371 | recipients and, optionally a list of filenames to attach. For example: 372 | 373 | ``` example 374 | cat Greetings.txt | jaro compose friends@dyne.org picture01.jpg jingle02.mp3 ~/myicons/* 375 | ``` 376 | 377 | The command above may send an email with various separate attachments 378 | (using MIME encapsulation): a picture, an hopefully small audio file and 379 | a list of icons which are all the files contained into the myicons/ 380 | directory. In this case the recipient will be friends@dyne.org, but may 381 | be any other email address found on the commandline in any position. 382 | 383 | Once executed you will find this email in **jaro outbox**, ready to be 384 | reviewed and sent with **jaro send**. 385 | 386 | ### Reply messages 387 | 388 | While browsing through the index of emails in various folders, one can 389 | reply any of them just by pressing the \[ **r** \] key, which will ask 390 | if the original message should be quoted and then open your favorite 391 | editor to compose your text. 392 | 393 | If the email you are replying has been sent to multiple recipients (for 394 | instance using multiple addresses in the Cc: or From: fields) they will 395 | all be included, but you will have the possibility to exclude them by 396 | hand, editing the Cc: field. To remove them all at once use \[ 397 | **ctrl-k** \] just like deliting a line on the terminal. 398 | 399 | It is also possible to forward a message to someone else than the 400 | sender, for instance to submit it to his or her attention, or that of a 401 | mailinglist. To do that, you can use the \[ **f** \] key which will 402 | present you with the full message and the possibility to write something 403 | on top of it, to describe its contents to its new recipients. Forwards 404 | include all attachments and are sent as attachments themselves, but this 405 | behavious can be changed as a confirmation to \"send forward as attach\" 406 | is asked. 407 | 408 | ### Peek without downloading anything 409 | 410 | If you are around and like to see your new mails without downloading 411 | them, then you can use the **peek** function: 412 | 413 | ``` example 414 | jaro peek 415 | ``` 416 | 417 | This will open the default configured IMAP account and folder over SSL 418 | protocol (securing the data transfer) and allow you to browse, read and 419 | reply your emails without downloading them. 420 | 421 | Using peek you can reply and even delete emails, but be careful since 422 | what you delete here will be removed from the server and won\'t be there 423 | when you download it from home. 424 | 425 | This functionality can be also very useful if you are from a slow 426 | connection and need to delete some email that is clogging it and that 427 | you are not able to download because of its size. 428 | 429 | The peek command will automatically open the INBOX, but also other 430 | remote imap folders can be specified, like for instance **priv** or 431 | **unsorted** if whitelisting is also setup server-side (the sieve 432 | filters generated by Jaro Mail need to be uploaded on the server). To 433 | have a list of imap folders on the server a command is also available: 434 | 435 | ``` example 436 | jaro imap listfolders 437 | ``` 438 | 439 | Will list on the terminal all folders found on the imap account, one per 440 | line. 441 | 442 | ### Save important emails for later 443 | 444 | Sometimes one can be on the rush while reading emails (local or via 445 | imap) and flagging them as important can be useful to keep focus on 446 | priorities. In some cases it is very useful to save such important 447 | messages locally for later reference, for instance in a folder keeping 448 | messages that need to be remembered and that will constitute a kind of 449 | TODO list (a\'la GTD). 450 | 451 | Jaro Mail implements such functionalities: by pressing the \[ **F** \] 452 | key (uppercase) one can flag an email, which will turn bright-green in 453 | the index. In addition to that there is a folder called **remember/** 454 | where one can copy emails on the fly using the \[ **R** \] key 455 | (uppercase) any time. Messages will be duplicated into the remember 456 | folder (which of course can be opened with the command **jaro 457 | remember**) so they can also be edited with annotations on the task they 458 | refer to, for instance using the \[ **e** \] key, without affecting the 459 | original message. 460 | 461 | ### Workflow in brief 462 | 463 | Below a recapitulation of keys commonly used in our workflow 464 | 465 | Key Function 466 | --------- -------------------------------------- 467 | **m** Compose a new message 468 | **Tab** Complete addresses and folders input 469 | **r** Reply to the sender of a message 470 | **d** Delete a message 471 | **y** Send a message (queue in outbox) 472 | **f** Forward a message to new recipients 473 | **=** List all filtered maildir folders 474 | **c** Change to another folder 475 | **F** Flag a message as important 476 | **R** Copy a message to remember 477 | **s** Move a message to another folder 478 | **C** Copy a message to another folder 479 | 480 | ## Searching 481 | 482 | Searching across all your emails it is as important as demanding of a 483 | task. Jaro Mail implements it using [Notmuch](https://notmuchmail.org/) 484 | which is relying on the [Xapian](http://xapian.org) search engine, 485 | completely relying on local computations made on your machine, there is 486 | no data at all being communicated on-line. 487 | 488 | To index and tag all your emails that are locally archived in Jaro Mail 489 | use: 490 | 491 | ``` example 492 | jaro index 493 | ``` 494 | 495 | This will take a while and increase the size of the storage of about one 496 | sixth of its total occupation, but will definitely come useful when in 497 | need of searching rapidly across all available emails. To run a search 498 | for emails containing the \'*open source*\' string, do 499 | 500 | ``` example 501 | jaro search open source 502 | ``` 503 | 504 | To search for all emails containing this string and dated between now 505 | and the last two weeks, do 506 | 507 | ``` example 508 | jaro search open source date:2w.. 509 | ``` 510 | 511 | The search command prints out a list of found filenames which may be 512 | useful to a script, but less useful to a human. In order to read a quick 513 | summary of the emails found it is possible to pipe the results into the 514 | **headers** command which will print out date, sender and subject of 515 | each file 516 | 517 | ``` example 518 | jaro search open source date:2w.. | jaro headers 519 | ``` 520 | 521 | Searching has also an interactive interface called **alot** which pops 522 | up to show search results and browse through them, refine the terms and 523 | in general operate on emails with the usual keys. One can also reply to 524 | emails directly from alot: 525 | 526 | ``` example 527 | jaro alot search expression strings folder:known 528 | ``` 529 | 530 | To restrict the search to a single folder, one can use the **folder:** 531 | prefix to search terms. Tags can be used also with **tag:** as well 532 | dates can be specified with ranges using **date:**. Consecutive string 533 | expressions are aloud to refine the search match, connected with logical 534 | and/or, plus also the header to search can be indicated, as for instance 535 | **from:** or **to:**. Read more about this below in the *Search term* 536 | and *Date and time search* sections (extracts from the 537 | **notmuch-search-terms** manpage) and on the notmuch webpage at 538 | 539 | 540 | With the **addr** command the search will be run on the whitelist 541 | addressbook entries instead of actual email contents. 542 | 543 | ``` example 544 | jaro addr joe 545 | ``` 546 | 547 | Will list all addresses matching the string \'joe\' inside the 548 | *whitelist* addressbook. Also the blacklist can be searched this way 549 | adding the switch **-l blacklist**. 550 | 551 | ### Combining terms 552 | 553 | In addition to individual terms, multiple terms can be combined with 554 | Boolean operators ( **and**, **or**, **not** , etc.). Each term in the 555 | query will be implicitly connected by a logical AND if no explicit 556 | operator is provided. 557 | 558 | Parentheses can also be used to control the combination of the Boolean 559 | operators, but will have to be protected from interpretation by the 560 | shell, (such as by putting quotation marks around any parenthesized 561 | expression). 562 | 563 | ### Search terms 564 | 565 | The search terms can consist of free-form text (and quoted phrases) 566 | which will match all messages that contain all of the given 567 | terms/phrases in the body, the subject, or any of the sender or 568 | recipient headers. 569 | 570 | As a special case, a search string consisting of exactly a single 571 | asterisk \"\*\" will match all messages. 572 | 573 | In addition to free text, the following prefixes can be used to force 574 | terms to match against specific portions of an email, (where 575 | \ indicate user-supplied values): 576 | 577 | ``` example 578 | from: 579 | to: 580 | subject: 581 | attachment: 582 | tag: (or is:) 583 | id: 584 | thread: 585 | folder: 586 | date:.. 587 | ``` 588 | 589 | The *from:* prefix is used to match the name or address of the sender of 590 | an email message. 591 | 592 | The *to:* prefix is used to match the names or addresses of any 593 | recipient of an email message, (whether To, Cc, or Bcc). 594 | 595 | Any term prefixed with *subject:* will match only text from the subject 596 | of an email. Searching for a phrase in the subject is supported by 597 | including quotation marks around the phrase, immediately following 598 | *subject:*. 599 | 600 | The / prefix can be used to search for specific filenames 601 | (or extensions) of attachments to email messages. 602 | 603 | For / and *is:* valid tag values include *inbox* and *unread* by 604 | default for new messages added by *notmuch new* as well as any other tag 605 | values added manually with *notmuch tag*. 606 | 607 | For *id:*, message ID values are the literal contents of the Message-ID: 608 | header of email messages, but without the \'\<\', \'\>\' delimiters. 609 | 610 | The *thread:* prefix can be used with the thread ID values that are 611 | generated internally by notmuch (and do not appear in email messages). 612 | These thread ID values can be seen in the first column of output from 613 | *notmuch search* 614 | 615 | The *folder:* prefix can be used to search for email message files that 616 | are contained within particular directories within the mail store. If 617 | the same email message has multiple message files associated with it, 618 | it\'s sufficient for a match that at least one of the files is contained 619 | within a matching directory. Only the directory components below the 620 | top-level mail database path are available to be searched. 621 | 622 | ### Date and time search 623 | 624 | See *DATE AND TIME SEARCH* below for details on the range expression, 625 | and supported syntax for \ and \ date and time 626 | expressions. 627 | 628 | The *date:* prefix can be used to restrict the results to only messages 629 | within a particular time range (based on the Date: header) with a range 630 | syntax of: 631 | 632 | ``` example 633 | date:.. 634 | ``` 635 | 636 | The syntax *\..\* can be 637 | represented using the number of seconds since 1970-01-01 00:00:00 UTC. 638 | 639 | The search syntax also understands a variety of standard and natural 640 | ways of expressing dates and times, both in absolute terms 641 | \'*2012-10-24*\' and in relative terms \'*yesterday*\'. Any number of 642 | relative terms can be combined \'*1 hour 25 minutes*\' and an absolute 643 | date/time can be combined with relative terms to further adjust it. A 644 | non-exhaustive description of the syntax supported for absolute and 645 | relative terms is given below. 646 | 647 | #### The range expression 648 | 649 | ``` example 650 | date:.. 651 | ``` 652 | 653 | The above expression restricts the results to only messages from 654 | \ to \, based on the Date: header. 655 | 656 | \ and \ can describe imprecise times, such as 657 | \"yesterday\". In this case, \ is taken as the earliest time it 658 | could describe (the beginning of yesterday) and \ is taken as 659 | the latest time it could describe (the end of yesterday). Similarly, 660 | date:january..february matches from the beginning of January to the end 661 | of February. 662 | 663 | Currently, we do not support spaces in range expressions. You can 664 | replace the spaces with \'\\\_\', or (in most cases) \'-\', or (in some 665 | cases) leave the spaces out altogether. Examples in this man page use 666 | spaces for clarity. 667 | 668 | Open-ended ranges are supported (since Xapian 1.2.1), i.e. it\'s 669 | possible to specify date:..\ or date:\.. to not limit 670 | the start or end time, respectively. 671 | 672 | Entering date:expr without \"..\" (for example date:yesterday) won\'t 673 | work, as it\'s not interpreted as a range expression at all. You can 674 | achieve the expected result by duplicating the expr both sides of \"..\" 675 | (for example date:yesterday..yesterday). 676 | 677 | ### Relative date and time 678 | 679 | ``` example 680 | [N|number] 681 | (years|months|weeks|days|hours|hrs|minutes|mins|seconds|secs) [...] 682 | ``` 683 | 684 | All refer to past, can be repeated and will be accumulated. 685 | 686 | Units can be abbreviated to any length, with the otherwise ambiguous 687 | single m being m for minutes and M for months. 688 | 689 | Number can also be written out one, two, ..., ten, dozen, hundred. 690 | Additionally, the unit may be preceded by \"last\" or \"this\" (e.g., 691 | \"last week\" or \"this month\"). 692 | 693 | When combined with absolute date and time, the relative date and time 694 | specification will be relative from the specified absolute date and 695 | time. 696 | 697 | Examples: 698 | 699 | ``` example 700 | 5M2d 701 | ``` 702 | 703 | ``` example 704 | two weeks 705 | ``` 706 | 707 | #### Absolute time formats 708 | 709 | ``` example 710 | H[H]:MM[:SS] 711 | [(am|a.m.|pm|p.m.)] 712 | H[H] (am|a.m.|pm|p.m.) 713 | HHMMSS 714 | now 715 | noon 716 | midnight 717 | ``` 718 | 719 | Examples: 720 | 721 | ``` example 722 | 17:05 723 | ``` 724 | 725 | ``` example 726 | 5pm 727 | ``` 728 | 729 | #### Absolute date formats 730 | 731 | ``` example 732 | YYYY-MM[-DD] 733 | DD-MM[-[YY]YY] 734 | MM-YYYY 735 | M[M]/D[D][/[YY]YY] 736 | M[M]/YYYY 737 | D[D].M[M][.[YY]YY] 738 | D[D][(st|nd|rd|th)] Mon[thname] [YYYY] 739 | Mon[thname] D[D][(st|nd|rd|th)] [YYYY] 740 | Wee[kday] 741 | ``` 742 | 743 | Month names can be abbreviated at three or more characters. 744 | 745 | Weekday names can be abbreviated at three or more characters. 746 | 747 | Examples: 748 | 749 | ``` example 750 | 2012-07-31 751 | ``` 752 | 753 | ``` example 754 | 31-07-2012 755 | ``` 756 | 757 | ``` example 758 | 7/31/2012 759 | ``` 760 | 761 | ``` example 762 | August 3 763 | ``` 764 | 765 | #### Time zones 766 | 767 | ``` example 768 | (+|-)HH:MM 769 | ``` 770 | 771 | ``` example 772 | (+|-)HH[MM] 773 | ``` 774 | 775 | Some time zone codes. 776 | 777 | Examples: 778 | 779 | ``` example 780 | UTC 781 | EET 782 | ``` 783 | 784 | ## Compute and visualize statistics 785 | 786 | The **stats** command is useful to quickly visualize statistics 787 | regarding folder usage as well the frequency of emails found in a stream 788 | from stdin. Such streams can be produced by the **search** and 789 | **extract** commands for instance and passed to stats in order to have a 790 | more graphical (yet ASCII based) visualization of results. 791 | 792 | For example lets visualize the frequency of email domain hosts in our 793 | whitelist: 794 | 795 | ``` example 796 | jaro addr | jaro stat emails 797 | ``` 798 | 799 | Will print out bars and domains in descending order, highlighting the 800 | most frequent email domain in our contacts, which turns out to be very 801 | often gmail.com, unfortunately for our own privacy. 802 | 803 | To visualize the frequency of traffic across our filtered folders in the 804 | past month: 805 | 806 | ``` example 807 | jaro search date:1w.. | jaro stat folders 808 | ``` 809 | 810 | Will show quantities of mails filed to folders during the past week, 811 | quickly highlighting the mailinglists that have seen more recent 812 | activity. 813 | 814 | To see who is most active in a mailinglist which is filtered to a 815 | folder: 816 | 817 | ``` example 818 | jaro search folder:org.dyne.dng | jaro extract stdin from | jaro stat names 819 | ``` 820 | 821 | Will give an overview on who is the most prolific writer in the 822 | *org.dyne.dng* mailinglist, filed into the folder by a rule in 823 | **Filters.txt** like: 824 | 825 | ``` example 826 | to dng@lists.dyne save org.dyne.dng 827 | ``` 828 | 829 | Please note the **extract** command is there to extract email addresses 830 | and names found in the *From:* field of all search hits, the command is 831 | explained better in the next chapter: [Addressbook][]*. 832 | 833 | ### Replay results of expensive operations 834 | 835 | Working on the commandline can have some disadvantages. One of them is 836 | that if one runs a long operation to see its result and forgets to save 837 | it also on a file (i.e. using tee) the operation needs to be re-run and 838 | saved. 839 | 840 | Jaro Mail helps the user to **replay** the last output print by saving 841 | it everytime in its own cache. Replay can also save per-command outputs 842 | so that long pipe chains can be repeated selectively by naming the 843 | command. Only some commands have the replay capability, to have a list 844 | of available replays on your system do, based on your last run commands: 845 | 846 | ``` example 847 | jaro replay list 848 | ``` 849 | 850 | To replay the last search command and pipe it into headers to have a 851 | better view of it: 852 | 853 | ``` example 854 | jaro replay search | jaro headers 855 | ``` 856 | 857 | For instance imagine giving the command that searches for all mails sent 858 | to *nettime-l* and extracts all addresses in the *From:* including 859 | duplicates, then sorts them and eliminates duplicates 860 | 861 | ``` example 862 | jaro search to:nettime-l | jaro extract stdin from | sort | uniq 863 | ``` 864 | 865 | Depending from the size of your nettime archives, this operation may 866 | take some time and one may not want to repeat it in order to compute 867 | some stats on the extract result. So one can go on and send the old 868 | output to a new command: 869 | 870 | ``` example 871 | jaro replay extract | jaro stat names 872 | ``` 873 | 874 | This will print out statistics about the most prolific write to the 875 | nettime list according to your archives. 876 | 877 | ### Statistics in brief 878 | 879 | All **stats** commands takes lists of addresses or email messages from 880 | stdin. 881 | 882 | command effect 883 | --------------- ------------------------------------------------------------------------------ 884 | stats email reads addresses from stdin, prints out stats on frequency of emails found 885 | stats names reads addresses from stdin, prints out stats on frequency of names found 886 | stats folders reads paths to messages from stdin, prints out stats on frequency of folders 887 | 888 | So in case of **stats email** or **stats names** any result of search 889 | must be first filtered by **extract** in order to provide addresses to 890 | stats, else errors will occur. To limit the stats to the *From:* field 891 | use the **extract stdin from** also shown in examples, any other 892 | refinement can be done also in the domain of the search commands. 893 | 894 | ## Addressbook 895 | 896 | Addressbooks are the files storing the whitelist, the blacklist and 897 | optionally other custom lists of addresses. The format we use is native 898 | **abook** database files, by convention in 899 | *\$JAROMAILDIR/whitelist.abook* and *\$JAROMAILDIR/blacklist.abook*. 900 | More custom addressbooks can be used by specifying them using **-l** on 901 | the commandline, for instance **-l family** will query the 902 | *\$JAROMAILDIR/family.abook* addressbook; when not used, **whitelist** 903 | is the default. 904 | 905 | Addressbooks can be edited using a interactive console interface, for 906 | instance to add or delete entries by hand: use the **abook** command and 907 | optionally the **-l** option. 908 | 909 | ``` example 910 | jaro abook 911 | ``` 912 | 913 | This will open the current whitelist for edit. To edit the blacklist add 914 | **-l blacklist** instead. 915 | 916 | To quickly dump to the console all names and addresses in the Jaro Mail 917 | addressbook, one can use the **list** command 918 | 919 | ``` example 920 | jaro list 921 | ``` 922 | 923 | To match a string across the addressbook, simply use the composite 924 | command **addr** followed by strings, for instance: 925 | 926 | ``` example 927 | jaro addr dyne 928 | ``` 929 | 930 | will list all addresses containing \'dyne\' in your whitelist. 931 | 932 | ### Address lists 933 | 934 | Jaro Mail handles lists of addresses as plain text files or streams with 935 | entries formatted as \'*Name \*\' and newline terminated. This 936 | simple format conforms (or is normalized to) the RFC822 standard and 937 | UTF-8 charset encoding, both produced on *stdout* and read from *stdin* 938 | by various useful commands to take advantage of console piping. 939 | 940 | Such lists of addresses are the output of the **extract** command, which 941 | is able to read the output of other commands and extract a list of email 942 | addresses found. 943 | 944 | ``` example 945 | jaro search open source date:2w.. | jaro extract stdin 946 | ``` 947 | 948 | Will print to stdout the list of addresses found among the results of a 949 | search for *open source* through all the emails archived in the past 2 950 | weeks. 951 | 952 | ``` example 953 | jaro search date:1y.. and folder:known | jaro extract 954 | ``` 955 | 956 | Will print a sorted list of unique addresses found in the emails 957 | matching the search expression \'*date:1y.. and folder:known*\', meaning 958 | all messages stored in the \'*known*\' folder and not older than 1 year 959 | from now. 960 | 961 | The **import** command is complementary to extraction: it reads an 962 | address list from stdin and imports it inside an addressbook specified 963 | using \'-l\' or a *group* list file provided as argument. 964 | 965 | ``` example 966 | jaro search folder:unsorted | jaro extract | jaro import -l blacklist 967 | ``` 968 | 969 | Will extract all addresses found in unsorted (the maildir collecting all 970 | non-mailinglist emails in which we are not an explicit recipient) and 971 | put them into our blacklist. 972 | 973 | ### Export to VCard and other formats 974 | 975 | VCard is an exchange format useful to interface with other addressbook 976 | software and mobile phones, as well with spyware as Google and Apple 977 | mail. Jaro Mail supports converting address lists to a variety of 978 | formats thanks to *abook*: 979 | 980 | ``` example 981 | jaro addr | jaro export vcard 982 | ``` 983 | 984 | Will take the list of addresses in whitelist and convert it to the 985 | **vcard** format on stdout, ready to be redirected to a file. 986 | 987 | Here below a list of output formats supported as argument to export: 988 | 989 | Format Description 990 | --------- ------------------------------------- 991 | abook abook native format 992 | ldif ldif / Netscape addressbook (.4ld) 993 | vcard vCard 2 file 994 | mutt mutt alias 995 | muttq mutt query format (internal use) 996 | html html document 997 | pine pine addressbook 998 | csv comma separated values 999 | allcsv comma separated values (all fields) 1000 | palmcsv Palm comma separated values 1001 | elm elm alias 1002 | text plain text 1003 | wl Wanderlust address book 1004 | spruce Spruce address book 1005 | bsdcal BSD calendar 1006 | custom Custom format 1007 | 1008 | Of course **export** works with any list of addresses from stdin, for 1009 | instance the result of **extract** operations on search queries, so that 1010 | multiple commands can be concatenated. 1011 | 1012 | ### Addressbook in brief 1013 | 1014 | Here a roundup on the addressbook commands that are available from the 1015 | *jaro* commandline script. Arguments \'-l abook\' take the string to 1016 | identify 1017 | 1018 | Command Arguments Function (print on stdout, import from stdin) 1019 | ------------- ------------- -------------------------------------------------- 1020 | **abook** -l listname edit the addressbook (default whitelist) 1021 | **addr** search expr print list of addresses matching expression 1022 | **extract** maildir print address list of all mails in maildir 1023 | **extract** gpg keyring print address list of gpg public keyring 1024 | **extract** gpg pubkey print address list of gpg key signatures 1025 | **extract** vcard file print address list of entries in VCard file 1026 | **import** -l listname import address list from stdin to addressbook 1027 | **export** format convert address list to a format (default vcard) 1028 | 1029 | ## Filters 1030 | 1031 | In the mail directory a file named `Filters.txt` is filled in with 1032 | filtering rules referencing the contents of the **From:** or **To:** 1033 | fields. 1034 | 1035 | The format of the filters configurarion is pretty easy and self 1036 | explanatory, just have a look at this file and when something changes 1037 | update the filter engine using `jaro update`. 1038 | 1039 | Then use `jaro filter any-maildir/` and the mails contained in 1040 | `any-maildir` will be moved according to the updated filter rules. 1041 | 1042 | Beware that filtering is a lengthy operation, especially on big 1043 | maildirs. 1044 | 1045 | ### Merge maildirs 1046 | 1047 | Mblaze can safely move all e-mails stored in one maildir to another. 1048 | 1049 | `mlist latest-mails | mrefile global-archive` 1050 | 1051 | The above command will move all emails stored inside the maildir folder 1052 | `latest-mails` to the other maildir folder `global-archive`. 1053 | 1054 | ### Backup mails 1055 | 1056 | Backup strategies can be easily managed: just move all emails older than 1057 | a certain period from one maildir to another. 1058 | 1059 | Using jaromail search function with date we obtain a list of matches 1060 | and process them using mblaze's `mrefile` command: 1061 | 1062 | For instance to move all archived mails older than 3 years into a 1063 | separate folder: 1064 | 1065 | ``` example 1066 | jaro search date:3y.. | mrefile /media/backup/old-mails 1067 | ``` 1068 | 1069 | This will move into the maildir `/media/backup/old.mails` all the 1070 | emails older than 3 years that are found in any folder. 1071 | 1072 | One can also use **jaro link** to create symlinks into a new maildir: 1073 | to review results without increasing filesystem occupation, then open 1074 | the destination maildir normally using `neomutt -r -f destination/` 1075 | 1076 | 1077 | ### Security 1078 | 1079 | We love to keep our own email private, this is how jaromail does it. 1080 | 1081 | ### Password storage 1082 | 1083 | Our MUA (Mutt), MTA (Fetchmail) and SMTP (msmtp) require the user to 1084 | input account passwords every time they run, jeopardizing their 1085 | secrecy. 1086 | 1087 | Jaromail saves and provides passwords to these components without 1088 | saving them on the filesystem in clear: they are stored securely 1089 | through [password-store](https://www.passwordstore.org/) (also known 1090 | as `pass`, the standard UNIX password manager). We save All passwords 1091 | in the `$HOME/.password-store` GPG encrypted database under the 1092 | `email/` path followed by the main account email. 1093 | 1094 | ### Secure storage 1095 | 1096 | Jaromail is fully compatible with **Tomb, the Crypto Undertaker** [^4] 1097 | another Dyne.org softwareto manage encrypted volumes. 1098 | 1099 | Using a light combination of scripts between Jaromail and Tomb is 1100 | possible to achieve a strong level of personal security, definitely 1101 | above the average. 1102 | 1103 | In particular, Jaro Mail does not needs system-wide installation, but 1104 | can be installed and used in a way that makes it totally self-contained 1105 | and transportable across systems inside a Tomb. 1106 | 1107 | ### Anonymous emails 1108 | 1109 | To send an anonymous email just change the *From:* header field to 1110 | `anon@mixmaster`. Our application will recognize that as a request 1111 | to send the email across the MixMaster anonymous network. 1112 | 1113 | To change *From:* in Mutt: after composition, when headers and 1114 | attachments are shown, press **ESC** and then **f**, then type the 1115 | special sender address `anon@mixmaster` and press **[Enter]**. 1116 | 1117 | ## Shell environment 1118 | 1119 | ### Zsh commandline completion 1120 | 1121 | For Zsh users out there there is a completion recipe that can facilitate 1122 | the use of Jaro Mail by adding tab completion on the console terminal: 1123 | commands and accounts will be listed and completed automatically just 1124 | like with other commands. 1125 | 1126 | To activate the completion move the file **src/completion/\_jaromail** 1127 | into the path where zsh loads vendor completions, typically that is 1128 | **/usr/share/zsh/vendor-completions**. 1129 | 1130 | ### Quickly send a file via email on Apple/OSX 1131 | 1132 | To right-click on a file and send it via email attach using Jaro Mail 1133 | you must create a \"Service\" using the application \"Automator\". It is 1134 | fairly simple: 1135 | 1136 | 1. Start Automator 1137 | 2. Choose the Service template 1138 | 3. In the dropdown boxes that appear choose \"files or folders\" and 1139 | \"Finder\" 1140 | 4. Look for \"Run Applescript\" in the Library tree 1141 | 5. Drag \"Run Applescript\" in the workflow area and paste this script 1142 | into it: 1143 | 1144 | ``` example 1145 | on run {input, parameters} 1146 | tell application "Terminal" 1147 | activate 1148 | tell window 1 1149 | do script "/Applications/JaroMail.app/Contents/Resources/jaro/bin/jaro " & POSIX path of input 1150 | end tell 1151 | end tell 1152 | end run 1153 | ``` 1154 | 1155 | Now Save the new service (you can name it \"Send file via Jaro Mail\") 1156 | and when you will right click on a file, in the submenu \"Services\" you 1157 | will find the option you just scripted, which will open a Terminal 1158 | asking you the email address, while the file will be already configured 1159 | as attach. 1160 | 1161 | 1162 | ### License 1163 | 1164 | The following copyright notice applies to this manual, the software 1165 | included is licensed under the same or different GNU GPL or BSD 1166 | licenses, or available in the public domain. 1167 | 1168 | ``` example 1169 | Copyleft (C) 2010-2023 Denis Roio 1170 | 1171 | Permission is granted to copy, distribute and/or modify this document 1172 | under the terms of the GNU Free Documentation License, Version 1.3 or 1173 | any later version published by the Free Software Foundation; 1174 | Permission is granted to make and distribute verbatim copies of this 1175 | manual page provided the above copyright notice and this permission 1176 | notice are preserved on all copies. 1177 | ``` 1178 | 1179 | [^1]: The Mutt configuration manual is found on 1180 | or simply typing \'man mutt\' in a 1181 | console terminal. 1182 | 1183 | [^2]: 1184 | 1185 | What this virtuous, sometimes very cryptical man is trying to say 1186 | here is that the Maildir format in its simplicity of implementation 1187 | represents an extremely reliable way to retreive and store emails 1188 | without the risk of losing any if the Internet connection goes down. 1189 | 1190 | While skipping over the internal details of this storage system, 1191 | which basically consists in plain text files saved into 1192 | sub-directories, we will have a look at some very interesting 1193 | features that Jaro Mail can offer to its users and to the even 1194 | larger audience of Maildir format users. 1195 | 1196 | [^3]: The keyring is encrypted using weak symmetric encryption via 1197 | GnuPG, the only protection for the data inside then is the password 1198 | memorized by the used. 1199 | 1200 | To explicitly change a password one can operate the default keyring 1201 | manager or use the command **jaro passwd** (and specify other 1202 | acconts using **-a accountname**)) which will prompt to set for a 1203 | new password even if an old one is known. 1204 | 1205 | [^4]: 1206 | -------------------------------------------------------------------------------- /src/jaromail/docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ECF8F7 !important; 3 | } 4 | .md-header { 5 | background-color: #36968C !important; 6 | } 7 | -------------------------------------------------------------------------------- /src/jaromail/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Jaromail Manual 2 | site_url: https://dyne.org/docs/jaromail 3 | 4 | theme: 5 | name: material 6 | logo: images/dyneorg.svg 7 | favicon: images/favicon.png 8 | 9 | extra_css: 10 | - stylesheets/extra.css 11 | -------------------------------------------------------------------------------- /src/tomb/README.md: -------------------------------------------------------------------------------- 1 | To update have tomb source in ~/devel/tomb and do `make` 2 | 3 | Then commit the resulting manpage rendering 4 | -------------------------------------------------------------------------------- /src/tomb/docs/Makefile: -------------------------------------------------------------------------------- 1 | render: 2 | $(if $(wildcard ${HOME}/devel/tomb/doc/tomb.1),,$(error tomb source not found in ~/devel/tomb)) 3 | perl man-to-md.pl -f < ~/devel/tomb/doc/tomb.1 \ 4 | | sed 's/^.B//; s/.B$$//; s/.EX/\n```\n/; s/.EE/\n```\n/; s/·//;' \ 5 | | awk '/^
.B .IP/ { next; } /tomb\(1\)/ {print("# Tomb, folder encryption on GNU/Linux"); next;} /^# / {printf("#%s",$$0); next} /^tomb,/ {print("Manpage update: " $0)} { print $0 }' > manpage.md
6 | 


--------------------------------------------------------------------------------
/src/tomb/docs/images/awesome-shot.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/awesome-shot.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/cryptounderstaker.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/cryptounderstaker.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/github_tomb.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/github_tomb.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/monmort1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/monmort1.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/nerdonthestreet.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/nerdonthestreet.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/tomb_crew_hkm11.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/tomb_crew_hkm11.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/tomb_n_bats.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/tomb_n_bats.webp


--------------------------------------------------------------------------------
/src/tomb/docs/images/tomb_songs.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyne/docs/63a6a94f6a693341fd5a46ce6fea9dc816f456e3/src/tomb/docs/images/tomb_songs.webp


--------------------------------------------------------------------------------
/src/tomb/docs/index.md:
--------------------------------------------------------------------------------
  1 | ---
  2 | layout: ../../layouts/Layout.astro
  3 | title: "Tomb :: Folder Encryption on GNU/Linux"
  4 | description: "Tomb is a system to make strong encryption easy for everyday use. A tomb is like a locked folder that can be safely transported and hidden in a filesystem."
  5 | cover: "https://dyne.org/social/tomb.png"
  6 | ---
  7 | 
  8 | 
  9 | 
10 | ![Alocate diskspace](images/tomb_n_bats.webp "Tombs and Bats") 11 |
Tombs and Bats
12 |
13 | 14 | Tomb is a **100% Free and Open Source** tool to manage secret files in volumes protected by **strong encryption**. 15 | 16 | Tomb's ambition is to improve safety by way of: 17 | 18 | - A **minimalist** design consisting of small and readable code 19 | - The facilitation of **good practices**, i.e.: key/storage physical separation 20 | - The adoption of a few standards and **battle-tested** components 21 | 22 | 23 | ## How it works 24 | 25 | We design Tomb's hidden file encryption to generate encrypted **storage folders** to be opened and closed using associated **key files**, which are also protected with a **password** chosen by the user. 26 | 27 | A tomb is a file whose **contents are kept secret and indistinguishable**; it can be safely **renamed, transported and hidden in filesystems**; its **keys should be kept separate**, for instance, keeping the tomb file on your computer's hard disk and the key files on a USB stick. **Once open, the tomb looks like a folder**. 28 | 29 | Tomb derives from scripts used in the [dyne:bolic](http://dynebolic.org/) 100% Free GNU/Linux distribution and a shell script (Zsh) using standard filesystem tools (GNU) and the cryptographic API of the Linux kernel (dm-crypt and LUKS via cryptsetup). Tomb's status and error messages are **translated into many human languages** and have **multiple graphical applications** to operate. 30 | 31 |
32 | ![Alocate diskspace](images/awesome-shot.webp "Screenshot") 33 |
Screenshot of a menu entry in a Desktop Environment
34 |
35 | 36 | 37 | ## Get Started 38 | 39 | **Tomb works only on GNU/Linux systems and WSL2 starting with Windows11**. 40 | 41 | If you are already familiar with using the command line, [download the tar.gz](https://files.dyne.org/tomb) and jump to the [installation instructions](https://github.com/dyne/Tomb/blob/master/INSTALL.md). 42 | 43 | Tomb is also found in [many distributions](https://repology.org/project/tomb/versions), so you can use your package manager to install it. 44 | 45 | However, **Tomb is a single script** and is very easy to install manually. Using `make install` in our source distribution will copy it into `/usr/local/bin` along with its manpage (`man tomb`) and language translations. 46 | 47 | Be in charge of your system, and **may the source be with you**! 48 | 49 |
50 | ![Alocate diskspace](images/tomb_songs.webp "Tomb Songs") 51 |
Tomb Songs are the best kept musical secrets in the world
52 |
53 | 54 | 55 | ## Usage 56 | 57 | Tombs are operated from a terminal command line and require **root access** to the machine (or just sudo access to the script). 58 | 59 | To create a 100MB tomb called "secret" do: 60 | 61 | ``` 62 | tomb dig -s 100 secret.tomb 63 | tomb forge secret.tomb.key 64 | tomb lock secret.tomb -k secret.tomb.key 65 | ``` 66 | 67 | To open it, do 68 | ``` 69 | tomb open secret.tomb -k secret.tomb.key 70 | ``` 71 | And to close it 72 | ``` 73 | tomb close 74 | ``` 75 | Or if you are in a hurry 76 | ``` 77 | tomb slam all 78 | ``` 79 | Will close immediately all open tombs, killing all applications using them. 80 | 81 | Here is a **lovely review made by the Linux Action Show guys** in August 2014, where they recommend Tomb as a replacement for Veracrypt 82 | 83 | 84 | 85 | 86 | ## Advanced usage 87 | 88 | The tomb script takes care of several details to improve a user’s 89 | behaviour and the security of tombs in everyday usage: it protects the 90 | typing of passwords from keyloggers, facilitates hiding keys inside 91 | images, mounts directories in place without copying delicate files around, allows a user to kill all running processes and slam close a tomb in a straightforward command, warns the user about free space and last-time usage, etc. 92 | 93 | ![Tomb logo by monmort](images/monmort1.webp) 94 | 95 | One can use **multiple tombs** simultaneously on the same system and list them using `tomb list`. 96 | 97 | ![Tomb logo by monmort](images/monmort1.webp) 98 | 99 | Using `tomb resize`, one can **expand tombs** to have more space (but cannot shrink them). 100 | 101 | ![Tomb logo by monmort](images/monmort1.webp) 102 | 103 | When it is open, a tomb can **bind contents inside the user’s `$HOME`** folder using `bind-hooks`. For instance, `.gnupg` will only be found inside your `$HOME` when the tomb opens. 104 | 105 | ![Tomb logo by monmort](images/monmort1.webp) 106 | 107 | A tomb can be used on a local machine with **keys on a server** and never stored on the same device: `ssh me@dyne.org 'cat my.tomb.key' | tomb open my.tomb -k -` the option `-k -` tells tomb to take the key from stdin. 108 | 109 | ![Tomb logo by monmort](images/monmort1.webp) 110 | 111 | It is also possible to **store a tomb on a cloud service and mount it locally**, ensuring remote servers cannot access contents. One can use **sshfs** for this: 112 | 113 | ``` 114 | sshfs -o allow_root me@dyne.org:/ /mnt/cloud/ 115 | tomb open /mnt/cloud/my.tomb -k my.key 116 | ``` 117 | 118 | [This paper](https://www.researchgate.net/publication/262698824_Data_privacy_in_Desktop_as_a_Service) provides a lot of details about using tombs hosted on cloud storage. 119 | 120 | ![Tomb logo by monmort](images/monmort1.webp) 121 | 122 | Tomb also supports **deniable key storage** using steganography. One can `tomb bury` and `tomb exhume` keys to and from `JPEG` images when the utility `steghide` is installed. When securing private data, one must never forget where the keys are. It may be easier to remember a picture, as well it may be less suspicious to transport it and exchange it as a file. 123 | 124 | ![Tomb logo by monmort](images/monmort1.webp) 125 | 126 | The command `tomb engrave` also allows to backup keys on paper by saving them as printable QR codes, to hide it between the pages of a book. To recover an engraved key, one can scan it with any phone and save the resulting plain text file as the tomb key. 127 | 128 | You can also watch this other video guide by Nerd on the Street. 129 | 130 | 131 | 132 | ## External applications 133 | 134 | The following applications are compatible with Tomb: 135 | 136 | - [pass-tomb](https://github.com/roddhjav/pass-tomb) is a console-based wrapper of the excellent password-keeping program [pass](https://www.passwordstore.org) that helps to keep the whole tree of passwords encrypted inside a tomb. 137 | 138 | - [Secrets](https://secrets.dyne.org) is an online software to split a Tomb key into shares that a quorum of owners can merge to reconstitute. 139 | 140 | - [Mausoleum](https://github.com/mandeep/Mausoleum) is a graphical interface to facilitate the creation and management of tombs, written in Python. 141 | 142 | - [zuluCrypt](https://mhogomchungu.github.io/zuluCrypt/) is a graphical application to manage various types of encrypted volumes on GNU/Linux, among them also Tombs, written in C++. 143 | 144 | 145 | ## Frequently asked questions 146 | 147 | You can find a list of [Frequently Asked Questions (FAQ) on the website](https://dyne.org/tomb) 148 | 149 | ## Development 150 | 151 |
152 | ![Alocate diskspace](images/github_tomb.webp "Github Tomb") 153 |
A sugarskull octocat
154 |
155 | 156 | Tomb is on [GitHub](https://github.com/dyne/Tomb), where most of the community activity goes. 157 | 158 | Developers can interact with us via a discussion area, issues, or pull requests. The README is also a brief introduction for developers willing to engage. 159 | 160 | The [short tomb tester howto](https://github.com/dyne/Tomb/wiki/TesterHowTo) provides a guide to troubleshooting problems. Anyone planning to write code in Tomb should first look at the [short tomb developer howto](https://github.com/dyne/Tomb/wiki/DeveloperHowto). 161 | 162 | To get in touch with us in person please plan to participate in one of the yearly [italian hackmeeting](http://hackmeeting.org), usually held during summer on the peninsula. 163 | 164 |
165 | ![Alocate diskspace](images/tomb_crew_hkm11.webp "Tomb Crew") 166 |
A cheerful picture of Tomb developers crew at Hackmeeting 2011 in Firenze
167 |
168 | 169 | 170 | 171 | 172 | > All I know is what the words know, and dead things, and that makes a handsome little sum, with a beginning and a middle and an end, as in the well-built phrase and the long sonata of the dead. - Samuel Beckett 173 | 174 | -------------------------------------------------------------------------------- /src/tomb/docs/manpage.md: -------------------------------------------------------------------------------- 1 | # Tomb, folder encryption on GNU/Linux 2 | 3 | Manpage update: 4 | tomb, Jun 25, 2023 5 | 6 | 7 | 8 | 9 | 10 | ## Description 11 | 12 | Tomb is an application to manage the creation and access of encrypted 13 | storage files: it can be operated from commandline and it can 14 | integrate with a user's graphical desktop. 15 | 16 | Tomb generates encrypted storage files to be opened and closed using 17 | their associated keys, which are also protected with a password chosen 18 | by the user. To create, open and close tombs a user will need super 19 | user rights to execute the tomb commandline utility. 20 | 21 | A tomb is like a locked folder that can be safely transported and 22 | hidden in a filesystem; it encourages users to keep their keys 23 | separate from tombs, for instance keeping a tomb file on your computer 24 | harddisk and its key file on a USB stick. 25 | 26 | 27 | 28 | 29 | 30 | ## Commands 31 | 32 | 33 | 34 | * dig 35 | Generates a file that can be used as a tomb and will occupy as much 36 | space as its desired initial size, the unlocked _.tomb_ file can 37 | then be locked using a _key_. It takes a mandatory _-s_ option 38 | which is the size in megabytes (MiB). Tombs are digged using random 39 | data gathered from a non-blocking source (/dev/urandom). For very 40 | large tombs this may take up too much time and entropy, then it is 41 | possible to use _fallocate(1)_ being aware it does not pre-fill 42 | with random data, decreasing the tomb's security. 43 | 44 | 45 | * forge 46 | Creates a new _key_ and prompts the user for a _password_ to protect 47 | its usage using symmetric encryption. This operation uses random data from a 48 | non-blocking source (/dev/urandom) and it may take long only in some cases; to 49 | switch using a blocking source the _--use-random_ flag can be used. The 50 | _-g_ option switches on the use of a GPG key instead of a password 51 | (asymmetric encryption), then the _-r_ option indicates the recipient key; 52 | more recipient GPG ids can be indicated (comma separated). The default cipher 53 | to protect the key is AES256, a custom one can be specified using the _-o_ 54 | option, for a list of supported ciphers use _-v_. For additional protection 55 | against dictionary attacks on keys, the _--kdf_ option can be used when 56 | forging a key, making sure that the binaries in _extras/kdf_ were compiled 57 | and installed on the system. 58 | 59 | 60 | * lock 61 | Initializes and locks an empty tomb (made with _dig_) using a key 62 | (made with _forge_), making it ready for usage. After this 63 | operation, the tomb can only be opened in possession of the key and 64 | knowing its password. As in any other command requiring a key, the 65 | option _-k_ should be used to specify a key file; in case of 66 | encryption to GPG recipients the _-g_ flag should be used followed 67 | by _-r_ and the recipient's secret GPG key id. The _-o_ 68 | option can be used to specify the cipher specification: default is 69 | "aes-xts-plain64", old versions of Tomb used "aes-cbc-essiv:sha256". 70 | If you are looking for something exotic, also try 71 | "serpent-xts-plain64". More options may be found in cryptsetup(8) and 72 | Linux documentation. The _--filesystem_ option can be used to 73 | specify an alternative filesystem used to format the tomb, 74 | in place of the default "ext4". This operation requires root 75 | privileges to loopback mount, format the tomb (using LUKS and mkfs), 76 | then set the key in its first LUKS slot. 77 | 78 | Supported filesystems for _--filesystem_: 79 | * ext3 80 | using operating system defaults 81 | * ext4 82 | using operating system defaults 83 | * btrfs 84 | for tombs >= 47MB using operating system defaults 85 | * btrfsmixedmode 86 | for tombs >=18MB btrfs mixed mode (see mkfs.btrfs(8)) 87 | * ext3maxinodes 88 | ext3 with a maximum of inodes (for many small files) 89 | * ext4maxinodes 90 | ext4 with a maximum of inodes (for many small files) 91 | 92 | 93 | * open 94 | Opens an existing _tomb file_ (first argument) using a key 95 | (_-k_) which can also be hidden inside a _jpeg image_ (see 96 | _bury_/_exhume_) or a long text file 97 | (see_cloak_/_uncloak_). If a second argument is given it will 98 | indicate the _mountpoint_ where the tomb should be made 99 | accessible, else the tomb is mounted in a directory inside /media (if 100 | not available it uses /run/media/$USER). The option _-o_ can be 101 | used to pass mount(8) options (default: rw,noatime,nodev). The 102 | _-g_ option is needed when using GPG encryption to recipients. 103 | 104 | 105 | * list 106 | List all the tombs found open, including information about the time 107 | they were opened and the hooks that they mounted. If the first 108 | argument is present, then shows only the tomb named that way or 109 | returns an error if it's not found. If the option 110 | _--get-mountpoint_ is used then print a simple list of currently 111 | open tomb mountpoint paths. 112 | 113 | 114 | * ps 115 | List all the processes found running inside the tombs that are open, 116 | printing out their PIDs and owners. This is useful to have an overview 117 | of programs that are keeping the tombs busy and would eventually be 118 | killed by the _slam_ command. The lsof(8) utility is used 119 | internally to enumerate processes running in one or all tombs. 120 | 121 | 122 | * index 123 | Creates or updates the search indexes of all tombs currently open: 124 | enables use of the _search_ command using simple word patterns on 125 | file names. Indexes are created using plocate's updatedb(8) and 126 | recoll(1) if they are found on the system. Indexes allow one to search 127 | very fast for filenames and contents inside a tomb, they are stored 128 | inside it and are not accessible if the Tomb is closed. To avoid 129 | indexing a specific tomb simply touch a _.noindex_ file in it. 130 | Useful tools to have: poppler-utils, aspell, xdg-utils, plocate. 131 | 132 | 133 | * search 134 | Takes any string as argument and searches for them through all tombs 135 | currently open and previously indexed using the _index_ command. 136 | The search matches filenames if plocate is installed and then also 137 | file contents if recoll is installed, all results are listed on the 138 | console. 139 | One can also run recoll's GUI using _recoll -c /media/tomb_ 140 | 141 | 142 | * close 143 | Closes a currently open tomb. If more tombs are open, the first 144 | argument should be used to specify the name of the tomb to be closed, 145 | or _all_ to close all currently open tombs. This command fails if 146 | the tomb is in use by running processes (to force close, see 147 | _slam_ below). 148 | 149 | 150 | * slam 151 | Closes a tomb like the command _close_ does, but it doesn't fail 152 | even if the tomb is in use by other application processes: it looks 153 | for and closes each of them (in order: TERM, HUP, KILL). This command may 154 | provoke unsaved data loss, but assists users to face surprise 155 | situations. It requires _lsof_ else it falls back to _close_. 156 | 157 | 158 | 159 | * passwd 160 | Changes the password protecting a key file specified using 161 | _-k_. With keys encrypted for GPG recipients use _-g_ followed 162 | by _-r_ to indicate the new recipient key, or a comma separated 163 | list.. The user will need to know the key's current password, or 164 | possess at least one of the current recipients GPG secret keys, 165 | because the key contents will be decoded and reencoded using the new 166 | passwords or keys. If the key file is broken (missing headers) this 167 | function also attempts its recovery. 168 | 169 | 170 | * setkey 171 | Changes the key file that locks a tomb, substituting the old one with 172 | a new one. Both the old and the new key files are needed for this 173 | operation and their passwords or GPG recipient(s) secret keys must be 174 | available. The new key must be specified using the _-k_ option, 175 | the first argument should be the old key and the second and last 176 | argument the tomb file. Use the _-g_ option to unlock the tomb 177 | with a GPG key, the _-r_ to indicate the recipient or a comma 178 | separated list for more than one recipient. 179 | 180 | 181 | * resize 182 | Increase the size of a tomb file to the amount specified by the 183 | _-s_ option, which is the new size in megabytes (MiB). Full access 184 | to the tomb using a key (_-k_) and its password is required. Tombs 185 | can only grow and can never be made smaller. This command makes use of 186 | the cryptsetup(8) resize feature and the resize2fs command: its much 187 | more practical than creating a new tomb and moving everything into 188 | it. There is no data-loss if a failure occurs during resize: the 189 | command can be re-launched and the resize operation will complete. 190 | 191 | 192 | * engrave 193 | This command transforms a tomb key into an image that can be printed 194 | on paper and physically stored as backup, i.e. hidden in a book. It 195 | Renders a QRCode of the tomb key, still protected by its password: a 196 | PNG image (extension _.qr.png_) will be created in the current 197 | directory and can be later printed (fits an A4 or Letter format). To 198 | recover an engraved key one can use any QRCode reader on a smartphone: 199 | save it into a file and then use that file as a key (_-k_). 200 | 201 | 202 | * bury 203 | Hides a tomb key (_-k_) inside a _jpeg image_ (first argument) 204 | using _steganography_: the image will change in a way that cannot 205 | be noticed by human eye and hardly detected by data analysis. This 206 | option is useful to backup tomb keys in unsuspected places; it depends 207 | from the availability of _steghide_. Use the _-g_ flag and 208 | _-r_ option followed by recipient id to use GPG asymmetric 209 | encryption. 210 | 211 | 212 | * exhume 213 | This command recovers from jpeg images the keys that were previously 214 | hidden into them using _bury_. Exhume requires a key filename 215 | (_-k_) and a _jpeg image_ file (first argument) known to be 216 | containing a key. If the right key password is given, the key will be 217 | exhumed. If the password is not known, it is very hard to verify if a 218 | key is buried in any image or not. 219 | 220 | 221 | * cloak 222 | Cloaks a tomb key (_-k_) disguising it as a text file using a 223 | cipher from _extras/cloak/ciphers_ (second argument) using 224 | _cloakify_. This option is useful to backup tomb keys in 225 | unsuspected places; it needs _extras/cloak_ installed and 226 | _python3_. 227 | 228 | 229 | * uncloak 230 | Recovers a tomb key from a cloaked text file. Uncloak requires a text 231 | file (first argument), a cipher file (second argument) and optionally 232 | an output file (third argument). If the first two parameters are 233 | correct then the output will be a valid tomb key file restored from 234 | cloak. 235 | 236 | 237 | 238 | 239 | ## Options 240 | 241 | 242 | 243 | * -k _<keyfile>_ 244 | For all operations requiring a key, this option specifies the location 245 | of the key file to use. Arguments can also be _jpeg image_ files 246 | where keys have been hidden using the _bury_ or _cloak_ 247 | commands, or text files retrieved from _engraved_ QR codes. If the 248 | _keyfile_ argument is "-" (dash), Tomb will read the key from 249 | stdin (blocking). 250 | 251 | * -n 252 | Skip processing of exec-hooks and bind-hooks if found inside the tomb. 253 | See the _HOOKS_ section in this manual for more information. 254 | 255 | * -p 256 | When opening a tomb, preserves the ownership of all files and 257 | directories contained in it. Normally the _open_ command changes 258 | the ownership of a tomb's contents to the UID and GID of the user who 259 | has successfully opened it: it is a usability feature in case a tomb is 260 | used by a single user across different systems. This flag deactivates 261 | this behaviour. 262 | 263 | * -o 264 | Manually specify mount options to be used when opening a tomb instead 265 | of the default _rw,noatime,nodev_, i.e. to mount a tomb read-only 266 | (ro) to prevent any modification of its data. Can also be used to 267 | change the symmetric encryption algorithm for keys during _forge_ 268 | operations (default _AES256_) or the LUKS encryption method during 269 | _lock_ operations (default _aes-xts-plain64_). 270 | 271 | * -f 272 | Force flag, currently used to override swap checks, might be 273 | overriding more wimpy behaviours in future, but make sure you know 274 | what you are doing if you force an operation. 275 | 276 | * -s _<MBytes>_ 277 | When digging or resizing a tomb, this option must be used to specify 278 | the _size_ of the new file to be created. Units are megabytes (MiB). 279 | 280 | * -g 281 | Tell tomb to use an asymmetric GnuPG key encryption instead of a 282 | symmetric passphrase to protect a tomb key. This option can be 283 | followed by _-r_ when the command needs to specify recipient(s). 284 | 285 | * -r _<gpg\_id>[,<gpg\_id2>]_ 286 | Provide a new set of recipient(s) to encrypt a tomb key. _gpg\_ids_ 287 | can be one or more GPG key ID, comma separated. All GPG keys must be 288 | trusted keys in GPG. 289 | 290 | * --kdf _<itertime>_ 291 | Activate the KDF feature against dictionary attacks when creating a key: forces 292 | a delay of _<itertime>_ times every time this key is used. The actual time 293 | to wait depends on the CPU speed (default) or the RAM size (argon2) of the 294 | computer where the key is used. Using 5 or 10 is a sane amount for modern 295 | computers, the value is multiplied by 1 million. 296 | 297 | * --kdftype _argon2 | pbkdf2_ 298 | Adopt the _argon2_ algorithm for KDF, stressing the RAM capacity rather 299 | than the CPU speed of the computer decrypting the tomb. Requires the 300 | _argon2_ binary by P-H-C to be installed, as packaged by most distros. 301 | Default is _pbkdf2_. 302 | 303 | * --kdfmem _<memory>_ 304 | In case of _argon2_ KDF algorithm, this value specifies the size of RAM 305 | used: it consists of a number which is the elevated power of two in kilobytes. 306 | Default is 18 which is 250 MiB (2^18 = 262,144 kilobytes). 307 | 308 | * --sudo _<executable>_ 309 | Select a different tool than sudo for privilege escalation. 310 | Alternatives supported so far are: pkexec, doas, sup, sud. For any 311 | alternative to work the executable must be included in the current 312 | PATH. 313 | 314 | 315 | * -h 316 | Display a help text and quit. 317 | 318 | * -v 319 | Display version and quit. 320 | 321 | * -q 322 | Run more quietly 323 | 324 | * -D 325 | Print more information while running, for debugging purposes 326 | 327 | 328 | 329 | 330 | ## Dev Mode 331 | 332 | 333 | * --no-color 334 | Suppress colors in console output (needed for string parsing by 335 | wrappers). 336 | 337 | * --unsafe 338 | Enable using dev-mode arguments, i.e. to pass passwords from 339 | commandline options. This is mostly used needed for execution by 340 | wrappers and testing suite. 341 | 342 | * --use-random 343 | Use a blocking random source. Tomb uses by default /dev/urandom since 344 | the non-blocking source of Linux kernel doesn't degrades the quality 345 | of random. 346 | 347 | * --tomb-pwd <string> 348 | Use string as password when needed on tomb. 349 | 350 | * --tomb-old-pwd <string> 351 | Use string as old password when needed in tomb commands requiring 352 | multiple keys, like _passwd_ or _setkey_. 353 | 354 | * -U 355 | Switch to this user ID when dropping privileges. 356 | 357 | * -G 358 | Switch to this group ID when dropping privileges. 359 | 360 | * -T 361 | Switch to this TTY terminal when dropping privileges. 362 | 363 | 364 | 365 | 366 | ## Hooks 367 | 368 | Hooks are special files that can be placed inside the tomb and trigger 369 | actions when it is opened and closed; there are two kinds of such 370 | files: _bind-hooks_ and _exec-hooks_ can be placed in the 371 | base root of the tomb. 372 | 373 | 374 | 375 | * bind-hooks 376 | This hook file consists of a simple text file named _bind-hooks_ 377 | containing a two column list of paths to files or directories inside 378 | the tomb. The files and directories will be made directly 379 | accessible by the tomb _open_ command inside the current user's 380 | home directory. Tomb uses internally the "mount -o bind" command to 381 | bind locations inside the tomb to locations found in $HOME. In the 382 | first column are indicated paths relative to the tomb and in the 383 | second column are indicated paths relative to $HOME contents, for 384 | example: 385 | 386 | ``` 387 | 388 | mail mail 389 | .gnupg .gnupg 390 | .fmrc .fetchmailrc 391 | .mozilla .mozilla 392 | 393 | ``` 394 | 395 | 396 | 397 | * exec-hooks 398 | This hook file gets executed as user by tomb with the first argument 399 | determining the step of execution (_open_ or _close_) and the second 400 | being the full path to the mountpoint. The _exec-hooks_ file should be 401 | executable (ELF or shell script) and present inside the Tomb. Tomb 402 | executes this hook as user and adds the name, loopback device and 403 | dev-mapper device paths as additional arguments for the _close_ 404 | command. 405 | 406 | 407 | 408 | 409 | ## Privilege Escalation 410 | 411 | The tomb commandline tool needs to acquire super user rights to 412 | execute most of its operations: so it uses sudo(8) or other configured 413 | tools, while pinentry(1) is adopted to collect passwords from the 414 | user. Tomb executes as super user only when required. 415 | 416 | To be made available on multi user systems, the superuser execution of 417 | the tomb script can be authorized for users without jeopardizing the 418 | whole system's security: just add such a line to _/etc/sudoers_: 419 | 420 | 421 | ``` 422 | 423 | username ALL=NOPASSWD: /usr/local/bin/tomb 424 | 425 | ``` 426 | 427 | 428 | To avoid that tomb execution is logged by _syslog_ also add: 429 | 430 | 431 | ``` 432 | 433 | Cmnd_Alias TOMB = /usr/local/bin/tomb 434 | Defaults!TOMB !syslog 435 | 436 | ``` 437 | 438 | 439 | 440 | 441 | 442 | ## Password Input 443 | 444 | Password input is handled by the pinentry program: it can be text 445 | based or graphical and is usually configured with a symlink. When 446 | using Tomb in a graphical environment (X11 or Wayland) it is better 447 | to use either pinentry-gtk2 (deprecated), pinentry-gnome or 448 | pinentry-qt because it helps preventing keylogging by other clients. 449 | When using it from a remote ssh connection it might be necessary to 450 | force use of pinentry-tty for instance by unsetting the DISPLAY (X11) 451 | or WAYLAND_DISPLAY (Wayland) environment var. 452 | 453 | 454 | 455 | 456 | ## Swap 457 | 458 | On execution of certain commands Tomb will complain about swap memory 459 | on disk when present and abort if your system has swap 460 | activated. You can disable this behaviour using the 461 | _--force_. Before doing that, however, you may be interested in 462 | knowing the risks of doing so: 463 | 464 | * 465 | During such operations a lack of available memory could cause the swap 466 | to write your secret key on the disk. 467 | * 468 | Even while using an opened tomb, another application could occupy too 469 | much memory so that the swap needs to be used, this way it is possible 470 | that some contents of files contained into the tomb are physically 471 | written on your disk, not encrypted. 472 | 473 | 474 | If you don't need swap, execute _ swapoff -a_. If you really need 475 | it, you could make an encrypted swap partition. Tomb doesn't detect if 476 | your swap is encrypted, and will complain anyway. 477 | 478 | 479 | 480 | 481 | ## Deniability 482 | 483 | The possibility to have an encrypted volume which is invisible and 484 | cannot be detected is called "deniability". The cryptographic layer of 485 | the device mapper in Linux (dm-crypt) does not implement 486 | deniability. Tomb is just a wrapper on top of that and it doesn't add 487 | cryptographic deniability. However a certain way of using tomb can 488 | facilitate a weak sort of deniability outside of the scenario of 489 | seized devices and forensic analysis of files and blocks on disc. 490 | 491 | For instance to eliminate any trace of tomb usage from the shell 492 | history ZSh users can activate the "HISTIGNORESPACE" feature and 493 | prefix all invocations of tomb with a blank space, including two lines 494 | in ".zshrc": 495 | 496 | 497 | ``` 498 | 499 | export HISTIGNORESPACE=1 500 | alias tomb=' tomb' 501 | 502 | ``` 503 | 504 | 505 | 506 | 507 | 508 | ## Share a Tomb 509 | A tomb key can be encrypted with more than one recipient. Therefore, a 510 | tomb can be shared between different users. The recipients are given 511 | using the _-r_ (or/and _-R_) option and if multiple each GPG 512 | key ID must be separated by a comma (_,_). Sharing a tomb is a 513 | very sensitive action and the user needs to trust that all the GPG 514 | public keys used are kept safe. If one of them its stolen or lost, it 515 | will be always possible to use it to access the tomb key unless all 516 | its copies are destroyed. The _-r_ option can be used in the tomb 517 | commands: _open_, _forge_ _setkey_, _passwd_, 518 | _bury_, _exhume_ and _resize_. 519 | 520 | 521 | 522 | 523 | ## Examples 524 | 525 | 526 | * 527 | Create a 128MB large "secret" tomb and its keys, then open it: 528 | 529 | 530 | ``` 531 | 532 | tomb dig -s 128 secret.tomb 533 | 534 | tomb forge secret.tomb.key 535 | 536 | tomb lock secret.tomb -k secret.tomb.key 537 | 538 | tomb open secret.tomb -k secret.tomb.key 539 | 540 | ``` 541 | 542 | 543 | * 544 | Open a Tomb using the key from a remote SSH shell, without saving any 545 | local copy of it: 546 | 547 | 548 | ``` 549 | 550 | ssh user@my.shell.net 'cat .secrets/tomb.key' | tomb open secret.tomb -k - 551 | 552 | ``` 553 | 554 | 555 | * 556 | Open a Tomb on a remote server passing the unencrypted local key on stdin via SSH, 557 | without saving any remote copy of it: 558 | 559 | 560 | ``` 561 | 562 | gpg -d .secrets/tomb.key | ssh server tomb open secret.tomb -k cleartext --unsafe 563 | 564 | ``` 565 | 566 | 567 | * 568 | Create a bind hook that places your GnuPG folder inside the tomb, but 569 | makes it reachable from the standard $HOME/.gnupg location every time 570 | the tomb will be opened: 571 | 572 | 573 | ``` 574 | 575 | tomb open GPG.tomb -k GPG.tomb.key 576 | echo ".gnupg .gnupg" > /media/GPG.tomb/bind-hooks 577 | mv ~/.gnupg /media/GPG.tomb/.gnupg && mkdir ~/.gnupg 578 | tomb close GPG && tomb open GPG.tomb -k GPG.tomb.key 579 | 580 | ``` 581 | 582 | 583 | * 584 | Script a tomb to launch the Firefox browser every time is opened, 585 | keeping all its profile data inside it: 586 | 587 | 588 | ``` 589 | 590 | tomb open FOX.tomb -k FOX.tomb.key 591 | cat <<EOF > /media/FOX.tomb/exec-hooks 592 | #!/bin/sh 593 | if [ "$1" = "open" ]; then 594 | firefox -no-remote -profile "$2"/firefox-pro & 595 | fi 596 | EOF 597 | chmod +x /media/FOX.tomb/exec-hooks 598 | mkdir /media/FOX.tomb/firefox-pro 599 | 600 | ``` 601 | 602 | 603 | * 604 | Script a tomb to archive Pictures using Shotwell, launching it on open: 605 | 606 | 607 | ``` 608 | 609 | tomb open Pictures.tomb -k Pictures.tomb.key 610 | cat <<EOF > /media/Pictures.tomb/bind-hooks 611 | Pictures Pictures 612 | EOF 613 | cat <<EOF > /media/Pictures.tomb/exec-hooks 614 | #!/bin/sh 615 | if [ "$1" = "open" ]; then 616 | which shotwell > /dev/null 617 | if [ "$?" = "0" ]; then 618 | shotwell -d "$2"/Pictures/.shotwell & 619 | fi 620 | fi 621 | EOF 622 | chmod +x /media/Pictures.tomb/exec-hooks 623 | 624 | ``` 625 | 626 | 627 | 628 | 629 | 630 | ## Bugs 631 | Please report bugs on the Github issue tracker at 632 | [](https://github.com/dyne/Tomb/issues) 633 | 634 | One can also try to get in touch with developers via the #dyne chat 635 | channel on _https://irc.dyne.org_. 636 | 637 | 638 | 639 | 640 | ## Copying 641 | 642 | This manual is Copyright (c) 2011-2021 by Denis Roio <_jaromil@dyne.org_> 643 | 644 | This manual includes contributions by Boyska and Hellekin O. Wolf. 645 | 646 | Permission is granted to copy, distribute and/or modify this manual 647 | under the terms of the GNU Free Documentation License, Version 1.1 or 648 | any later version published by the Free Software Foundation. 649 | Permission is granted to make and distribute verbatim copies of this 650 | manual page provided the above copyright notice and this permission 651 | notice are preserved on all copies. 652 | 653 | 654 | 655 | 656 | ## Availability 657 | 658 | The most recent version of Tomb sourcecode and up to date 659 | documentation is available for download from its website on 660 | _https://tomb.dyne.org_. 661 | 662 | 663 | 664 | 665 | ## See Also 666 | 667 | 668 | 669 | * cryptsetup(8) 670 | 671 | * pinentry(1) 672 | 673 | * gpg-agent(1) 674 | 675 | GnuPG website: https://www.gnupg.org 676 | 677 | DM-Crypt website: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt 678 | 679 | LUKS website: https://gitlab.com/cryptsetup/cryptsetup/wikis/home 680 | -------------------------------------------------------------------------------- /src/tomb/docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ECF8F7 !important; 3 | } 4 | .md-header { 5 | background-color: #36968C !important; 6 | } 7 | -------------------------------------------------------------------------------- /src/tomb/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Tomb Manual 2 | site_url: https://dyne.org/docs/tomb 3 | 4 | theme: 5 | name: material 6 | logo: images/dyneorg.svg 7 | favicon: images/favicon.png 8 | 9 | extra_css: 10 | - stylesheets/extra.css 11 | 12 | nav: 13 | - Introduction: index.md 14 | - Manpage: manpage.md 15 | 16 | markdown_extensions: 17 | - attr_list 18 | - md_in_html 19 | - admonition 20 | - pymdownx.details 21 | - pymdownx.superfences 22 | --------------------------------------------------------------------------------