Compare commits

...

355 commits

Author SHA1 Message Date
71491ab6fc
Update to release v2.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Waiting to run
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Failing after 3s
2024-09-21 17:03:14 -04:00
5041e0c991
Let's try again.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 16s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Failing after 3s
2024-09-21 16:59:42 -04:00
66c237727b
Apparently on: [tags] doesn't work.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 17s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Failing after 0s
2024-09-21 16:55:55 -04:00
505d01cea1
Hopefully finalize the release logic.
All checks were successful
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 20s
2024-09-21 16:52:41 -04:00
c7433bb745
Order actions properly.
All checks were successful
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 15s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Successful in 3s
2024-09-21 16:36:26 -04:00
8546ddb909
Get the ref name properly.
All checks were successful
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 15s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Successful in 2s
2024-09-21 16:35:18 -04:00
0e946b2422
Fix Release artifact
All checks were successful
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 15s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Successful in 3s
2024-09-21 16:32:15 -04:00
12e11f74a1
Fix typo in Git command.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Failing after 10s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Successful in 2s
2024-09-21 16:26:57 -04:00
3304f8c08f
Add release job.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Failing after 9s
Release Telodendria / Release Telodendria (aarch64, alpine) (push) Failing after 18s
2024-09-21 16:23:19 -04:00
59e3a6d3e2 Okay nevermind, that breaks CI.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Failing after 10s
2024-09-21 15:54:33 -04:00
46dcf8ab59 Fix submodule url.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Failing after 2s
2024-09-21 15:49:59 -04:00
21b830e514 Cytoplasm submodule now clones over SSH.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Failing after 2s
2024-09-21 15:49:06 -04:00
42223c94bb Basic work toward compiling on Darwin.
Some checks failed
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Failing after 2s
2024-09-21 15:47:25 -04:00
e083ece2ed Fast-forward Cytoplasm to latest master.
All checks were successful
Compile Telodendria / Compile Telodendria (aarch64, alpine) (push) Successful in 20s
2024-09-21 15:21:11 -04:00
2fcd51e810 Use Forgejo action runner. 2024-09-21 15:20:05 -04:00
lda
775b1d9571 Use hashtypes(c.f Cytoplasm#47) (#57)
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
This makes Telodendria compatible with Telodendria/Cytoplasm#47.

---

Please review the developer certificate of origin:

1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution—including all
personal information I submit with it—is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.

- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

Co-authored-by: Jordan Bancino <jordan@bancino.net>
Co-authored-by: LDA <lda@ari.lt>
Reviewed-on: #57
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-08-27 09:47:25 -04:00
6dd4440125 remove use of install in Makefile (#56)
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
The current make `install` target uses `install -D` to create leading components when install into a directory.
This doesn't work on some variants of `install(1)`.

Also see Telodendria/Cytoplasm#45 and Telodendria/Cytoplasm#13 and 08166dd3a7.

---

Please review the developer certificate of origin:

1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution&mdash;including all
personal information I submit with it&mdash;is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.

- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

Reviewed-on: #56
Co-authored-by: LevitatingBusinessMan (Rein Fernhout) <me@levitati.ng>
Co-committed-by: LevitatingBusinessMan (Rein Fernhout) <me@levitati.ng>
2024-08-23 16:16:33 -04:00
lda
e263eca5dc Fix build issues with #28 (#55)
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
Just here to fix old code issues with #28. (we really need CI back, don't we?)

---

Please review the developer certificate of origin:

1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution&mdash;including all
personal information I submit with it&mdash;is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.

- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

Co-authored-by: LDA <lda@ari.lt>
Reviewed-on: #55
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-08-21 14:32:42 -04:00
lda
ac9372a30a User Directory Patch #70 (#28)
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
Reviewed-on: #28
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-08-18 19:31:14 -04:00
a8924b8437
Update Cytoplasm to v0.4.1.
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
2024-05-18 10:55:15 -04:00
lda
ff85b72899 Fix IPv6 issue in parser (#52)
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
Fixes compilation issue in the parser (and checks IPv6 slightly more).
---

Please review the developer certificate of origin:

1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution&mdash;including all
personal information I submit with it&mdash;is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.

- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

Co-authored-by: Jordan Bancino <jordan@bancino.net>
Reviewed-on: #52
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-03-29 11:48:25 -05:00
lda
bccbb3bcac Fix other double-free issue with router. (#53)
Some checks are pending
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Waiting to run
Similar issue to #33.
---

Please review the developer certificate of origin:

1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution&mdash;including all
personal information I submit with it&mdash;is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.

- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

Co-authored-by: Jordan Bancino <jordan@bancino.net>
Reviewed-on: #53
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-03-29 11:48:04 -05:00
dede82ad33 Update docs/dev/hosting.md
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Successful in 19s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Successful in 24s
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 24s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Successful in 31s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Successful in 30s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Successful in 42s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 42s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Successful in 50s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Successful in 1m38s
2024-01-14 14:13:53 -05:00
fde2b26857 Update docs/dev/hosting.md
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Successful in 14s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Successful in 15s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Successful in 30s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Successful in 26s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 26s
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 23s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Successful in 27s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Successful in 33s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Successful in 42s
2024-01-14 09:43:47 -05:00
6305f5d76e Update docs/dev/hosting.md
Some checks are pending
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Successful in 25s
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Successful in 23s
2024-01-14 09:36:57 -05:00
95a5f6f087 Fix compile warnings on 32-bit systems.
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 14s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 17s
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Successful in 21s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Successful in 25s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Successful in 24s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Successful in 26s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Successful in 26s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Successful in 30s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Successful in 37s
2024-01-13 20:41:29 -05:00
129802fe94 Fix ordering of LDFLAGS.
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 13s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 18s
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Successful in 20s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Failing after 25s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Failing after 26s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Successful in 27s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Failing after 27s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Successful in 30s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Successful in 39s
2024-01-13 20:31:49 -05:00
c7d44866c3 Put -L before -l in LDFLAGS.
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 12s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 17s
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Failing after 19s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Failing after 23s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Failing after 22s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Failing after 23s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Failing after 26s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Failing after 28s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Failing after 35s
2024-01-13 20:26:46 -05:00
85672985eb Fix compiler warnings on 32-bit platforms in json.c.
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 14s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 16s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Failing after 23s
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Failing after 19s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Failing after 22s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Failing after 24s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Failing after 24s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Failing after 28s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Failing after 36s
2024-01-13 20:25:16 -05:00
19443a1c24 Fix unused argument error on Clang. 2024-01-13 20:25:03 -05:00
15fb6d8c2a Make sure CI checks out submodules.
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 13s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 18s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Failing after 24s
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Successful in 21s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Failing after 24s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Failing after 27s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Successful in 28s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Successful in 29s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Failing after 31s
2024-01-13 20:14:42 -05:00
cd22aea772 Require Cytoplasm to be compiled separately.
Some checks failed
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Failing after 5s
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Failing after 6s
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Failing after 5s
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Failing after 8s
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Failing after 10s
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Failing after 10s
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Failing after 8s
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Failing after 12s
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Failing after 14s
Also add the Gitea CI runner jobs.
2024-01-13 20:11:58 -05:00
ae0724f01c Support building a local copy of Cytoplasm.
Previously, one would have to install Cytoplasm globally to compile
Telodendria. Now, Telodendria builds and links against its own copy
unless --cytoplasm is set to nothing.
2024-01-13 20:02:57 -05:00
e62389aa14 Make Telodendria compatible with latest Cytoplasm.
This also brings Telodendria to C99 compliance.
2024-01-13 20:02:07 -05:00
f2a4a64b27 Add Cytoplasm as a submodule of Telodendria. 2024-01-13 18:05:00 -05:00
258f509413 Update docs/dev/hosting.md 2024-01-13 10:09:39 -05:00
2e92daeb00 Update docs/dev/hosting.md 2024-01-13 10:06:06 -05:00
ac7ea4dec1 Add docs/dev/hosting.md 2024-01-13 09:51:14 -05:00
54420f0036 Improvements to #44: Implement #22 and #9 (#51)
This pull request makes a very small commit on top of #44.

Closes #44.
Closes #9.
Closes #22.

Co-authored-by: LoaD Accumulator <lda@freetards.xyz>
Co-authored-by: lda <lda@freetards.xyz>
Co-authored-by: lda <lda@noreply.git.telodendria.io>
Reviewed-on: #51
2024-01-11 19:33:50 -05:00
lda
243de4f1a0 Add new entry to CONTRIBUTORS.txt (#50)
Reviewed-on: #50
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-01-06 10:02:53 -05:00
35b9ef51f9 PID File: Properly initialize variables in Main(). 2024-01-05 21:02:45 -05:00
83eb69f2cd Use j2s for the Config API. (#49)
Closes #7.
Closes #46.
Closes #47.

This pull request makes some minor on top of #46.

Co-authored-by: LoaD Accumulator <lda@freetards.xyz>
Co-authored-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
Co-authored-by: lda <lda@freetards.xyz>
Co-authored-by: lda <lda@noreply.git.telodendria.io>
Reviewed-on: #49
2024-01-05 21:00:27 -05:00
22d0e88dde Update copyright year in code. 2024-01-05 20:23:27 -05:00
f83be63d53 Add CONTRIBUTORS.txt and make a note of it in the LICENSE.txt and documentation. 2024-01-05 18:57:19 -05:00
lda
af4fd5dceb Update licensing text for 2024 (#48)
Co-authored-by: Jordan Bancino <jordan@bancino.net>
Reviewed-on: #48
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2024-01-04 19:32:03 -05:00
lda
2c6d5194d2 Set an error message with MatrixErrorCreate whenever applicable (#45)
Closes #6.

Co-authored-by: Jordan Bancino <jordan@bancino.net>
Reviewed-on: #45
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2023-12-02 10:24:08 -05:00
0a91a0c40b Remove site files & update README with current site.
The website is now managed in Grav.
2023-11-21 09:16:50 -05:00
d3dcf334f0 Update change log. 2023-11-21 09:14:03 -05:00
lda
3dae19e82d Refactor code to comply with #8 (#39)
Reviewed-on: #39
Co-authored-by: lda <lda@freetards.xyz>
Co-committed-by: lda <lda@freetards.xyz>
2023-11-21 09:11:45 -05:00
2d30719be4 Implement Registration Token Administrator API (#43)
This pull request fully implements and documents all of the registration token administrator API endpoints.

**NOTE:** There is a memory leak when listing all of the registration tokens. Debug this before merging.
 
~~Closes~~ Supersedes #37.

Closes #26.

This pull request is based off of #37, which addresses #26. This pull makes a number of improvements to the logic, organization, and behavior of the API endpoints.

Co-authored-by: hatkid <daichi93100@gmail.com>
Co-authored-by: LoaD Accumulator <lda@freetards.xyz>
Co-authored-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
Co-authored-by: lda <lda@freetards.xyz>
Co-authored-by: Load Accumulator <lda@freetards.xyz>
Reviewed-on: #43
2023-11-10 09:30:53 -05:00
503bfb6104 Suppress warnings of unused variables.
I will use them eventually when I implement all these functions.

I'm probably going to start CI work here soon, so I don't want warnings showing up in the logs unless they're important.
2023-11-08 15:17:27 -05:00
77800e4117 Housekeeping tasks with documentation and versioning. 2023-11-08 14:30:45 -05:00
db4ae0408c Fix admin endpoint names in documentation 2023-11-08 11:21:20 -05:00
edee1288d8 Remove unused global variables. 2023-11-08 09:45:49 -05:00
4b90800a2b Fix leak in RouteConfig, update documentation.
Closes #15.
2023-11-07 01:26:26 -05:00
6e7f170768 Start working on #15. 2023-11-06 20:42:39 -05:00
1f02f3c2a2 Allow customization of compiler in configure. 2023-11-04 15:56:57 -04:00
582c79b608 Schema are now generated out-of-tree.
Closes #40.
2023-11-04 15:28:20 -04:00
42a901b7f5 Update docs/dev/rationale.md 2023-11-01 20:35:48 -04:00
1fee47a628 Use Makefiles instead of a custom script (#38)
This pull request also requires the use of the external [Cytoplasm](/Telodendria/Cytoplasm) repository by removing the in-tree copy of Cytoplasm. The increased modularity requires a little more complex build process, but is overall better. Closes #19

The appropriate documentation has been updated. Closes #18

---

Please review the developer certificate of origin:

1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution&mdash;including all
personal information I submit with it&mdash;is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.

- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

Reviewed-on: #38
2023-11-01 12:27:45 -04:00
6377689a83 Update docs/CHANGELOG.md 2023-11-01 12:16:03 -04:00
23237f97b5 Format source code and apply license. 2023-09-28 19:16:45 -04:00
82ae2d4e41 Update 'docs/CHANGELOG.md' 2023-09-25 16:18:35 -04:00
7d3d84d969 Move Admin routes to /_telodendria/admin/v1 (with version number)
Closes #16.
2023-09-25 16:10:44 -04:00
bf1ce839d0 If HOST_NAME_MAX is undefined, use _POSIX_HOST_NAME_MAX.
Probably good enough. Closes #2
2023-09-25 16:02:09 -04:00
f8d3e54fec Use int instead of char in EvalExpr.
Closes #5
2023-09-25 15:58:43 -04:00
LoaD Accumulator
cb41716bf3 Implement #27 (#36)
Implements #27.

Co-authored-by: LoaD Accumulator <lda@freetards.xyz>
Co-authored-by: Jordan Bancino <jordan@bancino.net>
Reviewed-on: Telodendria/telodendria#36
Co-authored-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
Co-committed-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
2023-09-25 09:39:21 -04:00
6247085df1 Add change log entry for #35. 2023-09-11 11:01:50 -04:00
LoaD Accumulator
0172fa083b Fixes issue #33 related to a memory issue, and format some code. (#35)
Fixes #33.

Co-authored-by: LoaD Accumulator <lda@freetards.xyz>
Reviewed-on: Telodendria/telodendria#35
Co-authored-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
Co-committed-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
2023-09-11 10:57:16 -04:00
0b820b80f7 Convert configuration documentation. 2023-09-09 17:43:43 -04:00
6dcfa7dc02 Remove send-patch and tp. See #20. 2023-09-09 16:58:47 -04:00
024482d4e8 Put the finishing touches on CONTRIBUTING.md. 2023-09-09 16:57:52 -04:00
7a091c5b93 Add contributing documentation. 2023-09-09 16:50:38 -04:00
9e8523d92e Fix issue config. 2023-09-09 15:39:12 -04:00
419017bcc9 Don't allow blank issues. 2023-09-09 15:36:58 -04:00
1a009e87c3 Fix a few small bugs in Gitea templates. 2023-09-09 15:32:43 -04:00
08594e0fb1 Add Gitea issue templates. 2023-09-09 15:28:33 -04:00
56508afe4c Merge branch 'master' of https://git.telodendria.io/telodendria/telodendria 2023-09-09 00:12:07 -04:00
ac3582ddeb Fix table rendering in stats.md 2023-09-09 00:12:00 -04:00
61f7ab1040 Fix table rendering in stats.md 2023-09-09 00:11:32 -04:00
a672c05112 Finish moving over current Administrator API documentation. 2023-09-09 00:03:09 -04:00
09023089f5 Another typo. 2023-09-08 23:27:55 -04:00
6d6fd1645c Fix typo in privileges.md. 2023-09-08 23:27:14 -04:00
043c2e9e33 Add privileges documentation. 2023-09-08 23:26:47 -04:00
9e2f047e82 Fix typo in docs/user/admin/README.md 2023-09-08 17:23:06 -04:00
c78d075a93 Add admin documentation home page. 2023-09-08 17:22:24 -04:00
e4a217550f Add logo and center title. 2023-09-08 16:40:33 -04:00
d50372a91a Add technical rationale document. 2023-09-08 16:34:27 -04:00
fa3b5e95bd Add a nice README which will serve as the basis for the website. 2023-09-08 16:04:48 -04:00
7033a1f0b1 Add repository structure documentation. 2023-09-08 12:12:07 -04:00
f6c54cbc7f Add setup documentation. 2023-09-08 11:58:54 -04:00
3cb04417ff Add porting instructions. 2023-09-07 21:53:22 -04:00
93e6582db5 Add usage and install documentation. 2023-09-07 21:10:46 -04:00
ee62d31c68 Add documentation home page. 2023-09-07 20:23:40 -04:00
4bd527aa9a Remove old change log. 2023-09-07 20:06:12 -04:00
79ce36c860 Add CHANGELOG.md 2023-09-07 19:53:56 -04:00
be3ee54bd8 Merge pull request 'added git ignore and removed cvs ignore files' (#29) from array-in-a-matrix/telodendria:master into master
Reviewed-on: Telodendria/telodendria#29
2023-09-06 14:37:29 -04:00
array-in-a-matrix
5367ffca96 replaced .cvsignore with .gitignore 2023-09-06 11:45:44 -04:00
c5b2fcf586 Convert Cytoplasm README to markdown. 2023-09-05 22:10:33 -04:00
2b43a93524 Break proposals/admin.7 into multiple issues.
Closes #17
2023-09-05 21:54:26 -04:00
fd28f97449 Finish remaining issues in TODO.txt and add docs/ROADMAP.md. 2023-09-05 21:30:09 -04:00
745a208f14 Move over some more issues. 2023-09-05 19:31:46 -04:00
8843b34ba6 Merge branch 'master' of https://git.telodendria.io/telodendria/telodendria 2023-09-05 17:11:13 -04:00
b059f966f1 Make progress toward migrating TODO.txt to issues.
Still have a ways to go, but wanted to save my progress.
2023-09-05 17:09:58 -04:00
Jordan Bancino
8bf8afd91d Merge pull request '[MOD] Make the README(Markdown) file reflect the current situation.' (#11) from lda/telodendria:lda-dev into master
Reviewed-on: Telodendria/telodendria#11
2023-09-05 16:34:04 -04:00
6db3f3c612
[MOD] Make the README(Markdown) file reflect the current situation.
Signed-off-by: LoaD Accumulator <lda@freetards.xyz>
2023-09-05 22:25:39 +02:00
fd1172ff56 Summarize Matrix room activity in TODO.txt
I really want to get back to work on Telodendria. I need to find some
more time for it.
2023-09-04 13:35:28 +00:00
468656eee6 Apply #72 2023-09-04 13:30:22 +00:00
b625655439 Fix memory leak in some generated code. 2023-08-17 18:09:53 +00:00
dab666c969 Update documentation on UtilServerTs(). 2023-08-17 18:09:20 +00:00
36413b4dca Ignore special case in Int64Str. This is hack but good enough for now. 2023-08-13 12:33:18 +00:00
1c32e18c74 Json now uses Int64 for integers.
This should fix all timestamp errors on 32-bit systems in Cytoplasm and
Telodendria.
2023-08-13 03:11:40 +00:00
2382638005 Make all timestamps use UInt64. 2023-08-12 23:02:06 +00:00
38a303da91 Allow forcing the emulation mode for testing purposes. 2023-08-12 21:51:51 +00:00
2f76d5b9ae Add signed 64-bit integer support. 2023-08-12 19:59:16 +00:00
93c4b6bfc4 Add 64-bit emulation for platforms that don't have a native 64-bit type. 2023-08-12 16:30:24 +00:00
d565640455 Add schema for PDUs v1 and v3, the only unique PDU formats.
All other room versions use one of these two PDU formats.
2023-08-10 00:08:33 +00:00
bc71a7ec01 Add admin privilege to manage room aliases. 2023-08-09 15:50:03 +00:00
69d28f39d1 Begin working on room aliases.
These endpoints will help me build out some functionality that will be
needed when actually implementing rooms.
2023-08-09 15:19:45 +00:00
e0af88145e Add RouteCreateRoom stub. 2023-08-08 15:11:50 +00:00
6ef965d1e0 Apply patch to make MatrixErrorCreate() take a custom message. 2023-08-05 19:26:03 +00:00
28d9e1cb3b Add RoomCreateRequest schema. 2023-08-05 15:00:52 +00:00
78302d6320 Print admin registration token to configured log, not default stdout.
If Telodendria is started as a daemon and is logging to the syslog, we
want the token to show up in the syslog.
2023-08-05 14:12:02 +00:00
6ec87b8d76 Properly exclude Schema directories from showing up in CVS. 2023-08-05 14:03:08 +00:00
5f3220372e Implement filter validation by using j2s. 2023-08-05 13:46:23 +00:00
77d71989df Don't install configuration files. 2023-08-04 21:15:49 +00:00
e9600a21e9 Add support for arrays of primitives. 2023-08-04 20:47:36 +00:00
942d2aad18 Fix memory leaks and remove logging messages. 2023-08-01 22:36:52 +00:00
aeaa8487c3 Add leaky Cytoplasm JSON -> Struct code generator.
It is basically complete, I just have to finish cleaning up some of the
memory leaks and remove the log messages.
2023-08-01 20:23:19 +00:00
ed37afe564 Add [time] to interpolate dates and times using strftime(). 2023-07-29 18:27:35 +00:00
2e193d4bcf Format code. 2023-07-29 18:27:17 +00:00
d22baf440f Update TODO. 2023-07-29 15:50:45 +00:00
c467d0913d Add tp, a simple but powerful text preprocessor.
I might rename it, and I have yet to document it in a man page, but I have
found this extremely useful so I thought I'd give it a home here.
2023-07-29 00:04:42 +00:00
68b644a4f2 Add HashMapKeys() and HashMapValues() functions for convenience. 2023-07-18 00:15:29 +00:00
b65394ab50 Add basic Graph API.
This is going to be useful with state resolution and dependency ordering,
both of which will be crutial components of Telodendria.
2023-07-16 01:12:56 +00:00
a958c4a529 Apply #71: Add ArrayUnique() function. 2023-07-15 22:27:24 +00:00
c96ac30f28 Fix Unicode handling in Json, don't sign-extend bytes in Stream. 2023-07-15 17:57:21 +00:00
a4330123b9 Add EventRedact() prototype. 2023-07-09 23:18:18 +00:00
b1c23ee53a Begin prototyping state resolution API. 2023-07-07 03:15:13 +00:00
bc8283f844 Begin prototyping room API. 2023-07-07 02:56:09 +00:00
5f34b846ee Fix stable release version scheme (more details in an upcoming newsletter) 2023-07-01 20:18:59 +00:00
3054a80906 Fix Unicode handling. 2023-06-21 02:49:58 +00:00
539fde773f Fix CanonicalJson and ArraySort. 2023-06-21 02:37:56 +00:00
1fa07d2d3c Update TODO. 2023-06-18 03:25:03 +00:00
80da024e4e Update change log. 2023-06-18 03:19:12 +00:00
e3badbd55c Format source code. 2023-06-18 02:53:52 +00:00
861d4146c0 Add Filter API to validate filters and process events. 2023-06-18 02:53:06 +00:00
f9e1250d47 Begin working on filtering. 2023-06-17 19:09:06 +00:00
4e184102cb Add Sha1 implementation. 2023-06-17 17:36:46 +00:00
8bda70b1fb Refactor Sha API to return raw bytes, added Sha1() function. 2023-06-17 17:36:11 +00:00
8f0d197480 Bump version: v0.3.0 -> v0.4.0 2023-06-16 16:01:19 +00:00
b9641e89d6 Update TODO 2023-06-13 14:06:05 +00:00
1381a31cbd Update TODO. 2023-06-13 14:05:34 +00:00
c3287c1674 Update TODO. 2023-06-12 18:00:26 +00:00
071a86114c Apply #70: Add StrLower() function. 2023-06-12 14:10:59 +00:00
1f14169284 Apply #70: Fix warnings of unused variables. 2023-06-12 14:10:08 +00:00
2f946848cb Telodendria Bot can now send messages again.
The problem here is that some Matrix homeservers reject requests that don't
have a Content-Length. http was not sending a Content-Length because it was
reading from standard input. By reading from an actual file, we can actually
easily get the size of the file to send as the Content-Length.
2023-06-12 14:01:56 +00:00
2b3d0aaeaf Prepare for v0.3.0 release.
Not exactly as complete as I initially imagined, but I want to get something
out because I've been spending too much time on the same issues.
2023-06-10 13:29:56 +00:00
af15234799 Make the debug server more accurately mimic the actual server. 2023-06-10 13:16:41 +00:00
971f099bb6 Fix potential race condition. 2023-06-09 19:27:49 +00:00
96a1d3c3c4 Move stream assignment; this makes debugging easier. 2023-06-04 18:50:02 +00:00
095e05e927 Make Memory use a recursive mutex.
This allows some additional operations to be performed inside the memory
hooks, although it's still a bad idea to allocate or free memory while
inside the hook.
2023-06-04 18:44:37 +00:00
c511ca9f0f Add a recipe to build the examples. 2023-05-30 13:20:23 +00:00
faaa12c51f Re-add memory bounds checking.
Also fixed a recursive lock error in some configurations, and replaced
a usage of strcpy() with strncpy().
2023-05-29 23:53:17 +00:00
88f73a6131 Fix a few segfaults in http and json. 2023-05-29 22:48:50 +00:00
c206ec495d Format code. 2023-05-27 18:22:38 +00:00
27e40135ad Log a message stating that TLS is disabled if the config requests it. 2023-05-27 17:55:49 +00:00
5df684b609 Show human-readable thread ID in log messages.
This helps debug some multithreading issues.
2023-05-27 17:10:07 +00:00
b5b1a021d8 It appears that OpenSSL closes the socket descriptor for us.
When we close it again manually, we may actually be closing another thread's
file descriptor, which causes all kinds of problems.
2023-05-27 17:03:40 +00:00
54924b9444 Fix potential write out of bounds. 2023-05-26 23:47:36 +00:00
42526c95bb Remove memory bound checking logic.
While this was nifty and impressive, it seems like it is too easy to mess
up, and is too platform-specific.
2023-05-26 23:10:00 +00:00
34f33a1c1b Fix SIGBUS on some platforms. Memory alignment matters!
This is a temporary fix; I'm not convinced it will work on all platforms,
so I will probably end up removing all of the memory boundary code
altogether.
2023-05-26 23:05:35 +00:00
d24c1161f6 Add a Cytoplasm example, which I'll use to debug some stuff. 2023-05-26 22:25:03 +00:00
d81600d944 Fix more memory leaks in json.
By doing a little reference tracking, we can make sure we don't miss any
JsonValues that may be floating around by the time we're done.
2023-05-26 22:11:07 +00:00
efb27c9db8 Push Main return value into MainArgs.
This prevents weird things from happing on some architectures.
2023-05-26 21:05:06 +00:00
3b659ce09e Adjust milestone requirements. I really want v0.3.0 out soon. 2023-05-26 19:21:25 +00:00
34eb9ff670 Report memory hook issues as errors, segfault on error. 2023-05-25 18:26:17 +00:00
e87a0647e0 Fix incorrect block size. 2023-05-25 00:03:17 +00:00
836229fd1a Don't log anything at the end of main; user may have redirected and closeed stream.
This would cause a segfault.
2023-05-24 23:32:53 +00:00
2693b89598 Add sane default memory hook to Cytoplasm, fix more leaks in json. 2023-05-23 22:43:37 +00:00
e22cf38eac Fix leaks in json. 2023-05-23 20:34:27 +00:00
b1049a9a70 Fix leak in http. 2023-05-23 20:19:27 +00:00
441599b088 Don't leak so much memory. 2023-05-23 17:53:19 +00:00
42191ec03f Properly initialize and destroy logging mutex in LogConfigCreate() and
LogConfigFree(), respectively.
2023-05-23 17:42:08 +00:00
a4f369a0a9 Fix leak in HttpClient. 2023-05-21 13:55:49 +00:00
4cc876eb10 Fix warning about integer size mismatch. 2023-05-21 13:35:56 +00:00
51b9e2eaed Clean Cytoplasm when td clean is run. 2023-05-21 13:34:05 +00:00
e71ffec164 Add some basic heap memory bounds protection. 2023-05-21 13:24:00 +00:00
d38ec7cb38 Document hdoc 2023-05-21 00:21:39 +00:00
896f561213 Apparently this expansion syntax only works on ksh. 2023-05-20 21:38:03 +00:00
f2f972bb9d Fix memory leaks in hdoc. 2023-05-15 22:38:52 +00:00
ff0a9f33b8 Update TODO. 2023-05-15 01:43:46 +00:00
4043285413 Telodendria and all tools now use the Cytoplasm runtime stub.
This reduces the amount of manual work programs have to do, and gives us
some free features, like automatic leak reports in all tools.
2023-05-14 22:15:48 +00:00
8021cff122 Make Telodendria use Cytoplasm.
This commit removes all the duplicate code and makes Telodendria use the
new Cytoplasm library.
2023-05-14 19:35:23 +00:00
5c8a42117c Import new Cytoplasm library based off of code from Telodendria.
Telodendria doesn't use this library yet, but it will soon.
2023-05-13 17:30:09 +00:00
a1e3bd7d8e Clean up TODO 2023-05-11 12:00:44 +00:00
4d9c907b58 Attach device ID to authenticated user.
Now RouteWhoAmI can use UserAuthenticate just like the other endpoints.
2023-05-11 03:03:40 +00:00
c1c57fd4cf Make RandState thread-specific. 2023-05-11 02:17:04 +00:00
609890654e Fix handling of STATIC and broken compilation on GNU systems. 2023-05-10 03:32:56 +00:00
31866a14b4 Remove some extraneous whitespace from Util.c, not sure how that got there. 2023-05-07 12:08:26 +00:00
e6dd20e2b2 Update changelog. 2023-05-07 03:21:52 +00:00
ebc3da9b23 Fix some compile warnings. 2023-05-06 23:06:13 +00:00
a2eec3946c I missed an instance of strcmp() 2023-05-06 23:02:46 +00:00
0b11b97022 Add StrEquals(), as equality checking is the most common use for strcmp().
This allows us to get rid of the hideous MATRIX_PATH_PART_EQUALS macro,
and prevents inconsistent usage of strcmp() (for example, !strcmp() vs
strcmp() == 0).

StrEquals() also has sensible behavior for dealing with NULL strings (it
doesn't just segfault like strcmp()).
2023-05-06 22:34:36 +00:00
0e69a12784 Register route. 2023-05-06 22:06:54 +00:00
2a87583d2f Add /_matrix/client/v3/account/deactivate 2023-05-06 22:06:23 +00:00
95ceba0645 Add length calculations to JsonEncode() so we can set Content-Length. 2023-05-06 19:23:13 +00:00
bbea55be6c Document http-debug-server, fixed typo in HttpServer docs. 2023-05-06 18:21:21 +00:00
3d9a7664b1 Add support for building static and shared libraries. 2023-05-06 17:04:35 +00:00
cb7ee91908 Update telodendria(8) 2023-04-30 02:20:59 +00:00
f1f66c6331 Fix the Makefile by sourcing tools/env.sh if TELODENDRIA_ENV is unset. 2023-04-30 01:47:27 +00:00
abbbfe4d7f Replace all usages of curl in tp, document tp and tt. 2023-04-29 23:28:33 +00:00
872fa1aa66 More documentation. It never ends! 2023-04-29 19:52:51 +00:00
a08018870e Remove obsolete documentation. 2023-04-29 18:47:20 +00:00
e0c94d7bd2 Site now pulls built man pages. 2023-04-29 18:39:01 +00:00
f819093b7d Don't spew unknown expression warnings if @suppress-warnings is set. 2023-04-29 15:28:42 +00:00
0b1b4a8b29 Cope with preprocessor macro usage at the top level of the header.
This workaround allows us to parse the Routes.h properly, although it
notably lacks support for multi-word unknown expressions.
2023-04-29 15:24:46 +00:00
a3cc06ff2a Fix line numbers when parsing multi-line macros. 2023-04-29 15:16:58 +00:00
2d8d5244c4 Document some new headers. 2023-04-29 15:04:16 +00:00
b70c3f0bed Finish converting all existing documentation. Next up is writing new docs. 2023-04-29 02:54:49 +00:00
71fa96d10d Format source code. 2023-04-27 20:05:08 +00:00
a00ded6d06 Add support for parsing global variables, not just function declarations. 2023-04-27 20:04:15 +00:00
9292f1d9da Add docs recipe for generating documentation from the headers.
Note that since all the headers are not documented yet, this will fail
because an undocumented function is a fatal error in hdoc.
2023-04-27 18:39:05 +00:00
9880aac674 Split format recipe into format and license.
Format formats only C source code. License applies the license file to
C source code *and* header files.
2023-04-27 18:03:32 +00:00
24a03ba126 Added some more header documentation. 2023-04-27 18:00:26 +00:00
95cb14213f Add support for return types that are const, structs, or enums. 2023-04-27 16:02:15 +00:00
6e976a2b8d Fix line counts on syntax errors. 2023-04-27 15:54:21 +00:00
72467f6503 Begin moving documentation to headers. 2023-04-27 03:08:39 +00:00
3b06ab120b Add some flags to hdoc to make it more useful. 2023-04-27 02:30:44 +00:00
2447bb63cc Add hdoc, a simple tool for generating documentation from a C header.
This is a very early prototype. It works, but it is probably not efficient
or reliable. However, the documentation format it parses is stable, so I
will begin moving the documentation into the headers.
2023-04-27 01:34:49 +00:00
fdcf7ec065 Update changelog, add LD_EXTRA variable in td. 2023-04-26 01:43:32 +00:00
459b2e856f Format source code. 2023-04-25 22:13:28 +00:00
96ca9a725d Finish up capabilities for now. 2023-04-25 22:11:34 +00:00
e1367d5bff Use snprintf() instead of sprintf().
All linker warnings should now be eliminated.
2023-04-25 22:01:58 +00:00
d83db35df0 Use strncpy() instead of strcpy().
The OpenBSD linker is complaining about it. Even though every single
case strcpy() was used is safe, strncpy() provides a little bit of extra
security, and makes the linker happy.
2023-04-25 21:54:51 +00:00
d933d12e1b Make Rand use a provided Mersenne Twister.
This implementation is loosely inspired by the original paper on the
Mersenne Twister, and borrows code from a public-domain implementation of
it, adapting it to fit the style of Telodendria's code, and fixing a few
bugs regarding the size of the data type used.

Neither C nor POSIX provide a good, thread-safe pseudorandom number
generator. The OpenBSD linker started complaining about the use of
rand_r(), and no standard alternative presented itself as worthy of
consideration, so I finally decided it was time to roll my own PRNG.
2023-04-25 21:28:55 +00:00
098eed44a0 Fix bug in MatrixWellKnown(), begin /_matrix/client/v3/capabilities 2023-04-25 18:37:25 +00:00
2ac08ad74d Clean out finished TODO items. 2023-04-25 01:54:03 +00:00
3e4698bf72 Update porting documentation. 2023-04-24 22:24:32 +00:00
38565d4aa6 Update changelog. 2023-04-24 21:21:25 +00:00
05cf076ebc Begin debugging OpenSSL. 2023-04-24 17:05:59 +00:00
a525830b64 Telodendria now responds correctly to SIGTERM. 2023-04-24 16:23:50 +00:00
279f261aed Fix race conditions that are possible in Db.
This is accomplished by locking the entire database, and keeping it locked
until the last reference is unlocked. We get rid of per-reference locks,
because those are what cause race conditions.
2023-04-24 16:19:17 +00:00
313249ca88 Fixed some caching bugs in Db.
Note that Db has the potential to deadlock when caching is being used,
and when caching isn't being used, an inconsistent state can occur. Future
changes to Db will fix both of these issues.
2023-04-24 15:43:24 +00:00
737e060243 Finish up Uia fallback. 2023-04-22 15:40:25 +00:00
5431c2cd90 Fix double-free in UiaCleanup(). 2023-04-22 13:45:01 +00:00
2bbe13aaf0 Fix error setting up UIA flows. 2023-04-22 02:06:22 +00:00
866343071a Continued work on UIA fallback. 2023-04-22 00:59:03 +00:00
6a5d89e14b Work on implementing user interactive authentication fallback. 2023-04-21 02:13:06 +00:00
fb24f93aaa Fix bug with TLS where cert and key files were used after freeing them. 2023-04-20 21:12:08 +00:00
0b7282c36a Fix build errors on some compilers due to missing symbols. 2023-04-20 19:19:23 +00:00
ec09882dbe Fix warnings about memset() 2023-04-20 17:50:22 +00:00
3b28af2031 Fix warning on some compilers. 2023-04-20 17:40:14 +00:00
19b0dcac5a Don't build the routing tree until absolutely necessary.
Saves us a lot of time and memory in case of an error.
2023-04-20 17:37:18 +00:00
4a5c7480aa Fix up a few small warnings. 2023-04-20 13:49:25 +00:00
687b89a83a Add some more user documentation to clarify how configuration works. 2023-04-20 01:39:09 +00:00
25b7c0d059 Begin documenting Admin API. 2023-04-19 21:45:15 +00:00
ffeb45375e Implement /_telodendria/admin/privileges
Note that it's not exactly as the proposal defines it; theres a bit more
nuance that will be documented soon.
2023-04-19 18:52:05 +00:00
ae38791df2 Format code, remove dataDir from sample production.conf 2023-04-19 02:07:38 +00:00
0cca38115a Move configuration to database, add process control API, fix memory leaks. 2023-04-19 00:33:38 +00:00
ff4d265dcc Registration tokens now determine what privileges a user gets. 2023-04-16 18:32:22 +00:00
582df63a31 Format source code. 2023-04-16 17:51:52 +00:00
4ee66ae3c7 Begin implementing user privileges. 2023-04-16 17:51:03 +00:00
768ecda41a Break up todo items into more milestones. 2023-04-15 13:31:08 +00:00
6ca1265076 Begin working on User-Interactive authentication fallback. 2023-04-15 02:36:28 +00:00
e882693c78 Add route for requestToken endpoints. 2023-04-14 23:59:40 +00:00
b21d018daa Move router building function into a more sensible location. 2023-04-14 21:37:00 +00:00
83971dfaff Refactor routing system to use HttpRouter. 2023-04-14 21:20:56 +00:00
a90f7c4b9e Apply #69 2023-04-14 17:50:14 +00:00
3192063340 Fix broken tt script. 2023-04-07 14:20:22 +00:00
1f8df737da Add HttpRouter API; still have to convert the code to use it. 2023-04-06 01:48:32 +00:00
7c865d06fd Format code. 2023-04-01 02:46:59 +00:00
e0c8530b12 Clean up http client enough to replace curl in send-patch. 2023-04-01 02:46:07 +00:00
e592840c99 Clean up some HTTP client stuff. 2023-04-01 02:13:41 +00:00
7b3d537175 Remove UtilStreamCopy() 2023-04-01 00:20:18 +00:00
f341fd2b6e Fix OpenSSL server accept call.
Apparently it can EAGAIN on non-blocking connections... I don't think
LibreSSL's TLS library does this, but something to keep in mind if it
doesn't work for somebody.
2023-03-31 23:10:52 +00:00
eef615fc9a Fix warnings in RouteChangePwd.c 2023-03-28 02:28:58 +00:00
9b21e2460a Accept #67: Add the password modification endpoint. 2023-03-28 01:17:47 +00:00
c6f4a4a546 Fix leak of StreamStdout() when logging to a file. 2023-03-27 17:56:45 +00:00
a9da9fbca7 Update TODO 2023-03-27 17:52:20 +00:00
c37d3801b2 Fix warning about uninitialized variable. 2023-03-25 00:00:53 +00:00
a24c27bf4f Fix leak in TlsOpenSSL. 2023-03-24 17:37:44 +00:00
af776c64a7 Remove duplicate return line. 2023-03-24 14:18:29 +00:00
a25573063f Fix up TlsOpenSSL a little bit.
Server is still broken...
2023-03-24 03:05:12 +00:00
aeb49f80e5 Add support for OpenSSL. This is a good demo of how easy it is to support TLS libraries. 2023-03-24 02:41:01 +00:00
007e639b0c Don't require the TLS_ in the environment variable.
It's redundant.
2023-03-24 00:25:44 +00:00
fe32c652cd Fix bug in HttpClient where it wouldn't retry on EAGAIN. 2023-03-24 00:23:49 +00:00
20d41d794b Fix compile error. I had this in here at some point, not sure where it went. 2023-03-23 17:41:02 +00:00
b4e4263cea Remove my testing configuration from contrib/development.conf 2023-03-23 16:40:23 +00:00
e13442c122 Fix strange behavior in TlsLibreSSL.
tls_read() and tls_write() may return TLS_WANT_POLLIN or TLS_WANT_POLLOUT
if data isn't ready to be read or written yet. We have to account for this
by converting it to EAGAIN, which is how a typical read() or write()
function should behave.

Also installed a SIGPIPE handler; we do not want to be terminated by
SIGPIPE, and it's safe to ignore this signal because it should be
handled thoroughly in the code.
2023-03-23 16:39:15 +00:00
2441f07848 Add support for spinning up multiple HTTP servers.
This is useful for having a TLS and a non-TLS version port, like Synapse.
I verified that the multiple-servers does in fact work as intended,
although the TLS server part is broken; I must be doing something
incorrectly with LibreSSL in setting up the server.
2023-03-23 02:12:45 +00:00
2fab7b55fe Remove obsolete warning about setting root directory.
We don't use chroot() anymore.
2023-03-22 18:30:30 +00:00
089d8d4d94 Only install the memory hook if -v is given.
This way, we can still set the debug level in the configuration, and not
see the log just absolutely flooded with memory allocations and whatnot.
This is helpful because I want debug messages to show up in development,
but not in production, but having all the memory logging makes it
almost impossible to pick anything else out of the log. I want the
feature available, just not on by default because it's useful in limited
circumstances.
2023-03-22 18:29:05 +00:00
9ec330f40a Log once we get the response status, not right when we get the request. 2023-03-22 18:13:59 +00:00
fccd15b239 Don't unconditionally close standard input; it may have been used and
closed before. If it was never used, it was never opened.
2023-03-22 18:12:46 +00:00
35f65a667d Update changelog. 2023-03-22 17:49:06 +00:00
8faf6f2126 Delete TelodendriaConfig.c 2023-03-22 17:20:53 +00:00
fc975e6a93 TelodendriaConfig -> Config 2023-03-22 17:17:30 +00:00
413c7ad803 Start building support for running multiple HTTP servers.
The standard use case for this is going to be running a TLS and a non-TLS
HTTP server. I can't see a need for *more* than two, but it is theoretically
possible.

We shouldn't have to change anything with the database or anything; it
should suffice to simply spin up more HTTP servers, and they should
interact with each other the same way a single HTTP server with multiple
threads will.
2023-03-22 17:00:48 +00:00
e30fa3ee33 Remove remnants of non-global LogConfig from TelodendriaConfig 2023-03-22 16:31:24 +00:00
e6f3dfad18 Add an ArraySet() method for replacing entries in an array.
This is much more efficient than using ArrayDelete() and ArrayInsert(),
and will serve us well in the future.
2023-03-22 16:31:06 +00:00
b8d00bc8bf Make td run warn if Memory.txt gets created. 2023-03-22 14:57:57 +00:00
f3c4c0ac65 Add a global log configuration.
This is the easiest and cleanest way to get logging into some of the
fundamental APIs, such as the database and TLS APIs. We don't want to
have to pass logging functions to those, but they can safely use the
global logging configuration.
2023-03-22 14:52:04 +00:00
8782aa046d Fix compile error in Tls, work on getting certs and keys into HttpServer. 2023-03-22 02:18:31 +00:00
bdaea9872e Format source code. 2023-03-22 01:46:45 +00:00
b58ca7d22e Start working on adding TLS support to HttpServer. 2023-03-22 01:46:24 +00:00
6561b5bae1 Add TLS build support to td. 2023-03-22 01:17:42 +00:00
996356832e Define TLS API, update HttpClient to support optional TLS.
Also added a LibreSSL TLS implementation. Client is verified to work;
server has not been tested yet.
2023-03-22 00:41:21 +00:00
d1b4ecff48 Apparently the order of LDFLAGS matters to some compilers.
Also don't to -pg in debug mode, because that's not supported on all
compilers either.
2023-03-22 00:13:27 +00:00
63d07365db Don't close standard output twice, that leads to a segfault! 2023-03-22 00:12:04 +00:00
2a92d0de7e Fix bit flag check. 2023-03-22 00:11:24 +00:00
4a27f50538 Remove calls to pledge(), unveil(), and chroot().
Not only does this make us more POSIX, it actually makes things a lot
easier because TLS implementations will need to be able to access the
trusted certificates file, which most likely will not live in the
data directory.
2023-03-20 19:23:37 +00:00
6c9e939b9f Fix broken IoVprintf().
You can't call vsnprintf() on the same va_list more than once! I learned
this the hard way with StreamVprintf().
2023-03-18 14:55:04 +00:00
5289c16e2b Convert all code to new Stream API.
Also made a number of improvmements to tt, making it compatible with more
shells.
2023-03-18 14:32:09 +00:00
a97a593f21 Format code. 2023-03-16 16:53:18 +00:00
27b3b6cdc6 Add StreamPuts(), don't make StreamVprintf() defer to IoVprintf(). 2023-03-16 16:51:41 +00:00
8539a03d5b Add StreamFile() convenience method. 2023-03-16 16:25:24 +00:00
e0a3760a37 Don't buffer in IoWrite(), indicate that fwrite() returns size_t, not ssize_t. 2023-03-16 14:17:04 +00:00
6ee1857f5f Format source code. 2023-03-16 12:29:38 +00:00
7d9770fc12 Add some convenience functions for working with Io and Stream.
Also broke out IoFd into it's own file, and did the same with IoFile.
2023-03-16 12:28:55 +00:00
65f4c90df3 Rename HttpStream() to HttpServerStream() to match HttpClientStream() 2023-03-16 02:17:48 +00:00
ff52cc78dc Update TODO 2023-03-15 17:30:14 +00:00
ab4755240a Add IoCopy() and StreamCopy()
Both do buffered reads and writes, but IoCopy() uses IoRead() and
IoWrite() directly, whereas StreamCopy() relies on StreamGetc() and
StreamPutc(), which manipulate the stream buffers.
2023-03-15 17:14:16 +00:00
92da3542a6 Move low-level fopencookie()/funopen() functionality to Io API.
The Stream API now provides the buffered I/O functionality analogous to
the C standard library.
2023-03-15 16:47:34 +00:00
5dbaf3c223 Apply #65, remove printf() in Db, and make tt show login messages. 2023-03-15 13:36:49 +00:00
afc7667737 Begin prototyping Stream API. 2023-03-15 02:40:23 +00:00
ae97d8116c Apply #64: Registration tokens. 2023-03-14 00:37:24 +00:00
76bfa120ee Fix CPU pin if clients don't shutdown() their socket properly.
If we haven't read any bytes yet, then we try a few times a few ms apart
to see if we get anything. If not, treat it as an EOF. Otherwise, read
bytes until we get an EOF or EAGAIN. EAGAIN after a consistent read of
bytes is treaded as an EOF immediately.
2023-03-12 15:08:50 +00:00
62cd1cdc98 Misc changes. 2023-03-12 03:37:57 +00:00
7fa982a16f Fix bug in Uia 2023-03-12 03:36:40 +00:00
aba1ef9251 Add some more documentation. 2023-03-12 03:36:19 +00:00
b4a394c44b Move send-patch and td to section one of the manual.
I think they fit there better.
2023-03-10 23:02:09 +00:00
64add9c9ab Fix unused variable warning. 2023-03-10 20:12:25 +00:00
3037f12907 Add tt and http-debug-server tools. 2023-03-10 18:48:52 +00:00
2d9b706f38 Fix I/O in JsonConsumeWhitespace() and UtilStreamCopy().
These functions previously operated on the assumption that fgetc() would
block; however it will not block on HttpServer streams because those are
non-blocking. They now check error conditions properly before failing
prematurely.
2023-03-10 18:46:03 +00:00
fd12dee62e Make sure a newline is printed after JSON object is pretty-printed. 2023-03-10 04:30:56 +00:00
8ead9cc93a Apply #63, make some general bug fixes. 2023-03-10 03:24:04 +00:00
3af2d3d12b Format code, update TODO items. 2023-03-09 03:35:40 +00:00
7344d4fa46 Apparently some shells interpret the - in a string as an argument delimiter??? 2023-03-09 02:49:14 +00:00
ca053a12b1 Break out main() into Main.c, fix some compile warnings on Cygwin. 2023-03-09 02:46:04 +00:00
9a1300ff2e Make sure input is initialized. 2023-03-09 02:22:13 +00:00
c32c3abfd6 Update TODO 2023-03-09 00:10:32 +00:00
012c334ee5 Make send-patch use json instead of jq. 2023-03-09 00:06:15 +00:00
20ebeb9c32 Switch tp from using jq to json; format td 2023-03-08 22:47:40 +00:00
76413f834e Make json use ^ for removing fields, instead of !
Room IDs start with '!', we want to be able to access these.
2023-03-08 22:47:07 +00:00
efdf168085 Allow encoding user-provided strings. 2023-03-08 20:31:49 +00:00
50e599f1cd Implement a mostly-functional query language for JSON. 2023-03-08 19:49:06 +00:00
7b22fb02a2 Implement pretty-printing option in Json.
Telodendria itself doesn't use it, but the json CLI tool does.
2023-03-08 17:15:43 +00:00
cb8c4fceb5 Begin working on JSON CLI tool.
This is a similar situation to the HTTP CLI tool: since we have the
Json API anyway, we might as well have a little command line tool to
replace jq.
2023-03-08 04:06:43 +00:00
19e89110cd Bump version number to v0.3.0 2023-03-08 03:46:38 +00:00
1a169d1a2e Fix usage message. 2023-03-08 03:31:34 +00:00
8d75d8a023 Add simple HTTP CLI tool that uses the HttpClient API.
You might be asking why I would just write a simple curl replacement
when curl does the job just fine. Well, the most immediate reason is
to test the HttpClient API, but since Telodendria's goal is to not
be dependent on any third-party code if at all possible, it makes
sense to have a simple HTTP client to use not only for testing
Telodendria, but also for configuring it. When we move the
configuration to the database, we'll ship a script that uses this
tool to allow admins to easily submit API requests.

Do not be concerned that HttpClient does not support TLS yet. TLS
support is necessary for federation to work, so it is coming
eventually.
2023-03-08 03:30:36 +00:00
7e144ae488 Clean up a few bugs in HttpClient and Uri 2023-03-08 02:53:47 +00:00
3e42da279c Make improvements to HttpClient, add Uri 2023-03-08 01:54:33 +00:00
313f0e2e73 Add HttpClient API 2023-03-07 23:10:06 +00:00
185 changed files with 10978 additions and 15237 deletions

View file

@ -1,6 +0,0 @@
build
data
.env
*.patch
*.log
vgcore.*

View file

@ -0,0 +1,49 @@
name: Bug Report
about: File a bug report regarding Telodendria, its website, or its documentation.
body:
- type: markdown
attributes:
value: |
You are submitting a bug report. Please be sure to fill out the
title with a brief description of the bug.
- type: dropdown
attributes:
label: Type
description: Select the type of issue.
options:
- Memory Leak
- Crash
- Unexpected Error Message
- Documentation
- Website
- Other
validations:
required: true
- type: textarea
attributes:
label: Description
description: |
Please give a thorough and detailed description of the bug you
are reporting. Provide all the information you have, and do
some investigating to ensure you are providing a legitimate
issue report that is well thought out. **Include details on
how to reproduce the issue, or explicitly state that you were
unable to reproduce it.**
validations:
required: true
- type: textarea
attributes:
label: Log Output
description: |
Please copy and paste the relevant sections of the log output,
or the entire log if it is not unreasonably large. The logs
will be automatically formatted, no code block is necessary.
render: shell
validations:
required: true
- type: markdown
attributes:
value: |
Please attach any additional files that may aid in our
investigation of this issue, including screenshots, debugging
session stack traces and dumps, etc.

View file

@ -0,0 +1,7 @@
blank_issues_enabled: false
contact_links:
- name: General Matrix Room
url: "https://matrix.to/#/#telodendria-general:bancino.net"
about: |
General discussion on Telodendria happens in this Matrix room. You
may get quicker feedback from there.

View file

@ -0,0 +1,18 @@
name: Feature Request
about: Request a new feature or enhancement be added to Telodendria.
title: "[Feature] "
body:
- type: markdown
attributes:
value: |
You are submitting a feature request. Please be sure to fill
out the title with a brief description of the feature you are
requesting.
- type: textarea
attributes:
label: Description
description: |
Please give a thorough and detailed description of the feature
you are requesting.
validations:
required: true

View file

@ -0,0 +1,25 @@
---
Please review the developer certificate of origin:
1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution&mdash;including all
personal information I submit with it&mdash;is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.
- [ ] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.

View file

@ -0,0 +1,27 @@
name: Compile Telodendria
run-name: Compile Telodendria on ${{ forgejo.actor }}
on:
push:
branches:
- 'ma*'
pull_request:
types: [opened, synchronize, reopened]
jobs:
"Compile Telodendria":
strategy:
matrix:
os: [alpine]
arch: [aarch64]
runs-on: ["${{ matrix.os }}", "${{ matrix.arch }}"]
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
submodules: true
- name: Configure Telodendria
run: ./configure
- name: Configure & Build Cytoplasm
run: make cytoplasm
- name: Build Telodendria
run: make

View file

@ -0,0 +1,44 @@
name: Release Telodendria
run-name: Release Telodendria on ${{ forgejo.actor }}
on:
push:
tags:
- 'v*'
jobs:
"Release Telodendria":
strategy:
matrix:
os: [alpine]
arch: [aarch64]
runs-on: ["${{ matrix.os }}", "${{ matrix.arch }}"]
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
submodules: true
- name: Archive submodules
run: git submodule foreach --recursive 'git archive --format tar --prefix=$displaypath/ -o submodule.tar HEAD'
- name: Archive repository
run: git archive --format tar -o release.tar HEAD
- name: Produce release archive
run: |
TOPDIR=$(pwd) git submodule --quiet foreach --recursive 'cd $TOPDIR; tar --concatenate --file=release.tar $displaypath/submodule.tar; rm -fv $displaypath/submodule.tar'
gzip release.tar
mkdir release
mv release.tar.gz release/Telodendria-$GITHUB_REF_NAME.tar.gz
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: Telodendria-$GITHUB_REF_NAME.tar.gz
path: release/Telodendria-$GITHUB_REF_NAME.tar.gz
- name: Publish release
uses: actions/forgejo-release@v2
with:
tag: $GITHUB_REF_NAME
title: "Telodendria $GITHUB_REF_NAME"
release-dir: release/
release-notes: "docs/CHANGELOG.md"
direction: upload
prerelease: true

18
.gitignore vendored Normal file
View file

@ -0,0 +1,18 @@
# Telodendria .gitignore
build
out
data
Makefile
*-leaked.txt
.env
*.patch
*.orig
*.log
vgcore.*
*.core
contrib/.vagrant
src/Schema
src/include/Schema
man/mandoc.db

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "Cytoplasm"]
path = Cytoplasm
url = https://git.telodendria.io/Telodendria/Cytoplasm.git

16
CONTRIBUTORS.txt Normal file
View file

@ -0,0 +1,16 @@
N: Jordan Bancino
E: jordan@bancino.net
M: @jordan:bancino.net
W: https://bancino.net
D: Project Lead
L: United States
N: LDA
E: marie@doskel.net
E: ldasta@tedomum.fr
E: lda@freetards.xyz
M: @lda:a.freetards.xyz
M: @lda:pain.agency
M: @fourier:ari.lt
D: Developer
L: France

1
Cytoplasm Submodule

@ -0,0 +1 @@
Subproject commit 4f316ff7b3a955b831ca4aefb8679ddf3396a7d0

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net>
* Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> with
* other valuable contributors. See CONTRIBUTORS.txt for the full list.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files

136
README.md
View file

@ -1,7 +1,135 @@
# [Telodendria](https://telodendria.io)
<h1 style="text-align: center;">Lightweight, Decentralized Chat.</h1>
**Telodendria** is an open source Matrix homeserver implementation written from scratch in ANSI C and designed to be lightweight and simple, yet functional.
**Telodendria** is an extremely powerful, yet lightweight and portable
chat server designed to be easy to install and configure. Powered by
the [Matrix](https://matrix.org) protocol, Telodendria empowers
everyone to run their own chat server on ordinary hardware, including
old and embedded devices. Whether you want a simple chat server just
for you and your friends and family, or want to talk to users on other
Matrix homeservers but don't want to go through all the hastle of
hosting a complicated, high-maintenance homeserver or joining an
existing homeserver for privacy or other reasons, then Telodendria
might be for you.
**Important:** This project is not developed on GitHub, or even with Git. As such, GitHub Pull Requests are not accepted. But that doesn't mean we don't want your contribution! You're more than welcome to clone this repo and use Git to make changes to the project if you'd prefer it to CVS, but when it comes time to actually submit your changes to this project, use [git format-patch](https://git-scm.com/docs/git-format-patch) to generate patch files, then submit them to the official Matrix room: [#telodendria-patches:bancino.net](https://matrix.to/#/#telodendria-patches:bancino.net).
!!!! **Note:** Telodendria still in development. See **Status** below.
Please see the `README.txt` file for the actual project `README`, which simply details the repository structure a little bit. All of **Telodendria**'s user and developer documentation is available as `man` pages, or online.
## What is Matrix?
Matrix is an **open standard** for *interoperable*, *decentralized*,
*secure*, and *real-time* communication over the internet.
Matrix can be thought of as the successor to email, but it works
very similar to iMessage, Discord, or direct messaging on most
social media networks. The primary difference between Matrix and these
other services, however, is that Matrix doesn't depend on one central
authority, and is designed in such a way to respect your privacy.
Matrix has proven itself over the last few
years to be a reliable communication tool, and has only gotten more
user-friendly over the course of its development. Matrix is capable
enough that it can&mdash;and should&mdash;totally replace any other
means of digital communication, and it offers a much higher degree
of security, simplicity, and functionality.
Strictly speaking, Matrix itself is just the *protocol* by which
clients and servers communicate. In order to use Matrix, we need
implementations of both clients and servers. Telodendria is a server
implementation of the Matrix protocol.
## Why Telodendria?
- **Lightweight:** Written in the C programming language, Telodendria
is automatically lighter and faster than other self-hosted chat servers.
It has very few external dependencies and is as self-contained as
possible.
- **Fully-Featured:** Most lightweight chat solutions compromise on
features. Telodendria is built on the fully-featured Matrix protocol,
which provides a chat experience that most normal users are familiar
with.
- **Portable:** You can run Telodendria on just about everything,
including more traditional options like a personal home server or VPS,
but also more obscure platforms like Raspberry Pis or retro computers.
Telodendria can run on a broad number of operating systems, which means
that no matter which platform and OS you prefer, there is a good chance
you can add Telodendria without much difficulty. It is also extremely
easy to migrate a Telodendria instance between platforms; just copy the
data directory to a new device.
- **Simple:** Telodendria is designed to be a simple, no-frills
chat server. It is easy to install, easy to configure, and easy to
maintain.
- **Stable:** Other Matrix homeservers develop at the pace of the
Matrix specification itself, which is to say quite rapidly. Changes are
always being made, and a version shipped 6 months ago is already
incredibly outdated. Telodendria, on the other hand, aims to be stable.
It should *just work* for long periods of time between upgrades, and
you should never feel like Telodendria is going to change significantly
between upgrades.
- **Well-Documented:** Telodendria places as much emphasis on documentation as on code, which means you can be sure that the documentation will always remain up-to-date, accurate, and most importantly, reasonably exhaustive.
[Read Technical Rationale &rightarrow;](https://git.telodendria.io/Telodendria/Telodendria/src/branch/master/docs/dev/rationale.md)
## Get Started
Check out the [Documentation](https://git.telodendria.io/Telodendria/telodendria/src/branch/master/docs/README.md) to get started with
Telodendria.
## Status
Telodendria is in the very early stages of development. As such, it may
not yet deliver on all of its promises. Currently, Telodendria is not
ready for end-users yet. While it features very basic user
authentication, it does not actually work as a chat server yet.
We are hoping to ship Telodendria `v1.7.0-alpha4` by January of 2025. This
release should be usable for communication between **local users**
only. Additional features, including federation with other Matrix
homeservers will be added in future releases.
You can help speed up development by **sponsoring**
Telodendria or [getting involved](https://git.telodendria.io/Telodendria/Telodendria/src/branch/master/docs/CONTRIBUTING.md).
## Sponsorship
Telodendria is maintained by a loosely-knit band of volunteers. The
project currently has no sponsors and thus no source of income to
pay for infrastructure costs and developer time. To ensure
Telodendria's long-term success, please consider sponsoring the
project.
You can make a recurring donation to Telodendria using
[LiberaPay](https://liberapay.com/Telodendria/donate). You can also make
one-time donations using
[Stripe](https://donate.stripe.com/8wM29AfF5bRJc48eUU). If you would
like to make a recurring donation larger than that allowed by
LiberaPay, please contact Jordan Bancino over Matrix at
`@jordan:bancino.net` or email at `jordan@bancino.net`.
### Benefits
While there are no set sponsorship tiers at this time, sponsoring
Telodendria is a mutually beneficial relationship. Depending on the
amount you donate, you can get your name, logo, and website links
on the [Sponsors](../sponsors) page, the project `README`, or the
main website.
## License
All of the code and documentation for Telodendria is licensed under a
modified MIT license. The MIT license is an extremely permissive
license that has very few restrictions. Please consult the
[`LICENSE.txt`](https://git.telodendria.io/Telodendria/Telodendria/src/branch/master/LICENSE.txt) file for the actual license text. It is
important to note that the Telodendria license text differs from the
original MIT license in the following ways:
- Where the MIT license states that the copyright notice and permission
notice shall be included in all copies or *substantial* portions of the
software, the Telodendria requires the copyright notice and
permission notice be included with *all* portions, regardless of the
size, by omitting the word *substantial*.
The Telodendria logo in all its forms, including the ASCII
representation, belongs solely to the Telodendria project. It must be
used only to represent the official Telodendria project. You are free
to use the logo in any way as long as it represents or links to the
official project. If Telodendria is forked, the logo must be removed
completely from the project, and optionally replaced by a different
one.

View file

@ -1,64 +0,0 @@
.= -=-
:.:+ .=:.
.=+-==. :.
.+- =.
.+ :+.
==. -+:
=++==--:: =+.
.:::--=+=: :+=
:==. -=:
===----=-. ... :+.
:==+=======: .-+-::-+-=+=
.==*%#======= :+- ..
.:--=-===+=========-. :+:
.=++=::..:============-+=-=-
:+=: :=+-: .-=========-. .
=+++: .:=+-: .:--. .--:==:
::---:.. :=+: ==
++. .+-
=+ .+- ...:
+- -+-:-+=::+:
:=-....:-=: .--: =-
-++=:.:::..
=======================================================
|_ _|__| | ___ __| | ___ _ __ __| |_ __(_) __ _
| |/ _ \ |/ _ \ / _` |/ _ \ '_ \ / _` | '__| |/ _` |
| | __/ | (_) | (_| | __/ | | | (_| | | | | (_| |
|_|\___|_|\___/ \__,_|\___|_| |_|\__,_|_| |_|\__,_|
=======================================================
Copyright (C) 2023 Jordan Bancino <@jordan:bancino.net>
This is the source code for Telodendria, a Matrix homeserver written
in C. All of the documentation is available as man pages in the
man/ directory, or online at https://telodendria.io
If information is missing from the documentation, please feel free
to reach out to #telodendria-general:bancino.net on Matrix.
This file documents the directory structure of the source code
repository.
Telodendria/
contrib/ - Supplemental files, such as example configs.
man/ - The official documentation as man pages.
proposals/ - Proposals for new features or fixes, as man pages.
site/ - The official website.
src/ - The C source code for Telodendria.
include/ - Header files for the source code.
Routes/ - Where Matrix API endpoints are implemented.
Static/ - Endpoints that just generate static HTML pages.
tests/ - Unit and integration tests will eventually go here.
tools/ - Development environment and tools.
To cut a new release for Telodendria, perform the following
steps. This is just a reference for me so I don't mess it up.
- Update tools/bin/td to declare the next version number.
- Make sure man/man7/telodendria-changelog.7 is up to date.
with the latest information. (Be sure to set the date
correctly)
- Commit all changes.
- Run the release recipe: td release
- Deploy the site: td site

58
Schema/ClientEvent.json Normal file
View file

@ -0,0 +1,58 @@
{
"guard": "TELODENDRIA_SCHEMA_CLIENTEVENT_H",
"header": "Schema/ClientEvent.h",
"types": {
"ClientEventUnsignedData": {
"type": "struct",
"fields": {
"age": {
"type": "integer"
},
"prev_content": {
"type": "object"
},
"redacted_because": {
"type": "object"
},
"transaction_id": {
"type": "string"
}
}
},
"ClientEvent": {
"type": "struct",
"fields": {
"content": {
"type": "object",
"required": true
},
"event_id": {
"type": "string",
"required": true
},
"origin_server_ts": {
"type": "integer",
"required": true
},
"room_id": {
"type": "string",
"required": true
},
"sender": {
"type": "string",
"required": true
},
"state_key": {
"type": "string"
},
"type": {
"type": "string",
"required": true
},
"_unsigned": {
"type": "ClientEventUnsignedData"
}
}
}
}
}

88
Schema/Config.json Normal file
View file

@ -0,0 +1,88 @@
{
"guard": "TELODENDRIA_SCHEMA_CONFIG_H",
"header": "Schema\/Config.h",
"include": [ "Cytoplasm\/Db.h", "Cytoplasm/HttpServer.h" ],
"types": {
"ConfigTls": {
"fields": {
"cert": { "type": "string", "required": true },
"key": { "type": "string", "required": true }
},
"type": "struct"
},
"ConfigListener": {
"fields": {
"port": { "type": "integer", "required": true },
"threads": { "type": "integer", "required": false },
"maxConnections": { "type": "integer", "required": false },
"tls": { "type": "ConfigTls", "required": false }
},
"type": "struct"
},
"ConfigRunAs": {
"fields": {
"uid": { "type": "string", "required": false },
"gid": { "type": "string", "required": true }
},
"type": "struct"
},
"ConfigLogOutput": {
"fields": {
"stdout": { "name": "CONFIG_LOG_OUTPUT_STDOUT" },
"file": { "name": "CONFIG_LOG_OUTPUT_FILE" },
"syslog": { "name": "CONFIG_LOG_OUTPUT_SYSLOG" }
},
"type": "enum"
},
"ConfigLogLevel": {
"fields": {
"message": { "name": "CONFIG_LOG_LEVEL_MESSAGE" },
"debug": { "name": "CONFIG_LOG_LEVEL_DEBUG" },
"notice": { "name": "CONFIG_LOG_LEVEL_NOTICE" },
"warning": { "name": "CONFIG_LOG_LEVEL_WARNING" },
"error": { "name": "CONFIG_LOG_LEVEL_ERROR" }
},
"type": "enum"
},
"ConfigLogConfig": {
"fields": {
"output": { "type": "ConfigLogOutput", "required": true },
"level": { "type": "ConfigLogLevel", "required": false },
"timestampFormat":{ "type": "string", "required": false },
"color": { "type": "boolean", "required": false }
},
"type": "struct"
},
"Db *": { "type": "extern" },
"DbRef *": { "type": "extern" },
"char *": { "type": "extern" },
"Config": {
"fields": {
"db": { "type": "Db *", "ignore": true },
"ref": { "type": "DbRef *", "ignore": true },
"ok": { "type": "boolean", "ignore": true },
"err": { "type": "char *", "ignore": true },
"listen": { "type": "[ConfigListener]", "required": true },
"runAs": { "type": "ConfigRunAs", "required": false },
"log": { "type": "ConfigLogConfig", "required": true },
"serverName": { "type": "string", "required": true },
"baseUrl": { "type": "string", "required": false },
"identityServer": { "type": "string", "required": false },
"pid": { "type": "string", "required": false },
"maxCache": { "type": "integer", "required": false },
"federation": { "type": "boolean", "required": true },
"registration": { "type": "boolean", "required": true }
},
"type": "struct"
}
}
}

121
Schema/Filter.json Normal file
View file

@ -0,0 +1,121 @@
{
"guard": "TELODENDRIA_SCHEMA_FILTER_H",
"header": "Schema\/Filter.h",
"types": {
"FilterRoom": {
"fields": {
"not_rooms": {
"type": "[string]"
},
"state": {
"type": "FilterRoomEvent"
},
"include_leave": {
"type": "boolean"
},
"timeline": {
"type": "FilterRoomEvent"
},
"account_data": {
"type": "FilterRoomEvent"
},
"rooms": {
"type": "[string]"
},
"ephemeral": {
"type": "FilterRoomEvent"
}
},
"type": "struct"
},
"FilterEventFormat": {
"fields": {
"federation": {
"name": "FILTER_FORMAT_FEDERATION"
},
"client": {
"name": "FILTER_FORMANT_CLIENT"
}
},
"type": "enum"
},
"FilterEvent": {
"fields": {
"not_senders": {
"type": "[string]"
},
"limit": {
"type": "integer"
},
"senders": {
"type": "[string]"
},
"types": {
"type": "[string]"
},
"not_types": {
"type": "[string]"
}
},
"type": "struct"
},
"Filter": {
"fields": {
"event_format": {
"type": "FilterEventFormat"
},
"presence": {
"type": "FilterEvent"
},
"account_data": {
"type": "FilterEvent"
},
"room": {
"type": "FilterRoom"
},
"event_fields": {
"type": "[string]"
}
},
"type": "struct"
},
"FilterRoomEvent": {
"fields": {
"not_rooms": {
"type": "[string]"
},
"not_senders": {
"type": "[string]"
},
"limit": {
"type": "integer"
},
"senders": {
"type": "[string]"
},
"include_redundant_members": {
"type": "boolean"
},
"types": {
"type": "[string]"
},
"rooms": {
"type": "[string]"
},
"lazy_load_members": {
"type": "boolean"
},
"not_types": {
"type": "[string]"
},
"contains_url": {
"type": "boolean"
},
"unread_thread_notifications": {
"type": "boolean"
}
},
"type": "struct"
}
}
}

38
Schema/LoginRequest.json Normal file
View file

@ -0,0 +1,38 @@
{
"header": "Schema\/LoginRequest.h",
"types": {
"LoginRequestType": {
"fields": {
"m.login.password": { "name": "REQUEST_TYPE_PASSWORD" }
},
"type": "enum"
},
"LoginRequestUserIdentifier": {
"fields": {
"type": { "type": "string" },
"user": { "type": "string" }
},
"type": "struct"
},
"LoginRequest": {
"fields": {
"type": { "type": "LoginRequestType" },
"identifier": { "type": "object" },
"password": { "type": "string" },
"address": { "type": "string" },
"user": { "type": "string" },
"device_id": { "type": "string" },
"initial_device_display_name": { "type": "string" },
"medium": { "type": "string" },
"token": { "type": "string" },
"refresh_token": { "type": "boolean" }
},
"type": "struct"
}
},
"guard": "TELODENDRIA_SCHEMA_LOGIN_REQUEST_H"
}

81
Schema/PduV1.json Normal file
View file

@ -0,0 +1,81 @@
{
"guard": "TELODENDRIA_SCHEMA_PDUV1_H",
"header": "Schema/PduV1.h",
"types": {
"PduV1EventHash": {
"type": "struct",
"fields": {
"sha256": {
"type": "string",
"required": true
}
}
},
"PduV1UnsignedData": {
"type": "struct",
"fields": {
"age": {
"type": "integer"
}
}
},
"PduV1": {
"type": "struct",
"fields": {
"auth_events": {
"type": "array",
"required": true
},
"content": {
"type": "object",
"required": true
},
"depth": {
"type": "integer",
"required": true
},
"event_id": {
"type": "string",
"required": true
},
"hashes": {
"type": "PduV1EventHash",
"required": true
},
"origin_server_ts": {
"type": "integer",
"required": true
},
"prev_events": {
"type": "array",
"required": true
},
"redacts": {
"type": "string"
},
"room_id": {
"type": "string",
"required": true
},
"sender": {
"type": "string",
"required": true
},
"signatures": {
"type": "object",
"required": true
},
"state_key": {
"type": "string"
},
"type": {
"type": "string",
"required": true
},
"_unsigned": {
"type": "PduV1UnsignedData"
}
}
}
}
}

77
Schema/PduV3.json Normal file
View file

@ -0,0 +1,77 @@
{
"guard": "TELODENDRIA_SCHEMA_PDUV3_H",
"header": "Schema/PduV3.h",
"types": {
"PduV3EventHash": {
"type": "struct",
"fields": {
"sha256": {
"type": "string",
"required": true
}
}
},
"PduV3UnsignedData": {
"type": "struct",
"fields": {
"age": {
"type": "integer"
}
}
},
"PduV3": {
"type": "struct",
"fields": {
"auth_events": {
"type": "[string]",
"required": true
},
"content": {
"type": "object",
"required": true
},
"depth": {
"type": "integer",
"required": true
},
"hashes": {
"type": "PduV3EventHash",
"required": true
},
"origin_server_ts": {
"type": "integer",
"required": true
},
"prev_events": {
"type": "[string]",
"required": true
},
"redacts": {
"type": "string"
},
"room_id": {
"type": "string",
"required": true
},
"sender": {
"type": "string",
"required": true
},
"signatures": {
"type": "object",
"required": true
},
"state_key": {
"type": "string"
},
"type": {
"type": "string",
"required": true
},
"_unsigned": {
"type": "PduV3UnsignedData"
}
}
}
}
}

49
Schema/RegToken.json Normal file
View file

@ -0,0 +1,49 @@
{
"guard": "TELODENDRIA_SCHEMA_REGTOKEN_H",
"header": "Schema\/RegToken.h",
"include": [
"Cytoplasm\/Db.h"
],
"types": {
"Db *": {
"type": "extern"
},
"DbRef *": {
"type": "extern"
},
"RegTokenInfo": {
"fields": {
"db": {
"type": "Db *",
"ignore": true
},
"ref": {
"type": "DbRef *",
"ignore": true
},
"name": {
"type": "string"
},
"created_by": {
"type": "string"
},
"created_on": {
"type": "integer"
},
"expires_on": {
"type": "integer"
},
"used": {
"type": "integer"
},
"uses": {
"type": "integer"
},
"grants": {
"type": "array"
}
},
"type": "struct"
}
}
}

17
Schema/Registration.json Normal file
View file

@ -0,0 +1,17 @@
{
"header": "Schema\/Registration.h",
"types": {
"RegistrationRequest": {
"fields": {
"username": { "type": "string" },
"password": { "type": "string" },
"device_id": { "type": "string" },
"inhibit_login": { "type": "boolean" },
"initial_device_display_name": { "type": "string" },
"refresh_token": { "type": "boolean" }
},
"type": "struct"
}
},
"guard": "TELODENDRIA_SCHEMA_REGISTRATION_H"
}

21
Schema/RequestToken.json Normal file
View file

@ -0,0 +1,21 @@
{
"header": "Schema\/RequestToken.h",
"types": {
"RequestToken": {
"fields": {
"client_secret": { "type": "string" },
"send_attempt": { "type": "integer" },
"next_link": { "type": "string" },
"id_access_token": { "type": "string" },
"id_server": { "type": "string" },
"email": { "type": "string" },
"country": { "type": "string" },
"phone_number": { "type": "string" }
},
"type": "struct"
}
},
"guard": "TELODENDRIA_SCHEMA_REQUESTTOKEN_H"
}

View file

@ -0,0 +1,120 @@
{
"guard": "TELODENDRIA_SCHEMA_ROOMCREATE_H",
"header": "Schema/RoomCreateRequest.h",
"types": {
"RoomVisibility": {
"fields": {
"public": {
"name": "ROOM_PUBLIC"
},
"private": {
"name": "ROOM_PRIVATE"
}
},
"type": "enum"
},
"RoomCreateRequest": {
"fields": {
"invite": {
"type": "[string]"
},
"room_version": {
"type": "string"
},
"invite_3pid": {
"type": "[RoomInvite3Pid]"
},
"topic": {
"type": "string"
},
"visibility": {
"type": "RoomVisibility"
},
"creation_content": {
"type": "object"
},
"is_direct": {
"type": "boolean"
},
"name": {
"type": "string"
},
"initial_state": {
"type": "[RoomStateEvent]"
},
"power_level_content_override": {
"type": "object"
},
"room_alias_name": {
"type": "string"
},
"preset": {
"type": "RoomCreatePreset"
}
},
"type": "struct"
},
"RoomInvite3Pid": {
"fields": {
"id_access_token": {
"required": true,
"type": "string"
},
"address": {
"required": true,
"type": "string"
},
"medium": {
"required": true,
"type": "Room3PidMedium"
},
"id_server": {
"required": true,
"type": "string"
}
},
"type": "struct"
},
"Room3PidMedium": {
"fields": {
"msisdn": {
"name": "ROOM_3PID_MSISDN"
},
"email": {
"name": "ROOM_3PID_EMAIL"
}
},
"type": "enum"
},
"RoomCreatePreset": {
"fields": {
"public_chat": {
"name": "ROOM_CREATE_PUBLIC"
},
"trusted_private_chat": {
"name": "ROOM_CREATE_TRUSTED"
},
"private_chat": {
"name": "ROOM_CREATE_PRIVATE"
}
},
"type": "enum"
},
"RoomStateEvent": {
"fields": {
"content": {
"required": true,
"type": "object"
},
"state_key": {
"type": "string"
},
"type": {
"required": true,
"type": "string"
}
},
"type": "struct"
}
}
}

View file

@ -0,0 +1,13 @@
{
"header": "Schema\/UserDirectoryRequest.h",
"types": {
"UserDirectoryRequest": {
"fields": {
"search_term": { "type": "string" },
"limit": { "type": "integer" }
},
"type": "struct"
}
},
"guard": "TELODENDRIA_SCHEMA_USERDIRECTORYREQUEST_H"
}

View file

@ -1,91 +0,0 @@
Telodendria To-Do List
======================
Key:
[ ] Not Started
[x] Done
[~] In Progress
[!] Won't Fix
Milestone: v0.3.0
-----------------
[ ] Stream API
[ ] TLS
[ ] SOCKS
[ ] Multi-output
[ ] HTTP Client API
[ ] Option to pretty-print Json
[ ] Simple command line tool to make matrix requests
- Built on HTTP client API
[ ] Simple command line tool for working with JSON
- Like a simpler version of jq
- Should pretty-print Json
- Should be able to query fields for use in shell scripts.
[ ] Move configuration to database
[ ] Initial configuration
[ ] If no config, create one-time use registration token that
grants user admin privileges.
[ ] /_telodendria/admin/config endpoint
[ ] Refactor TelodendriaConfig to just Config (ConfigLock() and ConfigUnlock())
[ ] Client-Server API
[ ] 4: Token-based user registration
[ ] Implement user-interactive auth flow
[ ] Token validity endpoint
[ ] Add m.login.registration_token to registration endpoint
flow
- Ensure that registration tokens can be used even if
registration is disabled.
[ ] 4: Account management
[ ] Deactivate
[ ] Make sure UserLogin() fails if user is deactivated.
[ ] Change password
[ ] Whoami
[ ] 9: User Data
[ ] 5: Capabilities negotiation
[ ] 10: Security (Rate Limiting)
Milestone: v0.4.0
-----------------
[ ] Client-Server API
[ ] 6: Filtering
[ ] 7: Events
[ ] 8: Rooms
Milestone: v0.5.0
-----------------
[~] Client-Server API
[ ] Modules
[ ] Content Repository
Milestone: v1.0.0
-----------------
[~] Client-Server API
[ ] Modules
[ ] Instant Messaging
[ ] Voice over IP
[ ] Receipts
[ ] Fully Read Markers
[ ] Send-To-Device Messaging
[ ] Server-Server API
[ ] Application Service API
[ ] Identity Service API
[ ] Push Gateway API
[ ] Room Versions
Milestone v1.1.0
----------------
[ ] Database upgrades/migration path
[ ] Create a command line tool to manage Telodendria
[ ] User management
[ ] Room management
[ ] Migrate from Synapse or Dendrite, whichever is more mainstream by
the time we get here.

321
configure vendored Executable file
View file

@ -0,0 +1,321 @@
#!/usr/bin/env sh
#
# Argument Parsing
#
echo "Build Configuration"
echo "-------------------"
BUILD="build"
OUT="out"
SRC="src"
INCLUDE="src/include"
TOOLS="tools/src"
SCHEMA="Schema"
CYTOPLASM="Cytoplasm"
CFLAGS="-O1 -D_DEFAULT_SOURCE -I${INCLUDE} -I${BUILD}"
LIBS="-lm -pthread -lCytoplasm"
# Set default args for all platforms
SCRIPT_ARGS="--prefix=/usr/local --bin-name=telodendria --version=1.7.0-alpha4"
if [ -f "${CYTOPLASM}/configure" ]; then
SCRIPT_ARGS="${SCRIPT_ARGS} --cytoplasm=${CYTOPLASM}"
else
SCRIPT_ARGS="${SCRIPT_ARGS} --cytoplasm=" # No cytoplasm path.
fi
# Set compiler depending on the platform.
case "$(uname)" in
Linux|NetBSD)
# These systems typically use GCC.
SCRIPT_ARGS="${SCRIPT_ARGS} --cc=gcc"
;;
OpenBSD|FreeBSD|Darwin)
# These systems typically use Clang.
SCRIPT_ARGS="${SCRIPT_ARGS} --cc=clang"
;;
*)
# Use default compiler which is required to be present on
# all POSIX-compliant systems.
SCRIPT_ARGS="${SCRIPT_ARGS} --cc=c99"
;;
esac
# Append any additional args specified by user
SCRIPT_ARGS="${SCRIPT_ARGS} $@"
echo "Processing options..."
echo "Ran with arguments: $SCRIPT_ARGS"
# Process all arguments
for arg in $SCRIPT_ARGS; do
case "$arg" in
--cc=*)
CC=$(echo "$arg" | cut -d '=' -f 2-)
case "${CC}" in
gcc*|clang*)
# "Fancy" compilers that support a plethora of additional flags we
# want to enable if present.
CFLAGS="-Wall -Wextra -Werror -pedantic -std=c99 -O3 ${CFLAGS}"
LDFLAGS="${LDFLAGS} -flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections"
;;
esac
;;
--prefix=*)
PREFIX=$(echo "$arg" | cut -d '=' -f 2-)
;;
--bin-name=*)
BIN_NAME=$(echo "$arg" | cut -d '=' -f 2-)
;;
--version=*)
VERSION=$(echo "$arg" | cut -d '=' -f 2-)
;;
--enable-debug)
DEBUG="-O0 -g"
;;
--disable-debug)
DEBUG=""
;;
--cytoplasm=*)
CYTOPLASM=$(echo "$arg" | cut -d '=' -f 2-)
if [ -n "${CYTOPLASM}" ]; then
if [ ! -f "${CYTOPLASM}/configure" ]; then
echo "Path for Cytoplasm does not appear to actually contain Cytoplasm source:"
echo "${CYTOPLASM}"
exit 1
fi
CFLAGS="${CFLAGS} -I${CYTOPLASM}/include"
LDFLAGS="-L${CYTOPLASM}/out/lib ${LDFLAGS}"
fi
;;
*)
echo "Invalid argument: $arg"
exit 1
;;
esac
done
CFLAGS="${CFLAGS} '-DTELODENDRIA_VERSION=\"${VERSION}\"' ${DEBUG}"
LDFLAGS="${LDFLAGS} ${LIBS}"
#
# Makefile generation
#
collect() {
from="$1"
orig_ext="$2"
new_ext="$3"
prefix="$4"
exec="$5"
find "${from}" -name "*${orig_ext}" -type f | while IFS= read -r src; do
src=$(echo "$src" | sed -e "s|^${from}||g")
obj=$(echo "$src" | sed -e "s|${orig_ext}\$|${new_ext}|g")
obj="${prefix}${obj}"
src="${from}${src}"
"${exec}" "${src}" "${obj}"
done
}
prefix() {
prefix="$1"
shift
for thing in $@; do
printf "${prefix}${thing} "
done
}
cytoplasm_tool() {
tool="$1"
if [ -n "${CYTOPLASM}" ]; then
echo "LD_LIBRARY_PATH=${CYTOPLASM}/out/lib ${CYTOPLASM}/out/bin/$tool"
else
echo "$tool"
fi
}
print_src() {
printf '%s ' "$1"
}
print_obj() {
printf '%s ' "$2"
}
get_deps() {
src="$1"
${CC} -I${INCLUDE} -I${BUILD} $(if [ -n "${CYTOPLASM}" ]; then echo "-I${CYTOPLASM}/include"; fi) -E "$src" \
| grep '^#' \
| awk '{print $3}' \
| cut -d '"' -f 2 \
| sort \
| uniq \
| grep -v '^[/<]' \
| grep -e "^${SRC}/" -e "^${BUILD}/" \
| while IFS= read -r dep; do
printf "%s " "$dep"
done
}
compile_obj() {
src="$1"
obj="$2"
pref="${obj}: $(get_deps ${src})"
echo "$pref $(collect ${SCHEMA}/ .json .h ${BUILD}/Schema/ print_obj)"
echo "${TAB}@mkdir -p $(dirname ${obj})"
echo "${TAB}\$(CC) \$(CFLAGS) -fPIC -c -o \"${obj}\" \"${src}\""
}
compile_bin() {
src="$1"
out="$2"
depObjs=$(prefix ${BUILD}/ CanonicalJson.o Telodendria.o)
echo "${out}: ${src}"
echo "${TAB}@mkdir -p ${OUT}/bin"
echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" $depObjs \$(LDFLAGS)"
}
compile_doc() {
src="$1"
out="$2"
if echo "${src}" | grep "Schema" > /dev/null; then
return
fi
echo "${out}: ${src}"
echo "${TAB}@mkdir -p ${OUT}/man/man3"
echo "${TAB}$(cytoplasm_tool hdoc) -D \"Os=${BIN_NAME}\" -i \"${src}\" -o \"${out}\""
}
print_doc() {
if echo "${src}" | grep "Schema" > /dev/null; then
return
fi
printf '%s ' "$2"
}
compile_schema() {
src="$1"
out="$2"
obj="${BUILD}/Schema/${out}.o"
echo "${BUILD}/Schema/${out}.h:"
echo "${TAB}@mkdir -p ${BUILD}/Schema"
echo "${TAB}$(cytoplasm_tool j2s) -s \"${src}\" -h \"${BUILD}/Schema/${out}.h\" -c \"${BUILD}/Schema/${out}.c\""
echo "${BUILD}/Schema/${out}.c:"
echo "${TAB}@mkdir -p ${BUILD}/Schema"
echo "${TAB}$(cytoplasm_tool j2s) -s \"${src}\" -h \"${BUILD}/Schema/${out}.h\" -c \"${BUILD}/Schema/${out}.c\""
echo "${obj}: ${src} ${BUILD}/Schema/${out}.c"
echo "${TAB}@mkdir -p ${BUILD}/Schema"
echo "${TAB}\$(CC) \$(CFLAGS) -fPIC -c -o \"${obj}\" \"${BUILD}/Schema/${out}.c\""
}
install_out() {
src="$1"
out="$2"
dir=$(dirname "$out")
echo "${TAB}mkdir -p \"$dir\""
echo "${TAB}cp \"$src\" \"$out\""
}
install_man() {
src="${OUT}/man/man3/${BIN_NAME}-$(basename $1 .h).3"
out="$2"
dir=$(dirname "$out")
echo "${TAB}mkdir -p \"$dir\""
echo "${TAB}cp \"$src\" \"$out\""
}
uninstall_out() {
src="$1"
out="$2"
echo "${TAB}rm \"$out\""
}
echo "Generating Makefile..."
OBJS="$(collect ${SRC}/ .c .o ${BUILD}/ print_obj) $(collect ${SCHEMA}/ .json .o ${BUILD}/Schema/ print_obj)"
TAB=$(printf '\t')
cat << EOF > Makefile
.POSIX:
# Generated by '$0' on $(date).
# This file should generally not be manually edited.
CC = ${CC}
PREFIX = ${PREFIX}
CFLAGS = ${CFLAGS}
LDFLAGS = ${LDFLAGS}
all: ${BIN_NAME} docs tools
docs: $(collect ${INCLUDE}/ .h .3 ${OUT}/man/man3/${BIN_NAME}- print_doc)
tools: $(collect ${TOOLS}/ .c '' ${OUT}/bin/ print_obj)
format:
${TAB}find . -name '*.c' | while IFS= read -r src; do \\
${TAB} if indent "\$\$src"; then \\
${TAB} rm \$\$(basename "\$\$src").BAK; \\
${TAB} fi \\
${TAB}done
license:
${TAB}find . -name '*.[ch]' | while IFS= read -r src; do \\
${TAB} srcHeader=\$\$(grep -n -m 1 '^ \*/' "\$\$src" | cut -d ':' -f 1); \\
${TAB} head -n\$\$srcHeader \$\$src | \\
${TAB} diff -u -p - "LICENSE.txt" | \\
${TAB} patch "\$\$src" | grep -v "^Hmm"; \\
${TAB}done
${BIN_NAME}: ${OUT}/bin/${BIN_NAME}
install: ${BIN_NAME}
${TAB}mkdir -p \$(PREFIX)/bin
${TAB}cp ${OUT}/bin/${BIN_NAME} \$(PREFIX)/bin/${BIN_NAME}
uninstall:
${TAB}rm \$(PREFIX)/bin/${BIN_NAME}
clean:
${TAB}rm -r "${BUILD}" "${OUT}"
${OUT}/bin/${BIN_NAME}: ${OBJS}
${TAB}@mkdir -p "${OUT}/bin"
${TAB}\$(CC) -o "${OUT}/bin/${BIN_NAME}" ${OBJS} \$(CFLAGS) \$(LDFLAGS)
$(collect ${SCHEMA}/ .json '' '' compile_schema)
$(collect ${SRC}/ .c .o ${BUILD}/ compile_obj)
$(collect ${TOOLS}/ .c '' ${OUT}/bin/ compile_bin)
$(collect ${INCLUDE}/ .h .3 ${OUT}/man/man3/${BIN_NAME}- compile_doc)
$(
if [ -n "${CYTOPLASM}" ]; then
echo "cytoplasm:"
echo "${TAB}cd ${CYTOPLASM} && ./configure && \$(MAKE)"
fi
)
EOF
echo "Done. Run 'make' to build ${BIN_NAME}."

View file

@ -1 +0,0 @@
.vagrant

View file

@ -3,6 +3,4 @@ all:
install:
install build/telodendria $(PREFIX)/bin/telodendria
mkdir -p $(PREFIX)/share/examples/telodendria
install contrib/production.conf $(PREFIX)/share/examples/telodendria/telodendria.conf
find man -name 'telodendria*\.[1-8]' -exec install {} $(PREFIX)/{} \;

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net>
* Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> with
* other valuable contributors. See CONTRIBUTORS.txt for the full list.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
@ -21,45 +22,44 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TELODENDRIA_DB_H
#define TELODENDRIA_DB_H
#include <Tls.h>
#include <stddef.h>
#if TLS_IMPL == TLS_TEMPLATE /* Set your TLS_* implementation
* flag here */
#include <HashMap.h>
#include <Array.h>
/*
* #include statements and any implementation structures
* needed should go here.
*/
typedef struct Db Db;
typedef struct DbRef DbRef;
void *
TlsInitClient(int fd, const char *serverName)
{
return NULL;
}
extern Db *
DbOpen(char *, size_t);
void *
TlsInitServer(int fd, const char *crt, const char *key)
{
return NULL;
}
extern void
DbClose(Db *);
ssize_t
TlsRead(void *cookie, void *buf, size_t nBytes)
{
return -1;
}
extern DbRef *
DbCreate(Db *, size_t,...);
ssize_t
TlsWrite(void *cookie, void *buf, size_t nBytes)
{
return -1;
}
extern int
DbDelete(Db *, size_t,...);
extern DbRef *
DbLock(Db *, size_t,...);
extern int
DbUnlock(Db *, DbRef *);
extern int
DbExists(Db *, size_t,...);
extern Array *
DbList(Db *, size_t,...);
extern void
DbListFree(Array *);
extern HashMap *
DbJson(DbRef *);
int
TlsClose(void *cookie)
{
return -1;
}
#endif

View file

@ -1,14 +1,18 @@
{
"serverName": "localhost",
"baseUrl": "http://localhost:8008",
"dataDir": "./data",
"federation": true,
"registration": true,
"threads": 2,
"log": {
"output": "stdout",
"//level": "debug",
"timestampFormat": "none",
"color": true
}
"log": {
"output": "stdout",
"color": true,
"timestampFormat": "none",
"level": "debug"
},
"listen": [
{
"port": 8008,
"tls": false
}
],
"registration": true,
"serverName": "localhost",
"baseUrl": "http:\/\/localhost:8008",
"federation": true
}

View file

@ -1,13 +1,24 @@
{
"serverName": "example.com",
"baseUrl": "https://matrix.example.com",
"identityServer": "https://identity.example.com",
"dataDir": "/var/telodendria",
"federation": true,
"registration": false,
"threads": 4,
"maxCache": 512000000,
"log": {
"output": "file"
"log": {
"output": "file"
},
"listen": [
{
"port": 8008,
"tls": false
},
{
"port": 8448,
"tls": {
"cert": "telodendria.crt",
"key": "telodendria.key"
}
}
],
"serverName": "example.com",
"identityServer": "https://identity.example.com",
"baseUrl": "https://matrix.example.com",
"registration": false,
"federation": true,
"maxCache": 512000000
}

291
docs/CHANGELOG.md Normal file
View file

@ -0,0 +1,291 @@
# Telodendria Change Log
This document contains the complete change log for every official release of Telodendria.
It is intended to be updated with every commit that makes a user-facing change worth
reporting in the change log. As such, it changes frequently between releases. Final
change log entries are published as [Releases](releases).
## v1.7.0-alpha4
**Not Released Yet.**
This release brings filters, rooms, and events! The core of the Matrix
protocol architecture is now in place.
Note that the versioning scheme has changed from `v0.X.0` to
`v1.7.0-alphaX`. This is so that Telodendria releases correspond to the
Matrix specification that they implement, in accordance with
[this blog post](https://telodendria.io/blog/on-matrixs-release-cadence-and-state-resolution-v1).
This versioning scheme change does not indicate a drastic leap forward
in Telodendria's development&mdash;the `-alpha4` suffix indicates that
this is the 4th pre-release, with the target being a stable `v1.7.0`.
Note also that we still have a *long* way to go before we reach that
stable release.
### Matrix Specification
The following endpoints were added:
- **POST** `/_matrix/client/v3/user/{userId}/filter`
- **GET** `/_matrix/client/v3/user/{userId}/filter/{filterId}`
### Bug Fixes & General Improvements
- Use `j2s` for parsing the configuration
- Fixed a double-free in `RouteUserProfile()` that would cause errors
with certain Matrix clients. (#35)
- Improved compatibility with NetBSD on various platforms.
- Moved [Cytoplasm](/Telodendria/Cytoplasm) to its own repository. It
will now be maintained separately and have its own releases as well.
- Use a `configure` script and `make` to build Telodendria instead of
custom scripts.
- Greatly simplified some endpoint code by using Cytoplasm's `j2s` for
parsing request bodies.
- Create a parser API for grammars found in Matrix, and refactor the
User API to use it.
### New Features
- Implemented a `"pid"` option in the configuration, allowing Telodendria
to write its process ID to a specified file.
- Moved all administrator API endpoints to `/_telodendria/admin/v1`,
because later revisions of the administrator API may break clients, so
we want a way to give those breaking revisions new endpoints.
- Implemented `/_telodendria/admin/v1/deactivate/[localpart]` for admins
to be able to deactivate users.
- Added a **PUT** option to `/_telodendria/admin/v1/config` that gives
the ability to change only a subset of the configuration.
- Implemented the following APIs for managing registration tokens:
- **GET** `/_telodendria/admin/tokens`
- **GET** `/_telodendria/admin/tokens/[token]`
- **POST** `/_telodendria/admin/tokens`
- **DELETE** `/_telodendria/admin/tokens/[token]`
- **GET** `/_matrix/client/v3/directory/room/[alias]`
- **PUT** `/_matrix/client/v3/directory/room/[alias]`
- **DELETE** `/_matrix/client/v3/directory/room/[alias]`
- **GET** `/_matrix/client/v3/rooms/[id]/aliases`
## v0.3.0
**Saturday, June 10, 2023**
Introducing a new configuration API and Cytoplasm, a general-purpose C library that
supports source/sink-agnostic I/O, TLS, an HTTP client, and more! The third major
release of Telodendria packs a lot of architectural improvements on top of supporting
more of the Matrix specification.
### Matrix Specification
Added support for the following endpoints:
- `/_matrix/client/v3/account/whoami`
- `/_matrix/client/v3/account/password`
- `/_matrix/client/v3/account/deactivate`
- `/_matrix/client/v3/profile/*`
- `/_matrix/client/v3/capabilities`
- `/_matrix/client/v3/auth/*/fallback/web`
There is also support for token-based user registration. Note that there is as of
yet no admin-facing way to create these registration tokens, but the APIs are in
place.
### New Features
- Added a new `HttpClient` API for making HTTP requests. This will eventually be
used for federating with other Matrix homeservers.
- Added support for pretty-printing JSON in `Json`. Telodendria itself does not
pretty-print JSON, but this is useful for debugging and building useful tools.
- Added a handful of new development tools built on the Telodendria APIs. New
tools include `http`, a command line tool for making HTTP requests, similar to
`curl`, `json`, a command line tool for working with JSON, similar to `jq`, and
`http-debug-server`, a simple HTTP server that just prints requests out to standard
output and returns an empty JSON object. `http` and `json` are replacements for
`curl` and `jq` that build on the `HttpClient` and `Json` APIs. They exist mainly
to test those APIs, but also to reduce the number of dependencies that Telodendria
has. `http-debug-server` exists to test the `HttpServer` and `HttpClient` APIs.
- Replaced all usage of `jq` with the new `json` tool. `jq` is no longer a development
dependency.
- Replaced all usage of `curl` with the new `http` tool. `curl` is no longer a
required development dependency.
- Added a new `tt` script for easily making Matrix requests against Telodendria
in development.
- Added TLS support to both the HTTP client and server. Currently, Telodendria
supports LibreSSL and OpenSSL, but other TLS libraries should be extremely easy
to add support for.
- Added support for spinning up multiple HTTP servers. This is useful for having
a TLS port and a non-TLS port, for example.
- Moved all program configuration to the data directory and added an administrator
API endpoint to manage it. It is now no longer recommended to manually update the
configuration file. Consult the [Administrator API](user/admin/README.md) documentation
and the [Configuration](user/config.md) documentation.
- Added an administrator API endpoint for process control. Telodendria can now be
restarted or shutdown via API endpoint.
- Added an administrator API endpoint for getting statistics about the running
Telodendria process.
- Added support for user privileges, a way to have fine-grained control over what
users are allowed to do with the administrator API. Administrator APIs for setting
and getting privileges is now supported, and registration tokens have privileges
associated with them so that users created with a token will automatically be given
the specified privileges.
### Fixes & General Improvements
- Fixed a few warnings that were generated on some obscure compilers.
- Moved the `main()` function to its own file to make it easier to link other
programs with the Telodendria APIs.
- Fixed the development tools environment script. Apparently using a hyphen as a bullet
point is not very portable, because some shell implementations of `printf` interpret it
as a flag. Switched to an asterisk.
- Fixed some intermittent I/O errors that would occur as a result of race conditions in
`JsonConsomeWhitespace()`. This function, and a few others, expect I/O to be blocking,
but the `HttpServer` sets up I/O to be non-blocking, leading to occasional failures in
JSON parsing.
- Abstracted all I/O into the new `Io` and `Stream` APIs, which provide an input- and
output- agnostic stream processing interface. This allows for a simple implementation of
proxies, TLS, and other stream filters without having to change any of the existing
code.
- Remove all non-POSIX function calls, including the call to `chroot()` and, on
OpenBSD, `pledge()` and `unveil()`. This may seem like a downgrade in security, but
these are platform-specific system calls that should be patched in by package maintainers
if they are desired. They also caused problems when implementing other features, because
some library calls need to be able to access files on the filesystem.
- Fixed the build script to supply `LDFLAGS` after the object files when linking.
Apparently the order in which libraries are passed matters to some compilers.
- Added the response status of a request to the log output. This means that requests are
logged after they have completed, not before they are started.
- Memory allocations, reallocations, and frees are no longer loged when the log level
is set to debug in the configuration file. To enable the logging of memory operations,
pass the `-v` flag.
- Implemented a proper HTTP request router with POSIX regular expression support.
Previously, a series of nested `if`-statements were used to route requests, but this
approach quickly becamse very messy. While the HTTP request router incurs a small memory
and runtime speed penalty, the code is now much more maintainable and easier to follow.
- Fixed some memory bugs in `Db` that were related to caching data. Caching should
now work as expected.
- Fixed a major design flaw in `Db` that would cause deadlock when multiple threads
request access to the same object. Database locking is now in a per-thread basis,
instead of a per-reference basis.
- Telodendria now shuts down cleanly in response to `SIGTERM`.
- Did some general refactoring to make the source code more readable and easier
to maintain.
Fixed a number of memory-related issues, including switching out some unsafe
functions for safer versions, per the recommendations of the OpenBSD linker.
- Moved all code documentation into the C header files to make it more likely
that it will get updated. A simple header file parser and documentation generator
have been added to the code base. See the `hdoc` man pages for documentation.
- Updated the build script to provide static and shared libraries containing
the code for Telodendria to make it easier to statically and dynamically link to
other programs. The idea is that these libraries should be shipped with Telodendria,
or as a separate package, and can be used to provide a high-level programming
environment.
- Updated the `Json` API to calculate the length of a JSON object. This is
used to set the `Content-Length` header in HTTP requests and reponses.
- Added some string functions, including `StrEquals()`, which replaced almost all
uses of `strcmp()`, since `strcmp()` is used almost exclusively for equality
checking. `StrEquals()` provides a standard way to do so, because previously,
multiple different conventions could be found throughout the code base (for example:
`!strcmp(str1, str2)` vs `strcmp(str1, str2) == 0`).
... And many more!
## v0.2.1
**Monday, March 6, 2023**
This is a patch release that fixes a few typos and other minor issues.
## v0.2.0
**Monday, March 6, 2023**
This release is focused on providing a decent amount of the client authentication
API. You can now create accounts on a Telodendria homeserver, and log in to
get access tokens.
### New
- Added the basic form of the user registration API. If registration is enabled
in the configuration file, clients can now register for Matrix accounts.
- Added the basic form of the user login API. Clients can now log in to
their accounts and generate access tokens to be used to authenticate requests.
- Added the basic form of the user interactive authentication API, which can be used
by endpoints that the spec says requires it. Currently, it only implements the
dummy and password stages, but more stages, such as the registration token stage,
will be added in future releases.
- Added a simple landing page that allows those setting up Telodendria to
quickly verify that it is accessible where it needs to be.
- Added the static login page for clients that don't support regular login.
### Changes
- Improved HTTP request logging by removing unnecessary log entries and making
errors more specific.
- Leaked memory is now hexdump-ed out to the log if the log level is set to debug.
This greatly simplifies debugging, because developers can now see exactly what the
contents of the leaked memory are. Note that in some circumstances, this memory
may contain sensitive data, such as access tokens, usernames, or passwords. However,
Telodendria should not be leaking memory at all, so if you encounter any leaks,
please report them.
- Refactored a lot of the code and accompanying documentation to be more readable and
maintainable.
### Bug Fixes
- Fixed a memory leak that would occur when parsing an invalid JSON object.
- Fixed an edge case where HTTP response headers were being sent before they were
properly set, causing the server to report a status of 200 even when that wasn't the
desired status.
- Fixed a few memory leaks in the HTTP parameter decoder that would occur in some
edge cases.
- Fixed an "off-by-one" error in the HTTP server request parser that would prevent
`GET` parameters from being parsed.
- Fixed the database file name descriptor to prevent directory traversal attacks
by replacing special characters with safer ones.
- Fixed a memory leak that would occur when closing a database that contains
cached objects.
- Fixed a memory leak that would occur when deleting database objects.
- Fixed a few non-fatal memory warnings that would show up as a result of passing a
constant string into certain functions.
### Misc.
- Fixed a bug in `td` that caused `cvs` to be invoked in the wrong directory when
tagging a new release.
- Added support for environment variable substitution in all site files. This
makes it easier to release Telodendria versions.
- Fix whitespace issues in various shell scripts.
- Fixed the debug log output so that it only shows the file name, not the
entire file path in the repository.
- Updated the copyright year in the source code and compiled output.
- Switched the `-std=c89` flag to `-ansi`, as `-ansi` might be more supported.
- Fixed the `-v` flag. It now sets the log level to debug as soon as possible to
allow debugging configuration file parsing if necessary.
... And many more bug fixes and feature additions! Too much has changed to make a
comprehensive change log. A lot of things have been done under the hood to make
Telodendria easier to develop in the future. Please test the current functionality,
and report bugs.
The following platforms have been known to compile and run Telodendria:
- OpenBSD
- Linux (GNU and non-GNU)
- Windows (via Cygwin)
- FreeBSD
- NetBSD
- DragonFlyBSD
- Haiku OS
- Android (via Termux)
Telodendria is about being portable; if you compile it on an obscure operating system,
do let us know about it!
## v0.1.0
**Tuesday, December 13, 2022**
This is the first public release of Telodendria so there are no changes to report.
Future releases will have a complete change log entry here.
This is a symbolic release targeted at developers, so there's nothing useful to
ordinary users yet. Stay tuned for future releases though!

256
docs/CONTRIBUTING.md Normal file
View file

@ -0,0 +1,256 @@
# Contributing
Telodendria is a fully open source project. As such, it welcomes
contributions. There are many ways you can contribute, and any way you
can is greatly appreciated. This document details the ways you can
contribute, and how to go about contributing.
## Sponsoring Telodendria
If you would like to sponsor Telodendria, see the
[Sponsorship](../README.md#sponsorship) section on the main project
page. Donations of any size are greatly appreciated.
## Reporting Issues
An important way to get involved is to just report issues you find with
Telodendria during experimentation or normal use. To report an issue,
go to [Issues](/Telodendria/telodendria/issues) &rightarrow;
[New Issue](/Telodendria/telodendria/issues/new/choose) and follow the
instructions.
> **Note:** GitHub issues are not accepted. Issues may only be
> submitted to the official [Gitea](https://git.telodendria.io)
> instance.
### Feature Requests
Feature requests are allowed, but note that they are low-priority in
comparison to existing issues and features. That being said, don't
hesitate to submit feature requests. Just select the "Feature Request"
option when submitting an issue.
## Developing
If you want to write code for Telodendria, either to fix an issue or
add a new feature, you're in the right place. Please follow all the
guidelines in this document to ensure the contribution workflow goes
as smoothly as possible.
### Who can develop Telodendria?
Everyone is welcome to contribute code to Telodendria, provided that
they are willing to license their contributions under the same license
as the project itself.
The primary language used to write Telodendria code is ANSI C. Other
languages you'll find in the Telodendria repository include shell
scripts, `mdoc`, a little bit of HTML and CSS, and `Makefiles`.
Experience with any of these is preferred, but if you want to use
Telodendria to learn, that's okay too! Telodendria's code base should
hopefully be a good learning tool, and if you are serious about
submitting quality work, we'll guide you through the process and
offer suggestions.
### What do I need?
You'll need a couple of things to develop Telodendria:
- A Unix-like operating system that provides standard POSIX behavior,
or the Windows Subsystem for Linux (WSL), Cygwin, or Msys2 if you are
running Windows.
- A C compiler capable of compiling ANSI C89 code (pretty much all of
them do&mdash;pick your favorite, and if you find it doesn't work,
open an issue!).
- `make` for building the project.
- `git` for managing your changes.
- [Cytoplasm](/Telodendria/Cytoplasm), a simple C library written by
the Telodendria developers for the purpose of supporting Telodendria
in a modular way.
Optionally, you may also find these tools helpful:
- `indent` for formatting code.
- `valgrind` for debugging particularly nasty issues.
### Getting The Code
Telodendria is developed using Git. The easiest way to contribute
changes is to fork the main repository, and then creating a pull
request to ask us to pull your changes into our repo.
1. If you don't have an account on the
[Gitea instance](https://git.telodendria.io), create one and sign in.
1. Fork this repository.
1. In your development environment, clone your fork:
```shell
git clone https://git.telodendria.io/[YOUR_USERNAME]/Telodendria.git
cd Telodendria
```
Please base your changes on the `master` branch. If you need help
getting started with Git, that is beyond the scope of this
document, but you can find many good tutorials on the web.
### Building &amp; Running
Telodendria uses the `make` build system. Because it aims at maximum
portability, it targets POSIX `make` and should thus run on any POSIX
system that provides a `make`, be it GNU, BSD, or something different
entirely. To facilitate this, Telodendria provides a `configure` script
which generates the `Makefile`, because the `Makefile` would be far too
verbose and tedious to maintain in a POSIX-compatible way otherwise.
This is similar to how other C programs and libraries are built, although
note that Telodendria's `configure` script is not nearly as advanced as
an `autoconf` script, for example.
Please follow the build and installation directions for
[Cytoplasm](/Telodendria/Cytoplasm) first before attempting to build
Telodendria, because Telodendria depends on Cytoplasm and assumes it is
installed in the standard location for your system. For the best results,
it is recommended to take the time to enable TLS, unless you plan on
running Telodendria behind a reverse proxy.
To build Telodendria, simply run `configure`, then `make`:
```
$ ./configure
$ make
```
You may find some of the following options for `configure` helpful:
- `--prefix=<path>`: Set the install prefix to set by default in the `Makefile`. This defaults to `/usr/local`, which should be appropriate for most Unix-like systems.
- `--(enable|disable)-ld-extra`: Control whether or not to enable additional linking flags that create a more optimized binary. For large compilers such as GCC and Clang, these flags should be enabled. However, if you are using a small or more obscure compiler, then these flags may not be supported, so you can disable them with this option.
- `--(enable|disable)-debug`: Control whether or not to enable debug mode. This sets the optimization level to 0 and builds with debug symbols. Useful for running with a debugger.
- `--static` and `--no-static`: Controls whether static binaries are built by default. On BSD systems, `--static` is perfectly acceptable, but on GNU systems, `--no-static` is often desirable to silence warnings about static binaries emitted by the GNU linker.
Telodendria can be customized with the following options:
- `--bin-name=<name>`: The output name of the server binary. This defaults to `telodendria`. Common alternatives are `matrix-telodendria` or `telodendria-server`.
- `--version=<version>`: The version string to embed in the binary. This can be used to indicate build customizations or non-release versions of Telodendria.
The following recipes are available in the generated `Makefile`:
- `all`: This is the default target. It builds everything.
- `telodendria`: Build the `telodendria` binary. If you specified an alternative `--bin-name`, then this target will be named after that.
- `docs`: Generate the header documentation as `man` pages.
- `tools`: Build the supplemental tools which may be useful for development.
- `clean`: Remove the build and output directories. Telodendria builds are out-of-tree, which greatly simplifies this recipe compared to in-tree builds.
If you're developing Telodendria, these recipes may also be helpful:
- `format`: Format the source code using `indent`. This may require a BSD `indent` because last time I tried GNU `indent`, it didn't like the flags in `indent.pro`. Your mileage may vary.
- `license`: Update the license headers in all source code files with the contents of the `LICENSE.txt`.
To install Telodendria to your system, the following recipes are available:
- `install`: This installs Telodendria under the prefix set with `./configure --prefix=<dir>` or with `make PREFIX=<dir>`. By default, the `make` `PREFIX` is set to whatever was set with `configure --prefix`.
- `uninstall`: Uninstall Telodendria from the same prefix as specified above.
After a build, you can find the object files in `build/` and the output binary in `out/bin/`.
### Pull Requests
> **Note:** Telodendria does not accept GitHub pull requests at this
> time. Please submit your pull requests via Gitea.
Telodendria follows the standard pull request procedures. Once you have
made your changes, committed them, and pushed to your fork, you should
be able to open a pull request on the main repository. When you do, you
will be prompted to write a description. Be sure to include the
related issue that you are closing in your description.
### Code Style
In general, these are the conventions used by the code base. This
guide may be slightly outdated or subject to change, but it should be
a good start. The source code itself is always the absolute source of
truth, so as long as you make your code look like the code surrounding
it, you should be fine.
- All function, enumeration, structure, and header names are
`CamelCase`. This is preferred to `snake_case` because it is more
compact.
- All variable names are `lowerCamelCase`. This is preferred to
`snake_case` because it is more compact. One exception to this rule is
if a variable name, such as a member of a struct, directly represents
a JSON key in an object specified by the Matrix specification, which
may be in `snake_case`.
- Enumerations and structures are always `typedef`-ed to their same
name. The `typedef` should occur in the public API header, and the
actual declaration should live in the implementation file, unless
the enumeration or structure is intended to be made fully public.
- A feature of the code base lives in a single C source file that has a
matching header. The header file should only export public symbols;
everything else in the C source should be static.
- Except where absolutely necessary, global variables are forbidden
to prevent problems with threads and whatnot. Every variable a
function needs should be passed to it either through a structure, or
as a separate argument.
- Anywhere that C allows curly braces to be optional, there still must
be curly braces. This makes it easier to read the code by making it
less ambiguous, and it makes it easier to add on to the code later.
As far as actually formatting the code goes, such as where to put
brackets, and whether or not to use tabs or spaces, use `indent` to
take care of that. The repository contains a `.indent.pro` that should
automatically be loaded by `indent` to set the correct rules. If you
don't have a working `indent`, then just indicate in your pull
request that I should run my `indent` on the code.
### Documentation
This project places a strong emphasis on documentation. Well-documented
code is fundamental to a successful project, so when you are writing
code, please also make sure that it is documented appropriately.
- If you are adding a header, make sure you add the necessary comments
detailing the header and the functions in it.
- If you are adding a function, make sure you add the necessary
comments to the appropriate header.
If your pull request does not also include proper documentation, it
will likely be rejected.
### Be Recognized!
If your pull request gets approved, you should be recognized for your
contributions to the project!
To have your work recognized, add your information to the `CONTRIBUTORS.txt`
file in the root of the Telodendria repository if it isn't there already.
You should do this as a part of your pull request so that when it is merged,
your information will be automatically added to the repository.
The `CONTRIBUTORS.txt` file loosely follows the Linux kernel's
[CREDITS](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/CREDITS)
file format. It is designed to be human-readable, but also parsable by
scripts.
The following fields are available:
```
(N) Name
(E) Email
(M) Matrix ID
(W) Website
(D) Description of contribution
(L) Physical location
```
Here are the rules:
* All fields are optional. If you don't want to include a field, that's
okay, simply omit it.
* All fields identify you however you wish. The goal is to recognize you for
your contribution, but if you wish to remain anonymous, you don't have to
use your real information.
* All fields can be specified multiple times. For example, if you have
multiple email addresses, websites, or Matrix IDs and you want to include
all of them, you absolutely may. Likewise, if you have made multiple
contributions, you can add multiple description entries.
* You can make up your own fields if you want. Just add their description
above.
* Leave exactly one blank like between entries in this file.

32
docs/README.md Normal file
View file

@ -0,0 +1,32 @@
# Telodendria Documentation
Here you will find all of the documentation for Telodendria. If you
find that some documentation is missing or incorrect, please open an
issue, and, even better, a pull request to fix the issue.
You are also welcome to join the
[`#telodendria-general:bancino.net`](https://matrix.to/#/#telodendria-general:bancino.net)
matrix room, where you can discuss Telodnedria with others and ask
questions.
## User Documentation
- [System Requirements](user/requirements.md)
- [Install](user/install.md)
- [Usage & Running](user/usage.md)
- [Initial Set Up](user/setup.md)
- [Configuration Options](user/config.md)
- [Administrator API](user/admin/README.md)
## Developer Documentation
- [Repository Structure](dev/repo.md)
- [Contributing Guidelines](CONTRIBUTING.md)
- [Porting Guidelines](dev/ports.md)
## Miscellaneous
- [Matrix Specification](https://spec.matrix.org) ([Mirror](https://telodendria.io/spec.matrix.org))
- [Change Log](CHANGELOG.md)
- [Project Road Map](ROADMAP.md)

54
docs/ROADMAP.md Normal file
View file

@ -0,0 +1,54 @@
# Telodendria Matrix Specification Roadmap
This document provides a high-level overview of Telodendria's roadmap as it pertains to implementing the Matrix specification. Essentially, the Matrix specification is divided up into manageable portions amongst Telodendria releases, so that each release up until the first stable release implements a small portion of it.
**Note:** The first stable release of Telodendria will implement Matrix v1.7, no newer version. The Matrix specification changes too frequently, so I had to just pick a version in order to make this project manageable. Once v1.7 is complete, then we can move on to later specs.
This document will be updated to include more implementation details as they come up. It contains the big picture for far-out releases, and more relevant implementation details for near releases.
## Milestone v0.4.0
- [ ] Client-Server API
- [ ] **7:** Events
- [x] Compute size of JSON object in `CanonicalJson`
- [x] Rename `Sha2.h` to just `Sha.h`; add `Sha1()` function
- [x] Make `Sha256()` just return raw bytes; add function to convert to hex string.
- [ ] **8:** Rooms
- [ ] **9:** User Data
- [x] Profiles
- [ ] Directory
## Milestone v0.5.0
- [ ] Client-Server API
- [ ] Modules
- [ ] Content Repository
## Milestone v0.6.0
- [ ] Client-Server API
- [ ] Modules
- [ ] Instant Messaging
- [ ] Voice over IP
- [ ] Receipts
- [ ] Fully Read Markers
- [ ] Send-To-Device Messaging
- [ ] Security (Rate Limiting)
## Milestone v0.7.0
- [ ] Server-Server API
## Milestone v0.8.0
- [ ] Application Service API
- [ ] YAML parser?
## Milestone v0.9.0
- [ ] Identity Service API
## Milestone v1.7.0 (Stable Release!)
- [ ] Push Gateway API
- [ ] Room Versions

94
docs/dev/hosting.md Normal file
View file

@ -0,0 +1,94 @@
# Hosting Telodendria
These are just my own personal notes for hosting Telodendria's code infrastructure. This document is not intended to be used by normal Telodendria users or developers. It may be useful if you are *forking* Telodendria, but I sincerely hope you'll contribute to the upstream project instead. I'm writing this document solely for my own reference, but I am placing it into Telodendria's code repository in the name of transparency.
## Runners
The general sequence of steps required for setting up a CI runner is as follows:
1. Install the runner OS with all the defaults. I typically install my runners in virtual machines with 1 vcpu and 512mb RAM. Only Debian complained about this configuration, but since I didn't install a desktop environment, it worked out fine.
2. Install the packages required to build and execute the runner. These are:
- Git for checking out the source code.
- NodeJS for running `actions/checkout`, I think. Not really sure, all I know is that the runner will fail all jobs without NodeJS.
- Go for compiling the runner itself.
Run these commands to install the packages:
- **OpenBSD:** `pkg_add git go node`
- **FreeBSD:** `pkg install git go node`
- **NetBSD:** `pkgin install git go nodejs openssl mozilla-rootcerts-openssl`
(Note that the `go` executable is `go121` or whatever version was installed. and that NetBSD has no root certificates installed by default)
- **Debian:** `apt install git golang nodejs`
- **Alpine:** `apk add git go nodejs`
3. Install any development packages required to build Telodendria. For the BSDs, all development tools are built in so no additional packages are necessary. For the Linux distributions I've messed with, install these additional packages:
- **Debian:** `apt install make gcc libssl-dev`
- **Alpine:** `apk add make gcc musl-dev openssl-dev`
4. Clone `https://git.telodendria.io/Telodendria/act_runner.git`.
5. Run `go build` in the `act_runner` directory. On NetBSD, you may have to `umount /tmp` first because `/tmp` is by default very small. Otherwise, make `/tmp` larger during installation. 2GB should be plenty.
6. Run `./act_runner register` to register the runner. When prompted for the tags, follow following convention:
- **Linux Distros:** `linux`, `<distro>-v<version>`, `<arch>`
- **BSD Derivatives:** `bsd`, `<osname>-v<version>`, `<arch>`
- **Windows:** `windows`, `windows-v<version>`, `<arch>`
- **MacOS:** `macos`, `macos-v<version>`, `<arch>`
- **Others:** `other`, `<osname>-v<version>`, `<arch>`
Where `<arch>` is one of `x86` or `x64` for now. ARM runners will be a future project.
7. Run `./act_runner daemon`.
### Startup Scripts
We will obviously want `act_runner` to execute on bootup. Here are the start scripts I used:
#### Alpine
In `/etc/init.d/act_runner`:
```shell
#!/sbin/openrc-run
directory="/home/runner/act_runner"
command="/home/runner/act_runner/act_runner"
command_args="daemon"
command_user="runner:runner"
command_background="true"
pidfile="/run/act_runner.pid"
```
Don't forget to `chmod +x /etc/init.d/act_runner`.
Then just `rc-update add act_runner` and `rc-service act_runner start`.
#### Debian
In `/etc/systemd/system/act_runner.service`:
```
[Unit]
Description=Gitea Actions runner
[Service]
ExecStart=/home/runner/act_runner/act_runner daemon
ExecReload=/bin/kill -s HUP $MAINPID
WorkingDirectory=/home/runner/act_runner
TimeoutSec=0
RestartSec=10
Restart=always
User=runner
[Install]
WantedBy=multi-user.target
```
Then just `systemctl enable act_runner` and `systemctl start act_runner`.
#### Other
Eventually I got sick of writing init scripts for all the various operating systems.
Just put this in `runner`'s `crontab`:
```
@reboot cd /home/runner/act_runner && ./act_runner daemon
```
That seems to do the job good enough, and it's cross platform.

92
docs/dev/ports.md Normal file
View file

@ -0,0 +1,92 @@
## Ports
Telodendria is distributed primarily as source code, and the project
itself does not offer a convenient install process such as in the form
of a shell script. This is intentional; the Telodendria project is
primarily concerned with developing Telodendria itself, not packaging
it for the hundreds of different operating systems and linux
distributions that exist. It is my firm belief that distributing an
open source project is not the job of the open source developer; that
is the reason software distributions exist: to collect and
*distribute* software.
It would be impossible to single-handedly package Telodendria for
every platform, because each platform has very different expectations
and conventions for software. Even different Linux distributions have
different conventions for where manual pages, binaries, and
configuration files go.
That being said, this document aims to assist those who want to
package Telodendria for their operating system or software
distribution.
---
Before attempting to package Telodendria, make sure that you can build
it and that it builds cleanly on your target platform. See
[Install &rightarrow; From Source](../user/install.md#from-source)
for general build instructions.
To package Telodendria, you should collect the following files, and
figure out where they should be installed on your system:
- The `telodendria` server binary itself.
- An init script. People that wish to install Telodendria on their
system using your package are going to expect it to be integrated
enough that Telodendria can easily be started at boot and otherwise
managed by the system's daemon tools, be it `systemd` or another
init system. Consult your system's documentation for writing an init
script. **Note:** Telodendria *does not* fork itself to the background;
the init script should do that.
- You may also wish to ship the `docs/` directory
so that the user can read the documentation offline, and ensure that
they are reading the correct documentation for the installed version.
You may wish to optionally create a dedicated user under which
Telodendria should run. Telodendria can be directly started as that
user, or start as root and be configured to automatically drop to that
user. Additionally, it might be helpful to provide a default
configuration, which can be placed in the samples directory on your
platform, or in a default location that Telodendria will load from.
A good default directory that you may wish to provide for configuration,
data, and logs could perhaps be `/var/telodendria` or `/var/db/telodendria` on Unix-like systems.
Once you have collected the necessary files and directories that need
to be installed, make sure your package performs the following tasks
on install:
- If necessary and depending on the configuration used, create a new
system user for the Telodnedria daemon to run as.
- If conventional for your system, enable the Telodendria init script
so that Telodendria is started on system boot.
- Instruct the user to carefully read the [Setup](../user/setup.md)
(`docs/user/setup.md`) instructions and the
[Configuration](../user/config.md) (`docs/user/config.md`) instructions
before starting Telodendria.
The goal of a package should be to get everything as ready-to-run as
possible. The user should be able to start Telodendria right away and
begin configuring it.
Remember to publicly document the setup of Telodendria on your platform
if there are additional steps required that are not mentioned in the
official Telodendria documentation. This ensures that users can get
up and running quickly and easily. If you're packaging Telodendria
for a container system such as Docker, you can omit the things that
containers typically do not have, such as the init scripts and
documentation.
Also remember that your port should feel like it belongs on your target
system. Follow all of your system's conventions when placing files
on the filesystem, so your users know what to expect. The goal is not
necessarily to have a unified experience across all operating systems,
rather, you should cater to the opinions of your operating system.
Telodendria is architected in such a way that it does not impose the
developer's opinions of where things should go, and since the
configuration lives in the database, it is fairly self contained.
If there are any changes necessary to the upstream code or build
system that would make your job in porting Telodendria easier, do not
hesitate to get involved by opening an issue and/or submitting a pull
request.

109
docs/dev/rationale.md Normal file
View file

@ -0,0 +1,109 @@
# Rationale
This document seeks to answer the question of "why Telodendria?" from
a technical perspective by comparing it to existing Matrix homservers.
Telodendria is written entirely from scratch in ANSI C. It is designed
to be lightweight, simple, and functional. Telodendria differentiates
itself from other homeserver implementations because it:
- Is written C, a stable, low-level programming language with a long
history, low build and runtime overhead, and wide compatibility.
- Is written with minimalism as a primary design goal. Whenever possible
and practical, no third-party libraries are pulled into the code.
Everything Telodnedria needs is custom written. As a result, Telodendria
depends only on a standard C compiler and a POSIX C library to be
built, both of which should come with any good Unix-style operating
system already, which means you shouldn't have to install anything
additional to use Telodendria.
- Uses a flat-file directory structure to store data instead of a
real database. This has a number of advantages:
- It make setup and mainenance much easier.
- It allows Telodendria to run on systems with fewer resources.
- Is packaged as a single small, statically-linked and highly-optimized
binary that can be run just about anywhere. It is designed to be
extremely easy to set up and consume as few resources as possible.
- Is permissively licensed. Telodendria is licensed under a modified
MIT license, which imposes very few restrictions on what you can do
with it.
## What about [Conduit](https://conduit.rs)?
At this point, you may be wondering why one would prefer Telodendria
over Conduit, a Matrix homeserver that could also say pretty much
everything this document has said so far. After all, Conduit is older
and thus better established, and written in Rust, a Memory Safe&trade;
programming language.
In this section, we will discuss some additional advantages of
Telodendria that Conduit lacks.
### Small Dependency Chain
Conduit's dependency chain is quite large. What this means is that
Conduit depends on a lot of code that it does not control, making it
vulnerable to supply chain attacks. A problem with Rust Crates
is that they are developer-published, so they don't go through any sort
of auditing process like a Debian package would, for example.
If any one of the dependencies is
hijacked or otherwise compromised, then Conduit itself is compromised
and it is likely that this would go unnoticed for quite a while. While
one could argue that this is extremely unlikely to happen, sometimes you
just don't want to take that risk, especially not if you're deploying a
Matrix homeserver, likely for the purpose of secure, private chat.
Telodendria doesn't pull in any packages from developer repositories, so
the risk of supply chain attacks is much lower. It
only uses its own code and code provided by the operating system it is running
on, which has been vetted by a large number of developers and can be trusted
due to the sheer scope of an operating system. A supply chain attack against
Telodendria would be a supply chain attack against the entire operating system;
at that point, end users have much bigger problems.
Minimal dependencies doesn't only mitigate supply chain attacks. It also makes
maintenance much easier. Telodendria can spend more time writing code than
Conduit because Conduit developers have to ensure dependencies stay up to date and
when they inevitably break things, Conduit must pause development to fix those.
Telodendria doesn't suffer from this problem: because most of the code is developed
along side of Telodendria, it can remain as stable or become as volatile as the
developers choose. Additionally, because Telodendria is so low-level, the code on
which it depends is extremely unlikely to be changed in any significant way,
since so many other programs depend on that code.
### Standardized
Conduit is written in Rust, which has no formal standard. This makes it less than
ideal for long-lived software projects, because it changes frequently and often
breaks existing code. Telodendria is written in C, a stable, mature, and standardized
language that will always compile the same code the same way, making it more
portable and sustainable for the future because we don't ever have to worry about
upgrading our toolchain&mdash;using standard tools built into most operating systems
will suffice.
Because the language in which Telodendria is written never changes, Telodendria can
continually optimize and improve the code, instead of having to fix breaking changes.
This ensures that Telodendria's code will last. Rust code becomes obsolete with in a
few years at best&mdash;programs written in Rust last year probably won't compile or run
properly on the latest Rust toolchain. Telodendria, on the other hand, is written in C89,
which compiled and ran the same way in 1989 as it does today and will continue to for the
foreseeable future.
### Fast Compile Times
Rust is well-known for taking an extremely long time to compile moderately-sized
programs. Since a Matrix homeserver is such a large project, the compile times would
be prohibitively large for rapid development. By writing Telodendria in C, we can take
advantage of decades worth of compiler optimizations and speed improvements, resulting
in extremely fast builds.
### Portable
One does not typically think of C as more portable than something like Rust, but
Telodendria is written in such a way that it is. Rust relies on LLVM, which doesn't
support some strange or exotic architectures in the same way that a specialized C
compiler for those architectures will. This allows users to run Telodendria on the
hardware of their choice, even if that hardware is so strange that the modern world
has totally left it behind.
Telodendria doesn't just aim at being lightweight and portable, it aims to empower
people to use common hardware that they already have, even if it is typically thought
of as underpowered.

17
docs/dev/repo.md Normal file
View file

@ -0,0 +1,17 @@
# Repository Structure
This document describes the filesystem layout of the Telodendria source
code repository.
- `Telodendria/`
- `Cytoplasm/`: The source code for Cytoplasm, Telodendria's
general-purpose support library that provides core functionality.
- `contrib/`: Supplemental files, such as example configurations.
- `docs/`: All user and developer documentation as Markdown.
- `site/`: The official website source code as HTML.
- `src/': The C source code and headers for Telodendria.
- `Routes/`: Where the Matrix API endpoints are implemented.
- `Static/`: Endpoints that just generate static HTML pages.
- `include/`: Header files.
- `tools/`: Development environment and tools.

37
docs/user/admin/README.md Normal file
View file

@ -0,0 +1,37 @@
# Administrator API
Telodendria provides an administrator API as an extension to the
Matrix specification that allows for administrator control over the
homeserver. This includes profiling and examining the state of
running instances, as well as managing users and media.
Like Synapse, Telodendria supports designating specific local users as
administrators. However, unlike Synapse, Telodendria uses a more
fine-grained privilege model that allows a server administrator to
delegate specific administration tasks to other users while not
compromising and granting them full administrative access to the server.
To authenticate with the administrator API, simply use your login
access token just like you would authenticate any other Matrix client
request.
- [Privileges](privileges.md)
- [Configuration](config.md)
- [Server Statistics](stats.md)
- [Process Control](proc.md)
- [Registration Tokens](tokens.md)
## API Conventions
Unless otherwise indicated, HTTP response codes that are not `200 Ok`
will be accompanied by a standard Matrix API error. Consult the Matrix
specification for the format of these errors. The following error
conditions are assumed to be possible for all API endpoints listed
in the Administrator API documentation:
| Response Code | Description |
|---------------|-------------|
| 400 | The user is not authenticated, did not provide a valid JSON object, or provided a JSON object with invalid or missing parameters.|
| 403 | The user does not have the privileges necessary to carry out the requested action.|
| 500 | A fatal server error occurred. Check the logs for more information.|

62
docs/user/admin/config.md Normal file
View file

@ -0,0 +1,62 @@
# Administrator API: Configuration
As mentioned in [Setup](../setup.md), Telodendria's configuration is
intended to be managed via the configuration API. Consult the
[Configuration](../config.md) document for a complete list of supported
configuration options. This document simply describes the API used to
update the configuration described in that document.
## API Endpoints
### **GET** `/_telodendria/admin/v1/config`
Retrieve the current configuration.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The current configuration was successfully retrieved.|
### **POST** `/_telodendria/admin/v1/config`
Installs a new configuration. This endpoint validates the request body,
ensuring it is a proper configuration, then it replaces the existing
configuration with the new one.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The new configuration was successfully installed.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `restart_required` | `Boolean` | Whether or not the process needs to be restarted to finish applying the configuration. If this is `true`, then the restart endpoint should be used at a convenient time to apply the configuration.
### **PUT** `/_telodendria/admin/v1/config`
Update the currently installed configuration instead of completely replacing it. This endpoint
validates the request body, merges it on top of the current configuration, validates the resulting
configuration, then updates it in the database. This is useful when only one or two properties
in the configuration needs to be changed.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The new configuration was successfully installed.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `restart_required` | `Boolean` | Whether or not the process needs to be restarted to finish applying the configuration. If this is `true`, then the restart endpoint should be used at a convenient time to apply the configuration.

View file

@ -0,0 +1,141 @@
# Administrator API: Privileges
This document describes the privilege model and the API endpoints that
allow administrators to modify privileges for users.
## List Of Privileges
A local user can have any of the following privileges. Unless otherwise
indicated, these privileges only grant access to certain parts of the
administrator API; the regular Matrix API is unaffected.
- **DEACTIVATE:** Allows a user to deactivate any other local users.
- **ISSUE_TOKENS:** Allows a user to create, modify, and delete
registration tokens.
- **CONFIG:** Allows a user to modify the Telodendria server daemon's
configuration.
- **GRANT_PRIVILEGES:** Allows a user to modify his or her own
privileges or the privileges of other local users.
- **ALIAS:** Allows a user to modify and see room aliases created by
other users. By default, users can only manage their own room aliases,
but an administrator may wish to take over an alias or remove an
offensive alias.
- **PROC_CONTROL:** Allows a user to get statistics on the running
process, as well as shutdown and resetart the Telodendria daemon
itself. Typically this will pair well with **CONFIG**, because there
are certain configuration options that require the process to be
restarted to take full effect.
There is also a special "pseudo-privilege":
- **ALL:** Grants a user all of the aforementioned privileges, as well
as privileges that do not yet exist. That is, if an update to
Telodendria adds more privileges, users with this privilege will
automatically gain those new privileges in addition to having all the
existing privileges. This privilege should only be used with
fully-trusted users. It is typical for a server administrator to not
fully trust anyone else, and be the only one that holds an account with
this privilege level.
## API Endpoints
The following API endpoints are implemented for managing privileges.
### **GET** `/_telodendria/admin/v1/privileges/[localpart]`
Retrieve the permissions for a user. If the localpart is omitted, then
retrieve the privileges for the user that owns the access token being
used. Note that the owner of the access token must have the
**GRANT_PRIVILEGES** privilege to use this endpoint.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The privileges were successfully retrieved.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|
### **POST** `/_telodendria/admin/v1/privileges/[localpart]`
Update the privileges of a local user by replacing the privileges array
with the one specified in the request. Like the **GET** version of this
endpoint, the localpart can be omitted to operate on the user that
owns the access token.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The privileges were successfully replaced.|
#### Request Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|
### **PUT** `/_telodendria/admin/v1/privileges/[localpart]`
Update the privileges of a local user by adding the privileges
specified in the request to the users existing privileges.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The privileges were successfully added.|
#### Request Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|
### **DELETE** `/_telodendria/admin/v1/privileges/[localpart]`
Update the privileges of a local user by removing the privileges
specified in the request from the user's existing privileges.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The privileges were successfully removed.|
#### Request Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `privileges` | `Array` | An array of privileges, as described above. The privileges are encoded as JSON strings.|

49
docs/user/admin/proc.md Normal file
View file

@ -0,0 +1,49 @@
# Administrator API: Process Control
This document describes the administrator APIs that allow a server
administrator to manage the Telodendria process itself.
## API Endpoints
### **POST** `/_telodendria/admin/v1/restart`
Restart the Telodendria daemon cleanly. This endpoint will respond
immediately after signaling to the daemon that it should be restarted
as soon as possible. Note that the restart wmay not happen
instantaneously, as Telodendria will finish processing all current
requests before restarting. Also note that this is not a true restart;
the process does not exit and restart, rather, Telodendria simply tears
down all its state and then jumps back to the beginning of its code and
starts over.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The restart request was successfully sent.|
On success, this endpoint simply returns an empty JSON object.
### **POST** `/_telodendria/admin/v1/shutdown`
Shut down the Telodendria process cleanly. This endpoint will respond
immediately after signalling to the daemon that it should be shut
down as soon as possible. Note that the shutdown may not happen
instantaneously, as Telodendria will finish processing all current
requests before shutting down. Also note that once shut down, Telodendria
may be automatically restarted by the system's service manager.
Otherwise, it will have to be manually restarted. This is a true
shutdown; the Telodendria process exits as soon as possible.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The shutdown request was successfully sent.|
On success, this endpoint simply returns an empty JSON object.

26
docs/user/admin/stats.md Normal file
View file

@ -0,0 +1,26 @@
# Administrator API: Server Statistics
The administrator API allows users with the proper privileges to get
information about how the server process is performing.
## API Endpoints
### **GET** `/_telodendria/admin/v1/stats`
Retrieve basic statistics about the currently running Telodendria
process.
| Requires Token | Rate Limited |
|----------------|--------------|
| Yes | Yes |
| Response Code | Description |
|---------------|-------------|
| 200 | The server statistics were successfully retrieved.|
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `memory_allocated` | `Integer` | The total amount of memory allocated, measured in bytes.|
| `version` | `String` | The current version of Telodendria.|

106
docs/user/admin/tokens.md Normal file
View file

@ -0,0 +1,106 @@
# Administrator API: Registration Tokens
Telodendria implements registration tokens as specified by the Matrix
specification. These tokens can be used for registration using the
`m.login.registration_token` login type. This API provides a Telodendria
administrator with a mechanism for generating and managing these tokens,
which allows controlled registration on the homeserver.
It is generally safer than completely open registration to use
registration tokens that either expire after a short period of time, or
have a limited number of uses.
## Registration Token
A registration token is represented by the following `RegToken` JSON
object:
| Field | Type | Description |
|-------|------|-------------|
| `name` | `String` | The token identifier; what is used when registering. |
| `created_by` | `String` | The localpart of the user that created this token. |
| `created_on` | `Integer` | A timestamp of when the token was created. |
| `expires_on` | `Integer` | An expiration stamp, or 0 if the token never expires. |
| `used` | `Integer` | The number of times the token has been used. |
| `uses` | `Integer` | The total number of allowed uses, or -1 for unlimited. |
| `grants` | `[String]` | An array of privileges to grant users that register with this token as described in [Privileges](privileges.md). |
All endpoints in this API will operate on some variation of this
structure. The remaining number of uses can be computed by performing
the subtraction: `uses - used`. `used` should never be greater than
`uses` or less than `0`.
Example:
```json
{
"name": "q34jgapo8uq34hg",
"created_by": "admin",
"created_on": 1699467640000,
"expires_on": 0,
"used": 3,
"uses": 5
}
```
## API Endpoints
### **GET** `/_telodendria/admin/v1/tokens`
Get a list of all registration tokens and information about them.
#### 200 Response Format
| Field | Type | Description |
|-------|------|-------------|
| `tokens` | `[RegToken]` | An array of registration tokens. |
### **GET** `/_telodendria/admin/v1/tokens/[name]`
Get information about the specified registration token.
#### Request Parameters
| Field | Type | Description |
|-------|------|-------------|
| `name` | `String` | The name of the token, as it would be used to register a user. |
#### 200 Response Format
This endpoint returns a `RegToken` object that represents the server's
record of the registration token.
### **POST** `/_telodendria/admin/v1/tokens`
Create a new registration token.
#### Request Format
This endpoint accepts a `RegToken` object, as described above. If no
`name` is provided, one will be randomly generated. Note that the fields
`created_by`, `created_on`, and `used` are ignored and set by the server
when this request is made. All other fields may be set by the request
body.
#### 200 Response Format
If the creation of the registration token was successful, a `RegToken`
that represents the server's record of it is returned.
### **DELETE** `/_telodendria/admin/v1/tokens/[name]`
Delete the specified registration token. It will no longer be usable for
the registration of users. Any users that have completed the
`m.login.registration_token` step but have not yet created their account
should still be able to do so until their user-interactive auth session
expires.
#### Request Parameters
| Field | Type | Description |
|-------|------|-------------|
| `name` | `String` | The name of the token, as it would be used to register a user. |
#### 200 Response Format
On success, this endpoint returns an empty JSON object.

248
docs/user/config.md Normal file
View file

@ -0,0 +1,248 @@
# Configuration
Telodendria is designed to be configurable. It is configured using
JSON, which is intended to be submitted to the [Administrator
API](admin/README.md). This document details Telodendria's configuration
JSON format, which is used in both the administrator API and on-disk
in the database. The configuration file on the disk in the databsae
is `config.json`, though that file should not be edited by hand.
Use the API described in
[Administrator API &rightarrow; Configuration](admin/config.md).
## JSON Format
Telodendria's configuration is just a JSON object in the standard
key-value form:
```json
{
"serverName": "telodendria.io",
"listen": [
{
"port": 8008
}
]
/* ... */
}
```
Some keys, called *directives* in this document, have values that are
objects themselves.
## Directives
Here are the top-level directives:
- **listen:** `Array`
An array of listener description objects. Telodendria supports
listening on multiple ports, and each port is configured
independently of the others. A listener object looks like this:
- **port:** `integer`
The port to listen on. Telodendria will bind to all interfaces,
so it is recommended to configure your firewall to only allow
access on the desired interfaces. Note that Telodendria offers all
APIs over each port, including the administrator APIs; there is no
way to control which APIs are made available over which ports. If
this is a concern, a reverse-proxy such as `relayd` can be placed
in front of Telodendria to block access to undesired APIs.
- **tls:** `Object`
Telodendria can be compiled with TLS support. If it is, then a
particular listener can be set to use TLS for connections. If
**tls** is not `null` or `false`, then it can be an object with
the following directives:
- **cert:** `String`
The full path&mdash;or path relative to the data
directory&mdash;of the certificate file to load. The certificate
file should be in the format expected by the platform's TLS
library.
- **key:** `String`
Same as **cert**, but this should be the private key that matches
the certificate being used.
- **threads:** `Integer`
How many worker threads to spin up to handle requests for this
listener. This should generally be less than the total CPU core
count, to prevent overloading the system. The most efficient number
of threads ultimately depends on the configuration of the machine
running Telodendria, so you may just have to play around with
different values here to see which gives the best performance.
Note that this can be set as low as 0; in that case, the listener
will never respond to requests. Each listener needs to have at
least one thread to be useful. Also note that Telodendria may spin
up additional threads for background work, so the actual total
thread count at any given time may exceed the sum of threads
specified in the configuration.
This directive is optional. The default value is `4` in the upstream
code, but your software distribution may have patched this to be
different.
- **maxConnections:** `Integer`
The maximum number of simultanious connections to allow to the
daemon. This option prevents the daemon from allocating large
amounts of memory in the event that it undergoes a denial of
service attack. It is optional, defaults to `32`, and typically
does not need to be adjusted.
- **serverName:** `String`
Configure the domain name of your homeserver. Note that Matrix
servers cannot be migrated to other domains, so once this is set,
it should never change unless you want unexpected things to happen
or you want to start over. **serverName** should be a DNS name that
can be publicly resolved. This directive is required.
- **pid:** `String`
Configure the file Telodendria writes its PID to.
- **baseUrl:** `String`
Set the server's base URL. **baseUrl** should be a valid URL,
complete with the protocol. It does not need to be the same as the
server name; in fact, it is common for a subdomain of the server name
to be the base URL for the Matrix homeserver.
This URL is the URL at which Matrix clients will connect to the
server, and is thus served as a part of the `.well-known`
manifest.
This directive is optional. If unspecified, it is automatically
deduced from the server name.
- **identityServer:** `String`
The identity server that clients should use to perform identity
lookups. **identityServer** folows the same rules as **baseUrl**.
It also is optional, and is set to be the same as the **baseUrl**
if left unspecified.
- **runAs:** `Object`
The effective Unix user and group to drop to after binding to the
socket and completing any setup that may potentially require
elevated privileges. This directive only takes effect if
Telodendria is started as the root user, and is used as a security
mechanism. If this option is set and Telodendria is started as a
non-privileged user, then a warning is printed to the log if that
user and group do not match what's specified here. This directive
is optional, but should be used as a sanity check even if not
running as `root`, just to make sure you have your permissions
working properly.
This directive takes an object with the following directives:
- **uid:** `String`
The Unix username to switch to. If **runAs** is specified, this
directive is required.
- **gid:** `String`
The Unix group to switch to. This directive is optional; if left
unspecified, then the value of **uid** is copied.
- **federation:** `Boolean`
Whether or not to enable federation with other Matrix homeservers.
Matrix by its very nature is a federated protocol, but if you just
want to rn your own internal chat server with no contact with the
outside, then you can use this option to disable federation. It is
highly recommended to set this to `true`, however, if you wish to
be able to communicate with users on other Matrix servers. This
directive is required.
- **registration:** `Boolean`
Whether or not to enable new user registration or not. For security
and anti-spam reasons, you can set this to `false`. If you do, you
can still allow only certain users to be registered using
registration tokens, which can be managed via the administrator API.
This directive is required.
In an ideal world, everyone would run their own Matrix homeserver,
so no public registration would ever be required. Unfortunately,
not everyone has the means to run their own homeserver, especially
because of the fact that IPv4 addresses are becoming increasingly
hard to come by. If you would like to provide a service to those
that are unable to run their homeserver, then set this to `true`,
thereby allowing anyone to create an account.
Telodendria *should* be capable of handling a large amount of users
without difficulty, but it is targetted at smaller deployments.
- **log:** `Object`
The logging configuration. Telodendria uses its own logging
facility, which can output logs to standard output, a file, or the
syslog. This directive is required, and it takes an object with the
following directives:
- **output:** `Enum`
The log output destination. This can either be `stdout`, `file`,
or `syslog`. If set to `file`, Telodendria will log to
`telodendria.log` inside the data directory.
- **level:** `Enum`
The level of messages to log. Each level shows all the levels above
it. The levels are as follows:
- `error`
- `warning`
- `notice`
- `message`
- `debug`
For example, setting the level to `error` will show only errors,
while setting the level to `warning` will show both warnings
*and* errors. The `debug` level shows all messages.
- **timestampFormat:** `Enum`
If you want to customize the timestamp format shown in the log,
or disable it altogether, you can do so via this option. Acceptable
values are `none`, `default`, or a formatter string as described
by your system's `strftime()` documentation. This option only
applies if **log** is `stdout` or `file`.
- **color:** `Boolean`
Whether or not to enable colored output on TTYs. Note that ANSI
color sequences will not be written to a log file, only a real
terminal, so this option only applies if the log is being written
to a standard output which is connected to a terminal.
- **maxCache:** `Integer`
The maximum size of the cache. Telodendria relies heavily on caching
for performance reasons. The cache grows as data is loaded from the
data directory. All cache is stored in memory. This option limits the
size of the memory cache. If you have a system with a lot of memory
to spare, you'll get better performance if this option is set higher.
Otherwise, this value should be lowered on systems that have a
minimal amount of memory available.
## Examples
A number of example configuration files are shipped with Telodendria's
source code. They can be found in the `contrib/` directory if you are
viewing the source code directly. Otherwise, if you installed
Telodendria from a package, it is possible that the example
configurations were placed in the default locations for such files on
your operating system.

56
docs/user/install.md Normal file
View file

@ -0,0 +1,56 @@
# Installation
There are multiple methods of installing Telodendria. Choose the one
best suited to your use case.
## Package Manager Or System Ports
This is the recommended way to install Telodendria. If your operating
system has an official package or port of Telodendria, you should
prefer to use that instead of the other methods documented here,
because your operating system or software distribution will have
already figured out how to best integrate Telodendria with your system.
Consult your operating system or software distribution's system
manual for instructions on how to install packages. Also consult the
official repository of your distribution to see if a package is
available. If a package exists but it is too out of date for your
tastes, please contact the package's maintainer to notify them, or
offer to update the package yourself using the
[porting instructions](../dev/ports.md).
If you are maintaining a port or package for an operating system or
software distribution, open a pull request to include your
platform-specific instructions as a subheader of this section.
Eventually, this section should contain basic instructions for the
operating systems that have packages or ports.
See [Ports](../dev/ports.md) for the project's distribution
philosophy.
## Container
At this time, Telodendria does not have any officially recommended
procedure for running in a container such as Docker or Vagrant. You
may find helpful files in the [`contrib/`](../../contrib) directory,
however.
If you are publishing container images, please open a pull request to
add your source files to `contrib/`, as well as to add documentation
under this section explaining how to get set started.
## Release Binary
At this time, Telodendria does not publish any official binaries that
can be downloaded. The tentative plan is to eventually provide binaries
with each release for a number of supported platforms. When that
happens, instructions will be provided here for dealing with the
binaries.
## From Source
If you would like to build Telodendria from source, you can download
the latest release code from the
[Releases](/Telodendria/telodendria/releases) page. After extracting
the tarball, read
[Contributing &rightarrow; Developing &rightarrow; Building &amp; Running](../CONTRIBUTING.md#building-amp-running)
for details on how to build Telodendria.

60
docs/user/setup.md Normal file
View file

@ -0,0 +1,60 @@
# Initial Set Up
While Telodendria strives to be extremely simple to deploy and run,
in most circumstances a few basic setup steps will be necessary.
Telodendria does not have a traditional configuration file like most
daemons. Instead, its configuration lives in its database; as such,
all configuration happens through the administrator API. This design
decision makes Telodendria extremely flexible, because it is possible
to re-configure Telodendria without having to manually edit files on
the filesystem, thus allowing administrators to secure their server
better.
Please follow the instructions followed here carefully in the order
they are presented for the best results.
This document assumes that you have installed Telodendria using any
of the instructions found in [Install](install.md). After installation,
follow these steps:
1. Start Telodendria. If you installed it via a package or container,
consult your operating system or container system's documentation. If
you are running Telodendria from a release binary or have built it from
source, execute the binary directly. If needed, consult the
[Usage](usage.md) page for details on how to run Telodendria.
1. Assuming that Telodendria started properly, it will spin up and
initialize its database directly with a simple&mdash;and, importantly,
safe&mdash;default configuration, as well as a randomly generated,
single-use registration token that grants a user all privileges
documented in the [Administrator API](admin/README.md) documentation.
Consult the log file for this administrator registration token. By
default, the log file is located in the data directory, and is named
`telodendria.log`.
1. Use the registration token to register for an account on the
server. This account will be the administrator account. You can do this
using the client of your choice, or using tools such as `curl` or
`http`, following the Matrix specification for registering accounts.
The administrator account behaves just like a normal local account
that an ordinary user would have registered on the server, except that
it also has all privileges granted to it, so it can make full use of
the Administrator API.
1. Using the access token granted for the administrator account via
the login process, configure Telodendria as descibed in
[Configuration](config.md). See the [Administrator API](admin/README.md)
documentation for the configuration endpoint details.
This is the recommended way to set up Telodendria. However, if you
wish to bypass the account creation step and want to configure
Telodendria by directly writing a configuration file instead of using
the administrator API, you can manually create the configuration file
in the database before starting Telodendria. Simply create `config.json`
following the description in [Configuration](config.md), then start
Telodendria.
While this alternative method may seem simpler and more convenient
to some administrators, it is only so in the short-term. Note that this
method is not supported, because it gives no access to the
administrator API whatsoever, unless you manually modify the database
further to give a user admin privileges, which is error-prone and
bypasses some of Telodendria's safety mechanisms.

64
docs/user/usage.md Normal file
View file

@ -0,0 +1,64 @@
# Usage
This document provides general documentation on how to use the
`telodendria` server binary, as well as details on how it behaves.
The details here will be useful for setting up init systems, running
Telodendria in a container, or manually executing the binary for
testing or debugging purposes.
## Command Line Options
Typically, Telodendria is controlled via the
[Administrator API](admin/README.md), but the Telodendria binary does include
a few command line options, which can be used in init scripts or for
debugging purposes.
The command line arguments are as follows:
- **`-d <dir>`** Specify the data directory to use. All persistent
storage that Telodendria requires is saved to and loaded from here.
- **`-V`** Only print the version information header and then quit
with a success exit code.
- **`-v`** Verbose mode. This overrides the configuration and sets the
log level to `debug`. It also enables additional logging of memory
operations, which can be useful for debugging.
Before proposing additional command line arguments, consider whether or
not the functionality requested can be provided via a (potentially new
and as of yet uncreated) administrator API endpoint.
## Environment
Telodendria does not read any environment variables. All configuration
should be done via the [Configuration API](config.md).
## Signals
Telodendria recognizes and responds to a number of signals:
- **`PIPE`:** This signal is ignored, because all I/O errors should
already be handled properly.
- **`USR1`:** Perform a soft restart by shutting down the HTTP servers
and resetting the program state. Note that the daemon process does
not exit.
- **`TERM`:** Perform a clean shutdown after all existing connections
are closed.
- **`INT`:** Same as `TERM`.
Any other signals are not explicitly handled, so they have the
default behavior as defind by the operating system.
## Exit Status
Telodendria exits with a non-0 exit code if the configuration file is
invalid, or one or more of required paths or files is inaccessible.
Telodendria will print an error to the log and then terminate
abnormally.
Telodendria exits with a code of 0 if the configuration file is valid,
all paths and files required are accessible, and the HTTP listener
starts as intended. If Telodendria is sent a signal that it catches
after it begins servicing requests, it will still exit normally after
it safely shuts down, because the bootstrap process completed
successfully, and by all accounts, it ran normally and exitted
normally.

View file

@ -1 +0,0 @@
mandoc.db

View file

@ -0,0 +1,18 @@
.Dd $Mdocdate: May 6 2023 $
.Dt HTTP-DEBUG-SERVER 1
.Os Telodendria Project
.Sh NAME
.Nm http-debug-server
.Nd A simple HTTP server that logs requests to the standard output.
.Sh DESCRIPTION
.Pp
.Nm
spins up an HTTP server, listening on port 8008, in the exact same
manner as Telodendria itself. Any request it receives is written to
the standard output, and an empty JSON object is returned to the
client.
.Pp
This command exists just to test the HTTP server API during
development. It probably serves no other practical purpose.
.Sh SEE ALSO
.Xr HttpServer 3

111
man/man1/json.1 Normal file
View file

@ -0,0 +1,111 @@
.Dd $Mdocdate: March 12 2023 $
.Dt JSON 1
.Os Telodendria Project
.Sh NAME
.Nm json
.Nd A simple command line utility for parsing and generating JSON.
.Sh SYNOPSIS
.Nm
.Op Fl s Ar query
.Op Fl e Ar str
.Sh DESCRIPTION
.Nm
is a simple command line utility for dealing with JSON. It is
somewhat inspired by
.Xr jq 1 ,
but is not compatible in any way with it.
.Nm
is designed to be much simpler than
.Xr jq 1 ,
and is built on Telodendria's own
.Xr Json 3
API. It primarily exists to ease development of Telodendria, and
to make development possible without having to install any external
tools.
.Pp
The options are as follows. Unless stated otherwise, these options
are mutually exclusive, and the last one specified takes precedence.
All positional parameters are ignored.
.Bl -tag -width Ds
.It Fl s Ar query
Use
.Va query
to query a field from a JSON object given on the standard input.
The query syntax very vaguely resembles C code, but it is much
more primitive. Multiple queries are separated by an arrow
(``->''). This makes it trivial to drill down into nested
objects and arrays.
.Pp
To select a value from an object, just specify the key. To select
an element from an array specify the key whose value is the array,
and then use the C square bracket syntax to select an element.
.Pp
A number of ``functions'' exist to make
.Nm
more versatile. Functions are called by prefacing the key with
a ``@'' symbol. Functions can appear anywhere in the query, provided
they make sense within the context of the JSON object being processed.
The available functions are as follows:
.Bl -tag -width Ds
.It keys
When applied to an object, outputs an array of keys.
.It length
When applied to an array, outputs the number of elements in the
array. When applied to a string, returns the number of bytes
needed to store the decoded version of the string.
.It decode
When applied to a string, outputs the decoded version of the
string.
.El
.Pp
When a key is prefaced with the ``^'' symbol, then instead of getting
the value at that key, it is removed from the object, and the new
object is passed along.
.It Fl e Ar str
Encode
.Va str
as a JSON string and print it to standard output. This is useful for
generating JSON with shell scripts.
.El
.Pp
If no options are specified, then the default behavior of
.Nm
is to read a JSON object given on the standard input and pretty-print
it to the standard output, or print an error to standard error if
the given input is invalid.
.Sh EXAMPLES
.Pp
Get the error string of an error returned by a Matrix API endpoint:
.Bd -literal -offset indent
json -s 'error->@decode'
.Ed
.Pp
Get the number of stages in the first flow listed in a list
of user-interactive authentication flows:
.Bd -literal -offset indent
json -s 'flows[0]->stages->@length'
.Ed
.Pp
Get the first stage of the first flow listed in a list
of user-interactive authentication flows:
.Bd -literal -offset indent
json -s 'flows[0]->stages[0]->@decode'
.Ed
.Pp
List the keys in a JSON object:
.Bd -literal -offset indent
json -s '@keys'
.Ed
.Pp
Get the number of keys in a JSON object:
.Bd -literal -offset indent
json -s '@keys->@length'
.Ed
.Sh EXIT STATUS
.Nm
exits with
.Va EXIT_SUCCESS
if all command line options were valid and the given JSON object
parses successfully. It exits with
.Va EXIT_FAILURE
in all other scenarios.

34
man/man1/tt.1 Normal file
View file

@ -0,0 +1,34 @@
.Dd $Mdocdate: April 29 2023 $
.Dt TT 1
.Os Telodendria Project
.Sh NAME
.Nm tt
.Nd Make authenticated Matrix requests.
.Sh SYNPOSIS
.Nm
.Op request-path
.Sh DESCRIPTION
.Nm
is an extremely simple wrapper over
.Xr http 1
and
.Xr json 1
that automatically registers a user and continues to log in as that
user. It obtains an access token that it uses to authenticate the
given request, and then logs out when the request has completed. It
also doesn't require the whole URL to be typed; only the path name
is needed.
.Sh ENVIRONMENT
.Bl -tag
.It Ev METH
The request method to use for the user-specified request.
.It Ev DATA
The data to pass to
.Xr http 1 .
This can either be a string, or a file. Consult the
.Xr http 1
page for details.
.El
.Sh SEE ALSO
.Xr http 1 ,
.Xr json 1

View file

@ -1,132 +0,0 @@
.Dd $Mdocdate: November 24 2022 $
.Dt ARRAY 3
.Os Telodendria Project
.Sh NAME
.Nm Array
.Nd A simple dynamic array data structure.
.Sh SYNOPSIS
.In Array.h
.Ft Array *
.Fn ArrayCreate "void"
.Ft void
.Fn ArrayFree "Array *"
.Ft int
.Fn ArrayTrim "Array *"
.Ft size_t
.Fn ArraySize "Array *"
.Ft void *
.Fn ArrayGet "Array *" "size_t"
.Ft int
.Fn ArrayInsert "Array *" "void *" "size_t"
.Ft int
.Fn ArrayAdd "Array *" "void *"
.Ft void *
.Fn ArrayDelete "Array *" "size_t"
.Ft void
.Fn ArraySort "Array *" "int (*) (void *, void *)"
.Ft Array *
.Fn ArrayFromVarArgs "size_t" "va_list"
.Ft Array *
.Fn ArrayDuplicate "Array *"
.Sh DESCRIPTION
These functions implement a simple array data structure that
is automatically resized as necessary when new values are added.
This implementation does not actually store the values of the
items in it; it only stores pointers to the data. As such, you will
still have to manually maintain all your data. The advantage of this
is that these functions don't have to copy data, and thus don't care
how big the data is. Furthermore, arbitrary data can be stored in the
array.
.Pp
This array implementation is optimized for storage space and appending.
Deletions are expensive in that all the items of the list above a deletion
are moved down to fill the hole where the deletion occurred. Insertions are
also expensive in that all the elements above the given index must be shifted
up to make room for the new element.
.Pp
Due to these design choices, this array implementation is best suited to
linear writing, and then linear or random reading.
.Pp
These functions operate on an array structure which is opaque to the
caller.
.Pp
.Fn ArrayCreate
and
.Fn ArrayFree
allocate and deallocate an array, respectively.
Note that
.Fn ArrayFree
does not free any of the values stored in the array; it is the caller's
job to manage the memory for each item. Typically, the caller would
iterate over all the items in the array and free them before freeing
the array.
.Fn ArrayTrim
reduces the amount of unused memory by calling
.Xr realloc 3
on the internal structure to perfectly fit the elements in the array. It
is intended to be used by functions that return relatively read-only arrays
that will be long-lived.
.Pp
.Fn ArrayInsert
and
.Fn ArrayDelete
are the main functions used to modify the array.
.Fn ArrayAdd
is a convenience method that simply appends a value to the end of the
array. It uses
.Fn ArrayInsert .
The array can also be sorted by using
.Fn ArraySort ,
which takes a pointer to a function that compares elements. The function
should take two
.Dv void
pointers as parameters, and return an integer. The return value indicates
to the algorithm how the elements relate to each other. A return value of
0 indicates the elements are identical. A return value greater than 0
indicates that the first item is "bigger" than the second item and should
thus appear after it in the array, and a value less than zero indicates
the opposite: the second element should appear after the first in the array.
.Pp
.Fn ArrayGet
is used to get the element at the specified index.
.Pp
.Fn ArrayFromVarArgs
is used to convert a variadic arguments list into an Array. In many
cases, the Array API is much easier to work with than
.Fn va_arg
and friends.
.Pp
.Fn ArrayDuplicate
duplicates an existing array. Note that Arrays only hold
pointers to data, not the data itself, so the duplicated array will
point to the same places in memory as the original array.
.Sh RETURN VALUES
.Fn ArrayCreate ,
.Fn ArrayFromVarArgs ,
and
.Fn ArrayDuplicate
return a pointer on the heap to a newly allocated array structure, or
.Dv NULL
if the allocation fails.
.Pp
.Fn ArrayGet
and
.Fn ArrayDelete
return pointers to values that were put into the array, or
.Dv NULL
if the provided array is
.Dv NULL
or the provided index was out of bounds.
.Fn ArrayDelete
returns the element at the specified index after removing it so that
it can be properly handled by the caller.
.Pp
.Fn ArrayTrim ,
.Fn ArrayInsert ,
and
.Fn ArrayAdd
return a boolean value indicating their status. They return a value of zero
on failure, and a non-zero value on success.
.Sh SEE ALSO
.Xr HashMap 3 ,
.Xr Queue 3

View file

@ -1,81 +0,0 @@
.Dd $Mdocdate: September 30 2022 $
.Dt BASE64 3
.Os Telodendria Project
.Sh NAME
.Nm Base64
.Nd A simple base64 encoder/decoder with "unpadded base64" support.
.Sh SYNOPSIS
.In Base64.h
.Ft size_t
.Fn Base64EncodedSize "size_t"
.Ft size_t
.Fn Base64DecodedSize "const char *" "size_t"
.Ft char *
.Fn Base64Encode "const char *" "size_t"
.Ft char *
.Fn Base64Decode "const char *" "size_t"
.Ft void
.Fn Base64Unpad "char *" "size_t"
.Ft int
.Fn Base64Pad "char **" "size_t"
.Sh DESCRIPTION
This is an efficient yet simple base64 encoding and decoding
library that supports regular base64, as well as the Matrix
specification's extension to base64, called "unpadded base64."
.Nm provides the ability to convert between the two, instead of
just implementing "unpadded base64."
.Pp
.Fn Base64EncodedSize
and
.Fn Base64DecodedSize
compute the amount of characters needed to store an encoded or
decoded message, respectively. Both functions take the size of
the message being encoded or decoded, but
.Fn Base64DecodedSize
also takes a pointer to an encoded string, because a few bytes of
the string need to be read in order to compute the size.
.Pp
.Fn Base64Encode
and
.Fn Base64Decode
do the actual work of encoding and decoding base64 data. They both
take a string and its length.
.Pp
.Fn Base64Unpad
and
.Fn Base64Pad
are used to implement Matrix unpadded base64.
.Fn Base64Unpad
takes a valid base64 string and strips off the trailing equal signs,
as per the specification.
.Fn Base64Pad
does the opposite; it takes an unpadded base64 input string, and pads
it with equal signs as necessary, so that it can be properly decoded
with
.Fn Base64Decode
if necessary. However, the Matrix specification envisons unpadded base64
as opaque; that is, once it's encoded, it never needs to be decoded.
In practice, a homeserver might need to decode an unpadded base64 string.
.Sh RETURN VALUES
.Fn Base64EncodedSize
and
.Fn Base64DecodedSize
simply return unsigned integers representing a number of bytes generated
from a simple computation.
.Pp
.Fn Base64Encode
and
.Fn Base64Decode
return pointers to new strings, allocated on the heap, or
.Dv NULL
if a heap allocation fails. These pointers must be
.Xr free 3 -ed
at some point when they are no longer needed.
.Pp
.Fn Base64Unpad
modifies the passed string in-place. It thus has no return value, because
it cannot fail. If the passed pointer is invalid, the behavior is undefined.
.Fn Base64Pad
returns a boolean value indicating whether the pad operation was successful.
In practice, this function will only fail if a bigger string is necessary, but
could not be automatically allocated on the heap.

View file

@ -1,69 +0,0 @@
.Dd $Mdocdate: November 30 2022 $
.Dt CANONICALJSON 3
.Os Telodendria Project
.Sh NAME
.Nm CanonicalJson
.Nd An extension of JSON that produces the Matrix spec's "canonical" JSON.
.Sh SYNOPSIS
.In CanonicalJson.h
.Ft int
.Fn CanonicalJsonEncode "HashMap *" "FILE *"
.Ft char *
.Fn CanonicalJsonEncodeToString "HashMap *"
.Sh DESCRIPTION
.Pp
.Nm
is an extension of
.Xr Json 3
that is specifically designed to produce the Matrix specification's
"canonical" JSON.
.Pp
Canonical JSON is defined as JSON that:
.Bl -bullet -offset indent
.It
Does not have any unecessary whitespace.
.It
Has all object keys lexicographically sorted.
.It
Does not contain any floating point numerical values.
.El
.Pp
The regular JSON encoder has no such rules, because normally they are
not needed. However, Canonical JSON is needed to consistently sign JSON
objects.
.Pp
.Fn CanonicalJsonEncode
encodes a JSON object following the rules of Canonical Json. See the
documentation for
.Fn JsonEncode ,
documented in
.Xr Json 3
for more details on how JSON encoding operates. This function exists
as an alternative to
.Fn JsonEncode ,
but should not be preferred to it in most circumstances. It is a lot
more costly, as it must lexicographically sort all keys and strip out
float values. If at all possible, use
.Fn JsonEncode
because it is much cheaper both in terms of memory and CPU time.
.Pp
.Fn CanonicalJsonEncodeToString
encodes a JSON object to a string.
.Xr Json 3
doesn't have any way to send JSON to a string, because there's
absolutely no reason to handle JSON strings in most cases. However,
the sole reason Canonical JSON exists is so that JSON objects can
be signed in a consistent way. Thus, you need a string to pass to
the signing function.
.Sh RETURN VALUES
.Pp
.Fn CanonicalJsonEncode
returns whether or not the JSON encoding operation was sucessful.
This function will fail only if NULL was given for any parameter.
Otherwise, if an invalid pointer is given, undefined behavior results.
.Pp
.Fn CanonicalJsonEncodeToString
returns a C string containing the canonical JSON representation of
the given object, or NULL if the encoding failed.
.Sh SEE ALSO
.Xr Json 3

View file

@ -1,96 +0,0 @@
.Dd $Mdocdate: December 24 2022 $
.Dt CRON 3
.Os Telodendria Project
.Sh NAME
.Nm Cron
.Nd Basic periodic job scheduler.
.Sh SYNOPSIS
.In Cron.h
.Ft Cron *
.Fn CronCreate "unsigned long"
.Ft void
.Fn CronOnce "Cron *" "void (*) (void *)" "void *"
.Ft void
.Fn CronEvery "Cron *" "unsigned long" "void (*) (void *)" "void *"
.Ft void
.Fn CronStart "Cron *"
.Ft void
.Fn CronStop "Cron *"
.Ft void
.Fn CronFree "Cron *"
.Sh DESCRIPTION
.Pp
.Nm
is an extremely basic job scheduler. So basic, in fact,
that it runs all jobs on a single thread, which means that it
is intended for short-lived jobs. In the future,
.Nm
might be extended to support a one-thread-per-job model, but
for now, jobs should consider that they are sharing their
thread, so they should not be long-running jobs.
.Pp
.Nm
works by "ticking" at an interval defined by the caller of
.Fn CronCreate .
At each tick, all the jobs are queried, and if they are due
to run again, their function is executed. As much as possible,
.Nm
tries to tick at constant intervals, however it is possible that
a job may overrun the tick duration. If this happens,
.Nm
ticks again immediately after all the jobs for the previous tick
have completed. This is in an effort to compensate for the lost
time, however it is important to note that when jobs overrun the
tick interval, the interval is pushed back. In this way,
.Nm
is best suited for scheduling jobs that should happen
"approximately" every so often; it is not a real-time scheduler
by any means.
.Pp
.Fn CronCreate
creates a new
.Nm
object that all the other functions use. Like most of the other
APIs in this project, it must be freed with
.Fn CronFree
when it is no longer needed.
.Pp
Jobs can be scheduled with
.Fn CronOnce
and
.Fn CronEvery .
.Fn CronOnce
schedules a one-off job to be executed only at the next tick, and
then discarded. This is useful for scheduling tasks that only have
to happen once, or very infrequently depending on conditions other
than the current time, but don't have to happen immediately. The
caller simply indicates that it wishes for the task to execute at
some time in the future. How far into the future this practically
ends up being is determined by how long it takes other jobs to
finish, and what the tick interval is.
.Pp
.Fn CronEvery
schedules a repetitive task to be executed at approximately the
given interval. As stated above, this is a fuzzy interval; depending
on the jobs being run and the tick interval, tasks may not happen
at exactly the scheduled time, but they will eventually happen.
.Pp
.Fn CronStart
and
.Fn CronStop
start and stop the ticking, respectively.
.Fn CronFree
discards all the job references and frees all memory associated
with the given instance of the
.Nm
instance.
.Sh RETURN VALUES
.Pp
.Fn CronCreate
returns a reference to a
.Nm ,
or NULL if it was unable to allocate memory for it.
.Pp
The other functions in this header don't return anything. They
are assumed to usually work, unless their input is obviously
wrong.

View file

@ -1,121 +0,0 @@
.Dd $Mdocdate: March 6 2023 $
.Dt DB 3
.Os Telodendria Project
.Sh NAME
.Nm Db
.Nd A minimal flat-file database with object locking and an efficient cache.
.Sh SYNOPSIS
.In Db.h
.Ft Db *
.Fn DbOpen "char *" "size_t"
.Ft void
.Fn DbClose "Db *"
.Ft DbRef *
.Fn DbCreate "Db *" "size_t" "..."
.Ft int
.Fn DbDelete "Db *" "size_t" "..."
.Ft DbRef *
.Fn DbLock "Db *" "size_t" "..."
.Ft int
.Fn DbUnlock "Db *" "DbRef *"
.Ft int
.Fn DbExists "Db *" "size_t" "..."
.Ft Array *
.Fn DbList "Db *" "size_t" "..."
.Ft void
.Fn DbListFree "Array *"
.Ft HashMap *
.Fn DbJson "DbRef *"
.Sh DESCRIPTION
.Pp
Telodendria operates on a flat-file database instead of a traditional relational
database. This greatly simplifies the persistent storage code, and creates a
relatively basic API, described by this page.
.Pp
.Fn DbOpen
and
.Fn DbClose
open and close a data directory.
.Fn DbOpen
takes the path to open, and a cache size in bytes. This API relies heavily on
caching, so the cache must be greater than the DB_MIN_CACHE preprocessor
constant.
.Pp
.Fn DbCreate
and
.Fn DbLock
load data objects from the database, with the notable difference being that
.Fn DbCreate
will fail if an object already exists, and
.Fn DbLock
will fail if an object does not exist. These are both variadic functions that
take a variable number of C strings, with the exact number being specified by
the second paramter. These C strings are used to generate a filesystem path from
which an object is loaded, unless it is already in the cache.
.Pp
Objects, when loaded, are locked both in memory and on disk, so that other threads
or processes cannot access them while they are locked. This is to ensure data
integrity.
.Pp
.Fn DbUnlock
unlocks an object and returns it back to the database, which syncs it to the
filesystem and caches it, if it isn't in the cache already.
.Pp
.Fn DbExists
checks the existence of the given database object in a more efficient
manner than attempting to lock it with
.Fn DbLock .
.Fn DbExists
does not lock the object, nor does it load it into memory if it exists. It
takes the same arguments as
.Fn DbLock
and
.Fn DbUnlock .
.Pp
.Fn DbJson
converts a database reference into JSON. At this time, the database actually
stores objects as JSON, so this just returns an internal pointer, but in the
future it may have to be generated by decompressing a binary blob, or something
of that nature.
.Pp
.Fn DbDelete
completely removes an object from the database. It purges it from both the
cache and the disk as soon as no more references to it are open.
.Pp
.Fn DbList
lists all of the objects at a given path. Unlike the other varargs
functions, it does not take a path to a specific object; it takes
a directory to be iterated. Note that the resulting list only contains
the objects in that directory, not subdirectories.
.Fn DbListFree
frees the list returned by this function.
.Sh RETURN VALUES
.Pp
.Fn DbOpen
returns a reference to a database pointer, or NULL if there was an error
allocating memory, or opening the given directory with the given cache size.
.Pp
.Fn DbCreate
and
.Fn DbLock
return a database reference, or NULL if there was an error obtaining a reference
to the specified object.
.Pp
.Fn DbUnlock
returns a boolean value indicating whether or not the reference was successfully
unlocked. If the unlock is successful, then a non-zero value is returned. If it
isn't, 0 is returned, and it is up to the caller to decide how to proceed.
.Pp
.Fn DbDelete
follows the same return value conventions as
.Fn DbUnlock ;
it reports the status of the deletion operation as a boolean value.
.Pp
.Fn DbList
returns an array of strings, or NULL if there was a memory or
filesystem error.
.Pp
.Fn DbJson
returns a JSON object. Consult
.Xr Json 3
for the API used to manipulate this object.

View file

@ -1,146 +0,0 @@
.Dd $Mdocdate: October 11 2022 $
.Dt HASHMAP 3
.Os Telodendria Project
.Sh NAME
.Nm HashMap
.Nd A simple hash map implementation.
.Sh SYNOPSIS
.In HashMap.h
.Ft HashMap *
.Fn HashMapCreate "void"
.Ft void
.Fn HashMapFree "HashMap *"
.Ft void
.Fn HashMapLoadSet "HashMap *" "float"
.Ft void
.Fn HashMapFunctionSet "HashMap *" "unsigned long (*) (const char *)"
.Ft void *
.Fn HashMapSet "HashMap *" "char *" "void *"
.Ft void *
.Fn HashMapGet "HashMap *" "char *"
.Ft void *
.Fn HashMapDelete "HashMap *" "char *"
.Ft int
.Fn HashMapIterate "HashMap *" "char **" "void **"
.Sh DESCRIPTION
This is the public interface for Telodendria's hash map implementation.
This hash map is designed to be simple, well documented, and generally
readable and understandable, yet also performant enough to be useful,
because it is used extensively in Telodendria.
.Pp
Fundamentally, this is an entirely generic map implementation. It can
be used for many general purposes, but it is designed to only implement
the features that Telodendria needs to function well. One example of a
Telodendria-specific feature is that keys are
.Dv NULL -terminated
strings, not any arbitrary data.
.Pp
These functions operate on an opaque
.Dv HashMap
structure, which the caller has no knowledge about.
.Pp
.Fn HashMapCreate
creates a new hash map that is ready to be used with the rest of the
hash map functions.
.Fn HashMapFree
frees this hash map, such that it becomes invalid and any future use
with the functions in this API results in undefined behavior. Note that
it does not free the keys or values stored in the hash map, since this
implementation has no way of knowing what is actually stored in it, and
where it is located. You should use
.Fn HashMapIterate
to free the values appropriately.
.Pp
.Fn HashMapMaxLoadSet
controls the maximum load of the hash map before it is expanded.
When the hash map reaches the given capacity, it is grown. You don't
want to only grow hash maps when they are full, because that makes
them perform very poorly. The maximum load value is a percentage of how
full the hash map is, and it should be between 0
and 1, where 0 means that no elements will cause the map to be expanded,
and 1 means that the hash map must be completely full before it is
expanded. The default maximum load on a new
.Dv HashMap
object is 0.75, which should be good enough for most purposes, but
if you need finer tuning, feel free to play with the max load with
this function. The changes take effect on the next insert.
.Pp
.Fn HashMapFunctionSet
allows the given hash map to use a custom hashing function. New hash
maps have a sane hashing function that should work okay for most use
cases, but if you have a better hash function, it can be specified with
this function. Do not change the hash function after keys have been
added; doing so results in undefined behavior. Only set the hash
function immediately after constructing a new hash map.
.Pp
.Fn HashMapSet
sets the given string key to the given value. Note neither the key nor the
value is copied into the hash map's own memory space; only pointers are
stored. It is the caller's job to ensure that the key and value memory
remains valid for the life of the HashMap, and are freed when they are no
longer needed.
.Fn HashMapGet
retrieves the value for the given key and .Fn HashMapDelete
removes a value from a given key.
.Pp
.Fn HashMapIterate
iterates over all the keys and values of a hash map. This function works
very similarly to
.Xr getopt 3 ,
where calls are repeatedly made in a
.Dv while
loop until there are no more items to go over. The difference is that this
function does not rely on globals; it takes pointer pointers, and stores all
necessary state inside the hash map structure itself. Note that this does not
make this function thread-safe; two threads cannot be iterating over any given
hash map at the same time, though they can be iterating over different hash
maps at the same time.
.Pp
This function can be tricky to use in some scenarios, as it continues where
it left off on each call, until there are no more elements to go through in
the hash map. If you are not iterating over the entire map in one go, and
happen to break the loop, then the next time you attempt to iterate the
hash map, you'll start somewhere in the middle. Thus, it's recommended to
always iterate over the entire hash map if you're going to use this
function. Also note that the behavior of this function is undefined if
insertions or deletions occur during the iteration. It may work fine; it may
not. That functionality has not been tested.
.Pp
.Fn HashMapIterate
takes a pointer to a string ponter, and a pointer to a value pointer. When
iterating over the keys and values of the hash map, it sets these pointers
to the current position in the map so that the caller can use them for his
own purposes.
.Sh RETURN VALUES
.Fn HashMapCreate
may return
.Dv NULL
if memory could not be allocated on the heap. Otherwise, it returns a
valid pointer to a
.Dv HashMap
structure which can be used with the other functions in this API.
.Pp
.Fn HashMapSet
returns the previous value at the passed key, or
.Dv NULL
if no such value exists. All keys must have values; you can't set a key
to
.Dv NULL .
To delete a key, use the
.Fn HashMapDelete
function.
.Pp
.Fn HashMapDelete
returns the value that was deleted from the hash map at the given key,
or
.Dv NULL
if no such value exists.
.Pp
.Fn HashMapIterate
returns 1 if there are still elements left in the current iteration of the
hash map, or 0 if no valid hash map was provided, or there are no more elements
in it for the current iteration. Note that as soon as this function returns 0
on a hash map, subsequent iterations will start from the beginning.
.Sh SEE ALSO
.Xr HashMap 3 ,
.Xr Queue 3

View file

@ -1,171 +0,0 @@
.Dd $Mdocdate: December 13 2022 $
.Dt HTTP 3
.Os Telodendria Project
.Sh NAME
.Nm Http
.Nd Encode and decode various parts of the HTTP protocol.
.Sh SYNOPSIS
.In Http.h
.Ft const char *
.Fn HttpStatusToString "const HttpStatus"
.Ft HttpRequestMethod
.Fn HttpRequestMethodFromString "const char *"
.Ft const char *
.Fn HttpRequestMethodToString "const HttpRequestMethod"
.Ft char *
.Fn HttpUrlEncode "char *"
.Ft char *
.Fn HttpUrlDecode "char *"
.Ft HashMap *
.Fn HttpParamDecode "char *"
.Ft char *
.Fn HttpParamEncode "HashMap *"
.Sh DESCRIPTION
.Pp
.Nm
is a collection of utility functions that are useful for dealing with
HTTP. HTTP is not a complex protocol, but this API makes it a lot easier
to work with.
.Pp
.Fn HttpStatusToString
takes an HttpStatus and converts it into a string description of the
status, which is to be used in an HTTP response. For example, calling
.Fn HttpStatusToString "HTTP_GATEWAY_TIMEOUT"
produces the string "Gateway Timeout".
.Pp
HttpStatus is an enumeration that corresponds to the actual integer
values of the valid HTTP response codes. For example, calling
.Fn HttpStatusToString "504"
produces the same output. HttpStatus is defined as follows:
.Bd -literal -offset indent
typedef enum HttpStatus
{
/* Informational responses */
HTTP_CONTINUE = 100,
HTTP_SWITCHING_PROTOCOLS = 101,
HTTP_EARLY_HINTS = 103,
/* Successful responses */
HTTP_OK = 200,
HTTP_CREATED = 201,
HTTP_ACCEPTED = 202,
HTTP_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_NO_CONTENT = 204,
HTTP_RESET_CONTENT = 205,
HTTP_PARTIAL_CONTENT = 206,
/* Redirection messages */
HTTP_MULTIPLE_CHOICES = 300,
HTTP_MOVED_PERMANENTLY = 301,
HTTP_FOUND = 302,
HTTP_SEE_OTHER = 303,
HTTP_NOT_MODIFIED = 304,
HTTP_TEMPORARY_REDIRECT = 307,
HTTP_PERMANENT_REDIRECT = 308,
/* Client error messages */
HTTP_BAD_REQUEST = 400,
HTTP_UNAUTHORIZED = 401,
HTTP_FORBIDDEN = 403,
HTTP_NOT_FOUND = 404,
HTTP_METHOD_NOT_ALLOWED = 405,
HTTP_NOT_ACCEPTABLE = 406,
HTTP_PROXY_AUTH_REQUIRED = 407,
HTTP_REQUEST_TIMEOUT = 408,
HTTP_CONFLICT = 409,
HTTP_GONE = 410,
HTTP_LENGTH_REQUIRED = 411,
HTTP_PRECONDITION_FAILED = 412,
HTTP_PAYLOAD_TOO_LARGE = 413,
HTTP_URI_TOO_LONG = 414,
HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_RANGE_NOT_SATISFIABLE = 416,
HTTP_EXPECTATION_FAILED = 417,
HTTP_TEAPOT = 418,
HTTP_UPGRADE_REQUIRED = 426,
HTTP_PRECONDITION_REQUIRED = 428,
HTTP_TOO_MANY_REQUESTS = 429,
HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
/* Server error responses */
HTTP_INTERNAL_SERVER_ERROR = 500,
HTTP_NOT_IMPLEMENTED = 501,
HTTP_BAD_GATEWAY = 502,
HTTP_SERVICE_UNAVAILABLE = 503,
HTTP_GATEWAY_TIMEOUT = 504,
HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_VARIANT_ALSO_NEGOTIATES = 506,
HTTP_NOT_EXTENDED = 510,
HTTP_NETWORK_AUTH_REQUIRED = 511
} HttpStatus;
.Ed
.Pp
.Fn HttpRequestMethodFromString
and
.Fn HttpRequestMethodToString
convert an HttpRequestMethod enumeration value from and to a
string, respectively. The HttpRequestMethod enumeration is
defined as follows:
.Bd -literal -offset indent
typedef enum HttpRequestMethod
{
HTTP_METHOD_UNKNOWN,
HTTP_GET,
HTTP_HEAD,
HTTP_POST,
HTTP_PUT,
HTTP_DELETE,
HTTP_CONNECT,
HTTP_OPTIONS,
HTTP_TRACE,
HTTP_PATCH
} HttpRequestMethod;
.Ed
.Pp
These can be used for parsing a request method and then storing
it efficiently; it doesn't have be stored as a string, and it's
much nicer to work with enumeration values than it is with
strings in C. The very first enumeration value is not to be
passed to
.Fn HttpRequestMethodToString ,
rather it may be returned by
.Fn HttpRequestMethodFromString
if it cannot identify the request method string passed to it.
.Pp
.Fn HttpUrlEncode
and
.Fn HttpUrlDecode
deal with URL-safe strings.
.Fn HttpUrlEncode
encodes a C string such that it can appear in a URL, and
.Fn HttpUrlDecode
does the opposite; it decodes a URL string into the actual
bytes it is supposed to represent.
.Pp
.Fn HttpParamDecode
and
.Fn HttpParamEncode
convert HTTP parameters in the form of "param=value&param2=val2"
to and from a hash map for easy parsing, manipulation, and encoding.
.Sh RETURN VALUES
.Pp
.Fn HttpStatusToString
and
.Fn HttpRequestMethodToString
both return constant strings; they are not to be manipulated because
doing so would result in a segmentation fault, as these strings
are stored in the data segment of the program.
.Pp
.Fn HttpUrlEncode ,
.Fn HttpUrlDecode ,
.Fn HttpParamDecode ,
and
.Fn HttpParamEncode
all return strings that were allocated on the heap using the
Memory API, or NULL if there was an error allocating memory.
Thee strings returned can be manipulated at will, and must be
freed using the Memory API when they're no longer needed.
.Sh SEE ALSO
.Xr HashMap 3 ,
.Xr Memory 3

View file

@ -1,157 +0,0 @@
.Dd $Mdocdate: December 13 2022 $
.Dt HTTPSERVER 3
.Os Telodendria Project
.Sh NAME
.Nm HttpServer
.Nd Extremely simple HTTP server.
.Sh SYNOPSIS
.In HttpServer.h
.Ft HttpServer *
.Fn HttpServerCreate "unsigned short" "unsigned int" "unsigned int" "HttpHandler *" "void *"
.Ft void
.Fn HttpServerFree "HttpServer *"
.Ft int
.Fn HttpServerStart "HttpServer *"
.Ft void
.Fn HttpServerJoin "HttpServer *"
.Ft void
.Fn HttpServerStop "HttpServer *"
.Ft HashMap *
.Fn HttpRequestHeaders "HttpServerContext *"
.Ft HttpRequestMethod
.Fn HttpRequestMethodGet "HttpServerContext *"
.Ft char *
.Fn HttpRequestPath "HttpServerContext *"
.Ft HashMap *
.Fn HttpRequestParams "HttpServerContext *"
.Ft char *
.Fn HttpResponseHeader "HttpServerContext *" "char *" "char *"
.Ft void
.Fn HttpResponseStatus "HttpServerContext *" HttpStatus"
.Ft FILE *
.Fn HttpStream "HttpServerContext *"
.Ft void
.Fn HttpSendHeaders "HttpServerContext *"
.Sh DESCRIPTION
.Nm
builds on the
.Xr Http 3
API, and provides a very simple, yet very functional API for
creating an HTTP server. It aims at being easy to use and minimal,
yet also efficient. It uses non-blocking I/O, is fully multi-threaded,
very configurable, yet also able to be set up in just two function calls.
.Pp
This API should be familiar to those that have dealt with the HTTP server
libraries of other programming languages, particularly Java. In fact,
much of the terminology used in this code came from Java, and you'll
notice that the way responses are sent and received very closely resemble
the way it's done in Java.
.Pp
An HTTP server itself is created with
.Fn HttpServerCreate ,
which takes the port number to create the server on, the number of threads to
use, the maximum number of connections, a request handler function, and the
arguments to that function, in that order. The request handler function is
of the following type:
.Bd -literal -offset indent
typedef void (HttpHandler) (HttpServerContext *, void *)
.Ed
.Pp
Where the void pointer received is the same pointer that was passed into
.Fn HttpServerCreate
as the last parameter.
.Pp
The returned HttpServer pointer is then managed by
.Fn HttpServerStart ,
.Fn HttpServerStop ,
.Fn HttpServerJoin ,
and
.Fn HttpServerFree .
.Fn HttpServerStart
attempts to start the HTTP server, and returns immediately with the status.
This API is fully threaded and asyncronous, so the caller can continue working
while the HTTP server is running in a separate thread, and managing a pool
of threads to handle responses. Typically at some point after calling
.Fn HttpServerStart ,
the program will have no more work to do, and so it will want to wait for
the HTTP server to finish. This is accomplished with
.Fn HttpServerJoin ,
which joins the HTTP worker thread to the calling thread, making the
calling thread wait until the HTTP server has stopped.
.Pp
The only condition that will cause the HTTP server to stop is when
.Fn HttpServerStop
is invoked. This will typically happen in a signal handler that catches
signals instructing the program to shut down. Only after the server has
been stopped can it be freed with
.Fn HttpServerFree .
Note that calling
.Fn HttpServerFree
while the server is running results in undefined behavior.
.Pp
The remainder of the functions in this API are used inside of the
HTTP handler function passed by the caller of
.Fn HttpServerCreate .
They allow the handler to figure out the context of an HTTP request,
which includes the path that was requested, any parameters, and the
headers used to make the request. They also allow the handler
to respond with a status code, headers, and a body.
.Pp
.Fn HttpRequestHeaders ,
.Fn HttpRequestMethodGet ,
.Fn HttpRequestPath ,
and
.Fn HttpRequestParams
get the information about the request. They should all be passed the
server context pointer that was passed into the handler function.
The data returned by these functions should be treated as read-only,
and should not be freed; their memory is handled outside of the HTTP
server handler function.
.Pp
.Fn HttpResponseHeader
and
.Fn HttpResponseStatus
are used to set response headers, and the response status of the
request, respectively.
.Pp
.Fn HttpStream
returns a stream that is both readable and writable. Reading from
the stream reads the request body that the client sent, if there is
one. Note that the request headers have already been read, so the stream
is correctly positioned at the beginning of the body of the request.
.Fn HttpSendHeaders
must be called before the stream is written to, otherwise a malformed
HTTP response will be sent. An HTTP handler should properly set all
the headers it intends to send, send those headers, and then write the
response body to the stream. Finally, note that the stream does not
need to be closed by the HTTP handler; in fact, doing so results in
undefined behavior. The stream is managed by the server itself.
.Sh RETURN VALUES
.Pp
.Fn HttpRequestHeaders
and
.Fn HttpRequestParams
return a hash map that can be used to access the request headers and
parameters, if necessary. Note that the request parameters would be
GET parameters, attached to the path that was requested. To get POST
parameters, read the stream returned by
.Fn HttpStream
and pass the contents into
.Fn HttpParamDecode
to get a hash map.
.Pp
.Fn HttpRequestPath
returns a string that represents the path that the client requested. Note
that it is not normalized; it is exactly what the client sent, so it should
be checked for path traversal attacks and other malformed paths that the
client may sent.
.Pp
.Fn HttpResponseHeader
returns the previous value of the given header, or NULL if there was no
previous value.
.Pp
.Fn HttpStream
returns a FILE pointer that can be read and written using the C standard
I/O functions.
.Sh SEE ALSO
.Xr Http 3

View file

@ -1,252 +0,0 @@
.Dd $Mdocdate: March 6 2023 $
.Dt JSON 3
.Os Telodendria Project
.Sh NAME
.Nm Json
.Nd A fully-featured JSON API.
.Sh SYNOPSIS
.In Json.h
.Ft JsonType
.Fn JsonValueType "JsonValue *"
.Ft JsonValue *
.Fn JsonValueObject "HashMap *"
.Ft HashMap *
.Fn JsonValueAsObject "JsonValue *"
.Ft JsonValue *
.Fn JsonValueArray "Array *"
.Ft Array *
.Fn JsonValueAsArray "
.Ft JsonValue *
.Fn JsonValueString "char *"
.Ft char *
.Fn JsonValueAsString "JsonValue *"
.Ft JsonValue *
.Fn JsonValueInteger "long"
.Ft long
.Fn JsonValueAsInteger "JsonValue *"
.Ft JsonValue *
.Fn JsonValueFloat "double"
.Ft double
.Fn JsonValueAsFloat "JsonValue *"
.Ft JsonValue *
.Fn JsonValueBoolean "int"
.Ft int
.Fn JsonValueAsBoolean "JsonValue *"
.Ft JsonValue *
.Fn JsonValueNull "void"
.Ft void
.Fn JsonValueFree "JsonValue *"
.Ft void
.Fn JsonFree "HashMap *"
.Ft void
.Fn JsonEncodeString "const char *" "FILE *"
.Ft void
.Fn JsonEncodeValue "JsonValue *" "FILE *"
.Ft int
.Fn JsonEncode "HashMap *" "FILE *"
.Ft HashMap *
.Fn JsonDecode "FILE *"
.Ft JsonValue *
.Fn JsonGet "HashMap *" "size_t" "..."
.Ft JsonValue *
.Fn JsonSet "HashMap *" "size_t" "..."
.Sh DESCRIPTION
.Nm
is a fully-featured JSON API for C using
.Xr Array 3
and
.Xr HashMap 3
that can parse JSON, and serialize an in-memory structure
to JSON.
It builds on the foundation set up by those APIs because
that's all JSON really is, just maps and arrays.
.Nm
also provides a structure for encapsulating an arbitrary
value and identifying its type, making it easy for a program
to work with JSON data.
.Nm
is very strict and tries to adhere as closely as possible to
the proper defintion of JSON. It will fail on syntax errors
of any kind, which is fine for a Matrix homeserver because we can
just return M_BAD_JSON if anything here fails, but it may not
be suitable for other purposes.
.Pp
This JSON implementation focuses primarily on serialization and
deserialization to and from streams. It does not provide facilities
for handling JSON strings; it only writes JSON to output streams, and
reads them from input streams. If course, you can use the POSIX
.Xr fmemopen 3
and
.Xr open_memstream 3
if you want to deal with JSON strings, but JSON is intended to be an
exchange format. Data should be converted to JSON right before it is
leaving the program, and converted from JSON as soon as it is coming
in.
.Pp
The
.Nm
header defines the following enumeration for identifying types of
values:
.Bd -literal -offset indent
typedef enum JsonType
{
JSON_NULL, /* Maps to C NULL */
JSON_OBJECT, /* Maps to a HashMap of JsonValues */
JSON_ARRAY, /* Maps to an Array of JsonValues */
JSON_STRING, /* Maps to a NULL-terminated C string */
JSON_INTEGER, /* Maps to a C long */
JSON_FLOAT, /* Maps to a C double */
JSON_BOOLEAN /* Maps to a C boolean, 1 or 0 */
} JsonType;
.Ed
.Pp
A JsonValue encapsulates all the possible types that can be stored in
JSON. It is an opaque structure that can be managed entirely by the
functions defined in this API. It is important to note that in the case
of objects, arrays, and strings, this structure only stores pointers to
the allocated data, it doesn't store the data itself, but the data IS
freed when using
.Fn JsonFree .
.Pp
Objects are represented as hash maps consisting entirely of JsonValue
structures, and arrays are represented as arrays consisting entirely
of JsonValue structures. When generating a JSON object, any
attempt to stuff a value into a hash map or array without encoding it
as a JsonValue first will result in undefined behavior.
.Pp
.Fn JsonValueType
determines the type of a given JsonValue.
.Pp
The
.Fn JsonValue*
functions wrap their input in a JsonValue that represents the given
value. The
.Fn JsonValueAs*
functions do the opposite; they unwrap a JsonValue and return the
actual usable value itself. They all closely resemble each other and
they all behave the same way, so to save on time and effort, they're
not explicitly documented individually. If something is unclear about
how these functions work, consult the source code, and feel free
to write the documentation yourself for clarification. Otherwise,
reach out to the official Matrix rooms, and someone should be able
to help you.
.Pp
.Fn JsonValueNull
is a special case that represents a JSON null. Because
.Xr Array 3
and
.Xr HashMap 3
do not accept NULL values, this function should be used to represent
NULL in JSON. Even though a small amount of memory is allocated just
to point to NULL, this keeps the APIs clean.
.Pp
.Fn JsonValueFree
frees the memory being used by a JSON value. Note that this will
recursively free all Arrays, HashMaps, and other JsonValues that
are reachable from the given value. It also invokes
.Fn Free
(documented in
.Xr Memory )
on all strings, so make sure passed string pointers point to strings
on the heap, not the stack. This will be the case for all strings
returned by
.Fn JsonDecode ,
but if you are manually creating JSON objects and stitching them
together, you should be aware that calling this function on a value
that contains a pointer to a stack string will result in undefined
behavior.
.Pp
.Fn JsonFree
recursively frees a JSON object, iterating over all the values and
freeing them using
.Fn JsonValueFree .
.Pp
.Fn JsonEncodeString
encodes the given string in such a way that it can be embedded in a
JSON stream. This entails:
.Bl -bullet -offset indent
.It
Escaping quotes, backslashes, and other special characters using
their backslash escape.
.It
Encoding bytes that are not UTF-8 using escapes.
.It
Wrapping the entire string in double quotes.
.El
.Pp
This function is provided via the public
.Nm
API so that it is accessible to custom JSON encoders, such as
.Xr CanonicalJson 3 .
This will typically be used for encoding JSON keys; for encoding
values, just use
.Fn JsonEncodeValue .
.Pp
.Fn JsonEncodeValue
serializes a JsonValue as it would appear in JSON output. This is
a recursive function that also encodes all child values reachable
from the given value. This function is exposed via the public
.Nm
API so that it is accessible to custom JSON encoders. Normal users
that are not writing custom encoders should in most cases just use
.Fn JsonEncode
to encode an entire object.
.Pp
.Fn JsonEncode
encodes a JSON object as minimized JSON and writes it to the given
output stream. This function is recursive; it will serialize
everything accessible from the passed object.
.Fn JsonDecode
does the opposite; it reads from a JSON stream and decodes it
into a hash map of JsonValues.
.Pp
.Fn JsonSet
and
.Fn JsonGet
are convenience functions that allow the caller to retrieve and
manipulate arbitrarily deep keys within a JSON object. They take
a root JSON object, the number of levels deep to go, and then that
number of keys as a varargs list. All keys must have objects
as values, with the exception of the last one, which is the one
being retrieved or set.
.Fn JsonSet
will create any intermediate objects as necessary to set the
proper key.
.Sh RETURN VALUES
.Pp
.Fn JsonValueType
returns a JsonType, documented above, that tells what the given
value actually is, or JSON_NULL if the passed value is NULL.
Note that even a fully valid JsonValue may actually be of type
JSON_NULL, so this function should not be used to determine
whether or not a given value is valid.
.Pp
The
.Fn JsonValue*
functions return a JsonValue that holds a pointer to the passed
value, or NULL if there was an error allocating memory. The
.Fn JsonValueAs*
functions return the actual value represented by the given
JsonValue so that it can be manipulated by the program, or
NULL if no value was provided, or the value is not of the
correct type expected by the function.
.Pp
.Fn JsonEncode
returns whether or not the encoding operation was successful.
This function will fail if any passed parameters are NULL,
otherwise it will assume all pointers are valid and return a
success value.
.Pp
.Fn JsonDecode
returns a hash map of JsonValues that can be manipulated by
this API, or NULL if there was an error parsing the JSON.
.Pp
.Fn JsonGet
returns a JsonValue, or NULL if the requested key is not set
in the object.
.Fn JsonGet
returns the previous value of the provided key, or NULL if there
was no previous value.
.Sh SEE ALSO
.Xr HashMap 3 ,
.Xr Array 3

View file

@ -1,155 +0,0 @@
.Dd $Mdocdate: February 15 2023 $
.Dt LOG 3
.Os Telodendria Project
.Sh NAME
.Nm Log
.Nd A simple logging framework for logging to files, standard output, or the system log.
.Sh SYNOPSIS
.In Log.h
.Ft LogConfig *
.Fn LogConfigCreate "void"
.Ft void
.Fn LogConfigFree "LogConfig *"
.Ft void
.Fn LogConfigLevelSet "LogConfig *" "int"
.Ft void
.Fn LogConfigIndent "LogConfig *"
.Ft void
.Fn LogConfigUnindent "LogConfig *"
.Ft void
.Fn LogConfigIndentSet "LogConfig *" "size_t"
.Ft void
.Fn LogConfigOutputSet "LogConfig *" "FILE *"
.Ft void
.Fn LogConfigFlagSet "LogConfig *" "int"
.Ft void
.Fn LogConfigFlagClear "LogConfig *" "int"
.Ft void
.Fn LogConfigTimeStampFormatSet "LogConfig *" "char *"
.Ft void
.Fn Log "LogConfig *" "int" "const char *" "..."
.Sh DESCRIPTION
.Pp
A heavily-modifed version of Shlog, a simple C logging library facility
that allows for colorful outputs, timestamps, and custom log levels.
This library differs from Shlog in that the naming conventions have
been updated to be consistent with Telodendria, and system log support
has been added.
.Pp
Shlog was originally a learning project. It worked well and produced
elegant logging output, so it was chosen to be the main logging
mechanism of Telodendria. The original Shlog project is now dead; Shlog
lives on now only as Telodendria's logging mechanism.
.Pp
One of the design choices made in this library, which unfortunately
makes code using it a little more verbose, is that multiple logging
configurations can exist in a program. No global variables are used,
and all functions are thread-safe.
.Pp
.Fn LogConfigCreate
creates a new log configuration with sane defaults that can be used
immediately. Note that every call to
.Fn Log
requires a valid configuration pointer.
.Fn LogConfigFree
frees all memory associated with that configuration, invalidating
it. Passing an invalid configuration pointer into any of the
functions defined here result in undefined behavior. The
.Fn LogConfig*Set
functions manipulate the data pointed to by the pointer returned
by
.Fn LogConfigCreate .
.Pp
.Fn LogConfigLevelSet
sets the current log level on the specified log configuration. This
indicates that only messages at or above this level should be
logged; all other messages are silently discarded by the
.Fn Log
function. The passed log level should be one of the log levels
defined by
.Xr syslog 3 .
Refer to that page for a complete list of acceptable log levels,
and note that passing in an invalid or unknown log level will
result in undefined behavior.
.Pp
.Fn LogConfigIndent
causes the output of
.Fn Log
to be indented two more spaces than it was previously. This can be
helpful when generating stack traces, or otherwise producing
hierarchical output. After calling this function, all future
messages using the given config will be indented two more spaces
than they were before. This is just a wrapper function around
.Fn LogConfigIndentSet ,
which allows the caller to specify an arbitrary indentation in
spaces.
.Fn LogConfigUnindent
does the exact opposite of
.Fn LogConfigIndent ;
it subtracts two spaces from the indentation level, unless there
is no indent, then it does nothing.
.Pp
.Fn LogConfigOutputSet
sets the file stream that logging output should be written to. This
defaults to standard output, but it can be standard error, or some
other file stream. Passing a NULL value for the file pointer sets
the log output to standard output. Note that the output file stream
is only used if FLAG_OUTPUT_SYSLOG is not set.
.Pp
.Fn LogConfigFlagSet
and
.Fn LogConfigFlagClear
are used for setting a number of boolean options on a log
configuration. They utilize bitwise operators, so multiple options
can be set or cleared with a single function call using bitwise OR
operators. The flags defined as preprocessor macros, and are as
follows:
.Bl -tag -width Ds
.It LOG_FLAG_COLOR
When set, enable color-coded output on TTYs. Note that colors are
implemented as ANSI escape sequences, and are not written to file
streams that are not actually connected to a TTY, to prevent those
sequences from being written to a file.
.Xr isatty 3
is checked before writing ANSI sequences.
.It LOG_FLAG_SYSLOG
When enabled, log output to the syslog using
.Xr syslog 3 ,
instead of logging to the file set by
.Fn LogConfigOutputSet .
This flag always overrides the file stream set by that function,
regardless of when it was set.
.El
.Pp
.Fn LogConfigTimeStampFormatSet
allows a custom timestamp to be prepended to each message
if the output is not going to the system log. Consult your
system's documentation for
.Xr strftime 3 .
A value of NULL disables outputting a timestamp before messages.
.Pp
The
.Fn Log
function actually writes a log message to a console, file, system
log, or other supported output device using the given configuration.
This function is thread-safe; it locks a mutex before writing a
message, and then unlocks it after the message was written. Each
log configuration has its own mutex, so this function can be used
with mutiple active log configurations.
.Pp
This function only logs messages if their level is above or equal to
the currently configured log level, making it easy to turn some
messages on or off. The function has the same usage as
.Xr printf 3 .
.Sh RETURN VALUES
.Pp
.Fn LogConfigCreate
returns a pointer to a configuration structure on the heap, or NULL
if there was an error allocating memory for it. The returned
structure is opaque to the caller; the
.Fn LogConfig*
functions should be used to manipulate it.
.Pp
All other functions do not return anything. They are simply
assumed to always succeed. If any arguments are NULL, then the
functions do nothing, unless otherwise specifically noted.

View file

@ -1,141 +0,0 @@
.Dd $Mdocdate: March 6 2023 $
.Dt MATRIX 3
.Os Telodendria Project
.Sh NAME
.Nm Matrix
.Nd Functions for writing Matrix API endpoints.
.Sh SYNOPSIS
.In Matrix.h
.Ft void
.Fn MatrixHttpHandler "HttpServerContext *" "void *"
.Ft void
.Fn MatrixErrorCreate "MatrixError"
.Ft HashMap *
.Fn MatrixRateLimit "HttpServerContext *" "Db *"
.Ft HashMap *
.Fn MatrixGetAccessToken "HttpServerContext *" "char **"
.Ft HashMap *
.Fn MatrixClientWellKnown "char *" "char *"
.Sh DESCRIPTION
.Nm
provides some helper functions that bind to the
.Xr HttpServer 3
interface and add basic Matrix functionality, turning an
HTTP server into a Matrix homeserver.
.Pp
.Xr MatrixHttpHandler
is the HTTP handler function that handles all Matrix homeserver
functionality. It should be passed into
.Fn HttpServerCreate ,
and it expects that an instance of MatrixHttpHandlerArgs will also
be provided, because that's what the void pointer is cast to.
That structure is defined as follows:
.Bd -literal -offset indent
typedef struct MatrixHttpHandlerArgs
{
LogConfig *lc;
TelodendriaConfig *config;
Db *db;
} MatrixHttpHandlerArgs;
.Ed
.Pp
This structure should be populated once and then never modified again
for the duration of the HTTP server.
.Pp
.Fn MatrixErrorCreate
is a convenience function that constructs an error payload, including
the error code and message, given just a MatrixError. MatrixErrors
exactly follow the errors in the Matrix specification, and are
defined as follows:
.Bd -literal -offset indent
typedef enum MatrixError
{
M_FORBIDDEN,
M_UNKNOWN_TOKEN,
M_MISSING_TOKEN,
M_BAD_JSON,
M_NOT_JSON,
M_NOT_FOUND,
M_LIMIT_EXCEEDED,
M_UNKNOWN,
M_UNRECOGNIZED,
M_UNAUTHORIZED,
M_USER_DEACTIVATED,
M_USER_IN_USE,
M_INVALID_USERNAME,
M_ROOM_IN_USE,
M_IVALID_ROOM_STATE,
M_THREEPID_IN_USE,
M_THREEPID_NOT_FOUND,
M_THREEPID_AUTH_FAILED,
M_THREEPID_DENIED,
M_SERVER_NOT_TRUSTED,
M_UNSUPPORTED_ROOM_VERSION,
M_BAD_STATE,
M_GUEST_ACCESS_FORBIDDEN,
M_CAPTCHA_NEEDED,
M_CAPTCHA_INVALID,
M_MISSING_PARAM,
M_INVALID_PARAM,
M_TOO_LARGE,
M_EXCLUSIVE,
M_RESOURCE_LIMIT_EXCEEDED,
M_CANNOT_LEAVE_SERVER_NOTICE_ROOM
} MatrixError;
.Ed
.Pp
.Fn MatrixRateLimit
determines whether or not the request should be rate limited. It is
expected that this will occur before most, if not all of the caller's
logic.
.Pp
.Fn MatrixGetAccessToken
reads the request headers and parameters, and attempts to obtain
the access token it found. The matrix specification says that an
access token can either be in an
.Dv Authorization
header, or in a
.Dv access_token
.Sy GET
paramter. This function checks both, and stores the access token
it finds in the passed character pointer.
.Pp
.Fn MatrixClientWellKnown
builds a client ``well-known'' JSON object, which contains
information about the homeserver base URL and identity server,
both of which should be provided by the caller in that order. This
object can be sent to a client as-is, as is the case with the
.Pa /.well-known/matrix/client
endpoint, or it can be added as a key in a response, as is the
case with a few endpoints.
.Sh RETURN VALUES
.Pp
.Fn MatrixErrorCreate
returns a JSON object that represents the given error code. It can be
immediately returned as the HTTP response body, or modified as needed.
.Pp
.Fn MatrixUserInteractiveAuth ,
.Fn MatrixAuthenticate ,
and
.Fn MatrixRateLimit
all return NULL when they are successful. That is, if these functions
return NULL, then the caller can proceed assuming that all is well
and no further action needs to be taken. If these functions do not
return NULL, then the returned JSON object should be passed along to the
client immediately without continuing.
.Pp
.Fn MatrixGetAccessToken
returns a JSON object that should be immediately passed to the client
if it is not NULL. This JSON object holds an error message, indicating
that something went wrong. If this function does return NULL, then
the access token can be checked for validity. Otherwise, the access
token is either not valid or not provided so it should not be
checked.
.Pp
.Fn MatrixClientWellKnown
returns a JSON object, or NULL if something went wrong.
.Sh SEE ALSO
.Xr HttpServer 3 ,
.Xr Log 3 ,
.Xr TelodendriaConfig 3 ,
.Xr Db 3

View file

@ -1,145 +0,0 @@
.Dd $Mdocdate: January 9 2023 $
.Dt MEMORY 3
.Os Telodendria Project
.Sh NAME
.Nm Memory
.Nd Smart memory management.
.Sh SYNOPSIS
.In Memory.h
.Ft void *
.Fn MemoryAllocate "size_t" "const char *" "int"
.Ft void *
.Fn MemoryReallocate "void *" "size_t" "const char *" "int"
.Ft void
.Fn MemoryFree "void *" "const char *" "int"
.Ft size_t
.Fn MemoryAllocated "void"
.Ft void
.Fn MemoryFreeAll "void"
.Ft MemoryInfo *
.Fn MemoryInfoGet "void *"
.Ft size_t
.Fn MemoryInfoGetSize "MemoryInfo *"
.Ft const char *
.Fn MemoryInfoGetFile "MemoryInfo *"
.Ft int
.Fn MemoryInfoGetLine "MemoryInfo *"
.Ft void *
.Fn MemoryInfoGetPointer "MemoryInfo *"
.Ft void
.Fn MemoryIterate "void (*) (MemoryInfo *, void *)" "void *"
.Ft void
.Fn MemoryHook "void (*) (MemoryAction, MemoryInfo *, void *" "void *"
.Ft void
.Fn MemoryHexDump "MemoryInfo *" "void (*) (size_t, char *, char *, void *)" "void *"
.Sh DESCRIPTION
.Nm
is an API that allows for smart memory management and profiling. It wraps
the standard library functions
.Xr malloc 3 ,
.Xr realloc 3 ,
and
.Xr free 3 ,
and offers identical semantics, while providing functionality that the
standard library doesn't have, such as getting statistics on the total
memory allocated on the heap, and getting the size of a block of memory
given a pointer. Additionally, thanks to preprocessor macros, the exact
file and line number at which an allocation, reallocation, or free occured
can be obtained given a pointer. Finally, all the blocks allocated on the
heap can be iterated and evaluated, and a callback function can be executed
every time a memory operation occurs.
.Pp
A number of macros are available, which make using the
.Nm
API much more useful.
.Fn Malloc
expands to
.Fn MemoryAllocate
with the __FILE__ and __LINE__ constants for the second and third
arguments respectively. Likewise,
.Fn Realloc
and
.Fn Free
expand to
.Fn MemoryReallocate
and
.Fn MemoryFree
with __FILE__ and __LINE__ as the second and third parameters.
This allows the API to be used exactly how the standard library
would be used. In fact, the functions which these macros expand to
are not intended to be called directly; only use the macros for the
best results.
.Pp
If all memory used in the program is managed by this API, there are some
helpful functions that allow the program to probe the state of the heap.
These functions are described here.
.Pp
.Fn MemoryAllocated
gets the total memory that the program has on the heap. This operation
iterates over all the heap allocations made with
.Fn MemoryAllocate
and then returns a total count, in bytes.
.Pp
.Fn MemoryFreeAll
iterates over all the heap allocations made with
.Fn MemoryAllocate
and calls
.Fn MemoryFree
on them. It immediately invalidates all pointers, and any subsequent
reads or writes to heap memory result in undefined behavior. This
is typically used at the end of the program.
.Pp
.Fn MemoryInfoGet
takes a pointer and fetches information about it, storing it in a
structure that can then be queried.
.Pp
.Fn MemoryInfoGetSize ,
.Fn MemoryInfoGetFile ,
.Fn MemoryInfoGetLine ,
and
.Fn MemoryInfoGetPointer
all take in the structure returned by
.Fn MemoryInfoGet ,
and return the respective property about the given property. These are
especially useful for logging and debugging with
.Fn MemoryIterate
and
.Fn MemoryHook .
.Pp
.Fn MemoryIterate
takes a pointer to a function that takes the memory information structure,
as well as a void pointer for caller-provided arguments. It iterates over
all the heap memory currently allocated at the time of calling.
.Fn MemoryHook
has a similar prototype, although the function pointer it takes is slightly
different. It also takes a memory action as the first argument. The
.Nm
API stores the pointer to this function, and executes it every time memory
is allocated, reallocated, or freed. This allows a program to execute code
whenever memory is allocated.
.Pp
.Fn MemoryHexDump
can be useful for debugging memory errors. It reads over a block of memory
and generates a hexadecimal and an ASCII string for each chunk of the block.
It takes a memory infomation structure and a callback function that processes
the offset, hexadecimal string, and ASCII string. This callback function
typically prints the strings out to a console, file, or other output
device.
.Sh RETURN VALUES
.Pp
.Fn MemoryAllocate
and
.Fn MemoryReallocate
return the same as their standard library counterparts. That is, a pointer
to memory on the heap, or NULL if there was an error allocating it.
.Pp
.Fn MemoryInfoGet
returns a pointer to information about a block on the heap, or NULL if the
passed pointer was not allocated by the
.Nm
API, or is no longer allocated.
.Pp
.Fn MemoryAllocated
returns an unsigned integer that indicates the number of bytes currently
allocated on the heap.

View file

@ -1,100 +0,0 @@
.Dd $Mdocdate: November 25 2022 $
.Dt QUEUE 3
.Os Telodendria Project
.Sh NAME
.Nm Array
.Nd A simple static queue data structure.
.Sh SYNOPSIS
.In Queue.h
.Ft Queue *
.Fn QueueCreate "size_t"
.Ft void
.Fn QueueFree "Array *"
.Ft int
.Fn QueuePush "Queue *" "void *"
.Ft void *
.Fn QueuePop "Queue *"
.Ft void *
.Fn QueuePeek "Queue *"
.Ft int
.Fn QueueFull "Queue *"
.Ft int
.Fn QueueEmpty "Queue *"
.Sh DESCRIPTION
These functions implement a simple queue data structure that
is statically sized.
This implementation does not actually store the values of the
items in it; it only stores pointers to the data. As such, you will
still have to manually maintain all your data. The advantage of this
is that these functions don't have to copy data, and thus don't care
how big the data is. Furthermore, arbitrary data can be stored in the
queue.
.Pp
This queue implementation operates on the heap. It is a circular
queue, and it does not grow as it is used. Once the size is set, the
queue never gets any bigger.
.Pp
These functions operate on a queue structure which is opaque to the
caller.
.Pp
.Fn QueueCreate
and
.Fn QueueFree
allocate and deallocate a queue, respectively.
Note that
.Fn QueueFree
does not free any of the values stored in the queue; it is the caller's
job to manage the memory for each item. Typically, the caller would
dequeue all the items in the queue and free them before freeing
the queue itself.
.Pp
.Fn QueuePush
and
.Fn QueuePop
are the main functions used to modify the array. They enqueue and dequeue
elements from the queue structure, respectively.
.Pp
.Fn QueuePeek
simply returns the pointer that is next up in the queue without actually
discarding it, such that the next call to
.Fn QueuePeek
or
.Fn QueuePop
return the same pointer.
.Pp
.Fn QueueFull
and
.Fn QueueEmpty
return a boolean value that indicates whether or not the queue is full
or empty, respectively.
.Sh RETURN VALUES
.Pp
.Fn QueueCreate
returns a queue structure, or
.Dv NULL
if there was a memory allocation error.
.Pp
.Fn QueuePush
as well as
.Fn QueueFull
and
.Fn QueueEmpty
all return boolean values. In the case of
.Fn QueuePush
whether or not the push was actually successful is returned. This will
only happen if the queue is already full, or a
.Dv NULL
pointer is passed.
.Pp
.Fn QueuePop
and
.Fn QueuePeek
both return caller-managed pointers that would have been at some point
pushed into the queue with the
.Fn QueuePush
function. They may also return
.Dv NULL
if the queue is empty.
.Sh SEE ALSO
.Xr Array 3 ,
.Xr HashMap 3

View file

@ -1,44 +0,0 @@
.Dd $Mdocdate: February 16 2023 $
.Dt RAND 3
.Os Telodendria Project
.Sh NAME
.Nm Rand
.Nd Thread-safe random numbers.
.Sh SYNOPSIS
.In Rand.h
.Ft int
.Fn RandInt "unsigned int"
.Ft void
.Fn RandIntN "int *" "size_t" "unsigned int"
.Sh DESCRIPTION
.Nm
is used for generating random numbers in a thread-safe way. Currently,
one seed is shared across all threads, which means only one thread can
generate random numbers at a time. In the future, a seed pool may be
maintained. The seed is initialized on the first call to a function
that needs it. It is initialized with the current timestamp,
the process ID, and the thread ID. These should be sufficiently random
sources, so the seed should be secure enough.
.Pp
.Fn RandInt
generates a single random integer between 0 and the passed value.
.Fn RandIntN
takes an integer pointer, a buffer size, and the maximum value a
random number is allowed to be. It generates the number of random
integers specified by the buffer size, and stores them at the passed
pointer. This allows a caller to get multiple random numbers at a
time, as each call to
.Fn RandInt
will have to lock and unlock a mutex, whereas
.Fn RandIntN
can obtain multiple random integers in a single pass.
.Sh RETURN VALUES
.Pp
.Fn RandInt
returns the value of
.Xr rand_r 3
with the internally-stored seed. The return value should be in the
range of 0 to RAND_MAX.
.Sh SEE ALSO
.Xr Util 3 ,
.Xr rand 3

View file

@ -1,87 +0,0 @@
.Dd $Mdocdate: December 12 2022 $
.Dt ROUTES 3
.Os Telodendria Project
.Sh NAME
.Nm Routes
.Nd Matrix API endpoint abstractions.
.Sh SYNOPSIS
.In Routes.h
.Ft char *
.Fn MATRIX_PATH_POP "MATRIX_PATH"
.Ft size_t
.Fn MATRIX_PATH_PARTS "MATRIX_PATH"
.Ft int
.Fn MATRIX_PATH_EQUALS "char *" "char *"
.Sh DESCRIPTION
.Pp
.Nm
provides all of the Matrix API route functions, as well as a few
helpful macros to be used to declare those route functions, and some
macros that are intended to be used inside them.
.Pp
The route macros are intended to increase the readability of the header,
so the individual routes are not documented here; only the helper
macros and structures are documented here. Consult the
.Pa Routes.h
file for a list of the registered route functions.
.Pp
.Fn MATRIX_PATH_POP
and
.Fn MATRIX_PATH_PARTS
are macros that abstract away the underlying data structure of the
path so that that routes don't have to care what it is. The reason
this design choice was made was so that the data structure can be
switched out without breaking all the routes. These macros should
be preferred to the actual underlying data structure functions,
because the data structure may change in the future.
.Pp
At the moment, the path data structure is just an array, but it would
be much more efficient to switch to a queue (which can be easily done
with the current Queue implementation if we just add a function that
computes how many elements are in the queue.)
.Pp
.Fn MATRIX_PATH_POP
returns the next available part of the path, and removes it from
the path such that the next call to
.Fn MATRIX_PATH_POP
returns the part after.
.Fn MATRIX_PATH_PARTS
returns the number of path parts remaining.
.Pp
.Fn MATRIX_PATH_EQUALS
is just a simple string comparison macro. It takes two strings and
returns a boolean value indicating whether or not they're equal.
.Pp
.Nm
also defines
.Fn ROUTE
and
.Fn ROUTE_IMPL .
.Fn ROUTE
is intended to be used only inside the route header, and should be
invoked to declare a new route function prototype. It takes the
route function name, which by convention starts with "Route".
.Fn ROUTE_IMPL
may be used to actually implement a route function. It takes the
route function name, and the name of the variable to put the
RouteArgs in.
.Pp
Every route function takes a RouteArgs structure, which is defined
as follows:
.Bd -literal -offset indent
typedef struct RouteArgs
{
MatrixHttpHandlerArgs *matrixArgs;
HttpServerContext *context;
MATRIX_PATH *path;
} RouteArgs;
.Ed
.Sh RETURN VALUES
.Pp
Each route returns a JSON hash map that contains the response it
intends to return to the client making the request. Routes
should NOT return NULL, because then no body will be returned to
the client, and that is almost always a bug. The Matrix specification
usually mandates that at least an empty JSON object is returned.
.Sh SEE ALSO
.Xr Matrix 3

View file

@ -1,27 +0,0 @@
.Dd $Mdocdate: December 19 2022 $
.Dt SHA2 3
.Os Telodendria Project
.Sh NAME
.Nm Sha2
.Nd A simple implementation of the SHA2 hashing functions.
.Sh SYNOPSIS
.In Sha2.h
.Ft char *
.Fn Sha256 "char *"
.Sh DESCRIPTION
.Pp
This API defines simple functions for computing SHA2 hashes. At the
moment, it only defines
.Fn Sha256 ,
which computes the SHA-256 hash of the given C string. It is not trivial
to implement SHA-512 in ANSI C due to the lack of a 64-bit integer
type, so that hash function has been omitted.
.Sh RETURN VALUES
.Pp
.Fn Sha256
returns a string allocated on the heap using the Memory API, or NULL
if there was an error allocating memory for it. The returned string
should be freed when it is no longer needed.
.Sh SEE ALSO
.Xr Memory 3 ,
.Xr Base64 3

View file

@ -1,55 +0,0 @@
.Dd $Mdocdate: February 15 2023 $
.Dt STR 3
.Os Telodendria Project
.Sh NAME
.Nm Str
.Nd Functions for manipulating and creating strings.
.Sh SYNOPSIS
.In Str.h
.Ft char *
.Fn StrUtf8Encode "unsigned long"
.Ft char *
.Fn StrDuplicate "const char *"
.Ft char *
.Fn StrConcat "size_t" "..."
.Ft char *
.Fn StrRandom "size_t"
.Sh DESCRIPTION
.Nm
provides string-related functions. It is called
.Nm ,
not String, because some platforms (Windows) do not have
case-sensitive filesystems, so String and string are the same thing, which poses
a problem because string is a standard library header.
.Pp
.Fn StrUtf8Encode
takes a UTF-8 codepoint and encodes it into a string buffer containing between
1 and 4 bytes. The string buffer is allocated on the heap, so it should be freed
when it is no longer needed.
.Pp
.Fn StrDuplicate
duplicates a NULL-terminated string, and returns a new string on the heap. This is
useful when a function takes in a string that it needs to store for long amounts
of time, even perhaps after the original string is gone.
.Pp
.Fn StrConcat
is a var-args function that takes the number of NULL-terminated strings specified
by the first argument, and returns a new string that contains their concatenation.
It works a lot like
.Xr strcat 3 ,
but it takes care of allocating memory big enough to hold all the strings. Any
strings may be NULL. If a string is NULL, it is treated like an empty string.
.Pp
.Fn StrRandom
generates a random string of the specified length.
.Sh RETURN VALUES
.Pp
.Fn StrUtf8Encode ,
.Fn StrDuplicate ,
.Fn StrConcat ,
and
.Fn StrRandom
return a pointer to a NULL-terminated C string on the heap, or NULL if a memory
allocation error occurs. Returned pointers should be freed using the Memory API.
.Sh SEE ALSO
.Xr Memory 3

View file

@ -1,95 +0,0 @@
.Dd $Mdocdate: December 10 2022 $
.Dt TELODENDRIACONFIG 3
.Os Telodendria Project
.Sh NAME
.Nm TelodendriaConfig
.Nd Parse the configuration file into a structure.
.Sh SYNOPSIS
.In TelodendriaConfig.h
.Ft TelodendriaConfig *
.Fn TelodendriaConfigParse "HashMap *" "LogConfig *"
.Ft void
.Fn TelodendriaConfigFree "TelodendriaConfig *"
.Sh DESCRIPTION
.Pp
Validate and maintain the Telodendria server's configuration data. This API
builds on the JSON API to add Telodendria-specific parsing. It takes a
fully-parsed JSON object and converts it into a TelodendriaConfig, which is
much more structured and easier to work with than the JSON. The config
structure is not opaque like many other structures in Telodendria. This is
intentional; defining functions for all of the fields would just add a lot
of unecessary overhead. The structure is defined as follows:
.Bd -literal -offset indent
typedef struct TelodendriaConfig
{
char *serverName;
char *baseUrl;
char *identityServer;
char *uid;
char *gid;
char *dataDir;
unsigned short listenPort;
unsigned int flags;
unsigned int threads;
unsigned int maxConnections;
size_t maxCache;
char *logTimestamp;
int logLevel;
} TelodendriaConfig;
.Ed
.Pp
Since the configuration will live in memory for a long time, it is important
that unused values are freed as soon as possible. Therefore, the Telodendria
structure is not opaque; values are accessed directly, and they can be
freed as the program wishes. Do note that if you're going to free a value, you
should set it to NULL, because
.Fn TelodendriaConfigFree
will unconditionally call
.Fn Free
on all values.
.Pp
The flags variable in this structure is a bit field that contains the OR-ed values
of any of the given flags:
.Bd -literal -offset indent
typedef enum TelodendriaConfigFlag
{
TELODENDRIA_FEDERATION,
TELODENDRIA_REGISTRATION,
TELODENDRIA_LOG_COLOR,
TELODENDRIA_LOG_FILE,
TELODENDRIA_LOG_STDOUT,
TELODENDRIA_LOG_SYSLOG
} TelodendriaConfigFlag;
.Ed
.Pp
Do note that the actual values of these enums are omitted, but they can be
OR-ed together and added to flags.
.Pp
.Fn TelodendriaConfigParse
parses a JSON map, extracting the necessary values, validating them, and then
adding them to a new TelodendriaConfig for future use by the program. All values
are copied, so the JSON hash map can be safely freed if this function
succeeds. It takes a working log configuration so that messages can be written
to the log as the parsing progresses, to warn users about default values and
report errors, for example.
.Pp
.Fn TelodendriaConfigFree
frees all of the memory allocated for the given configuration. This function
unconditionally calls
.Fn Free
on all items in the structure, so make sure that items that were already freed
are NULL.
.Sh RETURN VALUES
.Pp
.Fn TelodendriaConfigParse
returns a TelodendriaConfig that is completely independent of the passed
configuration hash map, or NULL if one or more required values is missing, or
there was some other error while parsing the configuration.
.Sh SEE ALSO
.Xr Json 3

View file

@ -1,123 +0,0 @@
.Dd $Mdocdate: March 7 2023 $
.Dt UIA 3
.Os Telodendria Project
.Sh NAME
.Nm Uia
.Nd User Interactive Authentication API.
.Sh SYNOPSIS
.In Uia.h
.Ft UiaStage *
.Fn UiaStageBuild "char *" "HashMap *"
.Ft Array *
.Fn UiaDummyFlow "void"
.Ft void
.Fn UiaCleanup "MatrixHttpHandlerArgs *"
.Ft int
.Fn UiaComplete "Array *" "HttpServerContext *" "Db *" "HashMap *" "HashMap **" "TelodendriaConfig *"
.Ft void
.Fn UiaFlowsFree "Array *"
.Sh DESCRIPTION
.Nm
takes care of all the logic for performing user interactive
authentication as defined by the Matrix specification. API endpoints
that require authentication via user interactive authentication
build up flows and any necessary parameters, and pass them into
.Fn UiaComplete ,
which validates
.Dv auth
objects and maintains session state to track the progress of a
client through the user interactive authentication flows. The idea
is that an API endpoint will not progress until user interactive
authentication has succeeded.
.Nm
makes it easy for the numerous API endpoints that utilize this
authentication mechanism to implement it.
.Pp
.Fn UiaStageBuild
builds a single stage. A stage consists of a string identifying its
type, which is used to instruct the client as to what should be
done, and parameters, which is a JSON object that contains
implementation-specific parameters for completing the stage. This
function takes those two parameters in that order.
.Pp
.Fn UiaDummyFlow
builds a flow that consists only of a dummy stage. This is useful
when an endpoint is required to use user interactive authentication,
but doesn't actually want to require the user to do anything. Since
the dummy flow is a pretty common flow, it seemed sensible to have
a function for it. Other flows are built by the caller that wishes
to perform user interactive authentication.
.Pp
.Fn UiaCleanup
should be called periodically to purge old sessions. Session are
only valid for a few minutes after their last access. After that, they
should be purged so the database doesn't fill up with session files.
This function is specifically designed to be called via
.Xr Cron 3 .
.Pp
.Fn UiaComplete
does the bulk of the work for user interactive authentication. It
takes many paramters:
.Bl -bullet
.It
An array of arrays of stages. Stages should be created with
.Fn UiaStageBuild ,
and then put into an array to create a flow. Those flows should then
be put into an array and passed as this paramter. Do note that
because of the loose typing of Telodendria's Array API, it is very
easy to make mistakes here; if you are implementing a new route that
requires user interactive authentication, then refer to an existing
route so you can see how it works.
.It
An HTTP server context. This is required to set the response headers
in the event of an error.
.It
The database where user interactive authentication sessons are
persisted.
.It
The JSON request body that contains the client's
.Dv auth
object, which will be read, parsed, and handled as appropriate.
.It
A pointer to a pointer where a JSON response can be placed if
necessary. If
.Fn UiaComplete
encounters a client error, such as a failure to authenticate, or
outstanding stages that have not been completed, it will place a
JSON response here that is expected to be returned to the client.
This response will include a description of all the flows, stages,
and their parameters.
.It
A valid Telodendria configuration structure, because a few values
are read from the configuration during certain stages of the
authentication.
.El
.Pp
.Fn UiaFlowsFree
frees an array of flows, as described above. Even though the
caller constructs this array, it is convenient to free it in its
entirety in a single function call.
.Sh RETURN VALUES
.Pp
.Fn UiaStageBuild
returns an opaque structure that represents a user interactive
authentication stage, and any parameters the client needs to complete
it. It may return NULL if there is an error allocating memory.
.Pp
.Fn UiaDummyFlow
returns an array that represents a dummy authentication flow, or
NULL if it could not allocate memory for it.
.Pp
.Fn UiaComplete
returns an integer less than zero if it experiences an internal
failure, such as a failure to allocate memory, or a corrupted
database. It returns 0 if the client has remaining stages to
complete. In this case, it will have set the response headers
and the passed response pointer, so the caller should immediately
return the response to the client. This function returns 1 if the
user has successfully completed all stages. Only in this case shall
the caller proceed with its logic.
.Sh SEE ALSO
.Xr User 3 ,
.Xr Db 3 ,
.Xr Cron 3

View file

@ -1,219 +0,0 @@
.Dd $Mdocdate: March 6 2023 $
.Dt USER 3
.Os Telodendria Project
.Sh NAME
.Nm User
.Nd Convenience functions for working with local users.
.Sh SYNOPSIS
.In User.h
.Ft int
.Fn UserValidate "char *" "char *"
.Ft int
.Fn UserHistoricalValidate "char *" "char *"
.Ft int
.Fn UserExists "Db *" "char *"
.Ft User *
.Fn UserCreate "Db *" "char *" "char *"
.Ft User *
.Fn UserLock "Db *" "char *"
.Ft User *
.Fn UserAuthenticate "Db *" "char *"
.Ft int
.Fn UserUnlock "User *"
.Ft UserLoginInfo *
.Fn UserLogin "User *" "char *" "char *" "char *" "int"
.Ft char *
.Fn UserGetName "User *"
.Ft int
.Fn UserCheckPassword "User *" "char *"
.Ft int
.Fn UserSetPassword "User *" "char *"
.Ft int
.Fn UserDeactivate "User *"
.Ft HashMap *
.Fn UserGetDevices "User *"
.Ft UserAccessToken *
.Fn UserGenerateAccessToken "User *" "char *" "int"
.Ft int
.Fn UserAccessTokenSave "Db *" "UserAccessToken *"
.Ft void
.Fn UserAccessTokenFree "UserAccessToken *"
.Ft int
.Fn UserDeleteToken "User *" "char *"
.Ft int
.Fn UserDeleteTokens "User *"
.Ft UserId *
.Fn UserIdParse "char *" "char *"
.Ft void
.Fn UserIdFree "UserId *"
.Sh DESCRIPTION
The
.Nm
API provides a wrapper over the database and offers an easy way for managing
local users. It supports all of the locking mechanisms that the database does,
and provides features for authenticating local users, among other tasks.
.Pp
.Bd -literal -offset indent
typedef struct UserLoginInfo
{
UserAccessToken *accessToken;
char *refreshToken;
} UserLoginInfo;
typedef struct UserAccessToken
{
char *user;
char *string;
char *deviceId;
long lifetime;
} UserAccessToken;
typedef struct UserId
{
char *localpart;
char *server;
} UserId;
.Ed
.Pp
.Fn UserValidate
takes a localpart and domain as separate parameters and validates it against the
rules of the Matrix specification. The reason the domain is required is because
the spec imposes limitations on the length of the user name, and the longer the
domain name is, the shorter the local part can be. This function is used to
ensure that client-provided localparts are valid on this server.
.Fn UserHistoricalValidate
is called the exact same way, except it is a little more lenient. It is used to
validate user parts on other servers, since some usernames might exist that are
not fully spec compliant, but remain in use due to historical reasons.
.Pp
.Fn UserExists
takes a localpart and checks whether or not it exists in the database.
.Pp
.Fn UserCreate
creates a new user. It takes a localpart, which is assumed to be valid, and
a password.
.Pp
.Fn UserLock
takes a localpart and obtains a database reference to the user represented by that
localpart. It behaves analogously to
.Fn DbLock ,
and in fact uses it under the hood to ensure that the user can only be modified
by the thread that has locked the user.
.Fn UserUnlock
returns the user reference back to the database. It uses
.Fn DbUnlock
under the hood.
.Pp
.Fn UserAuthenticate
takes an access token, figures out what user it belongs to, and returns the
reference to that user. This function should be used by most endpoints that
require valid user authentication, since most endpoints are authenticated via
access tokens.
.Pp
.Fn UserLogin
is used for logging in a user. It takes the user's password, device ID, device
display name, and a boolean value indicating whether or not the client supports
refresh tokens. This function logs in the user and generates an access token to be
returned to the client.
.Pp
.Fn UserGetName
gets the name attached to a user object. It can be used for the few cases where
it's necessary to know the localpart of a user.
.Pp
.Fn UserCheckPassword
takes a password and verifies it against a user object. Telodendria does not
store passwords in plain text, so this function hashes the password and and
checks it against what's stored in the database.
.Pp
.Fn UserSetPassword
resets the given user's password by hashing a plain text password and
storing it in the database.
.Pp
.Fn UserDeactivate
deactivates a user such that it can no longer be used to log in, but
the username is still taken. This is to prevent future users from
pretending to be previous users of a given localpart.
.Pp
.Fn UserGetDevices
fetches the devices that belong to the user, in JSON format,
identical to what's stored in the database. In fact, this JSON is
still linked to the database, so it should not be freed with
.Fn JsonFree .
.Pp
.Fn UserAccessTokenGenerate ,
.Fn UserAccessTokenSave ,
and
.Fn UserAccessTokenFree
are used for managing individual access tokens on a user. They
operate on the UserAccessToken structure.
.Fn UserAccessTokenGenerate
takes the user localpart to generate the token for, the device ID,
for the token, and a boolean value indicating whether or not the token
should expire.
.Fn UserAccessTokenSave
writes the access token to the database.
.Pp
.Fn UserDeleteToken
and
.Fn UserDeleteTokens
delete a specific access token/refresh token pair, or all the access
and refresh tokens for a given user, respectively.
.Pp
.Fn UserIdParse
parses either a localpart or a fully-qualified Matrix ID.
.Fn UserIdFree
frees the result of this parsing.
.Sh RETURN VALUES
.Pp
.Fn UserValidate ,
.Fn UserHistoricalValidate ,
.Fn UserExists ,
.Fn UserUnlock ,
.Fn UserCheckPassword ,
.Fn UserSetPassword ,
.Fn UserDeactivate ,
.Fn UserAccessTokenSave ,
.Fn UserDeleteToken ,
and
.Fn UserDeleteTokens
all return a boolean value. Non-zero values indicate success, and zero values
indicate failure.
.Pp
.Fn UserCreate ,
.Fn UserLock ,
and
.Fn UserAuthenticate
return a pointer to a User, or NULL if an error occurred.
.Pp
.Fn UserGetName
returns a pointer to the string that holds the localpart of the user represented
by the given user pointer. This pointer should not be freed by the caller , as it
is used internally and will be freed when the user is unlocked.
.Pp
.Fn UserLogin
returns a UserLoginInfo struct, or
.Dv NULL
if something goes wrong.
All this information should be returned to the client that is logging in. If the
client doesn't support refresh tokens, then refreshToken will be NULL.
.Pp
.Fn UserGetDevices
returns a JSON object that is linked to the database, or NULL if
there was an error. The result should not be freed with
.Fn JsonFree
because it is still directly attached to the database. This object
is an exact representation of what is stored on the disk.
.Pp
.Fn UserAccessTokenGenerate
generates an access token structure that should be freed when it is
no longer needed, or
.Dv NULL
if there was a memory error.
.Pp
.Fn UserIdParse
returns a UserId structure that should be freed when it is no longer
needed, or
.Dv NULL
if there was a memory error.
.Sh SEE ALSO
.Xr Db 3

View file

@ -1,101 +0,0 @@
.Dd $Mdocdate: February 15 2023 $
.Dt UTIL 3
.Os Telodendria Project
.Sh NAME
.Nm Util
.Nd Some misc. helper functions that don't need their own headers.
.Sh SYNOPSIS
.In Util.h
.Ft unsigned long
.Fn UtilServerTs "void"
.Ft unsigned long
.Fn UtilLastModified "char *"
.Ft int
.Fn UtilMkdir "const char *" "const mode_t"
.Ft int
.Fn UtilSleepMillis "long"
.Ft size_t
.Fn UtilParseBytes "char *"
.Ft ssize_t
.Fn UtilGetDelim "char **" "size_t *" "int" "FILE *"
.Ft ssize_t
.Fn UtilGetLine "char **" "size_t *" "FILE *"
.Sh DESCRIPTION
.Pp
This header holds a number of random functions related to strings,
time, and other tasks that don't require a full API, just one or
two functions. For the most part, the functions here are entirely
standalone, depending only on POSIX functions, however there are a
few that specifically utilize Telodendria APIs. Those are noted.
.Pp
.Fn UtilServerTs
gets the current time in milliseconds since the Unix epoch. This
uses
.Xr gettimeofday 2
and time_t, and converts it to a single number, which is then
returned to the caller. A note on the 2038 problem: as long as
sizeof(long) >= 8, that is, as long as the long datatype is 64 bits
or more, which it is on all modern 64-bit Unix-like operating
systems, then everything should be fine. Expect Telodendria on 32 bit
machines to break in 2038. I didn't want to try to hack together
some system to store larger numbers than the architecture supports.
We can always re-evaluate things over the next decade.
.Pp
.Fn UtilMkdir
behaves just like the system call
.Xr mkdir 2 ,
but it creates any intermediate directories if necessary, unlike
.Xr mkdir 2 .
.Pp
.Fn UtilSleepMillis
sleeps the calling thread for the given number of milliseconds. It
occurred to me that POSIX does not specify a super friendly way to
sleep, so this is a wrapper around the POSIX
.Xr nanosleep 2
designed to make its usage much, much simpler.
.Pp
.Fn UtilLastModified
uses
.Xr stat 2
to get the last modified time of the given file. This is used
primarily for caching file data.
.Pp
.Fn UtilParseBytes
is a highly specialized function used in parsing the configuration file.
It takes in a string which is supposed to represent a number of bytes.
It must consist of an integer, followed by an optional suffix of k, K, m, M,
g, or G, indicating the value is kilobytes, megabytes, or gigabytes.
.Pp
.Fn UtilGetDelim
and
.Fn UtilGetLine
work identically to the POSIX equivalents, documented in
.Xr getdelim 3 ,
except it assumes pointers were allocated using the Memory API, and it
uses the Memory API itself to reallocate necessary pointers.
.Sh RETURN VALUES
.Pp
.Fn UtilServerTs
and
.Fn UtilLastModified
return timestamps in the form of milliseconds since the Unix epoch as an unsigned
long. The Matrix specification requires timestamps be in milliseconds, so these
functions are designed to make that easy and convenient.
.Pp
.Fn UtilMkdir
returns 0 on success, and -1 on failure, just like
.Xr mkdir 2 .
It also sets errno as appropriate.
.Pp
.Fn UtilSleepMillis
returns the result of calling
.Xr nanosleep 2 .
.Pp
.Fn UtilParseBytes
returns a number of bytes, or 0 if there was an error parsing the byte string.
.Pp
.Fn UtilGetDelim
and
.Fn UtilGetLine
return the same value as their POSIX equivalents, documented in
.Xr getdelim 3 .

View file

@ -1,209 +0,0 @@
.Dd $Mdocdate: February 15 2023 $
.Dt TELODENDRIA.CONF 5
.Os Telodendria Project
.Sh NAME
.Nm telodendria.conf
.Nd Configuration file for Telodendria.
.Sh DESCRIPTION
.Nm
is the configuration file for the Telodendria homeserver,
.Xr telodendria 8 .
Telodendria is designed to be extremely configurable. As such,
it has a fairly extensive configuration file. The configuration
file can be passed to the Telodendria binary with the
.Sy -f
option, and is typically located at
.Pa /etc/telodendria.conf
.sp
.Nm
uses JSON for its configuration file syntax, which should be
familiar. Very early versions of
.Nm
used a custom OpenBSD-style configuration file, but this was
not as versatile or familiar as JSON.
.Sh DIRECTIVES
Here are the top-level directives:
.Bl -tag -width Ds
.It Ic listen Ar port
The port to listen on. Telodendria will bind to all interfaces, but it
is recommended to configure your firewall so that it only listens on
localhost, and then configure a reverse proxy such as
.Xr relayd 8
in front of it, because Telodendria does not implement TLS. Note that
Telodendria doesn't provide multiple ports for the various services it
offers. ALl APIs are made available over the same port, so care should
be taken in
.Xr relayd.conf 5
to ensure that only the public Matrix API paths are made available over
the internet.
.Ar port
should be a decimal port number. This directive is entirely optional. If
it is omitted, then Telodendria will listen on port 8008 by default.
.It Ic serverName Ar name
Configure the domain name of your homeserver. Note that Matrix servers
cannot be migrated to other domains, so once this is set, it should never
change unless you want unexpected things to happen, or you want to start
over.
.Ar name
should be a DNS name that can be publically resolved. This directive
is required.
.It Ic baseUrl Ar url
Set the server's base URL.
.Ar url
should be a valid URL, complete with the protocol. It does not need to
be the same as the server name; in fact, it is common for a subdomain of
the server name to be the base URL for the Matrix homeserver.
.Pp
This URL is the URL at which Matrix clients will connect to the server,
and is thus served as a part of the
.Pa .well-known
manifest.
.Pp
This directive is optional. If it is not specified, it is automatically
deduced from the server name.
.It Ic identityServer Ar url
The identity server that clients should use to perform identity lookups.
.Pp
.Ar url
follows the same rules as
.Ic baseUrl .
.Pp
This directive is optional. If it is not specified, it is automatically
set to be the same as the base URL.
.It Ic runAs Ar uidObj
The effective UNIX user and group to drop to after binding to the socket
and changing the filesystem root for the process. This only works if
Telodendria is running as the root user, and is used as a security mechanism.
If this option is set and Telodendria is started as a non-priviledged user,
then a warning is printed to the log if that user does not match what's
specified here. This directive is optional, but should be used as a sanity
check, if nothing more, to make sure the permissions are working properly.
.Pp
This directive takes an object with the following directives:
.Bl -tag -width Ds
.It Ic uid Ar user
The UNIX username to drop to. If
.Ic runAs
is specified, this directive is required.
.It Ic gid Ar group
The UNIX group to drop to. This directive is optional; if it is not
specified, then the value of
.Ic uid
is copied.
.El
.It Ic dataDir Ar directory
The data directory into which Telodendria will write all user and event
information. Telodendria doesn't use a database like other Matrix homeserver
implementations; it uses a flat-file directory structure, similar to how an
SMTP server uses Maildirs to deliver email. This directive is required.
.Pp
Telodendria will
.Xr chroot 2
into this directory as soon as possible for security reasons. If the
.Ic log
directive is configured to write to a file, the log file will be written
in the data directory.
.Ar directory
should be an absolute path, under which all Telodendria data will live.
.It Ic federation Ar true|false
Whether to enable federation with other Matrix homeservers or not. Matrix is
by its very nature a federated protocol, but if you just want to run your
own internal chat server with no contact with the outside, then you can use
this option to disable federation. It is highly recommended to set this to
.Ar true ,
however, if you wish to be able to communicate with users on other Matrix
servers. This directive is required.
.It Ic registration Ar true|false
Whether or not to enable new user registration or not. For security and anti-spam
reasons, you can set this to
.Ar false .
If you do, you can still add users via the administrator API. In an ideal world,
everyone would run their own homeserver, so no public registration would ever
be required. Unfortunately, not everyone has the means to run their own homeserver,
especially because of the fact that public IPv4 addresses are becoming increasingly
harder to come by. If you would like to provide a service to those that are unable
to run their own homeserver, you can aset this to
.Ar true ,
which will allow anyone to create an account. Telodendria should be capable of handling
a large amount of users without difficulty or security issues. This directive is
required.
.It Ic log Ar logObj
The log file configuration. Telodendria uses its own logging facility, which can
output logs to standard output, a file, or the syslog. This directive is required,
and it takes an object with the following directives:
.Bl -tag -width Ds
.It Ic output Ar stdout|file|syslog
The lot output destination. If set to
.Ar file ,
Telodendria will log to
.Pa telodendria.log
inside the
.Ic dataDir .
.It Ic level Ar error|warning|notice|message|debug
The level of messages to log at. Each level shows all the levels above it. For
example, setting the level to
.Ar error
will show only errors, while setting the level to
.Ar warning
will show warnings and errors.
.Ar notice
shows notices, warnings, and errors, and so on. The
.Ar debug
level shows all messages.