49 Commits

Author SHA1 Message Date
eccdbf29ab build: Move built openssl to out where it belongs.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 24m26s
2025-02-02 14:39:36 -05:00
28d181f8bc build: Fix.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-02-02 14:28:40 -05:00
d386daf2ff build: Rename the macosdebug/macosrelease targets to debug/release. #101
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 19m44s
2025-02-02 14:08:27 -05:00
0c1e116c1e build: More concise build context.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 24m17s
2025-02-02 13:04:22 -05:00
bb0ed67827 httpd: Move starting the http server into C.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 24m27s
2025-02-02 12:27:06 -05:00
b111d06851 ssb: I think this fixes missing a range in some circumstances.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 25m8s
2025-02-02 10:14:14 -05:00
79388845ea build: Remove the dependency on zsign on macos.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 23m4s
2025-02-01 22:30:35 -05:00
99faef2e77 build: valid bash?
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 24m8s
2025-02-01 19:59:18 -05:00
21fffbfe10 build: Valid yaml?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 7s
2025-02-01 19:58:28 -05:00
64fb9f0c2a build: +zlib. 2025-02-01 19:55:02 -05:00
a42e0bef2c build: The journey continues.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 21m24s
2025-02-01 19:15:50 -05:00
45a09006e1 build: Build zsign for the sake of the ios build.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 20m54s
2025-02-01 18:52:20 -05:00
240484be4c build: Fix docker build, and speed it up a bit?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 23m44s
2025-02-01 18:19:44 -05:00
22f4d115e3 build: Finally ios is happy. Now let's un-break docker.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 4m33s
2025-02-01 18:07:56 -05:00
32920e0e5d build: Still trying to get ios to build on this worker.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 4m40s
2025-02-01 17:58:55 -05:00
f03a5918d1 build: Apparently we need file.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 23m11s
2025-02-01 17:19:28 -05:00
dd1870b52a build: Nope, OpenSSL assumes this directory is SDKs, so it is SDKs.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 21m38s
2025-02-01 16:51:10 -05:00
f0c1a8f98f build: Minor cleanup and a disappointing workaround for iOS cross-compiling toolchain issues I don't understand.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 20m9s
2025-02-01 16:25:23 -05:00
0c181d7e7c build: Maybe maybe maybe.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 26m48s
2025-02-01 14:55:26 -05:00
e3dc0e833a build: Some docs say the syntax is like this.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 18m29s
2025-02-01 14:17:15 -05:00
6de875edea build: Print some configuration that is confusing me.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-02-01 13:38:52 -05:00
986a55173f build: I think CI can cross-build ios.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 22m0s
2025-02-01 12:50:31 -05:00
59c8cabf02 build: fix?
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 21m55s
2025-02-01 11:39:58 -05:00
a33b9fab07 build: I misunderstood these makefile conditionals.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 2m56s
2025-02-01 11:32:01 -05:00
f8a725e1e7 build: ios dist is conditional on having the SDK.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 19m27s
2025-02-01 11:02:21 -05:00
b3ab3af01b build: dist uses curl.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 20m23s
2025-02-01 10:10:59 -05:00
79f9463e56 build: Can I get CI to artifact the dist files?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 20m34s
2025-02-01 09:49:49 -05:00
4257b2ed51 ssb: Unknown message types need some padding.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-02-01 09:41:22 -05:00
6488ab60ec build: Docker build no longer needs libssl installed.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-02-01 09:40:34 -05:00
18bd3dfcf9 build: So close. +docker?
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 20m55s
2025-02-01 09:00:06 -05:00
ec114e160d build: on node:23-bookworm-slim
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 19m35s
2025-02-01 08:34:42 -05:00
de033af18f build: Oh, now I can use a normal image, maybe with a more reasonable compiler? Also, update libbacktrace.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 1m20s
2025-02-01 08:31:33 -05:00
e971c6fcb7 build: Go home, -fanalyze, you're confused.
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 15m38s
2025-02-01 08:14:11 -05:00
d3c465391c build: +zip
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 15m57s
2025-01-31 21:47:24 -05:00
f1fa19593d build: Better system OpenSSL logic?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 3m50s
2025-01-31 21:43:18 -05:00
60b6f9c73e build: +build-essential
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 3m14s
2025-01-31 21:32:17 -05:00
55b95ddecb build: +make
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 2m40s
2025-01-31 21:27:14 -05:00
0800a251b2 build: +unzip
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 3m15s
2025-01-31 21:23:22 -05:00
82cf7a80eb build: Maybe I don't need sudo here?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 1m46s
2025-01-31 21:19:22 -05:00
379f3d12eb build: Maybe we can just install the git we need?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 4s
2025-01-31 21:15:19 -05:00
e52972d4d4 build: Version shenanigans?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 10s
2025-01-31 21:11:35 -05:00
1a0ca4dec2 build: I guess this requires node?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 12s
2025-01-31 21:08:57 -05:00
0bac9d8d5a build: Can I specify the image we build on like this?
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 10s
2025-01-31 21:07:01 -05:00
a9608363c5 core: Don't actually start the http server unless we've specified a port or are asking for a port to be determined and written to file. 2025-01-31 20:57:59 -05:00
f1a2c5ae8e ssb: Silence some persistent broadcast noise.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 20m40s
2025-01-31 20:45:35 -05:00
192a81ede7 core: As an experiment, handle running from a subdirectory (generally out/debug or out/release, since people tend to do that). Remove unused File.stat().
Some checks failed
Build Tilde Friends / Build-All (push) Failing after 4m49s
2025-01-31 20:37:14 -05:00
916aa5abbd cli: Fix create_invite's expire option. 2025-01-30 22:16:06 -05:00
d4a5cc6eee build: Let's start work on 0.0.28.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 19m44s
2025-01-30 12:46:52 -05:00
d19605cc8d build: Fixes nix. Now everybody is happy.
Some checks are pending
Build Tilde Friends / Build-All (push) Waiting to run
2025-01-30 12:35:43 -05:00
27 changed files with 508 additions and 410 deletions

View File

@ -1,4 +1,3 @@
.svn
db.sqlite
out/**/*.o
out/**/*.d
.git
db.sqlite*
out/

View File

