Blame clients/tui/nmt-ip-entry.c

Packit Service b23acc
// SPDX-License-Identifier: GPL-2.0+
Packit Service b23acc
/*
Packit Service b23acc
 * Copyright (C) 2013 Red Hat, Inc.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * SECTION:nmt-ip-entry
Packit Service b23acc
 * @short_description: #NmtNewtEntry for IP address entry
Packit Service b23acc
 *
Packit Service b23acc
 * #NmtIPEntry is an #NmtNewtEntry for entering IP addresses, or IP
Packit Service b23acc
 * address/prefix combination. It will only allow typing characters
Packit Service b23acc
 * that are valid in an IP address, and will set its
Packit Service b23acc
 * #NmtNewtWidget:valid property depending on whether it currently
Packit Service b23acc
 * contains a valid IP address.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
#include "nm-default.h"
Packit Service b23acc
Packit Service b23acc
#include <arpa/inet.h>
Packit Service b23acc
#include <netinet/in.h>
Packit Service b23acc
#include <stdlib.h>
Packit Service b23acc
Packit Service b23acc
#include "nmt-ip-entry.h"
Packit Service b23acc
Packit Service b23acc
G_DEFINE_TYPE (NmtIPEntry, nmt_ip_entry, NMT_TYPE_NEWT_ENTRY)
Packit Service b23acc
Packit Service b23acc
#define NMT_IP_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_IP_ENTRY, NmtIPEntryPrivate))
Packit Service b23acc
Packit Service b23acc
typedef struct {
Packit Service b23acc
	int family;
Packit Service b23acc
	gboolean prefix;
Packit Service b23acc
	gboolean optional;
Packit Service b23acc
Packit Service b23acc
} NmtIPEntryPrivate;
Packit Service b23acc
Packit Service b23acc
enum {
Packit Service b23acc
	PROP_0,
Packit Service b23acc
	PROP_FAMILY,
Packit Service b23acc
	PROP_PREFIX,
Packit Service b23acc
	PROP_OPTIONAL,
Packit Service b23acc
Packit Service b23acc
	LAST_PROP
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nmt_ip_entry_new:
Packit Service b23acc
 * @width: the width of the entry
Packit Service b23acc
 * @family: the IP address family. Eg, %AF_INET
Packit Service b23acc
 * @prefix: whether to require a trailing "/prefix"
Packit Service b23acc
 * @optional: whether the address is optional
Packit Service b23acc
 *
Packit Service b23acc
 * Creates a new #NmtIPEntry, to accept IP addresses in the indicated
Packit Service b23acc
 * @family, or (if @prefix is %TRUE), to accept IP address/prefix combos.
Packit Service b23acc
 *
Packit Service b23acc
 * If @optional is %TRUE then the address is considered optional, and
Packit Service b23acc
 * so will still be #NmtNewtWidget:valid even when it is empty. If
Packit Service b23acc
 * @optional is %FALSE, the entry will be invalid when it is empty.
Packit Service b23acc
 */
Packit Service b23acc
NmtNewtWidget *
Packit Service b23acc
nmt_ip_entry_new (int      width,
Packit Service b23acc
                  int      family,
Packit Service b23acc
                  gboolean prefix,
Packit Service b23acc
                  gboolean optional)
