Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bfd977df5 | ||
|
|
e313b97dc3 | ||
|
|
38f144d38f | ||
|
|
3fd1f67b3b | ||
|
|
61b3452840 | ||
|
|
8361062427 | ||
|
|
fb63e66c65 | ||
|
|
a5e6c23d53 | ||
|
|
dfd12c7187 | ||
|
|
9b98aec864 | ||
|
|
0f49b2447f | ||
|
|
2e69450243 | ||
|
|
f0343e4c41 | ||
|
|
5ed3a1def2 |
No files matched your search
@@ -0,0 +1,8 @@
|
||||
build-*
|
||||
*.swp
|
||||
*~
|
||||
tags
|
||||
TAGS
|
||||
*.orig
|
||||
cscope.*
|
||||
*.dSYM
|
||||
@@ -1,17 +1,60 @@
|
||||
novacomd
|
||||
========
|
||||
|
||||
This build of novacomd is for armhf (raspberry Pi 3!)
|
||||
A 2026 build of novacomd for UNIX-like hosts built on top of libusb-compat-0.1. novacomd runs as a daemon or service on the host and the device.
|
||||
|
||||
Requires libusb-dev
|
||||
## Dependencies
|
||||
|
||||
To build:
|
||||
Building from source needs a C compiler (GCC or Clang), **GNU make**, and **libusb-compat-0.1**.
|
||||
|
||||
make host && mv build-novacom-host /usr/local/webos/usr/sbin/novacomd (or whatever your preferred install location is in your $PATH)
|
||||
Get a compiler:
|
||||
|
||||
novacomd runs as a daemon or service on the host and the device
|
||||
* **macOS:** Apple's Clang and make come with the Xcode Command Line Tools (`xcode-select --install`).
|
||||
* **Linux:** install your distribution's build tools (`build-essential` on Debian/Ubuntu, `base-devel` on Arch, etc.).
|
||||
|
||||
# Copyright and License Information
|
||||
Get libusb-compat-0.1:
|
||||
|
||||
| Platform | Command |
|
||||
| --- | --- |
|
||||
| macOS (Homebrew) | `brew install libusb-compat` |
|
||||
| Debian / Ubuntu | `sudo apt install libusb-dev` |
|
||||
| Fedora | `sudo dnf install libusb-compat-0.1-devel` |
|
||||
| Arch | `sudo pacman -S libusb-compat` |
|
||||
| Void | `doas xbps-install -Su libusb-compat-devel` |
|
||||
|
||||
(On Debian/Ubuntu the libusb-0.1 development package is named `libusb-dev`; `libusb-1.0-0-dev` is a legacy, unused package.)
|
||||
|
||||
## Building
|
||||
|
||||
Run the build script from the source directory. It picks a compiler and adds `-std=gnu17` when supported:
|
||||
|
||||
> ./install-novacomd.sh
|
||||
|
||||
To force a specific compiler, set `CC`:
|
||||
|
||||
> CC="gcc -std=gnu17" ./install-novacomd.sh
|
||||
|
||||
The built daemon lands at `build-novacomd-host/novacomd`.
|
||||
|
||||
## Installing
|
||||
|
||||
**Linux** — re-run the script with privilege escalation. It still builds as your normal user, then installs to `/usr/local/bin` (override with `INSTALL_DIR`):
|
||||
|
||||
> sudo ./install-novacomd.sh
|
||||
|
||||
`doas ./install-novacomd.sh` works too.
|
||||
|
||||
**macOS** — build *without* privilege escalation (running the script as root is refused), then copy the binary into your Palm SDK `bin`, usually `/opt/nova/bin`:
|
||||
|
||||
> ./install-novacomd.sh
|
||||
>
|
||||
> sudo cp build-novacomd-host/novacomd /opt/nova/bin/novacomd
|
||||
|
||||

