1 /*
2 * funnel.c
3 *
4 * EPAN's GUI mini-API
5 *
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 *
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15 #include "config.h"
16
17 #include <epan/funnel.h>
18 #include <wsutil/glib-compat.h>
19
20 typedef struct _funnel_menu_t {
21 char *name;
22 register_stat_group_t group;
23 funnel_menu_callback callback;
24 gpointer callback_data;
25 funnel_menu_callback_data_free callback_data_free;
26 gboolean retap;
27 struct _funnel_menu_t* next;
28 } funnel_menu_t;
29
30 /* XXX This assumes one main window and one capture file. */
31 static const funnel_ops_t* ops = NULL;
32 static funnel_menu_t* registered_menus = NULL;
33 static funnel_menu_t* added_menus = NULL;
34 static funnel_menu_t* removed_menus = NULL;
35 static gboolean menus_registered = FALSE;
36
funnel_get_funnel_ops(void)37 const funnel_ops_t* funnel_get_funnel_ops(void) { return ops; }
funnel_set_funnel_ops(const funnel_ops_t * o)38 void funnel_set_funnel_ops(const funnel_ops_t* o) { ops = o; }
39
funnel_insert_menu(funnel_menu_t ** menu_list,funnel_menu_t * menu)40 static void funnel_insert_menu (funnel_menu_t** menu_list, funnel_menu_t *menu)
41 {
42 if (!(*menu_list)) {
43 *menu_list = menu;
44 } else {
45 funnel_menu_t* c;
46 for (c = *menu_list; c->next; c = c->next);
47 c->next = menu;
48 }
49 }
50
funnel_remove_menu(funnel_menu_t ** menu_list,funnel_menu_t * menu)51 static void funnel_remove_menu (funnel_menu_t ** menu_list, funnel_menu_t *menu)
52 {
53 funnel_menu_t *m = *menu_list, *p = NULL;
54
55 while (m) {
56 if (m->callback == menu->callback) {
57 if (p) {
58 p->next = m->next;
59 } else {
60 *menu_list = m->next;
61 }
62 g_free(m->name);
63 if (m->callback_data_free) {
64 m->callback_data_free(m->callback_data);
65 }
66 g_free(m);
67 if (p) {
68 m = p->next;
69 } else {
70 m = *menu_list;
71 }
72 } else {
73 p = m;
74 m = m->next;
75 }
76 }
77 }
78
funnel_clear_menu(funnel_menu_t ** menu_list)79 static void funnel_clear_menu (funnel_menu_t** menu_list)
80 {
81 funnel_menu_t *m;
82
83 while (*menu_list) {
84 m = *menu_list;
85 *menu_list = m->next;
86 g_free(m->name);
87 g_free(m);
88 }
89 *menu_list = NULL;
90 }
91
funnel_register_menu(const char * name,register_stat_group_t group,funnel_menu_callback callback,gpointer callback_data,funnel_menu_callback_data_free callback_data_free,gboolean retap)92 void funnel_register_menu(const char *name,
93 register_stat_group_t group,
94 funnel_menu_callback callback,
95 gpointer callback_data,
96 funnel_menu_callback_data_free callback_data_free,
97 gboolean retap)
98 {
99 funnel_menu_t* m = g_new(funnel_menu_t, 1);
100 m->name = g_strdup(name);
101 m->group = group;
102 m->callback = callback;
103 m->callback_data = callback_data;
104 m->callback_data_free = callback_data_free;
105 m->retap = retap;
106 m->next = NULL;
107
108 funnel_insert_menu(®istered_menus, m);
109 if (menus_registered) {
110 funnel_menu_t* m_r = (funnel_menu_t *)g_memdup2(m, sizeof *m);
111 m_r->name = g_strdup(name);
112 funnel_insert_menu(&added_menus, m_r);
113 }
114 }
115
funnel_deregister_menus(funnel_menu_callback callback)116 void funnel_deregister_menus(funnel_menu_callback callback)
117 {
118 funnel_menu_t* m = g_new0(funnel_menu_t, 1);
119 m->callback = callback;
120
121 funnel_remove_menu(®istered_menus, m);
122 funnel_insert_menu(&removed_menus, m);
123 }
124
funnel_register_all_menus(funnel_registration_cb_t r_cb)125 void funnel_register_all_menus(funnel_registration_cb_t r_cb)
126 {
127 funnel_menu_t* c;
128 for (c = registered_menus; c; c = c->next) {
129 r_cb(c->name,c->group,c->callback,c->callback_data,c->retap);
130 }
131 menus_registered = TRUE;
132 }
133
funnel_reload_menus(funnel_deregistration_cb_t d_cb,funnel_registration_cb_t r_cb)134 void funnel_reload_menus(funnel_deregistration_cb_t d_cb,
135 funnel_registration_cb_t r_cb)
136 {
137 funnel_menu_t* c;
138 for (c = removed_menus; c; c = c->next) {
139 d_cb(c->callback);
140 }
141 for (c = added_menus; c; c = c->next) {
142 r_cb(c->name,c->group,c->callback,c->callback_data,c->retap);
143 }
144
145 funnel_clear_menu(&removed_menus);
146 funnel_clear_menu(&added_menus);
147 }
148
funnel_cleanup(void)149 void funnel_cleanup(void)
150 {
151 funnel_clear_menu(®istered_menus);
152 }
153
154 /*
155 * Editor modelines - https://www.wireshark.org/tools/modelines.html
156 *
157 * Local variables:
158 * c-basic-offset: 4
159 * tab-width: 8
160 * indent-tabs-mode: nil
161 * End:
162 *
163 * vi: set shiftwidth=4 tabstop=8 expandtab:
164 * :indentSize=4:tabSize=8:noTabs=true:
165 */
166