@ -6,15 +6,38 @@ jobs:
Build-All:
runs-on: ubuntu-latest
container:
valid_volumes: ['/opt/keys']
image: node:23-bookworm-slim
valid_volumes:
- '/opt/keys'
- '/opt/deps'
volumes:
- /opt/keys:/opt/keys
- /opt/deps:/opt/deps
steps:
- run: >
apt update && apt install -y \
build-essential \
clang \
cmake \
curl \
docker.io \
doxygen \
file \
gcc-aarch64-linux-gnu \
git \
graphviz \
libgpgme11 \
libssl-dev \
mingw-w64 \
unzip \
zip \
zlib1g-dev
- name: check out code
uses: actions/checkout@v4
with:
submodules: true
- run: ln -s /opt/keys .keys
- run: ln -s /opt/deps/ios_toolchain deps/ios_toolchain
- name: Setup JDK
uses: actions/setup-java@v3
with:
@ -24,9 +47,8 @@ jobs:
uses: android-actions/setup-android@v3
with:
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11 gcc-aarch64-linux-gnu
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs
- run: docker build .
- run: DOCKER_BUILDKIT=1 docker build .
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all dist docs
- uses: actions/upload-artifact@v3
with:
path: |
@ -35,3 +57,7 @@ jobs:
out/tildefriends-x86_64.AppImage
out/release/tildefriends.standalone
out/armrelease/tildefriends.standalone
- uses: actions/upload-artifact@v3
with:
name: dist
path: dist/*

3
.gitmodules vendored
View File

@ -29,3 +29,6 @@
[submodule "docs"]
path = docs
url = https://dev.tildefriends.net/cory/tildefriends.wiki.git
[submodule "deps/zsign"]
path = deps/zsign
url = https://github.com/zhlynn/zsign.git

View File

@ -1,19 +1,16 @@
FROM bitnami/minideb:bullseye AS build
FROM bitnami/minideb:bookworm AS build
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc \
libc6-dev \
libssl-dev \
perl \
make
COPY . /app
RUN make -C /app -j $(nproc) release
FROM bitnami/minideb:bullseye
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libssl1.1
FROM bitnami/minideb:bookworm
COPY --from=build /app/out/release/tildefriends /app/out/release/tildefriends
COPY --from=build /app/apps /app/apps

View File

@ -16,8 +16,8 @@ MAKEFLAGS += --no-builtin-rules
## LD := Linker.
## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 32
VERSION_NUMBER := 0.0.27
VERSION_CODE := 33
VERSION_NUMBER := 0.0.28-wip
VERSION_NAME := This program kills fascists.
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3480000.zip
@ -33,22 +33,22 @@ UNAME_M := $(shell uname -m)
ANDROID_SDK ?= ~/Android/Sdk
BUNDLETOOL = out/bundletool.jar
HAVE_WIN := 0
HAVE_CROSS_AARCH64 := 0
USE_SYSTEM_SSL := 0
HAVE_WIN :=
HAVE_CROSS_AARCH64 :=
USE_SYSTEM_SSL :=
export SOURCE_DATE_EPOCH=1
export TZ=UTC
ifeq ($(UNAME_S),Darwin)
BUILD_TYPES := macosdebug macosrelease iosdebug iosrelease iossimdebug iossimrelease
BUILD_TYPES := debug release iosdebug iosrelease iossimdebug iossimrelease
else ifeq ($(UNAME_S),Linux)
BUILD_TYPES := debug release
HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1,0)
HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1,0)
HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1,0)
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_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,0)
HAVE_CROSS_AARCH64 = $(if $(shell which aarch64-linux-gnu-gcc),1)
endif
else ifeq ($(UNAME_S),Haiku)
BUILD_TYPES := debug release
@ -64,12 +64,15 @@ CFLAGS += \
LDFLAGS += \
-lexecinfo \
-lc++abi
HAVE_ANDROID := 0
HAVE_LINUX_IOS := 0
HAVE_ANDROID :=
HAVE_LINUX_IOS :=
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))
CFLAGS += \
-std=gnu11 \
-Wall \
@ -137,12 +140,16 @@ ifeq ($(HAVE_CROSS_AARCH64),1)
BUILD_TYPES += armdebug armrelease
endif
LINUX_TARGETS := \
HOST_TARGETS := \
out/debug/tildefriends \
out/release/tildefriends
ifeq ($(UNAME_S),Darwin)
MACOS_TARGETS := \
out/macosdebug/tildefriends \
out/macosrelease/tildefriends
out/debug/tildefriends \
out/release/tildefriends
else
MACOS_TARGETS :=
endif
IOS_TARGETS := \
out/iosdebug/tildefriends \
out/iosrelease/tildefriends
@ -170,7 +177,6 @@ DEBUG_TARGETS := \
out/windebug/tildefriends.exe \
out/iosdebug/tildefriends \
out/iossimdebug/tildefriends \
out/macosdebug/tildefriends \
out/androiddebug/tildefriends \
out/androiddebug-armv7a/tildefriends \
out/androiddebug-x86_64/tildefriends \
@ -181,7 +187,6 @@ RELEASE_TARGETS := \
out/winrelease/tildefriends.exe \
out/iosrelease/tildefriends \
out/iossimrelease/tildefriends \
out/macosrelease/tildefriends \
out/androidrelease/tildefriends \
out/androidrelease-armv7a/tildefriends \
out/androidrelease-x86_64/tildefriends \
@ -222,25 +227,25 @@ $(WINDOWS_TARGETS): CFLAGS += \
-D_WIN32_WINNT=0x0A00 \
-DWINVER=0x0A00 \
-DNTDDI_VERSION=NTDDI_WIN10 \
-Ideps/openssl/mingw64/usr/local/include
-Iout/openssl/mingw64/usr/local/include
$(WINDOWS_TARGETS): LDFLAGS += \
-static \
-lm \
-Ldeps/openssl/mingw64/usr/local/lib
-Lout/openssl/mingw64/usr/local/lib
$(AARCH64_TARGETS): CC = aarch64-linux-gnu-gcc
$(AARCH64_TARGETS): AS = $(CC)
$(AARCH64_TARGETS): CFLAGS += -Ideps/openssl/Linux/aarch64/usr/local/include
$(AARCH64_TARGETS): LDFLAGS += -Ldeps/openssl/Linux/aarch64/usr/local/lib
$(AARCH64_TARGETS): CFLAGS += -Iout/openssl/Linux/aarch64/usr/local/include
$(AARCH64_TARGETS): LDFLAGS += -Lout/openssl/Linux/aarch64/usr/local/lib
ifeq ($(UNAME_S),Darwin)
$(MACOS_TARGETS): CC = xcrun clang
$(HOST_TARGETS): CC = xcrun clang
$(IOS_TARGETS): IOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path)
$(IOS_TARGETS): CC = xcrun --sdk iphoneos clang -isysroot $(IOS_SYSROOT) -arch arm64
$(IOSSIM_TARGETS): IOSSIM_SYSROOT := $(shell xcrun --sdk iphonesimulator --show-sdk-path)
$(IOSSIM_TARGETS): CC = xcrun --sdk iphonesimulator clang -isysroot $(IOSSIM_SYSROOT) -arch x86_64
else ifeq ($(UNAME_S),Linux)
$(IOS_TARGETS): CFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk -arch arm64
$(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 deps/ios_toolchain/target/bin/arm-apple-darwin11-clang
$(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
endif
$(ANDROID_X86_64_TARGETS): ANDROID_NDK_TARGET_TRIPLE := x86_64-linux-android
$(ANDROID_X86_TARGETS): ANDROID_NDK_TARGET_TRIPLE := i686-linux-android
@ -251,30 +256,30 @@ $(ANDROID_TARGETS): AS = $(CC)
$(ANDROID_TARGETS): CFLAGS += \
-target $(ANDROID_NDK_TARGET_TRIPLE)$(ANDROID_MIN_SDK_VERSION) \
-Wno-unknown-warning-option
$(ANDROID_ARMV7A_TARGETS): CFLAGS += -Ideps/openssl/android/armeabi-v7a/usr/local/include
$(ANDROID_ARMV7A_TARGETS): LDFLAGS += -Ldeps/openssl/android/armeabi-v7a/usr/local/lib
$(ANDROID_ARM64_TARGETS): CFLAGS += -Ideps/openssl/android/arm64-v8a/usr/local/include
$(ANDROID_ARM64_TARGETS): LDFLAGS += -Ldeps/openssl/android/arm64-v8a/usr/local/lib
$(ANDROID_X86_TARGETS): CFLAGS += -Ideps/openssl/android/x86/usr/local/include
$(ANDROID_ARMV7A_TARGETS): CFLAGS += -Iout/openssl/android/armeabi-v7a/usr/local/include
$(ANDROID_ARMV7A_TARGETS): LDFLAGS += -Lout/openssl/android/armeabi-v7a/usr/local/lib
$(ANDROID_ARM64_TARGETS): CFLAGS += -Iout/openssl/android/arm64-v8a/usr/local/include
$(ANDROID_ARM64_TARGETS): LDFLAGS += -Lout/openssl/android/arm64-v8a/usr/local/lib
$(ANDROID_X86_TARGETS): CFLAGS += -Iout/openssl/android/x86/usr/local/include
$(ANDROID_X86_TARGETS): CFLAGS += -Wno-atomic-alignment
$(ANDROID_X86_TARGETS): LDFLAGS += -Ldeps/openssl/android/x86/usr/local/lib
$(ANDROID_X86_64_TARGETS): CFLAGS += -Ideps/openssl/android/x86_64/usr/local/include
$(ANDROID_X86_64_TARGETS): LDFLAGS += -Ldeps/openssl/android/x86_64/usr/local/lib
$(ANDROID_X86_TARGETS): LDFLAGS += -Lout/openssl/android/x86/usr/local/lib
$(ANDROID_X86_64_TARGETS): CFLAGS += -Iout/openssl/android/x86_64/usr/local/include
$(ANDROID_X86_64_TARGETS): LDFLAGS += -Lout/openssl/android/x86_64/usr/local/lib
$(NONMACOS_TARGETS): CFLAGS += -Wno-cast-function-type
$(DEADSTRIP_TARGETS): LDFLAGS += -Wl,--gc-sections
$(IOS_TARGETS): CFLAGS += -miphoneos-version-min=9.0
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0
ifeq ($(UNAME_S),Darwin)
$(IOS_TARGETS): CFLAGS += -Ideps/openssl/ios/ios64-xcrun/usr/local/include
$(IOS_TARGETS): LDFLAGS += -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib
$(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 += -Ideps/openssl/$(UNAME_S)/ios64-cross/usr/local/include
$(IOS_TARGETS): LDFLAGS += -Ldeps/openssl/$(UNAME_S)/ios64-cross/usr/local/lib
$(IOS_TARGETS): CFLAGS += -Iout/openssl/$(UNAME_S)/ios64-cross/usr/local/include
$(IOS_TARGETS): LDFLAGS += -Lout/openssl/$(UNAME_S)/ios64-cross/usr/local/lib
endif
$(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include
$(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib
$(LINUX_TARGETS) $(MACOS_TARGETS): CFLAGS += -Ideps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/include
$(LINUX_TARGETS) $(MACOS_TARGETS): LDFLAGS += -Ldeps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib
$(IOSSIM_TARGETS): CFLAGS += -Iout/openssl/ios/iossimulator-xcrun/usr/local/include
$(IOSSIM_TARGETS): LDFLAGS += -Lout/openssl/ios/iossimulator-xcrun/usr/local/lib
$(HOST_TARGETS): CFLAGS += -Iout/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/include
$(HOST_TARGETS): LDFLAGS += -Lout/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib
ifeq ($(UNAME_M),x86_64)
ifeq ($(UNAME_S),Linux)
@ -293,13 +298,14 @@ endif
get_objs = \
$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
$(foreach build_type,debug release armdebug armrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
$(foreach build_type,windebug winrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_win))))) \
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androiddebug-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_android))))) \
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_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,macosdebug macosrelease iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos))))) \
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_ios))))) \
$(foreach build_type,androiddebug-x86 androidrelease-x86,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_x86)))))
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease,$(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))))))
APP_SOURCES := $(wildcard src/*.c)
APP_SOURCES_ios := $(wildcard src/*.m)
@ -321,10 +327,12 @@ $(APP_OBJS): CFLAGS += \
-Ideps/valgrind \
-Wdouble-promotion \
-Werror
ifneq ($(UNAME_S),Darwin)
ifeq ($(UNAME_M),x86_64)
$(filter-out $(BUILD_DIR)/android% $(BUILD_DIR)/macos% $(BUILD_DIR)/ios%,$(APP_OBJS)): CFLAGS += \
$(filter-out $(BUILD_DIR)/android% $(BUILD_DIR)/ios%,$(APP_OBJS)): CFLAGS += \
-fanalyzer
endif
endif
ARES_SOURCES := \
deps/c-ares/src/lib/ares_addrinfo2hostent.c \
@ -757,12 +765,12 @@ $(MINIUNZIP_OBJS): CFLAGS += \
LDFLAGS += \
-pthread \
-lm
$(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS): LDFLAGS += \
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS): LDFLAGS += \
-lssl \
-lcrypto
ifneq ($(UNAME_S),Haiku)
ifneq ($(UNAME_S),OpenBSD)
debug release $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
-ldl
endif
endif
@ -795,27 +803,15 @@ $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
##
## Common targets:
##
debug: ## Build a debug executable for the current platform.
release: ## Build a release executable for the current platform.
all: $(BUILD_TYPES) ## Build all targets that appear possible to build on this machine.
debug: ## Build a debug executable for the current host platform.
release: ## Build a release executable for the current host platform.
armdebug: ## Cross-compile aarch64 debug on Linux.
armrelease: ## Cross-compile aarch64 release on Linux.
all: $(BUILD_TYPES) ## Build all targets that appear possible to build on this machine.
unix: debug release ## Build all UNIX targets.
win: windebug winrelease ## Build all Windows targets.
windebug: ## Cross-compile a debug win32 executable on Linux.
winrelease: ## Cross-compile a release win32 executable on Linux.
.PHONY: all win unix
##
## Windows targets:
##
windebug: ## Build a debug win32 executable.
winrelease: ## Build a release win32 executable.
##
## MacOS targets:
##
macosdebug: ## Build a MacOS debug executable.
macosrelease: ## Build a MacOS release executable.
ALL_APP_OBJS := \
$(APP_OBJS) \
$(ARES_OBJS) \
@ -1093,12 +1089,17 @@ out/data.zip: $(RAW_FILES)
@echo [zip] $@
@zip -u $@ -q -9 $(RAW_FILES)
out/tildefriends-%.app/tildefriends: out/%/tildefriends out/tildefriends-%.app/Info.plist out/tildefriends-%.app/tildefriends.png out/data.zip
out/zsign_build/zsign: $(wildcard deps/zsign/*.cpp deps/zsign/*.h deps/zsign/*.txt deps/zsign/common/*)
@echo [cmake] $@
@cmake -B out/zsign_build deps/zsign
@cmake --build out/zsign_build
out/tildefriends-%.app/tildefriends: out/%/tildefriends out/tildefriends-%.app/Info.plist out/tildefriends-%.app/tildefriends.png out/data.zip $(if $(HAVE_LINUX_IOS),out/zsign_build/zsign)
@mkdir -p $(dir $@)
@cp -v $< $@
@cp -v $(filter-out out/zsign%,$<) $@
@cp -v out/data.zip $(@D)/
ifeq ($(HAVE_LINUX_IOS),1)
@zsign -q -k .keys/apple.p12 -f -m src/ios/embedded.mobileprovision $(realpath $(dir $@))
@out/zsign_build/zsign -q -k .keys/apple.p12 -f -m src/ios/embedded.mobileprovision $(realpath $(dir $@))
endif
.SECONDARY:
out/tildefriends-%.ipa: out/tildefriends-ios%.app/tildefriends
@ -1136,26 +1137,28 @@ iossimdebuggo: out/tildefriends-iossimdebug.app/tildefriends ## Build, install,
xcrun simctl launch booted com.unprompted.tildefriends
.PHONY: iossimdebuggo
ANDROID_DEPS := deps/openssl/android/arm64-v8a/usr/local/lib/libssl.a
ANDROID_DEPS := out/openssl/android/arm64-v8a/usr/local/lib/libssl.a
$(ANDROID_DEPS):
+@ANDROID_NDK_ROOT=$(ANDROID_NDK) tools/ssl-android
$(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS)
ifeq ($(UNAME_S),Linux)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
ifneq ($(USE_SYSTEM_SSL),1)
LOCAL_DEPS := out/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@/usr/bin/env bash tools/ssl-local
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): $(if $(USE_SYSTEM_SSL), , | $(LOCAL_DEPS))
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
endif
ifeq ($(HAVE_CROSS_AARCH64),1)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/aarch64/usr/local/lib/libssl.a
LOCAL_DEPS := out/openssl/$(UNAME_S)/aarch64/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@OPTIONS="--cross-compile-prefix=aarch64-linux-gnu-" BUILD_TARGET=aarch64 tools/ssl-local
$(filter $(BUILD_DIR)/armdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/armrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
endif
ifeq ($(HAVE_LINUX_IOS),1)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/ios64-cross/usr/local/lib/libssl.a
LOCAL_DEPS := out/openssl/$(UNAME_S)/ios64-cross/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@PATH=deps/ios_toolchain/target/bin:$$PATH \
BUILD_TARGET=ios64-cross \
@ -1171,21 +1174,21 @@ endif
endif
ifeq ($(UNAME_S),Darwin)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
LOCAL_DEPS := out/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@tools/ssl-local
$(filter $(BUILD_DIR)/macosdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/macosrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
endif
ifeq ($(HAVE_WIN),1)
WINDOWS_DEPS := deps/openssl/mingw64/usr/local/lib/libssl.a
WINDOWS_DEPS := out/openssl/mingw64/usr/local/lib/libssl.a
$(WINDOWS_DEPS):
+@tools/ssl-mingw64
$(filter $(BUILD_DIR)/win%,$(APP_OBJS)): | $(WINDOWS_DEPS)
endif
ifeq ($(UNAME_S),Darwin)
IOS_DEPS := deps/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
IOS_DEPS := out/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
$(IOS_DEPS):
+@tools/ssl-ios
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS)
@ -1259,7 +1262,6 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
--exclude=deps/libsodium/test \
--exclude=deps/libuv/docs \
--exclude=deps/libuv/test \
--exclude=deps/openssl \
--exclude=deps/speedscope/*.map \
--exclude=deps/sqlite/shell.c \
--exclude=deps/zlib/contrib/vstudio \
@ -1270,7 +1272,7 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
.PHONY: tarball
dist: ## Build versions of all distributables for release.
dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefriends.standalone.exe) out/TildeFriends-release.fdroid.apk appimage tarball out/release/tildefriends.standalone $(if $(HAVE_CROSS_AARCH64), out/armrelease/tildefriends.standalone)
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)
@mkdir -p dist/
@echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz"
@cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz
@ -1278,8 +1280,8 @@ dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefrien
@cp out/TildeFriends-x86-release.zopfli.apk dist/TildeFriends-x86-$(VERSION_NUMBER).apk
@echo "[cp] TildeFriends-arm-$(VERSION_NUMBER).apk"
@cp out/TildeFriends-arm-release.zopfli.apk dist/TildeFriends-arm-$(VERSION_NUMBER).apk
@echo "[cp] TildeFriends-$(VERSION_NUMBER).ipa"
@cp out/tildefriends-release.ipa dist/TildeFriends-$(VERSION_NUMBER).ipa
@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_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"

View File

@ -1,5 +1,5 @@
{
"type": "tildefriends-app",
"emoji": "🦀",
"previous": "&m5ZrkzoyAjv7AY6AukzVoWIyUFUL97uuDDWCtxCloAU=.sha256"
"previous": "&zAW/4XKD1wcsEM12bkzZD0V7Wyne3OPpQne2rtncxXM=.sha256"
}

View File

@ -775,7 +775,9 @@ class TfMessageElement extends LitElement {
}
} else {
return this.render_small_frame(
html`<div class="w3-container"><b>type</b>: ${content.type}</div>`
html`<div class="w3-container">
<p><b>type</b>: ${content.type}</p>
</div>`
);
}
} else if (typeof this.message.content == 'string') {

View File

@ -298,7 +298,7 @@ class TfTabNewsFeedElement extends LitElement {
let now = new Date().valueOf();
let start_time = now - 24 * 60 * 60 * 1000;
this.start_time = start_time;
this.time_range = [this.start_time, now + 24 * 60 * 60 * 1000];
this.time_range = [now + 24 * 60 * 60 * 1000, now + 24 * 60 * 60 * 1000];
messages = await this.fetch_messages(null, this.time_range[1]);
this.update_time_range_from_messages(
messages.filter((x) => x.timestamp < this.time_range[1])

View File

@ -81,9 +81,8 @@ App.prototype.send = function (message) {
* TODOC
* @param {*} request
* @param {*} response
* @param {*} client
*/
async function socket(request, response, client) {
exports.app_socket = async function socket(request, response) {
let process;
let options = {};
let credentials = await httpd.auth_query(request.headers);
@ -245,6 +244,6 @@ async function socket(request, response, client) {
};
response.upgrade(100, {});
}
};
export {socket, App};
export {App};

