1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/* Copyright (C) 2004 Carlos Garnacho
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; either version 2 of the
7
* License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18
* Authors: Carlos Garnacho Parro <carlosg@gnome.org>
23
#include "gst-filter.h"
31
/* gets the value of a numeric IP address section */
33
get_address_section_value (const gchar *text, gint start, gint len)
35
gchar *c = (gchar *) &text[start];
36
gchar *str = g_strndup (c, len);
37
gint value = g_strtod (str, NULL);
40
for (i = 0; i < len; i++)
42
if ((str[i] < '0') || (str [i] > '9'))
53
/* I don't expect this function to be understood, but
54
* it works with IPv4, IPv6 and IPv4 embedded in IPv6
57
gst_filter_check_ip_address (const gchar *text)
59
gint i, len, numsep, section_val, nsegments;
60
gboolean has_double_colon, segment_has_alpha;
65
return GST_ADDRESS_INCOMPLETE;
71
has_double_colon = FALSE;
72
segment_has_alpha = FALSE;
74
for (i = 0; text[i]; i++)
78
if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
83
((ver == IP_V6) && (i == 1) && (text[0] == ':')) ||
84
((ver == IP_V6) && (len > 4)))
85
return GST_ADDRESS_ERROR;
90
segment_has_alpha = TRUE;
92
else if (c >='0' && c <='9')
95
section_val = get_address_section_value (text, i - len + 1, len);
97
if (((ver == IP_V4) && ((len > 3) || (section_val > 255))) ||
98
((ver == IP_V6) && (i == 1) && (text[0] == ':')) ||
99
((ver == IP_V6) && (len > 4)) ||
100
((ver == IP_UNK) && (len > 4)))
101
return GST_ADDRESS_ERROR;
103
if ((ver == IP_UNK) && ((len == 4) || (section_val > 255)))
108
section_val = get_address_section_value (text, i - len, len);
112
((ver == IP_V4) && (numsep > 3)) ||
113
((ver == IP_V6) && ((numsep > 6) || (len > 3) || (len == 0) || (section_val > 255))))
114
return GST_ADDRESS_ERROR;
116
if ((ver == IP_V6) && (len >= 1) && (len <= 3) && (!segment_has_alpha) && (section_val <= 255))
122
if ((ver == IP_UNK) && (section_val <= 255))
131
if ((ver == IP_V4) ||
133
((len == 0) && (has_double_colon)))
134
return GST_ADDRESS_ERROR;
136
if ((numsep > 1) && (len == 0) && (!has_double_colon))
137
has_double_colon = TRUE;
143
segment_has_alpha = FALSE;
146
return GST_ADDRESS_ERROR;
149
if ((ver == IP_V4) && (numsep == 3) && (len > 0))
150
return GST_ADDRESS_IPV4;
151
else if ((ver == IP_V6) && (len > 0) && ((numsep == 8) || has_double_colon))
152
return GST_ADDRESS_IPV6;
155
return GST_ADDRESS_IPV4_INCOMPLETE;
156
else if (ver == IP_V6)
157
return GST_ADDRESS_IPV6_INCOMPLETE;
159
return GST_ADDRESS_INCOMPLETE;
163
check_string (gint filter, const gchar *str)
165
gboolean success = FALSE;
168
if ((filter == GST_FILTER_IP) ||
169
(filter == GST_FILTER_IPV4) ||
170
(filter == GST_FILTER_IPV6))
172
ret = gst_filter_check_ip_address (str);
174
if (filter == GST_FILTER_IP)
175
success = ((ret == GST_ADDRESS_INCOMPLETE) ||
176
(ret == GST_ADDRESS_IPV4_INCOMPLETE) ||
177
(ret == GST_ADDRESS_IPV4) ||
178
(ret == GST_ADDRESS_IPV6_INCOMPLETE) ||
179
(ret == GST_ADDRESS_IPV6));
180
else if (filter == GST_FILTER_IPV4)
181
success = ((ret == GST_ADDRESS_INCOMPLETE) ||
182
(ret == GST_ADDRESS_IPV4_INCOMPLETE) ||
183
(ret == GST_ADDRESS_IPV4));
184
else if (filter == GST_FILTER_IPV6)
185
success = ((ret == GST_ADDRESS_INCOMPLETE) ||
186
(ret == GST_ADDRESS_IPV6_INCOMPLETE) ||
187
(ret == GST_ADDRESS_IPV6));
189
else if (filter == GST_FILTER_PHONE)
190
success = (strspn (str, "0123456789abcdABCD,#*") == strlen (str));
196
insert_filter (GtkEditable *editable, const gchar *text, gint length, gint *pos, gpointer data)
199
gchar *str, *pre, *post;
201
filter = GPOINTER_TO_INT (data);
202
pre = gtk_editable_get_chars (editable, 0, *pos);
203
post = gtk_editable_get_chars (editable, *pos, -1);
205
str = g_strconcat (pre, text, post, NULL);
207
if (!check_string (filter, str))
208
g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
216
delete_filter (GtkEditable *editable, gint start, gint end, gpointer data)
219
gchar *str, *pre, *post;
221
filter = GPOINTER_TO_INT (data);
222
pre = gtk_editable_get_chars (editable, 0, start);
223
post = gtk_editable_get_chars (editable, end, -1);
225
str = g_strconcat (pre, post, NULL);
227
if (!check_string (filter, str))
228
g_signal_stop_emission_by_name (G_OBJECT (editable), "delete-text");
236
gst_filter_init (GtkEntry *entry, gint filter)
238
g_signal_connect (G_OBJECT (entry), "insert-text",
239
G_CALLBACK (insert_filter), GINT_TO_POINTER (filter));
241
g_signal_connect (G_OBJECT (entry), "delete-text",
242
G_CALLBACK (delete_filter), GINT_TO_POINTER (filter));