~guadalinex-members/gnome-system-tools/gnome-system-tools-2.22.2

« back to all changes in this revision

Viewing changes to src/common/gst-filter.c

  • Committer: Juanje Ojeda Croissier
  • Date: 2009-04-06 15:47:26 UTC
  • Revision ID: jojeda@emergya.es-20090406154726-h29t5g1n1wwc4x2h
Tags: gnome-system-tools-2.22.2-0ubuntu3
Imported the g-s-t code directly from the source package gnome-system-tools-2.22.2-0ubuntu3 (jaunty)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
 
2
/* Copyright (C) 2004 Carlos Garnacho
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
18
 * Authors: Carlos Garnacho Parro  <carlosg@gnome.org>
 
19
 */
 
20
 
 
21
#include <string.h>
 
22
 
 
23
#include "gst-filter.h"
 
24
 
 
25
typedef enum {
 
26
  IP_UNK,
 
27
  IP_V4,
 
28
  IP_V6
 
29
} IpVersion;
 
30
 
 
31
/* gets the value of a numeric IP address section */
 
32
static gint
 
33
get_address_section_value (const gchar *text, gint start, gint len)
 
34
{
 
35
  gchar *c = (gchar *) &text[start];
 
36
  gchar *str = g_strndup (c, len);
 
37
  gint value = g_strtod (str, NULL);
 
38
  gint i;
 
39
 
 
40
  for (i = 0; i < len; i++)
 
41
    {
 
42
      if ((str[i] < '0') || (str [i] > '9'))
 
43
        {
 
44
          g_free (str);
 
45
          return 256;
 
46
        }
 
47
    }
 
48
 
 
49
  g_free (str);
 
50
  return value;
 
51
}
 
52
 
 
53
/* I don't expect this function to be understood, but
 
54
 * it works with IPv4, IPv6 and IPv4 embedded in IPv6
 
55
 */
 
56
GstAddressRet
 
57
gst_filter_check_ip_address (const gchar *text)
 
58
{
 
59
  gint      i, len, numsep, section_val, nsegments;
 
60
  gboolean  has_double_colon, segment_has_alpha;
 
61
  IpVersion ver;
 
62
  gchar     c;
 
63
 
 
64
  if (!text)
 
65
    return GST_ADDRESS_INCOMPLETE;
 
66
 
 
67
  ver = IP_UNK;
 
68
  len = 0;
 
69
  numsep = 0;
 
70
  nsegments = 0;
 
71
  has_double_colon = FALSE;
 
72
  segment_has_alpha = FALSE;
 
73
 
 
74
  for (i = 0; text[i]; i++)
 
75
    {
 
76
      c = text[i];
 
77
 
 
78
      if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
 
79
        {
 
80
          len++;
 
81
 
 
82
          if ((ver == IP_V4) ||
 
83
              ((ver == IP_V6) && (i == 1) && (text[0] == ':')) ||
 
84
              ((ver == IP_V6) && (len > 4)))
 
85
            return GST_ADDRESS_ERROR;
 
86
 
 
87
          if (ver == IP_UNK)
 
88
            ver = IP_V6;
 
89
 
 
90
          segment_has_alpha = TRUE;
 
91
        }
 
92
      else if (c >='0' && c <='9')
 
93
        {
 
94
        len++;
 
95
        section_val = get_address_section_value (text, i - len + 1, len);
 
96
 
 
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;
 
102
 
 
103
        if ((ver == IP_UNK) && ((len == 4) || (section_val > 255)))
 
104
          ver = IP_V6;
 
105
        }
 
106
      else if (c == '.')
 
107
        {
 
108
        section_val = get_address_section_value (text, i - len, len);
 
109
        numsep++;
 
110
 
 
111
        if ((len == 0) ||
 
112
            ((ver == IP_V4) && (numsep > 3)) ||
 
113
            ((ver == IP_V6) && ((numsep > 6) || (len > 3) || (len == 0) || (section_val > 255))))
 
114
          return GST_ADDRESS_ERROR;
 
115
 
 
116
        if ((ver == IP_V6) && (len >= 1) && (len <= 3) && (!segment_has_alpha) && (section_val <= 255))
 
117
          {
 
118
            ver = IP_V4;
 
119
            numsep = 1;
 
120
          }
 
121
 
 
122
        if ((ver == IP_UNK) && (section_val <= 255))
 
123
          ver = IP_V4;
 
124
 
 
125
        len = 0;
 
126
        }
 
127
      else if (c == ':')
 
128
        {
 
129
          numsep++;
 
130
 
 
131
          if ((ver == IP_V4) ||
 
132
              (numsep >= 8) ||
 
133
              ((len == 0) && (has_double_colon)))
 
134
            return GST_ADDRESS_ERROR;
 
135
 
 
136
          if ((numsep > 1) && (len == 0) && (!has_double_colon))
 
137
            has_double_colon = TRUE;
 
138
 
 
139
          if (ver == IP_UNK)
 
140
            ver = IP_V6;
 
141
 
 
142
          len = 0;
 
143
          segment_has_alpha = FALSE;
 
144
        }
 
145
      else 
 
146
        return GST_ADDRESS_ERROR;
 
147
    }
 
148
 
 
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;
 
153
 
 
154
  if (ver == IP_V4)
 
155
    return GST_ADDRESS_IPV4_INCOMPLETE;
 
156
  else if (ver == IP_V6)
 
157
    return GST_ADDRESS_IPV6_INCOMPLETE;
 
158
 
 
159
  return GST_ADDRESS_INCOMPLETE;
 
160
}
 
