1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2020 Canonical Ltd.
4 *
5 * Licensed under the GNU General Public License Version 2
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <arpa/inet.h>
23 #include <NetworkManager.h>
24
25 #include "ce-netmask-entry.h"
26
27 struct _CENetmaskEntry
28 {
29 GtkEntry parent_instance;
30 };
31
32 static void ce_netmask_entry_editable_init (GtkEditableInterface *iface);
33
G_DEFINE_TYPE_WITH_CODE(CENetmaskEntry,ce_netmask_entry,GTK_TYPE_ENTRY,G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,ce_netmask_entry_editable_init))34 G_DEFINE_TYPE_WITH_CODE (CENetmaskEntry, ce_netmask_entry, GTK_TYPE_ENTRY,
35 G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
36 ce_netmask_entry_editable_init))
37
38 static gboolean
39 parse_netmask (const char *str, guint32 *prefix)
40 {
41 struct in_addr tmp_addr;
42 glong tmp_prefix;
43
44 /* Is it a prefix? */
45 errno = 0;
46 if (!strchr (str, '.'))
47 {
48 tmp_prefix = strtol (str, NULL, 10);
49 if (!errno && tmp_prefix >= 0 && tmp_prefix <= 32)
50 {
51 if (prefix != NULL)
52 *prefix = tmp_prefix;
53 return TRUE;
54 }
55 }
56
57 /* Is it a netmask? */
58 if (inet_pton (AF_INET, str, &tmp_addr) > 0)
59 {
60 if (prefix != NULL)
61 *prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr);
62 return TRUE;
63 }
64
65 return FALSE;
66 }
67
68 static void
ce_netmask_entry_changed(GtkEditable * editable)69 ce_netmask_entry_changed (GtkEditable *editable)
70 {
71 CENetmaskEntry *self = CE_NETMASK_ENTRY (editable);
72 GtkStyleContext *context;
73
74 context = gtk_widget_get_style_context (GTK_WIDGET (self));
75 if (ce_netmask_entry_is_valid (self))
76 gtk_style_context_remove_class (context, "error");
77 else
78 gtk_style_context_add_class (context, "error");
79 }
80
81 static void
ce_netmask_entry_init(CENetmaskEntry * self)82 ce_netmask_entry_init (CENetmaskEntry *self)
83 {
84 }
85
86 static void
ce_netmask_entry_editable_init(GtkEditableInterface * iface)87 ce_netmask_entry_editable_init (GtkEditableInterface *iface)
88 {
89 iface->changed = ce_netmask_entry_changed;
90 }
91
92 static void
ce_netmask_entry_class_init(CENetmaskEntryClass * klass)93 ce_netmask_entry_class_init (CENetmaskEntryClass *klass)
94 {
95 }
96
97 CENetmaskEntry *
ce_netmask_entry_new(void)98 ce_netmask_entry_new (void)
99 {
100 return CE_NETMASK_ENTRY (g_object_new (ce_netmask_entry_get_type (), NULL));
101 }
102
103 gboolean
ce_netmask_entry_is_empty(CENetmaskEntry * self)104 ce_netmask_entry_is_empty (CENetmaskEntry *self)
105 {
106 const gchar *text;
107
108 g_return_val_if_fail (CE_IS_NETMASK_ENTRY (self), FALSE);
109
110 text = gtk_entry_get_text (GTK_ENTRY (self));
111 return text[0] == '\0';
112 }
113
114 gboolean
ce_netmask_entry_is_valid(CENetmaskEntry * self)115 ce_netmask_entry_is_valid (CENetmaskEntry *self)
116 {
117 const gchar *text;
118
119 g_return_val_if_fail (CE_IS_NETMASK_ENTRY (self), FALSE);
120
121 text = gtk_entry_get_text (GTK_ENTRY (self));
122 return text[0] == '\0' || parse_netmask (text, NULL);
123 }
124
125 guint32
ce_netmask_entry_get_prefix(CENetmaskEntry * self)126 ce_netmask_entry_get_prefix (CENetmaskEntry *self)
127 {
128 const gchar *text;
129 guint32 prefix = 0;
130
131 g_return_val_if_fail (CE_IS_NETMASK_ENTRY (self), 0);
132
133 text = gtk_entry_get_text (GTK_ENTRY (self));
134 parse_netmask (text, &prefix);
135
136 return prefix;
137 }
138