From 96cfaf67a383cd3676a7dba61040e8c4b7a47b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig=20Bj=C3=B8rlykke?= Date: Mon, 27 Sep 2021 13:10:43 +0200 Subject: [PATCH] Qt: Reload Lua FileHandler when having a capture file Support reloading a Lua FileHandler when this is in use for a loaded capture file. Prompt to save the file if having unsaved changes because the file must be reloaded. Fixes #17615 --- debian/libwiretap0.symbols | 1 + epan/wslua/wslua.h | 1 + epan/wslua/wslua_file_handler.c | 12 +++++++++++- ui/qt/main_window_slots.cpp | 25 ++++++++++++++++++++++++- wiretap/file_access.c | 14 ++++++++++++++ wiretap/wtap.h | 2 ++ 6 files changed, 53 insertions(+), 2 deletions(-) diff --git a/debian/libwiretap0.symbols b/debian/libwiretap0.symbols index d2a133cc6f..218240f8ed 100644 --- a/debian/libwiretap0.symbols +++ b/debian/libwiretap0.symbols @@ -180,4 +180,5 @@ libwiretap.so.0 libwiretap0 #MINVER# wtap_snapshot_length@Base 1.9.1 wtap_strerror@Base 1.9.1 wtap_tsprec_string@Base 1.99.9 + wtap_uses_lua_filehandler@Base 3.5.1 wtap_write_shb_comment@Base 1.9.1 diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h index aab1c1c8e2..95c5eb559f 100644 --- a/epan/wslua/wslua.h +++ b/epan/wslua/wslua.h @@ -296,6 +296,7 @@ struct _wslua_filehandler { int write_close_ref; int file_type; gboolean registered; + gboolean removed; /* This is set during reload Lua plugins */ }; struct _wslua_dir { diff --git a/epan/wslua/wslua_file_handler.c b/epan/wslua/wslua_file_handler.c index 0e2b8f6e82..6ddfed8714 100644 --- a/epan/wslua/wslua_file_handler.c +++ b/epan/wslua/wslua_file_handler.c @@ -75,6 +75,9 @@ report_error(int *err, gchar **err_info, const char *fmt, ...) report_error(err, err_info, "Error in file %s: no Lua FileHandler object", #name); \ return retval; \ } \ + if (fh->removed) { \ + return retval; \ + } \ if (!fh->registered) { \ report_error(err, err_info, "Error in file %s: Lua FileHandler is not registered", #name); \ return retval; \ @@ -310,6 +313,11 @@ wslua_filehandler_seek_read(wtap *wth, gint64 seek_off, CaptureInfo *fc = NULL; FrameInfo *fi = NULL; + if (fh->removed) { + /* Return success when removed during reloading Lua plugins */ + return TRUE; + } + INIT_FILEHANDLER_ROUTINE(seek_read,FALSE,err,err_info); /* Reset errno */ @@ -1285,7 +1293,9 @@ int FileHandler_register(lua_State* L) { int wslua_deregister_filehandlers(lua_State* L _U_) { for (GSList *it = registered_file_handlers; it; it = it->next) { - wslua_deregister_filehandler_work((FileHandler)it->data); + FileHandler fh = (FileHandler)it->data; + wslua_deregister_filehandler_work(fh); + fh->removed = TRUE; } g_slist_free(registered_file_handlers); registered_file_handlers = NULL; diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index a6f313d94c..01009f53b9 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -1529,6 +1529,22 @@ void MainWindow::reloadLuaPlugins() if (wsApp->isReloadingLua()) return; + gboolean uses_lua_filehandler = FALSE; + + if (capture_file_.capFile()) { + // Check if the current capture file is opened with a Lua FileHandler + capture_file *cf = capture_file_.capFile(); + uses_lua_filehandler = wtap_uses_lua_filehandler(cf->provider.wth); + + if (uses_lua_filehandler && cf->unsaved_changes) { + // Prompt to save the file before reloading, in case the FileHandler has changed + QString before_what(tr(" before reloading Lua plugins")); + if (!testCaptureFileClose(before_what, Reload)) { + return; + } + } + } + wsApp->setReloadingLua(true); wslua_reload_plugins(NULL, NULL); @@ -1544,7 +1560,14 @@ void MainWindow::reloadLuaPlugins() prefs_apply_all(); fieldsChanged(); - redissectPackets(); + + if (uses_lua_filehandler) { + // Reload the file in case the FileHandler has changed + cf_reload(capture_file_.capFile()); + proto_free_deregistered_fields(); + } else { + redissectPackets(); + } wsApp->setReloadingLua(false); SimpleDialog::displayQueuedMessages(); diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 896a3317f0..93c638f5ba 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -591,6 +591,20 @@ wtap_has_open_info(const gchar *name) return FALSE; } +gboolean +wtap_uses_lua_filehandler(const wtap* wth) +{ + if (wth && wth->wslua_data != NULL) { + /* + * Currently, wslua_data is set if and only if using a Lua + * file handler. + */ + return TRUE; + } + + return FALSE; +} + /* * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't * define them either.) diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 2a59e7f6e0..dd23d31d20 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -2236,6 +2236,8 @@ void wtap_register_open_info(struct open_info *oi, const gboolean first_routine) WS_DLL_PUBLIC gboolean wtap_has_open_info(const gchar *name); WS_DLL_PUBLIC +gboolean wtap_uses_lua_filehandler(const wtap* wth); +WS_DLL_PUBLIC void wtap_deregister_open_info(const gchar *name); WS_DLL_PUBLIC