Compare commits
24 Commits
v0.0.26
...
8f51eb63b0
Author | SHA1 | Date | |
---|---|---|---|
8f51eb63b0 | |||
855f5f7af4 | |||
c85dd2655c | |||
fb0e4060cd | |||
707b4990a6 | |||
9c8b922069 | |||
d4b421421d | |||
58e9646fa6 | |||
500f172561 | |||
68f6c90ea4 | |||
41e91f2922 | |||
999117cfeb | |||
6185df512f | |||
0cbf66c007 | |||
cd378b721d | |||
547d38d1ef | |||
dca56af5b9 | |||
224442772e | |||
003951fdf7 | |||
d51b3da1b4 | |||
69f4af84db | |||
771759b252 | |||
20c7a71db6 | |||
8475ee0985 |
@ -24,15 +24,14 @@ jobs:
|
||||
uses: android-actions/setup-android@v3
|
||||
with:
|
||||
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
|
||||
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11
|
||||
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11 gcc-aarch64-linux-gnu
|
||||
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs
|
||||
- run: docker build .
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: out/TildeFriends-release.fdroid.apk
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: out/winrelease/tildefriends.exe
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: out/tildefriends-x86_64.AppImage
|
||||
path: |
|
||||
out/TildeFriends-release.fdroid.apk
|
||||
out/winrelease/tildefriends.exe
|
||||
out/tildefriends-x86_64.AppImage
|
||||
out/release/tildefriends.standalone
|
||||
out/armrelease/tildefriends.standalone
|
||||
|
72
GNUmakefile
72
GNUmakefile
@ -16,8 +16,8 @@ MAKEFLAGS += --no-builtin-rules
|
||||
## LD := Linker.
|
||||
## ANDROID_SDK := Path to the Android SDK.
|
||||
|
||||
VERSION_CODE := 31
|
||||
VERSION_NUMBER := 0.0.26
|
||||
VERSION_CODE := 32
|
||||
VERSION_NUMBER := 0.0.27-wip
|
||||
VERSION_NAME := This program kills fascists.
|
||||
|
||||
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3470200.zip
|
||||
@ -34,6 +34,7 @@ ANDROID_SDK ?= ~/Android/Sdk
|
||||
BUNDLETOOL = out/bundletool.jar
|
||||
|
||||
HAVE_WIN := 0
|
||||
HAVE_CROSS_AARCH64 := 0
|
||||
|
||||
export SOURCE_DATE_EPOCH=1
|
||||
export TZ=UTC
|
||||
@ -45,6 +46,9 @@ BUILD_TYPES := debug release
|
||||
HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1,0)
|
||||
HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1,0)
|
||||
HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1,0)
|
||||
ifneq ($(UNAME_M),aarch64)
|
||||
HAVE_CROSS_AARCH64 = $(if $(shell which aarch64-linux-gnu-gcc),1,0)
|
||||
endif
|
||||
else ifeq ($(UNAME_S),Haiku)
|
||||
BUILD_TYPES := debug release
|
||||
CFLAGS += -Dstatic_assert=_Static_assert
|
||||
@ -125,6 +129,13 @@ ifeq ($(HAVE_WIN),1)
|
||||
BUILD_TYPES += windebug winrelease
|
||||
endif
|
||||
|
||||
AARCH64_TARGETS := \
|
||||
out/armdebug/tildefriends \
|
||||
out/armrelease/tildefriends
|
||||
ifeq ($(HAVE_CROSS_AARCH64),1)
|
||||
BUILD_TYPES += armdebug armrelease
|
||||
endif
|
||||
|
||||
LINUX_TARGETS := \
|
||||
out/debug/tildefriends \
|
||||
out/release/tildefriends
|
||||
@ -149,6 +160,9 @@ all: $(IOS_APPS) \
|
||||
out/tildefriends-iossimdebug.app/tildefriends \
|
||||
out/tildefriends-iossimrelease.app/tildefriends
|
||||
endif
|
||||
ifeq ($(HAVE_CROSS_AARCH64),1)
|
||||
all: out/armrelease/tildefriends.standalone
|
||||
endif
|
||||
|
||||
DEBUG_TARGETS := \
|
||||
out/debug/tildefriends \
|
||||
@ -159,7 +173,8 @@ DEBUG_TARGETS := \
|
||||
out/androiddebug/tildefriends \
|
||||
out/androiddebug-armv7a/tildefriends \
|
||||
out/androiddebug-x86_64/tildefriends \
|
||||
out/androiddebug-x86/tildefriends
|
||||
out/androiddebug-x86/tildefriends \
|
||||
out/armdebug/tildefriends
|
||||
RELEASE_TARGETS := \
|
||||
out/release/tildefriends \
|
||||
out/winrelease/tildefriends.exe \
|
||||
@ -169,7 +184,8 @@ RELEASE_TARGETS := \
|
||||
out/androidrelease/tildefriends \
|
||||
out/androidrelease-armv7a/tildefriends \
|
||||
out/androidrelease-x86_64/tildefriends \
|
||||
out/androidrelease-x86/tildefriends
|
||||
out/androidrelease-x86/tildefriends \
|
||||
out/armrelease/tildefriends
|
||||
ALL_TARGETS = $(DEBUG_TARGETS) $(RELEASE_TARGETS)
|
||||
ANDROID_RELEASE_TARGETS := $(filter-out $(DEBUG_TARGETS),$(ANDROID_TARGETS))
|
||||
NONANDROID_RELEASE_TARGETS := $(filter-out $(ANDROID_ARM64_TARGETS),$(RELEASE_TARGETS))
|
||||
@ -192,11 +208,14 @@ $(ANDROID_TARGETS): CFLAGS += \
|
||||
-Wno-unknown-warning-option
|
||||
$(ANDROID_TARGETS): LDFLAGS += --sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC
|
||||
$(DEBUG_TARGETS): CFLAGS += -DDEBUG -Og
|
||||
$(DEBUG_TARGETS): LDFLAGS += -Og
|
||||
$(RELEASE_TARGETS): CFLAGS += \
|
||||
-DNDEBUG \
|
||||
-flto
|
||||
$(NONANDROID_RELEASE_TARGETS): CFLAGS += -O3
|
||||
$(ANDROID_RELEASE_TARGETS): CFLAGS += -Oz
|
||||
$(ANDROID_RELEASE_TARGETS): LDFLAGS += -Oz
|
||||
$(NONANDROID_RELEASE_TARGETS): CFLAGS += -Os
|
||||
$(NONANDROID_RELEASE_TARGETS): LDFLAGS += -Os
|
||||
$(WINDOWS_TARGETS): CC = x86_64-w64-mingw32-gcc-win32
|
||||
$(WINDOWS_TARGETS): AS = $(CC)
|
||||
$(WINDOWS_TARGETS): CFLAGS += \
|
||||
@ -208,6 +227,10 @@ $(WINDOWS_TARGETS): LDFLAGS += \
|
||||
-static \
|
||||
-lm \
|
||||
-Ldeps/openssl/mingw64/usr/local/lib
|
||||
$(AARCH64_TARGETS): CC = aarch64-linux-gnu-gcc
|
||||
$(AARCH64_TARGETS): AS = $(CC)
|
||||
$(AARCH64_TARGETS): CFLAGS += -Ideps/openssl/Linux/aarch64/usr/local/include
|
||||
$(AARCH64_TARGETS): LDFLAGS += -Ldeps/openssl/Linux/aarch64/usr/local/lib
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
$(MACOS_TARGETS): CC = xcrun clang
|
||||
$(IOS_TARGETS): IOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path)
|
||||
@ -242,10 +265,12 @@ $(IOS_TARGETS): CFLAGS += -miphoneos-version-min=9.0 -Ideps/openssl/ios/ios64-xc
|
||||
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0 -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib
|
||||
$(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include
|
||||
$(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib
|
||||
$(LINUX_TARGETS) $(MACOS_TARGETS): CFLAGS += -Ideps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/include
|
||||
$(LINUX_TARGETS) $(MACOS_TARGETS): LDFLAGS += -Ldeps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib
|
||||
|
||||
ifeq ($(UNAME_M),x86_64)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
all: appimage
|
||||
all: appimage out/release/tildefriends.standalone
|
||||
endif
|
||||
ifneq ($(UNAME_S),Haiku)
|
||||
out/debug/tildefriends: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
|
||||
@ -260,7 +285,7 @@ endif
|
||||
|
||||
get_objs = \
|
||||
$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
|
||||
$(foreach build_type,debug release,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
||||
$(foreach build_type,debug release armdebug armrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
||||
$(foreach build_type,windebug winrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_win))))) \
|
||||
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androiddebug-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_android))))) \
|
||||
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
||||
@ -725,7 +750,7 @@ $(MINIUNZIP_OBJS): CFLAGS += \
|
||||
LDFLAGS += \
|
||||
-pthread \
|
||||
-lm
|
||||
$(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
|
||||
$(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS): LDFLAGS += \
|
||||
-lssl \
|
||||
-lcrypto
|
||||
ifneq ($(UNAME_S),Haiku)
|
||||
@ -765,6 +790,8 @@ $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
|
||||
##
|
||||
debug: ## Build a debug executable for the current platform.
|
||||
release: ## Build a release executable for the current platform.
|
||||
armdebug: ## Cross-compile aarch64 debug on Linux.
|
||||
armrelease: ## Cross-compile aarch64 release on Linux.
|
||||
all: $(BUILD_TYPES) ## Build all targets that appear possible to build on this machine.
|
||||
unix: debug release ## Build all UNIX targets.
|
||||
win: windebug winrelease ## Build all Windows targets.
|
||||
@ -1106,6 +1133,27 @@ $(ANDROID_DEPS):
|
||||
+@ANDROID_NDK_ROOT=$(ANDROID_NDK) tools/ssl-android
|
||||
$(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS)
|
||||
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
|
||||
$(LOCAL_DEPS):
|
||||
+@tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||
|
||||
ifeq ($(HAVE_CROSS_AARCH64),1)
|
||||
LOCAL_DEPS := deps/openssl/$(UNAME_S)/aarch64/usr/local/lib/libssl.a
|
||||
$(LOCAL_DEPS):
|
||||
+@OPTIONS=--cross-compile-prefix=aarch64-linux-gnu- BUILD_TARGET=aarch64 tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/armdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/armrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
|
||||
$(LOCAL_DEPS):
|
||||
+@tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/macosdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/macosrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_WIN),1)
|
||||
WINDOWS_DEPS := deps/openssl/mingw64/usr/local/lib/libssl.a
|
||||
$(WINDOWS_DEPS):
|
||||
@ -1198,7 +1246,7 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
|
||||
.PHONY: tarball
|
||||
|
||||
dist: ## Build versions of all distributables for release.
|
||||
dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefriends.standalone.exe) out/TildeFriends-release.fdroid.apk appimage tarball
|
||||
dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefriends.standalone.exe) out/TildeFriends-release.fdroid.apk appimage tarball out/release/tildefriends.standalone $(if $(HAVE_CROSS_AARCH64), out/armrelease/tildefriends.standalone)
|
||||
@mkdir -p dist/
|
||||
@echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz"
|
||||
@cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz
|
||||
@ -1216,6 +1264,10 @@ dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefrien
|
||||
@cp out/TildeFriends-release.fdroid.apk dist/TildeFriends-$(VERSION_NUMBER).fdroid.apk
|
||||
@echo "[cp] TildeFriends-x86_64-$(VERSION_NUMBER).AppImage"
|
||||
@cp out/tildefriends-x86_64.AppImage dist/TildeFriends-x86_64-$(VERSION_NUMBER).AppImage
|
||||
@echo "[cp] tildefriends-linux-$(UNAME_M)-$(VERSION_NUMBER)"
|
||||
@cp out/release/tildefriends.standalone dist/tildefriends-linux-$(UNAME_M)-$(VERSION_NUMBER)
|
||||
@test $(HAVE_CROSS_AARCH64) && echo "[cp] tildefriends-linux-aarch64-$(VERSION_NUMBER)"
|
||||
@test $(HAVE_CROSS_AARCH64) && cp out/armrelease/tildefriends.standalone dist/tildefriends-linux-aarch64-$(VERSION_NUMBER)
|
||||
.PHONY: dist
|
||||
|
||||
dist-test: dist ## Exercise some built distributable files, making sure they work as intended.
|
||||
@ -1258,7 +1310,7 @@ help: ## Display this help message.
|
||||
/^##/ { sub(/^## ?/, ""); print $$0 } \
|
||||
/^[[:alnum:]-]+:.*##/ { \
|
||||
sub(/:.*##\s?/, ":"); \
|
||||
printf " %s%-20s%s %s%s%s\n", G, $$1, R, O, $$2, R \
|
||||
printf " %s%-21s%s %s%s%s\n", G, $$1, R, O, $$2, R \
|
||||
} \
|
||||
' < $(filter-out %.d,$(MAKEFILE_LIST))
|
||||
@echo "" # Blank line.
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "🐌",
|
||||
"previous": "&q/1uGp0jMvsYGW7Gj8E33kf6UFo/uNYDXg3zo1sVKQg=.sha256"
|
||||
"emoji": "🦀",
|
||||
"previous": "&Us7cb8UfbwNoFVPQXDnGBdGDmxQwPdNwcNjaiai80YA=.sha256"
|
||||
}
|
||||
|
@ -112,27 +112,25 @@ class TfElement extends LitElement {
|
||||
|
||||
keydown(event) {
|
||||
if (event.altKey && event.key == 'ArrowUp') {
|
||||
this.next_channel(1);
|
||||
this.next_channel(-1);
|
||||
event.preventDefault();
|
||||
} else if (event.altKey && event.key == 'ArrowDown') {
|
||||
this.next_channel(-1);
|
||||
this.next_channel(1);
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
next_channel(delta) {
|
||||
let channel_names = ['', '@'].concat(this.channels);
|
||||
let channel_names = ['', '@', '🔐', ...this.channels.map((x) => '#' + x)];
|
||||
let index = channel_names.indexOf(this.hash.substring(1));
|
||||
if (index != -1) {
|
||||
index += delta;
|
||||
this.set_hash(
|
||||
index = index != -1 ? index + delta : 0;
|
||||
tfrpc.rpc.setHash(
|
||||
'#' +
|
||||
encodeURIComponent(
|
||||
channel_names[(index + channel_names.length) % channel_names.length]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
set_hash(hash) {
|
||||
this.hash = decodeURIComponent(hash || '#');
|
||||
@ -150,6 +148,7 @@ class TfElement extends LitElement {
|
||||
async fetch_about(ids, users) {
|
||||
const k_cache_version = 1;
|
||||
let cache = await tfrpc.rpc.databaseGet('about');
|
||||
let original_cache = cache;
|
||||
cache = cache ? JSON.parse(cache) : {};
|
||||
if (cache.version !== k_cache_version) {
|
||||
cache = {
|
||||
@ -215,7 +214,13 @@ class TfElement extends LitElement {
|
||||
}
|
||||
}
|
||||
cache.last_row_id = max_row_id;
|
||||
await tfrpc.rpc.databaseSet('about', JSON.stringify(cache));
|
||||
let new_cache = JSON.stringify(cache);
|
||||
if (new_cache !== original_cache) {
|
||||
let start_time = new Date();
|
||||
tfrpc.rpc.databaseSet('about', new_cache).then(function () {
|
||||
console.log('saving about took', (new Date() - start_time) / 1000);
|
||||
});
|
||||
}
|
||||
users = users || {};
|
||||
for (let id of Object.keys(cache.about)) {
|
||||
users[id] = Object.assign(users[id] || {}, cache.about[id]);
|
||||
@ -313,6 +318,7 @@ class TfElement extends LitElement {
|
||||
UNION
|
||||
SELECT '' AS channel, MAX(messages.rowid) AS rowid FROM messages
|
||||
JOIN json_each(?2) AS following ON messages.author = following.value
|
||||
WHERE messages.content ->> 'type' = 'post' AND messages.content ->> 'root' IS NULL
|
||||
UNION
|
||||
SELECT '@' AS channel, MAX(messages.rowid) AS rowid FROM messages_fts(?3)
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
@ -538,15 +544,14 @@ class TfElement extends LitElement {
|
||||
)}
|
||||
</div>
|
||||
`;
|
||||
let contents = !this.loaded
|
||||
? this.loading
|
||||
let contents =
|
||||
!this.loaded || this.loading
|
||||
? html`<div
|
||||
class="w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge"
|
||||
class="w3-display-middle w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge w3-xlarge"
|
||||
>
|
||||
<span class="w3-spin" style="display: inline-block">🦀</span>
|
||||
Loading...
|
||||
</div>
|
||||
${this.render_tab()}`
|
||||
: html`<div>Select or create an identity.</div>`
|
||||
</div>`
|
||||
: this.render_tab();
|
||||
return html`
|
||||
<div
|
||||
|
@ -15,6 +15,7 @@ class TfComposeElement extends LitElement {
|
||||
drafts: {type: Object},
|
||||
author: {type: String},
|
||||
channel: {type: String},
|
||||
new_thread: {type: Boolean},
|
||||
};
|
||||
}
|
||||
|
||||
@ -28,6 +29,7 @@ class TfComposeElement extends LitElement {
|
||||
this.apps = undefined;
|
||||
this.drafts = {};
|
||||
this.author = undefined;
|
||||
this.new_thread = false;
|
||||
}
|
||||
|
||||
process_text(text) {
|
||||
@ -200,9 +202,23 @@ class TfComposeElement extends LitElement {
|
||||
channel: this.channel,
|
||||
};
|
||||
if (this.root || this.branch) {
|
||||
message.root = this.root;
|
||||
message.root = this.new_thread ? (this.branch ?? this.root) : this.root;
|
||||
message.branch = this.branch;
|
||||
}
|
||||
let reply = Object.fromEntries(
|
||||
(
|
||||
await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.id, messages.author FROM messages
|
||||
JOIN json_each(?) AS refs ON messages.id = refs.value
|
||||
`,
|
||||
[JSON.stringify([this.root, this.branch])]
|
||||
)
|
||||
).map((row) => [row.id, row.author])
|
||||
);
|
||||
if (Object.keys(reply).length) {
|
||||
message.reply = reply;
|
||||
}
|
||||
if (Object.values(draft.mentions || {}).length) {
|
||||
message.mentions = Object.values(draft.mentions);
|
||||
}
|
||||
@ -469,6 +485,20 @@ class TfComposeElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
render_new_thread() {
|
||||
let self = this;
|
||||
if (
|
||||
this.root !== undefined &&
|
||||
this.branch !== undefined &&
|
||||
this.root != this.branch
|
||||
) {
|
||||
return html`
|
||||
<input type="checkbox" class="w3-check w3-theme-d1" id="new_thread" @change=${() => (self.new_thread = !self.new_thread)} ?checked=${self.new_thread}></input>
|
||||
<label for="new_thread">New Thread</label>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
get_draft() {
|
||||
return this.drafts[this.branch || ''] || {};
|
||||
}
|
||||
@ -563,6 +593,7 @@ class TfComposeElement extends LitElement {
|
||||
self.render_mention(x)
|
||||
)}
|
||||
${this.render_attach_app()} ${this.render_content_warning()}
|
||||
${this.render_new_thread()}
|
||||
<button class="w3-button w3-theme-d1" id="submit" @click=${this.submit}>
|
||||
Submit
|
||||
</button>
|
||||
|
@ -210,7 +210,7 @@ class TfNewsElement extends LitElement {
|
||||
channel=${this.channel}
|
||||
channel_unread=${this.channel_unread}
|
||||
></tf-message>
|
||||
${x.rowid == unread_rowid && x != final_messages[0]
|
||||
${x.rowid == unread_rowid
|
||||
? html`<div style="display: flex; flex-direction: row">
|
||||
<div
|
||||
style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px"
|
||||
|
@ -175,6 +175,9 @@ class TfTabConnectionsElement extends LitElement {
|
||||
.map((x) => html`<li>${this.render_connection(x)}</li>`)}
|
||||
${this.render_room_peers(connection.id)}
|
||||
</ul>
|
||||
<div ?hidden=${!connection.destroy_reason} class="w3-panel w3-red">
|
||||
<p>${connection.destroy_reason}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
if (this.hash == '#@') {
|
||||
result = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
WITH mentions AS (SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM messages_fts(?1)
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
JOIN json_each(?2) AS following ON messages.author = following.value
|
||||
@ -59,7 +59,13 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
messages.author != ?1 AND
|
||||
messages.timestamp >= ?3 AND
|
||||
messages.timestamp < ?4
|
||||
ORDER BY timestamp DESC limit 20
|
||||
ORDER BY timestamp DESC limit 20)
|
||||
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM mentions
|
||||
JOIN messages_refs ON mentions.id = messages_refs.ref
|
||||
JOIN messages ON messages_refs.message = messages.id
|
||||
UNION
|
||||
SELECT * FROM mentions
|
||||
`,
|
||||
[
|
||||
'"' + this.whoami.replace('"', '""') + '"',
|
||||
|
@ -176,7 +176,7 @@ class TfTabNewsElement extends LitElement {
|
||||
return html`
|
||||
<div
|
||||
class="w3-sidebar w3-bar-block w3-theme-d1 w3-collapse w3-animate-left"
|
||||
style="width: 2in; left: 0; z-index: 5"
|
||||
style="width: 2in; left: 0; z-index: 5; box-sizing: border-box"
|
||||
id="sidebar"
|
||||
>
|
||||
<div
|
||||
@ -216,6 +216,18 @@ class TfTabNewsElement extends LitElement {
|
||||
style=${this.hash == '#🔐' ? 'font-weight: bold' : undefined}
|
||||
>🔐private ${this.unread_status('🔐')}</a
|
||||
>
|
||||
${Object.keys(this.drafts)
|
||||
.sort()
|
||||
.map(
|
||||
(x) => html`
|
||||
<a
|
||||
href=${'#' + encodeURIComponent(x)}
|
||||
class="w3-bar-item w3-button"
|
||||
style="text-wrap: nowrap; text-overflow: ellipsis"
|
||||
>📝 ${this.drafts[x]?.text ?? x}</a
|
||||
>
|
||||
`
|
||||
)}
|
||||
${this.channels.map(
|
||||
(x) => html`
|
||||
<a
|
||||
|
@ -21,14 +21,14 @@
|
||||
}:
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
pname = "tildefriends";
|
||||
version = "0.0.25";
|
||||
version = "0.0.26";
|
||||
|
||||
src = pkgs.fetchFromGitea {
|
||||
domain = "dev.tildefriends.net";
|
||||
owner = "cory";
|
||||
repo = "tildefriends";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-Rfk+CUhi+Ss0z70CCgmtVM/w4nCL1GX/MsD4sPYIa5s=";
|
||||
hash = "sha256-XJ7M++risfsRn9GkS1zjTQpqqV5S09uyimeVzU9hGGg=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.unprompted.tildefriends"
|
||||
android:versionCode="31"
|
||||
android:versionName="0.0.26">
|
||||
android:versionCode="32"
|
||||
android:versionName="0.0.27-wip">
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application
|
||||
|
@ -738,25 +738,6 @@ static void _httpd_endpoint_mem(tf_http_request_t* request)
|
||||
tf_free(response);
|
||||
}
|
||||
|
||||
static void _httpd_endpoint_disconnections(tf_http_request_t* request)
|
||||
{
|
||||
if (_httpd_redirect(request))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tf_task_t* task = request->user_data;
|
||||
char* response = tf_task_get_disconnections(task);
|
||||
const char* headers[] = {
|
||||
"Content-Type",
|
||||
"application/json; charset=utf-8",
|
||||
"Access-Control-Allow-Origin",
|
||||
"*",
|
||||
};
|
||||
tf_http_respond(request, 200, headers, tf_countof(headers) / 2, response, response ? strlen(response) : 0);
|
||||
tf_free(response);
|
||||
}
|
||||
|
||||
static void _httpd_endpoint_hitches(tf_http_request_t* request)
|
||||
{
|
||||
if (_httpd_redirect(request))
|
||||
@ -2317,7 +2298,6 @@ void tf_httpd_register(JSContext* context)
|
||||
|
||||
tf_http_add_handler(http, "/robots.txt", _httpd_endpoint_robots_txt, NULL, NULL);
|
||||
tf_http_add_handler(http, "/debug", _httpd_endpoint_debug, NULL, task);
|
||||
tf_http_add_handler(http, "/disconnections", _httpd_endpoint_disconnections, NULL, task);
|
||||
tf_http_add_handler(http, "/hitches", _httpd_endpoint_hitches, NULL, task);
|
||||
tf_http_add_handler(http, "/mem", _httpd_endpoint_mem, NULL, task);
|
||||
tf_http_add_handler(http, "/trace", _httpd_endpoint_trace, NULL, task);
|
||||
|
148
src/main.c
148
src/main.c
@ -25,6 +25,7 @@
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@ -41,7 +42,102 @@
|
||||
|
||||
struct backtrace_state* g_backtrace_state;
|
||||
|
||||
const char* k_db_path_default = "db.sqlite";
|
||||
#if !defined(TARGET_OS_IPHONE)
|
||||
static const char* _get_db_path()
|
||||
{
|
||||
const char* k_db_path_default = "db.sqlite";
|
||||
#if defined(__linux__)
|
||||
if (stat(k_db_path_default, &(struct stat) { 0 }) == 0)
|
||||
{
|
||||
return tf_strdup(k_db_path_default);
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
char* data_home = NULL;
|
||||
size_t size = sizeof(buffer);
|
||||
int r = uv_os_getenv("XDG_DATA_HOME", buffer, &size);
|
||||
if (r == 0 || r == UV_ENOBUFS)
|
||||
{
|
||||
size++;
|
||||
data_home = alloca(size);
|
||||
if (uv_os_getenv("XDG_DATA_HOME", data_home, &size) != 0)
|
||||
{
|
||||
data_home = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data_home)
|
||||
{
|
||||
size = sizeof(buffer);
|
||||
r = uv_os_getenv("HOME", buffer, &size);
|
||||
if (r == 0 || r == UV_ENOBUFS)
|
||||
{
|
||||
size++;
|
||||
char* home = alloca(size);
|
||||
r = uv_os_getenv("HOME", home, &size);
|
||||
if (r == 0)
|
||||
{
|
||||
size = snprintf(NULL, 0, "%s/.local/share", home) + 1;
|
||||
data_home = alloca(size);
|
||||
snprintf(data_home, size, "%s/.local/share", home);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data_home)
|
||||
{
|
||||
size = snprintf(NULL, 0, "%s/tildefriends/db.sqlite", data_home) + 1;
|
||||
char* path = alloca(size);
|
||||
snprintf(path, size, "%s/tildefriends/db.sqlite", data_home);
|
||||
return tf_strdup(path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return tf_strdup(k_db_path_default);
|
||||
}
|
||||
|
||||
static void _create_directories_for_file(const char* path, int mode)
|
||||
{
|
||||
if (stat(path, &(struct stat) { 0 }) == 0)
|
||||
{
|
||||
/* It already exists. OK. */
|
||||
return;
|
||||
}
|
||||
|
||||
size_t length = strlen(path) + 1;
|
||||
char* copy = alloca(length);
|
||||
memcpy(copy, path, length);
|
||||
#if defined(_WIN32)
|
||||
for (char* c = copy; *c; c++)
|
||||
{
|
||||
if (*c == '\\')
|
||||
{
|
||||
*c = '/';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
char* slash = copy;
|
||||
while (slash)
|
||||
{
|
||||
slash = strchr(slash + 1, '/');
|
||||
if (slash)
|
||||
{
|
||||
*slash = '\0';
|
||||
#if defined(_WIN32)
|
||||
if (mkdir(copy) == 0)
|
||||
#else
|
||||
if (mkdir(copy, mode) == 0)
|
||||
#endif
|
||||
{
|
||||
tf_printf("Created directory %s.\n", copy);
|
||||
}
|
||||
*slash = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_IPHONE && !defined(__ANDROID__)
|
||||
static int _tf_command_export(const char* file, int argc, char* argv[]);
|
||||
@ -131,7 +227,8 @@ static int _tf_command_test(const char* file, int argc, char* argv[])
|
||||
static int _tf_command_import(const char* file, int argc, char* argv[])
|
||||
{
|
||||
const char* user = "import";
|
||||
const char* db_path = k_db_path_default;
|
||||
const char* default_db_path = _get_db_path();
|
||||
const char* db_path = default_db_path;
|
||||
bool show_usage = false;
|
||||
|
||||
while (!show_usage)
|
||||
@ -169,11 +266,13 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
|
||||
tf_printf("\n%s import [options] [paths...]\n\n", file);
|
||||
tf_printf("options:\n");
|
||||
tf_printf(" -u, --user user User into whose account apps will be imported (default: \"import\").\n");
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
|
||||
tf_printf(" -h, --help Show this usage information.\n");
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
_create_directories_for_file(db_path, 0700);
|
||||
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
|
||||
if (optind < argc)
|
||||
{
|
||||
@ -189,13 +288,15 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
|
||||
tf_ssb_import(ssb, user, "apps");
|
||||
}
|
||||
tf_ssb_destroy(ssb);
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int _tf_command_export(const char* file, int argc, char* argv[])
|
||||
{
|
||||
const char* user = "core";
|
||||
const char* db_path = k_db_path_default;
|
||||
const char* default_db_path = _get_db_path();
|
||||
const char* db_path = default_db_path;
|
||||
bool show_usage = false;
|
||||
|
||||
while (!show_usage)
|
||||
@ -233,10 +334,11 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
|
||||
tf_printf("\n%s export [options] [paths...]\n\n", file);
|
||||
tf_printf("options:\n");
|
||||
tf_printf(" -u, --user user User from whose account apps will be exported (default: \"core\").\n");
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
|
||||
tf_printf(" -h, --help Show this usage information.\n");
|
||||
tf_printf("\n");
|
||||
tf_printf("paths Paths of apps to export (example: /~core/ssb /~user/app).\n");
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -271,6 +373,7 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
tf_ssb_destroy(ssb);
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -298,7 +401,8 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
|
||||
{
|
||||
const char* user = NULL;
|
||||
const char* identity = NULL;
|
||||
const char* db_path = k_db_path_default;
|
||||
const char* default_db_path = _get_db_path();
|
||||
const char* db_path = default_db_path;
|
||||
const char* content = NULL;
|
||||
bool show_usage = false;
|
||||
|
||||
@ -346,14 +450,16 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
|
||||
tf_printf("options:\n");
|
||||
tf_printf(" -u, --user user User owning identity with which to publish.\n");
|
||||
tf_printf(" -i, --id identity Identity with which to publish message.\n");
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
|
||||
tf_printf(" -c, --content json JSON content of message to publish.\n");
|
||||
tf_printf(" -h, --help Show this usage information.\n");
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int result = EXIT_FAILURE;
|
||||
tf_printf("Posting %s as account %s belonging to %s...\n", content, identity, user);
|
||||
_create_directories_for_file(db_path, 0700);
|
||||
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
|
||||
uint8_t private_key[512] = { 0 };
|
||||
if (tf_ssb_db_identity_get_private_key(ssb, user, identity, private_key, sizeof(private_key)))
|
||||
@ -386,12 +492,14 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
|
||||
tf_printf("Did not find private key for identity %s belonging to %s.\n", identity, user);
|
||||
}
|
||||
tf_ssb_destroy(ssb);
|
||||
tf_free((void*)default_db_path);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int _tf_command_store_blob(const char* file, int argc, char* argv[])
|
||||
{
|
||||
const char* db_path = k_db_path_default;
|
||||
const char* default_db_path = _get_db_path();
|
||||
const char* db_path = default_db_path;
|
||||
const char* file_path = NULL;
|
||||
bool show_usage = false;
|
||||
|
||||
@ -429,9 +537,10 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
|
||||
{
|
||||
tf_printf("\n%s store_blob [options]\n\n", file);
|
||||
tf_printf("options:\n");
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
|
||||
tf_printf(" -f, --file file_path Path to file to add to the blob store.\n");
|
||||
tf_printf(" -h, --help Show this usage information.\n");
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -441,6 +550,7 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
|
||||
if (!blob_file)
|
||||
{
|
||||
tf_printf("Failed to open %s: %s.\n", file_path, strerror(errno));
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -464,11 +574,13 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
|
||||
tf_printf("Failed to read %s: %s.\n", file_path, strerror(errno));
|
||||
fclose(blob_file);
|
||||
tf_free(data);
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fclose(blob_file);
|
||||
|
||||
char id[256];
|
||||
_create_directories_for_file(db_path, 0700);
|
||||
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
|
||||
if (tf_ssb_db_blob_store(ssb, (const uint8_t*)data, size, id, sizeof(id), NULL))
|
||||
{
|
||||
@ -476,13 +588,15 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
|
||||
}
|
||||
tf_ssb_destroy(ssb);
|
||||
tf_free(data);
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int _tf_command_verify(const char* file, int argc, char* argv[])
|
||||
{
|
||||
const char* identity = NULL;
|
||||
const char* db_path = k_db_path_default;
|
||||
const char* default_db_path = _get_db_path();
|
||||
const char* db_path = default_db_path;
|
||||
bool show_usage = false;
|
||||
|
||||
while (!show_usage)
|
||||
@ -520,8 +634,9 @@ static int _tf_command_verify(const char* file, int argc, char* argv[])
|
||||
tf_printf("\n%s import [options] [paths...]\n\n", file);
|
||||
tf_printf("options:\n");
|
||||
tf_printf(" -i, --identity identity Identity to verify.\n");
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
|
||||
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
|
||||
tf_printf(" -h, --help Show this usage information.\n");
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -529,6 +644,7 @@ static int _tf_command_verify(const char* file, int argc, char* argv[])
|
||||
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
|
||||
bool verified = tf_ssb_db_verify(ssb, identity);
|
||||
tf_ssb_destroy(ssb);
|
||||
tf_free((void*)default_db_path);
|
||||
return verified ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
@ -673,13 +789,14 @@ static void _shed_privileges()
|
||||
|
||||
static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
{
|
||||
const char* default_db_path = _get_db_path();
|
||||
tf_run_args_t args = {
|
||||
.count = 1,
|
||||
.script = "core/core.js",
|
||||
.http_port = 12345,
|
||||
.https_port = 12346,
|
||||
.ssb_port = 8008,
|
||||
.db_path = k_db_path_default,
|
||||
.db_path = default_db_path,
|
||||
};
|
||||
bool show_usage = false;
|
||||
|
||||
@ -764,7 +881,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
tf_printf(" -b, --ssb-port port Port on which to run SSB (default: 8008, 0 disables).\n");
|
||||
tf_printf(" -p, --http-port port Port on which to run Tilde Friends web server (default: 12345).\n");
|
||||
tf_printf(" -q, --https-port port Port on which to run secure Tilde Friends web server (default: 12346).\n");
|
||||
tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", k_db_path_default);
|
||||
tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", default_db_path);
|
||||
tf_printf(" -k, --ssb-network-key key SSB network key to use.\n");
|
||||
tf_printf(" -n, --count count Number of instances to run.\n");
|
||||
tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true.\n");
|
||||
@ -772,6 +889,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
tf_printf(" -z, --zip path Zip archive from which to load files.\n");
|
||||
tf_printf(" -v, --verbose Log raw messages.\n");
|
||||
tf_printf(" -h, --help Show this usage information.\n");
|
||||
tf_free((void*)default_db_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -780,6 +898,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
setpgid(0, 0);
|
||||
#endif
|
||||
|
||||
_create_directories_for_file(args.db_path, 0700);
|
||||
if (args.count == 1)
|
||||
{
|
||||
result = _tf_run_task(&args, 0);
|
||||
@ -807,6 +926,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
tf_free(data);
|
||||
tf_free(threads);
|
||||
}
|
||||
tf_free((void*)default_db_path);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1088,7 +1208,7 @@ void tf_run_thread_start(const char* zip_path)
|
||||
.http_port = 12345,
|
||||
.https_port = 12346,
|
||||
.ssb_port = 8008,
|
||||
.db_path = k_db_path_default,
|
||||
.db_path = "db.sqlite",
|
||||
.one_proc = true,
|
||||
.zip = zip_path,
|
||||
};
|
||||
|
267
src/ssb.c
267
src/ssb.c
@ -71,8 +71,6 @@ enum
|
||||
{
|
||||
k_connections_changed_callbacks_max = 8,
|
||||
k_tf_ssb_rpc_message_body_length_max = 1 * 1024 * 1024,
|
||||
k_debug_close_message_count = 256,
|
||||
k_debug_close_connection_count = 32,
|
||||
k_seed_expire_seconds = 10 * 60,
|
||||
k_seed_check_interval_seconds = 5 * 60,
|
||||
k_udp_discovery_expires_seconds = 10,
|
||||
@ -84,24 +82,6 @@ typedef struct _tf_ssb_broadcast_t tf_ssb_broadcast_t;
|
||||
typedef struct _tf_ssb_connection_t tf_ssb_connection_t;
|
||||
typedef struct _tf_ssb_request_t tf_ssb_request_t;
|
||||
|
||||
typedef struct _tf_ssb_debug_message_t
|
||||
{
|
||||
bool outgoing;
|
||||
int flags;
|
||||
int32_t request_number;
|
||||
time_t timestamp;
|
||||
size_t size;
|
||||
uint8_t data[];
|
||||
} tf_ssb_debug_message_t;
|
||||
|
||||
typedef struct _tf_ssb_debug_close_t
|
||||
{
|
||||
char id[k_id_base64_len];
|
||||
char tunnel[k_id_base64_len];
|
||||
char reason[128];
|
||||
tf_ssb_debug_message_t* messages[k_debug_close_message_count];
|
||||
} tf_ssb_debug_close_t;
|
||||
|
||||
typedef struct _tf_ssb_request_t
|
||||
{
|
||||
char name[256];
|
||||
@ -218,7 +198,6 @@ typedef struct _tf_ssb_t
|
||||
uint8_t priv[crypto_sign_SECRETKEYBYTES];
|
||||
|
||||
bool verbose;
|
||||
bool store_debug_messages;
|
||||
bool shutting_down;
|
||||
bool shutting_down_deferred;
|
||||
|
||||
@ -252,8 +231,6 @@ typedef struct _tf_ssb_t
|
||||
tf_ssb_broadcasts_changed_callback_node_t* broadcasts_changed;
|
||||
int broadcasts_changed_count;
|
||||
|
||||
tf_ssb_debug_close_t debug_close[k_debug_close_connection_count];
|
||||
|
||||
int32_t thread_busy_count;
|
||||
int32_t thread_busy_max;
|
||||
|
||||
@ -296,6 +273,7 @@ typedef struct _tf_ssb_connection_t
|
||||
uv_async_t async;
|
||||
uv_async_t scheduled_async;
|
||||
uv_timer_t handshake_timer;
|
||||
uv_timer_t linger_timer;
|
||||
bool closing;
|
||||
|
||||
tf_ssb_connection_t* tunnel_connection;
|
||||
@ -356,7 +334,6 @@ typedef struct _tf_ssb_connection_t
|
||||
tf_ssb_connection_scheduled_t* scheduled;
|
||||
int scheduled_count;
|
||||
|
||||
tf_ssb_debug_message_t* debug_messages[k_debug_close_message_count];
|
||||
int ref_count;
|
||||
|
||||
int read_back_pressure;
|
||||
@ -375,6 +352,8 @@ static int s_connection_index;
|
||||
static int s_tunnel_index;
|
||||
|
||||
static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broadcast, int expires_seconds);
|
||||
static uint64_t _tf_ssb_callback_pre(tf_ssb_t* ssb);
|
||||
static void _tf_ssb_callback_post(tf_ssb_t* ssb, void* callback, uint64_t pre);
|
||||
static void _tf_ssb_connection_client_send_hello(tf_ssb_connection_t* connection);
|
||||
static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason);
|
||||
static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* reason);
|
||||
@ -415,63 +394,6 @@ static const char* _tf_ssb_connection_state_to_string(tf_ssb_state_t state)
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_add_debug_close(tf_ssb_t* ssb, tf_ssb_connection_t* connection, const char* reason)
|
||||
{
|
||||
if (!ssb->store_debug_messages)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < k_debug_close_message_count; i++)
|
||||
{
|
||||
tf_free(ssb->debug_close[k_debug_close_connection_count - 1].messages[i]);
|
||||
}
|
||||
for (int i = k_debug_close_connection_count - 1; i > 0; i--)
|
||||
{
|
||||
ssb->debug_close[i] = ssb->debug_close[i - 1];
|
||||
}
|
||||
|
||||
tf_ssb_id_bin_to_str(ssb->debug_close[0].id, sizeof(ssb->debug_close[0].id), connection->serverpub);
|
||||
if (connection->tunnel_connection)
|
||||
{
|
||||
tf_ssb_id_bin_to_str(ssb->debug_close[0].tunnel, sizeof(ssb->debug_close[0].tunnel), connection->tunnel_connection->serverpub);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(ssb->debug_close[0].tunnel, 0, sizeof(ssb->debug_close[0].tunnel));
|
||||
}
|
||||
memcpy(ssb->debug_close[0].messages, connection->debug_messages, sizeof(connection->debug_messages));
|
||||
memset(connection->debug_messages, 0, sizeof(connection->debug_messages));
|
||||
snprintf(ssb->debug_close[0].reason, sizeof(ssb->debug_close[0].reason), "%s", reason);
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_add_debug_message(tf_ssb_connection_t* connection, bool outgoing, int flags, int32_t request_number, const uint8_t* data, size_t size)
|
||||
{
|
||||
if (!connection->ssb->store_debug_messages)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (connection->debug_messages[k_debug_close_message_count - 1])
|
||||
{
|
||||
tf_free(connection->debug_messages[k_debug_close_message_count - 1]);
|
||||
}
|
||||
for (int i = k_debug_close_message_count - 1; i > 0; i--)
|
||||
{
|
||||
connection->debug_messages[i] = connection->debug_messages[i - 1];
|
||||
}
|
||||
tf_ssb_debug_message_t* message = tf_malloc(sizeof(tf_ssb_debug_message_t) + size);
|
||||
*message = (tf_ssb_debug_message_t) {
|
||||
.outgoing = outgoing,
|
||||
.flags = flags,
|
||||
.request_number = request_number,
|
||||
.timestamp = time(NULL),
|
||||
.size = size,
|
||||
};
|
||||
memcpy(message + 1, data, size);
|
||||
connection->debug_messages[0] = message;
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_send_close(tf_ssb_connection_t* connection)
|
||||
{
|
||||
uint8_t message_enc[34];
|
||||
@ -497,7 +419,6 @@ static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char
|
||||
else if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified)
|
||||
{
|
||||
tf_printf("Connection %s %p is closing: %s.\n", connection->name, connection, reason);
|
||||
_tf_ssb_add_debug_close(connection->ssb, connection, reason);
|
||||
connection->state = k_tf_ssb_state_closing;
|
||||
_tf_ssb_connection_send_close(connection);
|
||||
}
|
||||
@ -679,7 +600,9 @@ static void _tf_ssb_connection_dispatch_scheduled(tf_ssb_connection_t* connectio
|
||||
memmove(connection->scheduled, connection->scheduled + 1, sizeof(tf_ssb_connection_scheduled_t) * (connection->scheduled_count - 1));
|
||||
connection->scheduled_count--;
|
||||
tf_trace_begin(connection->ssb->trace, "scheduled callback");
|
||||
PRE_CALLBACK(connection->ssb, scheduled.callback);
|
||||
scheduled.callback(connection, scheduled.user_data);
|
||||
POST_CALLBACK(connection->ssb, scheduled.callback);
|
||||
tf_trace_end(connection->ssb->trace);
|
||||
}
|
||||
}
|
||||
@ -921,7 +844,6 @@ bool tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false", k_ssb_type_names[flags & k_ssb_rpc_mask_type],
|
||||
request_number, size, (flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary ? 0 : (int)size, message);
|
||||
}
|
||||
_tf_ssb_connection_add_debug_message(connection, true, flags & k_ssb_rpc_mask_send, request_number, message, size);
|
||||
_tf_ssb_connection_box_stream_send(connection, combined, 1 + 2 * sizeof(uint32_t) + size);
|
||||
tf_free(combined);
|
||||
connection->ssb->rpc_out++;
|
||||
@ -1360,7 +1282,9 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection,
|
||||
connection->state = k_tf_ssb_state_verified;
|
||||
if (connection->connect_callback)
|
||||
{
|
||||
PRE_CALLBACK(connection->ssb, connection->connect_callback);
|
||||
connection->connect_callback(connection, NULL, connection->connect_callback_user_data);
|
||||
POST_CALLBACK(connection->ssb, connection->connect_callback);
|
||||
connection->connect_callback = NULL;
|
||||
connection->connect_callback_user_data = NULL;
|
||||
}
|
||||
@ -1653,7 +1577,6 @@ static void _tf_ssb_name_to_string(JSContext* context, JSValue object, char* buf
|
||||
static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const uint8_t* message, size_t size)
|
||||
{
|
||||
connection->ssb->rpc_in++;
|
||||
_tf_ssb_connection_add_debug_message(connection, false, flags, request_number, message, size);
|
||||
bool close_connection = false;
|
||||
if (size == 0)
|
||||
{
|
||||
@ -1917,19 +1840,32 @@ JSValue tf_ssb_sign_message(tf_ssb_t* ssb, const char* author, const uint8_t* pr
|
||||
return root;
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_linger_timer(uv_timer_t* timer)
|
||||
{
|
||||
tf_ssb_connection_t* connection = timer->data;
|
||||
uv_close((uv_handle_t*)&connection->linger_timer, _tf_ssb_connection_on_close);
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* reason)
|
||||
{
|
||||
tf_ssb_t* ssb = connection->ssb;
|
||||
if (!connection->closing)
|
||||
{
|
||||
connection->closing = true;
|
||||
uv_timer_start(&connection->linger_timer, _tf_ssb_connection_linger_timer, 5000, 0);
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_update, connection);
|
||||
}
|
||||
if (connection->connect_callback)
|
||||
{
|
||||
PRE_CALLBACK(connection->ssb, connection->connect_callback);
|
||||
connection->connect_callback(NULL, reason, connection->connect_callback_user_data);
|
||||
POST_CALLBACK(connection->ssb, connection->connect_callback);
|
||||
connection->connect_callback = NULL;
|
||||
connection->connect_callback_user_data = NULL;
|
||||
}
|
||||
if (!connection->destroy_reason)
|
||||
{
|
||||
connection->destroy_reason = reason;
|
||||
connection->destroy_reason = tf_strdup(reason);
|
||||
}
|
||||
_tf_ssb_connection_dispatch_scheduled(connection);
|
||||
tf_free(connection->scheduled);
|
||||
@ -1955,14 +1891,6 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch
|
||||
tf_ssb_connection_remove_request(*it, (*it)->requests[i].request_number);
|
||||
}
|
||||
}
|
||||
if (*it == connection)
|
||||
{
|
||||
*it = connection->next;
|
||||
connection->next = NULL;
|
||||
ssb->connections_count--;
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_remove, connection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool again = true;
|
||||
while (again)
|
||||
@ -2010,22 +1938,29 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch
|
||||
}
|
||||
|
||||
if (JS_IsUndefined(connection->object) && !connection->async.data && !connection->scheduled_async.data && !connection->tcp.data && !connection->connect.data &&
|
||||
!connection->handshake_timer.data && connection->ref_count == 0)
|
||||
!connection->handshake_timer.data && !connection->linger_timer.data && connection->ref_count == 0)
|
||||
{
|
||||
tf_free(connection->message_requests);
|
||||
connection->message_requests = NULL;
|
||||
connection->message_requests_count = 0;
|
||||
|
||||
for (int i = 0; i < k_debug_close_message_count; i++)
|
||||
for (tf_ssb_connection_t** it = &connection->ssb->connections; *it; it = &(*it)->next)
|
||||
{
|
||||
tf_free(connection->debug_messages[i]);
|
||||
connection->debug_messages[i] = NULL;
|
||||
if (*it == connection)
|
||||
{
|
||||
*it = connection->next;
|
||||
connection->next = NULL;
|
||||
ssb->connections_count--;
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_remove, connection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (--connection->ssb->connection_ref_count == 0 && connection->ssb->shutting_down_deferred)
|
||||
{
|
||||
tf_ssb_destroy(connection->ssb);
|
||||
}
|
||||
tf_free((void*)connection->destroy_reason);
|
||||
tf_free(connection);
|
||||
}
|
||||
}
|
||||
@ -2290,7 +2225,6 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, const char* db_path
|
||||
|
||||
char buffer[8] = { 0 };
|
||||
size_t buffer_size = sizeof(buffer);
|
||||
ssb->store_debug_messages = uv_os_getenv("TF_DEBUG_CLOSE", buffer, &buffer_size) == 0 && strcmp(buffer, "1") == 0;
|
||||
buffer_size = sizeof(buffer);
|
||||
ssb->verbose = uv_os_getenv("TF_SSB_VERBOSE", buffer, &buffer_size) == 0 && strcmp(buffer, "1") == 0;
|
||||
|
||||
@ -2684,13 +2618,6 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
||||
ssb->broadcasts_count--;
|
||||
tf_free(broadcast);
|
||||
}
|
||||
for (int i = 0; i < k_debug_close_connection_count; i++)
|
||||
{
|
||||
for (int j = 0; j < k_debug_close_message_count; j++)
|
||||
{
|
||||
tf_free(ssb->debug_close[i].messages[j]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ssb->db_readers_count; i++)
|
||||
{
|
||||
sqlite3_close(ssb->db_readers[i]);
|
||||
@ -2813,6 +2740,9 @@ static tf_ssb_connection_t* _tf_ssb_connection_create(
|
||||
uv_timer_init(ssb->loop, &connection->handshake_timer);
|
||||
uv_timer_start(&connection->handshake_timer, _tf_ssb_connection_handshake_timer_callback, k_handshake_timeout_ms, 0);
|
||||
|
||||
connection->linger_timer.data = connection;
|
||||
uv_timer_init(ssb->loop, &connection->linger_timer);
|
||||
|
||||
connection->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetOpaque(connection->object, connection);
|
||||
char public_key_str[k_id_base64_len] = { 0 };
|
||||
@ -2886,6 +2816,9 @@ tf_ssb_connection_t* tf_ssb_connection_tunnel_create(tf_ssb_t* ssb, const char*
|
||||
uv_timer_init(ssb->loop, &tunnel->handshake_timer);
|
||||
uv_timer_start(&tunnel->handshake_timer, _tf_ssb_connection_handshake_timer_callback, k_handshake_timeout_ms, 0);
|
||||
|
||||
tunnel->linger_timer.data = tunnel;
|
||||
uv_timer_init(ssb->loop, &tunnel->linger_timer);
|
||||
|
||||
tunnel->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetOpaque(tunnel->object, tunnel);
|
||||
JS_SetPropertyStr(context, tunnel->object, "id", JS_NewString(context, target_id));
|
||||
@ -3046,6 +2979,9 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
|
||||
uv_timer_init(ssb->loop, &connection->handshake_timer);
|
||||
uv_timer_start(&connection->handshake_timer, _tf_ssb_connection_handshake_timer_callback, k_handshake_timeout_ms, 0);
|
||||
|
||||
connection->linger_timer.data = connection;
|
||||
uv_timer_init(ssb->loop, &connection->linger_timer);
|
||||
|
||||
struct sockaddr_storage addr = { 0 };
|
||||
int size = sizeof(addr);
|
||||
if (uv_tcp_getpeername(&connection->tcp, (struct sockaddr*)&addr, &size) == 0)
|
||||
@ -3306,7 +3242,9 @@ static void _tf_ssb_notify_broadcasts_changed(tf_ssb_t* ssb)
|
||||
if (node->callback)
|
||||
{
|
||||
tf_trace_begin(ssb->trace, "broadcasts changed");
|
||||
PRE_CALLBACK(ssb, node->callback);
|
||||
node->callback(ssb, node->user_data);
|
||||
POST_CALLBACK(ssb, node->callback);
|
||||
tf_trace_end(ssb->trace);
|
||||
}
|
||||
}
|
||||
@ -3410,7 +3348,9 @@ void tf_ssb_visit_broadcasts(tf_ssb_t* ssb,
|
||||
if (node->mtime - now < 60)
|
||||
{
|
||||
tf_trace_begin(ssb->trace, "broadcast");
|
||||
PRE_CALLBACK(ssb, callback);
|
||||
callback(node->host, &node->addr, node->origin, node->tunnel_connection, node->pub, user_data);
|
||||
POST_CALLBACK(ssb, callback);
|
||||
tf_trace_end(ssb->trace);
|
||||
}
|
||||
}
|
||||
@ -3718,7 +3658,9 @@ void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* id, JSValue message_
|
||||
{
|
||||
next = node->next;
|
||||
tf_trace_begin(ssb->trace, "message added callback");
|
||||
PRE_CALLBACK(ssb, node->callback);
|
||||
node->callback(ssb, id, node->user_data);
|
||||
POST_CALLBACK(ssb, node->callback);
|
||||
tf_trace_end(ssb->trace);
|
||||
}
|
||||
|
||||
@ -3794,7 +3736,9 @@ void tf_ssb_notify_blob_want_added(tf_ssb_t* ssb, const char* id)
|
||||
{
|
||||
next = node->next;
|
||||
tf_trace_begin(ssb->trace, "blob want added callback");
|
||||
PRE_CALLBACK(ssb, node->callback);
|
||||
node->callback(ssb, id, node->user_data);
|
||||
POST_CALLBACK(ssb, node->callback);
|
||||
tf_trace_end(ssb->trace);
|
||||
}
|
||||
}
|
||||
@ -3952,44 +3896,6 @@ void tf_ssb_connection_set_ebt_request_number(tf_ssb_connection_t* connection, i
|
||||
connection->ebt_request_number = request_number;
|
||||
}
|
||||
|
||||
JSValue tf_ssb_get_disconnection_debug(tf_ssb_t* ssb, JSContext* context)
|
||||
{
|
||||
JSValue result = JS_NewObject(context);
|
||||
JSValue disconnections = JS_NewArray(context);
|
||||
for (int i = 0; i < k_debug_close_connection_count; i++)
|
||||
{
|
||||
JSValue disconnection = JS_NewObject(context);
|
||||
if (*ssb->debug_close[i].id)
|
||||
{
|
||||
JS_SetPropertyStr(context, disconnection, "id", JS_NewString(context, ssb->debug_close[i].id));
|
||||
if (*ssb->debug_close[i].tunnel)
|
||||
{
|
||||
JS_SetPropertyStr(context, disconnection, "tunnel", JS_NewString(context, ssb->debug_close[i].tunnel));
|
||||
}
|
||||
JS_SetPropertyStr(context, disconnection, "reason", JS_NewString(context, ssb->debug_close[i].reason));
|
||||
JSValue messages = JS_NewArray(context);
|
||||
for (int j = 0; j < k_debug_close_message_count; j++)
|
||||
{
|
||||
if (ssb->debug_close[i].messages[j])
|
||||
{
|
||||
JSValue message = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, message, "direction", JS_NewString(context, ssb->debug_close[i].messages[j]->outgoing ? "out" : "in"));
|
||||
JS_SetPropertyStr(context, message, "flags", JS_NewInt32(context, ssb->debug_close[i].messages[j]->flags));
|
||||
JS_SetPropertyStr(context, message, "request_number", JS_NewInt32(context, ssb->debug_close[i].messages[j]->request_number));
|
||||
JS_SetPropertyStr(context, message, "timestamp", JS_NewFloat64(context, ssb->debug_close[i].messages[j]->timestamp));
|
||||
JS_SetPropertyStr(
|
||||
context, message, "payload", JS_NewStringLen(context, (const char*)ssb->debug_close[i].messages[j]->data, ssb->debug_close[i].messages[j]->size));
|
||||
JS_SetPropertyUint32(context, messages, j, message);
|
||||
}
|
||||
}
|
||||
JS_SetPropertyStr(context, disconnection, "messages", messages);
|
||||
}
|
||||
JS_SetPropertyUint32(context, disconnections, i, disconnection);
|
||||
}
|
||||
JS_SetPropertyStr(context, result, "disconnections", disconnections);
|
||||
return result;
|
||||
}
|
||||
|
||||
void tf_ssb_record_thread_busy(tf_ssb_t* ssb, bool busy)
|
||||
{
|
||||
int32_t busy_value = __atomic_add_fetch(&ssb->thread_busy_count, busy ? 1 : -1, __ATOMIC_RELAXED);
|
||||
@ -4071,7 +3977,9 @@ static void _tf_ssb_connection_after_work_callback(uv_work_t* work, int status)
|
||||
if (data->after_work_callback)
|
||||
{
|
||||
tf_trace_begin(data->connection->ssb->trace, data->after_name);
|
||||
PRE_CALLBACK(data->connection->ssb, data->after_work_callback);
|
||||
data->after_work_callback(data->connection, status, data->user_data);
|
||||
POST_CALLBACK(data->connection->ssb, data->after_work_callback);
|
||||
tf_trace_end(data->connection->ssb->trace);
|
||||
}
|
||||
data->connection->ref_count--;
|
||||
@ -4138,7 +4046,9 @@ static void _tf_ssb_after_work_callback(uv_work_t* work, int status)
|
||||
if (data->after_work_callback)
|
||||
{
|
||||
tf_trace_begin(data->ssb->trace, data->after_name);
|
||||
PRE_CALLBACK(data->ssb, data->after_work_callback);
|
||||
data->after_work_callback(data->ssb, status, data->user_data);
|
||||
POST_CALLBACK(data->ssb, data->after_work_callback);
|
||||
tf_trace_end(data->ssb->trace);
|
||||
}
|
||||
tf_ssb_unref(data->ssb);
|
||||
@ -4222,63 +4132,19 @@ typedef struct _update_settings_t
|
||||
char room_name[1024];
|
||||
} update_settings_t;
|
||||
|
||||
static bool _get_global_setting_string(tf_ssb_t* ssb, const char* name, char* out_value, size_t size)
|
||||
{
|
||||
bool result = false;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
snprintf(out_value, size, "%s", sqlite3_column_text(statement, 0));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool _get_global_setting_bool(tf_ssb_t* ssb, const char* name, bool default_value)
|
||||
{
|
||||
bool result = default_value;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
result = sqlite3_column_int(statement, 0) != 0;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _tf_ssb_update_settings_work(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
update_settings_t* update = user_data;
|
||||
update->is_room = _get_global_setting_bool(ssb, "room", true);
|
||||
update->is_replicator = _get_global_setting_bool(ssb, "replicator", true);
|
||||
update->is_peer_exchange = _get_global_setting_bool(ssb, "peer_exchange", true);
|
||||
_get_global_setting_string(ssb, "room_name", update->room_name, sizeof(update->room_name));
|
||||
_get_global_setting_string(ssb, "seeds_host", update->seeds_host, sizeof(update->seeds_host));
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
update->is_room = true;
|
||||
update->is_replicator = true;
|
||||
update->is_peer_exchange = true;
|
||||
tf_ssb_db_get_global_setting_bool(db, "room", &update->is_room);
|
||||
tf_ssb_db_get_global_setting_bool(db, "replicator", &update->is_replicator);
|
||||
tf_ssb_db_get_global_setting_bool(db, "peer_exchange", &update->is_peer_exchange);
|
||||
tf_ssb_db_get_global_setting_string(db, "room_name", update->room_name, sizeof(update->room_name));
|
||||
tf_ssb_db_get_global_setting_string(db, "seeds_host", update->seeds_host, sizeof(update->seeds_host));
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
}
|
||||
|
||||
static void _tf_ssb_update_settings_after_work(tf_ssb_t* ssb, int result, void* user_data)
|
||||
@ -4321,7 +4187,9 @@ void tf_ssb_set_verbose(tf_ssb_t* ssb, bool verbose)
|
||||
static void _tf_ssb_scheduled_timer(uv_timer_t* handle)
|
||||
{
|
||||
tf_ssb_timer_t* timer = handle->data;
|
||||
PRE_CALLBACK(timer->ssb, timer->callback);
|
||||
timer->callback(timer->ssb, timer->user_data);
|
||||
POST_CALLBACK(timer->ssb, timer->callback);
|
||||
uv_close((uv_handle_t*)handle, _tf_ssb_on_timer_close);
|
||||
}
|
||||
|
||||
@ -4423,6 +4291,11 @@ void tf_ssb_connection_adjust_write_count(tf_ssb_connection_t* connection, int d
|
||||
uv_async_send(&connection->scheduled_async);
|
||||
}
|
||||
|
||||
const char* tf_ssb_connection_get_destroy_reason(tf_ssb_connection_t* connection)
|
||||
{
|
||||
return connection ? connection->destroy_reason : NULL;
|
||||
}
|
||||
|
||||
void tf_ssb_sync_start(tf_ssb_t* ssb)
|
||||
{
|
||||
tf_ssb_connections_sync_start(ssb->connections_tracker);
|
||||
|
94
src/ssb.db.c
94
src/ssb.db.c
@ -1681,34 +1681,13 @@ bool tf_ssb_db_set_account_password(uv_loop_t* loop, sqlite3* db, JSContext* con
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool _tf_ssb_db_get_global_setting_bool(sqlite3* db, const char* name, bool default_value)
|
||||
{
|
||||
bool result = default_value;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_type(statement, 0) != SQLITE_NULL)
|
||||
{
|
||||
result = sqlite3_column_int(statement, 0) != 0;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_register_account(uv_loop_t* loop, sqlite3* db, JSContext* context, const char* name, const char* password)
|
||||
{
|
||||
bool result = false;
|
||||
JSValue users_array = JS_UNDEFINED;
|
||||
|
||||
bool registration_allowed = _tf_ssb_db_get_global_setting_bool(db, "account_registration", true);
|
||||
bool registration_allowed = true;
|
||||
tf_ssb_db_get_global_setting_bool(db, "account_registration", ®istration_allowed);
|
||||
if (registration_allowed)
|
||||
{
|
||||
sqlite3_stmt* statement = NULL;
|
||||
@ -2030,3 +2009,72 @@ bool tf_ssb_db_user_has_permission(tf_ssb_t* ssb, sqlite3* db, const char* id, c
|
||||
}
|
||||
return has_permission;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_get_global_setting_bool(sqlite3* db, const char* name, bool* out_value)
|
||||
{
|
||||
bool result = false;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
*out_value = sqlite3_column_int(statement, 0) != 0;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_get_global_setting_int64(sqlite3* db, const char* name, int64_t* out_value)
|
||||
{
|
||||
bool result = false;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_type(statement, 0) != SQLITE_NULL)
|
||||
{
|
||||
*out_value = sqlite3_column_int64(statement, 0);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size)
|
||||
{
|
||||
bool result = false;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
snprintf(out_value, size, "%s", sqlite3_column_text(statement, 0));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
28
src/ssb.db.h
28
src/ssb.db.h
@ -455,6 +455,34 @@ bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id);
|
||||
*/
|
||||
bool tf_ssb_db_user_has_permission(tf_ssb_t* ssb, sqlite3* db, const char* id, const char* permission);
|
||||
|
||||
/**
|
||||
** Get a boolean global setting value.
|
||||
** @param db The database.
|
||||
** @param name The setting name.
|
||||
** @param out_value Populated with the value.
|
||||
** @return true if the setting was found.
|
||||
*/
|
||||
bool tf_ssb_db_get_global_setting_bool(sqlite3* db, const char* name, bool* out_value);
|
||||
|
||||
/**
|
||||
** Get an int64_t global setting value.
|
||||
** @param db The database.
|
||||
** @param name The setting name.
|
||||
** @param out_value Populated with the value.
|
||||
** @return true if the setting was found.
|
||||
*/
|
||||
bool tf_ssb_db_get_global_setting_int64(sqlite3* db, const char* name, int64_t* out_value);
|
||||
|
||||
/**
|
||||
** Get a string global setting value.
|
||||
** @param db The database.
|
||||
** @param name The setting name.
|
||||
** @param out_value Populated with the value.
|
||||
** @param size The size of the out_value buffer.
|
||||
** @return true if the setting was found.
|
||||
*/
|
||||
bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size);
|
||||
|
||||
/**
|
||||
** An SQLite authorizer callback. See https://www.sqlite.org/c3ref/set_authorizer.html for use.
|
||||
** @param user_data User data registered with the authorizer.
|
||||
|
15
src/ssb.h
15
src/ssb.h
@ -947,14 +947,6 @@ void tf_ssb_get_stats(tf_ssb_t* ssb, tf_ssb_stats_t* out_stats);
|
||||
*/
|
||||
tf_ssb_blob_wants_t* tf_ssb_connection_get_blob_wants_state(tf_ssb_connection_t* connection);
|
||||
|
||||
/**
|
||||
** Get a report of information about recent disconnections.
|
||||
** @param ssb The SSB instance.
|
||||
** @param context A JS context.
|
||||
** @return Information about disconnections.
|
||||
*/
|
||||
JSValue tf_ssb_get_disconnection_debug(tf_ssb_t* ssb, JSContext* context);
|
||||
|
||||
/**
|
||||
** Record whether the calling thread is busy.
|
||||
** @param ssb The SSB instance.
|
||||
@ -1101,6 +1093,13 @@ void tf_ssb_connection_adjust_read_backpressure(tf_ssb_connection_t* connection,
|
||||
*/
|
||||
void tf_ssb_connection_adjust_write_count(tf_ssb_connection_t* connection, int delta);
|
||||
|
||||
/**
|
||||
** Get the reason why a connection is going away.
|
||||
** @param connection The connection.
|
||||
** @return The reason or NULL.
|
||||
*/
|
||||
const char* tf_ssb_connection_get_destroy_reason(tf_ssb_connection_t* connection);
|
||||
|
||||
/**
|
||||
** Initiate a tunnel connection.
|
||||
** @param ssb The SSB instance.
|
||||
|
@ -1120,6 +1120,11 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in
|
||||
int flags = tf_ssb_connection_get_flags(connection);
|
||||
JS_SetPropertyStr(context, flags_object, "one_shot", JS_NewBool(context, (flags & k_tf_ssb_connect_flag_one_shot) != 0));
|
||||
JS_SetPropertyStr(context, object, "flags", flags_object);
|
||||
const char* destroy_reason = tf_ssb_connection_get_destroy_reason(connection);
|
||||
if (destroy_reason)
|
||||
{
|
||||
JS_SetPropertyStr(context, object, "destroy_reason", JS_NewString(context, destroy_reason));
|
||||
}
|
||||
JS_SetPropertyUint32(context, result, i, object);
|
||||
}
|
||||
}
|
||||
|
@ -20,30 +20,6 @@ static void _tf_ssb_rpc_send_peers_exchange(tf_ssb_connection_t* connection);
|
||||
static void _tf_ssb_rpc_start_delete_blobs(tf_ssb_t* ssb, int delay_ms);
|
||||
static void _tf_ssb_rpc_start_delete_feeds(tf_ssb_t* ssb, int delay_ms);
|
||||
|
||||
static int64_t _get_global_setting_int64(tf_ssb_t* ssb, const char* name, int64_t default_value)
|
||||
{
|
||||
int64_t result = default_value;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_type(statement, 0) != SQLITE_NULL)
|
||||
{
|
||||
result = sqlite3_column_int64(statement, 0);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool _get_global_setting_bool(tf_ssb_t* ssb, const char* name, bool default_value)
|
||||
{
|
||||
bool result = default_value;
|
||||
@ -243,7 +219,10 @@ static void _tf_ssb_request_blob_wants_work(tf_ssb_connection_t* connection, voi
|
||||
blob_wants_work_t* work = user_data;
|
||||
tf_ssb_blob_wants_t* blob_wants = tf_ssb_connection_get_blob_wants_state(connection);
|
||||
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
||||
int64_t age = _get_global_setting_int64(ssb, "blob_fetch_age_seconds", -1);
|
||||
int64_t age = -1;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
tf_ssb_db_get_global_setting_int64(db, "blob_fetch_age_seconds", &age);
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
int64_t timestamp = -1;
|
||||
if (age == 0)
|
||||
{
|
||||
@ -256,7 +235,7 @@ static void _tf_ssb_request_blob_wants_work(tf_ssb_connection_t* connection, voi
|
||||
timestamp = now - age * 1000ULL;
|
||||
}
|
||||
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT id FROM blob_wants_view WHERE id > ? AND timestamp > ? ORDER BY id LIMIT ?", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
@ -1003,7 +982,10 @@ static void _tf_ssb_rpc_ebt_replicate_send_clock_work(tf_ssb_connection_t* conne
|
||||
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
||||
JSValue full_clock = JS_NewObject(context);
|
||||
|
||||
int64_t depth = _get_global_setting_int64(ssb, "replication_hops", 2);
|
||||
int64_t depth = 2;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
tf_ssb_db_get_global_setting_int64(db, "replication_hops", &depth);
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
|
||||
/* Ask for every identity we know is being followed from local accounts. */
|
||||
const char** visible = tf_ssb_db_get_all_visible_identities(ssb, depth);
|
||||
@ -1400,14 +1382,17 @@ typedef struct _delete_t
|
||||
static void _tf_ssb_rpc_delete_blobs_work(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
delete_t* delete = user_data;
|
||||
int64_t age = _get_global_setting_int64(ssb, "blob_expire_age_seconds", -1);
|
||||
int64_t age = -1;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
tf_ssb_db_get_global_setting_int64(db, "blob_expire_age_seconds", &age);
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
if (age <= 0)
|
||||
{
|
||||
_tf_ssb_rpc_checkpoint(ssb);
|
||||
return;
|
||||
}
|
||||
int64_t start_ns = uv_hrtime();
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
db = tf_ssb_acquire_db_writer(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
int64_t now = (int64_t)time(NULL) * 1000ULL;
|
||||
int64_t timestamp = now - age * 1000ULL;
|
||||
@ -1474,7 +1459,10 @@ static void _tf_ssb_rpc_delete_feeds_work(tf_ssb_t* ssb, void* user_data)
|
||||
return;
|
||||
}
|
||||
int64_t start_ns = uv_hrtime();
|
||||
int replication_hops = (int)_get_global_setting_int64(ssb, "replication_hops", 2);
|
||||
int64_t replication_hops = 2;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
tf_ssb_db_get_global_setting_int64(db, "replication_hops", &replication_hops);
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
const char** identities = tf_ssb_db_get_all_visible_identities(ssb, replication_hops);
|
||||
|
||||
JSMallocFunctions funcs = { 0 };
|
||||
@ -1493,7 +1481,7 @@ static void _tf_ssb_rpc_delete_feeds_work(tf_ssb_t* ssb, void* user_data)
|
||||
JS_FreeValue(context, json);
|
||||
JS_FreeValue(context, array);
|
||||
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
db = tf_ssb_acquire_db_writer(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db,
|
||||
"DELETE FROM messages WHERE author IN ("
|
||||
|
15
src/task.c
15
src/task.c
@ -932,21 +932,6 @@ char* tf_task_get_hitches(tf_task_t* task)
|
||||
return result;
|
||||
}
|
||||
|
||||
char* tf_task_get_disconnections(tf_task_t* task)
|
||||
{
|
||||
JSContext* context = task->_context;
|
||||
tf_trace_begin(task->_trace, __func__);
|
||||
JSValue object = tf_ssb_get_disconnection_debug(task->_ssb, context);
|
||||
JSValue json = JS_JSONStringify(context, object, JS_NULL, JS_NewInt32(context, 2));
|
||||
const char* string = JS_ToCString(context, json);
|
||||
char* result = tf_strdup(string);
|
||||
JS_FreeCString(context, string);
|
||||
JS_FreeValue(context, json);
|
||||
JS_FreeValue(context, object);
|
||||
tf_trace_end(task->_trace);
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_task_getFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_task_t* task = JS_GetContextOpaque(context);
|
||||
|
@ -310,14 +310,6 @@ void tf_task_remove_child(tf_task_t* task, tf_taskstub_t* child);
|
||||
*/
|
||||
bool tf_task_send_error_to_parent(tf_task_t* task, JSValue error);
|
||||
|
||||
/**
|
||||
** Get a report of recent disconnections.
|
||||
** @param task The task.
|
||||
** @return A JSON representation of recent disconnections that must be freed
|
||||
** with tf_free().
|
||||
*/
|
||||
char* tf_task_get_disconnections(tf_task_t* task);
|
||||
|
||||
/**
|
||||
** Get a report of miscellaneous debug information.
|
||||
** @param task The task.
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define VERSION_NUMBER "0.0.26"
|
||||
#define VERSION_NUMBER "0.0.27-wip"
|
||||
#define VERSION_NAME "This program kills fascists."
|
||||
|
@ -73,8 +73,10 @@ build_the_thing() {
|
||||
no-whirlpool
|
||||
no-weak-ssl-ciphers
|
||||
no-zlib
|
||||
-Os
|
||||
-Oz
|
||||
-DOPENSSL_SMALL_FOOTPRINT
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-flto"
|
||||
pwd
|
||||
echo "./Configure $SSL_TARGET $OPTIONS $GLOBAL_OPTIONS" && \
|
||||
|
@ -29,14 +29,14 @@ do
|
||||
case $build_target in
|
||||
ios64-xcrun)
|
||||
TRIBLE="arm64-darwin-ios"
|
||||
OPTIONS="--static -static -ffunction-sections -fdata-sections -fPIC -Wno-macro-redefined -miphoneos-version-min=9.0"
|
||||
OPTIONS="--static -static -Os -ffunction-sections -fdata-sections -fPIC -Wno-macro-redefined -miphoneos-version-min=9.0"
|
||||
DESTDIR="/tmp/$BUILD_DIR/arm64-ios"
|
||||
SSL_TARGET="ios64-xcrun"
|
||||
CC=clang
|
||||
;;
|
||||
iossimulator-xcrun)
|
||||
TRIBLE="x86_64-darwin-ios"
|
||||
OPTIONS="--static -static -ffunction-sections -fdata-sections -fPIC -Wno-macro-redefined"
|
||||
OPTIONS="--static -static -Os -ffunction-sections -fdata-sections -fPIC -Wno-macro-redefined"
|
||||
DESTDIR="/tmp/$BUILD_DIR/x86_64-iossim"
|
||||
SSL_TARGET="iossimulator-xcrun"
|
||||
CC=clang
|
||||
|
91
tools/ssl-local
Executable file
91
tools/ssl-local
Executable file
@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
|
||||
BUILD_PLATFORM=$(uname -s)
|
||||
if [[ -z $BUILD_TARGET ]]; then
|
||||
BUILD_TARGET=$(uname -m)
|
||||
WORK_DIR=out/openssl-local
|
||||
else
|
||||
WORK_DIR=out/openssl-$BUILD_TARGET
|
||||
SSL_TARGET=linux-$BUILD_TARGET
|
||||
fi
|
||||
|
||||
rm -rf $WORK_DIR
|
||||
cp -aRf deps/openssl_src/ $WORK_DIR
|
||||
|
||||
echo "Building"
|
||||
pwd
|
||||
pushd $WORK_DIR || exit 128
|
||||
rm -rf $DESTDIR
|
||||
echo $PATH
|
||||
export GLOBAL_OPTIONS="
|
||||
no-apps
|
||||
no-asm
|
||||
no-async
|
||||
no-autoerrinit
|
||||
no-autoload-config
|
||||
no-cmp
|
||||
no-cms
|
||||
no-comp
|
||||
no-deprecated
|
||||
no-dgram
|
||||
no-docs
|
||||
no-dsa
|
||||
no-dso
|
||||
no-dtls
|
||||
no-dtls1
|
||||
no-dtls1-method
|
||||
no-dynamic-engine
|
||||
no-ec2m
|
||||
no-egd
|
||||
no-engine
|
||||
no-err
|
||||
no-filenames
|
||||
no-gost
|
||||
no-http
|
||||
no-idea
|
||||
no-legacy
|
||||
no-md2
|
||||
no-md4
|
||||
no-module
|
||||
no-multiblock
|
||||
no-nextprotoneg
|
||||
no-ocsp
|
||||
no-psk
|
||||
no-shared
|
||||
no-sock
|
||||
no-srp
|
||||
no-ssl
|
||||
no-ssl3
|
||||
no-ssl-trace
|
||||
no-stdio
|
||||
no-tests
|
||||
no-thread-pool
|
||||
no-threads
|
||||
no-tls1
|
||||
no-tls1-method
|
||||
no-trace
|
||||
no-ui-console
|
||||
no-uplink
|
||||
no-whirlpool
|
||||
no-weak-ssl-ciphers
|
||||
no-zlib
|
||||
-Os
|
||||
-DOPENSSL_SMALL_FOOTPRINT
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-flto"
|
||||
pwd
|
||||
echo "./Configure $SSL_TARGET $OPTIONS $GLOBAL_OPTIONS" && \
|
||||
./Configure $SSL_TARGET $OPTIONS $GLOBAL_OPTIONS && \
|
||||
make -s clean && \
|
||||
make -s build_generated && \
|
||||
make -s libcrypto.a libssl.a || exit 128
|
||||
popd
|
||||
echo WORK_DIR=$WORK_DIR
|
||||
rm -rf deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/
|
||||
mkdir -p deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
|
||||
mkdir -p deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
|
||||
cp -R $WORK_DIR/include/* deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
|
||||
cp $WORK_DIR/*.a deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
|
||||
|
||||
echo Success
|
Reference in New Issue
Block a user