View File

@ -835,59 +835,4 @@ exports.callAppHandler = async function callAppHandler(
response.end(answer?.data);
};
/**
* TODOC
*/
loadSettings()
.then(function (settings) {
if (tildefriends.https_port && settings.http_redirect) {
httpd.set_http_redirect(settings.http_redirect);
}
httpd.all('/app/socket', app.socket);
let port = httpd.start(tildefriends.http_port);
if (tildefriends.args.out_http_port_file) {
print('Writing the port file.');
File.writeFile(
tildefriends.args.out_http_port_file,
port.toString() + '\n'
)
.then(function (r) {
print(
'Wrote the port file:',
tildefriends.args.out_http_port_file,
r
);
})
.catch(function () {
print('Failed to write the port file.');
});
}
if (tildefriends.https_port) {
async function start_tls() {
const kCertificatePath = 'data/httpd/certificate.pem';
const kPrivateKeyPath = 'data/httpd/privatekey.pem';
let privateKey;
let certificate;
try {
privateKey = utf8Decode(await File.readFile(kPrivateKeyPath));
certificate = utf8Decode(await File.readFile(kCertificatePath));
} catch (e) {
print(`TLS disabled (${e.message}).`);
return;
}
let context = new TlsContext();
context.setPrivateKey(privateKey);
context.setCertificate(certificate);
httpd.start(tildefriends.https_port, context);
}
start_tls();
}
})
.catch(function (error) {
print('Failed to load settings.');
printError({print: print}, error);
exit(1);
});
export {invoke, getProcessBlob};

