Compare commits
62 Commits
e5899fca58
...
v0.0.28
Author | SHA1 | Date | |
---|---|---|---|
c74f90ef04 | |||
26cb7e5a17 | |||
2bad6672d8 | |||
71c4011526 | |||
5e81078f59 | |||
31b78e74df | |||
2ff689aab0 | |||
0a6f0ed3f7 | |||
bfec46673d | |||
3a16614c72 | |||
9c9efb845c | |||
6192f1b94d | |||
ce451b2449 | |||
8534e16469 | |||
f6cc6f2eae | |||
0904425221 | |||
a729886522 | |||
e5dfedc7d1 | |||
f02423d084 | |||
8f4b6e83eb | |||
3029919553 | |||
ac67db0591 | |||
1e08838f5b | |||
d814f7ee77
|
|||
7edfb9d386 | |||
6928d6caba | |||
1a626875cf | |||
6eb3b64334 | |||
09f3595e93 | |||
11e89622d4 | |||
0fa8acc264 | |||
afc7c64ed8 | |||
c794c1b885 | |||
6247529799 | |||
ad3eedc1fb | |||
1cfac3cae6 | |||
478bcd5d13 | |||
6932da69b3 | |||
857f47bf55 | |||
373d742751 | |||
575622c522 | |||
a3e86ccb1d | |||
e491798ff1 | |||
15df4ac236 | |||
017a74c4e4 | |||
6e5b1127f3 | |||
95f4f88949 | |||
92858882d7 | |||
4cba95ec8c | |||
bbb2f89d85 | |||
88213038b2 | |||
cc18b41e76 | |||
f16127a238 | |||
2a6ecfaede | |||
cf4a09bf03 | |||
20e60262fd | |||
9e3928c976 | |||
95d8768545 | |||
8679d09040 | |||
4cc5c6acb3 | |||
6f9b548b1a | |||
fbff3386a9 |
@ -18,7 +18,7 @@ jobs:
|
||||
run: >
|
||||
apt update && apt install -y \
|
||||
build-essential \
|
||||
clang \
|
||||
clang-19 \
|
||||
cmake \
|
||||
curl \
|
||||
docker.io \
|
||||
@ -40,8 +40,11 @@ jobs:
|
||||
submodules: true
|
||||
- name: Setup environment
|
||||
run: |
|
||||
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100
|
||||
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-19 100
|
||||
ln -s /opt/keys .keys
|
||||
ln -s /opt/deps/ios_toolchain deps/ios_toolchain
|
||||
ln -sf /opt/deps/ios_toolchain deps/
|
||||
ln -sf /opt/deps/macos_toolchain deps/
|
||||
- name: Build documentation
|
||||
run: |
|
||||
mkdir -p out/html/ ~/.ssh/
|
||||
|
4
.gitignore
vendored
@ -1,11 +1,13 @@
|
||||
build/
|
||||
*.core
|
||||
db.*
|
||||
deps/ios_toolchain/
|
||||
deps/ios_toolchain
|
||||
deps/macos_toolchain
|
||||
deps/openssl/
|
||||
dist/
|
||||
.flatpak-builder
|
||||
.keys
|
||||
**/.DS_Store
|
||||
logs/
|
||||
**/node_modules
|
||||
out
|
||||
|
2
Doxyfile
@ -1680,7 +1680,7 @@ DISABLE_INDEX = NO
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
GENERATE_TREEVIEW = NO
|
||||
GENERATE_TREEVIEW = YES
|
||||
|
||||
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
|
||||
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
|
||||
|
166
GNUmakefile
@ -17,10 +17,13 @@ MAKEFLAGS += --no-builtin-rules
|
||||
## ANDROID_SDK := Path to the Android SDK.
|
||||
|
||||
VERSION_CODE := 33
|
||||
VERSION_NUMBER := 0.0.28-wip
|
||||
VERSION_CODE_IOS := 9
|
||||
VERSION_NUMBER := 0.0.28
|
||||
VERSION_NAME := This program kills fascists.
|
||||
|
||||
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3480000.zip
|
||||
IPHONEOS_VERSION_MIN=14.0
|
||||
|
||||
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3490100.zip
|
||||
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
|
||||
APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool
|
||||
@ -46,6 +49,7 @@ else ifeq ($(UNAME_S),Linux)
|
||||
BUILD_TYPES := debug release
|
||||
HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1)
|
||||
HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1)
|
||||
HAVE_LINUX_MACOS = $(if $(shell which deps/macos_toolchain/bin/oa64-clang),1)
|
||||
HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1)
|
||||
ifneq ($(UNAME_M),aarch64)
|
||||
HAVE_CROSS_AARCH64 = $(if $(shell which aarch64-linux-gnu-gcc),1)
|
||||
@ -67,20 +71,22 @@ LDFLAGS += \
|
||||
-lc++abi
|
||||
HAVE_ANDROID :=
|
||||
HAVE_LINUX_IOS :=
|
||||
HAVE_LINUX_MACOS :=
|
||||
USE_SYSTEM_SSL := 1
|
||||
else
|
||||
$(error Unexpected host platform $(UNAME_S).)
|
||||
endif
|
||||
|
||||
# Everything is set above.
|
||||
$(info Building Tilde Friends $(VERSION_NUMBER) android=$(if $(HAVE_ANDROID),1,0) win=$(if $(HAVE_WIN),1,0) cross_aarch64=$(if $(HAVE_CROSS_AARCH64),1,0) cross_ios=$(if $(HAVE_LINUX_IOS),1,0) system_ssl=$(if $(USE_SYSTEM_SSL),1,0))
|
||||
$(info Building Tilde Friends $(VERSION_NUMBER) android=$(if $(HAVE_ANDROID),1,0) win=$(if $(HAVE_WIN),1,0) cross_aarch64=$(if $(HAVE_CROSS_AARCH64),1,0) cross_ios=$(if $(HAVE_LINUX_IOS),1,0) cross_macos=$(if $(HAVE_LINUX_MACOS),1,0) system_ssl=$(if $(USE_SYSTEM_SSL),1,0))
|
||||
|
||||
CFLAGS += \
|
||||
-std=gnu11 \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-cast-function-type-mismatch \
|
||||
-Wno-unknown-warning-option \
|
||||
-Wno-unused-parameter \
|
||||
-MMD \
|
||||
-MP \
|
||||
-ffunction-sections \
|
||||
@ -149,6 +155,18 @@ ifeq ($(UNAME_S),Darwin)
|
||||
MACOS_TARGETS := \
|
||||
out/debug/tildefriends \
|
||||
out/release/tildefriends
|
||||
else ifeq ($(UNAME_S),Linux)
|
||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
||||
MACOS_TARGETS := \
|
||||
out/macosdebug-arm/tildefriends \
|
||||
out/macosrelease-arm/tildefriends \
|
||||
out/macosdebug-x86_64/tildefriends \
|
||||
out/macosrelease-x86_64/tildefriends
|
||||
all: out/macosdebug/tildefriends.standalone
|
||||
all: out/macosrelease/tildefriends.standalone
|
||||
else
|
||||
MACOS_TARGETS :=
|
||||
endif
|
||||
else
|
||||
MACOS_TARGETS :=
|
||||
endif
|
||||
@ -165,6 +183,14 @@ ifeq ($(HAVE_LINUX_IOS),1)
|
||||
BUILD_TYPES += iosdebug iosrelease
|
||||
all: $(IOS_APPS)
|
||||
endif
|
||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
||||
BUILD_TYPES += \
|
||||
macosdebug-arm \
|
||||
macosrelease-arm \
|
||||
macosdebug-x86_64 \
|
||||
macosrelease-x86_64
|
||||
all: $(IOS_APPS)
|
||||
endif
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
all: $(IOS_APPS) \
|
||||
out/tildefriends-iossimdebug.app/tildefriends \
|
||||
@ -183,7 +209,9 @@ DEBUG_TARGETS := \
|
||||
out/androiddebug-armv7a/tildefriends \
|
||||
out/androiddebug-x86_64/tildefriends \
|
||||
out/androiddebug-x86/tildefriends \
|
||||
out/armdebug/tildefriends
|
||||
out/armdebug/tildefriends \
|
||||
out/macosdebug-arm/tildefriends \
|
||||
out/macosdebug-x86_64/tildefriends
|
||||
RELEASE_TARGETS := \
|
||||
out/release/tildefriends \
|
||||
out/winrelease/tildefriends.exe \
|
||||
@ -193,7 +221,9 @@ RELEASE_TARGETS := \
|
||||
out/androidrelease-armv7a/tildefriends \
|
||||
out/androidrelease-x86_64/tildefriends \
|
||||
out/androidrelease-x86/tildefriends \
|
||||
out/armrelease/tildefriends
|
||||
out/armrelease/tildefriends \
|
||||
out/macosrelease-arm/tildefriends \
|
||||
out/macosrelease-x86_64/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))
|
||||
@ -204,7 +234,9 @@ $(NONMACOS_TARGETS): LDFLAGS += -static-libgcc
|
||||
endif
|
||||
|
||||
$(NONANDROID_TARGETS): CFLAGS += -fno-omit-frame-pointer
|
||||
$(filter-out $(WINDOWS_TARGETS),$(ALL_TARGETS)): LDFLAGS += -rdynamic
|
||||
$(filter-out $(WINDOWS_TARGETS),$(ALL_TARGETS)): LDFLAGS += \
|
||||
-rdynamic \
|
||||
-gz=zlib
|
||||
$(ANDROID_TARGETS): CFLAGS += \
|
||||
--sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/sysroot \
|
||||
-fPIC \
|
||||
@ -247,6 +279,10 @@ else ifeq ($(UNAME_S),Linux)
|
||||
$(IOS_TARGETS): CFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk -arch arm64 -DTARGET_OS_IPHONE=1
|
||||
$(IOS_TARGETS): LDFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk
|
||||
$(IOS_TARGETS): CC = PATH=$$PATH:deps/ios_toolchain/target/bin LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/ios_toolchain/target/lib deps/ios_toolchain/target/bin/arm-apple-darwin11-clang
|
||||
$(filter $(BUILD_DIR)/macosdebug-x86_64/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/o64-clang
|
||||
$(filter $(BUILD_DIR)/macosdebug-arm/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/oa64-clang
|
||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/o64-clang
|
||||
$(filter $(BUILD_DIR)/macosrelease-arm/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/oa64-clang
|
||||
endif
|
||||
$(ANDROID_X86_64_TARGETS): ANDROID_NDK_TARGET_TRIPLE := x86_64-linux-android
|
||||
$(ANDROID_X86_TARGETS): ANDROID_NDK_TARGET_TRIPLE := i686-linux-android
|
||||
@ -269,14 +305,22 @@ $(ANDROID_X86_64_TARGETS): LDFLAGS += -Lout/openssl/android/x86_64/usr/local/lib
|
||||
$(NONMACOS_TARGETS): CFLAGS += -Wno-cast-function-type
|
||||
$(MACOS_TARGETS): LDFLAGS += -Wl,-dead_strip
|
||||
$(NONMACOS_TARGETS): LDFLAGS += -Wl,--gc-sections -Wl,--as-needed
|
||||
$(IOS_TARGETS): CFLAGS += -miphoneos-version-min=9.0
|
||||
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0
|
||||
$(IOS_TARGETS): CFLAGS += -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)
|
||||
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
$(IOS_TARGETS): CFLAGS += -Iout/openssl/ios/ios64-xcrun/usr/local/include
|
||||
$(IOS_TARGETS): LDFLAGS += -Lout/openssl/ios/ios64-xcrun/usr/local/lib
|
||||
else
|
||||
$(IOS_TARGETS): CFLAGS += -Iout/openssl/$(UNAME_S)/ios64-cross/usr/local/include
|
||||
$(IOS_TARGETS): LDFLAGS += -Lout/openssl/$(UNAME_S)/ios64-cross/usr/local/lib
|
||||
$(filter $(BUILD_DIR)/macosdebug-x86_64/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-x86_64/usr/local/include
|
||||
$(filter $(BUILD_DIR)/macosdebug-arm/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-arm/usr/local/include
|
||||
$(filter $(BUILD_DIR)/macosdebug-x86_64/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-x86_64/usr/local/lib
|
||||
$(filter $(BUILD_DIR)/macosdebug-arm/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-arm/usr/local/lib
|
||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-x86_64/usr/local/include
|
||||
$(filter $(BUILD_DIR)/macosrelease-arm/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-arm/usr/local/include
|
||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-x86_64/usr/local/lib
|
||||
$(filter $(BUILD_DIR)/macosrelease-arm/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-arm/usr/local/lib
|
||||
endif
|
||||
$(IOSSIM_TARGETS): CFLAGS += -Iout/openssl/ios/iossimulator-xcrun/usr/local/include
|
||||
$(IOSSIM_TARGETS): LDFLAGS += -Lout/openssl/ios/iossimulator-xcrun/usr/local/lib
|
||||
@ -304,7 +348,7 @@ get_objs = \
|
||||
$(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)_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))))) \
|
||||
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_ios))))) \
|
||||
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos))))) \
|
||||
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease macosdebug-arm macosrelease-arm macosdebug-x86_64 macosrelease-x86_64,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos))))) \
|
||||
$(foreach build_type,androiddebug-x86 androidrelease-x86,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_x86))))) \
|
||||
$(if $(findstring Darwin,$(UNAME_S)),$(foreach build_type,debug release,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos)))))) \
|
||||
$(if $(findstring Darwin,$(UNAME_S)),,$(foreach build_type,debug release armdebug armrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))))
|
||||
@ -331,7 +375,7 @@ $(APP_OBJS): CFLAGS += \
|
||||
-Werror
|
||||
ifneq ($(UNAME_S),Darwin)
|
||||
ifeq ($(UNAME_M),x86_64)
|
||||
$(filter-out $(BUILD_DIR)/android% $(BUILD_DIR)/ios%,$(APP_OBJS)): CFLAGS += \
|
||||
$(filter-out $(BUILD_DIR)/android% $(BUILD_DIR)/ios% $(BUILD_DIR)/macos%,$(APP_OBJS)): CFLAGS += \
|
||||
-fanalyzer
|
||||
endif
|
||||
endif
|
||||
@ -767,7 +811,7 @@ $(MINIUNZIP_OBJS): CFLAGS += \
|
||||
LDFLAGS += \
|
||||
-pthread \
|
||||
-lm
|
||||
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS): LDFLAGS += \
|
||||
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS) $(filter-out $(HOST_TARGETS),$(MACOS_TARGETS)): LDFLAGS += \
|
||||
-lssl \
|
||||
-lcrypto
|
||||
ifneq ($(UNAME_S),Haiku)
|
||||
@ -869,6 +913,17 @@ src/android/AndroidManifest.xml : $(firstword $(MAKEFILE_LIST))
|
||||
-e 's/android:targetSdkVersion="[[:digit:]]*"/android:targetSdkVersion="$(ANDROID_TARGET_SDK_VERSION)"/' \
|
||||
$@
|
||||
|
||||
src/ios/Info.plist : $(firstword $(MAKEFILE_LIST))
|
||||
@echo "[ios_version] $@"
|
||||
@cat $@ | \
|
||||
tr '\n' '^' | \
|
||||
sed -r \
|
||||
-e 's@(<key>CFBundleShortVersionString</key>\^[[:space:]]*<string>)[0-9.]*(</string>)@\1$(VERSION_NUMBER:%-wip=%)\2@' \
|
||||
-e 's@(<key>CFBundleVersion</key>\^[[:space:]]*<string>)[[:digit:]]+(</string>)@\1$(VERSION_CODE_IOS)\2@' \
|
||||
-e 's@(<key>MinimumOSVersion</key>\^[[:space:]]*<string>)[0-9.]*(</string>)@\1$(IPHONEOS_VERSION_MIN)\2@' | \
|
||||
tr '^' '\n' > \
|
||||
$@.tmp && mv $@.tmp $@ || rm -f $@.tmp
|
||||
|
||||
##
|
||||
## Android targets:
|
||||
##
|
||||
@ -886,29 +941,30 @@ out/res/layout_activity_main.xml.flat: src/android/res/layout/activity_main.xml
|
||||
@echo "[aapt2] $@"
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ src/android/res/layout/activity_main.xml
|
||||
|
||||
out/res/drawable_icon.xml.flat: src/android/res/drawable/icon.xml
|
||||
out/res/drawable_%.xml.flat: src/android/res/drawable/%.xml
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "[aapt2] $@"
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ src/android/res/drawable/icon.xml
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ $(<)
|
||||
|
||||
out/apk/res.apk out/gen/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat src/android/AndroidManifest.xml
|
||||
out/apk/res.apk out/gen/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat out/res/drawable_logo.xml.flat src/android/AndroidManifest.xml
|
||||
@echo [aapt2 link] res.apk
|
||||
@mkdir -p out/apk/
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat \
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat out/res/drawable_logo.xml.flat \
|
||||
--min-sdk-version $(ANDROID_MIN_SDK_VERSION) \
|
||||
--target-sdk-version $(ANDROID_TARGET_SDK_VERSION) \
|
||||
--manifest src/android/AndroidManifest.xml \
|
||||
-o out/apk/res.apk \
|
||||
--java out/gen/
|
||||
|
||||
out/apk/res.fdroid.apk out/gen_fdroid/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat src/android/AndroidManifest.xml
|
||||
out/apk/res.fdroid.apk out/gen_fdroid/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon_fdroid.xml.flat out/res/drawable_logo.xml.flat src/android/AndroidManifest.xml
|
||||
@echo [aapt2 link] res.fdroid.apk
|
||||
@mkdir -p out/apk/
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat \
|
||||
@sed -e 's@drawable/icon@drawable/icon_fdroid@' src/android/AndroidManifest.xml > out/apk/AndroidManifest.fdroid.xml
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon_fdroid.xml.flat out/res/drawable_logo.xml.flat \
|
||||
--min-sdk-version $(ANDROID_MIN_SDK_VERSION) \
|
||||
--target-sdk-version $(ANDROID_TARGET_SDK_VERSION) \
|
||||
--rename-manifest-package com.unprompted.tildefriends.fdroid \
|
||||
--manifest src/android/AndroidManifest.xml \
|
||||
--manifest out/apk/AndroidManifest.fdroid.xml \
|
||||
-o out/apk/res.fdroid.apk \
|
||||
--java out/gen_fdroid/
|
||||
|
||||
@ -925,11 +981,11 @@ out/apk/classes.dex: $(CLASS_FILES)
|
||||
@$(ANDROID_BUILD_TOOLS)/d8 --lib $(ANDROID_PLATFORM)/android.jar --output $(dir $@) out/classes/com/unprompted/tildefriends/*.class
|
||||
|
||||
PACKAGE_DIRS := \
|
||||
apps/ \
|
||||
core/ \
|
||||
deps/codemirror/ \
|
||||
deps/prettier/ \
|
||||
deps/lit/
|
||||
apps \
|
||||
core \
|
||||
deps/codemirror \
|
||||
deps/prettier \
|
||||
deps/lit
|
||||
|
||||
RAW_FILES := $(sort $(filter-out apps/blog% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f -not -name '.*')))
|
||||
|
||||
@ -959,6 +1015,7 @@ out/TildeFriends.aab: out/apk/classes.dex $(filter-out %debug%, $(ANDROID_TARGET
|
||||
--manifest src/android/AndroidManifest.xml \
|
||||
-R out/res/layout_activity_main.xml.flat \
|
||||
-R out/res/drawable_icon.xml.flat \
|
||||
-R out/res/drawable_logo.xml.flat \
|
||||
--auto-add-overlay
|
||||
@unzip out/aab/temporary.apk -d out/aab/staging/
|
||||
@mkdir -p out/aab/staging/root/deps
|
||||
@ -1176,10 +1233,34 @@ $(LOCAL_DEPS):
|
||||
CROSS_TOP=../../deps/ios_toolchain/target \
|
||||
CROSS_SDK=iPhoneOS18.2.sdk \
|
||||
CC=clang \
|
||||
OPTIONS=-miphoneos-version-min=9.0 \
|
||||
OPTIONS=-miphoneos-version-min=$(IPHONEOS_VERSION_MIN) \
|
||||
tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/macos-arm/usr/local/lib/libssl.a
|
||||
$(LOCAL_DEPS):
|
||||
+@PATH=../../deps/macos_toolchain/bin:$$PATH \
|
||||
BUILD_TARGET=macos-arm \
|
||||
SSL_TARGET=darwin64-arm64 \
|
||||
CC=../../deps/macos_toolchain/bin/oa64-clang \
|
||||
RANLIB=../../deps/macos_toolchain/bin/x86_64-apple-darwin24-ranlib \
|
||||
AR=../../deps/macos_toolchain/bin/arm64-apple-darwin24-ar \
|
||||
tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/macosrelease-arm/% $(BUILD_DIR)/macosdebug-arm/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||
|
||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/macos-x86_64/usr/local/lib/libssl.a
|
||||
$(LOCAL_DEPS):
|
||||
+@PATH=../../deps/macos_toolchain/bin:$$PATH \
|
||||
BUILD_TARGET=macos-x86_64 \
|
||||
SSL_TARGET=darwin64-x86_64 \
|
||||
CC=../../deps/macos_toolchain/bin/o64-clang \
|
||||
RANLIB=../../deps/macos_toolchain/bin/x86_64-apple-darwin24-ranlib \
|
||||
AR=../../deps/macos_toolchain/bin/x86_64-apple-darwin24-ar \
|
||||
tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/% $(BUILD_DIR)/macosdebug-x86_64/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
@ -1199,11 +1280,16 @@ endif
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
IOS_DEPS := out/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
|
||||
$(IOS_DEPS):
|
||||
+@BUILD_PLATFORM=ios BUILD_TARGET=ios64-xcrun SSL_TARGET=ios64-xcrun OPTIONS="-fPIC -Wno-macro-redefined -miphoneos-version-min=9.0" tools/ssl-local
|
||||
+@BUILD_PLATFORM=ios BUILD_TARGET=ios64-xcrun SSL_TARGET=ios64-xcrun OPTIONS="-fPIC -Wno-macro-redefined -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)" tools/ssl-local
|
||||
+@BUILD_PLATFORM=ios BUILD_TARGET=iossimulator-xcrun SSL_TARGET=iossimulator-xcrun OPTIONS="-fPIC -Wno-macro-redefined" tools/ssl-local
|
||||
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS)
|
||||
endif
|
||||
|
||||
out/macos%/tildefriends: out/macos%-arm/tildefriends out/macos%-x86_64/tildefriends
|
||||
@echo [lipo] $@
|
||||
@mkdir -p $(@D)
|
||||
@deps/macos_toolchain/bin/lipo -create -output $@ $^
|
||||
|
||||
##
|
||||
## Linux package targets:
|
||||
##
|
||||
@ -1282,7 +1368,20 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
|
||||
.PHONY: tarball
|
||||
|
||||
dist: ## Build versions of all distributables for release.
|
||||
dist: release-apk $(if $(HAVE_LINUX_IOS), 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)
|
||||
dist: release-apk aab out/TildeFriends-release.fdroid.apk appimage tarball out/release/tildefriends.standalone
|
||||
ifeq ($(HAVE_LINUX_IOS),1)
|
||||
dist: iosrelease-ipa
|
||||
endif
|
||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
||||
dist: out/macosrelease/tildefriends.standalone
|
||||
endif
|
||||
ifeq ($(HAVE_WIN),1)
|
||||
dist: out/winrelease/tildefriends.standalone.exe
|
||||
endif
|
||||
ifeq ($(HAVE_CROSS_AARCH64),1)
|
||||
dist: out/armrelease/tildefriends.standalone
|
||||
endif
|
||||
dist:
|
||||
@mkdir -p dist/
|
||||
@echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz"
|
||||
@cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz
|
||||
@ -1292,6 +1391,8 @@ dist: release-apk $(if $(HAVE_LINUX_IOS), iosrelease-ipa) aab $(if $(HAVE_WIN),
|
||||
@cp out/TildeFriends-arm-release.zopfli.apk dist/TildeFriends-arm-$(VERSION_NUMBER).apk
|
||||
@test $(HAVE_LINUX_IOS) && echo "[cp] TildeFriends-$(VERSION_NUMBER).ipa"
|
||||
@test $(HAVE_LINUX_IOS) && cp out/tildefriends-release.ipa dist/TildeFriends-$(VERSION_NUMBER).ipa
|
||||
@test $(HAVE_LINUX_MACOS) && echo "[cp] tildefriends-macos-$(VERSION_NUMBER)"
|
||||
@test $(HAVE_LINUX_MACOS) && cp out/macosrelease/tildefriends.standalone dist/tildefriends-macos-$(VERSION_NUMBER)
|
||||
@test $(HAVE_WIN) && echo "[cp] tildefriends-$(VERSION_NUMBER).exe"
|
||||
@test $(HAVE_WIN) && cp out/winrelease/tildefriends.standalone.exe dist/tildefriends-$(VERSION_NUMBER).exe
|
||||
@echo "[cp] TildeFriends-$(VERSION_NUMBER).aab"
|
||||
@ -1313,6 +1414,17 @@ dist-test: dist ## Exercise some built distributable files, making sure they wor
|
||||
@rm -rf tildefriends-$(VERSION_NUMBER)
|
||||
.PHONY: dist-test
|
||||
|
||||
dist-ios: iosrelease-app
|
||||
rm -rfv out/Payload out/tildefriends.ipa
|
||||
mkdir -p out/Payload/tildefriends.app
|
||||
cp -avR out/tildefriends-iosrelease.app/* out/Payload/tildefriends.app/
|
||||
cp src/ios/tildefriends.png out/Payload/tildefriends.app/
|
||||
xcrun -sdk iphoneos actool --compile out/Payload/tildefriends.app/ --platform iphoneos --minimum-deployment-target $(IPHONEOS_VERSION_MIN) --app-icon AppIcon src/ios/icons/Assets.xcassets src/ios/icons/*.png --output-partial-info-plist out/actool.plist
|
||||
cp src/ios/distribution.mobileprovision out/Payload/tildefriends.app/embedded.mobileprovision
|
||||
xcrun -sdk iphoneos codesign -f -s 'Apple Distribution' --entitlements src/ios/Entitlements.plist --generate-entitlement-der out/Payload/tildefriends.app
|
||||
cd out; zip -r tildefriends.ipa Payload; cd ..
|
||||
xcrun -sdk iphoneos altool --upload-app -f out/tildefriends.ipa -t ios -u $$(cat .keys/altool-user) -p $$(cat .keys/altool-password)
|
||||
|
||||
##
|
||||
## Targets for tidying up:
|
||||
##
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "🎛",
|
||||
"previous": "&R49FywYF8CXPhoSEydLbSCgvCddeyTiBwGuDU/gqY+M=.sha256"
|
||||
"previous": "&kmKNyb/uaXNb24gCinJtfS8iWx4cLUWdtl0y2DwEUas=.sha256"
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ ${description.value}</textarea
|
||||
</button>
|
||||
</li>
|
||||
`;
|
||||
} else {
|
||||
} else if (description.type != 'hidden') {
|
||||
return html`
|
||||
<li class="w3-row">
|
||||
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label>
|
||||
|
@ -1,7 +1,9 @@
|
||||
async function main() {
|
||||
let host = core.url.match(/.*\/\/(.*?)\//)[1];
|
||||
print(core.url);
|
||||
let host = core.url.match(/.*?\/\/([^:/]*)/)[1];
|
||||
let port = await ssb.port();
|
||||
let id = (await ssb.getServerIdentity()).substring(1);
|
||||
let room = `net:${host}:${ssb.port}~shs:${id}:SSB+Room+SK3TLYC2T86EHQCUHBUHASCASE18JBV24=`;
|
||||
let room = `net:${host}:${port}~shs:${id}:SSB+Room+SK3TLYC2T86EHQCUHBUHASCASE18JBV24=`;
|
||||
await app.setDocument(`
|
||||
<body style="color: #fff">
|
||||
<h1>Server</h1>
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "🦀",
|
||||
"previous": "&0ZtxnihH3oETfi0vhhEwc9O66SrjfiFcHDVBAIxICy0=.sha256"
|
||||
"previous": "&jAAzd36Nmpw0sRA1Dx9wLiIwGX+q//+S/Han+RLlEOw=.sha256"
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ class TfProfileElement extends LitElement {
|
||||
}
|
||||
|
||||
modify(change) {
|
||||
let self = this;
|
||||
tfrpc.rpc
|
||||
.appendMessage(
|
||||
this.whoami,
|
||||
@ -73,6 +74,10 @@ class TfProfileElement extends LitElement {
|
||||
change
|
||||
)
|
||||
)
|
||||
.then(function () {
|
||||
self._follow_whoami = undefined;
|
||||
self.load();
|
||||
})
|
||||
.catch(function (error) {
|
||||
alert(error?.message);
|
||||
});
|
||||
|
@ -21,7 +21,9 @@ class TfUserElement extends LitElement {
|
||||
render() {
|
||||
let user = this.users[this.id];
|
||||
let shape =
|
||||
!user?.follow_depth || user.follow_depth >= 2 ? 'w3-circle' : 'w3-round';
|
||||
user?.follow_depth === undefined || user.follow_depth >= 2
|
||||
? 'w3-circle'
|
||||
: 'w3-round';
|
||||
let image = html`<span
|
||||
class=${'w3-theme-l4 ' + shape}
|
||||
style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em"
|
||||
|
@ -222,9 +222,9 @@
|
||||
<div class="w3-container w3-padding-64 w3-light-grey w3-center">
|
||||
<h1 class="w3-jumbo"><b>Built the Old Fashioned Way</b></h1>
|
||||
<p>
|
||||
Tilde Friends strives to use only simple and widely adopted
|
||||
dependencies in order to keep it easy to build for all sorts of
|
||||
platforms and maintainable for a very long time.
|
||||
Tilde Friends strives to use only simple and widely adopted dependencies
|
||||
in order to keep it easy to build for all sorts of platforms and
|
||||
maintainable for a very long time.
|
||||
</p>
|
||||
<p>
|
||||
Though of course for building Tilde Friends apps, you are free to use
|
||||
|
@ -470,7 +470,6 @@ async function getProcessBlob(blobId, key, options) {
|
||||
imports.ssb = Object.fromEntries(
|
||||
Object.keys(ssb).map((key) => [key, ssb[key].bind(ssb)])
|
||||
);
|
||||
imports.ssb.port = tildefriends.ssb_port;
|
||||
imports.ssb.createIdentity = () => process.createIdentity();
|
||||
imports.ssb.addIdentity = function (id) {
|
||||
if (
|
||||
|
@ -1,4 +1,8 @@
|
||||
# How to upgrade to a newer version
|
||||
# - On the june and december release, you'll have to update nixpkgs to the current branch
|
||||
# Change `nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";`
|
||||
# to the latest release (see https://nixos.org/)
|
||||
# - Run `$ nix flake update`
|
||||
# - Comment `src.hash`
|
||||
# - Change `version`
|
||||
# - Run `$ nix build`
|
||||
|
2
deps/codemirror/cm6.js
vendored
194
deps/codemirror_src/package-lock.json
generated
vendored
@ -19,9 +19,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.18.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz",
|
||||
"integrity": "sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA==",
|
||||
"version": "6.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
|
||||
"integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
@ -69,9 +69,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-javascript": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz",
|
||||
"integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==",
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz",
|
||||
"integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.6.0",
|
||||
@ -115,9 +115,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/search": {
|
||||
"version": "6.5.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.8.tgz",
|
||||
"integrity": "sha512-PoWtZvo7c1XFeZWmmyaOp2G0XVbOnm+fJzvghqGAktBW3cufwJUWvSCcNG0ppXiBEM05mZu6RhMtXPv2hpllig==",
|
||||
"version": "6.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz",
|
||||
"integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
@ -125,9 +125,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.1.tgz",
|
||||
"integrity": "sha512-3rA9lcwciEB47ZevqvD8qgbzhM9qMb8vCcQCNmDfVRPQG4JT9mSb0Jg8H7YjKGGQcFnLN323fj9jdnG59Kx6bg==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
||||
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
||||
"dependencies": {
|
||||
"@marijn/find-cluster-break": "^1.0.0"
|
||||
}
|
||||
@ -144,9 +144,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.36.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.2.tgz",
|
||||
"integrity": "sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA==",
|
||||
"version": "6.36.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.3.tgz",
|
||||
"integrity": "sha512-N2bilM47QWC8Hnx0rMdDxO2x2ImJ1FvZWXubwKgjeoOrWwEiFrtpA7SFHcuZ+o2Ze2VzbkgbzWVj4+V18LVkeg==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.5.0",
|
||||
"style-mod": "^4.1.0",
|
||||
@ -344,9 +344,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.1.tgz",
|
||||
"integrity": "sha512-/pqA4DmqyCm8u5YIDzIdlLcEmuvxb0v8fZdFhVMszSpDTgbQKdw3/mB3eMUHIbubtJ6F9j+LtmyCnHTEqIHyzA==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
|
||||
"integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -356,9 +356,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.1.tgz",
|
||||
"integrity": "sha512-If3PDskT77q7zgqVqYuj7WG3WC08G1kwXGVFi9Jr8nY6eHucREHkfpX79c0ACAjLj3QIWKPJR7w4i+f5EdLH5Q==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
|
||||
"integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -368,9 +368,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.1.tgz",
|
||||
"integrity": "sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
|
||||
"integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -380,9 +380,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.1.tgz",
|
||||
"integrity": "sha512-sFvF+t2+TyUo/ZQqUcifrJIgznx58oFZbdHS9TvHq3xhPVL9nOp+yZ6LKrO9GWTP+6DbFtoyLDbjTpR62Mbr3Q==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
|
||||
"integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -392,9 +392,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.1.tgz",
|
||||
"integrity": "sha512-NbOa+7InvMWRcY9RG+B6kKIMD/FsnQPH0MWUvDlQB1iXnF/UcKSudCXZtv4lW+C276g3w5AxPbfry5rSYvyeYA==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
|
||||
"integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -404,9 +404,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.1.tgz",
|
||||
"integrity": "sha512-JRBRmwvHPXR881j2xjry8HZ86wIPK2CcDw0EXchE1UgU0ubWp9nvlT7cZYKc6bkypBt745b4bglf3+xJ7hXWWw==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
|
||||
"integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -416,9 +416,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.1.tgz",
|
||||
"integrity": "sha512-PKvszb+9o/vVdUzCCjL0sKHukEQV39tD3fepXxYrHE3sTKrRdCydI7uldRLbjLmDA3TFDmh418XH19NOsDRH8g==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
|
||||
"integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -428,9 +428,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.1.tgz",
|
||||
"integrity": "sha512-9WHEMV6Y89eL606ReYowXuGF1Yb2vwfKWKdD1A5h+OYnPZSJvxbEjxTRKPgi7tkP2DSnW0YLab1ooy+i/FQp/Q==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
|
||||
"integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -440,9 +440,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.1.tgz",
|
||||
"integrity": "sha512-tZWc9iEt5fGJ1CL2LRPw8OttkCBDs+D8D3oEM8mH8S1ICZCtFJhD7DZ3XMGM8kpqHvhGUTvNUYVDnmkj4BDXnw==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
|
||||
"integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -452,9 +452,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.1.tgz",
|
||||
"integrity": "sha512-FTYc2YoTWUsBz5GTTgGkRYYJ5NGJIi/rCY4oK/I8aKowx1ToXeoVVbIE4LGAjsauvlhjfl0MYacxClLld1VrOw==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
|
||||
"integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -464,9 +464,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.1.tgz",
|
||||
"integrity": "sha512-F51qLdOtpS6P1zJVRzYM0v6MrBNypyPEN1GfMiz0gPu9jN8ScGaEFIZQwteSsGKg799oR5EaP7+B2jHgL+d+Kw==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
|
||||
"integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@ -476,9 +476,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.1.tgz",
|
||||
"integrity": "sha512-wO0WkfSppfX4YFm5KhdCCpnpGbtgQNj/tgvYzrVYFKDpven8w2N6Gg5nB6w+wAMO3AIfSTWeTjfVe+uZ23zAlg==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
|
||||
"integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@ -488,9 +488,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.1.tgz",
|
||||
"integrity": "sha512-iWswS9cIXfJO1MFYtI/4jjlrGb/V58oMu4dYJIKnR5UIwbkzR0PJ09O0PDZT0oJ3LYWXBSWahNf/Mjo6i1E5/g==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
|
||||
"integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@ -500,9 +500,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.1.tgz",
|
||||
"integrity": "sha512-RKt8NI9tebzmEthMnfVgG3i/XeECkMPS+ibVZjZ6mNekpbbUmkNWuIN2yHsb/mBPyZke4nlI4YqIdFPgKuoyQQ==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
|
||||
"integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@ -512,9 +512,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.1.tgz",
|
||||
"integrity": "sha512-WQFLZ9c42ECqEjwg/GHHsouij3pzLXkFdz0UxHa/0OM12LzvX7DzedlY0SIEly2v18YZLRhCRoHZDxbBSWoGYg==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
|
||||
"integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -524,9 +524,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.1.tgz",
|
||||
"integrity": "sha512-BLoiyHDOWoS3uccNSADMza6V6vCNiphi94tQlVIL5de+r6r/CCQuNnerf+1g2mnk2b6edp5dk0nhdZ7aEjOBsA==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
|
||||
"integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -536,9 +536,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.1.tgz",
|
||||
"integrity": "sha512-w2l3UnlgYTNNU+Z6wOR8YdaioqfEnwPjIsJ66KxKAf0p+AuL2FHeTX6qvM+p/Ue3XPBVNyVSfCrfZiQh7vZHLQ==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
|
||||
"integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -548,9 +548,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.1.tgz",
|
||||
"integrity": "sha512-Am9H+TGLomPGkBnaPWie4F3x+yQ2rr4Bk2jpwy+iV+Gel9jLAu/KqT8k3X4jxFPW6Zf8OMnehyutsd+eHoq1WQ==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
|
||||
"integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@ -560,9 +560,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.1.tgz",
|
||||
"integrity": "sha512-ar80GhdZb4DgmW3myIS9nRFYcpJRSME8iqWgzH2i44u+IdrzmiXVxeFnExQ5v4JYUSpg94bWjevMG8JHf1Da5Q==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
|
||||
"integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -733,9 +733,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.32.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.1.tgz",
|
||||
"integrity": "sha512-z+aeEsOeEa3mEbS1Tjl6sAZ8NE3+AalQz1RJGj81M+fizusbdDMoEJwdJNHfaB40Scr4qNu+welOfes7maKonA==",
|
||||
"version": "4.34.8",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz",
|
||||
"integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.6"
|
||||
},
|
||||
@ -747,25 +747,25 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.32.1",
|
||||
"@rollup/rollup-android-arm64": "4.32.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.32.1",
|
||||
"@rollup/rollup-darwin-x64": "4.32.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.32.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.32.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.32.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.32.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.32.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.32.1",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.32.1",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.32.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.32.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.32.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.32.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.32.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.32.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.32.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.32.1",
|
||||
"@rollup/rollup-android-arm-eabi": "4.34.8",
|
||||
"@rollup/rollup-android-arm64": "4.34.8",
|
||||
"@rollup/rollup-darwin-arm64": "4.34.8",
|
||||
"@rollup/rollup-darwin-x64": "4.34.8",
|
||||
"@rollup/rollup-freebsd-arm64": "4.34.8",
|
||||
"@rollup/rollup-freebsd-x64": "4.34.8",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.34.8",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.34.8",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.34.8",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.34.8",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.34.8",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.34.8",
|
||||
"@rollup/rollup-linux-x64-musl": "4.34.8",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.34.8",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.34.8",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.34.8",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@ -840,9 +840,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.37.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
|
||||
"integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
|
||||
"version": "5.39.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
|
||||
"integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
|
2
deps/libbacktrace
vendored
2
deps/openssl_src
vendored
2
deps/speedscope/index.html
vendored
@ -11,7 +11,7 @@
|
||||
<link rel="icon" type="image/x-icon" href="favicon-FOKUP5Y5.ico">
|
||||
</head>
|
||||
<body>
|
||||
<script src="speedscope-CAEVGCWN.js"></script>
|
||||
<script src="speedscope-VHEG2FVF.js"></script>
|
||||
|
||||
|
||||
|
||||
|
6
deps/speedscope/release.txt
vendored
@ -1,3 +1,3 @@
|
||||
speedscope@1.22.0
|
||||
Thu Jan 16 16:49:47 PST 2025
|
||||
bd7b44a0a7d63375ee6ea0a0d1b96e65a456642f
|
||||
speedscope@1.22.2
|
||||
Sat Feb 15 13:02:38 PST 2025
|
||||
1c254dcb3e2b4f6d921340d20e972d9d27b788f4
|
||||
|
24
deps/sqlite/shell.c
vendored
@ -357,6 +357,11 @@ void sqlite3_fsetmode(FILE *stream, int mode);
|
||||
** use O_U8TEXT when writing to the Windows console (or anything
|
||||
** else for which _isatty() returns true) and to use O_BINARY or O_TEXT
|
||||
** for all other output channels.
|
||||
**
|
||||
** The SQLITE_USE_W32_FOR_CONSOLE_IO macro is also available. If
|
||||
** defined, it forces the use of Win32 APIs for all console I/O, both
|
||||
** input and output. This is necessary for some non-Microsoft run-times
|
||||
** that implement stdio differently from Microsoft/Visual-Studio.
|
||||
*/
|
||||
#if defined(SQLITE_U8TEXT_ONLY)
|
||||
# define UseWtextForOutput(fd) 1
|
||||
@ -459,10 +464,10 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){
|
||||
*/
|
||||
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
|
||||
if( b1==0 ) return 0;
|
||||
#ifndef SQLITE_USE_STDIO_FOR_CONSOLE
|
||||
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
|
||||
DWORD nRead = 0;
|
||||
if( IsConsole(in)
|
||||
&& ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0)
|
||||
&& ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz-1, &nRead, 0)
|
||||
){
|
||||
b1[nRead] = 0;
|
||||
}else
|
||||
@ -537,7 +542,7 @@ int sqlite3_fputs(const char *z, FILE *out){
|
||||
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
|
||||
b1[sz] = 0;
|
||||
|
||||
#ifndef SQLITE_STDIO_FOR_CONSOLE
|
||||
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
|
||||
DWORD nWr = 0;
|
||||
if( IsConsole(out)
|
||||
&& WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
|
||||
@ -547,8 +552,9 @@ int sqlite3_fputs(const char *z, FILE *out){
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
/* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined
|
||||
** then write using the standard library. */
|
||||
/* As long as SQLITE_USE_W32_FOR_CONSOLE_IO is not defined, or for
|
||||
** non-console I/O even if that macro is defined, write using the
|
||||
** standard library. */
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
if( UseBinaryWText(out) ){
|
||||
piecemealOutput(b1, sz, out);
|
||||
@ -5314,7 +5320,7 @@ static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){
|
||||
deliberate_fall_through; /* FALLTHRU */
|
||||
case 1:
|
||||
pOut[0] = (qv>>16) & 0xff;
|
||||
deliberate_fall_through; /* FALLTHRU */
|
||||
break;
|
||||
}
|
||||
pOut += nbo;
|
||||
}
|
||||
@ -17199,7 +17205,7 @@ static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
|
||||
sqlite3_vfs *pRoot = pInfo->pRootVfs;
|
||||
vfstraceOnOff(pInfo, VTR_DLCLOSE);
|
||||
vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
|
||||
vfstrace_printf(pInfo, "%s.xDlClose()\n", pInfo->zVfsName);
|
||||
pRoot->xDlClose(pRoot, pHandle);
|
||||
}
|
||||
|
||||
@ -28885,6 +28891,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
const char *zName;
|
||||
int op;
|
||||
} aDbConfig[] = {
|
||||
{ "attach_create", SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE },
|
||||
{ "attach_write", SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE },
|
||||
{ "comments", SQLITE_DBCONFIG_ENABLE_COMMENTS },
|
||||
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
|
||||
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
|
||||
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
|
||||
@ -31635,6 +31644,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ 0x04000000, 1, "NullUnusedCols" },
|
||||
{ 0x08000000, 1, "OnePass" },
|
||||
{ 0x10000000, 1, "OrderBySubq" },
|
||||
{ 0x20000000, 1, "StarQuery" },
|
||||
{ 0xffffffff, 0, "All" },
|
||||
};
|
||||
unsigned int curOpt;
|
||||
|
4064
deps/sqlite/sqlite3.c
vendored
153
deps/sqlite/sqlite3.h
vendored
@ -146,9 +146,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.48.0"
|
||||
#define SQLITE_VERSION_NUMBER 3048000
|
||||
#define SQLITE_SOURCE_ID "2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010"
|
||||
#define SQLITE_VERSION "3.49.1"
|
||||
#define SQLITE_VERSION_NUMBER 3049001
|
||||
#define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@ -2211,7 +2211,15 @@ struct sqlite3_mem_methods {
|
||||
** CAPI3REF: Database Connection Configuration Options
|
||||
**
|
||||
** These constants are the available integer configuration options that
|
||||
** can be passed as the second argument to the [sqlite3_db_config()] interface.
|
||||
** can be passed as the second parameter to the [sqlite3_db_config()] interface.
|
||||
**
|
||||
** The [sqlite3_db_config()] interface is a var-args functions. It takes a
|
||||
** variable number of parameters, though always at least two. The number of
|
||||
** parameters passed into sqlite3_db_config() depends on which of these
|
||||
** constants is given as the second parameter. This documentation page
|
||||
** refers to parameters beyond the second as "arguments". Thus, when this
|
||||
** page says "the N-th argument" it means "the N-th parameter past the
|
||||
** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()".
|
||||
**
|
||||
** New configuration options may be added in future releases of SQLite.
|
||||
** Existing configuration options might be discontinued. Applications
|
||||
@ -2223,8 +2231,14 @@ struct sqlite3_mem_methods {
|
||||
** <dl>
|
||||
** [[SQLITE_DBCONFIG_LOOKASIDE]]
|
||||
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
|
||||
** <dd> ^This option takes three additional arguments that determine the
|
||||
** [lookaside memory allocator] configuration for the [database connection].
|
||||
** <dd> The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the
|
||||
** configuration of the lookaside memory allocator within a database
|
||||
** connection.
|
||||
** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are <i>not</i>
|
||||
** in the [DBCONFIG arguments|usual format].
|
||||
** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two,
|
||||
** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE
|
||||
** should have a total of five parameters.
|
||||
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
|
||||
** pointer to a memory buffer to use for lookaside memory.
|
||||
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
|
||||
@ -2247,7 +2261,8 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
|
||||
** <dd> ^This option is used to enable or disable the enforcement of
|
||||
** [foreign key constraints]. There should be two additional arguments.
|
||||
** [foreign key constraints]. This is the same setting that is
|
||||
** enabled or disabled by the [PRAGMA foreign_keys] statement.
|
||||
** The first argument is an integer which is 0 to disable FK enforcement,
|
||||
** positive to enable FK enforcement or negative to leave FK enforcement
|
||||
** unchanged. The second parameter is a pointer to an integer into which
|
||||
@ -2269,13 +2284,13 @@ struct sqlite3_mem_methods {
|
||||
** <p>Originally this option disabled all triggers. ^(However, since
|
||||
** SQLite version 3.35.0, TEMP triggers are still allowed even if
|
||||
** this option is off. So, in other words, this option now only disables
|
||||
** triggers in the main database schema or in the schemas of ATTACH-ed
|
||||
** triggers in the main database schema or in the schemas of [ATTACH]-ed
|
||||
** databases.)^ </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
|
||||
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
|
||||
** There should be two additional arguments.
|
||||
** There must be two additional arguments.
|
||||
** The first argument is an integer which is 0 to disable views,
|
||||
** positive to enable views or negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer into which
|
||||
@ -2294,7 +2309,7 @@ struct sqlite3_mem_methods {
|
||||
** <dd> ^This option is used to enable or disable the
|
||||
** [fts3_tokenizer()] function which is part of the
|
||||
** [FTS3] full-text search engine extension.
|
||||
** There should be two additional arguments.
|
||||
** There must be two additional arguments.
|
||||
** The first argument is an integer which is 0 to disable fts3_tokenizer() or
|
||||
** positive to enable fts3_tokenizer() or negative to leave the setting
|
||||
** unchanged.
|
||||
@ -2309,7 +2324,7 @@ struct sqlite3_mem_methods {
|
||||
** interface independently of the [load_extension()] SQL function.
|
||||
** The [sqlite3_enable_load_extension()] API enables or disables both the
|
||||
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
|
||||
** There should be two additional arguments.
|
||||
** There must be two additional arguments.
|
||||
** When the first argument to this interface is 1, then only the C-API is
|
||||
** enabled and the SQL function remains disabled. If the first argument to
|
||||
** this interface is 0, then both the C-API and the SQL function are disabled.
|
||||
@ -2323,23 +2338,30 @@ struct sqlite3_mem_methods {
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
||||
** <dd> ^This option is used to change the name of the "main" database
|
||||
** schema. ^The sole argument is a pointer to a constant UTF8 string
|
||||
** which will become the new schema name in place of "main". ^SQLite
|
||||
** does not make a copy of the new main schema name string, so the application
|
||||
** must ensure that the argument passed into this DBCONFIG option is unchanged
|
||||
** until after the database connection closes.
|
||||
** schema. This option does not follow the
|
||||
** [DBCONFIG arguments|usual SQLITE_DBCONFIG argument format].
|
||||
** This option takes exactly one additional argument so that the
|
||||
** [sqlite3_db_config()] call has a total of three parameters. The
|
||||
** extra argument must be a pointer to a constant UTF8 string which
|
||||
** will become the new schema name in place of "main". ^SQLite does
|
||||
** not make a copy of the new main schema name string, so the application
|
||||
** must ensure that the argument passed into SQLITE_DBCONFIG MAINDBNAME
|
||||
** is unchanged until after the database connection closes.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
|
||||
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
|
||||
** <dd> Usually, when a database in wal mode is closed or detached from a
|
||||
** database handle, SQLite checks if this will mean that there are now no
|
||||
** connections at all to the database. If so, it performs a checkpoint
|
||||
** operation before closing the connection. This option may be used to
|
||||
** override this behavior. The first parameter passed to this operation
|
||||
** is an integer - positive to disable checkpoints-on-close, or zero (the
|
||||
** default) to enable them, and negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer
|
||||
** <dd> Usually, when a database in [WAL mode] is closed or detached from a
|
||||
** database handle, SQLite checks if if there are other connections to the
|
||||
** same database, and if there are no other database connection (if the
|
||||
** connection being closed is the last open connection to the database),
|
||||
** then SQLite performs a [checkpoint] before closing the connection and
|
||||
** deletes the WAL file. The SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE option can
|
||||
** be used to override that behavior. The first argument passed to this
|
||||
** operation (the third parameter to [sqlite3_db_config()]) is an integer
|
||||
** which is positive to disable checkpoints-on-close, or zero (the default)
|
||||
** to enable them, and negative to leave the setting unchanged.
|
||||
** The second argument (the fourth parameter) is a pointer to an integer
|
||||
** into which is written 0 or 1 to indicate whether checkpoints-on-close
|
||||
** have been disabled - 0 if they are not disabled, 1 if they are.
|
||||
** </dd>
|
||||
@ -2500,7 +2522,7 @@ struct sqlite3_mem_methods {
|
||||
** statistics. For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is prepared and when it
|
||||
** is stepped. The flag is set (collection of statistics is enabled)
|
||||
** by default. This option takes two arguments: an integer and a pointer to
|
||||
** by default. <p>This option takes two arguments: an integer and a pointer to
|
||||
** an integer.. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the statement scanstatus option. If the second argument
|
||||
** is not NULL, then the value of the statement scanstatus setting after
|
||||
@ -2514,7 +2536,7 @@ struct sqlite3_mem_methods {
|
||||
** in which tables and indexes are scanned so that the scans start at the end
|
||||
** and work toward the beginning rather than starting at the beginning and
|
||||
** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the
|
||||
** same as setting [PRAGMA reverse_unordered_selects]. This option takes
|
||||
** same as setting [PRAGMA reverse_unordered_selects]. <p>This option takes
|
||||
** two arguments which are an integer and a pointer to an integer. The first
|
||||
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
|
||||
** reverse scan order flag, respectively. If the second argument is not NULL,
|
||||
@ -2523,7 +2545,76 @@ struct sqlite3_mem_methods {
|
||||
** first argument.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE option enables or disables
|
||||
** the ability of the [ATTACH DATABASE] SQL command to create a new database
|
||||
** file if the database filed named in the ATTACH command does not already
|
||||
** exist. This ability of ATTACH to create a new database is enabled by
|
||||
** default. Applications can disable or reenable the ability for ATTACH to
|
||||
** create new database files using this DBCONFIG option.<p>
|
||||
** This option takes two arguments which are an integer and a pointer
|
||||
** to an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the attach-create flag, respectively. If the second
|
||||
** argument is not NULL, then 0 or 1 is written into the integer that the
|
||||
** second argument points to depending on if the attach-create flag is set
|
||||
** after processing the first argument.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the
|
||||
** ability of the [ATTACH DATABASE] SQL command to open a database for writing.
|
||||
** This capability is enabled by default. Applications can disable or
|
||||
** reenable this capability using the current DBCONFIG option. If the
|
||||
** the this capability is disabled, the [ATTACH] command will still work,
|
||||
** but the database will be opened read-only. If this option is disabled,
|
||||
** then the ability to create a new database using [ATTACH] is also disabled,
|
||||
** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]
|
||||
** option.<p>
|
||||
** This option takes two arguments which are an integer and a pointer
|
||||
** to an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the ability to ATTACH another database for writing,
|
||||
** respectively. If the second argument is not NULL, then 0 or 1 is written
|
||||
** into the integer to which the second argument points, depending on whether
|
||||
** the ability to ATTACH a read/write database is enabled or disabled
|
||||
** after processing the first argument.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_COMMENTS]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_COMMENTS</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_ENABLE_COMMENTS option enables or disables the
|
||||
** ability to include comments in SQL text. Comments are enabled by default.
|
||||
** An application can disable or reenable comments in SQL text using this
|
||||
** DBCONFIG option.<p>
|
||||
** This option takes two arguments which are an integer and a pointer
|
||||
** to an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the ability to use comments in SQL text,
|
||||
** respectively. If the second argument is not NULL, then 0 or 1 is written
|
||||
** into the integer that the second argument points to depending on if
|
||||
** comments are allowed in SQL text after processing the first argument.
|
||||
** </dd>
|
||||
**
|
||||
** </dl>
|
||||
**
|
||||
** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3>
|
||||
**
|
||||
** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the
|
||||
** overall call to [sqlite3_db_config()] has a total of four parameters.
|
||||
** The first argument (the third parameter to sqlite3_db_config()) is a integer.
|
||||
** The second argument is a pointer to an integer. If the first argument is 1,
|
||||
** then the option becomes enabled. If the first integer argument is 0, then the
|
||||
** option is disabled. If the first argument is -1, then the option setting
|
||||
** is unchanged. The second argument, the pointer to an integer, may be NULL.
|
||||
** If the second argument is not NULL, then a value of 0 or 1 is written into
|
||||
** the integer to which the second argument points, depending on whether the
|
||||
** setting is disabled or enabled after applying any changes specified by
|
||||
** the first argument.
|
||||
**
|
||||
** <p>While most SQLITE_DBCONFIG options use the argument format
|
||||
** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME]
|
||||
** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the
|
||||
** documentation of those exceptional options for details.
|
||||
*/
|
||||
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
||||
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
||||
@ -2545,7 +2636,10 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
|
||||
#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */
|
||||
#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
@ -10748,8 +10842,9 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c
|
||||
/*
|
||||
** CAPI3REF: Serialize a database
|
||||
**
|
||||
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
|
||||
** that is a serialization of the S database on [database connection] D.
|
||||
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
|
||||
** memory that is a serialization of the S database on
|
||||
** [database connection] D. If S is a NULL pointer, the main database is used.
|
||||
** If P is not a NULL pointer, then the size of the database in bytes
|
||||
** is written into *P.
|
||||
**
|
||||
|
@ -4,12 +4,17 @@
|
||||
- run the tests
|
||||
- format + prettier
|
||||
- update metadata/en-US/changelogs
|
||||
- git tag
|
||||
- git tag v1.2.3
|
||||
- git tag -f latest_release
|
||||
- push
|
||||
- make dist
|
||||
- make a release on gitea
|
||||
- upload the artifacts
|
||||
- upload the AppImage and zsyncmake
|
||||
- upload to Google
|
||||
- upload to Apple with dist-ios on macos
|
||||
- nix
|
||||
- june and december: update release version
|
||||
- run `nix flake update`
|
||||
- comment out the hash in default.nix
|
||||
- update the version
|
||||
- run `nix-build`
|
||||
|
14
flake.lock
generated
@ -5,11 +5,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -20,16 +20,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1717281328,
|
||||
"narHash": "sha256-evZPzpf59oNcDUXxh2GHcxHkTEG4fjae2ytWP85jXRo=",
|
||||
"lastModified": 1739758141,
|
||||
"narHash": "sha256-uq6A2L7o1/tR6VfmYhZWoVAwb3gTy7j4Jx30MIrH0rE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b3b2b28c1daa04fe2ae47c21bb76fd226eac4ca1",
|
||||
"rev": "c618e28f70257593de75a7044438efc1c1fc0791",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
description = "Tilde Friends is a platform for making, running, and sharing web applications.";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
|
15
metadata/en-US/changelogs/33.txt
Normal file
@ -0,0 +1,15 @@
|
||||
* Allow specifying all global settings from the command-line (CLI usage changed).
|
||||
* Replication improvements.
|
||||
* An iOS build is on TestFlight.
|
||||
* macOS targets are debug and release like everywhere else.
|
||||
* Running from a subdirectory is fine.
|
||||
* Patchwork compatibility improvements.
|
||||
* Invite fixes.
|
||||
* Follow/block UI fixes.
|
||||
* Mobile automatically logs in.
|
||||
* Updates:
|
||||
* CodeMirror
|
||||
* OpenSSL 3.4.1
|
||||
* libbacktrace
|
||||
* speedscope 1.22.2
|
||||
* sqlite 3.49.1
|
6
package-lock.json
generated
@ -11,9 +11,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
|
||||
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz",
|
||||
"integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.unprompted.tildefriends"
|
||||
android:versionCode="33"
|
||||
android:versionName="0.0.28-wip">
|
||||
android:versionName="0.0.28">
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application
|
||||
|
@ -421,7 +421,7 @@ public class TildeFriendsActivity extends Activity {
|
||||
base_url = "http://127.0.0.1:" + String.valueOf(port) + "/";
|
||||
runOnUiThread(() -> {
|
||||
hide_status();
|
||||
web_view.loadUrl(base_url);
|
||||
web_view.loadUrl(base_url + "login/auto");
|
||||
});
|
||||
observer = null;
|
||||
} else {
|
||||
|
@ -1,55 +1,16 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="65dp"
|
||||
android:height="65dp"
|
||||
android:viewportWidth="61"
|
||||
android:viewportHeight="65">
|
||||
<path
|
||||
android:pathData="M6,0h49a8,8 45,0 1,8 8v49a8,8 135,0 1,-8 8H6a8,8 45,0 1,-8 -8V8a8,8 135,0 1,8 -8Z"
|
||||
android:strokeWidth=".712717"
|
||||
android:fillColor="#0af"
|
||||
android:fillAlpha="1"/>
|
||||
<path
|
||||
android:pathData="m1.6762,36.6891v-4.0039q2.0703,-2.3438 5.4297,-2.3438 1.1719,0 2.4609,0.3516 1.2891,0.332 3.6719,1.3477 1.3477,0.5664 2.0117,0.7422 0.6836,0.1758 1.3672,0.1758 1.2695,0 2.6172,-0.7617 1.3672,-0.7617 2.4219,-1.9141v4.1406q-1.25,1.1719 -2.5391,1.6992 -1.2695,0.5273 -2.8711,0.5273 -1.1719,0 -2.2461,-0.2734 -1.0547,-0.2734 -3.3789,-1.3086 -2.3047,-1.0352 -3.8477,-1.0352 -1.25,0 -2.3633,0.5469 -1.0938,0.5273 -2.7344,2.1094z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M42.4653,32.2273m-16.7723,0a16.7723,16.7723 0,1 1,33.5446 0a16.7723,16.7723 0,1 1,-33.5446 0"
|
||||
android:fillColor="#fcea2b"/>
|
||||
<path
|
||||
android:pathData="M49.2697,34.097c2.8899,0 5.2344,-2.0871 5.2344,-4.6591 0,-1.2871 0.3267,-2.5742 -0.6213,-3.4164 -0.9473,-0.843 -3.1685,-1.2426 -4.6131,-1.2426 -1.7188,0 -3.7504,0.1043 -4.7043,1.2426 -0.6519,0.7766 -0.5302,2.3722 -0.5302,3.4164 0,2.572 2.343,4.6591 5.2344,4.6591zM34.9819,34.097c2.8899,0 5.2351,-2.0871 5.2351,-4.6591 0,-1.2871 0.326,-2.5742 -0.6213,-3.4164 -0.948,-0.843 -3.1685,-1.2426 -4.6138,-1.2426 -1.7181,0 -3.7497,0.1043 -4.7043,1.2426 -0.6512,0.7766 -0.5302,2.3722 -0.5302,3.4164 0,2.572 2.343,4.6591 5.2344,4.6591z"
|
||||
android:fillColor="#3f3f3f"/>
|
||||
<path
|
||||
android:pathData="M42.3829,32.2681m-16.7723,0a16.7723,16.7723 0,1 1,33.5446 0a16.7723,16.7723 0,1 1,-33.5446 0"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M49.5403,38.6897c-4.794,2.5705 -10.242,2.6675 -14.3148,0M29.983,28.1903s-0.695,6.2349 5.0025,5.774c1.9106,-0.1546 5.7004,-0.474 5.7369,-6.0832 0.0036,-0.509 -0.0051,-1.1668 -0.5907,-1.9179 -0.7766,-0.9969 -2.6048,-1.4373 -7.2522,-1.037 0,0 -2.5129,-0.0729 -2.8965,3.264z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="m30.0341,27.8016 l-0.3158,-2.459 2.7951,-0.3843M54.6733,28.1903s0.695,6.2349 -5.0025,5.774c-1.9106,-0.1546 -5.7004,-0.474 -5.7376,-6.0832 -0.0029,-0.509 0.0058,-1.1668 0.5914,-1.9179 0.7766,-0.9969 2.6048,-1.4373 7.2522,-1.037 0,0 2.5129,-0.0729 2.8965,3.264z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M39.1874,25.2383s3.0073,1.8479 6.3129,0M40.6685,28.813s1.6058,-2.7353 3.3078,0M54.6172,27.803l0.3158,-2.4582 -2.7951,-0.385"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M40.974,27.8716s1.309,-2.7346 2.6974,0"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:gravity="center"
|
||||
android:width="256dp"
|
||||
android:height="256dp">
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#0af"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:drawable="@drawable/logo"
|
||||
android:width="65dp"
|
||||
android:height="65dp"
|
||||
android:gravity="center"/>
|
||||
</layer-list>
|
||||
|
16
src/android/res/drawable/icon_fdroid.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:gravity="center"
|
||||
android:width="256dp"
|
||||
android:height="256dp">
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#0fa"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:drawable="@drawable/logo"
|
||||
android:width="65dp"
|
||||
android:height="65dp"
|
||||
android:gravity="center"/>
|
||||
</layer-list>
|
51
src/android/res/drawable/logo.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="65dp"
|
||||
android:height="65dp"
|
||||
android:viewportWidth="65"
|
||||
android:viewportHeight="65">
|
||||
<path
|
||||
android:pathData="m1.6762,36.6891v-4.0039q2.0703,-2.3438 5.4297,-2.3438 1.1719,0 2.4609,0.3516 1.2891,0.332 3.6719,1.3477 1.3477,0.5664 2.0117,0.7422 0.6836,0.1758 1.3672,0.1758 1.2695,0 2.6172,-0.7617 1.3672,-0.7617 2.4219,-1.9141v4.1406q-1.25,1.1719 -2.5391,1.6992 -1.2695,0.5273 -2.8711,0.5273 -1.1719,0 -2.2461,-0.2734 -1.0547,-0.2734 -3.3789,-1.3086 -2.3047,-1.0352 -3.8477,-1.0352 -1.25,0 -2.3633,0.5469 -1.0938,0.5273 -2.7344,2.1094z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M42.4653,32.2273m-16.7723,0a16.7723,16.7723 0,1 1,33.5446 0a16.7723,16.7723 0,1 1,-33.5446 0"
|
||||
android:fillColor="#fcea2b"/>
|
||||
<path
|
||||
android:pathData="M49.2697,34.097c2.8899,0 5.2344,-2.0871 5.2344,-4.6591 0,-1.2871 0.3267,-2.5742 -0.6213,-3.4164 -0.9473,-0.843 -3.1685,-1.2426 -4.6131,-1.2426 -1.7188,0 -3.7504,0.1043 -4.7043,1.2426 -0.6519,0.7766 -0.5302,2.3722 -0.5302,3.4164 0,2.572 2.343,4.6591 5.2344,4.6591zM34.9819,34.097c2.8899,0 5.2351,-2.0871 5.2351,-4.6591 0,-1.2871 0.326,-2.5742 -0.6213,-3.4164 -0.948,-0.843 -3.1685,-1.2426 -4.6138,-1.2426 -1.7181,0 -3.7497,0.1043 -4.7043,1.2426 -0.6512,0.7766 -0.5302,2.3722 -0.5302,3.4164 0,2.572 2.343,4.6591 5.2344,4.6591z"
|
||||
android:fillColor="#3f3f3f"/>
|
||||
<path
|
||||
android:pathData="M42.3829,32.2681m-16.7723,0a16.7723,16.7723 0,1 1,33.5446 0a16.7723,16.7723 0,1 1,-33.5446 0"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M49.5403,38.6897c-4.794,2.5705 -10.242,2.6675 -14.3148,0M29.983,28.1903s-0.695,6.2349 5.0025,5.774c1.9106,-0.1546 5.7004,-0.474 5.7369,-6.0832 0.0036,-0.509 -0.0051,-1.1668 -0.5907,-1.9179 -0.7766,-0.9969 -2.6048,-1.4373 -7.2522,-1.037 0,0 -2.5129,-0.0729 -2.8965,3.264z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="m30.0341,27.8016 l-0.3158,-2.459 2.7951,-0.3843M54.6733,28.1903s0.695,6.2349 -5.0025,5.774c-1.9106,-0.1546 -5.7004,-0.474 -5.7376,-6.0832 -0.0029,-0.509 0.0058,-1.1668 0.5914,-1.9179 0.7766,-0.9969 2.6048,-1.4373 7.2522,-1.037 0,0 2.5129,-0.0729 2.8965,3.264z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M39.1874,25.2383s3.0073,1.8479 6.3129,0M40.6685,28.813s1.6058,-2.7353 3.3078,0M54.6172,27.803l0.3158,-2.4582 -2.7951,-0.385"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M40.974,27.8716s1.309,-2.7346 2.6974,0"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
154
src/httpd.js.c
@ -2166,6 +2166,111 @@ static void _httpd_endpoint_logout(tf_http_request_t* request)
|
||||
tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
|
||||
}
|
||||
|
||||
typedef struct _auto_login_t
|
||||
{
|
||||
tf_http_request_t* request;
|
||||
bool autologin;
|
||||
const char* users;
|
||||
} auto_login_t;
|
||||
|
||||
static void _httpd_auto_login_work(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
auto_login_t* request = user_data;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
tf_ssb_db_get_global_setting_bool(db, "autologin", &request->autologin);
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
|
||||
if (request->autologin)
|
||||
{
|
||||
request->users = tf_ssb_db_get_property(ssb, "auth", "users");
|
||||
if (request->users && strcmp(request->users, "[]") == 0)
|
||||
{
|
||||
tf_free((void*)request->users);
|
||||
request->users = NULL;
|
||||
}
|
||||
|
||||
if (!request->users)
|
||||
{
|
||||
JSMallocFunctions funcs = { 0 };
|
||||
tf_get_js_malloc_functions(&funcs);
|
||||
JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL);
|
||||
JSContext* context = JS_NewContext(runtime);
|
||||
static const char* k_account_name = "mobile";
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
bool registered = tf_ssb_db_register_account(tf_ssb_get_loop(ssb), db, context, k_account_name, k_account_name);
|
||||
tf_ssb_release_db_writer(ssb, db);
|
||||
if (registered)
|
||||
{
|
||||
_make_administrator_if_first(ssb, context, k_account_name, true);
|
||||
}
|
||||
JS_FreeContext(context);
|
||||
JS_FreeRuntime(runtime);
|
||||
|
||||
request->users = tf_ssb_db_get_property(ssb, "auth", "users");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_data)
|
||||
{
|
||||
auto_login_t* work = user_data;
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
const char* session_token = NULL;
|
||||
if (!work->autologin)
|
||||
{
|
||||
const char* k_payload = tf_http_status_text(404);
|
||||
tf_http_respond(work->request, 404, NULL, 0, k_payload, strlen(k_payload));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (work->users)
|
||||
{
|
||||
JSValue json = JS_ParseJSON(context, work->users, strlen(work->users), NULL);
|
||||
JSValue user = JS_GetPropertyUint32(context, json, 0);
|
||||
const char* user_string = JS_ToCString(context, user);
|
||||
session_token = _make_session_jwt(context, ssb, user_string);
|
||||
JS_FreeCString(context, user_string);
|
||||
JS_FreeValue(context, user);
|
||||
JS_FreeValue(context, json);
|
||||
}
|
||||
if (session_token)
|
||||
{
|
||||
const char* cookie = _make_set_session_cookie_header(work->request, session_token);
|
||||
tf_free((void*)session_token);
|
||||
const char* headers[] = {
|
||||
"Set-Cookie",
|
||||
cookie,
|
||||
"Location",
|
||||
"/",
|
||||
};
|
||||
tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0);
|
||||
tf_free((void*)cookie);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* headers[] = {
|
||||
"Location",
|
||||
"/",
|
||||
};
|
||||
tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0);
|
||||
}
|
||||
}
|
||||
tf_http_request_unref(work->request);
|
||||
tf_free((void*)work->users);
|
||||
tf_free(work);
|
||||
}
|
||||
|
||||
static void _httpd_endpoint_login_auto(tf_http_request_t* request)
|
||||
{
|
||||
tf_task_t* task = request->user_data;
|
||||
tf_http_request_ref(request);
|
||||
tf_ssb_t* ssb = tf_task_get_ssb(task);
|
||||
|
||||
auto_login_t* work = tf_malloc(sizeof(auto_login_t));
|
||||
*work = (auto_login_t) { .request = request };
|
||||
tf_ssb_run_work(ssb, _httpd_auto_login_work, _httpd_auto_login_after_work, work);
|
||||
}
|
||||
|
||||
static void _httpd_endpoint_app_socket(tf_http_request_t* request)
|
||||
{
|
||||
tf_task_t* task = request->user_data;
|
||||
@ -2206,35 +2311,6 @@ static void _httpd_endpoint_app_socket(tf_http_request_t* request)
|
||||
JS_FreeValue(context, global);
|
||||
}
|
||||
|
||||
static int _tf_httpd_get_tildefriends_int(JSContext* context, const char* arg)
|
||||
{
|
||||
JSValue global = JS_GetGlobalObject(context);
|
||||
JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends");
|
||||
JSValue arg_value = JS_GetPropertyStr(context, tildefriends, arg);
|
||||
int value = 0;
|
||||
JS_ToInt32(context, &value, arg_value);
|
||||
JS_FreeValue(context, arg_value);
|
||||
JS_FreeValue(context, tildefriends);
|
||||
JS_FreeValue(context, global);
|
||||
return value;
|
||||
}
|
||||
|
||||
static const char* _tf_httpd_get_tildefriends_arg_string(JSContext* context, const char* arg)
|
||||
{
|
||||
JSValue global = JS_GetGlobalObject(context);
|
||||
JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends");
|
||||
JSValue args = JS_GetPropertyStr(context, tildefriends, "args");
|
||||
JSValue arg_value = JS_GetPropertyStr(context, args, arg);
|
||||
const char* value = !JS_IsUndefined(arg_value) ? JS_ToCString(context, arg_value) : NULL;
|
||||
const char* result = value ? tf_strdup(value) : NULL;
|
||||
JS_FreeCString(context, value);
|
||||
JS_FreeValue(context, arg_value);
|
||||
JS_FreeValue(context, args);
|
||||
JS_FreeValue(context, tildefriends);
|
||||
JS_FreeValue(context, global);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _httpd_free_user_data(void* user_data)
|
||||
{
|
||||
tf_free(user_data);
|
||||
@ -2281,10 +2357,6 @@ void tf_httpd_register(JSContext* context)
|
||||
fprintf(stderr, "Failed to register Request.\n");
|
||||
}
|
||||
|
||||
int http_port = _tf_httpd_get_tildefriends_int(context, "http_port");
|
||||
int https_port = _tf_httpd_get_tildefriends_int(context, "https_port");
|
||||
const char* out_http_port_file = _tf_httpd_get_tildefriends_arg_string(context, "out_http_port_file");
|
||||
|
||||
JSValue global = JS_GetGlobalObject(context);
|
||||
JSValue httpd = JS_NewObjectClass(context, _httpd_class_id);
|
||||
|
||||
@ -2295,6 +2367,15 @@ void tf_httpd_register(JSContext* context)
|
||||
tf_http_set_trace(http, tf_task_get_trace(task));
|
||||
JS_SetOpaque(httpd, http);
|
||||
|
||||
int64_t http_port = 0;
|
||||
int64_t https_port = 0;
|
||||
char out_http_port_file[512] = "";
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
tf_ssb_db_get_global_setting_int64(db, "http_port", &http_port);
|
||||
tf_ssb_db_get_global_setting_int64(db, "https_port", &https_port);
|
||||
tf_ssb_db_get_global_setting_string(db, "out_http_port_file", out_http_port_file, sizeof(out_http_port_file));
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
|
||||
if (https_port)
|
||||
{
|
||||
http_user_data_t* user_data = tf_http_get_user_data(http);
|
||||
@ -2341,6 +2422,7 @@ void tf_httpd_register(JSContext* context)
|
||||
tf_http_add_handler(http, "/trace", _httpd_endpoint_trace, NULL, task);
|
||||
|
||||
tf_http_add_handler(http, "/login/logout", _httpd_endpoint_logout, NULL, task);
|
||||
tf_http_add_handler(http, "/login/auto", _httpd_endpoint_login_auto, NULL, task);
|
||||
tf_http_add_handler(http, "/login", _httpd_endpoint_login, NULL, task);
|
||||
|
||||
tf_http_add_handler(http, "/app/socket", _httpd_endpoint_app_socket, NULL, task);
|
||||
@ -2349,14 +2431,14 @@ void tf_httpd_register(JSContext* context)
|
||||
JS_SetPropertyStr(context, global, "httpd", httpd);
|
||||
JS_FreeValue(context, global);
|
||||
|
||||
if (http_port > 0 || out_http_port_file)
|
||||
if (http_port > 0 || *out_http_port_file)
|
||||
{
|
||||
httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t));
|
||||
*listener = (httpd_listener_t) { 0 };
|
||||
int assigned_port = tf_http_listen(http, http_port, NULL, _httpd_listener_cleanup, listener);
|
||||
tf_printf(CYAN "~😎 Tilde Friends" RESET " " YELLOW VERSION_NUMBER RESET " is now up at " MAGENTA "http://127.0.0.1:%d/" RESET ".\n", assigned_port);
|
||||
|
||||
if (out_http_port_file)
|
||||
if (*out_http_port_file)
|
||||
{
|
||||
const char* actual_http_port_file = tf_task_get_path_with_root(task, out_http_port_file);
|
||||
FILE* file = fopen(actual_http_port_file, "wb");
|
||||
@ -2393,6 +2475,4 @@ void tf_httpd_register(JSContext* context)
|
||||
tf_free((char*)private_key);
|
||||
}
|
||||
}
|
||||
|
||||
tf_free((void*)out_http_port_file);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ void tf_run_thread_start(const char* zip_path);
|
||||
|
||||
static void _start_initial_load(WKWebView* web_view)
|
||||
{
|
||||
[web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:12345/"]]];
|
||||
[web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:12345/login/auto"]]];
|
||||
}
|
||||
|
||||
@implementation ViewController : UIViewController
|
||||
|
@ -7,6 +7,6 @@
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>EDVXQ27EB5</string>
|
||||
<key>get-task-allow</key>
|
||||
<true/>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -2,34 +2,86 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>tildefriends</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Tilde Friends</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>tildefriends</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.unprompted.tildefriends</string>
|
||||
<key>CFBundleResourceSpecification</key>
|
||||
<string>ResourceRules.plist</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>tildefriends</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.28</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>9</string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>iphoneos</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Tilde Friends</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>tildefriends.png</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>14.0</string>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UILaunchScreen</key>
|
||||
<dict>
|
||||
<key>UIImageName</key>
|
||||
<string>tildefriends.png</string>
|
||||
</dict>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>24D70</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>22C146</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>18.2</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>22C146</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>iphoneos18.2</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1620</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>16C5032a</string>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~iphone</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon60x60</string>
|
||||
</array>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
BIN
src/ios/distribution.mobileprovision
Normal file
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/100.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/1024.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/114.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/120.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/144.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/152.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/167.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/180.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/20.png
Normal file
After Width: | Height: | Size: 974 B |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/29.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/40.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/50.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/57.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/58.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/60.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/72.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/76.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/80.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
src/ios/icons/Assets.xcassets/AppIcon.appiconset/87.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
@ -0,0 +1 @@
|
||||
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]}
|
BIN
src/ios/icons/appstore.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
src/ios/icons/playstore.png
Normal file
After Width: | Height: | Size: 56 KiB |
56
src/main.c
@ -1057,7 +1057,7 @@ static int _tf_command_get_profile(const char* file, int argc, char* argv[])
|
||||
sqlite3_close(db);
|
||||
tf_free((void*)profile);
|
||||
tf_free((void*)default_db_path);
|
||||
return profile != NULL;
|
||||
return profile != NULL ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static int _tf_command_get_contacts(const char* file, int argc, char* argv[])
|
||||
@ -1217,9 +1217,6 @@ typedef struct tf_run_args_t
|
||||
{
|
||||
const char* script;
|
||||
const char* network_key;
|
||||
int ssb_port;
|
||||
int http_port;
|
||||
int https_port;
|
||||
const char* db_path;
|
||||
int count;
|
||||
const char* args;
|
||||
@ -1244,9 +1241,6 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
|
||||
tf_printf("setting zip path to %s\n", args->zip);
|
||||
tf_task_set_zip_path(task, args->zip);
|
||||
tf_task_set_ssb_network_key(task, args->network_key);
|
||||
tf_task_set_ssb_port(task, args->ssb_port ? args->ssb_port + index : 0);
|
||||
tf_task_set_http_port(task, args->http_port ? args->http_port + index : 0);
|
||||
tf_task_set_https_port(task, args->https_port ? args->https_port + index : 0);
|
||||
tf_task_set_args(task, args->args);
|
||||
tf_task_set_one_proc(task, args->one_proc);
|
||||
const char* db_path = args->db_path;
|
||||
@ -1301,7 +1295,16 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
|
||||
tf_task_activate(task);
|
||||
tf_ssb_set_verbose(tf_task_get_ssb(task), args->verbose);
|
||||
tf_ssb_start_periodic(tf_task_get_ssb(task));
|
||||
if (args->http_port || args->https_port)
|
||||
tf_ssb_t* ssb = tf_task_get_ssb(task);
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
int64_t http_port = 0;
|
||||
int64_t https_port = 0;
|
||||
char out_http_port_file[512] = "";
|
||||
tf_ssb_db_get_global_setting_int64(db, "http_port", &http_port);
|
||||
tf_ssb_db_get_global_setting_int64(db, "https_port", &https_port);
|
||||
tf_ssb_db_get_global_setting_string(db, "out_http_port_file", out_http_port_file, sizeof(out_http_port_file));
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
if (http_port || https_port || *out_http_port_file)
|
||||
{
|
||||
if (args->zip)
|
||||
{
|
||||
@ -1417,9 +1420,6 @@ 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,
|
||||
.http_port = 12345,
|
||||
.https_port = 12346,
|
||||
.ssb_port = 8008,
|
||||
.db_path = default_db_path,
|
||||
};
|
||||
bool show_usage = false;
|
||||
@ -1436,10 +1436,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
{
|
||||
static const struct option k_options[] = {
|
||||
{ "script", required_argument, NULL, 's' },
|
||||
{ "ssb-port", required_argument, NULL, 'b' },
|
||||
{ "ssb-network-key", required_argument, NULL, 'k' },
|
||||
{ "http-port", required_argument, NULL, 'p' },
|
||||
{ "https-port", required_argument, NULL, 'q' },
|
||||
{ "db-path", required_argument, NULL, 'd' },
|
||||
{ "count", required_argument, NULL, 'n' },
|
||||
{ "args", required_argument, NULL, 'a' },
|
||||
@ -1448,7 +1445,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
};
|
||||
int c = getopt_long(argc, argv, "s:b:k:p:q:d:n:a:oz:vh", k_options, NULL);
|
||||
int c = getopt_long(argc, argv, "s:k:d:n:a:oz:vh", k_options, NULL);
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
@ -1467,15 +1464,6 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
case 'k':
|
||||
args.network_key = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
args.ssb_port = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
args.http_port = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
args.https_port = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
args.db_path = optarg;
|
||||
break;
|
||||
@ -1502,13 +1490,11 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
tf_printf("\n%s run [options]\n\n", file);
|
||||
tf_printf("options\n");
|
||||
tf_printf(" -s, --script script Script to run (default: core/core.js).\n");
|
||||
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", 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");
|
||||
tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true (note: these are persisted to the database).\n");
|
||||
tf_util_document_settings(" ");
|
||||
tf_printf(" -o, --one-proc Run everything in one process (unsafely!).\n");
|
||||
tf_printf(" -z, --zip path Zip archive from which to load files.\n");
|
||||
tf_printf(" -v, --verbose Log raw messages.\n");
|
||||
@ -1744,18 +1730,15 @@ static jint _tf_server_main(JNIEnv* env, jobject this_object, jstring files_dir,
|
||||
tf_printf("uv_chdir: %s\n", uv_strerror(result));
|
||||
}
|
||||
|
||||
size_t port_file_arg_length = strlen(out_port_file) + strlen("out_http_port_file=") + 1;
|
||||
char* port_file_arg = alloca(port_file_arg_length);
|
||||
snprintf(port_file_arg, port_file_arg_length, "out_http_port_file=%s", out_port_file);
|
||||
size_t args_length = strlen(out_port_file) + strlen("--args=http_port=0,out_http_port_file=") + 1;
|
||||
char* args_buffer = alloca(args_length);
|
||||
snprintf(args_buffer, args_length, "--args=http_port=0,out_http_port_file=%s", out_port_file);
|
||||
|
||||
const char* args[] = {
|
||||
"run",
|
||||
"-z",
|
||||
apk,
|
||||
"-a",
|
||||
port_file_arg,
|
||||
"-p",
|
||||
"0",
|
||||
args_buffer,
|
||||
};
|
||||
|
||||
tf_task_set_android_service_callbacks(_tf_service_start, _tf_service_stop);
|
||||
@ -1847,9 +1830,6 @@ void tf_run_thread_start(const char* zip_path)
|
||||
tf_run_thread_data_t* data = tf_malloc(sizeof(tf_run_thread_data_t));
|
||||
tf_run_args_t args = {
|
||||
.count = 1,
|
||||
.http_port = 12345,
|
||||
.https_port = 12346,
|
||||
.ssb_port = 8008,
|
||||
.db_path = "db.sqlite",
|
||||
.one_proc = true,
|
||||
.zip = zip_path,
|
||||
|
69
src/ssb.c
@ -746,13 +746,16 @@ static bool _tf_ssb_connection_get_request_callback(
|
||||
*out_name = request->name;
|
||||
}
|
||||
request->last_active = uv_now(connection->ssb->loop);
|
||||
if (connection->flags & k_tf_ssb_connect_flag_one_shot)
|
||||
if (tf_ssb_connection_is_connected(connection) && !tf_ssb_connection_is_closing(connection) && !tf_ssb_is_shutting_down(tf_ssb_connection_get_ssb(connection)))
|
||||
{
|
||||
uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0);
|
||||
}
|
||||
if (uv_timer_get_due_in(&connection->ssb->request_activity_timer) == 0)
|
||||
{
|
||||
uv_timer_start(&connection->ssb->request_activity_timer, _tf_ssb_request_activity_timer, k_rpc_active_ms, 0);
|
||||
if ((connection->flags & k_tf_ssb_connect_flag_one_shot))
|
||||
{
|
||||
uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0);
|
||||
}
|
||||
if (uv_timer_get_due_in(&connection->ssb->request_activity_timer) == 0)
|
||||
{
|
||||
uv_timer_start(&connection->ssb->request_activity_timer, _tf_ssb_request_activity_timer, k_rpc_active_ms, 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -799,13 +802,16 @@ void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t requ
|
||||
connection->requests_count++;
|
||||
connection->ssb->request_count++;
|
||||
}
|
||||
if (connection->flags & k_tf_ssb_connect_flag_one_shot)
|
||||
if (tf_ssb_connection_is_connected(connection) && !tf_ssb_connection_is_closing(connection) && !tf_ssb_is_shutting_down(tf_ssb_connection_get_ssb(connection)))
|
||||
{
|
||||
uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0);
|
||||
}
|
||||
if (uv_timer_get_due_in(&connection->ssb->request_activity_timer) == 0)
|
||||
{
|
||||
uv_timer_start(&connection->ssb->request_activity_timer, _tf_ssb_request_activity_timer, k_rpc_active_ms, 0);
|
||||
if (connection->flags & k_tf_ssb_connect_flag_one_shot)
|
||||
{
|
||||
uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0);
|
||||
}
|
||||
if (uv_timer_get_due_in(&connection->ssb->request_activity_timer) == 0)
|
||||
{
|
||||
uv_timer_start(&connection->ssb->request_activity_timer, _tf_ssb_request_activity_timer, k_rpc_active_ms, 0);
|
||||
}
|
||||
}
|
||||
_tf_ssb_notify_connections_changed(connection->ssb, k_tf_ssb_change_update, connection);
|
||||
connection->last_notified_active = now_ms;
|
||||
@ -1404,7 +1410,7 @@ tf_ssb_connection_t* tf_ssb_connection_get_tunnel(tf_ssb_connection_t* connectio
|
||||
return connection ? connection->tunnel_connection : NULL;
|
||||
}
|
||||
|
||||
static bool _tf_ssb_is_already_connected(tf_ssb_t* ssb, uint8_t* id, tf_ssb_connection_t* ignore_connection)
|
||||
static tf_ssb_connection_t* _tf_ssb_is_already_connected(tf_ssb_t* ssb, uint8_t* id, tf_ssb_connection_t* ignore_connection)
|
||||
{
|
||||
for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next)
|
||||
{
|
||||
@ -1412,15 +1418,15 @@ static bool _tf_ssb_is_already_connected(tf_ssb_t* ssb, uint8_t* id, tf_ssb_conn
|
||||
{
|
||||
if (memcmp(connection->serverpub, id, k_id_bin_len) == 0)
|
||||
{
|
||||
return true;
|
||||
return connection;
|
||||
}
|
||||
else if (memcmp(ssb->pub, id, k_id_bin_len) == 0)
|
||||
{
|
||||
return true;
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_is_account_a_stranger_work(tf_ssb_connection_t* connection, void* user_data)
|
||||
@ -1436,19 +1442,26 @@ static void _tf_ssb_connection_is_account_a_stranger_work(tf_ssb_connection_t* c
|
||||
{
|
||||
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);
|
||||
connection->is_stranger = !tf_ssb_db_has_invite(db, id);
|
||||
if (connection->is_stranger)
|
||||
{
|
||||
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);
|
||||
for (int i = 0; identities[i]; i++)
|
||||
if (connection->is_stranger)
|
||||
{
|
||||
if (strcmp(id, identities[i]) == 0)
|
||||
const char** identities = tf_ssb_db_get_all_visible_identities(ssb, replication_hops);
|
||||
for (int i = 0; identities[i]; i++)
|
||||
{
|
||||
connection->is_stranger = false;
|
||||
break;
|
||||
if (strcmp(id, identities[i]) == 0)
|
||||
{
|
||||
connection->is_stranger = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tf_free((void*)identities);
|
||||
}
|
||||
tf_free((void*)identities);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1538,14 +1551,14 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
|
||||
}
|
||||
uint8_t* detached_signature_A = m;
|
||||
|
||||
if (_tf_ssb_is_already_connected(connection->ssb, m + 64, connection))
|
||||
tf_ssb_connection_t* other_connection = NULL;
|
||||
while ((other_connection = _tf_ssb_is_already_connected(connection->ssb, m + 64, connection)))
|
||||
{
|
||||
char id_base64[k_id_base64_len] = { 0 };
|
||||
tf_ssb_id_bin_to_str(id_base64, sizeof(id_base64), m + 64);
|
||||
char reason[256];
|
||||
snprintf(reason, sizeof(reason), "already connected: %s\n", id_base64);
|
||||
tf_ssb_connection_close(connection, reason);
|
||||
return;
|
||||
snprintf(reason, sizeof(reason), "Replacing connection: %s\n", id_base64);
|
||||
tf_ssb_connection_close(other_connection, reason);
|
||||
}
|
||||
|
||||
memcpy(connection->serverpub, m + 64, sizeof(connection->serverpub));
|
||||
@ -1990,7 +2003,7 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch
|
||||
if (!connection->is_closing)
|
||||
{
|
||||
connection->is_closing = true;
|
||||
uv_timer_start(&connection->linger_timer, _tf_ssb_connection_linger_timer, 5000, 0);
|
||||
uv_timer_start(&connection->linger_timer, _tf_ssb_connection_linger_timer, ssb->shutting_down ? 0 : 5000, 0);
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_update, connection);
|
||||
}
|
||||
if (connection->connect_callback)
|
||||
|
86
src/ssb.db.c
@ -1277,7 +1277,7 @@ static int _following_compare(const void* a, const void* b)
|
||||
|
||||
static bool _has_following_entry(const char* id, following_t** list, int count)
|
||||
{
|
||||
return count ? bsearch(id, list, count, sizeof(following_t*), _following_compare) != 0 : false;
|
||||
return count ? bsearch(id, list, count, sizeof(following_t*), _following_compare) != NULL : false;
|
||||
}
|
||||
|
||||
static bool _add_following_entry(following_t*** list, int* count, following_t* add)
|
||||
@ -1432,21 +1432,22 @@ static void _populate_follows_and_blocks(tf_ssb_t* ssb, following_t* entry, foll
|
||||
static void _get_following(
|
||||
tf_ssb_t* ssb, following_t* entry, following_t*** following, int* following_count, int depth, int max_depth, block_node_t* active_blocks, bool include_blocks)
|
||||
{
|
||||
int old_depth = entry->depth;
|
||||
entry->depth = tf_min(depth, entry->depth);
|
||||
if (depth < max_depth && !entry->populated && !_is_blocked_by_active_blocks(entry->id, active_blocks))
|
||||
if (depth < max_depth && depth < old_depth)
|
||||
{
|
||||
entry->populated = true;
|
||||
_populate_follows_and_blocks(ssb, entry, following, following_count, active_blocks, include_blocks);
|
||||
|
||||
if (depth < max_depth)
|
||||
if (!_is_blocked_by_active_blocks(entry->id, active_blocks))
|
||||
{
|
||||
if (!entry->populated)
|
||||
{
|
||||
entry->populated = true;
|
||||
_populate_follows_and_blocks(ssb, entry, following, following_count, active_blocks, include_blocks);
|
||||
}
|
||||
|
||||
block_node_t blocks = { .entry = entry, .parent = active_blocks };
|
||||
for (int i = 0; i < entry->following_count; i++)
|
||||
{
|
||||
if (!_has_following_entry(entry->following[i]->id, entry->blocking, entry->blocking_count))
|
||||
{
|
||||
_get_following(ssb, entry->following[i], following, following_count, depth + 1, max_depth, &blocks, include_blocks);
|
||||
}
|
||||
_get_following(ssb, entry->following[i], following, following_count, depth + 1, max_depth, &blocks, include_blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2126,6 +2127,51 @@ bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* ou
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_set_global_setting_from_string(sqlite3* db, const char* name, char* value)
|
||||
{
|
||||
tf_setting_kind_t kind = tf_util_get_global_setting_kind(name);
|
||||
if (kind == k_kind_unknown)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db,
|
||||
"INSERT INTO properties (id, key, value) VALUES ('core', 'settings', json_object(?1, ?2)) ON CONFLICT DO UPDATE SET value = json_set(value, '$.' || ?1, ?2)", -1,
|
||||
&statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
bool bound = false;
|
||||
switch (kind)
|
||||
{
|
||||
case k_kind_bool:
|
||||
bound = sqlite3_bind_int(statement, 2, value && (strcmp(value, "true") == 0 || atoi(value))) == SQLITE_OK;
|
||||
break;
|
||||
case k_kind_int:
|
||||
bound = sqlite3_bind_int(statement, 2, atoi(value)) == SQLITE_OK;
|
||||
break;
|
||||
case k_kind_string:
|
||||
bound = sqlite3_bind_text(statement, 2, value, -1, NULL) == SQLITE_OK;
|
||||
break;
|
||||
case k_kind_unknown:
|
||||
break;
|
||||
}
|
||||
if (bound && sqlite3_step(statement) == SQLITE_DONE)
|
||||
{
|
||||
result = sqlite3_changes(db) != 0;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* tf_ssb_db_get_profile(sqlite3* db, const char* id)
|
||||
{
|
||||
const char* result = NULL;
|
||||
@ -2255,8 +2301,8 @@ bool tf_ssb_db_use_invite(sqlite3* db, const char* id)
|
||||
{
|
||||
bool used = false;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "UPDATE invites SET use_count = use_count - 1 WHERE invite_public_key = ? AND expires >= ? AND (use_count > 0 OR use_count = -1)", -1, &statement,
|
||||
NULL) == SQLITE_OK)
|
||||
if (sqlite3_prepare(db, "UPDATE invites SET use_count = use_count - 1 WHERE invite_public_key = ? AND (expires < 0 OR expires >= ?) AND (use_count > 0 OR use_count = -1)", -1,
|
||||
&statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, (int64_t)time(NULL)) == SQLITE_OK)
|
||||
{
|
||||
@ -2269,3 +2315,19 @@ bool tf_ssb_db_use_invite(sqlite3* db, const char* id)
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_has_invite(sqlite3* db, const char* id)
|
||||
{
|
||||
bool has = false;
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT COUNT(*) FROM invites WHERE invite_public_key = ? AND (expires < 0 OR expires >= ?) AND (use_count > 0 OR use_count = -1)", -1, &statement,
|
||||
NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, (int64_t)time(NULL)) == SQLITE_OK)
|
||||
{
|
||||
has = sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_int(statement, 0) > 0;
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
return has;
|
||||
}
|
||||
|
17
src/ssb.db.h
@ -486,6 +486,15 @@ bool tf_ssb_db_get_global_setting_int64(sqlite3* db, const char* name, int64_t*
|
||||
*/
|
||||
bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size);
|
||||
|
||||
/**
|
||||
** Set a global setting from a string representation of its value.
|
||||
** @param db The database.
|
||||
** @param name The setting name.
|
||||
** @param value The settinv value.
|
||||
** @return true if the setting was set.
|
||||
*/
|
||||
bool tf_ssb_db_set_global_setting_from_string(sqlite3* db, const char* name, char* value);
|
||||
|
||||
/**
|
||||
** Get the latest profile information for the given identity.
|
||||
** @param db The database.
|
||||
@ -547,4 +556,12 @@ bool tf_ssb_db_is_account_familiar(sqlite3* db, const char* id, int depth);
|
||||
*/
|
||||
int tf_ssb_sqlite_authorizer(void* user_data, int action_code, const char* arg0, const char* arg1, const char* arg2, const char* arg3);
|
||||
|
||||
/**
|
||||
** Check if we have an invite for the given account.
|
||||
** @param db The database.
|
||||
** @param id The invite public key to check.
|
||||
** @return true If we have a valid invite for the address.
|
||||
*/
|
||||
bool tf_ssb_db_has_invite(sqlite3* db, const char* id);
|
||||
|
||||
/** @} */
|
||||
|
@ -2357,6 +2357,12 @@ static JSValue _tf_ssb_set_user_permission(JSContext* context, JSValueConst this
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_port(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
return JS_NewInt32(context, tf_ssb_server_get_port(ssb));
|
||||
}
|
||||
|
||||
void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
|
||||
{
|
||||
JS_NewClassID(&_tf_ssb_classId);
|
||||
@ -2403,6 +2409,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
|
||||
JS_SetPropertyStr(context, object, "createTunnel", JS_NewCFunction(context, _tf_ssb_createTunnel, "createTunnel", 3));
|
||||
JS_SetPropertyStr(context, object, "following", JS_NewCFunction(context, _tf_ssb_following, "following", 2));
|
||||
JS_SetPropertyStr(context, object, "sync", JS_NewCFunction(context, _tf_ssb_sync, "sync", 0));
|
||||
JS_SetPropertyStr(context, object, "port", JS_NewCFunction(context, _tf_ssb_port, "port", 0));
|
||||
/* Write. */
|
||||
JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1));
|
||||
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 1));
|
||||
|
@ -83,6 +83,19 @@ static void _tf_ssb_rpc_blobs_get_after_work(tf_ssb_connection_t* connection, in
|
||||
tf_free(work);
|
||||
}
|
||||
|
||||
static void _tf_ssb_blobs_get_callback(tf_ssb_connection_t* connection, bool skip, void* user_data)
|
||||
{
|
||||
blobs_get_work_t* work = user_data;
|
||||
if (!skip)
|
||||
{
|
||||
tf_ssb_connection_run_work(connection, _tf_ssb_rpc_blobs_get_work, _tf_ssb_rpc_blobs_get_after_work, work);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tf_ssb_rpc_blobs_get_after_work(connection, -1, work);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_rpc_blobs_get(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
if (flags & k_ssb_rpc_flag_end_error)
|
||||
@ -122,7 +135,7 @@ static void _tf_ssb_rpc_blobs_get(tf_ssb_connection_t* connection, uint8_t flags
|
||||
.request_number = request_number,
|
||||
};
|
||||
snprintf(work->id, sizeof(work->id), "%s", id);
|
||||
tf_ssb_connection_run_work(connection, _tf_ssb_rpc_blobs_get_work, _tf_ssb_rpc_blobs_get_after_work, work);
|
||||
tf_ssb_connection_schedule_idle(connection, id, _tf_ssb_blobs_get_callback, work);
|
||||
|
||||
JS_FreeCString(context, id);
|
||||
JS_FreeValue(context, arg);
|
||||
@ -1101,6 +1114,23 @@ static void _tf_ssb_rpc_ebt_replicate_resend_clock(tf_ssb_connection_t* connecti
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_rpc_ebt_schedule_send_clock(tf_ssb_connection_t* connection)
|
||||
{
|
||||
tf_ssb_ebt_t* ebt = tf_ssb_connection_get_ebt(connection);
|
||||
int pending = tf_ssb_ebt_get_send_clock_pending(ebt) + 1;
|
||||
tf_ssb_ebt_set_send_clock_pending(ebt, pending);
|
||||
if (pending == 1)
|
||||
{
|
||||
resend_clock_t* resend = tf_malloc(sizeof(resend_clock_t));
|
||||
*resend = (resend_clock_t) {
|
||||
.connection = connection,
|
||||
.request_number = -tf_ssb_connection_get_ebt_request_number(connection),
|
||||
.pending = pending,
|
||||
};
|
||||
tf_ssb_connection_schedule_idle(connection, "ebt.clock", _tf_ssb_rpc_ebt_replicate_resend_clock, resend);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_rpc_ebt_replicate(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
||||
@ -1140,18 +1170,7 @@ static void _tf_ssb_rpc_ebt_replicate(tf_ssb_connection_t* connection, uint8_t f
|
||||
|
||||
if (resend_clock && tf_ssb_connection_is_connected(connection) && !tf_ssb_is_shutting_down(tf_ssb_connection_get_ssb(connection)) && !tf_ssb_connection_is_closing(connection))
|
||||
{
|
||||
int pending = tf_ssb_ebt_get_send_clock_pending(ebt) + 1;
|
||||
tf_ssb_ebt_set_send_clock_pending(ebt, pending);
|
||||
if (pending == 1)
|
||||
{
|
||||
resend_clock_t* resend = tf_malloc(sizeof(resend_clock_t));
|
||||
*resend = (resend_clock_t) {
|
||||
.connection = connection,
|
||||
.request_number = request_number,
|
||||
.pending = pending,
|
||||
};
|
||||
tf_ssb_connection_schedule_idle(connection, "ebt.clock", _tf_ssb_rpc_ebt_replicate_resend_clock, resend);
|
||||
}
|
||||
_tf_ssb_rpc_ebt_schedule_send_clock(connection);
|
||||
}
|
||||
JS_FreeValue(context, name);
|
||||
JS_FreeValue(context, author);
|
||||
@ -1775,10 +1794,16 @@ static void _tf_ssb_invite_use_message_store_callback(const char* id, bool verif
|
||||
{
|
||||
invite_t* work = user_data;
|
||||
tf_ssb_connection_t* connection = work->connection;
|
||||
if (verified && is_new)
|
||||
if (verified && is_new && tf_ssb_connection_is_connected(connection) && !tf_ssb_connection_is_closing(connection))
|
||||
{
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL, (const uint8_t*)work->message, strlen(work->message), NULL, NULL, NULL);
|
||||
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
JSValue payload = JS_NewObject(context);
|
||||
JSValue message = JS_ParseJSON(context, work->message, strlen(work->message), NULL);
|
||||
JS_SetPropertyStr(context, payload, "key", JS_NewString(context, id));
|
||||
JS_SetPropertyStr(context, payload, "value", message);
|
||||
tf_ssb_connection_rpc_send_json(connection, 0, -work->request_number, NULL, payload, NULL, NULL, NULL);
|
||||
JS_FreeValue(context, payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1822,6 +1847,7 @@ static void _tf_ssb_rpc_invite_use_after_work(tf_ssb_connection_t* connection, i
|
||||
{
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection, k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error, -work->request_number, NULL, (const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
|
||||
tf_ssb_connection_close(connection, "Invite not accepted.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1848,10 +1874,25 @@ static void _tf_ssb_rpc_invite_use(tf_ssb_connection_t* connection, uint8_t flag
|
||||
tf_ssb_connection_run_work(connection, _tf_ssb_rpc_invite_use_work, _tf_ssb_rpc_invite_use_after_work, work);
|
||||
}
|
||||
|
||||
static void _tf_ssb_rpc_message_added_callback(tf_ssb_t* ssb, const char* id, void* user_data)
|
||||
{
|
||||
tf_ssb_connection_t* connections[256];
|
||||
int count = tf_ssb_get_connections(ssb, connections, tf_countof(connections));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
tf_ssb_connection_t* connection = connections[i];
|
||||
if (tf_ssb_connection_is_connected(connection) && !tf_ssb_is_shutting_down(tf_ssb_connection_get_ssb(connection)) && !tf_ssb_connection_is_closing(connection))
|
||||
{
|
||||
_tf_ssb_rpc_ebt_schedule_send_clock(connections[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tf_ssb_rpc_register(tf_ssb_t* ssb)
|
||||
{
|
||||
tf_ssb_add_connections_changed_callback(ssb, _tf_ssb_rpc_connections_changed_callback, NULL, NULL);
|
||||
tf_ssb_add_broadcasts_changed_callback(ssb, _tf_ssb_rpc_broadcasts_changed_callback, NULL, NULL);
|
||||
tf_ssb_add_message_added_callback(ssb, _tf_ssb_rpc_message_added_callback, NULL, NULL);
|
||||
tf_ssb_add_rpc_callback(ssb, "gossip.ping", _tf_ssb_rpc_gossip_ping, NULL, NULL); /* DUPLEX */
|
||||
tf_ssb_add_rpc_callback(ssb, "blobs.get", _tf_ssb_rpc_blobs_get, NULL, NULL); /* SOURCE */
|
||||
tf_ssb_add_rpc_callback(ssb, "blobs.has", _tf_ssb_rpc_blobs_has, NULL, NULL); /* ASYNC */
|
||||
|
@ -913,7 +913,7 @@ static void _write_file(const char* path, const char* contents)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
#define TEST_ARGS " --ssb-port=0 --http-port=0 --https-port=0"
|
||||
#define TEST_ARGS " --args=ssb_port=0,http_port=0,https_port=0"
|
||||
|
||||
void tf_ssb_test_encrypt(const tf_test_options_t* options)
|
||||
{
|
||||
|
100
src/task.c
@ -9,6 +9,7 @@
|
||||
#include "packetstream.h"
|
||||
#include "serialize.h"
|
||||
#include "socket.js.h"
|
||||
#include "ssb.db.h"
|
||||
#include "ssb.h"
|
||||
#include "ssb.js.h"
|
||||
#include "taskstub.js.h"
|
||||
@ -154,9 +155,6 @@ typedef struct _tf_task_t
|
||||
JSValue _loadedFiles;
|
||||
|
||||
const char* _network_key;
|
||||
int _ssb_port;
|
||||
int _http_port;
|
||||
int _https_port;
|
||||
char _db_path[256];
|
||||
char _zip_path[256];
|
||||
char _root_path[256];
|
||||
@ -398,6 +396,7 @@ static JSValue _tf_task_exit(JSContext* context, JSValueConst this_val, int argc
|
||||
int exitCode = 0;
|
||||
JS_ToInt32(task->_context, &exitCode, argv[0]);
|
||||
tf_trace_end(task->_trace);
|
||||
tf_printf("EXIT %d\n", exitCode);
|
||||
exit(exitCode);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
@ -1680,38 +1679,6 @@ void tf_task_activate(tf_task_t* task)
|
||||
JS_DefinePropertyGetSet(context, global, atom, JS_NewCFunction(context, _tf_task_get_parent, "parent", 0), JS_UNDEFINED, 0);
|
||||
JS_FreeAtom(context, atom);
|
||||
|
||||
JSValue tildefriends = JS_NewObject(context);
|
||||
JSValue args = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, tildefriends, "args", args);
|
||||
if (task->_args)
|
||||
{
|
||||
char* saveptr = NULL;
|
||||
char* copy = tf_strdup(task->_args);
|
||||
char* start = copy;
|
||||
while (true)
|
||||
{
|
||||
char* assignment = strtok_r(start, ",", &saveptr);
|
||||
start = NULL;
|
||||
if (!assignment)
|
||||
{
|
||||
break;
|
||||
}
|
||||
char* equals = strchr(assignment, '=');
|
||||
if (equals)
|
||||
{
|
||||
*equals = '\0';
|
||||
JS_SetPropertyStr(context, args, assignment, JS_NewString(context, equals + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("Assignment missing '=': %s.\n", assignment);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
tf_free(copy);
|
||||
}
|
||||
JS_SetPropertyStr(context, global, "tildefriends", tildefriends);
|
||||
|
||||
task->_trace = tf_trace_create();
|
||||
if (task->_trusted)
|
||||
{
|
||||
@ -1732,23 +1699,45 @@ void tf_task_activate(tf_task_t* task)
|
||||
tf_ssb_register(context, task->_ssb);
|
||||
tf_ssb_set_hitch_callback(task->_ssb, _tf_task_record_hitch, task);
|
||||
|
||||
int actual_ssb_port = task->_ssb_port;
|
||||
if (task->_args)
|
||||
{
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(task->_ssb);
|
||||
char* saveptr = NULL;
|
||||
char* copy = tf_strdup(task->_args);
|
||||
char* start = copy;
|
||||
while (true)
|
||||
{
|
||||
char* assignment = strtok_r(start, ",", &saveptr);
|
||||
start = NULL;
|
||||
if (!assignment)
|
||||
{
|
||||
break;
|
||||
}
|
||||
char* equals = strchr(assignment, '=');
|
||||
if (equals)
|
||||
{
|
||||
*equals = '\0';
|
||||
tf_ssb_db_set_global_setting_from_string(db, assignment, equals + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("Assignment missing '=': %s.\n", assignment);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
tf_free(copy);
|
||||
tf_ssb_release_db_writer(task->_ssb, db);
|
||||
}
|
||||
|
||||
if (task->_ssb_port)
|
||||
int64_t ssb_port = 0;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(task->_ssb);
|
||||
tf_ssb_db_get_global_setting_int64(db, "ssb_port", &ssb_port);
|
||||
tf_ssb_release_db_reader(task->_ssb, db);
|
||||
if (ssb_port)
|
||||
{
|
||||
tf_ssb_broadcast_listener_start(task->_ssb, false);
|
||||
tf_ssb_broadcast_sender_start(task->_ssb);
|
||||
actual_ssb_port = tf_ssb_server_open(task->_ssb, task->_ssb_port);
|
||||
}
|
||||
|
||||
JS_SetPropertyStr(context, tildefriends, "ssb_port", JS_NewInt32(context, actual_ssb_port));
|
||||
if (task->_http_port)
|
||||
{
|
||||
JS_SetPropertyStr(context, tildefriends, "http_port", JS_NewInt32(context, task->_http_port));
|
||||
}
|
||||
if (task->_https_port)
|
||||
{
|
||||
JS_SetPropertyStr(context, tildefriends, "https_port", JS_NewInt32(context, task->_https_port));
|
||||
tf_ssb_server_open(task->_ssb, ssb_port);
|
||||
}
|
||||
|
||||
JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0));
|
||||
@ -1999,21 +1988,6 @@ void tf_task_set_ssb_network_key(tf_task_t* task, const char* network_key)
|
||||
task->_network_key = network_key;
|
||||
}
|
||||
|
||||
void tf_task_set_ssb_port(tf_task_t* task, int port)
|
||||
{
|
||||
task->_ssb_port = port;
|
||||
}
|
||||
|
||||
void tf_task_set_http_port(tf_task_t* task, int port)
|
||||
{
|
||||
task->_http_port = port;
|
||||
}
|
||||
|
||||
void tf_task_set_https_port(tf_task_t* task, int port)
|
||||
{
|
||||
task->_https_port = port;
|
||||
}
|
||||
|
||||
void tf_task_set_db_path(tf_task_t* task, const char* db_path)
|
||||
{
|
||||
snprintf(task->_db_path, sizeof(task->_db_path), "%s", db_path);
|
||||
|
21
src/task.h
@ -76,27 +76,6 @@ void tf_task_configure_from_fd(tf_task_t* task, int fd);
|
||||
*/
|
||||
void tf_task_set_ssb_network_key(tf_task_t* task, const char* network_key);
|
||||
|
||||
/**
|
||||
** Set the port number on which to run an SSB secure handshake server.
|
||||
** @param task The task.
|
||||
** @param port The port number or 0 to disable.
|
||||
*/
|
||||
void tf_task_set_ssb_port(tf_task_t* task, int port);
|
||||
|
||||
/**
|
||||
** Set the port number on which to run an HTTP server.
|
||||
** @param task The task.
|
||||
** @param port The port number of 0 to disable.
|
||||
*/
|
||||
void tf_task_set_http_port(tf_task_t* task, int port);
|
||||
|
||||
/**
|
||||
** Set the port number on which to run an HTTPS server.
|
||||
** @param task The task.
|
||||
** @param port The port number of 0 to disable.
|
||||
*/
|
||||
void tf_task_set_https_port(tf_task_t* task, int port);
|
||||
|
||||
/**
|
||||
** Set the path to the SQLite database.
|
||||
** @param task The task.
|
||||
|
11
src/tests.c
@ -32,7 +32,7 @@
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#define TEST_ARGS " --ssb-port=0 --http-port=0 --https-port=0"
|
||||
#define TEST_ARGS " --args=ssb_port=0,http_port=0,https_port=0"
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
static void _write_file(const char* path, const char* contents)
|
||||
@ -311,7 +311,7 @@ static void _test_database(const tf_test_options_t* options)
|
||||
" print('Expected but did not find: ' + JSON.stringify(expected));\n"
|
||||
" exit(4);\n"
|
||||
" }\n"
|
||||
" if (JSON.stringify(await databases.list('%')) != '[\"testdb\"]') {\n"
|
||||
" if (JSON.stringify(await databases.list('%')) != '[\"core\",\"testdb\"]') {\n"
|
||||
" exit(7);\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
@ -864,9 +864,6 @@ static void _test_httpd(const tf_test_options_t* options)
|
||||
uv_loop_init(&loop);
|
||||
|
||||
unlink("out/test_db0.sqlite");
|
||||
char command[256];
|
||||
snprintf(command, sizeof(command), "%s run -b 0 --db-path=out/test_db0.sqlite" TEST_ARGS, options->exe_path);
|
||||
|
||||
uv_stdio_container_t stdio[] = {
|
||||
[STDIN_FILENO] = { .flags = UV_IGNORE },
|
||||
[STDOUT_FILENO] = { .flags = UV_INHERIT_FD },
|
||||
@ -876,7 +873,7 @@ static void _test_httpd(const tf_test_options_t* options)
|
||||
uv_spawn(&loop, &process,
|
||||
&(uv_process_options_t) {
|
||||
.file = options->exe_path,
|
||||
.args = (char*[]) { (char*)options->exe_path, "run", "-b0", "--db-path=out/test_db0.sqlite", "--http-port=8080", "--https-port=0", NULL },
|
||||
.args = (char*[]) { (char*)options->exe_path, "run", "--db-path=out/test_db0.sqlite", "--args=ssb_port=0,http_port=8080,https_port=0", NULL },
|
||||
.stdio_count = sizeof(stdio) / sizeof(*stdio),
|
||||
.stdio = stdio,
|
||||
});
|
||||
@ -960,7 +957,7 @@ static void _test_auto(const tf_test_options_t* options)
|
||||
unlink("out/selenium.sqlite-shm");
|
||||
unlink("out/selenium.sqlite-wal");
|
||||
|
||||
char* args[] = { executable, "run", "-d", "out/selenium.sqlite", "-b", "0", "-p", "8888", NULL };
|
||||
char* args[] = { executable, "run", "-d", "out/selenium.sqlite", "-a", "ssb_port=0,http_port=8888", NULL };
|
||||
|
||||
uv_stdio_container_t io[3] = {
|
||||
{ .flags = UV_INHERIT_FD },
|
||||
|
@ -314,13 +314,6 @@ static JSValue _util_parseHttpResponse(JSContext* context, JSValueConst this_val
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef enum _value_kind_t
|
||||
{
|
||||
k_kind_bool,
|
||||
k_kind_int,
|
||||
k_kind_string,
|
||||
} value_kind_t;
|
||||
|
||||
static const char* k_kind_name[] = {
|
||||
[k_kind_bool] = "bool",
|
||||
[k_kind_int] = "int",
|
||||
@ -329,7 +322,7 @@ static const char* k_kind_name[] = {
|
||||
|
||||
typedef struct _setting_value_t
|
||||
{
|
||||
value_kind_t kind;
|
||||
tf_setting_kind_t kind;
|
||||
union
|
||||
{
|
||||
bool bool_value;
|
||||
@ -348,6 +341,13 @@ typedef struct _setting_t
|
||||
|
||||
static const setting_t k_settings[] = {
|
||||
{ .name = "code_of_conduct", .type = "textarea", .description = "Code of conduct presented at sign-in.", .default_value = { .kind = k_kind_string, .string_value = NULL } },
|
||||
{ .name = "ssb_port",
|
||||
.type = "integer",
|
||||
.description = "Port on which to listen for SSB secure handshake connections.",
|
||||
.default_value = { .kind = k_kind_int, .int_value = 8008 } },
|
||||
{ .name = "http_port", .type = "integer", .description = "Port on which to listen for HTTP connections.", .default_value = { .kind = k_kind_int, .int_value = 12345 } },
|
||||
{ .name = "https_port", .type = "integer", .description = "Port on which to listen for secure HTTP connections.", .default_value = { .kind = k_kind_int, .int_value = 0 } },
|
||||
{ .name = "out_http_port_file", .type = "hidden", .description = "File to which to write bound HTTP port.", .default_value = { .kind = k_kind_string, .string_value = NULL } },
|
||||
{ .name = "blob_fetch_age_seconds",
|
||||
.type = "integer",
|
||||
.description = "Only blobs mentioned more recently than this age will be automatically fetched.",
|
||||
@ -393,21 +393,31 @@ static const setting_t k_settings[] = {
|
||||
.type = "boolean",
|
||||
.description = "Whether connections are accepted from accounts that aren't in the replication range or otherwise already known.",
|
||||
.default_value = { .kind = k_kind_bool, .bool_value = true } },
|
||||
{ .name = "autologin", .type = "boolean", .description = "Whether mobile autologin is supported.", .default_value = { .kind = k_kind_bool, .bool_value = TF_IS_MOBILE != 0 } },
|
||||
};
|
||||
|
||||
static const setting_t* _util_get_setting(const char* name, value_kind_t kind)
|
||||
static const setting_t* _util_get_setting(const char* name, tf_setting_kind_t kind)
|
||||
{
|
||||
for (int i = 0; i < tf_countof(k_settings); i++)
|
||||
{
|
||||
if (strcmp(k_settings[i].name, name) == 0 && k_settings[i].default_value.kind == kind)
|
||||
if (strcmp(k_settings[i].name, name) == 0 && (kind == k_kind_unknown || k_settings[i].default_value.kind == kind))
|
||||
{
|
||||
return &k_settings[i];
|
||||
}
|
||||
}
|
||||
tf_printf("Did not find global setting of type %s: %s.\n", k_kind_name[kind], name);
|
||||
if (kind != k_kind_unknown)
|
||||
{
|
||||
tf_printf("Did not find global setting of type %s: %s.\n", k_kind_name[kind], name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tf_setting_kind_t tf_util_get_global_setting_kind(const char* name)
|
||||
{
|
||||
const setting_t* setting = _util_get_setting(name, k_kind_unknown);
|
||||
return setting ? setting->default_value.kind : k_kind_unknown;
|
||||
}
|
||||
|
||||
bool tf_util_get_default_global_setting_bool(const char* name)
|
||||
{
|
||||
const setting_t* setting = _util_get_setting(name, k_kind_bool);
|
||||
@ -446,12 +456,41 @@ static JSValue _util_defaultGlobalSettings(JSContext* context, JSValueConst this
|
||||
JS_SetPropertyStr(
|
||||
context, entry, "default_value", k_settings[i].default_value.string_value ? JS_NewString(context, k_settings[i].default_value.string_value) : JS_UNDEFINED);
|
||||
break;
|
||||
case k_kind_unknown:
|
||||
break;
|
||||
}
|
||||
JS_SetPropertyStr(context, settings, k_settings[i].name, entry);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
void tf_util_document_settings(const char* line_prefix)
|
||||
{
|
||||
char buffer[32];
|
||||
for (int i = 0; i < tf_countof(k_settings); i++)
|
||||
{
|
||||
const char* default_value = NULL;
|
||||
const char* quote = "";
|
||||
switch (k_settings[i].default_value.kind)
|
||||
{
|
||||
case k_kind_bool:
|
||||
default_value = k_settings[i].default_value.bool_value ? "true" : "false";
|
||||
break;
|
||||
case k_kind_string:
|
||||
quote = "\"";
|
||||
default_value = k_settings[i].default_value.string_value ? k_settings[i].default_value.string_value : "";
|
||||
break;
|
||||
case k_kind_int:
|
||||
snprintf(buffer, sizeof(buffer), "%d", k_settings[i].default_value.int_value);
|
||||
default_value = buffer;
|
||||
break;
|
||||
case k_kind_unknown:
|
||||
break;
|
||||
}
|
||||
tf_printf("%s%s (default: %s%s%s): %s\n", line_prefix, k_settings[i].name, quote, default_value, quote, k_settings[i].description);
|
||||
}
|
||||
}
|
||||
|
||||
JSValue tf_util_new_uint8_array(JSContext* context, const uint8_t* data, size_t size)
|
||||
{
|
||||
JSValue array_buffer = JS_NewArrayBufferCopy(context, data, size);
|
||||
@ -639,3 +678,8 @@ int tf_util_backtrace(void** buffer, int count)
|
||||
return backtrace(buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool tf_util_is_mobile()
|
||||
{
|
||||
return TF_IS_MOBILE != 0;
|
||||
}
|
||||
|
@ -10,6 +10,17 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
** Type of a setting.
|
||||
*/
|
||||
typedef enum _tf_setting_kind_t
|
||||
{
|
||||
k_kind_unknown,
|
||||
k_kind_bool,
|
||||
k_kind_int,
|
||||
k_kind_string,
|
||||
} tf_setting_kind_t;
|
||||
|
||||
/** An event loop. */
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
@ -188,10 +199,29 @@ bool tf_util_get_default_global_setting_bool(const char* name);
|
||||
int tf_util_get_default_global_setting_int(const char* name);
|
||||
|
||||
/**
|
||||
** Get teh default value of a global setting as a string.
|
||||
** Get the default value of a global setting as a string.
|
||||
** @param name The setting name.
|
||||
** @return The default value.
|
||||
*/
|
||||
const char* tf_util_get_default_global_setting_string(const char* name);
|
||||
|
||||
/**
|
||||
** Get the expected kind of a global setting.
|
||||
** @param name The setting name.
|
||||
** @return The setting kind or unknown if nonexistent.
|
||||
*/
|
||||
tf_setting_kind_t tf_util_get_global_setting_kind(const char* name);
|
||||
|
||||
/**
|
||||
** Log documentation for the available settings.
|
||||
** @param line_prefix Text to prefix each line with."
|
||||
*/
|
||||
void tf_util_document_settings(const char* line_prefix);
|
||||
|
||||
/**
|
||||
** Check if the app is running on a mobile device.
|
||||
** @return true for iPhone/Android, false otherwise.
|
||||
*/
|
||||
bool tf_util_is_mobile();
|
||||
|
||||
/** @} */
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define VERSION_NUMBER "0.0.28-wip"
|
||||
#define VERSION_NUMBER "0.0.28"
|
||||
#define VERSION_NAME "This program kills fascists."
|
||||
|
@ -25,6 +25,7 @@ def fix_title(entry):
|
||||
return entry.title.split('\n')[0]
|
||||
|
||||
def get_entries():
|
||||
seen = set()
|
||||
results = []
|
||||
for name, url in k_feeds.items():
|
||||
feed = feedparser.parse(url)
|
||||
@ -41,9 +42,13 @@ def get_entries():
|
||||
continue
|
||||
if entry.summary.startswith('<a href='):
|
||||
for m in re.findall(r'<a href="(.*?)">.*?</a>$\s*^([^\n]+)$', entry.summary, re.S | re.M):
|
||||
results.append((time.mktime(entry.get('updated_parsed')), name, m[0], m[1]))
|
||||
if not m[0] in seen:
|
||||
seen.add(m[0])
|
||||
results.append((time.mktime(entry.get('updated_parsed')), name, m[0], m[1]))
|
||||
else:
|
||||
results.append((time.mktime(entry.get('updated_parsed')), name, entry.link, entry.title.split('\n')[0]))
|
||||
if not entry.link in seen:
|
||||
seen.add(entry.link)
|
||||
results.append((time.mktime(entry.get('updated_parsed')), name, entry.link, entry.title.split('\n')[0]))
|
||||
results.sort()
|
||||
results.reverse()
|
||||
return results
|
||||
|
14
tools/ios-distribute
Normal file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash -e
|
||||
rm -rfv out/tildefriends-iosrelease.app out/Payload out/tildefriends.ipa
|
||||
make iosrelease-app
|
||||
cp src/ios/tildefriends.png out/tildefriends-iosrelease.app/tildefriends.png
|
||||
cp src/ios/icons/Assets.car out/tildefriends-iosrelease.app/
|
||||
cp src/ios/icons/ios/icon-72.png out/tildefriends-iosrelease.app/
|
||||
cp src/ios/icons/ios/icon-120.png out/tildefriends-iosrelease.app/
|
||||
cp src/ios/icons/ios/icon-152.png out/tildefriends-iosrelease.app/
|
||||
cp src/ios/distribution.mobileprovision out/tildefriends-iosrelease.app/embedded.mobileprovision
|
||||
xcrun -sdk iphoneos codesign -f -s 'Apple Distribution: Cory McWilliams' --entitlements src/ios/Entitlements.plist --generate-entitlement-der out/tildefriends-iosrelease.app
|
||||
mkdir -p out/Payload/tildefriends.app
|
||||
cp -avR out/tildefriends-iosrelease.app/* out/Payload/tildefriends.app/
|
||||
cd out; zip -r tildefriends.ipa Payload; cd ..
|
||||
xcrun -sdk iphoneos altool --upload-app -f out/tildefriends.ipa -t ios -u $(cat .keys/altool-user) -p $(cat .keys/altool-password)
|