/*
 * Copyright (c) 2001 Fenris, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * File:  callbacks.c
 *
 * Purpose:  This file contains the definitions for use of events in the
 * gui portion of the realtime network monitor.
 *
 */


#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include <gtk/gtk.h>
#include <limits.h>             /* UINT_MAX */
#include <math.h>               /* pow */
#include <stdio.h>
#include <string.h>             /* strncat */

#include "bool.h"
#include "callbacks.h"
#include "display.h"
#include "network.h"
#include "globals.h"
#include "interface.h"
#include "support.h"
#include "tree.h"
#include "cache_list.h"


#define MARGIN  10
#define RADIUS  7
#define VSPACE  40

static GdkPixmap        *pixmap                 = NULL;
static Display          *display                = NULL;
enum bool		src_chk			= false;
enum bool		dst_chk			= false;
static char		filter_buf[255]         = "Displaying all traffic.";
static char		src_ports_buf[255];
static char		dst_ports_buf[255];
static char		src_addr_buf[255];
static char		dst_addr_buf[255];
static char		status_text[1276];

void draw(GtkWidget* widget)
{
    static GdkFont *    	font            = NULL;
    static int          	fontx;
    static GdkGC *      	gc              = NULL;
    static GdkColormap *	cmap            = NULL;
    GdkColor            	color;
    Tree_Node *         	src_tree        = NULL;
    Tree_Node *         	dst_tree        = NULL;
    Dsp_Node *          	node;
    Dsp_Obj *           	dobj;
    int                 	ldot            = widget->allocation.width / 3;
    int                 	rdot            = ldot * 2;
    int                 	y;
    unsigned char       	src[MAX_HOSTNAME_LEN];
    unsigned char       	dst[MAX_HOSTNAME_LEN];

    if (widget == NULL) {
        return;
    }

    /* Initialize the static variables, if necessary. */
    if ((font == NULL) || (gc == NULL) || (cmap == NULL) || (display == NULL)) {
        font = gdk_font_load("lucidasans-10");
        fontx = gdk_string_height(font, "!") / 2 + 1;

        gc = gdk_gc_new(widget->window);
        cmap = gdk_colormap_get_system();

        if ((display = malloc(sizeof(Display))) == NULL)
            die("malloc");

        display->min_rate = 0;
        display->max_rate = 1000;
        init_dsp(display);
    }

    if (pixmap != NULL) {
        gdk_pixmap_unref(pixmap);
    }

    if (widget->window == NULL) {
        return;
    }

    pixmap = gdk_pixmap_new(widget->window,
                            widget->allocation.width,
                            widget->allocation.height,
                            -1);

    if (pixmap == NULL) {
        return;
    }

    gdk_draw_rectangle(pixmap,
                       widget->style->white_gc,
                       TRUE,
                       0, 0,
                       widget->allocation.width,
                       widget->allocation.height);

    clear_dsp(display);
    populate_dsp(display, net);

    y = VSPACE;
    node = display->src_list->head;
    while (node != NULL) {
        if ((dobj = node->obj) == NULL) {
            break;
        }

        set_root(&src_tree, dobj->src, y);
        strncpy(src, dobj->src_name, MAX_HOSTNAME_LEN);

        gdk_draw_string(pixmap, font, widget->style->black_gc,
                        ldot - MARGIN - gdk_string_width(font, src),
                        y + fontx,
                        src);

        color.red = dobj->color.red;
        color.green = dobj->color.green;
        color.blue = dobj->color.blue;
        gdk_colormap_alloc_color(cmap, &color, TRUE, TRUE);
        gdk_gc_set_foreground(gc, &color);

        gdk_draw_arc(pixmap, gc, TRUE,
                     ldot - (RADIUS / 2),
                     y - (RADIUS / 2),
                     RADIUS, RADIUS, 0, 360 * 64);

        node = node->next;
        y += VSPACE;
    }

    y = VSPACE;
    node = display->dst_list->head;
    while (node != NULL) {
        if ((dobj = node->obj) == NULL) {
            break;
        }

        set_root(&dst_tree, dobj->dst, y);
        strncpy(dst, dobj->dst_name, MAX_HOSTNAME_LEN);

        gdk_draw_string(pixmap, font, widget->style->black_gc,
                        rdot + MARGIN + 1,
                        y + fontx,
                        dst);

        color.red = dobj->color.red;
        color.green = dobj->color.green;
        color.blue = dobj->color.blue;
        gdk_colormap_alloc_color(cmap, &color, TRUE, TRUE);
        gdk_gc_set_foreground(gc, &color);

        gdk_draw_arc(pixmap, gc, TRUE,
                     rdot - (RADIUS / 2),
                     y - (RADIUS / 2),
                     RADIUS, RADIUS, 0, 360 * 64);

        node = node->next;
        y += VSPACE;
    }

    node = display->pair_list->head;
    while (node != NULL) {
        if ((dobj = node->obj) == NULL) {
            break;
        }

        color.red = dobj->color.red;
        color.green = dobj->color.green;
        color.blue = dobj->color.blue;
        gdk_colormap_alloc_color(cmap, &color, TRUE, TRUE);
        gdk_gc_set_foreground(gc, &color);

        gdk_draw_line(pixmap, gc,
                      ldot, get_node(&src_tree, dobj->src),
                      rdot, get_node(&dst_tree, dobj->dst));

        node = node->next;
    }

    clean_tree(&src_tree);
    clean_tree(&dst_tree);

    gdk_draw_pixmap(widget->window,
                    widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
                    pixmap,
                    0, 0, 0, 0,
                    widget->allocation.width, widget->allocation.height);
    return;
}


