From 02057200fd73fc70cc4a6eeece5c033c14f0c50a Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Thu, 14 Nov 2019 08:08:28 -0800 Subject: [PATCH] macOS: Add support for automatic updates using Sparkle. Add support for automatic updates using the Sparkle framework. Add FindSparkle.cmake and associated CMake plumbing. Add a public key and other info to Info.plist.in. Add ui/macosx/sparkle_bridge.{h,m}, which wraps the Sparkle API. Make code that's specific to WinSparkle Windows-only. Add Sparkle installation steps to the macos-setup scripts. Sparkle prints a warning if your bundle is unsigned (which is the case during development) so disable installing it by default. Updating here takes a long time. We might be able to fix that by shipping our DSYMs separately. Change-Id: I6cc6671db5657dadc514bda6bf6e1c8bbc9468a5 Reviewed-on: https://code.wireshark.org/review/35090 Petri-Dish: Gerald Combs Tested-by: Petri Dish Buildbot Reviewed-by: Gerald Combs --- CMakeLists.txt | 7 +++ CMakeOptions.txt | 3 +- cmake/modules/FindSparkle.cmake | 22 +++++++++ cmakeconfig.h.in | 2 +- docbook/release-notes.adoc | 1 + packaging/macosx/Info.plist.in | 17 +++++++ packaging/macosx/osx-app.sh.in | 6 +++ tools/macos-setup-brew.sh | 3 ++ tools/macos-setup.sh | 44 ++++++++++++++++++ ui/macosx/sparkle_bridge.h | 38 ++++++++++++++++ ui/macosx/sparkle_bridge.m | 44 ++++++++++++++++++ ui/qt/main_window.cpp | 2 +- ui/qt/main_window.h | 2 +- ui/qt/main_window_slots.cpp | 2 +- ui/qt/wireshark_application.cpp | 8 ++-- ui/qt/wireshark_application.h | 6 +-- ui/software_update.c | 79 ++++++++++++++++++++------------- ui/software_update.h | 10 +++++ 18 files changed, 254 insertions(+), 42 deletions(-) create mode 100644 cmake/modules/FindSparkle.cmake create mode 100644 ui/macosx/sparkle_bridge.h create mode 100644 ui/macosx/sparkle_bridge.m diff --git a/CMakeLists.txt b/CMakeLists.txt index 956b34d102..959dee687d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1089,6 +1089,7 @@ if(BUILD_wireshark) ) if(APPLE) list(APPEND QT_PACKAGELIST Qt5MacExtras) + ws_find_package(Sparkle ENABLE_SPARKLE HAVE_SOFTWARE_UPDATE) endif() if(WIN32) list(APPEND QT_PACKAGELIST Qt5WinExtras) @@ -1651,6 +1652,7 @@ endif() feature_summary(WHAT ALL) +# Should this be part of libui? if(WIN32) set(PLATFORM_UI_SRC ui/win32/console_win32.c @@ -1663,6 +1665,9 @@ elseif(APPLE) set(PLATFORM_UI_SRC ui/macosx/cocoa_bridge.mm ) + if (SPARKLE_FOUND) + list(APPEND PLATFORM_UI_SRC ui/macosx/sparkle_bridge.m) + endif() endif() set(TSHARK_TAP_SRC @@ -2266,6 +2271,7 @@ if(BUILD_wireshark AND QT_FOUND) ${APPLE_APPKIT_LIBRARY} ${APPLE_CORE_FOUNDATION_LIBRARY} ${APPLE_SYSTEM_CONFIGURATION_LIBRARY} + ${SPARKLE_LIBRARY} ${WIN_WS2_32_LIBRARY} ${WIN_VERSION_LIBRARY} ${WINSPARKLE_LIBRARIES} @@ -2312,6 +2318,7 @@ if(BUILD_wireshark AND QT_FOUND) endif() target_link_libraries(wireshark ${wireshark_LIBS}) + target_include_directories(wireshark SYSTEM PRIVATE ${SPARKLE_INCLUDE_DIR}) install( TARGETS wireshark diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 8745f2da90..fb9133ec7d 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -75,7 +75,7 @@ option(ENABLE_LUA "Build with Lua dissector support" ON) option(ENABLE_SMI "Build with libsmi snmp support" ON) option(ENABLE_GNUTLS "Build with RSA decryption support" ON) if(WIN32) - option(ENABLE_WINSPARKLE "Enable WinSparkle support" ON) + option(ENABLE_WINSPARKLE "Enable automatic updates using WinSparkle" ON) endif() if (NOT WIN32) option(ENABLE_CAP "Build with Posix capabilities support" ON) @@ -105,4 +105,5 @@ endif() if(APPLE) option(ENABLE_APPLICATION_BUNDLE "Build a macOS application bundle (Wireshark.app)" ON) + option(ENABLE_SPARKLE "Enable automatic updates using Sparkle" ON) endif() diff --git a/cmake/modules/FindSparkle.cmake b/cmake/modules/FindSparkle.cmake new file mode 100644 index 0000000000..7da80be0ea --- /dev/null +++ b/cmake/modules/FindSparkle.cmake @@ -0,0 +1,22 @@ +# +# Find the Sparkle framework +# +# This defines the following: +# SPARKLE_FOUND - True if we found Sparkle +# SPARKLE_INCLUDE_DIR - Path to Sparkle.h +# SPARKLE_LIBRARY - Path to Sparkle.framework + +include(FindPackageHandleStandardArgs) + +file(GLOB USR_LOCAL_HINT "/usr/local/Sparkle-[1-9]*/") +file(GLOB HOMEBREW_HINT "/usr/local/Caskroom/sparkle/[1-9]*/") + +find_path(SPARKLE_INCLUDE_DIR Sparkle.h + HINTS ${USR_LOCAL_HINT} ${HOMEBREW_HINT} +) +find_library(SPARKLE_LIBRARY NAMES Sparkle + HINTS ${USR_LOCAL_HINT} ${HOMEBREW_HINT} +) + +find_package_handle_standard_args(Sparkle DEFAULT_MSG SPARKLE_INCLUDE_DIR SPARKLE_LIBRARY) +mark_as_advanced(SPARKLE_INCLUDE_DIR SPARKLE_LIBRARY) diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index f6a3b15cea..bbac41f02b 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -290,7 +290,7 @@ /* Define to 1 if you have the `setresuid' function. */ #cmakedefine HAVE_SETRESUID 1 -/* Define to 1 if you have the WinSparkle library */ +/* Define to 1 if you have the Sparkle or WinSparkle library */ #cmakedefine HAVE_SOFTWARE_UPDATE 1 /* Define if you have the 'strptime' function. */ diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 1505d5d957..063c348e63 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -34,6 +34,7 @@ section below for more details. The following features are new (or have been significantly updated) since version 3.1.0: +* Automatic updates are supported on macOS. * You can now follow HTTP/2 and QUIC streams. * You can once again mark and unmark packets using the middle mouse button. This feature went missing around 2009 or so. diff --git a/packaging/macosx/Info.plist.in b/packaging/macosx/Info.plist.in index 09b08557c0..f78c1282c1 100644 --- a/packaging/macosx/Info.plist.in +++ b/packaging/macosx/Info.plist.in @@ -241,5 +241,22 @@ --> LSMinimumSystemVersion @MIN_MACOS_VERSION@ + + + SUFeedURL + https://www.wireshark.org/update/0/Wireshark/@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_PATCH_VERSION@/macOS/x86-64/en-US/stable.xml + SUEnableAutomaticChecks + + SUPublicEDKey + BeSuPpEZOmOzkON9QMnfIdwyi06P/LcVoik8M5O2bsQ= + SUEnableSystemProfiling + + + SUAutomaticallyUpdate + + diff --git a/packaging/macosx/osx-app.sh.in b/packaging/macosx/osx-app.sh.in index 3b5d17f72d..3cda62a076 100755 --- a/packaging/macosx/osx-app.sh.in +++ b/packaging/macosx/osx-app.sh.in @@ -114,6 +114,8 @@ if [ ! -d "$qt_frameworks_dir" ] ; then exit 1 fi +sparkle_frameworks_dir="@SPARKLE_LIBRARY@" + # # Leave the Qt frameworks out of the special processing. # @@ -228,6 +230,10 @@ fi # /usr/bin/install_name_tool -delete_rpath "$qt_frameworks_dir" $pkgexec/Wireshark +if [ -d "$sparkle_frameworks_dir" ] ; then + cp -r "$sparkle_frameworks_dir" "$pkglib" || exit 1 +fi + # NOTE: we must rpathify *all* files, *including* Qt libraries etc., # rpathify_file () { diff --git a/tools/macos-setup-brew.sh b/tools/macos-setup-brew.sh index b93052bd0c..0360a20e11 100755 --- a/tools/macos-setup-brew.sh +++ b/tools/macos-setup-brew.sh @@ -18,6 +18,9 @@ brew install c-ares glib libgcrypt gnutls lua@5.1 cmake python nghttp2 snappy lz #install Qt5 brew install qt5 +# Uncomment to enable automatic updates using Sparkle +#brew cask install sparkle + # # Editor modelines # diff --git a/tools/macos-setup.sh b/tools/macos-setup.sh index dc8acb9d9e..5b349ab98d 100755 --- a/tools/macos-setup.sh +++ b/tools/macos-setup.sh @@ -172,6 +172,8 @@ PYTHON3_VERSION=3.7.1 BROTLI_VERSION=1.0.7 # minizip ZLIB_VERSION=1.2.11 +# Uncomment to enable automatic updates using Sparkle +#SPARKLE_VERSION=1.22.0 # # Asciidoctor is required to build the documentation. @@ -1836,6 +1838,32 @@ uninstall_minizip() { fi } +install_sparkle() { + if [ "$SPARKLE_VERSION" ] && [ ! -f sparkle-$SPARKLE_VERSION-done ] ; then + echo "Downloading and installing Sparkle:" + # + # Download the tarball and unpack it in /usr/local/Sparkle-x.y.z + # + [ -f Sparkle-$SPARKLE_VERSION.tar.bz2 ] || curl -L -o Sparkle-$SPARKLE_VERSION.tar.bz2 https://github.com/sparkle-project/Sparkle/releases/download/$SPARKLE_VERSION/Sparkle-$SPARKLE_VERSION.tar.bz2 || exit 1 + $no_build && echo "Skipping installation" && return + sudo mkdir -f "/usr/local/Sparkle-$SPARKLE_VERSION" + sudo tar -C "/usr/local/Sparkle-$SPARKLE_VERSION" -xf Sparkle-$SPARKLE_VERSION.tar.bz2 + touch sparkle-$SPARKLE_VERSION-done + fi +} + +uninstall_sparkle() { + if [ -n "$installed_sparkle_version" ]; then + echo "Uninstalling Sparkle:" + sudo rm -rf "/usr/local/Sparkle-$installed_sparkle_version" + if [ "$#" -eq 1 ] && [ "$1" = "-r" ] ; then + rm -f "Sparkle-$installed_sparkle_version.tar.bz2" + fi + + installed_sparkle_version="" + fi +} + install_all() { # # Check whether the versions we have installed are the versions @@ -2234,6 +2262,17 @@ install_all() { uninstall_minizip -r fi + if [ ! -z "$installed_sparkle_version" -a \ + "$installed_sparkle_version" != "$SPARKLE_VERSION" ] ; then + echo "Installed Sparkle version is $installed_sparkle_version" + if [ -z "$SPARKLE_VERSION" ] ; then + echo "Sparkle is not requested" + else + echo "Requested Sparkle version is $SPARKLE_VERSION" + fi + uninstall_sparkle -r + fi + # # Start with curl: we may need it to download and install xz. # @@ -2341,6 +2380,8 @@ install_all() { install_brotli install_minizip + + install_sparkle } uninstall_all() { @@ -2357,6 +2398,8 @@ uninstall_all() { # We also do a "make distclean", so that we don't have leftovers from # old configurations. # + uninstall_sparkle + uninstall_minizip uninstall_brotli @@ -2568,6 +2611,7 @@ then installed_python3_version=`ls python3-*-done 2>/dev/null | sed 's/python3-\(.*\)-done/\1/'` installed_brotli_version=`ls brotli-*-done 2>/dev/null | sed 's/brotli-\(.*\)-done/\1/'` installed_minizip_version=`ls minizip-*-done 2>/dev/null | sed 's/minizip-\(.*\)-done/\1/'` + installed_sparkle_version=`ls sparkle-*-done 2>/dev/null | sed 's/sparkle-\(.*\)-done/\1/'` cd $topdir fi diff --git a/ui/macosx/sparkle_bridge.h b/ui/macosx/sparkle_bridge.h new file mode 100644 index 0000000000..ee23582f55 --- /dev/null +++ b/ui/macosx/sparkle_bridge.h @@ -0,0 +1,38 @@ +/* sparkle_bridge.h + * + * C wrapper for the Sparkle API + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +// XXX We could alternatively do this via C++: +// https://github.com/sparkle-project/Sparkle/issues/1137 + + +#ifndef SPARKLE_BRIDGE_H +#define SPARKLE_BRIDGE_H + +#include + +void sparkle_software_update_init(const char *url, bool enabled, int interval); + +void sparkle_software_update_check(void); + +#endif // SPARKLE_BRIDGE_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/macosx/sparkle_bridge.m b/ui/macosx/sparkle_bridge.m new file mode 100644 index 0000000000..a78d6a953e --- /dev/null +++ b/ui/macosx/sparkle_bridge.m @@ -0,0 +1,44 @@ +/* sparkle_bridge.m + * + * C wrapper for the Sparkle API + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include + +#import + +#import + +// https://sparkle-project.org/documentation/customization/ +// Sparkle stores its state in ~/Library/Preferences/org.wireshark.Wireshark.plist + +void sparkle_software_update_init(const char *url, bool enabled, int interval) +{ + [[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates: enabled]; + [[SUUpdater sharedUpdater] setUpdateCheckInterval: interval]; + [[SUUpdater sharedUpdater] setFeedURL: [NSURL URLWithString: [[NSString alloc] initWithUTF8String: url] ]]; +} + +void sparkle_software_update_check(void) +{ + [[SUUpdater sharedUpdater] checkForUpdatesInBackground]; +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index f2edc78db9..1376bdc35f 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -365,7 +365,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(wsApp, SIGNAL(updateRecentCaptureStatus(const QString &, qint64, bool)), this, SLOT(updateRecentCaptures())); updateRecentCaptures(); -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) connect(wsApp, SIGNAL(softwareUpdateRequested()), this, SLOT(softwareUpdateRequested()), Qt::BlockingQueuedConnection); connect(wsApp, SIGNAL(softwareUpdateClose()), this, SLOT(close()), diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index ef787cbe3d..bbe9d90d32 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -416,7 +416,7 @@ private slots: void openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata); void openTapParameterDialog(); -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) void softwareUpdateRequested(); #endif diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 0080360706..a4c6784956 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -1642,7 +1642,7 @@ void MainWindow::openTapParameterDialog() openTapParameterDialog(cfg_str, NULL, NULL); } -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) void MainWindow::softwareUpdateRequested() { // We could call testCaptureFileClose here, but that would give us yet // another dialog. Just try again later. diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp index 038d70aa37..ae00b84867 100644 --- a/ui/qt/wireshark_application.cpp +++ b/ui/qt/wireshark_application.cpp @@ -223,7 +223,7 @@ extern "C" void menu_recent_file_write_all(FILE *rf) { } } -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) /** Check to see if Wireshark can shut down safely (e.g. offer to save the * current capture). */ @@ -236,7 +236,7 @@ extern "C" int software_update_can_shutdown_callback(void) { extern "C" void software_update_shutdown_request_callback(void) { wsApp->softwareUpdateShutdownRequest(); } -#endif // HAVE_SOFTWARE_UPDATE +#endif // HAVE_SOFTWARE_UPDATE && Q_OS_WIN // Check each recent item in a separate thread so that we don't hang while // calling stat(). This is called periodically because files and entire @@ -861,7 +861,7 @@ WiresharkApplication::WiresharkApplication(int &argc, char **argv) : QPalette gui_pal = qApp->palette(); prefs_set_gui_theme_is_dark(gui_pal.windowText().color().value() > gui_pal.window().color().value()); -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) connect(this, SIGNAL(softwareUpdateQuit()), this, SLOT(quit()), Qt::QueuedConnection); #endif @@ -1301,7 +1301,7 @@ void WiresharkApplication::zoomTextFont(int zoomLevel) emit zoomMonospaceFont(zoomed_font_); } -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) bool WiresharkApplication::softwareUpdateCanShutdown() { software_update_ok_ = true; // At this point the update is ready to install, but WinSparkle has diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h index b512ec5864..01d03056b6 100644 --- a/ui/qt/wireshark_application.h +++ b/ui/qt/wireshark_application.h @@ -123,7 +123,7 @@ public: const QString windowTitleString(QStringList title_parts); const QString windowTitleString(QString title_part) { return windowTitleString(QStringList() << title_part); } void applyCustomColorsFromRecent(); -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) void rejectSoftwareUpdate() { software_update_ok_ = false; } bool softwareUpdateCanShutdown(); void softwareUpdateShutdownRequest(); @@ -156,7 +156,7 @@ private: static QString window_title_separator_; QList app_signals_; int active_captures_; -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) bool software_update_ok_; #endif @@ -194,7 +194,7 @@ signals: void checkDisplayFilter(); void fieldsChanged(); void reloadLuaPlugins(); -#ifdef HAVE_SOFTWARE_UPDATE +#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) // Each of these are called from a separate thread. void softwareUpdateRequested(); void softwareUpdateClose(); diff --git a/ui/software_update.c b/ui/software_update.c index f143e47a71..01a59b53ab 100644 --- a/ui/software_update.c +++ b/ui/software_update.c @@ -20,12 +20,15 @@ * - The schema version (fixed, 0) * - The application name (fixed, "Wireshark") * - The application version ("..") - * - The operating system (varable, one of "windows" or "osx") + * - The operating system (varable, one of "Windows" or "macOS") * - The architecture name (variable, one of "x86", "x86-64") * - The locale (fixed, "en-US) * - The update channel (variable, one of "development" or "stable") + .xml * * Based on https://wiki.mozilla.org/Software_Update:Checking_For_Updates + * + * To do for version 1: + * - Distinguish between NSIS (.exe) and WiX (.msi) on Windows. */ #ifdef HAVE_SOFTWARE_UPDATE @@ -35,28 +38,30 @@ #define SU_LOCALE "en-US" #endif /* HAVE_SOFTWARE_UPDATE */ -#if defined(HAVE_SOFTWARE_UPDATE) && defined (_WIN32) +#ifdef HAVE_SOFTWARE_UPDATE #include "glib.h" +#ifdef _WIN32 #include - #define SU_OSNAME "Windows" +#elif defined(__APPLE__) +#include +#define SU_OSNAME "macOS" +#else +#error HAVE_SOFTWARE_UPDATE can only be defined for Windows or macOS. +#endif -static GString *update_url_str = NULL; +// https://sourceforge.net/p/predef/wiki/Architectures/ +#if defined(__x86_64__) || defined(_M_X64) +#define SU_ARCH "x86-64" +#elif defined(defined(__i386__) || defined(_M_IX86) +#define SU_ARCH "x86" +#endif -static const char *get_appcast_update_url(software_update_channel_e chan) { +static char *get_appcast_update_url(software_update_channel_e chan) { + GString *update_url_str = g_string_new("");; const char *chan_name; - const char *arch = "x86"; - - if (!update_url_str) { - update_url_str = g_string_new(""); - } - - /* XXX Add WOW64 checks similar to version_info.c? */ - if (sizeof(arch) != 4) { - arch = "x86-64"; - } switch (chan) { case UPDATE_CHANNEL_DEVELOPMENT: @@ -72,11 +77,12 @@ static const char *get_appcast_update_url(software_update_channel_e chan) { SU_APPLICATION, VERSION, SU_OSNAME, - arch, + SU_ARCH, chan_name); - return update_url_str->str; + return g_string_free(update_url_str, FALSE); } +#ifdef _WIN32 /** Initialize software updates. */ void @@ -115,7 +121,32 @@ extern void software_update_cleanup(void) { win_sparkle_cleanup(); } -#else /* defined(HAVE_SOFTWARE_UPDATE) && defined (_WIN32) */ +#elif defined (__APPLE__) +/** Initialize software updates. + */ +void +software_update_init(void) { + char *update_url = get_appcast_update_url(prefs.gui_update_channel); + + sparkle_software_update_init(update_url, prefs.gui_update_enabled, prefs.gui_update_interval); + + g_free(update_url); +} + +/** Force a software update check. + */ +void +software_update_check(void) { + sparkle_software_update_check(); +} + +/** Clean up software update checking. + */ +void software_update_cleanup(void) { +} +#endif + +#else /* No updates */ /** Initialize software updates. */ @@ -134,18 +165,6 @@ software_update_check(void) { void software_update_cleanup(void) { } -/** Check to see if Wireshark can shut down safely (e.g. offer to save the - * current capture). - */ -int software_update_can_shutdown_callback(void) { - return FALSE; -} - -/** Shut down Wireshark in preparation for an upgrade. - */ -void software_update_shutdown_request_callback(void) { -} - #endif /* defined(HAVE_SOFTWARE_UPDATE) && defined (_WIN32) */ /* diff --git a/ui/software_update.h b/ui/software_update.h index 5ac764a832..b764c5b5b4 100644 --- a/ui/software_update.h +++ b/ui/software_update.h @@ -11,6 +11,14 @@ #ifndef __SOFTWARE_UPDATE_H__ #define __SOFTWARE_UPDATE_H__ +/** @file + * Automatic update routines. + * + * Routines that integrate with WinSparkle on Windows and Sparkle on + * macOS. + * @ingroup main_ui_group + */ + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -33,6 +41,7 @@ extern void software_update_check(void); */ extern void software_update_cleanup(void); +#ifdef _WIN32 /** Check to see if Wireshark can shut down safely (e.g. offer to save the * current capture). Called from a separate thread. * @@ -46,6 +55,7 @@ extern int software_update_can_shutdown_callback(void); * Does nothing on platforms that don't support software updates. */ extern void software_update_shutdown_request_callback(void); +#endif #ifdef __cplusplus }