Packit Service b23acc
{
Packit Service b23acc
	return g_object_new (NMT_TYPE_IP_ENTRY,
Packit Service b23acc
	                     "width", width,
Packit Service b23acc
	                     "family", family,
Packit Service b23acc
	                     "prefix", prefix,
Packit Service b23acc
	                     "optional", optional,
Packit Service b23acc
	                     NULL);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
ip_entry_filter (NmtNewtEntry *entry,
Packit Service b23acc
                 const char   *text,
Packit Service b23acc
                 int           ch,
Packit Service b23acc
                 int           position,
Packit Service b23acc
                 gpointer      user_data)
Packit Service b23acc
{
Packit Service b23acc
	NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (entry);
Packit Service b23acc
	const char *slash;
Packit Service b23acc
	gboolean inaddr;
Packit Service b23acc
Packit Service b23acc
	if (g_ascii_isdigit (ch))
Packit Service b23acc
		return TRUE;
Packit Service b23acc
Packit Service b23acc
	slash = strchr (text, '/');
Packit Service b23acc
	if (ch == '/')
Packit Service b23acc
		return priv->prefix && slash == NULL;
Packit Service b23acc
Packit Service b23acc
	inaddr = !slash || (position <= (slash - text));
Packit Service b23acc
Packit Service b23acc
	if (priv->family == AF_INET) {
Packit Service b23acc
		if (ch == '.')
Packit Service b23acc
			return inaddr;
Packit Service b23acc
		else
Packit Service b23acc
			return FALSE;
Packit Service b23acc
	} else if (priv->family == AF_INET6) {
Packit Service b23acc
		if (g_ascii_isxdigit (ch) || ch == ':')
Packit Service b23acc
			return inaddr;
Packit Service b23acc
		else
Packit Service b23acc
			return FALSE;
Packit Service b23acc
	} else
Packit Service b23acc
		g_return_val_if_reached (FALSE);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
ip_entry_validate (NmtNewtEntry *entry,
Packit Service b23acc
                   const char   *text,
Packit Service b23acc
                   gpointer      user_data)
Packit Service b23acc
{
Packit Service b23acc
	NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (entry);
Packit Service b23acc
Packit Service b23acc
	if (!*text)
Packit Service b23acc
		return priv->optional;
Packit Service b23acc
	if (priv->prefix)
Packit Service b23acc
		return nm_utils_parse_inaddr_prefix (priv->family, text, NULL, NULL);
Packit Service b23acc
	return nm_utils_parse_inaddr (priv->family, text, NULL);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nmt_ip_entry_init (NmtIPEntry *entry)
Packit Service b23acc
{
Packit Service b23acc
	nmt_newt_entry_set_filter (NMT_NEWT_ENTRY (entry), ip_entry_filter, NULL);
Packit Service b23acc
	nmt_newt_entry_set_validator (NMT_NEWT_ENTRY (entry), ip_entry_validate, NULL);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nmt_ip_entry_set_property (GObject      *object,
Packit Service b23acc
                           guint         prop_id,
Packit Service b23acc
                           const GValue *value,
Packit Service b23acc
                           GParamSpec   *pspec)
Packit Service b23acc
{
Packit Service b23acc
	NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (object);
Packit Service b23acc
Packit Service b23acc
	switch (prop_id) {
Packit Service b23acc
	case PROP_FAMILY:
Packit Service b23acc
		priv->family = g_value_get_int (value);
Packit Service b23acc
		break;
Packit Service b23acc
	case PROP_PREFIX:
Packit Service b23acc
		priv->prefix = g_value_get_boolean (value);
Packit Service b23acc
		break;
Packit Service b23acc
	case PROP_OPTIONAL:
Packit Service b23acc
		priv->optional = g_value_get_boolean (value);
Packit Service b23acc
		break;
Packit Service b23acc
	default:
Packit Service b23acc
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nmt_ip_entry_get_property (GObject    *object,
Packit Service b23acc
                           guint       prop_id,
Packit Service b23acc
                           GValue     *value,
Packit Service b23acc
                           GParamSpec *pspec)
Packit Service b23acc
{
Packit Service b23acc
	NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (object);
Packit Service b23acc
Packit Service b23acc
	switch (prop_id) {
Packit Service b23acc
	case PROP_FAMILY:
Packit Service b23acc
		g_value_set_int (value, priv->family);
Packit Service b23acc
		break;
Packit Service b23acc
	case PROP_PREFIX:
Packit Service b23acc
		g_value_set_boolean (value, priv->prefix);
Packit Service b23acc
		break;
Packit Service b23acc
	case PROP_OPTIONAL:
Packit Service b23acc
		g_value_set_boolean (value, priv->optional);
Packit Service b23acc
		break;
Packit Service b23acc
	default:
Packit Service b23acc
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nmt_ip_entry_class_init (NmtIPEntryClass *entry_class)
Packit Service b23acc
{
Packit Service b23acc
	GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
Packit Service b23acc
Packit Service b23acc
	g_type_class_add_private (entry_class, sizeof (NmtIPEntryPrivate));
Packit Service b23acc
Packit Service b23acc
	/* virtual methods */
Packit Service b23acc
	object_class->set_property = nmt_ip_entry_set_property;
Packit Service b23acc
	object_class->get_property = nmt_ip_entry_get_property;
Packit Service b23acc
Packit Service b23acc
	/**
Packit Service b23acc
	 * NmtIPEntry:family:
Packit Service b23acc
	 *
Packit Service b23acc
	 * The address family. Eg, %AF_INET
Packit Service b23acc
	 */
Packit Service b23acc
	g_object_class_install_property
Packit Service b23acc
		(object_class, PROP_FAMILY,
Packit Service b23acc
		 g_param_spec_int ("family", "", "",
Packit Service b23acc
		                   0, G_MAXINT, 0,
Packit Service b23acc
		                   G_PARAM_READWRITE |
Packit Service b23acc
		                   G_PARAM_CONSTRUCT_ONLY |
Packit Service b23acc
		                   G_PARAM_STATIC_STRINGS));
Packit Service b23acc
	/**
Packit Service b23acc
	 * NmtIPEntry:prefix:
Packit Service b23acc
	 *
Packit Service b23acc
	 * If %TRUE, the entry accepts address/prefix combinations. If
Packit Service b23acc
	 * %FALSE it accepts just addresses.
Packit Service b23acc
	 */
Packit Service b23acc
	g_object_class_install_property
Packit Service b23acc
		(object_class, PROP_PREFIX,
Packit Service b23acc
		 g_param_spec_boolean ("prefix", "", "",
Packit Service b23acc
		                       FALSE,
Packit Service b23acc
		                       G_PARAM_READWRITE |
Packit Service b23acc
		                       G_PARAM_CONSTRUCT_ONLY |
Packit Service b23acc
		                       G_PARAM_STATIC_STRINGS));
Packit Service b23acc
	/**
Packit Service b23acc
	 * NmtIPEntry:optional:
Packit Service b23acc
	 *
Packit Service b23acc
	 * If %TRUE, the entry will be #NmtNewtWidget:valid when it is
Packit Service b23acc
	 * empty. If %FALSE, it will only be valid when it contains a
Packit Service b23acc
	 * valid address or address/prefix.
Packit Service b23acc
	 */
Packit Service b23acc
	g_object_class_install_property
Packit Service b23acc
		(object_class, PROP_OPTIONAL,
Packit Service b23acc
		 g_param_spec_boolean ("optional", "", "",
Packit Service b23acc
		                       FALSE,
Packit Service b23acc
		                       G_PARAM_READWRITE |
Packit Service b23acc
		                       G_PARAM_CONSTRUCT_ONLY |
Packit Service b23acc
		                       G_PARAM_STATIC_STRINGS));
Packit Service b23acc
}