From cdc9bc45f21174d82af7350d967d771e425563c4 Mon Sep 17 00:00:00 2001 From: Mike Black W9MDB Date: Sat, 14 Oct 2023 16:55:43 -0500 Subject: [PATCH] Add -b/bind_all option to rigctld By default rigctld will not try all interfaces Windows was not recognizing duplicate rigctld instances and failing with Log4OM https://github.com/Hamlib/Hamlib/issues/1400 --- NEWS | 1 + doc/man1/rigctld.1 | 4 ++++ tests/rigctld.c | 29 ++++++++++++++++++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index f04668579..8c9b8ecb7 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Version 5.x -- future * Change FT1000MP Mark V model names to align with FT1000MP Version 4.6 + * rigctld has new -b/bind-all option to try all interfaces -- restores original behavior. This was done to fix duplicate rigctld instances on Windows * Yaesu rigs can now use send_morse to send keyer message 1-5 or a CW message up to 50 chars (which will use memory 1) * rig set level METER can now take SWR,COMP,ALC,IC/ID,DB,PO,VDD,TEMP arguments to set which meter to display * reg get level displays meter number=name now diff --git a/doc/man1/rigctld.1 b/doc/man1/rigctld.1 index c3491429a..bde60512d 100644 --- a/doc/man1/rigctld.1 +++ b/doc/man1/rigctld.1 @@ -400,6 +400,10 @@ Sets password on rigctld which requires hamlib to use rig_set_password and rigct Will make rigctld close the rig when no clients are connected. Normally remains connected to speed up connects. . .TP +.BR \-b ", " \-\-bind_all +Will make rigctld try to bind to first network device available. +. +.TP .BR \-h ", " \-\-help Show a summary of these options and exit. . diff --git a/tests/rigctld.c b/tests/rigctld.c index c02dda666..e72e0b488 100644 --- a/tests/rigctld.c +++ b/tests/rigctld.c @@ -109,6 +109,7 @@ static struct option long_options[] = {"multicast-port", 1, 0, 'n'}, {"password", 1, 0, 'A'}, {"rigctld-idle", 0, 0, 'R'}, + {"bind-all", 0, 0, 'b'}, {0, 0, 0, 0} }; @@ -153,6 +154,7 @@ extern powerstat_t rig_powerstat; static int rigctld_idle = 0; // if true then rig will close when no clients are connected static int skip_open = 0; +static int bind_all = 0; #define MAXCONFLEN 2048 @@ -257,7 +259,7 @@ int main(int argc, char *argv[]) struct addrinfo hints, *result, *saved_result; int sock_listen; - int reuseaddr = 1; +// int reuseaddr = 1; int twiddle_timeout = 0; int twiddle_rit = 0; int uplink = 0; @@ -316,6 +318,10 @@ int main(int argc, char *argv[]) rigctld_idle = 1; break; + case 'b': + bind_all = 1; + break; + case 'A': strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1); //char *md5 = rig_make_m d5(rigctld_password); @@ -886,6 +892,7 @@ int main(int argc, char *argv[]) exit(2); } +#if 0 if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, @@ -898,6 +905,7 @@ int main(int argc, char *argv[]) freeaddrinfo(saved_result); /* No longer needed */ exit(1); } +#endif #ifdef IPV6_V6ONLY @@ -923,19 +931,26 @@ int main(int argc, char *argv[]) #endif - if (0 == bind(sock_listen, result->ai_addr, result->ai_addrlen)) + int retval = bind(sock_listen, result->ai_addr, result->ai_addrlen); + if (retval == 0) { break; } + { + rig_debug(RIG_DEBUG_ERR,"%s: bind: %s\n", __func__, strerror(errno)); + } - handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)"); + if (bind_all) + handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)"); + else + handle_error(RIG_DEBUG_WARN, "binding failed"); #ifdef __MINGW32__ closesocket(sock_listen); #else close(sock_listen); #endif } - while ((result = result->ai_next) != NULL); + while (bind_all && ((result = result->ai_next) != NULL)); freeaddrinfo(saved_result); /* No longer needed */ @@ -1122,7 +1137,11 @@ int main(int argc, char *argv[]) { rig_debug(RIG_DEBUG_WARN, "%u outstanding client(s)\n", client_count); } - +#ifdef __MINGW__ + closesocket(sock_listen); +#else + close(sock_listen); +#endif rig_close(my_rig); mutex_rigctld(0); #else