View File

@ -21,14 +21,14 @@
}:
pkgs.stdenv.mkDerivation rec {
pname = "tildefriends";
version = "0.0.27";
version = "0.0.27.1";
src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net";
owner = "cory";
repo = "tildefriends";
rev = "v${version}";
hash = "sha256-NhoTBWYsWc206f1+M9haxHSJU6ZSGoP5nPStymAIyRk=";
hash = "sha256-3t1m9ZomQF3DteWyALJWrnCq0EAROEK8shKXh6Ao38c=";
fetchSubmodules = true;
};

1
deps/zsign vendored Submodule

Submodule deps/zsign added at d995d539ff

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends"
android:versionCode="32"
android:versionName="0.0.27">
android:versionCode="33"
android:versionName="0.0.28-wip">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application

View File

@ -18,21 +18,8 @@
static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
static JSValue _file_read_file_zip(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
static JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
static JSValue _file_stat_zip(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
static JSValue _file_write_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
static double _time_spec_to_double(const uv_timespec_t* time_spec);
static void _file_on_stat_complete(uv_fs_t* request);
typedef struct file_stat_t
{
void* _task;
JSContext* _context;
promiseid_t _promise;
uv_fs_t _request;
} file_stat_t;
typedef struct fs_req_t
{
uv_fs_t fs;
@ -45,12 +32,11 @@ void tf_file_register(JSContext* context)
{
JSValue global = JS_GetGlobalObject(context);
JSValue file = JS_NewObject(context);
void* task = JS_GetContextOpaque(context);
tf_task_t* task = JS_GetContextOpaque(context);
const char* zip = tf_task_get_zip_path(task);
JS_SetPropertyStr(context, global, "File", file);
JS_SetPropertyStr(context, file, "readFile", JS_NewCFunction(context, zip ? _file_read_file_zip : _file_read_file, "readFile", 1));
JS_SetPropertyStr(context, file, "writeFile", JS_NewCFunction(context, _file_write_file, "writeFile", 2));
JS_SetPropertyStr(context, file, "stat", JS_NewCFunction(context, zip ? _file_stat_zip : _file_stat, "stat", 1));
JS_FreeValue(context, global);
}
@ -123,7 +109,7 @@ static void _file_write_open_callback(uv_fs_t* req)
static JSValue _file_write_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
void* task = JS_GetContextOpaque(context);
tf_task_t* task = JS_GetContextOpaque(context);
const char* file_name = JS_ToCString(context, argv[0]);
size_t size;
@ -224,8 +210,9 @@ static void _file_read_open_callback(uv_fs_t* req)
static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
void* task = JS_GetContextOpaque(context);
tf_task_t* task = JS_GetContextOpaque(context);
const char* file_name = JS_ToCString(context, argv[0]);
const char* actual = tf_task_get_path_with_root(task, file_name);
promiseid_t promise = -1;
JSValue promise_value = tf_task_allocate_promise(task, &promise);
@ -239,7 +226,7 @@ static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int ar
.size = k_file_read_max,
};
memset(req + 1, 0, k_file_read_max);
int result = uv_fs_open(tf_task_get_loop(task), &req->fs, file_name, UV_FS_O_RDONLY, 0, _file_read_open_callback);
int result = uv_fs_open(tf_task_get_loop(task), &req->fs, actual, UV_FS_O_RDONLY, 0, _file_read_open_callback);
if (result < 0)
{
tf_task_reject_promise(task, promise, JS_ThrowInternalError(context, "Failed to open %s for read: %s", file_name, uv_strerror(result)));
@ -247,6 +234,7 @@ static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int ar
tf_free(req);
}
JS_FreeCString(context, file_name);
tf_free((char*)actual);
return promise_value;
}
@ -365,81 +353,6 @@ static JSValue _file_read_file_zip(JSContext* context, JSValueConst this_val, in
return promise_value;
}
static JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
void* task = JS_GetContextOpaque(context);
const char* path = JS_ToCString(context, argv[0]);
promiseid_t promise = -1;
JSValue promise_value = tf_task_allocate_promise(task, &promise);
file_stat_t* data = tf_malloc(sizeof(file_stat_t));
data->_task = task;
data->_promise = promise;
data->_request.data = data;
data->_context = context;
int result = uv_fs_stat(tf_task_get_loop(task), &data->_request, path, _file_on_stat_complete);
if (result)
{
tf_task_reject_promise(task, promise, JS_NewInt32(context, result));
uv_fs_req_cleanup(&data->_request);
tf_free(data);
}
JS_FreeCString(context, path);
return promise_value;
}
static JSValue _file_stat_zip(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
void* task = JS_GetContextOpaque(context);
promiseid_t promise = -1;
JSValue promise_value = tf_task_allocate_promise(task, &promise);
file_stat_t* data = tf_malloc(sizeof(file_stat_t));
data->_task = task;
data->_promise = promise;
data->_request.data = data;
data->_context = context;
/* Ignore the requested path and stat the zip itself. */
int result = uv_fs_stat(tf_task_get_loop(task), &data->_request, tf_task_get_zip_path(task), _file_on_stat_complete);
if (result)
{
tf_task_reject_promise(task, promise, JS_NewInt32(context, result));
uv_fs_req_cleanup(&data->_request);
tf_free(data);
}
return promise_value;
}
static double _time_spec_to_double(const uv_timespec_t* time_spec)
{
return time_spec->tv_sec + (double)(time_spec->tv_nsec) / 1e9;
}
static void _file_on_stat_complete(uv_fs_t* request)
{
file_stat_t* data = (file_stat_t*)(request->data);
JSContext* context = data->_context;
if (request->result)
{
tf_task_reject_promise(data->_task, data->_promise, JS_NewInt32(context, request->result));
}
else
{
JSValue result = JS_NewObject(context);
JS_SetPropertyStr(context, result, "mtime", JS_NewFloat64(context, _time_spec_to_double(&request->statbuf.st_mtim)));
JS_SetPropertyStr(context, result, "ctime", JS_NewFloat64(context, _time_spec_to_double(&request->statbuf.st_ctim)));
JS_SetPropertyStr(context, result, "atime", JS_NewFloat64(context, _time_spec_to_double(&request->statbuf.st_atim)));
JS_SetPropertyStr(context, result, "size", JS_NewFloat64(context, request->statbuf.st_size));
tf_task_resolve_promise(data->_task, data->_promise, result);
JS_FreeValue(context, result);
}
uv_fs_req_cleanup(request);
tf_free(data);
}
typedef struct _stat_t
{
uv_fs_t request;

View File

@ -7,6 +7,7 @@
#include "ssb.db.h"
#include "ssb.h"
#include "task.h"
#include "tls.h"
#include "tlscontext.js.h"
#include "trace.h"
#include "util.js.h"
@ -233,46 +234,6 @@ static JSValue _httpd_make_response_object(JSContext* context, tf_http_request_t
return response_object;
}
static void _httpd_callback_internal(tf_http_request_t* request, bool is_websocket)
{
http_handler_data_t* data = request->user_data;
JSContext* context = data->context;
JSValue request_object = JS_NewObject(context);
JS_SetPropertyStr(context, request_object, "method", JS_NewString(context, request->method));
JS_SetPropertyStr(context, request_object, "uri", JS_NewString(context, request->path));
JSValue headers = JS_NewObject(context);
for (int i = 0; i < request->headers_count; i++)
{
JS_SetPropertyStr(context, headers, request->headers[i].name, JS_NewString(context, request->headers[i].value));
}
JS_SetPropertyStr(context, request_object, "headers", headers);
if (request->query)
{
JS_SetPropertyStr(context, request_object, "query", JS_NewString(context, request->query));
}
if (request->body)
{
JS_SetPropertyStr(context, request_object, "body", tf_util_new_uint8_array(context, request->body, request->content_length));
}
JSValue client = JS_NewObject(context);
JS_SetPropertyStr(context, client, "tls", request->is_tls ? JS_TRUE : JS_FALSE);
JS_SetPropertyStr(context, request_object, "client", client);
JSValue response_object = _httpd_make_response_object(context, request);
/* The ref is owned by the JS object and will be released by the finalizer. */
tf_http_request_ref(request);
JSValue args[] = {
request_object,
response_object,
};
JSValue response = JS_Call(context, data->callback, JS_UNDEFINED, 2, args);
tf_util_report_error(context, response);
JS_FreeValue(context, request_object);
JS_FreeValue(context, response);
JS_FreeValue(context, response_object);
}
static bool _httpd_redirect(tf_http_request_t* request)
{
if (request->is_tls)
@ -292,16 +253,6 @@ static bool _httpd_redirect(tf_http_request_t* request)
return true;
}
static void _httpd_callback(tf_http_request_t* request)
{
if (_httpd_redirect(request))
{
return;
}
_httpd_callback_internal(request, false);
}
static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_http_request_t* request = JS_GetOpaque(this_val, _httpd_request_class_id);
@ -388,71 +339,19 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va
return JS_UNDEFINED;
}
static void _httpd_cleanup_callback(void* user_data)
{
http_handler_data_t* data = user_data;
JS_FreeValue(data->context, data->callback);
tf_free(data);
}
static JSValue _httpd_endpoint_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id);
const char* pattern = JS_ToCString(context, argv[0]);
http_handler_data_t* data = tf_malloc(sizeof(http_handler_data_t));
*data = (http_handler_data_t) { .context = context, .callback = JS_DupValue(context, argv[1]) };
tf_http_add_handler(http, pattern, _httpd_callback, _httpd_cleanup_callback, data);
JS_FreeCString(context, pattern);
return JS_UNDEFINED;
}
typedef struct _httpd_listener_t
{
JSContext* context;
JSValue tls;
tf_tls_context_t* tls;
} httpd_listener_t;
static void _httpd_listener_cleanup(void* user_data)
{
httpd_listener_t* listener = user_data;
JS_FreeValue(listener->context, listener->tls);
tf_free(listener);
}
static JSValue _httpd_endpoint_start(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id);
int port = 0;
JS_ToInt32(context, &port, argv[0]);
httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t));
*listener = (httpd_listener_t) { .context = context, .tls = JS_DupValue(context, argv[1]) };
tf_tls_context_t* tls = tf_tls_context_get(listener->tls);
int assigned_port = tf_http_listen(http, port, tls, _httpd_listener_cleanup, listener);
tf_printf(CYAN "~😎 Tilde Friends" RESET " " YELLOW VERSION_NUMBER RESET " is now up at " MAGENTA "http%s://127.0.0.1:%d/" RESET ".\n", tls ? "s" : "", assigned_port);
return JS_NewInt32(context, assigned_port);
}
static void _httpd_free_user_data(void* user_data)
{
tf_free(user_data);
}
static JSValue _httpd_set_http_redirect(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id);
http_user_data_t* user_data = tf_http_get_user_data(http);
if (!user_data)
if (listener->tls)
{
user_data = tf_malloc(sizeof(http_user_data_t));
memset(user_data, 0, sizeof(http_user_data_t));
tf_http_set_user_data(http, user_data, _httpd_free_user_data);
tf_tls_context_destroy(listener->tls);
}
const char* redirect = JS_ToCString(context, argv[0]);
snprintf(user_data->redirect, sizeof(user_data->redirect), "%s", redirect ? redirect : "");
JS_FreeCString(context, redirect);
return JS_UNDEFINED;
tf_free(listener);
}
typedef struct _auth_query_work_t
@ -783,13 +682,24 @@ typedef struct _http_file_t
char etag[512];
} http_file_t;
static bool _ends_with(const char* a, const char* suffix)
{
if (!a || !suffix)
{
return false;
}
size_t alen = strlen(a);
size_t suffixlen = strlen(suffix);
return alen >= suffixlen && strcmp(a + alen - suffixlen, suffix) == 0;
}
static void _httpd_endpoint_static_read(tf_task_t* task, const char* path, int result, const void* data, void* user_data)
{
http_file_t* file = user_data;
tf_http_request_t* request = file->request;
if (result >= 0)
{
if (strcmp(path, "core/tfrpc.js") == 0)
if (strcmp(path, "core/tfrpc.js") == 0 || _ends_with(path, "core/tfrpc.js"))
{
const char* content_type = _ext_to_content_type(strrchr(path, '.'), true);
const char* headers[] = {
@ -931,9 +841,10 @@ static void _httpd_endpoint_static(tf_http_request_t* request)
}
tf_task_t* task = request->user_data;
size_t size = strlen(file_path) + strlen(after) + 1;
const char* root_path = tf_task_get_root_path(task);
size_t size = (root_path ? strlen(root_path) + 1 : 0) + strlen(file_path) + strlen(after) + 1;
char* path = alloca(size);
snprintf(path, size, "%s%s", file_path, after);
snprintf(path, size, "%s%s%s%s", root_path ? root_path : "", root_path ? "/" : "", file_path, after);
tf_http_request_ref(request);
tf_file_stat(task, path, _httpd_endpoint_static_stat, request);
}
@ -2255,6 +2166,100 @@ static void _httpd_endpoint_logout(tf_http_request_t* request)
tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
}
static void _httpd_endpoint_app_socket(tf_http_request_t* request)
{
tf_task_t* task = request->user_data;
tf_ssb_t* ssb = tf_task_get_ssb(task);
JSContext* context = tf_ssb_get_context(ssb);
JSValue global = JS_GetGlobalObject(context);
JSValue exports = JS_GetPropertyStr(context, global, "exports");
JSValue app_socket = JS_GetPropertyStr(context, exports, "app_socket");
JSValue request_object = JS_NewObject(context);
JSValue headers = JS_NewObject(context);
for (int i = 0; i < request->headers_count; i++)
{
JS_SetPropertyStr(context, headers, request->headers[i].name, JS_NewString(context, request->headers[i].value));
}
JS_SetPropertyStr(context, request_object, "headers", headers);
JSValue response = _httpd_make_response_object(context, request);
tf_http_request_ref(request);
JSValue args[] = {
request_object,
response,
};
JSValue result = JS_Call(context, app_socket, JS_NULL, tf_countof(args), args);
tf_util_report_error(context, result);
JS_FreeValue(context, result);
for (int i = 0; i < tf_countof(args); i++)
{
JS_FreeValue(context, args[i]);
}
JS_FreeValue(context, app_socket);
JS_FreeValue(context, exports);
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);
}
static const char* _httpd_read_file(tf_task_t* task, const char* path)
{
const char* actual = tf_task_get_path_with_root(task, path);
const size_t k_max_read = 8 * 1024 * 1024;
char* result = NULL;
char* buffer = tf_malloc(k_max_read);
FILE* file = fopen(actual, "rb");
if (file)
{
size_t size = fread(buffer, 1, k_max_read, file);
result = tf_malloc(size + 1);
memcpy(result, buffer, size);
result[size] = '\0';
fclose(file);
}
tf_free(buffer);
tf_free((char*)actual);
return result;
}
void tf_httpd_register(JSContext* context)
{
JS_NewClassID(&_httpd_class_id);
@ -2275,15 +2280,41 @@ 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);
tf_task_t* task = tf_task_get(context);
tf_ssb_t* ssb = tf_task_get_ssb(task);
uv_loop_t* loop = tf_task_get_loop(task);
tf_http_t* http = tf_http_create(loop);
tf_http_set_trace(http, tf_task_get_trace(task));
JS_SetOpaque(httpd, http);
if (https_port)
{
http_user_data_t* user_data = tf_http_get_user_data(http);
if (!user_data)
{
user_data = tf_malloc(sizeof(http_user_data_t));
memset(user_data, 0, sizeof(http_user_data_t));
tf_http_set_user_data(http, user_data, _httpd_free_user_data);
}
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
tf_ssb_db_get_global_setting_string(db, "http_redirect", user_data->redirect, sizeof(user_data->redirect));
tf_ssb_release_db_reader(ssb, db);
/* Workaround. */
if (strcmp(user_data->redirect, "0") == 0)
{
*user_data->redirect = '\0';
}
}
tf_http_add_handler(http, "/", _httpd_endpoint_root, NULL, task);
tf_http_add_handler(http, "/codemirror/*", _httpd_endpoint_static, NULL, task);
tf_http_add_handler(http, "/lit/*", _httpd_endpoint_static, NULL, task);
@ -2312,10 +2343,56 @@ void tf_httpd_register(JSContext* context)
tf_http_add_handler(http, "/login/logout", _httpd_endpoint_logout, NULL, task);
tf_http_add_handler(http, "/login", _httpd_endpoint_login, NULL, task);
JS_SetPropertyStr(context, httpd, "all", JS_NewCFunction(context, _httpd_endpoint_all, "all", 2));
JS_SetPropertyStr(context, httpd, "start", JS_NewCFunction(context, _httpd_endpoint_start, "start", 2));
JS_SetPropertyStr(context, httpd, "set_http_redirect", JS_NewCFunction(context, _httpd_set_http_redirect, "set_http_redirect", 1));
tf_http_add_handler(http, "/app/socket", _httpd_endpoint_app_socket, NULL, task);
JS_SetPropertyStr(context, httpd, "auth_query", JS_NewCFunction(context, _httpd_auth_query, "auth_query", 1));
JS_SetPropertyStr(context, global, "httpd", httpd);
JS_FreeValue(context, global);
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)
{
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");
if (file)
{
fprintf(file, "%d", assigned_port);
fclose(file);
tf_printf("Wrote the port file: %s.\n", out_http_port_file);
}
else
{
tf_printf("Failed to open %s for write: %s.\n", out_http_port_file, strerror(errno));
}
tf_free((char*)actual_http_port_file);
}
if (https_port)
{
const char* k_certificate = "data/httpd/certificate.pem";
const char* k_private_key = "data/httpd/privatekey.pem";
const char* certificate = _httpd_read_file(task, k_certificate);
const char* private_key = _httpd_read_file(task, k_private_key);
if (certificate && private_key)
{
tf_tls_context_t* tls = tf_tls_context_create();
tf_tls_context_set_certificate(tls, certificate);
tf_tls_context_set_private_key(tls, private_key);
httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t));
*listener = (httpd_listener_t) { .tls = tls };
int assigned_port = tf_http_listen(http, https_port, tls, _httpd_listener_cleanup, listener);
tf_printf(CYAN "~😎 Tilde Friends" RESET " " YELLOW VERSION_NUMBER RESET " is now up at " MAGENTA "https://127.0.0.1:%d/" RESET ".\n", assigned_port);
}
tf_free((char*)certificate);
tf_free((char*)private_key);
}
}
tf_free((void*)out_http_port_file);
}