gint draw_timer(gpointer data)
{
    draw(GTK_WIDGET(data));
    gtk_timeout_add(3000, draw_timer, data);

    return FALSE;
}


gboolean event_configure(GtkWidget *widget,
                         GdkEventConfigure *event, gpointer data)
{
    draw(widget);
    return FALSE;
}


gboolean event_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
    gdk_draw_pixmap(widget->window,
                    widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
                    pixmap,
                    event->area.x, event->area.y,
                    event->area.x, event->area.y,
                    event->area.width, event->area.height);

    return FALSE;
}


void event_destroy(GtkObject *object, gpointer data)
{
    gtk_main_quit();
    return;
}


void on_file_exit_activate                  (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    gtk_main_quit();
}


void on_f_arp_all_activate                  (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = arp_m;
    opts->net_submenu.arp = arp_all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf, "Displaying all ARP traffic.");
    set_status_bar_text();
}


void on_f_ip_all_activate                   (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = ip_all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf, "Displaying all IP traffic.");
    set_status_bar_text();
}


void on_f_ip_icmp_all_activate              (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = icmp_m;
    opts->net_submenu.ip_submenu.icmp = icmp_all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf, "Displaying all ICMP traffic.");
    set_status_bar_text();
}


void on_f_ip_igmp_all_activate              (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = igmp_m;
    opts->net_submenu.ip_submenu.igmp = igmp_all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf, "Displaying all IGMP traffic.");
    set_status_bar_text();
}


void on_f_ip_tcp_all_activate               (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = tcp_m;
    opts->net_submenu.ip_submenu.tcp = tcp_all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf, "Displaying all TCP traffic.");
    set_status_bar_text();
}


void on_f_ip_udp_all_activate               (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = udp_m;
    opts->net_submenu.ip_submenu.udp = udp_all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying all UDP traffic.");
    set_status_bar_text();
}


void on_f_ip_icmp_request_activate          (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = icmp_m;
    opts->net_submenu.ip_submenu.icmp = icmp_rqst;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying ICMP requests.");
    set_status_bar_text();
}


void on_f_ip_icmp_reply_activate            (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = icmp_m;
    opts->net_submenu.ip_submenu.icmp = icmp_rply;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying ICMP replies.");
    set_status_bar_text();
}


void on_f_ip_icmp_pair_activate             (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = icmp_m;
    opts->net_submenu.ip_submenu.icmp = icmp_pair;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying ICMP request/reply pairs.");
    set_status_bar_text();
}


void on_f_ip_tcp_http_activate              (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = tcp_m;
    opts->net_submenu.ip_submenu.tcp = tcp_http;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying TCP traffic on port 80 (http).");
    set_status_bar_text();
}


void on_f_ip_tcp_ftp_activate               (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = tcp_m;
    opts->net_submenu.ip_submenu.tcp = tcp_ftp;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying TCP traffic on port 21 (ftp).");
    set_status_bar_text();
}


