This patch adds support for configuration profiles, which can be used to

configure and use more than one set of preferences and configuration files.

This can be found in the "Configuration Profiles..." menu item from the Edit
menu, or by pressing Shift-Ctrl-A.  It's also possible to start wireshark
and tshark with a named profile by using the "-C ProfileName" option.
A new status pane in the main window will show the current profile.

The configuration files currently stored in the Profiles are:
- Preferences
- Capture Filters
- Display Filters
- Coloring Rules
- Disabled Protocols
- User Accessible Tables

The recent data are by design not added to the profile.

Planned future enhancements:
- make a more convenient function to switch between profiles
- add a "clone profile" button to copy an existing profile
- make the profiles list active and accept return as OK
- save users "Decode as" in the profile
- make new, clone and deletion of profiles more secure
- make some of the recent values available in the profile

This patch also fixes:
- setting default status pane sizes
- a bug setting status pane for packets when not having main lower pane.

svn path=/trunk/; revision=24089
This commit is contained in:
Stig Bjørlykke 2008-01-14 16:40:23 +00:00
parent e189eb8887
commit a2d1e9005d
37 changed files with 1587 additions and 159 deletions

View File

@ -298,6 +298,23 @@ color_filters_init(void)
color_filters_read_globals(&color_filter_list);
}
void
color_filters_reload(void)
{
/* "move" old entries to the deleted list
* we must keep them until the dissection no longer needs them */
color_filter_deleted_list = g_slist_concat(color_filter_deleted_list, color_filter_list);
color_filter_list = NULL;
/* start the list with the temporary colorizing rules */
color_filters_add_tmp(&color_filter_list);
/* try to read the users filters */
if (!read_users_filters(&color_filter_list))
/* if that failed, try to read the global filters */
color_filters_read_globals(&color_filter_list);
}
void
color_filters_cleanup(void)
{
@ -612,7 +629,7 @@ read_users_filters(GSList **cfl)
gboolean ret;
/* decide what file to open (from dfilter code) */
path = get_persconffile_path("colorfilters", FALSE);
path = get_persconffile_path("colorfilters", TRUE, FALSE);
if ((f = eth_fopen(path, "r")) == NULL) {
if (errno != ENOENT) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@ -737,7 +754,7 @@ color_filters_write(GSList *cfl)
return FALSE;
}
path = get_persconffile_path("colorfilters", TRUE);
path = get_persconffile_path("colorfilters", TRUE, TRUE);
if ((f = eth_fopen(path, "w+")) == NULL) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Could not open\n%s\nfor writing: %s.",

View File

@ -50,6 +50,9 @@ typedef struct _color_filter {
/** Init the color filters (incl. initial read from file). */
void color_filters_init(void);
/** Reload the color filters */
void color_filters_reload(void);
/** Cleanup remaining color filter zombies */
void color_filters_cleanup(void);

View File

@ -108,7 +108,7 @@ read_disabled_protos_list(char **gpath_return, int *gopen_errno_return,
}
/* Construct the pathname of the user's disabled protocols file. */
ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, FALSE);
ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, TRUE, FALSE);
/* Read the user's disabled protocols file, if it exists. */
*path_return = NULL;
@ -319,7 +319,6 @@ void
save_disabled_protos_list(char **pref_path_return, int *errno_return)
{
gchar *ff_path, *ff_path_new;
const gchar *ff_name;
FILE *ff;
gint i;
protocol_t *protocol;
@ -327,9 +326,7 @@ save_disabled_protos_list(char **pref_path_return, int *errno_return)
*pref_path_return = NULL; /* assume no error */
ff_name = PROTOCOLS_FILE_NAME;
ff_path = get_persconffile_path(ff_name, TRUE);
ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, TRUE, TRUE);
/* Write to "XXX.new", and rename if that succeeds.
That means we don't trash the file if we fail to write it out

View File

@ -178,6 +178,7 @@ FILE SECTION
<!ENTITY WiresharkGUIColumnsPreferences SYSTEM "./wsug_graphics/ws-gui-columns-preferences.png" NDATA PNG>
<!ENTITY WiresharkGUIFontPreferences SYSTEM "./wsug_graphics/ws-gui-font-preferences.png" NDATA PNG>
<!ENTITY WiresharkGUIColorsPreferences SYSTEM "./wsug_graphics/ws-gui-colors-preferences.png" NDATA PNG>
<!ENTITY WiresharkGUIConfigProfiles SYSTEM "./wsug_graphics/ws-gui-config-profiles.png" NDATA PNG>
<!ENTITY WiresharkCapturePreferences SYSTEM "./wsug_graphics/ws-capture-preferences.png" NDATA PNG>
<!ENTITY WiresharkPrintingPreferences SYSTEM "./wsug_graphics/ws-printing-preferences.png" NDATA PNG>
<!ENTITY WiresharkNameResolutionPreferences SYSTEM "./wsug_graphics/ws-nameresolution-preferences.png" NDATA PNG>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -929,6 +929,157 @@ standard libpcap format.
<graphic entityref="WiresharkGUIPreferences" format="PNG"/>
</figure>
</section>
<section id="ChCustConfigProfilesSection"><title>Configuration Profiles</title>
<para>
Configuration Profiles can be used to configure and use more than one set of preferences
and configurations. Select the <command>Configuration Profiles...</command> menu item from
the <command>Edit</command> menu, or simply press Shift-Ctrl-A; and Wireshark will pop up the
Configuration Profiles dialog box as shown in <xref linked="ChCustGUIConfigProfilesPage"/>.
</para>
<para>
Configuration files stored in the Profiles:
<itemizedlist>
<listitem>
<para>
Preferences (preferences)
</para>
</listitem>
<listitem>
<para>
Capture Filters (cfilters)
</para>
</listitem>
<listitem>
<para>
Display Filters (dfilters)
</para>
</listitem>
<listitem>
<para>
Coloring Rules (colorfilters)
</para>
</listitem>
<listitem>
<para>
Disabled Protocols (disabled_protos)
</para>
</listitem>
<listitem>
<para>
User Accessible Tables:
<itemizedlist>
<listitem>
<para>
Display Filter Macros (dfilter_macros)
</para>
</listitem>
<listitem>
<para>
K12 Protocols (k12_protos)
</para>
</listitem>
<listitem>
<para>
SCCP Users Table (sccp_users)
</para>
</listitem>
<listitem>
<para>
SMI Modules (smi_modules)
</para>
</listitem>
<listitem>
<para>
SMI Paths (smi_paths)
</para>
</listitem>
<listitem>
<para>
SNMP Users (snmp_users)
</para>
</listitem>
<listitem>
<para>
User DLTs Table (user_dlts)
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
<note><title>Note!</title>
<para>
All other configurations are stored in the personal configuration folder,
and are common to all profiles.
</para>
</note>
</para>
<figure id="ChCustGUIConfigProfilesPage">
<title>The configuration profiles dialog box</title>
<graphic entityref="WiresharkGUIConfigProfiles" format="PNG"/>
</figure>
<para>
<variablelist>
<varlistentry><term><command>New</command></term>
<listitem>
<para>
This button adds a new profile to the profiles list.
</para>
</listitem>
</varlistentry>
<varlistentry><term><command>Delete</command></term>
<listitem>
<para>
This button deletes the selected profile.
</para>
</listitem>
</varlistentry>
<varlistentry><term><command>Configuration Profiles</command></term>
<listitem>
<para>
You can select a configuration profile from this list (which will fill
in the profile name in the fields down at the bottom of the dialog box).
</para>
</listitem>
</varlistentry>
<varlistentry><term><command>Profile name:</command></term>
<listitem>
<para>
You can change the name of the currently selected profile here.
</para>
<note><title>Note!</title>
<para>
The profile name will be used as a folder name in the configured
"Personal configurations" folder. If adding multiple profiles with the
same name, only one profile will be created.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry><term><command>OK</command></term>
<listitem>
<para>
This button saves all changes, applies the selected profile and closes the dialog.
</para>
</listitem>
</varlistentry>
<varlistentry><term><command>Apply</command></term>
<listitem>
<para>
This button saves all changes, applies the selected profile and keeps the dialog open.
</para>
</listitem>
</varlistentry>
<varlistentry><term><command>Cancel</command></term>
<listitem>
<para>
Close this dialog. This will discard unsaved settings.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section id="ChUserTable"><title>User Table</title>
<para>
The User Table editor is used for managing various tables in wireshark. Its main dialog works

View File

@ -444,7 +444,7 @@ static void initialize_services(void)
/* set personal services path */
if (g_pservices_path == NULL)
g_pservices_path = get_persconffile_path(ENAME_SERVICES, FALSE);
g_pservices_path = get_persconffile_path(ENAME_SERVICES, FALSE, FALSE);
parse_services_file(g_pservices_path);
@ -1194,7 +1194,7 @@ static void initialize_ethers(void)
* with it. It's used in get_ethbyname() and get_ethbyaddr()
*/
if (g_pethers_path == NULL)
g_pethers_path = get_persconffile_path(ENAME_ETHERS, FALSE);
g_pethers_path = get_persconffile_path(ENAME_ETHERS, FALSE, FALSE);
/* manuf hash table initialization */
@ -1587,7 +1587,7 @@ static void initialize_ipxnets(void)
* with it. It's used in get_ipxnetbyname() and get_ipxnetbyaddr()
*/
if (g_pipxnets_path == NULL)
g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, FALSE);
g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, FALSE, FALSE);
} /* initialize_ipxnets */
@ -1784,7 +1784,7 @@ host_name_lookup_init(void) {
/*
* Load the user's hosts file, if they have one.
*/
hostspath = get_persconffile_path(ENAME_HOSTS, FALSE);
hostspath = get_persconffile_path(ENAME_HOSTS, FALSE, FALSE);
if (!read_hosts_file(hostspath) && errno != ENOENT) {
report_open_failure(hostspath, errno, FALSE);
}

View File

@ -1527,7 +1527,7 @@ proto_register_radius(void)
g_array_append_vals(ri.hf, base_hf, array_length(base_hf));
g_array_append_vals(ri.ett, base_ett, array_length(base_ett));
dir = get_persconffile_path("radius", FALSE);
dir = get_persconffile_path("radius", FALSE, FALSE);
if (test_for_directory(dir) != EISDIR) {
/* Although dir isn't a directory it may still use memory */

View File

@ -1139,7 +1139,7 @@ static void init_xml_names(void) {
xmlpi_xml_ns->elements = NULL;
dirname = get_persconffile_path("dtds", FALSE);
dirname = get_persconffile_path("dtds", FALSE, FALSE);
if (test_for_directory(dirname) != EISDIR) {
/* Although dir isn't a directory it may still use memory */

View File

@ -55,10 +55,12 @@
#include "privileges.h"
#include <wiretap/file_util.h>
#define PROFILES_DIR "profiles"
#define U3_MY_CAPTURES "\\My Captures"
char *persconffile_dir = NULL;
char *persdatafile_dir = NULL;
char *persconfprofile = NULL;
/*
* Given a pathname, return a pointer to the last pathname separator
@ -780,6 +782,27 @@ char *getenv_utf8(const char *varname)
}
#endif
void
set_profile_name(const gchar *profilename)
{
if (persconfprofile) {
g_free (persconfprofile);
}
if (profilename && strlen(profilename) > 0) {
persconfprofile = g_strdup (profilename);
} else {
/* Default Profile */
persconfprofile = NULL;
}
}
const char *
get_profile_name(void)
{
return persconfprofile;
}
/*
* Get the directory in which personal configuration files reside;
* in UNIX-compatible systems, it's ".wireshark", under the user's home
@ -788,7 +811,7 @@ char *getenv_utf8(const char *varname)
* (which is what %APPDATA% normally is on Windows 2000).
*/
static const char *
get_persconffile_dir(void)
get_persconffile_dir_no_profile(void)
{
#ifdef _WIN32
char *appdatadir;
@ -828,7 +851,7 @@ get_persconffile_dir(void)
* Concatenate %APPDATA% with "\Wireshark".
*/
persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
appdatadir, PF_DIR);
appdatadir, PF_DIR);
} else {
/*
* OK, %APPDATA% wasn't set, so use
@ -874,6 +897,119 @@ get_persconffile_dir(void)
return persconffile_dir;
}
const char *
get_profiles_dir(void)
{
static char *profiles_dir = NULL;
if (profiles_dir) {
g_free (profiles_dir);
}
profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
G_DIR_SEPARATOR_S, PROFILES_DIR);
return profiles_dir;
}
static const char *
get_persconffile_dir(const gchar *profilename)
{
static char *persconffile_profile_dir = NULL;
if (persconffile_profile_dir) {
g_free (persconffile_profile_dir);
}
if (profilename) {
persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (), G_DIR_SEPARATOR_S,
profilename);
} else {
persconffile_profile_dir = g_strdup_printf (get_persconffile_dir_no_profile ());
}
return persconffile_profile_dir;
}
gboolean
profile_exists(const gchar *profilename)
{
if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
return TRUE;
}
return FALSE;
}
static int
delete_directory (const char *directory, char **pf_dir_path_return)
{
ETH_DIR *dir;
ETH_DIRENT *file;
gchar *filename;
int ret = 0;
if ((dir = eth_dir_open(directory, 0, NULL)) != NULL) {
while ((file = eth_dir_read_name(dir)) != NULL) {
filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S, eth_dir_get_name(file));
if (test_for_directory(filename) != EISDIR) {
ret = eth_remove(filename);
#if 0
} else {
/* The user has manually created a directory in the profile directory */
/* I do not want to delete the directory recursively yet */
ret = delete_directory (filename, pf_dir_path_return);
#endif
}
if (ret != 0) {
*pf_dir_path_return = filename;
break;
}
g_free (filename);
}
eth_dir_close(dir);
}
if (ret == 0 && (ret = eth_remove(directory)) != 0) {
*pf_dir_path_return = g_strdup (directory);
}
return ret;
}
int
delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
{
const char *profile_dir = get_persconffile_dir(profilename);
int ret = 0;
if (test_for_directory (profile_dir) == EISDIR) {
ret = delete_directory (profile_dir, pf_dir_path_return);
}
return ret;
}
int
rename_persconffile_profile(const char *fromname, const char *toname,
char **pf_from_dir_path_return, char **pf_to_dir_path_return)
{
char *from_dir = g_strdup (get_persconffile_dir(fromname));
char *to_dir = g_strdup (get_persconffile_dir(toname));
int ret = 0;
ret = eth_rename (from_dir, to_dir);
if (ret != 0) {
*pf_from_dir_path_return = g_strdup (from_dir);
*pf_to_dir_path_return = g_strdup (to_dir);
}
g_free (from_dir);
g_free (to_dir);
return ret;
}
/*
* Create the directory that holds personal configuration files, if
* necessary. If we attempted to create it, and failed, return -1 and
@ -882,7 +1018,7 @@ get_persconffile_dir(void)
* return 0.
*/
int
create_persconffile_dir(char **pf_dir_path_return)
create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
{
const char *pf_dir_path;
#ifdef _WIN32
@ -891,8 +1027,23 @@ create_persconffile_dir(char **pf_dir_path_return)
#endif
struct stat s_buf;
int ret;
if (profilename) {
/*
* Check if profiles directory exists.
* If not then create it.
*/
pf_dir_path = get_profiles_dir ();
if (eth_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
ret = eth_mkdir(pf_dir_path, 0755);
if (ret == -1) {
*pf_dir_path_return = g_strdup(pf_dir_path);
return ret;
}
}
}
pf_dir_path = get_persconffile_dir();
pf_dir_path = get_persconffile_dir(profilename);
if (eth_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
#ifdef _WIN32
/*
@ -940,6 +1091,12 @@ create_persconffile_dir(char **pf_dir_path_return)
return ret;
}
int
create_persconffile_dir(char **pf_dir_path_return)
{
return create_persconffile_profile(get_profile_name(), pf_dir_path_return);
}
/*
* Get the (default) directory in which personal data is stored.
*
@ -1065,7 +1222,7 @@ get_home_dir(void)
* from earlier versions can be read.
*/
char *
get_persconffile_path(const char *filename, gboolean for_writing
get_persconffile_path(const char *filename, gboolean from_profile, gboolean for_writing
#ifndef _WIN32
_U_
#endif
@ -1077,8 +1234,13 @@ get_persconffile_path(const char *filename, gboolean for_writing
char *old_path;
#endif
path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_persconffile_dir(),
filename);
if (from_profile) {
path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
get_persconffile_dir(get_profile_name()), filename);
} else {
path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
get_persconffile_dir(NULL), filename);
}
#ifdef _WIN32
if (!for_writing) {
if (eth_stat(path, &s_buf) != 0 && errno == ENOENT) {

View File

@ -70,6 +70,55 @@ extern char *get_datafile_path(const char *filename);
*/
extern const char *get_systemfile_dir(void);
/*
* Set the configuration profile name to be used for storing
* personal configuration files.
*/
extern void set_profile_name(const gchar *profilename);
/*
* Get the current configuration profile name used for storing
* personal configuration files.
*/
extern const char *get_profile_name(void);
/*
* Get the directory used to store configuration profile directories.
*/
extern const char *get_profiles_dir(void);
/*
* Check if given configuration profile exists.
*/
extern gboolean profile_exists(const gchar *profilename);
/*
* Create a directory for the given configuration profile.
* If we attempted to create it, and failed, return -1 and
* set "*pf_dir_path_return" to the pathname of the directory we failed
* to create (it's g_mallocated, so our caller should free it); otherwise,
* return 0.
*/
extern int create_persconffile_profile(const char *profilename,
char **pf_dir_path_return);
/*
* Delete the directory for the given configuration profile.
* If we attempted to delete it, and failed, return -1 and
* set "*pf_dir_path_return" to the pathname of the directory we failed
* to delete (it's g_mallocated, so our caller should free it); otherwise,
* return 0.
*/
extern int delete_persconffile_profile(const char *profilename,
char **pf_dir_path_return);
/*
* Rename the directory for the given confinguration profile.
*/
extern int rename_persconffile_profile(const char *fromname, const char *toname,
char **pf_from_dir_path_return,
char **pf_to_dir_path_return);
/*
* Create the directory that holds personal configuration files, if
* necessary. If we attempted to create it, and failed, return -1 and
@ -81,7 +130,8 @@ extern int create_persconffile_dir(char **pf_dir_path_return);
/*
* Construct the path name of a personal configuration file, given the
* file name.
* file name. If using configuration profiles this directory will be
* used if "from_profile" is TRUE.
*
* On Win32, if "for_writing" is FALSE, we check whether the file exists
* and, if not, construct a path name relative to the ".wireshark"
@ -89,7 +139,8 @@ extern int create_persconffile_dir(char **pf_dir_path_return);
* exists; if it does, we return that, so that configuration files
* from earlier versions can be read.
*/
extern char *get_persconffile_path(const char *filename, gboolean for_writing);
extern char *get_persconffile_path(const char *filename, gboolean from_profile,
gboolean for_writing);
/*
* Get the (default) directory in which personal data is stored.

View File

@ -99,6 +99,7 @@ copy_prefs
crc16_ccitt_tvb
create_dissector_handle
create_persconffile_dir
create_persconffile_profile
data_out_file DATA
dcerpc_add_conv_to_bind_table
dcerpc_get_proto_hf_opnum
@ -117,6 +118,7 @@ decode_boolean_bitfield
decode_enumerated_bitfield_shifted
decode_enumerated_bitfield
decode_numeric_bitfield
delete_persconffile_profile
deletefile
dfilter_apply_edt
dfilter_compile
@ -437,6 +439,8 @@ get_persconffile_path
get_persdatafile_dir
get_plugin_dir
get_plugins_pers_dir
get_profile_name
get_profiles_dir
get_progfile_dir
get_rose_ctx
get_systemfile_dir
@ -572,14 +576,17 @@ prefs_register_static_text_preference
prefs_register_string_preference
prefs_register_uat_preference
prefs_register_uint_preference
prefs_reset
prefs_set_pref
process_reassembled_data
process_stat_cmd_arg
profile_exists
proto_all_finfos
proto_can_match_selected
proto_can_toggle_protocol
proto_construct_match_selected_string
proto_data DATA
proto_enable_all
proto_find_field_from_offset
proto_find_finfo
proto_frame DATA
@ -730,6 +737,7 @@ rel_time_to_secs_str
rel_time_to_str
relinquish_special_privs_perm
remove_tap_listener
rename_persconffile_profile
report_failure
report_open_failure
report_read_failure
@ -770,6 +778,7 @@ se_strndup
se_tree_create
se_tree_create_non_persistent
set_actual_length
set_profile_name
show_fragment_seq_tree
show_fragment_tree
sid_name_snooping DATA
@ -923,6 +932,7 @@ uat_fld_chk_str_isxdigit
uat_foreach_table
uat_load
uat_new
uat_reload_all
uat_remove_record_idx
uat_save
uat_swap

View File

@ -454,7 +454,7 @@ static inline oid_kind_t smikind(SmiNode* sN, oid_key_t** key_p) {
#ifdef WIN32
#define PATH_SEPARATOR ";"
#define DEFAULT_PATH_FMT "%s;%s"
#define DEFAULT_PATH_ARGS get_datafile_path("snmp\\mibs"), get_persconffile_path("snmp\\mibs", FALSE)
#define DEFAULT_PATH_ARGS get_datafile_path("snmp\\mibs"), get_persconffile_path("snmp\\mibs", FALSE, FALSE)
#else
#define PATH_SEPARATOR ":"
#define DEFAULT_PATH_FMT "%s"

View File

@ -371,7 +371,7 @@ plugins_scan_dir(const char *dirname)
/* Return value is malloced so the caller should g_free() it. */
char *get_plugins_pers_dir(void)
{
return get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
return get_persconffile_path(PLUGINS_DIR_NAME, FALSE, FALSE);
}
/*

View File

@ -1221,6 +1221,13 @@ init_prefs(void) {
prefs_initialized = TRUE;
}
/* Reset preferences */
void
prefs_reset(void)
{
prefs_initialized = FALSE;
init_prefs();
}
/* Read the preferences file, fill in "prefs", and return a pointer to it.
@ -1305,7 +1312,7 @@ read_prefs(int *gpf_errno_return, int *gpf_read_errno_return,
}
/* Construct the pathname of the user's preferences file. */
pf_path = get_persconffile_path(PF_NAME, FALSE);
pf_path = get_persconffile_path(PF_NAME, TRUE, FALSE);
/* Read the user's preferences file, if it exists. */
*pf_path_return = NULL;
@ -2440,7 +2447,7 @@ write_prefs(char **pf_path_return)
*/
if (pf_path_return != NULL) {
pf_path = get_persconffile_path(PF_NAME, TRUE);
pf_path = get_persconffile_path(PF_NAME, TRUE, TRUE);
if ((pf = eth_fopen(pf_path, "w")) == NULL) {
*pf_path_return = pf_path;
return errno;

View File

@ -169,6 +169,9 @@ typedef struct pref_module module_t;
/** Sets up memory used by proto routines. Called at program startup */
extern void prefs_init(void);
/** Reset preferences to default values. Called at profile change */
extern void prefs_reset(void);
/** Frees memory used by proto routines. Called at program shutdown */
extern void prefs_cleanup(void);

View File

@ -3730,6 +3730,23 @@ proto_set_decoding(int proto_id, gboolean enabled)
protocol->is_enabled = enabled;
}
void
proto_enable_all(void)
{
protocol_t *protocol;
GList *list_item = protocols;
if (protocols == NULL)
return;
while (list_item) {
protocol = list_item->data;
if (protocol->can_toggle)
protocol->is_enabled = TRUE;
list_item = g_list_next(list_item);
}
}
void
proto_set_cant_toggle(int proto_id)
{

View File

@ -1507,6 +1507,9 @@ extern const char *proto_get_protocol_filter_name(int proto_id);
@param enabled enable / disable the protocol */
extern void proto_set_decoding(int proto_id, gboolean enabled);
/** Enable all protocols */
extern void proto_enable_all(void);
/** Disable disabling/enabling of protocol of the given item number.
@param proto_id protocol id (0-indexed) */
extern void proto_set_cant_toggle(int proto_id);

View File

@ -155,7 +155,7 @@ void uat_remove_record_idx(uat_t* uat, guint idx) {
}
gchar* uat_get_actual_filename(uat_t* uat, gboolean for_writing) {
gchar* pers_fname = get_persconffile_path(uat->filename,for_writing);
gchar* pers_fname = get_persconffile_path(uat->filename, TRUE, for_writing);
if (! for_writing ) {
gchar* data_fname = get_datafile_path(uat->filename);
@ -285,6 +285,18 @@ void* uat_se_dup(uat_t* uat, guint* len_p) {
return size ? se_memdup(uat->user_data->data,size) : NULL ;
}
void uat_reload_all(void) {
guint i;
for (i=0; i < all_uats->len; i++) {
uat_t* u = g_ptr_array_index(all_uats,i);
uat_clear(u);
u->loaded = FALSE;
}
uat_load_all();
}
void uat_cleanup(void) {
while( all_uats->len ) {
uat_destroy((uat_t*)all_uats->pdata);

View File

@ -269,6 +269,7 @@ gboolean uat_fld_chk_str_ ## what (void*, const char*, unsigned, void*, void*, c
typedef void (*uat_cb_t)(void* uat,void* user_data);
void uat_foreach_table(uat_cb_t cb,void* user_data);
void uat_reload_all(void);
char* uat_undquote(const char* si, guint in_len, guint* len_p);
char* uat_unbinstring(const char* si, guint in_len, guint* len_p);

View File

@ -296,7 +296,7 @@ int wslua_init(lua_State* LS) {
/* if we are indeed superuser run user scripts only if told to do so */
if ( (!started_with_special_privs()) || run_anyway ) {
filename = get_persconffile_path("init.lua", FALSE);
filename = get_persconffile_path("init.lua", FALSE, FALSE);
if (( file_exists(filename))) {
lua_load_script(filename);

View File

@ -165,7 +165,7 @@ const char* wslua_get_actual_filename(const char* fname) {
return fname_clean;
}
filename = get_persconffile_path(fname_clean,FALSE);
filename = get_persconffile_path(fname_clean,FALSE,FALSE);
if ( file_exists(filename) ) {
return filename;
@ -220,7 +220,7 @@ WSLUA_FUNCTION wslua_dofile(lua_State* L) {
WSLUA_FUNCTION wslua_persconffile_path(lua_State* L) {
#define WSLUA_OPTARG_persconffile_path_FILENAME 1 /* a filename */
const char *fname = luaL_optstring(L, WSLUA_OPTARG_persconffile_path_FILENAME,"");
const char* filename = get_persconffile_path(fname,FALSE);
const char* filename = get_persconffile_path(fname,FALSE,FALSE);
lua_pushstring(L,filename);
WSLUA_RETURN(1); /* the full pathname for a file in the personal configuration directory */

View File

@ -145,7 +145,7 @@ read_filter_list(filter_list_type_t list_type, char **pref_path_return,
}
/* try to open personal "cfilters"/"dfilters" file */
ff_path = get_persconffile_path(ff_name, FALSE);
ff_path = get_persconffile_path(ff_name, TRUE, FALSE);
if ((ff = eth_fopen(ff_path, "r")) == NULL) {
/*
* Did that fail because the file didn't exist?
@ -168,7 +168,7 @@ read_filter_list(filter_list_type_t list_type, char **pref_path_return,
* a particular list.
*/
g_free(ff_path);
ff_path = get_persconffile_path(FILTER_FILE_NAME, FALSE);
ff_path = get_persconffile_path(FILTER_FILE_NAME, FALSE, FALSE);
if ((ff = eth_fopen(ff_path, "r")) == NULL) {
/*
* Did that fail because the file didn't exist?
@ -487,7 +487,7 @@ save_filter_list(filter_list_type_t list_type, char **pref_path_return,
return;
}
ff_path = get_persconffile_path(ff_name, TRUE);
ff_path = get_persconffile_path(ff_name, TRUE, TRUE);
/* Write to "XXX.new", and rename if that succeeds.
That means we don't trash the file if we fail to write it out

View File

@ -98,6 +98,7 @@ noinst_HEADERS = \
plugins_dlg.h \
prefs_dlg.h \
print_prefs.h \
profile_dlg.h \
proto_dlg.h \
proto_draw.h \
proto_hier_stats_dlg.h \

View File

@ -96,6 +96,7 @@ WIRESHARK_GTK_SRC = \
prefs_dlg.c \
print_dlg.c \
print_prefs.c \
profile_dlg.c \
progress_dlg.c \
proto_dlg.c \
proto_draw.c \

View File

@ -369,7 +369,7 @@ about_folders_page_new(void)
g_free((void *) path);
/* pers conf */
path = get_persconffile_path("", FALSE);
path = get_persconffile_path("", FALSE, FALSE);
about_folders_row(table, "Personal configuration", path,
"\"dfilters\", \"preferences\", \"ethers\", ...");
g_free((void *) path);

View File

@ -410,6 +410,9 @@ topic_action(topic_action_e action)
case(HELP_COLORING_RULES_DIALOG):
help_topic_html("ChCustColorizationSection.html");
break;
case(HELP_CONFIG_PROFILES_DIALOG):
help_topic_html("ChCustConfigProfilesSection.html");
break;
case(HELP_PRINT_DIALOG):
help_topic_html("ChIOPrintSection.html");
break;

View File

@ -57,6 +57,7 @@ typedef enum {
HELP_CAPTURE_FILTERS_DIALOG,
HELP_DISPLAY_FILTERS_DIALOG,
HELP_COLORING_RULES_DIALOG,
HELP_CONFIG_PROFILES_DIALOG,
HELP_PRINT_DIALOG,
HELP_FIND_DIALOG,
HELP_FILESET_DIALOG,

View File

@ -98,6 +98,7 @@
#include "merge.h"
#include "u3.h"
#include "uat_gui.h"
#include "epan/uat.h"
#ifdef HAVE_LIBPCAP
@ -210,7 +211,7 @@ GtkWidget *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
GtkWidget *pkt_scrollw;
static GtkWidget *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
static GtkWidget *main_first_pane, *main_second_pane;
static GtkWidget *status_pane;
static GtkWidget *status_pane_left, *status_pane_right;
static GtkWidget *menubar, *main_vbox, *main_tb, *stat_hbox, *filter_tb;
static GtkWidget *priv_warning_dialog;
@ -222,10 +223,13 @@ static int airpcap_dll_ret_val = -1;
static GtkWidget *info_bar;
static GtkWidget *packets_bar = NULL;
static GtkWidget *profile_bar = NULL;
static GtkWidget *welcome_pane;
static guint main_ctx, file_ctx, help_ctx;
static guint packets_ctx;
static guint profile_ctx;
static gchar *packets_str = NULL;
static gchar *profile_str = NULL;
GString *comp_info_str, *runtime_info_str;
gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
@ -1033,6 +1037,29 @@ void packets_bar_update(void)
}
}
/*
* update the packets statusbar to the current values
*/
void profile_bar_update(void)
{
const char *profile_name;
if (profile_bar) {
/* remove old status */
if(profile_str) {
g_free(profile_str);
gtk_statusbar_pop(GTK_STATUSBAR(profile_bar), profile_ctx);
}
profile_name = get_profile_name ();
if (!profile_name) {
profile_name = DEFAULT_PROFILE;
}
profile_str = g_strdup_printf (" Profile: %s", profile_name);
gtk_statusbar_push(GTK_STATUSBAR(profile_bar), profile_ctx, profile_str);
}
}
void
main_set_for_capture_file(gboolean have_capture_file_in)
{
@ -1168,11 +1195,13 @@ main_load_window_geometry(GtkWidget *widget)
window_set_geometry(widget, &geom);
if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_status_pane)
gtk_paned_set_position(GTK_PANED(status_pane), recent.gui_geometry_status_pane);
if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_left)
gtk_paned_set_position(GTK_PANED(status_pane_left), recent.gui_geometry_status_pane_left);
if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_right)
gtk_paned_set_position(GTK_PANED(status_pane_right), recent.gui_geometry_status_pane_right);
}
@ -1200,7 +1229,8 @@ main_save_window_geometry(GtkWidget *widget)
recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
recent.gui_geometry_status_pane = gtk_paned_get_position(GTK_PANED(status_pane));
recent.gui_geometry_status_pane_left = gtk_paned_get_position(GTK_PANED(status_pane_left));
recent.gui_geometry_status_pane_right = gtk_paned_get_position(GTK_PANED(status_pane_right));
#endif
}
@ -1303,6 +1333,7 @@ print_usage(gboolean print_ver) {
fprintf(output, "\n");
fprintf(output, "User interface:\n");
fprintf(output, " -C <config profile> start with specified configuration profile\n");
fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
fprintf(output, " -m <font> set the font name used for most text\n");
fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
@ -2146,6 +2177,112 @@ get_gui_runtime_info(GString *str
}
static e_prefs *
read_configuration_files(char **gdp_path, char **dp_path)
{
int gpf_open_errno, gpf_read_errno;
int cf_open_errno, df_open_errno;
int gdp_open_errno, gdp_read_errno;
int dp_open_errno, dp_read_errno;
char *gpf_path, *pf_path;
char *cf_path, *df_path;
int pf_open_errno, pf_read_errno;
e_prefs *prefs;
/* Read the preference files. */
prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
&pf_open_errno, &pf_read_errno, &pf_path);
if (gpf_path != NULL) {
if (gpf_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open global preferences file\n\"%s\": %s.", gpf_path,
strerror(gpf_open_errno));
}
if (gpf_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
strerror(gpf_read_errno));
}
}
if (pf_path != NULL) {
if (pf_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your preferences file\n\"%s\": %s.", pf_path,
strerror(pf_open_errno));
}
if (pf_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading your preferences file\n\"%s\": %s.", pf_path,
strerror(pf_read_errno));
}
g_free(pf_path);
pf_path = NULL;
}
#ifdef _WIN32
/* if the user wants a console to be always there, well, we should open one for him */
if (prefs->gui_console_open == console_open_always) {
create_console();
}
#endif
/* Fill in capture options with values from the preferences */
prefs_to_capture_opts();
/* Read the capture filter file. */
read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
if (cf_path != NULL) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your capture filter file\n\"%s\": %s.", cf_path,
strerror(cf_open_errno));
g_free(cf_path);
}
/* Read the display filter file. */
read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
if (df_path != NULL) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your display filter file\n\"%s\": %s.", df_path,
strerror(df_open_errno));
g_free(df_path);
}
/* Read the disabled protocols file. */
read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
dp_path, &dp_open_errno, &dp_read_errno);
if (*gdp_path != NULL) {
if (gdp_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open global disabled protocols file\n\"%s\": %s.",
*gdp_path, strerror(gdp_open_errno));
}
if (gdp_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading global disabled protocols file\n\"%s\": %s.",
*gdp_path, strerror(gdp_read_errno));
}
g_free(*gdp_path);
*gdp_path = NULL;
}
if (*dp_path != NULL) {
if (dp_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
strerror(dp_open_errno));
}
if (dp_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
strerror(dp_read_errno));
}
g_free(*dp_path);
*dp_path = NULL;
}
return prefs;
}
/* And now our feature presentation... [ fade to music ] */
int
main(int argc, char *argv[])
@ -2162,14 +2299,7 @@ main(int argc, char *argv[])
char *rf_path;
int rf_open_errno;
char *gpf_path, *pf_path;
char *cf_path, *df_path;
char *gdp_path, *dp_path;
int gpf_open_errno, gpf_read_errno;
int pf_open_errno, pf_read_errno;
int cf_open_errno, df_open_errno;
int gdp_open_errno, gdp_read_errno;
int dp_open_errno, dp_read_errno;
int err;
#ifdef HAVE_LIBPCAP
gboolean start_capture = FALSE;
@ -2194,7 +2324,7 @@ main(int argc, char *argv[])
/*gchar *cant_get_if_list_errstr;*/
#endif
#define OPTSTRING_INIT "a:b:c:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
#define OPTSTRING_INIT "a:b:c:C:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
#if defined HAVE_LIBPCAP && defined _WIN32
#define OPTSTRING_WIN32 "B:"
@ -2315,6 +2445,14 @@ main(int argc, char *argv[])
optind_initial = optind;
while ((opt = getopt(argc, argv, optstring)) != -1) {
switch (opt) {
case 'C': /* Configuration Profile */
if (profile_exists (optarg)) {
set_profile_name (optarg);
} else {
cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
exit(1);
}
break;
case 'h': /* Print help and exit */
print_usage(TRUE);
exit(0);
@ -2502,94 +2640,7 @@ main(int argc, char *argv[])
splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
/* Read the preference files. */
prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
&pf_open_errno, &pf_read_errno, &pf_path);
if (gpf_path != NULL) {
if (gpf_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open global preferences file\n\"%s\": %s.", gpf_path,
strerror(gpf_open_errno));
}
if (gpf_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
strerror(gpf_read_errno));
}
}
if (pf_path != NULL) {
if (pf_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your preferences file\n\"%s\": %s.", pf_path,
strerror(pf_open_errno));
}
if (pf_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading your preferences file\n\"%s\": %s.", pf_path,
strerror(pf_read_errno));
}
g_free(pf_path);
pf_path = NULL;
}
#ifdef _WIN32
/* if the user wants a console to be always there, well, we should open one for him */
if (prefs->gui_console_open == console_open_always) {
create_console();
}
#endif
/* Fill in capture options with values from the preferences */
prefs_to_capture_opts();
/* Read the capture filter file. */
read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
if (cf_path != NULL) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your capture filter file\n\"%s\": %s.", cf_path,
strerror(cf_open_errno));
g_free(cf_path);
}
/* Read the display filter file. */
read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
if (df_path != NULL) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your display filter file\n\"%s\": %s.", df_path,
strerror(df_open_errno));
g_free(df_path);
}
/* Read the disabled protocols file. */
read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
&dp_path, &dp_open_errno, &dp_read_errno);
if (gdp_path != NULL) {
if (gdp_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open global disabled protocols file\n\"%s\": %s.",
gdp_path, strerror(gdp_open_errno));
}
if (gdp_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading global disabled protocols file\n\"%s\": %s.",
gdp_path, strerror(gdp_read_errno));
}
g_free(gdp_path);
}
if (dp_path != NULL) {
if (dp_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
strerror(dp_open_errno));
}
if (dp_read_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
strerror(dp_read_errno));
}
g_free(dp_path);
}
prefs = read_configuration_files (&gdp_path, &dp_path);
/* Read the (static part) of the recent file. Only the static part of it will be read, */
/* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
@ -2630,6 +2681,9 @@ main(int argc, char *argv[])
break;
/*** all non capture option specific ***/
case 'C':
/* Configuration profile settings were already processed just ignore them this time*/
break;
case 'D': /* Print a list of capture devices and exit */
#ifdef HAVE_LIBPCAP
capture_opts_list_interfaces(FALSE);
@ -2910,7 +2964,7 @@ main(int argc, char *argv[])
/* read in rc file from global and personal configuration paths. */
rc_file = get_datafile_path(RC_FILE);
gtk_rc_parse(rc_file);
rc_file = get_persconffile_path(RC_FILE, FALSE);
rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
gtk_rc_parse(rc_file);
font_init();
@ -3321,10 +3375,23 @@ static GtkWidget *packets_bar_new(void)
packets_bar = gtk_statusbar_new();
packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
packets_bar_update();
#if GTK_MAJOR_VERSION >= 2
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(packets_bar), FALSE);
#endif
return packets_bar;
}
static GtkWidget *profile_bar_new(void)
{
/* tip: tooltips don't work on statusbars! */
profile_bar = gtk_statusbar_new();
profile_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(profile_bar), "profile");
profile_bar_update();
return profile_bar;
}
/*
* Helper for main_widgets_rearrange()
@ -3377,7 +3444,9 @@ void main_widgets_rearrange(void) {
gtk_widget_ref(stat_hbox);
gtk_widget_ref(info_bar);
gtk_widget_ref(packets_bar);
gtk_widget_ref(status_pane);
gtk_widget_ref(profile_bar);
gtk_widget_ref(status_pane_left);
gtk_widget_ref(status_pane_right);
gtk_widget_ref(main_pane_v1);
gtk_widget_ref(main_pane_v2);
gtk_widget_ref(main_pane_h1);
@ -3387,7 +3456,8 @@ void main_widgets_rearrange(void) {
/* empty all containers participating */
gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
gtk_container_foreach(GTK_CONTAINER(stat_hbox), foreach_remove_a_child, stat_hbox);
gtk_container_foreach(GTK_CONTAINER(status_pane), foreach_remove_a_child, status_pane);
gtk_container_foreach(GTK_CONTAINER(status_pane_left), foreach_remove_a_child, status_pane_left);
gtk_container_foreach(GTK_CONTAINER(status_pane_right), foreach_remove_a_child, status_pane_right);
gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
@ -3486,9 +3556,11 @@ void main_widgets_rearrange(void) {
#endif
/* statusbar */
gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane, TRUE, TRUE, 0);
gtk_paned_pack1(GTK_PANED(status_pane), info_bar, FALSE, FALSE);
gtk_paned_pack2(GTK_PANED(status_pane), packets_bar, FALSE, FALSE);
gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane_left, TRUE, TRUE, 0);
gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar, FALSE, FALSE);
gtk_paned_pack2(GTK_PANED(status_pane_left), status_pane_right, TRUE, FALSE);
gtk_paned_pack1(GTK_PANED(status_pane_right), packets_bar, TRUE, FALSE);
gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar, FALSE, FALSE);
/* hide widgets on users recent settings */
main_widgets_show_or_hide();
@ -4067,9 +4139,9 @@ main_widgets_show_or_hide(void)
}
if (recent.statusbar_show) {
gtk_widget_show(status_pane);
gtk_widget_show(status_pane_left);
} else {
gtk_widget_hide(status_pane);
gtk_widget_hide(status_pane_left);
}
if (recent.filter_toolbar_show) {
@ -4833,14 +4905,20 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
packets_bar = packets_bar_new();
gtk_widget_show(packets_bar);
/* profile statusbar */
profile_bar = profile_bar_new();
gtk_widget_show(profile_bar);
/* Filter/status hbox */
stat_hbox = gtk_hbox_new(FALSE, 1);
gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
gtk_widget_show(stat_hbox);
/* Pane for the statusbar */
status_pane = gtk_hpaned_new();
gtk_widget_show(status_pane);
status_pane_left = gtk_hpaned_new();
gtk_widget_show(status_pane_left);
status_pane_right = gtk_hpaned_new();
gtk_widget_show(status_pane_right);
/* Pane for the welcome screen */
welcome_pane = welcome_new();
@ -4938,3 +5016,37 @@ prefs_to_capture_opts(void)
/* Set the name resolution code's flags from the preferences. */
g_resolv_flags = prefs.name_resolve;
}
/* Change configuration profile */
void change_configuration_profile (const gchar *profile_name)
{
char *gdp_path, *dp_path;
/* First set profile name and update the status bar */
set_profile_name (profile_name);
profile_bar_update ();
/* Reset current preferences and apply the new */
prefs_reset();
(void) read_configuration_files (&gdp_path, &dp_path);
prefs_apply_all();
uat_reload_all();
/* Update window view and redraw the toolbar */
update_main_window_name();
toolbar_redraw_all();
/* Enable all protocols and disable from the disabled list */
proto_enable_all();
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
}
/* Reload color filters */
color_filters_reload();
/* Recreate the packet list according to new preferences */
packet_list_recreate ();
user_font_apply();
}