View File

@ -808,8 +808,8 @@ static int _tf_command_create_invite(const char* file, int argc, char* argv[])
const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
const char* identity = NULL;
int use_count = 0;
int expires = 0;
int use_count = 1;
int expires = 3600;
bool show_usage = false;
const char* host = NULL;
int port = 0;
@ -868,8 +868,8 @@ static int _tf_command_create_invite(const char* file, int argc, char* argv[])
tf_printf(" -i, --identity identity Account from which to get latest sequence number.\n");
tf_printf(" -a, --address address Address to which the recipient will connect.\n");
tf_printf(" -p, --port port Port to which the recipient will connect.\n");
tf_printf(" -u, --use_count count Number of times this invite may be used.\n");
tf_printf(" -e, --expires seconds How long this invite is valid in seconds (-1 for indefinitely).\n");
tf_printf(" -u, --use_count count Number of times this invite may be used (default: 1).\n");
tf_printf(" -e, --expires seconds How long this invite is valid in seconds (-1 for indefinitely, default: 1 hour).\n");
tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
@ -1256,6 +1256,47 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
snprintf(db_path_buffer, sizeof(db_path_buffer), "%s.%d", args->db_path, index);
db_path = db_path_buffer;
}
char* cwd = NULL;
if (!args->zip)
{
size_t cwd_size = 1;
uv_cwd((char[1]) { 0 }, &cwd_size);
cwd = alloca(cwd_size);
if (uv_cwd(cwd, &cwd_size) == 0)
{
size_t test_path_size = cwd_size + strlen("/core/core.js");
char* test_path = alloca(test_path_size);
uv_loop_t* loop = tf_task_get_loop(task);
uv_fs_t req = { 0 };
while (true)
{
snprintf(test_path, test_path_size, "%s/core/core.js", cwd);
int r = uv_fs_access(loop, &req, test_path, 0000, NULL);
uv_fs_req_cleanup(&req);
if (r != UV_ENOENT)
{
break;
}
char* slash = strrchr(cwd, '/');
if (slash)
{
*slash = '\0';
}
else
{
break;
}
}
tf_printf("Using %s as the working directory.\n", cwd);
}
if (!*cwd)
{
cwd = NULL;
}
}
tf_task_set_db_path(task, db_path);
tf_task_activate(task);
tf_ssb_set_verbose(tf_task_get_ssb(task), args->verbose);
@ -1266,13 +1307,33 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
{
tf_ssb_import_from_zip(tf_task_get_ssb(task), args->zip, "core", "apps");
}
else if (cwd)
{
size_t apps_path_size = strlen(cwd) + strlen("/apps") + 1;
char* apps_path = alloca(apps_path_size);
snprintf(apps_path, apps_path_size, "%s/apps", cwd);
tf_ssb_import(tf_task_get_ssb(task), "core", apps_path);
}
else
{
tf_ssb_import(tf_task_get_ssb(task), "core", "apps");
}
}
tf_ssb_set_main_thread(tf_task_get_ssb(task), true);
if (tf_task_execute(task, args->script))
const char* script = args->script;
if (!script && cwd)
{
size_t script_size = (cwd ? strlen(cwd) : 0) + strlen("/core/core.js") + 1;
char* script_buffer = alloca(script_size);
snprintf(script_buffer, script_size, "%s/core/core.js", cwd);
script = script_buffer;
}
else if (!script)
{
script = "core/core.js";
}
tf_task_set_root_path(task, cwd);
if (tf_task_execute(task, script))
{
tf_task_run(task);
result = 0;
@ -1356,7 +1417,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,
.script = "core/core.js",
.http_port = 12345,
.https_port = 12346,
.ssb_port = 8008,
@ -1787,7 +1847,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,
.script = "core/core.js",
.http_port = 12345,
.https_port = 12346,
.ssb_port = 8008,

View File

@ -372,7 +372,7 @@ static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value);
static void _tf_ssb_connection_on_close(uv_handle_t* handle);
static void _tf_ssb_nonce_inc(uint8_t* nonce);
static void _tf_ssb_notify_connections_changed(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection);
static bool _tf_ssb_parse_connect_string(const char* in_broadcast, tf_ssb_broadcast_t* out_broadcast);
static bool _tf_ssb_parse_connect_string(tf_ssb_t* ssb, const char* in_broadcast, tf_ssb_broadcast_t* out_broadcast);
static void _tf_ssb_start_update_settings(tf_ssb_t* ssb);
static void _tf_ssb_update_settings(tf_ssb_t* ssb);
static void _tf_ssb_write(tf_ssb_connection_t* connection, void* data, size_t size);
@ -3322,7 +3322,7 @@ static void _tf_ssb_update_seeds_after_work(tf_ssb_t* ssb, int status, void* use
for (int i = 0; i < seeds->seeds_count; i++)
{
tf_ssb_broadcast_t broadcast = { .origin = k_tf_ssb_broadcast_origin_peer_exchange };
if (_tf_ssb_parse_connect_string(seeds->seeds[i], &broadcast))
if (_tf_ssb_parse_connect_string(ssb, seeds->seeds[i], &broadcast))
{
_tf_ssb_add_broadcast(ssb, &broadcast, k_seed_expire_seconds);
}
@ -3431,7 +3431,7 @@ bool tf_ssb_whoami(tf_ssb_t* ssb, char* out_id, size_t out_id_size)
return tf_ssb_id_bin_to_str(out_id, out_id_size, ssb->pub);
}
static bool _tf_ssb_parse_connect_string(const char* in_broadcast, tf_ssb_broadcast_t* out_broadcast)
static bool _tf_ssb_parse_connect_string(tf_ssb_t* ssb, const char* in_broadcast, tf_ssb_broadcast_t* out_broadcast)
{
char public_key_str[54] = { 0 };
char secret_key_str[45] = { 0 };
@ -3450,7 +3450,7 @@ static bool _tf_ssb_parse_connect_string(const char* in_broadcast, tf_ssb_broadc
return tf_ssb_id_str_to_bin(out_broadcast->pub, public_key_str) &&
tf_base64_decode(secret_key_str, strlen(secret_key_str), out_broadcast->invite, sizeof(out_broadcast->invite));
}
else if (strncmp(in_broadcast, "ws:", 3) == 0)
else if (ssb->verbose && strncmp(in_broadcast, "ws:", 3) == 0)
{
tf_printf("Unsupported broadcast: %s\n", in_broadcast);
}
@ -3460,7 +3460,7 @@ static bool _tf_ssb_parse_connect_string(const char* in_broadcast, tf_ssb_broadc
void tf_ssb_connect_str(tf_ssb_t* ssb, const char* address, int connect_flags, tf_ssb_connect_callback_t* callback, void* user_data)
{
tf_ssb_broadcast_t broadcast = { 0 };
if (_tf_ssb_parse_connect_string(address, &broadcast))
if (_tf_ssb_parse_connect_string(ssb, address, &broadcast))
{
if (memcmp(broadcast.invite, (uint8_t[crypto_sign_ed25519_SEEDBYTES]) { 0 }, crypto_sign_ed25519_SEEDBYTES) == 0)
{
@ -3556,7 +3556,7 @@ static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broad
void tf_ssb_add_broadcast(tf_ssb_t* ssb, const char* connection, tf_ssb_broadcast_origin_t origin, int64_t expires_seconds)
{
tf_ssb_broadcast_t broadcast = { .origin = origin };
if (_tf_ssb_parse_connect_string(connection, &broadcast))
if (_tf_ssb_parse_connect_string(ssb, connection, &broadcast))
{
_tf_ssb_add_broadcast(ssb, &broadcast, expires_seconds);
}
@ -3579,7 +3579,7 @@ static void _tf_ssb_on_broadcast_listener_recv(uv_udp_t* handle, ssize_t nread,
while (entry)
{
tf_ssb_broadcast_t broadcast = { .origin = k_tf_ssb_broadcast_origin_discovery };
if (_tf_ssb_parse_connect_string(entry, &broadcast))
if (_tf_ssb_parse_connect_string(ssb, entry, &broadcast))
{
_tf_ssb_add_broadcast(ssb, &broadcast, k_udp_discovery_expires_seconds);
}

View File

@ -2182,7 +2182,7 @@ const char* tf_ssb_db_get_profile_name(sqlite3* db, const char* id)
static void _tf_ssb_db_invite_cleanup(sqlite3* db)
{
sqlite3_stmt* statement;
if (sqlite3_prepare(db, "DELETE FROM invites WHERE use_count = 0 OR expires < ?", -1, &statement, NULL) == SQLITE_OK)
if (sqlite3_prepare(db, "DELETE FROM invites WHERE use_count = 0 OR (expires > 0 AND expires < ?)", -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_bind_int64(statement, 1, (int64_t)time(NULL)) == SQLITE_OK)
{
@ -2190,7 +2190,13 @@ static void _tf_ssb_db_invite_cleanup(sqlite3* db)
{
if (sqlite3_changes(db))
{
tf_printf("Cleaned up %d used/expired invites.\n", sqlite3_changes(db));
char buffer[2] = { 0 };
size_t buffer_size = sizeof(buffer);
bool verbose = uv_os_getenv("TF_SSB_VERBOSE", buffer, &buffer_size) == 0 && strcmp(buffer, "1") == 0;
if (verbose)
{
tf_printf("Cleaned up %d used/expired invites.\n", sqlite3_changes(db));
}
}
}
else
@ -2231,7 +2237,8 @@ bool tf_ssb_db_generate_invite(sqlite3* db, const char* id, const char* host, in
if (sqlite3_prepare(db, "INSERT INTO invites (invite_public_key, account, use_count, expires) VALUES (?, ?, ?, ?)", -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_bind_text(statement, 1, public, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, id, -1, NULL) == SQLITE_OK &&
sqlite3_bind_int(statement, 3, use_count) == SQLITE_OK && sqlite3_bind_int64(statement, 4, (int64_t)time(NULL) + expires_seconds) == SQLITE_OK)
sqlite3_bind_int(statement, 3, use_count) == SQLITE_OK &&
sqlite3_bind_int64(statement, 4, (expires_seconds > 0 ? (int64_t)time(NULL) : 0) + expires_seconds) == SQLITE_OK)
{
inserted = sqlite3_step(statement) == SQLITE_DONE;
}

View File

@ -18,6 +18,10 @@
#include "sodium/crypto_sign.h"
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#if !defined(_WIN32)
#include <sys/wait.h>
#endif

View File

@ -40,6 +40,10 @@
#define WEXITSTATUS(x) (x)
#endif
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#if !defined(__APPLE__) && !defined(__OpenBSD__)
#include <malloc.h>
#endif
@ -155,6 +159,7 @@ typedef struct _tf_task_t
int _https_port;
char _db_path[256];
char _zip_path[256];
char _root_path[256];
unzFile _zip;
const char* _args;
@ -363,7 +368,15 @@ static const char* _task_loadFile(tf_task_t* task, const char* fileName, size_t*
}
else
{
FILE* file = fopen(fileName, "rb");
const char* actual = fileName;
if (*task->_root_path)
{
size_t size = strlen(task->_root_path) + strlen(fileName) + 2;
char* buffer = alloca(size);
snprintf(buffer, size, "%s/%s", task->_root_path, fileName);
actual = fileName;
}
FILE* file = fopen(actual, "rb");
if (file)
{
fseek(file, 0, SEEK_END);
@ -716,7 +729,6 @@ static JSValue _tf_task_platform(JSContext* context, JSValueConst this_val, int
#elif defined(__ANDROID__)
return JS_NewString(context, "android");
#elif defined(__APPLE__)
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
return JS_NewString(context, "iphone");
#else
@ -1714,7 +1726,6 @@ void tf_task_activate(tf_task_t* task)
JS_SetPropertyStr(context, global, "TlsContext", tf_tls_context_register(context));
tf_file_register(context);
tf_database_register(context);
tf_httpd_register(context);
task->_ssb = tf_ssb_create(&task->_loop, task->_context, task->_db_path, task->_network_key);
tf_ssb_set_trace(task->_ssb, task->_trace);
@ -1731,10 +1742,18 @@ void tf_task_activate(tf_task_t* task)
}
JS_SetPropertyStr(context, tildefriends, "ssb_port", JS_NewInt32(context, actual_ssb_port));
JS_SetPropertyStr(context, tildefriends, "http_port", JS_NewInt32(context, task->_http_port));
JS_SetPropertyStr(context, tildefriends, "https_port", JS_NewInt32(context, task->_https_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));
}
JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0));
tf_httpd_register(context);
}
else
{
@ -2015,11 +2034,34 @@ void tf_task_set_zip_path(tf_task_t* task, const char* zip_path)
}
}
void tf_task_set_root_path(tf_task_t* task, const char* path)
{
snprintf(task->_root_path, sizeof(task->_root_path), "%s", path ? path : "");
}
const char* tf_task_get_zip_path(tf_task_t* task)
{
return task->_zip ? task->_zip_path : NULL;
}
const char* tf_task_get_root_path(tf_task_t* task)
{
return *task->_root_path ? task->_root_path : NULL;
}
const char* tf_task_get_path_with_root(tf_task_t* task, const char* path)
{
if (!*task->_root_path)
{
return tf_strdup(path);
}
size_t size = strlen(task->_root_path) + 1 + strlen(path) + 1;
char* result = tf_malloc(size);
snprintf(result, size, "%s/%s", task->_root_path, path);
return result;
}
void tf_task_set_args(tf_task_t* task, const char* args)
{
task->_args = args;

View File

@ -112,12 +112,34 @@ void tf_task_set_db_path(tf_task_t* task, const char* path);
void tf_task_set_zip_path(tf_task_t* task, const char* path);
/**
** Get the path to the zipp file being used for static data.
** Set the path to the root of the project directory for data.
** @param task The task.
** @param path The file path or NULL.
*/
void tf_task_set_root_path(tf_task_t* task, const char* path);
/**
** Get the path to the zip file being used for static data.
** @param task The task.
** @return The zip file path or NULL.
*/
const char* tf_task_get_zip_path(tf_task_t* task);
/**
** Get the path to use for reading loose files.
** @param task The task.
** @return The path or NULL.
*/
const char* tf_task_get_root_path(tf_task_t* task);
/**
** Get the path to use for reading a given loose file.
** @param task The task.
** @param path The path to the file.
** @return The path or NULL. Free with tf_free().
*/
const char* tf_task_get_path_with_root(tf_task_t* task, const char* path);
/**
** Set arbitrary named arguments that will be made available to the task.
** @param task The task.

View File

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.27"
#define VERSION_NUMBER "0.0.28-wip"
#define VERSION_NAME "This program kills fascists."

View File

@ -126,11 +126,11 @@ do
build_the_thing
popd
echo WORK_DIR=$WORK_DIR
rm -rf deps/openssl/android/$build_target/
mkdir -p deps/openssl/android/$build_target/usr/local/include/
mkdir -p deps/openssl/android/$build_target/usr/local/lib/
cp -R $WORK_DIR/include/* deps/openssl/android/$build_target/usr/local/include/
cp $WORK_DIR/*.a deps/openssl/android/$build_target/usr/local/lib/
rm -rf out/openssl/android/$build_target/
mkdir -p out/openssl/android/$build_target/usr/local/include/
mkdir -p out/openssl/android/$build_target/usr/local/lib/
cp -R $WORK_DIR/include/* out/openssl/android/$build_target/usr/local/include/
cp $WORK_DIR/*.a out/openssl/android/$build_target/usr/local/lib/
done
echo Success

View File

@ -47,11 +47,11 @@ do
build_the_thing
popd
echo WORK_DIR=$WORK_DIR
rm -rf deps/openssl/ios/$build_target/
mkdir -p deps/openssl/ios/$build_target/usr/local/include/
mkdir -p deps/openssl/ios/$build_target/usr/local/lib/
cp -R $WORK_DIR/include/* deps/openssl/ios/$build_target/usr/local/include/
cp $WORK_DIR/*.a deps/openssl/ios/$build_target/usr/local/lib/
rm -rf out/openssl/ios/$build_target/
mkdir -p out/openssl/ios/$build_target/usr/local/include/
mkdir -p out/openssl/ios/$build_target/usr/local/lib/
cp -R $WORK_DIR/include/* out/openssl/ios/$build_target/usr/local/include/
cp $WORK_DIR/*.a out/openssl/ios/$build_target/usr/local/lib/
done
echo Success

View File

@ -85,10 +85,10 @@ make -s build_generated && \
make -s libcrypto.a libssl.a || exit 128
popd
echo WORK_DIR=$WORK_DIR
rm -rf deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/
mkdir -p deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
mkdir -p deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
cp -R $WORK_DIR/include/* deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
cp $WORK_DIR/*.a deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
rm -rf out/openssl/$BUILD_PLATFORM/$BUILD_TARGET/
mkdir -p out/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
mkdir -p out/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
cp -R $WORK_DIR/include/* out/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
cp $WORK_DIR/*.a out/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
echo Success

View File

@ -84,11 +84,11 @@ do
build_the_thing
popd
echo WORK_DIR=$WORK_DIR
rm -rf deps/openssl/$build_target/
mkdir -p deps/openssl/$build_target/usr/local/include/
mkdir -p deps/openssl/$build_target/usr/local/lib/
cp -R $WORK_DIR/include/* deps/openssl/$build_target/usr/local/include/
cp $WORK_DIR/*.a deps/openssl/$build_target/usr/local/lib/
rm -rf out/openssl/$build_target/
mkdir -p out/openssl/$build_target/usr/local/include/
mkdir -p out/openssl/$build_target/usr/local/lib/
cp -R $WORK_DIR/include/* out/openssl/$build_target/usr/local/include/
cp $WORK_DIR/*.a out/openssl/$build_target/usr/local/lib/
done
echo Success