diff options
| author | Michael Biebl <biebl@debian.org> | 2010-11-29 00:47:11 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2010-11-29 00:47:11 +0100 |
| commit | 9fae01fa351805b2903e535736e06971bc0b925e (patch) | |
| tree | c19bccf84c9f894e50fae678ba6ee2b2044e2d30 /cli | |
Imported Upstream version 0.8.1 upstream/0.8.1
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/Makefile.am | 2 | ||||
| -rw-r--r-- | cli/Makefile.in | 620 | ||||
| -rw-r--r-- | cli/src/Makefile.am | 38 | ||||
| -rw-r--r-- | cli/src/Makefile.in | 703 | ||||
| -rw-r--r-- | cli/src/connections.c | 1642 | ||||
| -rw-r--r-- | cli/src/connections.h | 27 | ||||
| -rw-r--r-- | cli/src/devices.c | 1294 | ||||
| -rw-r--r-- | cli/src/devices.h | 27 | ||||
| -rw-r--r-- | cli/src/network-manager.c | 278 | ||||
| -rw-r--r-- | cli/src/network-manager.h | 27 | ||||
| -rw-r--r-- | cli/src/nmcli.c | 363 | ||||
| -rw-r--r-- | cli/src/nmcli.h | 114 | ||||
| -rw-r--r-- | cli/src/settings.c | 1369 | ||||
| -rw-r--r-- | cli/src/settings.h | 59 | ||||
| -rw-r--r-- | cli/src/utils.c | 298 | ||||
| -rw-r--r-- | cli/src/utils.h | 36 |
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 *) ×tamp)); + 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 */ |