diff --git a/NEWS b/NEWS
index 780829e..9732b5d 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ xboxdrv 0.7.1 - (??/???/2011)
 * fixed --dpad-only
 * added support for Playstation button names (triangle,
   circle, square, cross, L1, L2, L3, R1, R2, R3)
+* added --on-connect and --on-disconnect to xboxdrv --daemon
 
 
 xboxdrv 0.7.0 - (28/Jan/2011)
diff --git a/TODO b/TODO
index 10df7dc..b29d742 100644
--- a/TODO
+++ b/TODO
@@ -56,6 +56,7 @@ Stuff to do before 0.7.1 release:
 
 * fix device name of mimic_xpad
 
+
 * allow multiple controllers in non-daemon mode
 
 * improve output in daemon mode, when --quiet is not given print the
@@ -89,11 +90,6 @@ Stuff to do before 0.7.1 release:
 * remember controllers that couldn't be used when all slots where full
   and use them when a slot got free
 
-* implement --on-connect and --on-disconnect for the daemon
-  - maybe have a more general event interface that allows to run stuff
-    on configuration changes, controller plug-ins, etc. (notifiy area as example)
-  - also supply useful information as argument
-
 * improve output on which uinput devices are created (even with udev
   there doesn't seem to be a bullet proof way to detect what gets
   created)
@@ -105,6 +101,8 @@ Stuff to do before 0.7.1 release:
 Stuff to do before 0.7.2 release:
 =================================
 
+* add extra arguments to --on-connect and --on-disconnect (controller name, usb path, etc.)
+
 * boost::lexical_cast<> error messages are useless, make some better ones
 
 * couldn't convert 'XK_Page_Up' to enum, not a member of X11Keysym
diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
index f35988f..706a848 100644
--- a/src/command_line_options.cpp
+++ b/src/command_line_options.cpp
@@ -180,8 +180,8 @@ CommandLineParser::init_argp()
     .add_option(OPTION_DAEMON,        'D', "daemon",    "", "Run as daemon")
     .add_option(OPTION_DAEMON_DETACH,   0, "detach",      "", "Detach the daemon from the current shell")
     .add_option(OPTION_DAEMON_PID_FILE, 0, "pid-file",    "FILE", "Write daemon pid to FILE")
-    .add_option(OPTION_DAEMON_ON_CONNECT,    0, "on-connect", "FILE", "Launch EXE when a new controller is connected", false)
-    .add_option(OPTION_DAEMON_ON_DISCONNECT, 0, "on-disconnect", "FILE", "Launch EXE when a controller is disconnected", false)
+    .add_option(OPTION_DAEMON_ON_CONNECT,    0, "on-connect", "FILE", "Launch EXE when a new controller is connected")
+    .add_option(OPTION_DAEMON_ON_DISCONNECT, 0, "on-disconnect", "FILE", "Launch EXE when a controller is disconnected")
     .add_newline()
 
     .add_text("Device Options: ")
diff --git a/src/helper.cpp b/src/helper.cpp
index c4f17de..8f0bbdb 100644
--- a/src/helper.cpp
+++ b/src/helper.cpp
@@ -18,12 +18,15 @@
 
 #include "helper.hpp"
 
+#include <assert.h>
 #include <boost/format.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/lexical_cast.hpp>
 #include <stdio.h>
 #include <sys/time.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
+#include <errno.h>
 #include <iostream>
 
 #include "raise_exception.hpp"
@@ -175,5 +178,34 @@ int get_terminal_width()
     return w.ws_col;
   }
 }
+
+void spawn_exe(const std::string& arg0)
+{
+  std::vector<std::string> args;
+  args.push_back(arg0);
+  spawn_exe(args);
+}
+
+void spawn_exe(const std::vector<std::string>& args)
+{
+  assert(!args.empty());
+
+  pid_t pid = fork();
+  if (pid == 0)
+  {
+    char** argv = static_cast<char**>(malloc(sizeof(char*) * (args.size() + 1)));
+    for(size_t i = 0; i < args.size(); ++i)
+    {
+      argv[i] = strdup(args[i].c_str());
+    }
+    argv[args.size()] = NULL;
+
+    if (execvp(args[0].c_str(), argv) == -1)
+    {
+      log_error(args[0] << ": exec failed: " << strerror(errno));
+      _exit(EXIT_FAILURE);
+    }
+  }
+}
 
 /* EOF */
