Remove dbus-glib dependency and create libdhcpcd.
authorRoy Marples <roy@marples.name>
Wed, 15 Apr 2009 15:46:14 +0000 (15:46 +0000)
committerRoy Marples <roy@marples.name>
Wed, 15 Apr 2009 15:46:14 +0000 (15:46 +0000)
This allows us to easily create GUI front ends from this without having
to worry about toolkit specific DBus bindings.

This project will now become dhcpcd-ui :)

29 files changed:
Makefile
README [new file with mode: 0644]
mk/debug.mk [new file with mode: 0644]
mk/dist.mk
mk/lib.mk [new file with mode: 0644]
mk/sys.mk
src/config.h [deleted file]
src/dhcpcd-config.c [deleted file]
src/dhcpcd-config.h [deleted file]
src/dhcpcd-gtk/Makefile [moved from src/Makefile with 72% similarity]
src/dhcpcd-gtk/dhcpcd-gtk.desktop [moved from src/dhcpcd-gtk.desktop with 100% similarity]
src/dhcpcd-gtk/dhcpcd-gtk.h [moved from src/dhcpcd-gtk.h with 68% similarity]
src/dhcpcd-gtk/main.c [new file with mode: 0644]
src/dhcpcd-gtk/menu.c [moved from src/menu.c with 72% similarity]
src/dhcpcd-gtk/prefs.c [moved from src/prefs.c with 75% similarity]
src/dhcpcd-gtk/wpa.c [new file with mode: 0644]
src/libdhcpcd/Makefile [new file with mode: 0644]
src/libdhcpcd/Makefile.inc [new file with mode: 0644]
src/libdhcpcd/config.c [new file with mode: 0644]
src/libdhcpcd/dispatch.c [new file with mode: 0644]
src/libdhcpcd/libdhcpcd.h [new file with mode: 0644]
src/libdhcpcd/main.c [new file with mode: 0644]
src/libdhcpcd/misc.c [new file with mode: 0644]
src/libdhcpcd/wpa.c [new file with mode: 0644]
src/main.c [deleted file]
src/menu.h [deleted file]
src/prefs.h [deleted file]
src/wpa.c [deleted file]
src/wpa.h [deleted file]

index 1767e6a3b9bf26f0ecba0dc720b217551fed0dce..70f12beeee546f172b22452e2db5a5876dcce7f8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
-PROG=          dhcpcd-gtk
+PROG=          dhcpcd-ui
+VERSION=       0.4.0
 
-SUBDIR=        src icons
+SUBDIR=                src icons
 
 MK=    mk
 include ${MK}/subdir.mk
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9cbf9e6
--- /dev/null
+++ b/README
@@ -0,0 +1,8 @@
+dhcpcd-ui is the graphical interface to dhcpcd
+
+It has a helper library in C so you don't *have* to learn each toolkit
+DBus implementation, or depend on it (dbus-glib, edbus, qt-dbus, etc).
+
+Currently only a GTK+ front end is available, but there are plans to
+create an EWL (Enlightment E17) front end.
+I don't use KDE/QT much, but it should be quite easy.
diff --git a/mk/debug.mk b/mk/debug.mk
new file mode 100644 (file)
index 0000000..4008efa
--- /dev/null
@@ -0,0 +1,16 @@
+# rules to enable debugging support
+# Copyright 2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+_RC_DEBUG_SH=  case "${DEBUG}" in "") echo "";; *) echo "-DRC_DEBUG";; esac
+_RC_DEBUG!=    ${_RC_DEBUG_SH}
+CPPFLAGS+=     ${_RC_DEBUG}$(shell ${_RC_DEBUG_SH})
+
+# Should we enable this with a different flag?
+_LD_DEBUG_SH=  case "${DEBUG}" in "") echo "";; *) echo "-Wl,--rpath=../librc -Wl,--rpath=../libeinfo";; esac
+_LD_DEBUG!=    ${_LD_DEBUG_SH}
+LDFLAGS+=      ${_LD_DEBUG}$(shell ${_LD_DEBUG_SH})
+
+_GGDB_SH=      case "${DEBUG}" in "") echo "";; *) echo "-ggdb";; esac
+_GGDB!=                ${_GGDB_SH}
+CFLAGS+=       ${_GGDB}$(shell ${_GGDB_SH})
index a2b933ebcc0e939a980ffe9cfaf7df6c026f44ec..b45436ecf1a3a355130eeed7e0c0ed58e2820e27 100644 (file)
@@ -7,10 +7,6 @@ DISTFILE?=     ${DISTPREFIX}.tar.bz2
 
 CLEANFILES+=   *.tar.bz2
 
-_VERSION_SH=   sed -n 's/\#define VERSION[[:space:]]*"\(.*\)".*/\1/p' src/config.h
-_VERSION!=     ${_VERSION_SH}
-VERSION=       ${_VERSION}$(shell ${_VERSION_SH})
-
 _SNAP_SH=      date -u +%Y%m%d%H%M
 _SNAP!=                ${_SNAP_SH}
 SNAP=          ${_SNAP}$(shell ${_SNAP_SH})
diff --git a/mk/lib.mk b/mk/lib.mk
new file mode 100644 (file)
index 0000000..707cfe6
--- /dev/null
+++ b/mk/lib.mk
@@ -0,0 +1,58 @@
+# rules to build a library
+
+SHLIB=                 lib${LIB}.so.${SHLIB_MAJOR}
+SHLIB_LINK=            lib${LIB}.so
+LIBNAME=               lib${LIB}.a
+SONAME?=               ${SHLIB}
+
+OBJS+=                 ${SRCS:.c=.o}
+SOBJS+=                        ${OBJS:.o=.So}
+LIBS?=                 ${LIBNAME} ${SHLIB}
+
+CLEANFILES+=           ${OBJS} ${SOBJS} ${LIBS} ${SHLIB_LINK}
+
+LIBINSTALL?=           _libinstall
+
+.SUFFIXES:             .So
+
+.c.o:
+       ${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@
+
+.c.So:
+       ${CC} ${PICFLAG} -DPIC ${CPPFLAGS} ${CFLAGS} -c $< -o $@
+
+all: depend ${LIBS}
+
+${LIBNAME}:    ${OBJS} ${STATICOBJS}
+       @${ECHO} building static library $@
+       ${AR} cr $@ ${STATICOBJS} ${OBJS}
+       ${RANLIB} $@
+
+${SHLIB}:      ${SOBJS}
+       @${ECHO} building shared library $@
+       @rm -f $@ ${SHLIB_LINK}
+       @ln -fs $@ ${SHLIB_LINK}
+       ${CC} ${LDFLAGS} -shared -Wl,-x -o $@ -Wl,-soname,${SONAME} \
+               ${SOBJS} ${LDADD}
+
+_libinstall:   all
+       ${INSTALL} -d ${DESTDIR}${LIBDIR}
+       ${INSTALL} -m ${LIBMODE} ${LIB} ${DESTDIR}${LIBDIR}
+       ${INSTALL} -d ${DESTDIR}${SHLIBDIR}
+       ${INSTALL} -m ${LIBMODE} ${SHLIB} ${DESTDIR}${SHLIBDIR}
+       ln -fs ${SHLIB} ${DESTDIR}${SHLIBDIR}/${SHLIB_LINK}
+       ${INSTALL} -d ${DESTDIR}${INCDIR}
+       for x in ${INCS}; do ${INSTALL} -m ${INCMODE} $$x ${DESTDIR}${INCDIR}; done
+
+install: ${LIBINSTALL}
+
+clean:
+       rm -f ${OBJS} ${SOBJS} ${LIBS} ${SHLIB_LINK} ${CLEANFILES}
+
+extra_depend:
+       @TMP=depend.$$$$; \
+       ${SED} -e 's/^\([^\.]*\).o[ ]*:/\1.o \1.So:/' .depend > $${TMP}; \
+       mv $${TMP} .depend
+
+include ${MK}/sys.mk
+include ${MK}/depend.mk
index 441a4d22ab59d5eddfed455de22058e5bc00ecf3..b6605121404f6c12fead4c867b6a955a8af55b41 100644 (file)
--- a/mk/sys.mk
+++ b/mk/sys.mk
@@ -8,7 +8,10 @@ NONBINMODE?=   0644
 
 SYSCONFDIR?=   ${PREFIX}/etc
 
+AR?=           ar
+ECHO?=         echo
 INSTALL?=      install
+RANLIB?=       ranlib
 SED?=          sed
 
 _LIBNAME_SH=           case `readlink /lib` in "") echo "lib";; *) basename `readlink /lib`;; esac
diff --git a/src/config.h b/src/config.h
deleted file mode 100644 (file)
index 51c7d46..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#define PACKAGE                        "dhcpcd-gtk"
-#define VERSION                        "0.3.0"
-
-#define DHCPCD_SERVICE         "name.marples.roy.dhcpcd"
-#define DHCPCD_PATH            "/name/marples/roy/dhcpcd"
-
-#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
-# define _unused   __attribute__((__unused__))
-#else
-# define _unused
-#endif
-
-#endif
diff --git a/src/dhcpcd-config.c b/src/dhcpcd-config.c
deleted file mode 100644 (file)
index 19934fe..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "dhcpcd-config.h"
-#include "dhcpcd-gtk.h"
-
-void
-free_config(GPtrArray **config)
-{
-       unsigned int i;
-
-       if (config == NULL || *config == NULL)
-               return;
-       for (i = 0; i < (*config)->len; i++)
-               g_value_array_free(g_ptr_array_index(*config, i));
-       g_ptr_array_free(*config, TRUE);
-       *config = NULL;
-}      
-
-GPtrArray *
-load_config(const char *block, const char *name)
-{
-       GType otype;
-       GError *error;
-       GPtrArray *config;
-
-       error = NULL;
-       otype = dbus_g_type_get_struct("GValueArray",
-           G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-       otype = dbus_g_type_get_collection("GPtrArray", otype);
-       if (!dbus_g_proxy_call(dbus, "GetConfig", &error,
-               G_TYPE_STRING, block, G_TYPE_STRING, name, G_TYPE_INVALID,
-               otype, &config, G_TYPE_INVALID))
-       {
-               g_critical("GetConfig: %s", error->message);
-               g_clear_error(&error);
-               return NULL;
-       }
-       return config;
-}
-
-static int
-_get_config(GPtrArray *config, int idx, const char *opt, const char **value)
-{
-       GValueArray *c;
-       GValue *val;
-       const char *str;
-
-       if (config == NULL)
-               return -1;
-       for (; (uint)idx < config->len; idx++) {
-               c = g_ptr_array_index(config, idx);
-               val = g_value_array_get_nth(c, 0);
-               str = g_value_get_string(val);
-               if (strcmp(str, opt) != 0)
-                       continue;
-               if (value != NULL) {
-                       val = g_value_array_get_nth(c, 1);
-                       str = g_value_get_string(val);
-                       if (*str == '\0')
-                               *value = NULL;
-                       else
-                               *value = str;
-               }
-               return idx;
-       }
-       if (value != NULL)
-               *value = NULL;
-       return -1;
-}
-
-int
-get_config(GPtrArray *config, const char *opt, const char **value)
-{
-
-       return _get_config(config, 0, opt, value);
-}
-
-int
-get_config_static(GPtrArray *config, const char *var, const char **value)
-{
-       int idx;
-       const char *val;
-
-       idx = -1;
-       while ((idx = _get_config(config, idx + 1, "static", &val)) != -1) {
-               if (g_str_has_prefix(val, var)) {
-                       if (value)
-                               *value = val + strlen(var);
-                       return idx;
-               }
-       }
-       if (value)
-               *value = NULL;
-       return -1;
-}
-
-void
-set_option(GPtrArray *config, bool sopt, const char *var, const char *val)
-{
-       int i;
-       GValueArray *va;
-       GValue nv, *v;
-       char *n;
-
-       if (sopt)
-               i = get_config_static(config, var, NULL);
-       else
-               i = get_config(config, var, NULL);
-       if (val == NULL) {
-               if (i != -1) {
-                       va = g_ptr_array_remove_index(config, i);
-                       g_value_array_free(va);
-               }
-       } else {
-               if (sopt)
-                       n = g_strconcat(var, val, NULL);
-               else
-                       n = NULL;
-               memset(&nv, 0, sizeof(v));
-               g_value_init(&nv, G_TYPE_STRING);
-               if (i == -1) {
-                       va = g_value_array_new(2);
-                       g_ptr_array_add(config, va);
-                       g_value_set_static_string(&nv, sopt ? "static" : var);
-                       va = g_value_array_append(va, &nv);
-               } else {
-                       va = g_ptr_array_index(config, i);
-                       va = g_value_array_remove(va, 1);
-               }
-               g_value_set_static_string(&nv, sopt ? n : val);
-               va = g_value_array_append(va, &nv);
-               g_free(n);
-       }
-}
-
-bool
-save_config(const char *block, const char *name, GPtrArray *config)
-{
-       GError *error;
-       GType otype;
-       
-       error = NULL;
-       otype = dbus_g_type_get_struct("GValueArray",
-           G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-       otype = dbus_g_type_get_collection("GPtrArray", otype);
-       if (!dbus_g_proxy_call(dbus, "SetConfig", &error,
-               G_TYPE_STRING, block,
-               G_TYPE_STRING, name,
-               otype, config,
-               G_TYPE_INVALID,
-               G_TYPE_INVALID))
-       {
-               g_critical("SetConfig: %s", error->message);
-               g_clear_error(&error);
-               return false;
-       }
-       return true;
-}
diff --git a/src/dhcpcd-config.h b/src/dhcpcd-config.h
deleted file mode 100644 (file)
index f0bc293..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef DHCPCD_CONFIG_H
-#define DHCPCD_CONFIG_H
-
-#include <stdbool.h>
-
-#include <glib.h>
-
-void free_config(GPtrArray **);
-GPtrArray *load_config(const char *, const char *);
-int get_config(GPtrArray *, const char *, const char **);
-int get_config_static(GPtrArray *, const char *, const char **);
-void set_option(GPtrArray *, bool, const char *, const char *);
-bool save_config(const char *, const char *, GPtrArray *);
-
-#endif
similarity index 72%
rename from src/Makefile
rename to src/dhcpcd-gtk/Makefile
index 9555ffabbbb978e9c51613018f0537f54f4e10dd..55781dd38f6e860e72434292b475f89884c4a0a0 100644 (file)
@@ -3,25 +3,28 @@
 # Copyright 2008 Roy Marples <roy@marples.name>
 
 PROG=          dhcpcd-gtk
-SRCS=          main.c menu.c dhcpcd-config.c prefs.c wpa.c
+SRCS=          main.c menu.c prefs.c wpa.c
 
 ICONDIR?=      ${PREFIX}/share/dhcpcd/icons
 SYSCONFDIR?=   ${PREFIX}/etc/xdg/autostart
 FILESDIR?=     ${SYSCONFDIR}
 FILES=         dhcpcd-gtk.desktop
 
+include ../libdhcpcd/Makefile.inc
+
 CPPFLAGS+=     -DICONDIR=\"${ICONDIR}\"
+CPPFLAGS+=     -DNOTIFY
 
-_PKGCFLAGS_SH= pkg-config --cflags dbus-glib-1 gtk+-2.0 libnotify
+_PKGCFLAGS_SH= pkg-config --cflags gtk+-2.0 libnotify
 _PKGCFLAGS!=   ${_PKGCFLAGS_SH}
 PKGCFLAGS?=    ${_PKGCFLAGS}$(shell ${_PKGCFLAGS_SH})
 CFLAGS+=       ${PKGCFLAGS}
 
-_PKGLIBS_SH=   pkg-config --libs dbus-glib-1 gtk+-2.0 libnotify
+_PKGLIBS_SH=   pkg-config --libs gtk+-2.0 libnotify
 _PKGLIBS!=     ${_PKGLIBS_SH}
 PKGLIBS?=      ${_PKGLIBS}$(shell ${_PKGLIBS_SH})
 LDADD+=                ${PKGLIBS}
 
-MK=            ../mk
+MK=            ../../mk
 include ${MK}/sys.mk
 include ${MK}/prog.mk
similarity index 68%
rename from src/dhcpcd-gtk.h
rename to src/dhcpcd-gtk/dhcpcd-gtk.h
index 911503ee7dcabeb27a26affb55bad42d308eeb15..2f8fcad554f23af9dc129d51fe7a5d77146f9747 100644 (file)
 
 #include <stdbool.h>
 
-#include <dbus/dbus-glib.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <libintl.h>
 
-#include "config.h"
+#include "libdhcpcd.h"
+
+#define PACKAGE "dhcpcd-gtk"
+#define VERSION "0.4.0"
 
 /* Work out if we have a private address or not
  * 10/8
  * 192.168/16
  */
 #ifndef IN_PRIVATE
-# define IN_PRIVATE(addr) (((addr & IN_CLASSA_NET) == 0x0a000000) || \
-                          ((addr & 0xfff00000)    == 0xac100000) || \
-                          ((addr & IN_CLASSB_NET) == 0xc0a80000))
+#  define IN_PRIVATE(addr) (((addr & IN_CLASSA_NET) == 0x0a000000) ||        \
+           ((addr & 0xfff00000)    == 0xac100000) ||                         \
+           ((addr & IN_CLASSB_NET) == 0xc0a80000))
 #endif
 #ifndef IN_LINKLOCAL
-# define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == 0xa9fe0000)
+#  define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == 0xa9fe0000)
 #endif
 
 #define UNCONST(a)              ((void *)(unsigned long)(const void *)(a))
 
