Merge branch 'master' into wimax
This commit is contained in:
@@ -751,6 +751,7 @@ main (int argc, char **argv)
|
|||||||
if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) {
|
if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) {
|
||||||
g_warning ("%s\n", error->message);
|
g_warning ("%s\n", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
g_free (d);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,8 +16,6 @@ NETWORKMANAGER_BIN=${sbindir}/NetworkManager
|
|||||||
PID=`pidof -o %PPID $NETWORKMANAGER_BIN`
|
PID=`pidof -o %PPID $NETWORKMANAGER_BIN`
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
ck_daemon hal && /etc/rc.d/hal start
|
|
||||||
sleep 1
|
|
||||||
stat_busy "Starting NetworkManager"
|
stat_busy "Starting NetworkManager"
|
||||||
if [ -z "$PID" ]; then
|
if [ -z "$PID" ]; then
|
||||||
$NETWORKMANAGER_BIN
|
$NETWORKMANAGER_BIN
|
||||||
|
@@ -41,6 +41,8 @@ object. dbus-glib generates the same bound function names for D-Bus the methods
|
|||||||
|
|
||||||
<property name="WirelessEnabled" type="b" access="readwrite"/>
|
<property name="WirelessEnabled" type="b" access="readwrite"/>
|
||||||
<property name="WirelessHardwareEnabled" type="b" access="read"/>
|
<property name="WirelessHardwareEnabled" type="b" access="read"/>
|
||||||
|
<property name="WwanEnabled" type="b" access="readwrite"/>
|
||||||
|
<property name="WwanHardwareEnabled" type="b" access="read"/>
|
||||||
<property name="ActiveConnections" type="ao" access="read"/>
|
<property name="ActiveConnections" type="ao" access="read"/>
|
||||||
<property name="State" type="u" access="read"/>
|
<property name="State" type="u" access="read"/>
|
||||||
|
|
||||||
|
@@ -108,6 +108,18 @@
|
|||||||
</tp:docstring>
|
</tp:docstring>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<property name="WwanEnabled" type="b" access="readwrite">
|
||||||
|
<tp:docstring>
|
||||||
|
Indicates if mobile broadband devices are currently enabled or not.
|
||||||
|
</tp:docstring>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="WwanHardwareEnabled" type="b" access="read">
|
||||||
|
<tp:docstring>
|
||||||
|
Indicates if the mobile broadband hardware is currently enabled, i.e. the state of the RF kill switch.
|
||||||
|
</tp:docstring>
|
||||||
|
</property>
|
||||||
|
|
||||||
<property name="ActiveConnections" type="ao" access="read">
|
<property name="ActiveConnections" type="ao" access="read">
|
||||||
<tp:docstring>
|
<tp:docstring>
|
||||||
List of active connection object paths.
|
List of active connection object paths.
|
||||||
|
@@ -110,7 +110,7 @@ libnm_glib_la_LIBADD = \
|
|||||||
$(GUDEV_LIBS)
|
$(GUDEV_LIBS)
|
||||||
|
|
||||||
libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \
|
libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \
|
||||||
-version-info "3:0:1"
|
-version-info "4:0:2"
|
||||||
|
|
||||||
noinst_PROGRAMS = libnm-glib-test
|
noinst_PROGRAMS = libnm-glib-test
|
||||||
|
|
||||||
|
@@ -40,6 +40,9 @@ global:
|
|||||||
nm_client_wireless_get_enabled;
|
nm_client_wireless_get_enabled;
|
||||||
nm_client_wireless_hardware_get_enabled;
|
nm_client_wireless_hardware_get_enabled;
|
||||||
nm_client_wireless_set_enabled;
|
nm_client_wireless_set_enabled;
|
||||||
|
nm_client_wwan_get_enabled;
|
||||||
|
nm_client_wwan_hardware_get_enabled;
|
||||||
|
nm_client_wwan_set_enabled;
|
||||||
nm_dbus_settings_get_connection_by_path;
|
nm_dbus_settings_get_connection_by_path;
|
||||||
nm_dbus_settings_get_type;
|
nm_dbus_settings_get_type;
|
||||||
nm_dbus_settings_new;
|
nm_dbus_settings_new;
|
||||||
|
@@ -60,6 +60,9 @@ typedef struct {
|
|||||||
|
|
||||||
gboolean wireless_enabled;
|
gboolean wireless_enabled;
|
||||||
gboolean wireless_hw_enabled;
|
gboolean wireless_hw_enabled;
|
||||||
|
|
||||||
|
gboolean wwan_enabled;
|
||||||
|
gboolean wwan_hw_enabled;
|
||||||
} NMClientPrivate;
|
} NMClientPrivate;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -68,6 +71,8 @@ enum {
|
|||||||
PROP_MANAGER_RUNNING,
|
PROP_MANAGER_RUNNING,
|
||||||
PROP_WIRELESS_ENABLED,
|
PROP_WIRELESS_ENABLED,
|
||||||
PROP_WIRELESS_HARDWARE_ENABLED,
|
PROP_WIRELESS_HARDWARE_ENABLED,
|
||||||
|
PROP_WWAN_ENABLED,
|
||||||
|
PROP_WWAN_HARDWARE_ENABLED,
|
||||||
PROP_ACTIVE_CONNECTIONS,
|
PROP_ACTIVE_CONNECTIONS,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
@@ -153,6 +158,36 @@ wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|||||||
poke_wireless_devices_with_rf_status (NM_CLIENT (object));
|
poke_wireless_devices_with_rf_status (NM_CLIENT (object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_wwan_status (NMClient *client, gboolean notify)
|
||||||
|
{
|
||||||
|
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
|
||||||
|
gboolean val;
|
||||||
|
|
||||||
|
val = _nm_object_get_boolean_property (NM_OBJECT (client),
|
||||||
|
NM_DBUS_INTERFACE,
|
||||||
|
"WwanHardwareEnabled");
|
||||||
|
if (val != priv->wwan_hw_enabled) {
|
||||||
|
priv->wwan_hw_enabled = val;
|
||||||
|
if (notify)
|
||||||
|
_nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_WWAN_HARDWARE_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->wwan_hw_enabled == FALSE)
|
||||||
|
val = FALSE;
|
||||||
|
else {
|
||||||
|
val = _nm_object_get_boolean_property (NM_OBJECT (client),
|
||||||
|
NM_DBUS_INTERFACE,
|
||||||
|
"WwanEnabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val != priv->wwan_enabled) {
|
||||||
|
priv->wwan_enabled = val;
|
||||||
|
if (notify)
|
||||||
|
_nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_WWAN_ENABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
new_active_connection (DBusGConnection *connection, const char *path)
|
new_active_connection (DBusGConnection *connection, const char *path)
|
||||||
{
|
{
|
||||||
@@ -217,6 +252,8 @@ register_for_property_changed (NMClient *client)
|
|||||||
{ NM_CLIENT_STATE, _nm_object_demarshal_generic, &priv->state },
|
{ NM_CLIENT_STATE, _nm_object_demarshal_generic, &priv->state },
|
||||||
{ NM_CLIENT_WIRELESS_ENABLED, _nm_object_demarshal_generic, &priv->wireless_enabled },
|
{ NM_CLIENT_WIRELESS_ENABLED, _nm_object_demarshal_generic, &priv->wireless_enabled },
|
||||||
{ NM_CLIENT_WIRELESS_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wireless_hw_enabled },
|
{ NM_CLIENT_WIRELESS_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wireless_hw_enabled },
|
||||||
|
{ NM_CLIENT_WWAN_ENABLED, _nm_object_demarshal_generic, &priv->wwan_enabled },
|
||||||
|
{ NM_CLIENT_WWAN_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wwan_hw_enabled },
|
||||||
{ NM_CLIENT_ACTIVE_CONNECTIONS, demarshal_active_connections, &priv->active_connections },
|
{ NM_CLIENT_ACTIVE_CONNECTIONS, demarshal_active_connections, &priv->active_connections },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
@@ -291,6 +328,7 @@ constructor (GType type,
|
|||||||
|
|
||||||
if (priv->manager_running) {
|
if (priv->manager_running) {
|
||||||
update_wireless_status (NM_CLIENT (object), FALSE);
|
update_wireless_status (NM_CLIENT (object), FALSE);
|
||||||
|
update_wwan_status (NM_CLIENT (object), FALSE);
|
||||||
nm_client_get_state (NM_CLIENT (object));
|
nm_client_get_state (NM_CLIENT (object));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,6 +391,20 @@ set_property (GObject *object, guint prop_id,
|
|||||||
_nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WIRELESS_HARDWARE_ENABLED);
|
_nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WIRELESS_HARDWARE_ENABLED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PROP_WWAN_ENABLED:
|
||||||
|
b = g_value_get_boolean (value);
|
||||||
|
if (priv->wwan_enabled != b) {
|
||||||
|
priv->wwan_enabled = b;
|
||||||
|
_nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WWAN_ENABLED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROP_WWAN_HARDWARE_ENABLED:
|
||||||
|
b = g_value_get_boolean (value);
|
||||||
|
if (priv->wwan_hw_enabled != b) {
|
||||||
|
priv->wwan_hw_enabled = b;
|
||||||
|
_nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WWAN_HARDWARE_ENABLED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -381,6 +433,12 @@ get_property (GObject *object,
|
|||||||
case PROP_WIRELESS_HARDWARE_ENABLED:
|
case PROP_WIRELESS_HARDWARE_ENABLED:
|
||||||
g_value_set_boolean (value, priv->wireless_hw_enabled);
|
g_value_set_boolean (value, priv->wireless_hw_enabled);
|
||||||
break;
|
break;
|
||||||
|
case PROP_WWAN_ENABLED:
|
||||||
|
g_value_set_boolean (value, priv->wwan_enabled);
|
||||||
|
break;
|
||||||
|
case PROP_WWAN_HARDWARE_ENABLED:
|
||||||
|
g_value_set_boolean (value, priv->wwan_hw_enabled);
|
||||||
|
break;
|
||||||
case PROP_ACTIVE_CONNECTIONS:
|
case PROP_ACTIVE_CONNECTIONS:
|
||||||
g_value_set_boxed (value, nm_client_get_active_connections (self));
|
g_value_set_boxed (value, nm_client_get_active_connections (self));
|
||||||
break;
|
break;
|
||||||
@@ -457,6 +515,32 @@ nm_client_class_init (NMClientClass *client_class)
|
|||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMClient::wwan-enabled:
|
||||||
|
*
|
||||||
|
* Whether WWAN functionality is enabled.
|
||||||
|
**/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_WWAN_ENABLED,
|
||||||
|
g_param_spec_boolean (NM_CLIENT_WWAN_ENABLED,
|
||||||
|
"WwanEnabled",
|
||||||
|
"Is WWAN enabled",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMClient::wwan-hardware-enabled:
|
||||||
|
*
|
||||||
|
* Whether the WWAN hardware is enabled.
|
||||||
|
**/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_WWAN_HARDWARE_ENABLED,
|
||||||
|
g_param_spec_boolean (NM_CLIENT_WWAN_HARDWARE_ENABLED,
|
||||||
|
"WwanHardwareEnabled",
|
||||||
|
"Is WWAN hardware enabled",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMClient::active-connections:
|
* NMClient::active-connections:
|
||||||
*
|
*
|
||||||
@@ -566,9 +650,12 @@ proxy_name_owner_changed (DBusGProxy *proxy,
|
|||||||
free_object_array (&priv->active_connections);
|
free_object_array (&priv->active_connections);
|
||||||
priv->wireless_enabled = FALSE;
|
priv->wireless_enabled = FALSE;
|
||||||
priv->wireless_hw_enabled = FALSE;
|
priv->wireless_hw_enabled = FALSE;
|
||||||
|
priv->wwan_enabled = FALSE;
|
||||||
|
priv->wwan_hw_enabled = FALSE;
|
||||||
} else {
|
} else {
|
||||||
_nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_MANAGER_RUNNING);
|
_nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_MANAGER_RUNNING);
|
||||||
update_wireless_status (client, TRUE);
|
update_wireless_status (client, TRUE);
|
||||||
|
update_wwan_status (client, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,6 +960,61 @@ nm_client_wireless_hardware_get_enabled (NMClient *client)
|
|||||||
return NM_CLIENT_GET_PRIVATE (client)->wireless_hw_enabled;
|
return NM_CLIENT_GET_PRIVATE (client)->wireless_hw_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_client_wwan_get_enabled:
|
||||||
|
* @client: a #NMClient
|
||||||
|
*
|
||||||
|
* Determines whether WWAN is enabled.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if WWAN is enabled
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
nm_client_wwan_get_enabled (NMClient *client)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
|
||||||
|
|
||||||
|
return NM_CLIENT_GET_PRIVATE (client)->wwan_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_client_wwan_set_enabled:
|
||||||
|
* @client: a #NMClient
|
||||||
|
* @enabled: %TRUE to enable WWAN
|
||||||
|
*
|
||||||
|
* Enables or disables WWAN devices.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
nm_client_wwan_set_enabled (NMClient *client, gboolean enabled)
|
||||||
|
{
|
||||||
|
GValue value = {0,};
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_CLIENT (client));
|
||||||
|
|
||||||
|
g_value_init (&value, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean (&value, enabled);
|
||||||
|
|
||||||
|
_nm_object_set_property (NM_OBJECT (client),
|
||||||
|
NM_DBUS_INTERFACE,
|
||||||
|
"WwanEnabled",
|
||||||
|
&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_client_wwan_hardware_get_enabled:
|
||||||
|
* @client: a #NMClient
|
||||||
|
*
|
||||||
|
* Determines whether the WWAN hardware is enabled.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the WWAN hardware is enabled
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
nm_client_wwan_hardware_get_enabled (NMClient *client)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
|
||||||
|
|
||||||
|
return NM_CLIENT_GET_PRIVATE (client)->wwan_hw_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_client_get_state:
|
* nm_client_get_state:
|
||||||
* @client: a #NMClient
|
* @client: a #NMClient
|
||||||
|
@@ -45,6 +45,8 @@ G_BEGIN_DECLS
|
|||||||
#define NM_CLIENT_MANAGER_RUNNING "manager-running"
|
#define NM_CLIENT_MANAGER_RUNNING "manager-running"
|
||||||
#define NM_CLIENT_WIRELESS_ENABLED "wireless-enabled"
|
#define NM_CLIENT_WIRELESS_ENABLED "wireless-enabled"
|
||||||
#define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled"
|
#define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled"
|
||||||
|
#define NM_CLIENT_WWAN_ENABLED "wwan-enabled"
|
||||||
|
#define NM_CLIENT_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled"
|
||||||
#define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections"
|
#define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -89,6 +91,11 @@ void nm_client_deactivate_connection (NMClient *client, NMActiveConnection *acti
|
|||||||
gboolean nm_client_wireless_get_enabled (NMClient *client);
|
gboolean nm_client_wireless_get_enabled (NMClient *client);
|
||||||
void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled);
|
void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled);
|
||||||
gboolean nm_client_wireless_hardware_get_enabled (NMClient *client);
|
gboolean nm_client_wireless_hardware_get_enabled (NMClient *client);
|
||||||
|
|
||||||
|
gboolean nm_client_wwan_get_enabled (NMClient *client);
|
||||||
|
void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled);
|
||||||
|
gboolean nm_client_wwan_hardware_get_enabled (NMClient *client);
|
||||||
|
|
||||||
NMState nm_client_get_state (NMClient *client);
|
NMState nm_client_get_state (NMClient *client);
|
||||||
gboolean nm_client_get_manager_running (NMClient *client);
|
gboolean nm_client_get_manager_running (NMClient *client);
|
||||||
const GPtrArray *nm_client_get_active_connections (NMClient *client);
|
const GPtrArray *nm_client_get_active_connections (NMClient *client);
|
||||||
|
@@ -1042,15 +1042,12 @@ NMConnection *
|
|||||||
nm_connection_new_from_hash (GHashTable *hash, GError **error)
|
nm_connection_new_from_hash (GHashTable *hash, GError **error)
|
||||||
{
|
{
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
NMConnectionPrivate *priv;
|
|
||||||
|
|
||||||
g_return_val_if_fail (hash != NULL, NULL);
|
g_return_val_if_fail (hash != NULL, NULL);
|
||||||
|
|
||||||
connection = nm_connection_new ();
|
connection = nm_connection_new ();
|
||||||
g_hash_table_foreach (hash, parse_one_setting, connection);
|
g_hash_table_foreach (hash, parse_one_setting, connection);
|
||||||
|
|
||||||
priv = NM_CONNECTION_GET_PRIVATE (connection);
|
|
||||||
|
|
||||||
if (!nm_connection_verify (connection, error)) {
|
if (!nm_connection_verify (connection, error)) {
|
||||||
g_object_unref (connection);
|
g_object_unref (connection);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -1598,7 +1598,6 @@ nm_utils_rsa_key_encrypt (const GByteArray *data,
|
|||||||
gsize key_len = 0, enc_len = 0;
|
gsize key_len = 0, enc_len = 0;
|
||||||
GString *pem = NULL;
|
GString *pem = NULL;
|
||||||
char *tmp, *tmp_password = NULL;
|
char *tmp, *tmp_password = NULL;
|
||||||
gboolean success = FALSE;
|
|
||||||
int left;
|
int left;
|
||||||
const char *p;
|
const char *p;
|
||||||
GByteArray *ret = NULL;
|
GByteArray *ret = NULL;
|
||||||
@@ -1679,14 +1678,13 @@ nm_utils_rsa_key_encrypt (const GByteArray *data,
|
|||||||
g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len);
|
g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len);
|
||||||
if (tmp_password && out_password)
|
if (tmp_password && out_password)
|
||||||
*out_password = g_strdup (tmp_password);
|
*out_password = g_strdup (tmp_password);
|
||||||
success = TRUE;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (key) {
|
if (key) {
|
||||||
memset (key, 0, key_len);
|
memset (key, 0, key_len);
|
||||||
g_free (key);
|
g_free (key);
|
||||||
}
|
}
|
||||||
if (!enc) {
|
if (enc) {
|
||||||
memset (enc, 0, enc_len);
|
memset (enc, 0, enc_len);
|
||||||
g_free (enc);
|
g_free (enc);
|
||||||
}
|
}
|
||||||
|
@@ -329,14 +329,16 @@ static gboolean
|
|||||||
parse_state_file (const char *filename,
|
parse_state_file (const char *filename,
|
||||||
gboolean *net_enabled,
|
gboolean *net_enabled,
|
||||||
gboolean *wifi_enabled,
|
gboolean *wifi_enabled,
|
||||||
|
gboolean *wwan_enabled,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GKeyFile *state_file;
|
GKeyFile *state_file;
|
||||||
GError *tmp_error = NULL;
|
GError *tmp_error = NULL;
|
||||||
gboolean wifi, net;
|
gboolean wifi, net, wwan;
|
||||||
|
|
||||||
g_return_val_if_fail (net_enabled != NULL, FALSE);
|
g_return_val_if_fail (net_enabled != NULL, FALSE);
|
||||||
g_return_val_if_fail (wifi_enabled != NULL, FALSE);
|
g_return_val_if_fail (wifi_enabled != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (wwan_enabled != NULL, FALSE);
|
||||||
|
|
||||||
state_file = g_key_file_new ();
|
state_file = g_key_file_new ();
|
||||||
if (!state_file) {
|
if (!state_file) {
|
||||||
@@ -374,6 +376,7 @@ parse_state_file (const char *filename,
|
|||||||
/* Write out the initial state to the state file */
|
/* Write out the initial state to the state file */
|
||||||
g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled);
|
g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled);
|
||||||
g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled);
|
g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled);
|
||||||
|
g_key_file_set_boolean (state_file, "main", "WWANEnabled", *wwan_enabled);
|
||||||
|
|
||||||
data = g_key_file_to_data (state_file, &len, NULL);
|
data = g_key_file_to_data (state_file, &len, NULL);
|
||||||
if (data)
|
if (data)
|
||||||
@@ -400,7 +403,7 @@ parse_state_file (const char *filename,
|
|||||||
*net_enabled = net;
|
*net_enabled = net;
|
||||||
g_clear_error (&tmp_error);
|
g_clear_error (&tmp_error);
|
||||||
|
|
||||||
wifi = g_key_file_get_boolean (state_file, "main", "WirelessEnabled", error);
|
wifi = g_key_file_get_boolean (state_file, "main", "WirelessEnabled", &tmp_error);
|
||||||
if (tmp_error) {
|
if (tmp_error) {
|
||||||
g_clear_error (error);
|
g_clear_error (error);
|
||||||
g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
|
g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
|
||||||
@@ -408,6 +411,14 @@ parse_state_file (const char *filename,
|
|||||||
*wifi_enabled = wifi;
|
*wifi_enabled = wifi;
|
||||||
g_clear_error (&tmp_error);
|
g_clear_error (&tmp_error);
|
||||||
|
|
||||||
|
wwan = g_key_file_get_boolean (state_file, "main", "WWANEnabled", &tmp_error);
|
||||||
|
if (tmp_error) {
|
||||||
|
g_clear_error (error);
|
||||||
|
g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
|
||||||
|
} else
|
||||||
|
*wwan_enabled = wwan;
|
||||||
|
g_clear_error (&tmp_error);
|
||||||
|
|
||||||
g_key_file_free (state_file);
|
g_key_file_free (state_file);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -426,7 +437,7 @@ main (int argc, char *argv[])
|
|||||||
char *pidfile = NULL, *user_pidfile = NULL;
|
char *pidfile = NULL, *user_pidfile = NULL;
|
||||||
char *config = NULL, *plugins = NULL;
|
char *config = NULL, *plugins = NULL;
|
||||||
char *state_file = NM_DEFAULT_SYSTEM_STATE_FILE;
|
char *state_file = NM_DEFAULT_SYSTEM_STATE_FILE;
|
||||||
gboolean wifi_enabled = TRUE, net_enabled = TRUE;
|
gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
NMPolicy *policy = NULL;
|
NMPolicy *policy = NULL;
|
||||||
NMVPNManager *vpn_manager = NULL;
|
NMVPNManager *vpn_manager = NULL;
|
||||||
@@ -509,7 +520,7 @@ main (int argc, char *argv[])
|
|||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
|
||||||
/* Parse the state file */
|
/* Parse the state file */
|
||||||
if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &error)) {
|
if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &error)) {
|
||||||
g_warning ("State file %s parsing failed: (%d) %s.",
|
g_warning ("State file %s parsing failed: (%d) %s.",
|
||||||
state_file,
|
state_file,
|
||||||
error ? error->code : -1,
|
error ? error->code : -1,
|
||||||
@@ -583,7 +594,13 @@ main (int argc, char *argv[])
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
manager = nm_manager_get (config, plugins, state_file, net_enabled, wifi_enabled, &error);
|
manager = nm_manager_get (config,
|
||||||
|
plugins,
|
||||||
|
state_file,
|
||||||
|
net_enabled,
|
||||||
|
wifi_enabled,
|
||||||
|
wwan_enabled,
|
||||||
|
&error);
|
||||||
if (manager == NULL) {
|
if (manager == NULL) {
|
||||||
nm_error ("Failed to initialize the network manager: %s",
|
nm_error ("Failed to initialize the network manager: %s",
|
||||||
error && error->message ? error->message : "(unknown)");
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
@@ -178,7 +178,7 @@ nm_dhcp_device_watch_cleanup (NMDHCPDevice * device)
|
|||||||
static void
|
static void
|
||||||
nm_dhcp_device_destroy (NMDHCPDevice *device)
|
nm_dhcp_device_destroy (NMDHCPDevice *device)
|
||||||
{
|
{
|
||||||
int ret;
|
int ignored;
|
||||||
|
|
||||||
nm_dhcp_device_timeout_cleanup (device);
|
nm_dhcp_device_timeout_cleanup (device);
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ nm_dhcp_device_destroy (NMDHCPDevice *device)
|
|||||||
g_hash_table_destroy (device->options);
|
g_hash_table_destroy (device->options);
|
||||||
|
|
||||||
if (device->conf_file) {
|
if (device->conf_file) {
|
||||||
ret = unlink (device->conf_file);
|
ignored = unlink (device->conf_file);
|
||||||
g_free (device->conf_file);
|
g_free (device->conf_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -92,7 +92,9 @@ stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_d
|
|||||||
if (!error)
|
if (!error)
|
||||||
nm_device_activate_schedule_stage2_device_config (device);
|
nm_device_activate_schedule_stage2_device_config (device);
|
||||||
else {
|
else {
|
||||||
nm_warning ("CDMA modem connection failed: %s", error->message);
|
nm_warning ("CDMA modem connection failed: (%d) %s",
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
|
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
|
||||||
}
|
}
|
||||||
@@ -115,21 +117,55 @@ create_connect_properties (NMConnection *connection)
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NMActStageReturn
|
static void
|
||||||
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
do_connect (NMModem *modem)
|
||||||
{
|
{
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
GHashTable *properties;
|
GHashTable *properties;
|
||||||
|
|
||||||
connection = nm_act_request_get_connection (nm_device_get_act_request (device));
|
connection = nm_act_request_get_connection (nm_device_get_act_request (NM_DEVICE (modem)));
|
||||||
g_assert (connection);
|
g_assert (connection);
|
||||||
|
|
||||||
properties = create_connect_properties (connection);
|
properties = create_connect_properties (connection);
|
||||||
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_SIMPLE),
|
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM_SIMPLE),
|
||||||
"Connect", stage1_prepare_done,
|
"Connect", stage1_prepare_done,
|
||||||
device, NULL, 120000,
|
modem, NULL, 120000,
|
||||||
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
||||||
G_TYPE_INVALID);
|
G_TYPE_INVALID);
|
||||||
|
g_hash_table_destroy (properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||||
|
{
|
||||||
|
NMDevice *device = NM_DEVICE (user_data);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID))
|
||||||
|
do_connect (NM_MODEM (device));
|
||||||
|
else {
|
||||||
|
nm_warning ("CDMA modem enable failed: (%d) %s",
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
g_error_free (error);
|
||||||
|
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NMActStageReturn
|
||||||
|
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
|
{
|
||||||
|
gboolean enabled = nm_modem_get_mm_enabled (NM_MODEM (device));
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
do_connect (NM_MODEM (device));
|
||||||
|
else {
|
||||||
|
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM),
|
||||||
|
"Enable", stage1_enable_done,
|
||||||
|
device, NULL, 20000,
|
||||||
|
G_TYPE_BOOLEAN, TRUE,
|
||||||
|
G_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||||
}
|
}
|
||||||
|
@@ -173,8 +173,11 @@ stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_d
|
|||||||
clear_pin (device);
|
clear_pin (device);
|
||||||
required_secret = NM_SETTING_GSM_PIN;
|
required_secret = NM_SETTING_GSM_PIN;
|
||||||
retry_secret = TRUE;
|
retry_secret = TRUE;
|
||||||
} else
|
} else {
|
||||||
nm_warning ("GSM modem connection failed: %s", error->message);
|
nm_warning ("GSM modem connection failed: (%d) %s",
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
}
|
||||||
|
|
||||||
if (required_secret) {
|
if (required_secret) {
|
||||||
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
|
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
|
||||||
@@ -247,6 +250,41 @@ create_connect_properties (NMConnection *connection)
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_connect (NMModem *modem)
|
||||||
|
{
|
||||||
|
NMConnection *connection;
|
||||||
|
GHashTable *properties;
|
||||||
|
|
||||||
|
connection = nm_act_request_get_connection (nm_device_get_act_request (NM_DEVICE (modem)));
|
||||||
|
g_assert (connection);
|
||||||
|
|
||||||
|
properties = create_connect_properties (connection);
|
||||||
|
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM_SIMPLE),
|
||||||
|
"Connect", stage1_prepare_done,
|
||||||
|
modem, NULL, 120000,
|
||||||
|
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
||||||
|
G_TYPE_INVALID);
|
||||||
|
g_hash_table_destroy (properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||||
|
{
|
||||||
|
NMDevice *device = NM_DEVICE (user_data);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID))
|
||||||
|
do_connect (NM_MODEM (device));
|
||||||
|
else {
|
||||||
|
nm_warning ("GSM modem enable failed: (%d) %s",
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
g_error_free (error);
|
||||||
|
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static NMActStageReturn
|
static NMActStageReturn
|
||||||
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
@@ -264,14 +302,18 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
|||||||
|
|
||||||
setting_name = nm_connection_need_secrets (connection, &hints);
|
setting_name = nm_connection_need_secrets (connection, &hints);
|
||||||
if (!setting_name) {
|
if (!setting_name) {
|
||||||
GHashTable *properties;
|
NMModem *modem = NM_MODEM (device);
|
||||||
|
gboolean enabled = nm_modem_get_mm_enabled (modem);
|
||||||
|
|
||||||
properties = create_connect_properties (connection);
|
if (enabled)
|
||||||
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_SIMPLE),
|
do_connect (modem);
|
||||||
"Connect", stage1_prepare_done,
|
else {
|
||||||
device, NULL, 120000,
|
dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM),
|
||||||
DBUS_TYPE_G_MAP_OF_VARIANT, properties,
|
"Enable", stage1_enable_done,
|
||||||
|
modem, NULL, 20000,
|
||||||
|
G_TYPE_BOOLEAN, TRUE,
|
||||||
G_TYPE_INVALID);
|
G_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||||
}
|
}
|
||||||
|
@@ -15,8 +15,12 @@
|
|||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
#include "nm-serial-device-glue.h"
|
#include "nm-serial-device-glue.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
|
#include "nm-dbus-glib-types.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMModem, nm_modem, NM_TYPE_DEVICE)
|
static void device_interface_init (NMDeviceInterface *iface_class);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_EXTENDED (NMModem, nm_modem, NM_TYPE_DEVICE, 0,
|
||||||
|
G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init))
|
||||||
|
|
||||||
#define NM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM, NMModemPrivate))
|
#define NM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM, NMModemPrivate))
|
||||||
|
|
||||||
@@ -25,19 +29,24 @@ enum {
|
|||||||
PROP_DEVICE,
|
PROP_DEVICE,
|
||||||
PROP_PATH,
|
PROP_PATH,
|
||||||
PROP_IP_METHOD,
|
PROP_IP_METHOD,
|
||||||
|
PROP_ENABLED,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDBusManager *dbus_mgr;
|
NMDBusManager *dbus_mgr;
|
||||||
char *path;
|
|
||||||
DBusGProxy *proxy;
|
DBusGProxy *proxy;
|
||||||
|
DBusGProxy *props_proxy;
|
||||||
|
|
||||||
|
char *path;
|
||||||
NMPPPManager *ppp_manager;
|
NMPPPManager *ppp_manager;
|
||||||
NMIP4Config *pending_ip4_config;
|
NMIP4Config *pending_ip4_config;
|
||||||
guint32 ip_method;
|
guint32 ip_method;
|
||||||
char *device;
|
char *device;
|
||||||
|
|
||||||
|
gboolean mm_enabled;
|
||||||
|
|
||||||
/* PPP stats */
|
/* PPP stats */
|
||||||
guint32 in_bytes;
|
guint32 in_bytes;
|
||||||
guint32 out_bytes;
|
guint32 out_bytes;
|
||||||
@@ -60,6 +69,14 @@ nm_modem_get_ppp_manager (NMModem *self)
|
|||||||
return NM_MODEM_GET_PRIVATE (self)->ppp_manager;
|
return NM_MODEM_GET_PRIVATE (self)->ppp_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_modem_get_mm_enabled (NMModem *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_MODEM (self), TRUE);
|
||||||
|
|
||||||
|
return NM_MODEM_GET_PRIVATE (self)->mm_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
DBusGProxy *
|
DBusGProxy *
|
||||||
nm_modem_get_proxy (NMModem *self,
|
nm_modem_get_proxy (NMModem *self,
|
||||||
const char *interface)
|
const char *interface)
|
||||||
@@ -74,6 +91,9 @@ nm_modem_get_proxy (NMModem *self,
|
|||||||
if (interface == NULL)
|
if (interface == NULL)
|
||||||
interface = MM_DBUS_INTERFACE_MODEM;
|
interface = MM_DBUS_INTERFACE_MODEM;
|
||||||
|
|
||||||
|
if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES))
|
||||||
|
return priv->props_proxy;
|
||||||
|
|
||||||
current_iface = dbus_g_proxy_get_interface (priv->proxy);
|
current_iface = dbus_g_proxy_get_interface (priv->proxy);
|
||||||
if (!current_iface || strcmp (current_iface, interface))
|
if (!current_iface || strcmp (current_iface, interface))
|
||||||
dbus_g_proxy_set_interface (priv->proxy, interface);
|
dbus_g_proxy_set_interface (priv->proxy, interface);
|
||||||
@@ -425,6 +445,10 @@ device_state_changed (NMDeviceInterface *device,
|
|||||||
{
|
{
|
||||||
NMModem *self = NM_MODEM (user_data);
|
NMModem *self = NM_MODEM (user_data);
|
||||||
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
||||||
|
gboolean was_connected = FALSE;
|
||||||
|
|
||||||
|
if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED))
|
||||||
|
was_connected = TRUE;
|
||||||
|
|
||||||
/* Make sure we don't leave the serial device open */
|
/* Make sure we don't leave the serial device open */
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
@@ -436,10 +460,11 @@ device_state_changed (NMDeviceInterface *device,
|
|||||||
case NM_DEVICE_STATE_UNAVAILABLE:
|
case NM_DEVICE_STATE_UNAVAILABLE:
|
||||||
case NM_DEVICE_STATE_FAILED:
|
case NM_DEVICE_STATE_FAILED:
|
||||||
case NM_DEVICE_STATE_DISCONNECTED:
|
case NM_DEVICE_STATE_DISCONNECTED:
|
||||||
dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, NULL),
|
if (was_connected) {
|
||||||
"Enable",
|
dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
|
||||||
G_TYPE_BOOLEAN, FALSE,
|
"Disconnect",
|
||||||
G_TYPE_INVALID);
|
G_TYPE_INVALID);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -480,8 +505,121 @@ real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||||
|
{
|
||||||
|
NMModem *self = NM_MODEM (user_data);
|
||||||
|
GError *error = NULL;
|
||||||
|
GValue value = { 0, };
|
||||||
|
|
||||||
|
if (!dbus_g_proxy_end_call (proxy, call_id, &error,
|
||||||
|
G_TYPE_VALUE, &value,
|
||||||
|
G_TYPE_INVALID)) {
|
||||||
|
g_warning ("%s: failed get modem enabled state: (%d) %s",
|
||||||
|
__func__,
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_VALUE_HOLDS_BOOLEAN (&value)) {
|
||||||
|
NM_MODEM_GET_PRIVATE (self)->mm_enabled = g_value_get_boolean (&value);
|
||||||
|
g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED);
|
||||||
|
} else
|
||||||
|
g_warning ("%s: failed get modem enabled state: unexpected reply type", __func__);
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
query_mm_enabled (NMModem *self)
|
||||||
|
{
|
||||||
|
dbus_g_proxy_begin_call (NM_MODEM_GET_PRIVATE (self)->props_proxy,
|
||||||
|
"Get", get_mm_enabled_done,
|
||||||
|
self, NULL,
|
||||||
|
G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
|
||||||
|
G_TYPE_STRING, "Enabled",
|
||||||
|
G_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
|
||||||
|
g_warning ("%s: failed to enable/disable modem: (%d) %s",
|
||||||
|
__func__,
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update enabled/disabled state again */
|
||||||
|
query_mm_enabled (NM_MODEM (user_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
real_set_enabled (NMDeviceInterface *device, gboolean enabled)
|
||||||
|
{
|
||||||
|
NMModem *self = NM_MODEM (device);
|
||||||
|
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
/* FIXME: For now this just toggles the ModemManager enabled state. In the
|
||||||
|
* future we want to tie this into rfkill state instead so that the user can
|
||||||
|
* toggle rfkill status of the WWAN modem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (priv->mm_enabled != enabled) {
|
||||||
|
DBusGProxy *proxy;
|
||||||
|
|
||||||
|
proxy = nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM);
|
||||||
|
dbus_g_proxy_begin_call (proxy,
|
||||||
|
"Enable", set_mm_enabled_done,
|
||||||
|
device, NULL,
|
||||||
|
G_TYPE_BOOLEAN, enabled,
|
||||||
|
G_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_properties_changed (DBusGProxy *proxy,
|
||||||
|
const char *interface,
|
||||||
|
GHashTable *props,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NMModem *self = NM_MODEM (user_data);
|
||||||
|
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
||||||
|
GValue *value;
|
||||||
|
|
||||||
|
if (strcmp (interface, MM_DBUS_INTERFACE_MODEM))
|
||||||
|
return;
|
||||||
|
|
||||||
|
value = g_hash_table_lookup (props, "Enabled");
|
||||||
|
if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
|
||||||
|
NMDeviceState state;
|
||||||
|
|
||||||
|
priv->mm_enabled = g_value_get_boolean (value);
|
||||||
|
g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED);
|
||||||
|
|
||||||
|
if (priv->mm_enabled == FALSE) {
|
||||||
|
state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
|
||||||
|
if (IS_ACTIVATING_STATE (state) || (state == NM_DEVICE_STATE_ACTIVATED)) {
|
||||||
|
nm_device_state_changed (NM_DEVICE (self),
|
||||||
|
NM_DEVICE_STATE_DISCONNECTED,
|
||||||
|
NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_interface_init (NMDeviceInterface *iface_class)
|
||||||
|
{
|
||||||
|
iface_class->set_enabled = real_set_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_modem_init (NMModem *self)
|
nm_modem_init (NMModem *self)
|
||||||
{
|
{
|
||||||
@@ -497,6 +635,7 @@ constructor (GType type,
|
|||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
NMModemPrivate *priv;
|
NMModemPrivate *priv;
|
||||||
|
DBusGConnection *bus;
|
||||||
|
|
||||||
object = G_OBJECT_CLASS (nm_modem_parent_class)->constructor (type,
|
object = G_OBJECT_CLASS (nm_modem_parent_class)->constructor (type,
|
||||||
n_construct_params,
|
n_construct_params,
|
||||||
@@ -516,11 +655,32 @@ constructor (GType type,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
|
bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||||
MM_DBUS_SERVICE, priv->path, MM_DBUS_INTERFACE_MODEM);
|
priv->proxy = dbus_g_proxy_new_for_name (bus,
|
||||||
|
MM_DBUS_SERVICE,
|
||||||
|
priv->path,
|
||||||
|
MM_DBUS_INTERFACE_MODEM);
|
||||||
|
|
||||||
|
priv->props_proxy = dbus_g_proxy_new_for_name (bus,
|
||||||
|
MM_DBUS_SERVICE,
|
||||||
|
priv->path,
|
||||||
|
DBUS_INTERFACE_PROPERTIES);
|
||||||
|
dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
|
||||||
|
G_TYPE_INVALID);
|
||||||
|
dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged",
|
||||||
|
G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
|
||||||
|
G_TYPE_INVALID);
|
||||||
|
dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged",
|
||||||
|
G_CALLBACK (modem_properties_changed),
|
||||||
|
object,
|
||||||
|
NULL);
|
||||||
|
|
||||||
g_signal_connect (object, "state-changed", G_CALLBACK (device_state_changed), object);
|
g_signal_connect (object, "state-changed", G_CALLBACK (device_state_changed), object);
|
||||||
|
|
||||||
|
query_mm_enabled (NM_MODEM (object));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@@ -544,6 +704,9 @@ get_property (GObject *object, guint prop_id,
|
|||||||
case PROP_IP_METHOD:
|
case PROP_IP_METHOD:
|
||||||
g_value_set_uint (value, priv->ip_method);
|
g_value_set_uint (value, priv->ip_method);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENABLED:
|
||||||
|
g_value_set_boolean (value, priv->mm_enabled);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -569,6 +732,8 @@ set_property (GObject *object, guint prop_id,
|
|||||||
case PROP_IP_METHOD:
|
case PROP_IP_METHOD:
|
||||||
priv->ip_method = g_value_get_uint (value);
|
priv->ip_method = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENABLED:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -583,6 +748,9 @@ finalize (GObject *object)
|
|||||||
if (priv->proxy)
|
if (priv->proxy)
|
||||||
g_object_unref (priv->proxy);
|
g_object_unref (priv->proxy);
|
||||||
|
|
||||||
|
if (priv->props_proxy)
|
||||||
|
g_object_unref (priv->props_proxy);
|
||||||
|
|
||||||
g_object_unref (priv->dbus_mgr);
|
g_object_unref (priv->dbus_mgr);
|
||||||
|
|
||||||
g_free (priv->path);
|
g_free (priv->path);
|
||||||
@@ -639,6 +807,14 @@ nm_modem_class_init (NMModemClass *klass)
|
|||||||
MM_MODEM_IP_METHOD_PPP,
|
MM_MODEM_IP_METHOD_PPP,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_ENABLED,
|
||||||
|
g_param_spec_boolean (NM_MODEM_ENABLED,
|
||||||
|
"Enabled",
|
||||||
|
"Enabled",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
signals[PPP_STATS] =
|
signals[PPP_STATS] =
|
||||||
g_signal_new ("ppp-stats",
|
g_signal_new ("ppp-stats",
|
||||||
|
@@ -19,6 +19,7 @@ G_BEGIN_DECLS
|
|||||||
#define NM_MODEM_PATH "path"
|
#define NM_MODEM_PATH "path"
|
||||||
#define NM_MODEM_DEVICE "device"
|
#define NM_MODEM_DEVICE "device"
|
||||||
#define NM_MODEM_IP_METHOD "ip-method"
|
#define NM_MODEM_IP_METHOD "ip-method"
|
||||||
|
#define NM_MODEM_ENABLED "enabled"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDevice parent;
|
NMDevice parent;
|
||||||
@@ -46,6 +47,8 @@ DBusGProxy *nm_modem_get_proxy (NMModem *self,
|
|||||||
const char *nm_modem_get_ppp_name (NMModem *self,
|
const char *nm_modem_get_ppp_name (NMModem *self,
|
||||||
NMConnection *connection);
|
NMConnection *connection);
|
||||||
|
|
||||||
|
gboolean nm_modem_get_mm_enabled (NMModem *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* NM_MODEM_H */
|
#endif /* NM_MODEM_H */
|
||||||
|
@@ -1913,13 +1913,10 @@ mdio_read (NMDeviceEthernet *self, int fd, struct ifreq *ifr, int location)
|
|||||||
{
|
{
|
||||||
struct mii_ioctl_data *mii;
|
struct mii_ioctl_data *mii;
|
||||||
int val = -1;
|
int val = -1;
|
||||||
const char * iface;
|
|
||||||
|
|
||||||
g_return_val_if_fail (fd >= 0, -1);
|
g_return_val_if_fail (fd >= 0, -1);
|
||||||
g_return_val_if_fail (ifr != NULL, -1);
|
g_return_val_if_fail (ifr != NULL, -1);
|
||||||
|
|
||||||
iface = nm_device_get_iface (NM_DEVICE (self));
|
|
||||||
|
|
||||||
mii = (struct mii_ioctl_data *) &ifr->ifr_ifru;
|
mii = (struct mii_ioctl_data *) &ifr->ifr_ifru;
|
||||||
mii->reg_num = location;
|
mii->reg_num = location;
|
||||||
|
|
||||||
|
@@ -355,3 +355,12 @@ nm_device_interface_can_assume_connection (NMDeviceInterface *device)
|
|||||||
return !!NM_DEVICE_INTERFACE_GET_INTERFACE (device)->connection_match_config;
|
return !!NM_DEVICE_INTERFACE_GET_INTERFACE (device)->connection_match_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_device_interface_set_enabled (NMDeviceInterface *device, gboolean enabled)
|
||||||
|
{
|
||||||
|
g_return_if_fail (NM_IS_DEVICE_INTERFACE (device));
|
||||||
|
|
||||||
|
if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->set_enabled)
|
||||||
|
return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->set_enabled (device, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -97,6 +97,8 @@ struct _NMDeviceInterface {
|
|||||||
|
|
||||||
NMConnection * (*connection_match_config) (NMDeviceInterface *device, const GSList *specs);
|
NMConnection * (*connection_match_config) (NMDeviceInterface *device, const GSList *specs);
|
||||||
|
|
||||||
|
void (*set_enabled) (NMDeviceInterface *device, gboolean enabled);
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
void (*state_changed) (NMDeviceInterface *device,
|
void (*state_changed) (NMDeviceInterface *device,
|
||||||
NMDeviceState new_state,
|
NMDeviceState new_state,
|
||||||
@@ -131,4 +133,6 @@ NMConnection * nm_device_interface_connection_match_config (NMDeviceInterface *d
|
|||||||
|
|
||||||
gboolean nm_device_interface_can_assume_connection (NMDeviceInterface *device);
|
gboolean nm_device_interface_can_assume_connection (NMDeviceInterface *device);
|
||||||
|
|
||||||
|
void nm_device_interface_set_enabled (NMDeviceInterface *device, gboolean enabled);
|
||||||
|
|
||||||
#endif /* NM_DEVICE_INTERFACE_H */
|
#endif /* NM_DEVICE_INTERFACE_H */
|
||||||
|
@@ -909,7 +909,7 @@ check_companion_cb (gpointer user_data)
|
|||||||
if (priv->device_added_cb != 0)
|
if (priv->device_added_cb != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, NULL);
|
manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
priv->device_added_cb = g_signal_connect (manager, "device-added",
|
priv->device_added_cb = g_signal_connect (manager, "device-added",
|
||||||
G_CALLBACK (device_added_cb), self);
|
G_CALLBACK (device_added_cb), self);
|
||||||
|
@@ -69,8 +69,10 @@ static gboolean impl_device_get_access_points (NMDeviceWifi *device,
|
|||||||
|
|
||||||
#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries"
|
#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries"
|
||||||
|
|
||||||
|
static void device_interface_init (NMDeviceInterface *iface_class);
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
|
G_DEFINE_TYPE_EXTENDED (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE, 0,
|
||||||
|
G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init))
|
||||||
|
|
||||||
#define NM_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIFI, NMDeviceWifiPrivate))
|
#define NM_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIFI, NMDeviceWifiPrivate))
|
||||||
|
|
||||||
@@ -3231,7 +3233,6 @@ activation_success_handler (NMDevice *dev)
|
|||||||
|
|
||||||
priv->ap_list = g_slist_remove (priv->ap_list, ap);
|
priv->ap_list = g_slist_remove (priv->ap_list, ap);
|
||||||
g_object_unref (ap);
|
g_object_unref (ap);
|
||||||
ap = tmp_ap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@@ -3420,15 +3421,13 @@ nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled)
|
real_set_enabled (NMDeviceInterface *device, gboolean enabled)
|
||||||
{
|
{
|
||||||
NMDeviceWifiPrivate *priv;
|
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
|
||||||
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||||
NMDeviceState state;
|
NMDeviceState state;
|
||||||
|
|
||||||
g_return_if_fail (NM_IS_DEVICE_WIFI (self));
|
|
||||||
|
|
||||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
|
||||||
if (priv->enabled == enabled)
|
if (priv->enabled == enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3490,6 +3489,12 @@ nm_device_wifi_new (const char *udi,
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_interface_init (NMDeviceInterface *iface_class)
|
||||||
|
{
|
||||||
|
iface_class->set_enabled = real_set_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_device_wifi_init (NMDeviceWifi * self)
|
nm_device_wifi_init (NMDeviceWifi * self)
|
||||||
{
|
{
|
||||||
|
@@ -102,8 +102,6 @@ NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *self);
|
|||||||
|
|
||||||
NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
|
NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
|
||||||
|
|
||||||
void nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled);
|
|
||||||
|
|
||||||
guint32 nm_device_wifi_get_ifindex (NMDeviceWifi *self);
|
guint32 nm_device_wifi_get_ifindex (NMDeviceWifi *self);
|
||||||
|
|
||||||
RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self);
|
RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self);
|
||||||
|
318
src/nm-manager.c
318
src/nm-manager.c
@@ -58,6 +58,13 @@
|
|||||||
#define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
|
#define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
|
||||||
#define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd"
|
#define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd"
|
||||||
|
|
||||||
|
#define NM_MANAGER_STATE "state"
|
||||||
|
#define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled"
|
||||||
|
#define NM_MANAGER_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled"
|
||||||
|
#define NM_MANAGER_WWAN_ENABLED "wwan-enabled"
|
||||||
|
#define NM_MANAGER_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled"
|
||||||
|
#define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections"
|
||||||
|
|
||||||
static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err);
|
static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err);
|
||||||
static void impl_manager_activate_connection (NMManager *manager,
|
static void impl_manager_activate_connection (NMManager *manager,
|
||||||
const char *service_name,
|
const char *service_name,
|
||||||
@@ -143,6 +150,21 @@ typedef struct {
|
|||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
} PendingConnectionInfo;
|
} PendingConnectionInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gboolean enabled;
|
||||||
|
gboolean hw_enabled;
|
||||||
|
const char *desc;
|
||||||
|
const char *key;
|
||||||
|
const char *prop;
|
||||||
|
const char *hw_prop;
|
||||||
|
/* Hack for WWAN for 0.8 release; we'll start using udev
|
||||||
|
* after 0.8 gets out.
|
||||||
|
*/
|
||||||
|
gboolean ignore_udev;
|
||||||
|
RfKillState (*other_enabled_func) (NMManager *);
|
||||||
|
gboolean (*object_filter_func) (GObject *);
|
||||||
|
} RadioState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *config_file;
|
char *config_file;
|
||||||
char *state_file;
|
char *state_file;
|
||||||
@@ -164,8 +186,8 @@ typedef struct {
|
|||||||
GSList *secrets_calls;
|
GSList *secrets_calls;
|
||||||
|
|
||||||
PendingConnectionInfo *pending_connection_info;
|
PendingConnectionInfo *pending_connection_info;
|
||||||
gboolean wireless_enabled;
|
|
||||||
gboolean wireless_hw_enabled;
|
RadioState radio_states[RFKILL_TYPE_MAX];
|
||||||
gboolean sleeping;
|
gboolean sleeping;
|
||||||
|
|
||||||
NMVPNManager *vpn_manager;
|
NMVPNManager *vpn_manager;
|
||||||
@@ -207,6 +229,8 @@ enum {
|
|||||||
PROP_STATE,
|
PROP_STATE,
|
||||||
PROP_WIRELESS_ENABLED,
|
PROP_WIRELESS_ENABLED,
|
||||||
PROP_WIRELESS_HARDWARE_ENABLED,
|
PROP_WIRELESS_HARDWARE_ENABLED,
|
||||||
|
PROP_WWAN_ENABLED,
|
||||||
|
PROP_WWAN_HARDWARE_ENABLED,
|
||||||
PROP_ACTIVE_CONNECTIONS,
|
PROP_ACTIVE_CONNECTIONS,
|
||||||
|
|
||||||
/* Not exported */
|
/* Not exported */
|
||||||
@@ -434,7 +458,7 @@ aipd_handle_event (DBusGProxy *proxy,
|
|||||||
NMManager *manager = NM_MANAGER (user_data);
|
NMManager *manager = NM_MANAGER (user_data);
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
gboolean handled;
|
gboolean handled = FALSE;
|
||||||
|
|
||||||
if (!event || !iface) {
|
if (!event || !iface) {
|
||||||
nm_warning ("Incomplete message received from avahi-autoipd");
|
nm_warning ("Incomplete message received from avahi-autoipd");
|
||||||
@@ -1148,28 +1172,34 @@ write_value_to_state_file (const char *filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
manager_set_wireless_enabled (NMManager *manager, gboolean enabled)
|
manager_set_radio_enabled (NMManager *manager,
|
||||||
|
RadioState *rstate,
|
||||||
|
gboolean enabled)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (priv->wireless_enabled == enabled)
|
/* Do nothing for radio types not yet implemented */
|
||||||
|
if (!rstate->prop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (rstate->enabled == enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Can't set wireless enabled if it's disabled in hardware */
|
/* Can't set wireless enabled if it's disabled in hardware */
|
||||||
if (!priv->wireless_hw_enabled && enabled)
|
if (!rstate->hw_enabled && enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
priv->wireless_enabled = enabled;
|
rstate->enabled = enabled;
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (manager), NM_MANAGER_WIRELESS_ENABLED);
|
g_object_notify (G_OBJECT (manager), rstate->prop);
|
||||||
|
|
||||||
/* Update "WirelessEnabled" key in state file */
|
/* Update enabled key in state file */
|
||||||
if (priv->state_file) {
|
if (priv->state_file) {
|
||||||
if (!write_value_to_state_file (priv->state_file,
|
if (!write_value_to_state_file (priv->state_file,
|
||||||
"main", "WirelessEnabled",
|
"main", rstate->key,
|
||||||
G_TYPE_BOOLEAN, (gpointer) &priv->wireless_enabled,
|
G_TYPE_BOOLEAN, (gpointer) &enabled,
|
||||||
&error)) {
|
&error)) {
|
||||||
g_warning ("Writing to state file %s failed: (%d) %s.",
|
g_warning ("Writing to state file %s failed: (%d) %s.",
|
||||||
priv->state_file,
|
priv->state_file,
|
||||||
@@ -1184,10 +1214,8 @@ manager_set_wireless_enabled (NMManager *manager, gboolean enabled)
|
|||||||
|
|
||||||
/* enable/disable wireless devices as required */
|
/* enable/disable wireless devices as required */
|
||||||
for (iter = priv->devices; iter; iter = iter->next) {
|
for (iter = priv->devices; iter; iter = iter->next) {
|
||||||
if (NM_IS_DEVICE_WIFI (iter->data))
|
if (rstate->object_filter_func (G_OBJECT (iter->data)))
|
||||||
nm_device_wifi_set_enabled (NM_DEVICE_WIFI (iter->data), enabled);
|
nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (iter->data), enabled);
|
||||||
else if (NM_IS_WIMAX_DEVICE (iter->data))
|
|
||||||
nm_wimax_device_set_enabled (NM_WIMAX_DEVICE (iter->data), enabled);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1276,48 +1304,108 @@ nm_manager_get_ipw_rfkill_state (NMManager *self)
|
|||||||
return ipw_state;
|
return ipw_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static RfKillState
|
||||||
nm_manager_rfkill_update (NMManager *self)
|
nm_manager_get_modem_enabled_state (NMManager *self)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
RfKillState udev_state, ipw_state, composite;
|
GSList *iter;
|
||||||
gboolean new_we = TRUE, new_whe = TRUE;
|
RfKillState wwan_state = RFKILL_UNBLOCKED;
|
||||||
|
|
||||||
udev_state = nm_udev_manager_get_rfkill_state (priv->udev_mgr);
|
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
||||||
ipw_state = nm_manager_get_ipw_rfkill_state (self);
|
NMDevice *candidate = NM_DEVICE (iter->data);
|
||||||
|
RfKillState candidate_state = RFKILL_UNBLOCKED;
|
||||||
|
|
||||||
/* The composite state is the "worst" of either udev or ipw states */
|
if (NM_IS_MODEM (candidate)) {
|
||||||
if (udev_state == RFKILL_HARD_BLOCKED || ipw_state == RFKILL_HARD_BLOCKED)
|
if (nm_modem_get_mm_enabled (NM_MODEM (candidate)) == FALSE)
|
||||||
|
candidate_state = RFKILL_SOFT_BLOCKED;
|
||||||
|
|
||||||
|
if (candidate_state > wwan_state)
|
||||||
|
wwan_state = candidate_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wwan_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
rfkill_wlan_filter (GObject *object)
|
||||||
|
{
|
||||||
|
return NM_IS_DEVICE_WIFI (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
rfkill_wwan_filter (GObject *object)
|
||||||
|
{
|
||||||
|
return NM_IS_MODEM (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
manager_rfkill_update_one_type (NMManager *self,
|
||||||
|
RadioState *rstate,
|
||||||
|
RfKillType rtype)
|
||||||
|
{
|
||||||
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
|
RfKillState udev_state = RFKILL_UNBLOCKED;
|
||||||
|
RfKillState other_state = RFKILL_UNBLOCKED;
|
||||||
|
RfKillState composite;
|
||||||
|
gboolean new_e = TRUE, new_he = TRUE;
|
||||||
|
|
||||||
|
if (!rstate->ignore_udev)
|
||||||
|
udev_state = nm_udev_manager_get_rfkill_state (priv->udev_mgr, rtype);
|
||||||
|
|
||||||
|
if (rstate->other_enabled_func)
|
||||||
|
other_state = rstate->other_enabled_func (self);
|
||||||
|
|
||||||
|
/* The composite state is the "worst" of either udev or other states */
|
||||||
|
if (udev_state == RFKILL_HARD_BLOCKED || other_state == RFKILL_HARD_BLOCKED)
|
||||||
composite = RFKILL_HARD_BLOCKED;
|
composite = RFKILL_HARD_BLOCKED;
|
||||||
else if (udev_state == RFKILL_SOFT_BLOCKED || ipw_state == RFKILL_SOFT_BLOCKED)
|
else if (udev_state == RFKILL_SOFT_BLOCKED || other_state == RFKILL_SOFT_BLOCKED)
|
||||||
composite = RFKILL_SOFT_BLOCKED;
|
composite = RFKILL_SOFT_BLOCKED;
|
||||||
else
|
else
|
||||||
composite = RFKILL_UNBLOCKED;
|
composite = RFKILL_UNBLOCKED;
|
||||||
|
|
||||||
switch (composite) {
|
switch (composite) {
|
||||||
case RFKILL_UNBLOCKED:
|
case RFKILL_UNBLOCKED:
|
||||||
new_we = TRUE;
|
new_e = TRUE;
|
||||||
new_whe = TRUE;
|
new_he = TRUE;
|
||||||
break;
|
break;
|
||||||
case RFKILL_SOFT_BLOCKED:
|
case RFKILL_SOFT_BLOCKED:
|
||||||
new_we = FALSE;
|
new_e = FALSE;
|
||||||
new_whe = TRUE;
|
new_he = TRUE;
|
||||||
break;
|
break;
|
||||||
case RFKILL_HARD_BLOCKED:
|
case RFKILL_HARD_BLOCKED:
|
||||||
new_we = FALSE;
|
new_e = FALSE;
|
||||||
new_whe = FALSE;
|
new_he = FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_info ("Wireless now %s by radio killswitch",
|
if (new_he != rstate->hw_enabled) {
|
||||||
(new_we && new_whe) ? "enabled" : "disabled");
|
nm_info ("%s now %s by radio killswitch",
|
||||||
if (new_whe != priv->wireless_hw_enabled) {
|
rstate->desc,
|
||||||
priv->wireless_hw_enabled = new_whe;
|
(new_e && new_he) ? "enabled" : "disabled");
|
||||||
g_object_notify (G_OBJECT (self), NM_MANAGER_WIRELESS_HARDWARE_ENABLED);
|
|
||||||
|
rstate->hw_enabled = new_he;
|
||||||
|
g_object_notify (G_OBJECT (self), rstate->hw_prop);
|
||||||
}
|
}
|
||||||
manager_set_wireless_enabled (self, new_we);
|
manager_set_radio_enabled (self, rstate, new_e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
|
||||||
|
{
|
||||||
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (rtype != RFKILL_TYPE_UNKNOWN) {
|
||||||
|
manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise sync all radio types */
|
||||||
|
for (i = 0; i < RFKILL_TYPE_MAX; i++)
|
||||||
|
manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1325,7 +1413,15 @@ manager_ipw_rfkill_state_changed (NMDeviceWifi *device,
|
|||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
nm_manager_rfkill_update (NM_MANAGER (user_data));
|
nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WLAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
manager_modem_enabled_changed (NMModem *device,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WWAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1373,10 +1469,22 @@ add_device (NMManager *self, NMDevice *device)
|
|||||||
/* Update global rfkill state with this device's rfkill state, and
|
/* Update global rfkill state with this device's rfkill state, and
|
||||||
* then set this device's rfkill state based on the global state.
|
* then set this device's rfkill state based on the global state.
|
||||||
*/
|
*/
|
||||||
nm_manager_rfkill_update (self);
|
nm_manager_rfkill_update (self, RFKILL_TYPE_WLAN);
|
||||||
nm_device_wifi_set_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled);
|
nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device),
|
||||||
} else if (NM_IS_WIMAX_DEVICE (device))
|
priv->radio_states[RFKILL_TYPE_WLAN].enabled);
|
||||||
nm_wimax_device_set_enabled (NM_WIMAX_DEVICE (device), priv->wireless_enabled);
|
} else if (NM_IS_MODEM (device)) {
|
||||||
|
g_signal_connect (device, "notify::" NM_MODEM_ENABLED,
|
||||||
|
G_CALLBACK (manager_modem_enabled_changed),
|
||||||
|
self);
|
||||||
|
|
||||||
|
nm_manager_rfkill_update (self, RFKILL_TYPE_WWAN);
|
||||||
|
/* Until we start respecting WWAN rfkill switches the modem itself
|
||||||
|
* is the source of the enabled/disabled state, so the manager shouldn't
|
||||||
|
* touch it here.
|
||||||
|
nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device),
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].enabled);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
type_desc = nm_device_get_type_desc (device);
|
type_desc = nm_device_get_type_desc (device);
|
||||||
g_assert (type_desc);
|
g_assert (type_desc);
|
||||||
@@ -1696,10 +1804,11 @@ udev_device_removed_cb (NMUdevManager *manager,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
udev_manager_rfkill_changed_cb (NMUdevManager *udev_mgr,
|
udev_manager_rfkill_changed_cb (NMUdevManager *udev_mgr,
|
||||||
|
RfKillType rtype,
|
||||||
RfKillState udev_state,
|
RfKillState udev_state,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
nm_manager_rfkill_update (NM_MANAGER (user_data));
|
nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *
|
GSList *
|
||||||
@@ -1823,7 +1932,6 @@ user_get_secrets_cb (DBusGProxy *proxy,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GetSecretsInfo *info = (GetSecretsInfo *) user_data;
|
GetSecretsInfo *info = (GetSecretsInfo *) user_data;
|
||||||
NMManagerPrivate *priv;
|
|
||||||
GHashTable *settings = NULL;
|
GHashTable *settings = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GObject *provider;
|
GObject *provider;
|
||||||
@@ -1832,8 +1940,6 @@ user_get_secrets_cb (DBusGProxy *proxy,
|
|||||||
g_return_if_fail (info->provider);
|
g_return_if_fail (info->provider);
|
||||||
g_return_if_fail (info->setting_name);
|
g_return_if_fail (info->setting_name);
|
||||||
|
|
||||||
priv = NM_MANAGER_GET_PRIVATE (info->manager);
|
|
||||||
|
|
||||||
provider = g_object_ref (info->provider);
|
provider = g_object_ref (info->provider);
|
||||||
|
|
||||||
if (dbus_g_proxy_end_call (proxy, call, &error,
|
if (dbus_g_proxy_end_call (proxy, call, &error,
|
||||||
@@ -2555,20 +2661,25 @@ impl_manager_sleep (NMManager *self, gboolean sleep, GError **error)
|
|||||||
/* Ensure rfkill state is up-to-date since we don't respond to state
|
/* Ensure rfkill state is up-to-date since we don't respond to state
|
||||||
* changes during sleep.
|
* changes during sleep.
|
||||||
*/
|
*/
|
||||||
nm_manager_rfkill_update (self);
|
nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
|
||||||
|
|
||||||
/* Re-manage managed devices */
|
/* Re-manage managed devices */
|
||||||
for (iter = priv->devices; iter; iter = iter->next) {
|
for (iter = priv->devices; iter; iter = iter->next) {
|
||||||
NMDevice *device = NM_DEVICE (iter->data);
|
NMDevice *device = NM_DEVICE (iter->data);
|
||||||
gboolean wifi_enabled = (priv->wireless_hw_enabled && priv->wireless_enabled);
|
guint i;
|
||||||
|
|
||||||
/* enable/disable wireless devices since that we don't respond
|
/* enable/disable wireless devices since that we don't respond
|
||||||
* to killswitch changes during sleep.
|
* to killswitch changes during sleep.
|
||||||
*/
|
*/
|
||||||
if (NM_IS_DEVICE_WIFI (iter->data))
|
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
|
||||||
nm_device_wifi_set_enabled (NM_DEVICE_WIFI (iter->data), wifi_enabled);
|
RadioState *rstate = &priv->radio_states[i];
|
||||||
else if (NM_IS_WIMAX_DEVICE (iter->data))
|
gboolean enabled = (rstate->hw_enabled && rstate->enabled);
|
||||||
nm_wimax_device_set_enabled (NM_WIMAX_DEVICE (iter->data), wifi_enabled);
|
|
||||||
|
if ( rstate->object_filter_func
|
||||||
|
&& rstate->object_filter_func (G_OBJECT (device))) {
|
||||||
|
nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nm_device_clear_autoconnect_inhibit (device);
|
nm_device_clear_autoconnect_inhibit (device);
|
||||||
if (nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs))
|
if (nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs))
|
||||||
@@ -2702,29 +2813,42 @@ void
|
|||||||
nm_manager_start (NMManager *self)
|
nm_manager_start (NMManager *self)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
gboolean we = FALSE;
|
guint i;
|
||||||
|
|
||||||
switch (nm_udev_manager_get_rfkill_state (priv->udev_mgr)) {
|
/* Set initial radio enabled/disabled state */
|
||||||
|
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
|
||||||
|
RadioState *rstate = &priv->radio_states[i];
|
||||||
|
gboolean enabled = TRUE, hw_enabled = TRUE;
|
||||||
|
|
||||||
|
if (!rstate->desc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!rstate->ignore_udev) {
|
||||||
|
switch (nm_udev_manager_get_rfkill_state (priv->udev_mgr, i)) {
|
||||||
case RFKILL_UNBLOCKED:
|
case RFKILL_UNBLOCKED:
|
||||||
we = TRUE;
|
enabled = TRUE;
|
||||||
priv->wireless_hw_enabled = TRUE;
|
hw_enabled = TRUE;
|
||||||
break;
|
break;
|
||||||
case RFKILL_SOFT_BLOCKED:
|
case RFKILL_SOFT_BLOCKED:
|
||||||
we = FALSE;
|
enabled = FALSE;
|
||||||
priv->wireless_hw_enabled = TRUE;
|
hw_enabled = TRUE;
|
||||||
break;
|
break;
|
||||||
case RFKILL_HARD_BLOCKED:
|
case RFKILL_HARD_BLOCKED:
|
||||||
we = FALSE;
|
enabled = FALSE;
|
||||||
priv->wireless_hw_enabled = FALSE;
|
hw_enabled = FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nm_info ("Wireless %s by radio killswitch; %s by state file",
|
rstate->hw_enabled = hw_enabled;
|
||||||
(priv->wireless_hw_enabled && we) ? "enabled" : "disabled",
|
nm_info ("%s %s by radio killswitch; %s by state file",
|
||||||
(priv->wireless_enabled) ? "enabled" : "disabled");
|
rstate->desc,
|
||||||
manager_set_wireless_enabled (self, priv->wireless_enabled && we);
|
(rstate->hw_enabled && enabled) ? "enabled" : "disabled",
|
||||||
|
(rstate->enabled) ? "enabled" : "disabled");
|
||||||
|
manager_set_radio_enabled (self, rstate, rstate->enabled && enabled);
|
||||||
|
}
|
||||||
|
|
||||||
system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self);
|
system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self);
|
||||||
system_hostname_changed_cb (priv->sys_settings, NULL, self);
|
system_hostname_changed_cb (priv->sys_settings, NULL, self);
|
||||||
@@ -2747,6 +2871,7 @@ nm_manager_get (const char *config_file,
|
|||||||
const char *state_file,
|
const char *state_file,
|
||||||
gboolean initial_net_enabled,
|
gboolean initial_net_enabled,
|
||||||
gboolean initial_wifi_enabled,
|
gboolean initial_wifi_enabled,
|
||||||
|
gboolean initial_wwan_enabled,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
static NMManager *singleton = NULL;
|
static NMManager *singleton = NULL;
|
||||||
@@ -2777,7 +2902,8 @@ nm_manager_get (const char *config_file,
|
|||||||
|
|
||||||
priv->sleeping = !initial_net_enabled;
|
priv->sleeping = !initial_net_enabled;
|
||||||
|
|
||||||
priv->wireless_enabled = initial_wifi_enabled;
|
priv->radio_states[RFKILL_TYPE_WLAN].enabled = initial_wifi_enabled;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].enabled = initial_wwan_enabled;
|
||||||
|
|
||||||
g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
|
g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
|
||||||
G_CALLBACK (system_unmanaged_devices_changed_cb), singleton);
|
G_CALLBACK (system_unmanaged_devices_changed_cb), singleton);
|
||||||
@@ -2894,9 +3020,19 @@ static void
|
|||||||
set_property (GObject *object, guint prop_id,
|
set_property (GObject *object, guint prop_id,
|
||||||
const GValue *value, GParamSpec *pspec)
|
const GValue *value, GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
|
NMManager *self = NM_MANAGER (object);
|
||||||
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_WIRELESS_ENABLED:
|
case PROP_WIRELESS_ENABLED:
|
||||||
manager_set_wireless_enabled (NM_MANAGER (object), g_value_get_boolean (value));
|
manager_set_radio_enabled (NM_MANAGER (object),
|
||||||
|
&priv->radio_states[RFKILL_TYPE_WLAN],
|
||||||
|
g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_WWAN_ENABLED:
|
||||||
|
manager_set_radio_enabled (NM_MANAGER (object),
|
||||||
|
&priv->radio_states[RFKILL_TYPE_WWAN],
|
||||||
|
g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@@ -2917,10 +3053,16 @@ get_property (GObject *object, guint prop_id,
|
|||||||
g_value_set_uint (value, priv->state);
|
g_value_set_uint (value, priv->state);
|
||||||
break;
|
break;
|
||||||
case PROP_WIRELESS_ENABLED:
|
case PROP_WIRELESS_ENABLED:
|
||||||
g_value_set_boolean (value, priv->wireless_enabled);
|
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].enabled);
|
||||||
break;
|
break;
|
||||||
case PROP_WIRELESS_HARDWARE_ENABLED:
|
case PROP_WIRELESS_HARDWARE_ENABLED:
|
||||||
g_value_set_boolean (value, priv->wireless_hw_enabled);
|
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
|
||||||
|
break;
|
||||||
|
case PROP_WWAN_ENABLED:
|
||||||
|
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].enabled);
|
||||||
|
break;
|
||||||
|
case PROP_WWAN_HARDWARE_ENABLED:
|
||||||
|
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
|
||||||
break;
|
break;
|
||||||
case PROP_ACTIVE_CONNECTIONS:
|
case PROP_ACTIVE_CONNECTIONS:
|
||||||
g_value_take_boxed (value, get_active_connections (self, NULL));
|
g_value_take_boxed (value, get_active_connections (self, NULL));
|
||||||
@@ -2942,10 +3084,30 @@ nm_manager_init (NMManager *manager)
|
|||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||||
DBusGConnection *g_connection;
|
DBusGConnection *g_connection;
|
||||||
guint id;
|
guint id, i;
|
||||||
|
|
||||||
|
/* Initialize rfkill structures and states */
|
||||||
|
memset (priv->radio_states, 0, sizeof (priv->radio_states));
|
||||||
|
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].enabled = TRUE;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled";
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].other_enabled_func = nm_manager_get_ipw_rfkill_state;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WLAN].object_filter_func = rfkill_wlan_filter;
|
||||||
|
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].enabled = TRUE;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled";
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].other_enabled_func = nm_manager_get_modem_enabled_state;
|
||||||
|
priv->radio_states[RFKILL_TYPE_WWAN].object_filter_func = rfkill_wwan_filter;
|
||||||
|
|
||||||
|
for (i = 0; i < RFKILL_TYPE_MAX; i++)
|
||||||
|
priv->radio_states[i].hw_enabled = TRUE;
|
||||||
|
|
||||||
priv->wireless_enabled = TRUE;
|
|
||||||
priv->wireless_hw_enabled = TRUE;
|
|
||||||
priv->sleeping = FALSE;
|
priv->sleeping = FALSE;
|
||||||
priv->state = NM_STATE_DISCONNECTED;
|
priv->state = NM_STATE_DISCONNECTED;
|
||||||
|
|
||||||
@@ -3037,6 +3199,22 @@ nm_manager_class_init (NMManagerClass *manager_class)
|
|||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_WWAN_ENABLED,
|
||||||
|
g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED,
|
||||||
|
"WwanEnabled",
|
||||||
|
"Is mobile broadband enabled",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_WWAN_HARDWARE_ENABLED,
|
||||||
|
g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED,
|
||||||
|
"WwanHardwareEnabled",
|
||||||
|
"Whether WWAN is disabled by a hardware switch or not",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_ACTIVE_CONNECTIONS,
|
(object_class, PROP_ACTIVE_CONNECTIONS,
|
||||||
g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS,
|
g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS,
|
||||||
|
@@ -35,11 +35,6 @@
|
|||||||
#define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_MANAGER))
|
#define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_MANAGER))
|
||||||
#define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass))
|
#define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass))
|
||||||
|
|
||||||
#define NM_MANAGER_STATE "state"
|
|
||||||
#define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled"
|
|
||||||
#define NM_MANAGER_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled"
|
|
||||||
#define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections"
|
|
||||||
|
|
||||||
/* Not exported */
|
/* Not exported */
|
||||||
#define NM_MANAGER_HOSTNAME "hostname"
|
#define NM_MANAGER_HOSTNAME "hostname"
|
||||||
#define NM_MANAGER_SLEEPING "sleeping"
|
#define NM_MANAGER_SLEEPING "sleeping"
|
||||||
@@ -79,6 +74,7 @@ NMManager *nm_manager_get (const char *config_file,
|
|||||||
const char *state_file,
|
const char *state_file,
|
||||||
gboolean initial_net_enabled,
|
gboolean initial_net_enabled,
|
||||||
gboolean initial_wifi_enabled,
|
gboolean initial_wifi_enabled,
|
||||||
|
gboolean initial_wwan_enabled,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void nm_manager_start (NMManager *manager);
|
void nm_manager_start (NMManager *manager);
|
||||||
|
@@ -28,5 +28,18 @@ typedef enum {
|
|||||||
RFKILL_HARD_BLOCKED = 2
|
RFKILL_HARD_BLOCKED = 2
|
||||||
} RfKillState;
|
} RfKillState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RFKILL_TYPE_WLAN = 0,
|
||||||
|
RFKILL_TYPE_WWAN = 1,
|
||||||
|
RFKILL_TYPE_WIMAX = 2,
|
||||||
|
|
||||||
|
/* UNKNOWN and MAX should always be 1 more than
|
||||||
|
* the last rfkill type since RFKILL_TYPE_MAX is
|
||||||
|
* used as an array size.
|
||||||
|
*/
|
||||||
|
RFKILL_TYPE_UNKNOWN = 3, /* KEEP LAST */
|
||||||
|
RFKILL_TYPE_MAX = RFKILL_TYPE_UNKNOWN
|
||||||
|
} RfKillType;
|
||||||
|
|
||||||
#endif /* NM_RFKILL_H */
|
#endif /* NM_RFKILL_H */
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ typedef struct {
|
|||||||
GUdevClient *client;
|
GUdevClient *client;
|
||||||
|
|
||||||
/* Authoritative rfkill state (RFKILL_* enum) */
|
/* Authoritative rfkill state (RFKILL_* enum) */
|
||||||
RfKillState rfkill_state;
|
RfKillState rfkill_states[RFKILL_TYPE_MAX];
|
||||||
GSList *killswitches;
|
GSList *killswitches;
|
||||||
|
|
||||||
gboolean disposed;
|
gboolean disposed;
|
||||||
@@ -70,19 +70,21 @@ typedef struct {
|
|||||||
guint64 seqnum;
|
guint64 seqnum;
|
||||||
char *path;
|
char *path;
|
||||||
char *driver;
|
char *driver;
|
||||||
|
RfKillType rtype;
|
||||||
gint state;
|
gint state;
|
||||||
} Killswitch;
|
} Killswitch;
|
||||||
|
|
||||||
RfKillState
|
RfKillState
|
||||||
nm_udev_manager_get_rfkill_state (NMUdevManager *self)
|
nm_udev_manager_get_rfkill_state (NMUdevManager *self, RfKillType rtype)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (self != NULL, RFKILL_UNBLOCKED);
|
g_return_val_if_fail (self != NULL, RFKILL_UNBLOCKED);
|
||||||
|
g_return_val_if_fail (rtype < RFKILL_TYPE_MAX, RFKILL_UNBLOCKED);
|
||||||
|
|
||||||
return NM_UDEV_MANAGER_GET_PRIVATE (self)->rfkill_state;
|
return NM_UDEV_MANAGER_GET_PRIVATE (self)->rfkill_states[rtype];
|
||||||
}
|
}
|
||||||
|
|
||||||
static Killswitch *
|
static Killswitch *
|
||||||
killswitch_new (GUdevDevice *device)
|
killswitch_new (GUdevDevice *device, RfKillType rtype)
|
||||||
{
|
{
|
||||||
Killswitch *ks;
|
Killswitch *ks;
|
||||||
GUdevDevice *parent = NULL;
|
GUdevDevice *parent = NULL;
|
||||||
@@ -92,6 +94,7 @@ killswitch_new (GUdevDevice *device)
|
|||||||
ks->name = g_strdup (g_udev_device_get_name (device));
|
ks->name = g_strdup (g_udev_device_get_name (device));
|
||||||
ks->seqnum = g_udev_device_get_seqnum (device);
|
ks->seqnum = g_udev_device_get_seqnum (device);
|
||||||
ks->path = g_strdup (g_udev_device_get_sysfs_path (device));
|
ks->path = g_strdup (g_udev_device_get_sysfs_path (device));
|
||||||
|
ks->rtype = rtype;
|
||||||
|
|
||||||
driver = g_udev_device_get_property (device, "DRIVER");
|
driver = g_udev_device_get_property (device, "DRIVER");
|
||||||
if (!driver) {
|
if (!driver) {
|
||||||
@@ -148,7 +151,12 @@ recheck_killswitches (NMUdevManager *self)
|
|||||||
{
|
{
|
||||||
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
|
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
RfKillState poll_state = RFKILL_UNBLOCKED;
|
RfKillState poll_states[RFKILL_TYPE_MAX];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Default state is unblocked */
|
||||||
|
for (i = 0; i < RFKILL_TYPE_MAX; i++)
|
||||||
|
poll_states[i] = RFKILL_UNBLOCKED;
|
||||||
|
|
||||||
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
|
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
|
||||||
Killswitch *ks = iter->data;
|
Killswitch *ks = iter->data;
|
||||||
@@ -160,15 +168,17 @@ recheck_killswitches (NMUdevManager *self)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev_state = sysfs_state_to_nm_state (g_udev_device_get_property_as_int (device, "RFKILL_STATE"));
|
dev_state = sysfs_state_to_nm_state (g_udev_device_get_property_as_int (device, "RFKILL_STATE"));
|
||||||
if (dev_state > poll_state)
|
if (dev_state > poll_states[ks->rtype])
|
||||||
poll_state = dev_state;
|
poll_states[ks->rtype] = dev_state;
|
||||||
|
|
||||||
g_object_unref (device);
|
g_object_unref (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll_state != priv->rfkill_state) {
|
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
|
||||||
priv->rfkill_state = poll_state;
|
if (poll_states[i] != priv->rfkill_states[i]) {
|
||||||
g_signal_emit (self, signals[RFKILL_CHANGED], 0, priv->rfkill_state);
|
priv->rfkill_states[i] = poll_states[i];
|
||||||
|
g_signal_emit (self, signals[RFKILL_CHANGED], 0, i, priv->rfkill_states[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,21 +199,39 @@ killswitch_find_by_name (NMUdevManager *self, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const RfKillType
|
||||||
|
rfkill_type_to_enum (const char *str)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (str != NULL, RFKILL_TYPE_UNKNOWN);
|
||||||
|
|
||||||
|
if (!strcmp (str, "wlan"))
|
||||||
|
return RFKILL_TYPE_WLAN;
|
||||||
|
else if (!strcmp (str, "wwan"))
|
||||||
|
return RFKILL_TYPE_WWAN;
|
||||||
|
else if (!strcmp (str, "wimax"))
|
||||||
|
return RFKILL_TYPE_WIMAX;
|
||||||
|
|
||||||
|
return RFKILL_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_one_killswitch (NMUdevManager *self, GUdevDevice *device)
|
add_one_killswitch (NMUdevManager *self, GUdevDevice *device)
|
||||||
{
|
{
|
||||||
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
|
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
|
||||||
const char *type;
|
const char *str_type;
|
||||||
|
RfKillType rtype;
|
||||||
Killswitch *ks;
|
Killswitch *ks;
|
||||||
|
|
||||||
type = g_udev_device_get_property (device, "RFKILL_TYPE");
|
str_type = g_udev_device_get_property (device, "RFKILL_TYPE");
|
||||||
if (!type || strcmp (type, "wlan"))
|
rtype = rfkill_type_to_enum (str_type);
|
||||||
|
if (rtype == RFKILL_TYPE_UNKNOWN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ks = killswitch_new (device);
|
ks = killswitch_new (device, rtype);
|
||||||
priv->killswitches = g_slist_prepend (priv->killswitches, ks);
|
priv->killswitches = g_slist_prepend (priv->killswitches, ks);
|
||||||
|
|
||||||
nm_info ("Found radio killswitch %s (at %s) (driver %s)",
|
nm_info ("Found %s radio killswitch %s (at %s) (driver %s)",
|
||||||
|
str_type,
|
||||||
ks->name,
|
ks->name,
|
||||||
ks->path,
|
ks->path,
|
||||||
ks->driver ? ks->driver : "<unknown>");
|
ks->driver ? ks->driver : "<unknown>");
|
||||||
@@ -431,8 +459,11 @@ nm_udev_manager_init (NMUdevManager *self)
|
|||||||
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
|
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
|
||||||
const char *subsys[3] = { "rfkill", "net", NULL };
|
const char *subsys[3] = { "rfkill", "net", NULL };
|
||||||
GList *switches, *iter;
|
GList *switches, *iter;
|
||||||
|
guint32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < RFKILL_TYPE_MAX; i++)
|
||||||
|
priv->rfkill_states[i] = RFKILL_UNBLOCKED;
|
||||||
|
|
||||||
priv->rfkill_state = RFKILL_UNBLOCKED;
|
|
||||||
priv->client = g_udev_client_new (subsys);
|
priv->client = g_udev_client_new (subsys);
|
||||||
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
|
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
|
||||||
|
|
||||||
@@ -501,8 +532,7 @@ nm_udev_manager_class_init (NMUdevManagerClass *klass)
|
|||||||
G_SIGNAL_RUN_FIRST,
|
G_SIGNAL_RUN_FIRST,
|
||||||
G_STRUCT_OFFSET (NMUdevManagerClass, rfkill_changed),
|
G_STRUCT_OFFSET (NMUdevManagerClass, rfkill_changed),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__UINT,
|
_nm_marshal_VOID__UINT_UINT,
|
||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
|
||||||
G_TYPE_UINT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ typedef struct {
|
|||||||
|
|
||||||
void (*device_removed) (NMUdevManager *manager, GUdevDevice *device);
|
void (*device_removed) (NMUdevManager *manager, GUdevDevice *device);
|
||||||
|
|
||||||
void (*rfkill_changed) (NMUdevManager *manager, RfKillState state);
|
void (*rfkill_changed) (NMUdevManager *manager, RfKillType rtype, RfKillState state);
|
||||||
} NMUdevManagerClass;
|
} NMUdevManagerClass;
|
||||||
|
|
||||||
GType nm_udev_manager_get_type (void);
|
GType nm_udev_manager_get_type (void);
|
||||||
@@ -66,7 +66,7 @@ NMUdevManager *nm_udev_manager_new (void);
|
|||||||
|
|
||||||
void nm_udev_manager_query_devices (NMUdevManager *manager);
|
void nm_udev_manager_query_devices (NMUdevManager *manager);
|
||||||
|
|
||||||
RfKillState nm_udev_manager_get_rfkill_state (NMUdevManager *manager);
|
RfKillState nm_udev_manager_get_rfkill_state (NMUdevManager *manager, RfKillType rtype);
|
||||||
|
|
||||||
#endif /* NM_UDEV_MANAGER_H */
|
#endif /* NM_UDEV_MANAGER_H */
|
||||||
|
|
||||||
|
@@ -584,7 +584,6 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
|
|||||||
NMSetting8021x *setting_8021x,
|
NMSetting8021x *setting_8021x,
|
||||||
const char *connection_uid)
|
const char *connection_uid)
|
||||||
{
|
{
|
||||||
NMSupplicantConfigPrivate *priv;
|
|
||||||
char *value;
|
char *value;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
const char *key_mgmt, *auth_alg;
|
const char *key_mgmt, *auth_alg;
|
||||||
@@ -594,8 +593,6 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
|
|||||||
g_return_val_if_fail (setting != NULL, FALSE);
|
g_return_val_if_fail (setting != NULL, FALSE);
|
||||||
g_return_val_if_fail (connection_uid != NULL, FALSE);
|
g_return_val_if_fail (connection_uid != NULL, FALSE);
|
||||||
|
|
||||||
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
|
|
||||||
|
|
||||||
key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting);
|
key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting);
|
||||||
if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, FALSE))
|
if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -708,7 +705,6 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
|
|||||||
const char *connection_uid,
|
const char *connection_uid,
|
||||||
gboolean wired)
|
gboolean wired)
|
||||||
{
|
{
|
||||||
NMSupplicantConfigPrivate *priv;
|
|
||||||
char *tmp;
|
char *tmp;
|
||||||
const char *peapver, *value, *path;
|
const char *peapver, *value, *path;
|
||||||
gboolean success, added;
|
gboolean success, added;
|
||||||
@@ -719,8 +715,6 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
|
|||||||
g_return_val_if_fail (setting != NULL, FALSE);
|
g_return_val_if_fail (setting != NULL, FALSE);
|
||||||
g_return_val_if_fail (connection_uid != NULL, FALSE);
|
g_return_val_if_fail (connection_uid != NULL, FALSE);
|
||||||
|
|
||||||
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
|
|
||||||
|
|
||||||
value = nm_setting_802_1x_get_password (setting);
|
value = nm_setting_802_1x_get_password (setting);
|
||||||
if (!add_string_val (self, value, "password", FALSE, TRUE))
|
if (!add_string_val (self, value, "password", FALSE, TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@@ -254,6 +254,7 @@ nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self)
|
|||||||
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
|
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
|
gboolean have_hostname_providers = FALSE;
|
||||||
|
|
||||||
/* Hostname returned is the hostname returned from the first plugin
|
/* Hostname returned is the hostname returned from the first plugin
|
||||||
* that provides one.
|
* that provides one.
|
||||||
@@ -263,6 +264,8 @@ nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self)
|
|||||||
|
|
||||||
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
|
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
|
||||||
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
|
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
|
||||||
|
have_hostname_providers = TRUE;
|
||||||
|
|
||||||
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
|
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
|
||||||
if (hostname && strlen (hostname))
|
if (hostname && strlen (hostname))
|
||||||
return hostname;
|
return hostname;
|
||||||
@@ -271,7 +274,7 @@ nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If no plugin provided a hostname, try the original hostname of the machine */
|
/* If no plugin provided a hostname, try the original hostname of the machine */
|
||||||
if (priv->orig_hostname)
|
if (!have_hostname_providers && priv->orig_hostname)
|
||||||
hostname = g_strdup (priv->orig_hostname);
|
hostname = g_strdup (priv->orig_hostname);
|
||||||
|
|
||||||
return hostname;
|
return hostname;
|
||||||
|
@@ -2170,7 +2170,6 @@ make_wireless_setting (shvarFile *ifcfg,
|
|||||||
if (value) {
|
if (value) {
|
||||||
gsize ssid_len = 0, value_len = strlen (value);
|
gsize ssid_len = 0, value_len = strlen (value);
|
||||||
char *p = value, *tmp;
|
char *p = value, *tmp;
|
||||||
gboolean quoted = FALSE;
|
|
||||||
char buf[33];
|
char buf[33];
|
||||||
|
|
||||||
ssid_len = value_len;
|
ssid_len = value_len;
|
||||||
@@ -2182,7 +2181,6 @@ make_wireless_setting (shvarFile *ifcfg,
|
|||||||
value[value_len - 1] = '\0';
|
value[value_len - 1] = '\0';
|
||||||
svUnescape (p);
|
svUnescape (p);
|
||||||
ssid_len = strlen (p);
|
ssid_len = strlen (p);
|
||||||
quoted = TRUE;
|
|
||||||
} else if ((value_len > 2) && (strncmp (value, "0x", 2) == 0)) {
|
} else if ((value_len > 2) && (strncmp (value, "0x", 2) == 0)) {
|
||||||
/* Hex representation */
|
/* Hex representation */
|
||||||
if (value_len % 2) {
|
if (value_len % 2) {
|
||||||
|
@@ -339,17 +339,13 @@ write_8021x_certs (NMSetting8021x *s_8021x,
|
|||||||
char *generated_pw = NULL;
|
char *generated_pw = NULL;
|
||||||
gboolean success = FALSE, is_pkcs12 = FALSE;
|
gboolean success = FALSE, is_pkcs12 = FALSE;
|
||||||
const ObjectType *otype = NULL;
|
const ObjectType *otype = NULL;
|
||||||
const char *prop;
|
|
||||||
const GByteArray *blob = NULL;
|
const GByteArray *blob = NULL;
|
||||||
|
|
||||||
/* CA certificate */
|
/* CA certificate */
|
||||||
if (phase2) {
|
if (phase2)
|
||||||
prop = NM_SETTING_802_1X_PHASE2_CA_CERT;
|
|
||||||
otype = &phase2_ca_type;
|
otype = &phase2_ca_type;
|
||||||
} else {
|
else
|
||||||
prop = NM_SETTING_802_1X_CA_CERT;
|
|
||||||
otype = &ca_type;
|
otype = &ca_type;
|
||||||
}
|
|
||||||
|
|
||||||
if (!write_object (s_8021x, ifcfg, NULL, otype, error))
|
if (!write_object (s_8021x, ifcfg, NULL, otype, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -407,13 +403,10 @@ write_8021x_certs (NMSetting8021x *s_8021x,
|
|||||||
phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT",
|
phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT",
|
||||||
NULL, FALSE);
|
NULL, FALSE);
|
||||||
} else {
|
} else {
|
||||||
if (phase2) {
|
if (phase2)
|
||||||
prop = NM_SETTING_802_1X_PHASE2_CLIENT_CERT;
|
|
||||||
otype = &phase2_client_type;
|
otype = &phase2_client_type;
|
||||||
} else {
|
else
|
||||||
prop = NM_SETTING_802_1X_CLIENT_CERT;
|
|
||||||
otype = &client_type;
|
otype = &client_type;
|
||||||
}
|
|
||||||
|
|
||||||
/* Save the client certificate */
|
/* Save the client certificate */
|
||||||
if (!write_object (s_8021x, ifcfg, NULL, otype, error))
|
if (!write_object (s_8021x, ifcfg, NULL, otype, error))
|
||||||
|
@@ -2,12 +2,6 @@
|
|||||||
pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la
|
pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la
|
||||||
|
|
||||||
libnm_settings_plugin_ifcfg_suse_la_SOURCES = \
|
libnm_settings_plugin_ifcfg_suse_la_SOURCES = \
|
||||||
nm-suse-connection.c \
|
|
||||||
nm-suse-connection.h \
|
|
||||||
shvar.c \
|
|
||||||
shvar.h \
|
|
||||||
parser.c \
|
|
||||||
parser.h \
|
|
||||||
plugin.c \
|
plugin.c \
|
||||||
plugin.h
|
plugin.h
|
||||||
|
|
||||||
@@ -15,8 +9,6 @@ libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \
|
|||||||
$(GLIB_CFLAGS) \
|
$(GLIB_CFLAGS) \
|
||||||
$(GMODULE_CFLAGS) \
|
$(GMODULE_CFLAGS) \
|
||||||
$(DBUS_CFLAGS) \
|
$(DBUS_CFLAGS) \
|
||||||
$(POLKIT_CFLAGS) \
|
|
||||||
$(GUDEV_CFLAGS) \
|
|
||||||
-DG_DISABLE_DEPRECATED \
|
-DG_DISABLE_DEPRECATED \
|
||||||
-I${top_srcdir}/src/system-settings \
|
-I${top_srcdir}/src/system-settings \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
@@ -30,7 +22,5 @@ libnm_settings_plugin_ifcfg_suse_la_LIBADD = \
|
|||||||
$(top_builddir)/libnm-glib/libnm-glib.la \
|
$(top_builddir)/libnm-glib/libnm-glib.la \
|
||||||
$(GLIB_LIBS) \
|
$(GLIB_LIBS) \
|
||||||
$(GMODULE_LIBS) \
|
$(GMODULE_LIBS) \
|
||||||
$(POLKIT_LIBS) \
|
|
||||||
$(GUDEV_LIBS) \
|
|
||||||
$(GIO_LIBS)
|
$(GIO_LIBS)
|
||||||
|
|
||||||
|
@@ -1,171 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
||||||
/* NetworkManager system settings service
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* (C) Copyright 2008 Novell, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <glib/gstdio.h>
|
|
||||||
#include <gio/gio.h>
|
|
||||||
#include <NetworkManager.h>
|
|
||||||
#include <nm-settings-connection-interface.h>
|
|
||||||
#include <nm-setting-connection.h>
|
|
||||||
#include "nm-suse-connection.h"
|
|
||||||
#include "parser.h"
|
|
||||||
#include "nm-system-config-error.h"
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMSuseConnection, nm_suse_connection, NM_TYPE_SYSCONFIG_CONNECTION)
|
|
||||||
|
|
||||||
#define NM_SUSE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionPrivate))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GFileMonitor *monitor;
|
|
||||||
guint monitor_id;
|
|
||||||
|
|
||||||
const char *iface;
|
|
||||||
NMDeviceType dev_type;
|
|
||||||
char *filename;
|
|
||||||
} NMSuseConnectionPrivate;
|
|
||||||
|
|
||||||
static void
|
|
||||||
file_changed (GFileMonitor *monitor,
|
|
||||||
GFile *file,
|
|
||||||
GFile *other_file,
|
|
||||||
GFileMonitorEvent event_type,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
NMSuseConnection *self = NM_SUSE_CONNECTION (user_data);
|
|
||||||
NMSuseConnectionPrivate *priv = NM_SUSE_CONNECTION_GET_PRIVATE (self);
|
|
||||||
NMConnection *new;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
switch (event_type) {
|
|
||||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
|
||||||
new = parse_ifcfg (priv->iface, priv->dev_type);
|
|
||||||
if (new) {
|
|
||||||
if (!nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (self),
|
|
||||||
NM_CONNECTION (new),
|
|
||||||
TRUE,
|
|
||||||
&error)) {
|
|
||||||
g_warning ("%s: '%s' / '%s' invalid: %d",
|
|
||||||
__func__,
|
|
||||||
error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)",
|
|
||||||
(error && error->message) ? error->message : "(none)",
|
|
||||||
error ? error->code : -1);
|
|
||||||
g_clear_error (&error);
|
|
||||||
}
|
|
||||||
g_object_unref (new);
|
|
||||||
} else
|
|
||||||
g_signal_emit_by_name (self, "removed");
|
|
||||||
break;
|
|
||||||
case G_FILE_MONITOR_EVENT_DELETED:
|
|
||||||
g_signal_emit_by_name (self, "removed");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NMSuseConnection *
|
|
||||||
nm_suse_connection_new (const char *iface, NMDeviceType dev_type)
|
|
||||||
{
|
|
||||||
NMConnection *tmp;
|
|
||||||
GFile *file;
|
|
||||||
GFileMonitor *monitor;
|
|
||||||
NMSuseConnection *exported;
|
|
||||||
NMSuseConnectionPrivate *priv;
|
|
||||||
NMSettingConnection *s_con;
|
|
||||||
|
|
||||||
g_return_val_if_fail (iface != NULL, NULL);
|
|
||||||
|
|
||||||
tmp = parse_ifcfg (iface, dev_type);
|
|
||||||
if (!tmp)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Ensure the read connection is read-only since we don't have write capability yet */
|
|
||||||
s_con = (NMSettingConnection *) nm_connection_get_setting (tmp, NM_TYPE_SETTING_CONNECTION);
|
|
||||||
g_assert (s_con);
|
|
||||||
if (!nm_setting_connection_get_read_only (s_con)) {
|
|
||||||
g_warning ("%s: expected read-only connection!", __func__);
|
|
||||||
g_object_unref (tmp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
exported = (NMSuseConnection *) g_object_new (NM_TYPE_SUSE_CONNECTION, NULL);
|
|
||||||
if (!exported) {
|
|
||||||
g_object_unref (tmp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update our settings with what was read from the file */
|
|
||||||
nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (exported), tmp, FALSE, NULL);
|
|
||||||
g_object_unref (tmp);
|
|
||||||
|
|
||||||
priv = NM_SUSE_CONNECTION_GET_PRIVATE (exported);
|
|
||||||
|
|
||||||
priv->iface = g_strdup (iface);
|
|
||||||
priv->dev_type = dev_type;
|
|
||||||
priv->filename = g_strdup_printf (SYSCONFDIR "/sysconfig/network/ifcfg-%s", iface);
|
|
||||||
|
|
||||||
file = g_file_new_for_path (priv->filename);
|
|
||||||
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
if (monitor) {
|
|
||||||
priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), exported);
|
|
||||||
priv->monitor = monitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return exported;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GObject */
|
|
||||||
|
|
||||||
static void
|
|
||||||
nm_suse_connection_init (NMSuseConnection *connection)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
finalize (GObject *object)
|
|
||||||
{
|
|
||||||
NMSuseConnectionPrivate *priv = NM_SUSE_CONNECTION_GET_PRIVATE (object);
|
|
||||||
|
|
||||||
if (priv->monitor) {
|
|
||||||
if (priv->monitor_id)
|
|
||||||
g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
|
|
||||||
|
|
||||||
g_file_monitor_cancel (priv->monitor);
|
|
||||||
g_object_unref (priv->monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
nm_connection_clear_secrets (NM_CONNECTION (object));
|
|
||||||
g_free (priv->filename);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (nm_suse_connection_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nm_suse_connection_class_init (NMSuseConnectionClass *suse_connection_class)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (suse_connection_class);
|
|
||||||
|
|
||||||
g_type_class_add_private (suse_connection_class, sizeof (NMSuseConnectionPrivate));
|
|
||||||
|
|
||||||
/* Virtual methods */
|
|
||||||
object_class->finalize = finalize;
|
|
||||||
}
|
|
@@ -1,51 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
||||||
/* NetworkManager system settings service
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* (C) Copyright 2008 Novell, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NM_SUSE_CONNECTION_H
|
|
||||||
#define NM_SUSE_CONNECTION_H
|
|
||||||
|
|
||||||
#include <NetworkManager.h>
|
|
||||||
#include <nm-sysconfig-connection.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define NM_TYPE_SUSE_CONNECTION (nm_suse_connection_get_type ())
|
|
||||||
#define NM_SUSE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUSE_CONNECTION, NMSuseConnection))
|
|
||||||
#define NM_SUSE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionClass))
|
|
||||||
#define NM_IS_SUSE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SUSE_CONNECTION))
|
|
||||||
#define NM_IS_SUSE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SUSE_CONNECTION))
|
|
||||||
#define NM_SUSE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionClass))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
NMSysconfigConnection parent;
|
|
||||||
} NMSuseConnection;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
NMSysconfigConnectionClass parent;
|
|
||||||
} NMSuseConnectionClass;
|
|
||||||
|
|
||||||
GType nm_suse_connection_get_type (void);
|
|
||||||
|
|
||||||
NMSuseConnection *nm_suse_connection_new (const char *iface,
|
|
||||||
NMDeviceType dev_type);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* NM_SUSE_CONNECTION_H */
|
|
@@ -1,703 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
|
|
||||||
|
|
||||||
/* NetworkManager system settings service
|
|
||||||
*
|
|
||||||
* Søren Sandmann <sandmann@daimi.au.dk>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* (C) Copyright 2007 Red Hat, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/inotify.h>
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include <nm-connection.h>
|
|
||||||
#include <NetworkManager.h>
|
|
||||||
#include <nm-setting-connection.h>
|
|
||||||
#include <nm-setting-ip4-config.h>
|
|
||||||
#include <nm-setting-wired.h>
|
|
||||||
#include <nm-setting-wireless.h>
|
|
||||||
#include <nm-setting-8021x.h>
|
|
||||||
#include <nm-utils.h>
|
|
||||||
|
|
||||||
#include "shvar.h"
|
|
||||||
#include "parser.h"
|
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#define WPA_PMK_LEN 32
|
|
||||||
|
|
||||||
/* Common */
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
get_int (const char *str, int *value)
|
|
||||||
{
|
|
||||||
char *e;
|
|
||||||
|
|
||||||
*value = strtol (str, &e, 0);
|
|
||||||
if (*e != '\0')
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NMSetting *
|
|
||||||
make_connection_setting (shvarFile *file,
|
|
||||||
const char *iface,
|
|
||||||
const char *type,
|
|
||||||
const char *suggested)
|
|
||||||
{
|
|
||||||
NMSettingConnection *s_con;
|
|
||||||
char *str = NULL;
|
|
||||||
|
|
||||||
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
|
|
||||||
if (suggested) {
|
|
||||||
/* For cosmetic reasons, if the suggested name is the same as
|
|
||||||
* the ifcfg files name, don't use it.
|
|
||||||
*/
|
|
||||||
if (strcmp (iface, suggested))
|
|
||||||
str = g_strdup_printf ("System %s (%s)", suggested, iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!str)
|
|
||||||
str = g_strdup_printf ("System %s", iface);
|
|
||||||
|
|
||||||
g_object_set (s_con,
|
|
||||||
NM_SETTING_CONNECTION_ID, str,
|
|
||||||
NM_SETTING_CONNECTION_TYPE, type,
|
|
||||||
NM_SETTING_CONNECTION_READ_ONLY, TRUE,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = nm_utils_uuid_generate_from_string (file->fileName);
|
|
||||||
g_object_set (s_con, NM_SETTING_CONNECTION_UUID, str, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = svGetValue (file, "STARTMODE");
|
|
||||||
if (str && !g_ascii_strcasecmp (str, "manual"))
|
|
||||||
g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL);
|
|
||||||
else
|
|
||||||
g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
return (NMSetting *) s_con;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NMSetting *
|
|
||||||
make_ip4_setting (shvarFile *ifcfg)
|
|
||||||
{
|
|
||||||
NMSettingIP4Config *s_ip4;
|
|
||||||
char *str;
|
|
||||||
NMIP4Address *addr;
|
|
||||||
|
|
||||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "BOOTPROTO");
|
|
||||||
if (str) {
|
|
||||||
if (!g_ascii_strcasecmp (str, "bootp") || !g_ascii_strcasecmp (str, "dhcp"))
|
|
||||||
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
|
|
||||||
else if (!g_ascii_strcasecmp (str, "static"))
|
|
||||||
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
|
|
||||||
else if (!g_ascii_strcasecmp (str, "autoip"))
|
|
||||||
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, NULL);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nm_setting_ip4_config_get_method (s_ip4))
|
|
||||||
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
|
|
||||||
|
|
||||||
addr = nm_ip4_address_new ();
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "IPADDR");
|
|
||||||
if (str) {
|
|
||||||
char **pieces;
|
|
||||||
struct in_addr ip4_addr;
|
|
||||||
|
|
||||||
pieces = g_strsplit (str, "/", 2);
|
|
||||||
|
|
||||||
if (inet_pton (AF_INET, pieces[0], &ip4_addr) > 0) {
|
|
||||||
nm_ip4_address_set_address (addr, ip4_addr.s_addr);
|
|
||||||
|
|
||||||
if (g_strv_length (pieces) == 2)
|
|
||||||
nm_ip4_address_set_prefix (addr, atoi (pieces[1]));
|
|
||||||
} else
|
|
||||||
g_warning ("Ignoring invalid IP4 address '%s'", str);
|
|
||||||
|
|
||||||
g_strfreev (pieces);
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nm_ip4_address_get_address (addr) && nm_ip4_address_get_prefix (addr) == 0) {
|
|
||||||
str = svGetValue (ifcfg, "PREFIXLEN");
|
|
||||||
if (str) {
|
|
||||||
nm_ip4_address_set_prefix (addr, atoi (str));
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nm_ip4_address_get_address (addr) && nm_ip4_address_get_prefix (addr) == 0) {
|
|
||||||
str = svGetValue (ifcfg, "NETMASK");
|
|
||||||
if (str) {
|
|
||||||
struct in_addr mask_addr;
|
|
||||||
|
|
||||||
if (inet_pton (AF_INET, str, &mask_addr) > 0)
|
|
||||||
nm_ip4_address_set_prefix (addr, nm_utils_ip4_netmask_to_prefix (mask_addr.s_addr));
|
|
||||||
else {
|
|
||||||
g_warning ("Ignoring invalid IP4 address: invalid netmask: '%s'", str);
|
|
||||||
nm_ip4_address_set_address (addr, 0);
|
|
||||||
nm_ip4_address_set_prefix (addr, 0);
|
|
||||||
}
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nm_ip4_address_get_prefix (addr) || nm_ip4_address_get_prefix (addr) > 32) {
|
|
||||||
g_warning ("Ignoring invalid IP4 address: invalid prefix: '%d'", nm_ip4_address_get_prefix (addr));
|
|
||||||
nm_ip4_address_set_address (addr, 0);
|
|
||||||
nm_ip4_address_set_prefix (addr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nm_ip4_address_get_address (addr)) {
|
|
||||||
if (!nm_setting_ip4_config_add_address (s_ip4, addr))
|
|
||||||
g_warning ("Ignoring duplicate IP4 address");
|
|
||||||
}
|
|
||||||
|
|
||||||
nm_ip4_address_unref (addr);
|
|
||||||
|
|
||||||
return NM_SETTING (s_ip4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ethernet */
|
|
||||||
|
|
||||||
static NMSetting *
|
|
||||||
make_wired_setting (shvarFile *ifcfg)
|
|
||||||
{
|
|
||||||
NMSettingWired *s_wired;
|
|
||||||
char *str;
|
|
||||||
int mtu;
|
|
||||||
|
|
||||||
s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "MTU");
|
|
||||||
if (str) {
|
|
||||||
if (strlen (str) < 1)
|
|
||||||
/* Ignore empty MTU */
|
|
||||||
;
|
|
||||||
else if (get_int (str, &mtu)) {
|
|
||||||
if (mtu >= 0 && mtu < G_MAXINT)
|
|
||||||
g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu, NULL);
|
|
||||||
} else
|
|
||||||
g_warning ("Ignoring invalid MTU: '%s'", str);
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (NMSetting *) s_wired;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
parse_ethernet (NMConnection *connection, shvarFile *file, const char *iface)
|
|
||||||
{
|
|
||||||
NMSetting *setting;
|
|
||||||
|
|
||||||
setting = make_connection_setting (file, iface, NM_SETTING_WIRED_SETTING_NAME, NULL);
|
|
||||||
nm_connection_add_setting (connection, setting);
|
|
||||||
|
|
||||||
setting = make_wired_setting (file);
|
|
||||||
nm_connection_add_setting (connection, setting);
|
|
||||||
|
|
||||||
setting = make_ip4_setting (file);
|
|
||||||
nm_connection_add_setting (connection, setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wireless */
|
|
||||||
|
|
||||||
static char *
|
|
||||||
get_one_wep_key (shvarFile *ifcfg, guint8 idx, GError **err)
|
|
||||||
{
|
|
||||||
char *shvar_key;
|
|
||||||
char *key = NULL;
|
|
||||||
char *value = NULL;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
g_return_val_if_fail (idx <= 3, NULL);
|
|
||||||
|
|
||||||
shvar_key = g_strdup_printf ("WIRELESS_KEY_%d", idx);
|
|
||||||
value = svGetValue (ifcfg, shvar_key);
|
|
||||||
g_free (shvar_key);
|
|
||||||
|
|
||||||
/* Ignore empty keys */
|
|
||||||
if (!value)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (strlen (value) < 1) {
|
|
||||||
g_free (value);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ASCII */
|
|
||||||
if (g_str_has_prefix (value, "s:")) {
|
|
||||||
p = value + 2;
|
|
||||||
if (strlen (p) != 5 || strlen (p) != 13)
|
|
||||||
g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid hexadecimal WEP key.");
|
|
||||||
else {
|
|
||||||
while (*p) {
|
|
||||||
if (!isascii (*p)) {
|
|
||||||
g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid hexadecimal WEP key.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!err)
|
|
||||||
key = g_strdup (p);
|
|
||||||
} else if (g_str_has_prefix (value, "h:")) {
|
|
||||||
/* Hashed passphrase */
|
|
||||||
p = value + 2;
|
|
||||||
if (p && (strlen (p) > 0 || strlen (p) < 65))
|
|
||||||
key = g_strdup (p);
|
|
||||||
else
|
|
||||||
g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid WEP passphrase.");
|
|
||||||
} else {
|
|
||||||
/* Hexadecimal */
|
|
||||||
GString *str;
|
|
||||||
|
|
||||||
str = g_string_sized_new (26);
|
|
||||||
p = value + 2;
|
|
||||||
while (*p) {
|
|
||||||
if (g_ascii_isxdigit (*p))
|
|
||||||
str = g_string_append_c (str, *p);
|
|
||||||
else if (*p != '-') {
|
|
||||||
g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid hexadecimal WEP key.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = str->str;
|
|
||||||
|
|
||||||
if (p && (strlen (p) == 10 || strlen (p) == 26))
|
|
||||||
key = g_string_free (str, FALSE);
|
|
||||||
else
|
|
||||||
g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid hexadecimal WEP key.");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (value);
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define READ_WEP_KEY(idx) \
|
|
||||||
{ \
|
|
||||||
char *key = get_one_wep_key (ifcfg, idx, &err); \
|
|
||||||
if (err) \
|
|
||||||
goto error; \
|
|
||||||
if (key) { \
|
|
||||||
g_object_set (G_OBJECT (security), \
|
|
||||||
NM_SETTING_WIRELESS_SECURITY_WEP_KEY##idx, \
|
|
||||||
key, \
|
|
||||||
NULL); \
|
|
||||||
g_free (key); \
|
|
||||||
have_key = TRUE; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
read_wep_settings (shvarFile *ifcfg, NMSettingWirelessSecurity *security)
|
|
||||||
{
|
|
||||||
char *value;
|
|
||||||
GError *err = NULL;
|
|
||||||
gboolean have_key = FALSE;
|
|
||||||
|
|
||||||
READ_WEP_KEY(0)
|
|
||||||
READ_WEP_KEY(1)
|
|
||||||
READ_WEP_KEY(2)
|
|
||||||
READ_WEP_KEY(3)
|
|
||||||
|
|
||||||
if (have_key)
|
|
||||||
g_object_set (security, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL);
|
|
||||||
|
|
||||||
value = svGetValue (ifcfg, "WIRELESS_DEFAULT_KEY");
|
|
||||||
if (value) {
|
|
||||||
gboolean success;
|
|
||||||
int key_idx = 0;
|
|
||||||
|
|
||||||
success = get_int (value, &key_idx);
|
|
||||||
if (success && (key_idx >= 0) && (key_idx <= 3))
|
|
||||||
g_object_set (security, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, key_idx, NULL);
|
|
||||||
else
|
|
||||||
g_warning ("Invalid default WEP key: '%s'", value);
|
|
||||||
|
|
||||||
g_free (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (err) {
|
|
||||||
g_warning ("%s", err->message);
|
|
||||||
g_error_free (err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
read_wpa_psk_settings (shvarFile *ifcfg,
|
|
||||||
NMSettingWirelessSecurity *security,
|
|
||||||
NMSettingWireless *s_wireless)
|
|
||||||
{
|
|
||||||
char *value;
|
|
||||||
|
|
||||||
value = svGetValue (ifcfg, "WIRELESS_WPA_PSK");
|
|
||||||
if (value) {
|
|
||||||
if (strlen (value) > 64 || strlen (value) < 8)
|
|
||||||
g_warning ("Error loading WIRELESS_WPA_PSK: not between 8 and 64 characters inclusive");
|
|
||||||
else
|
|
||||||
g_object_set (security, NM_SETTING_WIRELESS_SECURITY_PSK, value, NULL);
|
|
||||||
g_free (value);
|
|
||||||
} else
|
|
||||||
g_warning ("Missing WPA-PSK key");
|
|
||||||
}
|
|
||||||
|
|
||||||
static NMSetting *
|
|
||||||
read_wpa_eap_settings (shvarFile *ifcfg)
|
|
||||||
{
|
|
||||||
NMSetting8021x *s_802_1x;
|
|
||||||
char *str;
|
|
||||||
GError *err = NULL;
|
|
||||||
NMSetting8021xCKType cert_type;
|
|
||||||
|
|
||||||
s_802_1x = NM_SETTING_802_1X (nm_setting_802_1x_new ());
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_EAP_MODE");
|
|
||||||
if (str) {
|
|
||||||
char **pieces;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
pieces = g_strsplit (str, " ", 0);
|
|
||||||
for (i = 0; pieces[i]; i++)
|
|
||||||
nm_setting_802_1x_add_eap_method (s_802_1x, pieces[i]);
|
|
||||||
|
|
||||||
g_free (pieces);
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_WPA_ANONID");
|
|
||||||
g_object_set (s_802_1x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, str, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_PEAP_VERSION");
|
|
||||||
g_object_set (s_802_1x, NM_SETTING_802_1X_PHASE1_PEAPVER, str, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_EAP_AUTH");
|
|
||||||
g_object_set (s_802_1x, NM_SETTING_802_1X_PHASE2_AUTH, str, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_WPA_IDENTITY");
|
|
||||||
g_object_set (s_802_1x, NM_SETTING_802_1X_IDENTITY, str, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_WPA_PASSWORD");
|
|
||||||
g_object_set (s_802_1x, NM_SETTING_802_1X_PASSWORD, str, NULL);
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_CA_CERT");
|
|
||||||
if (str) {
|
|
||||||
nm_setting_802_1x_set_ca_cert_from_file (s_802_1x, str, &cert_type, &err);
|
|
||||||
if (err) {
|
|
||||||
g_warning ("Error loading WIRELESS_CA_CERT: %s", err->message);
|
|
||||||
g_error_free (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_CLIENT_CERT");
|
|
||||||
if (str) {
|
|
||||||
nm_setting_802_1x_set_client_cert_from_file (s_802_1x, str, &cert_type, &err);
|
|
||||||
if (err) {
|
|
||||||
g_warning ("Error loading WIRELESS_CLIENT_CERT: %s", err->message);
|
|
||||||
g_error_free (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_CLIENT_KEY");
|
|
||||||
if (str) {
|
|
||||||
char *password;
|
|
||||||
|
|
||||||
password = svGetValue (ifcfg, "WIRELESS_CLIENT_KEY_PASSWORD");
|
|
||||||
if (password) {
|
|
||||||
nm_setting_802_1x_set_private_key_from_file (s_802_1x, str, password, &cert_type, &err);
|
|
||||||
if (err) {
|
|
||||||
g_warning ("Error loading WIRELESS_CLIENT_KEY: %s", err->message);
|
|
||||||
g_error_free (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (password);
|
|
||||||
} else
|
|
||||||
g_warning ("Missing WIRELESS_CLIENT_KEY_PASSWORD");
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (NMSetting *) s_802_1x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NMSetting *
|
|
||||||
make_wireless_security_setting (shvarFile *ifcfg, NMSettingWireless *s_wireless)
|
|
||||||
{
|
|
||||||
NMSettingWirelessSecurity *security;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_AUTH_MODE");
|
|
||||||
if (!str || !g_ascii_strcasecmp (str, "no-encryption")) {
|
|
||||||
g_free (str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_ascii_strcasecmp (str, "eap"))
|
|
||||||
return read_wpa_eap_settings (ifcfg);
|
|
||||||
|
|
||||||
security = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
|
|
||||||
|
|
||||||
if (!g_ascii_strcasecmp (str, "open")) {
|
|
||||||
g_object_set (security, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL);
|
|
||||||
read_wep_settings (ifcfg, security);
|
|
||||||
} else if (!g_ascii_strcasecmp (str, "sharedkey")) {
|
|
||||||
g_object_set (security, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL);
|
|
||||||
read_wep_settings (ifcfg, security);
|
|
||||||
} else if (!g_ascii_strcasecmp (str, "psk")) {
|
|
||||||
g_object_set (security, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
|
|
||||||
read_wpa_psk_settings (ifcfg, security, s_wireless);
|
|
||||||
} else
|
|
||||||
g_warning ("Invalid authentication algorithm: '%s'", str);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
return (NMSetting *) security;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NMSetting *
|
|
||||||
make_wireless_setting (shvarFile *ifcfg)
|
|
||||||
{
|
|
||||||
NMSettingWireless *s_wireless;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRELESS_ESSID");
|
|
||||||
if (str) {
|
|
||||||
gsize len = strlen (str);
|
|
||||||
|
|
||||||
if (len > 0 && len <= 32) {
|
|
||||||
GByteArray *ssid;
|
|
||||||
|
|
||||||
ssid = g_byte_array_sized_new (len);
|
|
||||||
g_byte_array_append (ssid, (const guint8 *) str, len);
|
|
||||||
g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL);
|
|
||||||
g_byte_array_free (ssid, TRUE);
|
|
||||||
} else
|
|
||||||
g_warning ("Ignoring invalid ESSID '%s', (size %zu not between 1 and 32 inclusive)", str, len);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
str = svGetValue (ifcfg, "WIRLESS_MODE");
|
|
||||||
if (str) {
|
|
||||||
const char *mode;
|
|
||||||
|
|
||||||
if (!g_ascii_strcasecmp (str, "ad-hoc"))
|
|
||||||
mode = "adhoc";
|
|
||||||
else if (!g_ascii_strcasecmp (str, "managed"))
|
|
||||||
mode = "infrastructure";
|
|
||||||
else
|
|
||||||
mode = NULL;
|
|
||||||
|
|
||||||
if (mode)
|
|
||||||
g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, mode, NULL);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: channel/freq, other L2 parameters like RTS
|
|
||||||
|
|
||||||
return NM_SETTING (s_wireless);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
get_printable_ssid (NMSetting *setting)
|
|
||||||
{
|
|
||||||
const GByteArray *ssid;
|
|
||||||
char *printable_ssid = NULL;
|
|
||||||
|
|
||||||
ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting));
|
|
||||||
if (ssid)
|
|
||||||
printable_ssid = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len);
|
|
||||||
|
|
||||||
return printable_ssid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
parse_wireless (NMConnection *connection, shvarFile *file, const char *iface)
|
|
||||||
{
|
|
||||||
NMSetting *setting;
|
|
||||||
NMSetting *security;
|
|
||||||
char *printable_ssid;
|
|
||||||
|
|
||||||
setting = make_wireless_setting (file);
|
|
||||||
nm_connection_add_setting (connection, setting);
|
|
||||||
|
|
||||||
security = make_wireless_security_setting (file, NM_SETTING_WIRELESS (setting));
|
|
||||||
if (security) {
|
|
||||||
const char *security_str;
|
|
||||||
|
|
||||||
if (NM_IS_SETTING_802_1X (security))
|
|
||||||
security_str = NM_SETTING_802_1X_SETTING_NAME;
|
|
||||||
else if (NM_IS_SETTING_WIRELESS_SECURITY (security))
|
|
||||||
security_str = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
|
|
||||||
else {
|
|
||||||
security_str = NULL;
|
|
||||||
g_warning ("Invalid security type: '%s'", G_OBJECT_TYPE_NAME (security));
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_set (G_OBJECT (setting), NM_SETTING_WIRELESS_SEC, security_str, NULL);
|
|
||||||
nm_connection_add_setting (connection, security);
|
|
||||||
}
|
|
||||||
|
|
||||||
printable_ssid = get_printable_ssid (setting);
|
|
||||||
setting = make_connection_setting (file, iface, NM_SETTING_WIRELESS_SETTING_NAME, printable_ssid);
|
|
||||||
nm_connection_add_setting (connection, setting);
|
|
||||||
g_free (printable_ssid);
|
|
||||||
|
|
||||||
setting = make_ip4_setting (file);
|
|
||||||
nm_connection_add_setting (connection, setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
static shvarFile *
|
|
||||||
parser_get_ifcfg_for_iface (const char *iface)
|
|
||||||
{
|
|
||||||
char *filename;
|
|
||||||
shvarFile *file = NULL;
|
|
||||||
|
|
||||||
filename = g_strdup_printf (SYSCONFDIR "/sysconfig/network/ifcfg-%s", iface);
|
|
||||||
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
|
|
||||||
file = svNewFile (filename);
|
|
||||||
|
|
||||||
g_free (filename);
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
NMConnection *
|
|
||||||
parse_ifcfg (const char *iface, NMDeviceType type)
|
|
||||||
{
|
|
||||||
shvarFile *file;
|
|
||||||
NMConnection *connection;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (iface != NULL, NULL);
|
|
||||||
|
|
||||||
file = parser_get_ifcfg_for_iface (iface);
|
|
||||||
if (!file)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
connection = nm_connection_new ();
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case NM_DEVICE_TYPE_ETHERNET:
|
|
||||||
parse_ethernet (connection, file, iface);
|
|
||||||
break;
|
|
||||||
case NM_DEVICE_TYPE_WIFI:
|
|
||||||
parse_wireless (connection, file, iface);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
svCloseFile (file);
|
|
||||||
|
|
||||||
if (!nm_connection_verify (connection, &error)) {
|
|
||||||
g_warning ("%s: Invalid connection for %s: '%s' / '%s' invalid: %d",
|
|
||||||
__func__, iface,
|
|
||||||
g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
|
|
||||||
error->message, error->code);
|
|
||||||
g_error_free (error);
|
|
||||||
g_object_unref (connection);
|
|
||||||
connection = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
parser_ignore_device (const char *iface)
|
|
||||||
{
|
|
||||||
shvarFile *file;
|
|
||||||
gboolean ignore = FALSE;
|
|
||||||
|
|
||||||
file = parser_get_ifcfg_for_iface (iface);
|
|
||||||
if (file) {
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
if (!svTrueValue (file, "NM_CONTROLLED", 1))
|
|
||||||
ignore = TRUE;
|
|
||||||
|
|
||||||
str = svGetValue (file, "STARTMODE");
|
|
||||||
if (str && !g_ascii_strcasecmp (str, "off"))
|
|
||||||
ignore = TRUE;
|
|
||||||
g_free (str);
|
|
||||||
|
|
||||||
svCloseFile (file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
guint32
|
|
||||||
parser_parse_routes (const char *filename)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
char *buf;
|
|
||||||
char buffer[512];
|
|
||||||
guint route = 0;
|
|
||||||
|
|
||||||
g_return_val_if_fail (filename != NULL, 0);
|
|
||||||
|
|
||||||
if ((f = fopen (filename, "r"))) {
|
|
||||||
while (fgets (buffer, 512, f) && !feof (f)) {
|
|
||||||
buf = strtok (buffer, " ");
|
|
||||||
if (strcmp (buf, "default") == 0) {
|
|
||||||
buf = strtok (NULL, " ");
|
|
||||||
if (buf)
|
|
||||||
route = inet_addr (buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fclose (f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return route;
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
/* NetworkManager system settings service
|
|
||||||
*
|
|
||||||
* Søren Sandmann <sandmann@daimi.au.dk>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* (C) Copyright 2007 Red Hat, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PARSER_H_
|
|
||||||
#define _PARSER_H_
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <NetworkManager.h>
|
|
||||||
#include <nm-connection.h>
|
|
||||||
|
|
||||||
#define IFCFG_TAG "ifcfg-"
|
|
||||||
#define BAK_TAG ".bak"
|
|
||||||
|
|
||||||
NMConnection *parse_ifcfg (const char *iface, NMDeviceType type);
|
|
||||||
gboolean parser_ignore_device (const char *iface);
|
|
||||||
|
|
||||||
guint32 parser_parse_routes (const char *filename);
|
|
||||||
|
|
||||||
#endif /* _PARSER_H_ */
|
|
@@ -24,32 +24,19 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/inotify.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <glib/gi18n.h>
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include <nm-setting-connection.h>
|
|
||||||
#include <nm-setting-ip4-config.h>
|
|
||||||
|
|
||||||
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
|
|
||||||
#include <gudev/gudev.h>
|
|
||||||
|
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "parser.h"
|
|
||||||
#include "nm-suse-connection.h"
|
|
||||||
#include "nm-system-config-interface.h"
|
#include "nm-system-config-interface.h"
|
||||||
#include "wireless-helper.h"
|
|
||||||
|
|
||||||
#define IFCFG_PLUGIN_NAME "ifcfg-suse"
|
#define IFCFG_PLUGIN_NAME "ifcfg-suse"
|
||||||
#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list."
|
#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list."
|
||||||
#define IFCFG_DIR SYSCONFDIR "/sysconfig/network"
|
#define IFCFG_DIR SYSCONFDIR "/sysconfig/network"
|
||||||
|
#define CONF_DHCP IFCFG_DIR "/dhcp"
|
||||||
|
#define HOSTNAME_FILE "/etc/HOSTNAME"
|
||||||
|
|
||||||
static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
|
static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
|
||||||
|
|
||||||
@@ -63,15 +50,9 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
|
|||||||
#define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
|
#define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GUdevClient *client;
|
GFileMonitor *hostname_monitor;
|
||||||
|
GFileMonitor *dhcp_monitor;
|
||||||
gboolean initialized;
|
char *hostname;
|
||||||
GHashTable *connections;
|
|
||||||
GHashTable *unmanaged_specs;
|
|
||||||
|
|
||||||
guint32 default_gw;
|
|
||||||
GFileMonitor *default_gw_monitor;
|
|
||||||
guint default_gw_monitor_id;
|
|
||||||
} SCPluginIfcfgPrivate;
|
} SCPluginIfcfgPrivate;
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
@@ -85,285 +66,153 @@ ifcfg_plugin_error_quark (void)
|
|||||||
return error_quark;
|
return error_quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
typedef void (*FileChangedFn) (gpointer user_data);
|
||||||
ignore_cb (NMSettingsConnectionInterface *connection,
|
|
||||||
GError *error,
|
typedef struct {
|
||||||
gpointer user_data)
|
FileChangedFn callback;
|
||||||
{
|
gpointer user_data;
|
||||||
}
|
} FileMonitorInfo;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_connections (SCPluginIfcfg *self)
|
file_changed (GFileMonitor *monitor,
|
||||||
{
|
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
GHashTableIter iter;
|
|
||||||
gpointer value;
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, priv->connections);
|
|
||||||
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
|
||||||
NMSuseConnection *exported = NM_SUSE_CONNECTION (value);
|
|
||||||
NMSettingIP4Config *ip4_config;
|
|
||||||
|
|
||||||
ip4_config = (NMSettingIP4Config *) nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_IP4_CONFIG);
|
|
||||||
if (!ip4_config)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (nm_setting_ip4_config_get_num_addresses (ip4_config)) {
|
|
||||||
/* suse only has one address per device */
|
|
||||||
NMIP4Address *ip4_address;
|
|
||||||
|
|
||||||
ip4_address = nm_setting_ip4_config_get_address (ip4_config, 0);
|
|
||||||
if (nm_ip4_address_get_gateway (ip4_address) != priv->default_gw) {
|
|
||||||
nm_ip4_address_set_gateway (ip4_address, priv->default_gw);
|
|
||||||
nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (exported),
|
|
||||||
ignore_cb,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
routes_changed (GFileMonitor *monitor,
|
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GFile *other_file,
|
GFile *other_file,
|
||||||
GFileMonitorEvent event_type,
|
GFileMonitorEvent event_type,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
|
FileMonitorInfo *info;
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
char *filename;
|
|
||||||
guint32 new_gw;
|
|
||||||
|
|
||||||
switch (event_type) {
|
switch (event_type) {
|
||||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||||
case G_FILE_MONITOR_EVENT_DELETED:
|
case G_FILE_MONITOR_EVENT_DELETED:
|
||||||
filename = g_file_get_path (file);
|
info = (FileMonitorInfo *) user_data;
|
||||||
new_gw = parser_parse_routes (filename);
|
info->callback (info->user_data);
|
||||||
g_free (filename);
|
|
||||||
|
|
||||||
if (priv->default_gw != new_gw) {
|
|
||||||
priv->default_gw = new_gw;
|
|
||||||
update_connections (self);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GFileMonitor *
|
||||||
monitor_routes (SCPluginIfcfg *self, const char *filename)
|
monitor_file_changes (const char *filename,
|
||||||
|
FileChangedFn callback,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
GFile *file;
|
GFile *file;
|
||||||
GFileMonitor *monitor;
|
GFileMonitor *monitor;
|
||||||
|
FileMonitorInfo *info;
|
||||||
|
|
||||||
file = g_file_new_for_path (filename);
|
file = g_file_new_for_path (filename);
|
||||||
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
|
|
||||||
if (monitor) {
|
if (monitor) {
|
||||||
priv->default_gw_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (routes_changed), self);
|
info = g_new0 (FileMonitorInfo, 1);
|
||||||
priv->default_gw_monitor = monitor;
|
info->callback = callback;
|
||||||
}
|
info->user_data = user_data;
|
||||||
|
g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, info);
|
||||||
|
g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
return monitor;
|
||||||
read_connection (SCPluginIfcfg *self, GUdevDevice *device, NMDeviceType dev_type)
|
|
||||||
{
|
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
const char *iface, *address;
|
|
||||||
guint32 ifindex;
|
|
||||||
|
|
||||||
iface = g_udev_device_get_name (device);
|
|
||||||
if (!iface)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX");
|
|
||||||
|
|
||||||
if (parser_ignore_device (iface)) {
|
|
||||||
char *spec;
|
|
||||||
|
|
||||||
address = g_udev_device_get_sysfs_attr (device, "address");
|
|
||||||
if (address && (strlen (address) == 17)) {
|
|
||||||
spec = g_strdup_printf ("mac:%s", address);
|
|
||||||
g_hash_table_insert (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex), spec);
|
|
||||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
|
||||||
} else
|
|
||||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " (%s) error getting hardware address", iface);
|
|
||||||
} else {
|
|
||||||
NMSuseConnection *connection;
|
|
||||||
|
|
||||||
connection = nm_suse_connection_new (iface, dev_type);
|
|
||||||
if (connection) {
|
|
||||||
g_hash_table_insert (priv->connections,
|
|
||||||
GUINT_TO_POINTER (ifindex),
|
|
||||||
connection);
|
|
||||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
read_connections_by_type (SCPluginIfcfg *self, NMDeviceType dev_type)
|
|
||||||
{
|
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
GList *devices, *iter;
|
|
||||||
|
|
||||||
if ( (dev_type != NM_DEVICE_TYPE_ETHERNET)
|
|
||||||
&& (dev_type != NM_DEVICE_TYPE_WIFI))
|
|
||||||
return;
|
|
||||||
|
|
||||||
devices = g_udev_client_query_by_subsystem (priv->client, "net");
|
|
||||||
for (iter = devices; iter; iter = g_list_next (iter)) {
|
|
||||||
read_connection (self, G_UDEV_DEVICE (iter->data), dev_type);
|
|
||||||
g_object_unref (G_UDEV_DEVICE (iter->data));
|
|
||||||
}
|
|
||||||
g_list_free (devices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_wireless (GUdevDevice *device)
|
hostname_is_dynamic (void)
|
||||||
{
|
{
|
||||||
char phy80211_path[255];
|
GIOChannel *channel;
|
||||||
struct stat s;
|
const char *pattern = "DHCLIENT_SET_HOSTNAME=";
|
||||||
int fd;
|
char *str = NULL;
|
||||||
struct iwreq iwr;
|
int pattern_len;
|
||||||
const char *ifname, *path;
|
gboolean dynamic = FALSE;
|
||||||
gboolean is_wifi = FALSE;
|
|
||||||
|
|
||||||
ifname = g_udev_device_get_name (device);
|
channel = g_io_channel_new_file (CONF_DHCP, "r", NULL);
|
||||||
g_assert (ifname);
|
if (!channel)
|
||||||
|
return dynamic;
|
||||||
|
|
||||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
pattern_len = strlen (pattern);
|
||||||
strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ);
|
|
||||||
|
|
||||||
path = g_udev_device_get_sysfs_path (device);
|
while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
|
||||||
snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path);
|
if (!strncmp (str, pattern, pattern_len)) {
|
||||||
|
if (!strncmp (str + pattern_len, "\"yes\"", 5))
|
||||||
|
dynamic = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
|
||||||
if ( (ioctl (fd, SIOCGIWNAME, &iwr) == 0)
|
g_io_channel_shutdown (channel, FALSE, NULL);
|
||||||
|| (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
|
g_io_channel_unref (channel);
|
||||||
is_wifi = TRUE;
|
|
||||||
|
|
||||||
close (fd);
|
return dynamic;
|
||||||
return is_wifi;
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
hostname_read ()
|
||||||
|
{
|
||||||
|
GIOChannel *channel;
|
||||||
|
char *hostname = NULL;
|
||||||
|
|
||||||
|
channel = g_io_channel_new_file (HOSTNAME_FILE, "r", NULL);
|
||||||
|
if (channel) {
|
||||||
|
g_io_channel_read_line (channel, &hostname, NULL, NULL, NULL);
|
||||||
|
g_io_channel_shutdown (channel, FALSE, NULL);
|
||||||
|
g_io_channel_unref (channel);
|
||||||
|
|
||||||
|
if (hostname)
|
||||||
|
hostname = g_strchomp (hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_uevent (GUdevClient *client,
|
hostname_changed (gpointer data)
|
||||||
const char *action,
|
|
||||||
GUdevDevice *device,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
|
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (data);
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
const char *subsys;
|
|
||||||
gboolean wifi;
|
|
||||||
|
|
||||||
g_return_if_fail (action != NULL);
|
g_free (priv->hostname);
|
||||||
|
if (hostname_is_dynamic ())
|
||||||
|
priv->hostname = NULL;
|
||||||
|
else
|
||||||
|
priv->hostname = hostname_read ();
|
||||||
|
|
||||||
/* A bit paranoid */
|
g_object_notify (G_OBJECT (data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
||||||
subsys = g_udev_device_get_subsystem (device);
|
|
||||||
g_return_if_fail (subsys != NULL);
|
|
||||||
g_return_if_fail (strcmp (subsys, "net") == 0);
|
|
||||||
|
|
||||||
wifi = is_wireless (device);
|
|
||||||
|
|
||||||
if (!strcmp (action, "add")) {
|
|
||||||
read_connection (self,
|
|
||||||
device,
|
|
||||||
wifi ? NM_DEVICE_TYPE_WIFI : NM_DEVICE_TYPE_ETHERNET);
|
|
||||||
} else if (!strcmp (action, "remove")) {
|
|
||||||
NMExportedConnection *exported;
|
|
||||||
guint32 ifindex;
|
|
||||||
|
|
||||||
ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX");
|
|
||||||
if (g_hash_table_remove (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex)))
|
|
||||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
|
||||||
|
|
||||||
exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections,
|
|
||||||
GUINT_TO_POINTER (ifindex));
|
|
||||||
if (exported) {
|
|
||||||
nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (exported),
|
|
||||||
ignore_cb,
|
|
||||||
NULL);
|
|
||||||
g_hash_table_remove (priv->connections, GUINT_TO_POINTER (ifindex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname)
|
||||||
|
{
|
||||||
|
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||||
|
GIOChannel *channel;
|
||||||
|
|
||||||
|
channel = g_io_channel_new_file (HOSTNAME_FILE, "w", NULL);
|
||||||
|
if (channel) {
|
||||||
|
g_io_channel_write_chars (channel, hostname, -1, NULL, NULL);
|
||||||
|
g_io_channel_write_chars (channel, "\n", -1, NULL, NULL);
|
||||||
|
g_io_channel_shutdown (channel, TRUE, NULL);
|
||||||
|
g_io_channel_unref (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (priv->hostname);
|
||||||
|
priv->hostname = hostname ? g_strdup (hostname) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init (NMSystemConfigInterface *config)
|
init (NMSystemConfigInterface *config)
|
||||||
{
|
{
|
||||||
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
|
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
const char *subsys[2] = { "net", NULL };
|
|
||||||
|
|
||||||
priv->client = g_udev_client_new (subsys);
|
priv->hostname_monitor = monitor_file_changes (HOSTNAME_FILE, hostname_changed, config);
|
||||||
if (!priv->client) {
|
priv->dhcp_monitor = monitor_file_changes (CONF_DHCP, hostname_changed, config);
|
||||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error initializing libgudev");
|
|
||||||
} else
|
|
||||||
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GSList *
|
if (!hostname_is_dynamic ())
|
||||||
get_connections (NMSystemConfigInterface *config)
|
priv->hostname = hostname_read ();
|
||||||
{
|
|
||||||
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
|
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
GSList *list = NULL;
|
|
||||||
GHashTableIter iter;
|
|
||||||
gpointer value;
|
|
||||||
|
|
||||||
if (!priv->initialized) {
|
|
||||||
const char *filename;
|
|
||||||
|
|
||||||
read_connections_by_type (self, NM_DEVICE_TYPE_ETHERNET);
|
|
||||||
read_connections_by_type (self, NM_DEVICE_TYPE_WIFI);
|
|
||||||
|
|
||||||
filename = SYSCONFDIR"/sysconfig/network/routes";
|
|
||||||
monitor_routes (self, filename);
|
|
||||||
priv->default_gw = parser_parse_routes (filename);
|
|
||||||
if (priv->default_gw)
|
|
||||||
update_connections (self);
|
|
||||||
|
|
||||||
priv->initialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, priv->connections);
|
|
||||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
|
||||||
list = g_slist_prepend (list, value);
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_one_unmanaged_spec (gpointer key, gpointer val, gpointer user_data)
|
|
||||||
{
|
|
||||||
GSList **list = (GSList **) key;
|
|
||||||
|
|
||||||
*list = g_slist_prepend (*list, g_strdup ((const char *) val));
|
|
||||||
}
|
|
||||||
|
|
||||||
static GSList *
|
|
||||||
get_unmanaged_specs (NMSystemConfigInterface *config)
|
|
||||||
{
|
|
||||||
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
|
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
GSList *list = NULL;
|
|
||||||
|
|
||||||
g_hash_table_foreach (priv->unmanaged_specs, add_one_unmanaged_spec, &list);
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_plugin_ifcfg_init (SCPluginIfcfg *self)
|
sc_plugin_ifcfg_init (SCPluginIfcfg *self)
|
||||||
{
|
{
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
|
||||||
|
|
||||||
priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
|
||||||
priv->unmanaged_specs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -371,19 +220,13 @@ dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
|
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
|
||||||
|
|
||||||
g_hash_table_destroy (priv->connections);
|
if (priv->dhcp_monitor)
|
||||||
g_hash_table_destroy (priv->unmanaged_specs);
|
g_object_unref (priv->dhcp_monitor);
|
||||||
|
|
||||||
if (priv->default_gw_monitor) {
|
if (priv->hostname_monitor)
|
||||||
if (priv->default_gw_monitor_id)
|
g_object_unref (priv->hostname_monitor);
|
||||||
g_signal_handler_disconnect (priv->default_gw_monitor, priv->default_gw_monitor_id);
|
|
||||||
|
|
||||||
g_file_monitor_cancel (priv->default_gw_monitor);
|
g_free (priv->hostname);
|
||||||
g_object_unref (priv->default_gw_monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->client)
|
|
||||||
g_object_unref (priv->client);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
|
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@@ -400,10 +243,29 @@ get_property (GObject *object, guint prop_id,
|
|||||||
g_value_set_string (value, IFCFG_PLUGIN_INFO);
|
g_value_set_string (value, IFCFG_PLUGIN_INFO);
|
||||||
break;
|
break;
|
||||||
case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
|
||||||
g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE);
|
g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
|
||||||
break;
|
break;
|
||||||
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
|
||||||
g_value_set_string (value, "");
|
g_value_set_string (value, SC_PLUGIN_IFCFG_GET_PRIVATE (object)->hostname);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
const char *hostname;
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
|
||||||
|
hostname = g_value_get_string (value);
|
||||||
|
if (hostname && strlen (hostname) < 1)
|
||||||
|
hostname = NULL;
|
||||||
|
plugin_set_hostname (SC_PLUGIN_IFCFG (object), hostname);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@@ -419,6 +281,7 @@ sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class)
|
|||||||
g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate));
|
g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate));
|
||||||
|
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
object_class->set_property = set_property;
|
||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
|
|
||||||
g_object_class_override_property (object_class,
|
g_object_class_override_property (object_class,
|
||||||
@@ -442,8 +305,6 @@ static void
|
|||||||
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
|
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
|
||||||
{
|
{
|
||||||
/* interface implementation */
|
/* interface implementation */
|
||||||
system_config_interface_class->get_connections = get_connections;
|
|
||||||
system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
|
|
||||||
system_config_interface_class->init = init;
|
system_config_interface_class->init = init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#define PLUGIN_NAME "ifcfg"
|
#define PLUGIN_NAME "ifcfg-suse"
|
||||||
|
|
||||||
#define SC_TYPE_PLUGIN_IFCFG (sc_plugin_ifcfg_get_type ())
|
#define SC_TYPE_PLUGIN_IFCFG (sc_plugin_ifcfg_get_type ())
|
||||||
#define SC_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfg))
|
#define SC_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfg))
|
||||||
|
@@ -1,403 +0,0 @@
|
|||||||
/*
|
|
||||||
* shvar.c
|
|
||||||
*
|
|
||||||
* Implementation of non-destructively reading/writing files containing
|
|
||||||
* only shell variable declarations and full-line comments.
|
|
||||||
*
|
|
||||||
* Includes explicit inheritance mechanism intended for use with
|
|
||||||
* Red Hat Linux ifcfg-* files. There is no protection against
|
|
||||||
* inheritance loops; they will generally cause stack overflows.
|
|
||||||
* Furthermore, they are only intended for one level of inheritance;
|
|
||||||
* the value setting algorithm assumes this.
|
|
||||||
*
|
|
||||||
* Copyright 1999,2000 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "shvar.h"
|
|
||||||
|
|
||||||
/* Open the file <name>, returning a shvarFile on success and NULL on failure.
|
|
||||||
Add a wrinkle to let the caller specify whether or not to create the file
|
|
||||||
(actually, return a structure anyway) if it doesn't exist. */
|
|
||||||
static shvarFile *
|
|
||||||
svOpenFile(const char *name, gboolean create)
|
|
||||||
{
|
|
||||||
shvarFile *s = NULL;
|
|
||||||
int closefd = 0;
|
|
||||||
|
|
||||||
s = g_malloc0(sizeof(shvarFile));
|
|
||||||
|
|
||||||
#if 1 /* NetworkManager local change */
|
|
||||||
s->fd = open(name, O_RDONLY); /* NOT O_CREAT */
|
|
||||||
if (s->fd != -1) closefd = 1;
|
|
||||||
#else
|
|
||||||
s->fd = open(name, O_RDWR); /* NOT O_CREAT */
|
|
||||||
if (s->fd == -1) {
|
|
||||||
/* try read-only */
|
|
||||||
s->fd = open(name, O_RDONLY); /* NOT O_CREAT */
|
|
||||||
if (s->fd != -1) closefd = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
s->fileName = g_strdup(name);
|
|
||||||
|
|
||||||
if (s->fd != -1) {
|
|
||||||
struct stat buf;
|
|
||||||
char *p, *q;
|
|
||||||
|
|
||||||
if (fstat(s->fd, &buf) < 0) goto bail;
|
|
||||||
s->arena = g_malloc0(buf.st_size + 1);
|
|
||||||
|
|
||||||
if (read(s->fd, s->arena, buf.st_size) < 0) goto bail;
|
|
||||||
|
|
||||||
/* we'd use g_strsplit() here, but we want a list, not an array */
|
|
||||||
for(p = s->arena; (q = strchr(p, '\n')) != NULL; p = q + 1) {
|
|
||||||
s->lineList = g_list_append(s->lineList, g_strndup(p, q - p));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* closefd is set if we opened the file read-only, so go ahead and
|
|
||||||
close it, because we can't write to it anyway */
|
|
||||||
if (closefd) {
|
|
||||||
close(s->fd);
|
|
||||||
s->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (create) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
bail:
|
|
||||||
if (s->fd != -1) close(s->fd);
|
|
||||||
if (s->arena) g_free (s->arena);
|
|
||||||
if (s->fileName) g_free (s->fileName);
|
|
||||||
g_free (s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file <name>, return shvarFile on success, NULL on failure */
|
|
||||||
shvarFile *
|
|
||||||
svNewFile(const char *name)
|
|
||||||
{
|
|
||||||
return svOpenFile(name, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a new file structure, returning actual data if the file exists,
|
|
||||||
* and a suitable starting point if it doesn't. */
|
|
||||||
shvarFile *
|
|
||||||
svCreateFile(const char *name)
|
|
||||||
{
|
|
||||||
return svOpenFile(name, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove escaped characters in place */
|
|
||||||
static void
|
|
||||||
unescape(char *s) {
|
|
||||||
int len, i;
|
|
||||||
|
|
||||||
len = strlen(s);
|
|
||||||
if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
|
|
||||||
i = len - 2;
|
|
||||||
if (i == 0)
|
|
||||||
s[0] = '\0';
|
|
||||||
else {
|
|
||||||
memmove(s, s+1, i);
|
|
||||||
s[i+1] = '\0';
|
|
||||||
len = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
if (s[i] == '\\') {
|
|
||||||
memmove(s+i, s+i+1, len-(i+1));
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
s[len] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* create a new string with all necessary characters escaped.
|
|
||||||
* caller must free returned string
|
|
||||||
*/
|
|
||||||
static const char escapees[] = "\"'\\$~`"; /* must be escaped */
|
|
||||||
static const char spaces[] = " \t|&;()<>"; /* only require "" */
|
|
||||||
static char *
|
|
||||||
escape(const char *s) {
|
|
||||||
char *new;
|
|
||||||
int i, j, mangle = 0, space = 0;
|
|
||||||
int newlen, slen;
|
|
||||||
static int esclen, splen;
|
|
||||||
|
|
||||||
if (!esclen) esclen = strlen(escapees);
|
|
||||||
if (!splen) splen = strlen(spaces);
|
|
||||||
slen = strlen(s);
|
|
||||||
|
|
||||||
for (i = 0; i < slen; i++) {
|
|
||||||
if (strchr(escapees, s[i])) mangle++;
|
|
||||||
if (strchr(spaces, s[i])) space++;
|
|
||||||
}
|
|
||||||
if (!mangle && !space) return strdup(s);
|
|
||||||
|
|
||||||
newlen = slen + mangle + 3; /* 3 is extra ""\0 */
|
|
||||||
new = g_malloc0(newlen);
|
|
||||||
if (!new) return NULL;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
new[j++] = '"';
|
|
||||||
for (i = 0; i < slen; i++) {
|
|
||||||
if (strchr(escapees, s[i])) {
|
|
||||||
new[j++] = '\\';
|
|
||||||
}
|
|
||||||
new[j++] = s[i];
|
|
||||||
}
|
|
||||||
new[j++] = '"';
|
|
||||||
g_assert(j == slen + mangle + 2); /* j is the index of the '\0' */
|
|
||||||
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the value associated with the key, and leave the current pointer
|
|
||||||
* pointing at the line containing the value. The char* returned MUST
|
|
||||||
* be freed by the caller.
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
svGetValue(shvarFile *s, const char *key)
|
|
||||||
{
|
|
||||||
char *value = NULL;
|
|
||||||
char *line;
|
|
||||||
char *keyString;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
g_assert(s);
|
|
||||||
g_assert(key);
|
|
||||||
|
|
||||||
keyString = g_malloc0(strlen(key) + 2);
|
|
||||||
strcpy(keyString, key);
|
|
||||||
keyString[strlen(key)] = '=';
|
|
||||||
len = strlen(keyString);
|
|
||||||
|
|
||||||
for (s->current = s->lineList; s->current; s->current = s->current->next) {
|
|
||||||
line = s->current->data;
|
|
||||||
if (!strncmp(keyString, line, len)) {
|
|
||||||
value = g_strdup(line + len);
|
|
||||||
unescape(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_free(keyString);
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
if (value[0]) {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
g_free(value);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s->parent) value = svGetValue(s->parent, key);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return 1 if <key> resolves to any truth value (e.g. "yes", "y", "true")
|
|
||||||
* return 0 if <key> resolves to any non-truth value (e.g. "no", "n", "false")
|
|
||||||
* return <default> otherwise
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
svTrueValue(shvarFile *s, const char *key, int def)
|
|
||||||
{
|
|
||||||
char *tmp;
|
|
||||||
int returnValue = def;
|
|
||||||
|
|
||||||
tmp = svGetValue(s, key);
|
|
||||||
if (!tmp) return returnValue;
|
|
||||||
|
|
||||||
if ( (!strcasecmp("yes", tmp)) ||
|
|
||||||
(!strcasecmp("true", tmp)) ||
|
|
||||||
(!strcasecmp("t", tmp)) ||
|
|
||||||
(!strcasecmp("y", tmp)) ) returnValue = 1;
|
|
||||||
else
|
|
||||||
if ( (!strcasecmp("no", tmp)) ||
|
|
||||||
(!strcasecmp("false", tmp)) ||
|
|
||||||
(!strcasecmp("f", tmp)) ||
|
|
||||||
(!strcasecmp("n", tmp)) ) returnValue = 0;
|
|
||||||
|
|
||||||
g_free (tmp);
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the variable <key> equal to the value <value>.
|
|
||||||
* If <key> does not exist, and the <current> pointer is set, append
|
|
||||||
* the key=value pair after that line. Otherwise, prepend the pair
|
|
||||||
* to the top of the file. Here's the algorithm, as the C code
|
|
||||||
* seems to be rather dense:
|
|
||||||
*
|
|
||||||
* if (value == NULL), then:
|
|
||||||
* if val2 (parent): change line to key= or append line key=
|
|
||||||
* if val1 (this) : delete line
|
|
||||||
* else noop
|
|
||||||
* else use this table:
|
|
||||||
* val2
|
|
||||||
* NULL value other
|
|
||||||
* v NULL append line noop append line
|
|
||||||
* a
|
|
||||||
* l value noop noop noop
|
|
||||||
* 1
|
|
||||||
* other change line delete line change line
|
|
||||||
*
|
|
||||||
* No changes are ever made to the parent config file, only to the
|
|
||||||
* specific file passed on the command line.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
svSetValue(shvarFile *s, const char *key, const char *value)
|
|
||||||
{
|
|
||||||
char *newval = NULL, *val1 = NULL, *val2 = NULL;
|
|
||||||
char *keyValue;
|
|
||||||
|
|
||||||
g_assert(s);
|
|
||||||
g_assert(key);
|
|
||||||
/* value may be NULL */
|
|
||||||
|
|
||||||
if (value) newval = escape(value);
|
|
||||||
keyValue = g_strdup_printf("%s=%s", key, newval ? newval : "");
|
|
||||||
|
|
||||||
val1 = svGetValue(s, key);
|
|
||||||
if (val1 && newval && !strcmp(val1, newval)) goto bail;
|
|
||||||
if (s->parent) val2 = svGetValue(s->parent, key);
|
|
||||||
|
|
||||||
if (!newval || !newval[0]) {
|
|
||||||
/* delete value somehow */
|
|
||||||
if (val2) {
|
|
||||||
/* change/append line to get key= */
|
|
||||||
if (s->current) s->current->data = keyValue;
|
|
||||||
else s->lineList = g_list_append(s->lineList, keyValue);
|
|
||||||
s->freeList = g_list_append(s->freeList, keyValue);
|
|
||||||
s->modified = 1;
|
|
||||||
} else if (val1) {
|
|
||||||
/* delete line */
|
|
||||||
s->lineList = g_list_remove_link(s->lineList, s->current);
|
|
||||||
g_list_free_1(s->current);
|
|
||||||
s->modified = 1;
|
|
||||||
goto bail; /* do not need keyValue */
|
|
||||||
}
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!val1) {
|
|
||||||
if (val2 && !strcmp(val2, newval)) goto end;
|
|
||||||
/* append line */
|
|
||||||
s->lineList = g_list_append(s->lineList, keyValue);
|
|
||||||
s->freeList = g_list_append(s->freeList, keyValue);
|
|
||||||
s->modified = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* deal with a whole line of noops */
|
|
||||||
if (val1 && !strcmp(val1, newval)) goto end;
|
|
||||||
|
|
||||||
/* At this point, val1 && val1 != value */
|
|
||||||
if (val2 && !strcmp(val2, newval)) {
|
|
||||||
/* delete line */
|
|
||||||
s->lineList = g_list_remove_link(s->lineList, s->current);
|
|
||||||
g_list_free_1(s->current);
|
|
||||||
s->modified = 1;
|
|
||||||
goto bail; /* do not need keyValue */
|
|
||||||
} else {
|
|
||||||
/* change line */
|
|
||||||
if (s->current) s->current->data = keyValue;
|
|
||||||
else s->lineList = g_list_append(s->lineList, keyValue);
|
|
||||||
s->freeList = g_list_append(s->freeList, keyValue);
|
|
||||||
s->modified = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (newval) free(newval);
|
|
||||||
if (val1) free(val1);
|
|
||||||
if (val2) free(val2);
|
|
||||||
return;
|
|
||||||
|
|
||||||
bail:
|
|
||||||
if (keyValue) free (keyValue);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the current contents iff modified. Returns -1 on error
|
|
||||||
* and 0 on success. Do not write if no values have been modified.
|
|
||||||
* The mode argument is only used if creating the file, not if
|
|
||||||
* re-writing an existing file, and is passed unchanged to the
|
|
||||||
* open() syscall.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
svWriteFile(shvarFile *s, int mode)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
int tmpfd;
|
|
||||||
|
|
||||||
if (s->modified) {
|
|
||||||
if (s->fd == -1)
|
|
||||||
s->fd = open(s->fileName, O_WRONLY|O_CREAT, mode);
|
|
||||||
if (s->fd == -1)
|
|
||||||
return -1;
|
|
||||||
if (ftruncate(s->fd, 0) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
tmpfd = dup(s->fd);
|
|
||||||
f = fdopen(tmpfd, "w");
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
for (s->current = s->lineList; s->current; s->current = s->current->next) {
|
|
||||||
char *line = s->current->data;
|
|
||||||
fprintf(f, "%s\n", line);
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Close the file descriptor (if open) and delete the shvarFile.
|
|
||||||
* Returns -1 on error and 0 on success.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
svCloseFile(shvarFile *s)
|
|
||||||
{
|
|
||||||
|
|
||||||
g_assert(s);
|
|
||||||
|
|
||||||
if (s->fd != -1) close(s->fd);
|
|
||||||
|
|
||||||
g_free(s->arena);
|
|
||||||
for (s->current = s->freeList; s->current; s->current = s->current->next) {
|
|
||||||
g_free(s->current->data);
|
|
||||||
}
|
|
||||||
g_free(s->fileName);
|
|
||||||
g_list_free(s->freeList);
|
|
||||||
g_list_foreach (s->lineList, (GFunc) g_free, NULL);
|
|
||||||
g_list_free(s->lineList); /* implicitly frees s->current */
|
|
||||||
g_free(s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* shvar.h
|
|
||||||
*
|
|
||||||
* Interface for non-destructively reading/writing files containing
|
|
||||||
* only shell variable declarations and full-line comments.
|
|
||||||
*
|
|
||||||
* Includes explicit inheritance mechanism intended for use with
|
|
||||||
* Red Hat Linux ifcfg-* files. There is no protection against
|
|
||||||
* inheritance loops; they will generally cause stack overflows.
|
|
||||||
* Furthermore, they are only intended for one level of inheritance;
|
|
||||||
* the value setting algorithm assumes this.
|
|
||||||
*
|
|
||||||
* Copyright 1999 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef _SHVAR_H
|
|
||||||
#define _SHVAR_H
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
typedef struct _shvarFile shvarFile;
|
|
||||||
struct _shvarFile {
|
|
||||||
char *fileName; /* read-only */
|
|
||||||
int fd; /* read-only */
|
|
||||||
char *arena; /* ignore */
|
|
||||||
GList *lineList; /* read-only */
|
|
||||||
GList *freeList; /* ignore */
|
|
||||||
GList *current; /* set implicitly or explicitly,
|
|
||||||
points to element of lineList */
|
|
||||||
shvarFile *parent; /* set explicitly */
|
|
||||||
int modified; /* ignore */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Create the file <name>, return shvarFile on success, NULL on failure */
|
|
||||||
shvarFile *
|
|
||||||
svCreateFile(const char *name);
|
|
||||||
|
|
||||||
/* Open the file <name>, return shvarFile on success, NULL on failure */
|
|
||||||
shvarFile *
|
|
||||||
svNewFile(const char *name);
|
|
||||||
|
|
||||||
/* Get the value associated with the key, and leave the current pointer
|
|
||||||
* pointing at the line containing the value. The char* returned MUST
|
|
||||||
* be freed by the caller.
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
svGetValue(shvarFile *s, const char *key);
|
|
||||||
|
|
||||||
/* return 1 if <key> resolves to any truth value (e.g. "yes", "y", "true")
|
|
||||||
* return 0 if <key> resolves to any non-truth value (e.g. "no", "n", "false")
|
|
||||||
* return <def> otherwise
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
svTrueValue(shvarFile *s, const char *key, int def);
|
|
||||||
|
|
||||||
/* Set the variable <key> equal to the value <value>.
|
|
||||||
* If <key> does not exist, and the <current> pointer is set, append
|
|
||||||
* the key=value pair after that line. Otherwise, prepend the pair
|
|
||||||
* to the top of the file.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
svSetValue(shvarFile *s, const char *key, const char *value);
|
|
||||||
|
|
||||||
|
|
||||||
/* Write the current contents iff modified. Returns -1 on error
|
|
||||||
* and 0 on success. Do not write if no values have been modified.
|
|
||||||
* The mode argument is only used if creating the file, not if
|
|
||||||
* re-writing an existing file, and is passed unchanged to the
|
|
||||||
* open() syscall.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
svWriteFile(shvarFile *s, int mode);
|
|
||||||
|
|
||||||
/* Close the file descriptor (if open) and delete the shvarFile.
|
|
||||||
* Returns -1 on error and 0 on success.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
svCloseFile(shvarFile *s);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif /* ! _SHVAR_H */
|
|
Reference in New Issue
Block a user