/*
* dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
+ * Copyright 2009-2014 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
*/
#include <sys/types.h>
+#include <arpa/inet.h>
#include <net/if.h>
#include <errno.h>
static GtkWidget *dialog, *blocks, *names, *controls, *clear, *rebind;
static GtkWidget *autoconf, *address, *router, *dns_servers, *dns_search;
-static DHCPCD_CONFIG *config;
+static DHCPCD_OPTION *config;
static char *block, *name;
static DHCPCD_IF *iface;
static void
-show_config(DHCPCD_CONFIG *conf)
+config_err_dialog(DHCPCD_CONNECTION *con, bool writing, const char *txt)
+{
+ GtkWidget *edialog;
+ char *t;
+
+ t = g_strconcat(_(writing ? "Error saving" : "Error reading"), " ",
+ dhcpcd_cffile(con), "\n\n", txt, NULL);
+ edialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", t);
+ gtk_window_set_title(GTK_WINDOW(edialog), _("Config error"));
+ gtk_dialog_run(GTK_DIALOG(edialog));
+ gtk_widget_destroy(edialog);
+ g_free(t);
+}
+
+static void
+show_config(DHCPCD_OPTION *conf)
{
const char *val;
bool autocnf;
}
static bool
-set_option(DHCPCD_CONFIG **conf, bool s, const char *opt, const char *val,
+set_option(DHCPCD_OPTION **conf, bool s, const char *opt, const char *val,
bool *ret)
{
- bool r;
- if (s)
- r = dhcpcd_config_set_static(conf, opt, val);
- else
- r = dhcpcd_config_set(conf, opt, val);
- if (r)
- return true;
- g_error("libdhcpcd: %s", strerror(errno));
+ if (s) {
+ if (!dhcpcd_config_set_static(conf, opt, val))
+ g_critical("dhcpcd_config_set_static: %s",
+ strerror(errno));
+ else
+ return true;
+ } else {
+ if (!dhcpcd_config_set(conf, opt, val))
+ g_critical("dhcpcd_config_set: %s",
+ strerror(errno));
+ else
+ return true;
+ }
+
if (ret)
*ret = false;
return false;
}
static bool
-make_config(DHCPCD_CONFIG **conf)
+make_config(DHCPCD_OPTION **conf)
{
const char *val, ns[] = "";
bool a, ret;
set_option(conf, false, "inform", a ? val : NULL, &ret);
set_option(conf, true, "ip_address=", a ? NULL : val, &ret);
}
-
+
val = gtk_entry_get_text(GTK_ENTRY(router));
if (a && *val == '\0')
val = NULL;
set_option(conf, true, "routers=", val, &ret);
-
+
val = gtk_entry_get_text(GTK_ENTRY(dns_servers));
if (a && *val == '\0')
val = NULL;
set_option(conf, true, "domain_name_servers=", val, &ret);
-
+
val = gtk_entry_get_text(GTK_ENTRY(dns_search));
if (a && *val == '\0')
val = NULL;
set_option(conf, true, "domain_search=", val, &ret);
-
+
return ret;
}
+static bool
+write_config(DHCPCD_CONNECTION *con, DHCPCD_OPTION **conf)
+{
+
+ if (make_config(conf) &&
+ !dhcpcd_config_write(con, block, name, *conf))
+ {
+ const char *s;
+
+ s = strerror(errno);
+ g_warning("dhcpcd_config_write: %s", s);
+ config_err_dialog(con, true, s);
+ return false;
+ }
+ return true;
+}
+
static GdkPixbuf *
load_icon(const char *iname)
{
list = NULL;
for (i = dhcpcd_interfaces(con); i; i = i->next)
- list = g_slist_append(list, i->ifname);
+ if (strcmp(i->type, "ipv4") == 0)
+ list = g_slist_append(list, UNCONST(i->ifname));
return list;
}
static GSList *
-list_ssids(WI_SCAN *scans)
+list_ssids(WI_SCANS *scans)
{
GSList *list, *l;
WI_SCAN *w;
DHCPCD_WI_SCAN *wis;
list = NULL;
- for (w = scans; w; w = w->next) {
+ TAILQ_FOREACH(w, scans, next) {
for (wis = w->scans; wis; wis = wis->next) {
for (l = list; l; l = l->next)
if (g_strcmp0((const char *)l->data,
char **list, **lp;
const char *iname, *nn;
GSList *l, *new_names;
- GtkIconTheme *it;
GdkPixbuf *pb;
int n;
con = (DHCPCD_CONNECTION *)data;
if (name) {
- if (make_config(&config))
- dhcpcd_config_save(con, block, name, config);
+ write_config(con, &config);
dhcpcd_config_free(config);
config = NULL;
show_config(config);
block = combo_active_text(widget);
store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(names)));
gtk_list_store_clear(store);
- list = dhcpcd_config_blocks_get(con, block);
-
- it = gtk_icon_theme_get_default();
+ list = dhcpcd_config_blocks(con, block);
+
if (g_strcmp0(block, "interface") == 0)
new_names = list_interfaces(con);
else
- new_names = list_ssids(wi_scans);
+ new_names = list_ssids(&wi_scans);
n = 0;
for (l = new_names; l; l = l->next) {
nn = (const char *)l->data;
- for (lp = list; *lp; lp++)
- if (g_strcmp0(nn, *lp) == 0)
- break;
- if (*lp)
- iname = "document-save";
- else
+ if (list) {
+ for (lp = list; *lp; lp++)
+ if (g_strcmp0(nn, *lp) == 0)
+ break;
+ if (*lp)
+ iname = "document-save";
+ else
+ iname = "document-new";
+ } else
iname = "document-new";
pb = load_icon(iname);
gtk_list_store_append(store, &iter);
n++;
}
- for (lp = list; *lp; lp++) {
+ for (lp = list; lp && *lp; lp++) {
for (l = new_names; l; l = l->next)
if (g_strcmp0((const char *)l->data, *lp) == 0)
break;
con = (DHCPCD_CONNECTION *)data;
if (name) {
- if (make_config(&config))
- dhcpcd_config_save(con, block, name, config);
+ write_config(con, &config);
g_free(name);
}
name = combo_active_text(names);
gtk_widget_set_sensitive(address,
iface && (iface->flags & IFF_POINTOPOINT) == 0);
if (block && name) {
- config = dhcpcd_config_load(con, block, name);
- if (config == NULL && dhcpcd_error(con))
- g_error("libdhcpcd: %s\n", dhcpcd_error(con));
+ errno = 0;
+ config = dhcpcd_config_read(con, block, name);
+ if (config == NULL && errno) {
+ const char *s;
+
+ s = strerror(errno);
+ g_warning("dhcpcd_config_read: %s", s);
+ config_err_dialog(con, false, s);
+ }
} else
config = NULL;
show_config(config);
}
}
retval = inet_aton(addr, &in) == 0 ? false : true;
-
+
out:
g_free(addr);
return retval;
}
-
static bool
address_lost_focus(GtkEntry *entry)
{
}
static void
-on_clear(_unused GtkObject *o, gpointer data)
+on_clear(_unused GtkWidget *o, gpointer data)
{
DHCPCD_CONNECTION *con;
con = (DHCPCD_CONNECTION *)data;
dhcpcd_config_free(config);
config = NULL;
- if (dhcpcd_config_save(con, block, name, config)) {
+ if (dhcpcd_config_write(con, block, name, config)) {
set_name_active_icon("document-new");
show_config(config);
- }
+ } else
+ g_critical("dhcpcd_config_write: %s", strerror(errno));
}
static void
-on_rebind(_unused GtkWidget *widget, gpointer data)
+on_rebind(_unused GObject *widget, gpointer data)
{
DHCPCD_CONNECTION *con;
DHCPCD_IF *i;
con = (DHCPCD_CONNECTION *)data;
- if (make_config(&config) &&
- dhcpcd_config_save(con, block, name, config)) {
+ if (write_config(con, &config)) {
set_name_active_icon(config == NULL ?
"document-new" : "document-save");
show_config(config);
- if (g_strcmp0(block, "interface") == 0)
- dhcpcd_rebind(con, iface);
- else {
+ if (g_strcmp0(block, "interface") == 0) {
+ if (dhcpcd_rebind(con, iface->ifname) == -1)
+ g_critical("dhcpcd_rebind %s: %s",
+ iface->ifname, strerror(errno));
+ } else {
for (i = dhcpcd_interfaces(con); i; i = i->next) {
- if (g_strcmp0(i->ssid, name) == 0)
- dhcpcd_rebind(con, i);
+ if (g_strcmp0(i->ssid, name) == 0) {
+ if (dhcpcd_rebind(con, i->ifname) == -1)
+ g_critical(
+ "dhcpcd_rebind %s: %s",
+ i->ifname,
+ strerror(errno));
+ }
}
}
- if (dhcpcd_error(con))
- g_warning("libdhcpcd: %s", dhcpcd_error(con));
}
}
static void
-on_destroy(_unused GtkObject *o, gpointer data)
+on_destroy(_unused GObject *o, gpointer data)
{
+
if (name != NULL) {
- if (make_config(&config))
- dhcpcd_config_save((DHCPCD_CONNECTION *)data,
- block, name, config);
+ write_config((DHCPCD_CONNECTION *)data, &config);
g_free(block);
g_free(name);
block = name = NULL;
}
static void
-dhcpcd_prefs_close(void)
+prefs_close(void)
{
if (dialog != NULL) {
gtk_widget_destroy(dialog);
}
void
-dhcpcd_prefs_abort(void)
+prefs_abort(void)
{
g_free(name);
name = NULL;
- dhcpcd_prefs_close();
+ prefs_close();
}
+#if GTK_MAJOR_VERSION == 2
+static GtkWidget *
+gtk_separator_new(GtkOrientation o)
+{
+
+ if (o == GTK_ORIENTATION_HORIZONTAL)
+ return gtk_hseparator_new();
+ else
+ return gtk_vseparator_new();
+}
+#endif
+
void
-dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
+prefs_show(DHCPCD_CONNECTION *con)
{
GtkWidget *dialog_vbox, *hbox, *vbox, *table, *w;
GtkListStore *store;
GtkTreeIter iter;
GtkCellRenderer *rend;
GdkPixbuf *pb;
-
+
if (dialog) {
gtk_window_present(GTK_WINDOW(dialog));
return;
gtk_window_set_type_hint(GTK_WINDOW(dialog),
GDK_WINDOW_TYPE_HINT_DIALOG);
- dialog_vbox = gtk_vbox_new(false, 10);
+ dialog_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_container_set_border_width(GTK_CONTAINER(dialog), 10);
gtk_container_add(GTK_CONTAINER(dialog), dialog_vbox);
- hbox = gtk_hbox_new(false, 0);
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(GTK_BOX(dialog_vbox), hbox, false, false, 3);
w = gtk_label_new("Configure:");
gtk_box_pack_start(GTK_BOX(hbox), w, false, false, 3);
G_CALLBACK(blocks_on_change), con);
g_signal_connect(G_OBJECT(names), "changed",
G_CALLBACK(names_on_change), con);
-
- w = gtk_hseparator_new();
+
+ w = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start(GTK_BOX(dialog_vbox), w, true, false, 3);
- controls = gtk_vbox_new(false, 10);
+ controls = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_widget_set_sensitive(controls, false);
gtk_box_pack_start(GTK_BOX(dialog_vbox), controls, true, true, 0);
- vbox = gtk_vbox_new(false, 3);
+ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
gtk_box_pack_start(GTK_BOX(controls), vbox, false, false, 0);
autoconf = gtk_check_button_new_with_label(
_("Automatically configure empty options"));
#define attach_entry(a, b, c, d, e) \
gtk_table_attach(GTK_TABLE(table), a, b, c, d, e, \
GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 3, 3);
-
+
w = gtk_label_new(_("IP Address:"));
address = gtk_entry_new();
- gtk_entry_set_max_length(GTK_ENTRY(address), 15);
+ gtk_entry_set_max_length(GTK_ENTRY(address), 18);
g_signal_connect(G_OBJECT(address), "focus-out-event",
G_CALLBACK(address_lost_focus), NULL);
attach_label(w, 0, 1, 0, 1);
w = gtk_label_new(_("Router:"));
router = gtk_entry_new();
- gtk_entry_set_max_length(GTK_ENTRY(router), 12);
+ gtk_entry_set_max_length(GTK_ENTRY(router), 15);
g_signal_connect(G_OBJECT(router), "focus-out-event",
G_CALLBACK(entry_lost_focus), NULL);
attach_label(w, 0, 1, 2, 3);
attach_label(w, 0, 1, 4, 5);
attach_entry(dns_search, 1, 2, 4, 5);
- hbox = gtk_hbox_new(false, 10);
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_pack_start(GTK_BOX(dialog_vbox), hbox, true, true, 3);
clear = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
gtk_widget_set_sensitive(clear, false);
gtk_box_pack_start(GTK_BOX(hbox), clear, false, false, 0);
g_signal_connect(G_OBJECT(clear), "clicked",
- G_CALLBACK(on_clear), NULL);
+ G_CALLBACK(on_clear), con);
rebind = gtk_button_new_with_mnemonic(_("_Rebind"));
gtk_widget_set_sensitive(rebind, false);
w = gtk_image_new_from_stock(GTK_STOCK_EXECUTE,
w = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
gtk_box_pack_end(GTK_BOX(hbox), w, false, false, 0);
g_signal_connect(G_OBJECT(w), "clicked",
- G_CALLBACK(dhcpcd_prefs_close), NULL);
-
+ G_CALLBACK(prefs_close), NULL);
+
blocks_on_change(blocks, con);
show_config(NULL);
gtk_widget_show_all(dialog);