-struct if_ap {
-       char *ifname;
-       char *bssid;
-       int frequency;
-       int quality;
-       int noise;
-       int level;
-       char *flags;
-       char *ssid;
-};
-
-struct if_msg {
-       char *ifname;
-       unsigned int flags;
-       char *reason;
-       struct in_addr ip;
-       unsigned char cidr;
-       bool wireless;
-       char *ssid;
-       GSList *scan_results;
-};
-
-extern DBusGProxy *dbus;
-extern GSList *interfaces;
-extern GtkIconTheme *icontheme;
+#ifdef __GNUC__
+#  define _unused __attribute__((__unused__))
+#else
+#  define _unused
+#endif
+
+typedef struct wi_scan {
+       DHCPCD_CONNECTION *connection;
+       DHCPCD_IF *interface;
+       DHCPCD_WI_SCAN *scans;
+       struct wi_scan *next;
+} WI_SCAN;
+
+extern WI_SCAN *wi_scans;
+
+WI_SCAN * wi_scan_find(DHCPCD_WI_SCAN *);
+
+void menu_init(GtkStatusIcon *, DHCPCD_CONNECTION *);
 
 void notify_close(void);
+
+void dhcpcd_prefs_show(DHCPCD_CONNECTION *con);
+void dhcpcd_prefs_abort(void);
+
+bool wpa_configure(DHCPCD_CONNECTION *, DHCPCD_IF *, DHCPCD_WI_SCAN *);
 #endif
diff --git a/src/dhcpcd-gtk/main.c b/src/dhcpcd-gtk/main.c
new file mode 100644 (file)
index 0000000..b4cf28f
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * dhcpcd-gtk
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <locale.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef NOTIFY
+#  include <libnotify/notify.h>
+static NotifyNotification *nn;
+#endif
+
+#include "dhcpcd-gtk.h"
+
+static GtkStatusIcon *status_icon;
+static int ani_timer;
+static int ani_counter;
+static bool online;
+static bool carrier;
+
+struct watch {
+       struct pollfd pollfd;
+       int eventid;
+       GIOChannel *gio;
+       struct watch *next;
+};
+static struct watch *watches;
+
+WI_SCAN *wi_scans;
+
+WI_SCAN *
+wi_scan_find(DHCPCD_WI_SCAN *scan)
+{
+       WI_SCAN *w;
+       DHCPCD_WI_SCAN *dw;
+
+       for (w = wi_scans; w; w = w->next) {
+               for (dw = w->scans; dw; dw = dw->next)
+                       if (dw == scan)
+                               break;
+               if (dw)
+                       return w;
+       }
+       return NULL;
+}
+
+static gboolean
+animate_carrier(_unused gpointer data)
+{
+       const char *icon;
+       
+       if (ani_timer == 0)
+               return false;
+
+       switch(ani_counter++) {
+       case 0:
+               icon = "network-transmit";
+               break;
+       case 1:
+               icon = "network-receive";
+               break;
+       default:
+               icon = "network-idle";
+               ani_counter = 0;
+               break;
+       }
+       gtk_status_icon_set_from_icon_name(status_icon, icon);
+       return true;
+}
+
+static gboolean
+animate_online(_unused gpointer data)
+{
+       const char *icon;
+       
+       if (ani_timer == 0)
+               return false;
+
+       if (ani_counter++ > 6) {
+               ani_timer = 0;
+               ani_counter = 0;
+               return false;
+       }
+
+       if (ani_counter % 2 == 0)
+               icon = "network-idle";
+       else
+               icon = "network-transmit-receive";
+       gtk_status_icon_set_from_icon_name(status_icon, icon);
+       return true;
+}
+
+static void
+update_online(DHCPCD_CONNECTION *con, bool showif)
+{
+       bool ison, iscarrier;
+       char *msg, *msgs, *tmp;
+       DHCPCD_IF *ifs, *i;
+
+       ison = iscarrier = false;
+       msgs = NULL;
+       ifs = dhcpcd_interfaces(con);
+       for (i = ifs; i; i = i->next) {
+               if (showif)
+                       g_message("%s: %s", i->ifname, i->reason);
+               if (strcmp(i->reason, "RELEASE") == 0 ||
+                   strcmp(i->reason, "STOP") == 0)
+                       continue;
+               if (dhcpcd_if_up(i))
+                       ison = iscarrier = true;
+               if (!iscarrier && g_strcmp0(i->reason, "CARRIER") == 0)
+                       iscarrier = true;
+               msg = dhcpcd_if_message(i);
+               if (msgs) {
+                       tmp = g_strconcat(msgs, "\n", msg, NULL);
+                       g_free(msgs);
+                       g_free(msg);
+                       msgs = tmp;
+               } else
+                       msgs = msg;
+       }
+
+       if (online != ison || carrier != iscarrier) {
+               online = ison;
+               if (ani_timer != 0) {
+                       g_source_remove(ani_timer);
+                       ani_timer = 0;
+                       ani_counter = 0;
+               }
+               if (ison) {
+                       animate_online(NULL);
+                       ani_timer = g_timeout_add(300, animate_online, NULL);
+               } else if (iscarrier) {
+                       animate_carrier(NULL);
+                       ani_timer = g_timeout_add(500, animate_carrier, NULL);
+               } else {
+                       gtk_status_icon_set_from_icon_name(status_icon,
+                           "network-offline");
+               }
+       }
+       gtk_status_icon_set_tooltip(status_icon, msgs);
+       g_free(msgs);
+}
+
+void
+notify_close(void)
+{
+#ifdef NOTIFY
+       if (nn != NULL)
+               notify_notification_close(nn, NULL);
+#endif
+}
+
+static void
+notify_closed(void)
+{
+#ifdef NOTIFY
+       nn = NULL;
+#endif
+}
+
+#ifdef NOTIFY
+static void
+notify(const char *title, const char *msg, const char *icon)
+{
+       char **msgs, **m;
+
+       msgs = g_strsplit(msg, "\n", 0);
+       for (m = msgs; *m; m++)
+               g_message("%s", *m);
+       g_strfreev(msgs);
+       if (nn != NULL)
+               notify_notification_close(nn, NULL);
+       if (gtk_status_icon_get_visible(status_icon))
+               nn = notify_notification_new_with_status_icon(title,
+                   msg, icon, status_icon);
+       else
+               nn = notify_notification_new(title, msg, icon, NULL);
+       notify_notification_set_timeout(nn, 5000);
+       g_signal_connect(nn, "closed", G_CALLBACK(notify_closed), NULL);
+       notify_notification_show(nn, NULL);
+}
+#else
+#  define notify(a, b, c)
+#endif
+
+static void
+event_cb(DHCPCD_CONNECTION *con, DHCPCD_IF *i, _unused void *data)
+{
+       char *msg;
+       const char *icon;
+
+       g_message("%s: %s", i->ifname, i->reason);
+       update_online(con, false);
+       
+       /* We should ignore renew and stop so we don't annoy the user */
+       if (g_strcmp0(i->reason, "RENEW") == 0 ||
+           g_strcmp0(i->reason, "STOP") == 0)
+               return;
+
+       msg = dhcpcd_if_message(i);
+       if (dhcpcd_if_up(i))
+               icon = "network-transmit-receive";
+       else
+               icon = "network-transmit";
+       if (dhcpcd_if_down(i))
+               icon = "network-offline";
+       notify(_("Network event"), msg, icon);
+       g_free(msg);
+}
+
+static void
+status_cb(DHCPCD_CONNECTION *con, const char *status, _unused void *data)
+{
+       static char *last = NULL;
+       char *version;
+       const char *msg;
+       bool refresh;
+       WI_SCAN *w;
+
+       g_message("Status changed to %s", status);
+       if (g_strcmp0(status, "down") == 0) {
+               msg = N_(last ?
+                   "Connection to dhcpcd lost" : "dhcpcd not running");
+               gtk_status_icon_set_tooltip(status_icon, msg);
+               notify(_("No network"), msg, "network-offline");
+               dhcpcd_prefs_abort();
+               while (wi_scans) {
+                       w = wi_scans->next;
+                       dhcpcd_wi_scans_free(w->scans);
+                       free(wi_scans);
+                       wi_scans = w;
+               }
+       } else {
+               if ((last == NULL || g_strcmp0(last, "down") == 0) &&
+                   dhcpcd_command(con, "GetDhcpcdVersion", NULL, &version))
+               {
+                       g_message(_("Connected to %s-%s"), "dhcpcd", version);
+                       g_free(version);
+                       refresh = true;
+               } else
+                       refresh = false;
+               update_online(con, refresh);
+       }
+       last = g_strdup(status);
+}
+
+static void
+scan_cb(DHCPCD_CONNECTION *con, DHCPCD_IF *i, _unused void *data)
+{
+       WI_SCAN *w;
+       DHCPCD_WI_SCAN *scans, *s1, *s2;
+       char *txt, *t;
+       const char *msg;
+
+       g_message(_("%s: Received scan results"), i->ifname);
+       scans = dhcpcd_wi_scans(con, i);
+       for (w = wi_scans; w; w = w->next)
+               if (w->connection == con && w->interface == i)
+                       break;
+       if (w == NULL) {
+               w = g_malloc(sizeof(*w));
+               w->connection = con;
+               w->interface = i;
+               w->next = wi_scans;
+               wi_scans = w;
+       } else {
+               txt = NULL;
+               msg = N_("New Access Point");
+               for (s1 = scans; s1; s1 = s1->next) {
+                       for (s2 = w->scans; s2; s2 = s2->next)
+                               if (g_strcmp0(s1->ssid, s2->ssid) == 0)
+                                       break;
+                       if (s2 == NULL) {
+                               if (txt == NULL)
+                                       txt = g_strdup(s1->ssid);
+                               else {
+                                       msg = N_("New Access Points");
+                                       t = g_strconcat(txt, "\n",
+                                           s1->ssid, NULL);
+                                       g_free(txt);
+                                       txt = t;
+                               }
+                       }
+               }
+               if (txt) {
+                       notify(msg, txt, "network-wireless");
+                       g_free(txt);
+               }
+               g_free(w->scans);
+       }
+       w->scans = scans;
+}
+
+static gboolean
+gio_callback(GIOChannel *gio, _unused GIOCondition c, _unused gpointer d)
+{
+       int fd;
+
+       fd = g_io_channel_unix_get_fd(gio);
+       dhcpcd_dispatch(fd);
+       return true;
+}
+
+static void
+delete_watch_cb(_unused DHCPCD_CONNECTION *con, const struct pollfd *fd,
+    _unused void *data)
+{
+       struct watch *w, *l;
+
+       l = NULL;
+       for (w = watches; w; w = w->next) {
+               if (w->pollfd.fd == fd->fd) {
+                       if (l == NULL)
+                               watches = w->next;
+                       else
+                               l->next = w->next;
+                       g_source_remove(w->eventid);
+                       g_io_channel_unref(w->gio);
+                       g_free(w);
+                       break;
+               }
+       }
+}
+
+static void
+add_watch_cb(DHCPCD_CONNECTION *con, const struct pollfd *fd,
+    _unused void *data)
+{
+       struct watch *w;
+       GIOChannel *gio;
+       int flags, eventid;
+
+       /* Remove any existing watch */
+       delete_watch_cb(con, fd, data);
+       
+       gio = g_io_channel_unix_new(fd->fd);
+       if (gio == NULL) {
+               g_error(_("Error creating new GIO Channel\n"));
+               return;
+       }
+       flags = 0;
+       if (fd->events & POLLIN)
+               flags |= G_IO_IN;
+       if (fd->events & POLLOUT)
+               flags |= G_IO_OUT;
+       if (fd->events & POLLERR)
+               flags |= G_IO_ERR;
+       if (fd->events & POLLHUP)
+               flags |= G_IO_HUP;
+       if ((eventid = g_io_add_watch(gio, flags, gio_callback, con)) == 0) {
+               g_io_channel_unref(gio);
+               g_error(_("Error creating watch\n"));
+               return;
+       }
+       w = g_malloc(sizeof(*w));
+       memcpy(&w->pollfd, fd, sizeof(w->pollfd));
+       w->eventid = eventid;
+       w->gio = gio;
+       w->next = watches;
+       watches = w;
+}
+
+int
+main(int argc, char *argv[])
+{
+       char *error = NULL;
+       char *version = NULL;
+       DHCPCD_CONNECTION *con;
+               
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, NULL);
+       bind_textdomain_codeset(PACKAGE, "UTF-8");
+       textdomain(PACKAGE); 
+
+       gtk_init(&argc, &argv);
+       g_set_application_name("Network Configurator");
+       gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
+           ICONDIR);
+       status_icon = gtk_status_icon_new_from_icon_name("network-offline");
+       
+       gtk_status_icon_set_tooltip(status_icon,
+           _("Connecting to dhcpcd ..."));
+       gtk_status_icon_set_visible(status_icon, true);
+
+       notify_init(PACKAGE);
+
+       g_message(_("Connecting ..."));
+       con = dhcpcd_open(&error);
+       if (con ==  NULL)
+               g_critical("libdhcpcd: %s", error);
+
+       gtk_status_icon_set_tooltip(status_icon, _("Triggering dhcpcd ..."));
+       online = false;
+
+       if (!dhcpcd_command(con, "GetVersion", NULL, &version)) {
+               g_critical("libdhcpcd: GetVersion: %s", dhcpcd_error(con));
+               exit(EXIT_FAILURE);
+       }
+       g_message(_("Connected to %s-%s"), "dhcpcd-dbus", version);
+       g_free(version);
+
+       dhcpcd_set_watch_functions(con, add_watch_cb, delete_watch_cb, NULL);
+       dhcpcd_set_signal_functions(con, event_cb, status_cb, scan_cb, NULL);
+       if (dhcpcd_error(con))
+               g_error("libdhcpcd: %s", dhcpcd_error(con));
+
+       menu_init(status_icon, con);
+
+       gtk_main();
+       dhcpcd_close(con);
+       return 0;
+}
similarity index 72%
rename from src/menu.c
rename to src/dhcpcd-gtk/menu.c
index e1452ed8fb11bd1921231173fb5eed567b245891..51b74dd522de39e021dae9d31e11bb9e6b1b265e 100644 (file)
  */
 
 #include "dhcpcd-gtk.h"
-#include "menu.h"
-#include "prefs.h"
-#include "wpa.h"
 
 static const char *copyright = "Copyright (c) 2009 Roy Marples";
 static const char *authors[] = { "Roy Marples <roy@marples.name>", NULL };
 
 static void
-on_pref(void)
+on_pref(_unused GtkObject *o, gpointer data)
 {
-       dhcpcd_prefs_show();
+       dhcpcd_prefs_show((DHCPCD_CONNECTION *)data);
 }
 
-
 static void
 on_quit(void)
 {
@@ -73,7 +69,13 @@ url_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer data)
 static void
 ssid_hook(_unused GtkMenuItem *item, gpointer data)
 {
-       wpa_configure((const struct if_ap *)data);
+       DHCPCD_WI_SCAN *scan;
+       WI_SCAN *wi;
+
+       scan = (DHCPCD_WI_SCAN *)data;
+       wi = wi_scan_find(scan);
+       if (wi)
+               wpa_configure(wi->connection, wi->interface, scan);
 }
 
 static void
@@ -93,29 +95,30 @@ on_about(_unused GtkMenuItem *item)
            NULL);
 }
 
-static void
-add_scan_results(GtkMenu *menu, const struct if_msg *ifm)
+static GtkWidget *
+add_scans(WI_SCAN *scan)
 {
-       GSList *gl;
-       const struct if_ap *ifa;
-       GtkWidget *item, *image, *box, *label, *bar;
+       DHCPCD_WI_SCAN *wis;
+       GtkWidget *menu, *item, *image, *box, *label, *bar;
        double perc;
        int strength;
        const char *icon;
        char *tip;
 
-       for (gl = ifm->scan_results; gl; gl = gl->next) {
-               ifa = (const struct if_ap *)gl->data;
+       menu = gtk_menu_new();
+       for (wis = scan->scans; wis; wis = wis->next) {
                item = gtk_check_menu_item_new();
-               gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item), TRUE); 
-               box = gtk_hbox_new(FALSE, 6);
+               gtk_check_menu_item_set_draw_as_radio(
+                       GTK_CHECK_MENU_ITEM(item), true); 
+               box = gtk_hbox_new(false, 6);
                gtk_container_add(GTK_CONTAINER(item), box); 
-               label = gtk_label_new(ifa->ssid);
+               label = gtk_label_new(wis->ssid);
                gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
 
-               if (g_strcmp0(ifm->ssid, ifa->ssid) == 0)
-                       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
-               if (ifa->flags == NULL)
+               if (g_strcmp0(wis->ssid, scan->interface->ssid) == 0)
+                       gtk_check_menu_item_set_active(
+                               GTK_CHECK_MENU_ITEM(item), true);
+               if (wis->flags == NULL)
                        icon = "network-wireless";
                else
                        icon = "network-wireless-encrypted";
@@ -126,11 +129,11 @@ add_scan_results(GtkMenu *menu, const struct if_msg *ifm)
                bar = gtk_progress_bar_new();
                gtk_widget_set_size_request(bar, 100, -1);
                gtk_box_pack_end(GTK_BOX(box), bar, FALSE, TRUE, 0);
-               strength = CLAMP(ifa->quality, 0, 100);
+               strength = CLAMP(wis->quality, 0, 100);
                perc = strength / 100.0;
                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), perc);
 
-               tip = g_strconcat(ifa->bssid, " ", ifa->flags, NULL);
+               tip = g_strconcat(wis->bssid, " ", wis->flags, NULL);
                gtk_widget_set_tooltip_text(item, tip);
                g_free(tip);
 
@@ -139,53 +142,38 @@ add_scan_results(GtkMenu *menu, const struct if_msg *ifm)
                gtk_widget_show(image);
                gtk_widget_show(box);
                g_signal_connect(G_OBJECT(item), "activate",
-                   G_CALLBACK(ssid_hook), gl->data);
+                   G_CALLBACK(ssid_hook), wis);
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
        }