void on_f_ip_tcp_ssh_activate               (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = tcp_m;
    opts->net_submenu.ip_submenu.tcp = tcp_ssh;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf , "Displaying TCP traffic on port 22 (ssh).");
    set_status_bar_text();
}


void on_f_ip_port_activate                  (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    GtkWidget *ports_dialog = user_data;

    gtk_widget_show(ports_dialog);

    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = ip_port;
    pthread_mutex_unlock(filter_mutex);
}


void on_f_ip_tcp_port_activate              (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    GtkWidget *ports_dialog = user_data;

    gtk_widget_show(ports_dialog);

    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = tcp_m;
    opts->net_submenu.ip_submenu.tcp = tcp_port;
    pthread_mutex_unlock(filter_mutex);

}


void on_f_ip_udp_port_activate              (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    GtkWidget *ports_dialog = user_data;

    gtk_widget_show(ports_dialog);

    pthread_mutex_lock(filter_mutex);
    opts->menu = ip_m;
    opts->net_submenu.ip = udp_m;
    opts->net_submenu.ip_submenu.udp = udp_port;
    pthread_mutex_unlock(filter_mutex);
}


void on_file_options_activate               (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    struct Options_Dialog_Context *context = user_data;
    char buf[64];
    unsigned int min;
    unsigned int max;
    int i = 0;

    pthread_mutex_lock(filter_mutex);
    min = display->min_rate;
    max = display->max_rate;
    pthread_mutex_unlock(filter_mutex);

    gtk_spin_button_set_value(context->buf_size, net->timeout);

    while (min > 0 && min % 1000 == 0 && i < 3) {
        min /= 1000;
        i++;
    }
    snprintf(buf, 64, "%u", min);
    gtk_entry_set_text(context->min, buf);
    gtk_option_menu_set_history(context->min_option, i);

    i = 0;
    while (max > 0 && max % 1000 == 0 && i < 3) {
        max /= 1000;
        i++;
    }
    snprintf(buf, 64, "%u", max);
    gtk_entry_set_text(context->max, buf);
    gtk_option_menu_set_history(context->max_option, i);

    gtk_widget_show(context->dialog);

    return;
}


void on_file_clear_dns_activate             (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    empty_cache_list(&dnscache);
    return;
}



void on_option_ok_clicked                   (GtkButton       *button,
                                             gpointer         user_data)
{
    struct Options_Dialog_Context *	context 	= user_data;
    unsigned long                       min;
    unsigned long                       max;
    unsigned long                       val;
    int                                 exp;
    char                                buf[16];

    val = atoi(gtk_entry_get_text(context->min));
    exp = g_list_index(GTK_MENU_SHELL(context->min_menu)->children,
                       gtk_menu_get_active(context->min_menu));
    min = val * pow(1000, exp);
    snprintf(buf, 15, "%d %sbps", val,
             (exp == 1 ? "K" : (exp == 2 ? "M" : (exp == 3 ? "G" : ""))));
    gtk_label_set_text(context->min_label, buf);

    val = atoi(gtk_entry_get_text(context->max));
    exp = g_list_index(GTK_MENU_SHELL(context->max_menu)->children,
                       gtk_menu_get_active(context->max_menu));
    max = val * pow(1000, exp);
    snprintf(buf, 15, "%d %sbps", val,
             (exp == 1 ? "K" : (exp == 2 ? "M" : (exp == 3 ? "G" : ""))));
    gtk_label_set_text(context->max_label, buf);

    pthread_mutex_lock(net_mutex);
    net->timeout = gtk_spin_button_get_value_as_int(context->buf_size);
    display->min_rate = (min > UINT_MAX) ? UINT_MAX : min;
    display->max_rate = (max > UINT_MAX) ? UINT_MAX : max;
    pthread_mutex_unlock(net_mutex);

    gtk_widget_hide(context->dialog);

    return;
}


void on_options_cancel_clicked              (GtkButton       *button,
                                             gpointer         user_data)
{
    GtkWidget *				options_dialog 	= user_data;

    gtk_widget_hide(options_dialog);

    return;
}


