From d85cf79aaa9fe60ddc6e7bc2d90e92c279ddab4b Mon Sep 17 00:00:00 2001 From: InterLinked1 <24227567+InterLinked1@users.noreply.github.com> Date: Sun, 29 Sep 2024 13:36:31 -0400 Subject: [PATCH] build: Fix compilation errors on FreeBSD. --- .github/workflows/main.yml | 6 ++++++ Makefile | 3 ++- bbs/Makefile | 9 ++++----- bbs/bbs.c | 2 +- bbs/config.c | 5 +---- bbs/fd.c | 13 ++++++++++--- bbs/logger.c | 5 +---- bbs/module.c | 5 +---- bbs/node.c | 5 +++++ bbs/pty.c | 2 ++ bbs/ratelimit.c | 5 +++++ bbs/socket.c | 8 ++++++++ bbs/thread.c | 7 ++++++- bbs/utils.c | 1 + external/filemgr.c | 2 +- external/modman.c | 25 +++++++++++++++++++++---- include/node.h | 1 + io/io_compress.c | 8 +++++++- modules/mod_asterisk_queues.c | 2 +- modules/mod_http.c | 5 +---- modules/mod_irc_client.c | 4 ++++ nets/net_ftp.c | 1 + nets/net_http.c | 4 +--- nets/net_irc.c | 5 +---- nets/net_msp.c | 2 +- nets/net_sieve.c | 1 + nets/net_ssh.c | 1 + nets/net_ws.c | 5 +---- scripts/install_prereq.sh | 13 +++++++------ 29 files changed, 103 insertions(+), 52 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 792eb0a..c8f6f5f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -209,6 +209,7 @@ jobs: - name: Run basic tests run: | tests/test -ttest_menus -ddddddddd -DDDDDDDDDD -x +# Binary fails to link due to uuid library missing in CI, but it will make all specified targets, so enumerate those freebsd-14: runs-on: ubuntu-24.04 name: FreeBSD @@ -222,6 +223,11 @@ jobs: ./scripts/install_prereq.sh gmake modcheck gmake modconfig + gmake main + gmake doors + gmake io + gmake modules + gmake nets gmake gmake install gmake samples diff --git a/Makefile b/Makefile index b6043f5..e215a30 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ BINDIR = $(PREFIX)/bin RM = rm -f LN = ln INSTALL = install +UNAME_S := $(shell uname -s) # Uncomment this to see all build commands instead of 'quiet' output #NOISY_BUILD=yes @@ -57,9 +58,9 @@ SILENT_BUILD_PREFIX := @ export CC export CFLAGS - export EXE +export UNAME_S export SUBMAKE # Run sub targets in parallel, but don't run top-level targets in parallel diff --git a/bbs/Makefile b/bbs/Makefile index 328b78d..82503c4 100644 --- a/bbs/Makefile +++ b/bbs/Makefile @@ -15,10 +15,11 @@ LIBS += -lcrypt -lcrypto -lcurl -lreadline -luuid -rdynamic # On SUSE, the remaining libraries are needed to link successfully # However, on other platforms they are generally not, and -liberty is likely to cause issues # Furthermore, some of the other libraries are also needed, if present, but must not be specified if not +# On FreeBSD, there is leading whitespace, so also trim for good measure LIBS += -lbfd -LIBERTY_CHECK = $(shell gcc -liberty 2>&1 | grep "cannot find" | wc -l ) -LZSTD_CHECK = $(shell gcc -lzstd 2>&1 | grep "cannot find" | wc -l ) -LSFRAME_CHECK = $(shell gcc -lsframe 2>&1 | grep "cannot find" | wc -l ) +LIBERTY_CHECK = $(shell gcc -liberty 2>&1 | grep "cannot find" | wc -l | tr -d ' ' ) +LZSTD_CHECK = $(shell gcc -lzstd 2>&1 | grep "cannot find" | wc -l | tr -d ' ' ) +LSFRAME_CHECK = $(shell gcc -lsframe 2>&1 | grep "cannot find" | wc -l | tr -d ' ' ) ifneq ($(LIBERTY_CHECK),1) LIBS += -liberty -lz -lopcodes endif @@ -29,8 +30,6 @@ ifneq ($(LSFRAME_CHECK),1) LIBS += -lsframe endif -UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S),Linux) LIBS += -lbsd -lcap endif diff --git a/bbs/bbs.c b/bbs/bbs.c index 133e984..84ed827 100644 --- a/bbs/bbs.c +++ b/bbs/bbs.c @@ -38,9 +38,9 @@ #include #include #include /* use O_NONBLOCK */ +#include /* use PATH_MAX */ #ifdef __linux__ -#include /* use PATH_MAX */ #include /* use prctl */ #include #include diff --git a/bbs/config.c b/bbs/config.c index 1cf2fb9..2f4d669 100644 --- a/bbs/config.c +++ b/bbs/config.c @@ -24,10 +24,7 @@ #include #include #include - -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/linkedlists.h" #include "include/config.h" diff --git a/bbs/fd.c b/bbs/fd.c index 2caabdd..5d25250 100644 --- a/bbs/fd.c +++ b/bbs/fd.c @@ -84,17 +84,24 @@ static int print_fds(int fd) { DIR *dir; struct dirent *entry; - char path[512]; char symlink[256]; + const char *fd_dir; ssize_t bytes; - if (!(dir = opendir("/proc/self/fd"))) { - bbs_error("Error opening directory - %s: %s\n", path, strerror(errno)); +#ifdef __linux__ + fd_dir = "/proc/self/fd"; +#else + fd_dir = "/dev/fd"; +#endif + + if (!(dir = opendir(fd_dir))) { + bbs_error("Error opening directory - %s: %s\n", fd_dir, strerror(errno)); return -1; } while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_LNK) { + char path[512]; int fdnum = atoi(entry->d_name); /* Only care about ones we don't know about */ if (ARRAY_IN_BOUNDS(fdnum, fdleaks) && fdleaks[fdnum].isopen) { diff --git a/bbs/logger.c b/bbs/logger.c index 9475874..b323581 100644 --- a/bbs/logger.c +++ b/bbs/logger.c @@ -31,10 +31,7 @@ #include /* use mkdir */ #include #include - -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/utils.h" /* use bbs_gettid, bbs_tvnow */ #include "include/linkedlists.h" diff --git a/bbs/module.c b/bbs/module.c index d85a64c..a0817a5 100644 --- a/bbs/module.c +++ b/bbs/module.c @@ -25,10 +25,7 @@ #include #include /* use usleep */ #include - -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/linkedlists.h" #include "include/stringlist.h" diff --git a/bbs/node.c b/bbs/node.c index f795f47..ce28d6a 100644 --- a/bbs/node.c +++ b/bbs/node.c @@ -30,6 +30,11 @@ #include #include +/* For FreeBSD */ +#ifndef CLOCK_MONOTONIC_RAW +#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC +#endif + #include "include/time.h" /* use timespecsub */ #include "include/node.h" #include "include/user.h" diff --git a/bbs/pty.c b/bbs/pty.c index e6199c1..974d505 100644 --- a/bbs/pty.c +++ b/bbs/pty.c @@ -269,7 +269,9 @@ int bbs_pty_allocate(struct bbs_node *node) if (bbs_pthread_create(&node->ptythread, NULL, pty_master, node)) { return -1; } +#ifdef __linux__ bbs_debug(8, "PTY thread %lu allocated for node %u\n", node->ptythread, node->id); +#endif /* We are the PTY slave */ node->slavefd = open(node->slavename, O_RDWR); diff --git a/bbs/ratelimit.c b/bbs/ratelimit.c index 859b279..a64d203 100644 --- a/bbs/ratelimit.c +++ b/bbs/ratelimit.c @@ -21,6 +21,11 @@ #include +/* For FreeBSD */ +#ifndef CLOCK_MONOTONIC_RAW +#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC +#endif + #include "include/time.h" /* use timespecsub */ #include "include/ratelimit.h" diff --git a/bbs/socket.c b/bbs/socket.c index cc943d9..21f4c6f 100644 --- a/bbs/socket.c +++ b/bbs/socket.c @@ -172,8 +172,16 @@ static int __bbs_socket_bind(int *sock, int rebind, int type, int port, const ch struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); safe_strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); +#ifdef __linux__ if (setsockopt(*sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) { bbs_error("Failed to set SO_BINDTODEVICE(%s): %s\n", interface, strerror(errno)); +#elif defined(__FreeBSD__) && defined(IP_SENDIF) + if (setsockopt(*sock, SOL_SOCKET, IP_SENDIF, &ifr, sizeof(ifr)) < 0) { + bbs_error("Failed to set IP_SENDIF(%s): %s\n", interface, strerror(errno)); +#else + if (1) { + bbs_error("Restricting binding to a specific interface is not supported on this platform\n"); +#endif close(*sock); return -1; } diff --git a/bbs/thread.c b/bbs/thread.c index 1917114..a8d2aff 100644 --- a/bbs/thread.c +++ b/bbs/thread.c @@ -114,7 +114,12 @@ static int __thread_unregister(pthread_t id, const char *file, int line, const c RWLIST_WRLOCK(&thread_list); RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) { - if (x->id == id) { +#ifdef __FreeBSD__ + /* Need both checks and it works */ + if ((unsigned long) x->id == (unsigned long) id || (unsigned long) x->lwp == (unsigned long) id) { +#else + if (x->id == id) { /* pthread_t isn't numeric on FreeBSD, so this check only works on Linux. */ +#endif if (x->detached || x->waitingjoin) { RWLIST_REMOVE_CURRENT(list); remove = 1; diff --git a/bbs/utils.c b/bbs/utils.c index 8daa11d..a0e7fdb 100644 --- a/bbs/utils.c +++ b/bbs/utils.c @@ -30,6 +30,7 @@ #include /* use time */ #include /* use gettimeofday */ #include /* use dirname, basename (FreeBSD) */ +#include /* use PATH_MAX */ #ifdef __linux__ #include /* use uuid_generate, uuid_unparse */ diff --git a/external/filemgr.c b/external/filemgr.c index 3a2dca1..621bb56 100644 --- a/external/filemgr.c +++ b/external/filemgr.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include diff --git a/external/modman.c b/external/modman.c index 4bb5411..176fa72 100644 --- a/external/modman.c +++ b/external/modman.c @@ -26,6 +26,7 @@ #include #include #include +#include /* use WIFEXITED, WEXITSTATUS */ #include @@ -196,7 +197,13 @@ static int check_lib(const char *modname, const char *libname) /* If we didn't reach the end, we hit an invalid character */ return 0; } + + /* ldconfig -p isn't valid on FreeBSD, so only try this on Linux: */ +#ifdef __FreeBSD__ + snprintf(cmd, sizeof(cmd), "ldconfig -r | grep 'lib%s.so' 2>/dev/null 1>&2", libname); +#else snprintf(cmd, sizeof(cmd), "ldconfig -p | grep 'lib%s.so' 2>/dev/null 1>&2", libname); +#endif res = system(cmd); /* ldconfig | grep returned nonzero, which means * we couldn't find any libraries by that name. */ @@ -413,7 +420,7 @@ static int check_header_file(const char *dirname, const char *modname, const cha rewind(mfp); snprintf(objname, sizeof(objname), "%s", modname); TERMINATE_AT(objname, '.'); - strncat(objname, ".o", sizeof(objname)); + strncat(objname, ".o", sizeof(objname) - 1); objnamelen = strlen(objname); while (fgets(buf, sizeof(buf), mfp)) { char *token, *tokens; @@ -481,7 +488,7 @@ static int check_headers(const char *dirname, const char *modname, FILE *mfp, in snprintf(filename, sizeof(filename), "%s/%s", dirname, modname); TERMINATE_AT(filename, '.'); - strncat(filename, ".c", sizeof(filename)); + strncat(filename, ".c", sizeof(filename) - 1); fp = fopen(filename, "r"); if (!fp) { @@ -500,6 +507,15 @@ static int check_headers(const char *dirname, const char *modname, FILE *mfp, in continue; } TERMINATE_AT(incfile, '>'); +#ifdef __FreeBSD__ + /* XXX Hardcoded exception: is only included on __linux__, + * but since we don't process conditional includes (#ifdef), + * we'll erroneously think this is missing on FreeBSD (for mod_irc_relay) + * when it's not needed. */ + if (!strcmp(incfile, "bsd/string.h")) { + continue; + } +#endif if (!check_header_file(dirname, modname, incfile, mfp, met_deps)) { unmet_headers++; } @@ -798,7 +814,7 @@ int main(int argc, char *argv[]) } } - optind = 0; + optind = 1; while ((c = getopt(argc, argv, getopt_settings)) != -1) { switch (c) { case '?': @@ -817,5 +833,6 @@ int main(int argc, char *argv[]) } } - return 0; + fprintf(stderr, "No arguments provided to modman, taking no action\n"); + return -1; } diff --git a/include/node.h b/include/node.h index 57265fb..04123f1 100644 --- a/include/node.h +++ b/include/node.h @@ -22,6 +22,7 @@ struct bbs_user; struct bbs_vars; struct readline_data; struct pollfd; +struct sockaddr_in; #define ANSI_CURSOR_QUERY (1 << 0) #define ANSI_CURSOR_SET (1 << 1) diff --git a/io/io_compress.c b/io/io_compress.c index 5a52474..c404cd8 100644 --- a/io/io_compress.c +++ b/io/io_compress.c @@ -350,7 +350,13 @@ static int cli_compression(struct bbs_cli_args *a) char send_pct[13], recv_pct[13]; snprintf(send_pct, sizeof(send_pct), "%d%%", (int) (100.0 * (double) z->sentbytes_comp / (double) z->sentbytes)); snprintf(recv_pct, sizeof(recv_pct), "%d%%", (int) (100.0 * (double) z->recvbytes_comp / (double) z->recvbytes)); - bbs_dprintf(a->fdout, "%3d %3d %8d %8d %5d %11lu %11lu %11lu %11lu %6s %6s %lu\n", z->rpfd[0], z->wpfd[1], z->orig_rfd, z->orig_wfd, z->level, z->sentbytes, z->sentbytes_comp, z->recvbytes, z->recvbytes_comp, send_pct, recv_pct, z->thread); +#ifdef __linux__ + bbs_dprintf(a->fdout, "%3d %3d %8d %8d %5d %11lu %11lu %11lu %11lu %6s %6s %lu\n", + z->rpfd[0], z->wpfd[1], z->orig_rfd, z->orig_wfd, z->level, z->sentbytes, z->sentbytes_comp, z->recvbytes, z->recvbytes_comp, send_pct, recv_pct, z->thread); +#else + bbs_dprintf(a->fdout, "%3d %3d %8d %8d %5d %11lu %11lu %11lu %11lu %6s %6s\n", + z->rpfd[0], z->wpfd[1], z->orig_rfd, z->orig_wfd, z->level, z->sentbytes, z->sentbytes_comp, z->recvbytes, z->recvbytes_comp, send_pct, recv_pct); +#endif } RWLIST_UNLOCK(&compressors); return 0; diff --git a/modules/mod_asterisk_queues.c b/modules/mod_asterisk_queues.c index c98b4b0..7283ae8 100644 --- a/modules/mod_asterisk_queues.c +++ b/modules/mod_asterisk_queues.c @@ -439,7 +439,7 @@ static int cli_asterisk_calls(struct bbs_cli_args *a) } /*! \note 4 and 6 should also be nonnull, but SET_FSM_STRING_VAR does a strlen_zero check, so we can't include them in the attribute */ -static __nonnull ((1, 5)) struct queue_call *new_call(struct queue *queue, int queueid, int ani2, const char *channel, const char *ani, const char *cnam, const char *dnis) +static __attribute__((nonnull (1, 5))) struct queue_call *new_call(struct queue *queue, int queueid, int ani2, const char *channel, const char *ani, const char *cnam, const char *dnis) { struct queue_call *call; char *data; diff --git a/modules/mod_http.c b/modules/mod_http.c index 165d3f3..e96558d 100644 --- a/modules/mod_http.c +++ b/modules/mod_http.c @@ -36,10 +36,7 @@ #include #include #include - -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/module.h" #include "include/node.h" diff --git a/modules/mod_irc_client.c b/modules/mod_irc_client.c index 027a00f..7967e9d 100644 --- a/modules/mod_irc_client.c +++ b/modules/mod_irc_client.c @@ -823,7 +823,11 @@ static int cli_irc_irc_clients(struct bbs_cli_args *a) bbs_dprintf(a->fdout, "%-20s %6s %3s %9s %-15s %s\n", "Name", "Status", "Log", "Callbacks", "Thread", "BotMsgScript"); RWLIST_RDLOCK(&irc_clients); RWLIST_TRAVERSE(&irc_clients, c, entry) { +#ifdef __linux__ bbs_dprintf(a->fdout, "%-20s %6s %3s %9s %15lu %s\n", c->name, irc_client_connected(c->client) ? "Online" : "Offline", BBS_YN(c->log), BBS_YN(c->callbacks), c->thread, S_IF(c->msgscript)); +#else + bbs_dprintf(a->fdout, "%-20s %6s %3s %9s %15s %s\n", c->name, irc_client_connected(c->client) ? "Online" : "Offline", BBS_YN(c->log), BBS_YN(c->callbacks), "", S_IF(c->msgscript)); +#endif } RWLIST_UNLOCK(&irc_clients); return 0; diff --git a/nets/net_ftp.c b/nets/net_ftp.c index 86a050d..24f33dc 100644 --- a/nets/net_ftp.c +++ b/nets/net_ftp.c @@ -26,6 +26,7 @@ #include #include #include +#include /* use PATH_MAX */ #include "include/module.h" #include "include/node.h" diff --git a/nets/net_http.c b/nets/net_http.c index 7dd8beb..9d0222b 100644 --- a/nets/net_http.c +++ b/nets/net_http.c @@ -24,9 +24,7 @@ #include "include/bbs.h" -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/module.h" #include "include/config.h" diff --git a/nets/net_irc.c b/nets/net_irc.c index f23c75c..7aa6db8 100644 --- a/nets/net_irc.c +++ b/nets/net_irc.c @@ -25,10 +25,7 @@ #include #include #include - -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/module.h" #include "include/config.h" diff --git a/nets/net_msp.c b/nets/net_msp.c index cdcec70..83ab850 100644 --- a/nets/net_msp.c +++ b/nets/net_msp.c @@ -215,7 +215,7 @@ static int msp_response(struct msp *restrict msp, const char *s, size_t len) if (msp->node) { bbs_node_fd_write(msp->node, msp->node->wfd, s, len); } else { - ssize_t res = sendto(udp_socket, s, len, 0, msp->in, msp->slen); + ssize_t res = sendto(udp_socket, s, len, 0, (const struct sockaddr*) msp->in, msp->slen); if (res <= 0) { bbs_error("sendto failed: %s\n", strerror(errno)); } diff --git a/nets/net_sieve.c b/nets/net_sieve.c index 7840eda..b07a88b 100644 --- a/nets/net_sieve.c +++ b/nets/net_sieve.c @@ -23,6 +23,7 @@ #include #include #include +#include /* use PATH_MAX */ #include "include/module.h" #include "include/config.h" diff --git a/nets/net_ssh.c b/nets/net_ssh.c index 896676e..2f6d7be 100644 --- a/nets/net_ssh.c +++ b/nets/net_ssh.c @@ -33,6 +33,7 @@ #include /* use sockaddr_in */ #include /* use pthread_kill */ #include /* use winsize */ +#include /* use PATH_MAX */ /* * The SSH driver has dependencies on libssh and libcrypto. diff --git a/nets/net_ws.c b/nets/net_ws.c index 3483b48..76cd132 100644 --- a/nets/net_ws.c +++ b/nets/net_ws.c @@ -22,10 +22,7 @@ #include #include /* use isdigit */ #include - -#ifdef __linux__ -#include /* use PATH_MAX */ -#endif +#include /* use PATH_MAX */ #include "include/module.h" #include "include/config.h" diff --git a/scripts/install_prereq.sh b/scripts/install_prereq.sh index 873ce9b..dfd183b 100755 --- a/scripts/install_prereq.sh +++ b/scripts/install_prereq.sh @@ -34,6 +34,7 @@ PACKAGES_DEBIAN="$PACKAGES_DEBIAN libcurl4-openssl-dev" PACKAGES_FEDORA="$PACKAGES_FEDORA libcurl-devel" PACKAGES_SUSE="$PACKAGES_SUSE libcurl-devel" PACKAGES_ARCH="$PACKAGES_ARCH curl" +PACKAGES_FREEBSD="$PACKAGES_FREEBSD curl" # PACKAGES_DEBIAN="$PACKAGES_DEBIAN binutils-dev" @@ -235,12 +236,15 @@ scripts/libcami.sh # lirc (mod_irc_client) scripts/lirc.sh -# libdiscord (mod_discord) -scripts/libdiscord.sh - # libwss (net_ws) scripts/libwss.sh +# mod_slack (also depends on libwss) +scripts/libslackrtm.sh + +# libdiscord (mod_discord) +scripts/libdiscord.sh + # libetpan fails to build successfully on Fedora-based distros, # so need to be able to skip that for now using an env var. if [ "$INSTALL_LIBETPAN" != "0" ]; then @@ -252,9 +256,6 @@ if [ "$INSTALL_LIBETPAN" != "0" ]; then scripts/evergreen.sh fi -# mod_slack (also depends on libwss) -scripts/libslackrtm.sh - # mod_smtp_filter_arc # milter pre-req can be hard to satisfy, so can be disabled using an env var if [ "$INSTALL_LIBOPENARC" != "0" ]; then