first commit
This commit is contained in:
commit
19dfc51360
85 files changed
+25504
No files matched your search
Executable
+168
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a Debian/Ubuntu package with dpkg-deb only (no debhelper needed).
|
||||
# scripts/build-deb.sh build release binary for the host and package it
|
||||
# scripts/build-deb.sh --no-build package an existing target/release/active-push
|
||||
# TARGET=aarch64-unknown-linux-gnu scripts/build-deb.sh (cross toolchain must be installed)
|
||||
set -euo pipefail
|
||||
ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
fail() { printf 'error: %s\n' "$*" >&2; exit 1; }
|
||||
command -v dpkg-deb >/dev/null || fail "dpkg-deb is required (apt install dpkg)"
|
||||
|
||||
VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)"
|
||||
REVISION="${DEB_REVISION:-1}"
|
||||
BUILD=1
|
||||
[[ "${1:-}" == "--no-build" ]] && BUILD=0
|
||||
HOST_ARCH="$(uname -m)"
|
||||
# Portable builds: link against an old glibc with cargo-zigbuild when available
|
||||
# (pip install ziglang && cargo install cargo-zigbuild). GLIBC_TARGET=0 disables it.
|
||||
GLIBC_TARGET="${GLIBC_TARGET:-2.31}"
|
||||
TARGET="${TARGET:-}"
|
||||
ZIG=0
|
||||
if [[ -z "$TARGET" && "$GLIBC_TARGET" != "0" ]] && command -v cargo-zigbuild >/dev/null 2>&1; then
|
||||
TARGET="${HOST_ARCH}-unknown-linux-gnu"
|
||||
ZIG=1
|
||||
fi
|
||||
case "${TARGET:-$HOST_ARCH}" in
|
||||
x86_64*) ARCH=amd64 ;;
|
||||
aarch64*) ARCH=arm64 ;;
|
||||
armv7*) ARCH=armhf ;;
|
||||
*) ARCH="$(dpkg --print-architecture 2>/dev/null || echo amd64)" ;;
|
||||
esac
|
||||
if [[ -n "${BIN:-}" ]]; then
|
||||
:
|
||||
elif [[ -n "$TARGET" ]]; then
|
||||
BIN="${CARGO_TARGET_DIR:-target}/$TARGET/release/active-push"
|
||||
else
|
||||
BIN="${CARGO_TARGET_DIR:-target}/release/active-push"
|
||||
fi
|
||||
|
||||
if [[ $BUILD == 1 ]]; then
|
||||
printf 'Building release binary %s...\n' "$VERSION"
|
||||
if [[ $ZIG == 1 ]]; then
|
||||
cargo zigbuild --release --locked --target "$TARGET.$GLIBC_TARGET"
|
||||
elif [[ -n "$TARGET" ]]; then
|
||||
cargo build --release --locked --target "$TARGET"
|
||||
else
|
||||
cargo build --release --locked
|
||||
fi
|
||||
fi
|
||||
[[ -x "$BIN" ]] || fail "binary $BIN not found"
|
||||
|
||||
# minimal libc6 version from the binary's versioned symbols
|
||||
LIBC_MIN="2.31"
|
||||
if command -v objdump >/dev/null; then
|
||||
v="$(objdump -T "$BIN" 2>/dev/null | grep -o 'GLIBC_[0-9.]*' | sed 's/GLIBC_//' | sort -V | tail -1)"
|
||||
[[ -n "$v" ]] && LIBC_MIN="$v"
|
||||
fi
|
||||
printf 'Binary %s requires glibc >= %s\n' "$BIN" "$LIBC_MIN"
|
||||
|
||||
PKG="active-push_${VERSION}-${REVISION}_${ARCH}"
|
||||
STAGE="$(mktemp -d)"
|
||||
trap 'rm -rf "$STAGE"' EXIT
|
||||
D="$STAGE/$PKG"
|
||||
|
||||
install -d -m 0755 "$D/DEBIAN" "$D/usr/bin" "$D/lib/systemd/system" "$D/etc/active-push" \
|
||||
"$D/usr/share/doc/active-push/examples" "$D/usr/share/active-push"
|
||||
install -m 0755 "$BIN" "$D/usr/bin/active-push"
|
||||
strip --strip-unneeded "$D/usr/bin/active-push" 2>/dev/null || true
|
||||
install -m 0644 deploy/active-push.service "$D/lib/systemd/system/active-push.service"
|
||||
install -m 0640 deploy/environment.example "$D/etc/active-push/environment"
|
||||
install -m 0644 deploy/nginx-active-push.conf "$D/usr/share/doc/active-push/examples/nginx-active-push.conf"
|
||||
install -m 0644 deploy/active-push-autodiscover.conf "$D/usr/share/doc/active-push/examples/active-push-autodiscover.conf"
|
||||
install -m 0644 README.md "$D/usr/share/doc/active-push/README.md"
|
||||
for f in docs/*.md; do install -m 0644 "$f" "$D/usr/share/doc/active-push/"; done
|
||||
install -m 0755 tools/zpush-import.py "$D/usr/share/active-push/zpush-import.py"
|
||||
install -m 0644 LICENSE "$D/usr/share/doc/active-push/copyright"
|
||||
gzip -9n -c CHANGELOG.md > "$D/usr/share/doc/active-push/changelog.gz"
|
||||
|
||||
SIZE="$(du -sk "$D" | cut -f1)"
|
||||
cat > "$D/DEBIAN/control" <<EOF
|
||||
Package: active-push
|
||||
Version: ${VERSION}-${REVISION}
|
||||
Section: mail
|
||||
Priority: optional
|
||||
Architecture: ${ARCH}
|
||||
Maintainer: ActivePush maintainers <root@localhost>
|
||||
Installed-Size: ${SIZE}
|
||||
Depends: libc6 (>= ${LIBC_MIN}), adduser, ca-certificates
|
||||
Recommends: nginx | apache2 | rust-proxy
|
||||
Suggests: dovecot-imapd, postfix, radicale
|
||||
Conflicts: z-push-common
|
||||
Description: Exchange ActiveSync server for IMAP/SMTP, CalDAV and CardDAV
|
||||
ActivePush lets phones and Outlook synchronise mail, calendars, tasks and
|
||||
contacts over Exchange ActiveSync (2.5-14.1) with standard IMAP/SMTP,
|
||||
CalDAV and CardDAV servers. It is a Rust rewrite of Z-Push with a built-in
|
||||
administration panel (devices, remote wipe, policies, live statistics).
|
||||
EOF
|
||||
# Z-Push can be installed side by side; drop the Conflicts line if you rely on that.
|
||||
sed -i '/^Conflicts: z-push-common/d' "$D/DEBIAN/control"
|
||||
|
||||
echo "/etc/active-push/environment" > "$D/DEBIAN/conffiles"
|
||||
|
||||
cat > "$D/DEBIAN/postinst" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
case "$1" in
|
||||
configure)
|
||||
if ! getent group active-push >/dev/null; then addgroup --system active-push >/dev/null; fi
|
||||
if ! getent passwd active-push >/dev/null; then
|
||||
adduser --system --ingroup active-push --home /var/lib/active-push --no-create-home \
|
||||
--shell /usr/sbin/nologin --gecos "ActivePush" active-push >/dev/null
|
||||
fi
|
||||
install -d -o active-push -g active-push -m 0700 /var/lib/active-push
|
||||
chown root:active-push /etc/active-push /etc/active-push/environment
|
||||
chmod 0750 /etc/active-push
|
||||
chmod 0640 /etc/active-push/environment
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
if [ -z "$2" ]; then
|
||||
systemctl enable --now active-push.service >/dev/null 2>&1 || true
|
||||
echo ""
|
||||
echo "ActivePush installed and started."
|
||||
echo " ActiveSync listener : 127.0.0.1:8081 (proxy /Microsoft-Server-ActiveSync and autodiscover here)"
|
||||
echo " Admin panel : http://127.0.0.1:9091/ (ssh -L 9091:127.0.0.1:9091 server)"
|
||||
echo " First administrator : sudo -u active-push active-push admin setup-token"
|
||||
echo " nginx example : /usr/share/doc/active-push/examples/nginx-active-push.conf"
|
||||
echo " Import Z-Push config: python3 /usr/share/active-push/zpush-import.py /usr/share/z-push > zpush.json"
|
||||
echo " sudo -u active-push active-push config apply zpush.json"
|
||||
echo ""
|
||||
else
|
||||
systemctl try-restart active-push.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
cat > "$D/DEBIAN/prerm" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
|
||||
systemctl disable --now active-push.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
cat > "$D/DEBIAN/postrm" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
if [ "$1" = purge ]; then
|
||||
rm -rf /etc/active-push
|
||||
# device states, statistics and settings
|
||||
rm -rf /var/lib/active-push
|
||||
if getent passwd active-push >/dev/null; then deluser --system active-push >/dev/null 2>&1 || true; fi
|
||||
if getent group active-push >/dev/null; then delgroup --system active-push >/dev/null 2>&1 || true; fi
|
||||
fi
|
||||
if [ -d /run/systemd/system ]; then systemctl daemon-reload >/dev/null 2>&1 || true; fi
|
||||
exit 0
|
||||
EOF
|
||||
chmod 0755 "$D/DEBIAN/postinst" "$D/DEBIAN/prerm" "$D/DEBIAN/postrm"
|
||||
|
||||
mkdir -p dist
|
||||
dpkg-deb --root-owner-group -Zxz --build "$D" "dist/$PKG.deb" >/dev/null
|
||||
sha256sum "dist/$PKG.deb" > "dist/$PKG.deb.sha256"
|
||||
printf 'Package: dist/%s.deb\n' "$PKG"
|
||||
dpkg-deb --info "dist/$PKG.deb" | sed -n '1,12p'
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify that every literal "Namespace:Tag" used in the sources exists in the WBXML code pages.
|
||||
|
||||
Element::new() panics on unknown names at runtime; this catches typos at build time.
|
||||
"""
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
root = pathlib.Path(__file__).resolve().parent.parent
|
||||
cp = (root / "src/wbxml/codepages.rs").read_text()
|
||||
namespaces = re.findall(r'"([^"]+)"', re.search(r"NAMESPACES: &\[&str\] = &\[(.*?)\];", cp, re.S).group(1))
|
||||
body = cp[cp.index("pub const PAGES"):]
|
||||
known = set()
|
||||
for i, chunk in enumerate(re.split(r"\n\s*// \d+ \w+\n", body)[1:]):
|
||||
for tag in re.findall(r'\(0x[0-9A-Fa-f]+,\s*"([^"]+)"\)', chunk):
|
||||
known.add(f"{namespaces[i]}:{tag}")
|
||||
|
||||
pattern = re.compile(r'"((?:%s):[A-Za-z0-9]+)"' % "|".join(re.escape(n) for n in namespaces))
|
||||
bad = []
|
||||
for f in (root / "src").rglob("*.rs"):
|
||||
if f.name == "codepages.rs":
|
||||
continue
|
||||
for n, line in enumerate(f.read_text().splitlines(), 1):
|
||||
for m in pattern.finditer(line):
|
||||
if m.group(1) not in known:
|
||||
bad.append(f"{f.relative_to(root)}:{n}: {m.group(1)}")
|
||||
if bad:
|
||||
print("Unknown WBXML tag names:\n " + "\n ".join(bad))
|
||||
sys.exit(1)
|
||||
print(f"WBXML names: OK ({len(known)} known tags)")
|
||||
Reference in new issue
Block a user