+       return menu;
 }
 
 static void
 on_activate(GtkStatusIcon *icon)
 {
-       GtkMenu *menu;
-       const struct if_msg *ifm;
-       GSList *l;
-       size_t n, na;
+       WI_SCAN *w;
+       GtkWidget *menu, *imenu, *item, *image;
 
        notify_close();
-
-       n = na =0;
-       for (l = interfaces; l; l = l->next) {
-               ifm = (const struct if_msg *)l->data;
-               if (ifm->wireless) {
-                       if (ifm->scan_results != NULL)
-                               ++na;
-                       if (++n > 1 && na != 0)
-                               break;
-               }
-       }
-       if (n == 0 || (n == 1 && na == 0))
+       if (wi_scans == NULL)
                return;
-
-       menu = (GtkMenu *)gtk_menu_new();
-
-       for (l = interfaces; l; l = l->next) {
-               ifm = (const struct if_msg *)l->data;
-               if (!ifm->wireless)
-                       continue;
-               if (n == 1) {
-                       add_scan_results(menu, ifm);
-                       break;
+       if (wi_scans->next) {
+               menu = gtk_menu_new();
+               for (w = wi_scans; w; w = w->next) {
+                       imenu = gtk_menu_new();
+                       item = gtk_image_menu_item_new_with_label(
+                               w->interface->ifname);
+                       image = gtk_image_new_from_icon_name(
+                               "network-wireless", GTK_ICON_SIZE_MENU);
+                       gtk_image_menu_item_set_image(
+                               GTK_IMAGE_MENU_ITEM(item), image);
+                       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+                       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),
+                           add_scans(w));
                }
-#if 0
-               item = gtk_image_menu_item_new_with_label(ifm->name);
-               image = gtk_image_new_from_icon_name("network-wireless",
-                   GTK_ICON_SIZE_MENU);
-               gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
-
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-#endif
-       }
+       } else
+               menu = add_scans(wi_scans);
+       
        gtk_widget_show_all(GTK_WIDGET(menu));
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
            gtk_status_icon_position_menu, icon,
@@ -195,19 +183,24 @@ on_activate(GtkStatusIcon *icon)
 static void
 on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
 {
+       DHCPCD_CONNECTION *con;
        GtkMenu *menu;
        GtkWidget *item, *image;
 
        notify_close();
 
+       con = (DHCPCD_CONNECTION *)data;
        menu = (GtkMenu *)gtk_menu_new();
 
        item = gtk_image_menu_item_new_with_mnemonic(_("_Preferences"));
        image = gtk_image_new_from_icon_name(GTK_STOCK_PREFERENCES,
            GTK_ICON_SIZE_MENU);
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
-       g_signal_connect(G_OBJECT(item), "activate",
-           G_CALLBACK(on_pref), icon);
+       if (g_strcmp0(dhcpcd_status(con), "down") == 0)
+               gtk_widget_set_sensitive(item, false);
+       else
+               g_signal_connect(G_OBJECT(item), "activate",
+                   G_CALLBACK(on_pref), data);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
 
        item = gtk_separator_menu_item_new();
@@ -231,16 +224,16 @@ on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
 
        gtk_widget_show_all(GTK_WIDGET(menu));
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
-           gtk_status_icon_position_menu, data, button, atime);
+           gtk_status_icon_position_menu, icon, button, atime);
        if (button == 0)
                gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), FALSE);
 }
 
 void
-menu_init(GtkStatusIcon *icon)
+menu_init(GtkStatusIcon *icon, DHCPCD_CONNECTION *con)
 {
-       g_signal_connect_object(G_OBJECT(icon), "activate",
-           G_CALLBACK(on_activate), icon, 0);
-       g_signal_connect_object(G_OBJECT(icon), "popup_menu",
-           G_CALLBACK(on_popup), icon, 0);
+       g_signal_connect(G_OBJECT(icon), "activate",
+           G_CALLBACK(on_activate), con);
+       g_signal_connect(G_OBJECT(icon), "popup_menu",
+           G_CALLBACK(on_popup), con);
 }
similarity index 75%
rename from src/prefs.c
rename to src/dhcpcd-gtk/prefs.c
index b2630e8138861ea7d06016585d6c30cb7d2ce60d..b0371cb8f8cf84233881197a24c77c273792e71c 100644 (file)
 
 #include <errno.h>
 
-#include "dhcpcd-config.h"
 #include "dhcpcd-gtk.h"
-#include "prefs.h"
 
 static GtkWidget *dialog, *blocks, *names, *controls, *clear, *rebind;
 static GtkWidget *autoconf, *address, *router, *dns_servers, *dns_search;
-static GPtrArray *config;
+static DHCPCD_CONFIG *config;
 static char *block, *name;
-static const struct if_msg *iface;
+static DHCPCD_IF *iface;
 
 static void
-show_config(GPtrArray *array)
+show_config(DHCPCD_CONFIG *conf)
 {
        const char *val;
        bool autocnf;
 
-       if (get_config_static(array, "ip_address=", &val) != -1)
+       if ((val = dhcpcd_config_get_static(conf, "ip_address=")) != NULL)
                autocnf = false;
        else {
-               if (get_config(array, "inform", &val) == -1 &&
+               if ((val = dhcpcd_config_get(conf, "inform")) == NULL &&
                    (iface && iface->flags & IFF_POINTOPOINT))
                        autocnf = false;
                else
@@ -55,11 +53,11 @@ show_config(GPtrArray *array)
        }
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(autoconf), autocnf);
        gtk_entry_set_text(GTK_ENTRY(address), val ? val : "");
-       get_config_static(array, "routers=", &val);
+       val = dhcpcd_config_get_static(conf, "routers=");
        gtk_entry_set_text(GTK_ENTRY(router), val ? val : "");
-       get_config_static(array, "domain_name_servers=", &val);
+       val = dhcpcd_config_get_static(conf, "domain_name_servers=");
        gtk_entry_set_text(GTK_ENTRY(dns_servers), val ? val : "");
-       get_config_static(array, "domain_search=", &val);
+       val = dhcpcd_config_get_static(conf, "domain_search=");
        gtk_entry_set_text(GTK_ENTRY(dns_search), val ? val : "");
 }
 
@@ -81,37 +79,58 @@ combo_active_text(GtkWidget *widget)
        return text;
 }
 
-static void
-make_config(GPtrArray *array)
+static bool
+set_option(DHCPCD_CONFIG **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 (ret)
+               *ret = false;
+       return false;
+}
+
+static bool
+make_config(DHCPCD_CONFIG **conf)
 {
        const char *val, ns[] = "";
-       bool a;
+       bool a, ret;
 
+       ret = true;
        a = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(autoconf));
        if (iface && iface->flags & IFF_POINTOPOINT)
-               set_option(array, true, "ip_address=", a ? NULL : ns);
+               set_option(conf, true, "ip_address=", a ? NULL : ns, &ret);
        else {
                val = gtk_entry_get_text(GTK_ENTRY(address));
                if (*val == '\0')
                        val = NULL;
-               set_option(array, false, "inform", a ? val : NULL);
-               set_option(array, true, "ip_address=", a ? NULL : val);
+               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(array, true, "routers=", val);
+       set_option(conf, true, "routers=", val, &ret);
        
        val = gtk_entry_get_text(GTK_ENTRY(dns_servers));
        if (a && *val == '\0')
                val = NULL;
-       set_option(array, true, "domain_name_servers=", val);
+       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(array, true, "domain_search=", val);
+       set_option(conf, true, "domain_search=", val, &ret);
+       
+       return ret;
 }
 
 static GdkPixbuf *
@@ -121,8 +140,8 @@ load_icon(const char *iname)
 
        if (!gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height))
                return NULL;
-       return gtk_icon_theme_load_icon(icontheme, iname, MIN(width, height),
-           0, NULL);
+       return gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
+           iname, MIN(width, height), 0, NULL);
 }
 
 static void
@@ -147,50 +166,44 @@ set_name_active_icon(const char *iname)
 }
 
 static GSList *
-list_interfaces(void)
+list_interfaces(DHCPCD_CONNECTION *con)
 {
-       GSList *list, *l;
-       const struct if_msg *ifm;
+       GSList *list;
+       DHCPCD_IF *i;
 
        list = NULL;
-       for (l = interfaces; l; l = l->next) {
-               ifm = (const struct if_msg *)l->data;
-               list = g_slist_append(list, ifm->ifname);
-       }
+       for (i = dhcpcd_interfaces(con); i; i = i->next)
+               list = g_slist_append(list, i->ifname);
        return list;
 }
 
 static GSList *