View File

@ -333,14 +333,23 @@ extern void dnd_open_file_cmd(gchar *cf_names_freeme);
/** Update the packets statusbar to the current values. */
extern void packets_bar_update(void);
/** Update the profile statusbar to the current values. */
extern void profile_bar_update(void);
#ifdef _WIN32
/** Win32 only: Create a console. Beware: cannot be closed again. */
extern void create_console(void);
#endif
/* Fill in capture options with values from the preferences */
/** Fill in capture options with values from the preferences */
extern void prefs_to_capture_opts(void);
/** Change configuration profile */
extern void change_configuration_profile(const gchar *profile_name);
#define DEFAULT_PROFILE "Default"
extern GtkWidget *pkt_scrollw;
#endif /* __MAIN_H__ */

View File

@ -46,6 +46,7 @@
#include "capture_dlg.h"
#include "color_dlg.h"
#include "filter_dlg.h"
#include "profile_dlg.h"
#include "dlg_utils.h"
#include "capture_file_dlg.h"
#include "fileset_dlg.h"
@ -520,6 +521,9 @@ static GtkItemFactoryEntry menu_items[] =
ITEM_FACTORY_ENTRY("/Edit/Find Next Reference", NULL, reftime_frame_cb, REFTIME_FIND_NEXT, NULL, NULL),
ITEM_FACTORY_ENTRY("/Edit/Find Previous Reference", NULL, reftime_frame_cb, REFTIME_FIND_PREV, NULL, NULL),
ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
#if GTK_MAJOR_VERSION >= 2
ITEM_FACTORY_ENTRY("/Edit/_Configuration Profiles...", "<shift><control>A", profile_dialog_cb, 0, NULL, NULL),
#endif
ITEM_FACTORY_STOCK_ENTRY("/Edit/_Preferences...", "<shift><control>P", prefs_cb,
0, GTK_STOCK_PREFERENCES),
ITEM_FACTORY_ENTRY("/_View", NULL, NULL, 0, "<Branch>", NULL),