|
||||
|
||||
Thanks to [incidentist](https://github.com/incidentist/novacomd) for the macOS build support.
|
||||
|
||||
## Copyright
|
||||
|
||||
Unless otherwise specified, all content, including all source code files
|
||||
and documentation files in this repository are:
|
||||
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build and (optionally) install novacomd -- NotAlexNoyle's 2025 libusb-compat fork.
|
||||
#
|
||||
# Run from the novacomd source dir, or point at it with $NOVACOMD_SRC or the first argument.
|
||||
# Unprivileged: builds only. As root (sudo/doas): builds as the invoking user, then installs.
|
||||
#
|
||||
# Environment overrides:
|
||||
# NOVACOMD_SRC source directory (default: this script's directory)
|
||||
# CC C compiler (default: gcc/cc + -std=gnu17 when supported; whitespace-split, no quoted args)
|
||||
# INSTALL_DIR install location (default: /usr/local/bin)
|
||||
# JOBS parallel make jobs (default: CPU count)
|
||||
#
|
||||
# Exit status: 0 on success, non-zero on failure. Public domain.
|
||||
# Author: NotAlexNoyle (alexnoyle@icloud.com)
|
||||
|
||||
set -u
|
||||
|
||||
readonly TARGET="novacomd"
|
||||
readonly BUILD_BIN="build-${TARGET}-host/${TARGET}"
|
||||
INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
|
||||
|
||||
log() { printf 'novacomd-install: %s\n' "$*"; }
|
||||
err() { printf 'novacomd-install: ERROR: %s\n' "$*" >&2; }
|
||||
die() { err "$*"; exit 1; }
|
||||
|
||||
# --- locate the source tree ---
|
||||
# Source precedence: argument 1, then $NOVACOMD_SRC, then this script's own directory.
|
||||
self="$(readlink -f -- "${BASH_SOURCE[0]}" 2>/dev/null || printf '%s' "${BASH_SOURCE[0]}")"
|
||||
script_dir="$(cd -- "$(dirname -- "$self")" >/dev/null 2>&1 && pwd -P)"
|
||||
src_dir="${1:-${NOVACOMD_SRC:-$script_dir}}"
|
||||
cd -- "$src_dir" >/dev/null 2>&1 || die "cannot enter novacomd source directory: $src_dir"
|
||||
src_dir="$(pwd -P)"
|
||||
|
||||
[ -f makefile ] || [ -f Makefile ] || die "no makefile in $src_dir -- pass the source directory as the first argument."
|
||||
|
||||
# --- privilege model ---
|
||||
# The build toolchain must never run as root; when root, drop to the invoking user for every build step.
|
||||
orig_user="${SUDO_USER:-${DOAS_USER:-}}"
|
||||
builder_prefix=()
|
||||
if (( EUID == 0 )); then
|
||||
builder_uid="$(id -u "$orig_user" 2>/dev/null || true)" # require a real, non-root account (UID > 0)
|
||||
if [ -n "$orig_user" ] && [[ "$builder_uid" =~ ^[1-9][0-9]*$ ]] && command -v runuser >/dev/null 2>&1; then
|
||||
builder_prefix=(runuser -u "$orig_user" --)
|
||||
else
|
||||
die "refusing to build as root -- run as a normal user; privilege escalation is only used to install."
|
||||
fi
|
||||
fi
|
||||
as_builder() { "${builder_prefix[@]}" "$@"; }
|
||||
|
||||
# --- preflight: build tools ---
|
||||
command -v make >/dev/null 2>&1 || die "'make' not found -- install your build tools (build-essential / base-devel)."
|
||||
|
||||
# --- compiler selection ---
|
||||
# Default the compiler when CC is unset, and add -std=gnu17 only if accepted (C23-default compilers need it).
|
||||
if [ -z "${CC:-}" ]; then
|
||||
if command -v gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi
|
||||
if printf 'int main(void){return 0;}\n' | as_builder $CC -std=gnu17 -fsyntax-only -xc - >/dev/null 2>&1; then
|
||||
CC="$CC -std=gnu17"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Split CC ("gcc -std=gnu17") into an argv array, then confirm a compiler is set and exists.
|
||||
read -r -a cc_argv <<<"$CC"
|
||||
[ "${#cc_argv[@]}" -gt 0 ] || die "CC is empty -- set it to a C compiler, e.g. CC=gcc."
|
||||
command -v "${cc_argv[0]}" >/dev/null 2>&1 || die "C compiler not found: ${cc_argv[0]}"
|
||||
|
||||
# --- preflight: libusb-compat header ---
|
||||
# The host transport needs libusb-compat-0.1 (<usb.h>); probe for it up front for a clear message.
|
||||
if ! printf '#include <usb.h>\nint main(void){return 0;}\n' | as_builder "${cc_argv[@]}" -fsyntax-only -xc - >/dev/null 2>&1; then
|
||||
die "missing libusb-compat-0.1 (<usb.h>). Install it, e.g.:
|
||||
Debian/Ubuntu: sudo apt install libusb-dev
|
||||
Fedora: sudo dnf install libusb-compat-0.1-devel
|
||||
Void: doas xbps-install -Su libusb-compat-devel
|
||||
Arch: sudo pacman -S libusb-compat"
|
||||
fi
|
||||
|
||||
# --- build ---
|
||||
# Default JOBS to the CPU count, and clear inherited make flags that could turn the build into a no-op.
|
||||
[ -n "${JOBS:-}" ] || JOBS="$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)"
|
||||
[[ "$JOBS" =~ ^[1-9][0-9]*$ ]] || JOBS=1
|
||||
unset MAKEFLAGS MFLAGS GNUMAKEFLAGS MAKEFILES
|
||||
|
||||
log "building $TARGET (CC=$CC, jobs=$JOBS${builder_prefix:+, as $orig_user})..."
|
||||
as_builder make -j"$JOBS" CC="$CC" host || die "build failed -- see the compiler output above."
|
||||
[ -f "$BUILD_BIN" ] && [ -x "$BUILD_BIN" ] || die "build reported success but $BUILD_BIN is missing."
|
||||
log "build succeeded: $BUILD_BIN"
|
||||
|
||||
# --- install (root only) ---
|
||||
if (( EUID == 0 )); then
|
||||
dest="$INSTALL_DIR/$TARGET"
|
||||
[ -d "$dest" ] && die "install destination is a directory: $dest"
|
||||
mkdir -p -- "$INSTALL_DIR" || die "cannot create $INSTALL_DIR"
|
||||
log "installing to $dest..."
|
||||
install -T -m 0755 -- "$BUILD_BIN" "$dest" || die "failed to install to $dest"
|
||||
[ -f "$dest" ] && [ -x "$dest" ] || die "post-install check failed: $dest"
|
||||
log "installed: $dest"
|
||||
else
|
||||
# Not root: print the manual install command using the available privilege escalation tool.
|
||||
if command -v doas >/dev/null 2>&1; then elevate="doas"; else elevate="sudo"; fi
|
||||
log "not running as root -- skipping install."
|
||||
log "to install: $elevate install -T -m 0755 '$src_dir/$BUILD_BIN' '$INSTALL_DIR/$TARGET'"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -39,7 +39,7 @@ CFLAGS :=
|
||||
ifneq ($(MACHINE),)
|
||||
MYCFLAGS += -DMACHINE=\"$(MACHINE)\"
|
||||
endif
|
||||
HOSTCFLAGS := $(MYCFLAGS) $(CFLAGS) -Isrc
|
||||
HOSTCFLAGS := $(MYCFLAGS) $(CFLAGS) -Isrc -DPLATFORM_PTHREADS=1
|
||||
DEVICECFLAGS := $(MYCFLAGS) $(OECFLAGS) $(TARGET_CC_ARCH) -DPLATFORM_PTHREADS=1
|
||||
CPPFLAGS := -g
|
||||
ASMFLAGS :=
|
||||
@@ -62,7 +62,7 @@ DEVICELD := arm-none-linux-gnueabi-ld
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(UNAME),Linux)
|
||||
ifeq ($(UNAME), $(filter $(UNAME), Linux Darwin))
|
||||
LDFLAGS += -Wl,-rpath,. # add the local path to the program's search path
|
||||
HOSTLDLIBS += -lpthread -lusb
|
||||
HOSTPLATFORM := pthreads
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ typedef struct recovery_entry_s {
|
||||
} recovery_entry_t;
|
||||
|
||||
/* list of recovery tokens */
|
||||
TAILQ_HEAD(recovery_queue_s, recovery_entry_s) t_recovery_queue;
|
||||
static TAILQ_HEAD(recovery_queue_s, recovery_entry_s) t_recovery_queue;
|
||||
static platform_mutex_t recovery_lock;
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <log.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#include "../novacom/mux.h"
|
||||
#include "device_list.h"
|
||||
|
||||
@@ -68,19 +67,9 @@ typedef struct {
|
||||
int iface;
|
||||
} novacom_usb_handle_t;
|
||||
|
||||
typedef struct recovery_entry_s {
|
||||
transport_recovery_token_t *t_token; /* transport recovery token */
|
||||
int timeout; /* timout value */
|
||||
|
||||
TAILQ_ENTRY(recovery_entry_s) entries; /* holds pointers to prev, next entries */
|
||||
} recovery_entry_t;
|
||||
|
||||
/* vars */
|
||||
static platform_thread_t findandattach_thread;
|
||||
volatile int novacom_shutdown = 0;
|
||||
/* list of recovery tokens */
|
||||
TAILQ_HEAD(recovery_queue_s, recovery_entry_s) t_recovery_queue;
|
||||
static platform_mutex_t recovery_lock;
|
||||
|
||||
|
||||
/* find_endpoints */
|
||||
@@ -541,9 +530,6 @@ static void *novacom_usb_findandattach_thread(void *arg)
|
||||
/* init records */
|
||||
usbrecords_init();
|
||||
|
||||
/* initialize records queue */
|
||||
TAILQ_INIT(&t_recovery_queue);
|
||||
|
||||
/* device discovery */
|
||||
while (!novacom_shutdown) {
|
||||
|
||||
@@ -578,7 +564,6 @@ int novacom_usb_transport_start(void)
|
||||
{
|
||||
novacom_shutdown = 0;
|
||||
platform_create_thread(&findandattach_thread, &novacom_usb_findandattach_thread, NULL);
|
||||
platform_mutex_init(&recovery_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -587,7 +572,6 @@ int novacom_usb_transport_stop(void)
|
||||
novacom_shutdown = 1;
|
||||
|
||||
platform_waitfor_thread(findandattach_thread);
|
||||
platform_mutex_destroy(&recovery_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -255,6 +255,10 @@ void *packet_thread(void *arg)
|
||||
break;
|
||||
case PACKET_HEADER_TYPE_ERR:
|
||||
TRACEF("unexpected incoming stderr data");
|
||||
rc = bufq_consume_sleep(args->in_queue, h.size);
|
||||
if ((size_t)rc < h.size)
|
||||
goto conn_fail;
|
||||
break;
|
||||
default:
|
||||
rc = bufq_consume_sleep(args->in_queue, h.size);
|
||||
if ((size_t)rc < h.size)
|
||||
|
||||
Reference in new issue
Block a user