diff --git a/src/helper.hpp b/src/helper.hpp
index 237ba04..5dd78e6 100644
--- a/src/helper.hpp
+++ b/src/helper.hpp
@@ -21,6 +21,7 @@
 
 #include <boost/function.hpp>
 #include <stdint.h>
+#include <vector>
 
 int hexstr2int(const std::string& str);
 
@@ -73,6 +74,8 @@ float to_float_no_range_check(int value, int min, int max);
 int from_float(float value, int min, int max);
 
 int get_terminal_width();
+void spawn_exe(const std::vector<std::string>& args);
+void spawn_exe(const std::string& arg0);
 
 #endif
 
diff --git a/src/xboxdrv.cpp b/src/xboxdrv.cpp
index d2fb3c9..a29d1d0 100644
--- a/src/xboxdrv.cpp
+++ b/src/xboxdrv.cpp
@@ -600,7 +600,7 @@ Xboxdrv::run_daemon(const Options& opts)
 
   if (!opts.detach)
   {
-    XboxdrvDaemon daemon;
+    XboxdrvDaemon daemon(opts);
     daemon.run(opts);
   }
   else
@@ -637,7 +637,7 @@ Xboxdrv::run_daemon(const Options& opts)
         }
         else
         {
-          XboxdrvDaemon daemon;
+          XboxdrvDaemon daemon(opts);
           daemon.run(opts);
         }
       }
diff --git a/src/xboxdrv_daemon.cpp b/src/xboxdrv_daemon.cpp
index f17004e..e505e95 100644
--- a/src/xboxdrv_daemon.cpp
+++ b/src/xboxdrv_daemon.cpp
@@ -87,8 +87,9 @@ bool get_usb_path(udev_device* device, int* bus, int* dev)
 }
 
 } // namespace
-
-XboxdrvDaemon::XboxdrvDaemon() :
+
+XboxdrvDaemon::XboxdrvDaemon(const Options& opts) :
+  m_opts(opts),
   m_udev(0),
   m_monitor(0),
   m_controller_slots(),
@@ -122,6 +123,8 @@ XboxdrvDaemon::cleanup_threads()
         delete i->thread;
         i->thread = 0;
         count += 1;
+
+        on_disconnect();
       }
     }
   }
@@ -495,6 +498,8 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
     thread->start_thread(opts);
     slot.thread = thread.release();
 
+    on_connect();
+
     log_info("launched XboxdrvThread for " << boost::format("%03d:%03d")
       % static_cast<int>(busnum) 
       % static_cast<int>(devnum)
@@ -519,4 +524,18 @@ XboxdrvDaemon::get_free_slot_count() const
   return slot_count;
 }
 
+void
+XboxdrvDaemon::on_connect()
+{
+  log_info("launching connect script");
+  spawn_exe(m_opts.on_connect);
+}
+
+void
+XboxdrvDaemon::on_disconnect()
+{
+  log_info("launching disconnect script");
+  spawn_exe(m_opts.on_disconnect);
+}
+
 /* EOF */
diff --git a/src/xboxdrv_daemon.hpp b/src/xboxdrv_daemon.hpp
index d2127cd..8d38a8e 100644
--- a/src/xboxdrv_daemon.hpp
+++ b/src/xboxdrv_daemon.hpp
@@ -31,6 +31,7 @@ struct XPadDevice;
 class XboxdrvDaemon
 {
 private:
+  const Options& m_opts;
   struct udev* m_udev;
   struct udev_monitor* m_monitor;
 
@@ -84,7 +85,7 @@ private:
   std::auto_ptr<UInput> m_uinput;
 
 public:
-  XboxdrvDaemon();
+  XboxdrvDaemon(const Options& opts);
   ~XboxdrvDaemon();
 
   void run(const Options& opts);
@@ -107,6 +108,9 @@ private:
                       ControllerSlot& slot);
   int get_free_slot_count() const;
   
+  void on_connect();
+  void on_disconnect();
+
 private:
   XboxdrvDaemon(const XboxdrvDaemon&);
   XboxdrvDaemon& operator=(const XboxdrvDaemon&);