-list_ssids(void)
+list_ssids(WI_SCAN *scans)
 {
-       GSList *list, *l, *a, *la;
-       const struct if_msg *ifm;
-       const struct if_ap *ifa;
+       GSList *list, *l;
+       WI_SCAN *w;
+       DHCPCD_WI_SCAN *wis;
 
        list = NULL;
-       for (l = interfaces; l; l = l->next) {
-               ifm = (const struct if_msg *)l->data;
-               if (!ifm->wireless)
-                       continue;
-               for (a = ifm->scan_results; a; a = a->next) {
-                       ifa = (const struct if_ap *)a->data;
-                       for (la = list; la; la = la->next)
-                               if (g_strcmp0((const char *)la->data,
-                                       ifa->ssid) == 0)
+       for (w = scans; w; w = w->next) {
+               for (wis = w->scans; wis; wis = wis->next) {
+                       for (l = list; l; l = l->next)
+                               if (g_strcmp0((const char *)l->data,
+                                       wis->ssid) == 0)
                                        break;
-                       if (la == NULL)
-                               list = g_slist_append(list, ifa->ssid);
+                       if (l == NULL)
+                               list = g_slist_append(list, wis->ssid);
                }
        }
        return list;
 }
 
 static void
-blocks_on_change(GtkWidget *widget)
+blocks_on_change(GtkWidget *widget, gpointer data)
 {
+       DHCPCD_CONNECTION *con;
        GtkListStore *store;
        GtkTreeIter iter;
-       GError *error;
        char **list, **lp;
        const char *iname, *nn;
        GSList *l, *new_names;
@@ -198,10 +211,12 @@ blocks_on_change(GtkWidget *widget)
        GdkPixbuf *pb;
        int n;
 
+       con = (DHCPCD_CONNECTION *)data;
        if (name) {
-               make_config(config);
-               save_config(block, name, config);
-               free_config(&config);
+               if (make_config(&config))
+                       dhcpcd_config_save(con, block, name, config);
+               dhcpcd_config_free(config);
+               config = NULL;
                show_config(config);
                g_free(block);
                g_free(name);
@@ -210,21 +225,13 @@ blocks_on_change(GtkWidget *widget)
        block = combo_active_text(widget);
        store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(names)));
        gtk_list_store_clear(store);
-       error = NULL;
-       if (!dbus_g_proxy_call(dbus, "GetConfigBlocks", &error,
-               G_TYPE_STRING, block, G_TYPE_INVALID,
-               G_TYPE_STRV, &list, G_TYPE_INVALID))
-       {
-               g_warning("GetConfigBlocks: %s", error->message);
-               g_clear_error(&error);
-               return;
-       }
-
+       list = dhcpcd_config_blocks_get(con, block);
+       
        it = gtk_icon_theme_get_default();
        if (g_strcmp0(block, "interface") == 0)
-               new_names = list_interfaces();
+               new_names = list_interfaces(con);
        else
-               new_names = list_ssids();
+               new_names = list_ssids(wi_scans);
 
        n = 0;
        for (l = new_names; l; l = l->next) {
@@ -261,28 +268,35 @@ blocks_on_change(GtkWidget *widget)
 }
 
 static void
-names_on_change(void)
+names_on_change(_unused GtkWidget *widget, gpointer data)
 {
-       GSList *l;
-       
+       DHCPCD_CONNECTION *con;
+       DHCPCD_IF *i;
+
+       con = (DHCPCD_CONNECTION *)data;
        if (name) {
-               make_config(config);
-               save_config(block, name, config);
+               if (make_config(&config))
+                       dhcpcd_config_save(con, block, name, config);
                g_free(name);
        }
        name = combo_active_text(names);
-       free_config(&config);
+       dhcpcd_config_free(config);
        iface = NULL;
        if (g_strcmp0(block, "interface") == 0) {
-               for (l = interfaces; l; l = l->next) {
-                       iface = (const struct if_msg *)l->data;
-                       if (g_strcmp0(name, iface->ifname) == 0)
+               for (i = dhcpcd_interfaces(con); i; i = i->next)
+                       if (g_strcmp0(name, i->ifname) == 0) {
+                               iface = i;
                                break;
-               }
+                       }
        }
        gtk_widget_set_sensitive(address,
            iface && (iface->flags & IFF_POINTOPOINT) == 0);
-       config = load_config(block, name);
+       if (block && name) {
+               config = dhcpcd_config_load(con, block, name);
+               if (config == NULL && dhcpcd_error(con))
+                       g_error("libdhcpcd: %s\n", dhcpcd_error(con));
+       } else
+               config = NULL;
        show_config(config);
        gtk_widget_set_sensitive(controls, name ? true : false);
        gtk_widget_set_sensitive(clear, name ? true : false);
@@ -351,73 +365,63 @@ entry_lost_focus(GtkEntry *entry)
 }
 
 static void
-on_clear(void)
+on_clear(_unused GtkObject *o, gpointer data)
 {
+       DHCPCD_CONNECTION *con;
 
-       free_config(&config);
-       config = g_ptr_array_new();
-       if (save_config(block, name, config)) {
+       con = (DHCPCD_CONNECTION *)data;
+       dhcpcd_config_free(config);
+       config = NULL;
+       if (dhcpcd_config_save(con, block, name, config)) {
                set_name_active_icon("document-new");
                show_config(config);
        }
 }
 
 static void
-rebind_interface(const char *ifname)
-{
-       GError *error;
-       
-       error = NULL;
-       if (!dbus_g_proxy_call(dbus, "Rebind", &error,
-               G_TYPE_STRING, ifname, G_TYPE_INVALID, G_TYPE_INVALID))
-       {
-               g_critical("Rebind: %s: %s", ifname, error->message);
-               g_clear_error(&error);
-       }
-}
-
-static void
-on_rebind(void)
+on_rebind(_unused GtkWidget *widget, gpointer data)
 {
-       GSList *l;
-       const struct if_msg *ifm;
+       DHCPCD_CONNECTION *con;
+       DHCPCD_IF *i;
 
-       make_config(config);
-       if (save_config(block, name, config)) {
-               set_name_active_icon(config->len == 0 ?
+       con = (DHCPCD_CONNECTION *)data;
+       if (make_config(&config) &&
+           dhcpcd_config_save(con, block, name, config)) {
+               set_name_active_icon(config == NULL ?
                    "document-new" : "document-save");
                show_config(config);
                if (g_strcmp0(block, "interface") == 0)
-                       rebind_interface(name);
+                       dhcpcd_rebind(con, iface);
                else {
-                       for (l = interfaces; l; l = l->next) {
-                               ifm = (const struct if_msg *)l->data;
-                               if (g_strcmp0(ifm->ssid, name) == 0)
-                                       rebind_interface(ifm->ifname);
+                       for (i = dhcpcd_interfaces(con); i; i = i->next) {
+                               if (g_strcmp0(i->ssid, name) == 0)
+                                       dhcpcd_rebind(con, i);
                        }
                }
+               if (dhcpcd_error(con))
+                       g_warning("libdhcpcd: %s", dhcpcd_error(con));
        }
 }
 
 static void
-on_destroy(void)
+on_destroy(_unused GtkObject *o, gpointer data)
 {
-       
        if (name != NULL) {
-               make_config(config);
-               save_config(block, name, config);
+               if (make_config(&config))
+                       dhcpcd_config_save((DHCPCD_CONNECTION *)data,
+                           block, name, config);
                g_free(block);
                g_free(name);
                block = name = NULL;
        }
-       free_config(&config);
+       dhcpcd_config_free(config);
+       config = NULL;
        dialog = NULL;
 }
 
-void
+static void
 dhcpcd_prefs_close(void)
 {
-       
        if (dialog != NULL) {
                gtk_widget_destroy(dialog);
                dialog = NULL;
@@ -425,7 +429,15 @@ dhcpcd_prefs_close(void)
 }
 
 void
-dhcpcd_prefs_show(void)
+dhcpcd_prefs_abort(void)
+{
+       g_free(name);
+       name = NULL;
+       dhcpcd_prefs_close();
+}
+
+void
+dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
 {
        GtkWidget *dialog_vbox, *hbox, *vbox, *table, *w;
        GtkListStore *store;
@@ -438,8 +450,12 @@ dhcpcd_prefs_show(void)
                return;
        }
 
+       if (g_strcmp0(dhcpcd_status(con), "down") == 0)
+               return;
+
        dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-       g_signal_connect(G_OBJECT(dialog), "destroy", on_destroy, NULL);
+       g_signal_connect(G_OBJECT(dialog), "destroy",
+           G_CALLBACK(on_destroy), con);
 
        gtk_window_set_title(GTK_WINDOW(dialog), _("Network Preferences"));
        gtk_window_set_resizable(GTK_WINDOW(dialog), false);
@@ -489,9 +505,9 @@ dhcpcd_prefs_show(void)
        gtk_widget_set_sensitive(names, false);
        gtk_box_pack_start(GTK_BOX(hbox), names, false, false, 3);
        g_signal_connect(G_OBJECT(blocks), "changed",
-           G_CALLBACK(blocks_on_change), NULL);
+           G_CALLBACK(blocks_on_change), con);
        g_signal_connect(G_OBJECT(names), "changed",
-           G_CALLBACK(names_on_change), NULL);
+           G_CALLBACK(names_on_change), con);
        
        w = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(dialog_vbox), w, true, false, 3);
@@ -549,20 +565,22 @@ dhcpcd_prefs_show(void)
        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", on_clear, NULL);
+       g_signal_connect(G_OBJECT(clear), "clicked",
+           G_CALLBACK(on_clear), NULL);
        rebind = gtk_button_new_with_mnemonic(_("_Rebind"));
        gtk_widget_set_sensitive(rebind, false);
        w = gtk_image_new_from_stock(GTK_STOCK_EXECUTE,
            GTK_ICON_SIZE_BUTTON);
        gtk_button_set_image(GTK_BUTTON(rebind), w);
        gtk_box_pack_start(GTK_BOX(hbox), rebind, false, false, 0);
-       g_signal_connect(G_OBJECT(rebind), "clicked", on_rebind, NULL);
+       g_signal_connect(G_OBJECT(rebind), "clicked",
+           G_CALLBACK(on_rebind), con);
        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",
-           dhcpcd_prefs_close, NULL);
+           G_CALLBACK(dhcpcd_prefs_close), NULL);
        
-       blocks_on_change(blocks);
+       blocks_on_change(blocks, con);
        show_config(NULL);
        gtk_widget_show_all(dialog);
 }
diff --git a/src/dhcpcd-gtk/wpa.c b/src/dhcpcd-gtk/wpa.c
new file mode 100644 (file)
index 0000000..5fd6f7b
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * dhcpcd-gtk
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "dhcpcd-gtk.h"
+
+static void
+wpa_dialog(const char *title, const char *txt)
+{
+       GtkWidget *dialog;
+
+       dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+           GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", txt);
+       gtk_window_set_title(GTK_WINDOW(dialog), title);
+       gtk_dialog_run(GTK_DIALOG(dialog));
+       gtk_widget_destroy(dialog);
+}
+
+static bool
+configure_network(DHCPCD_CONNECTION *con, DHCPCD_IF *i,
+    int id, const char *mgmt, const char *var, const char *val, bool quote)
+{
+       char *str;
+       static bool warned = false;
+
+       if (!dhcpcd_wpa_set_network(con, i, id, "key_mgmt", mgmt))
+               return false;
+       if (quote)
+               str = g_strconcat("\"", val, "\"", NULL);
+       else
+               str = NULL;
+       if (!dhcpcd_wpa_set_network(con, i, id, var, quote ? str : val)) {
+               g_warning("libdhcpcd: %s", dhcpcd_error(con));
+               dhcpcd_error_clear(con);
+               g_free(str);
+               wpa_dialog(_("Error setting password"),
+                   _("Failed to set password, probably too short."));
+               return false;
+       }
+       g_free(str);
+       if (!dhcpcd_wpa_command(con, i, "EnableNetwork", id))
+               return false;
+       if (!dhcpcd_wpa_command(con, i, "SaveConfig", -1)) {
+               g_warning("libdhcpcd: %s", dhcpcd_error(con));
+               dhcpcd_error_clear(con);
+               if (!warned) {
+                       warned = true;
+                       wpa_dialog(_("Error saving configuration"),
+                           _("Failed to save wpa_supplicant configuration.\n\nYou should add update_config=1 to /etc/wpa_supplicant.conf.\nThis warning will not appear again until program restarted."));
+               }
+               return false;
+       }
+/*
+  if (!dbus_g_proxy_call(dbus, "Disconnect", &error,
+  G_TYPE_STRING, ifname,
+  G_TYPE_INVALID,
+  G_TYPE_INVALID))
+  {
+  g_warning("Disconnect: %s", error->message);
+  g_error_free(error);
+  }
+*/
+       if (!dhcpcd_wpa_command(con, i, "Reassociate", -1))
+               return false;
+       return true;
+}
+
+static void
+onEnter(_unused GtkWidget *widget, gpointer *data)
+{
+       gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT);
+}
+
+bool
+wpa_configure(DHCPCD_CONNECTION *con, DHCPCD_IF *i, DHCPCD_WI_SCAN *s)
+{
+       GtkWidget *dialog, *label, *psk, *vbox, *hbox;
+       const char *var, *mgt;
+       int result, id;
+       bool retval;
+
+       dialog = gtk_dialog_new_with_buttons(s->ssid,
+           NULL,
+           GTK_DIALOG_MODAL,
+           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+           GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+           NULL);
+       gtk_window_set_resizable(GTK_WINDOW(dialog), false);
+       gtk_window_set_icon_name(GTK_WINDOW(dialog),
+           "network-wireless-encrypted");
+       gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+           GTK_RESPONSE_ACCEPT);
+       vbox = GTK_DIALOG(dialog)->vbox;
+
+       hbox = gtk_hbox_new(false, 2);
+       label = gtk_label_new(_("Pre Shared Key:"));
+       gtk_box_pack_start(GTK_BOX(hbox), label, false, false, 0);
+       psk = gtk_entry_new();
+       gtk_entry_set_max_length(GTK_ENTRY(psk), 130);
+       g_signal_connect(G_OBJECT(psk), "activate",
+           G_CALLBACK(onEnter), dialog);
+       gtk_box_pack_start(GTK_BOX(hbox), psk, true, true, 0);
+       gtk_container_add(GTK_CONTAINER(vbox), hbox);
+
+       gtk_widget_show_all(dialog);
+again:
+       result = gtk_dialog_run(GTK_DIALOG(dialog));
+       
+       id = -1;
+       retval = false;
+       if (result == GTK_RESPONSE_ACCEPT) {
+               id = dhcpcd_wpa_find_network_new(con, i, s->ssid);
+               if (g_strcmp0(s->flags, "[WEP]") == 0) {
+                       mgt = "NONE";
+                       var = "wep_key0";
+               } else {
+                       mgt = "WPA-PSK";
+                       var = "psk";
+               }
+               if (id != -1) {
+                       retval = configure_network(con, i, id, mgt, var,
+                           gtk_entry_get_text(GTK_ENTRY(psk)), true);
+               }
+               if (!retval && dhcpcd_error(con)) {
+                       wpa_dialog(_("Error"), dhcpcd_error(con));
+                       goto again;
+               }
+       }
+       gtk_widget_destroy(dialog);
+       return retval;
+}
diff --git a/src/libdhcpcd/Makefile b/src/libdhcpcd/Makefile
new file mode 100644 (file)
index 0000000..fb30f21
--- /dev/null
@@ -0,0 +1,21 @@
+LIB=           dhcpcd
+SHLIB_MAJOR=   1
+SRCS=          main.c config.c dispatch.c misc.c wpa.c
+
+_PKGCFLAGS_SH= pkg-config --cflags dbus-1
+_PKGCFLAGS!=   ${_PKGCFLAGS_SH}
+PKGCFLAGS?=    ${_PKGCFLAGS}$(shell ${_PKGCFLAGS_SH})
+CFLAGS+=       ${PKGCFLAGS}
+
+_PKGLIBS_SH=   pkg-config --libs dbus-1
+_PKGLIBS!=     ${_PKGLIBS_SH}
+PKGLIBS?=      ${_PKGLIBS}$(shell ${_PKGLIBS_SH})
+LDADD+=                ${PKGLIBS}
+
+# Don't install
+LIBINSTALL=
+
+MK=            ../../mk
+include ${MK}/lib.mk
+include ${MK}/cc.mk
+include ${MK}/debug.mk
diff --git a/src/libdhcpcd/Makefile.inc b/src/libdhcpcd/Makefile.inc
new file mode 100644 (file)
index 0000000..67e8caf
--- /dev/null
@@ -0,0 +1,11 @@
+CPPFLAGS+=     -I../libdhcpcd
+LDFLAGS+=      -L../libdhcpcd
+
+# We normally want to build in the static library
+MKSTATIC?=     yes
+_LDADD_SH=     case "${MKSTATIC}" in \
+               [Yy][Ee][Ss]) echo "-Wl,-Bstatic -ldhcpcd -Wl,-Bdynamic";; \
+               *) echo "-ldhcpcd";; \
+               esac
+_LDADD!=       ${_LDADD_SH}
+LDADD+=                ${_LDADD}$(shell ${_LDADD_SH})
diff --git a/src/libdhcpcd/config.c b/src/libdhcpcd/config.c
new file mode 100644 (file)
index 0000000..4f22464
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * libdhcpcd
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+
+#define IN_LIBDHCPCD
+#include "libdhcpcd.h"
+
+static DHCPCD_CONFIG *
+dhcpcd_config_new(const char *opt, const char *val)
+{
+       DHCPCD_CONFIG *c;
+
+       c = malloc(sizeof(*c));
+       if (c == NULL)
+               return NULL;
+       c->option = strdup(opt);
+       if (c->option == NULL) {
+               free(c);
+               return NULL;
+       }
+       c->value = strdup(val);
+       if (c->value == NULL) {
+               free(c->option);
+               free(c);
+               return NULL;
+       }
+       c->next = NULL;
+       return c;
+}
+
+void
+dhcpcd_config_free(DHCPCD_CONFIG *config)
+{
+       DHCPCD_CONFIG *c;
+       
+       while (config) {
+               c = config->next;
+               free(config->option);
+               free(config->value);
+               free(config);
+               config = c;
+       }
+}      
+
+char **
+dhcpcd_config_blocks_get(DHCPCD_CONNECTION *con, const char *block)
+{
+       DBusMessage *msg, *reply;
+       DBusMessageIter args;
+       DBusError error;
+       char **blocks;
+       int n_blocks;
+
+       msg = dbus_message_new_method_call(DHCPCD_SERVICE, DHCPCD_PATH,
+           DHCPCD_SERVICE, "GetConfigBlocks");
+       if (msg == NULL) {
+               dhcpcd_error_set(con, NULL, errno);
+               return NULL;
+       }
+       dbus_message_iter_init_append(msg, &args);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &block);
+       reply = dhcpcd_send_reply(con, msg);
+       dbus_message_unref(msg);
+       if (reply == NULL)
+               return NULL;
+       dbus_error_init(&error);
+       blocks = NULL;
+       n_blocks = 0;
+       if (!dbus_message_get_args(reply, &error, DBUS_TYPE_ARRAY,
+               DBUS_TYPE_STRING, &blocks, &n_blocks,
+               DBUS_TYPE_INVALID))
+       {
+               dhcpcd_error_set(con, error.message, 0);
+               dbus_error_free(&error);
+       }
+       dbus_message_unref(reply);
+       return blocks;  
+}
+
+DHCPCD_CONFIG *
+dhcpcd_config_load(DHCPCD_CONNECTION *con, const char *block, const char *name)
+{
+       DHCPCD_CONFIG *config, *c, *l;
+       DBusMessage *msg, *reply;
+       DBusMessageIter args, array, item;
+       const char ns[] = "", *option, *value;
+       int errors;
+
+       msg = dbus_message_new_method_call(DHCPCD_SERVICE, DHCPCD_PATH,
+           DHCPCD_SERVICE, "GetConfig");
+       if (msg == NULL) {
+               dhcpcd_error_set(con, NULL, errno);
+               return NULL;
+       }
+       dbus_message_iter_init_append(msg, &args);
+       if (block == NULL)
+               block = ns;
+       if (name == NULL)
+               name = ns;
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &block);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &name);
+       reply = dhcpcd_send_reply(con, msg);
+       dbus_message_unref(msg);
+       if (reply == NULL)
+               return NULL;
+       if (!dbus_message_iter_init(reply, &args) ||
+           dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
+       {
+               dbus_message_unref(reply);
+               dhcpcd_error_set(con, NULL, EINVAL);
+               return NULL;
+       }
+       config = l = NULL;
+       errors = con->errors;
+       dbus_message_iter_recurse(&args, &array);
+       for (;
+            dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT;
+            dbus_message_iter_next(&array))
+       {
+               dbus_message_iter_recurse(&array, &item);
+               if (!dhcpcd_iter_get(con, &item, DBUS_TYPE_STRING, &option) ||
+                   !dhcpcd_iter_get(con, &item, DBUS_TYPE_STRING, &value))
+                       break;
+               c = dhcpcd_config_new(option, value);
+               if (c == NULL) {
+                       dhcpcd_error_set(con, NULL, errno);
+                       break;
+               }
+               if (l == NULL)
+                       config = c;
+               else
+                       l->next = c;
+               l = c;
+       }
+       if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
+               if (con->errors == errors)
+                       dhcpcd_error_set(con, NULL, EINVAL);
+               dhcpcd_config_free(config);
+               config = NULL;
+       }
+       dbus_message_unref(reply);
+       return config;
+}
+
+bool
+dhcpcd_config_save(DHCPCD_CONNECTION *con, const char *block, const char *name,
+    DHCPCD_CONFIG *config)
+{
+       DBusMessage *msg, *reply;
+       DBusMessageIter args, array, item;
+       DHCPCD_CONFIG *c;
+       const char ns[] = "", *p;
+       bool retval;
+
+       msg = dbus_message_new_method_call(DHCPCD_SERVICE, DHCPCD_PATH,
+           DHCPCD_SERVICE, "SetConfig");
+       if (msg == NULL) {
+               dhcpcd_error_set(con, 0, errno);
+               return false;
+       }
+       dbus_message_iter_init_append(msg, &args);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &block);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &name);
+       dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY,
+           DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+           DBUS_TYPE_STRING_AS_STRING
+           DBUS_TYPE_STRING_AS_STRING
+           DBUS_STRUCT_END_CHAR_AS_STRING,
+           &array);
+       for (c = config; c; c = c->next) {
+               dbus_message_iter_open_container(&array,
+                   DBUS_TYPE_STRUCT, NULL, &item);
+               dbus_message_iter_append_basic(&item,
+                   DBUS_TYPE_STRING, &c->option);
+               if (c->value == NULL)
+                       p = ns;
+               else
+                       p = c->value;
+               dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &p);
+               dbus_message_iter_close_container(&array, &item);
+       }
+       dbus_message_iter_close_container(&args, &array);
+
+       reply = dhcpcd_send_reply(con, msg);
+       dbus_message_unref(msg);
+       if (reply == NULL)
+               retval = false;
+       else {
+               dbus_message_unref(reply);
+               retval = true;
+       }
+       return retval;
+}
+
+static DHCPCD_CONFIG *
+dhcpcd_config_get1(DHCPCD_CONFIG *config, const char *opt, DHCPCD_CONFIG **lst)
+{
+       DHCPCD_CONFIG *c;
+
+       for (c = config; c; c = c->next) {
+               if (strcmp(c->option, opt) == 0)
+                       return c;
+               if (lst)
+                       *lst = c;
+       }
+       errno = ESRCH;
+       return NULL;
+}
+
+const char *
+dhcpcd_config_get(DHCPCD_CONFIG *config, const char *opt)
+{
+       DHCPCD_CONFIG *c;
+
+       c = dhcpcd_config_get1(config, opt, NULL);
+       if (c == NULL)
+               return NULL;
+       return c->value;
+}
+
+static DHCPCD_CONFIG *
+dhcpcd_config_get_static1(DHCPCD_CONFIG *config, const char *opt,
+    DHCPCD_CONFIG **lst)
+{
+       DHCPCD_CONFIG *c;
+       size_t len;
+
+       c = config;
+       len = strlen(opt);
+       while ((c = dhcpcd_config_get1(c, "static", lst)) != NULL) {
+               if (strncmp(c->value, opt, len) == 0)
+                       return c;
+               if (lst)
+                       *lst = c;
+               c = c->next;
+       }
+       return NULL;
+}
+
+const char *
+dhcpcd_config_get_static(DHCPCD_CONFIG *config, const char *opt)
+{
+       DHCPCD_CONFIG *c;
+
+       c = dhcpcd_config_get_static1(config, opt, NULL);
+       if (c == NULL)
+               return NULL;
+       return c->value + strlen(opt);
+}
+
+static bool
+dhcpcd_config_set1(DHCPCD_CONFIG **config, const char *opt, const char *val,
+    bool s)
+{
+       DHCPCD_CONFIG *c, *l;
+       char *t;
+       size_t len;
+
+       l = NULL;
+       if (s)
+               c = dhcpcd_config_get_static1(*config, opt, &l);
+       else
+               c = dhcpcd_config_get1(*config, opt, &l);
+       if (val == NULL) {
+               if (c == NULL)
+                       return true;
+               if (c == *config)
+                       *config = c->next;
+               else if (l != NULL)
+                       l->next = c->next;
+               free(c->option);
+               free(c->value);
+               free(c);
+               return true;
+       }
+       if (s) {
+               len = strlen(opt) + strlen(val) + 2;
+               t = malloc(len);
+               if (t == NULL)
+                       return false;
+               snprintf(t, len, "%s%s", opt, val);
+       } else {
+               t = strdup(val);
+               if (t == NULL)
+                       return false;
+       }
+       if (c == NULL) {
+               if (s)
+                       c = dhcpcd_config_new("static", t);
+               else
+                       c = dhcpcd_config_new(opt, val);
+               if (c == NULL)
+                       return false;
+               if (l == NULL)
+                       *config = c;
+               else
+                       l->next = c;
+               return true;
+       }
+       free(c->value);
+       c->value = t;
+       return true;
+}
+
+bool
+dhcpcd_config_set(DHCPCD_CONFIG **config, const char *opt, const char *val)
+{
+       return dhcpcd_config_set1(config, opt, val, false);
+}
+
+bool
+dhcpcd_config_set_static(DHCPCD_CONFIG **config,
+    const char *opt, const char *val)
+{
+       return dhcpcd_config_set1(config, opt, val, true);
+}
diff --git a/src/libdhcpcd/dispatch.c b/src/libdhcpcd/dispatch.c
new file mode 100644 (file)
index 0000000..f1b90de
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * libdhcpcd
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+
+#define IN_LIBDHCPCD
+#include "libdhcpcd.h"
+
+static const char *
+dhcpcd_message_get_string(DHCPCD_MESSAGE *msg)
+{
+       DBusMessageIter args;
+       char *str;
+
+       if (dbus_message_iter_init(msg, &args) &&
+           dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_STRING)
+       {
+               dbus_message_iter_get_basic(&args, &str);
+               return str;
+       }
+       return NULL;
+}
+
+static void
+dhcpcd_handle_event(DHCPCD_CONNECTION *con, DHCPCD_MESSAGE *msg)
+{
+       DBusMessageIter args;
+       DHCPCD_IF *i, *e, *l, *n, *nl;
+       char *order, *o, *p;
+
+       if (!dbus_message_iter_init(msg, &args))
+               return;
+       order = NULL;
+       i = dhcpcd_if_new(con, &args, &order);
+       if (i == NULL)
+               return;
+       p = order;
+       n = nl = NULL;
+       while ((o = strsep(&p, " ")) != NULL) {
+               l = NULL;
+               for (e = con->interfaces; e; e = e->next) {
+                       if (strcmp(e->ifname, o) == 0)
+                               break;
+                       l = e;
+               }
+               if (e == NULL) {
+                       e = i;
+               } else {
+                       if (l != NULL)
+                               l->next = e->next;
+                       else
+                               con->interfaces = e->next;
+                       e->next = NULL;
+               }
+               if (e != i && strcmp(e->ifname, i->ifname) == 0) {
+                       /* Preserve the pointer */
+                       memcpy(e, i, sizeof(*e));
+                       free(i);
+                       i = e;
+               }
+               if (nl == NULL)
+                       n = nl = e;
+               else {
+                       nl->next = e;
+                       nl = nl->next;
+               }
+       }
+       if (nl != NULL)
+               nl->next = con->interfaces;
+       con->interfaces = n;
+       if (con->event)
+               con->event(con, i, con->signal_data);
+}
+
+bool
+dhcpcd_dispatch_message(DHCPCD_CONNECTION *con, DHCPCD_MESSAGE *msg)
+{
+       bool handled;
+       const char *str;
+
+       if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
+               return false;
+
+       handled = true;
+       dbus_connection_ref(con->bus);
+       dbus_message_ref(msg);
+       if (dbus_message_is_signal(msg, DHCPCD_SERVICE, "StatusChanged")) {
+               con->status = strdup(dhcpcd_message_get_string(msg));
+               if (strcmp(con->status, "down") == 0) {
+                       dhcpcd_if_free(con->interfaces);
+                       con->interfaces = NULL;
+               }
+               if (con->status_changed)
+                       con->status_changed(con, con->status,
+                           con->signal_data);
+       }
+       else if (dbus_message_is_signal(msg, DHCPCD_SERVICE, "ScanResults"))
+       {
+               if (con->wi_scanresults) {
+                       str = dhcpcd_message_get_string(msg);
+                       con->wi_scanresults(con, dhcpcd_if_find(con, str),
+                           con->signal_data);
+               }
+       } else if (dbus_message_is_signal(msg, DHCPCD_SERVICE, "Event"))
+               dhcpcd_handle_event(con, msg);
+       else
+               handled = false;
+       dbus_message_unref(msg);
+       dbus_connection_unref(con->bus);
+       return handled;
+}
diff --git a/src/libdhcpcd/libdhcpcd.h b/src/libdhcpcd/libdhcpcd.h
new file mode 100644 (file)
index 0000000..6f955bc
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * libdhcpcd
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LIBDHCPCD_H
+#define LIBDHCPCD_H
+
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <poll.h>
+#include <stdbool.h>
+
+#define IF_SSIDSIZE 33
+#define IF_BSSIDSIZE 64
+#define FLAGSIZE 8
+#define REASONSIZE 16
+
+typedef struct dhcpcd_wi_scan {
+       char bssid[IF_BSSIDSIZE];
+       int frequency;
+       int quality;
+       int noise;
+       int level;
+       char flags[FLAGSIZE];
+       char ssid[IF_SSIDSIZE];
+       struct dhcpcd_wi_scan *next;
+} DHCPCD_WI_SCAN;
+
+typedef struct dhcpcd_if {
+       char ifname[IF_NAMESIZE];
+       unsigned int flags;
+       char reason[REASONSIZE];
+       struct in_addr ip;
+       unsigned char cidr;
+       bool wireless;
+       char ssid[IF_SSIDSIZE];
+       struct dhcpcd_if *next;
+} DHCPCD_IF;
+
+/* Although we use DBus, we don't have to rely on it for our API */
+#ifdef IN_LIBDHCPCD
+#include <dbus/dbus.h>
+typedef DBusMessage DHCPCD_MESSAGE;
+typedef DBusMessageIter DHCPCD_MESSAGEITER;
+
+typedef struct dhcpcd_connection {
+       DBusConnection *bus;
+       char *error;
+       int err;
+       int errors;
+       char *status;
+       void (*add_watch)(struct dhcpcd_connection *, const struct pollfd *,
+           void *);
+       void (*delete_watch)(struct dhcpcd_connection *, const struct pollfd *,
+           void *);
+       void *watch_data;
+       void (*event)(struct dhcpcd_connection *, DHCPCD_IF *, void *);
+       void (*status_changed)(struct dhcpcd_connection *, const char *,
+           void *);
+       void (*wi_scanresults)(struct dhcpcd_connection *, DHCPCD_IF *,
+           void *);
+       void *signal_data;
+       DHCPCD_IF *interfaces;
+       struct dhcpcd_connection *next;
+} DHCPCD_CONNECTION;
+
+typedef struct dhcpcd_watch {
+       DHCPCD_CONNECTION *connection;
+       DBusWatch *watch;
+       struct pollfd pollfd;
+       struct dhcpcd_watch *next;
+} DHCPCD_WATCH;
+extern DHCPCD_WATCH *dhcpcd_watching;
+
+#define DHCPCD_SERVICE "name.marples.roy.dhcpcd"
+#define DHCPCD_PATH    "/name/marples/roy/dhcpcd"
+
+bool dhcpcd_iter_get(DHCPCD_CONNECTION *, DHCPCD_MESSAGEITER *, int, void *);
+DHCPCD_MESSAGE * dhcpcd_send_reply(DHCPCD_CONNECTION *, DHCPCD_MESSAGE *);
+DHCPCD_MESSAGE * dhcpcd_message_reply(DHCPCD_CONNECTION *,
+    const char *, const char *);
+void dhcpcd_error_set(DHCPCD_CONNECTION *, const char *, int);
+DHCPCD_IF * dhcpcd_if_new(DHCPCD_CONNECTION *, DBusMessageIter *, char **);
+void dhcpcd_if_free(DHCPCD_IF *);
+void dhcpcd_dispatch_signal(DHCPCD_CONNECTION *, const char *, void *);
+bool dhcpcd_dispatch_message(DHCPCD_CONNECTION *, DHCPCD_MESSAGE *);
+#else
+typedef void * DHCPCD_CONNECTION;
+#endif
+
+#define DHCPCD_CALLBACK void (*callback)(DHCPCD_CONNECTION *, void *, void *)
+
+DHCPCD_CONNECTION * dhcpcd_open(char **);
+bool dhcpcd_close(DHCPCD_CONNECTION *);
+const char * dhcpcd_error(DHCPCD_CONNECTION *);
+void dhcpcd_error_clear(DHCPCD_CONNECTION *);
+void dhcpcd_set_watch_functions(DHCPCD_CONNECTION *,
+    void (*)(DHCPCD_CONNECTION *, const struct pollfd *, void *),
+    void (*)(DHCPCD_CONNECTION *, const struct pollfd *, void *),
+    void *);
+void dhcpcd_set_signal_functions(DHCPCD_CONNECTION *,
+    void (*)(DHCPCD_CONNECTION *, DHCPCD_IF *, void *),
+    void (*)(DHCPCD_CONNECTION *, const char *, void *),
+    void (*)(DHCPCD_CONNECTION *, DHCPCD_IF *, void *),
+    void *);
+const char * dhcpcd_status(DHCPCD_CONNECTION *);
+bool dhcpcd_command(DHCPCD_CONNECTION *, const char *, const char *, char **);
+void dhcpcd_dispatch(int);
+DHCPCD_IF * dhcpcd_interfaces(DHCPCD_CONNECTION *);
+DHCPCD_IF * dhcpcd_if_find(DHCPCD_CONNECTION *, const char *);
+DHCPCD_CONNECTION * dhcpcd_if_connection(DHCPCD_IF *);
+
+bool dhcpcd_if_up(const DHCPCD_IF *);
+bool dhcpcd_if_down(const DHCPCD_IF *);
+char * dhcpcd_if_message(const DHCPCD_IF *);
+
+DHCPCD_WI_SCAN * dhcpcd_wi_scans(DHCPCD_CONNECTION *, DHCPCD_IF *);
+void dhcpcd_wi_scans_free(DHCPCD_WI_SCAN *);
+bool dhcpcd_wpa_command(DHCPCD_CONNECTION *, DHCPCD_IF *, const char *, int);
+bool dhcpcd_wpa_set_network(DHCPCD_CONNECTION *, DHCPCD_IF *,
+    int, const char *, const char *);
+int dhcpcd_wpa_find_network_new(DHCPCD_CONNECTION *, DHCPCD_IF *,
+    const char *);
+
+#define dhcpcd_rebind(c, i)                                                  \
+       dhcpcd_command(c, "Rebind", i ? (i)->ifname : NULL, NULL)
+#define dhcpcd_release(c, i)                                                 \
+       dhcpcd_command(c, "Release", i ? (i)->ifname : NULL, NULL)
+
+/* Our configuration is probably going to change ... */
+#ifdef IN_LIBDHCPCD
+typedef struct dhcpcd_config {
+       char *option;
+       char *value;
+       struct dhcpcd_config *next;
+} DHCPCD_CONFIG;
+#else
+typedef void *DHCPCD_CONFIG;
+#endif
+
+char ** dhcpcd_config_blocks_get(DHCPCD_CONNECTION *, const char *);
+DHCPCD_CONFIG * dhcpcd_config_load(DHCPCD_CONNECTION *,
+    const char *, const char *);
+void dhcpcd_config_free(DHCPCD_CONFIG *);
+const char * dhcpcd_config_get(DHCPCD_CONFIG *, const char *);
+const char * dhcpcd_config_get_static(DHCPCD_CONFIG *, const char *);
+bool dhcpcd_config_set(DHCPCD_CONFIG **, const char *, const char *);
+bool dhcpcd_config_set_static(DHCPCD_CONFIG **, const char *, const char *);
+bool dhcpcd_config_save(DHCPCD_CONNECTION *,
+    const char *, const char *, DHCPCD_CONFIG *);
+
+#endif
diff --git a/src/libdhcpcd/main.c b/src/libdhcpcd/main.c
new file mode 100644 (file)
index 0000000..327c3df
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * libdhcpcd
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+
+#define IN_LIBDHCPCD
+#include "libdhcpcd.h"
+
+#define DHCPCD_TIMEOUT_MS 500
+
+#ifndef _unused
+#  ifdef __GNUC__
+#    define _unused __attribute__((__unused__))
+#  else
+#    define _unused
+#  endif
+#endif
+
+DHCPCD_CONNECTION *dhcpcd_connections;
+DHCPCD_WATCH *dhcpcd_watching;
+
+static dbus_bool_t
+dhcpcd_add_watch(DBusWatch *watch, void *data)
+{
+       DHCPCD_WATCH *w;
+       int flags;
+
+       flags = dbus_watch_get_unix_fd(watch);
+       for (w = dhcpcd_watching; w; w = w->next) {
+               if (w->pollfd.fd == flags)
+                       break;
+       }
+       if (w == NULL) {
+               w = malloc(sizeof(*w));
+               if (w == NULL)
+                       return false;
+               w->next = dhcpcd_watching;
+               dhcpcd_watching = w;
+       }
+
+       w->connection = (DHCPCD_CONNECTION *)data;
+       w->watch = watch;
+       w->pollfd.fd = flags;
+       flags = dbus_watch_get_flags(watch);
+       w->pollfd.events = POLLHUP | POLLERR;
+       if (flags & DBUS_WATCH_READABLE)
+               w->pollfd.events |= POLLIN;
+       if (flags & DBUS_WATCH_WRITABLE)
+               w->pollfd.events |= POLLOUT;
+       if (w->connection->add_watch)
+               w->connection->add_watch(w->connection, &w->pollfd,
+                       w->connection->watch_data);
+       return true;
+}
+
+static void
+dhcpcd_delete_watch(DBusWatch *watch, void *data)
+{
+       DHCPCD_WATCH *w, *l;
+       int fd;
+
+       fd = dbus_watch_get_unix_fd(watch);
+       l = data = NULL;
+       for (w = dhcpcd_watching; w; w = w->next) {
+               if (w->pollfd.fd == fd) {
+                       if (w->connection->delete_watch)
+                               w->connection->delete_watch(w->connection,
+                                   &w->pollfd, w->connection->watch_data);
+                       if (l == NULL)
+                               dhcpcd_watching = w->next;
+                       else
+                               l->next = w->next;
+                       free(w);
+                       w = l;
+               }
+       }
+}
+
+static DBusHandlerResult
+dhcpcd_message(_unused DBusConnection *bus, DBusMessage *msg, void *data)
+{
+       if (dhcpcd_dispatch_message((DHCPCD_CONNECTION *)data, msg))
+               return DBUS_HANDLER_RESULT_HANDLED;
+       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+void
+dhcpcd_if_free(DHCPCD_IF *ifs)
+{
+       DHCPCD_IF *i;
+
+       while (ifs != NULL) {
+               i = ifs->next;
+               free(ifs);
+               ifs = i;
+       }
+}
+
+DHCPCD_CONNECTION *
+dhcpcd_open(char **error)
+{
+       DBusError err;
+       DHCPCD_CONNECTION *con;
+       DBusConnection *bus;
+       int tries;
+
+       dbus_error_init(&err);
+       bus = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+       if (dbus_error_is_set(&err)) {
+               if (error)
+                       *error = strdup(err.message);
+               dbus_error_free(&err);
+               return NULL;
+       }
+       if (bus == NULL)
+               return NULL;
+       con = malloc(sizeof(*con));
+       if (con == NULL)
+               goto bad;
+       memset(con, 0, sizeof(*con));
+       con->bus = bus;
+       if (!dbus_connection_set_watch_functions(bus,
+               dhcpcd_add_watch, dhcpcd_delete_watch, NULL, con, NULL))
+               goto bad;
+       dbus_bus_add_match(bus,
+           "type='signal',interface='" DHCPCD_SERVICE "'", &err);
+       dbus_connection_flush(bus);
+       if (dbus_error_is_set(&err)) {
+               if (error)
+                       *error = strdup(err.message);
+               dbus_error_free(&err);
+               goto bad;
+       }
+       if (!dbus_connection_add_filter(bus, dhcpcd_message, con, NULL))
+               goto bad;
+
+       /* Give dhcpcd-dbus a little time to automatically start */
+       tries = 5;
+       while (--tries > 0) {
+               if (dhcpcd_command(con, "GetVersion", NULL, NULL)) {
+                       dhcpcd_error_clear(con);
+                       break;
+               }
+       }
+
+       con->next = dhcpcd_connections;
+       dhcpcd_connections = con;
+
+       return con;
+
+bad:
+       free(con);
+       dbus_connection_unref(bus);
+       return NULL;
+}
+
+bool
+dhcpcd_close(DHCPCD_CONNECTION *con)
+{
+       DHCPCD_CONNECTION *c, *l;
+
+       l = NULL;
+       for (c = dhcpcd_connections; c; c = c->next) {
+               if (c == con) {
+                       if (l == NULL)
+                               dhcpcd_connections = con->next;
+                       else
+                               l->next = con->next;
+                       dbus_connection_unref(con->bus);
+                       dhcpcd_if_free(con->interfaces);
+                       free(con->status);
+                       free(con->error);
+                       free(con);
+                       return true;
+               }
+               l = c;
+       }
+       dhcpcd_error_set(con, NULL, ESRCH);
+       return false;
+}
+
+DHCPCD_CONNECTION *
+dhcpcd_if_connection(DHCPCD_IF *interface)
+{
+       DHCPCD_CONNECTION *c;
+       DHCPCD_IF *i;
+
+       for (c = dhcpcd_connections; c; c = c->next) {
+               for (i = c->interfaces; i; i = i->next)
+                       if (i == interface)
+                               return c;
+       }
+       return NULL;
+}
+
+void
+dhcpcd_error_clear(DHCPCD_CONNECTION *con)
+{
+       free(con->error);
+       con->error = NULL;
+       con->err = 0;
+}
+
+void
+dhcpcd_error_set(DHCPCD_CONNECTION *con, const char *error, int err)
+{
+       dhcpcd_error_clear(con);
+       if (error != NULL) {
+               con->error = strdup(error);
+               if (err == 0)
+                       err = EPROTO;
+       } else if (err != 0)
+               con->error = strdup(strerror(err));
+       con->err = err;
+       con->errors++;
+}
+
+const char *
+dhcpcd_error(DHCPCD_CONNECTION *con)
+{
+       return con->error;
+}
+
+bool
+dhcpcd_iter_get(DHCPCD_CONNECTION *con, DBusMessageIter *iter,
+    int type, void *arg)
+{
+       if (dbus_message_iter_get_arg_type(iter) == type) {
+               dbus_message_iter_get_basic(iter, arg);
+               dbus_message_iter_next(iter);
+               return true;
+       }
+       dhcpcd_error_set(con, 0, EINVAL);
+       return false;
+}
+
+static bool
+dhcpcd_message_error(DHCPCD_CONNECTION *con, DHCPCD_MESSAGE *msg)
+{
+       DBusMessageIter args;
+       char *s;
+       
+       if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR)
+               return false;
+       if (dbus_message_iter_init(msg, &args) &&
+           dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_STRING)
+       {
+               dbus_message_iter_get_basic(&args, &s);
+               dhcpcd_error_set(con, s, 0);
+       }
+       return true;
+}
+
+DHCPCD_MESSAGE *
+dhcpcd_send_reply(DHCPCD_CONNECTION *con, DHCPCD_MESSAGE *msg)
+{
+       DBusMessage *reply;
+       DBusPendingCall *pending;
+
+       pending = NULL;
+       if (!dbus_connection_send_with_reply(con->bus, msg, &pending,
+               DHCPCD_TIMEOUT_MS) ||
+           pending == NULL)
+               return NULL;
+       dbus_connection_flush(con->bus);
+
+       /* Block until we receive a reply */
+       dbus_pending_call_block(pending);
+       reply = dbus_pending_call_steal_reply(pending);
+       dbus_pending_call_unref(pending);
+       if (dhcpcd_message_error(con, reply)) {
+               dbus_message_unref(reply);
+               return NULL;
+       }
+       return reply;
+}
+
+DHCPCD_MESSAGE *
+dhcpcd_message_reply(DHCPCD_CONNECTION *con, const char *cmd, const char *arg)
+{
+       DBusMessage *msg, *reply;
+       DBusMessageIter args;
+       
+       msg = dbus_message_new_method_call(DHCPCD_SERVICE, DHCPCD_PATH,
+           DHCPCD_SERVICE, cmd);
+       if (msg == NULL) {
+               dhcpcd_error_set(con, 0, errno);
+               return NULL;
+       }
+       dbus_message_iter_init_append(msg, &args);
+       if (arg != NULL &&
+           !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &arg))
+       {
+               dbus_message_unref(msg);
+               dhcpcd_error_set(con, 0, EINVAL);
+               return NULL;
+       }
+       reply = dhcpcd_send_reply(con, msg);
+       dbus_message_unref(msg);
+       return reply;
+}
+
+bool
+dhcpcd_command(DHCPCD_CONNECTION *con, const char *cmd, const char *arg,
+       char **reply)
+{
+       DBusMessage *msg;
+       DBusMessageIter args;
+       char *s;
+
+       msg = dhcpcd_message_reply(con, cmd, arg);
+       if (msg == NULL)
+               return false;
+       if (dhcpcd_message_error(con, msg)) {
+               dbus_message_unref(msg);
+               return false;
+       }
+       if (reply != NULL &&
+           dbus_message_iter_init(msg, &args) &&
+           dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_STRING)
+       {
+               dbus_message_iter_get_basic(&args, &s);
+               *reply = strdup(s);
+       }
+       dbus_message_unref(msg);
+       return true;
+}
+
+void
+dhcpcd_dispatch(int fd)
+{
+       DHCPCD_WATCH *w;
+       struct pollfd fds;
+       int n, flags;
+
+       fds.fd = fd;
+       fds.events = (POLLIN | POLLHUP | POLLOUT | POLLERR);
+       n = poll(&fds, 1, 0);
+       flags = 0;
+       if (n == 1) {
+               if (fds.revents & POLLIN)
+                       flags |= DBUS_WATCH_READABLE;
+               if (fds.revents & POLLOUT)
+                       flags |= DBUS_WATCH_WRITABLE;
+               if (fds.revents & POLLHUP)
+                       flags |= DBUS_WATCH_HANGUP;
+               if (fds.revents & POLLERR)
+                       flags |= DBUS_WATCH_ERROR;
+       }
+       for (w = dhcpcd_watching; w; w = w->next) {
+               if (w->pollfd.fd == fd) {
+                       if (flags != 0)
+                               dbus_watch_handle(w->watch, flags);
+                       dbus_connection_ref(w->connection->bus);
+                       while (dbus_connection_dispatch(w->connection->bus) ==
+                           DBUS_DISPATCH_DATA_REMAINS)
+                               ;
+                       dbus_connection_unref(w->connection->bus);
+               }
+       }
+}
+
+DHCPCD_IF *
+dhcpcd_if_new(DHCPCD_CONNECTION *con, DBusMessageIter *array, char **order)
+{
+       DBusMessageIter dict, entry, var;
+       DHCPCD_IF *i;
+       char *s;
+       uint32_t u32;
+       bool b;
+       int errors;
+
+       if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) {
+               errno = EINVAL;
+               return NULL;
+       }
+       dbus_message_iter_recurse(array, &dict);
+       i = malloc(sizeof(*i));
+       if (i == NULL) {
+               dhcpcd_error_set(con, 0, errno);
+               return NULL;
+       }
+       memset(i, 0, sizeof(*i));
+       errors = con->errors;
+       for (;
+            dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY;
+            dbus_message_iter_next(&dict))
+       {
+               dbus_message_iter_recurse(&dict, &entry);
+               if (!dhcpcd_iter_get(con, &entry, DBUS_TYPE_STRING, &s))
+                       break;
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+                       break;
+               dbus_message_iter_recurse(&entry, &var);
+               if (strcmp(s, "Interface") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, &s))
+                               break;
+                       strlcpy(i->ifname, s, sizeof(i->ifname));
+               } else if (strcmp(s, "Flags") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_UINT32, &u32))
+                               break;
+                       i->flags = u32;
+               } else if (strcmp(s, "Reason") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, &s))
+                               break;
+                       strlcpy(i->reason, s, sizeof(i->reason));
+               } else if (strcmp(s, "Wireless") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_BOOLEAN, &b))
+                               break;
+                       i->wireless = b;
+               } else if (strcmp(s, "SSID") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, &s))
+                               break;
+                       strlcpy(i->ssid, s, sizeof(i->ssid));
+               } else if (strcmp(s, "IPAddress") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_UINT32, &u32))
+                               break;
+                               i->ip.s_addr = u32;
+               } else if (strcmp(s, "SubnetCIDR") == 0)
+                       dbus_message_iter_get_basic(&var, &i->cidr);
+               else if (order != NULL && strcmp(s, "InterfaceOrder") == 0)
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, order))
+                               break;
+       }
+
+       if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+               free(i);
+               if (con->errors == errors)
+                       dhcpcd_error_set(con, NULL, EINVAL);
+               return NULL;
+       }
+       return i;
+}
+
+DHCPCD_IF *
+dhcpcd_interfaces(DHCPCD_CONNECTION *con)
+{
+       DBusMessage *msg;
+       DBusMessageIter args, dict, entry;
+       DHCPCD_IF *i, *l;
+       int errors;
+       
+       if (con->interfaces != NULL)
+               return con->interfaces;
+       l = NULL;
+       msg = dhcpcd_message_reply(con, "GetInterfaces", NULL);
+       if (msg == NULL)
+               return NULL;
+       if (!dbus_message_iter_init(msg, &args) ||
+           dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
+       {
+               dbus_message_unref(msg);
+               dhcpcd_error_set(con, 0, EINVAL);
+               return NULL;
+       }
+
+       l = NULL;
+       errors = con->errors;
+       dbus_message_iter_recurse(&args, &dict);
+       for (;
+            dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY;
+            dbus_message_iter_next(&dict))    
+       {
+               dbus_message_iter_recurse(&dict, &entry);
+               dbus_message_iter_next(&entry);
+               i = dhcpcd_if_new(con, &entry, NULL);
+               if (i == NULL)
+                       break;
+               if (l == NULL)
+                       con->interfaces = i;
+               else
+                       l->next = i;
+               l = i;
+       }
+       dbus_message_unref(msg);
+       if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+               if (con->errors == errors)
+                       dhcpcd_error_set(con, 0, EINVAL);
+               dhcpcd_if_free(con->interfaces);
+               con->interfaces = NULL;
+       }
+       return con->interfaces;
+}
+
+DHCPCD_IF *
+dhcpcd_if_find(DHCPCD_CONNECTION *con, const char *ifname)
+{
+       DHCPCD_IF *i;
+
+       if (con->interfaces == NULL)
+               dhcpcd_interfaces(con);
+       for (i = con->interfaces; i; i = i ->next)
+               if (strcmp(i->ifname, ifname) == 0)
+                       return i;
+       return NULL;
+}
+
+const char *
+dhcpcd_status(DHCPCD_CONNECTION *con)
+{
+       if (con->status == NULL)
+               dhcpcd_command(con, "GetStatus", NULL, &con->status);
+       return con->status;
+}
+
+void
+dhcpcd_set_watch_functions(DHCPCD_CONNECTION *con,
+    void (*add_watch)(DHCPCD_CONNECTION *, const struct pollfd *, void *),
+    void (*delete_watch)(DHCPCD_CONNECTION *, const struct pollfd *, void *),
+    void *data)
+{
+       DHCPCD_WATCH *w;
+       
+       con->add_watch = add_watch;
+       con->delete_watch = delete_watch;
+       con->watch_data = data;
+       if (con->add_watch) {
+               for (w = dhcpcd_watching; w; w = w->next)
+                       if (w->connection == con)
+                               con->add_watch(con, &w->pollfd, data);
+       }
+}
+
+void
+dhcpcd_set_signal_functions(DHCPCD_CONNECTION *con,
+    void (*event)(DHCPCD_CONNECTION *, DHCPCD_IF *, void *),
+    void (*status_changed)(DHCPCD_CONNECTION *, const char *, void *),
+    void (*wi_scanresults)(DHCPCD_CONNECTION *, DHCPCD_IF *, void *),
+    void *data)
+{
+       DHCPCD_IF *i;
+       
+       con->event = event;
+       con->status_changed = status_changed;
+       con->wi_scanresults = wi_scanresults;
+       con->signal_data = data;
+       if (con->status_changed) {
+               if (con->status == NULL)
+                       dhcpcd_status(con);
+               con->status_changed(con, con->status, data);
+       }
+       if (con->wi_scanresults) {
+               for (i = dhcpcd_interfaces(con); i; i = i->next)
+                       if (i->wireless)
+                               con->wi_scanresults(con, i, data);
+       }
+}
diff --git a/src/libdhcpcd/misc.c b/src/libdhcpcd/misc.c
new file mode 100644 (file)
index 0000000..0037d8f
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * libdhcpcd
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <libintl.h>
+
+#define IN_LIBDHCPCD
+#include "libdhcpcd.h"
+
+#define _ gettext
+
+static const char *const dhcpcd_up_reasons[] = {
+       "BOUND",
+       "RENEW",
+       "REBIND",
+       "REBOOT",
+       "IPV4LL",
+       "INFORM",
+       "STATIC",
+       "TIMEOUT",
+       NULL
+};
+
+static const char *const dhcpcd_down_reasons[] = {
+       "EXPIRE",
+       "FAIL",
+       "NAK",
+       "NOCARRIER",
+       "STOP",
+       NULL
+};
+
+bool
+dhcpcd_if_up(const DHCPCD_IF *i)
+{
+       const char *const *r;
+
+       for (r = dhcpcd_up_reasons; *r; r++)
+               if (strcmp(*r, i->reason) == 0)
+                       return true;
+       return false;
+}
+
+bool
+dhcpcd_if_down(const DHCPCD_IF *i)
+{
+       const char *const *r;
+
+       for (r = dhcpcd_down_reasons; *r; r++)
+               if (strcmp(*r, i->reason) == 0)
+                       return true;
+       return false;
+}
+
+char *
+dhcpcd_if_message(const DHCPCD_IF *i)
+{
+       char *msg, *p;
+       const char *reason = NULL;
+       size_t len;
+       bool showip, showssid;
+    
+       showip = true;
+       showssid = false;
+       if (dhcpcd_if_up(i))
+               reason = _("Acquired address");
+       else if (strcmp(i->reason, "EXPIRE") == 0)
+               reason = _("Expired");
+       else if (strcmp(i->reason, "CARRIER") == 0) {
+               if (i->wireless) {
+                       reason = _("Associated with");
+                       if (i->ssid != NULL)
+                               showssid = true;
+               } else
+                       reason = _("Cable plugged in");
+               showip = false;
+       } else if (strcmp(i->reason, "NOCARRIER") == 0) {
+               if (i->wireless) {
+                       if (i->ssid != NULL || i->ip.s_addr != 0) {
+                               reason = _("Disassociated from");
+                               showssid = true;
+                       } else
+                               reason = _("Not associated");
+               } else
+                       reason = _("Cable unplugged");
+               showip = false;
+       } else if (strcmp(i->reason, "FAIL") == 0)
+               reason = _("Automatic configuration not possible");
+       else if (strcmp(i->reason, "3RDPARTY") == 0)
+               reason = _("Waiting for 3rd Party configuration");
+
+       if (reason == NULL)
+               reason = i->reason;
+       
+       len = strlen(i->ifname) + 3;
+       len += strlen(reason) + 1;
+       if (i->ip.s_addr != 0) {
+               len += 16; /* 000. * 4 */
+               if (i->cidr != 0)
+                       len += 3; /* /32 */
+       }
+       if (showssid)
+               len += strlen(i->ssid) + 1;
+       msg = p = malloc(len);
+       p += snprintf(msg, len, "%s: %s", i->ifname, reason);
+       if (showssid)
+               p += snprintf(p, len - (p - msg), " %s", i->ssid);
+       if (i->ip.s_addr != 0 && showip) {
+               p += snprintf(p, len - (p - msg), " %s", inet_ntoa(i->ip));
+               if (i->cidr != 0)
+                       snprintf(p, len - (p - msg), "/%d", i->cidr);
+       }
+       return msg;
+}
diff --git a/src/libdhcpcd/wpa.c b/src/libdhcpcd/wpa.c
new file mode 100644 (file)
index 0000000..0e287b0
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * libdhcpcd
+ * Copyright 2009 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#define IN_LIBDHCPCD
+#include "libdhcpcd.h"
+
+void
+dhcpcd_wi_scans_free(DHCPCD_WI_SCAN *wis)
+{
+       DHCPCD_WI_SCAN *n;
+
+       while (wis) {
+               n = wis->next;
+               free(wis);
+               wis = n;
+       }
+}
+
+static DHCPCD_WI_SCAN *
+dhcpcd_scanresult_new(DHCPCD_CONNECTION *con, DBusMessageIter *array)
+{
+       DBusMessageIter dict, entry, var;
+       DHCPCD_WI_SCAN *wis;
+       char *s;
+       int32_t i32;
+       int errors;
+
+       wis = malloc(sizeof(*wis));
+       if (wis == NULL) {
+               dhcpcd_error_set(con, NULL, errno);
+               return NULL;
+       }
+       memset(wis, 0, sizeof(*wis));
+       errors = con->errors;
+       dbus_message_iter_recurse(array, &dict);
+       for (;
+            dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY;
+            dbus_message_iter_next(&dict))
+       {
+               dbus_message_iter_recurse(&dict, &entry);
+               if (!dhcpcd_iter_get(con, &entry, DBUS_TYPE_STRING, &s))
+                   break;
+               if (dbus_message_iter_get_arg_type(&entry) !=
+                   DBUS_TYPE_VARIANT)
+                       break;
+               dbus_message_iter_recurse(&entry, &var);
+               if (strcmp(s, "BSSID") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, &s))
+                               break;
+                       strlcpy(wis->bssid, s, sizeof(wis->bssid));
+               } else if (strcmp(s, "Frequency") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_INT32, &i32))
+                               break;
+                       wis->frequency = i32;
+               } else if (strcmp(s, "Quality") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_INT32, &i32))
+                               break;
+                       wis->quality = i32;
+               } else if (strcmp(s, "Noise") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_INT32, &i32))
+                               break;
+                       wis->noise = i32;
+               } else if (strcmp(s, "Level") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_INT32, &i32))
+                               break;
+                       wis->level = i32;
+               } else if (strcmp(s, "Flags") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, &s))
+                               break;
+                       strlcpy(wis->flags, s, sizeof(wis->flags));
+               } else if (strcmp(s, "SSID") == 0) {
+                       if (!dhcpcd_iter_get(con, &var, DBUS_TYPE_STRING, &s))
+                               break;
+                       strlcpy(wis->ssid, s, sizeof(wis->ssid));
+               }
+       }
+       if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+               if (con->errors == errors)
+                       dhcpcd_error_set(con, NULL, EINVAL);
+               free(wis);
+               return NULL;
+       }
+       return wis;
+}
+
+DHCPCD_WI_SCAN *
+dhcpcd_wi_scans(DHCPCD_CONNECTION *con, DHCPCD_IF *i)
+{
+       DBusMessage *msg;
+       DBusMessageIter args, array;
+       DHCPCD_WI_SCAN *wis, *scans, *l;
+       int errors;
+
+       msg = dhcpcd_message_reply(con, "ScanResults", i->ifname);
+       if (!dbus_message_iter_init(msg, &args) ||
+           dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
+       {
+               dhcpcd_error_set(con, NULL, EINVAL);
+               return NULL;
+       }
+
+       scans = l = NULL;
+       errors = con->errors;
+       dbus_message_iter_recurse(&args, &array);
+       for(;
+           dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY;
+           dbus_message_iter_next(&array))
+       {
+               wis = dhcpcd_scanresult_new(con, &array);
+               if (wis == NULL)
+                       break;
+               if (l == NULL)
+                       scans = l = wis;
+               else {
+                       l->next = wis;
+                       l = l->next;
+               }
+       }
+       if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
+               if (con->errors == errors)
+                       dhcpcd_error_set(con, NULL, EINVAL);
+               dhcpcd_wi_scans_free(scans);
+               scans = NULL;
+       }
+       dbus_message_unref(msg);
+       return scans;
+}
+
+static int
+dhcpcd_wpa_find_network(DHCPCD_CONNECTION *con, DHCPCD_IF *i, const char *ssid)
+{
+       DBusMessage *msg;
+       DBusMessageIter args, array, entry;
+       int32_t id;
+       char *s;
+       int errors;
+
+       msg = dhcpcd_message_reply(con, "ListNetworks", i->ifname);
+       if (msg == NULL)
+               return -1;
+       if (!dbus_message_iter_init(msg, &args)) {
+               dhcpcd_error_set(con, NULL, EINVAL);
+               return -1;
+       }
+
+       errors = con->errors;
+       for(;
+           dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_ARRAY;
+           dbus_message_iter_next(&args))
+       {
+               dbus_message_iter_recurse(&args, &array);
+               for(;
+                   dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT;
+                   dbus_message_iter_next(&array))
+               {
+                       dbus_message_iter_recurse(&array, &entry);
+                       if (!dhcpcd_iter_get(con, &entry,
+                               DBUS_TYPE_INT32, &id) ||
+                           !dhcpcd_iter_get(con, &entry,
+                               DBUS_TYPE_STRING, &s))
+                               break;
+                       if (strcmp(s, ssid) == 0) {
+                               dbus_message_unref(msg);
+                               return (int)id;
+                       }
+               }
+       }
+       if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_INVALID &&
+           con->errors == errors)
+               dhcpcd_error_set(con, NULL, EINVAL);
+       dbus_message_unref(msg);
+       return -1;
+}
+       
+static int
+dhcpcd_wpa_add_network(DHCPCD_CONNECTION *con, DHCPCD_IF *i)
+{
+       DBusMessage *msg;
+       DBusMessageIter args;
+       int32_t id;
+       int ret;
+
+       msg = dhcpcd_message_reply(con, "AddNetwork", i->ifname);
+       if (msg == NULL)
+               return -1;
+       ret = -1;
+       if (dbus_message_iter_init(msg, &args)) {
+               if (dhcpcd_iter_get(con, &args, DBUS_TYPE_INT32, &id))
+                       ret = id;
+       } else
+               dhcpcd_error_set(con, NULL, EINVAL);
+       dbus_message_unref(msg);
+       return ret;
+}
+
+bool
+dhcpcd_wpa_set_network(DHCPCD_CONNECTION *con, DHCPCD_IF *i, int id,
+    const char *opt, const char *val)
+{
+       DBusMessage *msg, *reply;
+       DBusMessageIter args;
+       bool retval;
+       char *ifname;
+
+       msg = dbus_message_new_method_call(DHCPCD_SERVICE, DHCPCD_PATH,
+           DHCPCD_SERVICE, "SetNetwork");
+       if (msg == NULL) {
+               dhcpcd_error_set(con, 0, errno);
+               return false;
+       }
+       dbus_message_iter_init_append(msg, &args);
+       ifname = i->ifname;
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &ifname);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &id);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &opt);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &val);
+       reply = dhcpcd_send_reply(con, msg);
+       dbus_message_unref(msg);
+       if (reply == NULL)
+               retval = false;
+       else {
+               dbus_message_unref(reply);
+               retval = true;
+       }
+       return retval;
+}
+
+int
+dhcpcd_wpa_find_network_new(DHCPCD_CONNECTION *con, DHCPCD_IF *i,
+    const char *ssid)
+{
+       int errors, id;
+       char *q;
+       size_t len;
+       bool retval;
+
+       len = strlen(ssid) + 3;
+       q = malloc(len);
+       if (q == NULL) {
+               dhcpcd_error_set(con, 0, errno);
+               return -1;
+       }
+       errors = con->errors;
+       id = dhcpcd_wpa_find_network(con, i, ssid);
+       if (id != -1 || con->errors != errors) {
+               free(q);
+               return id;
+       }
+       id = dhcpcd_wpa_add_network(con, i);
+       if (id == -1) {
+               free(q);
+               return -1;
+       }
+       snprintf(q, len, "\"%s\"", ssid);
+       retval = dhcpcd_wpa_set_network(con, i, id, "ssid", q);
+       free(q);
+       return retval;
+}
+
+bool
+dhcpcd_wpa_command(DHCPCD_CONNECTION *con, DHCPCD_IF *i,
+    const char *cmd, int id)
+{
+       DBusMessage *msg, *reply;
+       DBusMessageIter args;
+       char *ifname;
+       bool retval;
+       
+       msg = dbus_message_new_method_call(DHCPCD_SERVICE, DHCPCD_PATH,
+           DHCPCD_SERVICE, cmd);
+       if (msg == NULL) {
+               dhcpcd_error_set(con, 0, errno);
+               return false;
+       }
+       dbus_message_iter_init_append(msg, &args);
+       ifname = i->ifname;
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &ifname);
+       if (id != -1)
+               dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &id);
+       reply = dhcpcd_send_reply(con, msg);
+       dbus_message_unref(msg);
+       if (reply == NULL)
+               retval = false;
+       else {
+               dbus_message_unref(reply);
+               retval = true;
+       }
+       return retval;
+}
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index 0c3874d..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* TODO: Animate the icon from carrier -> address
- * maybe use network-idle -> network-transmit ->
- * network-receive -> network-transmit-receive */
-
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libnotify/notify.h>
-
-#include "dhcpcd-gtk.h"
-#include "menu.h"
-
-DBusGProxy *dbus = NULL;
-GSList *interfaces = NULL;
-GtkIconTheme *icontheme = NULL;
-
-static GtkStatusIcon *status_icon;
-static int ani_timer;
-static int ani_counter;
-static bool online;
-static bool carrier;
-static char **interface_order;
-static NotifyNotification *nn;
-
-const char *const up_reasons[] = {
-       "BOUND",
-       "RENEW",
-       "REBIND",
-       "REBOOT",
-       "IPV4LL",
-       "INFORM",
-       "STATIC",
-       "TIMEOUT",
-       NULL
-};
-
-const char *const down_reasons[] = {
-       "EXPIRE",
-       "FAIL",
-       "NAK",
-       "NOCARRIER",
-       "STOP",
-       NULL
-};
-
-static bool
-ignore_if_msg(const struct if_msg *ifm)
-{
-       if (g_strcmp0(ifm->reason, "STOP") == 0 ||
-           g_strcmp0(ifm->reason, "RELEASE") == 0)
-               return true;
-       return false;
-}
-
-static struct if_msg *
-find_if_msg(const char *iface)
-{
-       GSList *gl;
-       struct if_msg *ifm;
-
-       for (gl = interfaces; gl; gl = gl->next) {
-               ifm = (struct if_msg *)gl->data;
-               if (g_strcmp0(ifm->ifname, iface) == 0)
-                       return ifm;
-       }
-       return NULL;
-}
-
-static void
-free_if_ap(struct if_ap *ifa)
-{
-       g_free(ifa->ifname);
-       g_free(ifa->bssid);
-       g_free(ifa->flags);
-       g_free(ifa->ssid);
-       g_free(ifa);
-}
-
-static void
-free_if_msg(struct if_msg *ifm)
-{
-       GSList *gl;
-
-       g_free(ifm->ifname);
-       g_free(ifm->reason);
-       g_free(ifm->ssid);
-       for (gl = ifm->scan_results; gl; gl = gl->next)
-               free_if_ap((struct if_ap *)gl->data);
-       g_slist_free(ifm->scan_results);
-       g_free(ifm);
-}
-
-static void
-error_exit(const char *msg, GError *error)
-{
-       GtkWidget *dialog;
-
-       if (error) {
-               g_critical("%s: %s", msg, error->message);
-               dialog = gtk_message_dialog_new(NULL, 0,
-                   GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
-                   "%s: %s", msg, error->message);
-       } else {
-               g_critical("%s", msg);
-               dialog = gtk_message_dialog_new(NULL, 0,
-                   GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", msg);
-       }
-       gtk_dialog_run(GTK_DIALOG(dialog));
-       gtk_widget_destroy(dialog);
-       if (gtk_main_level())
-               gtk_main_quit();
-       else
-               exit(EXIT_FAILURE);
-}
-
-static GSList *
-get_scan_results(struct if_msg *ifm)
-{
-       GType otype;
-       GError *error;
-       GPtrArray *array;
-       GHashTable *config;
-       GSList *list = NULL;
-       struct if_ap *ifa;
-       guint i;
-       GValue *val;
-
-       otype = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
-       otype = dbus_g_type_get_collection("GPtrArray", otype);
-
-       error = NULL;
-       if (!dbus_g_proxy_call(dbus, "ScanResults", &error,
-               G_TYPE_STRING, ifm->ifname, G_TYPE_INVALID,
-               otype, &array, G_TYPE_INVALID))
-               error_exit(_("ScanResults"), error);
-
-       for (i = 0; i < array->len; i++) {
-               config = g_ptr_array_index(array, i);
-               val = g_hash_table_lookup(config, "BSSID");
-               if (val == NULL)
-                       continue;
-               ifa = g_malloc0(sizeof(*ifa));
-               ifa->ifname = g_strdup(ifm->ifname);
-               ifa->bssid = g_strdup(g_value_get_string(val));
-               val = g_hash_table_lookup(config, "Frequency");
-               if (val)
-                       ifa->frequency = g_value_get_int(val);
-               val = g_hash_table_lookup(config, "Quality");
-               if (val)
-                       ifa->quality = g_value_get_int(val);
-               val = g_hash_table_lookup(config, "Noise");
-               if (val)
-                       ifa->noise = g_value_get_int(val);
-               val = g_hash_table_lookup(config, "Level");
-               if (val)
-                       ifa->level = g_value_get_int(val);
-               val = g_hash_table_lookup(config, "Flags");
-               if (val)
-                       ifa->flags = g_strdup(g_value_get_string(val));
-               val = g_hash_table_lookup(config, "SSID");
-               if (val)
-                       ifa->ssid = g_strdup(g_value_get_string(val));
-               list = g_slist_append(list, ifa);
-       }
-       return list;
-}
-
-static struct if_msg *
-make_if_msg(GHashTable *config)
-{
-       GValue *val;
-       struct if_msg *ifm;
-
-       val = g_hash_table_lookup(config, "Interface");
-       if (val == NULL)
-               return NULL;
-       ifm = g_malloc0(sizeof(*ifm));
-       ifm->ifname = g_strdup(g_value_get_string(val));
-       val = g_hash_table_lookup(config, "Flags");
-       if (val)
-               ifm->flags = g_value_get_uint(val);
-       val = g_hash_table_lookup(config, "Reason");
-       if (val)
-               ifm->reason = g_strdup(g_value_get_string(val));
-       val = g_hash_table_lookup(config, "Wireless");
-       if (val)
-               ifm->wireless = g_value_get_boolean(val);
-       if (ifm->wireless) {
-               val = g_hash_table_lookup(config, "SSID");
-               if (val)
-                       ifm->ssid = g_strdup(g_value_get_string(val));
-       }
-       val = g_hash_table_lookup(config, "IPAddress");
-       if (val)
-               ifm->ip.s_addr = g_value_get_uint(val);
-       val = g_hash_table_lookup(config, "SubnetCIDR");
-       if (val)
-               ifm->cidr = g_value_get_uchar(val);
-       val = g_hash_table_lookup(config, "InterfaceOrder");
-       if (val) {
-               g_strfreev(interface_order);
-               interface_order = g_strsplit(g_value_get_string(val), " ", 0);
-       }
-       return ifm;
-}
-
-static bool
-if_up(const struct if_msg *ifm)
-{
-       const char *const *r;
-
-       for (r = up_reasons; *r; r++)
-               if (g_strcmp0(*r, ifm->reason) == 0)
-                       return true;
-       return false;
-}
-
-static char *
-print_if_msg(const struct if_msg *ifm)
-{
-       char *msg, *p;
-       const char *reason = NULL;
-       size_t len;
-       bool showip, showssid;
-    
-       showip = true;
-       showssid = false;
-       if (if_up(ifm))
-               reason = N_("Acquired address");
-       else if (g_strcmp0(ifm->reason, "EXPIRE") == 0)
-               reason = N_("Expired");
-       else if (g_strcmp0(ifm->reason, "CARRIER") == 0) {
-               if (ifm->wireless) {
-                       reason = N_("Associated with");
-                       if (ifm->ssid != NULL)
-                               showssid = true;
-               } else
-                       reason = N_("Cable plugged in");
-               showip = false;
-       } else if (g_strcmp0(ifm->reason, "NOCARRIER") == 0) {
-               if (ifm->wireless) {
-                       if (ifm->ssid != NULL || ifm->ip.s_addr != 0) {
-                               reason = N_("Disassociated from");
-                               showssid = true;
-                       } else
-                               reason = N_("Not associated");
-               } else
-                       reason = N_("Cable unplugged");
-               showip = false;
-       } else if (g_strcmp0(ifm->reason, "FAIL") == 0)
-               reason = N_("Automatic configuration not possible");
-       else if (g_strcmp0(ifm->reason, "3RDPARTY") == 0)
-               reason = N_("Waiting for 3rd Party configuration");
-
-       if (reason == NULL)
-               reason = ifm->reason;
-       
-       len = strlen(ifm->ifname) + 3;
-       len += strlen(reason) + 1;
-       if (ifm->ip.s_addr != 0) {
-               len += 16; /* 000. * 4 */
-               if (ifm->cidr != 0)
-                       len += 3; /* /32 */
-       }
-       if (showssid)
-               len += strlen(ifm->ssid) + 1;
-       msg = p = g_malloc(len);
-       p += g_snprintf(msg, len, "%s: %s", ifm->ifname, reason);
-       if (showssid)
-               p += g_snprintf(p, len - (p - msg), " %s", ifm->ssid);
-       if (ifm->ip.s_addr != 0 && showip) {
-               p += g_snprintf(p, len - (p - msg), " %s", inet_ntoa(ifm->ip));
-               if (ifm->cidr != 0)
-                       g_snprintf(p, len - (p - msg), "/%d", ifm->cidr);
-       }
-       return msg;
-}
-
-static int
-if_msg_comparer(gconstpointer a, gconstpointer b)
-{
-       const struct if_msg *ifa, *ifb;
-       const char *const *order;
-
-       ifa = (const struct if_msg *)a;
-       ifb = (const struct if_msg *)b;
-       for (order = (const char *const *)interface_order; *order; order++) {
-               if (g_strcmp0(*order, ifa->ifname) == 0)
-                       return -1;
-               if (g_strcmp0(*order, ifb->ifname) == 0)
-                       return 1;
-       }
-       return 0;
-}
-
-static gboolean
-animate_carrier(_unused gpointer data)
-{
-       const char *icon;
-       
-       if (ani_timer == 0)
-               return false;
-
-       switch(ani_counter++) {
-       case 0:
-               icon = "network-transmit";
-               break;
-       case 1:
-               icon = "network-receive";
-               break;
-       default:
-               icon = "network-idle";
-               ani_counter = 0;
-               break;
-       }
-       gtk_status_icon_set_from_icon_name(status_icon, icon);
-       return true;
-}
-
-static gboolean
-animate_online(_unused gpointer data)
-{
-       const char *icon;
-       
-       if (ani_timer == 0)
-               return false;
-
-       if (ani_counter++ > 6) {
-               ani_timer = 0;
-               ani_counter = 0;
-               return false;
-       }
-
-       if (ani_counter % 2 == 0)
-               icon = "network-idle";
-       else
-               icon = "network-transmit-receive";
-       gtk_status_icon_set_from_icon_name(status_icon, icon);
-       return true;
-}
-
-static void
-update_online(void)
-{
-       bool ison, iscarrier;
-       char *msg, *msgs, *tmp;
-       const GSList *gl;
-       const struct if_msg *ifm;
-
-       ison = iscarrier = false;
-       msgs = NULL;
-       for (gl = interfaces; gl; gl = gl->next) {
-               ifm = (const struct if_msg *)gl->data;
-               if (if_up(ifm))
-                       ison = iscarrier = true;
-               if (!iscarrier && g_strcmp0(ifm->reason, "CARRIER") == 0)
-                       iscarrier = true;
-               msg = print_if_msg(ifm);
-               if (msgs) {
-                       tmp = g_strconcat(msgs, "\n", msg, NULL);
-                       g_free(msgs);
-                       g_free(msg);
-                       msgs = tmp;
-               } else
-                       msgs = msg;
-       }
-
-       if (online != ison || carrier != iscarrier) {
-               online = ison;
-               if (ani_timer != 0) {
-                       g_source_remove(ani_timer);
-                       ani_timer = 0;
-                       ani_counter = 0;
-               }
-               if (ison) {
-                       animate_online(NULL);
-                       ani_timer = g_timeout_add(300, animate_online, NULL);
-               } else if (iscarrier) {
-                       animate_carrier(NULL);
-                       ani_timer = g_timeout_add(500, animate_carrier, NULL);
-               } else {
-                       gtk_status_icon_set_from_icon_name(status_icon,
-                           "network-offline");
-               }
-       }
-       gtk_status_icon_set_tooltip(status_icon, msgs);
-       g_free(msgs);
-}
-
-void
-notify_close(void)
-{
-       if (nn != NULL)
-               notify_notification_close(nn, NULL);
-}
-
-static void
-notify_closed(void)
-{
-       nn = NULL;
-}
-
-static void
-notify(const char *title, const char *msg, const char *icon)
-{
-       char **msgs, **m;
-
-       msgs = g_strsplit(msg, "\n", 0);
-       for (m = msgs; *m; m++)
-               g_message("%s", *m);
-       g_strfreev(msgs);
-       if (nn != NULL)
-               notify_notification_close(nn, NULL);
-       if (gtk_status_icon_get_visible(status_icon))
-               nn = notify_notification_new_with_status_icon(title,
-                   msg, icon, status_icon);
-       else
-               nn = notify_notification_new(title, msg, icon, NULL);
-       notify_notification_set_timeout(nn, 5000);
-       g_signal_connect(nn, "closed", G_CALLBACK(notify_closed), NULL);
-       notify_notification_show(nn, NULL);
-}
-
-static void
-dhcpcd_event(_unused DBusGProxy *proxy, GHashTable *config, _unused void *data)
-{
-       struct if_msg *ifm, *ifp;
-       bool rem;
-       GSList *gl;
-       char *msg;
-       const char *icon;
-       const char *const *r;
-
-       ifm = make_if_msg(config);
-       if (ifm == NULL)
-               return;
-
-       rem = ignore_if_msg(ifm);
-       ifp = NULL;
-       for (gl = interfaces; gl; gl = gl->next) {
-               ifp = (struct if_msg *)gl->data;
-               if (g_strcmp0(ifp->ifname, ifm->ifname) == 0) {
-                       ifm->scan_results = ifp->scan_results;
-                       ifp->scan_results = NULL;
-                       free_if_msg(ifp);
-                       if (rem)
-                               interfaces =
-                                   g_slist_delete_link(interfaces, gl);
-                       else
-                               gl->data = ifm;
-                       break;
-               }
-       }
-       if (ifp == NULL && !rem)
-               interfaces = g_slist_prepend(interfaces, ifm);
-       interfaces = g_slist_sort(interfaces, if_msg_comparer);
-       update_online();
-
-       /* We should ignore renew and stop so we don't annoy the user */
-       if (g_strcmp0(ifm->reason, "RENEW") == 0 ||
-           g_strcmp0(ifm->reason, "STOP") == 0)
-               return;
-
-       msg = print_if_msg(ifm);
-       if (if_up(ifm))
-               icon = "network-transmit-receive";
-       else
-               icon = "network-transmit";
-       for (r = down_reasons; *r; r++) {
-               if (g_strcmp0(*r, ifm->reason) == 0) {
-                       icon = "network-offline";
-                       break;
-               }
-       }
-       notify(_("Network event"), msg, icon);
-       g_free(msg);
-}
-
-static void
-foreach_make_ifm(_unused gpointer key, gpointer value, _unused gpointer data)
-{
-       struct if_msg *ifm;
-
-       ifm = make_if_msg((GHashTable *)value);
-       if (ignore_if_msg(ifm))
-               g_free(ifm);
-       else if (ifm)
-               interfaces = g_slist_prepend(interfaces, ifm);
-}
-
-static void
-dhcpcd_get_interfaces()
-{
-       GHashTable *ifs;
-       GError *error = NULL;
-       GType otype;
-       GSList *gl, *gsl;
-       GPtrArray *array;
-       struct if_msg *ifm;
-
-       otype = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
-       otype = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, otype);
-       if (!dbus_g_proxy_call(dbus, "GetInterfaces", &error,
-               G_TYPE_INVALID,
-               otype, &ifs, G_TYPE_INVALID))
-               error_exit("GetInterfaces", error);
-       g_hash_table_foreach(ifs, foreach_make_ifm, NULL);
-       g_hash_table_unref(ifs);
-
-       /* Each interface config only remembers the last order when
-        * that interface was configured, so get the real order now. */
-       g_strfreev(interface_order);
-       interface_order = NULL;
-       if (!dbus_g_proxy_call(dbus, "ListInterfaces", &error,
-               G_TYPE_INVALID,
-               G_TYPE_STRV, &interface_order, G_TYPE_INVALID))
-               error_exit("ListInterfaces", error);
-       interfaces = g_slist_sort(interfaces, if_msg_comparer);
-
-       otype = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
-       otype = dbus_g_type_get_collection("GPtrArray", otype);
-       for (gl = interfaces; gl; gl = gl->next) {
-               ifm = (struct if_msg *)gl->data;
-               if (!ifm->wireless)
-                       continue;
-               if (!dbus_g_proxy_call(dbus, "ScanResults", &error,
-                       G_TYPE_STRING, ifm->ifname, G_TYPE_INVALID,
-                       otype, &array, G_TYPE_INVALID)) 
-               {
-                       g_message("ScanResults: %s", error->message);
-                       g_clear_error(&error);
-                       continue;
-               }
-               for (gsl = ifm->scan_results; gsl; gsl = gsl->next)
-                       g_free(gsl->data);
-               g_slist_free(ifm->scan_results);
-               ifm->scan_results = get_scan_results(ifm);
-       }
-
-       update_online();
-}
-
-static void
-check_status(const char *status)
-{
-       static char *last = NULL;
-       GSList *gl;
-       char *version;
-       const char *msg;
-       bool refresh;
-       GError *error = NULL;
-
-       g_message("Status changed to %s", status);
-       if (g_strcmp0(status, "down") == 0) {
-               for (gl = interfaces; gl; gl = gl->next)
-                       free_if_msg((struct if_msg *)gl->data);
-               g_slist_free(interfaces);
-               interfaces = NULL;
-               update_online();
-               msg = N_(last ?
-                   "Connection to dhcpcd lost" : "dhcpcd not running");
-               gtk_status_icon_set_tooltip(status_icon, msg);
-               notify(_("No network"), msg, "network-offline");
-       }
-
-       refresh = false;
-       if (last == NULL) {
-               if (g_strcmp0(status, "down") != 0)
-                       refresh = true;
-       } else {
-               if (g_strcmp0(status, last) == 0)
-                       return;
-               if (g_strcmp0(last, "down") == 0)
-                       refresh = true;
-               g_free(last);
-       }
-       last = g_strdup(status);
-
-       if (!refresh)
-               return;
-       if (!dbus_g_proxy_call(dbus, "GetDhcpcdVersion", &error,
-               G_TYPE_INVALID,
-               G_TYPE_STRING, &version, G_TYPE_INVALID))
-               error_exit(_("GetDhcpcdVersion"), error);
-       g_message(_("Connected to %s-%s"), "dhcpcd", version);
-       g_free(version);
-       dhcpcd_get_interfaces();
-}
-
-static void
-dhcpcd_status(_unused DBusGProxy *proxy, const char *status,
-    _unused void *data)
-{
-       check_status(status);
-}
-
-static void
-dhcpcd_scan_results(_unused DBusGProxy *proxy, const char *iface,
-    _unused void *data)
-{
-       struct if_msg *ifm;
-       struct if_ap *ifa, *ifa2;
-       GSList *gl, *aps, *l;
-       char *txt, *ntxt;
-
-       ifm = find_if_msg(iface);
-       if (ifm == NULL)
-               return;
-       g_message(_("%s: Received scan results"), ifm->ifname);
-       aps = get_scan_results(ifm);
-       txt = NULL;
-       for (gl = aps; gl; gl = gl->next) {
-               ifa = (struct if_ap *)gl->data;
-               for (l = ifm->scan_results; l; l = l->next) {
-                       ifa2 = (struct if_ap *)l->data;
-                       if (g_strcmp0(ifa->ssid, ifa2->ssid) == 0)
-                               break;
-               }
-               if (l == NULL) {
-                       if (txt == NULL)
-                               txt = g_strdup(ifa->ssid);
-                       else {
-                               ntxt = g_strconcat(txt, "\n", ifa->ssid, NULL);
-                               g_free(txt);
-                               txt = ntxt;
-                       }
-               }
-       }
-       for (gl = ifm->scan_results; gl; gl = gl->next)
-               free_if_ap((struct if_ap *)gl->data);
-       g_slist_free(ifm->scan_results);
-       ifm->scan_results = aps;
-       if (txt != NULL) {
-               notify(strchr(txt, '\n') ?
-                   N_("New Access Points") : N_("New Access Point"),
-                   txt, "network-wireless");
-               g_free(txt);
-       }
-}
-
-int
-main(int argc, char *argv[])
-{
-       DBusGConnection *bus;
-       GError *error = NULL;
-       char *version = NULL;
-       GType otype;
-       int tries = 5;
-               
-       setlocale(LC_ALL, "");
-       bindtextdomain(PACKAGE, NULL);
-       bind_textdomain_codeset(PACKAGE, "UTF-8");
-       textdomain(PACKAGE); 
-
-       gtk_init(&argc, &argv);
-       g_set_application_name("Network Configurator");
-       icontheme = gtk_icon_theme_get_default();
-       gtk_icon_theme_append_search_path(icontheme, ICONDIR);
-       status_icon = gtk_status_icon_new_from_icon_name("network-offline");
-       
-       gtk_status_icon_set_tooltip(status_icon,
-           _("Connecting to dhcpcd ..."));
-       gtk_status_icon_set_visible(status_icon, true);
-
-       notify_init(PACKAGE);
-
-       g_message(_("Connecting to dbus ..."));
-       bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
-       if (bus == NULL || error != NULL)
-               error_exit(_("Could not connect to system bus"), error);
-       dbus = dbus_g_proxy_new_for_name(bus,
-           DHCPCD_SERVICE,
-           DHCPCD_PATH,
-           DHCPCD_SERVICE);
-
-       g_message(_("Connecting to dhcpcd-dbus ..."));
-       while (--tries > 0) {
-               g_clear_error(&error);
-               if (dbus_g_proxy_call_with_timeout(dbus, "GetVersion", 500,
-                       &error, G_TYPE_INVALID,
-                       G_TYPE_STRING, &version, G_TYPE_INVALID))
-                       break;
-       }
-       if (tries == 0)
-               error_exit(_("GetVersion"), error);
-       g_message(_("Connected to %s-%s"), "dhcpcd-dbus", version);
-       g_free(version);
-
-       gtk_status_icon_set_tooltip(status_icon, _("Triggering dhcpcd ..."));
-       online = false;
-       menu_init(status_icon);
-
-       if (!dbus_g_proxy_call(dbus, "GetStatus", &error,
-               G_TYPE_INVALID,
-               G_TYPE_STRING, &version, G_TYPE_INVALID))
-               error_exit(_("GetStatus"), error);
-       check_status(version);
-       g_free(version);
-
-       otype = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
-       dbus_g_proxy_add_signal(dbus, "Event",
-           otype, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal(dbus, "Event",
-           G_CALLBACK(dhcpcd_event), bus, NULL);
-       dbus_g_proxy_add_signal(dbus, "StatusChanged",
-           G_TYPE_STRING, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal(dbus, "StatusChanged",
-           G_CALLBACK(dhcpcd_status), bus, NULL);
-       dbus_g_proxy_add_signal(dbus, "ScanResults",
-           G_TYPE_STRING, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal(dbus, "ScanResults",
-           G_CALLBACK(dhcpcd_scan_results), bus, NULL);
-
-       gtk_main();
-       return 0;
-}
diff --git a/src/menu.h b/src/menu.h
deleted file mode 100644 (file)
index d179f0f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MENU_H
-#define MENU_H
-
-void menu_init(GtkStatusIcon *);
-
-#endif
diff --git a/src/prefs.h b/src/prefs.h
deleted file mode 100644 (file)
index 28a371d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef PREFS_H
-#define PREFS_H
-
-void dhcpcd_prefs_show(void);
-void dhcpcd_prefs_close(void);
-
-#endif
diff --git a/src/wpa.c b/src/wpa.c
deleted file mode 100644 (file)
index 01ca691..0000000
--- a/src/wpa.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "dhcpcd-gtk.h"
-#include "wpa.h"
-
-static int
-find_network(const char *ifname, const char *ssid)
-{
-       GType otype;
-       GError *error;
-       int id;
-       size_t i;
-       GPtrArray *array;
-       GValueArray *varray;
-       GValue *val;
-       const char *str;
-       char *nssid;
-
-       otype = dbus_g_type_get_struct("GValueArray",
-           G_TYPE_INT,
-           G_TYPE_STRING,
-           G_TYPE_STRING,
-           G_TYPE_STRING,
-           G_TYPE_INVALID);
-       otype = dbus_g_type_get_collection("GPtrArray", otype);
-       error = NULL;
-       if (!dbus_g_proxy_call(dbus, "ListNetworks", &error,
-               G_TYPE_STRING, ifname, G_TYPE_INVALID,
-               otype, &array, G_TYPE_INVALID))
-       {
-               g_warning("ListNetworks: %s", error->message);
-               g_error_free(error);
-               return -1;
-       }
-
-       for (i = 0; i < array->len; i++) {
-               varray = g_ptr_array_index(array, i);
-               val = g_value_array_get_nth(varray, 1);
-               str = g_value_get_string(val);
-               if (g_strcmp0(str, ssid) == 0) {
-                       val = g_value_array_get_nth(varray, 0);
-                       return g_value_get_int(val);
-               }
-       }
-
-       if (!dbus_g_proxy_call(dbus, "AddNetwork", &error,
-               G_TYPE_STRING, ifname, G_TYPE_INVALID,
-               G_TYPE_INT, &id, G_TYPE_INVALID))
-       {
-               g_warning("AddNetwork: %s", error->message);
-               g_error_free(error);
-               return -1;
-       }
-
-       nssid = g_strconcat("\"", ssid, "\"", NULL);
-       if (!dbus_g_proxy_call(dbus, "SetNetwork", &error,
-               G_TYPE_STRING, ifname,
-               G_TYPE_INT, id,
-               G_TYPE_STRING, "ssid",
-               G_TYPE_STRING, nssid,
-               G_TYPE_INVALID,
-               G_TYPE_INVALID))
-       {
-               g_warning("SetNetwork: %s", error->message);
-               g_free(nssid);
-               g_error_free(error);
-               return -1;
-       }
-       g_free(nssid);
-
-       return id;
-}
-
-static int
-configure_network(const char *ifname, int id, const char *mgmt,
-    const char *var, const char *val,
-    bool quote)
-{
-       GError *error;
-       char *str;
-       static bool warned = false;
-       GtkWidget *dialog;
-
-       if (id == -1)
-               return -1;
-
-       dbus_g_proxy_call(dbus, "SetNetwork", &error,
-           G_TYPE_STRING, ifname,
-           G_TYPE_INT, id,
-           G_TYPE_STRING, "key_mgmt",
-           G_TYPE_STRING, mgmt,
-           G_TYPE_INVALID,
-           G_TYPE_INVALID);
-
-       error = NULL;
-       if (quote)
-               str = g_strconcat("\"", val, "\"", NULL);
-       else
-               str = NULL;
-       if (!dbus_g_proxy_call(dbus, "SetNetwork", &error,
-               G_TYPE_STRING, ifname,
-               G_TYPE_INT, id,
-               G_TYPE_STRING, var,
-               G_TYPE_STRING, quote ? str : val,
-               G_TYPE_INVALID,
-               G_TYPE_INVALID))
-       {
-               g_warning("SetNetwork: %s", error->message);
-               g_free(str);
-               g_error_free(error);
-               dialog = gtk_message_dialog_new(NULL,
-                   GTK_DIALOG_MODAL,
-                   GTK_MESSAGE_ERROR,
-                   GTK_BUTTONS_OK,
-                   _("Failed to set password, probably too short."));
-               gtk_window_set_title(GTK_WINDOW(dialog),
-                   _("Error setting password"));
-               gtk_dialog_run(GTK_DIALOG(dialog));
-               gtk_widget_destroy(dialog);
-               return -1;
-       }
-       g_free(str);
-
-       if (!dbus_g_proxy_call(dbus, "EnableNetwork", &error,
-               G_TYPE_STRING, ifname,
-               G_TYPE_INT, id,
-               G_TYPE_INVALID,
-               G_TYPE_INVALID))
-       {
-               g_warning("EnableNetwork: %s", error->message);
-               g_error_free(error);
-               return -1;
-       }
-
-       if (!dbus_g_proxy_call(dbus, "SaveConfig", &error,
-               G_TYPE_STRING, ifname,
-               G_TYPE_INVALID,
-               G_TYPE_INVALID))
-       {
-               g_warning("SaveConfig: %s", error->message);
-               if (!warned) {
-                       warned = true;
-                       dialog = gtk_message_dialog_new(NULL,
-                           GTK_DIALOG_MODAL,
-                           GTK_MESSAGE_ERROR,
-                           GTK_BUTTONS_OK,
-                           _("Failed to save wpa_supplicant configuration.\n\nYou should add update_config=1 to /etc/wpa_supplicant.conf.\nThis warning will not appear again until program restarted."));
-                       gtk_window_set_title(GTK_WINDOW(dialog),
-                           _("Error saving configuration"));
-                       gtk_dialog_run(GTK_DIALOG(dialog));
-                       gtk_widget_destroy(dialog);
-               }
-               g_error_free(error);
-       }
-/*
-  if (!dbus_g_proxy_call(dbus, "Disconnect", &error,
-  G_TYPE_STRING, ifname,
-  G_TYPE_INVALID,
-  G_TYPE_INVALID))
-  {
-  g_warning("Disconnect: %s", error->message);
-  g_error_free(error);
-  }
-*/
-       if (!dbus_g_proxy_call(dbus, "Reassociate", &error,
-               G_TYPE_STRING, ifname,
-               G_TYPE_INVALID,
-               G_TYPE_INVALID))
-       {
-               g_warning("Reassociate: %s", error->message);
-               g_error_free(error);
-       }
-       
-       return 0;
-}
-
-static void
-onEnter(_unused GtkWidget *widget, gpointer *data)
-{
-       gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT);
-}
-
-bool
-wpa_configure(const struct if_ap *ifa)
-{
-       GtkWidget *dialog, *label, *psk, *vbox, *hbox;
-       const char *var, *mgt;
-       int result, id, retval;
-
-       dialog = gtk_dialog_new_with_buttons(ifa->ssid,
-           NULL,
-           GTK_DIALOG_MODAL,
-           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-           GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-           NULL);
-       gtk_window_set_resizable(GTK_WINDOW(dialog), false);
-       gtk_window_set_icon_name(GTK_WINDOW(dialog), "network-wireless-encrypted");
-       gtk_dialog_set_default_response(GTK_DIALOG(dialog),
-           GTK_RESPONSE_ACCEPT);
-       vbox = GTK_DIALOG(dialog)->vbox;
-
-       hbox = gtk_hbox_new(false, 2);
-       label = gtk_label_new(_("Pre Shared Key:"));
-       gtk_box_pack_start(GTK_BOX(hbox), label, false, false, 0);
-       psk = gtk_entry_new();
-       gtk_entry_set_max_length(GTK_ENTRY(psk), 130);
-       g_signal_connect(G_OBJECT(psk), "activate", G_CALLBACK(onEnter), dialog);
-       gtk_box_pack_start(GTK_BOX(hbox), psk, true, true, 0);
-       gtk_container_add(GTK_CONTAINER(vbox), hbox);
-
-       gtk_widget_show_all(dialog);
-       result = gtk_dialog_run(GTK_DIALOG(dialog));
-       
-       id = -1;
-       retval = -1;
-       if (result == GTK_RESPONSE_ACCEPT) {
-               id = find_network(ifa->ifname, ifa->ssid);
-               if (g_strcmp0(ifa->flags, "[WEP]") == 0) {
-                       mgt = "NONE";
-                       var = "wep_key0";
-               } else {
-                       mgt = "WPA-PSK";
-                       var = "psk";
-               }
-               if (id != -1) {
-                       retval = configure_network(ifa->ifname, id, mgt, var,
-                           gtk_entry_get_text(GTK_ENTRY(psk)), true);
-               }
-       }
-       gtk_widget_destroy(dialog);
-       return retval == -1 ? false : true;
-}
diff --git a/src/wpa.h b/src/wpa.h
deleted file mode 100644 (file)
index 204d289..0000000
--- a/src/wpa.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * dhcpcd-gtk
- * Copyright 2009 Roy Marples <roy@marples.name>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef WPA_H
-#define WPA_H
-
-#include <stdbool.h>
-
-#include "dhcpcd-gtk.h"
-
-bool wpa_configure(const struct if_ap *);
-
-#endif