From af4fd5dcebf73fe88f6ac7fe690d19834ea16b49 Mon Sep 17 00:00:00 2001 From: lda Date: Thu, 4 Jan 2024 19:32:03 -0500 Subject: [PATCH 01/23] Update licensing text for 2024 (#48) Co-authored-by: Jordan Bancino Reviewed-on: https://git.telodendria.io/Telodendria/Telodendria/pulls/48 Co-authored-by: lda Co-committed-by: lda --- LICENSE.txt | 2 +- contrib/TlsImplTemplate.c | 2 +- src/CanonicalJson.c | 2 +- src/Config.c | 2 +- src/Filter.c | 2 +- src/Html.c | 2 +- src/Main.c | 2 +- src/Matrix.c | 2 +- src/RegToken.c | 2 +- src/Room.c | 2 +- src/Routes.c | 2 +- src/Routes/RouteAdminDeactivate.c | 2 +- src/Routes/RouteAdminTokens.c | 2 +- src/Routes/RouteAliasDirectory.c | 2 +- src/Routes/RouteCapabilities.c | 2 +- src/Routes/RouteChangePwd.c | 2 +- src/Routes/RouteConfig.c | 2 +- src/Routes/RouteCreateRoom.c | 2 +- src/Routes/RouteDeactivate.c | 2 +- src/Routes/RouteFilter.c | 2 +- src/Routes/RouteLogin.c | 2 +- src/Routes/RouteLogout.c | 2 +- src/Routes/RoutePrivileges.c | 2 +- src/Routes/RouteProcControl.c | 2 +- src/Routes/RouteRefresh.c | 2 +- src/Routes/RouteRegister.c | 2 +- src/Routes/RouteRequestToken.c | 2 +- src/Routes/RouteRoomAliases.c | 2 +- src/Routes/RouteStaticDefault.c | 2 +- src/Routes/RouteStaticLogin.c | 2 +- src/Routes/RouteStaticResources.c | 2 +- src/Routes/RouteTokenValid.c | 2 +- src/Routes/RouteUiaFallback.c | 2 +- src/Routes/RouteUserProfile.c | 2 +- src/Routes/RouteVersions.c | 2 +- src/Routes/RouteWellKnown.c | 2 +- src/Routes/RouteWhoami.c | 2 +- src/State.c | 2 +- src/Telodendria.c | 2 +- src/Uia.c | 2 +- src/User.c | 2 +- src/include/CanonicalJson.h | 2 +- src/include/Config.h | 2 +- src/include/Event.h | 2 +- src/include/Filter.h | 2 +- src/include/Html.h | 2 +- src/include/Matrix.h | 2 +- src/include/RegToken.h | 2 +- src/include/Room.h | 2 +- src/include/Routes.h | 2 +- src/include/State.h | 2 +- src/include/Telodendria.h | 2 +- src/include/Uia.h | 2 +- src/include/User.h | 2 +- tools/src/http-debug-server.c | 2 +- tools/src/json.c | 2 +- 56 files changed, 56 insertions(+), 56 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 90f6e6d..65961c2 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/contrib/TlsImplTemplate.c b/contrib/TlsImplTemplate.c index 0127cb8..dee73bb 100644 --- a/contrib/TlsImplTemplate.c +++ b/contrib/TlsImplTemplate.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/CanonicalJson.c b/src/CanonicalJson.c index 327e5c0..2828fcb 100644 --- a/src/CanonicalJson.c +++ b/src/CanonicalJson.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Config.c b/src/Config.c index c081540..6a43501 100644 --- a/src/Config.c +++ b/src/Config.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Filter.c b/src/Filter.c index 1ef4fed..9c50f17 100644 --- a/src/Filter.c +++ b/src/Filter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Html.c b/src/Html.c index 5957891..6a3e392 100644 --- a/src/Html.c +++ b/src/Html.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Main.c b/src/Main.c index 4b25c9e..2321b23 100644 --- a/src/Main.c +++ b/src/Main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Matrix.c b/src/Matrix.c index b6a4d21..7d2d5d2 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/RegToken.c b/src/RegToken.c index fa041d3..924430b 100644 --- a/src/RegToken.c +++ b/src/RegToken.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Room.c b/src/Room.c index 791c5d3..e0c55b1 100644 --- a/src/Room.c +++ b/src/Room.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes.c b/src/Routes.c index 353d5a4..af6c13e 100644 --- a/src/Routes.c +++ b/src/Routes.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteAdminDeactivate.c b/src/Routes/RouteAdminDeactivate.c index 2a48e92..2670996 100644 --- a/src/Routes/RouteAdminDeactivate.c +++ b/src/Routes/RouteAdminDeactivate.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteAdminTokens.c b/src/Routes/RouteAdminTokens.c index 968d98f..94b285b 100644 --- a/src/Routes/RouteAdminTokens.c +++ b/src/Routes/RouteAdminTokens.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteAliasDirectory.c b/src/Routes/RouteAliasDirectory.c index d2cb1a3..e223469 100644 --- a/src/Routes/RouteAliasDirectory.c +++ b/src/Routes/RouteAliasDirectory.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteCapabilities.c b/src/Routes/RouteCapabilities.c index d1eeb16..3a8cecf 100644 --- a/src/Routes/RouteCapabilities.c +++ b/src/Routes/RouteCapabilities.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteChangePwd.c b/src/Routes/RouteChangePwd.c index 81c51a0..c17e032 100644 --- a/src/Routes/RouteChangePwd.c +++ b/src/Routes/RouteChangePwd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteConfig.c b/src/Routes/RouteConfig.c index cb3c244..0b4f8a9 100644 --- a/src/Routes/RouteConfig.c +++ b/src/Routes/RouteConfig.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteCreateRoom.c b/src/Routes/RouteCreateRoom.c index 9ba1028..7a58d61 100644 --- a/src/Routes/RouteCreateRoom.c +++ b/src/Routes/RouteCreateRoom.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteDeactivate.c b/src/Routes/RouteDeactivate.c index 3a1a5d5..a36d6db 100644 --- a/src/Routes/RouteDeactivate.c +++ b/src/Routes/RouteDeactivate.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteFilter.c b/src/Routes/RouteFilter.c index 4a8500e..0903d6c 100644 --- a/src/Routes/RouteFilter.c +++ b/src/Routes/RouteFilter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteLogin.c b/src/Routes/RouteLogin.c index 327281d..5e86afd 100644 --- a/src/Routes/RouteLogin.c +++ b/src/Routes/RouteLogin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteLogout.c b/src/Routes/RouteLogout.c index bca3fe7..ebe3e19 100644 --- a/src/Routes/RouteLogout.c +++ b/src/Routes/RouteLogout.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RoutePrivileges.c b/src/Routes/RoutePrivileges.c index 1577155..c111837 100644 --- a/src/Routes/RoutePrivileges.c +++ b/src/Routes/RoutePrivileges.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteProcControl.c b/src/Routes/RouteProcControl.c index 0142ae9..aa1bced 100644 --- a/src/Routes/RouteProcControl.c +++ b/src/Routes/RouteProcControl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteRefresh.c b/src/Routes/RouteRefresh.c index 0195542..6ce7546 100644 --- a/src/Routes/RouteRefresh.c +++ b/src/Routes/RouteRefresh.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index 923f7f0..2a7cc4d 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteRequestToken.c b/src/Routes/RouteRequestToken.c index 6fdb865..2be7fb4 100644 --- a/src/Routes/RouteRequestToken.c +++ b/src/Routes/RouteRequestToken.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteRoomAliases.c b/src/Routes/RouteRoomAliases.c index 44eadfe..0bd1200 100644 --- a/src/Routes/RouteRoomAliases.c +++ b/src/Routes/RouteRoomAliases.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteStaticDefault.c b/src/Routes/RouteStaticDefault.c index 41c2970..259a2e0 100644 --- a/src/Routes/RouteStaticDefault.c +++ b/src/Routes/RouteStaticDefault.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteStaticLogin.c b/src/Routes/RouteStaticLogin.c index 465fdf2..1aefe51 100644 --- a/src/Routes/RouteStaticLogin.c +++ b/src/Routes/RouteStaticLogin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteStaticResources.c b/src/Routes/RouteStaticResources.c index 23c8cb4..d3ce0f6 100644 --- a/src/Routes/RouteStaticResources.c +++ b/src/Routes/RouteStaticResources.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteTokenValid.c b/src/Routes/RouteTokenValid.c index 997d3f9..25b38e0 100644 --- a/src/Routes/RouteTokenValid.c +++ b/src/Routes/RouteTokenValid.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteUiaFallback.c b/src/Routes/RouteUiaFallback.c index 0d99825..e8f2bdc 100644 --- a/src/Routes/RouteUiaFallback.c +++ b/src/Routes/RouteUiaFallback.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteUserProfile.c b/src/Routes/RouteUserProfile.c index e7153f5..fcb68bf 100644 --- a/src/Routes/RouteUserProfile.c +++ b/src/Routes/RouteUserProfile.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteVersions.c b/src/Routes/RouteVersions.c index d4ff0a8..441f25b 100644 --- a/src/Routes/RouteVersions.c +++ b/src/Routes/RouteVersions.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteWellKnown.c b/src/Routes/RouteWellKnown.c index 8d6e159..102d1cb 100644 --- a/src/Routes/RouteWellKnown.c +++ b/src/Routes/RouteWellKnown.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Routes/RouteWhoami.c b/src/Routes/RouteWhoami.c index 4f174b7..a89b574 100644 --- a/src/Routes/RouteWhoami.c +++ b/src/Routes/RouteWhoami.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/State.c b/src/State.c index 66c69c0..567e085 100644 --- a/src/State.c +++ b/src/State.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Telodendria.c b/src/Telodendria.c index b8612d4..54ba42b 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/Uia.c b/src/Uia.c index c0e7e7d..68fbffe 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/User.c b/src/User.c index d13ab90..d0105c6 100644 --- a/src/User.c +++ b/src/User.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/CanonicalJson.h b/src/include/CanonicalJson.h index 56901af..a453b91 100644 --- a/src/include/CanonicalJson.h +++ b/src/include/CanonicalJson.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Config.h b/src/include/Config.h index a651e2d..b6ced63 100644 --- a/src/include/Config.h +++ b/src/include/Config.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Event.h b/src/include/Event.h index 7e86e3b..4ee519b 100644 --- a/src/include/Event.h +++ b/src/include/Event.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Filter.h b/src/include/Filter.h index a12c680..f29718d 100644 --- a/src/include/Filter.h +++ b/src/include/Filter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Html.h b/src/include/Html.h index 77d2443..2c6e430 100644 --- a/src/include/Html.h +++ b/src/include/Html.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Matrix.h b/src/include/Matrix.h index e0b7fb6..b269538 100644 --- a/src/include/Matrix.h +++ b/src/include/Matrix.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/RegToken.h b/src/include/RegToken.h index 309a2c2..b17f035 100644 --- a/src/include/RegToken.h +++ b/src/include/RegToken.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Room.h b/src/include/Room.h index bcd5eab..80540f3 100644 --- a/src/include/Room.h +++ b/src/include/Room.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Routes.h b/src/include/Routes.h index 084daf8..f886fe5 100644 --- a/src/include/Routes.h +++ b/src/include/Routes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/State.h b/src/include/State.h index 44edd74..0f3f8d1 100644 --- a/src/include/State.h +++ b/src/include/State.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Telodendria.h b/src/include/Telodendria.h index f4fa63e..97ffe1b 100644 --- a/src/include/Telodendria.h +++ b/src/include/Telodendria.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/Uia.h b/src/include/Uia.h index c33efc6..bdac25a 100644 --- a/src/include/Uia.h +++ b/src/include/Uia.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/src/include/User.h b/src/include/User.h index bd30803..96ace6d 100644 --- a/src/include/User.h +++ b/src/include/User.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/tools/src/http-debug-server.c b/tools/src/http-debug-server.c index 12cc26a..0a24e44 100644 --- a/tools/src/http-debug-server.c +++ b/tools/src/http-debug-server.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files diff --git a/tools/src/json.c b/tools/src/json.c index 00235cb..7b23445 100644 --- a/tools/src/json.c +++ b/tools/src/json.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files From f83be63d53ddc4896f16144251717e6d6e8c1256 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 5 Jan 2024 18:57:19 -0500 Subject: [PATCH 02/23] Add CONTRIBUTORS.txt and make a note of it in the LICENSE.txt and documentation. --- CONTRIBUTORS.txt | 7 ++++++ LICENSE.txt | 3 ++- contrib/TlsImplTemplate.c | 3 ++- docs/CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++ src/CanonicalJson.c | 3 ++- src/Config.c | 3 ++- src/Filter.c | 3 ++- src/Html.c | 3 ++- src/Main.c | 3 ++- src/Matrix.c | 3 ++- src/RegToken.c | 3 ++- src/Room.c | 3 ++- src/Routes.c | 3 ++- src/Routes/RouteAdminDeactivate.c | 3 ++- src/Routes/RouteAdminTokens.c | 3 ++- src/Routes/RouteAliasDirectory.c | 3 ++- src/Routes/RouteCapabilities.c | 3 ++- src/Routes/RouteChangePwd.c | 3 ++- src/Routes/RouteConfig.c | 3 ++- src/Routes/RouteCreateRoom.c | 3 ++- src/Routes/RouteDeactivate.c | 3 ++- src/Routes/RouteFilter.c | 3 ++- src/Routes/RouteLogin.c | 3 ++- src/Routes/RouteLogout.c | 3 ++- src/Routes/RoutePrivileges.c | 3 ++- src/Routes/RouteProcControl.c | 3 ++- src/Routes/RouteRefresh.c | 3 ++- src/Routes/RouteRegister.c | 3 ++- src/Routes/RouteRequestToken.c | 3 ++- src/Routes/RouteRoomAliases.c | 3 ++- src/Routes/RouteStaticDefault.c | 3 ++- src/Routes/RouteStaticLogin.c | 3 ++- src/Routes/RouteStaticResources.c | 3 ++- src/Routes/RouteTokenValid.c | 3 ++- src/Routes/RouteUiaFallback.c | 3 ++- src/Routes/RouteUserProfile.c | 3 ++- src/Routes/RouteVersions.c | 3 ++- src/Routes/RouteWellKnown.c | 3 ++- src/Routes/RouteWhoami.c | 3 ++- src/State.c | 3 ++- src/Telodendria.c | 3 ++- src/Uia.c | 3 ++- src/User.c | 3 ++- src/include/CanonicalJson.h | 3 ++- src/include/Config.h | 3 ++- src/include/Event.h | 3 ++- src/include/Filter.h | 3 ++- src/include/Html.h | 3 ++- src/include/Matrix.h | 3 ++- src/include/RegToken.h | 3 ++- src/include/Room.h | 3 ++- src/include/Routes.h | 3 ++- src/include/State.h | 3 ++- src/include/Telodendria.h | 3 ++- src/include/Uia.h | 3 ++- src/include/User.h | 3 ++- tools/src/http-debug-server.c | 3 ++- tools/src/json.c | 3 ++- 58 files changed, 160 insertions(+), 56 deletions(-) create mode 100644 CONTRIBUTORS.txt diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt new file mode 100644 index 0000000..8277661 --- /dev/null +++ b/CONTRIBUTORS.txt @@ -0,0 +1,7 @@ +N: Jordan Bancino +E: jordan@bancino.net +M: @jordan:bancino.net +W: https://bancino.net +D: Project Lead +L: United States + diff --git a/LICENSE.txt b/LICENSE.txt index 65961c2..b745fbf 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/contrib/TlsImplTemplate.c b/contrib/TlsImplTemplate.c index dee73bb..bfcca23 100644 --- a/contrib/TlsImplTemplate.c +++ b/contrib/TlsImplTemplate.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f8f63ae..aa59be0 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -213,3 +213,44 @@ 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. + diff --git a/src/CanonicalJson.c b/src/CanonicalJson.c index 2828fcb..a865df3 100644 --- a/src/CanonicalJson.c +++ b/src/CanonicalJson.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Config.c b/src/Config.c index 6a43501..2f77365 100644 --- a/src/Config.c +++ b/src/Config.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Filter.c b/src/Filter.c index 9c50f17..4920691 100644 --- a/src/Filter.c +++ b/src/Filter.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Html.c b/src/Html.c index 6a3e392..4c9b0da 100644 --- a/src/Html.c +++ b/src/Html.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Main.c b/src/Main.c index 2321b23..d1406f1 100644 --- a/src/Main.c +++ b/src/Main.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Matrix.c b/src/Matrix.c index 7d2d5d2..7186461 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/RegToken.c b/src/RegToken.c index 924430b..0e018c2 100644 --- a/src/RegToken.c +++ b/src/RegToken.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Room.c b/src/Room.c index e0c55b1..9eb9328 100644 --- a/src/Room.c +++ b/src/Room.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes.c b/src/Routes.c index af6c13e..2562e78 100644 --- a/src/Routes.c +++ b/src/Routes.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteAdminDeactivate.c b/src/Routes/RouteAdminDeactivate.c index 2670996..f3d716a 100644 --- a/src/Routes/RouteAdminDeactivate.c +++ b/src/Routes/RouteAdminDeactivate.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteAdminTokens.c b/src/Routes/RouteAdminTokens.c index 94b285b..65ca67d 100644 --- a/src/Routes/RouteAdminTokens.c +++ b/src/Routes/RouteAdminTokens.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteAliasDirectory.c b/src/Routes/RouteAliasDirectory.c index e223469..b1ae042 100644 --- a/src/Routes/RouteAliasDirectory.c +++ b/src/Routes/RouteAliasDirectory.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteCapabilities.c b/src/Routes/RouteCapabilities.c index 3a8cecf..8eb3866 100644 --- a/src/Routes/RouteCapabilities.c +++ b/src/Routes/RouteCapabilities.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteChangePwd.c b/src/Routes/RouteChangePwd.c index c17e032..f8ad988 100644 --- a/src/Routes/RouteChangePwd.c +++ b/src/Routes/RouteChangePwd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteConfig.c b/src/Routes/RouteConfig.c index 0b4f8a9..66b031a 100644 --- a/src/Routes/RouteConfig.c +++ b/src/Routes/RouteConfig.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteCreateRoom.c b/src/Routes/RouteCreateRoom.c index 7a58d61..126f905 100644 --- a/src/Routes/RouteCreateRoom.c +++ b/src/Routes/RouteCreateRoom.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteDeactivate.c b/src/Routes/RouteDeactivate.c index a36d6db..6a21f70 100644 --- a/src/Routes/RouteDeactivate.c +++ b/src/Routes/RouteDeactivate.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteFilter.c b/src/Routes/RouteFilter.c index 0903d6c..13e482a 100644 --- a/src/Routes/RouteFilter.c +++ b/src/Routes/RouteFilter.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteLogin.c b/src/Routes/RouteLogin.c index 5e86afd..d689cd2 100644 --- a/src/Routes/RouteLogin.c +++ b/src/Routes/RouteLogin.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteLogout.c b/src/Routes/RouteLogout.c index ebe3e19..95397fe 100644 --- a/src/Routes/RouteLogout.c +++ b/src/Routes/RouteLogout.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RoutePrivileges.c b/src/Routes/RoutePrivileges.c index c111837..748cd8a 100644 --- a/src/Routes/RoutePrivileges.c +++ b/src/Routes/RoutePrivileges.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteProcControl.c b/src/Routes/RouteProcControl.c index aa1bced..6eb434e 100644 --- a/src/Routes/RouteProcControl.c +++ b/src/Routes/RouteProcControl.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteRefresh.c b/src/Routes/RouteRefresh.c index 6ce7546..e2e0b6a 100644 --- a/src/Routes/RouteRefresh.c +++ b/src/Routes/RouteRefresh.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index 2a7cc4d..6dbf859 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteRequestToken.c b/src/Routes/RouteRequestToken.c index 2be7fb4..318cbab 100644 --- a/src/Routes/RouteRequestToken.c +++ b/src/Routes/RouteRequestToken.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteRoomAliases.c b/src/Routes/RouteRoomAliases.c index 0bd1200..25a080a 100644 --- a/src/Routes/RouteRoomAliases.c +++ b/src/Routes/RouteRoomAliases.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteStaticDefault.c b/src/Routes/RouteStaticDefault.c index 259a2e0..3e017f1 100644 --- a/src/Routes/RouteStaticDefault.c +++ b/src/Routes/RouteStaticDefault.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteStaticLogin.c b/src/Routes/RouteStaticLogin.c index 1aefe51..13748fa 100644 --- a/src/Routes/RouteStaticLogin.c +++ b/src/Routes/RouteStaticLogin.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteStaticResources.c b/src/Routes/RouteStaticResources.c index d3ce0f6..b89dafe 100644 --- a/src/Routes/RouteStaticResources.c +++ b/src/Routes/RouteStaticResources.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteTokenValid.c b/src/Routes/RouteTokenValid.c index 25b38e0..5ea3441 100644 --- a/src/Routes/RouteTokenValid.c +++ b/src/Routes/RouteTokenValid.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteUiaFallback.c b/src/Routes/RouteUiaFallback.c index e8f2bdc..71ee1ed 100644 --- a/src/Routes/RouteUiaFallback.c +++ b/src/Routes/RouteUiaFallback.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteUserProfile.c b/src/Routes/RouteUserProfile.c index fcb68bf..16a310c 100644 --- a/src/Routes/RouteUserProfile.c +++ b/src/Routes/RouteUserProfile.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteVersions.c b/src/Routes/RouteVersions.c index 441f25b..12dcbb4 100644 --- a/src/Routes/RouteVersions.c +++ b/src/Routes/RouteVersions.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteWellKnown.c b/src/Routes/RouteWellKnown.c index 102d1cb..a11aaa8 100644 --- a/src/Routes/RouteWellKnown.c +++ b/src/Routes/RouteWellKnown.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Routes/RouteWhoami.c b/src/Routes/RouteWhoami.c index a89b574..31eade1 100644 --- a/src/Routes/RouteWhoami.c +++ b/src/Routes/RouteWhoami.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/State.c b/src/State.c index 567e085..71d4cc9 100644 --- a/src/State.c +++ b/src/State.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Telodendria.c b/src/Telodendria.c index 54ba42b..a242824 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/Uia.c b/src/Uia.c index 68fbffe..3a71d24 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/User.c b/src/User.c index d0105c6..9e36239 100644 --- a/src/User.c +++ b/src/User.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/CanonicalJson.h b/src/include/CanonicalJson.h index a453b91..aab3d08 100644 --- a/src/include/CanonicalJson.h +++ b/src/include/CanonicalJson.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Config.h b/src/include/Config.h index b6ced63..73052cd 100644 --- a/src/include/Config.h +++ b/src/include/Config.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Event.h b/src/include/Event.h index 4ee519b..09e65d7 100644 --- a/src/include/Event.h +++ b/src/include/Event.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Filter.h b/src/include/Filter.h index f29718d..a7dcc07 100644 --- a/src/include/Filter.h +++ b/src/include/Filter.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Html.h b/src/include/Html.h index 2c6e430..c1225a4 100644 --- a/src/include/Html.h +++ b/src/include/Html.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Matrix.h b/src/include/Matrix.h index b269538..2b18fcb 100644 --- a/src/include/Matrix.h +++ b/src/include/Matrix.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/RegToken.h b/src/include/RegToken.h index b17f035..f24a79c 100644 --- a/src/include/RegToken.h +++ b/src/include/RegToken.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Room.h b/src/include/Room.h index 80540f3..1de979a 100644 --- a/src/include/Room.h +++ b/src/include/Room.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Routes.h b/src/include/Routes.h index f886fe5..76de377 100644 --- a/src/include/Routes.h +++ b/src/include/Routes.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/State.h b/src/include/State.h index 0f3f8d1..1f5dd13 100644 --- a/src/include/State.h +++ b/src/include/State.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Telodendria.h b/src/include/Telodendria.h index 97ffe1b..f9022f0 100644 --- a/src/include/Telodendria.h +++ b/src/include/Telodendria.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/Uia.h b/src/include/Uia.h index bdac25a..268ec77 100644 --- a/src/include/Uia.h +++ b/src/include/Uia.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/src/include/User.h b/src/include/User.h index 96ace6d..6eb5530 100644 --- a/src/include/User.h +++ b/src/include/User.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/tools/src/http-debug-server.c b/tools/src/http-debug-server.c index 0a24e44..a41042e 100644 --- a/tools/src/http-debug-server.c +++ b/tools/src/http-debug-server.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 diff --git a/tools/src/json.c b/tools/src/json.c index 7b23445..9c1b86a 100644 --- a/tools/src/json.c +++ b/tools/src/json.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2022-2024 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 From 22d0e88dde90347e51c17b2720c322179e02f994 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 5 Jan 2024 20:23:27 -0500 Subject: [PATCH 03/23] Update copyright year in code. --- src/Telodendria.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Telodendria.c b/src/Telodendria.c index a242824..f254107 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -136,7 +136,7 @@ TelodendriaPrintHeader(void) Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION " (%s v%s)", CytoplasmGetName(), CytoplasmGetVersion()); Log(LOG_INFO, ""); Log(LOG_INFO, - "Copyright (C) 2023 Jordan Bancino <@jordan:bancino.net>"); + "Copyright (C) 2024 Jordan Bancino <@jordan:bancino.net>"); Log(LOG_INFO, "Documentation/Support: https://telodendria.io"); Log(LOG_INFO, ""); From 83eb69f2cdeb8af9e5527bde0673fcc95312f602 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 5 Jan 2024 21:00:27 -0500 Subject: [PATCH 04/23] 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 Co-authored-by: LoaD Accumulator Co-authored-by: lda Co-authored-by: lda Reviewed-on: https://git.telodendria.io/Telodendria/Telodendria/pulls/49 --- Schema/Config.json | 88 ++++++ docs/CHANGELOG.md | 3 + docs/user/config.md | 8 +- src/Config.c | 494 ++++++++-------------------------- src/Main.c | 141 +++++----- src/Routes/RouteChangePwd.c | 11 +- src/Routes/RouteConfig.c | 55 ++-- src/Routes/RouteDeactivate.c | 12 +- src/Routes/RouteFilter.c | 9 +- src/Routes/RouteLogin.c | 19 +- src/Routes/RouteRegister.c | 23 +- src/Routes/RouteUiaFallback.c | 15 +- src/Routes/RouteUserProfile.c | 18 +- src/Routes/RouteWellKnown.c | 16 +- src/Routes/RouteWhoami.c | 15 +- src/Uia.c | 6 +- src/include/Config.h | 76 +----- src/include/Uia.h | 2 +- 18 files changed, 383 insertions(+), 628 deletions(-) create mode 100644 Schema/Config.json diff --git a/Schema/Config.json b/Schema/Config.json new file mode 100644 index 0000000..be4b16d --- /dev/null +++ b/Schema/Config.json @@ -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" + } + } +} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6f62558..8ab1b23 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -31,6 +31,7 @@ The following endpoints were added: ### 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. @@ -43,6 +44,8 @@ parsing request bodies. ### 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. diff --git a/docs/user/config.md b/docs/user/config.md index f021633..ee19f62 100644 --- a/docs/user/config.md +++ b/docs/user/config.md @@ -19,8 +19,7 @@ key-value form: "serverName": "telodendria.io", "listen": [ { - "port": 8008, - "tls": false + "port": 8008 } ] @@ -51,7 +50,7 @@ Here are the top-level directives: 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|null|false` + - **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 @@ -106,6 +105,9 @@ Here are the top-level directives: 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, diff --git a/src/Config.c b/src/Config.c index 2f77365..1f7a9f7 100644 --- a/src/Config.c +++ b/src/Config.c @@ -22,405 +22,89 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include +#include #include #include #include #include #include #include -#include #include #include +#include +#include #include #include #include #include +#include +#include #ifndef HOST_NAME_MAX #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX #endif -#define CONFIG_REQUIRE(key, type) \ - value = HashMapGet(config, key); \ - if (!value) \ - { \ - tConfig->err = "Missing required " key " directive."; \ - goto error; \ - } \ - if (JsonValueType(value) == JSON_NULL) \ - { \ - tConfig->err = "Missing value for " key " directive."; \ - goto error; \ - } \ - if (JsonValueType(value) != type) \ - { \ - tConfig->err = "Expected " key " to be of type " #type; \ - goto error; \ - } - -#define CONFIG_COPY_STRING(into) \ - into = StrDuplicate(JsonValueAsString(value)); - -#define CONFIG_OPTIONAL_STRING(into, key, default) \ - value = HashMapGet(config, key); \ - if (value && JsonValueType(value) != JSON_NULL) \ - { \ - if (JsonValueType(value) != JSON_STRING) \ - { \ - tConfig->err = "Expected " key " to be of type JSON_STRING"; \ - goto error; \ - } \ - into = StrDuplicate(JsonValueAsString(value)); \ - } \ - else \ - { \ - into = default ? StrDuplicate(default) : NULL; \ - } - -#define CONFIG_OPTIONAL_INTEGER(into, key, default) \ - value = HashMapGet(config, key); \ - if (value && JsonValueType(value) != JSON_NULL) \ - { \ - if (JsonValueType(value) != JSON_INTEGER) \ - { \ - tConfig->err = "Expected " key " to be of type JSON_INTEGER"; \ - goto error; \ - } \ - into = Int64Low(JsonValueAsInteger(value)); \ - } \ - else \ - { \ - into = default; \ - } - -static int -ConfigParseRunAs(Config * tConfig, HashMap * config) -{ - JsonValue *value; - - CONFIG_REQUIRE("uid", JSON_STRING); - CONFIG_COPY_STRING(tConfig->uid); - - CONFIG_OPTIONAL_STRING(tConfig->gid, "gid", tConfig->uid); - - return 1; - -error: - return 0; -} - -static int -ConfigParseListen(Config * tConfig, Array * listen) +void +ConfigParse(HashMap * config, Config *tConfig) { size_t i; - if (!ArraySize(listen)) - { - tConfig->err = "Listen array cannot be empty; you must specify at least one listener."; - goto error; - } - - if (!tConfig->servers) - { - tConfig->servers = ArrayCreate(); - if (!tConfig->servers) - { - tConfig->err = "Unable to allocate memory for listener configurations."; - goto error; - } - } - - for (i = 0; i < ArraySize(listen); i++) - { - JsonValue *val = ArrayGet(listen, i); - HashMap *obj; - HttpServerConfig *serverCfg = Malloc(sizeof(HttpServerConfig)); - - if (!serverCfg) - { - tConfig->err = "Unable to allocate memory for listener configuration."; - goto error; - } - - if (JsonValueType(val) != JSON_OBJECT) - { - tConfig->err = "Invalid value in listener array. All listeners must be objects."; - goto error; - } - - obj = JsonValueAsObject(val); - - serverCfg->port = Int64Low(JsonValueAsInteger(HashMapGet(obj, "port"))); - serverCfg->threads = Int64Low(JsonValueAsInteger(HashMapGet(obj, "threads"))); - serverCfg->maxConnections = Int64Low(JsonValueAsInteger(HashMapGet(obj, "maxConnections"))); - - if (!serverCfg->port) - { - Free(serverCfg); - continue; - } - - if (!serverCfg->threads) - { - serverCfg->threads = 4; - } - - if (!serverCfg->maxConnections) - { - serverCfg->maxConnections = 32; - } - - val = HashMapGet(obj, "tls"); - if ((JsonValueType(val) == JSON_BOOLEAN && !JsonValueAsBoolean(val)) || JsonValueType(val) == JSON_NULL) - { - serverCfg->flags = HTTP_FLAG_NONE; - serverCfg->tlsCert = NULL; - serverCfg->tlsKey = NULL; - } - else if (JsonValueType(val) != JSON_OBJECT) - { - tConfig->err = "Invalid value for listener.tls. It must be an object."; - goto error; - } - else - { - serverCfg->flags = HTTP_FLAG_TLS; - - obj = JsonValueAsObject(val); - serverCfg->tlsCert = StrDuplicate(JsonValueAsString(HashMapGet(obj, "cert"))); - serverCfg->tlsKey = StrDuplicate(JsonValueAsString(HashMapGet(obj, "key"))); - - if (!serverCfg->tlsCert || !serverCfg->tlsKey) - { - tConfig->err = "TLS cert and key must both be valid file names."; - goto error; - } - } - ArrayAdd(tConfig->servers, serverCfg); - } - - return 1; -error: - return 0; -} - -static int -ConfigParseLog(Config * tConfig, HashMap * config) -{ - JsonValue *value; - char *str; - - CONFIG_REQUIRE("output", JSON_STRING); - str = JsonValueAsString(value); - - if (StrEquals(str, "stdout")) - { - tConfig->flags |= CONFIG_LOG_STDOUT; - } - else if (StrEquals(str, "file")) - { - tConfig->flags |= CONFIG_LOG_FILE; - } - else if (StrEquals(str, "syslog")) - { - tConfig->flags |= CONFIG_LOG_SYSLOG; - } - else - { - tConfig->err = "Invalid value for log.output"; - goto error; - } - - CONFIG_OPTIONAL_STRING(str, "level", "message"); - - if (StrEquals(str, "message")) - { - tConfig->logLevel = LOG_INFO; - } - else if (StrEquals(str, "debug")) - { - tConfig->logLevel = LOG_DEBUG; - } - else if (StrEquals(str, "notice")) - { - tConfig->logLevel = LOG_NOTICE; - } - else if (StrEquals(str, "warning")) - { - tConfig->logLevel = LOG_WARNING; - } - else if (StrEquals(str, "error")) - { - tConfig->logLevel = LOG_ERR; - } - else - { - tConfig->err = "Invalid value for log.level."; - goto error; - } - - Free(str); - - CONFIG_OPTIONAL_STRING(tConfig->logTimestamp, "timestampFormat", "default"); - - if (StrEquals(tConfig->logTimestamp, "none")) - { - Free(tConfig->logTimestamp); - tConfig->logTimestamp = NULL; - } - - value = HashMapGet(config, "color"); - if (value && JsonValueType(value) != JSON_NULL) - { - if (JsonValueType(value) != JSON_BOOLEAN) - { - tConfig->err = "Expected type JSON_BOOLEAN for log.color."; - goto error; - } - - if (JsonValueAsBoolean(value)) - { - tConfig->flags |= CONFIG_LOG_COLOR; - } - } - - return 1; - -error: - return 0; -} - -void -ConfigFree(Config * tConfig) -{ - if (!tConfig) - { - return; - } - - Free(tConfig->serverName); - Free(tConfig->baseUrl); - Free(tConfig->identityServer); - - Free(tConfig->uid); - Free(tConfig->gid); - - Free(tConfig->logTimestamp); - - if (tConfig->servers) - { - size_t i; - - for (i = 0; i < ArraySize(tConfig->servers); i++) - { - HttpServerConfig *serverCfg = ArrayGet(tConfig->servers, i); - - Free(serverCfg->tlsCert); - Free(serverCfg->tlsKey); - Free(serverCfg); - } - - ArrayFree(tConfig->servers); - } - - Free(tConfig); -} - -Config * -ConfigParse(HashMap * config) -{ - Config *tConfig; - JsonValue *value; - if (!config) { - return NULL; - } - - tConfig = Malloc(sizeof(Config)); - if (!tConfig) - { - return NULL; + tConfig->ok = 0; + tConfig->err = "Invalid object given as config."; + return; } memset(tConfig, 0, sizeof(Config)); - CONFIG_REQUIRE("listen", JSON_ARRAY); - if (!ConfigParseListen(tConfig, JsonValueAsArray(value))) + tConfig->maxCache = Int64Create(0, 0); + + if (!ConfigFromJson(config, tConfig, &tConfig->err)) { + ConfigFree(tConfig); goto error; } - - CONFIG_REQUIRE("serverName", JSON_STRING); - CONFIG_COPY_STRING(tConfig->serverName); - - value = HashMapGet(config, "baseUrl"); - if (value) - { - CONFIG_COPY_STRING(tConfig->baseUrl); - } - else + if (!tConfig->baseUrl) { size_t len = strlen(tConfig->serverName) + 10; tConfig->baseUrl = Malloc(len); if (!tConfig->baseUrl) { - tConfig->err = "Error allocating memory for default config value 'baseUrl'."; + tConfig->err = "Couldn't allocate enough memory for 'baseUrl'."; goto error; } - - snprintf(tConfig->baseUrl, len, "https://%s", tConfig->serverName); + snprintf(tConfig->baseUrl, len, "https://%s/", tConfig->serverName); } - - CONFIG_OPTIONAL_STRING(tConfig->identityServer, "identityServer", NULL); - - value = HashMapGet(config, "runAs"); - if (value && JsonValueType(value) != JSON_NULL) + if (!tConfig->log.timestampFormat) { - if (JsonValueType(value) == JSON_OBJECT) + tConfig->log.timestampFormat = StrDuplicate("default"); + } + for (i = 0; i < ArraySize(tConfig->listen); i++) + { + ConfigListener *listener = ArrayGet(tConfig->listen, i); + if (Int64Eq(listener->maxConnections, Int64Create(0, 0))) { - if (!ConfigParseRunAs(tConfig, JsonValueAsObject(value))) - { - goto error; - } + listener->maxConnections = Int64Create(0, 32); } - else + if (Int64Eq(listener->threads, Int64Create(0, 0))) { - tConfig->err = "Config directive 'runAs' should be a JSON object that contains a 'uid' and 'gid'."; - goto error; + listener->threads = Int64Create(0, 4); + } + if (Int64Eq(listener->port, Int64Create(0, 0))) + { + listener->port = Int64Create(0, 8008); } } - - CONFIG_OPTIONAL_INTEGER(tConfig->maxCache, "maxCache", 0); - - CONFIG_REQUIRE("federation", JSON_BOOLEAN); - if (JsonValueAsBoolean(value)) - { - tConfig->flags |= CONFIG_FEDERATION; - } - - CONFIG_REQUIRE("registration", JSON_BOOLEAN); - if (JsonValueAsBoolean(value)) - { - tConfig->flags |= CONFIG_REGISTRATION; - } - - CONFIG_REQUIRE("log", JSON_OBJECT); - if (!ConfigParseLog(tConfig, JsonValueAsObject(value))) - { - goto error; - } - tConfig->ok = 1; tConfig->err = NULL; - return tConfig; + return; error: tConfig->ok = 0; - return tConfig; + return; } int @@ -432,75 +116,91 @@ ConfigExists(Db * db) int ConfigCreateDefault(Db * db) { - DbRef *ref; + Config config; + ConfigListener *listener; + HashMap *json; - Array *listeners; - HashMap *listen; + JsonValue *val; - char hostname[HOST_NAME_MAX + 1]; + DbRef *ref; - if (!db) - { - return 0; - } + size_t len; + + memset(&config, 0, sizeof(Config)); + + + config.log.output = CONFIG_LOG_OUTPUT_FILE; + + config.runAs.gid = StrDuplicate(getgrgid(getgid())->gr_name); + config.runAs.uid = StrDuplicate(getpwuid(getuid())->pw_name); + + config.registration = 0; + config.federation = 1; + + /* Create serverName and baseUrl. */ + config.serverName = Malloc(HOST_NAME_MAX + 1); + memset(config.serverName, 0, HOST_NAME_MAX + 1); + gethostname(config.serverName, HOST_NAME_MAX); + len = strlen(config.serverName) + 10; + config.baseUrl = Malloc(len); + snprintf(config.baseUrl, len, "https://%s/", config.serverName); + + /* Add simple listener without TLS. */ + config.listen = ArrayCreate(); + listener = Malloc(sizeof(ConfigListener)); + listener->maxConnections = Int64Create(0, 32); + listener->port = Int64Create(0, 8008); + listener->threads = Int64Create(0, 4); + + ArrayAdd(config.listen, listener); + + /* Write it all out to the configuration file. */ + json = ConfigToJson(&config); + val = JsonGet(json, 1, "listen"); + val = ArrayGet(JsonValueAsArray(val), 0); + JsonValueFree(HashMapDelete(JsonValueAsObject(val), "tls")); ref = DbCreate(db, 1, "config"); if (!ref) { + ConfigFree(&config); return 0; } + DbJsonSet(ref, json); + DbUnlock(db, ref); - json = DbJson(ref); + ConfigFree(&config); + JsonFree(json); - JsonSet(json, JsonValueString("file"), 2, "log", "output"); - - listeners = ArrayCreate(); - listen = HashMapCreate(); - HashMapSet(listen, "port", JsonValueInteger(Int64Create(0, 8008))); - HashMapSet(listen, "tls", JsonValueBoolean(0)); - ArrayAdd(listeners, JsonValueObject(listen)); - HashMapSet(json, "listen", JsonValueArray(listeners)); - - if (gethostname(hostname, HOST_NAME_MAX + 1) < 0) - { - strncpy(hostname, "localhost", HOST_NAME_MAX); - } - HashMapSet(json, "serverName", JsonValueString(hostname)); - - HashMapSet(json, "federation", JsonValueBoolean(1)); - HashMapSet(json, "registration", JsonValueBoolean(0)); - - return DbUnlock(db, ref); + return 1; } -Config * -ConfigLock(Db * db) +void +ConfigLock(Db * db, Config *config) { - Config *config; DbRef *ref = DbLock(db, 1, "config"); if (!ref) { - return NULL; + config->ok = 0; + config->err = "Couldn't lock configuration."; } - config = ConfigParse(DbJson(ref)); - if (config) + ConfigParse(DbJson(ref), config); + if (config->ok) { config->db = db; config->ref = ref; } - - return config; } int -ConfigUnlock(Config * config) +ConfigUnlock(Config *config) { Db *db; DbRef *dbRef; - if (!config) + if (!config->ok) { return 0; } @@ -509,5 +209,25 @@ ConfigUnlock(Config * config) dbRef = config->ref; ConfigFree(config); + config->ok = 0; + return DbUnlock(db, dbRef); } +int +ConfigLogLevelToSyslog(ConfigLogLevel level) +{ + switch (level) + { + case CONFIG_LOG_LEVEL_NOTICE: + return LOG_NOTICE; + case CONFIG_LOG_LEVEL_ERROR: + return LOG_ERR; + case CONFIG_LOG_LEVEL_MESSAGE: + return LOG_INFO; + case CONFIG_LOG_LEVEL_DEBUG: + return LOG_DEBUG; + case CONFIG_LOG_LEVEL_WARNING: + return LOG_WARNING; + } + return LOG_INFO; +} diff --git a/src/Main.c b/src/Main.c index d1406f1..a7d7f3c 100644 --- a/src/Main.c +++ b/src/Main.c @@ -103,8 +103,11 @@ Main(Array * args) char *dbPath; /* Program configuration */ - Config *tConfig; + Config tConfig; Stream *logFile; + Stream *pidFile = NULL; + + char *pidPath = NULL; /* User validation */ struct passwd *userInfo; @@ -133,7 +136,6 @@ start: exit = EXIT_SUCCESS; flags = 0; dbPath = NULL; - tConfig = NULL; logFile = NULL; userInfo = NULL; groupInfo = NULL; @@ -262,33 +264,20 @@ start: Log(LOG_NOTICE, "Loading configuration..."); - tConfig = ConfigLock(matrixArgs.db); - if (!tConfig) + ConfigLock(matrixArgs.db, &tConfig); + if (!tConfig.ok) { - Log(LOG_ERR, "Error locking the configuration."); - Log(LOG_ERR, "The configuration object is corrupted or otherwise invalid."); - Log(LOG_ERR, "Please restore from a backup."); - exit = EXIT_FAILURE; - goto finish; - } - else if (!tConfig->ok) - { - Log(LOG_ERR, tConfig->err); + Log(LOG_ERR, tConfig.err); exit = EXIT_FAILURE; goto finish; } - if (!tConfig->logTimestamp || !StrEquals(tConfig->logTimestamp, "default")) + if (!tConfig.log.timestampFormat || !StrEquals(tConfig.log.timestampFormat, "default")) { - LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig->logTimestamp); - } - else - { - Free(tConfig->logTimestamp); - tConfig->logTimestamp = NULL; + LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig.log.timestampFormat); } - if (tConfig->flags & CONFIG_LOG_COLOR) + if (tConfig.log.color) { LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_COLOR); } @@ -297,9 +286,13 @@ start: LogConfigFlagClear(LogConfigGlobal(), LOG_FLAG_COLOR); } - LogConfigLevelSet(LogConfigGlobal(), flags & ARG_VERBOSE ? LOG_DEBUG : tConfig->logLevel); + LogConfigLevelSet( + LogConfigGlobal(), + flags & ARG_VERBOSE ? + LOG_DEBUG : + ConfigLogLevelToSyslog(tConfig.log.level)); - if (tConfig->flags & CONFIG_LOG_FILE) + if (tConfig.log.output == CONFIG_LOG_OUTPUT_FILE) { logFile = StreamOpen("telodendria.log", "a"); @@ -307,18 +300,18 @@ start: { Log(LOG_ERR, "Unable to open log file for appending."); exit = EXIT_FAILURE; - tConfig->flags &= CONFIG_LOG_STDOUT; + tConfig.log.output = CONFIG_LOG_OUTPUT_STDOUT; goto finish; } Log(LOG_INFO, "Logging to the log file. Check there for all future messages."); LogConfigOutputSet(LogConfigGlobal(), logFile); } - else if (tConfig->flags & CONFIG_LOG_STDOUT) + else if (tConfig.log.output == CONFIG_LOG_OUTPUT_STDOUT) { Log(LOG_DEBUG, "Already logging to standard output."); } - else if (tConfig->flags & CONFIG_LOG_SYSLOG) + else if (tConfig.log.output == CONFIG_LOG_OUTPUT_SYSLOG) { Log(LOG_INFO, "Logging to the syslog. Check there for all future messages."); LogConfigFlagSet(LogConfigGlobal(), LOG_FLAG_SYSLOG); @@ -328,13 +321,6 @@ start: * messages get passed to the syslog */ setlogmask(LOG_UPTO(LOG_DEBUG)); } - else - { - Log(LOG_ERR, "Unknown logging method in flags: '%d'", tConfig->flags); - Log(LOG_ERR, "This is a programmer error; please report it."); - exit = EXIT_FAILURE; - goto finish; - } /* If a token was created with a default config, print it to the * log */ @@ -344,14 +330,30 @@ start: Free(token); } + if (tConfig.pid) + { + pidFile = StreamOpen(tConfig.pid, "w+"); + if (!pidFile) + { + char *msg = "Couldn't lock PID file at '%s'"; + Log(LOG_ERR, msg, tConfig.pid); + exit = EXIT_FAILURE; + goto finish; + } + pidPath = StrDuplicate(tConfig.pid); + StreamPrintf(pidFile, "%ld", (long) getpid()); + StreamClose(pidFile); + } + Log(LOG_DEBUG, "Configuration:"); LogConfigIndent(LogConfigGlobal()); - Log(LOG_DEBUG, "Server Name: %s", tConfig->serverName); - Log(LOG_DEBUG, "Base URL: %s", tConfig->baseUrl); - Log(LOG_DEBUG, "Identity Server: %s", tConfig->identityServer); - Log(LOG_DEBUG, "Run As: %s:%s", tConfig->uid, tConfig->gid); - Log(LOG_DEBUG, "Max Cache: %ld", tConfig->maxCache); - Log(LOG_DEBUG, "Flags: %x", tConfig->flags); + Log(LOG_DEBUG, "Server Name: %s", tConfig.serverName); + Log(LOG_DEBUG, "Base URL: %s", tConfig.baseUrl); + Log(LOG_DEBUG, "Identity Server: %s", tConfig.identityServer); + Log(LOG_DEBUG, "Run As: %s:%s", tConfig.runAs.uid, tConfig.runAs.gid); + Log(LOG_DEBUG, "Max Cache: %ld", tConfig.maxCache); + Log(LOG_DEBUG, "Registration: %s", tConfig.registration ? "true" : "false"); + Log(LOG_DEBUG, "Federation: %s", tConfig.federation ? "true" : "false"); LogConfigUnindent(LogConfigGlobal()); httpServers = ArrayCreate(); @@ -363,41 +365,51 @@ start: } /* Bind servers before possibly dropping permissions. */ - for (i = 0; i < ArraySize(tConfig->servers); i++) + for (i = 0; i < ArraySize(tConfig.listen); i++) { - HttpServerConfig *serverCfg = ArrayGet(tConfig->servers, i); + ConfigListener *serverCfg = ArrayGet(tConfig.listen, i); + + HttpServerConfig args; + + args.port = serverCfg->port; + args.threads = serverCfg->maxConnections; + args.maxConnections = serverCfg->maxConnections; + args.tlsCert = serverCfg->tls.cert; + args.tlsKey = serverCfg->tls.key; + args.flags = args.tlsCert && args.tlsKey ? HTTP_FLAG_TLS : HTTP_FLAG_NONE; Log(LOG_DEBUG, "HTTP listener: %lu", i); LogConfigIndent(LogConfigGlobal()); Log(LOG_DEBUG, "Port: %hu", serverCfg->port); Log(LOG_DEBUG, "Threads: %u", serverCfg->threads); Log(LOG_DEBUG, "Max Connections: %u", serverCfg->maxConnections); - Log(LOG_DEBUG, "Flags: %d", serverCfg->flags); - Log(LOG_DEBUG, "TLS Cert: %s", serverCfg->tlsCert); - Log(LOG_DEBUG, "TLS Key: %s", serverCfg->tlsKey); + Log(LOG_DEBUG, "Flags: %d", args.flags); + Log(LOG_DEBUG, "TLS Cert: %s", serverCfg->tls.cert); + Log(LOG_DEBUG, "TLS Key: %s", serverCfg->tls.key); LogConfigUnindent(LogConfigGlobal()); - serverCfg->handler = MatrixHttpHandler; - serverCfg->handlerArgs = &matrixArgs; - if (serverCfg->flags & HTTP_FLAG_TLS) + args.handler = MatrixHttpHandler; + args.handlerArgs = &matrixArgs; + + if (args.flags & HTTP_FLAG_TLS) { - if (UInt64Eq(UtilLastModified(serverCfg->tlsCert), UInt64Create(0, 0))) + if (UInt64Eq(UtilLastModified(serverCfg->tls.cert), UInt64Create(0, 0))) { - Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tlsCert); + Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tls.cert); exit = EXIT_FAILURE; goto finish; } - if (UInt64Eq(UtilLastModified(serverCfg->tlsKey), UInt64Create(0, 0))) + if (UInt64Eq(UtilLastModified(serverCfg->tls.key), UInt64Create(0, 0))) { - Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tlsKey); + Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tls.key); exit = EXIT_FAILURE; goto finish; } } - server = HttpServerCreate(serverCfg); + server = HttpServerCreate(&args); if (!server) { Log(LOG_ERR, "Unable to create HTTP server on port %d: %s", @@ -418,10 +430,10 @@ start: Log(LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid()); - if (tConfig->uid && tConfig->gid) + if (tConfig.runAs.uid && tConfig.runAs.gid) { - userInfo = getpwnam(tConfig->uid); - groupInfo = getgrnam(tConfig->gid); + userInfo = getpwnam(tConfig.runAs.uid); + groupInfo = getgrnam(tConfig.runAs.gid); if (!userInfo || !groupInfo) { @@ -451,7 +463,7 @@ start: } else { - Log(LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig->uid, tConfig->gid); + Log(LOG_DEBUG, "Set uid/gid to %s:%s.", tConfig.runAs.uid, tConfig.runAs.gid); } } else @@ -463,7 +475,7 @@ start: } else { - if (tConfig->uid && tConfig->gid) + if (tConfig.runAs.uid && tConfig.runAs.gid) { if (getuid() != userInfo->pw_uid || getgid() != groupInfo->gr_gid) { @@ -476,17 +488,16 @@ start: } } - if (!tConfig->maxCache) + if (!tConfig.maxCache) { Log(LOG_WARNING, "Database caching is disabled."); Log(LOG_WARNING, "If this is not what you intended, check the config file"); Log(LOG_WARNING, "and ensure that maxCache is a valid number of bytes."); } - DbMaxCacheSet(matrixArgs.db, tConfig->maxCache); + DbMaxCacheSet(matrixArgs.db, tConfig.maxCache); - ConfigUnlock(tConfig); - tConfig = NULL; + ConfigUnlock(&tConfig); cron = CronCreate(60 * 1000); /* 1-minute tick */ if (!cron) @@ -593,7 +604,7 @@ finish: Log(LOG_DEBUG, "Stopped and freed job scheduler."); } - ConfigUnlock(tConfig); + ConfigUnlock(&tConfig); Log(LOG_DEBUG, "Unlocked configuration."); DbClose(matrixArgs.db); @@ -602,6 +613,12 @@ finish: HttpRouterFree(matrixArgs.router); Log(LOG_DEBUG, "Freed routing tree."); + if (pidPath) + { + remove(pidPath); + Free(pidPath); + } + /* * Uninstall the memory hook because it uses the Log * API, whose configuration is being freed now, so it diff --git a/src/Routes/RouteChangePwd.c b/src/Routes/RouteChangePwd.c index f8ad988..60272cb 100644 --- a/src/Routes/RouteChangePwd.c +++ b/src/Routes/RouteChangePwd.c @@ -68,13 +68,14 @@ ROUTE_IMPL(RouteChangePwd, path, argp) char *msg; - Config *config = ConfigLock(db); + Config config; - if (!config) + ConfigLock(db, &config); + if (!config.ok) { - Log(LOG_ERR, "Password endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, NULL); + return MatrixErrorCreate(M_UNKNOWN, config.err); } (void) path; @@ -157,7 +158,7 @@ ROUTE_IMPL(RouteChangePwd, path, argp) response = HashMapCreate(); finish: - ConfigUnlock(config); + ConfigUnlock(&config); UserUnlock(user); JsonFree(request); return response; diff --git a/src/Routes/RouteConfig.c b/src/Routes/RouteConfig.c index 66b031a..2c9fdfd 100644 --- a/src/Routes/RouteConfig.c +++ b/src/Routes/RouteConfig.c @@ -37,10 +37,10 @@ ROUTE_IMPL(RouteConfig, path, argp) char *msg; User *user = NULL; - Config *config = NULL; + Config config; HashMap *request = NULL; - Config *newConf; + Config newConf; HashMap *newJson = NULL; (void) path; @@ -67,20 +67,19 @@ ROUTE_IMPL(RouteConfig, path, argp) goto finish; } - config = ConfigLock(args->matrixArgs->db); - if (!config) + ConfigLock(args->matrixArgs->db, &config); + if (!config.ok) { - msg = "Internal server error while locking configuration."; - Log(LOG_ERR, "Config endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - response = MatrixErrorCreate(M_UNKNOWN, msg); + response = MatrixErrorCreate(M_UNKNOWN, config.err); goto finish; } switch (HttpRequestMethodGet(args->context)) { case HTTP_GET: - response = JsonDuplicate(DbJson(config->ref)); + response = JsonDuplicate(DbJson(config.ref)); break; case HTTP_POST: request = JsonDecode(HttpServerStream(args->context)); @@ -91,18 +90,10 @@ ROUTE_IMPL(RouteConfig, path, argp) break; } - newConf = ConfigParse(request); - if (!newConf) + ConfigParse(request, &newConf); + if (newConf.ok) { - msg = "Internal server error while parsing config."; - HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - response = MatrixErrorCreate(M_UNKNOWN, msg); - break; - } - - if (newConf->ok) - { - if (DbJsonSet(config->ref, request)) + if (DbJsonSet(config.ref, request)) { response = HashMapCreate(); /* @@ -121,10 +112,10 @@ ROUTE_IMPL(RouteConfig, path, argp) else { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_BAD_JSON, newConf->err); + response = MatrixErrorCreate(M_BAD_JSON, newConf.err); } - ConfigFree(newConf); + ConfigFree(&newConf); JsonFree(request); break; case HTTP_PUT: @@ -136,22 +127,14 @@ ROUTE_IMPL(RouteConfig, path, argp) break; } - newJson = JsonDuplicate(DbJson(config->ref)); + newJson = JsonDuplicate(DbJson(config.ref)); JsonMerge(newJson, request); - newConf = ConfigParse(newJson); + ConfigParse(newJson, &newConf); - if (!newConf) + if (newConf.ok) { - msg = "Internal server error while parsing config."; - HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - response = MatrixErrorCreate(M_UNKNOWN, msg); - break; - } - - if (newConf->ok) - { - if (DbJsonSet(config->ref, newJson)) + if (DbJsonSet(config.ref, newJson)) { response = HashMapCreate(); /* @@ -170,10 +153,10 @@ ROUTE_IMPL(RouteConfig, path, argp) else { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_BAD_JSON, newConf->err); + response = MatrixErrorCreate(M_BAD_JSON, newConf.err); } - ConfigFree(newConf); + ConfigFree(&newConf); JsonFree(request); JsonFree(newJson); break; @@ -186,6 +169,6 @@ ROUTE_IMPL(RouteConfig, path, argp) finish: UserUnlock(user); - ConfigUnlock(config); + ConfigUnlock(&config); return response; } diff --git a/src/Routes/RouteDeactivate.c b/src/Routes/RouteDeactivate.c index 6a21f70..3c0bf74 100644 --- a/src/Routes/RouteDeactivate.c +++ b/src/Routes/RouteDeactivate.c @@ -46,17 +46,19 @@ ROUTE_IMPL(RouteDeactivate, path, argp) Db *db = args->matrixArgs->db; User *user = NULL; - Config *config = ConfigLock(db); + Config config; + char *msg; (void) path; - if (!config) + ConfigLock(db, &config); + if (!config.ok) { - Log(LOG_ERR, "Deactivate endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - response = MatrixErrorCreate(M_UNKNOWN, NULL); + response = MatrixErrorCreate(M_UNKNOWN, config.err); goto finish; } @@ -149,6 +151,6 @@ ROUTE_IMPL(RouteDeactivate, path, argp) finish: JsonFree(request); UserUnlock(user); - ConfigUnlock(config); + ConfigUnlock(&config); return response; } diff --git a/src/Routes/RouteFilter.c b/src/Routes/RouteFilter.c index 13e482a..c2ead37 100644 --- a/src/Routes/RouteFilter.c +++ b/src/Routes/RouteFilter.c @@ -40,16 +40,17 @@ GetServerName(Db * db) { char *name; - Config *config = ConfigLock(db); + Config config; - if (!config) + ConfigLock(db, &config); + if (!config.ok) { return NULL; } - name = StrDuplicate(config->serverName); + name = StrDuplicate(config.serverName); - ConfigUnlock(config); + ConfigUnlock(&config); return name; } diff --git a/src/Routes/RouteLogin.c b/src/Routes/RouteLogin.c index d689cd2..158629d 100644 --- a/src/Routes/RouteLogin.c +++ b/src/Routes/RouteLogin.c @@ -65,13 +65,14 @@ ROUTE_IMPL(RouteLogin, path, argp) char *msg; - Config *config = ConfigLock(db); + Config config; - if (!config) + ConfigLock(db, &config); + if (!config.ok) { - Log(LOG_ERR, "Login endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, NULL); + return MatrixErrorCreate(M_UNKNOWN, config.err); } (void) path; @@ -150,7 +151,7 @@ ROUTE_IMPL(RouteLogin, path, argp) } - userId = UserIdParse(userIdentifier.user, config->serverName); + userId = UserIdParse(userIdentifier.user, config.serverName); if (!userId) { msg = "Invalid user ID."; @@ -159,7 +160,7 @@ ROUTE_IMPL(RouteLogin, path, argp) break; } - if (!StrEquals(userId->server, config->serverName) + if (!StrEquals(userId->server, config.serverName) || !UserExists(db, userId->localpart)) { msg = "Unknown user ID."; @@ -222,13 +223,13 @@ ROUTE_IMPL(RouteLogin, path, argp) } fullUsername = StrConcat(4, "@", UserGetName(user), ":", - config->serverName); + config.serverName); HashMapSet(response, "user_id", JsonValueString(fullUsername)); Free(fullUsername); HashMapSet(response, "well_known", JsonValueObject( - MatrixClientWellKnown(config->baseUrl, config->identityServer))); + MatrixClientWellKnown(config.baseUrl, config.identityServer))); UserAccessTokenFree(loginInfo->accessToken); Free(loginInfo->refreshToken); @@ -246,7 +247,7 @@ ROUTE_IMPL(RouteLogin, path, argp) UserIdFree(userId); JsonFree(request); - ConfigUnlock(config); + ConfigUnlock(&config); LoginRequestFree(&loginRequest); LoginRequestUserIdentifierFree(&userIdentifier); diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index 6dbf859..49c0104 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -73,7 +73,7 @@ ROUTE_IMPL(RouteRegister, path, argp) char *session; DbRef *sessionRef; - Config *config = ConfigLock(db); + Config config; regReq.username = NULL; regReq.password = NULL; @@ -82,15 +82,12 @@ ROUTE_IMPL(RouteRegister, path, argp) regReq.refresh_token = 0; regReq.inhibit_login = 0; - - - - if (!config) + ConfigLock(db, &config); + if (!config.ok) { - msg = "Internal server error while locking configuration."; - Log(LOG_ERR, "Registration endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, msg); + return MatrixErrorCreate(M_UNKNOWN, config.err); } if (ArraySize(path) == 0) @@ -118,7 +115,7 @@ ROUTE_IMPL(RouteRegister, path, argp) if (regReq.username) { - if (!UserValidate(regReq.username, config->serverName)) + if (!UserValidate(regReq.username, config.serverName)) { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); response = MatrixErrorCreate(M_INVALID_USERNAME, NULL); @@ -136,7 +133,7 @@ ROUTE_IMPL(RouteRegister, path, argp) uiaFlows = ArrayCreate(); ArrayAdd(uiaFlows, RouteRegisterRegFlow()); - if (config->flags & CONFIG_REGISTRATION) + if (config.registration) { ArrayAdd(uiaFlows, UiaDummyFlow()); } @@ -183,7 +180,7 @@ ROUTE_IMPL(RouteRegister, path, argp) response = HashMapCreate(); fullUsername = StrConcat(4, - "@", UserGetName(user), ":", config->serverName); + "@", UserGetName(user), ":", config.serverName); HashMapSet(response, "user_id", JsonValueString(fullUsername)); Free(fullUsername); @@ -260,7 +257,7 @@ finish: HttpResponseStatus(args->context, HTTP_BAD_REQUEST); response = MatrixErrorCreate(M_MISSING_PARAM, msg); } - else if (!UserValidate(username, config->serverName)) + else if (!UserValidate(username, config.serverName)) { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); response = MatrixErrorCreate(M_INVALID_USERNAME, NULL); @@ -284,6 +281,6 @@ finish: } end: - ConfigUnlock(config); + ConfigUnlock(&config); return response; } diff --git a/src/Routes/RouteUiaFallback.c b/src/Routes/RouteUiaFallback.c index 71ee1ed..3ae6d44 100644 --- a/src/Routes/RouteUiaFallback.c +++ b/src/Routes/RouteUiaFallback.c @@ -52,23 +52,22 @@ ROUTE_IMPL(RouteUiaFallback, path, argp) HashMap *request; HashMap *response; int uiaResult; - Config *config; + Config config; Array *flows; Array *flow; - config = ConfigLock(args->matrixArgs->db); - if (!config) + ConfigLock(args->matrixArgs->db, &config); + if (!config.ok) { - msg = "Internal server error: failed to lock configuration."; - Log(LOG_ERR, "UIA fallback failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, msg); + return MatrixErrorCreate(M_UNKNOWN, config.err); } request = JsonDecode(HttpServerStream(args->context)); if (!request) { - ConfigUnlock(config); + ConfigUnlock(&config); HttpResponseStatus(args->context, HTTP_BAD_REQUEST); return MatrixErrorCreate(M_NOT_JSON, NULL); } @@ -92,7 +91,7 @@ ROUTE_IMPL(RouteUiaFallback, path, argp) } JsonFree(request); - ConfigUnlock(config); + ConfigUnlock(&config); return response; } else if (HttpRequestMethodGet(args->context) != HTTP_GET) diff --git a/src/Routes/RouteUserProfile.c b/src/Routes/RouteUserProfile.c index 16a310c..5c1af7b 100644 --- a/src/Routes/RouteUserProfile.c +++ b/src/Routes/RouteUserProfile.c @@ -51,16 +51,18 @@ ROUTE_IMPL(RouteUserProfile, path, argp) char *msg; - Config *config = ConfigLock(db); + Config config; - if (!config) + ConfigLock(db, &config); + + if (!config.ok) { - Log(LOG_ERR, "User profile endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, NULL); + return MatrixErrorCreate(M_UNKNOWN, config.err); } - serverName = config->serverName; + serverName = config.serverName; username = ArrayGet(path, 0); userId = UserIdParse(username, serverName); @@ -181,11 +183,9 @@ ROUTE_IMPL(RouteUserProfile, path, argp) break; } finish: - ConfigUnlock(config); + ConfigUnlock(&config); - /* Username is handled by the router, freeing it *will* cause issues - * (see #33). I honestly don't know how it didn't come to bite us sooner. - Free(username); */ + /* Username is handled by the router, freeing it would cause issues. */ Free(entry); UserIdFree(userId); UserUnlock(user); diff --git a/src/Routes/RouteWellKnown.c b/src/Routes/RouteWellKnown.c index a11aaa8..19c0f63 100644 --- a/src/Routes/RouteWellKnown.c +++ b/src/Routes/RouteWellKnown.c @@ -36,21 +36,19 @@ ROUTE_IMPL(RouteWellKnown, path, argp) RouteArgs *args = argp; HashMap *response; - Config *config = ConfigLock(args->matrixArgs->db); + Config config; - char *msg; - - if (!config) + ConfigLock(args->matrixArgs->db, &config); + if (!config.ok) { - Log(LOG_ERR, "Well-known endpoint failed to lock configuration."); - msg = "Internal server error: couldn't lock database."; + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, msg); + return MatrixErrorCreate(M_UNKNOWN, config.err); } if (StrEquals(ArrayGet(path, 0), "client")) { - response = MatrixClientWellKnown(config->baseUrl, config->identityServer); + response = MatrixClientWellKnown(config.baseUrl, config.identityServer); } else { @@ -58,6 +56,6 @@ ROUTE_IMPL(RouteWellKnown, path, argp) response = MatrixErrorCreate(M_NOT_FOUND, NULL); } - ConfigUnlock(config); + ConfigUnlock(&config); return response; } diff --git a/src/Routes/RouteWhoami.c b/src/Routes/RouteWhoami.c index 31eade1..b98df15 100644 --- a/src/Routes/RouteWhoami.c +++ b/src/Routes/RouteWhoami.c @@ -45,14 +45,15 @@ ROUTE_IMPL(RouteWhoami, path, argp) char *deviceID; char *msg; - Config *config = ConfigLock(db); + Config config; - if (!config) + ConfigLock(db, &config); + + if (!config.ok) { - msg = "Internal server error: couldn't lock database."; - Log(LOG_ERR, "Who am I endpoint failed to lock configuration."); + Log(LOG_ERR, "%s", config.err); HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - return MatrixErrorCreate(M_UNKNOWN, msg); + return MatrixErrorCreate(M_UNKNOWN, config.err); } (void) path; @@ -76,7 +77,7 @@ ROUTE_IMPL(RouteWhoami, path, argp) response = HashMapCreate(); - userID = StrConcat(4, "@", UserGetName(user), ":", config->serverName); + userID = StrConcat(4, "@", UserGetName(user), ":", config.serverName); deviceID = StrDuplicate(UserGetDeviceId(user)); UserUnlock(user); @@ -88,6 +89,6 @@ ROUTE_IMPL(RouteWhoami, path, argp) Free(deviceID); finish: - ConfigUnlock(config); + ConfigUnlock(&config); return response; } diff --git a/src/Uia.c b/src/Uia.c index 3a71d24..2c0abb8 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -206,7 +206,7 @@ UiaStageBuild(char *type, HashMap * params) int UiaComplete(Array * flows, HttpServerContext * context, Db * db, - HashMap * request, HashMap ** response, Config * config) + HashMap * request, HashMap ** response, Config config) { JsonValue *val; HashMap *auth; @@ -363,10 +363,10 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db, type = JsonValueAsString(HashMapGet(identifier, "type")); userId = UserIdParse(JsonValueAsString(HashMapGet(identifier, "user")), - config->serverName); + config.serverName); if (!type || !StrEquals(type, "m.id.user") - || !userId || !StrEquals(userId->server, config->serverName)) + || !userId || !StrEquals(userId->server, config.serverName)) { HttpResponseStatus(context, HTTP_UNAUTHORIZED); ret = BuildResponse(flows, db, response, session, dbRef); diff --git a/src/include/Config.h b/src/include/Config.h index 73052cd..6d925b7 100644 --- a/src/include/Config.h +++ b/src/include/Config.h @@ -49,68 +49,12 @@ * .Xr telodendria-config 7 . */ +#include + #include #include #include -/** - * Bit flags that can be set in the flags field of the configuration - * structure. - */ -typedef enum ConfigFlag -{ - CONFIG_FEDERATION = (1 << 0), - CONFIG_REGISTRATION = (1 << 1), - CONFIG_LOG_COLOR = (1 << 2), - CONFIG_LOG_FILE = (1 << 3), - CONFIG_LOG_STDOUT = (1 << 4), - CONFIG_LOG_SYSLOG = (1 << 5) -} ConfigFlag; - -/** - * The configuration structure is not opaque like many of the other - * structures present in the other public APIs. This is intentional; - * defining functions for all of the fields would simply add too much - * unnecessary overhead. - */ -typedef struct Config -{ - /* - * These are used internally and should not be touched outside of - * the functions defined in this API. - */ - Db *db; - DbRef *ref; - - /* - * Whether or not the parsing was successful. If this boolean - * value is 0, then read the error message and assume that all - * other fields are invalid. - */ - int ok; - char *err; - - char *serverName; - char *baseUrl; - char *identityServer; - - char *uid; - char *gid; - - unsigned int flags; - - size_t maxCache; - - char *logTimestamp; - int logLevel; - - /* - * An array of HttpServerConfig structures. Consult the HttpServer - * API. - */ - Array *servers; -} Config; - /** * Parse a JSON object, extracting the necessary values, validating * them, and adding them to the configuration structure for use by the @@ -121,14 +65,7 @@ typedef struct Config * set the ok flag to 0. The caller should always check the ok flag, * and if there is an error, it should display the error to the user. */ -extern Config * ConfigParse(HashMap *); - -/** - * Free all the values inside of the given configuration structure, - * as well as the structure itself, such that it is completely invalid - * when this function returns. - */ -extern void ConfigFree(Config *); +extern void ConfigParse(HashMap *, Config *); /** * Check whether or not the configuration exists in the database, @@ -151,7 +88,7 @@ extern int ConfigCreateDefault(Db *); * The return value of this function is the same as * .Fn ConfigParse . */ -extern Config * ConfigLock(Db *); +extern void ConfigLock(Db *, Config *); /** * Unlock the specified configuration, returning it back to the @@ -161,4 +98,9 @@ extern Config * ConfigLock(Db *); */ extern int ConfigUnlock(Config *); +/** + * Converts a ConfigLogLevel into a valid syslog level. + */ +extern int ConfigLogLevelToSyslog(ConfigLogLevel); + #endif /* TELODENDRIA_CONFIG_H */ diff --git a/src/include/Uia.h b/src/include/Uia.h index 268ec77..91b4e0a 100644 --- a/src/include/Uia.h +++ b/src/include/Uia.h @@ -133,7 +133,7 @@ extern void UiaCleanup(MatrixHttpHandlerArgs *); * the caller proceed with its logic. */ extern int - UiaComplete(Array *, HttpServerContext *, Db *, HashMap *, HashMap **, Config *); + UiaComplete(Array *, HttpServerContext *, Db *, HashMap *, HashMap **, Config); /** * Free an array of flows, as described above. Even though the caller From 35b9ef51f906c2075143e57ff2835fdc4a5d4e8e Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 5 Jan 2024 21:02:45 -0500 Subject: [PATCH 05/23] PID File: Properly initialize variables in Main(). --- src/Main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Main.c b/src/Main.c index a7d7f3c..6865bc1 100644 --- a/src/Main.c +++ b/src/Main.c @@ -105,9 +105,9 @@ Main(Array * args) /* Program configuration */ Config tConfig; Stream *logFile; - Stream *pidFile = NULL; + Stream *pidFile; - char *pidPath = NULL; + char *pidPath; /* User validation */ struct passwd *userInfo; @@ -137,6 +137,8 @@ start: flags = 0; dbPath = NULL; logFile = NULL; + pidFile = NULL; + pidPath = NULL; userInfo = NULL; groupInfo = NULL; cron = NULL; From 243de4f1a050107b38c07dc4f8b763540314e2f7 Mon Sep 17 00:00:00 2001 From: lda Date: Sat, 6 Jan 2024 10:02:53 -0500 Subject: [PATCH 06/23] Add new entry to CONTRIBUTORS.txt (#50) Reviewed-on: https://git.telodendria.io/Telodendria/Telodendria/pulls/50 Co-authored-by: lda Co-committed-by: lda --- CONTRIBUTORS.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 8277661..3232b89 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -5,3 +5,12 @@ 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 From 54420f003639f1e077a79e529069fe3989061477 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Thu, 11 Jan 2024 19:33:50 -0500 Subject: [PATCH 07/23] 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 Co-authored-by: lda Co-authored-by: lda Reviewed-on: https://git.telodendria.io/Telodendria/Telodendria/pulls/51 --- docs/CHANGELOG.md | 6 + docs/user/admin/privileges.md | 8 +- src/Parser.c | 503 +++++++++++++++++++++++++++++++ src/Routes/RouteAliasDirectory.c | 106 ++++++- src/Routes/RouteFilter.c | 6 +- src/Routes/RouteLogin.c | 8 +- src/Routes/RouteRoomAliases.c | 65 +++- src/Routes/RouteUserProfile.c | 12 +- src/Routes/RouteVersions.c | 7 +- src/Routes/RouteWhoami.c | 1 - src/Uia.c | 7 +- src/User.c | 40 +-- src/include/Parser.h | 106 +++++++ src/include/User.h | 19 +- 14 files changed, 817 insertions(+), 77 deletions(-) create mode 100644 src/Parser.c create mode 100644 src/include/Parser.h diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8ab1b23..dc84eed 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -41,6 +41,8 @@ will now be maintained separately and have its own releases as well. 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 @@ -58,6 +60,10 @@ the ability to change only a subset of the configuration. - **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 diff --git a/docs/user/admin/privileges.md b/docs/user/admin/privileges.md index 9a8da06..b62e8d9 100644 --- a/docs/user/admin/privileges.md +++ b/docs/user/admin/privileges.md @@ -16,10 +16,10 @@ registration tokens. 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 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. +- **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 diff --git a/src/Parser.c b/src/Parser.c new file mode 100644 index 0000000..982fb5c --- /dev/null +++ b/src/Parser.c @@ -0,0 +1,503 @@ +/* + * 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 + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include +#include +#include + +#include +#include +#include + + +/* Iterate through a char **. */ +#define Iterate(s) (*(*s)++) + +/* Parse an extended localpart */ +static int +ParseUserLocalpart(char **str, char **out) +{ + char c; + char *start; + size_t length; + + if (!str || !out) + { + return 0; + } + /* An extended localpart contains every ASCII printable character, + * except an ':'. */ + start = *str; + while (isascii((c = Iterate(str))) && c != ':' && c) + { + /* Do nothing */ + } + length = (size_t) (*str - start) - 1; + if (length < 1) + { + *str = start; + return 0; + } + if (c == ':') + { + --(*str); + } + + *out = Malloc(length + 1); + memcpy(*out, start, length); + (*out)[length] = '\0'; + + return 1; +} +/* Parses an IPv4 address. */ +static int +ParseIPv4(char **str, char **out) +{ + /* Be *very* careful with this buffer */ + char buffer[4]; + char *start; + size_t length; + char c; + + int digit = 0; + int digits = 0; + + memset(buffer, 0, sizeof(buffer)); + start = *str; + + /* An IPv4 address is made of 4 blocks between 1-3 digits, like so: + * (1-3)*DIGIT.(1-3)*DIGIT.(1-3)*DIGIT.(1-3)*DIGIT */ + while ((isdigit(c = Iterate(str)) || c == '.') && c && digits < 4) + { + if (isdigit(c)) + { + digit++; + continue; + } + if (digit < 1 || digit > 3) + { + /* Current digit is too long for the spec! */ + *str = start; + return 0; + } + memcpy(buffer, *str - digit - 1, digit); + if (atoi(buffer) > 255) + { + /* Current digit is too large for the spec! */ + *str = start; + return 0; + } + memset(buffer, 0, sizeof(buffer)); + digit = 0; + digits++; /* We have parsed a digit. */ + } + if (c == '.' || digits != 3) + { + *str = start; + return 0; + } + length = (size_t) (*str - start) - 1; + *out = Malloc(length + 1); + memcpy(*out, start, length); + (*str)--; + return 1; +} +static int +IsIPv6Char(char c) +{ + return isxdigit(c) || c == ':' || c == '.'; +} +static int +ParseIPv6(char **str, char **out) +{ + char *start; + size_t length; + char c; + + int filled = 0; + int digit = 0; + int digits = 0; + + start = *str; + length = 0; + + if (Iterate(str) != '[') + { + goto fail; + } + + while ((c = Iterate(str)) && IsIPv6Char(c)) + { + char *ipv4; + if (isxdigit(c)) + { + digit++; + length++; + continue; + } + if (c == ':') + { + if (**str == ':') + { + digit = 0; + if (!filled) + { + filled = 1; + length++; + c = Iterate(str); /* Skip over the character */ + continue; + } + /* RFC3513 says the following: + * > 'The "::" can only appear once in an address.' */ + *str = start; + return 0; + } + if (digit < 1 || digit > 4) + { + goto fail; + } + /* We do not have to check whenever the digit here is valid, + * because it has to be. */ + digit = 0; + digits++; + + length++; + continue; + } + /* The only remaining character being '.', we are probably dealing + * with an IPv4 literal. */ + *str -= digit + 1; + length -= digit + 1; + if (ParseIPv4(str, &ipv4)) + { + length += strlen(ipv4); + Free(ipv4); + c = Iterate(str); + filled = 1; + goto end; + } + } +end: + --(*str); + if (Iterate(str) != ']') + { + goto fail; + } + + length = (size_t) (*str - start); + if (length < 4 || length > 47) + { + goto fail; + } + *out = Malloc(length + 1); + memset(*out, '\0', length + 1); + memcpy(*out, start, length); + + return 1; +fail: + *str = start; + return 0; +} +static int +ParseHostname(char **str, char **out) +{ + char *start; + size_t length = 0; + char c; + + start = *str; + while ((c = Iterate(str)) && + (isalnum(c) || c == '.' || c == '-') && + ++length < 256) + { + /* Do nothing. */ + } + if (length < 1 || length > 255) + { + *str = start; + return 0; + } + length = (size_t) (*str - start) - 1; + *out = Malloc(length + 1); + memcpy(*out, start, length); + (*str)--; + return 1; +} + +static int +ParseServerName(char **str, ServerPart *out) +{ + char c; + char *start; + char *startPort; + size_t chars = 0; + + char *host = NULL; + char *port = NULL; + + if (!str || !out) + { + return 0; + } + + start = *str; + + if (!host) + { + /* If we can parse an IPv4 address, use that. */ + ParseIPv4(str, &host); + } + if (!host) + { + /* If we can parse an IPv6 address, use that. */ + ParseIPv6(str, &host); + } + if (!host) + { + /* If we can parse an hostname, use that. */ + ParseHostname(str, &host); + } + if (!host) + { + /* Can't parse a valid server name. */ + return 0; + } + /* Now, there's only 2 options: a ':', or the end(everything else.) */ + if (**str != ':') + { + /* We're done. */ + out->hostname = host; + out->port = NULL; + return 1; + } + /* TODO: Separate this out */ + startPort = ++(*str); + while(isdigit(c = Iterate(str)) && c && ++chars < 5) + { + /* Do nothing. */ + } + if (chars < 1 || chars > 5) + { + *str = start; + Free(host); + host = NULL; + return 0; + } + + port = Malloc(chars + 1); + memcpy(port, startPort, chars); + port[chars] = '\0'; + if (atol(port) > 65535) + { + Free(port); + Free(host); + *str = start; + return 0; + } + + out->hostname = host; + out->port = port; + + return 1; +} +int +ParseServerPart(char *str, ServerPart *part) +{ + /* This is a wrapper behind the internal ParseServerName. */ + if (!str || !part) + { + return 0; + } + return ParseServerName(&str, part); +} +void +ServerPartFree(ServerPart part) +{ + if (part.hostname) + { + Free(part.hostname); + } + if (part.port) + { + Free(part.port); + } +} + +int +ParseCommonID(char *str, CommonID *id) +{ + char sigil; + + if (!str || !id) + { + return 0; + } + + /* There must at least be 2 chararacters: the sigil and a string.*/ + if (strlen(str) < 2) + { + return 0; + } + + sigil = *str++; + /* Some sigils have the following restriction: + * > MUST NOT exceed 255 bytes (including the # sigil and the domain). + */ + if ((sigil == '#' || sigil == '@') && strlen(str) > 255) + { + return 0; + } + id->sigil = sigil; + id->local = NULL; + id->server.hostname = NULL; + id->server.port = NULL; + + switch (sigil) + { + case '$': + /* For event IDs, it depends on the version, so we're just + * accepting it all. */ + if (!ParseUserLocalpart(&str, &id->local)) + { + return 0; + } + if (*str == ':') + { + (*str)++; + if (!ParseServerName(&str, &id->server)) + { + Free(id->local); + id->local = NULL; + return 0; + } + return 1; + } + break; + case '!': + case '#': /* It seems like the localpart should be the same as the + user's: everything, except ':'. */ + case '@': + if (!ParseUserLocalpart(&str, &id->local)) + { + return 0; + } + if (*str++ != ':') + { + Free(id->local); + id->local = NULL; + return 0; + } + if (!ParseServerName(&str, &id->server)) + { + Free(id->local); + id->local = NULL; + return 0; + } + break; + } + return 1; +} + +void +CommonIDFree(CommonID id) +{ + if (id.local) + { + Free(id.local); + } + ServerPartFree(id.server); +} +int +ValidCommonID(char *str, char sigil) +{ + CommonID id; + int ret; + memset(&id, 0, sizeof(CommonID)); + if (!str) + { + return 0; + } + + ret = ParseCommonID(str, &id) && id.sigil == sigil; + + CommonIDFree(id); + return ret; +} +char * +ParserRecomposeServerPart(ServerPart serverPart) +{ + if (serverPart.hostname && serverPart.port) + { + return StrConcat(3, serverPart.hostname, ":", serverPart.port); + } + if (serverPart.hostname) + { + return StrDuplicate(serverPart.hostname); + } + return NULL; +} +char * +ParserRecomposeCommonID(CommonID id) +{ + char *ret = Malloc(2 * sizeof(char)); + ret[0] = id.sigil; + ret[1] = '\0'; + + if (id.local) + { + char *tmp = StrConcat(2, ret, id.local); + Free(ret); + + ret = tmp; + } + if (id.server.hostname) + { + char *server = ParserRecomposeServerPart(id.server); + char *tmp = StrConcat(4, "@", ret, ":", server); + Free(ret); + Free(server); + + ret = tmp; + } + return ret; +} +int +ParserServerNameEquals(ServerPart serverPart, char *str) +{ + char *idServer; + int ret; + if (!str) + { + return 0; + } + idServer = ParserRecomposeServerPart(serverPart); + + ret = StrEquals(idServer, str); + Free(idServer); + + return ret; +} diff --git a/src/Routes/RouteAliasDirectory.c b/src/Routes/RouteAliasDirectory.c index b1ae042..2a93b1c 100644 --- a/src/Routes/RouteAliasDirectory.c +++ b/src/Routes/RouteAliasDirectory.c @@ -25,8 +25,12 @@ #include +#include #include #include + +#include +#include #include ROUTE_IMPL(RouteAliasDirectory, path, argp) @@ -38,20 +42,40 @@ ROUTE_IMPL(RouteAliasDirectory, path, argp) HashMap *response; Db *db = args->matrixArgs->db; - DbRef *ref; + DbRef *ref = NULL; HashMap *aliases; + HashMap *idObject; JsonValue *val; + Array *arr; char *token; + char *msg; User *user = NULL; - /* TODO: Return HTTP 400 M_INVALID_PARAM if alias is invalid */ + CommonID aliasID; + Config config; + + aliasID.sigil = '\0'; + aliasID.local = NULL; + aliasID.server.hostname = NULL; + aliasID.server.port = NULL; + + ConfigLock(db, &config); + + if (!ParseCommonID(alias, &aliasID) || aliasID.sigil != '#') + { + msg = "Invalid room alias."; + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_INVALID_PARAM, msg); + goto finish; + } ref = DbLock(db, 1, "aliases"); if (!ref && !(ref = DbCreate(db, 1, "aliases"))) { + msg = "Unable to access alias database.", HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR); - response = MatrixErrorCreate(M_UNKNOWN, "Unable to access alias database."); + response = MatrixErrorCreate(M_UNKNOWN, msg); goto finish; } @@ -69,8 +93,9 @@ ROUTE_IMPL(RouteAliasDirectory, path, argp) } else { + msg = "There is no mapped room ID for this room alias."; HttpResponseStatus(args->context, HTTP_NOT_FOUND); - response = MatrixErrorCreate(M_NOT_FOUND, "There is no mapped room ID for this room alias."); + response = MatrixErrorCreate(M_NOT_FOUND, msg); } break; case HTTP_PUT: @@ -92,9 +117,21 @@ ROUTE_IMPL(RouteAliasDirectory, path, argp) if (HttpRequestMethodGet(args->context) == HTTP_PUT) { HashMap *newAlias; + char *id; + char *serverPart; - /* TODO: Validate alias domain and make sure it matches - * server name and is well formed. */ + serverPart = ParserRecomposeServerPart(aliasID.server); + if (!StrEquals(serverPart, config.serverName)) + { + msg = "Invalid server name."; + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_INVALID_PARAM, msg); + + Free(serverPart); + goto finish; + } + + Free(serverPart); if (JsonGet(aliases, 2, "alias", alias)) { @@ -111,40 +148,81 @@ ROUTE_IMPL(RouteAliasDirectory, path, argp) goto finish; } - if (!JsonValueAsString(HashMapGet(request, "room_id"))) + id = JsonValueAsString(HashMapGet(request, "room_id")); + if (!id) { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); response = MatrixErrorCreate(M_BAD_JSON, "Missing or invalid room_id."); goto finish; } - - /* TODO: Validate room ID to make sure it is well - * formed. */ + + if (!ValidCommonID(id, '!')) + { + msg = "Invalid room ID."; + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_INVALID_PARAM, msg); + goto finish; + } newAlias = HashMapCreate(); HashMapSet(newAlias, "createdBy", JsonValueString(UserGetName(user))); - HashMapSet(newAlias, "id", JsonValueDuplicate(HashMapGet(request, "room_id"))); + HashMapSet(newAlias, "id", JsonValueString(id)); HashMapSet(newAlias, "servers", JsonValueArray(ArrayCreate())); JsonSet(aliases, JsonValueObject(newAlias), 2, "alias", alias); + + if (!(idObject = JsonValueAsObject(JsonGet(aliases, 2, "id", id)))) + { + arr = ArrayCreate(); + idObject = HashMapCreate(); + HashMapSet(idObject, "aliases", JsonValueArray(arr)); + JsonSet(aliases, JsonValueObject(idObject), 2, "id", id); + } + val = HashMapGet(idObject, "aliases"); + arr = JsonValueAsArray(val); + ArrayAdd(arr, JsonValueString(alias)); + } else { - if (!JsonGet(aliases, 2, "alias", alias)) + HashMap *roomAlias; + char *id; + + if (!(val = JsonGet(aliases, 2, "alias", alias))) { HttpResponseStatus(args->context, HTTP_NOT_FOUND); response = MatrixErrorCreate(M_NOT_FOUND, "Room alias not found."); goto finish; } + roomAlias = JsonValueAsObject(val); + id = StrDuplicate(JsonValueAsString(HashMapGet(roomAlias, "id"))); - if (!(UserGetPrivileges(user) & USER_ALIAS) && !StrEquals(UserGetName(user), JsonValueAsString(JsonGet(aliases, 3, "alias", alias, "createdBy")))) + if (!(UserGetPrivileges(user) & USER_ALIAS) && !StrEquals(UserGetName(user), JsonValueAsString(JsonGet(roomAlias, 1, "createdBy")))) { HttpResponseStatus(args->context, HTTP_UNAUTHORIZED); response = MatrixErrorCreate(M_UNAUTHORIZED, NULL); + Free(id); goto finish; } JsonValueFree(HashMapDelete(JsonValueAsObject(HashMapGet(aliases, "alias")), alias)); + + idObject = JsonValueAsObject(JsonGet(aliases, 2, "id", id)); + if (idObject) + { + size_t i; + val = HashMapGet(idObject, "aliases"); + arr = JsonValueAsArray(val); + for (i = 0; i < ArraySize(arr); i++) + { + if (StrEquals(JsonValueAsString(ArrayGet(arr, i)), alias)) + { + JsonValueFree(ArrayDelete(arr, i)); + break; + } + } + } + Free(id); } response = HashMapCreate(); @@ -156,6 +234,8 @@ ROUTE_IMPL(RouteAliasDirectory, path, argp) } finish: + CommonIDFree(aliasID); + ConfigUnlock(&config); UserUnlock(user); DbUnlock(db, ref); JsonFree(request); diff --git a/src/Routes/RouteFilter.c b/src/Routes/RouteFilter.c index c2ead37..c8f4fa8 100644 --- a/src/Routes/RouteFilter.c +++ b/src/Routes/RouteFilter.c @@ -64,7 +64,7 @@ ROUTE_IMPL(RouteFilter, path, argp) HashMap *response = NULL; User *user = NULL; - UserId *id = NULL; + CommonID *id = NULL; char *token = NULL; char *serverName = NULL; @@ -97,7 +97,7 @@ ROUTE_IMPL(RouteFilter, path, argp) goto finish; } - if (!StrEquals(id->server, serverName)) + if (!ParserServerNameEquals(id->server, serverName)) { msg = "Cannot use /filter for non-local users."; HttpResponseStatus(args->context, HTTP_UNAUTHORIZED); @@ -119,7 +119,7 @@ ROUTE_IMPL(RouteFilter, path, argp) goto finish; } - if (!StrEquals(id->localpart, UserGetName(user))) + if (!StrEquals(id->local, UserGetName(user))) { msg = "Unauthorized to use /filter."; HttpResponseStatus(args->context, HTTP_UNAUTHORIZED); diff --git a/src/Routes/RouteLogin.c b/src/Routes/RouteLogin.c index 158629d..6234f15 100644 --- a/src/Routes/RouteLogin.c +++ b/src/Routes/RouteLogin.c @@ -49,7 +49,7 @@ ROUTE_IMPL(RouteLogin, path, argp) LoginRequest loginRequest; LoginRequestUserIdentifier userIdentifier; - UserId *userId = NULL; + CommonID *userId = NULL; Db *db = args->matrixArgs->db; @@ -160,8 +160,8 @@ ROUTE_IMPL(RouteLogin, path, argp) break; } - if (!StrEquals(userId->server, config.serverName) - || !UserExists(db, userId->localpart)) + if (!ParserServerNameEquals(userId->server, config.serverName) + || !UserExists(db, userId->local)) { msg = "Unknown user ID."; HttpResponseStatus(args->context, HTTP_FORBIDDEN); @@ -175,7 +175,7 @@ ROUTE_IMPL(RouteLogin, path, argp) password = loginRequest.password; refreshToken = loginRequest.refresh_token; - user = UserLock(db, userId->localpart); + user = UserLock(db, userId->local); if (!user) { diff --git a/src/Routes/RouteRoomAliases.c b/src/Routes/RouteRoomAliases.c index 25a080a..2fa97bf 100644 --- a/src/Routes/RouteRoomAliases.c +++ b/src/Routes/RouteRoomAliases.c @@ -25,25 +25,80 @@ #include +#include #include +#include + +#include +#include ROUTE_IMPL(RouteRoomAliases, path, argp) { RouteArgs *args = argp; char *roomId = ArrayGet(path, 0); + char *token; + char *msg; - HashMap *request = NULL; HashMap *response = NULL; + HashMap *aliases = NULL; + HashMap *reversealias = NULL; + + JsonValue *val; Db *db = args->matrixArgs->db; DbRef *ref = NULL; - (void) roomId; + User *user = NULL; - /* TODO: Placeholder; remove. */ - goto finish; + if (HttpRequestMethodGet(args->context) != HTTP_GET) + { + msg = "Route only accepts GET."; + HttpResponseStatus(args->context, HTTP_FORBIDDEN); + response = MatrixErrorCreate(M_FORBIDDEN, msg); + goto finish; + } + + response = MatrixGetAccessToken(args->context, &token); + if (response) + { + goto finish; + } + user = UserAuthenticate(db, token); + if (!user) + { + HttpResponseStatus(args->context, HTTP_UNAUTHORIZED); + response = MatrixErrorCreate(M_UNKNOWN_TOKEN, NULL); + goto finish; + } + + /* TODO: Check whenever the user is in the room or if its world readable + * once this is implemented instead of just checking for the ALIAS + * privilege. */ + if (!(UserGetPrivileges(user) & USER_ALIAS)) + { + msg = "User is not allowed to get this room's aliases."; + HttpResponseStatus(args->context, HTTP_FORBIDDEN); + response = MatrixErrorCreate(M_FORBIDDEN, msg); + goto finish; + } + + ref = DbLock(db, 1, "aliases"); + aliases = DbJson(ref); + reversealias = JsonValueAsObject(JsonGet(aliases, 2, "id", roomId)); + if (!reversealias) + { + /* We do not know about the room ID. */ + msg = "Unknown room ID."; + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_INVALID_PARAM, msg); + goto finish; + } + + response = HashMapCreate(); + val = JsonGet(reversealias, 1, "aliases"); + HashMapSet(response, "aliases", JsonValueDuplicate(val)); finish: DbUnlock(db, ref); - JsonFree(request); + UserUnlock(user); return response; } diff --git a/src/Routes/RouteUserProfile.c b/src/Routes/RouteUserProfile.c index 5c1af7b..4c438b0 100644 --- a/src/Routes/RouteUserProfile.c +++ b/src/Routes/RouteUserProfile.c @@ -40,7 +40,7 @@ ROUTE_IMPL(RouteUserProfile, path, argp) HashMap *request = NULL; HashMap *response = NULL; - UserId *userId = NULL; + CommonID *userId = NULL; User *user = NULL; char *serverName; @@ -73,7 +73,7 @@ ROUTE_IMPL(RouteUserProfile, path, argp) response = MatrixErrorCreate(M_INVALID_PARAM, msg); goto finish; } - if (strcmp(userId->server, serverName)) + if (!ParserServerNameEquals(userId->server, serverName)) { /* TODO: Implement lookup over federation. */ msg = "User profile endpoint currently doesn't support lookup over " @@ -87,7 +87,7 @@ ROUTE_IMPL(RouteUserProfile, path, argp) switch (HttpRequestMethodGet(args->context)) { case HTTP_GET: - user = UserLock(db, userId->localpart); + user = UserLock(db, userId->local); if (!user) { msg = "Couldn't lock user."; @@ -147,11 +147,11 @@ ROUTE_IMPL(RouteUserProfile, path, argp) StrEquals(entry, "avatar_url")) { /* Check if user has privilege to do that action. */ - if (StrEquals(userId->localpart, UserGetName(user))) + if (StrEquals(userId->local, UserGetName(user))) { value = JsonValueAsString(HashMapGet(request, entry)); - /* TODO: Make UserSetProfile notify other - * parties of the change */ + /* TODO: Make UserSetProfile notify other parties of + * the change */ UserSetProfile(user, entry, value); response = HashMapCreate(); goto finish; diff --git a/src/Routes/RouteVersions.c b/src/Routes/RouteVersions.c index 12dcbb4..08560c3 100644 --- a/src/Routes/RouteVersions.c +++ b/src/Routes/RouteVersions.c @@ -37,9 +37,14 @@ ROUTE_IMPL(RouteVersions, path, argp) (void) argp; #define DECLARE_SPEC_VERSION(x) ArrayAdd(versions, JsonValueString(x)) + DECLARE_SPEC_VERSION("v1.2"); + DECLARE_SPEC_VERSION("v1.3"); + DECLARE_SPEC_VERSION("v1.4"); + DECLARE_SPEC_VERSION("v1.5"); + DECLARE_SPEC_VERSION("v1.6"); + /* The curently supported version. */ DECLARE_SPEC_VERSION("v1.7"); - /* Declare additional spec version support here. */ #undef DECLARE_SPEC_VERSION diff --git a/src/Routes/RouteWhoami.c b/src/Routes/RouteWhoami.c index b98df15..cfd8ee8 100644 --- a/src/Routes/RouteWhoami.c +++ b/src/Routes/RouteWhoami.c @@ -43,7 +43,6 @@ ROUTE_IMPL(RouteWhoami, path, argp) char *token; char *userID; char *deviceID; - char *msg; Config config; diff --git a/src/Uia.c b/src/Uia.c index 2c0abb8..8c83440 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -351,7 +351,7 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db, char *password = JsonValueAsString(HashMapGet(auth, "password")); HashMap *identifier = JsonValueAsObject(HashMapGet(auth, "identifier")); char *type; - UserId *userId; + CommonID *userId; User *user; if (!password || !identifier) @@ -366,7 +366,8 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db, config.serverName); if (!type || !StrEquals(type, "m.id.user") - || !userId || !StrEquals(userId->server, config.serverName)) + || !userId + || !ParserServerNameEquals(userId->server, config.serverName)) { HttpResponseStatus(context, HTTP_UNAUTHORIZED); ret = BuildResponse(flows, db, response, session, dbRef); @@ -374,7 +375,7 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db, goto finish; } - user = UserLock(db, userId->localpart); + user = UserLock(db, userId->local); if (!user) { HttpResponseStatus(context, HTTP_UNAUTHORIZED); diff --git a/src/User.c b/src/User.c index 9e36239..1fc872d 100644 --- a/src/User.c +++ b/src/User.c @@ -31,6 +31,8 @@ #include #include +#include + #include struct User @@ -882,10 +884,11 @@ finish: return arr; } -UserId * +CommonID * UserIdParse(char *id, char *defaultServer) { - UserId *userId; + CommonID *userId; + char *server; if (!id) { @@ -898,48 +901,38 @@ UserIdParse(char *id, char *defaultServer) return NULL; } - userId = Malloc(sizeof(UserId)); + userId = Malloc(sizeof(CommonID)); if (!userId) { goto finish; } + memset(userId, 0, sizeof(CommonID)); /* Fully-qualified user ID */ if (*id == '@') { - char *localStart = id + 1; - char *serverStart = localStart; - - while (*serverStart != ':' && *serverStart != '\0') + if (!ParseCommonID(id, userId) || !userId->server.hostname) { - serverStart++; - } + UserIdFree(userId); - if (*serverStart == '\0') - { - Free(userId); userId = NULL; goto finish; } - - *serverStart = '\0'; - serverStart++; - - userId->localpart = StrDuplicate(localStart); - userId->server = StrDuplicate(serverStart); } else { /* Treat it as just a localpart */ - userId->localpart = StrDuplicate(id); - userId->server = StrDuplicate(defaultServer); + userId->local = StrDuplicate(id); + ParseServerPart(defaultServer, &userId->server); } - if (!UserHistoricalValidate(userId->localpart, userId->server)) + server = ParserRecomposeServerPart(userId->server); + if (!UserHistoricalValidate(userId->local, server)) { UserIdFree(userId); userId = NULL; } + Free(server); finish: Free(id); @@ -947,12 +940,11 @@ finish: } void -UserIdFree(UserId * id) +UserIdFree(CommonID * id) { if (id) { - Free(id->localpart); - Free(id->server); + CommonIDFree(*id); Free(id); } } diff --git a/src/include/Parser.h b/src/include/Parser.h new file mode 100644 index 0000000..a4cadfa --- /dev/null +++ b/src/include/Parser.h @@ -0,0 +1,106 @@ +/* + * 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 + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef TELODENDRIA_PARSER_H +#define TELODENDRIA_PARSER_H + +/*** + * @Nm Parser + * @Nd Functions for dealing with grammars found in Matrix + * @Dd November 25 2023 + * @Xr User + * + * The + * .Nm + * API provides an interface for parsing grammars within the + * Matrix specification + */ + +/** + * The host[:port] format in a servername. + */ +typedef struct ServerPart { + char *hostname; + char *port; +} ServerPart; +/** + * A common identifier in the form '&local[:server]', where & determines the + * *type* of the identifier. + */ +typedef struct CommonID { + char sigil; + char *local; + ServerPart server; +} CommonID; + +/** + * Parses a common identifier, as per the Common Identifier Format as defined + * by the [matrix] specification. + */ +extern int ParseCommonID(char *, CommonID *); + +/** + * Parses the server part in a common identifier. + */ +extern int ParseServerPart(char *, ServerPart *); + +/** + * Checks whenever the string is a valid common ID with the correct sigil. + */ +extern int ValidCommonID(char *, char); + +/** + * Frees a CommonID's values. Note that it doesn't free the CommonID itself. + */ +extern void CommonIDFree(CommonID); + +/** + * Frees a ServerPart's values. Note that it doesn't free the ServerPart + * itself, and that + * .Fn CommonIDFree + * automatically deals with its server part. + */ +extern void ServerPartFree(ServerPart); + +/** + * Recompose a Common ID into a string which lives in the heap, and must + * therefore be freed with + * .Fn Free . + */ +extern char * ParserRecomposeCommonID(CommonID); + +/** + * Recompose a server part into a string which lives in the heap, and must + * therefore be freed with + * .Fn Free . + */ +extern char * ParserRecomposeServerPart(ServerPart); + +/** + * Compares whenever a ServerName is equivalent to a server name string. + */ +extern int ParserServerNameEquals(ServerPart, char *); + + +#endif /* TELODENDRIA_PARSER_H */ diff --git a/src/include/User.h b/src/include/User.h index 6eb5530..f84ac94 100644 --- a/src/include/User.h +++ b/src/include/User.h @@ -43,6 +43,8 @@ #include #include +#include + /** * Many functions here operate on an opaque user structure. */ @@ -88,15 +90,6 @@ typedef struct UserLoginInfo char *refreshToken; } UserLoginInfo; -/** - * A description of a Matrix user ID. - */ -typedef struct UserId -{ - char *localpart; - char *server; -} UserId; - /** * Take a localpart and domain as separate parameters and validate them * against the rules of the Matrix specification. The reasion the @@ -303,15 +296,15 @@ extern Array *UserEncodePrivileges(int); extern int UserDecodePrivilege(const char *); /** - * Parse either a localpart or a fully qualified Matrix ID. If the + * Parse either a localpart or a fully qualified Matrix common ID. If the * first argument is a localpart, then the second argument is used as * the server name. */ -extern UserId * UserIdParse(char *, char *); +extern CommonID * UserIdParse(char *, char *); /** - * Free the memory associated with the parsed Matrix ID. + * Frees the user's common ID and the memory allocated for it. */ -extern void UserIdFree(UserId *); +extern void UserIdFree(CommonID *); #endif /* TELODENDRIA_USER_H */ From ac7ea4dec11b40f484366578eb44ea649f6f6b9f Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 09:51:14 -0500 Subject: [PATCH 08/23] Add docs/dev/hosting.md --- docs/dev/hosting.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/dev/hosting.md diff --git a/docs/dev/hosting.md b/docs/dev/hosting.md new file mode 100644 index 0000000..f877a01 --- /dev/null +++ b/docs/dev/hosting.md @@ -0,0 +1,35 @@ +# 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 node 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. +6. Run `./act_runner register` to register the runner. When prompted for the tags, follow following convention: + - **Linux Distros:** `linux`, `-v`, `` + - **BSD Derivatives:** `bsd`, `-v`, `` + - **Windows:** `windows`, `windows-v`, `` + - **MacOS:** `macos`, `macos-v`, `` + - **Others:** `other`, `-v`, `` + + Where `` is one of `x86` or `x64` for now. ARM runners will be a future project. From 2e92daeb002114239b446cd8e458d1b4208a17e9 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 10:06:06 -0500 Subject: [PATCH 09/23] Update docs/dev/hosting.md --- docs/dev/hosting.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/dev/hosting.md b/docs/dev/hosting.md index f877a01..adf422c 100644 --- a/docs/dev/hosting.md +++ b/docs/dev/hosting.md @@ -24,7 +24,7 @@ The general sequence of steps required for setting up a CI runner is as follows: - **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. +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`, `-v`, `` - **BSD Derivatives:** `bsd`, `-v`, `` @@ -33,3 +33,4 @@ The general sequence of steps required for setting up a CI runner is as follows: - **Others:** `other`, `-v`, `` Where `` is one of `x86` or `x64` for now. ARM runners will be a future project. +7. Run `./act_runner daemon`. \ No newline at end of file From 258f5094135968742b0aa4631298b9d9cc120a19 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 10:09:39 -0500 Subject: [PATCH 10/23] Update docs/dev/hosting.md --- docs/dev/hosting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/hosting.md b/docs/dev/hosting.md index adf422c..be1c72a 100644 --- a/docs/dev/hosting.md +++ b/docs/dev/hosting.md @@ -15,7 +15,7 @@ The general sequence of steps required for setting up a CI runner is as follows: Run these commands to install the packages: - **OpenBSD:** `pkg_add git go node` - **FreeBSD:** `pkg install git go node` - - **NetBSD:** `pkgin install git go node openssl mozilla-rootcerts-openssl` + - **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` From f2a4a64b27ec0f6e1a3fa78dbd7f1ba665600f23 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 18:05:00 -0500 Subject: [PATCH 11/23] Add Cytoplasm as a submodule of Telodendria. --- .gitmodules | 3 +++ Cytoplasm | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 Cytoplasm diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d834568 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Cytoplasm"] + path = Cytoplasm + url = https://git.telodendria.io/Telodendria/Cytoplasm.git diff --git a/Cytoplasm b/Cytoplasm new file mode 160000 index 0000000..039a487 --- /dev/null +++ b/Cytoplasm @@ -0,0 +1 @@ +Subproject commit 039a487bdfc2b526141fb537a1efc7bc186d5d5b From e62389aa140670f08a53a76ccd7bc3da8cf90fe4 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:02:07 -0500 Subject: [PATCH 12/23] Make Telodendria compatible with latest Cytoplasm. This also brings Telodendria to C99 compliance. --- src/Config.c | 21 +++--- src/Main.c | 11 +-- src/Parser.c | 101 ++++++++++++++++------------ src/RegToken.c | 24 +++---- src/Routes/RouteProcControl.c | 16 +---- src/Routes/RouteRequestToken.c | 6 +- src/Telodendria.c | 2 +- src/Uia.c | 8 +-- src/User.c | 119 ++++++++++++++++----------------- src/include/Parser.h | 10 +-- src/include/RegToken.h | 3 +- src/include/User.h | 31 ++++----- tools/src/json.c | 30 +-------- 13 files changed, 175 insertions(+), 207 deletions(-) diff --git a/src/Config.c b/src/Config.c index 1f7a9f7..5c87c85 100644 --- a/src/Config.c +++ b/src/Config.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -59,7 +58,7 @@ ConfigParse(HashMap * config, Config *tConfig) memset(tConfig, 0, sizeof(Config)); - tConfig->maxCache = Int64Create(0, 0); + tConfig->maxCache = 0; if (!ConfigFromJson(config, tConfig, &tConfig->err)) { @@ -85,17 +84,17 @@ ConfigParse(HashMap * config, Config *tConfig) for (i = 0; i < ArraySize(tConfig->listen); i++) { ConfigListener *listener = ArrayGet(tConfig->listen, i); - if (Int64Eq(listener->maxConnections, Int64Create(0, 0))) + if (!listener->maxConnections) { - listener->maxConnections = Int64Create(0, 32); + listener->maxConnections = 32; } - if (Int64Eq(listener->threads, Int64Create(0, 0))) + if (!listener->threads) { - listener->threads = Int64Create(0, 4); + listener->threads = 4; } - if (Int64Eq(listener->port, Int64Create(0, 0))) + if (!listener->port) { - listener->port = Int64Create(0, 8008); + listener->port = 8008; } } tConfig->ok = 1; @@ -148,9 +147,9 @@ ConfigCreateDefault(Db * db) /* Add simple listener without TLS. */ config.listen = ArrayCreate(); listener = Malloc(sizeof(ConfigListener)); - listener->maxConnections = Int64Create(0, 32); - listener->port = Int64Create(0, 8008); - listener->threads = Int64Create(0, 4); + listener->maxConnections = 32; + listener->port = 8008; + listener->threads = 4; ArrayAdd(config.listen, listener); diff --git a/src/Main.c b/src/Main.c index 6865bc1..a4e2880 100644 --- a/src/Main.c +++ b/src/Main.c @@ -36,14 +36,12 @@ #include #include -#include #include #include #include #include #include #include -#include #include #include @@ -52,6 +50,9 @@ #include #include #include +#include +#include + static Array *httpServers; static volatile int restart; @@ -248,7 +249,7 @@ start: } token = StrRandom(32); - info = RegTokenCreate(matrixArgs.db, token, NULL, UInt64Create(0, 0), Int64Create(0, 1), USER_ALL); + info = RegTokenCreate(matrixArgs.db, token, NULL, /* expires */ 0, /* uses */ 1, USER_ALL); if (!info) { Free(token); @@ -396,14 +397,14 @@ start: if (args.flags & HTTP_FLAG_TLS) { - if (UInt64Eq(UtilLastModified(serverCfg->tls.cert), UInt64Create(0, 0))) + if (!UtilLastModified(serverCfg->tls.cert)) { Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tls.cert); exit = EXIT_FAILURE; goto finish; } - if (UInt64Eq(UtilLastModified(serverCfg->tls.key), UInt64Create(0, 0))) + if (UtilLastModified(serverCfg->tls.key)) { Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tls.key); exit = EXIT_FAILURE; diff --git a/src/Parser.c b/src/Parser.c index 982fb5c..f003b4c 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -38,7 +37,7 @@ #define Iterate(s) (*(*s)++) /* Parse an extended localpart */ -static int +static bool ParseUserLocalpart(char **str, char **out) { char c; @@ -47,7 +46,7 @@ ParseUserLocalpart(char **str, char **out) if (!str || !out) { - return 0; + return false; } /* An extended localpart contains every ASCII printable character, * except an ':'. */ @@ -60,7 +59,7 @@ ParseUserLocalpart(char **str, char **out) if (length < 1) { *str = start; - return 0; + return false; } if (c == ':') { @@ -71,8 +70,9 @@ ParseUserLocalpart(char **str, char **out) memcpy(*out, start, length); (*out)[length] = '\0'; - return 1; + return true; } + /* Parses an IPv4 address. */ static int ParseIPv4(char **str, char **out) @@ -102,14 +102,14 @@ ParseIPv4(char **str, char **out) { /* Current digit is too long for the spec! */ *str = start; - return 0; + return false; } memcpy(buffer, *str - digit - 1, digit); if (atoi(buffer) > 255) { /* Current digit is too large for the spec! */ *str = start; - return 0; + return false; } memset(buffer, 0, sizeof(buffer)); digit = 0; @@ -118,20 +118,22 @@ ParseIPv4(char **str, char **out) if (c == '.' || digits != 3) { *str = start; - return 0; + return false; } length = (size_t) (*str - start) - 1; *out = Malloc(length + 1); memcpy(*out, start, length); (*str)--; - return 1; + return true; } -static int + +static bool IsIPv6Char(char c) { - return isxdigit(c) || c == ':' || c == '.'; + return (isxdigit(c) || c == ':' || c == '.'); } -static int + +static bool ParseIPv6(char **str, char **out) { char *start; @@ -174,7 +176,7 @@ ParseIPv6(char **str, char **out) /* RFC3513 says the following: * > 'The "::" can only appear once in an address.' */ *str = start; - return 0; + return false; } if (digit < 1 || digit > 4) { @@ -217,12 +219,13 @@ end: memset(*out, '\0', length + 1); memcpy(*out, start, length); - return 1; + return true; fail: *str = start; - return 0; + return false; } -static int + +static bool ParseHostname(char **str, char **out) { char *start; @@ -239,16 +242,16 @@ ParseHostname(char **str, char **out) if (length < 1 || length > 255) { *str = start; - return 0; + return false; } length = (size_t) (*str - start) - 1; *out = Malloc(length + 1); memcpy(*out, start, length); (*str)--; - return 1; + return true; } -static int +static bool ParseServerName(char **str, ServerPart *out) { char c; @@ -261,7 +264,7 @@ ParseServerName(char **str, ServerPart *out) if (!str || !out) { - return 0; + return false; } start = *str; @@ -284,7 +287,7 @@ ParseServerName(char **str, ServerPart *out) if (!host) { /* Can't parse a valid server name. */ - return 0; + return false; } /* Now, there's only 2 options: a ':', or the end(everything else.) */ if (**str != ':') @@ -292,7 +295,7 @@ ParseServerName(char **str, ServerPart *out) /* We're done. */ out->hostname = host; out->port = NULL; - return 1; + return true; } /* TODO: Separate this out */ startPort = ++(*str); @@ -305,7 +308,7 @@ ParseServerName(char **str, ServerPart *out) *str = start; Free(host); host = NULL; - return 0; + return false; } port = Malloc(chars + 1); @@ -316,24 +319,26 @@ ParseServerName(char **str, ServerPart *out) Free(port); Free(host); *str = start; - return 0; + return false; } out->hostname = host; out->port = port; - return 1; + return true; } -int + +bool ParseServerPart(char *str, ServerPart *part) { /* This is a wrapper behind the internal ParseServerName. */ if (!str || !part) { - return 0; + return false; } return ParseServerName(&str, part); } + void ServerPartFree(ServerPart part) { @@ -347,20 +352,20 @@ ServerPartFree(ServerPart part) } } -int +bool ParseCommonID(char *str, CommonID *id) { char sigil; if (!str || !id) { - return 0; + return false; } /* There must at least be 2 chararacters: the sigil and a string.*/ if (strlen(str) < 2) { - return 0; + return false; } sigil = *str++; @@ -369,7 +374,7 @@ ParseCommonID(char *str, CommonID *id) */ if ((sigil == '#' || sigil == '@') && strlen(str) > 255) { - return 0; + return false; } id->sigil = sigil; id->local = NULL; @@ -383,7 +388,7 @@ ParseCommonID(char *str, CommonID *id) * accepting it all. */ if (!ParseUserLocalpart(&str, &id->local)) { - return 0; + return false; } if (*str == ':') { @@ -392,9 +397,9 @@ ParseCommonID(char *str, CommonID *id) { Free(id->local); id->local = NULL; - return 0; + return false; } - return 1; + return true; } break; case '!': @@ -403,23 +408,23 @@ ParseCommonID(char *str, CommonID *id) case '@': if (!ParseUserLocalpart(&str, &id->local)) { - return 0; + return false; } if (*str++ != ':') { Free(id->local); id->local = NULL; - return 0; + return false; } if (!ParseServerName(&str, &id->server)) { Free(id->local); id->local = NULL; - return 0; + return false; } break; } - return 1; + return true; } void @@ -431,15 +436,18 @@ CommonIDFree(CommonID id) } ServerPartFree(id.server); } -int + +bool ValidCommonID(char *str, char sigil) { CommonID id; - int ret; + bool ret; + memset(&id, 0, sizeof(CommonID)); + if (!str) { - return 0; + return false; } ret = ParseCommonID(str, &id) && id.sigil == sigil; @@ -447,6 +455,7 @@ ValidCommonID(char *str, char sigil) CommonIDFree(id); return ret; } + char * ParserRecomposeServerPart(ServerPart serverPart) { @@ -460,6 +469,7 @@ ParserRecomposeServerPart(ServerPart serverPart) } return NULL; } + char * ParserRecomposeCommonID(CommonID id) { @@ -485,15 +495,18 @@ ParserRecomposeCommonID(CommonID id) } return ret; } -int + +bool ParserServerNameEquals(ServerPart serverPart, char *str) { char *idServer; - int ret; + bool ret; + if (!str) { - return 0; + return false; } + idServer = ParserRecomposeServerPart(serverPart); ret = StrEquals(idServer, str); diff --git a/src/RegToken.c b/src/RegToken.c index 0e018c2..4b89e8b 100644 --- a/src/RegToken.c +++ b/src/RegToken.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -40,9 +39,9 @@ int RegTokenValid(RegTokenInfo * token) { HashMap *tokenJson; - Int64 uses, used; + int64_t uses, used; - UInt64 expiration; + uint64_t expiration; if (!token || !RegTokenExists(token->db, token->name)) { @@ -54,9 +53,7 @@ RegTokenValid(RegTokenInfo * token) used = JsonValueAsInteger(HashMapGet(tokenJson, "used")); expiration = JsonValueAsInteger(HashMapGet(tokenJson, "expires_on")); - return (UInt64Eq(expiration, UInt64Create(0, 0)) || - UInt64Geq(UtilServerTs(), expiration)) && - (Int64Eq(uses, Int64Neg(Int64Create(0, 1))) || Int64Lt(used, uses)); + return (!expiration || (UtilTsMillis() < expiration)) && (uses == -1 || used < uses); } void RegTokenUse(RegTokenInfo * token) @@ -68,13 +65,12 @@ RegTokenUse(RegTokenInfo * token) return; } - if (Int64Geq(token->uses, Int64Create(0, 0)) && - Int64Geq(token->used, token->uses)) + if (token->uses >= 0 && token->used >= token->uses) { return; } - token->used = Int64Add(token->used, Int64Create(0, 1)); + token->used++; /* Write the information to the hashmap */ tokenJson = DbJson(token->ref); @@ -199,11 +195,11 @@ RegTokenVerify(char *token) } RegTokenInfo * -RegTokenCreate(Db * db, char *name, char *owner, UInt64 expires, Int64 uses, int privileges) +RegTokenCreate(Db * db, char *name, char *owner, uint64_t expires, int64_t uses, int privileges) { RegTokenInfo *ret; - UInt64 timestamp = UtilServerTs(); + uint64_t timestamp = UtilTsMillis(); if (!db || !name) { @@ -213,13 +209,13 @@ RegTokenCreate(Db * db, char *name, char *owner, UInt64 expires, Int64 uses, int /* -1 indicates infinite uses; zero and all positive values are a * valid number of uses; althought zero would be rather useless. * Anything less than -1 doesn't make sense. */ - if (Int64Lt(uses, Int64Neg(Int64Create(0, 1)))) + if (uses < -1) { return NULL; } /* Verify the token */ - if (!RegTokenVerify(name) || (UInt64Gt(expires, UInt64Create(0, 0)) && UInt64Lt(expires, timestamp))) + if (!RegTokenVerify(name) || ((expires > 0) && (expires < timestamp))) { return NULL; } @@ -235,7 +231,7 @@ RegTokenCreate(Db * db, char *name, char *owner, UInt64 expires, Int64 uses, int } ret->name = StrDuplicate(name); ret->created_by = StrDuplicate(owner); - ret->used = Int64Create(0, 0); + ret->used = 0; ret->uses = uses; ret->created_on = timestamp; ret->expires_on = expires; diff --git a/src/Routes/RouteProcControl.c b/src/Routes/RouteProcControl.c index 6eb434e..7e38038 100644 --- a/src/Routes/RouteProcControl.c +++ b/src/Routes/RouteProcControl.c @@ -24,7 +24,6 @@ */ #include -#include #include #include #include @@ -86,24 +85,11 @@ ROUTE_IMPL(RouteProcControl, path, argp) if (StrEquals(op, "stats")) { size_t allocated = MemoryAllocated(); - Int64 a; response = HashMapCreate(); - if (sizeof(size_t) == sizeof(Int64)) - { - UInt32 high = (UInt32) (allocated >> 32); - UInt32 low = (UInt32) (allocated); - - a = Int64Create(high, low); - } - else - { - a = Int64Create(0, allocated); - } - HashMapSet(response, "version", JsonValueString(TELODENDRIA_VERSION)); - HashMapSet(response, "memory_allocated", JsonValueInteger(a)); + HashMapSet(response, "memory_allocated", JsonValueInteger(allocated)); goto finish; } diff --git a/src/Routes/RouteRequestToken.c b/src/Routes/RouteRequestToken.c index 318cbab..79f5983 100644 --- a/src/Routes/RouteRequestToken.c +++ b/src/Routes/RouteRequestToken.c @@ -40,8 +40,6 @@ ROUTE_IMPL(RouteRequestToken, path, argp) RequestToken reqTok; - Int64 minusOne = Int64Neg(Int64Create(0, 1)); - reqTok.client_secret = NULL; reqTok.next_link = NULL; reqTok.id_access_token = NULL; @@ -51,7 +49,7 @@ ROUTE_IMPL(RouteRequestToken, path, argp) reqTok.country = NULL; reqTok.phone_number = NULL; - reqTok.send_attempt = minusOne; + reqTok.send_attempt = -1; if (HttpRequestMethodGet(args->context) != HTTP_POST) { @@ -90,7 +88,7 @@ ROUTE_IMPL(RouteRequestToken, path, argp) goto finish; } - if (Int64Eq(reqTok.send_attempt, minusOne)) + if (reqTok.send_attempt == -1) { msg = "Invalid or inexistent 'send_attempt'"; HttpResponseStatus(args->context, HTTP_BAD_REQUEST); diff --git a/src/Telodendria.c b/src/Telodendria.c index f254107..d43c9da 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -133,7 +133,7 @@ TelodendriaPrintHeader(void) Log(LOG_INFO, "%s", TelodendriaHeader[i]); } - Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION " (%s v%s)", CytoplasmGetName(), CytoplasmGetVersion()); + Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION " (Cytoplasm v%s)", CytoplasmGetVersionStr()); Log(LOG_INFO, ""); Log(LOG_INFO, "Copyright (C) 2024 Jordan Bancino <@jordan:bancino.net>"); diff --git a/src/Uia.c b/src/Uia.c index 8c83440..8ff58b5 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -135,7 +135,7 @@ BuildResponse(Array * flows, Db * db, HashMap ** response, char *session, DbRef json = DbJson(ref); HashMapSet(json, "completed", JsonValueArray(ArrayCreate())); - HashMapSet(json, "last_access", JsonValueInteger(UtilServerTs())); + HashMapSet(json, "last_access", JsonValueInteger(UtilTsMillis())); DbUnlock(db, ref); HashMapSet(*response, "completed", JsonValueArray(ArrayCreate())); @@ -452,7 +452,7 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db, finish: ArrayFree(possibleNext); - JsonValueFree(HashMapSet(dbJson, "last_access", JsonValueInteger(UtilServerTs()))); + JsonValueFree(HashMapSet(dbJson, "last_access", JsonValueInteger(UtilTsMillis()))); DbUnlock(db, dbRef); return ret; } @@ -498,7 +498,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args) char *session = ArrayGet(sessions, i); DbRef *ref = DbLock(args->db, 2, "user_interactive", session); - UInt64 lastAccess; + uint64_t lastAccess; if (!ref) { @@ -513,7 +513,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args) /* If last access was greater than 15 minutes ago, remove this * session */ - if (UInt64Gt(UInt64Sub(UtilServerTs(), lastAccess), UInt64Create(0, 1000 * 60 * 15))) + if ((UtilTsMillis() - lastAccess) > (1000 * 60 * 15)) { DbDelete(args->db, 2, "user_interactive", session); Log(LOG_DEBUG, "Deleted session %s", session); diff --git a/src/User.c b/src/User.c index 1fc872d..3a38d34 100644 --- a/src/User.c +++ b/src/User.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include @@ -44,7 +42,7 @@ struct User char *deviceId; }; -int +bool UserValidate(char *localpart, char *domain) { size_t maxLen = 255 - strlen(domain) - 1; @@ -56,23 +54,23 @@ UserValidate(char *localpart, char *domain) if (i > maxLen) { - return 0; + return false; } if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '.') || (c == '_') || (c == '=') || (c == '-') || (c == '/'))) { - return 0; + return false; } i++; } - return 1; + return true; } -int +bool UserHistoricalValidate(char *localpart, char *domain) { size_t maxLen = 255 - strlen(domain) - 1; @@ -84,21 +82,21 @@ UserHistoricalValidate(char *localpart, char *domain) if (i > maxLen) { - return 0; + return false; } if (!((c >= 0x21 && c <= 0x39) || (c >= 0x3B && c <= 0x7E))) { - return 0; + return false; } i++; } - return 1; + return true; } -int +bool UserExists(Db * db, char *name) { return DbExists(db, 2, "users", name); @@ -133,7 +131,7 @@ UserAuthenticate(Db * db, char *accessToken) char *userName; char *deviceId; - UInt64 expires; + uint64_t expires; if (!db || !accessToken) { @@ -157,8 +155,7 @@ UserAuthenticate(Db * db, char *accessToken) return NULL; } - if (UInt64Neq(expires, UInt64Create(0, 0)) && - UInt64Geq(UtilServerTs(), expires)) + if (expires && UtilTsMillis() >= expires) { UserUnlock(user); DbUnlock(db, atRef); @@ -171,14 +168,14 @@ UserAuthenticate(Db * db, char *accessToken) return user; } -int +bool UserUnlock(User * user) { - int ret; + bool ret; if (!user) { - return 0; + return false; } Free(user->name); @@ -196,7 +193,7 @@ UserCreate(Db * db, char *name, char *password) User *user = NULL; HashMap *json = NULL; - UInt64 ts = UtilServerTs(); + uint64_t ts = UtilTsMillis(); /* TODO: Put some sort of password policy(like for example at least * 8 chars, or maybe check it's entropy)? */ @@ -233,7 +230,7 @@ UserCreate(Db * db, char *name, char *password) json = DbJson(user->ref); HashMapSet(json, "createdOn", JsonValueInteger(ts)); - HashMapSet(json, "deactivated", JsonValueBoolean(0)); + HashMapSet(json, "deactivated", JsonValueBoolean(false)); return user; } @@ -356,7 +353,7 @@ UserGetDeviceId(User * user) return user ? user->deviceId : NULL; } -int +bool UserCheckPassword(User * user, char *password) { HashMap *json; @@ -368,11 +365,11 @@ UserCheckPassword(User * user, char *password) char *hashedPwd; char *tmp; - int result; + bool result; if (!user || !password) { - return 0; + return false; } json = DbJson(user->ref); @@ -382,7 +379,7 @@ UserCheckPassword(User * user, char *password) if (!storedHash || !salt) { - return 0; + return false; } tmp = StrConcat(2, password, salt); @@ -398,7 +395,7 @@ UserCheckPassword(User * user, char *password) return result; } -int +bool UserSetPassword(User * user, char *password) { HashMap *json; @@ -410,7 +407,7 @@ UserSetPassword(User * user, char *password) if (!user || !password) { - return 0; + return false; } json = DbJson(user->ref); @@ -428,10 +425,10 @@ UserSetPassword(User * user, char *password) Free(hashBytes); Free(tmpstr); - return 1; + return true; } -int +bool UserDeactivate(User * user, char * from, char * reason) { HashMap *json; @@ -439,7 +436,7 @@ UserDeactivate(User * user, char * from, char * reason) if (!user) { - return 0; + return false; } /* By default, it's the target's username */ @@ -450,7 +447,7 @@ UserDeactivate(User * user, char * from, char * reason) json = DbJson(user->ref); - JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(1))); + JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(true))); val = JsonValueString(from); JsonValueFree(JsonSet(json, val, 2, "deactivate", "by")); @@ -460,38 +457,38 @@ UserDeactivate(User * user, char * from, char * reason) JsonValueFree(JsonSet(json, val, 2, "deactivate", "reason")); } - return 1; + return true; } -int +bool UserReactivate(User * user) { HashMap *json; if (!user) { - return 0; + return false; } json = DbJson(user->ref); - JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(0))); + JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(false))); JsonValueFree(HashMapDelete(json, "deactivate")); - return 1; + return true; } -int +bool UserDeactivated(User * user) { HashMap *json; if (!user) { - return 1; + return true; } json = DbJson(user->ref); @@ -537,17 +534,17 @@ UserAccessTokenGenerate(User * user, char *deviceId, int withRefresh) if (withRefresh) { - token->lifetime = Int64Create(0, 1000 * 60 * 60 * 24 * 7); /* 1 Week */ + token->lifetime = 1000 * 60 * 60 * 24 * 7; /* 1 Week */ } else { - token->lifetime = Int64Create(0, 0); + token->lifetime = 0; } return token; } -int +bool UserAccessTokenSave(Db * db, UserAccessToken * token) { DbRef *ref; @@ -555,14 +552,14 @@ UserAccessTokenSave(Db * db, UserAccessToken * token) if (!token) { - return 0; + return false; } ref = DbCreate(db, 3, "tokens", "access", token->string); if (!ref) { - return 0; + return false; } json = DbJson(ref); @@ -570,9 +567,9 @@ UserAccessTokenSave(Db * db, UserAccessToken * token) HashMapSet(json, "user", JsonValueString(token->user)); HashMapSet(json, "device", JsonValueString(token->deviceId)); - if (Int64Neq(token->lifetime, Int64Create(0, 0))) + if (token->lifetime) { - HashMapSet(json, "expires", JsonValueInteger(UInt64Add(UtilServerTs(), token->lifetime))); + HashMapSet(json, "expires", JsonValueInteger(UtilTsMillis() + token->lifetime)); } return DbUnlock(db, ref); @@ -592,7 +589,7 @@ UserAccessTokenFree(UserAccessToken * token) Free(token); } -int +bool UserDeleteToken(User * user, char *token) { char *username; @@ -610,14 +607,14 @@ UserDeleteToken(User * user, char *token) if (!user || !token) { - return 0; + return false; } db = user->db; /* First check if the token even exists */ if (!DbExists(db, 3, "tokens", "access", token)) { - return 0; + return false; } /* If it does, get it's username. */ @@ -625,7 +622,7 @@ UserDeleteToken(User * user, char *token) if (!tokenRef) { - return 0; + return false; } tokenJson = DbJson(tokenRef); username = JsonValueAsString(HashMapGet(tokenJson, "user")); @@ -635,7 +632,7 @@ UserDeleteToken(User * user, char *token) { /* Token does not match user, do not delete it */ DbUnlock(db, tokenRef); - return 0; + return false; } userJson = DbJson(user->ref); @@ -643,7 +640,7 @@ UserDeleteToken(User * user, char *token) if (!deviceObj) { - return 0; + return false; } /* Delete refresh token, if present */ @@ -657,17 +654,17 @@ UserDeleteToken(User * user, char *token) deletedVal = HashMapDelete(deviceObj, deviceId); if (!deletedVal) { - return 0; + return false; } JsonValueFree(deletedVal); /* Delete the access token. */ if (!DbUnlock(db, tokenRef) || !DbDelete(db, 3, "tokens", "access", token)) { - return 0; + return false; } - return 1; + return true; } char * @@ -699,7 +696,7 @@ UserSetProfile(User * user, char *name, char *val) JsonValueFree(JsonSet(json, JsonValueString(val), 2, "profile", name)); } -int +bool UserDeleteTokens(User * user, char *exempt) { HashMap *devices; @@ -708,13 +705,13 @@ UserDeleteTokens(User * user, char *exempt) if (!user) { - return 0; + return false; } devices = JsonValueAsObject(HashMapGet(DbJson(user->ref), "devices")); if (!devices) { - return 0; + return false; } while (HashMapIterate(devices, &deviceId, (void **) &deviceObj)) @@ -741,7 +738,7 @@ UserDeleteTokens(User * user, char *exempt) JsonValueFree(HashMapDelete(devices, deviceId)); } - return 1; + return true; } int @@ -755,30 +752,30 @@ UserGetPrivileges(User * user) return UserDecodePrivileges(JsonValueAsArray(HashMapGet(DbJson(user->ref), "privileges"))); } -int +bool UserSetPrivileges(User * user, int privileges) { JsonValue *val; if (!user) { - return 0; + return false; } if (!privileges) { JsonValueFree(HashMapDelete(DbJson(user->ref), "privileges")); - return 1; + return true; } val = JsonValueArray(UserEncodePrivileges(privileges)); if (!val) { - return 0; + return false; } JsonValueFree(HashMapSet(DbJson(user->ref), "privileges", val)); - return 1; + return true; } int diff --git a/src/include/Parser.h b/src/include/Parser.h index a4cadfa..2bbdf5a 100644 --- a/src/include/Parser.h +++ b/src/include/Parser.h @@ -25,6 +25,8 @@ #ifndef TELODENDRIA_PARSER_H #define TELODENDRIA_PARSER_H +#include + /*** * @Nm Parser * @Nd Functions for dealing with grammars found in Matrix @@ -58,17 +60,17 @@ typedef struct CommonID { * Parses a common identifier, as per the Common Identifier Format as defined * by the [matrix] specification. */ -extern int ParseCommonID(char *, CommonID *); +extern bool ParseCommonID(char *, CommonID *); /** * Parses the server part in a common identifier. */ -extern int ParseServerPart(char *, ServerPart *); +extern bool ParseServerPart(char *, ServerPart *); /** * Checks whenever the string is a valid common ID with the correct sigil. */ -extern int ValidCommonID(char *, char); +extern bool ValidCommonID(char *, char); /** * Frees a CommonID's values. Note that it doesn't free the CommonID itself. @@ -100,7 +102,7 @@ extern char * ParserRecomposeServerPart(ServerPart); /** * Compares whenever a ServerName is equivalent to a server name string. */ -extern int ParserServerNameEquals(ServerPart, char *); +extern bool ParserServerNameEquals(ServerPart, char *); #endif /* TELODENDRIA_PARSER_H */ diff --git a/src/include/RegToken.h b/src/include/RegToken.h index f24a79c..1acc943 100644 --- a/src/include/RegToken.h +++ b/src/include/RegToken.h @@ -41,7 +41,6 @@ */ #include -#include #include @@ -78,7 +77,7 @@ extern RegTokenInfo * RegTokenGetInfo(Db *, char *); * structure will be returned. Otherwise, NULL will be returned. */ extern RegTokenInfo * -RegTokenCreate(Db *, char *, char *, UInt64, Int64, int); +RegTokenCreate(Db *, char *, char *, uint64_t, int64_t, int); /** * Free the memory associated with the registration token. This should diff --git a/src/include/User.h b/src/include/User.h index f84ac94..f03ff39 100644 --- a/src/include/User.h +++ b/src/include/User.h @@ -39,12 +39,13 @@ * users, among many other tasks. */ -#include #include #include #include +#include + /** * Many functions here operate on an opaque user structure. */ @@ -77,7 +78,7 @@ typedef struct UserAccessToken char *user; char *string; char *deviceId; - Int64 lifetime; + uint64_t lifetime; } UserAccessToken; /** @@ -98,7 +99,7 @@ typedef struct UserLoginInfo * the local part is allowed to be. This function is used to ensure * that client-provided Matrix IDs are valid on this server. */ -extern int UserValidate(char *, char *); +extern bool UserValidate(char *, char *); /** * This function behaves just like @@ -109,13 +110,13 @@ extern int UserValidate(char *, char *); * spec compliant but remain in use since before the new restrictions * were put in place. */ -extern int UserHistoricalValidate(char *, char *); +extern bool UserHistoricalValidate(char *, char *); /** * Determine whether the user identified by the specified localpart * exists in the database. */ -extern int UserExists(Db *, char *); +extern bool UserExists(Db *, char *); /** * Create a new user with the specified localpart and password, in @@ -146,7 +147,7 @@ extern User * UserAuthenticate(Db *, char *); * .Fn DbUnlock * under the hood. */ -extern int UserUnlock(User *); +extern bool UserUnlock(User *); /** * Log in a user. This function takes the user's password, desired @@ -179,13 +180,13 @@ extern char * UserGetDeviceId(User *); * does not store passwords in plain text, so this function hashes the * password and checks it against what is stored in the database. */ -extern int UserCheckPassword(User *, char *); +extern bool UserCheckPassword(User *, char *); /** * Reset the given user's password by hashing a plain text password and * storing it in the database. */ -extern int UserSetPassword(User *, char *); +extern bool UserSetPassword(User *, char *); /** * Immediately deactivate the given user account such that it can no @@ -198,21 +199,21 @@ extern int UserSetPassword(User *, char *); * responsible for deactivating the target user is NULL, then it is * set to the target's own name. */ -extern int UserDeactivate(User *, char *, char *); +extern bool UserDeactivate(User *, char *, char *); /** * Reactivates the given user account if it has been deactvated with * .Fn UserDeactivate , * otherwise, it simply doesn't do anything. */ -extern int UserReactivate(User *); +extern bool UserReactivate(User *); /** * Return a boolean value indicating whether or not the user was * deactivated using * .Fn UserDeactivate . */ -extern int UserDeactivated(User *); +extern bool UserDeactivated(User *); /** * Fetches the devices that belong to the user, in JSON format, @@ -233,7 +234,7 @@ extern UserAccessToken * UserAccessTokenGenerate(User *, char *, int); * Write the specified access token to the database, returning a * boolean value indicating success. */ -extern int UserAccessTokenSave(Db *, UserAccessToken *); +extern bool UserAccessTokenSave(Db *, UserAccessToken *); /** * Free the memory associated with the given access token. @@ -243,7 +244,7 @@ extern void UserAccessTokenFree(UserAccessToken *); /** * Delete a specific access token by name. */ -extern int UserDeleteToken(User *, char *); +extern bool UserDeleteToken(User *, char *); /** * Get a string property from the user's profile given the specified @@ -262,7 +263,7 @@ extern void UserSetProfile(User *, char *, char *); * except for the one provided by name, unless NULL is provided for * the name. */ -extern int UserDeleteTokens(User *, char *); +extern bool UserDeleteTokens(User *, char *); /** * Get the current privileges of the user as a packed bit field. Use @@ -274,7 +275,7 @@ extern int UserGetPrivileges(User *); /** * Set the privileges of the user. */ -extern int UserSetPrivileges(User *, int); +extern bool UserSetPrivileges(User *, int); /** * Decode the JSON that represents the user privileges into a packed diff --git a/tools/src/json.c b/tools/src/json.c index 9c1b86a..fb390c1 100644 --- a/tools/src/json.c +++ b/tools/src/json.c @@ -70,41 +70,17 @@ query(char *select, HashMap * json, int canonical) { if (StrEquals(keyName + 1, "length")) { - UInt64 len; + uint64_t len; switch (JsonValueType(val)) { case JSON_ARRAY: - if (sizeof(size_t) == sizeof(UInt64)) - { - size_t slen = ArraySize(JsonValueAsArray(val)); - UInt32 high = slen >> 32; - UInt32 low = slen; - - len = UInt64Create(high, low); - } - else - { - len = UInt64Create(0, ArraySize(JsonValueAsArray(val))); - } - + len = ArraySize(JsonValueAsArray(val)); val = JsonValueInteger(len); ArrayAdd(cleanUp, val); break; case JSON_STRING: - if (sizeof(size_t) == sizeof(UInt64)) - { - size_t slen = strlen(JsonValueAsString(val)); - UInt32 high = slen >> 32; - UInt32 low = slen; - - len = UInt64Create(high, low); - } - else - { - len = UInt64Create(0, strlen(JsonValueAsString(val))); - } - + len = strlen(JsonValueAsString(val)); val = JsonValueInteger(len); ArrayAdd(cleanUp, val); break; From ae0724f01cc4f044bce8413b5b3bdfaa7523e2eb Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:02:57 -0500 Subject: [PATCH 13/23] 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. --- Cytoplasm | 2 +- configure | 113 ++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 89 insertions(+), 26 deletions(-) diff --git a/Cytoplasm b/Cytoplasm index 039a487..5d87da3 160000 --- a/Cytoplasm +++ b/Cytoplasm @@ -1 +1 @@ -Subproject commit 039a487bdfc2b526141fb537a1efc7bc186d5d5b +Subproject commit 5d87da31cda74e6808eebca72e9475aabde86532 diff --git a/configure b/configure index 70e0aad..7275ad0 100755 --- a/configure +++ b/configure @@ -13,13 +13,40 @@ SRC="src" INCLUDE="src/include" TOOLS="tools/src" SCHEMA="Schema" +CYTOPLASM="Cytoplasm" -CFLAGS="-Wall -Wextra -pedantic -std=c89 -O3 -pipe -D_DEFAULT_SOURCE -I${INCLUDE} -I${BUILD}" +CFLAGS="-O1 -D_DEFAULT_SOURCE -I${INCLUDE} -I${BUILD}" LIBS="-lm -pthread -lCytoplasm" # Set default args for all platforms -SCRIPT_ARGS="--cc=cc --prefix=/usr/local --enable-ld-extra --bin-name=telodendria --version=1.7.0-alpha4 --static $@" +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) + # 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" @@ -29,16 +56,18 @@ 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="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" + ;; + esac ;; --prefix=*) PREFIX=$(echo "$arg" | cut -d '=' -f 2-) ;; - --enable-ld-extra) - LD_EXTRA="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" - ;; - --disable-ld-extra) - LD_EXTRA="" - ;; --bin-name=*) BIN_NAME=$(echo "$arg" | cut -d '=' -f 2-) ;; @@ -47,20 +76,21 @@ for arg in $SCRIPT_ARGS; do ;; --enable-debug) DEBUG="-O0 -g" - echo "Notice: --enable-debug implies --disable-ld-extra and --no-static." - echo "You must explicitly provide --enable-ld-extra and/or --static after" - echo "specifying --enable-debug if you wish to enable these features in debug mode." - LD_EXTRA="" - STATIC="" ;; --disable-debug) DEBUG="" ;; - --static) - STATIC="-static -Wl,-static" - ;; - --no-static) - STATIC="" + --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} -L${CYTOPLASM}/out/lib -I${CYTOPLASM}/include" + fi ;; *) echo "Invalid argument: $arg" @@ -70,7 +100,7 @@ for arg in $SCRIPT_ARGS; do done CFLAGS="${CFLAGS} '-DTELODENDRIA_VERSION=\"${VERSION}\"' ${DEBUG}" -LDFLAGS="${LIBS} ${LD_EXTRA}" +LDFLAGS="${LIBS} ${LDFLAGS}" # # Makefile generation @@ -103,6 +133,16 @@ prefix() { 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" } @@ -111,11 +151,27 @@ 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=$(${CC} -I${INCLUDE} -I${BUILD} -MM -MT "${obj}" "${src}") + 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}\"" @@ -129,7 +185,7 @@ compile_bin() { echo "${out}: ${src}" echo "${TAB}@mkdir -p ${OUT}/bin" - echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" $depObjs \$(LDFLAGS) ${STATIC}" + echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" $depObjs \$(LDFLAGS)" } compile_doc() { @@ -142,7 +198,7 @@ compile_doc() { echo "${out}: ${src}" echo "${TAB}@mkdir -p ${OUT}/man/man3" - echo "${TAB}hdoc -D \"Os=${BIN_NAME}\" -i \"${src}\" -o \"${out}\"" + echo "${TAB}$(cytoplasm_tool hdoc) -D \"Os=${BIN_NAME}\" -i \"${src}\" -o \"${out}\"" } print_doc() { @@ -160,11 +216,11 @@ compile_schema() { echo "${BUILD}/Schema/${out}.h:" echo "${TAB}@mkdir -p ${BUILD}/Schema" - echo "${TAB}j2s -s \"${src}\" -h \"${BUILD}/Schema/${out}.h\" -c \"${BUILD}/Schema/${out}.c\"" + 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}j2s -s \"${src}\" -h \"${BUILD}/Schema/${out}.h\" -c \"${BUILD}/Schema/${out}.c\"" + 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" @@ -227,7 +283,7 @@ ${TAB} diff -u -p - "LICENSE.txt" | \\ ${TAB} patch "\$\$src" | grep -v "^Hmm"; \\ ${TAB}done -${BIN_NAME}: ${OUT}/bin/${BIN_NAME} +${BIN_NAME}: $(if [ -n "${CYTOPLASM}" ]; then echo "cytoplasm"; fi) ${OUT}/bin/${BIN_NAME} install: ${BIN_NAME} ${TAB}install -D ${OUT}/bin/${BIN_NAME} \$(PREFIX)/bin/${BIN_NAME} @@ -247,6 +303,13 @@ $(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}." From cd22aea7720c08a43c7e66dde5b4c8c486d028da Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:11:58 -0500 Subject: [PATCH 14/23] Require Cytoplasm to be compiled separately. Also add the Gitea CI runner jobs. --- .gitea/workflows/compile.yaml | 27 +++++++++++++++++++++++++++ configure | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/compile.yaml diff --git a/.gitea/workflows/compile.yaml b/.gitea/workflows/compile.yaml new file mode 100644 index 0000000..87b921c --- /dev/null +++ b/.gitea/workflows/compile.yaml @@ -0,0 +1,27 @@ +name: Compile Telodendria +run-name: Compile Telodendria on ${{ gitea.actor }} +on: [push] + +jobs: + "Compile Telodendria": + strategy: + matrix: + os: [debian-v12.4, alpine-v3.19, openbsd-v7.4, freebsd-v14.0, netbsd-v9.3] + arch: [x86, x86_64] + exclude: + # 32-bit OpenBSD does not behave well in QEMU. Even when using + # QEMU to emulate i386, it utilizes 100% of its CPU core and is + # still extremely sluggish. Thus, we don't have a working 32-bit + # OpenBSD runner, so exclude it from the matrix configuration. + - os: openbsd-v7.4 + arch: x86 + runs-on: ["${{ matrix.os }}", "${{ matrix.arch }}"] + steps: + - name: Check out repository + uses: actions/checkout@v3 + - name: Configure Telodendria + run: ./configure + - name: Configure & Build Cytoplasm + run: make cytoplasm + - name: Build Telodendria + run: make diff --git a/configure b/configure index 7275ad0..76bcd44 100755 --- a/configure +++ b/configure @@ -283,7 +283,7 @@ ${TAB} diff -u -p - "LICENSE.txt" | \\ ${TAB} patch "\$\$src" | grep -v "^Hmm"; \\ ${TAB}done -${BIN_NAME}: $(if [ -n "${CYTOPLASM}" ]; then echo "cytoplasm"; fi) ${OUT}/bin/${BIN_NAME} +${BIN_NAME}: ${OUT}/bin/${BIN_NAME} install: ${BIN_NAME} ${TAB}install -D ${OUT}/bin/${BIN_NAME} \$(PREFIX)/bin/${BIN_NAME} From 15fb6d8c2a6ab17fe38cd663c489db6c529b70f4 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:14:42 -0500 Subject: [PATCH 15/23] Make sure CI checks out submodules. --- .gitea/workflows/compile.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/compile.yaml b/.gitea/workflows/compile.yaml index 87b921c..0c578a8 100644 --- a/.gitea/workflows/compile.yaml +++ b/.gitea/workflows/compile.yaml @@ -19,6 +19,8 @@ jobs: steps: - name: Check out repository uses: actions/checkout@v3 + with: + submodules: true - name: Configure Telodendria run: ./configure - name: Configure & Build Cytoplasm From 19443a1c240a36cac2bc846688d6a08de73d7adb Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:25:03 -0500 Subject: [PATCH 16/23] Fix unused argument error on Clang. --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 76bcd44..f667973 100755 --- a/configure +++ b/configure @@ -89,7 +89,8 @@ for arg in $SCRIPT_ARGS; do exit 1 fi - CFLAGS="${CFLAGS} -L${CYTOPLASM}/out/lib -I${CYTOPLASM}/include" + CFLAGS="${CFLAGS} -I${CYTOPLASM}/include" + LDFLAGS="${LDFLAGS} -L${CYTOPLASM}/out/lib" fi ;; *) From 85672985ebfb581f8ee068f1b15b5760d4584f00 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:25:16 -0500 Subject: [PATCH 17/23] Fix compiler warnings on 32-bit platforms in json.c. --- tools/src/json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/json.c b/tools/src/json.c index fb390c1..899b81f 100644 --- a/tools/src/json.c +++ b/tools/src/json.c @@ -64,7 +64,7 @@ query(char *select, HashMap * json, int canonical) int expectArr = 0; int func = 0; - expectArr = (sscanf(key, "%127[^[][%lu]", keyName, &arrInd) == 2); + expectArr = (sscanf(key, "%127[^[][%zu]", keyName, &arrInd) == 2); if (keyName[0] == '@') { From c7d44866c30b6c45e8878a9dc2e02797d3cfb8d6 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:26:46 -0500 Subject: [PATCH 18/23] Put -L before -l in LDFLAGS. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f667973..ed24a17 100755 --- a/configure +++ b/configure @@ -90,7 +90,7 @@ for arg in $SCRIPT_ARGS; do fi CFLAGS="${CFLAGS} -I${CYTOPLASM}/include" - LDFLAGS="${LDFLAGS} -L${CYTOPLASM}/out/lib" + LDFLAGS="-L${CYTOPLASM}/out/lib ${LDFLAGS}" fi ;; *) From 129802fe946dc04dbefe7832cf315bebe4983434 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:31:49 -0500 Subject: [PATCH 19/23] Fix ordering of LDFLAGS. --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index ed24a17..1da5858 100755 --- a/configure +++ b/configure @@ -61,7 +61,7 @@ for arg in $SCRIPT_ARGS; do # "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="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" + LDFLAGS="${LDFLAGS} -flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" ;; esac ;; @@ -101,7 +101,7 @@ for arg in $SCRIPT_ARGS; do done CFLAGS="${CFLAGS} '-DTELODENDRIA_VERSION=\"${VERSION}\"' ${DEBUG}" -LDFLAGS="${LIBS} ${LDFLAGS}" +LDFLAGS="${LDFLAGS} ${LIBS}" # # Makefile generation From 95a5f6f087363f33cc020637d51745045a8d1310 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 20:41:29 -0500 Subject: [PATCH 20/23] Fix compile warnings on 32-bit systems. --- tools/src/json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/json.c b/tools/src/json.c index 899b81f..27e07ee 100644 --- a/tools/src/json.c +++ b/tools/src/json.c @@ -130,7 +130,7 @@ query(char *select, HashMap * json, int canonical) { size_t i; - if (sscanf(keyName + 1, "%lu", &i) == 1) + if (sscanf(keyName + 1, "%zu", &i) == 1) { JsonValueFree(ArrayDelete(JsonValueAsArray(val), i)); } From 6305f5d76ee55d3c88f2f0e54bdac12592862e11 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sun, 14 Jan 2024 09:36:57 -0500 Subject: [PATCH 21/23] Update docs/dev/hosting.md --- docs/dev/hosting.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/dev/hosting.md b/docs/dev/hosting.md index be1c72a..6cd15bd 100644 --- a/docs/dev/hosting.md +++ b/docs/dev/hosting.md @@ -33,4 +33,27 @@ The general sequence of steps required for setting up a CI runner is as follows: - **Others:** `other`, `-v`, `` Where `` is one of `x86` or `x64` for now. ARM runners will be a future project. -7. Run `./act_runner daemon`. \ No newline at end of file +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`. \ No newline at end of file From fde2b268571a406e31d6e2dcdbe5392bbed30be3 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sun, 14 Jan 2024 09:43:47 -0500 Subject: [PATCH 22/23] Update docs/dev/hosting.md --- docs/dev/hosting.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/dev/hosting.md b/docs/dev/hosting.md index 6cd15bd..75d933d 100644 --- a/docs/dev/hosting.md +++ b/docs/dev/hosting.md @@ -56,4 +56,25 @@ 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`. \ No newline at end of file +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 +``` \ No newline at end of file From dede82ad330c972b1c80ef184248089f1e4e54e1 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sun, 14 Jan 2024 14:13:53 -0500 Subject: [PATCH 23/23] Update docs/dev/hosting.md --- docs/dev/hosting.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/dev/hosting.md b/docs/dev/hosting.md index 75d933d..6d729a1 100644 --- a/docs/dev/hosting.md +++ b/docs/dev/hosting.md @@ -77,4 +77,18 @@ User=runner [Install] WantedBy=multi-user.target -``` \ No newline at end of file +``` + +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. \ No newline at end of file