void on_f_all_activate                      (GtkMenuItem     *menuitem,
                                             gpointer         user_data)
{
    pthread_mutex_lock(filter_mutex);
    opts->menu = all;
    pthread_mutex_unlock(filter_mutex);

    strcpy(filter_buf, "Displaying all traffic.");
    set_status_bar_text();
}



void on_by_address_activate                  (GtkMenuItem     *menuitem,
                                              gpointer         user_data)
{
    GtkWidget *ip_filter_dialog = user_data;

    gtk_widget_show(ip_filter_dialog);

}

void  on_filter_ok_clicked  		     (GtkButton       *button,
                                              gpointer         user_data)
{
    struct IP_Filter_Dialog_Context *	context 	= user_data;

    char *				src_1;
    char *				src_2;
    char *				src_3;
    char * 				src_4;
    char *				dst_1;
    char *				dst_2;
    char *				dst_3;
    char * 				dst_4;
    char *				src_mask;
    char *				dst_mask;

    int					temp;
    int					src_addr, dst_addr;
    int					src_cidr, dst_cidr;
    // moved from ports dialog
    enum bool 				range 		= false;
    char  				text[256];
    char  				num[16];
    int   				last;
    int   				i;
    char *                              src_port_entry;
    char *                              dst_port_entry;
    char *				c;

    // test buffers


    /*  right here, grab both check boxes, and all eight text boxes */

    if (gtk_toggle_button_get_active((GtkToggleButton*) context->src_chk) != false) {
	src_1 = gtk_entry_get_text(context->src_entry_1);    
        src_2 = gtk_entry_get_text(context->src_entry_2);    
        src_3 = gtk_entry_get_text(context->src_entry_3);    
        src_4 = gtk_entry_get_text(context->src_entry_4);    
        src_mask = gtk_entry_get_text(context->src_cidr);
        /* do the atoi thing before filter lock */
        src_addr = 0;
        temp = atoi(src_1);
        src_addr += temp;
        src_addr = src_addr << 8;
        temp = atoi(src_2);
        src_addr += temp;
        src_addr = src_addr << 8;
        temp = atoi(src_3);
        src_addr += temp;
        src_addr = src_addr << 8;
        temp = atoi(src_4);
        src_addr += temp;

        src_cidr = atoi(src_mask);

        pthread_mutex_lock(filter_mutex);
        opts->net_submenu.filter_on_src_addr = true;
        opts->net_submenu.src_addr = src_addr;
        opts->net_submenu.src_cidr = src_cidr;
	snprintf(src_addr_buf,255,"\nSource address %s.%s.%s.%s/%s", 
	   src_1, src_2, src_3, src_4, src_mask);
        pthread_mutex_unlock(filter_mutex);
    } else {
        pthread_mutex_lock(filter_mutex);
        opts->net_submenu.filter_on_src_addr = false;
        pthread_mutex_unlock(filter_mutex);
    }

    if (gtk_toggle_button_get_active((GtkToggleButton*) context->dst_chk) != false) {
        dst_1 = gtk_entry_get_text(context->dst_entry_1);    
        dst_2 = gtk_entry_get_text(context->dst_entry_2);    
        dst_3 = gtk_entry_get_text(context->dst_entry_3);    
        dst_4 = gtk_entry_get_text(context->dst_entry_4);    
        dst_mask = gtk_entry_get_text(context->dst_cidr);

        temp = atoi(dst_1);
        dst_addr += temp;
        dst_addr = dst_addr << 8;
        temp = atoi(dst_2);
        dst_addr += temp;
        dst_addr = dst_addr << 8;
        temp = atoi(dst_3);
        dst_addr += temp;
        dst_addr = dst_addr << 8;
        temp = atoi(dst_4);
        dst_addr += temp;

        dst_cidr = atoi(dst_mask);

        pthread_mutex_lock(filter_mutex);
        opts->net_submenu.filter_on_dst_addr = true;
        opts->net_submenu.dst_addr = dst_addr;
        opts->net_submenu.dst_cidr = dst_cidr;
	snprintf(dst_addr_buf,255,"\nDestination address %s.%s.%s.%s/%s", 
	   dst_1, dst_2, dst_3, dst_4, dst_mask);
        pthread_mutex_unlock(filter_mutex);
    } else {
        pthread_mutex_lock(filter_mutex);
        opts->net_submenu.filter_on_dst_addr = false;
        pthread_mutex_unlock(filter_mutex);
    }
/* XXX  insert ports dialog changes here.... */
    
    
    if (gtk_toggle_button_get_active((GtkToggleButton*) context->src_port_chk) != false) {
        src_port_entry = gtk_entry_get_text(context->src_port_entry);
    

        pthread_mutex_lock(filter_mutex);

        opts->net_submenu.filter_on_src_ports = true;

        for (i = 1; i <= NUM_OF_PORTS; ++i) {
            opts->net_submenu.src_ports[i] = false;
        }

        c = src_port_entry;
        while (*c != '\0') {
            if (IS_DIGIT(*c)) {
                i = 0;
                do {
                    num[i++] = *(c++);
                } while (IS_DIGIT(*c) && i < (sizeof(num) / sizeof(num[0]) - 1));
                num[i] = '\0';

                if (range) { 
                    for (i = last + 1; i <= atoi(num) && i <= NUM_OF_PORTS; ++i) {
                        opts->net_submenu.src_ports[i] = true;
                    }
                    range = false;
                } else { 
                    last = atoi(num);
                    if (last <= NUM_OF_PORTS) {
                        opts->net_submenu.src_ports[last] = true;
                    }
                }
            }

            if (*c == '-') {
                range = true;
            }

            ++c;
        }
    
        pthread_mutex_unlock(filter_mutex);
    } else opts->net_submenu.filter_on_src_ports = false;

    if (gtk_toggle_button_get_active((GtkToggleButton*) context->dst_port_chk) != false) {
        dst_port_entry = gtk_entry_get_text(context->dst_port_entry);
    
    
        pthread_mutex_lock(filter_mutex);
 
        opts->net_submenu.filter_on_dst_ports = true;

        for (i = 1; i <= NUM_OF_PORTS; ++i) {
            opts->net_submenu.dst_ports[i] = false;
        }

        c = dst_port_entry;
        while (*c != '\0') {
            if (IS_DIGIT(*c)) {
                i = 0;
                do {
                    num[i++] = *(c++);
                } while (IS_DIGIT(*c) && i < (sizeof(num) / sizeof(num[0]) - 1));
                num[i] = '\0';

                if (range) { 
                    for (i = last + 1; i <= atoi(num) && i <= NUM_OF_PORTS; ++i) {
                        opts->net_submenu.dst_ports[i] = true;
                    }
                    range = false;
                } else { 
                    last = atoi(num);
                    if (last <= NUM_OF_PORTS) {
                        opts->net_submenu.dst_ports[last] = true;
                    }
                }
            }

            if (*c == '-') {
                range = true;
            }

            ++c;
        }

        pthread_mutex_unlock(filter_mutex);
    } else opts->net_submenu.filter_on_dst_ports = false;   
    
    strncpy(dst_ports_buf, dst_port_entry, 255);
    pthread_mutex_lock(filter_mutex);

    snprintf(src_ports_buf, 255, "\nShowing source ports %s", src_port_entry);
    snprintf(dst_ports_buf, 255, "\nShowing destination ports %s", dst_port_entry);
   

    pthread_mutex_unlock(filter_mutex);

    gtk_widget_hide(context->dialog);

    set_status_bar_text();
}


void on_filter_cancel_clicked 		     (GtkButton       *button,
                                              gpointer         user_data)
{
    GtkWidget *				ip_filter_dialog 	= user_data;

    gtk_widget_hide(ip_filter_dialog);

}

void set_status_bar_text()
{
    strncpy(status_text, filter_buf, 255);

    pthread_mutex_lock(filter_mutex);
    if (opts->net_submenu.filter_on_src_addr == true) {
        strncat(status_text, src_addr_buf, 255);
    }
    if (opts->net_submenu.filter_on_dst_addr == true) {
        strncat(status_text, dst_addr_buf, 255);
    }
    if (opts->net_submenu.filter_on_src_ports == true) {
        strncat(status_text, src_ports_buf, 255);
    }
    if (opts->net_submenu.filter_on_dst_ports == true) {
        strncat(status_text, dst_ports_buf, 255);
    }
    pthread_mutex_unlock(filter_mutex);

   gtk_label_set_text(statusbar, status_text);


}


syntax highlighted by Code2HTML, v. 0.9.1