161
 
 
162
static gboolean
 
163
check_string (gint filter, const gchar *str)
 
164
{
 
165
  gboolean success = FALSE;
 
166
  gint ret;
 
167
 
 
168
  if ((filter == GST_FILTER_IP) ||
 
169
      (filter == GST_FILTER_IPV4) ||
 
170
      (filter == GST_FILTER_IPV6))
 
171
    {
 
172
      ret = gst_filter_check_ip_address (str);
 
173
 
 
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));
 
188
    }
 
189
  else if (filter == GST_FILTER_PHONE)
 
190
    success = (strspn (str, "0123456789abcdABCD,#*") == strlen (str));
 
191
 
 
192
  return success;
 
193
}
 
194
 
 
195
static void
 
196
insert_filter (GtkEditable *editable, const gchar *text, gint length, gint *pos, gpointer data)
 
197
{
 
198
  gint   filter;
 
199
  gchar *str, *pre, *post;
 
200
 
 
201
  filter = GPOINTER_TO_INT (data);
 
202
  pre  = gtk_editable_get_chars (editable, 0, *pos);
 
203
  post = gtk_editable_get_chars (editable, *pos, -1);
 
204
 
 
205
  str = g_strconcat (pre, text, post, NULL);
 
206
 
 
207
  if (!check_string (filter, str))
 
208
    g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
 
209
 
 
210
  g_free (pre);
 
211
  g_free (post);
 
212
  g_free (str);
 
213
}
 
214
 
 
215
static void
 
216
delete_filter (GtkEditable *editable, gint start, gint end, gpointer data)
 
217
{
 
218
  gint   filter;
 
219
  gchar *str, *pre, *post;
 
220
 
 
221
  filter = GPOINTER_TO_INT (data);
 
222
  pre  = gtk_editable_get_chars (editable, 0, start);
 
223
  post = gtk_editable_get_chars (editable, end, -1);
 
224
 
 
225
  str = g_strconcat (pre, post, NULL);
 
226
 
 
227
  if (!check_string (filter, str))
 
228
    g_signal_stop_emission_by_name (G_OBJECT (editable), "delete-text");
 
229
 
 
230
  g_free (pre);
 
231
  g_free (post);
 
232
  g_free (str);
 
233
}
 
234
 
 
235
void
 
236
gst_filter_init (GtkEntry *entry, gint filter)
 
237
{
 
238
  g_signal_connect (G_OBJECT (entry), "insert-text",
 
239
                    G_CALLBACK (insert_filter), GINT_TO_POINTER (filter));
 
240
 
 
241
  g_signal_connect (G_OBJECT (entry), "delete-text",
 
242
                    G_CALLBACK (delete_filter), GINT_TO_POINTER (filter));
 
243
}