791
gtk/profile_dlg.c Normal file
View File

@ -0,0 +1,791 @@
/* profile_dlg.c
* Dialog box for profiles editing
* Stig Bjørlykke <stig@bjorlykke.org>, 2008
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <gtk/gtk.h>
#include <epan/filesystem.h>
#include <wiretap/file_util.h>
#include "gtk/main.h"
#include "profile_dlg.h"
#include "dlg_utils.h"
#include "gui_utils.h"
#include "simple_dialog.h"
#include "compat_macros.h"
#include "gtkglobals.h"
#include "help_dlg.h"
#include <epan/prefs.h>
#if GTK_MAJOR_VERSION >= 2
#define E_PROF_PROFILE_L_KEY "profile_profile_l"
#define E_PROF_COPY_BT_KEY "profile_copy_bt"
#define E_PROF_DEL_BT_KEY "profile_del_bt"
#define E_PROF_NAME_TE_KEY "profile_name_te"
#define E_PROF_SELFUNC_KEY "profile_selfunc"
#define E_PROF_SELARG_KEY "profile_selarg"
static GtkWidget *global_profile_w = NULL;
static GList *current_profiles = NULL;
static GList *edited_profiles = NULL;
#define PROF_STAT_DEFAULT 1
#define PROF_STAT_EXISTS 2
#define PROF_STAT_NEW 3
#define PROF_STAT_CHANGED 4
#define PROF_STAT_COPY 5
typedef struct {
char *name; /* profile name */
char *reference; /* profile reference */
int status;
} profile_def;
static GList *
add_profile_entry(GList *fl, const char *profilename, const char *reference, int status)
{
profile_def *profile;
profile = (profile_def *) g_malloc(sizeof(profile_def));
profile->name = g_strdup(profilename);
profile->reference = g_strdup(reference);
profile->status = status;
return g_list_append(fl, profile);
}
static GList *
remove_profile_entry(GList *fl, GList *fl_entry)
{
profile_def *profile;
profile = (profile_def *) fl_entry->data;
g_free(profile->name);
g_free(profile->reference);
g_free(profile);
return g_list_remove_link(fl, fl_entry);
}
static GList *
add_to_profile_list(const char *name, const char *expression, int status)
{
edited_profiles = add_profile_entry(edited_profiles, name, expression, status);
return g_list_last(edited_profiles);
}
static void
remove_from_profile_list(GList *fl_entry)
{
edited_profiles = remove_profile_entry(edited_profiles, fl_entry);
}
static void
empty_profile_list(gboolean edit_list)
{
GList **flpp;
if (edit_list) {
flpp = &edited_profiles;
while(*flpp) {
*flpp = remove_profile_entry(*flpp, g_list_first(*flpp));
}
g_assert(g_list_length(*flpp) == 0);
}
flpp = &current_profiles;
while(*flpp) {
*flpp = remove_profile_entry(*flpp, g_list_first(*flpp));
}
g_assert(g_list_length(*flpp) == 0);
}
static void
copy_profile_list(void)
{
GList *flp_src;
profile_def *profile;
flp_src = edited_profiles;
/* throw away the "old" destination list - a NULL list is ok here */
empty_profile_list(FALSE);
/* copy the list entries */
while(flp_src) {
profile = (flp_src)->data;
current_profiles = add_profile_entry(current_profiles, profile->name,
profile->reference, profile->status);
flp_src = g_list_next(flp_src);
}
}
static GtkTreeIter *
fill_list(GtkWidget *main_w)
{
ETH_DIR *dir; /* scanned directory */
ETH_DIRENT *file; /* current file */
GList *fl_entry;
profile_def *profile;
GtkTreeView *profile_l;
GtkListStore *store;
GtkTreeIter iter, *l_select = NULL;
const gchar *profile_name = get_profile_name ();
const gchar *profiles_dir, *name;
gchar *filename;
profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
store = GTK_LIST_STORE(gtk_tree_view_get_model(profile_l));
fl_entry = add_to_profile_list(DEFAULT_PROFILE, DEFAULT_PROFILE, PROF_STAT_DEFAULT);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, DEFAULT_PROFILE, 1, fl_entry, -1);
if (profile_name == NULL || strlen(profile_name) == 0) {
l_select = g_memdup(&iter, sizeof(iter));
}
/* fill in data */
profiles_dir = get_profiles_dir();
if ((dir = eth_dir_open(profiles_dir, 0, NULL)) != NULL) {
while ((file = eth_dir_read_name(dir)) != NULL) {
name = eth_dir_get_name(file);
filename = g_strdup_printf ("%s%s%s", profiles_dir, G_DIR_SEPARATOR_S, name);
if (test_for_directory(filename) == EISDIR) {
fl_entry = add_to_profile_list(name, name, PROF_STAT_EXISTS);
profile = (profile_def *) fl_entry->data;
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, profile->name, 1, fl_entry, -1);
if (profile_name && profile->name) {
if (strcmp(profile_name, profile->name) == 0) {
/*
* XXX - We're assuming that we can just copy a GtkTreeIter
* and use it later without any crashes. This may not be a
* valid assumption.
*/
l_select = g_memdup(&iter, sizeof(iter));
}
}
}
g_free (filename);
}
eth_dir_close (dir);
}
/* Make the current list an the edited list equal */
copy_profile_list ();
return l_select;
}
static void
profile_select(GtkWidget *main_w, GtkTreeView *profile_l, gboolean destroy)
{
GList *fl_entry;
profile_def *profile;
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
if (fl_entry) {
profile = (profile_def *) fl_entry->data;
if (strcmp(profile->name, DEFAULT_PROFILE)!=0) {
change_configuration_profile (profile->name);
} else {
change_configuration_profile (NULL);
}
}
}
if (destroy) {
/*
* Destroy the profile dialog box.
*/
empty_profile_list (TRUE);
window_destroy(main_w);
}
}
static void
profile_dlg_select(GtkTreeView *profile_l, gpointer main_w_arg)
{
GtkWidget *main_w = GTK_WIDGET(main_w_arg);
profile_select(main_w, profile_l, TRUE);
}
static void
profile_apply(GtkWidget *main_w, gboolean destroy)
{
GtkTreeView *profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
profile_select(main_w, profile_l, destroy);
}
static void
profile_dlg_save(void)
{
char *pf_dir_path, *pf_dir_path2;
GList *fl1, *fl2;
profile_def *profile1, *profile2;
gboolean found;
fl1 = g_list_first(edited_profiles);
while (fl1) {
found = FALSE;
profile1 = (profile_def *) fl1->data;
if (profile1->status == PROF_STAT_NEW) {
/* We do not create a directory for the default profile */
if (strcmp(profile1->name, DEFAULT_PROFILE)!=0) {
if (create_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't create directory\n\"%s\":\n%s.",
pf_dir_path, strerror(errno));
g_free(pf_dir_path);
}
profile1->status = PROF_STAT_EXISTS;
}
} else if (profile1->status == PROF_STAT_CHANGED) {
if (strcmp(profile1->reference, profile1->name)!=0) {
/* Rename old profile directory to new */
if (rename_persconffile_profile(profile1->reference, profile1->name,
&pf_dir_path, &pf_dir_path2) == -1) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't rename directory\n\"%s\" to\n\"%s\":\n%s.",
pf_dir_path, pf_dir_path2, strerror(errno));
g_free(pf_dir_path);
}
profile1->status = PROF_STAT_EXISTS;
}
}
fl1 = g_list_next(fl1);
}
fl1 = g_list_first(current_profiles);
while (fl1) {
found = FALSE;
profile1 = (profile_def *) fl1->data;
fl2 = g_list_first(edited_profiles);
while (fl2) {
profile2 = (profile_def *) fl2->data;
if (strcmp(profile1->name, profile2->name)==0) {
/* Profile exists in both lists */
found = TRUE;
} else if (strcmp(profile1->name, profile2->reference)==0) {
/* Profile has been renamed */
found = TRUE;
}
fl2 = fl2->next;
}
if (!found) {
/* Exists in existing list and not in edited, this is a deleted profile */
if (delete_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't delete profile directory\n\"%s\":\n%s.",
pf_dir_path, strerror(errno));
g_free(pf_dir_path);
}
}
fl1 = g_list_next(fl1);
}
copy_profile_list();
}
static void
profile_dlg_ok_cb(GtkWidget *ok_bt, gpointer data _U_)
{
profile_dlg_save();
/*
* Destroy the dialog box and apply the profile.
*/
profile_apply(gtk_widget_get_toplevel(ok_bt), TRUE);
}
static void
profile_dlg_apply_cb(GtkWidget *apply_bt, gpointer data _U_)
{
profile_dlg_save();
/*
* Apply the profile, but don't destroy the dialog box.
*/
profile_apply(gtk_widget_get_toplevel(apply_bt), FALSE);
}
/* cancel button pressed, revert changes and exit dialog */
static void
profile_dlg_cancel_cb(GtkWidget *cancel_bt, gpointer data _U_)
{
GtkWidget *main_w = gtk_widget_get_toplevel(cancel_bt);
empty_profile_list (TRUE);
window_destroy(GTK_WIDGET(main_w));
}
/* Treat this as a cancel, by calling "profile_dlg_cancel_cb()" */
static gboolean
profile_dlg_delete_event_cb(GtkWidget *main_w, GdkEvent *event _U_,
gpointer data)
{
profile_dlg_cancel_cb(main_w, data);
return FALSE;
}
static void
profile_dlg_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
{
global_profile_w = NULL;
}
static gint
profile_sel_list_button_cb(GtkWidget *list, GdkEventButton *event,
gpointer data _U_)
{
void (* func)(GtkWidget *, gpointer);
gpointer func_arg;
if (event->type == GDK_2BUTTON_PRESS) {
func = OBJECT_GET_DATA(list, E_PROF_SELFUNC_KEY);
func_arg = OBJECT_GET_DATA(list, E_PROF_SELARG_KEY);
if (func)
(*func)(list, func_arg);
}
return FALSE;
}
static void
profile_sel_list_cb(GtkTreeSelection *sel, gpointer data _U_)
{
GtkWidget *profile_l = GTK_WIDGET(gtk_tree_selection_get_tree_view(sel));
GtkWidget *main_w = gtk_widget_get_toplevel(profile_l);
GtkTreeModel *model;
GtkTreeIter iter;
GtkWidget *name_te = OBJECT_GET_DATA(main_w, E_PROF_NAME_TE_KEY);
GtkWidget *copy_bt = OBJECT_GET_DATA(main_w, E_PROF_COPY_BT_KEY);
GtkWidget *del_bt = OBJECT_GET_DATA(main_w, E_PROF_DEL_BT_KEY);
profile_def *profile;
gchar *name = NULL;
GList *fl_entry;
gint sensitivity = FALSE;
if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
if (fl_entry) {
profile= (profile_def *) fl_entry->data;
name = g_strdup(profile->name);
if (profile->status!=PROF_STAT_DEFAULT) {
sensitivity = TRUE;
}
}
}
/*
* Did you know that this function is called when the window is destroyed?
* Funny, that.
* This means that we have to:
*
* attach to the top-level window data items containing pointers to
* the widgets we affect here;
*
* give each of those widgets their own destroy callbacks;
*
* clear that pointer when the widget is destroyed;
*
* don't do anything to the widget if the pointer we get back is
* null;
*
* so that if we're called after any of the widgets we'd affect are
* destroyed, we know that we shouldn't do anything to those widgets.
*/
if (name_te != NULL) {
gtk_entry_set_text(GTK_ENTRY(name_te), name ? name : "");
gtk_widget_set_sensitive(name_te, sensitivity);
}
if (copy_bt != NULL)
gtk_widget_set_sensitive(copy_bt, sensitivity);
if (del_bt != NULL)
gtk_widget_set_sensitive(del_bt, sensitivity);
if (name != NULL)
g_free(name);
}
static void
profile_new_bt_clicked_cb(GtkWidget *w, gpointer data _U_)
{
GtkWidget *main_w = gtk_widget_get_toplevel(w);
GtkTreeView *profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
GtkListStore *store;
GtkTreeIter iter;
GList *fl_entry;
const gchar *name = "New profile";
/* Add a new entry to the profile list. */
fl_entry = add_to_profile_list(name, "", PROF_STAT_NEW);
store = GTK_LIST_STORE(gtk_tree_view_get_model(profile_l));
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, name, 1, fl_entry, -1);
/* Select the item. */
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(profile_l), &iter);
}
#if 0
static void
profile_copy_bt_clicked_cb(GtkWidget *w, gpointer data _U_)
{
GtkWidget *main_w = gtk_widget_get_toplevel(w);
GtkWidget *name_te = OBJECT_GET_DATA(main_w, E_PROF_NAME_TE_KEY);
GtkTreeView *profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
GtkListStore *store;
GtkTreeIter iter;
GList *fl_entry;
const gchar *name = gtk_entry_get_text(GTK_ENTRY(name_te));
gchar *new_name;
new_name = g_strdup_printf ("%s (copy)", name);
/* Add a new entry to the profile list. */
fl_entry = add_to_profile_list(new_name, name, PROF_STAT_COPY);
store = GTK_LIST_STORE(gtk_tree_view_get_model(profile_l));
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, new_name, 1, fl_entry, -1);
/* Select the item. */
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(profile_l), &iter);
g_free (new_name);
}
#endif
static void
profile_name_te_changed_cb(GtkWidget *w, gpointer data _U_)
{
GtkWidget *main_w = gtk_widget_get_toplevel(w);
GtkWidget *name_te = OBJECT_GET_DATA(main_w, E_PROF_NAME_TE_KEY);
GtkWidget *profile_l = OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY);
profile_def *profile;
GList *fl_entry;
const gchar *name = "";
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
name = gtk_entry_get_text(GTK_ENTRY(name_te));
/* if something was selected */
if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
if (fl_entry != NULL) {
profile = (profile_def *) fl_entry->data;
if (strlen(name) > 0 && profile) {
if (profile->status != PROF_STAT_DEFAULT) {
g_free(profile->name);
profile->name = g_strdup(name);
if (profile->status != PROF_STAT_NEW) {
profile->status = PROF_STAT_CHANGED;
}
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, name, -1);
}
}
}
}
}
static void
profile_del_bt_clicked_cb(GtkWidget *w, gpointer data _U_)
{
GtkWidget *main_w = gtk_widget_get_toplevel(w);
GtkWidget *profile_l = OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY);
GList *fl_entry;
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
/* If something was selected */
if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
if (fl_entry != NULL) {
remove_from_profile_list (fl_entry);
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
}
}
if (gtk_tree_model_get_iter_first (model, &iter)) {
gtk_tree_selection_select_iter(sel, &iter);
}
}
static GtkWidget *
profile_dialog_new(void)
{
GtkWidget *main_w, /* main window */
*main_vb, /* main container */
*bbox, /* button container */
*ok_bt, /* "OK" button */
*apply_bt, /* "Apply" button */
*cancel_bt, /* "Cancel" button */
*help_bt; /* "Help" button */
GtkWidget *profile_vb, /* profile settings box */
*props_vb;
GtkWidget *top_hb,
*list_bb,
*new_bt,
#if 0
*copy_bt,
#endif
*del_bt,
*profile_sc,
*profile_l,
*middle_hb,
*name_lb,
*name_te,
*profile_fr,
*edit_fr,
*props_fr;
GtkTooltips *tooltips;
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *sel;
GtkTreeIter *l_select;
/* Get a pointer to a static variable holding the type of profile on
which we're working, so we can pass that pointer to callback
routines. */
tooltips = gtk_tooltips_new ();
main_w = dlg_window_new("Wireshark: Configuration Profiles");
gtk_window_set_default_size(GTK_WINDOW(main_w), 400, 400);
main_vb = gtk_vbox_new(FALSE, 0);
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
gtk_container_add(GTK_CONTAINER(main_w), main_vb);
gtk_widget_show(main_vb);
/* Container for each row of widgets */
profile_vb = gtk_vbox_new(FALSE, 0);
gtk_container_border_width(GTK_CONTAINER(profile_vb), 0);
gtk_container_add(GTK_CONTAINER(main_vb), profile_vb);
gtk_widget_show(profile_vb);
/* Top row: Buttons and profile list */
top_hb = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(profile_vb), top_hb);
gtk_widget_show(top_hb);
edit_fr = gtk_frame_new("Edit");
gtk_box_pack_start(GTK_BOX(top_hb), edit_fr, FALSE, FALSE, 0);
gtk_widget_show(edit_fr);
list_bb = gtk_vbox_new(TRUE, 0);
gtk_container_border_width(GTK_CONTAINER(list_bb), 5);
gtk_container_add(GTK_CONTAINER(edit_fr), list_bb);
gtk_widget_show(list_bb);
new_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_NEW);
SIGNAL_CONNECT(new_bt, "clicked", profile_new_bt_clicked_cb, NULL);
gtk_widget_show(new_bt);
gtk_box_pack_start (GTK_BOX (list_bb), new_bt, FALSE, FALSE, 0);
gtk_tooltips_set_tip (tooltips, new_bt,
"Create a new profile (with default properties)", NULL);
#if 0
copy_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_COPY);
gtk_widget_set_sensitive(copy_bt, FALSE);
SIGNAL_CONNECT(copy_bt, "clicked", profile_copy_bt_clicked_cb, NULL);
OBJECT_SET_DATA(main_w, E_PROF_COPY_BT_KEY, copy_bt);
gtk_widget_show(copy_bt);
gtk_box_pack_start (GTK_BOX (list_bb), copy_bt, FALSE, FALSE, 0);
gtk_tooltips_set_tip (tooltips, copy_bt,
"Copy the selected profile", NULL);
#endif
del_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_DELETE);
gtk_widget_set_sensitive(del_bt, FALSE);
SIGNAL_CONNECT(del_bt, "clicked", profile_del_bt_clicked_cb, NULL);
OBJECT_SET_DATA(main_w, E_PROF_DEL_BT_KEY, del_bt);
gtk_widget_show(del_bt);
gtk_box_pack_start (GTK_BOX (list_bb), del_bt, FALSE, FALSE, 0);
gtk_tooltips_set_tip (tooltips, del_bt, "Delete the selected profile", NULL);
profile_fr = gtk_frame_new("Configuration Profiles");
gtk_box_pack_start(GTK_BOX(top_hb), profile_fr, TRUE, TRUE, 0);
gtk_widget_show(profile_fr);
profile_sc = scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(profile_sc),
GTK_SHADOW_IN);
gtk_container_set_border_width (GTK_CONTAINER (profile_sc), 5);
gtk_container_add(GTK_CONTAINER(profile_fr), profile_sc);
gtk_widget_show(profile_sc);
store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
profile_l = tree_view_new(GTK_TREE_MODEL(store));
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(profile_l), FALSE);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
gtk_tree_view_column_set_sort_column_id(column, 0);
gtk_tree_view_append_column(GTK_TREE_VIEW(profile_l), column);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
SIGNAL_CONNECT(sel, "changed", profile_sel_list_cb, profile_vb);
SIGNAL_CONNECT(profile_l, "button_press_event", profile_sel_list_button_cb, NULL);
OBJECT_SET_DATA(main_w, E_PROF_PROFILE_L_KEY, profile_l);
gtk_container_add(GTK_CONTAINER(profile_sc), profile_l);
gtk_widget_show(profile_l);
OBJECT_SET_DATA(profile_l, E_PROF_SELFUNC_KEY, profile_dlg_select);
OBJECT_SET_DATA(profile_l, E_PROF_SELARG_KEY, main_w);
/* fill in data */
l_select = fill_list(main_w);
g_object_unref(G_OBJECT(store));
props_fr = gtk_frame_new("Properties");
gtk_box_pack_start(GTK_BOX(profile_vb), props_fr, FALSE, FALSE, 0);
gtk_widget_show(props_fr);
props_vb = gtk_vbox_new(FALSE, 3);
gtk_container_border_width(GTK_CONTAINER(props_vb), 5);
gtk_container_add(GTK_CONTAINER(props_fr), props_vb);
gtk_widget_show(props_vb);
/* row: Profile name entry */
middle_hb = gtk_hbox_new(FALSE, 3);
gtk_container_add(GTK_CONTAINER(props_vb), middle_hb);
gtk_widget_show(middle_hb);
name_lb = gtk_label_new("Profile name:");
gtk_box_pack_start(GTK_BOX(middle_hb), name_lb, FALSE, FALSE, 0);
gtk_widget_show(name_lb);
name_te = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(middle_hb), name_te, TRUE, TRUE, 0);
OBJECT_SET_DATA(main_w, E_PROF_NAME_TE_KEY, name_te);
SIGNAL_CONNECT(name_te, "changed", profile_name_te_changed_cb, NULL);
gtk_widget_show(name_te);
/* button row (create all possible buttons and hide the unrequired later - it's a lot easier) */
bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
gtk_widget_show(bbox);
ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
SIGNAL_CONNECT(ok_bt, "clicked", profile_dlg_ok_cb, NULL);
gtk_tooltips_set_tip (tooltips, ok_bt, "Apply the profiles and close this dialog", NULL);
/* Catch the "activate" signal on the profile name and profile
list entries, so that if the user types Return
there, we act as if the "OK" button had been selected, as
happens if Return is typed if some widget that *doesn't*
handle the Return key has the input focus. */
dlg_set_activate(name_te, ok_bt);
apply_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_APPLY);
SIGNAL_CONNECT(apply_bt, "clicked", profile_dlg_apply_cb, NULL);
gtk_tooltips_set_tip (tooltips, apply_bt, "Apply the profiles and keep this dialog open", NULL);
cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
gtk_tooltips_set_tip (tooltips, cancel_bt, "Cancel the changes", NULL);
SIGNAL_CONNECT(cancel_bt, "clicked", profile_dlg_cancel_cb, NULL);
window_set_cancel_button(main_w, cancel_bt, NULL);
help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
SIGNAL_CONNECT(help_bt, "clicked", topic_cb, HELP_CONFIG_PROFILES_DIALOG);
gtk_tooltips_set_tip (tooltips, help_bt, "Show topic specific help", NULL);
if(ok_bt) {
gtk_widget_grab_default(ok_bt);
}
/* DO SELECTION THINGS *AFTER* SHOWING THE DIALOG! */
/* otherwise the updatings can get confused */
if (l_select) {
gtk_tree_selection_select_iter(sel, l_select);
g_free(l_select);
}
SIGNAL_CONNECT(main_w, "delete_event", profile_dlg_delete_event_cb, NULL);
SIGNAL_CONNECT(main_w, "destroy", profile_dlg_destroy_cb, NULL);
gtk_widget_show(main_w);
window_present(main_w);
return main_w;
}
#endif
/* Create a profile dialog for editing display profiles; this is to be used
as a callback for menu items, toolbars, etc.. */
void
profile_dialog_cb(GtkWidget *w _U_)
{
#if GTK_MAJOR_VERSION >= 2
/* Has a profiles dialog box already been opened */
if (global_profile_w != NULL) {
/* Yes. Just reactivate it. */
reactivate_window(global_profile_w);
} else {
global_profile_w = profile_dialog_new ();
}
#endif
}

