about summary refs log tree commit diff
path: root/cli
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2010-11-29 00:47:11 +0100
committerMichael Biebl <biebl@debian.org>2010-11-29 00:47:11 +0100
commit9fae01fa351805b2903e535736e06971bc0b925e (patch)
treec19bccf84c9f894e50fae678ba6ee2b2044e2d30 /cli
Imported Upstream version 0.8.1 upstream/0.8.1
Diffstat (limited to 'cli')
-rw-r--r--cli/Makefile.am2
-rw-r--r--cli/Makefile.in620
-rw-r--r--cli/src/Makefile.am38
-rw-r--r--cli/src/Makefile.in703
-rw-r--r--cli/src/connections.c1642
-rw-r--r--cli/src/connections.h27
-rw-r--r--cli/src/devices.c1294
-rw-r--r--cli/src/devices.h27
-rw-r--r--cli/src/network-manager.c278
-rw-r--r--cli/src/network-manager.h27
-rw-r--r--cli/src/nmcli.c363
-rw-r--r--cli/src/nmcli.h114
-rw-r--r--cli/src/settings.c1369
-rw-r--r--cli/src/settings.h59
-rw-r--r--cli/src/utils.c298
-rw-r--r--cli/src/utils.h36
16 files changed, 6897 insertions, 0 deletions
diff --git a/cli/Makefile.am b/cli/Makefile.am
new file mode 100644
index 00000000..f2689244
--- /dev/null
+++ b/cli/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = src
+
diff --git a/cli/Makefile.in b/cli/Makefile.in
new file mode 100644
index 00000000..b4274994
--- /dev/null
+++ b/cli/Makefile.in
@@ -0,0 +1,620 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = cli
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+	$(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
+	$(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+IPTABLES_PATH = @IPTABLES_PATH@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POFILES = @POFILES@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = src
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cli/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu cli/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-am clean clean-generic clean-libtool \
+	ctags ctags-recursive distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am
new file mode 100644
index 00000000..572e122f
--- /dev/null
+++ b/cli/src/Makefile.am
@@ -0,0 +1,38 @@
+bin_PROGRAMS = \
+	nmcli
+
+INCLUDES = \
+	-I${top_srcdir} \
+	-I${top_srcdir}/include \
+	-I${top_builddir}/marshallers \
+	-I${top_srcdir}/libnm-util \
+	-I${top_srcdir}/libnm-glib
+
+nmcli_SOURCES = \
+	connections.c \
+	connections.h \
+	devices.c \
+	devices.h \
+	network-manager.c \
+	network-manager.h \
+	settings.c \
+	settings.h \
+	nmcli.c \
+	nmcli.h \
+	utils.c \
+	utils.h
+
+nmcli_CPPFLAGS = \
+	$(DBUS_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	-DNMCLI_LOCALEDIR=\"$(datadir)/locale\" \
+	-DG_DISABLE_DEPRECATED
+
+nmcli_LDADD = \
+	$(DBUS_LIBS) \
+	$(GLIB_LIBS) \
+	$(top_builddir)/marshallers/libmarshallers.la \
+	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/libnm-glib/libnm-glib.la
+
+
diff --git a/cli/src/Makefile.in b/cli/src/Makefile.in
new file mode 100644
index 00000000..4d26da6d
--- /dev/null
+++ b/cli/src/Makefile.in
@@ -0,0 +1,703 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = nmcli$(EXEEXT)
+subdir = cli/src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+	$(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
+	$(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_nmcli_OBJECTS = nmcli-connections.$(OBJEXT) nmcli-devices.$(OBJEXT) \
+	nmcli-network-manager.$(OBJEXT) nmcli-settings.$(OBJEXT) \
+	nmcli-nmcli.$(OBJEXT) nmcli-utils.$(OBJEXT)
+nmcli_OBJECTS = $(am_nmcli_OBJECTS)
+am__DEPENDENCIES_1 =
+nmcli_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(top_builddir)/marshallers/libmarshallers.la \
+	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/libnm-glib/libnm-glib.la
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(nmcli_SOURCES)
+DIST_SOURCES = $(nmcli_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+IPTABLES_PATH = @IPTABLES_PATH@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POFILES = @POFILES@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+	-I${top_srcdir} \
+	-I${top_srcdir}/include \
+	-I${top_builddir}/marshallers \
+	-I${top_srcdir}/libnm-util \
+	-I${top_srcdir}/libnm-glib
+
+nmcli_SOURCES = \
+	connections.c \
+	connections.h \
+	devices.c \
+	devices.h \
+	network-manager.c \
+	network-manager.h \
+	settings.c \
+	settings.h \
+	nmcli.c \
+	nmcli.h \
+	utils.c \
+	utils.h
+
+nmcli_CPPFLAGS = \
+	$(DBUS_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	-DNMCLI_LOCALEDIR=\"$(datadir)/locale\" \
+	-DG_DISABLE_DEPRECATED
+
+nmcli_LDADD = \
+	$(DBUS_LIBS) \
+	$(GLIB_LIBS) \
+	$(top_builddir)/marshallers/libmarshallers.la \
+	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/libnm-glib/libnm-glib.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cli/src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu cli/src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p || test -f $$p1; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+nmcli$(EXEEXT): $(nmcli_OBJECTS) $(nmcli_DEPENDENCIES) 
+	@rm -f nmcli$(EXEEXT)
+	$(LINK) $(nmcli_OBJECTS) $(nmcli_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli-connections.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli-devices.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli-network-manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli-nmcli.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli-settings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli-utils.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+nmcli-connections.o: connections.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-connections.o -MD -MP -MF $(DEPDIR)/nmcli-connections.Tpo -c -o nmcli-connections.o `test -f 'connections.c' || echo '$(srcdir)/'`connections.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-connections.Tpo $(DEPDIR)/nmcli-connections.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='connections.c' object='nmcli-connections.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-connections.o `test -f 'connections.c' || echo '$(srcdir)/'`connections.c
+
+nmcli-connections.obj: connections.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-connections.obj -MD -MP -MF $(DEPDIR)/nmcli-connections.Tpo -c -o nmcli-connections.obj `if test -f 'connections.c'; then $(CYGPATH_W) 'connections.c'; else $(CYGPATH_W) '$(srcdir)/connections.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-connections.Tpo $(DEPDIR)/nmcli-connections.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='connections.c' object='nmcli-connections.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-connections.obj `if test -f 'connections.c'; then $(CYGPATH_W) 'connections.c'; else $(CYGPATH_W) '$(srcdir)/connections.c'; fi`
+
+nmcli-devices.o: devices.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-devices.o -MD -MP -MF $(DEPDIR)/nmcli-devices.Tpo -c -o nmcli-devices.o `test -f 'devices.c' || echo '$(srcdir)/'`devices.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-devices.Tpo $(DEPDIR)/nmcli-devices.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='devices.c' object='nmcli-devices.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-devices.o `test -f 'devices.c' || echo '$(srcdir)/'`devices.c
+
+nmcli-devices.obj: devices.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-devices.obj -MD -MP -MF $(DEPDIR)/nmcli-devices.Tpo -c -o nmcli-devices.obj `if test -f 'devices.c'; then $(CYGPATH_W) 'devices.c'; else $(CYGPATH_W) '$(srcdir)/devices.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-devices.Tpo $(DEPDIR)/nmcli-devices.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='devices.c' object='nmcli-devices.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-devices.obj `if test -f 'devices.c'; then $(CYGPATH_W) 'devices.c'; else $(CYGPATH_W) '$(srcdir)/devices.c'; fi`
+
+nmcli-network-manager.o: network-manager.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-network-manager.o -MD -MP -MF $(DEPDIR)/nmcli-network-manager.Tpo -c -o nmcli-network-manager.o `test -f 'network-manager.c' || echo '$(srcdir)/'`network-manager.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-network-manager.Tpo $(DEPDIR)/nmcli-network-manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='network-manager.c' object='nmcli-network-manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-network-manager.o `test -f 'network-manager.c' || echo '$(srcdir)/'`network-manager.c
+
+nmcli-network-manager.obj: network-manager.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-network-manager.obj -MD -MP -MF $(DEPDIR)/nmcli-network-manager.Tpo -c -o nmcli-network-manager.obj `if test -f 'network-manager.c'; then $(CYGPATH_W) 'network-manager.c'; else $(CYGPATH_W) '$(srcdir)/network-manager.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-network-manager.Tpo $(DEPDIR)/nmcli-network-manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='network-manager.c' object='nmcli-network-manager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-network-manager.obj `if test -f 'network-manager.c'; then $(CYGPATH_W) 'network-manager.c'; else $(CYGPATH_W) '$(srcdir)/network-manager.c'; fi`
+
+nmcli-settings.o: settings.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-settings.o -MD -MP -MF $(DEPDIR)/nmcli-settings.Tpo -c -o nmcli-settings.o `test -f 'settings.c' || echo '$(srcdir)/'`settings.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-settings.Tpo $(DEPDIR)/nmcli-settings.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='settings.c' object='nmcli-settings.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-settings.o `test -f 'settings.c' || echo '$(srcdir)/'`settings.c
+
+nmcli-settings.obj: settings.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-settings.obj -MD -MP -MF $(DEPDIR)/nmcli-settings.Tpo -c -o nmcli-settings.obj `if test -f 'settings.c'; then $(CYGPATH_W) 'settings.c'; else $(CYGPATH_W) '$(srcdir)/settings.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-settings.Tpo $(DEPDIR)/nmcli-settings.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='settings.c' object='nmcli-settings.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-settings.obj `if test -f 'settings.c'; then $(CYGPATH_W) 'settings.c'; else $(CYGPATH_W) '$(srcdir)/settings.c'; fi`
+
+nmcli-nmcli.o: nmcli.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-nmcli.o -MD -MP -MF $(DEPDIR)/nmcli-nmcli.Tpo -c -o nmcli-nmcli.o `test -f 'nmcli.c' || echo '$(srcdir)/'`nmcli.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-nmcli.Tpo $(DEPDIR)/nmcli-nmcli.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='nmcli.c' object='nmcli-nmcli.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-nmcli.o `test -f 'nmcli.c' || echo '$(srcdir)/'`nmcli.c
+
+nmcli-nmcli.obj: nmcli.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-nmcli.obj -MD -MP -MF $(DEPDIR)/nmcli-nmcli.Tpo -c -o nmcli-nmcli.obj `if test -f 'nmcli.c'; then $(CYGPATH_W) 'nmcli.c'; else $(CYGPATH_W) '$(srcdir)/nmcli.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-nmcli.Tpo $(DEPDIR)/nmcli-nmcli.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='nmcli.c' object='nmcli-nmcli.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-nmcli.obj `if test -f 'nmcli.c'; then $(CYGPATH_W) 'nmcli.c'; else $(CYGPATH_W) '$(srcdir)/nmcli.c'; fi`
+
+nmcli-utils.o: utils.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-utils.o -MD -MP -MF $(DEPDIR)/nmcli-utils.Tpo -c -o nmcli-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-utils.Tpo $(DEPDIR)/nmcli-utils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='utils.c' object='nmcli-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+
+nmcli-utils.obj: utils.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nmcli-utils.obj -MD -MP -MF $(DEPDIR)/nmcli-utils.Tpo -c -o nmcli-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/nmcli-utils.Tpo $(DEPDIR)/nmcli-utils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='utils.c' object='nmcli-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nmcli-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic clean-libtool ctags distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags uninstall uninstall-am \
+	uninstall-binPROGRAMS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/cli/src/connections.c b/cli/src/connections.c
new file mode 100644
index 00000000..e9aa597d
--- /dev/null
+++ b/cli/src/connections.c
@@ -0,0 +1,1642 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <netinet/ether.h>
+
+#include <nm-client.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-olpc-mesh.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
+#include <nm-gsm-device.h>
+#include <nm-cdma-device.h>
+#include <nm-device-bt.h>
+//#include <nm-device-olpc-mesh.h>
+#include <nm-remote-settings.h>
+#include <nm-remote-settings-system.h>
+#include <nm-settings-interface.h>
+#include <nm-settings-connection-interface.h>
+#include <nm-vpn-connection.h>
+
+#include "utils.h"
+#include "settings.h"
+#include "connections.h"
+
+
+/* Available fields for 'con status' */
+static NmcOutputField nmc_fields_con_status[] = {
+	{"NAME",          N_("NAME"),         25, NULL, 0},  /* 0 */
+	{"UUID",          N_("UUID"),         38, NULL, 0},  /* 1 */
+	{"DEVICES",       N_("DEVICES"),      10, NULL, 0},  /* 2 */
+	{"SCOPE",         N_("SCOPE"),         8, NULL, 0},  /* 3 */
+	{"DEFAULT",       N_("DEFAULT"),       8, NULL, 0},  /* 4 */
+	{"DBUS-SERVICE",  N_("DBUS-SERVICE"), 45, NULL, 0},  /* 5 */
+	{"SPEC-OBJECT",   N_("SPEC-OBJECT"),  10, NULL, 0},  /* 6 */
+	{"VPN",           N_("VPN"),           5, NULL, 0},  /* 7 */
+	{NULL,            NULL,                0, NULL, 0}
+};
+#define NMC_FIELDS_CON_STATUS_ALL     "NAME,UUID,DEVICES,SCOPE,DEFAULT,VPN,DBUS-SERVICE,SPEC-OBJECT"
+#define NMC_FIELDS_CON_STATUS_COMMON  "NAME,UUID,DEVICES,SCOPE,DEFAULT,VPN"
+
+/* Available fields for 'con list' */
+static NmcOutputField nmc_fields_con_list[] = {
+	{"NAME",            N_("NAME"),           25, NULL, 0},  /* 0 */
+	{"UUID",            N_("UUID"),           38, NULL, 0},  /* 1 */
+	{"TYPE",            N_("TYPE"),           17, NULL, 0},  /* 2 */
+	{"SCOPE",           N_("SCOPE"),           8, NULL, 0},  /* 3 */
+	{"TIMESTAMP",       N_("TIMESTAMP"),      12, NULL, 0},  /* 4 */
+	{"TIMESTAMP-REAL",  N_("TIMESTAMP-REAL"), 34, NULL, 0},  /* 5 */
+	{"AUTOCONNECT",     N_("AUTOCONNECT"),    13, NULL, 0},  /* 6 */
+	{"READONLY",        N_("READONLY"),       10, NULL, 0},  /* 7 */
+	{NULL,              NULL,                  0, NULL, 0}
+};
+#define NMC_FIELDS_CON_LIST_ALL     "NAME,UUID,TYPE,SCOPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY"
+#define NMC_FIELDS_CON_LIST_COMMON  "NAME,UUID,TYPE,SCOPE,TIMESTAMP-REAL"
+
+
+/* Helper macro to define fields */
+#define SETTING_FIELD(setting, width) { setting, N_(setting), width, NULL, 0 }
+
+/* Available settings for 'con list id/uuid <con>' */
+static NmcOutputField nmc_fields_settings_names[] = {
+	SETTING_FIELD (NM_SETTING_CONNECTION_SETTING_NAME, 0),            /* 0 */
+	SETTING_FIELD (NM_SETTING_WIRED_SETTING_NAME, 0),                 /* 1 */
+	SETTING_FIELD (NM_SETTING_802_1X_SETTING_NAME, 0),                /* 2 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SETTING_NAME, 0),              /* 3 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, 0),     /* 4 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_SETTING_NAME, 0),            /* 5 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_SETTING_NAME, 0),            /* 6 */
+	SETTING_FIELD (NM_SETTING_SERIAL_SETTING_NAME, 0),                /* 7 */
+	SETTING_FIELD (NM_SETTING_PPP_SETTING_NAME, 0),                   /* 8 */
+	SETTING_FIELD (NM_SETTING_PPPOE_SETTING_NAME, 0),                 /* 9 */
+	SETTING_FIELD (NM_SETTING_GSM_SETTING_NAME, 0),                   /* 10 */
+	SETTING_FIELD (NM_SETTING_CDMA_SETTING_NAME, 0),                  /* 11 */
+	SETTING_FIELD (NM_SETTING_BLUETOOTH_SETTING_NAME, 0),             /* 12 */
+	SETTING_FIELD (NM_SETTING_OLPC_MESH_SETTING_NAME, 0),             /* 13 */
+	SETTING_FIELD (NM_SETTING_VPN_SETTING_NAME, 0),                   /* 14 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTINGS_NAMES_ALL    NM_SETTING_CONNECTION_SETTING_NAME","\
+                                         NM_SETTING_WIRED_SETTING_NAME","\
+                                         NM_SETTING_802_1X_SETTING_NAME","\
+                                         NM_SETTING_WIRELESS_SETTING_NAME","\
+                                         NM_SETTING_WIRELESS_SECURITY_SETTING_NAME","\
+                                         NM_SETTING_IP4_CONFIG_SETTING_NAME","\
+                                         NM_SETTING_IP6_CONFIG_SETTING_NAME","\
+                                         NM_SETTING_SERIAL_SETTING_NAME","\
+                                         NM_SETTING_PPP_SETTING_NAME","\
+                                         NM_SETTING_PPPOE_SETTING_NAME","\
+                                         NM_SETTING_GSM_SETTING_NAME","\
+                                         NM_SETTING_CDMA_SETTING_NAME","\
+                                         NM_SETTING_BLUETOOTH_SETTING_NAME","\
+                                         NM_SETTING_OLPC_MESH_SETTING_NAME","\
+                                         NM_SETTING_VPN_SETTING_NAME
+
+
+typedef struct {
+	NmCli *nmc;
+	int argc;
+	char **argv;
+} ArgsInfo;
+
+extern GMainLoop *loop;   /* glib main loop variable */
+
+static ArgsInfo args_info;
+
+/* static function prototypes */
+static void usage (void);
+static void quit (void);
+static void show_connection (NMConnection *data, gpointer user_data);
+static NMConnection *find_connection (GSList *list, const char *filter_type, const char *filter_val);
+static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap,
+                                            NMDevice **device, const char **spec_object, GError **error);
+static const char *active_connection_state_to_string (NMActiveConnectionState state);
+static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data);
+static void activate_connection_cb (gpointer user_data, const char *path, GError *error);
+static void get_connections_cb (NMSettingsInterface *settings, gpointer user_data);
+static NMCResultCode do_connections_list (NmCli *nmc, int argc, char **argv);
+static NMCResultCode do_connections_status (NmCli *nmc, int argc, char **argv);
+static NMCResultCode do_connection_up (NmCli *nmc, int argc, char **argv);
+static NMCResultCode do_connection_down (NmCli *nmc, int argc, char **argv);
+
+static void
+usage (void)
+{
+	fprintf (stderr,
+	 	 _("Usage: nmcli con { COMMAND | help }\n"
+		 "  COMMAND := { list | status | up | down }\n\n"
+		 "  list [id <id> | uuid <id> | system | user]\n"
+		 "  status\n"
+		 "  up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout <timeout>]\n"
+		 "  down id <id> | uuid <id>\n"));
+}
+
+/* quit main loop */
+static void
+quit (void)
+{
+	g_main_loop_quit (loop);  /* quit main loop */
+}
+
+static gboolean
+nmc_connection_detail (NMConnection *connection, NmCli *nmc)
+{
+	NMSetting *setting;
+	GError *error = NULL;
+	GArray *print_settings_array;
+	int i;
+	char *fields_str;
+	char *fields_all =    NMC_FIELDS_SETTINGS_NAMES_ALL;
+	char *fields_common = NMC_FIELDS_SETTINGS_NAMES_ALL;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+	gboolean was_output = FALSE;
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	print_settings_array = parse_output_fields (fields_str, nmc_fields_settings_names, &error);
+	if (error) {
+		if (error->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'con list': %s"), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'con list': %s; allowed fields: %s"), error->message, NMC_FIELDS_SETTINGS_NAMES_ALL);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		return FALSE;
+	}
+
+	nmc->allowed_fields = nmc_fields_settings_names;
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ONLY;
+	nmc->print_fields.header_name = _("Connection details");
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTINGS_NAMES_ALL, nmc->allowed_fields, NULL);
+	print_fields (nmc->print_fields, nmc->allowed_fields);
+
+	/* Loop through the required settings and print them. */
+	for (i = 0; i < print_settings_array->len; i++) {
+		int section_idx = g_array_index (print_settings_array, int, i);
+
+		if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output)
+			printf ("\n"); /* Empty line */
+
+		was_output = FALSE;
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[0].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+			if (setting) {
+				setting_connection_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[1].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+			if (setting) {
+				setting_wired_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[2].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+			if (setting) {
+				setting_802_1X_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[3].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+			if (setting) {
+				setting_wireless_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[4].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+			if (setting) {
+				setting_wireless_security_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[5].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+			if (setting) {
+				setting_ip4_config_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[6].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+			if (setting) {
+				setting_ip6_config_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[7].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL);
+			if (setting) {
+				setting_serial_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[8].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
+			if (setting) {
+				setting_ppp_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[9].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
+			if (setting) {
+				setting_pppoe_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[10].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
+			if (setting) {
+				setting_gsm_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[11].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
+			if (setting) {
+				setting_cdma_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[12].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+			if (setting) {
+				setting_bluetooth_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[13].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH);
+			if (setting) {
+				setting_olpc_mesh_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+
+		if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[14].name)) {
+			setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+			if (setting) {
+				setting_vpn_details (setting, nmc);
+				was_output = TRUE;
+				continue;
+			}
+		}
+	}
+
+	if (print_settings_array)
+		g_array_free (print_settings_array, FALSE);
+
+	return NMC_RESULT_SUCCESS;
+}
+
+static void
+show_connection (NMConnection *data, gpointer user_data)
+{
+	NMConnection *connection = (NMConnection *) data;
+	NmCli *nmc = (NmCli *) user_data;
+	NMSettingConnection *s_con;
+	guint64 timestamp;
+	char *timestamp_str;
+	char timestamp_real_str[64];
+
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	if (s_con) {
+		/* Obtain field values */
+		timestamp = nm_setting_connection_get_timestamp (s_con);
+		timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
+		strftime (timestamp_real_str, sizeof (timestamp_real_str), "%c", localtime ((time_t *) &timestamp));
+		nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con);
+		nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con);
+		nmc->allowed_fields[2].value = nm_setting_connection_get_connection_type (s_con);
+		nmc->allowed_fields[3].value = nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM ? _("system") : _("user");
+		nmc->allowed_fields[4].value = timestamp_str;
+		nmc->allowed_fields[5].value = timestamp ? timestamp_real_str : _("never");
+		nmc->allowed_fields[6].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no");
+		nmc->allowed_fields[7].value = nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no");
+
+		nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
+		print_fields (nmc->print_fields, nmc->allowed_fields);
+
+		g_free (timestamp_str);
+	}
+}
+
+static NMConnection *
+find_connection (GSList *list, const char *filter_type, const char *filter_val)
+{
+	NMSettingConnection *s_con;
+	NMConnection *connection;
+	GSList *iterator;
+	const char *id;
+	const char *uuid;
+
+	iterator = list;
+	while (iterator) {
+		connection = NM_CONNECTION (iterator->data);
+		s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+		if (s_con) {
+			id = nm_setting_connection_get_id (s_con);
+			uuid = nm_setting_connection_get_uuid (s_con);
+			if (filter_type) {
+				if ((strcmp (filter_type, "id") == 0 && strcmp (filter_val, id) == 0) ||
+				    (strcmp (filter_type, "uuid") == 0 && strcmp (filter_val, uuid) == 0)) {
+					return connection;
+				}
+			}
+		}
+		iterator = g_slist_next (iterator);
+	}
+
+	return NULL;
+}
+
+static NMCResultCode
+do_connections_list (NmCli *nmc, int argc, char **argv)
+{
+	GError *error1 = NULL;
+	GError *error2 = NULL;
+	char *fields_str;
+	char *fields_all =    NMC_FIELDS_CON_LIST_ALL;
+	char *fields_common = NMC_FIELDS_CON_LIST_COMMON;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+	gboolean valid_param_specified = FALSE;
+
+	nmc->should_wait = FALSE;
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	nmc->allowed_fields = nmc_fields_con_list;
+	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error1);
+	/* error1 is checked later - it's not valid for connection details */
+
+	if (argc == 0) {
+		if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2))
+			goto error;
+		if (error1)
+			goto error;
+		valid_param_specified = TRUE;
+
+		nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+		nmc->print_fields.header_name = _("System connections");
+		print_fields (nmc->print_fields, nmc->allowed_fields);
+		g_slist_foreach (nmc->system_connections, (GFunc) show_connection, nmc);
+
+		nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+		nmc->print_fields.header_name = _("User connections");
+		print_fields (nmc->print_fields, nmc->allowed_fields);
+		g_slist_foreach (nmc->user_connections, (GFunc) show_connection, nmc);
+	}
+	else {
+		while (argc > 0) {
+			if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
+				const char *selector = *argv;
+				NMConnection *con1;
+				NMConnection *con2;
+
+				if (next_arg (&argc, &argv) != 0) {
+					g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+					return nmc->return_value;
+				}
+				valid_param_specified = TRUE;
+				if (!nmc->mode_specified)
+					nmc->multiline_output = TRUE;  /* multiline mode is default for 'con list id|uuid' */
+
+				con1 = find_connection (nmc->system_connections, selector, *argv);
+				con2 = find_connection (nmc->user_connections, selector, *argv);
+				if (con1) nmc_connection_detail (con1, nmc);
+				if (con2) nmc_connection_detail (con2, nmc);
+				if (!con1 && !con2) {
+					g_string_printf (nmc->return_text, _("Error: %s - no such connection."), *argv);
+					nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+				}
+				break;
+			}
+			else if (strcmp (*argv, "system") == 0) {
+				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2))
+					goto error;
+				if (error1)
+					goto error;
+				valid_param_specified = TRUE;
+
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.header_name = _("System connections");
+				print_fields (nmc->print_fields, nmc->allowed_fields);
+				g_slist_foreach (nmc->system_connections, (GFunc) show_connection, nmc);
+				break;
+			}
+			else if (strcmp (*argv, "user") == 0) {
+				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2))
+					goto error;
+				if (error1)
+					goto error;
+				valid_param_specified = TRUE;
+
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.header_name = _("User connections");
+				print_fields (nmc->print_fields, nmc->allowed_fields);
+				g_slist_foreach (nmc->user_connections, (GFunc) show_connection, nmc);
+				break;
+			}
+			else {
+				fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+			}
+
+			argc--;
+			argv++;
+		}
+	}
+
+	if (!valid_param_specified) {
+		g_string_printf (nmc->return_text, _("Error: no valid parameter specified."));
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+	}
+	return nmc->return_value;
+
+error:
+	if (error1) {
+		if (error1->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'con list': %s"), error1->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'con list': %s; allowed fields: %s"), error1->message, NMC_FIELDS_CON_LIST_ALL);
+		g_error_free (error1);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+	}
+	if (error2) {
+		g_string_printf (nmc->return_text, _("Error: %s."), error2->message);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		g_error_free (error2);
+	}
+
+	return nmc->return_value;
+}
+
+typedef struct {
+	NmCli *nmc;
+	NMConnectionScope scope;
+} StatusInfo;
+
+static void
+show_active_connection (gpointer data, gpointer user_data)
+{
+	NMActiveConnection *active = NM_ACTIVE_CONNECTION (data);
+	StatusInfo *info = (StatusInfo *) user_data;
+	GSList *con_list, *iter;
+	const char *active_path;
+	NMConnectionScope active_service_scope;
+	NMSettingConnection *s_con;
+	const GPtrArray *devices;
+	GString *dev_str;
+	int i;
+
+	active_path = nm_active_connection_get_connection (active);
+	active_service_scope = nm_active_connection_get_scope (active);
+
+	if (active_service_scope != info->scope)
+		return;
+
+	/* Get devices of the active connection */
+	dev_str = g_string_new (NULL);
+	devices = nm_active_connection_get_devices (active);
+	for (i = 0; devices && (i < devices->len); i++) {
+		NMDevice *device = g_ptr_array_index (devices, i);
+
+		g_string_append (dev_str, nm_device_get_iface (device));
+		g_string_append_c (dev_str, ',');
+	}
+	if (dev_str->len > 0)
+		g_string_truncate (dev_str, dev_str->len - 1);  /* Cut off last ',' */
+
+	con_list = (info->scope == NM_CONNECTION_SCOPE_SYSTEM) ? info->nmc->system_connections : info->nmc->user_connections;
+	for (iter = con_list; iter; iter = g_slist_next (iter)) {
+		NMConnection *connection = (NMConnection *) iter->data;
+		const char *con_path = nm_connection_get_path (connection);
+
+		if (!strcmp (active_path, con_path)) {
+			/* This connection is active */
+			s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+			g_assert (s_con != NULL);
+
+			/* Obtain field values */
+			info->nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con);
+			info->nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con);
+			info->nmc->allowed_fields[2].value = dev_str->str;
+			info->nmc->allowed_fields[3].value = active_service_scope == NM_CONNECTION_SCOPE_SYSTEM ? _("system") : _("user");
+			info->nmc->allowed_fields[4].value = nm_active_connection_get_default (active) ? _("yes") : _("no");
+			info->nmc->allowed_fields[5].value = nm_active_connection_get_service_name (active);
+			info->nmc->allowed_fields[6].value = nm_active_connection_get_specific_object (active);
+			info->nmc->allowed_fields[7].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no");
+
+			info->nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
+			print_fields (info->nmc->print_fields, info->nmc->allowed_fields);
+			break;
+		}
+	}
+
+	g_string_free (dev_str, TRUE);
+}
+
+static NMCResultCode
+do_connections_status (NmCli *nmc, int argc, char **argv)
+{
+	const GPtrArray *active_cons;
+	GError *error = NULL;
+	StatusInfo *info;
+	char *fields_str;
+	char *fields_all =    NMC_FIELDS_CON_STATUS_ALL;
+	char *fields_common = NMC_FIELDS_CON_STATUS_COMMON;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	nmc->should_wait = FALSE;
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		return nmc->return_value;
+
+	active_cons = nm_client_get_active_connections (nmc->client);
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	nmc->allowed_fields = nmc_fields_con_status;
+	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
+
+	if (error) {
+		if (error->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'con status': %s"), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'con status': %s; allowed fields: %s"), error->message, NMC_FIELDS_CON_STATUS_ALL);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+	nmc->print_fields.header_name = _("Active connections");
+	print_fields (nmc->print_fields, nmc->allowed_fields);
+
+	if (active_cons && active_cons->len) {
+		info = g_malloc0 (sizeof (StatusInfo));
+		info->nmc = nmc;
+		info->scope = NM_CONNECTION_SCOPE_SYSTEM;
+		g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) info);
+		info->scope = NM_CONNECTION_SCOPE_USER;
+		g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) info);
+		g_free (info);
+	}
+
+error:
+
+	return nmc->return_value;
+}
+
+/* --------------------
+ * These function should be moved to libnm-glib in the end.
+ */
+static gboolean
+check_ethernet_compatible (NMDeviceEthernet *device, NMConnection *connection, GError **error)
+{
+	NMSettingConnection *s_con;
+	NMSettingWired *s_wired;
+	const char *connection_type;
+	gboolean is_pppoe = FALSE;
+
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	g_assert (s_con);
+
+	connection_type = nm_setting_connection_get_connection_type (s_con);
+	if (   strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
+	    && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a wired or PPPoE connection.");
+		return FALSE;
+	}
+
+	if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
+		is_pppoe = TRUE;
+
+	s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	/* Wired setting is optional for PPPoE */
+	if (!is_pppoe && !s_wired) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a valid wired connection.");
+		return FALSE;
+	}
+
+	if (s_wired) {
+		const GByteArray *mac;
+		const char *device_mac_str;
+		struct ether_addr *device_mac;
+
+		device_mac_str = nm_device_ethernet_get_hw_address (device);
+		device_mac = ether_aton (device_mac_str);
+		if (!device_mac) {
+			g_set_error (error, 0, 0, "Invalid device MAC address.");
+			return FALSE;
+		}
+
+		mac = nm_setting_wired_get_mac_address (s_wired);
+		if (mac && memcmp (mac->data, device_mac->ether_addr_octet, ETH_ALEN)) {
+			g_set_error (error, 0, 0,
+			             "The connection's MAC address did not match this device.");
+			return FALSE;
+		}
+	}
+
+	// FIXME: check bitrate against device capabilities
+
+	return TRUE;
+}
+
+static gboolean
+check_wifi_compatible (NMDeviceWifi *device, NMConnection *connection, GError **error)
+{
+	NMSettingConnection *s_con;
+	NMSettingWireless *s_wireless;
+
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	g_assert (s_con);
+
+	if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a WiFi connection.");
+		return FALSE;
+	}
+
+	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	if (!s_wireless) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a valid WiFi connection.");
+		return FALSE;
+	}
+
+	if (s_wireless) {
+		const GByteArray *mac;
+		const char *device_mac_str;
+		struct ether_addr *device_mac;
+
+		device_mac_str = nm_device_wifi_get_hw_address (device);
+		device_mac = ether_aton (device_mac_str);
+		if (!device_mac) {
+			g_set_error (error, 0, 0, "Invalid device MAC address.");
+			return FALSE;
+		}
+
+		mac = nm_setting_wireless_get_mac_address (s_wireless);
+		if (mac && memcmp (mac->data, device_mac->ether_addr_octet, ETH_ALEN)) {
+			g_set_error (error, 0, 0,
+		        	     "The connection's MAC address did not match this device.");
+			return FALSE;
+		}
+	}
+
+	// FIXME: check channel/freq/band against bands the hardware supports
+	// FIXME: check encryption against device capabilities
+	// FIXME: check bitrate against device capabilities
+
+	return TRUE;
+}
+
+static gboolean
+check_bt_compatible (NMDeviceBt *device, NMConnection *connection, GError **error)
+{
+	NMSettingConnection *s_con;
+	NMSettingBluetooth *s_bt;
+	const GByteArray *array;
+	char *str;
+	const char *device_hw_str;
+	int addr_match = FALSE;
+	const char *bt_type_str;
+	guint32 bt_type, bt_capab;
+
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	g_assert (s_con);
+
+	if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a Bluetooth connection.");
+		return FALSE;
+	}
+
+	s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+	if (!s_bt) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a valid Bluetooth connection.");
+		return FALSE;
+	}
+
+	array = nm_setting_bluetooth_get_bdaddr (s_bt);
+	if (!array || (array->len != ETH_ALEN)) {
+		g_set_error (error, 0, 0,
+		             "The connection did not contain a valid Bluetooth address.");
+		return FALSE;
+	}
+
+	bt_type_str = nm_setting_bluetooth_get_connection_type (s_bt);
+	g_assert (bt_type_str);
+
+	bt_type = NM_BT_CAPABILITY_NONE;
+	if (!strcmp (bt_type_str, NM_SETTING_BLUETOOTH_TYPE_DUN))
+		bt_type = NM_BT_CAPABILITY_DUN;
+	else if (!strcmp (bt_type_str, NM_SETTING_BLUETOOTH_TYPE_PANU))
+		bt_type = NM_BT_CAPABILITY_NAP;
+
+	bt_capab = nm_device_bt_get_capabilities (device);
+	if (!(bt_type & bt_capab)) {
+		g_set_error (error, 0, 0,
+		             "The connection was not compatible with the device's capabilities.");
+		return FALSE;
+	}
+
+	device_hw_str = nm_device_bt_get_hw_address (device);
+
+	str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+	                       array->data[0], array->data[1], array->data[2],
+	                       array->data[3], array->data[4], array->data[5]);
+	addr_match = !strcmp (device_hw_str, str);
+	g_free (str);
+
+	return addr_match;
+}
+
+#if 0
+static gboolean
+check_olpc_mesh_compatible (NMDeviceOlpcMesh *device, NMConnection *connection, GError **error)
+{
+	NMSettingConnection *s_con;
+	NMSettingOlpcMesh *s_mesh;
+
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	g_assert (s_con);
+
+	if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_OLPC_MESH_SETTING_NAME)) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a Mesh connection.");
+		return FALSE;
+	}
+
+	s_mesh = NM_SETTING_OLPC_MESH (nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH));
+	if (!s_mesh) {
+		g_set_error (error, 0, 0,
+		             "The connection was not a valid Mesh connection.");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+#endif
+
+static gboolean
+nm_device_is_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
+{
+	g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
+	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+	if (NM_IS_DEVICE_ETHERNET (device))
+		return check_ethernet_compatible (NM_DEVICE_ETHERNET (device), connection, error);
+	else if (NM_IS_DEVICE_WIFI (device))
+		return check_wifi_compatible (NM_DEVICE_WIFI (device), connection, error);
+	else if (NM_IS_DEVICE_BT (device))
+		return check_bt_compatible (NM_DEVICE_BT (device), connection, error);
+//	else if (NM_IS_DEVICE_OLPC_MESH (device))
+//		return check_olpc_mesh_compatible (NM_DEVICE_OLPC_MESH (device), connection, error);
+
+	g_set_error (error, 0, 0, "unhandled device type '%s'", G_OBJECT_TYPE_NAME (device));
+	return FALSE;
+}
+
+
+/**
+ * nm_client_get_active_connection_by_path:
+ * @client: a #NMClient
+ * @object_path: the object path to search for
+ *
+ * Gets a #NMActiveConnection from a #NMClient.
+ *
+ * Returns: the #NMActiveConnection for the given @object_path or %NULL if none is found.
+ **/
+static NMActiveConnection *
+nm_client_get_active_connection_by_path (NMClient *client, const char *object_path)
+{
+	const GPtrArray *actives;
+	int i;
+	NMActiveConnection *active = NULL;
+
+	g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+	g_return_val_if_fail (object_path, NULL);
+
+	actives = nm_client_get_active_connections (client);
+	if (!actives)
+		return NULL;
+
+	for (i = 0; i < actives->len; i++) {
+		NMActiveConnection *candidate = g_ptr_array_index (actives, i);
+		if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), object_path)) {
+			active = candidate;
+			break;
+		}
+	}
+
+	return active;
+}
+/* -------------------- */
+
+static NMActiveConnection *
+get_default_active_connection (NmCli *nmc, NMDevice **device)
+{
+	NMActiveConnection *default_ac = NULL;
+	NMDevice *non_default_device = NULL;
+	NMActiveConnection *non_default_ac = NULL;
+	const GPtrArray *connections;
+	int i;
+
+	g_return_val_if_fail (nmc != NULL, NULL);
+	g_return_val_if_fail (device != NULL, NULL);
+	g_return_val_if_fail (*device == NULL, NULL);
+
+	connections = nm_client_get_active_connections (nmc->client);
+	for (i = 0; connections && (i < connections->len); i++) {
+		NMActiveConnection *candidate = g_ptr_array_index (connections, i);
+		const GPtrArray *devices;
+
+		devices = nm_active_connection_get_devices (candidate);
+		if (!devices || !devices->len)
+			continue;
+
+		if (nm_active_connection_get_default (candidate)) {
+			if (!default_ac) {
+				*device = g_ptr_array_index (devices, 0);
+				default_ac = candidate;
+			}
+		} else {
+			if (!non_default_ac) {
+				non_default_device = g_ptr_array_index (devices, 0);
+				non_default_ac = candidate;
+			}
+		}
+	}
+
+	/* Prefer the default connection if one exists, otherwise return the first
+	 * non-default connection.
+	 */
+	if (!default_ac && non_default_ac) {
+		default_ac = non_default_ac;
+		*device = non_default_device;
+	}
+	return default_ac;
+}
+
+/* Find a device to activate the connection on.
+ * IN:  connection:  connection to activate
+ *      iface:       device interface name to use (optional)
+ *      ap:          access point to use (optional; valid just for 802-11-wireless)
+ * OUT: device:      found device
+ *      spec_object: specific_object path of NMAccessPoint
+ * RETURNS: TRUE when a device is found, FALSE otherwise.
+ */
+static gboolean
+find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap,
+                            NMDevice **device, const char **spec_object, GError **error)
+{
+	NMSettingConnection *s_con;
+	const char *con_type;
+	int i, j;
+
+	g_return_val_if_fail (nmc != NULL, FALSE);
+	g_return_val_if_fail (device != NULL && *device == NULL, FALSE);
+	g_return_val_if_fail (spec_object != NULL && *spec_object == NULL, FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	g_assert (s_con);
+	con_type = nm_setting_connection_get_connection_type (s_con);
+
+	if (strcmp (con_type, "vpn") == 0) {
+		/* VPN connections */
+		NMActiveConnection *active = NULL;
+		if (iface) {
+			const GPtrArray *connections = nm_client_get_active_connections (nmc->client);
+			for (i = 0; connections && (i < connections->len) && !active; i++) {
+				NMActiveConnection *candidate = g_ptr_array_index (connections, i);
+				const GPtrArray *devices = nm_active_connection_get_devices (candidate);
+				if (!devices || !devices->len)
+					continue;
+
+				for (j = 0; devices && (j < devices->len); j++) {
+					NMDevice *dev = g_ptr_array_index (devices, j);
+					if (!strcmp (iface, nm_device_get_iface (dev))) {
+						active = candidate;
+						*device = dev;
+						break;
+					}
+				}
+			}
+			if (!active) {
+				g_set_error (error, 0, 0, _("no active connection on device '%s'"), iface);
+				return FALSE;
+			}
+			*spec_object = nm_object_get_path (NM_OBJECT (active));
+			return TRUE;
+		} else {
+			active = get_default_active_connection (nmc, device);
+			if (!active) {
+				g_set_error (error, 0, 0, _("no active connection or device"));
+				return FALSE;
+			}
+			*spec_object = nm_object_get_path (NM_OBJECT (active));
+			return TRUE;
+		}
+	} else {
+		/* Other connections */
+		NMDevice *found_device = NULL;
+		const GPtrArray *devices = nm_client_get_devices (nmc->client);
+
+		for (i = 0; devices && (i < devices->len) && !found_device; i++) {
+			NMDevice *dev = g_ptr_array_index (devices, i);
+
+			if (iface) {
+				const char *dev_iface = nm_device_get_iface (dev);
+				if (   !strcmp (dev_iface, iface)
+				    && nm_device_is_connection_compatible (dev, connection, NULL)) {
+					found_device = dev;
+				}
+			} else {
+				if (nm_device_is_connection_compatible (dev, connection, NULL)) {
+					found_device = dev;
+				}
+			}
+
+			if (found_device && ap && !strcmp (con_type, "802-11-wireless") && NM_IS_DEVICE_WIFI (dev)) {
+				char *hwaddr_up = g_ascii_strup (ap, -1);
+				const GPtrArray *aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
+				found_device = NULL;  /* Mark as not found; set to the device again later, only if AP matches */
+
+				for (j = 0; aps && (j < aps->len); j++) {
+					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
+					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+
+					if (!strcmp (hwaddr_up, candidate_hwaddr)) {
+						found_device = dev;
+						*spec_object = nm_object_get_path (NM_OBJECT (candidate_ap));
+						break;
+					}
+				}
+				g_free (hwaddr_up);
+			}
+		}
+
+		if (found_device) {
+			*device = found_device;
+			return TRUE;
+		} else {
+			if (iface)
+				g_set_error (error, 0, 0, _("device '%s' not compatible with connection '%s'"), iface, nm_setting_connection_get_id (s_con));
+			else
+				g_set_error (error, 0, 0, _("no device found for connection '%s'"), nm_setting_connection_get_id (s_con));
+			return FALSE;
+		}
+	}
+}
+
+static const char *
+active_connection_state_to_string (NMActiveConnectionState state)
+{
+	switch (state) {
+	case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
+		return _("activating");
+	case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
+		return _("activated");
+	case NM_ACTIVE_CONNECTION_STATE_UNKNOWN:
+	default:
+		return _("unknown");
+	}
+}
+
+static const char *
+vpn_connection_state_to_string (NMVPNConnectionState state)
+{
+	switch (state) {
+	case NM_VPN_CONNECTION_STATE_PREPARE:
+		return _("VPN connecting (prepare)");
+	case NM_VPN_CONNECTION_STATE_NEED_AUTH:
+		return _("VPN connecting (need authentication)");
+	case NM_VPN_CONNECTION_STATE_CONNECT:
+		return _("VPN connecting");
+	case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
+		return _("VPN connecting (getting IP configuration)");
+	case NM_VPN_CONNECTION_STATE_ACTIVATED:
+		return _("VPN connected");
+	case NM_VPN_CONNECTION_STATE_FAILED:
+		return _("VPN connection failed");
+	case NM_VPN_CONNECTION_STATE_DISCONNECTED:
+		return _("VPN disconnected");
+	default:
+		return _("unknown");
+	}
+}
+
+static const char *
+vpn_connection_state_reason_to_string (NMVPNConnectionStateReason reason)
+{
+	switch (reason) {
+	case NM_VPN_CONNECTION_STATE_REASON_UNKNOWN:
+		return _("unknown reason");
+	case NM_VPN_CONNECTION_STATE_REASON_NONE:
+		return _("none");
+	case NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED:
+		return _("the user was disconnected");
+	case NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED:
+		return _("the base network connection was interrupted");
+	case NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED:
+		return _("the VPN service stopped unexpectedly");
+	case NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID:
+		return _("the VPN service returned invalid configuration");
+	case NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT:
+		return _("the connection attempt timed out");
+	case NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT:
+		return _("the VPN service did not start in time");
+	case NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED:
+		return _("the VPN service failed to start");
+	case NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS:
+		return _("no valid VPN secrets");
+	case NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED:
+		return _("invalid VPN secrets");
+	case NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED:
+		return _("the connection was removed");
+	default:
+		return _("unknown");
+	}
+}
+
+static void
+active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data)
+{
+	NmCli *nmc = (NmCli *) user_data;
+	NMActiveConnectionState state;
+
+	state = nm_active_connection_get_state (active);
+
+	printf (_("state: %s\n"), active_connection_state_to_string (state));
+
+	if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
+		printf (_("Connection activated\n"));
+		quit ();
+	} else if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) {
+		g_string_printf (nmc->return_text, _("Error: Connection activation failed."));
+		nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
+		quit ();
+	}
+}
+
+static void
+vpn_connection_state_cb (NMVPNConnection *vpn,
+                         NMVPNConnectionState state,
+                         NMVPNConnectionStateReason reason,
+                         gpointer user_data)
+{
+	NmCli *nmc = (NmCli *) user_data;
+
+	switch (state) {
+	case NM_VPN_CONNECTION_STATE_PREPARE:
+	case NM_VPN_CONNECTION_STATE_NEED_AUTH:
+	case NM_VPN_CONNECTION_STATE_CONNECT:
+	case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
+		printf (_("state: %s (%d)\n"), vpn_connection_state_to_string (state), state);
+		break;
+
+	case NM_VPN_CONNECTION_STATE_ACTIVATED:
+		printf (_("Connection activated\n"));
+		quit ();
+		break;
+
+	case NM_VPN_CONNECTION_STATE_FAILED:
+	case NM_VPN_CONNECTION_STATE_DISCONNECTED:
+		g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s."), vpn_connection_state_reason_to_string (reason));
+		nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
+		quit ();
+		break;
+
+	default:
+		break;
+	}
+}
+
+static gboolean
+timeout_cb (gpointer user_data)
+{
+	/* Time expired -> exit nmcli */
+
+	NmCli *nmc = (NmCli *) user_data;
+
+	g_string_printf (nmc->return_text, _("Error: Timeout %d sec expired."), nmc->timeout);
+	nmc->return_value = NMC_RESULT_ERROR_TIMEOUT_EXPIRED;
+	quit ();
+	return FALSE;
+}
+
+static void
+foo_active_connections_changed_cb (NMClient *client,
+                                   GParamSpec *pspec,
+                                   gpointer user_data)
+{
+	/* Call again activate_connection_cb with dummy arguments;
+	 * the correct ones are taken from its first call.
+	 */
+	activate_connection_cb (NULL, NULL, NULL);
+}
+
+static void
+activate_connection_cb (gpointer user_data, const char *path, GError *error)
+{
+	NmCli *nmc = (NmCli *) user_data;
+	NMActiveConnection *active;
+	NMActiveConnectionState state;
+	static gulong handler_id = 0;
+	static NmCli *orig_nmc;
+	static const char *orig_path;
+	static GError *orig_error;
+
+	if (nmc)
+	{
+		/* Called first time; store actual arguments */
+		orig_nmc = nmc;
+		orig_path = path;
+		orig_error = error;
+	}
+
+	/* Disconnect the handler not to be run any more */
+	if (handler_id != 0) {
+		g_signal_handler_disconnect (orig_nmc->client, handler_id);
+		handler_id = 0;
+	}
+
+	if (orig_error) {
+		g_string_printf (orig_nmc->return_text, _("Error: Connection activation failed: %s"), orig_error->message);
+		orig_nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
+		quit ();
+	} else {
+		active = nm_client_get_active_connection_by_path (orig_nmc->client, orig_path);
+		if (!active) {
+			/* The active connection path is not in active connections list yet; wait for active-connections signal. */
+			/* This is basically the case for VPN connections. */
+			if (nmc) {
+				/* Called first time, i.e. by nm_client_activate_connection() */
+				handler_id = g_signal_connect (orig_nmc->client, "notify::active-connections",
+				                               G_CALLBACK (foo_active_connections_changed_cb), NULL);
+				return;
+			} else {
+				g_string_printf (orig_nmc->return_text, _("Error: Obtaining active connection for '%s' failed."), orig_path);
+				orig_nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
+				quit ();
+				return;
+			}
+		}
+
+		state = nm_active_connection_get_state (active);
+
+		printf (_("Active connection state: %s\n"), active_connection_state_to_string (state));
+		printf (_("Active connection path: %s\n"), orig_path);
+
+		if (!orig_nmc->should_wait || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
+			/* don't want to wait or already activated */
+			quit ();
+		} else {
+			if (NM_IS_VPN_CONNECTION (active))
+				g_signal_connect (NM_VPN_CONNECTION (active), "vpn-state-changed", G_CALLBACK (vpn_connection_state_cb), orig_nmc);
+			else
+				g_signal_connect (active, "notify::state", G_CALLBACK (active_connection_state_cb), orig_nmc);
+
+			/* Start timer not to loop forever when signals are not emitted */
+			g_timeout_add_seconds (orig_nmc->timeout, timeout_cb, orig_nmc);
+		}
+	}
+}
+
+static NMCResultCode
+do_connection_up (NmCli *nmc, int argc, char **argv)
+{
+	NMDevice *device = NULL;
+	const char *spec_object = NULL;
+	gboolean device_found;
+	NMConnection *connection = NULL;
+	NMSettingConnection *s_con;
+	gboolean is_system;
+	const char *con_path;
+	const char *con_type;
+	const char *iface = NULL;
+	const char *ap = NULL;
+	gboolean id_specified = FALSE;
+	gboolean wait = TRUE;
+	GError *error = NULL;
+
+	/* Set default timeout for connection activation. It can take quite a long time.
+	 * Using 90 seconds.
+	 */
+	nmc->timeout = 90;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
+			const char *selector = *argv;
+			id_specified = TRUE;
+
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			if ((connection = find_connection (nmc->system_connections, selector, *argv)) == NULL)
+				connection = find_connection (nmc->user_connections, selector, *argv);
+
+			if (!connection) {
+				g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+				goto error;
+			}
+		}
+		else if (strcmp (*argv, "iface") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			iface = *argv;
+		}
+		else if (strcmp (*argv, "ap") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			ap = *argv;
+		}
+		else if (strcmp (*argv, "--nowait") == 0) {
+			wait = FALSE;
+		} else if (strcmp (*argv, "--timeout") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			errno = 0;
+			nmc->timeout = strtol (*argv, NULL, 10);
+			if (errno || nmc->timeout < 0) {
+				g_string_printf (nmc->return_text, _("Error: timeout value '%s' is not valid."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+		} else {
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+		}
+
+		argc--;
+		argv++;
+	}
+
+	if (!id_specified) {
+		g_string_printf (nmc->return_text, _("Error: id or uuid has to be specified."));
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto error;
+
+	is_system = (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) ? TRUE : FALSE;
+	con_path = nm_connection_get_path (connection);
+
+	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	g_assert (s_con);
+	con_type = nm_setting_connection_get_connection_type (s_con);
+
+	device_found = find_device_for_connection (nmc, connection, iface, ap, &device, &spec_object, &error);
+
+	if (!device_found) {
+		if (error)
+			g_string_printf (nmc->return_text, _("Error: No suitable device found: %s."), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: No suitable device found."));
+		nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
+		goto error;
+	}
+
+	nmc->should_wait = wait;
+	nm_client_activate_connection (nmc->client,
+	                               is_system ? NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS,
+	                               con_path,
+	                               device,
+	                               spec_object,
+	                               activate_connection_cb,
+	                               nmc);
+
+	return nmc->return_value;
+error:
+	nmc->should_wait = FALSE;
+	return nmc->return_value;
+}
+
+static NMCResultCode
+do_connection_down (NmCli *nmc, int argc, char **argv)
+{
+	NMConnection *connection = NULL;
+	NMActiveConnection *active = NULL;
+	const GPtrArray *active_cons;
+	const char *con_path;
+	const char *active_path;
+	NMConnectionScope active_service_scope, con_scope;
+	gboolean id_specified = FALSE;
+	gboolean wait = TRUE;
+	int i;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
+			const char *selector = *argv;
+			id_specified = TRUE;
+
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			if ((connection = find_connection (nmc->system_connections, selector, *argv)) == NULL)
+				connection = find_connection (nmc->user_connections, selector, *argv);
+
+			if (!connection) {
+				g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+				goto error;
+			}
+		}
+		else if (strcmp (*argv, "--nowait") == 0) {
+			wait = FALSE;
+		}
+		else {
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+		}
+
+		argc--;
+		argv++;
+	}
+
+	if (!id_specified) {
+		g_string_printf (nmc->return_text, _("Error: id or uuid has to be specified."));
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto error;
+
+	con_path = nm_connection_get_path (connection);
+	con_scope = nm_connection_get_scope (connection);
+
+	active_cons = nm_client_get_active_connections (nmc->client);
+	for (i = 0; active_cons && (i < active_cons->len); i++) {
+		NMActiveConnection *candidate = g_ptr_array_index (active_cons, i);
+
+		active_path = nm_active_connection_get_connection (candidate);
+		active_service_scope = nm_active_connection_get_scope (candidate);
+		if (!strcmp (active_path, con_path) && active_service_scope == con_scope) {
+			active = candidate;
+			break;
+		}
+	}
+
+	if (active)
+		nm_client_deactivate_connection (nmc->client, active);
+	else {
+		fprintf (stderr, _("Warning: Connection not active\n"));
+	}
+
+error:
+	nmc->should_wait = FALSE;
+	return nmc->return_value;
+}
+
+/* callback called when connections are obtained from the settings service */
+static void
+get_connections_cb (NMSettingsInterface *settings, gpointer user_data)
+{
+	ArgsInfo *args = (ArgsInfo *) user_data;
+	static gboolean system_cb_called = FALSE;
+	static gboolean user_cb_called = FALSE;
+	GError *error = NULL;
+
+	if (NM_IS_REMOTE_SETTINGS_SYSTEM (settings)) {
+		system_cb_called = TRUE;
+		args->nmc->system_connections = nm_settings_interface_list_connections (settings);
+	}
+	else {
+		user_cb_called = TRUE;
+		args->nmc->user_connections = nm_settings_interface_list_connections (settings);
+	}
+
+	/* return and wait for the callback of the second settings is called */
+	if (   (args->nmc->system_settings_running && !system_cb_called)
+	    || (args->nmc->user_settings_running && !user_cb_called))
+		return;
+
+	if (args->argc == 0) {
+		if (!nmc_terse_option_check (args->nmc->print_output, args->nmc->required_fields, &error))
+			goto opt_error;
+		args->nmc->return_value = do_connections_list (args->nmc, args->argc, args->argv);
+	} else {
+
+	 	if (matches (*args->argv, "list") == 0) {
+			args->nmc->return_value = do_connections_list (args->nmc, args->argc-1, args->argv+1);
+		}
+		else if (matches(*args->argv, "status") == 0) {
+			if (!nmc_terse_option_check (args->nmc->print_output, args->nmc->required_fields, &error))
+				goto opt_error;
+			args->nmc->return_value = do_connections_status (args->nmc, args->argc-1, args->argv+1);
+		}
+		else if (matches(*args->argv, "up") == 0) {
+			args->nmc->return_value = do_connection_up (args->nmc, args->argc-1, args->argv+1);
+		}
+		else if (matches(*args->argv, "down") == 0) {
+			args->nmc->return_value = do_connection_down (args->nmc, args->argc-1, args->argv+1);
+		}
+		else if (matches (*args->argv, "help") == 0) {
+			usage ();
+			args->nmc->should_wait = FALSE;
+		} else {
+			usage ();
+			g_string_printf (args->nmc->return_text, _("Error: 'con' command '%s' is not valid."), *args->argv);
+			args->nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+			args->nmc->should_wait = FALSE;
+		}
+	}
+
+	if (!args->nmc->should_wait)
+		quit ();
+	return;
+
+opt_error:
+	g_string_printf (args->nmc->return_text, _("Error: %s."), error->message);
+	args->nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+	args->nmc->should_wait = FALSE;
+	g_error_free (error);
+	quit ();
+	return;
+}
+
+
+/* Entry point function for connections-related commands: 'nmcli con' */
+NMCResultCode
+do_connections (NmCli *nmc, int argc, char **argv)
+{
+	DBusGConnection *bus;
+	GError *error = NULL;
+
+	nmc->should_wait = TRUE;
+
+	args_info.nmc = nmc;
+	args_info.argc = argc;
+	args_info.argv = argv;
+
+	/* connect to DBus' system bus */
+	bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (error || !bus) {
+		g_string_printf (nmc->return_text, _("Error: could not connect to D-Bus."));
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		return nmc->return_value;
+	}
+
+	/* get system settings */
+	if (!(nmc->system_settings = nm_remote_settings_system_new (bus))) {
+		g_string_printf (nmc->return_text, _("Error: Could not get system settings."));
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		return nmc->return_value;
+
+	}
+
+	/* get user settings */
+	if (!(nmc->user_settings = nm_remote_settings_new (bus, NM_CONNECTION_SCOPE_USER))) {
+		g_string_printf (nmc->return_text, _("Error: Could not get user settings."));
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		return nmc->return_value;
+	}
+
+	/* find out whether setting services are running */
+	g_object_get (nmc->system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &nmc->system_settings_running, NULL);
+	g_object_get (nmc->user_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &nmc->user_settings_running, NULL);
+
+	if (!nmc->system_settings_running && !nmc->user_settings_running) {
+		g_string_printf (nmc->return_text, _("Error: Can't obtain connections: settings services are not running."));
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		return nmc->return_value;
+	}
+
+	/* connect to signal "connections-read" - emitted when connections are fetched and ready */
+	if (nmc->system_settings_running)
+		g_signal_connect (nmc->system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ,
+		                  G_CALLBACK (get_connections_cb), &args_info);
+
+	if (nmc->user_settings_running)
+		g_signal_connect (nmc->user_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ,
+		                  G_CALLBACK (get_connections_cb), &args_info);
+
+	dbus_g_connection_unref (bus);
+
+	/* The rest will be done in get_connection_cb() callback.
+	 * We need to wait for signals that connections are read.
+	 */
+	return NMC_RESULT_SUCCESS;
+}
diff --git a/cli/src/connections.h b/cli/src/connections.h
new file mode 100644
index 00000000..a1ed1c1c
--- /dev/null
+++ b/cli/src/connections.h
@@ -0,0 +1,27 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef NMC_CONNECTIONS_H
+#define NMC_CONNECTIONS_H
+
+#include "nmcli.h"
+
+NMCResultCode do_connections (NmCli *nmc, int argc, char **argv);
+
+#endif /* NMC_CONNECTIONS_H */
diff --git a/cli/src/devices.c b/cli/src/devices.c
new file mode 100644
index 00000000..e2ce91e3
--- /dev/null
+++ b/cli/src/devices.c
@@ -0,0 +1,1294 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <nm-client.h>
+#include <nm-device-wifi.h>
+
+#include <nm-client.h>
+#include <nm-device.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
+#include <nm-gsm-device.h>
+#include <nm-cdma-device.h>
+#include <nm-device-bt.h>
+//#include <nm-device-olpc-mesh.h>
+#include <nm-utils.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-vpn-connection.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-olpc-mesh.h>
+
+#include "utils.h"
+#include "devices.h"
+
+
+/* Available fields for 'dev status' */
+static NmcOutputField nmc_fields_dev_status[] = {
+	{"DEVICE",  N_("DEVICE"),    10, NULL, 0},  /* 0 */
+	{"TYPE",    N_("TYPE"),      17, NULL, 0},  /* 1 */
+	{"STATE",   N_("STATE"),     12, NULL, 0},  /* 2 */
+	{NULL,      NULL,             0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_STATUS_ALL     "DEVICE,TYPE,STATE"
+#define NMC_FIELDS_DEV_STATUS_COMMON  "DEVICE,TYPE,STATE"
+
+
+/* Available sections for 'dev list' */
+static NmcOutputField nmc_fields_dev_list_sections[] = {
+	{"GENERAL",           N_("GENERAL"),           0, NULL, 0},  /* 0 */
+	{"CAPABILITIES",      N_("CAPABILITIES"),      0, NULL, 0},  /* 1 */
+	{"WIFI-PROPERTIES",   N_("WIFI-PROPERTIES"),   0, NULL, 0},  /* 2 */
+	{"AP",                N_("AP"),                0, NULL, 0},  /* 3 */
+	{"WIRED-PROPERTIES",  N_("WIRED-PROPERTIES"),  0, NULL, 0},  /* 4 */
+	{"IP4-SETTINGS",      N_("IP4-SETTINGS"),      0, NULL, 0},  /* 5 */
+	{"IP4-DNS",           N_("IP4-DNS"),           0, NULL, 0},  /* 6 */
+	{"IP6-SETTINGS",      N_("IP6-SETTINGS"),      0, NULL, 0},  /* 7 */
+	{"IP6-DNS",           N_("IP6-DNS"),           0, NULL, 0},  /* 8 */
+	{NULL,                NULL,                    0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_SECTIONS_ALL     "GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4-SETTINGS,IP4-DNS,IP6-SETTINGS,IP6-DNS"
+#define NMC_FIELDS_DEV_LIST_SECTIONS_COMMON  "GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4-SETTINGS,IP4-DNS,IP6-SETTINGS,IP6-DNS"
+
+/* Available fields for 'dev list' - GENERAL part */
+static NmcOutputField nmc_fields_dev_list_general[] = {
+	{"NAME",       N_("NAME"),        10, NULL, 0},  /* 0 */
+	{"DEVICE",     N_("DEVICE"),      10, NULL, 0},  /* 1 */
+	{"TYPE",       N_("TYPE"),        17, NULL, 0},  /* 2 */
+	{"DRIVER",     N_("DRIVER"),      10, NULL, 0},  /* 3 */
+	{"HWADDR",     N_("HWADDR"),      19, NULL, 0},  /* 4 */
+	{"STATE",      N_("STATE"),       14, NULL, 0},  /* 5 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_GENERAL_ALL     "NAME,DEVICE,TYPE,DRIVER,HWADDR,STATE"
+#define NMC_FIELDS_DEV_LIST_GENERAL_COMMON  "NAME,DEVICE,TYPE,DRIVER,HWADDR,STATE"
+
+/* Available fields for 'dev list' - CAPABILITIES part */
+static NmcOutputField nmc_fields_dev_list_cap[] = {
+	{"NAME",            N_("NAME"),            13, NULL, 0},  /* 0 */
+	{"CARRIER-DETECT",  N_("CARRIER-DETECT"),  16, NULL, 0},  /* 1 */
+	{"SPEED",           N_("SPEED"),           10, NULL, 0},  /* 2 */
+	{NULL,              NULL,                   0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_CAP_ALL     "NAME,CARRIER-DETECT,SPEED"
+#define NMC_FIELDS_DEV_LIST_CAP_COMMON  "NAME,CARRIER-DETECT,SPEED"
+
+/* Available fields for 'dev list' - wired properties part */
+static NmcOutputField nmc_fields_dev_list_wired_prop[] = {
+	{"NAME",            N_("NAME"),     18, NULL, 0},  /* 0 */
+	{"CARRIER",         N_("CARRIER"),  10, NULL, 0},  /* 1 */
+	{NULL,              NULL,            0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_WIRED_PROP_ALL     "NAME,CARRIER"
+#define NMC_FIELDS_DEV_LIST_WIRED_PROP_COMMON  "NAME,CARRIER"
+
+
+/* Available fields for 'dev list' - wireless properties part */
+static NmcOutputField nmc_fields_dev_list_wifi_prop[] = {
+	{"NAME",       N_("NAME"),        18, NULL, 0},  /* 0 */
+	{"WEP",        N_("WEP"),          5, NULL, 0},  /* 1 */
+	{"WPA",        N_("WPA"),          5, NULL, 0},  /* 2 */
+	{"WPA2",       N_("WPA2"),         6, NULL, 0},  /* 3 */
+	{"TKIP",       N_("TKIP"),         6, NULL, 0},  /* 4 */
+	{"CCMP",       N_("CCMP"),         6, NULL, 0},  /* 5 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_WIFI_PROP_ALL     "NAME,WEP,WPA,WPA2,TKIP,CCMP"
+#define NMC_FIELDS_DEV_LIST_WIFI_PROP_COMMON  "NAME,WEP,WPA,WPA2,TKIP,CCMP"
+
+/* Available fields for 'dev list' - IPv4 settings part */
+static NmcOutputField nmc_fields_dev_list_ip4_settings[] = {
+	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
+	{"ADDRESS",    N_("ADDRESS"),     15, NULL, 0},  /* 1 */
+	{"PREFIX",     N_("PREFIX"),      20, NULL, 0},  /* 2 */
+	{"GATEWAY",    N_("GATEWAY"),     20, NULL, 0},  /* 3 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_IP4_SETTINGS_ALL     "NAME,ADDRESS,PREFIX,GATEWAY"
+#define NMC_FIELDS_DEV_LIST_IP4_SETTINGS_COMMON  "NAME,ADDRESS,PREFIX,GATEWAY"
+
+/* Available fields for 'dev list' - IPv6 settings part */
+static NmcOutputField nmc_fields_dev_list_ip6_settings[] = {
+	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
+	{"ADDRESS",    N_("ADDRESS"),     15, NULL, 0},  /* 1 */
+	{"PREFIX",     N_("PREFIX"),      20, NULL, 0},  /* 2 */
+	{"GATEWAY",    N_("GATEWAY"),     20, NULL, 0},  /* 3 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_IP6_SETTINGS_ALL     "NAME,ADDRESS,PREFIX,GATEWAY"
+#define NMC_FIELDS_DEV_LIST_IP6_SETTINGS_COMMON  "NAME,ADDRESS,PREFIX,GATEWAY"
+
+/* Available fields for 'dev list' - IPv4 settings DNS part */
+static NmcOutputField nmc_fields_dev_list_ip4_dns[] = {
+	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
+	{"DNS",        N_("DNS"),         17, NULL, 0},  /* 1 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_IP4_DNS_ALL     "NAME,DNS"
+#define NMC_FIELDS_DEV_LIST_IP4_DNS_COMMON  "NAME,DNS"
+
+/* Available fields for 'dev list' - IPv6 settings DNS part */
+static NmcOutputField nmc_fields_dev_list_ip6_dns[] = {
+	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
+	{"DNS",        N_("DNS"),         17, NULL, 0},  /* 1 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_LIST_IP6_DNS_ALL     "NAME,DNS"
+#define NMC_FIELDS_DEV_LIST_IP6_DNS_COMMON  "NAME,DNS"
+
+/* Available fields for 'dev wifi list' */
+static NmcOutputField nmc_fields_dev_wifi_list[] = {
+	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
+	{"SSID",       N_("SSID"),        33, NULL, 0},  /* 1 */
+	{"BSSID",      N_("BSSID"),       19, NULL, 0},  /* 2 */
+	{"MODE",       N_("MODE"),        16, NULL, 0},  /* 3 */
+	{"FREQ",       N_("FREQ"),        10, NULL, 0},  /* 4 */
+	{"RATE",       N_("RATE"),        10, NULL, 0},  /* 5 */
+	{"SIGNAL",     N_("SIGNAL"),       8, NULL, 0},  /* 6 */
+	{"SECURITY",   N_("SECURITY"),    10, NULL, 0},  /* 7 */
+	{"WPA-FLAGS",  N_("WPA-FLAGS"),   25, NULL, 0},  /* 8 */
+	{"RSN-FLAGS",  N_("RSN-FLAGS"),   25, NULL, 0},  /* 9 */
+	{"DEVICE",     N_("DEVICE"),      10, NULL, 0},  /* 10 */
+	{"ACTIVE",     N_("ACTIVE"),       8, NULL, 0},  /* 11 */
+	{NULL,         NULL,               0, NULL, 0}
+};
+#define NMC_FIELDS_DEV_WIFI_LIST_ALL           "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE"
+#define NMC_FIELDS_DEV_WIFI_LIST_COMMON        "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,ACTIVE"
+#define NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST  "NAME,"NMC_FIELDS_DEV_WIFI_LIST_COMMON
+
+
+/* static function prototypes */
+static void usage (void);
+static const char *device_state_to_string (NMDeviceState state);
+static NMCResultCode do_devices_status (NmCli *nmc, int argc, char **argv);
+static NMCResultCode do_devices_list (NmCli *nmc, int argc, char **argv);
+static NMCResultCode do_device_disconnect (NmCli *nmc, int argc, char **argv);
+static NMCResultCode do_device_wifi (NmCli *nmc, int argc, char **argv);
+
+
+extern GMainLoop *loop;   /* glib main loop variable */
+
+static void
+usage (void)
+{
+	fprintf (stderr,
+	 	 _("Usage: nmcli dev { COMMAND | help }\n\n"
+		 "  COMMAND := { status | list | disconnect | wifi }\n\n"
+		 "  status\n"
+		 "  list [iface <iface>]\n"
+		 "  disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
+		 "  wifi [list [iface <iface>] [hwaddr <hwaddr>]]\n\n"));
+}
+
+/* quit main loop */
+static void
+quit (void)
+{
+	g_main_loop_quit (loop);  /* quit main loop */
+}
+
+static const char *
+device_state_to_string (NMDeviceState state)
+{
+	switch (state) {
+	case NM_DEVICE_STATE_UNMANAGED:
+		return _("unmanaged");
+	case NM_DEVICE_STATE_UNAVAILABLE:
+		return _("unavailable");
+	case NM_DEVICE_STATE_DISCONNECTED:
+		return _("disconnected");
+	case NM_DEVICE_STATE_PREPARE:
+		return _("connecting (prepare)");
+	case NM_DEVICE_STATE_CONFIG:
+		return _("connecting (configuring)");
+	case NM_DEVICE_STATE_NEED_AUTH:
+		return _("connecting (need authentication)");
+	case NM_DEVICE_STATE_IP_CONFIG:
+		return _("connecting (getting IP configuration)");
+	case NM_DEVICE_STATE_ACTIVATED:
+		return _("connected");
+	case NM_DEVICE_STATE_FAILED:
+		return _("connection failed");
+	default:
+		return _("unknown");
+	}
+}
+
+/* Return device type - use setting names to match with connection types */
+static const char *
+get_device_type (NMDevice * device)
+{
+	if (NM_IS_DEVICE_ETHERNET (device))
+		return NM_SETTING_WIRED_SETTING_NAME;
+	else if (NM_IS_DEVICE_WIFI (device))
+		return NM_SETTING_WIRELESS_SETTING_NAME;
+	else if (NM_IS_GSM_DEVICE (device))
+		return NM_SETTING_GSM_SETTING_NAME;
+	else if (NM_IS_CDMA_DEVICE (device))
+		return NM_SETTING_CDMA_SETTING_NAME;
+	else if (NM_IS_DEVICE_BT (device))
+		return NM_SETTING_BLUETOOTH_SETTING_NAME;
+//	else if (NM_IS_DEVICE_OLPC_MESH (device))
+//		return NM_SETTING_OLPC_MESH_SETTING_NAME;
+	else
+		return _("Unknown");
+}
+
+static char *
+ap_wpa_rsn_flags_to_string (guint32 flags)
+{
+	char *flags_str[16]; /* Enough space for flags and terminating NULL */
+	char *ret_str;
+	int i = 0;
+
+	if (flags & NM_802_11_AP_SEC_PAIR_WEP40)
+		flags_str[i++] = g_strdup ("pair_wpe40");
+	if (flags & NM_802_11_AP_SEC_PAIR_WEP104)
+		flags_str[i++] = g_strdup ("pair_wpe104");
+	if (flags & NM_802_11_AP_SEC_PAIR_TKIP)
+		flags_str[i++] = g_strdup ("pair_tkip");
+	if (flags & NM_802_11_AP_SEC_PAIR_CCMP)
+		flags_str[i++] = g_strdup ("pair_ccmp");
+	if (flags & NM_802_11_AP_SEC_GROUP_WEP40)
+		flags_str[i++] = g_strdup ("group_wpe40");
+	if (flags & NM_802_11_AP_SEC_GROUP_WEP104)
+		flags_str[i++] = g_strdup ("group_wpe104");
+	if (flags & NM_802_11_AP_SEC_GROUP_TKIP)
+		flags_str[i++] = g_strdup ("group_tkip");
+	if (flags & NM_802_11_AP_SEC_GROUP_CCMP)
+		flags_str[i++] = g_strdup ("group_ccmp");
+	if (flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
+		flags_str[i++] = g_strdup ("psk");
+	if (flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
+		flags_str[i++] = g_strdup ("802.1X");
+
+	if (i == 0)
+		flags_str[i++] = g_strdup (_("(none)"));
+
+	flags_str[i] = NULL;
+
+	ret_str = g_strjoinv (" ", flags_str);
+
+	i = 0;
+	while (flags_str[i])
+		 g_free (flags_str[i++]);
+
+	return ret_str;
+}
+
+static gchar *
+ip4_address_as_string (guint32 ip)
+{
+	struct in_addr tmp_addr;
+	char buf[INET_ADDRSTRLEN+1];
+
+	memset (&buf, '\0', sizeof (buf));
+	tmp_addr.s_addr = ip;
+
+	if (inet_ntop (AF_INET, &tmp_addr, buf, INET_ADDRSTRLEN)) {
+		return g_strdup (buf);
+	} else {
+		g_warning (_("%s: error converting IP4 address 0x%X"),
+		            __func__, ntohl (tmp_addr.s_addr));
+		return NULL;
+	}
+}
+
+static gchar *
+ip6_address_as_string (const struct in6_addr *ip)
+{
+	char buf[INET6_ADDRSTRLEN];
+
+	memset (&buf, '\0', sizeof (buf));
+
+	if (inet_ntop (AF_INET6, ip, buf, INET6_ADDRSTRLEN)) {
+		return g_strdup (buf);
+	} else {
+		int j;
+		GString *ip6_str = g_string_new (NULL);
+		g_string_append_printf (ip6_str, "%02X", ip->s6_addr[0]);
+		for (j = 1; j < 16; j++)
+			g_string_append_printf (ip6_str, " %02X", ip->s6_addr[j]);
+		nm_warning ("%s: error converting IP6 address %s",
+		            __func__, ip6_str->str);
+		g_string_free (ip6_str, TRUE);
+		return NULL;
+	}
+}
+
+typedef struct {
+	NmCli *nmc;
+	int index;
+	const char* active_bssid;
+	const char* device;
+} APInfo;
+
+static void
+detail_access_point (gpointer data, gpointer user_data)
+{
+	NMAccessPoint *ap = NM_ACCESS_POINT (data);
+	APInfo *info = (APInfo *) user_data;
+	gboolean active = FALSE;
+	guint32 flags, wpa_flags, rsn_flags, freq, bitrate;
+	guint8 strength;
+	const GByteArray *ssid; 
+	const char *hwaddr;
+	NM80211Mode mode;
+	char *freq_str, *ssid_str, *bitrate_str, *strength_str, *wpa_flags_str, *rsn_flags_str;
+	GString *security_str;
+	char *ap_name;
+
+	if (info->active_bssid) {
+		const char *current_bssid = nm_access_point_get_hw_address (ap);
+		if (current_bssid && !strcmp (current_bssid, info->active_bssid))
+			active = TRUE;
+	}
+
+	/* Get AP properties */
+	flags = nm_access_point_get_flags (ap);
+	wpa_flags = nm_access_point_get_wpa_flags (ap);
+	rsn_flags = nm_access_point_get_rsn_flags (ap);
+	ssid = nm_access_point_get_ssid (ap);
+	hwaddr = nm_access_point_get_hw_address (ap);
+	freq = nm_access_point_get_frequency (ap);
+	mode = nm_access_point_get_mode (ap);
+	bitrate = nm_access_point_get_max_bitrate (ap);
+	strength = nm_access_point_get_strength (ap);
+
+	/* Convert to strings */
+	ssid_str = ssid_to_printable ((const char *) ssid->data, ssid->len);
+	freq_str = g_strdup_printf (_("%u MHz"), freq);
+	bitrate_str = g_strdup_printf (_("%u MB/s"), bitrate/1000);
+	strength_str = g_strdup_printf ("%u", strength);
+	wpa_flags_str = ap_wpa_rsn_flags_to_string (wpa_flags);
+	rsn_flags_str = ap_wpa_rsn_flags_to_string (rsn_flags);
+
+	security_str = g_string_new (NULL);
+	if (   !(flags & NM_802_11_AP_FLAGS_PRIVACY)
+	    &&  (wpa_flags != NM_802_11_AP_SEC_NONE)
+	    &&  (rsn_flags != NM_802_11_AP_SEC_NONE))
+		g_string_append (security_str, _("Encrypted: "));
+
+	if (   (flags & NM_802_11_AP_FLAGS_PRIVACY)
+	    && (wpa_flags == NM_802_11_AP_SEC_NONE)
+	    && (rsn_flags == NM_802_11_AP_SEC_NONE))
+		g_string_append (security_str, _("WEP "));
+	if (wpa_flags != NM_802_11_AP_SEC_NONE)
+		g_string_append (security_str, _("WPA "));
+	if (rsn_flags != NM_802_11_AP_SEC_NONE)
+		g_string_append (security_str, _("WPA2 "));
+	if (   (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
+	    || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
+		g_string_append (security_str, _("Enterprise "));
+
+	if (security_str->len > 0)
+		g_string_truncate (security_str, security_str->len-1);  /* Chop off last space */
+
+	ap_name = g_strdup_printf ("AP%d", info->index++); /* AP */
+	info->nmc->allowed_fields[0].value = ap_name;
+	info->nmc->allowed_fields[1].value = ssid_str;
+	info->nmc->allowed_fields[2].value = hwaddr;
+	info->nmc->allowed_fields[3].value = mode == NM_802_11_MODE_ADHOC ? _("Ad-Hoc") : mode == NM_802_11_MODE_INFRA ? _("Infrastructure") : _("Unknown");
+	info->nmc->allowed_fields[4].value = freq_str;
+	info->nmc->allowed_fields[5].value = bitrate_str;
+	info->nmc->allowed_fields[6].value = strength_str;
+	info->nmc->allowed_fields[7].value = security_str->str;
+	info->nmc->allowed_fields[8].value = wpa_flags_str;
+	info->nmc->allowed_fields[9].value = rsn_flags_str;
+	info->nmc->allowed_fields[10].value = info->device;
+	info->nmc->allowed_fields[11].value = active ? _("yes") : _("no");
+
+	info->nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
+	print_fields (info->nmc->print_fields, info->nmc->allowed_fields);
+
+	g_free (ap_name);
+	g_free (ssid_str);
+	g_free (freq_str);
+	g_free (bitrate_str);
+	g_free (strength_str);
+	g_free (wpa_flags_str);
+	g_free (rsn_flags_str);
+	g_string_free (security_str, TRUE);
+}
+
+struct cb_info {
+	NMClient *client;
+	const GPtrArray *active;
+};
+
+static void
+show_device_info (gpointer data, gpointer user_data)
+{
+	NMDevice *device = NM_DEVICE (data);
+	NmCli *nmc = (NmCli *) user_data;
+	GError *error = NULL;
+	APInfo *info;
+	char *tmp;
+	const char *hwaddr = NULL;
+	NMDeviceState state = NM_DEVICE_STATE_UNKNOWN;
+	guint32 caps;
+	guint32 speed;
+	char *speed_str = NULL;
+	const GArray *array;
+	GArray *sections_array;
+	int k;
+	char *fields_str;
+	char *fields_all =    NMC_FIELDS_DEV_LIST_SECTIONS_ALL;
+	char *fields_common = NMC_FIELDS_DEV_LIST_SECTIONS_COMMON;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+	gboolean was_output = FALSE;
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	sections_array = parse_output_fields (fields_str, nmc_fields_dev_list_sections, &error);
+	if (error) {
+		if (error->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'dev list': %s"), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'dev list': %s; allowed fields: %s"), error->message, NMC_FIELDS_DEV_LIST_SECTIONS_ALL);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		return;
+	}
+
+	/* Main header */
+	nmc->allowed_fields = nmc_fields_dev_list_general;
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ONLY;
+	nmc->print_fields.header_name = _("Device details");
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_GENERAL_ALL, nmc->allowed_fields, NULL);
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+	/* Loop through the required sections and print them. */
+	for (k = 0; k < sections_array->len; k++) {
+		int section_idx = g_array_index (sections_array, int, k);
+
+		if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output)
+			printf ("\n"); /* Empty line */
+
+		was_output = FALSE;
+
+		state = nm_device_get_state (device);
+
+		/* section GENERAL */
+		if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[0].name)) {
+			nmc->allowed_fields = nmc_fields_dev_list_general;
+			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+			nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_GENERAL_ALL, nmc->allowed_fields, NULL);
+			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+			if (NM_IS_DEVICE_ETHERNET (device))
+				hwaddr = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device));
+			else if (NM_IS_DEVICE_WIFI (device))
+				hwaddr = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device));
+
+			nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[0].name;  /* "GENERAL"*/
+			nmc->allowed_fields[1].value = nm_device_get_iface (device);
+			nmc->allowed_fields[2].value = get_device_type (device);
+			nmc->allowed_fields[3].value = nm_device_get_driver (device) ? nm_device_get_driver (device) : _("(unknown)");
+			nmc->allowed_fields[4].value = hwaddr ? hwaddr : _("unknown)");
+			nmc->allowed_fields[5].value = device_state_to_string (state);
+
+			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+			was_output = TRUE;
+		}
+
+		/* section CAPABILITIES */
+		if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[1].name)) {
+			nmc->allowed_fields = nmc_fields_dev_list_cap;
+			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+			nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_CAP_ALL, nmc->allowed_fields, NULL);
+			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+			caps = nm_device_get_capabilities (device);
+			speed = 0;
+			if (NM_IS_DEVICE_ETHERNET (device)) {
+				/* Speed in Mb/s */
+				speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (device));
+			} else if (NM_IS_DEVICE_WIFI (device)) {
+				/* Speed in b/s */
+				speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (device));
+				speed /= 1000;
+			}
+			if (speed)
+				speed_str = g_strdup_printf (_("%u Mb/s"), speed);
+
+			nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[1].name;  /* "CAPABILITIES" */
+			nmc->allowed_fields[1].value = (caps & NM_DEVICE_CAP_CARRIER_DETECT) ? _("yes") : _("no");
+			nmc->allowed_fields[2].value = speed_str ? speed_str : _("unknown");
+
+			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+			g_free (speed_str);
+			was_output = TRUE;
+		}
+
+		/* Wireless specific information */
+		if ((NM_IS_DEVICE_WIFI (device))) {
+			guint32 wcaps;
+			NMAccessPoint *active_ap = NULL;
+			const char *active_bssid = NULL;
+			const GPtrArray *aps;
+
+			/* section WIFI-PROPERTIES */
+			if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[2].name)) {
+				wcaps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
+
+				nmc->allowed_fields = nmc_fields_dev_list_wifi_prop;
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_WIFI_PROP_ALL, nmc->allowed_fields, NULL);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+				nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[2].name;  /* "WIFI-PROPERTIES" */
+				nmc->allowed_fields[1].value = (wcaps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104)) ? _("yes") : _("no");
+				nmc->allowed_fields[2].value = (wcaps & NM_WIFI_DEVICE_CAP_WPA) ? _("yes") : _("no");
+				nmc->allowed_fields[3].value = (wcaps & NM_WIFI_DEVICE_CAP_RSN) ? _("yes") : _("no");
+				nmc->allowed_fields[4].value = (wcaps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) ? _("yes") : _("no");
+				nmc->allowed_fields[5].value = (wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) ? _("yes") : _("no");
+
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+				was_output = TRUE;
+			}
+
+			/* section AP */
+			if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[3].name)) {
+				if (state == NM_DEVICE_STATE_ACTIVATED) {
+					active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
+					active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
+				}
+
+				nmc->allowed_fields = nmc_fields_dev_wifi_list;
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST, nmc->allowed_fields, NULL);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+				info = g_malloc0 (sizeof (APInfo));
+				info->nmc = nmc;
+				info->index = 1;
+				info->active_bssid = active_bssid;
+				info->device = nm_device_get_iface (device);
+				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+				if (aps && aps->len)
+					g_ptr_array_foreach ((GPtrArray *) aps, detail_access_point, (gpointer) info);
+				g_free (info);
+				was_output = TRUE;
+			}
+		} else if (NM_IS_DEVICE_ETHERNET (device)) {
+			/* WIRED-PROPERTIES */
+			if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[4].name)) {
+				nmc->allowed_fields = nmc_fields_dev_list_wired_prop;
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_WIRED_PROP_ALL, nmc->allowed_fields, NULL);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+				nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[4].name;  /* "WIRED-PROPERTIES" */
+				nmc->allowed_fields[1].value = (nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (device))) ? _("on") : _("off");
+
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+				was_output = TRUE;
+			}
+		}
+
+		/* IP Setup info */
+		if (state == NM_DEVICE_STATE_ACTIVATED) {
+			NMIP4Config *cfg4 = nm_device_get_ip4_config (device);
+			NMIP6Config *cfg6 = nm_device_get_ip6_config (device);
+			GSList *iter;
+
+			/* IP4-SETTINGS */
+			if (cfg4 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[5].name)) {
+				nmc->allowed_fields = nmc_fields_dev_list_ip4_settings;
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_IP4_SETTINGS_ALL, nmc->allowed_fields, NULL);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+				for (iter = (GSList *) nm_ip4_config_get_addresses (cfg4); iter; iter = g_slist_next (iter)) {
+					NMIP4Address *addr = (NMIP4Address *) iter->data;
+					guint32 prefix = nm_ip4_address_get_prefix (addr);
+					char *tmp2;
+					char *addr_str, *prefix_str, *gateway_str;
+
+					addr_str = ip4_address_as_string (nm_ip4_address_get_address (addr));
+
+					tmp2 = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (prefix));
+					prefix_str = g_strdup_printf ("%d (%s)", prefix, tmp2);
+					g_free (tmp2);
+
+					gateway_str = ip4_address_as_string (nm_ip4_address_get_gateway (addr));
+
+					nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[5].name;  /* "IP4-SETTINGS" */
+					nmc->allowed_fields[1].value = addr_str;
+					nmc->allowed_fields[2].value = prefix_str;
+					nmc->allowed_fields[3].value = gateway_str;
+
+					nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+					print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+					g_free (addr_str);
+					g_free (prefix_str);
+					g_free (gateway_str);
+				}
+				was_output = TRUE;
+			}
+			/* IP4-DNS */
+			if (cfg4 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[6].name)) {
+				array = nm_ip4_config_get_nameservers (cfg4);
+				if (array) {
+					int i;
+
+					nmc->allowed_fields = nmc_fields_dev_list_ip4_dns;
+					nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+					nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_IP4_DNS_ALL, nmc->allowed_fields, NULL);
+					print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+					for (i = 0; i < array->len; i++) {
+						char *dns_name = g_strdup_printf ("%s%d", nmc_fields_dev_list_sections[6].name, i+1);
+						tmp = ip4_address_as_string (g_array_index (array, guint32, i));
+						nmc->allowed_fields[0].value = dns_name;  /* "IP4-DNS<num>" */
+						nmc->allowed_fields[1].value = tmp;
+
+						nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+						print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+						g_free (tmp);
+						g_free (dns_name);
+					}
+				}
+				was_output = TRUE;
+			}
+
+			/* IP6-SETTINGS */
+			if (cfg6 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[7].name)) {
+				nmc->allowed_fields = nmc_fields_dev_list_ip6_settings;
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_IP6_SETTINGS_ALL, nmc->allowed_fields, NULL);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+				for (iter = (GSList *) nm_ip6_config_get_addresses (cfg6); iter; iter = g_slist_next (iter)) {
+					NMIP6Address *addr = (NMIP6Address *) iter->data;
+					guint32 prefix = nm_ip6_address_get_prefix (addr);
+					char *addr_str, *prefix_str, *gateway_str;
+
+					addr_str = ip6_address_as_string (nm_ip6_address_get_address (addr));
+
+					prefix_str = g_strdup_printf ("%d", prefix);
+					gateway_str = ip6_address_as_string (nm_ip6_address_get_gateway (addr));
+
+					nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[7].name;  /* "IP6-SETTINGS" */
+					nmc->allowed_fields[1].value = addr_str;
+					nmc->allowed_fields[2].value = prefix_str;
+					nmc->allowed_fields[3].value = gateway_str;
+
+					nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+					print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+					g_free (addr_str);
+					g_free (prefix_str);
+					g_free (gateway_str);
+				}
+				was_output = TRUE;
+			}
+			/* IP6-DNS */
+			if (cfg6 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[8].name)) {
+				int i = 1;
+				nmc->allowed_fields = nmc_fields_dev_list_ip6_dns;
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_IP6_DNS_ALL, nmc->allowed_fields, NULL);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+				for (iter = (GSList *) nm_ip6_config_get_nameservers (cfg6); iter; iter = g_slist_next (iter)) {
+					char *dns_name = g_strdup_printf ("%s%d", nmc_fields_dev_list_sections[8].name, i++);
+
+					tmp = ip6_address_as_string (iter->data);
+					nmc->allowed_fields[0].value = dns_name;  /* "IP6-DNS<num>" */
+					nmc->allowed_fields[1].value = tmp;
+
+					nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+					print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+					g_free (tmp);
+					g_free (dns_name);
+				}
+				was_output = TRUE;
+			}
+		}
+	}
+
+	if (sections_array)
+		g_array_free (sections_array, TRUE);
+}
+
+static void
+show_device_status (NMDevice *device, NmCli *nmc)
+{
+	nmc->allowed_fields[0].value = nm_device_get_iface (device);
+	nmc->allowed_fields[1].value = get_device_type (device);
+	nmc->allowed_fields[2].value = device_state_to_string (nm_device_get_state (device));
+
+	nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
+	print_fields (nmc->print_fields, nmc->allowed_fields);
+}
+
+static NMCResultCode
+do_devices_status (NmCli *nmc, int argc, char **argv)
+{
+	GError *error = NULL;
+	const GPtrArray *devices;
+	int i;
+	char *fields_str;
+	char *fields_all =    NMC_FIELDS_DEV_STATUS_ALL;
+	char *fields_common = NMC_FIELDS_DEV_STATUS_COMMON;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	while (argc > 0) {
+		fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+		argc--;
+		argv++;
+	}
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto error;
+
+	devices = nm_client_get_devices (nmc->client);
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	nmc->allowed_fields = nmc_fields_dev_status;
+	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
+
+	if (error) {
+		if (error->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'dev status': %s"), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'dev status': %s; allowed fields: %s"), error->message, NMC_FIELDS_DEV_STATUS_ALL);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+	nmc->print_fields.header_name = _("Status of devices");
+	print_fields (nmc->print_fields, nmc->allowed_fields);
+
+	for (i = 0; devices && (i < devices->len); i++) {
+		NMDevice *device = g_ptr_array_index (devices, i);
+		show_device_status (device, nmc);
+	}
+
+	return NMC_RESULT_SUCCESS;
+
+error:
+	return nmc->return_value;
+}
+
+static NMCResultCode
+do_devices_list (NmCli *nmc, int argc, char **argv)
+{
+	const GPtrArray *devices;
+	NMDevice *device = NULL;
+	const char *iface = NULL;
+	gboolean iface_specified = FALSE;
+	int i;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "iface") == 0) {
+			iface_specified = TRUE;
+
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: '%s' argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			iface = *argv;
+		} else {
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+		}
+
+		argc--;
+		argv++;
+	}
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto error;
+
+	devices = nm_client_get_devices (nmc->client);
+
+	if (iface_specified) {
+		for (i = 0; devices && (i < devices->len); i++) {
+			NMDevice *candidate = g_ptr_array_index (devices, i);
+			const char *dev_iface = nm_device_get_iface (candidate);
+
+			if (!strcmp (dev_iface, iface))
+				device = candidate;
+		}
+		if (!device) {
+		 	g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface);
+			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			goto error;
+		}
+		show_device_info (device, nmc);
+	} else {
+		if (devices)
+			g_ptr_array_foreach ((GPtrArray *) devices, show_device_info, nmc);
+	}
+
+error:
+	return nmc->return_value;
+}
+
+static void
+device_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data)
+{
+	NmCli *nmc = (NmCli *) user_data;
+	NMDeviceState state;
+
+	state = nm_device_get_state (device);
+
+	if (state == NM_DEVICE_STATE_DISCONNECTED) {
+		g_string_printf (nmc->return_text, _("Success: Device '%s' successfully disconnected."), nm_device_get_iface (device));
+		quit ();
+	}
+}
+
+static gboolean
+timeout_cb (gpointer user_data)
+{
+	/* Time expired -> exit nmcli */
+
+	NmCli *nmc = (NmCli *) user_data;
+
+	g_string_printf (nmc->return_text, _("Error: Timeout %d sec expired."), nmc->timeout);
+	nmc->return_value = NMC_RESULT_ERROR_TIMEOUT_EXPIRED;
+	quit ();
+	return FALSE;
+}
+
+static void
+disconnect_device_cb (NMDevice *device, GError *error, gpointer user_data)
+{
+	NmCli *nmc = (NmCli *) user_data;
+	NMDeviceState state;
+
+	if (error) {
+		g_string_printf (nmc->return_text, _("Error: Device '%s' (%s) disconnecting failed: %s"),
+		                 nm_device_get_iface (device),
+		                 nm_object_get_path (NM_OBJECT (device)),
+		                 error->message ? error->message : _("(unknown)"));
+		nmc->return_value = NMC_RESULT_ERROR_DEV_DISCONNECT;
+		quit ();
+	} else {
+		state = nm_device_get_state (device);
+		printf (_("Device state: %d (%s)\n"), state, device_state_to_string (state));
+
+		if (!nmc->should_wait || state == NM_DEVICE_STATE_DISCONNECTED) {
+			/* Don't want to wait or device already disconnected */
+			quit ();
+		} else {
+			g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), nmc);
+			/* Start timer not to loop forever if "notify::state" signal is not issued */
+			g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc);
+		}
+
+	}
+}
+
+static NMCResultCode
+do_device_disconnect (NmCli *nmc, int argc, char **argv)
+{
+	const GPtrArray *devices;
+	NMDevice *device = NULL;
+	const char *iface = NULL;
+	gboolean iface_specified = FALSE;
+	gboolean wait = TRUE;
+	int i;
+
+	/* Set default timeout for disconnect operation */
+	nmc->timeout = 10;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "iface") == 0) {
+			iface_specified = TRUE;
+
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			iface = *argv;
+		} else if (strcmp (*argv, "--nowait") == 0) {
+			wait = FALSE;
+		} else if (strcmp (*argv, "--timeout") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+			errno = 0;
+			nmc->timeout = strtol (*argv, NULL, 10);
+			if (errno || nmc->timeout < 0) {
+				g_string_printf (nmc->return_text, _("Error: timeout value '%s' is not valid."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+
+		} else {
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+		}
+
+		argc--;
+		argv++;
+	}
+
+	if (!iface_specified) {
+		g_string_printf (nmc->return_text, _("Error: iface has to be specified."));
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto error;
+
+	devices = nm_client_get_devices (nmc->client);
+	for (i = 0; devices && (i < devices->len); i++) {
+		NMDevice *candidate = g_ptr_array_index (devices, i);
+		const char *dev_iface = nm_device_get_iface (candidate);
+
+		if (!strcmp (dev_iface, iface))
+			device = candidate;
+	}
+
+	if (!device) {
+		g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface);
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		goto error;
+	}
+
+	nmc->should_wait = wait;
+	nm_device_disconnect (device, disconnect_device_cb, nmc);
+
+error:
+	return nmc->return_value;
+}
+
+static void
+show_acces_point_info (NMDevice *device, NmCli *nmc)
+{
+	NMAccessPoint *active_ap = NULL;
+	const char *active_bssid = NULL;
+	const GPtrArray *aps;
+	APInfo *info;
+
+	if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
+		active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
+		active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
+	}
+
+	info = g_malloc0 (sizeof (APInfo));
+	info->nmc = nmc;
+	info->index = 1;
+	info->active_bssid = active_bssid;
+	info->device = nm_device_get_iface (device);
+	aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+	if (aps && aps->len)
+		g_ptr_array_foreach ((GPtrArray *) aps, detail_access_point, (gpointer) info);
+	g_free (info);
+}
+
+static NMCResultCode
+do_device_wifi_list (NmCli *nmc, int argc, char **argv)
+{
+	GError *error = NULL;
+	NMDevice *device = NULL;
+	NMAccessPoint *ap = NULL;
+	const char *iface = NULL;
+	const char *hwaddr_user = NULL;
+	const GPtrArray *devices;
+	const GPtrArray *aps;
+	APInfo *info;
+	int i, j;
+	char *fields_str;
+	char *fields_all =    NMC_FIELDS_DEV_WIFI_LIST_ALL;
+	char *fields_common = NMC_FIELDS_DEV_WIFI_LIST_COMMON;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "iface") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+			iface = *argv;
+		} else if (strcmp (*argv, "hwaddr") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+			hwaddr_user = *argv;
+		} else {
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+		}
+
+		argc--;
+		argv++;
+	}
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto error;
+
+	devices = nm_client_get_devices (nmc->client);
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	nmc->allowed_fields = nmc_fields_dev_wifi_list;
+	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
+
+	if (error) {
+		if (error->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'dev wifi': %s"), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'dev wifi': %s; allowed fields: %s"), error->message, NMC_FIELDS_DEV_WIFI_LIST_ALL);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+	nmc->print_fields.header_name = _("WiFi scan list");
+
+	if (iface) {
+		/* Device specified - list only APs of this interface */
+		for (i = 0; devices && (i < devices->len); i++) {
+			NMDevice *candidate = g_ptr_array_index (devices, i);
+			const char *dev_iface = nm_device_get_iface (candidate);
+
+			if (!strcmp (dev_iface, iface)) {
+				device = candidate;
+				break;
+			}
+		}
+
+		if (!device) {
+		 	g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface);
+			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			goto error;
+		}
+
+		if (NM_IS_DEVICE_WIFI (device)) {
+			if (hwaddr_user) {
+				/* Specific AP requested - list only that */
+				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+				for (j = 0; aps && (j < aps->len); j++) {
+					char *hwaddr_up;
+					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
+					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+
+					hwaddr_up = g_ascii_strup (hwaddr_user, -1);
+					if (!strcmp (hwaddr_up, candidate_hwaddr))
+						ap = candidate_ap;
+					g_free (hwaddr_up);
+				}
+				if (!ap) {
+				 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), hwaddr_user);
+					nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+					goto error;
+				}
+				info = g_malloc0 (sizeof (APInfo));
+				info->nmc = nmc;
+				info->index = 1;
+				info->active_bssid = NULL;
+				info->device = nm_device_get_iface (device);
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+				detail_access_point (ap, info);
+				g_free (info);
+			} else {
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+				show_acces_point_info (device, nmc);
+			}
+		} else {
+		 	g_string_printf (nmc->return_text, _("Error: Device '%s' is not a WiFi device."), iface);
+			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			goto error;
+		}
+	} else {
+		/* List APs for all devices */
+		print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+		if (hwaddr_user) {
+			/* Specific AP requested - list only that */
+			for (i = 0; devices && (i < devices->len); i++) {
+				NMDevice *dev = g_ptr_array_index (devices, i);
+
+				if (!NM_IS_DEVICE_WIFI (dev))
+					continue;
+
+				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
+				for (j = 0; aps && (j < aps->len); j++) {
+					char *hwaddr_up;
+					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
+					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+
+					hwaddr_up = g_ascii_strup (hwaddr_user, -1);
+					if (!strcmp (hwaddr_up, candidate_hwaddr)) {
+						ap = candidate_ap;
+
+						info = g_malloc0 (sizeof (APInfo));
+						info->nmc = nmc;
+						info->index = 1;
+						info->active_bssid = NULL;
+						info->device = nm_device_get_iface (dev);
+						detail_access_point (ap, info);
+						g_free (info);
+					}
+					g_free (hwaddr_up);
+				}
+			}
+			if (!ap) {
+			 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), hwaddr_user);
+				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+				goto error;
+			}
+		} else {
+			for (i = 0; devices && (i < devices->len); i++) {
+				NMDevice *dev = g_ptr_array_index (devices, i);
+				if (NM_IS_DEVICE_WIFI (dev))
+					show_acces_point_info (dev, nmc);
+			}
+		}
+	}
+
+error:
+	return nmc->return_value;
+}
+
+static NMCResultCode
+do_device_wifi (NmCli *nmc, int argc, char **argv)
+{
+	if (argc == 0)
+		nmc->return_value = do_device_wifi_list (nmc, argc-1, argv+1);
+	else if (argc > 0) {
+		if (matches (*argv, "list") == 0) {
+			nmc->return_value = do_device_wifi_list (nmc, argc-1, argv+1);
+		}
+		else {
+			g_string_printf (nmc->return_text, _("Error: 'dev wifi' command '%s' is not valid."), *argv);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		}
+	}
+
+	return nmc->return_value;
+}
+
+
+NMCResultCode
+do_devices (NmCli *nmc, int argc, char **argv)
+{
+	GError *error = NULL;
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto end;
+
+	if (argc == 0) {
+		if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+			goto opt_error;
+		nmc->return_value = do_devices_status (nmc, 0, NULL);
+	}
+
+	if (argc > 0) {
+		if (matches (*argv, "status") == 0) {
+			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+				goto opt_error;
+			nmc->return_value = do_devices_status (nmc, argc-1, argv+1);
+		}
+		else if (matches (*argv, "list") == 0) {
+			if (!nmc->mode_specified)
+				nmc->multiline_output = TRUE;  /* multiline mode is default for 'dev list' */
+			nmc->return_value = do_devices_list (nmc, argc-1, argv+1);
+		}
+		else if (matches (*argv, "disconnect") == 0) {
+			nmc->return_value = do_device_disconnect (nmc, argc-1, argv+1);
+		}
+		else if (matches (*argv, "wifi") == 0) {
+			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+				goto opt_error;
+			nmc->return_value = do_device_wifi (nmc, argc-1, argv+1);
+		}
+		else if (strcmp (*argv, "help") == 0) {
+			usage ();
+		}
+		else {
+			g_string_printf (nmc->return_text, _("Error: 'dev' command '%s' is not valid."), *argv);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		}
+	}
+
+end:
+	return nmc->return_value;
+
+opt_error:
+	g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+	nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+	g_error_free (error);
+	return nmc->return_value;
+}
diff --git a/cli/src/devices.h b/cli/src/devices.h
new file mode 100644
index 00000000..152dd207
--- /dev/null
+++ b/cli/src/devices.h
@@ -0,0 +1,27 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef NMC_DEVICES_H
+#define NMC_DEVICES_H
+
+#include "nmcli.h"
+
+NMCResultCode do_devices (NmCli *nmc, int argc, char **argv);
+
+#endif /* NMC_DEVICES_H */
diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c
new file mode 100644
index 00000000..b65dfcd7
--- /dev/null
+++ b/cli/src/network-manager.c
@@ -0,0 +1,278 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <nm-client.h>
+#include <nm-setting-connection.h>
+
+#include "utils.h"
+#include "network-manager.h"
+
+
+/* Available fields for 'nm status' */
+static NmcOutputField nmc_fields_nm_status[] = {
+	{"RUNNING",        N_("RUNNING"),         15, NULL, 0},  /* 0 */
+	{"STATE",          N_("STATE"),           15, NULL, 0},  /* 1 */
+	{"WIFI-HARDWARE",  N_("WIFI-HARDWARE"),   15, NULL, 0},  /* 2 */
+	{"WIFI",           N_("WIFI"),            10, NULL, 0},  /* 3 */
+	{"WWAN-HARDWARE",  N_("WWAN-HARDWARE"),   15, NULL, 0},  /* 4 */
+	{"WWAN",           N_("WWAN"),            10, NULL, 0},  /* 5 */
+	{NULL,             NULL,                   0, NULL, 0}
+};
+#define NMC_FIELDS_NM_STATUS_ALL     "RUNNING,STATE,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN"
+#define NMC_FIELDS_NM_STATUS_COMMON  "RUNNING,STATE,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN"
+#define NMC_FIELDS_NM_WIFI           "WIFI"
+#define NMC_FIELDS_NM_WWAN           "WWAN"
+
+
+extern GMainLoop *loop;
+
+/* static function prototypes */
+static void usage (void);
+static void quit (void);
+static const char *nm_state_to_string (NMState state);
+static NMCResultCode show_nm_status (NmCli *nmc);
+
+
+static void
+usage (void)
+{
+	fprintf (stderr,
+	 	 _("Usage: nmcli nm { COMMAND | help }\n\n"
+		 "  COMMAND := { status | sleep | wakeup | wifi | wwan }\n\n"
+		 "  status\n"
+		 "  sleep\n"
+		 "  wakeup\n"
+		 "  wifi [on|off]\n"
+		 "  wwan [on|off]\n\n"));
+}
+
+/* quit main loop */
+static void
+quit (void)
+{
+	g_main_loop_quit (loop);  /* quit main loop */
+}
+
+static const char *
+nm_state_to_string (NMState state)
+{
+	switch (state) {
+	case NM_STATE_ASLEEP:
+		return _("asleep");
+	case NM_STATE_CONNECTING:
+		return _("connecting");
+	case NM_STATE_CONNECTED:
+		return _("connected");
+	case NM_STATE_DISCONNECTED:
+		return _("disconnected");
+	case NM_STATE_UNKNOWN:
+	default:
+		return _("unknown");
+	}
+}
+
+static NMCResultCode
+show_nm_status (NmCli *nmc)
+{
+	gboolean nm_running;
+	NMState state;
+	const char *wireless_hw_enabled_str, *wireless_enabled_str;
+	const char *wwan_hw_enabled_str, *wwan_enabled_str;
+	GError *error = NULL;
+	const char *fields_str;
+	const char *fields_all =    NMC_FIELDS_NM_STATUS_ALL;
+	const char *fields_common = NMC_FIELDS_NM_STATUS_COMMON;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (nmc->client != NULL, NMC_RESULT_ERROR_UNKNOWN);
+
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else 
+		fields_str = nmc->required_fields;
+
+	nmc->allowed_fields = nmc_fields_nm_status;
+	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
+
+	if (error) {
+		if (error->code == 0)
+			g_string_printf (nmc->return_text, _("Error: 'nm status': %s"), error->message);
+		else
+			g_string_printf (nmc->return_text, _("Error: 'nm status': %s; allowed fields: %s"), error->message, NMC_FIELDS_NM_STATUS_ALL);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		return nmc->return_value;
+	}
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+	nmc->print_fields.header_name = _("NetworkManager status");
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+
+	nm_running = nm_client_get_manager_running (nmc->client);
+	state = nm_client_get_state (nmc->client);
+	if (nm_running) {
+		wireless_hw_enabled_str = nm_client_wireless_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
+		wireless_enabled_str = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled");
+		wwan_hw_enabled_str = nm_client_wwan_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
+		wwan_enabled_str = nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled");
+	} else {
+		wireless_hw_enabled_str = wireless_enabled_str = wwan_hw_enabled_str = wwan_enabled_str = _("unknown");
+	}
+
+	nmc->allowed_fields[0].value = nm_running ? _("running") : _("not running");
+	nmc->allowed_fields[1].value = nm_state_to_string (state);
+	nmc->allowed_fields[2].value = wireless_hw_enabled_str;
+	nmc->allowed_fields[3].value = wireless_enabled_str;
+	nmc->allowed_fields[4].value = wwan_hw_enabled_str;
+	nmc->allowed_fields[5].value = wwan_enabled_str;
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	return NMC_RESULT_SUCCESS;
+}
+
+
+/* entry point function for global network manager related commands 'nmcli nm' */
+NMCResultCode
+do_network_manager (NmCli *nmc, int argc, char **argv)
+{
+	GError *error = NULL;
+	gboolean enable_wifi;
+	gboolean enable_wwan;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	/* create NMClient */
+	if (!nmc->get_client (nmc))
+		goto end;
+
+	if (argc == 0) {
+		if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+			goto opt_error;
+		nmc->return_value = show_nm_status (nmc);
+	}
+
+	if (argc > 0) {
+		if (matches (*argv, "status") == 0) {
+			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+				goto opt_error;
+			nmc->return_value = show_nm_status (nmc);
+		}
+		else if (matches (*argv, "sleep") == 0) {
+			nm_client_sleep (nmc->client, TRUE);		
+		}
+		else if (matches (*argv, "wakeup") == 0) {
+			nm_client_sleep (nmc->client, FALSE);
+		}
+		else if (matches (*argv, "wifi") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				/* no argument, show current WiFi state */
+				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+					goto opt_error;
+				if (nmc->required_fields && strcasecmp (nmc->required_fields, "WIFI")) {
+					g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"),
+					                 nmc->required_fields, NMC_FIELDS_NM_WIFI);
+					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+					goto end;
+				}
+				nmc->allowed_fields = nmc_fields_nm_status;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_WIFI, nmc->allowed_fields, NULL);
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.header_name = _("WiFi enabled");
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+				nmc->allowed_fields[3].value = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled");
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+			} else {
+				if (!strcmp (*argv, "on"))
+					enable_wifi = TRUE;
+				else if (!strcmp (*argv, "off"))
+					enable_wifi = FALSE;
+				else {
+					g_string_printf (nmc->return_text, _("Error: invalid 'wifi' parameter: '%s'."), *argv);
+					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+					goto end;
+				}
+				nm_client_wireless_set_enabled (nmc->client, enable_wifi);
+			}
+		}
+		else if (matches (*argv, "wwan") == 0) {
+			if (next_arg (&argc, &argv) != 0) {
+				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
+					goto opt_error;
+				/* no argument, show current WWAN state */
+				if (nmc->required_fields && strcasecmp (nmc->required_fields, "WWAN")) {
+					g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"),
+					                 nmc->required_fields, NMC_FIELDS_NM_WWAN);
+					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+					goto end;
+				}
+				nmc->allowed_fields = nmc_fields_nm_status;
+				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_WWAN, nmc->allowed_fields, NULL);
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+				nmc->print_fields.header_name = _("WWAN enabled");
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+				nmc->allowed_fields[5].value = nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled");
+				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
+				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+			} else {
+				if (!strcmp (*argv, "on"))
+					enable_wwan = TRUE;
+				else if (!strcmp (*argv, "off"))
+					enable_wwan = FALSE;
+				else {
+					g_string_printf (nmc->return_text, _("Error: invalid 'wwan' parameter: '%s'."), *argv);
+					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+					goto end;
+				}
+				nm_client_wwan_set_enabled (nmc->client, enable_wwan);
+			}
+		}
+		else if (strcmp (*argv, "help") == 0) {
+			usage ();
+		}
+		else {
+			g_string_printf (nmc->return_text, _("Error: 'nm' command '%s' is not valid."), *argv);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		}
+	}
+
+end:
+	quit ();
+	return nmc->return_value;
+
+opt_error:
+	quit ();
+	g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+	nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+	g_error_free (error);
+	return nmc->return_value;
+}
diff --git a/cli/src/network-manager.h b/cli/src/network-manager.h
new file mode 100644
index 00000000..93cc1b07
--- /dev/null
+++ b/cli/src/network-manager.h
@@ -0,0 +1,27 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef NMC_NETWORK_MANAGER_H
+#define NMC_NETWORK_MANAGER_H
+
+#include "nmcli.h"
+
+NMCResultCode do_network_manager (NmCli *nmc, int argc, char **argv);
+
+#endif /* NMC_NETWORK_MANAGER_H */
diff --git a/cli/src/nmcli.c b/cli/src/nmcli.c
new file mode 100644
index 00000000..328a6d8e
--- /dev/null
+++ b/cli/src/nmcli.c
@@ -0,0 +1,363 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * Jiri Klimes <jklimes@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+/* Generated configuration file */
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <nm-client.h>
+#include <nm-setting-connection.h>
+#include <nm-remote-settings.h>
+#include <nm-remote-settings-system.h>
+#include <nm-settings-interface.h>
+#include <nm-settings-connection-interface.h>
+
+#include "nmcli.h"
+#include "utils.h"
+#include "connections.h"
+#include "devices.h"
+#include "network-manager.h"
+
+#if defined(NM_DIST_VERSION)
+# define NMCLI_VERSION NM_DIST_VERSION
+#else
+# define NMCLI_VERSION VERSION
+#endif
+
+
+typedef struct {
+	NmCli *nmc;
+	int argc;
+	char **argv;
+} ArgsInfo;
+
+/* --- Global variables --- */
+GMainLoop *loop = NULL;
+
+
+static void
+usage (const char *prog_name)
+{
+	fprintf (stderr,
+	         _("Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n\n"
+	         "OPTIONS\n"
+	         "  -t[erse]                                   terse output\n"
+	         "  -p[retty]                                  pretty output\n"
+	         "  -m[ode] tabular|multiline                  output mode\n"
+	         "  -f[ields] <field1,field2,...>|all|common   specify fields to output\n"
+	         "  -e[scape] yes|no                           escape columns separators in values\n"
+	         "  -v[ersion]                                 show program version\n"
+	         "  -h[elp]                                    print this help\n\n"
+	         "OBJECT\n"
+	         "  nm          NetworkManager status\n"
+	         "  con         NetworkManager connections\n"
+	         "  dev         devices managed by NetworkManager\n\n"),
+	          prog_name);
+}
+
+static NMCResultCode 
+do_help (NmCli *nmc, int argc, char **argv)
+{
+	usage ("nmcli");
+	return NMC_RESULT_SUCCESS;
+}
+
+static const struct cmd {
+	const char *cmd;
+	NMCResultCode (*func) (NmCli *nmc, int argc, char **argv);
+} nmcli_cmds[] = {
+	{ "nm",         do_network_manager },
+	{ "con",        do_connections },
+	{ "dev",        do_devices },
+	{ "help",       do_help },
+	{ 0 }
+};
+
+static NMCResultCode
+do_cmd (NmCli *nmc, const char *argv0, int argc, char **argv)
+{
+	const struct cmd *c;
+
+	for (c = nmcli_cmds; c->cmd; ++c) {
+		if (matches (argv0, c->cmd) == 0)
+			return c->func (nmc, argc-1, argv+1);
+	}
+
+	g_string_printf (nmc->return_text, _("Error: Object '%s' is unknown, try 'nmcli help'."), argv0);
+	nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+	return nmc->return_value;
+}
+
+static NMCResultCode
+parse_command_line (NmCli *nmc, int argc, char **argv)
+{
+	char *base;
+
+	base = strrchr (argv[0], '/');
+	if (base == NULL)
+		base = argv[0];
+	else
+		base++;
+
+	/* parse options */
+	while (argc > 1) {
+		char *opt = argv[1];
+		/* '--' ends options */
+		if (strcmp (opt, "--") == 0) {
+			argc--; argv++;
+			break;
+		}
+		if (opt[0] != '-')
+			break;
+		if (opt[1] == '-')
+			opt++;
+		if (matches (opt, "-terse") == 0) {
+			if (nmc->print_output == NMC_PRINT_TERSE) {
+				g_string_printf (nmc->return_text, _("Error: Option '--terse' is specified the second time."));
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			else if (nmc->print_output == NMC_PRINT_PRETTY) {
+				g_string_printf (nmc->return_text, _("Error: Option '--terse' is mutually exclusive with '--pretty'."));
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			else
+				nmc->print_output = NMC_PRINT_TERSE;
+		} else if (matches (opt, "-pretty") == 0) {
+			if (nmc->print_output == NMC_PRINT_PRETTY) {
+				g_string_printf (nmc->return_text, _("Error: Option '--pretty' is specified the second time."));
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			else if (nmc->print_output == NMC_PRINT_TERSE) {
+				g_string_printf (nmc->return_text, _("Error: Option '--pretty' is mutually exclusive with '--terse'."));
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			else
+				nmc->print_output = NMC_PRINT_PRETTY;
+		} else if (matches (opt, "-mode") == 0) {
+			nmc->mode_specified = TRUE;
+			next_arg (&argc, &argv);
+			if (argc <= 1) {
+		 		g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			if (!strcmp (argv[1], "tabular"))
+				nmc->multiline_output = FALSE;
+			else if (!strcmp (argv[1], "multiline"))
+				nmc->multiline_output = TRUE;
+			else {
+		 		g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+		} else if (matches (opt, "-escape") == 0) {
+			next_arg (&argc, &argv);
+			if (argc <= 1) {
+		 		g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			if (!strcmp (argv[1], "yes"))
+				nmc->escape_values = TRUE;
+			else if (!strcmp (argv[1], "no"))
+				nmc->escape_values = FALSE;
+			else {
+		 		g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+		} else if (matches (opt, "-fields") == 0) {
+			next_arg (&argc, &argv);
+			if (argc <= 1) {
+		 		g_string_printf (nmc->return_text, _("Error: fields for '%s' options are missing."), opt);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				return nmc->return_value;
+			}
+			nmc->required_fields = g_strdup (argv[1]);
+		} else if (matches (opt, "-version") == 0) {
+			printf (_("nmcli tool, version %s\n"), NMCLI_VERSION);
+			return NMC_RESULT_SUCCESS;
+		} else if (matches (opt, "-help") == 0) {
+			usage (base);
+			return NMC_RESULT_SUCCESS;
+		} else {
+			g_string_printf (nmc->return_text, _("Error: Option '%s' is unknown, try 'nmcli -help'."), opt);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+			return nmc->return_value;
+		}
+		argc--;
+		argv++;
+	}
+
+	if (argc > 1)
+		return do_cmd (nmc, argv[1], argc-1, argv+1);
+
+	usage (base);
+	return nmc->return_value;
+}
+
+static void
+signal_handler (int signo)
+{
+	if (signo == SIGINT || signo == SIGTERM) {
+		g_message (_("Caught signal %d, shutting down..."), signo);
+		g_main_loop_quit (loop);
+	}
+}
+
+static void
+setup_signals (void)
+{
+	struct sigaction action;
+	sigset_t mask;
+
+	sigemptyset (&mask);
+	action.sa_handler = signal_handler;
+	action.sa_mask = mask;
+	action.sa_flags = 0;
+	sigaction (SIGTERM,  &action, NULL);
+	sigaction (SIGINT,  &action, NULL);
+}
+
+static NMClient *
+nmc_get_client (NmCli *nmc)
+{
+	if (!nmc->client) {
+		nmc->client = nm_client_new ();
+		if (!nmc->client) {
+			g_string_printf (nmc->return_text, _("Error: Could not connect to NetworkManager."));
+			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		}
+	}
+
+	return nmc->client;
+}
+
+/* Initialize NmCli structure - set default values */
+static void
+nmc_init (NmCli *nmc)
+{
+	nmc->client = NULL;
+	nmc->get_client = &nmc_get_client;
+
+	nmc->return_value = NMC_RESULT_SUCCESS;
+	nmc->return_text = g_string_new (_("Success"));
+
+	nmc->timeout = 10;
+
+	nmc->system_settings = NULL;
+	nmc->user_settings = NULL;
+
+	nmc->system_settings_running = FALSE;
+	nmc->user_settings_running = FALSE;
+
+	nmc->system_connections = NULL;
+	nmc->user_connections = NULL;
+
+	nmc->should_wait = FALSE;
+	nmc->print_output = NMC_PRINT_NORMAL;
+	nmc->multiline_output = FALSE;
+	nmc->mode_specified = FALSE;
+	nmc->escape_values = TRUE;
+	nmc->required_fields = NULL;
+	nmc->allowed_fields = NULL;
+	memset (&nmc->print_fields, '\0', sizeof (NmcPrintFields));
+}
+
+static void
+nmc_cleanup (NmCli *nmc)
+{
+	if (nmc->client) g_object_unref (nmc->client);
+
+	g_string_free (nmc->return_text, TRUE);
+
+	if (nmc->system_settings) g_object_unref (nmc->system_settings);
+	if (nmc->user_settings) g_object_unref (nmc->user_settings);
+
+	g_slist_free (nmc->system_connections);
+	g_slist_free (nmc->user_connections);
+
+	g_free (nmc->required_fields);
+	if (nmc->print_fields.indices)
+		g_array_free (nmc->print_fields.indices, TRUE);
+}
+
+static gboolean
+start (gpointer data)
+{
+	ArgsInfo *info = (ArgsInfo *) data;
+	info->nmc->return_value = parse_command_line (info->nmc, info->argc, info->argv);
+
+	if (!info->nmc->should_wait)
+		g_main_loop_quit (loop);
+
+	return FALSE;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+	NmCli nmc;
+	ArgsInfo args_info = { &nmc, argc, argv };
+
+	/* Set locale to use environment variables */
+	setlocale (LC_ALL, "");
+
+#ifdef GETTEXT_PACKAGE
+	/* Set i18n stuff */
+	bindtextdomain (GETTEXT_PACKAGE, NMCLI_LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+#endif
+
+	g_type_init ();
+
+	nmc_init (&nmc);
+	g_idle_add (start, &args_info);
+
+	loop = g_main_loop_new (NULL, FALSE);  /* create main loop */
+	setup_signals ();                      /* setup UNIX signals */
+	g_main_loop_run (loop);                /* run main loop */
+
+	/* Print result descripting text */
+	if (nmc.return_value != NMC_RESULT_SUCCESS) {
+		fprintf (stderr, "%s\n", nmc.return_text->str);
+	}
+
+	g_main_loop_unref (loop);
+	nmc_cleanup (&nmc);
+
+	return nmc.return_value;
+}
diff --git a/cli/src/nmcli.h b/cli/src/nmcli.h
new file mode 100644
index 00000000..b4e4562b
--- /dev/null
+++ b/cli/src/nmcli.h
@@ -0,0 +1,114 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef NMC_NMCLI_H
+#define NMC_NMCLI_H
+
+#include <glib.h>
+
+#include <nm-client.h>
+#include <nm-remote-settings.h>
+#include <nm-remote-settings-system.h>
+
+/* nmcli exit codes */
+typedef enum {
+	/* Indicates successful execution */
+	NMC_RESULT_SUCCESS = 0,
+
+	/* Unknown / unspecified error */
+	NMC_RESULT_ERROR_UNKNOWN = 1,
+
+	/* Wrong invocation of nmcli */
+	NMC_RESULT_ERROR_USER_INPUT = 2,
+
+	/* A timeout expired */
+	NMC_RESULT_ERROR_TIMEOUT_EXPIRED = 3,
+
+	/* Error in connection activation */
+	NMC_RESULT_ERROR_CON_ACTIVATION = 4,
+
+	/* Error in connection deactivation */
+	NMC_RESULT_ERROR_CON_DEACTIVATION = 5,
+
+	/* Error in device disconnect */
+	NMC_RESULT_ERROR_DEV_DISCONNECT = 6
+} NMCResultCode;
+
+typedef enum {
+	NMC_PRINT_TERSE = 0,
+	NMC_PRINT_NORMAL = 1,
+	NMC_PRINT_PRETTY = 2
+} NMCPrintOutput;
+
+/* === Output fields === */
+typedef struct {
+	const char *name;       /* Field's name */
+	const char *name_l10n;  /* Field's name for translation */
+	int width;              /* Width in screen columns */
+	const char *value;      /* Value of current field */
+	guint32 flags;          /* Flags */
+} NmcOutputField;
+
+/* Flags for NmcPrintFields */
+#define	NMC_PF_FLAG_MULTILINE          0x00000001   /* Multiline output instead of tabular */
+#define	NMC_PF_FLAG_TERSE              0x00000002   /* Terse output mode */
+#define	NMC_PF_FLAG_PRETTY             0x00000004   /* Pretty output mode */
+#define	NMC_PF_FLAG_MAIN_HEADER_ADD    0x00000008   /* Print main header in addition to values/field names */
+#define	NMC_PF_FLAG_MAIN_HEADER_ONLY   0x00000010   /* Print main header only */
+#define	NMC_PF_FLAG_FIELD_NAMES        0x00000020   /* Print field names instead of values */
+#define	NMC_PF_FLAG_ESCAPE             0x00000040   /* Escape column separator and '\' */
+#define	NMC_PF_FLAG_SECTION_PREFIX     0x00000080   /* Use the first value as section prefix for the other field names - just in multiline */
+
+typedef struct {
+	GArray *indices;      /* Array of field indices to the array of allowed fields */
+	char *header_name;    /* Name of the output */
+	int indent;           /* Indent by this number of spaces */
+	guint32 flags;        /* Various flags for controlling output: see NMC_PF_FLAG_* values */
+} NmcPrintFields;
+
+/* NmCli - main structure */
+typedef struct _NmCli {
+	NMClient *client;                                 /* Pointer to NMClient of libnm-glib */
+	NMClient *(*get_client) (struct _NmCli *nmc);     /* Pointer to function for creating NMClient */
+
+	NMCResultCode return_value;                       /* Return code of nmcli */
+	GString *return_text;                             /* Reason text */
+
+	int timeout;                                      /* Operation timeout */
+
+	NMRemoteSettingsSystem *system_settings;          /* System settings */
+	NMRemoteSettings *user_settings;                  /* User settings */
+
+	gboolean system_settings_running;                 /* Is system settings service running? */
+	gboolean user_settings_running;                   /* Is user settings service running? */
+
+	GSList *system_connections;                       /* List of system connections */
+	GSList *user_connections;                         /* List of user connections */
+
+	gboolean should_wait;                             /* Indication that nmcli should not end yet */
+	NMCPrintOutput print_output;                      /* Output mode */
+	gboolean multiline_output;                        /* Multiline output instead of default tabular */
+	gboolean mode_specified;                          /* Whether tabular/multiline mode was specified via '--mode' option */
+	gboolean escape_values;                           /* Whether to escape ':' and '\' in terse tabular mode */
+	char *required_fields;                            /* Required fields in output: '--fields' option */
+	NmcOutputField *allowed_fields;                   /* Array of allowed fields for particular commands */
+	NmcPrintFields print_fields;                      /* Structure with field indices to print */
+} NmCli;
+
+#endif /* NMC_NMCLI_H */
diff --git a/cli/src/settings.c b/cli/src/settings.c
new file mode 100644
index 00000000..1371bfbe
--- /dev/null
+++ b/cli/src/settings.c
@@ -0,0 +1,1369 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libnm-util/nm-utils.h>
+
+#include "utils.h"
+#include "settings.h"
+
+
+/* Helper macro to define fields */
+#define SETTING_FIELD(setting, width) { setting, N_(setting), width, NULL, 0 }
+
+/* Available fields for NM_SETTING_CONNECTION_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_connection[] = {
+	SETTING_FIELD ("name",  15),                            /* 0 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_ID, 25),           /* 1 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_UUID, 38),         /* 2 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_TYPE, 17),         /* 3 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT, 13),  /* 4 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP, 10),    /* 5 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY, 10),    /* 6 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_CONNECTION_ALL     "name"","\
+                                              NM_SETTING_CONNECTION_ID","\
+                                              NM_SETTING_CONNECTION_UUID","\
+                                              NM_SETTING_CONNECTION_TYPE","\
+                                              NM_SETTING_CONNECTION_AUTOCONNECT","\
+                                              NM_SETTING_CONNECTION_TIMESTAMP","\
+                                              NM_SETTING_CONNECTION_READ_ONLY
+#define NMC_FIELDS_SETTING_CONNECTION_COMMON  NMC_FIELDS_SETTING_CONNECTION_ALL
+
+/* Available fields for NM_SETTING_WIRED_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_wired[] = {
+	SETTING_FIELD ("name",  17),                          /* 0 */
+	SETTING_FIELD (NM_SETTING_WIRED_PORT, 8),             /* 1 */
+	SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10),           /* 2 */
+	SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10),          /* 3 */
+	SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15),  /* 4 */
+	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19),     /* 5 */
+	SETTING_FIELD (NM_SETTING_WIRED_MTU, 6),              /* 6 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_WIRED_ALL     "name"","\
+                                         NM_SETTING_WIRED_PORT","\
+                                         NM_SETTING_WIRED_SPEED","\
+                                         NM_SETTING_WIRED_DUPLEX","\
+                                         NM_SETTING_WIRED_AUTO_NEGOTIATE","\
+                                         NM_SETTING_WIRED_MAC_ADDRESS","\
+                                         NM_SETTING_WIRED_MTU
+#define NMC_FIELDS_SETTING_WIRED_COMMON  NMC_FIELDS_SETTING_WIRED_ALL
+
+/* Available fields for NM_SETTING_802_1X_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_8021X[] = {
+	SETTING_FIELD ("name", 10),                                         /* 0 */
+	SETTING_FIELD (NM_SETTING_802_1X_EAP, 10),                          /* 1 */
+	SETTING_FIELD (NM_SETTING_802_1X_IDENTITY, 15),                     /* 2 */
+	SETTING_FIELD (NM_SETTING_802_1X_ANONYMOUS_IDENTITY, 15),           /* 3 */
+	SETTING_FIELD (NM_SETTING_802_1X_CA_CERT, 10),                      /* 4 */
+	SETTING_FIELD (NM_SETTING_802_1X_CA_PATH, 10),                      /* 5 */
+	SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT, 10),                  /* 6 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER, 10),               /* 7 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL, 10),             /* 8 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, 10),     /* 9 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH, 10),                  /* 10 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP, 10),               /* 11 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT, 20),               /* 12 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH, 20),               /* 13 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, 20),           /* 14 */
+	SETTING_FIELD (NM_SETTING_802_1X_PASSWORD, 10),                     /* 15 */
+	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY, 15),                  /* 16 */
+	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, 20),         /* 17 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, 20),           /* 18 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, 20),  /* 19 */
+	SETTING_FIELD (NM_SETTING_802_1X_PIN, 8),                           /* 20 */
+	SETTING_FIELD (NM_SETTING_802_1X_PSK, 8),                           /* 21 */
+	SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17),              /* 22 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_802_1X_ALL     "name"","\
+                                          NM_SETTING_802_1X_EAP","\
+                                          NM_SETTING_802_1X_IDENTITY","\
+                                          NM_SETTING_802_1X_ANONYMOUS_IDENTITY","\
+                                          NM_SETTING_802_1X_CA_CERT","\
+                                          NM_SETTING_802_1X_CA_PATH","\
+                                          NM_SETTING_802_1X_CLIENT_CERT","\
+                                          NM_SETTING_802_1X_PHASE1_PEAPVER","\
+                                          NM_SETTING_802_1X_PHASE1_PEAPLABEL","\
+                                          NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING","\
+                                          NM_SETTING_802_1X_PHASE2_AUTH","\
+                                          NM_SETTING_802_1X_PHASE2_AUTHEAP","\
+                                          NM_SETTING_802_1X_PHASE2_CA_CERT","\
+                                          NM_SETTING_802_1X_PHASE2_CA_PATH","\
+                                          NM_SETTING_802_1X_PHASE2_CLIENT_CERT","\
+                                          NM_SETTING_802_1X_PASSWORD","\
+                                          NM_SETTING_802_1X_PRIVATE_KEY","\
+                                          NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD","\
+                                          NM_SETTING_802_1X_PHASE2_PRIVATE_KEY","\
+                                          NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD","\
+                                          NM_SETTING_802_1X_PIN","\
+                                          NM_SETTING_802_1X_PSK","\
+                                          NM_SETTING_802_1X_SYSTEM_CA_CERTS
+#define NMC_FIELDS_SETTING_802_1X_COMMON  NMC_FIELDS_SETTING_802_1X_ALL
+
+/* Available fields for NM_SETTING_WIRELESS_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_wireless[] = {
+	SETTING_FIELD ("name", 17),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SSID, 34),                      /* 1 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MODE, 15),                      /* 2 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_BAND, 10),                      /* 3 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_CHANNEL, 10),                   /* 4 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_BSSID, 19),                     /* 5 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_RATE, 10),                      /* 6 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_TX_POWER, 10),                  /* 7 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS, 19),               /* 8 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6),                        /* 9 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35),               /* 10 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10),                       /* 11 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_WIRELESS_ALL     "name"","\
+                                            NM_SETTING_WIRELESS_SSID","\
+                                            NM_SETTING_WIRELESS_MODE","\
+                                            NM_SETTING_WIRELESS_BAND","\
+                                            NM_SETTING_WIRELESS_CHANNEL","\
+                                            NM_SETTING_WIRELESS_BSSID","\
+                                            NM_SETTING_WIRELESS_RATE","\
+                                            NM_SETTING_WIRELESS_TX_POWER","\
+                                            NM_SETTING_WIRELESS_MAC_ADDRESS","\
+                                            NM_SETTING_WIRELESS_MTU","\
+                                            NM_SETTING_WIRELESS_SEEN_BSSIDS","\
+                                            NM_SETTING_WIRELESS_SEC
+#define NMC_FIELDS_SETTING_WIRELESS_COMMON  NMC_FIELDS_SETTING_WIRELESS_ALL
+
+/* Available fields for NM_SETTING_WIRELESS_SECURITY_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_wireless_security[] = {
+	SETTING_FIELD ("name", 25),                                      /* 0 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, 10),       /* 1 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 15),  /* 2 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, 10),       /* 3 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_PROTO, 10),          /* 4 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, 10),       /* 5 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_GROUP, 10),          /* 6 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, 15),  /* 7 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, 10),       /* 8 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, 10),       /* 9 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, 10),       /* 10 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, 10),       /* 11 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_PSK, 6),             /* 12 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, 15),  /* 13 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, 15),   /* 14 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_WIRELESS_SECURITY_ALL     "name"","\
+                                                     NM_SETTING_WIRELESS_SECURITY_KEY_MGMT","\
+                                                     NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX","\
+                                                     NM_SETTING_WIRELESS_SECURITY_AUTH_ALG","\
+                                                     NM_SETTING_WIRELESS_SECURITY_PROTO","\
+                                                     NM_SETTING_WIRELESS_SECURITY_PAIRWISE","\
+                                                     NM_SETTING_WIRELESS_SECURITY_GROUP","\
+                                                     NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME","\
+                                                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY0","\
+                                                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY1","\
+                                                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY2","\
+                                                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY3","\
+                                                     NM_SETTING_WIRELESS_SECURITY_PSK","\
+                                                     NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD","\
+                                                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE
+#define NMC_FIELDS_SETTING_WIRELESS_SECURITY_COMMON  NMC_FIELDS_SETTING_WIRELESS_SECURITY_ALL
+
+/* Available fields for NM_SETTING_IP4_CONFIG_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_ip4_config[] = {
+	SETTING_FIELD ("name", 8),                                         /* 0 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_METHOD, 10),                  /* 1 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DNS, 20),                     /* 2 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DNS_SEARCH, 15),              /* 3 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_ADDRESSES, 20),               /* 4 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_ROUTES, 20),                  /* 5 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, 19),      /* 6 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, 16),         /* 7 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, 15),          /* 8 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, 19),      /* 9 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, 14),           /* 10 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, 15),           /* 11 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_IP4_CONFIG_ALL     "name"","\
+                                              NM_SETTING_IP4_CONFIG_METHOD","\
+                                              NM_SETTING_IP4_CONFIG_DNS","\
+                                              NM_SETTING_IP4_CONFIG_DNS_SEARCH","\
+                                              NM_SETTING_IP4_CONFIG_ADDRESSES","\
+                                              NM_SETTING_IP4_CONFIG_ROUTES","\
+                                              NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES","\
+                                              NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS","\
+                                              NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID","\
+                                              NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME","\
+                                              NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME","\
+                                              NM_SETTING_IP4_CONFIG_NEVER_DEFAULT
+#define NMC_FIELDS_SETTING_IP4_CONFIG_COMMON  NMC_FIELDS_SETTING_IP4_CONFIG_ALL
+
+/* Available fields for NM_SETTING_IP6_CONFIG_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_ip6_config[] = {
+	SETTING_FIELD ("name", 8),                                         /* 0 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_METHOD, 10),                  /* 1 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_DNS, 20),                     /* 2 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_DNS_SEARCH, 15),              /* 3 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDRESSES, 20),               /* 4 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_ROUTES, 20),                  /* 5 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, 19),      /* 6 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, 16),         /* 7 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, 15),           /* 8 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_IP6_CONFIG_ALL     "name"","\
+                                              NM_SETTING_IP6_CONFIG_METHOD","\
+                                              NM_SETTING_IP6_CONFIG_DNS","\
+                                              NM_SETTING_IP6_CONFIG_DNS_SEARCH","\
+                                              NM_SETTING_IP6_CONFIG_ADDRESSES","\
+                                              NM_SETTING_IP6_CONFIG_ROUTES","\
+                                              NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES","\
+                                              NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS","\
+                                              NM_SETTING_IP6_CONFIG_NEVER_DEFAULT
+#define NMC_FIELDS_SETTING_IP6_CONFIG_COMMON  NMC_FIELDS_SETTING_IP4_CONFIG_ALL
+
+/* Available fields for NM_SETTING_SERIAL_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_serial[] = {
+	SETTING_FIELD ("name", 10),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_SERIAL_BAUD, 10),                        /* 1 */
+	SETTING_FIELD (NM_SETTING_SERIAL_BITS, 10),                        /* 2 */
+	SETTING_FIELD (NM_SETTING_SERIAL_PARITY, 10),                      /* 3 */
+	SETTING_FIELD (NM_SETTING_SERIAL_STOPBITS, 10),                    /* 4 */
+	SETTING_FIELD (NM_SETTING_SERIAL_SEND_DELAY, 12),                  /* 5 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_SERIAL_ALL     "name"","\
+                                          NM_SETTING_SERIAL_BAUD","\
+                                          NM_SETTING_SERIAL_BITS","\
+                                          NM_SETTING_SERIAL_PARITY","\
+                                          NM_SETTING_SERIAL_STOPBITS","\
+                                          NM_SETTING_SERIAL_SEND_DELAY
+#define NMC_FIELDS_SETTING_SERIAL_COMMON  NMC_FIELDS_SETTING_SERIAL_ALL
+
+/* Available fields for NM_SETTING_PPP_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_ppp[] = {
+	SETTING_FIELD ("name", 10),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_PPP_NOAUTH, 10),                         /* 1 */
+	SETTING_FIELD (NM_SETTING_PPP_REFUSE_EAP, 10),                     /* 2 */
+	SETTING_FIELD (NM_SETTING_PPP_REFUSE_PAP, 10),                     /* 3 */
+	SETTING_FIELD (NM_SETTING_PPP_REFUSE_CHAP, 10),                    /* 4 */
+	SETTING_FIELD (NM_SETTING_PPP_REFUSE_MSCHAP, 10),                  /* 5 */
+	SETTING_FIELD (NM_SETTING_PPP_REFUSE_MSCHAPV2, 10),                /* 6 */
+	SETTING_FIELD (NM_SETTING_PPP_NOBSDCOMP, 10),                      /* 7 */
+	SETTING_FIELD (NM_SETTING_PPP_NODEFLATE, 10),                      /* 8 */
+	SETTING_FIELD (NM_SETTING_PPP_NO_VJ_COMP, 10),                     /* 9 */
+	SETTING_FIELD (NM_SETTING_PPP_REQUIRE_MPPE, 10),                   /* 10 */
+	SETTING_FIELD (NM_SETTING_PPP_REQUIRE_MPPE_128, 10),               /* 11 */
+	SETTING_FIELD (NM_SETTING_PPP_MPPE_STATEFUL, 10),                  /* 12 */
+	SETTING_FIELD (NM_SETTING_PPP_CRTSCTS, 10),                        /* 13 */
+	SETTING_FIELD (NM_SETTING_PPP_BAUD, 10),                           /* 14 */
+	SETTING_FIELD (NM_SETTING_PPP_MRU, 10),                            /* 15 */
+	SETTING_FIELD (NM_SETTING_PPP_MTU, 10),                            /* 16 */
+	SETTING_FIELD (NM_SETTING_PPP_LCP_ECHO_FAILURE, 17),               /* 17 */
+	SETTING_FIELD (NM_SETTING_PPP_LCP_ECHO_INTERVAL, 18),              /* 18 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_PPP_ALL     "name"","\
+                                       NM_SETTING_PPP_NOAUTH","\
+                                       NM_SETTING_PPP_REFUSE_EAP","\
+                                       NM_SETTING_PPP_REFUSE_PAP","\
+                                       NM_SETTING_PPP_REFUSE_CHAP","\
+                                       NM_SETTING_PPP_REFUSE_MSCHAP","\
+                                       NM_SETTING_PPP_REFUSE_MSCHAPV2","\
+                                       NM_SETTING_PPP_NOBSDCOMP","\
+                                       NM_SETTING_PPP_NODEFLATE","\
+                                       NM_SETTING_PPP_NO_VJ_COMP","\
+                                       NM_SETTING_PPP_REQUIRE_MPPE","\
+                                       NM_SETTING_PPP_REQUIRE_MPPE_128","\
+                                       NM_SETTING_PPP_MPPE_STATEFUL","\
+                                       NM_SETTING_PPP_CRTSCTS","\
+                                       NM_SETTING_PPP_BAUD","\
+                                       NM_SETTING_PPP_MRU","\
+                                       NM_SETTING_PPP_MTU","\
+                                       NM_SETTING_PPP_LCP_ECHO_FAILURE","\
+                                       NM_SETTING_PPP_LCP_ECHO_INTERVAL
+#define NMC_FIELDS_SETTING_PPP_COMMON  NMC_FIELDS_SETTING_PPP_ALL
+
+/* Available fields for NM_SETTING_PPPOE_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_pppoe[] = {
+	SETTING_FIELD ("name", 10),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_PPPOE_SERVICE, 12),                      /* 1 */
+	SETTING_FIELD (NM_SETTING_PPPOE_USERNAME, 15),                     /* 2 */
+	SETTING_FIELD (NM_SETTING_PPPOE_PASSWORD, 15),                     /* 3 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_PPPOE_ALL     "name"","\
+                                         NM_SETTING_PPPOE_SERVICE","\
+                                         NM_SETTING_PPPOE_USERNAME","\
+                                         NM_SETTING_PPPOE_PASSWORD
+#define NMC_FIELDS_SETTING_PPPOE_COMMON  NMC_FIELDS_SETTING_PPP_ALL
+
+/* Available fields for NM_SETTING_GSM_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_gsm[] = {
+	SETTING_FIELD ("name", 10),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_GSM_NUMBER, 10),                         /* 1 */
+	SETTING_FIELD (NM_SETTING_GSM_USERNAME, 15),                       /* 2 */
+	SETTING_FIELD (NM_SETTING_GSM_PASSWORD, 15),                       /* 3 */
+	SETTING_FIELD (NM_SETTING_GSM_APN, 25),                            /* 4 */
+	SETTING_FIELD (NM_SETTING_GSM_NETWORK_ID, 12),                     /* 5 */
+	SETTING_FIELD (NM_SETTING_GSM_NETWORK_TYPE, 15),                   /* 6 */
+	SETTING_FIELD (NM_SETTING_GSM_ALLOWED_BANDS, 15),                  /* 7 */
+	SETTING_FIELD (NM_SETTING_GSM_PIN, 10),                            /* 8 */
+	SETTING_FIELD (NM_SETTING_GSM_HOME_ONLY, 10),                      /* 9 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_GSM_ALL     "name"","\
+                                       NM_SETTING_GSM_NUMBER","\
+                                       NM_SETTING_GSM_USERNAME","\
+                                       NM_SETTING_GSM_PASSWORD","\
+                                       NM_SETTING_GSM_APN","\
+                                       NM_SETTING_GSM_NETWORK_ID","\
+                                       NM_SETTING_GSM_NETWORK_TYPE","\
+                                       NM_SETTING_GSM_ALLOWED_BANDS","\
+                                       NM_SETTING_GSM_PIN","\
+                                       NM_SETTING_GSM_HOME_ONLY
+#define NMC_FIELDS_SETTING_GSM_COMMON  NMC_FIELDS_SETTING_GSM_ALL
+
+/* Available fields for NM_SETTING_CDMA_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_cdma[] = {
+	SETTING_FIELD ("name", 10),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_CDMA_NUMBER, 15),                        /* 1 */
+	SETTING_FIELD (NM_SETTING_CDMA_USERNAME, 15),                      /* 2 */
+	SETTING_FIELD (NM_SETTING_CDMA_PASSWORD, 15),                      /* 3 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_CDMA_ALL     "name"","\
+                                        NM_SETTING_CDMA_NUMBER","\
+                                        NM_SETTING_CDMA_USERNAME","\
+                                        NM_SETTING_CDMA_PASSWORD
+#define NMC_FIELDS_SETTING_CDMA_COMMON  NMC_FIELDS_SETTING_CDMA_ALL
+
+/* Available fields for NM_SETTING_BLUETOOTH_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_bluetooth[] = {
+	SETTING_FIELD ("name", 11),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_BLUETOOTH_BDADDR, 19),                   /* 1 */
+	SETTING_FIELD (NM_SETTING_BLUETOOTH_TYPE, 10),                     /* 2 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_BLUETOOTH_ALL     "name"","\
+                                             NM_SETTING_BLUETOOTH_BDADDR","\
+                                             NM_SETTING_BLUETOOTH_TYPE
+#define NMC_FIELDS_SETTING_BLUETOOTH_COMMON  NMC_FIELDS_SETTING_BLUETOOTH_ALL
+
+/* Available fields for NM_SETTING_OLPC_MESH_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_olpc_mesh[] = {
+	SETTING_FIELD ("name", 18),                                        /* 0 */
+	SETTING_FIELD (NM_SETTING_OLPC_MESH_SSID, 34),                     /* 1 */
+	SETTING_FIELD (NM_SETTING_OLPC_MESH_CHANNEL, 12),                  /* 2 */
+	SETTING_FIELD (NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, 17),     /* 3 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_OLPC_MESH_ALL     "name"","\
+                                             NM_SETTING_OLPC_MESH_SSID","\
+                                             NM_SETTING_OLPC_MESH_CHANNEL","\
+                                             NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS
+#define NMC_FIELDS_SETTING_OLPC_MESH_COMMON  NMC_FIELDS_SETTING_OLPC_MESH_ALL
+
+/* Available fields for NM_SETTING_VPN_SETTING_NAME */
+static NmcOutputField nmc_fields_setting_vpn[] = {
+	SETTING_FIELD ("name", 6),                                         /* 0 */
+	SETTING_FIELD (NM_SETTING_VPN_SERVICE_TYPE, 40),                   /* 1 */
+	SETTING_FIELD (NM_SETTING_VPN_USER_NAME, 12),                      /* 2 */
+	SETTING_FIELD (NM_SETTING_VPN_DATA, 30),                           /* 3 */
+	SETTING_FIELD (NM_SETTING_VPN_SECRETS, 15),                        /* 4 */
+	{NULL, NULL, 0, NULL, 0}
+};
+#define NMC_FIELDS_SETTING_VPN_ALL     "name"","\
+                                       NM_SETTING_VPN_SERVICE_TYPE","\
+                                       NM_SETTING_VPN_USER_NAME","\
+                                       NM_SETTING_VPN_DATA","\
+                                       NM_SETTING_VPN_SECRETS
+#define NMC_FIELDS_SETTING_VPN_COMMON  NMC_FIELDS_SETTING_VPN_ALL
+
+
+static char *
+wep_key_type_to_string (NMWepKeyType type)
+{
+	switch (type) {
+	case NM_WEP_KEY_TYPE_KEY:
+		return g_strdup_printf (_("%d (hex-ascii-key)"), type);
+	case NM_WEP_KEY_TYPE_PASSPHRASE:
+		return g_strdup_printf (_("%d (104/128-bit passphrase)"), type);
+	case NM_WEP_KEY_TYPE_UNKNOWN:
+	default:
+		return g_strdup_printf (_("%d (unknown)"), type);
+	}
+}
+
+static char *
+blob_cert_to_string (const GByteArray *array)
+{
+	GString *cert = NULL;
+	int i;
+
+	if (array->len > 0)
+		cert = g_string_new (NULL);
+
+	for (i = 0; i < array->len; i++) {
+		g_string_append_printf (cert, "%02X", array->data[i]);
+	}
+
+	return cert ? g_string_free (cert, FALSE) : NULL;
+}
+
+static char *
+allowed_bands_to_string (guint32 bands)
+{
+	GString *band_str;
+
+	if (bands == NM_SETTING_GSM_BAND_UNKNOWN)
+		return g_strdup (_("0 (unknown)"));
+
+	band_str = g_string_new (NULL);
+	g_string_printf (band_str, "%d (", bands);
+
+	if (bands & NM_SETTING_GSM_BAND_ANY)
+		g_string_append (band_str, _("any, "));
+	if (bands & NM_SETTING_GSM_BAND_EGSM)
+		g_string_append (band_str, _("900 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_DCS)
+		g_string_append (band_str, _("1800 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_PCS)
+		g_string_append (band_str, _("1900 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_G850)
+		g_string_append (band_str, _("850 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U2100)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 2100 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U1800)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 1800 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U17IV)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 1700/2100 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U800)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 800 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U850)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 850 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U900)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 900 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U17IX)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 1700 MHz, "));
+
+	if (band_str->str[band_str->len-1] == '(')
+		g_string_assign (band_str, _("unknown"));
+	else
+		g_string_truncate (band_str, band_str->len-2);  /* chop off trailing ', ' */
+
+	g_string_append_c (band_str, ')');
+
+	return g_string_free (band_str, FALSE);
+}
+
+
+gboolean
+setting_connection_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingConnection *s_con;
+	guint64 timestamp;
+	char *timestamp_str;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
+	s_con = (NMSettingConnection *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_connection;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_CONNECTION_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	timestamp = nm_setting_connection_get_timestamp (s_con);
+	timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
+
+	nmc->allowed_fields[0].value = NM_SETTING_CONNECTION_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_connection_get_id (s_con);
+	nmc->allowed_fields[2].value = nm_setting_connection_get_uuid (s_con);
+	nmc->allowed_fields[3].value = nm_setting_connection_get_connection_type (s_con);
+	nmc->allowed_fields[4].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no");
+	nmc->allowed_fields[5].value = timestamp_str;
+	nmc->allowed_fields[6].value = nm_setting_connection_get_read_only (s_con) ? ("yes") : _("no");
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (timestamp_str);
+
+	return TRUE;
+}
+
+gboolean
+setting_wired_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingWired *s_wired;
+	const GByteArray *mac;
+	char *speed_str, *mtu_str, *mac_str = NULL;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
+	s_wired = (NMSettingWired *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_wired;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRED_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	speed_str = g_strdup_printf ("%d", nm_setting_wired_get_speed (s_wired));
+	mtu_str = g_strdup_printf ("%d", nm_setting_wired_get_mtu (s_wired));
+	mac = nm_setting_wired_get_mac_address (s_wired);
+	if (mac)
+		mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
+
+	nmc->allowed_fields[0].value = NM_SETTING_WIRED_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_wired_get_port (s_wired);
+	nmc->allowed_fields[2].value = speed_str;
+	nmc->allowed_fields[3].value = nm_setting_wired_get_duplex (s_wired);
+	nmc->allowed_fields[4].value = nm_setting_wired_get_auto_negotiate (s_wired) ? _("yes") : _("no");
+	nmc->allowed_fields[5].value = mac_str;
+	nmc->allowed_fields[6].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (speed_str);
+	g_free (mac_str);
+	g_free (mtu_str);
+
+	return TRUE;
+}
+
+gboolean
+setting_802_1X_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSetting8021x *s_8021X;
+	NMSetting8021xCKScheme scheme;
+	GString *eap_str;
+	char *ca_cert_str = NULL, *client_cert_str = NULL, *phase2_ca_cert_str = NULL;
+	char *phase2_client_cert_str = NULL, *private_key_str = NULL, *phase2_private_key_str = NULL;
+	int i;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
+	s_8021X = (NMSetting8021x *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_8021X;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_802_1X_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	eap_str = g_string_new (NULL);
+	for (i = 0; i < nm_setting_802_1x_get_num_eap_methods (s_8021X); i++) {
+		if (i > 0)
+			g_string_append_c (eap_str, ',');
+		g_string_append (eap_str, nm_setting_802_1x_get_eap_method (s_8021X, i));
+	}
+	scheme = nm_setting_802_1x_get_ca_cert_scheme (s_8021X);
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+		ca_cert_str = blob_cert_to_string (nm_setting_802_1x_get_ca_cert_blob (s_8021X));
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+		ca_cert_str = g_strdup (nm_setting_802_1x_get_ca_cert_path (s_8021X));
+
+	scheme = nm_setting_802_1x_get_client_cert_scheme (s_8021X);
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+		client_cert_str = blob_cert_to_string (nm_setting_802_1x_get_client_cert_blob (s_8021X));
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+		client_cert_str = g_strdup (nm_setting_802_1x_get_client_cert_path (s_8021X));
+
+	scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (s_8021X);
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+		phase2_ca_cert_str = blob_cert_to_string (nm_setting_802_1x_get_phase2_ca_cert_blob (s_8021X));
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+		phase2_ca_cert_str = g_strdup (nm_setting_802_1x_get_phase2_ca_cert_path (s_8021X));
+
+	scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (s_8021X);
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+		phase2_client_cert_str = blob_cert_to_string (nm_setting_802_1x_get_phase2_client_cert_blob (s_8021X));
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+		phase2_client_cert_str = g_strdup (nm_setting_802_1x_get_phase2_client_cert_path (s_8021X));
+
+	scheme = nm_setting_802_1x_get_private_key_scheme (s_8021X);
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+		private_key_str = blob_cert_to_string (nm_setting_802_1x_get_private_key_blob (s_8021X));
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+		private_key_str = g_strdup (nm_setting_802_1x_get_private_key_path (s_8021X));
+
+	scheme = nm_setting_802_1x_get_phase2_private_key_scheme (s_8021X);
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
+		phase2_private_key_str = blob_cert_to_string (nm_setting_802_1x_get_phase2_private_key_blob (s_8021X));
+	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
+		phase2_private_key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_path (s_8021X));
+
+	nmc->allowed_fields[0].value = NM_SETTING_802_1X_SETTING_NAME;
+	nmc->allowed_fields[1].value = eap_str->str;
+	nmc->allowed_fields[2].value = nm_setting_802_1x_get_identity (s_8021X);
+	nmc->allowed_fields[3].value = nm_setting_802_1x_get_anonymous_identity (s_8021X);
+	nmc->allowed_fields[4].value = ca_cert_str;
+	nmc->allowed_fields[5].value = nm_setting_802_1x_get_ca_path (s_8021X);
+	nmc->allowed_fields[6].value = client_cert_str;
+	nmc->allowed_fields[7].value = nm_setting_802_1x_get_phase1_peapver (s_8021X);
+	nmc->allowed_fields[8].value = nm_setting_802_1x_get_phase1_peaplabel (s_8021X);
+	nmc->allowed_fields[9].value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021X);
+	nmc->allowed_fields[10].value = nm_setting_802_1x_get_phase2_auth (s_8021X);
+	nmc->allowed_fields[11].value = nm_setting_802_1x_get_phase2_autheap (s_8021X);
+	nmc->allowed_fields[12].value = phase2_ca_cert_str;
+	nmc->allowed_fields[13].value = nm_setting_802_1x_get_phase2_ca_path (s_8021X);
+	nmc->allowed_fields[14].value = phase2_client_cert_str;
+	nmc->allowed_fields[15].value = nm_setting_802_1x_get_password (s_8021X);
+	nmc->allowed_fields[16].value = private_key_str;
+	nmc->allowed_fields[17].value = nm_setting_802_1x_get_private_key_password (s_8021X);
+	nmc->allowed_fields[18].value = phase2_private_key_str;
+	nmc->allowed_fields[19].value = nm_setting_802_1x_get_phase2_private_key_password (s_8021X);
+	nmc->allowed_fields[20].value = nm_setting_802_1x_get_pin (s_8021X);
+	nmc->allowed_fields[21].value = nm_setting_802_1x_get_psk (s_8021X);
+	nmc->allowed_fields[22].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no");
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (ca_cert_str);
+	g_free (client_cert_str);
+	g_free (phase2_ca_cert_str);
+	g_free (phase2_client_cert_str);
+	g_free (private_key_str);
+	g_free (phase2_private_key_str);
+	g_string_free (eap_str, TRUE);
+
+	return TRUE;
+}
+
+gboolean
+setting_wireless_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingWireless *s_wireless;
+	int i;
+	const GByteArray *ssid, *bssid, *mac;
+	char *ssid_str, *channel_str, *rate_str, *tx_power_str, *mtu_str;
+	char *mac_str = NULL, *bssid_str = NULL;
+	GString *seen_bssids;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE);
+	s_wireless = (NMSettingWireless *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_wireless;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRELESS_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	ssid = nm_setting_wireless_get_ssid (s_wireless);
+	ssid_str = ssid_to_printable ((const char *) ssid->data, ssid->len);
+	channel_str = g_strdup_printf ("%d", nm_setting_wireless_get_channel (s_wireless));
+	rate_str = g_strdup_printf ("%d", nm_setting_wireless_get_rate (s_wireless));
+	bssid = nm_setting_wireless_get_bssid (s_wireless);
+	if (bssid)
+		bssid_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", bssid->data[0], bssid->data[1], bssid->data[2], bssid->data[3], bssid->data[4], bssid->data[5]);
+	tx_power_str = g_strdup_printf ("%d", nm_setting_wireless_get_tx_power (s_wireless));
+	mtu_str = g_strdup_printf ("%d", nm_setting_wireless_get_mtu (s_wireless));
+	mac = nm_setting_wireless_get_mac_address (s_wireless);
+	if (mac)
+		mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
+	seen_bssids = g_string_new (NULL);
+	for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (s_wireless); i++) {
+		if (i > 0)
+			g_string_append_c (seen_bssids, ',');
+		g_string_append (seen_bssids, nm_setting_wireless_get_seen_bssid (s_wireless, i));
+	}
+
+	nmc->allowed_fields[0].value = NM_SETTING_WIRELESS_SETTING_NAME;
+	nmc->allowed_fields[1].value = ssid_str;
+	nmc->allowed_fields[2].value = nm_setting_wireless_get_mode (s_wireless);
+	nmc->allowed_fields[3].value = nm_setting_wireless_get_band (s_wireless);
+	nmc->allowed_fields[4].value = channel_str;
+	nmc->allowed_fields[5].value = bssid_str ? bssid_str : _("not set");
+	nmc->allowed_fields[6].value = rate_str;
+	nmc->allowed_fields[7].value = tx_power_str;
+	nmc->allowed_fields[8].value = mac_str ? mac_str : _("not set");
+	nmc->allowed_fields[9].value = strcmp (mtu_str, "0") ?  mtu_str : _("auto");
+	nmc->allowed_fields[10].value = seen_bssids->str;
+	nmc->allowed_fields[11].value = nm_setting_wireless_get_security (s_wireless);
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (ssid_str);
+	g_free (channel_str);
+	g_free (bssid_str);
+	g_free (rate_str);
+	g_free (tx_power_str);
+	g_free (mac_str);
+	g_free (mtu_str);
+	g_string_free (seen_bssids, TRUE);
+
+	return TRUE;
+}
+
+gboolean
+setting_wireless_security_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingWirelessSecurity *s_wireless_sec;
+	int i;
+	char *wep_tx_keyidx_str, *wep_key_type_str;
+	GString *protos, *pairwises, *groups;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
+	s_wireless_sec = (NMSettingWirelessSecurity *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_wireless_security;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRELESS_SECURITY_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	wep_tx_keyidx_str = g_strdup_printf ("%d", nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec));
+	protos = g_string_new (NULL);
+	for (i = 0; i < nm_setting_wireless_security_get_num_protos (s_wireless_sec); i++) {
+		if (i > 0)
+		g_string_append_c (protos, ',');
+		g_string_append (protos, nm_setting_wireless_security_get_proto (s_wireless_sec, i));
+	}
+	pairwises = g_string_new (NULL);
+	for (i = 0; i < nm_setting_wireless_security_get_num_pairwise (s_wireless_sec); i++) {
+		if (i > 0)
+		g_string_append_c (pairwises, ',');
+		g_string_append (pairwises, nm_setting_wireless_security_get_pairwise (s_wireless_sec, i));
+	}
+	groups = g_string_new (NULL);
+	for (i = 0; i < nm_setting_wireless_security_get_num_groups (s_wireless_sec); i++) {
+		if (i > 0)
+		g_string_append_c (groups, ',');
+		g_string_append (groups, nm_setting_wireless_security_get_group (s_wireless_sec, i));
+	}
+	wep_key_type_str = wep_key_type_to_string (nm_setting_wireless_security_get_wep_key_type (s_wireless_sec));
+
+	nmc->allowed_fields[0].value = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec);
+	nmc->allowed_fields[2].value = wep_tx_keyidx_str;
+	nmc->allowed_fields[3].value = nm_setting_wireless_security_get_auth_alg (s_wireless_sec);
+	nmc->allowed_fields[4].value = protos->str;
+	nmc->allowed_fields[5].value = pairwises->str;
+	nmc->allowed_fields[6].value = groups->str;
+	nmc->allowed_fields[7].value = nm_setting_wireless_security_get_leap_username (s_wireless_sec);
+	nmc->allowed_fields[8].value = nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0);
+	nmc->allowed_fields[9].value = nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1);
+	nmc->allowed_fields[10].value = nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2);
+	nmc->allowed_fields[11].value = nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3);
+	nmc->allowed_fields[12].value = nm_setting_wireless_security_get_psk (s_wireless_sec);
+	nmc->allowed_fields[13].value = nm_setting_wireless_security_get_leap_password (s_wireless_sec);
+	nmc->allowed_fields[14].value = wep_key_type_str;
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (wep_tx_keyidx_str);
+	g_free (wep_key_type_str);
+	g_string_free (protos, TRUE);
+	g_string_free (pairwises, TRUE);
+	g_string_free (groups, TRUE);
+
+	return TRUE;
+}
+
+gboolean
+setting_ip4_config_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingIP4Config *s_ip4;
+	GString *dns_str, *dns_search_str, *addr_str, *route_str;
+	int i, num;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE);
+	s_ip4 = (NMSettingIP4Config *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_ip4_config;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_IP4_CONFIG_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	dns_str = g_string_new (NULL);
+	num = nm_setting_ip4_config_get_num_dns (s_ip4);
+	for (i = 0; i < num; i++) {
+		char buf[INET_ADDRSTRLEN];
+		guint32 ip;
+
+		ip = nm_setting_ip4_config_get_dns (s_ip4, i);
+		memset (buf, 0, sizeof (buf));
+		inet_ntop (AF_INET, (const void *) &ip, buf, sizeof (buf));
+		if (i > 0)
+			g_string_append (dns_str, ", ");
+		g_string_append (dns_str, buf);
+	}
+
+	dns_search_str = g_string_new (NULL);
+	num = nm_setting_ip4_config_get_num_dns_searches (s_ip4);
+	for (i = 0; i < num; i++) {
+		const char *domain;
+
+		domain = nm_setting_ip4_config_get_dns_search (s_ip4, i);
+		if (i > 0)
+			g_string_append (dns_search_str, ", ");
+		g_string_append (dns_search_str, domain);
+	}
+
+	addr_str = g_string_new (NULL);
+	num = nm_setting_ip4_config_get_num_addresses (s_ip4);
+	for (i = 0; i < num; i++) {
+		char buf[INET_ADDRSTRLEN];
+		char *tmp;
+		NMIP4Address *addr;
+		guint32 ip;
+
+		if (i > 0)
+			g_string_append (addr_str, "; ");
+
+		g_string_append (addr_str, "{ ");
+
+		addr = nm_setting_ip4_config_get_address (s_ip4, i);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip4_address_get_address (addr);
+		inet_ntop (AF_INET, (const void *) &ip, buf, sizeof (buf));
+		g_string_append_printf (addr_str, "ip = %s", buf);
+
+		tmp = g_strdup_printf ("/%u", nm_ip4_address_get_prefix (addr));
+		g_string_append (addr_str, tmp);
+		g_free (tmp);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip4_address_get_gateway (addr);
+		inet_ntop (AF_INET, (const void *) &ip, buf, sizeof (buf));
+		g_string_append_printf (addr_str, ", gw = %s", buf);
+
+		g_string_append (addr_str, " }");
+	}
+
+	route_str = g_string_new (NULL);
+	num = nm_setting_ip4_config_get_num_routes (s_ip4);
+	for (i = 0; i < num; i++) {
+		char buf[INET_ADDRSTRLEN];
+		char *tmp;
+		NMIP4Route *route;
+		guint32 ip;
+
+		if (i > 0)
+			g_string_append (route_str, "; ");
+
+		g_string_append (route_str, "{ ");
+
+		route = nm_setting_ip4_config_get_route (s_ip4, i);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip4_route_get_dest (route);
+		inet_ntop (AF_INET, (const void *) &ip, buf, sizeof (buf));
+		g_string_append_printf (route_str, "dst = %s", buf);
+
+		tmp = g_strdup_printf ("/%u", nm_ip4_route_get_prefix (route));
+		g_string_append (route_str, tmp);
+		g_free (tmp);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip4_route_get_next_hop (route);
+		inet_ntop (AF_INET, (const void *) &ip, buf, sizeof (buf));
+		g_string_append_printf (route_str, ", nh = %s", buf);
+
+		tmp = g_strdup_printf (", mt = %u", nm_ip4_route_get_metric (route));
+		g_string_append (route_str, tmp);
+		g_free (tmp);
+
+		g_string_append (route_str, " }");
+	}
+
+	nmc->allowed_fields[0].value = NM_SETTING_IP4_CONFIG_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_ip4_config_get_method (s_ip4);
+	nmc->allowed_fields[2].value = dns_str->str;
+	nmc->allowed_fields[3].value = dns_search_str->str;
+	nmc->allowed_fields[4].value = addr_str->str;
+	nmc->allowed_fields[5].value = route_str->str;
+	nmc->allowed_fields[6].value = nm_setting_ip4_config_get_ignore_auto_routes (s_ip4) ? _("yes") : _("no");
+	nmc->allowed_fields[7].value = nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) ? _("yes") : _("no");
+	nmc->allowed_fields[8].value = nm_setting_ip4_config_get_dhcp_client_id (s_ip4);
+	nmc->allowed_fields[9].value = nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) ? _("yes") : _("no");
+	nmc->allowed_fields[10].value = nm_setting_ip4_config_get_dhcp_hostname (s_ip4);
+	nmc->allowed_fields[11].value = nm_setting_ip4_config_get_never_default (s_ip4) ? _("yes") : _("no");
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_string_free (dns_str, TRUE);
+	g_string_free (dns_search_str, TRUE);
+	g_string_free (addr_str, TRUE);
+	g_string_free (route_str, TRUE);
+
+	return TRUE;
+}
+
+gboolean
+setting_ip6_config_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingIP6Config *s_ip6;
+	GString *dns_str, *dns_search_str, *addr_str, *route_str;
+	int i, num;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), FALSE);
+	s_ip6 = (NMSettingIP6Config *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_ip6_config;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_IP6_CONFIG_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	dns_str = g_string_new (NULL);
+	num = nm_setting_ip6_config_get_num_dns (s_ip6);
+	for (i = 0; i < num; i++) {
+		char buf[INET6_ADDRSTRLEN];
+		const struct in6_addr *ip;
+
+		ip = nm_setting_ip6_config_get_dns (s_ip6, i);
+		memset (buf, 0, sizeof (buf));
+		inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+		if (i > 0)
+			g_string_append (dns_str, ", ");
+		g_string_append (dns_str, buf);
+	}
+
+	dns_search_str = g_string_new (NULL);
+	num = nm_setting_ip6_config_get_num_dns_searches (s_ip6);
+	for (i = 0; i < num; i++) {
+		const char *domain;
+
+		domain = nm_setting_ip6_config_get_dns_search (s_ip6, i);
+		if (i > 0)
+			g_string_append (dns_search_str, ", ");
+		g_string_append (dns_search_str, domain);
+	}
+
+	addr_str = g_string_new (NULL);
+	num = nm_setting_ip6_config_get_num_addresses (s_ip6);
+	for (i = 0; i < num; i++) {
+		char buf[INET6_ADDRSTRLEN];
+		char *tmp;
+		NMIP6Address *addr;
+		const struct in6_addr *ip;
+
+		if (i > 0)
+			g_string_append (addr_str, "; ");
+
+		g_string_append (addr_str, "{ ");
+
+		addr = nm_setting_ip6_config_get_address (s_ip6, i);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip6_address_get_address (addr);
+		inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+		g_string_append_printf (addr_str, "ip = %s", buf);
+
+		tmp = g_strdup_printf ("/%u", nm_ip6_address_get_prefix (addr));
+		g_string_append (addr_str, tmp);
+		g_free (tmp);
+
+		g_string_append (addr_str, " }");
+	}
+
+	route_str = g_string_new (NULL);
+	num = nm_setting_ip6_config_get_num_routes (s_ip6);
+	for (i = 0; i < num; i++) {
+		char buf[INET6_ADDRSTRLEN];
+		char *tmp;
+		NMIP6Route *route;
+		const struct in6_addr *ip;
+
+		if (i > 0)
+			g_string_append (route_str, "; ");
+
+		g_string_append (route_str, "{ ");
+
+		route = nm_setting_ip6_config_get_route (s_ip6, i);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip6_route_get_dest (route);
+		inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+		g_string_append_printf (route_str, "dst = %s", buf);
+
+		tmp = g_strdup_printf ("/%u", nm_ip6_route_get_prefix (route));
+		g_string_append (route_str, tmp);
+		g_free (tmp);
+
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip6_route_get_next_hop (route);
+		inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+		g_string_append_printf (route_str, ", nh = %s", buf);
+
+		tmp = g_strdup_printf (", mt = %u", nm_ip6_route_get_metric (route));
+		g_string_append (route_str, tmp);
+		g_free (tmp);
+
+		g_string_append (route_str, " }");
+	}
+
+	nmc->allowed_fields[0].value = NM_SETTING_IP6_CONFIG_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_ip6_config_get_method (s_ip6);
+	nmc->allowed_fields[2].value = dns_str->str;
+	nmc->allowed_fields[3].value = dns_search_str->str;
+	nmc->allowed_fields[4].value = addr_str->str;
+	nmc->allowed_fields[5].value = route_str->str;
+	nmc->allowed_fields[6].value = nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? _("yes") : _("no");
+	nmc->allowed_fields[7].value = nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? _("yes") : _("no");
+	nmc->allowed_fields[8].value = nm_setting_ip6_config_get_never_default (s_ip6) ? _("yes") : _("no");
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_string_free (dns_str, TRUE);
+	g_string_free (dns_search_str, TRUE);
+	g_string_free (addr_str, TRUE);
+	g_string_free (route_str, TRUE);
+
+	return TRUE;
+}
+
+gboolean
+setting_serial_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingSerial *s_serial;
+	char *baud_str, *bits_str, *parity_str, *stopbits_str, *send_delay_str;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), FALSE);
+	s_serial = (NMSettingSerial *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_serial;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_SERIAL_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	baud_str = g_strdup_printf ("%d", nm_setting_serial_get_baud (s_serial));
+	bits_str = g_strdup_printf ("%d", nm_setting_serial_get_bits (s_serial));
+	parity_str = g_strdup_printf ("%c", nm_setting_serial_get_parity (s_serial));
+	stopbits_str = g_strdup_printf ("%d", nm_setting_serial_get_stopbits (s_serial));
+	send_delay_str = g_strdup_printf ("%" G_GUINT64_FORMAT, nm_setting_serial_get_send_delay (s_serial));
+
+	nmc->allowed_fields[0].value = NM_SETTING_SERIAL_SETTING_NAME;
+	nmc->allowed_fields[1].value = baud_str;
+	nmc->allowed_fields[2].value = bits_str;
+	nmc->allowed_fields[3].value = parity_str;
+	nmc->allowed_fields[4].value = stopbits_str;
+	nmc->allowed_fields[5].value = send_delay_str;
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (baud_str);
+	g_free (bits_str);
+	g_free (parity_str);
+	g_free (stopbits_str);
+	g_free (send_delay_str);
+
+	return TRUE;
+}
+
+gboolean
+setting_ppp_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingPPP *s_ppp;
+	char *baud_str, *mru_str, *mtu_str, *lcp_echo_failure_str, *lcp_echo_interval_str;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE);
+	s_ppp = (NMSettingPPP *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_ppp;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_PPP_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	baud_str = g_strdup_printf ("%d", nm_setting_ppp_get_baud (s_ppp));
+	mru_str = g_strdup_printf ("%d", nm_setting_ppp_get_mru (s_ppp));
+	mtu_str = g_strdup_printf ("%d", nm_setting_ppp_get_mtu (s_ppp));
+	lcp_echo_failure_str = g_strdup_printf ("%d", nm_setting_ppp_get_lcp_echo_failure (s_ppp));
+	lcp_echo_interval_str = g_strdup_printf ("%d", nm_setting_ppp_get_lcp_echo_interval (s_ppp));
+
+	nmc->allowed_fields[0].value = NM_SETTING_PPP_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_ppp_get_noauth (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[2].value = nm_setting_ppp_get_refuse_eap (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[3].value = nm_setting_ppp_get_refuse_pap (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[4].value = nm_setting_ppp_get_refuse_chap (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[5].value = nm_setting_ppp_get_refuse_mschap (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[6].value = nm_setting_ppp_get_refuse_mschapv2 (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[7].value = nm_setting_ppp_get_nobsdcomp (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[8].value = nm_setting_ppp_get_nodeflate (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[9].value = nm_setting_ppp_get_no_vj_comp (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[10].value = nm_setting_ppp_get_require_mppe (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[11].value = nm_setting_ppp_get_require_mppe_128 (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[12].value = nm_setting_ppp_get_mppe_stateful (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[13].value = nm_setting_ppp_get_crtscts (s_ppp) ? _("yes") : _("no");
+	nmc->allowed_fields[14].value = baud_str;
+	nmc->allowed_fields[15].value = mru_str;
+	nmc->allowed_fields[16].value = mtu_str;
+	nmc->allowed_fields[17].value = lcp_echo_failure_str;
+	nmc->allowed_fields[18].value = lcp_echo_interval_str;
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (baud_str);
+	g_free (mru_str);
+	g_free (mtu_str);
+	g_free (lcp_echo_failure_str);
+	g_free (lcp_echo_interval_str);
+
+	return TRUE;
+}
+
+gboolean
+setting_pppoe_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingPPPOE *s_pppoe;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), FALSE);
+	s_pppoe = (NMSettingPPPOE *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_pppoe;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_PPPOE_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	nmc->allowed_fields[0].value = NM_SETTING_PPPOE_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_pppoe_get_service (s_pppoe);
+	nmc->allowed_fields[2].value = nm_setting_pppoe_get_username (s_pppoe);
+	nmc->allowed_fields[3].value = nm_setting_pppoe_get_password (s_pppoe);
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	return TRUE;
+}
+
+gboolean
+setting_gsm_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingGsm *s_gsm;
+	char *network_type_str, *allowed_bands_str;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_GSM (setting), FALSE);
+	s_gsm = (NMSettingGsm *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_gsm;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_GSM_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	network_type_str = g_strdup_printf ("%d", nm_setting_gsm_get_network_type (s_gsm));
+	allowed_bands_str = allowed_bands_to_string (nm_setting_gsm_get_allowed_bands (s_gsm));
+
+	nmc->allowed_fields[0].value = NM_SETTING_GSM_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_gsm_get_number (s_gsm);
+	nmc->allowed_fields[2].value = nm_setting_gsm_get_username (s_gsm);
+	nmc->allowed_fields[3].value = nm_setting_gsm_get_password (s_gsm);
+	nmc->allowed_fields[4].value = nm_setting_gsm_get_apn (s_gsm);
+	nmc->allowed_fields[5].value = nm_setting_gsm_get_network_id (s_gsm);
+	nmc->allowed_fields[6].value = network_type_str;
+	nmc->allowed_fields[7].value = allowed_bands_str;
+	nmc->allowed_fields[8].value = nm_setting_gsm_get_pin (s_gsm);
+	nmc->allowed_fields[9].value = nm_setting_gsm_get_home_only (s_gsm) ? _("yes") : _("no");
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (network_type_str);
+	g_free (allowed_bands_str);
+
+	return TRUE;
+}
+
+gboolean
+setting_cdma_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingCdma *s_cdma;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), FALSE);
+	s_cdma = (NMSettingCdma *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_cdma;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_CDMA_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	nmc->allowed_fields[0].value = NM_SETTING_CDMA_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_cdma_get_number (s_cdma);
+	nmc->allowed_fields[2].value = nm_setting_cdma_get_username (s_cdma);
+	nmc->allowed_fields[3].value = nm_setting_cdma_get_password (s_cdma);
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	return TRUE;
+}
+
+gboolean
+setting_bluetooth_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingBluetooth *s_bluetooth;
+	const GByteArray *bdaddr;
+	char *bdaddr_str = NULL;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_BLUETOOTH (setting), FALSE);
+	s_bluetooth = (NMSettingBluetooth *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_bluetooth;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BLUETOOTH_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	bdaddr = nm_setting_bluetooth_get_bdaddr (s_bluetooth);
+	if (bdaddr)
+		bdaddr_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", bdaddr->data[0], bdaddr->data[1], bdaddr->data[2],
+		                                                               bdaddr->data[3], bdaddr->data[4], bdaddr->data[5]);
+	nmc->allowed_fields[0].value = NM_SETTING_BLUETOOTH_SETTING_NAME;
+	nmc->allowed_fields[1].value = bdaddr_str;
+	nmc->allowed_fields[2].value = nm_setting_bluetooth_get_connection_type (s_bluetooth);
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (bdaddr_str);
+
+	return TRUE;
+}
+
+gboolean
+setting_olpc_mesh_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingOlpcMesh *s_olpc_mesh;
+	const GByteArray *ssid, *dhcp_anycast;
+	char *ssid_str, *channel_str, *dhcp_anycast_str = NULL;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_OLPC_MESH (setting), FALSE);
+	s_olpc_mesh = (NMSettingOlpcMesh *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_olpc_mesh;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_OLPC_MESH_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	ssid = nm_setting_olpc_mesh_get_ssid (s_olpc_mesh);
+	ssid_str = ssid_to_printable ((const char *) ssid->data, ssid->len);
+	channel_str = g_strdup_printf ("%d", nm_setting_olpc_mesh_get_channel (s_olpc_mesh));
+	dhcp_anycast = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_olpc_mesh);
+	if (dhcp_anycast)
+		dhcp_anycast_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", dhcp_anycast->data[0], dhcp_anycast->data[1], dhcp_anycast->data[2],
+		                                                                     dhcp_anycast->data[3], dhcp_anycast->data[4], dhcp_anycast->data[5]);
+	nmc->allowed_fields[0].value = NM_SETTING_OLPC_MESH_SETTING_NAME;
+	nmc->allowed_fields[1].value = ssid_str;
+	nmc->allowed_fields[2].value = channel_str;
+	nmc->allowed_fields[3].value = dhcp_anycast_str;
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_free (ssid_str);
+	g_free (channel_str);
+	g_free (dhcp_anycast_str);
+
+	return TRUE;
+}
+
+static void
+vpn_data_item (const char *key, const char *value, gpointer user_data)
+{
+	GString *ret_str = (GString *) user_data;
+
+	if (ret_str->len != 0)
+		g_string_append (ret_str, ", ");
+
+	g_string_append_printf (ret_str, "%s = %s", key, value);
+}
+
+gboolean
+setting_vpn_details (NMSetting *setting, NmCli *nmc)
+{
+	NMSettingVPN *s_vpn;
+	GString *data_item_str, *secret_str;
+	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
+	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
+	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+
+	g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
+	s_vpn = (NMSettingVPN *) setting;
+
+	nmc->allowed_fields = nmc_fields_setting_vpn;
+	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_VPN_ALL, nmc->allowed_fields, NULL);
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
+	print_fields (nmc->print_fields, nmc->allowed_fields);  /* Print field names */
+
+	data_item_str = g_string_new (NULL);
+	secret_str = g_string_new (NULL);
+	nm_setting_vpn_foreach_data_item (s_vpn, &vpn_data_item, data_item_str);
+	nm_setting_vpn_foreach_secret (s_vpn, &vpn_data_item, secret_str);
+
+	nmc->allowed_fields[0].value = NM_SETTING_VPN_SETTING_NAME;
+	nmc->allowed_fields[1].value = nm_setting_vpn_get_service_type (s_vpn);
+	nmc->allowed_fields[2].value = nm_setting_vpn_get_user_name (s_vpn);
+	nmc->allowed_fields[3].value = data_item_str->str;
+	nmc->allowed_fields[4].value = secret_str->str;
+
+	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
+	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+
+	g_string_free (data_item_str, TRUE);
+	g_string_free (secret_str, TRUE);
+
+	return TRUE;
+}
+
diff --git a/cli/src/settings.h b/cli/src/settings.h
new file mode 100644
index 00000000..aec71551
--- /dev/null
+++ b/cli/src/settings.h
@@ -0,0 +1,59 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef NMC_SETTINGS_H
+#define NMC_SETTINGS_H
+
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-serial.h>
+#include <nm-setting-ppp.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-olpc-mesh.h>
+#include <nm-setting-vpn.h>
+
+#include "nmcli.h"
+#include "utils.h"
+
+
+gboolean setting_connection_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_wired_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_802_1X_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_wireless_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_wireless_security_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_ip4_config_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_ip6_config_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_serial_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_ppp_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_pppoe_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_gsm_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_cdma_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_bluetooth_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_olpc_mesh_details (NMSetting *setting, NmCli *nmc);
+gboolean setting_vpn_details (NMSetting *setting, NmCli *nmc);
+
+#endif /* NMC_SETTINGS_H */
diff --git a/cli/src/utils.c b/cli/src/utils.c
new file mode 100644
index 00000000..0096a0ae
--- /dev/null
+++ b/cli/src/utils.c
@@ -0,0 +1,298 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "utils.h"
+
+int
+matches (const char *cmd, const char *pattern)
+{
+	int len = strlen (cmd);
+	if (len > strlen (pattern))
+		return -1;
+	return memcmp (pattern, cmd, len);
+}
+
+int
+next_arg (int *argc, char ***argv)
+{
+	if (*argc <= 1) {
+		return -1;
+	}
+	else {
+		(*argc)--;
+		(*argv)++;
+	}
+	return 0;
+}
+
+/*
+ *  Convert SSID to a printable form.
+ *  If it is an UTF-8 string, enclose it in quotes and return it.
+ *  Otherwise convert it to a hex string representation.
+ *  Caller has to free the returned string using g_free()
+ */
+char *
+ssid_to_printable (const char *str, gsize len)
+{
+	GString *printable;
+	char *printable_str;
+	int i;
+
+	if (str == NULL || len == 0)
+		 return NULL;
+
+	if (g_utf8_validate (str, len, NULL))
+		return g_strdup_printf ("'%.*s'", (int) len, str);
+
+	printable = g_string_new (NULL);
+	for (i = 0; i < len; i++) {
+		g_string_append_printf (printable, "%02X", (unsigned char) str[i]);
+	}
+	printable_str = g_string_free (printable, FALSE);
+	return printable_str;
+}
+
+/*
+ * Find out how many columns an UTF-8 string occupies on the screen
+ */
+int
+nmc_string_screen_width (const char *start, const char *end)
+{
+	int width = 0;
+
+	if (end == NULL)
+		end = start + strlen (start);
+
+	while (start < end) {
+		width += g_unichar_iswide (g_utf8_get_char (start)) ? 2 : g_unichar_iszerowidth (g_utf8_get_char (start)) ? 0 : 1;
+		start = g_utf8_next_char (start);
+	}
+	return width;
+}
+
+/*
+ * Parse comma separated fields in 'fields_str' according to 'fields_array'.
+ * IN:  'field_str':    comma-separated fields names
+ *      'fields_array': array of allowed fields
+ * RETURN: GArray with indices representing fields in 'fields_array'.
+ *         Caller is responsible to free it.
+ */
+GArray *
+parse_output_fields (const char *fields_str, const NmcOutputField fields_array[], GError **error)
+{
+	char **fields, **iter;
+	GArray *array;
+	int i;
+
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	array = g_array_new (FALSE, FALSE, sizeof (int));
+
+	/* Split supplied fields string */
+	fields = g_strsplit_set (fields_str, ",", -1);
+	for (iter = fields; iter && *iter; iter++) {
+		for (i = 0; fields_array[i].name; i++) {
+			if (strcasecmp (*iter, fields_array[i].name) == 0) {
+				g_array_append_val (array, i);
+				break;
+			}
+		}
+		if (fields_array[i].name == NULL) {
+			if (!strcasecmp (*iter, "all") || !strcasecmp (*iter, "common"))
+				g_set_error (error, 0, 0, _("field '%s' has to be alone"), *iter);
+
+			else
+				g_set_error (error, 0, 1, _("invalid field '%s'"), *iter);
+			g_array_free (array, TRUE);
+			array = NULL;
+			goto done;
+		}
+	}
+done:
+	if (fields)
+		g_strfreev (fields);
+	return array;
+}
+
+gboolean
+nmc_terse_option_check (NMCPrintOutput print_output, const char *fields, GError **error)
+{
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	if (print_output == NMC_PRINT_TERSE) {
+		if (!fields) {
+			g_set_error (error, 0, 0, _("Option '--terse' requires specifying '--fields'"));
+			return FALSE;
+		} else if (   !strcasecmp (fields, "all")
+		           || !strcasecmp (fields, "common")) {
+			g_set_error (error, 0, 0, _("Option '--terse' requires specific '--fields' option values , not '%s'"), fields);
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+/*
+ * Print both headers or values of 'field_values' array.
+ * Entries to print and their order are specified via indices
+ * in 'fields.indices' array.
+ * 'fields.flags' specify various aspects influencing the output.
+ */
+void
+print_fields (const NmcPrintFields fields, const NmcOutputField field_values[])
+{
+	GString *str;
+	int width1, width2;
+	int table_width = 0;
+	char *line = NULL;
+	char *indent_str;
+	const char *value;
+	const char *not_set_str = _("not set");
+	int i, idx;
+	gboolean multiline = fields.flags & NMC_PF_FLAG_MULTILINE;
+	gboolean terse = fields.flags & NMC_PF_FLAG_TERSE;
+	gboolean pretty = fields.flags & NMC_PF_FLAG_PRETTY;
+	gboolean main_header_add = fields.flags & NMC_PF_FLAG_MAIN_HEADER_ADD;
+	gboolean main_header_only = fields.flags & NMC_PF_FLAG_MAIN_HEADER_ONLY;
+	gboolean field_names = fields.flags & NMC_PF_FLAG_FIELD_NAMES;
+	gboolean escape = fields.flags & NMC_PF_FLAG_ESCAPE;
+	gboolean section_prefix = fields.flags & NMC_PF_FLAG_SECTION_PREFIX;
+	gboolean main_header = main_header_add || main_header_only;
+
+	/* No headers are printed in terse mode:
+	 * - neither main header nor field (column) names
+	 */
+	if ((main_header_only || field_names) && terse)
+		return;
+
+	if (multiline) {
+	/* --- Multiline mode --- */
+		enum { ML_HEADER_WIDTH = 79 };
+		if (main_header && pretty) {
+			/* Print the main header */
+			int header_width = nmc_string_screen_width (fields.header_name, NULL) + 4;
+			table_width = header_width < ML_HEADER_WIDTH ? ML_HEADER_WIDTH : header_width;
+
+			line = g_strnfill (ML_HEADER_WIDTH, '=');
+			width1 = strlen (fields.header_name);
+			width2 = nmc_string_screen_width (fields.header_name, NULL);
+			printf ("%s\n", line);
+			printf ("%*s\n", (table_width + width2)/2 + width1 - width2, fields.header_name);
+			printf ("%s\n", line);
+			g_free (line);
+		}
+
+		/* Print values */
+		if (!main_header_only && !field_names) {
+			for (i = 0; i < fields.indices->len; i++) {
+				char *tmp;
+				idx = g_array_index (fields.indices, int, i);
+				if (section_prefix && idx == 0)  /* The first field is section prefix */
+					continue;
+				tmp = g_strdup_printf ("%s%s%s:", section_prefix ? field_values[0].value : "",
+				                                  section_prefix ? "." : "",
+				                                  _(field_values[idx].name_l10n));
+				printf ("%-*s%s\n", terse ? 0 : 32, tmp, field_values[idx].value ? field_values[idx].value : not_set_str);
+				g_free (tmp);
+			}
+			if (pretty) {
+				line = g_strnfill (ML_HEADER_WIDTH, '-');
+				printf ("%s\n", line);
+				g_free (line);
+			}
+		}
+		return;
+	}
+
+	/* --- Tabular mode: each line = one object --- */
+	str = g_string_new (NULL);
+
+	for (i = 0; i < fields.indices->len; i++) {
+		idx = g_array_index (fields.indices, int, i);
+		if (field_names)
+			value = _(field_values[idx].name_l10n);
+		else
+			value = field_values[idx].value ? field_values[idx].value : not_set_str;
+		if (terse) {
+			if (escape) {
+				const char *p = value;
+				while (*p) {
+					if (*p == ':' || *p == '\\')
+						g_string_append_c (str, '\\');  /* Escaping by '\' */
+					g_string_append_c (str, *p);
+					p++;
+				}
+			}
+			else 
+				g_string_append_printf (str, "%s", value);
+			g_string_append_c (str, ':');  /* Column separator */
+		} else {
+			width1 = strlen (value);
+			width2 = nmc_string_screen_width (value, NULL);  /* Width of the string (in screen colums) */
+			if (strlen (value) == 0)
+				value = "--";
+			g_string_append_printf (str, "%-*s", field_values[idx].width + width1 - width2, value);
+			g_string_append_c (str, ' ');  /* Column separator */
+			table_width += field_values[idx].width + width1 - width2 + 1;
+		}
+	}
+
+	/* Print the main table header */
+	if (main_header && pretty) {
+		int header_width = nmc_string_screen_width (fields.header_name, NULL) + 4;
+		table_width = table_width < header_width ? header_width : table_width;
+
+		line = g_strnfill (table_width, '=');
+		width1 = strlen (fields.header_name);
+		width2 = nmc_string_screen_width (fields.header_name, NULL);
+		printf ("%s\n", line);
+		printf ("%*s\n", (table_width + width2)/2 + width1 - width2, fields.header_name);
+		printf ("%s\n", line);
+		g_free (line);
+	}
+
+	/* Print actual values */
+	if (!main_header_only && str->len > 0) {
+		g_string_truncate (str, str->len-1);  /* Chop off last column separator */
+		if (fields.indent > 0) {
+			indent_str = g_strnfill (fields.indent, ' ');
+			g_string_prepend (str, indent_str);
+			g_free (indent_str);
+		}
+		printf ("%s\n", str->str);
+	}
+
+	/* Print horizontal separator */
+	if (!main_header_only && field_names && pretty) {
+		if (str->len > 0) {
+			line = g_strnfill (table_width, '-');
+			printf ("%s\n", line);
+			g_free (line);
+		}
+	}
+
+	g_string_free (str, TRUE);
+}
+
diff --git a/cli/src/utils.h b/cli/src/utils.h
new file mode 100644
index 00000000..308f6401
--- /dev/null
+++ b/cli/src/utils.h
@@ -0,0 +1,36 @@
+/* nmcli - command-line tool to control NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef NMC_UTILS_H
+#define NMC_UTILS_H
+
+#include <glib.h>
+
+#include "nmcli.h"
+
+/* === Functions === */
+int matches (const char *cmd, const char *pattern);
+int next_arg (int *argc, char ***argv);
+char *ssid_to_printable (const char *str, gsize len);
+int nmc_string_screen_width (const char *start, const char *end);
+GArray *parse_output_fields (const char *fields_str, const NmcOutputField fields_array[], GError **error);
+gboolean nmc_terse_option_check (NMCPrintOutput print_output, const char *fields, GError **error);
+void print_fields (const NmcPrintFields fields, const NmcOutputField field_values[]);
+
+#endif /* NMC_UTILS_H */