Rename epan/stat.[ch] to epan/stat_cmd_args.[ch] - it only deals with
[obnox/wireshark/wip.git] / gtk / afp_stat.c
1 /* afp_stat.c
2  * Based on
3  * smb_stat   2003 Ronnie Sahlberg
4  *
5  * $Id$
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <string.h>
35
36 #include <gtk/gtk.h>
37
38 #include <epan/packet_info.h>
39 #include <epan/epan.h>
40 #include <epan/value_string.h>
41
42 #include <epan/stat_cmd_args.h>
43 #include "stat_menu.h"
44 #include <epan/tap.h>
45 #include <epan/dissectors/packet-afp.h>
46 #include "../register.h"
47 #include "../timestats.h"
48 #include "compat_macros.h"
49 #include "../simple_dialog.h"
50 #include "gui_utils.h" 
51 #include "dlg_utils.h"
52 #include "../file.h"
53 #include "../globals.h"
54 #include "filter_dlg.h"
55 #include "service_response_time_table.h"
56 #include "gtkglobals.h"
57
58
59 /* used to keep track of the statistics for an entire program interface */
60 typedef struct _afpstat_t {
61         GtkWidget *win;
62         srt_stat_table afp_srt_table;
63 } afpstat_t;
64
65 static void
66 afpstat_set_title(afpstat_t *ss)
67 {
68         char *title;
69
70         title = g_strdup_printf("AFP Service Response Time statistics: %s",
71             cf_get_display_name(&cfile));
72         gtk_window_set_title(GTK_WINDOW(ss->win), title);
73         g_free(title);
74 }
75
76 static void
77 afpstat_reset(void *pss)
78 {
79         afpstat_t *ss=(afpstat_t *)pss;
80
81         reset_srt_table_data(&ss->afp_srt_table);
82         afpstat_set_title(ss);
83 }
84
85 static int
86 afpstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
87 {
88         afpstat_t *ss=(afpstat_t *)pss;
89         const afp_request_val *request_val=prv;
90
91         /* if we havnt seen the request, just ignore it */
92         if(!request_val){
93                 return 0;
94         }
95
96         add_srt_table_data(&ss->afp_srt_table, request_val->command, &request_val->req_time, pinfo);
97
98         return 1;
99 }
100
101
102
103 static void
104 afpstat_draw(void *pss)
105 {
106         afpstat_t *ss=(afpstat_t *)pss;
107
108         draw_srt_table_data(&ss->afp_srt_table);
109 }
110
111
112 void protect_thread_critical_region(void);
113 void unprotect_thread_critical_region(void);
114 static void
115 win_destroy_cb(GtkWindow *win _U_, gpointer data)
116 {
117         afpstat_t *ss=(afpstat_t *)data;
118
119         protect_thread_critical_region();
120         remove_tap_listener(ss);
121         unprotect_thread_critical_region();
122
123         free_srt_table_data(&ss->afp_srt_table);
124         g_free(ss);
125 }
126
127
128 static void
129 gtk_afpstat_init(const char *optarg)
130 {
131         afpstat_t *ss;
132         const char *filter=NULL;
133         GtkWidget *label;
134         char filter_string[256];
135         GString *error_string;
136         int i;
137         GtkWidget *vbox;
138         GtkWidget *bbox;
139         GtkWidget *close_bt;
140
141         if(!strncmp(optarg,"afp,srt,",8)){
142                 filter=optarg+8;
143         } else {
144                 filter=NULL;
145         }
146
147         ss=g_malloc(sizeof(afpstat_t));
148
149         ss->win=window_new(GTK_WINDOW_TOPLEVEL, "afp-stat");
150         gtk_window_set_default_size(GTK_WINDOW(ss->win), 550, 600);
151         afpstat_set_title(ss);
152
153         vbox=gtk_vbox_new(FALSE, 3);
154         gtk_container_add(GTK_CONTAINER(ss->win), vbox);
155         gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
156
157         label=gtk_label_new("AFP Service Response Time statistics");
158         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
159
160         g_snprintf(filter_string,255,"Filter:%s",filter?filter:"");
161         label=gtk_label_new(filter_string);
162         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
163
164         label=gtk_label_new("AFP Commands");
165         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
166
167         /* We must display TOP LEVEL Widget before calling init_srt_table() */
168         gtk_widget_show_all(ss->win);
169
170         init_srt_table(&ss->afp_srt_table, 256, vbox, "afp.cmd");
171         for(i=0;i<256;i++){
172                 init_srt_table_row(&ss->afp_srt_table, i, val_to_str(i, CommandCode_vals, "Unknown(%u)"));
173         }
174
175
176         error_string=register_tap_listener("afp", ss, filter, afpstat_reset, afpstat_packet, afpstat_draw);
177         if(error_string){
178                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
179                 g_string_free(error_string, TRUE);
180                 g_free(ss);
181                 return;
182         }
183
184         /* Button row. */
185         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
186         gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
187
188         close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
189         window_set_cancel_button(ss->win, close_bt, window_cancel_button_cb);
190
191         SIGNAL_CONNECT(ss->win, "delete_event", window_delete_event_cb, NULL);
192         SIGNAL_CONNECT(ss->win, "destroy", win_destroy_cb, ss);
193
194         gtk_widget_show_all(ss->win);
195         window_present(ss->win);
196         
197         cf_retap_packets(&cfile);
198 }
199
200
201
202 static GtkWidget *dlg=NULL;
203 static GtkWidget *filter_entry;
204
205 static void
206 dlg_destroy_cb(void)
207 {
208         dlg=NULL;
209 }
210
211 static void
212 afpstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
213 {
214         GString *str;
215         const char *filter;
216
217         str = g_string_new("afp,srt");
218         filter=gtk_entry_get_text(GTK_ENTRY(filter_entry));
219         if(filter[0]!=0){
220                 g_string_sprintfa(str,",%s", filter);
221         }
222         gtk_afpstat_init(str->str);
223         g_string_free(str, TRUE);
224 }
225
226 static void
227 gtk_afpstat_cb(GtkWidget *w _U_, gpointer d _U_)
228 {
229         GtkWidget *dlg_box;
230         GtkWidget *filter_box, *filter_bt;
231         GtkWidget *bbox, *start_button, *cancel_button;
232         const char *filter;
233         static construct_args_t args = {
234           "Service Response Time Statistics Filter",
235           TRUE,
236           FALSE
237         };
238
239         /* if the window is already open, bring it to front */
240         if(dlg){
241                 gdk_window_raise(dlg->window);
242                 return;
243         }
244
245         dlg=dlg_window_new("Ethereal: Compute AFP SRT statistics");
246         gtk_window_set_default_size(GTK_WINDOW(dlg), 300, -1);
247
248         dlg_box=gtk_vbox_new(FALSE, 10);
249         gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
250         gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
251         gtk_widget_show(dlg_box);
252
253         /* Filter box */
254         filter_box=gtk_hbox_new(FALSE, 3);
255
256         /* Filter button */
257         filter_bt=BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
258         SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
259         gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, TRUE, 0);
260         gtk_widget_show(filter_bt);
261
262         /* Filter entry */
263         filter_entry=gtk_entry_new();
264         SIGNAL_CONNECT(filter_entry, "changed", filter_te_syntax_check_cb, NULL);
265
266         /* filter prefs dialog */
267         OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_entry);
268         /* filter prefs dialog */
269
270         gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
271         filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
272         if(filter){
273                 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
274         }
275         gtk_widget_show(filter_entry);
276
277         gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
278         gtk_widget_show(filter_box);
279
280         /* button box */
281         bbox = dlg_button_row_new(ETHEREAL_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
282         gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
283         gtk_widget_show(bbox);
284
285         start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
286         SIGNAL_CONNECT_OBJECT(start_button, "clicked",
287                               afpstat_start_button_clicked, NULL);
288
289         cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
290         window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
291
292         /* Catch the "activate" signal on the filter text entry, so that
293            if the user types Return there, we act as if the "Create Stat"
294            button had been selected, as happens if Return is typed if some
295            widget that *doesn't* handle the Return key has the input
296            focus. */
297         dlg_set_activate(filter_entry, start_button);
298
299         gtk_widget_grab_default(start_button );
300
301         /* Give the initial focus to the "Filter" entry box. */
302            gtk_widget_grab_focus(filter_entry);
303
304         SIGNAL_CONNECT(dlg, "delete_event", window_delete_event_cb, NULL);
305         SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
306
307         gtk_widget_show_all(dlg);
308         window_present(dlg);
309 }
310
311 void
312 register_tap_listener_gtkafpstat(void)
313 {
314         register_stat_cmd_arg("afp,srt", gtk_afpstat_init);
315
316         register_stat_menu_item("AFP...", REGISTER_STAT_GROUP_RESPONSE_TIME,
317             gtk_afpstat_cb, NULL, NULL, NULL);
318 }