41
gtk/profile_dlg.h Normal file
View File

@ -0,0 +1,41 @@
/* profile_dlg.h
* Definitions for dialog box for profiles editing.
* Stig Bjørlykke <stig@bjorlykke.org>, 2008
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PROFILE_DLG_H__
#define __PROFILE_DLG_H__
/** @file
* "Configuration Profiles" dialog box
* @ingroup dialog_group
*/
/** User requested the "Configuration Profiles" dialog box by menu or toolbar.
*
* @param widget parent widget
*/
void profile_dialog_cb(GtkWidget *widget);
#endif /* profile_dlg.h */

View File

@ -72,7 +72,8 @@
#define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized"
#define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
#define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
#define RECENT_GUI_GEOMETRY_STATUS_PANE "gui.geometry_status_pane"
#define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane"
#define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right"
#define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
#define RECENT_GUI_GEOMETRY "gui.geom."
#define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
@ -133,7 +134,7 @@ write_recent(void)
return FALSE;
}
rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE);
rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, TRUE);
if ((rf = eth_fopen(rf_path, "w")) == NULL) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't open recent file\n\"%s\": %s.", rf_path,
@ -259,9 +260,16 @@ write_recent(void)
fprintf(rf, "\n# Statusbar left pane size.\n");
fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
fprintf(rf, "# Decimal number.\n");
if (recent.gui_geometry_status_pane != 0) {
fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE ": %d\n",
recent.gui_geometry_status_pane);
if (recent.gui_geometry_status_pane_left != 0) {
fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n",
recent.gui_geometry_status_pane_left);
}
fprintf(rf, "\n# Statusbar middle pane size.\n");
fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
fprintf(rf, "# Decimal number.\n");
if (recent.gui_geometry_status_pane_right != 0) {
fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n",
recent.gui_geometry_status_pane_right);
}
fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
@ -446,13 +454,21 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
recent.gui_geometry_main_lower_pane = num;
recent.has_gui_geometry_main_lower_pane = TRUE;
} else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE) == 0) {
} else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) {
num = strtol(value, &p, 0);
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
if (num <= 0)
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
recent.gui_geometry_status_pane = num;
recent.gui_geometry_status_pane_right = num;
recent.has_gui_geometry_status_pane = TRUE;
} else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) {
num = strtol(value, &p, 0);
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
if (num <= 0)
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
recent.gui_geometry_status_pane_left = num;
recent.has_gui_geometry_status_pane = TRUE;
} else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) {
if(u3_active())
@ -580,7 +596,8 @@ recent_read_static(char **rf_path_return, int *rf_errno_return)
/* pane size of zero will autodetect */
recent.gui_geometry_main_upper_pane = 0;
recent.gui_geometry_main_lower_pane = 0;
recent.gui_geometry_status_pane = 0;
recent.gui_geometry_status_pane_left = (DEF_WIDTH/3);
recent.gui_geometry_status_pane_right = (DEF_WIDTH/3);
/* the following are only used if GTK2 is used (as GTK1 cannot read these geometry values) */
/* or if set through command line */
@ -598,7 +615,7 @@ recent_read_static(char **rf_path_return, int *rf_errno_return)
recent.privs_warn_if_no_npf = TRUE;
/* Construct the pathname of the user's recent file. */
rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
/* Read the user's recent file, if it exists. */
*rf_path_return = NULL;
@ -630,7 +647,7 @@ recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
/* Construct the pathname of the user's recent file. */
rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
/* Read the user's recent file, if it exists. */
*rf_path_return = NULL;

View File

@ -66,7 +66,8 @@ typedef struct recent_settings_tag {
gboolean has_gui_geometry_main_lower_pane; /* gui_geometry_main_lower_pane is valid */
gint gui_geometry_main_lower_pane; /* this is autodetected in GTK2 only */
gboolean has_gui_geometry_status_pane; /* gui_geometry_status_pane is valid */
gint gui_geometry_status_pane; /* this is autodetected in GTK2 only */
gint gui_geometry_status_pane_left; /* this is autodetected in GTK2 only */
gint gui_geometry_status_pane_right; /* this is autodetected in GTK2 only */
gboolean privs_warn_if_elevated;
gboolean privs_warn_if_no_npf;
} recent_settings_t;

View File

@ -259,6 +259,7 @@ print_usage(gboolean print_ver)
/*fprintf(output, "\n");*/
fprintf(output, "Output:\n");
fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
fprintf(output, " -C <config profile> start with specified configuration profile\n");
fprintf(output, " -F <output file type> set the output file type, default is libpcap\n");
fprintf(output, " an empty \"-F\" option will list the file types\n");
fprintf(output, " -V add output of packet tree (Packet Details)\n");
@ -725,7 +726,7 @@ main(int argc, char *argv[])
GLogLevelFlags log_flags;
int optind_initial;
#define OPTSTRING_INIT "a:b:c:d:De:E:f:F:G:hi:lLnN:o:pqr:R:s:St:T:vVw:xX:y:z:"
#define OPTSTRING_INIT "a:b:c:C:d:De:E:f:F:G:hi:lLnN:o:pqr:R:s:St:T:vVw:xX:y:z:"
#ifdef HAVE_LIBPCAP
#ifdef _WIN32
#define OPTSTRING_WIN32 "B:"
@ -761,6 +762,14 @@ main(int argc, char *argv[])
while ((opt = getopt(argc, argv, optstring)) != -1) {
switch (opt) {
case 'C': /* Configuration Profile */
if (profile_exists (optarg)) {
set_profile_name (optarg);
} else {
cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
exit(1);
}
break;
case 'X':
ex_opt_add(optarg);
break;
@ -956,6 +965,9 @@ main(int argc, char *argv[])
arg_error = TRUE;
#endif
break;
case 'C':
/* Configuration profile settings were already processed just ignore them this time*/
break;
case 'd': /* Decode as rule */
if (!add_decode_as(optarg))
exit(1);

View File

@ -312,7 +312,7 @@ update_check(gboolean interactive)
/* build update file name */
/* XXX - using the personal path, use temp dir instead? */
local_file = get_persconffile_path("wsupdate", TRUE /*for_writing*/);
local_file = get_persconffile_path("wsupdate", FALSE, TRUE /*for_writing*/);
if(local_file == NULL) {
g_warning("Couldn't create output path!");
return;