From 2c032d8f1c6292c1338a615e6ec40252889ba85c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 22 Jan 2015 00:29:39 +0100 Subject: Imported Upstream version 1.0.0 --- cli/src/Makefile.am | 40 - cli/src/Makefile.in | 809 ----- cli/src/common.c | 1168 ------ cli/src/common.h | 66 - cli/src/connections.c | 8706 --------------------------------------------- cli/src/connections.h | 27 - cli/src/devices.c | 2718 -------------- cli/src/devices.h | 27 - cli/src/network-manager.c | 917 ----- cli/src/network-manager.h | 29 - cli/src/nmcli.c | 449 --- cli/src/nmcli.h | 140 - cli/src/settings.c | 7333 -------------------------------------- cli/src/settings.h | 89 - cli/src/utils.c | 1128 ------ cli/src/utils.h | 97 - 16 files changed, 23743 deletions(-) delete mode 100644 cli/src/Makefile.am delete mode 100644 cli/src/Makefile.in delete mode 100644 cli/src/common.c delete mode 100644 cli/src/common.h delete mode 100644 cli/src/connections.c delete mode 100644 cli/src/connections.h delete mode 100644 cli/src/devices.c delete mode 100644 cli/src/devices.h delete mode 100644 cli/src/network-manager.c delete mode 100644 cli/src/network-manager.h delete mode 100644 cli/src/nmcli.c delete mode 100644 cli/src/nmcli.h delete mode 100644 cli/src/settings.c delete mode 100644 cli/src/settings.h delete mode 100644 cli/src/utils.c delete mode 100644 cli/src/utils.h (limited to 'cli/src') diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am deleted file mode 100644 index e61c0368..00000000 --- a/cli/src/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -bin_PROGRAMS = \ - nmcli - -AM_CPPFLAGS = \ - -I${top_srcdir} \ - -I${top_srcdir}/include \ - -I${top_builddir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-glib \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - -DNMCLI_LOCALEDIR=\"$(datadir)/locale\" - -nmcli_SOURCES = \ - common.c \ - common.h \ - 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_LDADD = \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) \ - $(READLINE_LIBS) \ - $(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 deleted file mode 100644 index 8f3129c7..00000000 --- a/cli/src/Makefile.in +++ /dev/null @@ -1,809 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 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@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -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.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.m4 \ - $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ - $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.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)/m4/nls.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/vapigen.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 = common.$(OBJEXT) connections.$(OBJEXT) \ - devices.$(OBJEXT) network-manager.$(OBJEXT) settings.$(OBJEXT) \ - nmcli.$(OBJEXT) utils.$(OBJEXT) -nmcli_OBJECTS = $(am_nmcli_OBJECTS) -am__DEPENDENCIES_1 = -nmcli_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(nmcli_SOURCES) -DIST_SOURCES = $(nmcli_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALL_LINGUAS = @ALL_LINGUAS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -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@ -INTLLIBS = @INTLLIBS@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -INTLTOOL_MERGE = @INTLTOOL_MERGE@ -INTLTOOL_PERL = @INTLTOOL_PERL@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ -INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ -INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ -INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ -INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ -INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ -INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ -INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ -IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ -KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -NM_VERSION = @NM_VERSION@ -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@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POLKIT_CFLAGS = @POLKIT_CFLAGS@ -POLKIT_LIBS = @POLKIT_LIBS@ -POSUB = @POSUB@ -PPPD_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -VERSION = @VERSION@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -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@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -AM_CPPFLAGS = \ - -I${top_srcdir} \ - -I${top_srcdir}/include \ - -I${top_builddir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-glib \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - -DNMCLI_LOCALEDIR=\"$(datadir)/locale\" - -nmcli_SOURCES = \ - common.c \ - common.h \ - 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_LDADD = \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) \ - $(READLINE_LIBS) \ - $(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) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - 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) $(EXTRA_nmcli_DEPENDENCIES) - @rm -f nmcli$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(nmcli_OBJECTS) $(nmcli_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connections.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devices.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network-manager.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - 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-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - 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" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -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: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -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 TAGS all all-am check check-am clean \ - clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ - ctags ctags-am 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 tags-am 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/common.c b/cli/src/common.c deleted file mode 100644 index e6712a8d..00000000 --- a/cli/src/common.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * nmcli - command-line tool for controlling NetworkManager - * Common functions and data shared between files. - * - * 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 2012 - 2014 Red Hat, Inc. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "common.h" -#include "utils.h" - -/* Available fields for IPv4 group */ -NmcOutputField nmc_fields_ip4_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"ADDRESS", N_("ADDRESS"), 68}, /* 1 */ - {"ROUTE", N_("ROUTE"), 68}, /* 2 */ - {"DNS", N_("DNS"), 35}, /* 3 */ - {"DOMAIN", N_("DOMAIN"), 35}, /* 4 */ - {"WINS", N_("WINS"), 20}, /* 5 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_IP4_CONFIG_ALL "GROUP,ADDRESS,ROUTE,DNS,DOMAIN,WINS" - -/* Available fields for DHCPv4 group */ -NmcOutputField nmc_fields_dhcp4_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"OPTION", N_("OPTION"), 80}, /* 1 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_DHCP4_CONFIG_ALL "GROUP,OPTION" - -/* Available fields for IPv6 group */ -NmcOutputField nmc_fields_ip6_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"ADDRESS", N_("ADDRESS"), 95}, /* 1 */ - {"ROUTE", N_("ROUTE"), 95}, /* 2 */ - {"DNS", N_("DNS"), 60}, /* 3 */ - {"DOMAIN", N_("DOMAIN"), 35}, /* 4 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_IP6_CONFIG_ALL "GROUP,ADDRESS,ROUTE,DNS,DOMAIN" - -/* Available fields for DHCPv6 group */ -NmcOutputField nmc_fields_dhcp6_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"OPTION", N_("OPTION"), 80}, /* 1 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_DHCP6_CONFIG_ALL "GROUP,OPTION" - - -gboolean -print_ip4_config (NMIP4Config *cfg4, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GSList *list, *iter; - const GArray *array; - const GPtrArray *ptr_array; - char **addr_arr = NULL; - char **route_arr = NULL; - char **dns_arr = NULL; - char **domain_arr = NULL; - char **wins_arr = NULL; - int i = 0; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (cfg4 == NULL) - return FALSE; - - tmpl = nmc_fields_ip4_config; - tmpl_len = sizeof (nmc_fields_ip4_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP4_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* addresses */ - list = (GSList *) nm_ip4_config_get_addresses (cfg4); - addr_arr = g_new (char *, g_slist_length (list) + 1); - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP4Address *addr = (NMIP4Address *) iter->data; - guint32 prefix; - char *ip_str, *gw_str; - - ip_str = nmc_ip4_address_as_string (nm_ip4_address_get_address (addr), NULL); - prefix = nm_ip4_address_get_prefix (addr); - gw_str = nmc_ip4_address_as_string (nm_ip4_address_get_gateway (addr), NULL); - - addr_arr[i++] = g_strdup_printf ("ip = %s/%u, gw = %s", ip_str, prefix, gw_str); - g_free (ip_str); - g_free (gw_str); - } - addr_arr[i] = NULL; - - /* routes */ - list = (GSList *) nm_ip4_config_get_routes (cfg4); - route_arr = g_new (char *, g_slist_length (list) + 1); - i = 0; - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP4Route *route = (NMIP4Route *) iter->data; - guint32 prefix, metric; - char *dest_str, *nexthop_str; - - dest_str = nmc_ip4_address_as_string (nm_ip4_route_get_dest (route), NULL); - nexthop_str = nmc_ip4_address_as_string (nm_ip4_route_get_next_hop (route), NULL); - prefix = nm_ip4_route_get_prefix (route); - metric = nm_ip4_route_get_metric (route); - - route_arr[i++] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u", dest_str, prefix, nexthop_str, metric); - g_free (dest_str); - g_free (nexthop_str); - } - route_arr[i] = NULL; - - /* DNS */ - array = nm_ip4_config_get_nameservers (cfg4); - if (array) { - dns_arr = g_new (char *, array->len + 1); - for (i = 0; i < array->len; i++) - dns_arr[i] = nmc_ip4_address_as_string (g_array_index (array, guint32, i), NULL); - - dns_arr[i] = NULL; - } - - /* domains */ - ptr_array = nm_ip4_config_get_domains (cfg4); - if (ptr_array) { - domain_arr = g_new (char *, ptr_array->len + 1); - for (i = 0; i < ptr_array->len; i++) - domain_arr[i] = g_strdup (g_ptr_array_index (ptr_array, i)); - - domain_arr[i] = NULL; - } - - /* WINS */ - array = nm_ip4_config_get_wins_servers (cfg4); - if (array) { - wins_arr = g_new (char *, array->len + 1); - for (i = 0; i < array->len; i++) - wins_arr[i] = nmc_ip4_address_as_string (g_array_index (array, guint32, i), NULL); - - wins_arr[i] = NULL; - } - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, addr_arr); - set_val_arr (arr, 2, route_arr); - set_val_arr (arr, 3, dns_arr); - set_val_arr (arr, 4, domain_arr); - set_val_arr (arr, 5, wins_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; -} - -gboolean -print_ip6_config (NMIP6Config *cfg6, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GSList *list, *iter; - const GPtrArray *ptr_array; - char **addr_arr = NULL; - char **route_arr = NULL; - char **dns_arr = NULL; - char **domain_arr = NULL; - int i = 0; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (cfg6 == NULL) - return FALSE; - - tmpl = nmc_fields_ip6_config; - tmpl_len = sizeof (nmc_fields_ip6_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP6_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* addresses */ - list = (GSList *) nm_ip6_config_get_addresses (cfg6); - addr_arr = g_new (char *, g_slist_length (list) + 1); - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP6Address *addr = (NMIP6Address *) iter->data; - guint32 prefix; - char *ip_str, *gw_str; - - ip_str = nmc_ip6_address_as_string (nm_ip6_address_get_address (addr), NULL); - prefix = nm_ip6_address_get_prefix (addr); - gw_str = nmc_ip6_address_as_string (nm_ip6_address_get_gateway (addr), NULL); - - addr_arr[i++] = g_strdup_printf ("ip = %s/%u, gw = %s", ip_str, prefix, gw_str); - g_free (ip_str); - g_free (gw_str); - } - addr_arr[i] = NULL; - - /* routes */ - list = (GSList *) nm_ip6_config_get_routes (cfg6); - route_arr = g_new (char *, g_slist_length (list) + 1); - i = 0; - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP6Route *route = (NMIP6Route *) iter->data; - guint32 prefix, metric; - char *dest_str, *nexthop_str; - - dest_str = nmc_ip6_address_as_string (nm_ip6_route_get_dest (route), NULL); - nexthop_str = nmc_ip6_address_as_string (nm_ip6_route_get_next_hop (route), NULL); - prefix = nm_ip6_route_get_prefix (route); - metric = nm_ip6_route_get_metric (route); - - route_arr[i++] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u", dest_str, prefix, nexthop_str, metric); - g_free (dest_str); - g_free (nexthop_str); - } - route_arr[i] = NULL; - - /* DNS */ - list = (GSList *) nm_ip6_config_get_nameservers (cfg6); - dns_arr = g_new (char *, g_slist_length (list) + 1); - i = 0; - for (iter = list; iter; iter = g_slist_next (iter)) - dns_arr[i++] = nmc_ip6_address_as_string (iter->data, NULL); - - dns_arr[i] = NULL; - - /* domains */ - ptr_array = nm_ip6_config_get_domains (cfg6); - if (ptr_array) { - domain_arr = g_new (char *, ptr_array->len + 1); - for (i = 0; i < ptr_array->len; i++) - domain_arr[i] = g_strdup (g_ptr_array_index (ptr_array, i)); - - domain_arr[i] = NULL; - } - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, addr_arr); - set_val_arr (arr, 2, route_arr); - set_val_arr (arr, 3, dns_arr); - set_val_arr (arr, 4, domain_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; -} - -gboolean -print_dhcp4_config (NMDHCP4Config *dhcp4, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GHashTable *table; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (dhcp4 == NULL) - return FALSE; - - table = nm_dhcp4_config_get_options (dhcp4); - if (table) { - GHashTableIter table_iter; - gpointer key, value; - char **options_arr = NULL; - int i = 0; - - tmpl = nmc_fields_dhcp4_config; - tmpl_len = sizeof (nmc_fields_dhcp4_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DHCP4_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - options_arr = g_new (char *, g_hash_table_size (table) + 1); - g_hash_table_iter_init (&table_iter, table); - while (g_hash_table_iter_next (&table_iter, &key, &value)) - options_arr[i++] = g_strdup_printf ("%s = %s", (char *) key, (char *) value); - options_arr[i] = NULL; - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, options_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; - } - return FALSE; -} - -gboolean -print_dhcp6_config (NMDHCP6Config *dhcp6, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GHashTable *table; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (dhcp6 == NULL) - return FALSE; - - table = nm_dhcp6_config_get_options (dhcp6); - if (table) { - GHashTableIter table_iter; - gpointer key, value; - char **options_arr = NULL; - int i = 0; - - tmpl = nmc_fields_dhcp6_config; - tmpl_len = sizeof (nmc_fields_dhcp6_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DHCP6_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - options_arr = g_new (char *, g_hash_table_size (table) + 1); - g_hash_table_iter_init (&table_iter, table); - while (g_hash_table_iter_next (&table_iter, &key, &value)) - options_arr[i++] = g_strdup_printf ("%s = %s", (char *) key, (char *) value); - options_arr[i] = NULL; - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, options_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; - } - return FALSE; -} - -/* - * Parse IPv4 address from string to NMIP4Address stucture. - * ip_str is the IPv4 address in the form address/prefix - * gw_str is the gateway address (it is optional) - */ -NMIP4Address * -nmc_parse_and_build_ip4_address (const char *ip_str, const char *gw_str, GError **error) -{ - NMIP4Address *addr = NULL; - guint32 ip4_addr, gw_addr; - char *tmp; - char *plen; - long int prefix; - - g_return_val_if_fail (ip_str != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - tmp = g_strdup (ip_str); - plen = strchr (tmp, '/'); /* prefix delimiter */ - if (plen) - *plen++ = '\0'; - - if (inet_pton (AF_INET, tmp, &ip4_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid IPv4 address '%s'"), tmp); - goto finish; - } - - prefix = 32; - if (plen) { - if (!nmc_string_to_int (plen, TRUE, 1, 32, &prefix)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid prefix '%s'; <1-32> allowed"), plen); - goto finish; - } - } - - if (inet_pton (AF_INET, gw_str ? gw_str : "0.0.0.0", &gw_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid gateway '%s'"), gw_str); - goto finish; - } - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip4_addr); - nm_ip4_address_set_prefix (addr, (guint32) prefix); - nm_ip4_address_set_gateway (addr, gw_addr); - -finish: - g_free (tmp); - return addr; -} - -/* - * Parse IPv6 address from string to NMIP6Address stucture. - * ip_str is the IPv6 address in the form address/prefix - * gw_str is the gateway address (it is optional) - */ -NMIP6Address * -nmc_parse_and_build_ip6_address (const char *ip_str, const char *gw_str, GError **error) -{ - NMIP6Address *addr = NULL; - struct in6_addr ip_addr, gw_addr; - char *tmp; - char *plen; - long int prefix; - - g_return_val_if_fail (ip_str != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - tmp = g_strdup (ip_str); - plen = strchr (tmp, '/'); /* prefix delimiter */ - if (plen) - *plen++ = '\0'; - - if (inet_pton (AF_INET6, tmp, &ip_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid IPv6 address '%s'"), tmp); - goto finish; - } - - prefix = 128; - if (plen) { - if (!nmc_string_to_int (plen, TRUE, 1, 128, &prefix)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid prefix '%s'; <1-128> allowed"), plen); - goto finish; - } - } - - if (inet_pton (AF_INET6, gw_str ? gw_str : "::", &gw_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid gateway '%s'"), gw_str); - goto finish; - } - - addr = nm_ip6_address_new (); - nm_ip6_address_set_address (addr, &ip_addr); - nm_ip6_address_set_prefix (addr, (guint32) prefix); - nm_ip6_address_set_gateway (addr, &gw_addr); - -finish: - g_free (tmp); - return addr; -} - -typedef struct { - long int prefix; - long int metric; - union _IpDest { - guint32 ip4_dst; - struct in6_addr ip6_dst; - } dst; - union _IpNextHop { - guint32 ip4_nh; - struct in6_addr ip6_nh; - } nh; -} ParsedRoute; - -/* - * _parse_and_build_route: - * @family: AF_INET or AF_INET6 - * @first: the route destination in the form of "address/prefix" - (/prefix is optional) - * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be - either next hop address or metric. (It can be NULL when @third is NULL). - * @third: (allow-none): route metric - * @out: (out): route struct to fill - * @error: location to store GError - * - * Parse route from strings and fill @out parameter. - * - * Returns: %TRUE on success, %FALSE on failure - */ -static gboolean -_parse_and_build_route (int family, - const char *first, - const char *second, - const char *third, - ParsedRoute *out, - GError **error) -{ - int max_prefix; - char *tmp, *plen; - gboolean success = FALSE; - - g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE); - g_return_val_if_fail (first != NULL, FALSE); - g_return_val_if_fail (second || !third, FALSE); - g_return_val_if_fail (out, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - max_prefix = (family == AF_INET) ? 32 : 128; - /* initialize default values */ - out->prefix = max_prefix; - out->metric = 0; - if (family == AF_INET) - out->nh.ip4_nh = 0; - else - out->nh.ip6_nh = in6addr_any; - - tmp = g_strdup (first); - plen = strchr (tmp, '/'); /* prefix delimiter */ - if (plen) - *plen++ = '\0'; - - if (inet_pton (family, tmp, family == AF_INET ? (void *) &out->dst.ip4_dst : (void *) &out->dst.ip6_dst) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid route destination address '%s'"), tmp); - goto finish; - } - - if (plen) { - if (!nmc_string_to_int (plen, TRUE, 1, max_prefix, &out->prefix)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid prefix '%s'; <1-%d> allowed"), - plen, max_prefix); - goto finish; - } - } - - if (second) { - if (inet_pton (family, second, family == AF_INET ? (void *) &out->nh.ip4_nh : (void *) &out->nh.ip6_nh) < 1) { - if (third) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid next hop address '%s'"), second); - goto finish; - } else { - /* 'second' can be a metric */ - if (!nmc_string_to_int (second, TRUE, 0, G_MAXUINT32, &out->metric)) { - g_set_error (error, 1, 0, _("the second component of route ('%s') is neither " - "a next hop address nor a metric"), second); - goto finish; - } - } - } - } - - if (third) { - if (!nmc_string_to_int (third, TRUE, 0, G_MAXUINT32, &out->metric)) { - g_set_error (error, 1, 0, _("invalid metric '%s'"), third); - goto finish; - } - } - - /* We don't accept default routes as NetworkManager handles it itself */ - if ( (family == AF_INET && out->dst.ip4_dst == 0) - || (family == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED (&out->dst.ip6_dst))) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("default route cannot be added (NetworkManager handles it by itself)")); - goto finish; - } - - success = TRUE; - -finish: - g_free (tmp); - return success; -} - -/* - * nmc_parse_and_build_ip4_route: - * @first: the IPv4 route destination in the form of "address/prefix" - (/prefix is optional) - * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be - either next hop address or metric. (It can be NULL when @third is NULL). - * @third: (allow-none): route metric - * @error: location to store GError - * - * Parse IPv4 route from strings to NMIP4Route stucture. - * - * Returns: route as a NMIP4Route object, or %NULL on failure - */ -NMIP4Route * -nmc_parse_and_build_ip4_route (const char *first, - const char *second, - const char *third, - GError **error) -{ - ParsedRoute tmp_route; - NMIP4Route *route = NULL; - - g_return_val_if_fail (first != NULL, NULL); - g_return_val_if_fail (second || !third, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (_parse_and_build_route (AF_INET, first, second, third, &tmp_route, error)) { - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, tmp_route.dst.ip4_dst); - nm_ip4_route_set_prefix (route, (guint32) tmp_route.prefix); - nm_ip4_route_set_next_hop (route, tmp_route.nh.ip4_nh); - nm_ip4_route_set_metric (route, (guint32) tmp_route.metric); - } - return route; -} - -/* - * nmc_parse_and_build_ip6_route: - * @first: the IPv6 route destination in the form of "address/prefix" - (/prefix is optional) - * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be - either next hop address or metric. (It can be NULL when @third is NULL). - * @third: (allow-none): route metric - * @error: location to store GError - * - * Parse IPv6 route from strings to NMIP6Route stucture. - * - * Returns: route as a NMIP6Route object, or %NULL on failure - */ -NMIP6Route * -nmc_parse_and_build_ip6_route (const char *first, - const char *second, - const char *third, - GError **error) -{ - ParsedRoute tmp_route; - NMIP6Route *route = NULL; - - g_return_val_if_fail (first != NULL, NULL); - g_return_val_if_fail (second || !third, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (_parse_and_build_route (AF_INET6, first, second, third, &tmp_route, error)) { - route = nm_ip6_route_new (); - nm_ip6_route_set_dest (route, &tmp_route.dst.ip6_dst); - nm_ip6_route_set_prefix (route, (guint32) tmp_route.prefix); - nm_ip6_route_set_next_hop (route, &tmp_route.nh.ip6_nh); - nm_ip6_route_set_metric (route, (guint32) tmp_route.metric); - } - return route; -} - -const char * -nmc_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_IP_CHECK: - return _("connecting (checking IP connectivity)"); - case NM_DEVICE_STATE_SECONDARIES: - return _("connecting (starting secondary connections)"); - case NM_DEVICE_STATE_ACTIVATED: - return _("connected"); - case NM_DEVICE_STATE_DEACTIVATING: - return _("deactivating"); - case NM_DEVICE_STATE_FAILED: - return _("connection failed"); - default: - return _("unknown"); - } -} - -const char * -nmc_device_reason_to_string (NMDeviceStateReason reason) -{ - switch (reason) { - case NM_DEVICE_STATE_REASON_NONE: - return _("No reason given"); - - case NM_DEVICE_STATE_REASON_UNKNOWN: - return _("Unknown error"); - - case NM_DEVICE_STATE_REASON_NOW_MANAGED: - return _("Device is now managed"); - - case NM_DEVICE_STATE_REASON_NOW_UNMANAGED: - return _("Device is now unmanaged"); - - case NM_DEVICE_STATE_REASON_CONFIG_FAILED: - return _("The device could not be readied for configuration"); - - case NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: - return _("IP configuration could not be reserved (no available address, timeout, etc.)"); - - case NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: - return _("The IP configuration is no longer valid"); - - case NM_DEVICE_STATE_REASON_NO_SECRETS: - return _("Secrets were required, but not provided"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: - return _("802.1X supplicant disconnected"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: - return _("802.1X supplicant configuration failed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: - return _("802.1X supplicant failed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: - return _("802.1X supplicant took too long to authenticate"); - - case NM_DEVICE_STATE_REASON_PPP_START_FAILED: - return _("PPP service failed to start"); - - case NM_DEVICE_STATE_REASON_PPP_DISCONNECT: - return _("PPP service disconnected"); - - case NM_DEVICE_STATE_REASON_PPP_FAILED: - return _("PPP failed"); - - case NM_DEVICE_STATE_REASON_DHCP_START_FAILED: - return _("DHCP client failed to start"); - - case NM_DEVICE_STATE_REASON_DHCP_ERROR: - return _("DHCP client error"); - - case NM_DEVICE_STATE_REASON_DHCP_FAILED: - return _("DHCP client failed"); - - case NM_DEVICE_STATE_REASON_SHARED_START_FAILED: - return _("Shared connection service failed to start"); - - case NM_DEVICE_STATE_REASON_SHARED_FAILED: - return _("Shared connection service failed"); - - case NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: - return _("AutoIP service failed to start"); - - case NM_DEVICE_STATE_REASON_AUTOIP_ERROR: - return _("AutoIP service error"); - - case NM_DEVICE_STATE_REASON_AUTOIP_FAILED: - return _("AutoIP service failed"); - - case NM_DEVICE_STATE_REASON_MODEM_BUSY: - return _("The line is busy"); - - case NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: - return _("No dial tone"); - - case NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: - return _("No carrier could be established"); - - case NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: - return _("The dialing request timed out"); - - case NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: - return _("The dialing attempt failed"); - - case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: - return _("Modem initialization failed"); - - case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: - return _("Failed to select the specified APN"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: - return _("Not searching for networks"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: - return _("Network registration denied"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: - return _("Network registration timed out"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: - return _("Failed to register with the requested network"); - - case NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: - return _("PIN check failed"); - - case NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: - return _("Necessary firmware for the device may be missing"); - - case NM_DEVICE_STATE_REASON_REMOVED: - return _("The device was removed"); - - case NM_DEVICE_STATE_REASON_SLEEPING: - return _("NetworkManager went to sleep"); - - case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: - return _("The device's active connection disappeared"); - - case NM_DEVICE_STATE_REASON_USER_REQUESTED: - return _("Device disconnected by user or client"); - - case NM_DEVICE_STATE_REASON_CARRIER: - return _("Carrier/link changed"); - - case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: - return _("The device's existing connection was assumed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: - return _("The supplicant is now available"); - - case NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: - return _("The modem could not be found"); - - case NM_DEVICE_STATE_REASON_BT_FAILED: - return _("The Bluetooth connection failed or timed out"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: - return _("GSM Modem's SIM card not inserted"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: - return _("GSM Modem's SIM PIN required"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: - return _("GSM Modem's SIM PUK required"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: - return _("GSM Modem's SIM wrong"); - - case NM_DEVICE_STATE_REASON_INFINIBAND_MODE: - return _("InfiniBand device does not support connected mode"); - - case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: - return _("A dependency of the connection failed"); - - case NM_DEVICE_STATE_REASON_BR2684_FAILED: - return _("A problem with the RFC 2684 Ethernet over ADSL bridge"); - - case NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE: - return _("ModemManager is unavailable"); - - case NM_DEVICE_STATE_REASON_SSID_NOT_FOUND: - return _("The Wi-Fi network could not be found"); - - case NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED: - return _("A secondary connection of the base connection failed"); - - case NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED: - return _("DCB or FCoE setup failed"); - - case NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED: - return _("teamd control failed"); - - case NM_DEVICE_STATE_REASON_MODEM_FAILED: - return _("Modem failed or no longer available"); - - case NM_DEVICE_STATE_REASON_MODEM_AVAILABLE: - return _("Modem now ready and available"); - - case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: - return _("SIM PIN was incorrect"); - - default: - /* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */ - return _("Unknown"); - } -} - - -/* Max priority values from libnm-util/nm-setting-vlan.c */ -#define MAX_SKB_PRIO G_MAXUINT32 -#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ - -/* - * Parse VLAN priority mappings from the following format: 2:1,3:4,7:3 - * and verify if the priority numbers are valid - * - * Return: string array with split maps, or NULL on error - * Caller is responsible for freeing the array. - */ -char ** -nmc_vlan_parse_priority_maps (const char *priority_map, - NMVlanPriorityMap map_type, - GError **error) -{ - char **mapping = NULL, **iter; - unsigned long from, to, from_max, to_max; - - g_return_val_if_fail (priority_map != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (map_type == NM_VLAN_INGRESS_MAP) { - from_max = MAX_8021P_PRIO; - to_max = MAX_SKB_PRIO; - } else { - from_max = MAX_SKB_PRIO; - to_max = MAX_8021P_PRIO; - } - - mapping = g_strsplit (priority_map, ",", 0); - for (iter = mapping; iter && *iter; iter++) { - char *left, *right; - - left = g_strstrip (*iter); - right = strchr (left, ':'); - if (!right) { - g_set_error (error, 1, 0, _("invalid priority map '%s'"), *iter); - g_strfreev (mapping); - return NULL; - } - *right++ = '\0'; - - if (!nmc_string_to_uint (left, TRUE, 0, from_max, &from)) { - g_set_error (error, 1, 0, _("priority '%s' is not valid (<0-%ld>)"), - left, from_max); - g_strfreev (mapping); - return NULL; - } - if (!nmc_string_to_uint (right, TRUE, 0, to_max, &to)) { - g_set_error (error, 1, 0, _("priority '%s' is not valid (<0-%ld>)"), - right, to_max); - g_strfreev (mapping); - return NULL; - } - *(right-1) = ':'; /* Put back ':' */ - } - return mapping; -} - -const char * -nmc_bond_validate_mode (const char *mode, GError **error) -{ - unsigned long mode_int; - static const char *valid_modes[] = { "balance-rr", - "active-backup", - "balance-xor", - "broadcast", - "802.3ad", - "balance-tlb", - "balance-alb", - NULL }; - if (nmc_string_to_uint (mode, TRUE, 0, 6, &mode_int)) { - /* Translate bonding mode numbers to mode names: - * https://www.kernel.org/doc/Documentation/networking/bonding.txt - */ - return valid_modes[mode_int]; - } else - return nmc_string_is_valid (mode, valid_modes, error); -} - -/* - * nmc_team_check_config: - * @config: file name with team config, or raw team JSON config data - * @out_config: raw team JSON config data (with removed new-line characters) - * @error: location to store error, or %NUL - * - * Check team config from @config parameter and return the checked/sanitized - * config in @out_config. - * - * Returns: %TRUE if the config is valid, %FALSE if it is invalid - */ -gboolean -nmc_team_check_config (const char *config, char **out_config, GError **error) -{ - char *contents = NULL; - size_t c_len = 0; - - *out_config = NULL; - - if (!config || strlen (config) == strspn (config, " \t")) - return TRUE; - - /* 'config' can be either a file name or raw JSON config data */ - if (g_file_test (config, G_FILE_TEST_EXISTS)) - (void) g_file_get_contents (config, &contents, NULL, NULL); - else - contents = g_strdup (config); - - if (contents) { - g_strstrip (contents); - c_len = strlen (contents); - } - - /* Do a simple validity check */ - if (!contents || !contents[0] || c_len > 100000 || contents[0] != '{' || contents[c_len-1] != '}') { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("'%s' is not a valid team configuration or file name."), config); - g_free (contents); - return FALSE; - } - *out_config = g_strdelimit (contents, "\r\n", ' '); - return TRUE; -} - -/* - * nmc_find_connection: - * @list: list of NMConnections to search in - * @filter_type: "id", "uuid", "path" or %NULL - * @filter_val: connection to find (connection name, UUID or path) - * @start: where to start in @list. The location is updated so that the function - * can be called multiple times (for connections with the same name). - * - * Find a connection in @list according to @filter_val. @filter_type determines - * what property is used for comparison. When @filter_type is NULL, compare - * @filter_val against all types. Otherwise, only compare against the specified - * type. If 'path' filter type is specified, comparison against numeric index - * (in addition to the whole path) is allowed. - * - * Returns: found connection, or %NULL - */ -NMConnection * -nmc_find_connection (GSList *list, - const char *filter_type, - const char *filter_val, - GSList **start) -{ - NMConnection *connection; - NMConnection *found = NULL; - GSList *iterator; - const char *id; - const char *uuid; - const char *path, *path_num; - - iterator = (start && *start) ? *start : list; - while (iterator) { - connection = NM_CONNECTION (iterator->data); - - id = nm_connection_get_id (connection); - uuid = nm_connection_get_uuid (connection); - path = nm_connection_get_path (connection); - path_num = path ? strrchr (path, '/') + 1 : NULL; - - /* When filter_type is NULL, compare connection ID (filter_val) - * against all types. Otherwise, only compare against the specific - * type. If 'path' filter type is specified, comparison against - * numeric index (in addition to the whole path) is allowed. - */ - if ( ( (!filter_type || strcmp (filter_type, "id") == 0) - && strcmp (filter_val, id) == 0) - || ( (!filter_type || strcmp (filter_type, "uuid") == 0) - && strcmp (filter_val, uuid) == 0) - || ( (!filter_type || strcmp (filter_type, "path") == 0) - && (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)))) { - if (!start) - return connection; - if (found) { - *start = iterator; - return found; - } - found = connection; - } - - iterator = g_slist_next (iterator); - } - - if (start) - *start = NULL; - return found; -} - -/** - * nmc_cleanup_readline: - * - * Cleanup readline when nmcli is terminated with a signal. - * It makes sure the terminal is not garbled. - */ -void -nmc_cleanup_readline (void) -{ - rl_free_line_state (); - rl_cleanup_after_signal (); -} - -/** - * nmc_readline: - * @prompt_fmt: prompt to print (telling user what to enter). It is standard - * printf() format string - * @...: a list of arguments according to the @prompt_fmt format string - * - * Wrapper around libreadline's readline() function. - * - * Returns: the user provided string. In case the user entered empty string, - * this function returns NULL. - */ -char * -nmc_readline (const char *prompt_fmt, ...) -{ - va_list args; - char *prompt, *str; - - va_start (args, prompt_fmt); - prompt = g_strdup_vprintf (prompt_fmt, args); - va_end (args); - - str = readline (prompt); - /* Return NULL, not empty string */ - if (str && *str == '\0') { - g_free (str); - str = NULL; - } - - if (str && *str) - add_history (str); - - g_free (prompt); - return str; -} - -/** - * nmc_rl_gen_func_basic: - * @text: text to complete - * @state: readline state; says whether start from scratch (state == 0) - * @words: strings for completion - * - * Basic function generating list of completion strings for readline. - * See e.g. http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC49 - */ -char * -nmc_rl_gen_func_basic (const char *text, int state, const char **words) -{ - static int list_idx, len; - const char *name; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - /* Return the next name which partially matches one from the 'words' list. */ - while ((name = words[list_idx])) { - list_idx++; - - if (strncmp (name, text, len) == 0) - return g_strdup (name); - } - return NULL; -} - diff --git a/cli/src/common.h b/cli/src/common.h deleted file mode 100644 index 228375b9..00000000 --- a/cli/src/common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * nmcli - command-line tool for controlling NetworkManager - * Common functions and data shared between files. - * - * 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 2012 - 2014 Red Hat, Inc. - */ - -#ifndef NMC_COMMON_H -#define NMC_COMMON_H - -#include - -#include -#include -#include -#include -#include - -#include "nmcli.h" - -gboolean print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix, const char *one_field); -gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix, const char *one_field); -gboolean print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix, const char *one_field); -gboolean print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix, const char *one_field); - -NMIP4Address *nmc_parse_and_build_ip4_address (const char *ip_str, const char *gw_str, GError **error); -NMIP6Address *nmc_parse_and_build_ip6_address (const char *ip_str, const char *gw_str, GError **error); - -NMIP4Route *nmc_parse_and_build_ip4_route (const char *first, const char *second, const char *third, GError **error); -NMIP6Route *nmc_parse_and_build_ip6_route (const char *first, const char *second, const char *third, GError **error); - -const char * nmc_device_state_to_string (NMDeviceState state); -const char * nmc_device_reason_to_string (NMDeviceStateReason reason); - -char ** -nmc_vlan_parse_priority_maps (const char *priority_map, - NMVlanPriorityMap map_type, - GError **error); - -const char *nmc_bond_validate_mode (const char *mode, GError **error); -gboolean nmc_team_check_config (const char *config, char **out_config, GError **error); - -NMConnection *nmc_find_connection (GSList *list, - const char *filter_type, - const char *filter_val, - GSList **start); - -void nmc_cleanup_readline (void); -char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2); -char *nmc_rl_gen_func_basic (const char *text, int state, const char **words); - -#endif /* NMC_COMMON_H */ diff --git a/cli/src/connections.c b/cli/src/connections.c deleted file mode 100644 index d17f7f12..00000000 --- a/cli/src/connections.c +++ /dev/null @@ -1,8706 +0,0 @@ -/* 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 - 2014 Red Hat, Inc. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#if WITH_WIMAX -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "common.h" -#include "settings.h" -#include "connections.h" - -/* Activation timeout waiting for bond/team/bridge slaves (in seconds) */ -#define SLAVES_UP_TIMEOUT 10 - -/* define some prompts for connection editor */ -#define EDITOR_PROMPT_SETTING _("Setting name? ") -#define EDITOR_PROMPT_PROPERTY _("Property name? ") -#define EDITOR_PROMPT_CON_TYPE _("Enter connection type: ") - -/* define some other prompts */ -#define PROMPT_CON_TYPE _("Connection type: ") -#define PROMPT_VPN_TYPE _("VPN type: ") -#define PROMPT_BOND_MASTER _("Bond master: ") -#define PROMPT_TEAM_MASTER _("Team master: ") -#define PROMPT_BRIDGE_MASTER _("Bridge master: ") -#define PROMPT_CONNECTION _("Connection (name, UUID, or path): ") - -static const char *nmc_known_vpns[] = - { "openvpn", "vpnc", "pptp", "openconnect", "openswan", "libreswan", - "ssh", "l2tp", "iodine", NULL }; - -/* Available fields for 'connection show' */ -static NmcOutputField nmc_fields_con_show[] = { - {"NAME", N_("NAME"), 25}, /* 0 */ - {"UUID", N_("UUID"), 38}, /* 1 */ - {"TYPE", N_("TYPE"), 17}, /* 2 */ - {"TIMESTAMP", N_("TIMESTAMP"), 12}, /* 3 */ - {"TIMESTAMP-REAL", N_("TIMESTAMP-REAL"), 34}, /* 4 */ - {"AUTOCONNECT", N_("AUTOCONNECT"), 13}, /* 5 */ - {"READONLY", N_("READONLY"), 10}, /* 6 */ - {"DBUS-PATH", N_("DBUS-PATH"), 42}, /* 7 */ - {"ACTIVE", N_("ACTIVE"), 10}, /* 8 */ - {"DEVICE", N_("DEVICE"), 10}, /* 9 */ - {"STATE", N_("STATE"), 12}, /* 10 */ - {"ACTIVE-PATH", N_("ACTIVE-PATH"), 51}, /* 11 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_CON_SHOW_ALL "NAME,UUID,TYPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY,DBUS-PATH,"\ - "ACTIVE,DEVICE,STATE,ACTIVE-PATH" -#define NMC_FIELDS_CON_SHOW_COMMON "NAME,UUID,TYPE,DEVICE" - -/* Helper macro to define fields */ -#define SETTING_FIELD(setting, props) { setting, N_(setting), 0, props, NULL, FALSE, FALSE, 0 } - -/* defined in settings.c */ -extern NmcOutputField nmc_fields_setting_connection[]; -extern NmcOutputField nmc_fields_setting_wired[]; -extern NmcOutputField nmc_fields_setting_8021X[]; -extern NmcOutputField nmc_fields_setting_wireless[]; -extern NmcOutputField nmc_fields_setting_wireless_security[]; -extern NmcOutputField nmc_fields_setting_ip4_config[]; -extern NmcOutputField nmc_fields_setting_ip6_config[]; -extern NmcOutputField nmc_fields_setting_serial[]; -extern NmcOutputField nmc_fields_setting_ppp[]; -extern NmcOutputField nmc_fields_setting_pppoe[]; -extern NmcOutputField nmc_fields_setting_adsl[]; -extern NmcOutputField nmc_fields_setting_gsm[]; -extern NmcOutputField nmc_fields_setting_cdma[]; -extern NmcOutputField nmc_fields_setting_bluetooth[]; -extern NmcOutputField nmc_fields_setting_olpc_mesh[]; -extern NmcOutputField nmc_fields_setting_vpn[]; -extern NmcOutputField nmc_fields_setting_wimax[]; -extern NmcOutputField nmc_fields_setting_infiniband[]; -extern NmcOutputField nmc_fields_setting_bond[]; -extern NmcOutputField nmc_fields_setting_vlan[]; -extern NmcOutputField nmc_fields_setting_bridge[]; -extern NmcOutputField nmc_fields_setting_bridge_port[]; -extern NmcOutputField nmc_fields_setting_team[]; -extern NmcOutputField nmc_fields_setting_team_port[]; -extern NmcOutputField nmc_fields_setting_dcb[]; - -/* Available settings for 'connection show ' - profile part */ -static NmcOutputField nmc_fields_settings_names[] = { - SETTING_FIELD (NM_SETTING_CONNECTION_SETTING_NAME, nmc_fields_setting_connection + 1), /* 0 */ - SETTING_FIELD (NM_SETTING_WIRED_SETTING_NAME, nmc_fields_setting_wired + 1), /* 1 */ - SETTING_FIELD (NM_SETTING_802_1X_SETTING_NAME, nmc_fields_setting_8021X + 1), /* 2 */ - SETTING_FIELD (NM_SETTING_WIRELESS_SETTING_NAME, nmc_fields_setting_wireless + 1), /* 3 */ - SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, nmc_fields_setting_wireless_security + 1), /* 4 */ - SETTING_FIELD (NM_SETTING_IP4_CONFIG_SETTING_NAME, nmc_fields_setting_ip4_config + 1), /* 5 */ - SETTING_FIELD (NM_SETTING_IP6_CONFIG_SETTING_NAME, nmc_fields_setting_ip6_config + 1), /* 6 */ - SETTING_FIELD (NM_SETTING_SERIAL_SETTING_NAME, nmc_fields_setting_serial + 1), /* 7 */ - SETTING_FIELD (NM_SETTING_PPP_SETTING_NAME, nmc_fields_setting_ppp + 1), /* 8 */ - SETTING_FIELD (NM_SETTING_PPPOE_SETTING_NAME, nmc_fields_setting_pppoe + 1), /* 9 */ - SETTING_FIELD (NM_SETTING_GSM_SETTING_NAME, nmc_fields_setting_gsm + 1), /* 10 */ - SETTING_FIELD (NM_SETTING_CDMA_SETTING_NAME, nmc_fields_setting_cdma + 1), /* 11 */ - SETTING_FIELD (NM_SETTING_BLUETOOTH_SETTING_NAME, nmc_fields_setting_bluetooth + 1), /* 12 */ - SETTING_FIELD (NM_SETTING_OLPC_MESH_SETTING_NAME, nmc_fields_setting_olpc_mesh + 1), /* 13 */ - SETTING_FIELD (NM_SETTING_VPN_SETTING_NAME, nmc_fields_setting_vpn + 1), /* 14 */ - SETTING_FIELD (NM_SETTING_WIMAX_SETTING_NAME, nmc_fields_setting_wimax + 1), /* 15 */ - SETTING_FIELD (NM_SETTING_INFINIBAND_SETTING_NAME, nmc_fields_setting_infiniband + 1), /* 16 */ - SETTING_FIELD (NM_SETTING_BOND_SETTING_NAME, nmc_fields_setting_bond + 1), /* 17 */ - SETTING_FIELD (NM_SETTING_VLAN_SETTING_NAME, nmc_fields_setting_vlan + 1), /* 18 */ - SETTING_FIELD (NM_SETTING_ADSL_SETTING_NAME, nmc_fields_setting_adsl + 1), /* 19 */ - SETTING_FIELD (NM_SETTING_BRIDGE_SETTING_NAME, nmc_fields_setting_bridge + 1), /* 20 */ - SETTING_FIELD (NM_SETTING_BRIDGE_PORT_SETTING_NAME, nmc_fields_setting_bridge_port + 1), /* 21 */ - SETTING_FIELD (NM_SETTING_TEAM_SETTING_NAME, nmc_fields_setting_team + 1), /* 22 */ - SETTING_FIELD (NM_SETTING_TEAM_PORT_SETTING_NAME, nmc_fields_setting_team_port + 1), /* 23 */ - SETTING_FIELD (NM_SETTING_DCB_SETTING_NAME, nmc_fields_setting_dcb + 1), /* 24 */ - {NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0} -}; -#define NMC_FIELDS_SETTINGS_NAMES_ALL_X 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_ADSL_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","\ - NM_SETTING_INFINIBAND_SETTING_NAME","\ - NM_SETTING_BOND_SETTING_NAME","\ - NM_SETTING_VLAN_SETTING_NAME","\ - NM_SETTING_BRIDGE_SETTING_NAME","\ - NM_SETTING_BRIDGE_PORT_SETTING_NAME","\ - NM_SETTING_TEAM_SETTING_NAME","\ - NM_SETTING_TEAM_PORT_SETTING_NAME"," \ - NM_SETTING_DCB_SETTING_NAME -#if WITH_WIMAX -#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X","\ - NM_SETTING_WIMAX_SETTING_NAME -#else -#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X -#endif - -/* Active connection data */ -/* Available fields for GENERAL group */ -static NmcOutputField nmc_fields_con_active_details_general[] = { - {"GROUP", N_("GROUP"), 9}, /* 0 */ - {"NAME", N_("NAME"), 25}, /* 1 */ - {"UUID", N_("UUID"), 38}, /* 2 */ - {"DEVICES", N_("DEVICES"), 10}, /* 3 */ - {"STATE", N_("STATE"), 12}, /* 4 */ - {"DEFAULT", N_("DEFAULT"), 8}, /* 5 */ - {"DEFAULT6", N_("DEFAULT6"), 9}, /* 6 */ - {"SPEC-OBJECT", N_("SPEC-OBJECT"), 10}, /* 7 */ - {"VPN", N_("VPN"), 5}, /* 8 */ - {"DBUS-PATH", N_("DBUS-PATH"), 51}, /* 9 */ - {"CON-PATH", N_("CON-PATH"), 44}, /* 10 */ - {"ZONE", N_("ZONE"), 15}, /* 11 */ - {"MASTER-PATH", N_("MASTER-PATH"), 44}, /* 12 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_CON_ACTIVE_DETAILS_GENERAL_ALL "GROUP,NAME,UUID,DEVICES,STATE,DEFAULT,DEFAULT6,"\ - "VPN,ZONE,DBUS-PATH,CON-PATH,SPEC-OBJECT,MASTER-PATH" - -/* IP group is handled by common.c */ - -/* Available fields for VPN group */ -static NmcOutputField nmc_fields_con_active_details_vpn[] = { - {"GROUP", N_("GROUP"), 9}, /* 0 */ - {"TYPE", N_("TYPE"), 15}, /* 1 */ - {"USERNAME", N_("USERNAME"), 15}, /* 2 */ - {"GATEWAY", N_("GATEWAY"), 25}, /* 3 */ - {"BANNER", N_("BANNER"), 120}, /* 4 */ - {"VPN-STATE", N_("VPN-STATE"), 40}, /* 5 */ - {"CFG", N_("CFG"), 120}, /* 6 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_CON_ACTIVE_DETAILS_VPN_ALL "GROUP,TYPE,USERNAME,GATEWAY,BANNER,VPN-STATE,CFG" - -/* defined in common.c */ -extern NmcOutputField nmc_fields_ip4_config[]; -extern NmcOutputField nmc_fields_ip6_config[]; -extern NmcOutputField nmc_fields_dhcp4_config[]; -extern NmcOutputField nmc_fields_dhcp6_config[]; - -/* Available fields for 'connection show ' - active part */ -static NmcOutputField nmc_fields_con_active_details_groups[] = { - {"GENERAL", N_("GENERAL"), 0, nmc_fields_con_active_details_general + 1}, /* 0 */ - {"IP4", N_("IP4"), 0, nmc_fields_ip4_config + 1 }, /* 1 */ - {"DHCP4", N_("DHCP4"), 0, nmc_fields_dhcp4_config + 1 }, /* 2 */ - {"IP6", N_("IP6"), 0, nmc_fields_ip6_config + 1 }, /* 3 */ - {"DHCP6", N_("DHCP6"), 0, nmc_fields_dhcp6_config + 1 }, /* 4 */ - {"VPN", N_("VPN"), 0, nmc_fields_con_active_details_vpn + 1 }, /* 5 */ - {NULL, NULL, 0, NULL} -}; -#define NMC_FIELDS_CON_ACTIVE_DETAILS_ALL "GENERAL,IP4,DHCP4,IP6,DHCP6,VPN" - -/* Pseudo group names for 'connection show ' */ -/* e.g.: nmcli -f profile con show my-eth0 */ -/* e.g.: nmcli -f active con show my-eth0 */ -#define CON_SHOW_DETAIL_GROUP_PROFILE "profile" -#define CON_SHOW_DETAIL_GROUP_ACTIVE "active" - -typedef struct { - NmCli *nmc; - int argc; - char **argv; -} ArgsInfo; - -/* glib main loop variable - defined in nmcli.c */ -extern GMainLoop *loop; - -static ArgsInfo args_info; -static guint progress_id = 0; /* ID of event source for displaying progress */ - -/* for readline TAB completion in editor */ -typedef struct { - NmCli *nmc; - char *con_type; - NMConnection *connection; - NMSetting *setting; -} TabCompletionInfo; -static TabCompletionInfo nmc_tab_completion = {NULL, NULL, NULL, NULL}; - -/* Global variable defined in nmcli.c - used for TAB completion */ -extern NmCli nm_cli; - -static char *gen_connection_types (const char *text, int state); - -static void -usage (void) -{ - fprintf (stderr, - _("Usage: nmcli connection { COMMAND | help }\n\n" - "COMMAND := { show | up | down | add | modify | edit | delete | reload | load }\n\n" - " show [--active] [[id | uuid | path | apath] ] ...\n\n" -#if WITH_WIMAX - " up [[id | uuid | path] ] [ifname ] [ap ] [nsp ]\n\n" -#else - " up [[id | uuid | path] ] [ifname ] [ap ]\n\n" -#endif - " down [id | uuid | path | apath] \n\n" - " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " modify [--temporary] [id | uuid | path] ([+|-]. )+\n\n" - " edit [id | uuid | path] \n" - " edit [type ] [con-name ]\n\n" - " delete [id | uuid | path] \n\n" - " reload\n\n" - " load [ ... ]\n\n")); -} - -static void -usage_connection_show (void) -{ - fprintf (stderr, - _("Usage: nmcli connection show { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [--active]\n" - "\n" - "List in-memory and on-disk connection profiles, some of which may also be\n" - "active if a device is using that connection profile. Without a parameter, all\n" - "profiles are listed. When --active option is specified, only the active\n" - "profiles are shown.\n" - "\n" - "ARGUMENTS := [--active] [id | uuid | path | apath] ...\n" - "\n" - "Show details for specified connections. By default, both static configuration\n" - "and active connection data are displayed. It is possible to filter the output\n" - "using global '--fields' option. Refer to the manual page for more information.\n" - "When --active option is specified, only the active profiles are taken into\n" - "account.\n")); -} - -static void -usage_connection_up (void) -{ - fprintf (stderr, - _("Usage: nmcli connection up { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] [ifname ] [ap ] [nsp ]\n" - "\n" - "Activate a connection on a device. The profile to activate is identified by its\n" - "name, UUID or D-Bus path.\n" - "\n" - "ARGUMENTS := ifname [ap ] [nsp ]\n" - "\n" - "Activate a device with a connection. The connection profile is selected\n" - "automatically by NetworkManager.\n" - "\n" - "ifname - specifies the device to active the connection on\n" - "ap - specifies AP to connect to (only valid for Wi-Fi)\n" - "nsp - specifies NSP to connect to (only valid for WiMAX)\n\n")); -} - -static void -usage_connection_down (void) -{ - fprintf (stderr, - _("Usage: nmcli connection down { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path | apath] \n" - "\n" - "Deactivate a connection from a device (without preventing the device from\n" - "further auto-activation). The profile to deactivate is identified by its name,\n" - "UUID or D-Bus path.\n\n")); -} - -static void -usage_connection_add (void) -{ - fprintf (stderr, - _("Usage: nmcli connection add { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " COMMON_OPTIONS:\n" - " type \n" - " ifname | \"*\"\n" - " [con-name ]\n" - " [autoconnect yes|no]\n\n" - " [save yes|no]\n\n" - " TYPE_SPECIFIC_OPTIONS:\n" - " ethernet: [mac ]\n" - " [cloned-mac ]\n" - " [mtu ]\n\n" - " wifi: ssid \n" - " [mac ]\n" - " [cloned-mac ]\n" - " [mtu ]\n\n" - " wimax: [mac ]\n" - " [nsp ]\n\n" - " pppoe: username \n" - " [password ]\n" - " [service ]\n" - " [mtu ]\n" - " [mac ]\n\n" - " gsm: apn \n" - " [user ]\n" - " [password ]\n\n" - " cdma: [user ]\n" - " [password ]\n\n" - " infiniband: [mac ]\n" - " [mtu ]\n" - " [transport-mode datagram | connected]\n" - " [parent ]\n" - " [p-key ]\n\n" - " bluetooth: [addr ]\n" - " [bt-type panu|dun-gsm|dun-cdma]\n\n" - " vlan: dev \n" - " id \n" - " [flags ]\n" - " [ingress ]\n" - " [egress ]\n" - " [mtu ]\n\n" - " bond: [mode balance-rr (0) | active-backup (1) | balance-xor (2) | broadcast (3) |\n" - " 802.3ad (4) | balance-tlb (5) | balance-alb (6)]\n" - " [primary ]\n" - " [miimon ]\n" - " [downdelay ]\n" - " [updelay ]\n" - " [arp-interval ]\n" - " [arp-ip-target ]\n\n" - " bond-slave: master \n\n" - " team: [config |]\n\n" - " team-slave: master \n" - " [config |]\n\n" - " bridge: [stp yes|no]\n" - " [priority ]\n" - " [forward-delay <2-30>]\n" - " [hello-time <1-10>]\n" - " [max-age <6-40>]\n" - " [ageing-time <0-1000000>]\n" - " [mac ]\n\n" - " bridge-slave: master \n" - " [priority <0-63>]\n" - " [path-cost <1-65535>]\n" - " [hairpin yes|no]\n\n" - " vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan|libreswan|ssh|l2tp|iodine|...\n" - " [user ]\n\n" - " olpc-mesh: ssid \n" - " [channel <1-13>]\n" - " [dhcp-anycast ]\n\n" - " IP_OPTIONS:\n" - " [ip4 ] [gw4 ]\n" - " [ip6 ] [gw6 ]\n\n")); -} - -static void -usage_connection_modify (void) -{ - fprintf (stderr, - _("Usage: nmcli connection modify { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] ([+|-]. )+\n" - "\n" - "Modify one or more properties of the connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path. For multi-valued\n" - "properties you can use optional '+' or '-' prefix to the property name.\n" - "The '+' sign allows appending items instead of overwriting the whole value.\n" - "The '-' sign allows removing selected items instead of the whole value.\n" - "\n" - "Examples:\n" - "nmcli con mod home-wifi wifi.ssid rakosnicek\n" - "nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, 10.10.1.5/8\"\n" - "nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n" - "nmcli con mod em1-1 -ipv4.dns 1\n" - "nmcli con mod em1-1 -ipv6.addr \"abbe::cafe/56\"\n" - "nmcli con mod bond0 +bond.options mii=500\n" - "nmcli con mod bond0 -bond.options downdelay\n\n")); -} - -static void -usage_connection_edit (void) -{ - fprintf (stderr, - _("Usage: nmcli connection edit { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] \n" - "\n" - "Edit an existing connection profile in an interactive editor.\n" - "The profile is identified by its name, UUID or D-Bus path\n" - "\n" - "ARGUMENTS := [type ] [con-name ]\n" - "\n" - "Add a new connection profile in an interactive editor.\n\n")); -} - -static void -usage_connection_delete (void) -{ - fprintf (stderr, - _("Usage: nmcli connection delete { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] \n" - "\n" - "Delete a connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path.\n\n")); -} - -static void -usage_connection_reload (void) -{ - fprintf (stderr, - _("Usage: nmcli connection reload { help }\n" - "\n" - "Reload all connection files from disk.\n\n")); -} - -static void -usage_connection_load (void) -{ - fprintf (stderr, - _("Usage: nmcli connection load { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [...]\n" - "\n" - "Load/reload one or more connection files from disk. Use this after manually\n" - "editing a connection file to ensure that NetworkManager is aware of its latest\n" - "state.\n\n")); -} - - -/* The real commands that do something - i.e. not 'help', etc. */ -static const char *real_con_commands[] = { - "show", - "up", - "down", - "add", - "modify", - "edit", - "delete", - "reload", - "load", - NULL -}; - -/* quit main loop */ -static void -quit (void) -{ - if (progress_id) { - g_source_remove (progress_id); - progress_id = 0; - nmc_terminal_erase_line (); - } - - g_main_loop_quit (loop); /* quit main loop */ -} - -static const char * -construct_header_name (const char *base, const char *spec) -{ - static char header_name[128]; - - if (spec == NULL) - return base; - - g_strlcpy (header_name, base, sizeof (header_name)); - g_strlcat (header_name, " (", sizeof (header_name)); - g_strlcat (header_name, spec, sizeof (header_name)); - g_strlcat (header_name, ")", sizeof (header_name)); - - return header_name; -} - -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_DEACTIVATING: - return _("deactivating"); - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: - return _("deactivated"); - 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"); - } -} - -/* Caller has to free the returned string */ -static char * -get_ac_device_string (NMActiveConnection *active) -{ - GString *dev_str; - const GPtrArray *devices; - int i; - - if (!active) - return NULL; - - /* 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); - const char *dev_iface = nm_device_get_iface (device); - - if (dev_iface) { - g_string_append (dev_str, dev_iface); - g_string_append_c (dev_str, ','); - } - } - if (dev_str->len > 0) - g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ - - return g_string_free (dev_str, FALSE); -} - -static NMActiveConnection * -get_ac_for_connection (const GPtrArray *active_cons, NMConnection *connection) -{ - const char *con_path; - int i; - NMActiveConnection *ac = NULL; - - /* Is the connection active? */ - con_path = nm_connection_get_path (connection); - for (i = 0; active_cons && i < active_cons->len; i++) { - NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); - - if (!g_strcmp0 (nm_active_connection_get_connection (candidate), con_path)) { - ac = candidate; - break; - } - } - return ac; -} - -static NMConnection * -get_connection_for_active (const GSList *con_list, NMActiveConnection *active) -{ - const GSList *iter; - const char *path; - - path = nm_active_connection_get_connection (active); - g_return_val_if_fail (path != NULL, NULL); - - for (iter = con_list; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = NM_CONNECTION (iter->data); - - if (strcmp (nm_connection_get_path (candidate), path) == 0) - return candidate; - } - return NULL; -} - -static gboolean -nmc_connection_profile_details (NMConnection *connection, NmCli *nmc) -{ - GError *error = NULL; - GArray *print_settings_array; - GPtrArray *prop_array = NULL; - int i; - char *fields_str; - char *fields_all = NMC_FIELDS_SETTINGS_NAMES_ALL; - char *fields_common = NMC_FIELDS_SETTINGS_NAMES_ALL; - const char *base_hdr = _("Connection profile details"); - 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, TRUE, &prop_array, &error); - if (error) { - g_string_printf (nmc->return_text, _("Error: 'connection show': %s"), error->message); - g_error_free (error); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - g_assert (print_settings_array); - - /* Main header */ - nmc->print_fields.header_name = (char *) construct_header_name (base_hdr, nm_connection_get_id (connection)); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTINGS_NAMES_ALL, - nmc_fields_settings_names, FALSE, NULL, NULL); - - nmc_fields_settings_names[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; - print_required_fields (nmc, nmc_fields_settings_names); - - /* Loop through the required settings and print them. */ - for (i = 0; i < print_settings_array->len; i++) { - NMSetting *setting; - int section_idx = g_array_index (print_settings_array, int, i); - const char *prop_name = (const char *) g_ptr_array_index (prop_array, i); - - if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output) - printf ("\n"); /* Empty line */ - - was_output = FALSE; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - setting = nm_connection_get_setting_by_name (connection, nmc_fields_settings_names[section_idx].name); - if (setting) { - setting_details (setting, nmc, prop_name); - was_output = TRUE; - continue; - } - } - - g_array_free (print_settings_array, TRUE); - if (prop_array) - g_ptr_array_free (prop_array, TRUE); - - return TRUE; -} - -static NMActiveConnection * -find_active_connection (const GPtrArray *active_cons, - const GSList *cons, - const char *filter_type, - const char *filter_val, - int *idx) -{ - int i; - int start = (idx && *idx > 0) ? *idx : 0; - const char *path, *a_path, *path_num, *a_path_num; - const char *id; - const char *uuid; - NMConnection *con; - NMActiveConnection *found = NULL; - - for (i = start; active_cons && (i < active_cons->len); i++) { - NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); - - path = nm_active_connection_get_connection (candidate); - a_path = nm_object_get_path (NM_OBJECT (candidate)); - uuid = nm_active_connection_get_uuid (candidate); - path_num = path ? strrchr (path, '/') + 1 : NULL; - a_path_num = a_path ? strrchr (a_path, '/') + 1 : NULL; - - con = get_connection_for_active (cons, candidate); - id = nm_connection_get_id (con); - - /* When filter_type is NULL, compare connection ID (filter_val) - * against all types. Otherwise, only compare against the specific - * type. If 'path' or 'apath' filter types are specified, comparison - * against numeric index (in addition to the whole path) is allowed. - */ - if ( ( (!filter_type || strcmp (filter_type, "id") == 0) - && strcmp (filter_val, id) == 0) - || ( (!filter_type || strcmp (filter_type, "uuid") == 0) - && strcmp (filter_val, uuid) == 0) - || ( (!filter_type || strcmp (filter_type, "path") == 0) - && (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0))) - || ( (!filter_type || strcmp (filter_type, "apath") == 0) - && (g_strcmp0 (filter_val, a_path) == 0 || (filter_type && g_strcmp0 (filter_val, a_path_num) == 0)))) { - if (!idx) - return candidate; - if (found) { - *idx = i; - return found; - } - found = candidate; - } - } - - if (idx) - *idx = 0; - return found; -} - -static void -fill_output_connection (gpointer data, gpointer user_data, gboolean active_only) -{ - NMConnection *connection = (NMConnection *) data; - NmCli *nmc = (NmCli *) user_data; - NMSettingConnection *s_con; - guint64 timestamp; - time_t timestamp_real; - char *timestamp_str; - char *timestamp_real_str = ""; - NmcOutputField *arr; - NMActiveConnection *ac = NULL; - const char *ac_path = NULL; - const char *ac_state = NULL; - char *ac_dev = NULL; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - ac = get_ac_for_connection (nm_client_get_active_connections (nmc->client), connection); - if (active_only && !ac) - return; - - if (ac) { - ac_path = nm_object_get_path (NM_OBJECT (ac)); - ac_state = active_connection_state_to_string (nm_active_connection_get_state (ac)); - ac_dev = get_ac_device_string (ac); - } - - /* Obtain field values */ - timestamp = nm_setting_connection_get_timestamp (s_con); - timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp); - if (timestamp) { - timestamp_real = timestamp; - timestamp_real_str = g_malloc0 (64); - strftime (timestamp_real_str, 64, "%c", localtime (×tamp_real)); - } - - arr = nmc_dup_fields_array (nmc_fields_con_show, - sizeof (nmc_fields_con_show), - 0); - set_val_strc (arr, 0, nm_setting_connection_get_id (s_con)); - set_val_strc (arr, 1, nm_setting_connection_get_uuid (s_con)); - set_val_strc (arr, 2, nm_setting_connection_get_connection_type (s_con)); - set_val_str (arr, 3, timestamp_str); - set_val_str (arr, 4, timestamp ? timestamp_real_str : g_strdup (_("never"))); - set_val_strc (arr, 5, nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no")); - set_val_strc (arr, 6, nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no")); - set_val_strc (arr, 7, nm_connection_get_path (connection)); - set_val_strc (arr, 8, ac ? _("yes") : _("no")); - set_val_str (arr, 9, ac_dev); - set_val_strc (arr, 10, ac_state); - set_val_strc (arr, 11, ac_path); - - g_ptr_array_add (nmc->output_data, arr); -} - -static void -fill_output_active_connection (NMActiveConnection *active, - NmCli *nmc, - gboolean with_group, - guint32 o_flags) -{ - GSList *iter; - const char *active_path; - NMSettingConnection *s_con; - const GPtrArray *devices; - GString *dev_str; - NMActiveConnectionState state; - int i; - GSList *con_list = nmc->system_connections; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - int idx_start = with_group ? 0 : 1; - - active_path = nm_active_connection_get_connection (active); - state = nm_active_connection_get_state (active); - - /* 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); - const char *dev_iface = nm_device_get_iface (device); - - if (dev_iface) { - g_string_append (dev_str, dev_iface); - g_string_append_c (dev_str, ','); - } - } - if (dev_str->len > 0) - g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ - - tmpl = nmc_fields_con_active_details_general; - tmpl_len = sizeof (nmc_fields_con_active_details_general); - if (!with_group) { - tmpl++; - tmpl_len -= sizeof (NmcOutputField); - } - - /* Fill field values */ - arr = nmc_dup_fields_array (tmpl, tmpl_len, o_flags); - if (with_group) - set_val_strc (arr, 0, nmc_fields_con_active_details_groups[0].name); - set_val_strc (arr, 1-idx_start, _("N/A")); - set_val_strc (arr, 2-idx_start, nm_active_connection_get_uuid (active)); - set_val_str (arr, 3-idx_start, dev_str->str); - set_val_strc (arr, 4-idx_start, active_connection_state_to_string (state)); - set_val_strc (arr, 5-idx_start, nm_active_connection_get_default (active) ? _("yes") : _("no")); - set_val_strc (arr, 6-idx_start, nm_active_connection_get_default6 (active) ? _("yes") : _("no")); - set_val_strc (arr, 7-idx_start, nm_active_connection_get_specific_object (active)); - set_val_strc (arr, 8-idx_start, NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no")); - set_val_strc (arr, 9-idx_start, nm_object_get_path (NM_OBJECT (active))); - set_val_strc (arr, 10-idx_start, nm_active_connection_get_connection (active)); - set_val_strc (arr, 11-idx_start, _("N/A")); - set_val_strc (arr, 12-idx_start, nm_active_connection_get_master (active)); - - 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 = nm_connection_get_setting_connection (connection); - g_assert (s_con != NULL); - - /* Fill field values that depend on NMConnection */ - set_val_strc (arr, 1-idx_start, nm_setting_connection_get_id (s_con)); - set_val_strc (arr, 11-idx_start, nm_setting_connection_get_zone (s_con)); - - break; - } - } - g_ptr_array_add (nmc->output_data, arr); - - g_string_free (dev_str, FALSE); -} - -typedef struct { - char **array; - guint32 idx; -} FillVPNDataInfo; - -static void -fill_vpn_data_item (const char *key, const char *value, gpointer user_data) -{ - FillVPNDataInfo *info = (FillVPNDataInfo *) user_data; - - info->array[info->idx++] = g_strdup_printf ("%s = %s", key, value); -} - -// FIXME: The same or similar code for VPN info appears also in nm-applet (applet-dialogs.c), -// and in gnome-control-center as well. It could probably be shared somehow. -static char * -get_vpn_connection_type (NMConnection *connection) -{ - const char *type, *p; - - /* The service type is in form of "org.freedesktop.NetworkManager.vpnc". - * Extract end part after last dot, e.g. "vpnc" - */ - type = nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection)); - p = strrchr (type, '.'); - return g_strdup (p ? p + 1 : type); -} - -/* VPN parameters can be found at: - * http://git.gnome.org/browse/network-manager-openvpn/tree/src/nm-openvpn-service.h - * http://git.gnome.org/browse/network-manager-vpnc/tree/src/nm-vpnc-service.h - * http://git.gnome.org/browse/network-manager-pptp/tree/src/nm-pptp-service.h - * http://git.gnome.org/browse/network-manager-openconnect/tree/src/nm-openconnect-service.h - * http://git.gnome.org/browse/network-manager-openswan/tree/src/nm-openswan-service.h - * See also 'properties' directory in these plugins. - */ -static const gchar * -find_vpn_gateway_key (const char *vpn_type) -{ - if (g_strcmp0 (vpn_type, "openvpn") == 0) return "remote"; - if (g_strcmp0 (vpn_type, "vpnc") == 0) return "IPSec gateway"; - if (g_strcmp0 (vpn_type, "pptp") == 0) return "gateway"; - if (g_strcmp0 (vpn_type, "openconnect") == 0) return "gateway"; - if (g_strcmp0 (vpn_type, "openswan") == 0) return "right"; - if (g_strcmp0 (vpn_type, "libreswan") == 0) return "right"; - if (g_strcmp0 (vpn_type, "ssh") == 0) return "remote"; - if (g_strcmp0 (vpn_type, "l2tp") == 0) return "gateway"; - return ""; -} - -static const gchar * -find_vpn_username_key (const char *vpn_type) -{ - if (g_strcmp0 (vpn_type, "openvpn") == 0) return "username"; - if (g_strcmp0 (vpn_type, "vpnc") == 0) return "Xauth username"; - if (g_strcmp0 (vpn_type, "pptp") == 0) return "user"; - if (g_strcmp0 (vpn_type, "openconnect") == 0) return "username"; - if (g_strcmp0 (vpn_type, "openswan") == 0) return "leftxauthusername"; - if (g_strcmp0 (vpn_type, "libreswan") == 0) return "leftxauthusername"; - if (g_strcmp0 (vpn_type, "l2tp") == 0) return "user"; - return ""; -} - -enum VpnDataItem { - VPN_DATA_ITEM_GATEWAY, - VPN_DATA_ITEM_USERNAME -}; - -static const gchar * -get_vpn_data_item (NMConnection *connection, enum VpnDataItem vpn_data_item) -{ - const char *key; - char *type = get_vpn_connection_type (connection); - - switch (vpn_data_item) { - case VPN_DATA_ITEM_GATEWAY: - key = find_vpn_gateway_key (type); - break; - case VPN_DATA_ITEM_USERNAME: - key = find_vpn_username_key (type); - break; - default: - key = ""; - break; - } - g_free (type); - - return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (connection), key); -} -/* FIXME end */ - -static gboolean -nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) -{ - GError *error = NULL; - GArray *print_groups; - GPtrArray *group_fields = NULL; - int i; - char *fields_str; - char *fields_all = NMC_FIELDS_CON_ACTIVE_DETAILS_ALL; - char *fields_common = NMC_FIELDS_CON_ACTIVE_DETAILS_ALL; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - const char *base_hdr = _("Activate connection details"); - 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_groups = parse_output_fields (fields_str, nmc_fields_con_active_details_groups, TRUE, &group_fields, &error); - if (error) { - g_string_printf (nmc->return_text, _("Error: 'connection show': %s"), error->message); - g_error_free (error); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - g_assert (print_groups); - - /* Main header */ - nmc->print_fields.header_name = (char *) construct_header_name (base_hdr, nm_active_connection_get_uuid (acon)); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_ALL, - nmc_fields_con_active_details_groups, FALSE, NULL, NULL); - - nmc_fields_con_active_details_groups[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; - print_required_fields (nmc, nmc_fields_con_active_details_groups); - - /* Loop through the groups and print them. */ - for (i = 0; i < print_groups->len; i++) { - int group_idx = g_array_index (print_groups, int, i); - char *group_fld = (char *) g_ptr_array_index (group_fields, i); - - if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output) - printf ("\n"); /* Empty line */ - - was_output = FALSE; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - /* GENERAL */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[0].name) == 0) { - /* Add field names */ - tmpl = nmc_fields_con_active_details_general; - tmpl_len = sizeof (nmc_fields_con_active_details_general); - nmc->print_fields.indices = parse_output_fields (group_fld ? group_fld : NMC_FIELDS_CON_ACTIVE_DETAILS_GENERAL_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* Fill in values */ - fill_output_active_connection (acon, nmc, TRUE, NMC_OF_FLAG_SECTION_PREFIX); - - print_data (nmc); /* Print all data */ - - was_output = TRUE; - } - - /* IP4 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[1].name) == 0) { - gboolean b1 = FALSE; - NMIP4Config *cfg4 = nm_active_connection_get_ip4_config (acon); - - b1 = print_ip4_config (cfg4, nmc, "IP4", group_fld); - was_output = was_output || b1; - } - - /* DHCP4 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[2].name) == 0) { - gboolean b1 = FALSE; - NMDHCP4Config *dhcp4 = nm_active_connection_get_dhcp4_config (acon); - - b1 = print_dhcp4_config (dhcp4, nmc, "DHCP4", group_fld); - was_output = was_output || b1; - } - - /* IP6 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[3].name) == 0) { - gboolean b1 = FALSE; - NMIP6Config *cfg6 = nm_active_connection_get_ip6_config (acon); - - b1 = print_ip6_config (cfg6, nmc, "IP6", group_fld); - was_output = was_output || b1; - } - - /* DHCP6 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[4].name) == 0) { - gboolean b1 = FALSE; - NMDHCP6Config *dhcp6 = nm_active_connection_get_dhcp6_config (acon); - - b1 = print_dhcp6_config (dhcp6, nmc, "DHCP6", group_fld); - was_output = was_output || b1; - } - - /* VPN */ - if (NM_IS_VPN_CONNECTION (acon) && - strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[5].name) == 0) { - NMConnection *con; - NMSettingConnection *s_con; - NMSettingVPN *s_vpn; - NMVPNConnectionState vpn_state; - char *type_str, *banner_str, *vpn_state_str; - const char *username = NULL; - char **vpn_data_array = NULL; - guint32 items_num; - - con = get_connection_for_active (nmc->system_connections, acon); - - s_con = nm_connection_get_setting_connection (con); - g_assert (s_con != NULL); - - tmpl = nmc_fields_con_active_details_vpn; - tmpl_len = sizeof (nmc_fields_con_active_details_vpn); - nmc->print_fields.indices = parse_output_fields (group_fld ? group_fld : NMC_FIELDS_CON_ACTIVE_DETAILS_VPN_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - s_vpn = nm_connection_get_setting_vpn (con); - if (s_vpn) { - items_num = nm_setting_vpn_get_num_data_items (s_vpn); - if (items_num > 0) { - FillVPNDataInfo info; - - vpn_data_array = g_new (char *, items_num + 1); - info.array = vpn_data_array; - info.idx = 0; - nm_setting_vpn_foreach_data_item (s_vpn, &fill_vpn_data_item, &info); - vpn_data_array[items_num] = NULL; - } - username = nm_setting_vpn_get_user_name (s_vpn); - } - - type_str = get_vpn_connection_type (con); - banner_str = g_strescape (nm_vpn_connection_get_banner (NM_VPN_CONNECTION (acon)), ""); - vpn_state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (acon)); - vpn_state_str = g_strdup_printf ("%d - %s", vpn_state, vpn_connection_state_to_string (vpn_state)); - - /* Add values */ - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, nmc_fields_con_active_details_groups[5].name); - set_val_str (arr, 1, type_str); - set_val_strc (arr, 2, username ? username : get_vpn_data_item (con, VPN_DATA_ITEM_USERNAME)); - set_val_strc (arr, 3, get_vpn_data_item (con, VPN_DATA_ITEM_GATEWAY)); - set_val_str (arr, 4, banner_str); - set_val_str (arr, 5, vpn_state_str); - set_val_arr (arr, 6, vpn_data_array); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - was_output = TRUE; - } - } - - g_array_free (print_groups, TRUE); - if (group_fields) - g_ptr_array_free (group_fields, TRUE); - - return TRUE; -} - -static gboolean -split_required_fields_for_con_show (const char *input, - char **profile_flds, - char **active_flds, - GError **error) -{ - char **fields, **iter; - char *dot; - GString *str1, *str2; - gboolean found; - gboolean group_profile = FALSE; - gboolean group_active = FALSE; - gboolean success = TRUE; - gboolean is_all, is_common; - int i; - - if (!input) { - *profile_flds = NULL; - *active_flds = NULL; - return TRUE; - } - - str1 = g_string_new (NULL); - str2 = g_string_new (NULL); - - /* Split supplied fields string */ - fields = g_strsplit_set (input, ",", -1); - for (iter = fields; iter && *iter; iter++) { - g_strstrip (*iter); - dot = strchr (*iter, '.'); - if (dot) - *dot = '\0'; - - is_all = !dot && strcasecmp (*iter, "all") == 0; - is_common = !dot && strcasecmp (*iter, "common") == 0; - - found = FALSE; - - for (i = 0; nmc_fields_settings_names[i].name; i++) { - if ( is_all || is_common - || !strcasecmp (*iter, nmc_fields_settings_names[i].name)) { - if (dot) - *dot = '.'; - g_string_append (str1, *iter); - g_string_append_c (str1, ','); - found = TRUE; - break; - } - } - if (found) - continue; - for (i = 0; nmc_fields_con_active_details_groups[i].name; i++) { - if ( is_all || is_common - || !strcasecmp (*iter, nmc_fields_con_active_details_groups[i].name)) { - if (dot) - *dot = '.'; - g_string_append (str2, *iter); - g_string_append_c (str2, ','); - found = TRUE; - break; - } - } - if (!found) { - if (dot) - *dot = '.'; - if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_PROFILE)) - group_profile = TRUE; - else if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_ACTIVE)) - group_active = TRUE; - else { - char *allowed1 = nmc_get_allowed_fields (nmc_fields_settings_names, -1); - char *allowed2 = nmc_get_allowed_fields (nmc_fields_con_active_details_groups, -1); - g_set_error (error, NMCLI_ERROR, 0, _("invalid field '%s'; allowed fields: %s and %s, or %s,%s"), - *iter, allowed1, allowed2, CON_SHOW_DETAIL_GROUP_PROFILE, CON_SHOW_DETAIL_GROUP_ACTIVE); - g_free (allowed1); - g_free (allowed2); - success = FALSE; - break; - } - } - } - if (fields) - g_strfreev (fields); - - /* Handle pseudo groups: profile, active */ - if (success && group_profile) { - if (str1->len > 0) { - g_set_error (error, NMCLI_ERROR, 0, _("'%s' has to be alone"), - CON_SHOW_DETAIL_GROUP_PROFILE); - success = FALSE; - } else - g_string_assign (str1, "all,"); - } - if (success && group_active) { - if (str2->len > 0) { - g_set_error (error, NMCLI_ERROR, 0, _("'%s' has to be alone"), - CON_SHOW_DETAIL_GROUP_ACTIVE); - success = FALSE; - } else - g_string_assign (str2, "all,"); - } - - if (success) { - if (str1->len > 0) - g_string_truncate (str1, str1->len - 1); - if (str2->len > 0) - g_string_truncate (str2, str2->len - 1); - *profile_flds = g_string_free (str1, str1->len == 0); - *active_flds = g_string_free (str2, str2->len == 0); - } else { - g_string_free (str1, TRUE); - g_string_free (str2, TRUE); - } - return success; -} - -static NMCResultCode -do_connections_show (NmCli *nmc, gboolean active_only, int argc, char **argv) -{ - GError *err = NULL; - char *profile_flds = NULL, *active_flds = NULL; - - nmc->should_wait = FALSE; - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto finish; - } - - if (argc == 0) { - char *fields_str; - char *fields_all = NMC_FIELDS_CON_SHOW_ALL; - char *fields_common = NMC_FIELDS_CON_SHOW_COMMON; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - GSList *iter; - - 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; - - tmpl = nmc_fields_con_show; - tmpl_len = sizeof (nmc_fields_con_show); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &err); - if (err) { - goto finish; - } - if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &err)) - goto finish; - - /* Add headers */ - nmc->print_fields.header_name = active_only ? _("NetworkManager active profiles") : - _("NetworkManager connection profiles"); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* Add values */ - for (iter = nmc->system_connections; iter; iter = g_slist_next (iter)) { - NMConnection *con = NM_CONNECTION (iter->data); - fill_output_connection (con, nmc, active_only); - } - print_data (nmc); /* Print all data */ - } else { - gboolean new_line = FALSE; - gboolean without_fields = (nmc->required_fields == NULL); - const GPtrArray *active_cons = nm_client_get_active_connections (nmc->client); - GSList *pos = NULL; - - /* multiline mode is default for 'connection show ' */ - if (!nmc->mode_specified) - nmc->multiline_output = TRUE; - - /* Split required fields into the settings and active ones. */ - if (!split_required_fields_for_con_show (nmc->required_fields, &profile_flds, &active_flds, &err)) - goto finish; - g_free (nmc->required_fields); - nmc->required_fields = NULL; - - while (argc > 0) { - NMConnection *con; - NMActiveConnection *acon = NULL; - const char *selector = NULL; - - if ( strcmp (*argv, "id") == 0 - || strcmp (*argv, "uuid") == 0 - || strcmp (*argv, "path") == 0 - || strcmp (*argv, "apath") == 0) { - selector = *argv; - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; - } - } - - /* Find connection by id, uuid, path or apath */ - con = nmc_find_connection (nmc->system_connections, selector, *argv, &pos); - if (!con) { - acon = find_active_connection (active_cons, nmc->system_connections, selector, *argv, NULL); - if (acon) - con = get_connection_for_active (nmc->system_connections, acon); - } - - /* Print connection details */ - if (con) { - gboolean res; - - /* Filter only active connections */ - if (!acon) - acon = get_ac_for_connection (active_cons, con); - if (active_only && !acon) { - next_arg (&argc, &argv); - continue; - } - - /* Show an empty line between connections */ - if (new_line) - printf ("\n"); - - /* Show profile configuration */ - if (without_fields || profile_flds) { - nmc->required_fields = profile_flds; - res = nmc_connection_profile_details (con, nmc); - nmc->required_fields = NULL; - if (!res) - goto finish; - } - - /* If the profile is active, print also active details */ - if (without_fields || active_flds) { - if (acon) { - nmc->required_fields = active_flds; - res = nmc_active_connection_details (acon, nmc); - nmc->required_fields = NULL; - if (!res) - goto finish; - } - } - new_line = TRUE; - } else { - g_string_printf (nmc->return_text, _("Error: %s - no such connection profile."), *argv); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto finish; - } - - /* Take next argument. - * But for pos != NULL we have more connections of the same name, - * so process the same argument again. - */ - if (!pos) - next_arg (&argc, &argv); - } - } - -finish: - if (err) { - g_string_printf (nmc->return_text, _("Error: %s."), err->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_error_free (err); - } - g_free (profile_flds); - g_free (active_flds); - return nmc->return_value; -} - -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) - * nsp: Network Service Provider to use (option; valid only for wimax) - * 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, - const char *nsp, - 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 = nm_connection_get_setting_connection (connection); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - - if (strcmp (con_type, NM_SETTING_VPN_SETTING_NAME) == 0) { - /* VPN connections */ - NMActiveConnection *active = NULL; - if (iface) { - *device = nm_client_get_device_by_iface (nmc->client, iface); - if (*device) - active = nm_device_get_active_connection (*device); - - if (!active) { - g_set_error (error, NMCLI_ERROR, 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_literal (error, NMCLI_ERROR, 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 ( !g_strcmp0 (dev_iface, iface) - && nm_device_connection_compatible (dev, connection, NULL)) { - found_device = dev; - } - } else { - if (nm_device_connection_compatible (dev, connection, NULL)) { - found_device = dev; - } - } - - if (found_device && ap && !strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME) && NM_IS_DEVICE_WIFI (dev)) { - char *bssid_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_bssid = nm_access_point_get_bssid (candidate_ap); - - if (!strcmp (bssid_up, candidate_bssid)) { - found_device = dev; - *spec_object = nm_object_get_path (NM_OBJECT (candidate_ap)); - break; - } - } - g_free (bssid_up); - } - -#if WITH_WIMAX - if ( found_device - && nsp - && !strcmp (con_type, NM_SETTING_WIMAX_SETTING_NAME) - && NM_IS_DEVICE_WIMAX (dev)) { - const GPtrArray *nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (dev)); - found_device = NULL; /* Mark as not found; set to the device again later, only if NSP matches */ - - for (j = 0; nsps && (j < nsps->len); j++) { - NMWimaxNsp *candidate_nsp = g_ptr_array_index (nsps, j); - const char *candidate_name = nm_wimax_nsp_get_name (candidate_nsp); - - if (!strcmp (nsp, candidate_name)) { - found_device = dev; - *spec_object = nm_object_get_path (NM_OBJECT (candidate_nsp)); - break; - } - } - } -#endif - } - - if (found_device) { - *device = found_device; - return TRUE; - } else { - if (iface) - g_set_error (error, NMCLI_ERROR, 0, _("device '%s' not compatible with connection '%s'"), - iface, nm_setting_connection_get_id (s_con)); - else - g_set_error (error, NMCLI_ERROR, 0, _("no device found for connection '%s'"), - nm_setting_connection_get_id (s_con)); - return FALSE; - } - } -} - -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); - - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - if (nmc->print_output == NMC_PRINT_PRETTY) - nmc_terminal_erase_line (); - printf (_("Connection successfully activated (D-Bus active path: %s)\n"), - nm_object_get_path (NM_OBJECT (active))); - quit (); - } else if ( state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED - || 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: - /* no operation */ - break; - - case NM_VPN_CONNECTION_STATE_ACTIVATED: - if (nmc->print_output == NMC_PRINT_PRETTY) - nmc_terminal_erase_line (); - printf (_("VPN connection successfully activated (D-Bus active path: %s)\n"), - nm_object_get_path (NM_OBJECT (vpn))); - 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 gboolean -progress_cb (gpointer user_data) -{ - const char *str = (const char *) user_data; - - nmc_terminal_show_progress (str); - - return TRUE; -} - -static gboolean -progress_device_cb (gpointer user_data) -{ - NMDevice *device = (NMDevice *) user_data; - - nmc_terminal_show_progress (device ? nmc_device_state_to_string (nm_device_get_state (device)) : ""); - - return TRUE; -} - -static gboolean -progress_vpn_cb (gpointer user_data) -{ - NMVPNConnection *vpn = (NMVPNConnection *) user_data; - const char *str; - - str = NM_IS_VPN_CONNECTION (vpn) ? - vpn_connection_state_to_string (nm_vpn_connection_get_vpn_state (vpn)) : - ""; - - nmc_terminal_show_progress (str); - - return TRUE; -} - -typedef struct { - NmCli *nmc; - NMDevice *device; -} ActivateConnectionInfo; - -static gboolean -master_iface_slaves_check (gpointer user_data) -{ - ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; - NmCli *nmc = info->nmc; - NMDevice *device = info->device; - const GPtrArray *slaves = NULL; - - if (NM_IS_DEVICE_BOND (device)) - slaves = nm_device_bond_get_slaves (NM_DEVICE_BOND (device)); - else if (NM_IS_DEVICE_TEAM (device)) - slaves = nm_device_team_get_slaves (NM_DEVICE_TEAM (device)); - else if (NM_IS_DEVICE_BRIDGE (device)) - slaves = nm_device_bridge_get_slaves (NM_DEVICE_BRIDGE (device)); - else - g_warning ("%s: should not be reached.", __func__); - - if (!slaves) { - g_string_printf (nmc->return_text, - _("Error: Device '%s' is waiting for slaves before proceeding with activation."), - nm_device_get_iface (device)); - nmc->return_value = NMC_RESULT_ERROR_TIMEOUT_EXPIRED; - quit (); - } - - g_free (info); - return FALSE; -} - -static void -activate_connection_cb (NMClient *client, NMActiveConnection *active, GError *error, gpointer user_data) -{ - ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; - NmCli *nmc = info->nmc; - NMDevice *device = info->device; - NMActiveConnectionState state; - const GPtrArray *ac_devs; - - if (error) { - g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s"), error->message); - nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; - quit (); - } else { - state = nm_active_connection_get_state (active); - if (!device) { - /* device could be NULL for virtual devices. Fill it here. */ - ac_devs = nm_active_connection_get_devices (active); - info->device = device = ac_devs && ac_devs->len > 0 ? g_ptr_array_index (ac_devs, 0) : NULL; - } - - if (nmc->nowait_flag || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - /* User doesn't want to wait or already activated */ - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - if (nmc->print_output == NMC_PRINT_PRETTY) - nmc_terminal_erase_line (); - printf (_("Connection successfully activated (D-Bus active path: %s)\n"), - nm_object_get_path (NM_OBJECT (active))); - } - quit (); - } else { - if (NM_IS_VPN_CONNECTION (active)) { - /* Monitor VPN state */ - g_signal_connect (G_OBJECT (active), "vpn-state-changed", G_CALLBACK (vpn_connection_state_cb), nmc); - - /* Start progress indication showing VPN states */ - if (nmc->print_output == NMC_PRINT_PRETTY) { - if (progress_id) - g_source_remove (progress_id); - progress_id = g_timeout_add (120, progress_vpn_cb, NM_VPN_CONNECTION (active)); - } - } else { - g_signal_connect (active, "notify::state", G_CALLBACK (active_connection_state_cb), nmc); - - /* Start progress indication showing device states */ - if (nmc->print_output == NMC_PRINT_PRETTY) { - if (progress_id) - g_source_remove (progress_id); - progress_id = g_timeout_add (120, progress_device_cb, device); - } - } - - /* Start timer not to loop forever when signals are not emitted */ - g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc); - - /* Check for bond or team or bridge slaves */ - if ( NM_IS_DEVICE_BOND (device) - || NM_IS_DEVICE_TEAM (device) - || NM_IS_DEVICE_BRIDGE (device)) { - g_timeout_add_seconds (SLAVES_UP_TIMEOUT, master_iface_slaves_check, info); - return; /* info will be freed in master_iface_slaves_check () */ - } - } - } - g_free (info); -} - -/* We were using nm_connection_get_virtual_iface_name() to determine whether the - * connection is virtual or not. But it did't work for VLANs without - * vlan.interface-name. nm_connection_get_virtual_iface_name() returns NULL for those. - * So we need to use our own implementation for now. - */ -static gboolean -is_connection_virtual (NMConnection *connection) -{ - if ( nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) - return TRUE; - if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { - NMSettingInfiniband *s_infi = nm_connection_get_setting_infiniband (connection); - int p_key = nm_setting_infiniband_get_p_key (s_infi); - const char *parent = nm_setting_infiniband_get_parent (s_infi); - - if (p_key != -1 && parent) - return TRUE; - } - return FALSE; -} - -static gboolean -nmc_activate_connection (NmCli *nmc, - NMConnection *connection, - const char *ifname, - const char *ap, - const char *nsp, - NMClientActivateFn callback, - GError **error) -{ - ActivateConnectionInfo *info; - NMDevice *device = NULL; - const char *spec_object = NULL; - gboolean device_found; - GError *local = NULL; - - g_return_val_if_fail (nmc != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (connection) { - device_found = find_device_for_connection (nmc, connection, ifname, ap, nsp, &device, &spec_object, &local); - - /* Virtual connection may not have their interfaces created yet */ - if (!device_found && !is_connection_virtual (connection)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_CON_ACTIVATION, - "%s", local && local->message ? local->message : _("unknown error")); - g_clear_error (&local); - return FALSE; - } - } else if (ifname) { - device = nm_client_get_device_by_iface (nmc->client, ifname); - if (!device) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_NOT_FOUND, - _("unknown device '%s'."), ifname); - return FALSE; - } - } else { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_NOT_FOUND, - _("neither a valid connection nor device given")); - return FALSE; - } - - info = g_malloc0 (sizeof (ActivateConnectionInfo)); - info->nmc = nmc; - info->device = device; - - nm_client_activate_connection (nmc->client, - connection, - device, - spec_object, - callback, - info); - return TRUE; -} - -static NMCResultCode -do_connection_up (NmCli *nmc, int argc, char **argv) -{ - NMConnection *connection = NULL; - const char *ifname = NULL; - const char *ap = NULL; - const char *nsp = NULL; - GError *error = NULL; - const char *selector = NULL; - const char *name = NULL; - char *line = NULL; - - /* - * Set default timeout for connection activation. - * Activation can take quite a long time, use 90 seconds. - */ - if (nmc->timeout == -1) - nmc->timeout = 90; - - if (argc == 0) { - if (nmc->ask) { - line = nmc_readline (PROMPT_CONNECTION); - name = line ? line : ""; - } - } else if (strcmp (*argv, "ifname") != 0) { - if ( strcmp (*argv, "id") == 0 - || strcmp (*argv, "uuid") == 0 - || strcmp (*argv, "path") == 0) { - - selector = *argv; - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), selector); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - name = *argv; - } - name = *argv; - next_arg (&argc, &argv); - } - - if (name) - connection = nmc_find_connection (nmc->system_connections, selector, name, NULL); - - while (argc > 0) { - if (strcmp (*argv, "ifname") == 0) { - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - - ifname = *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-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - - ap = *argv; - } -#if WITH_WIMAX - else if (strcmp (*argv, "nsp") == 0) { - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - - nsp = *argv; - } -#endif - else { - fprintf (stderr, _("Unknown parameter: %s\n"), *argv); - } - - argc--; - argv++; - } - - /* create NMClient */ - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto error; - } - - /* Use nowait_flag instead of should_wait because exiting has to be postponed till - * active_connection_state_cb() is called. That gives NM time to check our permissions - * and we can follow activation progress. - */ - nmc->nowait_flag = (nmc->timeout == 0); - nmc->should_wait = TRUE; - - if (!nmc_activate_connection (nmc, connection, ifname, ap, nsp, activate_connection_cb, &error)) { - g_string_printf (nmc->return_text, _("Error: %s."), - error ? error->message : _("unknown error")); - nmc->return_value = error ? error->code : NMC_RESULT_ERROR_CON_ACTIVATION; - g_clear_error (&error); - goto error; - } - - /* Start progress indication */ - if (nmc->print_output == NMC_PRINT_PRETTY) - progress_id = g_timeout_add (120, progress_cb, _("preparing")); - - g_free (line); - return nmc->return_value; -error: - nmc->should_wait = FALSE; - g_free (line); - return nmc->return_value; -} - -static NMCResultCode -do_connection_down (NmCli *nmc, int argc, char **argv) -{ - NMActiveConnection *active; - const GPtrArray *active_cons; - char *line = NULL; - char **arg_arr = NULL; - char **arg_ptr = argv; - int arg_num = argc; - int idx = 0; - - if (argc == 0) { - if (nmc->ask) { - line = nmc_readline (PROMPT_CONNECTION); - nmc_string_to_arg_array (line, "", &arg_arr, &arg_num); - arg_ptr = arg_arr; - } - if (arg_num == 0) { - g_string_printf (nmc->return_text, _("Error: No connection specified.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - } - - /* create NMClient */ - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto error; - } - - /* Get active connections */ - active_cons = nm_client_get_active_connections (nmc->client); - while (arg_num > 0) { - const char *selector = NULL; - - if ( strcmp (*arg_ptr, "id") == 0 - || strcmp (*arg_ptr, "uuid") == 0 - || strcmp (*arg_ptr, "path") == 0 - || strcmp (*arg_ptr, "apath") == 0) { - - selector = *arg_ptr; - if (next_arg (&arg_num, &arg_ptr) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), selector); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - } - - active = find_active_connection (active_cons, nmc->system_connections, selector, *arg_ptr, &idx); - if (active) { - nm_client_deactivate_connection (nmc->client, active); - } else { - g_string_printf (nmc->return_text, _("Error: '%s' is not an active connection."), *arg_ptr); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto error; - } - - if (idx == 0) - next_arg (&arg_num, &arg_ptr); - } - - // FIXME: do something better then sleep() - /* Don't quit immediatelly and give NM time to check our permissions */ - sleep (1); - -error: - nmc->should_wait = FALSE; - g_strfreev (arg_arr); - return nmc->return_value; -} - -/*----------------------------------------------------------------------------*/ - -typedef struct NameItem { - const char *name; - const char *alias; - const struct NameItem *settings; - gboolean mandatory; -} NameItem; - -static const NameItem nmc_generic_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_ethernet_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_DCB_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_infiniband_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_wifi_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", NULL, TRUE }, - { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-sec", NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_wimax_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIMAX_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_gsm_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_GSM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_cdma_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_mobile_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_GSM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bluetooth_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_adsl_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_ADSL_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -/* PPPoE is a base connection type from historical reasons. - * See libnm-util/nm-setting.c:_nm_setting_is_base_type() - */ -static const NameItem nmc_pppoe_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_PPPOE_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_olpc_mesh_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_vpn_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_VPN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_vlan_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_VLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bond_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BOND_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_team_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_TEAM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bridge_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BRIDGE_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bond_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_team_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_TEAM_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bridge_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - - -/* Available connection types */ -static const NameItem nmc_valid_connection_types[] = { - { NM_SETTING_GENERIC_SETTING_NAME, NULL, nmc_generic_settings }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", nmc_ethernet_settings }, - { NM_SETTING_PPPOE_SETTING_NAME, NULL, nmc_pppoe_settings }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", nmc_wifi_settings }, - { NM_SETTING_WIMAX_SETTING_NAME, NULL, nmc_wimax_settings }, - { NM_SETTING_GSM_SETTING_NAME, NULL, nmc_gsm_settings }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, nmc_cdma_settings }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, nmc_infiniband_settings }, - { NM_SETTING_ADSL_SETTING_NAME, NULL, nmc_adsl_settings }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, nmc_bluetooth_settings }, - { NM_SETTING_VPN_SETTING_NAME, NULL, nmc_vpn_settings }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", nmc_olpc_mesh_settings }, - { NM_SETTING_VLAN_SETTING_NAME, NULL, nmc_vlan_settings }, - { NM_SETTING_BOND_SETTING_NAME, NULL, nmc_bond_settings }, - { NM_SETTING_TEAM_SETTING_NAME, NULL, nmc_team_settings }, - { NM_SETTING_BRIDGE_SETTING_NAME, NULL, nmc_bridge_settings }, - { "bond-slave", NULL, nmc_bond_slave_settings }, - { "team-slave", NULL, nmc_team_slave_settings }, - { "bridge-slave", NULL, nmc_bridge_slave_settings }, - { NULL, NULL, NULL } -}; - -/* - * Return an alias for the 'name' if exists, else return the 'name'. - * The returned string must not be freed. - */ -static const char * -get_name_alias (const char *name, const NameItem array[]) -{ - const NameItem *iter = &array[0]; - - if (!name) - return NULL; - - while (iter && iter->name) { - if (!strcmp (name, iter->name)) { - if (iter->alias) - return iter->alias; - else - return iter->name; - } - iter++; - } - return name; -} - -/* - * Construct a string with names and aliases from the array formatted as: - * "name (alias), name, name (alias), name, name" - * - * Returns: string; the caller is responsible for freeing it. - */ -static char * -get_valid_options_string (const NameItem array[]) -{ - const NameItem *iter = &array[0]; - GString *str; - - str = g_string_sized_new (150); - while (iter && iter->name) { - if (str->len) - g_string_append (str, ", "); - if (iter->alias) - g_string_append_printf (str, "%s (%s)", iter->name, iter->alias); - else - g_string_append (str, iter->name); - iter++; - } - return g_string_free (str, FALSE); -} - -/* - * Check if 'val' is valid string in either array->name or array->alias. - * It accepts shorter string provided they are not ambiguous. - * 'val' == NULL doesn't hurt. - * - * Returns: pointer to array->name string or NULL on failure. - * The returned string must not be freed. - */ -static const char * -check_valid_name (const char *val, const NameItem array[], GError **error) -{ - const NameItem *iter; - GPtrArray *tmp_arr; - const char *str; - GError *tmp_err = NULL; - - /* Create a temporary array that can be used in nmc_string_is_valid() */ - tmp_arr = g_ptr_array_sized_new (30); - iter = &array[0]; - while (iter && iter->name) { - g_ptr_array_add (tmp_arr, (gpointer) iter->name); - if (iter->alias) - g_ptr_array_add (tmp_arr, (gpointer) iter->alias); - iter++; - } - g_ptr_array_add (tmp_arr, (gpointer) NULL); - - /* Check string validity */ - str = nmc_string_is_valid (val, (const char **) tmp_arr->pdata, &tmp_err); - if (!str) { - if (tmp_err->code == 1) - g_propagate_error (error, tmp_err); - else { - /* We want to handle aliases, so construct own error message */ - char *err_str = get_valid_options_string (array); - g_set_error (error, 1, 0, _("'%s' not among [%s]"), - val ? val : "", err_str); - g_free (err_str); - g_clear_error (&tmp_err); - } - g_ptr_array_free (tmp_arr, TRUE); - return NULL; - } - - /* Return a pointer to the found string in passed 'array' */ - iter = &array[0]; - while (iter && iter->name) { - if ( (iter->name && g_strcmp0 (iter->name, str) == 0) - || (iter->alias && g_strcmp0 (iter->alias, str) == 0)) { - g_ptr_array_free (tmp_arr, TRUE); - return iter->name; - } - iter++; - } - /* We should not really come here */ - g_ptr_array_free (tmp_arr, TRUE); - g_set_error (error, 1, 0, _("Unknown error")); - return NULL; -} - -static const NameItem * -get_valid_settings_array (const char *con_type) -{ - guint i, num; - - if (!con_type) - return NULL; - - num = G_N_ELEMENTS (nmc_valid_connection_types); - for (i = 0; i < num; i++) { - if (!g_strcmp0 (con_type, nmc_valid_connection_types[i].name)) - return nmc_valid_connection_types[i].settings; - } - return NULL; -} - -static gboolean -is_setting_mandatory (NMConnection *connection, NMSetting *setting) -{ - NMSettingConnection *s_con; - const char *c_type; - const NameItem *item; - const char *name; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - c_type = nm_setting_connection_get_connection_type (s_con); - - name = nm_setting_get_name (setting); - - item = get_valid_settings_array (c_type); - while (item && item->name) { - if (!strcmp (name, item->name)) - return item->mandatory; - item++; - } - return FALSE; -} - -/*----------------------------------------------------------------------------*/ - -static gboolean -check_and_convert_mac (const char *mac, - GByteArray **mac_array, - int type, - const char *keyword, - GError **error) -{ - GByteArray *local_mac_array = NULL; - g_return_val_if_fail (mac_array == NULL || *mac_array == NULL, FALSE); - - if (!mac) - return TRUE; - - local_mac_array = nm_utils_hwaddr_atoba (mac, type); - if (!local_mac_array) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s': '%s' is not a valid %s MAC address."), - keyword, mac, type == ARPHRD_INFINIBAND ? _("InfiniBand") : _("Ethernet")); - return FALSE; - } - - if (mac_array) - *mac_array = local_mac_array; - else - if (local_mac_array) - g_byte_array_free (local_mac_array, TRUE); - - return TRUE; -} - -static gboolean -check_and_convert_mtu (const char *mtu, guint32 *mtu_int, GError **error) -{ - unsigned long local_mtu_int; - - if (!mtu) - return TRUE; - - if (!nmc_string_to_uint (mtu, TRUE, 0, G_MAXUINT32, &local_mtu_int)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mtu': '%s' is not a valid MTU."), mtu); - return FALSE; - } - if (mtu_int) - *mtu_int = (guint32) local_mtu_int; - return TRUE; -} - -static gboolean -check_infiniband_parent (const char *parent, GError **error) -{ - if (!parent) - return TRUE; - - if (!nm_utils_iface_valid_name (parent)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'parent': '%s' is not a valid interface name."), parent); - return FALSE; - } - return TRUE; -} - - -static gboolean -check_infiniband_p_key (const char *p_key, guint32 *p_key_int, GError **error) -{ - unsigned long local_p_key_int; - gboolean p_key_valid = FALSE; - if (!p_key) - return TRUE; - - if (!strncmp (p_key, "0x", 2)) - p_key_valid = nmc_string_to_uint_base (p_key + 2, 16, TRUE, 0, G_MAXUINT16, &local_p_key_int); - else - p_key_valid = nmc_string_to_uint (p_key, TRUE, 0, G_MAXUINT16, &local_p_key_int); - if (!p_key_valid) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'p-key': '%s' is not a valid InfiniBand P_KEY."), p_key); - return FALSE; - } - if (p_key_int) - *p_key_int = (guint32) local_p_key_int; - return TRUE; -} - -/* Checks InfiniBand mode. - * It accepts shortcuts and normalizes them ('mode' argument is modified on success). - */ -static gboolean -check_infiniband_mode (char **mode, GError **error) -{ - char *tmp; - const char *checked_mode; - const char *modes[] = { "datagram", "connected", NULL }; - - if (!mode || !*mode) - return TRUE; - - tmp = g_strstrip (g_strdup (*mode)); - checked_mode = nmc_string_is_valid (tmp, modes, NULL); - g_free (tmp); - if (checked_mode) { - g_free (*mode); - *mode = g_strdup (checked_mode); - } else - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mode': '%s' is not a valid InfiniBand transport mode [datagram, connected]."), *mode); - return !!checked_mode; -} - -static gboolean -check_and_convert_vlan_flags (const char *flags, guint32 *flags_int, GError **error) -{ - unsigned long local_flags_int; - - if (!flags) - return TRUE; - - if (!nmc_string_to_uint (flags, TRUE, 0, 7, &local_flags_int)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'flags': '%s' is not valid; use <0-7>."), flags); - return FALSE; - } - if (flags_int) - *flags_int = (guint32) local_flags_int; - return TRUE; -} - -static gboolean -check_and_convert_vlan_prio_maps (const char *prio_map, - NMVlanPriorityMap type, - char ***prio_map_arr, - GError **error) -{ - char **local_prio_map_arr; - GError *local_err = NULL; - - if (!prio_map) - return TRUE; - - if (!(local_prio_map_arr = nmc_vlan_parse_priority_maps (prio_map, type, &local_err))) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s': '%s' is not valid; %s "), - type == NM_VLAN_INGRESS_MAP ? "ingress" : "egress", - prio_map, local_err->message); - return FALSE; - } - - if (prio_map_arr) - *prio_map_arr = local_prio_map_arr; - return TRUE; -} - -static gboolean -add_ip4_address_to_connection (NMIP4Address *ip4addr, NMConnection *connection) -{ - NMSettingIP4Config *s_ip4; - gboolean ret; - - if (!ip4addr) - return TRUE; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) { - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NULL); - } - ret = nm_setting_ip4_config_add_address (s_ip4, ip4addr); - nm_ip4_address_unref (ip4addr); - - return ret; -} - -static gboolean -add_ip6_address_to_connection (NMIP6Address *ip6addr, NMConnection *connection) -{ - NMSettingIP6Config *s_ip6; - gboolean ret; - - if (!ip6addr) - return TRUE; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!s_ip6) { - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NULL); - } - ret = nm_setting_ip6_config_add_address (s_ip6, ip6addr); - nm_ip6_address_unref (ip6addr); - - return ret; -} - -static char * -unique_master_iface_ifname (GSList *list, - const char *type, - const char *ifname_property, - const char *try_name) -{ - NMConnection *connection; - NMSetting *setting; - char *new_name; - unsigned int num = 1; - GSList *iterator = list; - char *ifname_val = NULL; - - new_name = g_strdup (try_name); - while (iterator) { - connection = NM_CONNECTION (iterator->data); - setting = nm_connection_get_setting_by_name (connection, type); - if (!setting) { - iterator = g_slist_next (iterator); - continue; - } - - g_object_get (setting, ifname_property, &ifname_val, NULL); - if (g_strcmp0 (new_name, ifname_val) == 0) { - g_free (new_name); - new_name = g_strdup_printf ("%s%d", try_name, num++); - iterator = list; - } else - iterator = g_slist_next (iterator); - g_free (ifname_val); - } - return new_name; -} - -static const char * -_strip_master_prefix (const char *master, const char *(**func)(NMConnection *)) -{ - if (!master) - return NULL; - - if (g_str_has_prefix (master, "ifname/")) { - master = master + strlen ("ifname/"); - if (func) - *func = nm_connection_get_virtual_iface_name; - } else if (g_str_has_prefix (master, "uuid/")) { - master = master + strlen ("uuid/"); - if (func) - *func = nm_connection_get_uuid; - } else if (g_str_has_prefix (master, "id/")) { - master = master + strlen ("id/"); - if (func) - *func = nm_connection_get_id; - } - return master; -} - -/* verify_master_for_slave: - * @connections: list af all connections - * @master: UUID, ifname or ID of the master connection - * @type: virtual connection type (bond, team, bridge, ...) - * - * Check whether master is a valid interface name, UUID or ID of some @type connection. - * First UUID and ifname are checked. If they don't match, ID is checked - * and replaced by UUID on a match. - * - * Returns: identifier of master connection if found, %NULL otherwise - */ -static const char * -verify_master_for_slave (GSList *connections, - const char *master, - const char *type) -{ - NMConnection *connection; - NMSettingConnection *s_con; - const char *con_type, *id, *uuid, *ifname; - GSList *iterator = connections; - const char *found_by_id = NULL; - const char *out_master = NULL; - const char *(*func) (NMConnection *) = NULL; - - if (!master) - return NULL; - - master = _strip_master_prefix (master, &func); - while (iterator) { - connection = NM_CONNECTION (iterator->data); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - if (g_strcmp0 (con_type, type) != 0) { - iterator = g_slist_next (iterator); - continue; - } - if (func) { - /* There was a prefix; only compare to that type. */ - if (g_strcmp0 (master, func (connection)) == 0) { - if (func == nm_connection_get_id) - out_master = nm_connection_get_uuid (connection); - else - out_master = master; - break; - } - } else { - id = nm_connection_get_id (connection); - uuid = nm_connection_get_uuid (connection); - ifname = nm_connection_get_virtual_iface_name (connection); - if ( g_strcmp0 (master, uuid) == 0 - || g_strcmp0 (master, ifname) == 0) { - out_master = master; - break; - } - if (!found_by_id && g_strcmp0 (master, id) == 0) - found_by_id = uuid; - } - - iterator = g_slist_next (iterator); - } - return out_master ? out_master : found_by_id; -} - -static gboolean -bridge_prop_string_to_uint (const char *str, - const char *nmc_arg, - GType bridge_type, - const char *propname, - unsigned long *out_val, - GError **error) -{ - GParamSpecUInt *pspec; - - pspec = (GParamSpecUInt *) g_object_class_find_property (g_type_class_peek (bridge_type), - propname); - g_assert (G_IS_PARAM_SPEC_UINT (pspec)); - - if (!nmc_string_to_uint (str, TRUE, pspec->minimum, pspec->maximum, out_val)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s': '%s' is not valid; use <%u-%u>."), - nmc_arg, str, pspec->minimum, pspec->maximum); - return FALSE; - } - return TRUE; -} - -#define WORD_YES "yes" -#define WORD_NO "no" -#define WORD_LOC_YES _("yes") -#define WORD_LOC_NO _("no") -static const char * -prompt_yes_no (gboolean default_yes, char *delim) -{ - static char prompt[128] = { 0 }; - - if (!delim) - delim = ""; - - snprintf (prompt, sizeof (prompt), "(%s/%s) [%s]%s ", - WORD_LOC_YES, WORD_LOC_NO, - default_yes ? WORD_LOC_YES : WORD_LOC_NO, delim); - - return prompt; -} - -static gboolean -normalize_yes_no (char **yes_no) -{ - char *tmp; - const char *checked_yes_no; - const char *strv[] = { WORD_LOC_YES, WORD_LOC_NO, NULL }; - - if (!yes_no || !*yes_no) - return FALSE; - - tmp = g_strstrip (g_strdup (*yes_no)); - checked_yes_no = nmc_string_is_valid (tmp, strv, NULL); - g_free (tmp); - if (g_strcmp0 (checked_yes_no, WORD_LOC_YES) == 0) { - g_free (*yes_no); - *yes_no = g_strdup (WORD_YES); - } else if (g_strcmp0 (checked_yes_no, WORD_LOC_NO) == 0) { - g_free (*yes_no); - *yes_no = g_strdup (WORD_NO); - } - return !!checked_yes_no; -} - -static gboolean -want_provide_opt_args (const char *type, int num) -{ - char *answer; - gboolean ret = TRUE; - - /* Ask for optional arguments. */ - printf (ngettext ("There is %d optional argument for '%s' connection type.\n", - "There are %d optional arguments for '%s' connection type.\n", num), - num, type); - answer = nmc_readline (ngettext ("Do you want to provide it? %s", - "Do you want to provide them? %s", num), - prompt_yes_no (TRUE, NULL)); - answer = answer ? g_strstrip (answer) : NULL; - if (answer && matches (answer, WORD_LOC_YES) != 0) - ret = FALSE; - g_free (answer); - return ret; -} - -static void -do_questionnaire_ethernet (gboolean ethernet, char **mtu, char **mac, char **cloned_mac) -{ - gboolean once_more; - GError *error = NULL; - const char *type = ethernet ? _("ethernet") : _("Wi-Fi"); - - /* Ask for optional arguments */ - if (!want_provide_opt_args (type, 3)) - return; - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } - if (!*cloned_mac) { - do { - *cloned_mac = nmc_readline (_("Cloned MAC [none]: ")); - once_more = !check_and_convert_mac (*cloned_mac, NULL, ARPHRD_ETHER, "cloned-mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*cloned_mac); - } - } while (once_more); - } -} - -#define WORD_DATAGRAM "datagram" -#define WORD_CONNECTED "connected" -#define PROMPT_IB_MODE "(" WORD_DATAGRAM "/" WORD_CONNECTED ") [" WORD_DATAGRAM "]: " -static void -do_questionnaire_infiniband (char **mtu, char **mac, char **mode, char **parent, char **p_key) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional arguments */ - if (!want_provide_opt_args (_("InfiniBand"), 5)) - return; - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_INFINIBAND, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } - if (!*mode) { - do { - *mode = nmc_readline (_("Transport mode %s"), PROMPT_IB_MODE); - if (!*mode) - *mode = g_strdup ("datagram"); - once_more = !check_infiniband_mode (mode, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mode); - } - } while (once_more); - } - if (!*parent) { - do { - *parent = nmc_readline (_("Parent interface [none]: ")); - once_more = !check_infiniband_parent (*parent, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*parent); - } - } while (once_more); - } - if (!*p_key) { - do { - *p_key = nmc_readline (_("P_KEY [none]: ")); - once_more = !check_infiniband_p_key (*p_key, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*p_key); - } - /* If parent is specified, so has to be P_KEY */ - if (!once_more && *parent && !*p_key) { - once_more = TRUE; - printf (_("Error: 'p-key' is mandatory when 'parent' is specified.\n")); - } - } while (once_more); - } -} - -static void -do_questionnaire_wifi (char **mtu, char **mac, char **cloned_mac) -{ - /* At present, the optional Wi-Fi arguments are the same as for ethernet. */ - return do_questionnaire_ethernet (FALSE, mtu, mac, cloned_mac); -} - -static void -do_questionnaire_wimax (char **mac) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'wimax' arguments. */ - if (!want_provide_opt_args (_("WiMAX"), 1)) - return; - - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } -} - -static void -do_questionnaire_pppoe (char **password, char **service, char **mtu, char **mac) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'pppoe' arguments. */ - if (!want_provide_opt_args (_("PPPoE"), 4)) - return; - - if (!*password) - *password = nmc_readline (_("Password [none]: ")); - if (!*service) - *service = nmc_readline (_("Service [none]: ")); - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } -} - -static void -do_questionnaire_mobile (char **user, char **password) -{ - /* Ask for optional 'gsm' or 'cdma' arguments. */ - if (!want_provide_opt_args (_("mobile broadband"), 2)) - return; - - if (!*user) - *user = nmc_readline (_("Username [none]: ")); - if (!*password) - *password = nmc_readline (_("Password [none]: ")); -} - -#define WORD_PANU "panu" -#define WORD_DUN_GSM "dun-gsm" -#define WORD_DUN_CDMA "dun-cdma" -#define PROMPT_BT_TYPE "(" WORD_PANU "/" WORD_DUN_GSM "/" WORD_DUN_CDMA ") [" WORD_PANU "]: " -static void -do_questionnaire_bluetooth (char **bt_type) -{ - gboolean once_more; - - /* Ask for optional 'bluetooth' arguments. */ - if (!want_provide_opt_args (_("bluetooth"), 1)) - return; - - if (!*bt_type) { - const char *types[] = { "dun", "dun-gsm", "dun-cdma", "panu", NULL }; - const char *tmp; - do { - *bt_type = nmc_readline (_("Bluetooth type %s"), PROMPT_BT_TYPE); - if (!*bt_type) - *bt_type = g_strdup ("panu"); - tmp = nmc_string_is_valid (*bt_type, types, NULL); - once_more = !tmp; - if (once_more) { - printf (_("Error: 'bt-type': '%s' is not a valid bluetooth type.\n"), *bt_type); - g_free (*bt_type); - } - } while (once_more); - g_free (*bt_type); - *bt_type = g_strdup (tmp); - } -} - -static void -do_questionnaire_vlan (char **mtu, char **flags, char **ingress, char **egress) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'vlan' arguments. */ - if (!want_provide_opt_args (_("VLAN"), 4)) - return; - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*flags) { - do { - *flags = nmc_readline (_("VLAN flags (<0-7>) [none]: ")); - once_more = !check_and_convert_vlan_flags (*flags, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*flags); - } - } while (once_more); - } - if (!*ingress) { - do { - *ingress = nmc_readline (_("Ingress priority maps [none]: ")); - once_more = !check_and_convert_vlan_prio_maps (*ingress, NM_VLAN_INGRESS_MAP, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*ingress); - } - } while (once_more); - } - if (!*egress) { - do { - *egress = nmc_readline (_("Egress priority maps [none]: ")); - once_more = !check_and_convert_vlan_prio_maps (*egress, NM_VLAN_EGRESS_MAP, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*egress); - } - } while (once_more); - } -} - -#define PROMPT_BOND_MODE _("Bonding mode [balance-rr]: ") -#define WORD_MIIMON "miimon" -#define WORD_ARP "arp" -#define PROMPT_BOND_MON_MODE "(" WORD_MIIMON "/" WORD_ARP ") [" WORD_MIIMON "]: " -static void -do_questionnaire_bond (char **mode, char **primary, char **miimon, - char **downdelay, char **updelay, - char **arpinterval, char **arpiptarget) -{ - char *monitor_mode; - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'bond' arguments. */ - if (!want_provide_opt_args (_("bond"), 7)) - return; - - if (!*mode) { - const char *mode_tmp; - do { - *mode = nmc_readline (PROMPT_BOND_MODE); - if (!*mode) - *mode = g_strdup ("balance-rr"); - mode_tmp = nmc_bond_validate_mode (*mode, &error); - g_free (*mode); - if (mode_tmp) { - *mode = g_strdup (mode_tmp); - } else { - printf ("%s\n", error->message); - g_clear_error (&error); - } - } while (!mode_tmp); - } - - if (g_strcmp0 (*mode, "active-backup") == 0 && !*primary) { - do { - *primary = nmc_readline (_("Bonding primary interface [none]: ")); - once_more = *primary && !nm_utils_iface_valid_name (*primary); - if (once_more) { - printf (_("Error: 'primary': '%s' is not a valid interface name.\n"), - *primary); - g_free (*primary); - } - } while (once_more); - } - - do { - monitor_mode = nmc_readline (_("Bonding monitoring mode %s"), PROMPT_BOND_MON_MODE); - if (!monitor_mode) - monitor_mode = g_strdup (WORD_MIIMON); - g_strstrip (monitor_mode); - once_more = matches (monitor_mode, WORD_MIIMON) != 0 && matches (monitor_mode, WORD_ARP) != 0; - if (once_more) { - printf (_("Error: '%s' is not a valid monitoring mode; use '%s' or '%s'.\n"), - monitor_mode, WORD_MIIMON, WORD_ARP); - g_free (monitor_mode); - } - } while (once_more); - - if (matches (monitor_mode, WORD_MIIMON) == 0) { - if (!*miimon) { - do { - *miimon = nmc_readline (_("Bonding miimon [100]: ")); - once_more = *miimon && !nmc_string_to_uint (*miimon, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'miimon': '%s' is not a valid number <0-%u>.\n"), - *miimon, G_MAXUINT32); - g_free (*miimon); - } - } while (once_more); - } - if (!*downdelay) { - do { - *downdelay = nmc_readline (_("Bonding downdelay [0]: ")); - once_more = *downdelay && !nmc_string_to_uint (*downdelay, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'downdelay': '%s' is not a valid number <0-%u>.\n"), - *downdelay, G_MAXUINT32); - g_free (*downdelay); - } - } while (once_more); - } - if (!*updelay) { - do { - *updelay = nmc_readline (_("Bonding updelay [0]: ")); - once_more = *updelay && !nmc_string_to_uint (*updelay, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'updelay': '%s' is not a valid number <0-%u>.\n"), - *updelay, G_MAXUINT32); - g_free (*updelay); - } - } while (once_more); - } - } else { - if (!*arpinterval) { - do { - *arpinterval = nmc_readline (_("Bonding arp-interval [0]: ")); - once_more = *arpinterval && !nmc_string_to_uint (*arpinterval, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'arp-interval': '%s' is not a valid number <0-%u>.\n"), - *arpinterval, G_MAXUINT32); - g_free (*arpinterval); - } - } while (once_more); - } - if (!*arpiptarget) { - //FIXME: verify the string - *arpiptarget = nmc_readline (_("Bonding arp-ip-target [none]: ")); - } - } - - g_free (monitor_mode); -} - -static void -do_questionnaire_team_common (const char *type_name, char **config) -{ - gboolean once_more; - char *json = NULL; - GError *error = NULL; - - /* Ask for optional arguments. */ - if (!want_provide_opt_args (type_name, 1)) - return; - - if (!*config) { - do { - *config = nmc_readline (_("Team JSON configuration [none]: ")); - once_more = !nmc_team_check_config (*config, &json, &error); - if (once_more) { - printf ("Error: %s\n", error->message); - g_clear_error (&error); - g_free (*config); - } - } while (once_more); - } - - *config = json; -} - -/* Both team and team-slave curently have just ithe same one optional argument */ -static void -do_questionnaire_team (char **config) -{ - do_questionnaire_team_common (_("team"), config); -} - -static void -do_questionnaire_team_slave (char **config) -{ - do_questionnaire_team_common (_("team-slave"), config); -} - -static void -do_questionnaire_bridge (char **stp, char **priority, char **fwd_delay, char **hello_time, - char **max_age, char **ageing_time, char **mac) -{ - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'bridge' arguments. */ - if (!want_provide_opt_args (_("bridge"), 7)) - return; - - if (!*stp) { - gboolean stp_bool; - do { - *stp = nmc_readline (_("Enable STP %s"), prompt_yes_no (TRUE, ":")); - *stp = *stp ? *stp : g_strdup ("yes"); - normalize_yes_no (stp); - once_more = !nmc_string_to_bool (*stp, &stp_bool, &error); - if (once_more) { - printf (_("Error: 'stp': %s.\n"), error->message); - g_clear_error (&error); - g_free (*stp); - } - } while (once_more); - } - if (!*priority) { - do { - *priority = nmc_readline (_("STP priority [32768]: ")); - *priority = *priority ? *priority : g_strdup ("32768"); - once_more = !nmc_string_to_uint (*priority, TRUE, 0, G_MAXUINT16, &tmp); - if (once_more) { - printf (_("Error: 'priority': '%s' is not a valid number <0-%d>.\n"), - *priority, G_MAXUINT16); - g_free (*priority); - } - } while (once_more); - } - if (!*fwd_delay) { - do { - *fwd_delay = nmc_readline (_("Forward delay [15]: ")); - *fwd_delay = *fwd_delay ? *fwd_delay : g_strdup ("15"); - once_more = !nmc_string_to_uint (*fwd_delay, TRUE, 2, 30, &tmp); - if (once_more) { - printf (_("Error: 'forward-delay': '%s' is not a valid number <2-30>.\n"), - *fwd_delay); - g_free (*fwd_delay); - } - } while (once_more); - } - - if (!*hello_time) { - do { - *hello_time = nmc_readline (_("Hello time [2]: ")); - *hello_time = *hello_time ? *hello_time : g_strdup ("2"); - once_more = !nmc_string_to_uint (*hello_time, TRUE, 1, 10, &tmp); - if (once_more) { - printf (_("Error: 'hello-time': '%s' is not a valid number <1-10>.\n"), - *hello_time); - g_free (*hello_time); - } - } while (once_more); - } - if (!*max_age) { - do { - *max_age = nmc_readline (_("Max age [20]: ")); - *max_age = *max_age ? *max_age : g_strdup ("20"); - once_more = !nmc_string_to_uint (*max_age, TRUE, 6, 40, &tmp); - if (once_more) { - printf (_("Error: 'max-age': '%s' is not a valid number <6-40>.\n"), - *max_age); - g_free (*max_age); - } - } while (once_more); - } - if (!*ageing_time) { - do { - *ageing_time = nmc_readline (_("MAC address ageing time [300]: ")); - *ageing_time = *ageing_time ? *ageing_time : g_strdup ("300"); - once_more = !nmc_string_to_uint (*ageing_time, TRUE, 0, 1000000, &tmp); - if (once_more) { - printf (_("Error: 'ageing-time': '%s' is not a valid number <0-1000000>.\n"), - *ageing_time); - g_free (*ageing_time); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_get_user_input (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } -} - -static void -do_questionnaire_bridge_slave (char **priority, char **path_cost, char **hairpin) -{ - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'bridge-slave' arguments. */ - if (!want_provide_opt_args (_("bridge-slave"), 3)) - return; - - if (!*priority) { - do { - *priority = nmc_readline (_("Bridge port priority [32]: ")); - *priority = *priority ? *priority : g_strdup ("32"); - once_more = !bridge_prop_string_to_uint (*priority, "priority", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PRIORITY, &tmp, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*priority); - } - } while (once_more); - } - if (!*path_cost) { - do { - *path_cost = nmc_readline (_("Bridge port STP path cost [100]: ")); - *path_cost = *path_cost ? *path_cost : g_strdup ("100"); - once_more = !bridge_prop_string_to_uint (*path_cost, "path-cost", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PATH_COST, &tmp, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*path_cost); - } - } while (once_more); - } - if (!*hairpin) { - gboolean hairpin_bool; - do { - *hairpin = nmc_readline (_("Hairpin %s"), prompt_yes_no (TRUE, ":")); - *hairpin = *hairpin ? *hairpin : g_strdup ("yes"); - normalize_yes_no (hairpin); - once_more = !nmc_string_to_bool (*hairpin, &hairpin_bool, &error); - if (once_more) { - printf (_("Error: 'hairpin': %s.\n"), error->message); - g_clear_error (&error); - g_free (*hairpin); - } - } while (once_more); - } -} - -static void -do_questionnaire_vpn (char **user) -{ - /* Ask for optional 'vpn' arguments. */ - if (!want_provide_opt_args (_("VPN"), 1)) - return; - - if (!*user) - *user = nmc_readline (_("Username [none]: ")); -} - -static void -do_questionnaire_olpc (char **channel, char **dhcp_anycast) -{ - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'olpc' arguments. */ - if (!want_provide_opt_args (_("OLPC Mesh"), 2)) - return; - - if (!*channel) { - do { - *channel = nmc_readline (_("OLPC Mesh channel [1]: ")); - once_more = *channel && !nmc_string_to_uint (*channel, TRUE, 1, 13, &tmp); - if (once_more) { - printf (_("Error: 'channel': '%s' is not a valid number <1-13>.\n"), - *channel); - g_free (*channel); - } - } while (once_more); - } - if (!*dhcp_anycast) { - do { - *dhcp_anycast = nmc_readline (_("DHCP anycast MAC address [none]: ")); - once_more = !check_and_convert_mac (*dhcp_anycast, NULL, ARPHRD_ETHER, "dhcp-anycast", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*dhcp_anycast); - } - } while (once_more); - } -} - -static gboolean -split_address (char* str, char **ip, char **gw, char **rest) -{ - size_t n1, n2, n3, n4, n5; - - *ip = *gw = *rest = NULL; - if (!str) - return FALSE; - - n1 = strspn (str, " \t"); - n2 = strcspn (str+n1, " \t\0") + n1; - n3 = strspn (str+n2, " \t") + n2; - n4 = strcspn (str+n3, " \t\0") + n3; - n5 = strspn (str+n4, " \t") + n4; - - str[n2] = str[n4] = '\0'; - *ip = str[n1] ? str + n1 : NULL; - *gw = str[n3] ? str + n3 : NULL; - *rest = str[n5] ? str + n5 : NULL; - - return TRUE; -} - -static void -ask_for_ip_addresses (NMConnection *connection, int family) -{ - gboolean ip_loop; - GError *error = NULL; - char *str, *ip, *gw, *rest; - const char *prompt; - gboolean added; - gpointer ipaddr; - - if (family == 4) - prompt =_("IPv4 address (IP[/plen] [gateway]) [none]: "); - else - prompt =_("IPv6 address (IP[/plen] [gateway]) [none]: "); - - ip_loop = TRUE; - do { - str = nmc_readline ("%s", prompt); - split_address (str, &ip, &gw, &rest); - if (ip) { - if (family == 4) - ipaddr = nmc_parse_and_build_ip4_address (ip, gw, &error); - else - ipaddr = nmc_parse_and_build_ip6_address (ip, gw, &error); - if (ipaddr) { - if (family == 4) - added = add_ip4_address_to_connection ((NMIP4Address *) ipaddr, connection); - else - added = add_ip6_address_to_connection ((NMIP6Address *) ipaddr, connection); - gw = gw ? gw : (family == 4) ? "0.0.0.0" : "::"; - if (added) - printf (_(" Address successfully added: %s %s\n"), ip, gw); - else - printf (_(" Warning: address already present: %s %s\n"), ip, gw); - if (rest) - printf (_(" Warning: ignoring garbage at the end: '%s'\n"), rest); - } else { - g_prefix_error (&error, _("Error: ")); - printf ("%s\n", error->message); - g_clear_error (&error); - } - } else - ip_loop = FALSE; - - g_free (str); - } while (ip_loop); -} - -static void -do_questionnaire_ip (NMConnection *connection) -{ - char *answer; - - /* Ask for IP addresses */ - answer = nmc_readline (_("Do you want to add IP addresses? %s"), prompt_yes_no (TRUE, NULL)); - answer = answer ? g_strstrip (answer) : NULL; - if (answer && matches (answer, WORD_LOC_YES) != 0) { - g_free (answer); - return; - } - - printf (_("Press to finish adding addresses.\n")); - - ask_for_ip_addresses (connection, 4); - ask_for_ip_addresses (connection, 6); - - g_free (answer); - return; -} - -static gboolean -complete_connection_by_type (NMConnection *connection, - const char *con_type, - GSList *all_connections, - gboolean ask, - int argc, - char **argv, - GError **error) -{ - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingInfiniband *s_infiniband; - NMSettingWireless *s_wifi; - NMSettingWimax *s_wimax; - NMSettingPPPOE *s_pppoe; - NMSettingGsm *s_gsm; - NMSettingCdma *s_cdma; - NMSettingBluetooth *s_bt; - NMSettingVlan *s_vlan; - NMSettingBond *s_bond; - NMSettingTeam *s_team; - NMSettingTeamPort *s_team_port; - NMSettingBridge *s_bridge; - NMSettingBridgePort *s_bridge_port; - NMSettingVPN *s_vpn; - NMSettingOlpcMesh *s_olpc_mesh; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - if (!strcmp (con_type, NM_SETTING_WIRED_SETTING_NAME)) { - /* Build up the settings required for 'ethernet' */ - gboolean success = FALSE; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - const char *cloned_mac_c = NULL; - char *cloned_mac = NULL; - GByteArray *array = NULL; - GByteArray *cloned_array = NULL; - nmc_arg_t exp_args[] = { {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {"cloned-mac", TRUE, &cloned_mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - mac = mac_c ? g_strdup (mac_c) : NULL; - cloned_mac = cloned_mac_c ? g_strdup (cloned_mac_c) : NULL; - if (ask) - do_questionnaire_ethernet (TRUE, &mtu, &mac, &cloned_mac); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_wired; - if (!check_and_convert_mac (mac, &array, ARPHRD_ETHER, "mac", error)) - goto cleanup_wired; - if (!check_and_convert_mac (cloned_mac, &cloned_array, ARPHRD_ETHER, "cloned-mac", error)) - goto cleanup_wired; - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - if (mtu) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu_int, NULL); - if (array) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, array, NULL); - if (cloned_array) - g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_array, NULL); - - success = TRUE; -cleanup_wired: - g_free (mtu); - g_free (mac); - g_free (cloned_mac); - if (array) - g_byte_array_free (array, TRUE); - if (cloned_array) - g_byte_array_free (cloned_array, TRUE); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_INFINIBAND_SETTING_NAME)) { - /* Build up the settings required for 'infiniband' */ - gboolean success = FALSE; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *array = NULL; - const char *mode_c = NULL; - char *mode = NULL; - const char *parent_c = NULL; - char *parent = NULL; - const char *p_key_c = NULL; - char *p_key = NULL; - guint32 p_key_int = 0; - nmc_arg_t exp_args[] = { {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {"transport-mode", TRUE, &mode_c, FALSE}, - {"parent", TRUE, &parent_c, FALSE}, - {"p-key", TRUE, &p_key_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - mac = mac_c ? g_strdup (mac_c) : NULL; - mode = mode_c ? g_strdup (mode_c) : NULL; - parent = parent_c ? g_strdup (parent_c) : NULL; - p_key = p_key_c ? g_strdup (p_key_c) : NULL; - if (ask) - do_questionnaire_infiniband (&mtu, &mac, &mode, &parent, &p_key); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_ib; - if (!check_and_convert_mac (mac, &array, ARPHRD_INFINIBAND, "mac", error)) - goto cleanup_ib; - if (!check_infiniband_mode (&mode, error)) - goto cleanup_ib; - if (p_key) { - if (!check_infiniband_p_key (p_key, &p_key_int, error)) - goto cleanup_ib; - if (!check_infiniband_parent (parent, error)) - goto cleanup_ib; - } else if (parent) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'parent': not valid without 'p-key'.")); - goto cleanup_ib; - } - - /* Add 'infiniband' setting */ - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); - - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, mode ? mode : "datagram", NULL); - if (mtu) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu_int, NULL); - if (array) { - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - if (p_key) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_P_KEY, p_key_int, NULL); - if (parent) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_PARENT, parent, NULL); - - - success = TRUE; -cleanup_ib: - g_free (mtu); - g_free (mac); - g_free (mode); - g_free (parent); - g_free (p_key); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME)) { - /* Build up the settings required for 'wifi' */ - gboolean success = FALSE; - char *ssid_ask = NULL; - const char *ssid = NULL; - GByteArray *ssid_arr = NULL; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - const char *cloned_mac_c = NULL; - char *cloned_mac = NULL; - GByteArray *cloned_mac_array = NULL; - nmc_arg_t exp_args[] = { {"ssid", TRUE, &ssid, !ask}, - {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {"cloned-mac", TRUE, &cloned_mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!ssid && ask) - ssid = ssid_ask = nmc_readline (_("SSID: ")); - if (!ssid) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'ssid' is required.")); - return FALSE; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - mac = mac_c ? g_strdup (mac_c) : NULL; - cloned_mac = cloned_mac_c ? g_strdup (cloned_mac_c) : NULL; - if (ask) - do_questionnaire_wifi (&mtu, &mac, &cloned_mac); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_wifi; - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_wifi; - if (!check_and_convert_mac (cloned_mac, &cloned_mac_array, ARPHRD_ETHER, "cloned-mac", error)) - goto cleanup_wifi; - - /* Add wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid_arr = g_byte_array_sized_new (strlen (ssid)); - g_byte_array_append (ssid_arr, (const guint8 *) ssid, strlen (ssid)); - g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid_arr, NULL); - - if (mtu) - g_object_set (s_wifi, NM_SETTING_WIRELESS_MTU, mtu_int, NULL); - if (mac_array) - g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_array, NULL); - if (cloned_mac_array) - g_object_set (s_wifi, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac_array, NULL); - - success = TRUE; -cleanup_wifi: - g_free (ssid_ask); - g_free (mtu); - g_free (mac); - g_free (cloned_mac); - if (ssid_arr) - g_byte_array_free (ssid_arr, TRUE); - if (mac_array) - g_byte_array_free (mac_array, TRUE); - if (cloned_mac_array) - g_byte_array_free (cloned_mac_array, TRUE); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_WIMAX_SETTING_NAME)) { - /* Build up the settings required for 'wimax' */ - gboolean success = FALSE; - const char *nsp_name = NULL; - char *nsp_name_ask = NULL; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - nmc_arg_t exp_args[] = { {"nsp", TRUE, &nsp_name, !ask}, - {"mac", TRUE, &mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!nsp_name && ask) - nsp_name = nsp_name_ask = nmc_readline (_("WiMAX NSP name: ")); - if (!nsp_name) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'nsp' is required.")); - goto cleanup_wimax; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - mac = mac_c ? g_strdup (mac_c) : NULL; - if (ask) - do_questionnaire_wimax (&mac); - - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_wimax; - - /* Add 'wimax' setting */ - s_wimax = (NMSettingWimax *) nm_setting_wimax_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wimax)); - g_object_set (s_wimax, NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); - - if (mac_array) { - g_object_set (s_wimax, NM_SETTING_WIMAX_MAC_ADDRESS, mac_array, NULL); - g_byte_array_free (mac_array, TRUE); - } - - success = TRUE; -cleanup_wimax: - g_free (nsp_name_ask); - g_free (mac); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_PPPOE_SETTING_NAME)) { - /* Build up the settings required for 'pppoe' */ - gboolean success = FALSE; - const char *username = NULL; - char *username_ask = NULL; - const char *password_c = NULL; - char *password = NULL; - const char *service_c = NULL; - char *service = NULL; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - nmc_arg_t exp_args[] = { {"username", TRUE, &username, !ask}, - {"password", TRUE, &password_c, FALSE}, - {"service", TRUE, &service_c, FALSE}, - {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!username && ask) - username = username_ask = nmc_readline (_("PPPoE username: ")); - if (!username) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'username' is required.")); - goto cleanup_pppoe; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - password = g_strdup (password_c); - service = g_strdup (service_c); - mtu = g_strdup (mtu_c); - mac = g_strdup (mac_c); - if (ask) - do_questionnaire_pppoe (&password, &service, &mtu, &mac); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_pppoe; - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_pppoe; - - /* Add 'pppoe' setting */ - s_pppoe = (NMSettingPPPOE *) nm_setting_pppoe_new (); - nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); - g_object_set (s_pppoe, NM_SETTING_PPPOE_USERNAME, username, NULL); - g_object_set (s_pppoe, NM_SETTING_PPPOE_PASSWORD, password, NULL); - g_object_set (s_pppoe, NM_SETTING_PPPOE_SERVICE, service, NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - if (mtu) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu_int, NULL); - if (mac_array) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_array, NULL); - - success = TRUE; -cleanup_pppoe: - g_free (username_ask); - g_free (password); - g_free (service); - g_free (mtu); - g_free (mac); - if (mac_array) - g_byte_array_free (mac_array, TRUE); - if (!success) - return FALSE; - - } else if ( !strcmp (con_type, NM_SETTING_GSM_SETTING_NAME) - || !strcmp (con_type, NM_SETTING_CDMA_SETTING_NAME)) { - /* Build up the settings required for 'gsm' or 'cdma' mobile broadband */ - gboolean success = FALSE; - const char *apn = NULL; - char *apn_ask = NULL; - const char *user_c = NULL; - char *user = NULL; - const char *password_c = NULL; - char *password = NULL; - gboolean is_gsm; - int i = 0; - nmc_arg_t gsm_args[] = { {NULL}, {NULL}, {NULL}, /* placeholders */ - {NULL} }; - - is_gsm = !strcmp (con_type, NM_SETTING_GSM_SETTING_NAME); - - if (is_gsm) - gsm_args[i++] = (nmc_arg_t) {"apn", TRUE, &apn, !ask}; - gsm_args[i++] = (nmc_arg_t) {"user", TRUE, &user_c, FALSE}; - gsm_args[i++] = (nmc_arg_t) {"password", TRUE, &password_c, FALSE}; - gsm_args[i++] = (nmc_arg_t) {NULL}; - - if (!nmc_parse_args (gsm_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!apn && ask && is_gsm) - apn = apn_ask = nmc_readline (_("APN: ")); - if (!apn && is_gsm) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'apn' is required.")); - goto cleanup_mobile; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - user = user_c ? g_strdup (user_c) : NULL; - password = password_c ? g_strdup (password_c) : NULL; - if (ask) - do_questionnaire_mobile (&user, &password); - - if (is_gsm) { - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, NULL); - - /* Add 'gsm' setting */ - s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); - g_object_set (s_gsm, - NM_SETTING_GSM_NUMBER, "*99#", - NM_SETTING_GSM_APN, apn, - NM_SETTING_GSM_USERNAME, user, - NM_SETTING_GSM_PASSWORD, password, - NULL); - g_free (apn_ask); - } else { - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_CDMA_SETTING_NAME, NULL); - - /* Add 'cdma' setting */ - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - g_object_set (s_cdma, - NM_SETTING_CDMA_NUMBER, "#777", - NM_SETTING_CDMA_USERNAME, user, - NM_SETTING_CDMA_PASSWORD, password, - NULL); - } - - success = TRUE; -cleanup_mobile: - g_free (user); - g_free (password); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_BLUETOOTH_SETTING_NAME)) { - /* Build up the settings required for 'bluetooth' */ - gboolean success = FALSE; - const char *addr = NULL; - char *addr_ask = NULL; - const char *bt_type_c = NULL; - char *bt_type = NULL; - GByteArray *array = NULL; - nmc_arg_t exp_args[] = { {"addr", TRUE, &addr, !ask}, - {"bt-type", TRUE, &bt_type_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!addr && ask) - addr = addr_ask = nmc_readline (_("Bluetooth device address: ")); - if (!addr) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'addr' is required.")); - return FALSE; - } - if (!check_and_convert_mac (addr, &array, ARPHRD_ETHER, "addr", error)) - goto cleanup_bt; - - /* Also ask for all optional arguments if '--ask' is specified. */ - bt_type = bt_type_c ? g_strdup (bt_type_c) : NULL; - if (ask) - do_questionnaire_bluetooth (&bt_type); - - /* Default to 'panu' if bt-type is not provided. */ - if (!bt_type) - bt_type = g_strdup (NM_SETTING_BLUETOOTH_TYPE_PANU); - - /* Add 'bluetooth' setting */ - s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bt)); - - if (array) { - g_object_set (s_bt, NM_SETTING_BLUETOOTH_BDADDR, array, NULL); - g_byte_array_free (array, TRUE); - } - - /* 'dun' type requires adding 'gsm' or 'cdma' setting */ - if ( !strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN) - || !strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm")) { - bt_type = g_strdup (NM_SETTING_BLUETOOTH_TYPE_DUN); - s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); - g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); -// g_object_set (s_gsm, NM_SETTING_GSM_APN, "FIXME", NULL; - - } else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma")) { - bt_type = g_strdup (NM_SETTING_BLUETOOTH_TYPE_DUN); - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - g_object_set (s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL); - - } else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { - /* no op */ - } else { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'bt-type': '%s' not valid; use [%s, %s (%s), %s]."), - bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU, NM_SETTING_BLUETOOTH_TYPE_DUN, - NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm", NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma"); - goto cleanup_bt; - } - g_object_set (s_bt, NM_SETTING_BLUETOOTH_TYPE, bt_type, NULL); - - success = TRUE; -cleanup_bt: - g_free (addr_ask); - g_free (bt_type); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_VLAN_SETTING_NAME)) { - /* Build up the settings required for 'vlan' */ - gboolean success = FALSE; - const char *ifname = NULL; - const char *parent = NULL; - char *parent_ask = NULL; - const char *vlan_id = NULL; - char *vlan_id_ask = NULL; - unsigned long id = 0; - const char *flags_c = NULL; - char *flags = NULL; - guint32 flags_int = 0; - const char *ingress_c = NULL, *egress_c = NULL; - char *ingress = NULL, *egress = NULL; - char **ingress_arr = NULL, **egress_arr = NULL, **p; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int; - GByteArray *addr_array = NULL; - nmc_arg_t exp_args[] = { {"dev", TRUE, &parent, !ask}, - {"id", TRUE, &vlan_id, !ask}, - {"flags", TRUE, &flags_c, FALSE}, - {"ingress", TRUE, &ingress_c, FALSE}, - {"egress", TRUE, &egress_c, FALSE}, - {"mtu", TRUE, &mtu_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!parent && ask) - parent = parent_ask = nmc_readline (_("VLAN parent device or connection UUID: ")); - if (!parent) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'dev' is required.")); - return FALSE; - } - if (!vlan_id && ask) - vlan_id = vlan_id_ask = nmc_readline (_("VLAN ID <0-4095>: ")); - if (!vlan_id) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'id' is required.")); - goto cleanup_vlan; - } - if (vlan_id) { - if (!nmc_string_to_uint (vlan_id, TRUE, 0, 4095, &id)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'id': '%s' is not valid; use <0-4095>."), - vlan_id); - goto cleanup_vlan; - } - } - - if ( !(addr_array = nm_utils_hwaddr_atoba (parent, ARPHRD_ETHER)) - && !nm_utils_is_uuid (parent) - && !nm_utils_iface_valid_name (parent)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'dev': '%s' is neither UUID, interface name, nor MAC."), - parent); - goto cleanup_vlan; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - flags = flags_c ? g_strdup (flags_c) : NULL; - ingress = ingress_c ? g_strdup (ingress_c) : NULL; - egress = egress_c ? g_strdup (egress_c) : NULL; - if (ask) - do_questionnaire_vlan (&mtu, &flags, &ingress, &egress); - - /* ifname is taken from connection's ifname */ - ifname = nm_setting_connection_get_interface_name (s_con); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_vlan; - if (!check_and_convert_vlan_flags (flags, &flags_int, error)) - goto cleanup_vlan; - if (!check_and_convert_vlan_prio_maps (ingress, NM_VLAN_INGRESS_MAP, &ingress_arr, error)) - goto cleanup_vlan; - if (!check_and_convert_vlan_prio_maps (egress, NM_VLAN_EGRESS_MAP, &egress_arr, error)) - goto cleanup_vlan; - - /* Add 'vlan' setting */ - s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); - nm_connection_add_setting (connection, NM_SETTING (s_vlan)); - - /* Add 'wired' setting if necessary */ - if (mtu || addr_array) { - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - if (mtu) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu_int, NULL); - if (addr_array) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, addr_array, NULL); - } - - /* Set 'vlan' properties */ - if (!addr_array) - g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL); - - if (ifname) - g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, ifname, NULL); - g_object_set (s_vlan, NM_SETTING_VLAN_ID, id, NULL); - - if (flags) - g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, flags_int, NULL); - for (p = ingress_arr; p && *p; p++) - nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_INGRESS_MAP, *p); - for (p = egress_arr; p && *p; p++) - nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_EGRESS_MAP, *p); - - success = TRUE; -cleanup_vlan: - g_free (mtu); - g_free (flags); - g_free (ingress); - g_free (egress); - if (addr_array) - g_byte_array_free (addr_array, TRUE); - g_free (parent_ask); - g_free (vlan_id_ask); - g_strfreev (ingress_arr); - g_strfreev (egress_arr); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_BOND_SETTING_NAME)) { - /* Build up the settings required for 'bond' */ - gboolean success = FALSE; - char *bond_ifname = NULL; - const char *ifname = NULL; - const char *bond_mode_c = NULL; - char *bond_mode = NULL; - const char *bond_primary_c = NULL; - char *bond_primary = NULL; - const char *bond_miimon_c = NULL; - char *bond_miimon = NULL; - const char *bond_downdelay_c = NULL; - char *bond_downdelay = NULL; - const char *bond_updelay_c = NULL; - char *bond_updelay = NULL; - const char *bond_arpinterval_c = NULL; - char *bond_arpinterval = NULL; - const char *bond_arpiptarget_c = NULL; - char *bond_arpiptarget = NULL; - nmc_arg_t exp_args[] = { {"mode", TRUE, &bond_mode_c, FALSE}, - {"primary", TRUE, &bond_primary_c, FALSE}, - {"miimon", TRUE, &bond_miimon_c, FALSE}, - {"downdelay", TRUE, &bond_downdelay_c, FALSE}, - {"updelay", TRUE, &bond_updelay_c, FALSE}, - {"arp-interval", TRUE, &bond_arpinterval_c, FALSE}, - {"arp-ip-target", TRUE, &bond_arpiptarget_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - bond_mode = bond_mode_c ? g_strdup (bond_mode_c) : NULL; - bond_primary = bond_primary_c ? g_strdup (bond_primary_c) : NULL; - bond_miimon = bond_miimon_c ? g_strdup (bond_miimon_c) : NULL; - bond_downdelay = bond_downdelay_c ? g_strdup (bond_downdelay_c) : NULL; - bond_updelay = bond_updelay_c ? g_strdup (bond_updelay_c) : NULL; - bond_arpinterval = bond_arpinterval_c ? g_strdup (bond_arpinterval_c) : NULL; - bond_arpiptarget = bond_arpiptarget_c ? g_strdup (bond_arpiptarget_c) : NULL; - if (ask) - do_questionnaire_bond (&bond_mode, &bond_primary, &bond_miimon, - &bond_downdelay, &bond_updelay, - &bond_arpinterval, &bond_arpiptarget); - - /* Use connection's ifname as 'bond' ifname if exists, else generate one */ - ifname = nm_setting_connection_get_interface_name (s_con); - if (!ifname) - bond_ifname = unique_master_iface_ifname (all_connections, - NM_SETTING_BOND_SETTING_NAME, - NM_SETTING_BOND_INTERFACE_NAME, - "nm-bond"); - else - bond_ifname = g_strdup (ifname); - - /* Add 'bond' setting */ - s_bond = (NMSettingBond *) nm_setting_bond_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bond)); - - /* Set bond options */ - g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, bond_ifname, NULL); - if (bond_mode) { - GError *err = NULL; - const char *bm; - if (!(bm = nmc_bond_validate_mode (bond_mode, &err))) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mode': %s."), err->message); - g_clear_error (&err); - goto cleanup_bond; - } - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MODE, bm); - } - if (bond_primary) { - if (!nm_utils_iface_valid_name (bond_primary)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'primary': '%s' is not a valid interface name."), - bond_primary); - goto cleanup_bond; - } - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_PRIMARY, bond_primary); - } - if (bond_miimon) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MIIMON, bond_miimon); - if (bond_downdelay && strcmp (bond_downdelay, "0") != 0) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, bond_downdelay); - if (bond_updelay && strcmp (bond_updelay, "0") != 0) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY, bond_updelay); - if (bond_arpinterval && strcmp (bond_arpinterval, "0") != 0) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL, bond_arpinterval); - if (bond_arpiptarget) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, bond_arpiptarget); - - success = TRUE; -cleanup_bond: - g_free (bond_ifname); - g_free (bond_mode); - g_free (bond_primary); - g_free (bond_miimon); - g_free (bond_downdelay); - g_free (bond_updelay); - g_free (bond_arpinterval); - g_free (bond_arpiptarget); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, "bond-slave")) { - /* Build up the settings required for 'bond-slave' */ - const char *master = NULL; - char *master_ask = NULL; - const char *checked_master = NULL; - const char *type = NULL; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, !ask}, - {"type", TRUE, &type, FALSE}, - {NULL} }; - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = NM_SETTING_BOND_SETTING_NAME; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - if (!master && ask) - master = master_ask = nmc_readline (PROMPT_BOND_MASTER); - if (!master) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'master' is required.")); - return FALSE; - } - /* Verify master argument */ - checked_master = verify_master_for_slave (all_connections, master, NM_SETTING_BOND_SETTING_NAME); - if (!checked_master) - printf (_("Warning: master='%s' doesn't refer to any existing profile.\n"), master); - - if (type) - printf (_("Warning: 'type' is currently ignored. " - "We only support ethernet slaves for now.\n")); - - /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, checked_master ? checked_master : _strip_master_prefix (master, NULL), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_free (master_ask); - - } else if (!strcmp (con_type, NM_SETTING_TEAM_SETTING_NAME)) { - /* Build up the settings required for 'team' */ - gboolean success = FALSE; - char *team_ifname = NULL; - const char *ifname = NULL; - const char *config_c = NULL; - char *config = NULL; - char *json = NULL; - nmc_arg_t exp_args[] = { {"config", TRUE, &config_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - config = g_strdup (config_c); - if (ask) - do_questionnaire_team (&config); - - /* Use connection's ifname as 'team' ifname if exists, else generate one */ - ifname = nm_setting_connection_get_interface_name (s_con); - if (!ifname) - team_ifname = unique_master_iface_ifname (all_connections, - NM_SETTING_TEAM_SETTING_NAME, - NM_SETTING_TEAM_INTERFACE_NAME, - "nm-team"); - else - team_ifname = g_strdup (ifname); - - /* Add 'team' setting */ - s_team = (NMSettingTeam *) nm_setting_team_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team)); - - if (!nmc_team_check_config (config, &json, error)) { - g_prefix_error (error, _("Error: ")); - goto cleanup_team; - } - - /* Set team options */ - g_object_set (s_team, NM_SETTING_TEAM_INTERFACE_NAME, team_ifname, NULL); - g_object_set (s_team, NM_SETTING_TEAM_CONFIG, json, NULL); - - success = TRUE; -cleanup_team: - g_free (team_ifname); - g_free (config); - g_free (json); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, "team-slave")) { - /* Build up the settings required for 'team-slave' */ - gboolean success = FALSE; - const char *master = NULL; - char *master_ask = NULL; - const char *checked_master = NULL; - const char *type = NULL; - const char *config_c = NULL; - char *config = NULL; - char *json = NULL; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, !ask}, - {"type", TRUE, &type, FALSE}, - {"config", TRUE, &config_c, FALSE}, - {NULL} }; - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = NM_SETTING_TEAM_SETTING_NAME; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - if (!master && ask) - master = master_ask = nmc_readline (PROMPT_TEAM_MASTER); - if (!master) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'master' is required.")); - return FALSE; - } - /* Verify master argument */ - checked_master = verify_master_for_slave (all_connections, master, NM_SETTING_TEAM_SETTING_NAME); - if (!checked_master) - printf (_("Warning: master='%s' doesn't refer to any existing profile.\n"), master); - - /* Also ask for all optional arguments if '--ask' is specified. */ - config = g_strdup (config_c); - if (ask) - do_questionnaire_team_slave (&config); - - if (type) - printf (_("Warning: 'type' is currently ignored. " - "We only support ethernet slaves for now.\n")); - - /* Add 'team-port' setting */ - s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team_port)); - - if (!nmc_team_check_config (config, &json, error)) { - g_prefix_error (error, _("Error: ")); - goto cleanup_team_slave; - } - - /* Set team-port options */ - g_object_set (s_team_port, NM_SETTING_TEAM_PORT_CONFIG, json, NULL); - - /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, checked_master ? checked_master : _strip_master_prefix (master, NULL), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - success = TRUE; -cleanup_team_slave: - g_free (master_ask); - g_free (config); - g_free (json); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_BRIDGE_SETTING_NAME)) { - /* Build up the settings required for 'bridge' */ - gboolean success = FALSE; - char *bridge_ifname = NULL; - const char *ifname = NULL; - const char *stp_c = NULL; - char *stp = NULL; - const char *priority_c = NULL; - char *priority = NULL; - const char *fwd_delay_c = NULL; - char *fwd_delay = NULL; - const char *hello_time_c = NULL; - char *hello_time = NULL; - const char *max_age_c = NULL; - char *max_age = NULL; - const char *ageing_time_c = NULL; - char *ageing_time = NULL; - gboolean stp_bool; - unsigned long stp_prio_int, fwd_delay_int, hello_time_int, - max_age_int, ageing_time_int; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - nmc_arg_t exp_args[] = { {"stp", TRUE, &stp_c, FALSE}, - {"priority", TRUE, &priority_c, FALSE}, - {"forward-delay", TRUE, &fwd_delay_c, FALSE}, - {"hello-time", TRUE, &hello_time_c, FALSE}, - {"max-age", TRUE, &max_age_c, FALSE}, - {"ageing-time", TRUE, &ageing_time_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - stp = stp_c ? g_strdup (stp_c) : NULL; - priority = priority_c ? g_strdup (priority_c) : NULL; - fwd_delay = fwd_delay_c ? g_strdup (fwd_delay_c) : NULL; - hello_time = hello_time_c ? g_strdup (hello_time_c) : NULL; - max_age = max_age_c ? g_strdup (max_age_c) : NULL; - ageing_time = ageing_time_c ? g_strdup (ageing_time_c) : NULL; - mac = g_strdup (mac_c); - if (ask) - do_questionnaire_bridge (&stp, &priority, &fwd_delay, &hello_time, - &max_age, &ageing_time, &mac); - - /* Use connection's ifname as 'bridge' ifname if exists, else generate one */ - ifname = nm_setting_connection_get_interface_name (s_con); - if (!ifname) - bridge_ifname = unique_master_iface_ifname (all_connections, - NM_SETTING_BRIDGE_SETTING_NAME, - NM_SETTING_BRIDGE_INTERFACE_NAME, - "nm-bridge"); - else - bridge_ifname = g_strdup (ifname); - - if (stp) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (stp, &stp_bool, &tmp_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'stp': %s."), tmp_err->message); - g_clear_error (&tmp_err); - goto cleanup_bridge; - } - } - - /* Add 'bond' setting */ - /* Must be done *before* bridge_prop_string_to_uint() so that the type is known */ - s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - - if (priority) - if (!bridge_prop_string_to_uint (priority, "priority", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_PRIORITY, &stp_prio_int, error)) - goto cleanup_bridge; - if (fwd_delay) - if (!bridge_prop_string_to_uint (fwd_delay, "forward-delay", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_FORWARD_DELAY, &fwd_delay_int, error)) - goto cleanup_bridge; - if (hello_time) - if (!bridge_prop_string_to_uint (hello_time, "hello-time", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_HELLO_TIME, &hello_time_int, error)) - goto cleanup_bridge; - if (max_age) - if (!bridge_prop_string_to_uint (max_age, "max-age", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_MAX_AGE, &max_age_int, error)) - goto cleanup_bridge; - if (ageing_time) - if (!bridge_prop_string_to_uint (ageing_time, "ageing-time", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_AGEING_TIME, &ageing_time_int, error)) - goto cleanup_bridge; - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_bridge; - - /* Set bridge options */ - g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, bridge_ifname, NULL); - if (stp) - g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, stp_bool, NULL); - if (priority) - g_object_set (s_bridge, NM_SETTING_BRIDGE_PRIORITY, stp_prio_int, NULL); - if (fwd_delay) - g_object_set (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY, fwd_delay_int, NULL); - if (hello_time) - g_object_set (s_bridge, NM_SETTING_BRIDGE_HELLO_TIME, hello_time_int, NULL); - if (max_age) - g_object_set (s_bridge, NM_SETTING_BRIDGE_MAX_AGE, max_age_int, NULL); - if (ageing_time) - g_object_set (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME, ageing_time_int, NULL); - if (mac_array) - g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, mac_array, NULL); - - success = TRUE; -cleanup_bridge: - g_free (bridge_ifname); - g_free (stp); - g_free (priority); - g_free (fwd_delay); - g_free (hello_time); - g_free (max_age); - g_free (ageing_time); - g_free (mac); - if (mac_array) - g_byte_array_free (mac_array, TRUE); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, "bridge-slave")) { - /* Build up the settings required for 'bridge-slave' */ - gboolean success = FALSE; - const char *master = NULL; - char *master_ask = NULL; - const char *checked_master = NULL; - const char *type = NULL; - const char *priority_c = NULL; - char *priority = NULL; - const char *path_cost_c = NULL; - char *path_cost = NULL; - const char *hairpin_c = NULL; - char *hairpin = NULL; - unsigned long prio_int, path_cost_int; - gboolean hairpin_bool; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, !ask}, - {"type", TRUE, &type, FALSE}, - {"priority", TRUE, &priority_c, FALSE}, - {"path-cost", TRUE, &path_cost_c, FALSE}, - {"hairpin", TRUE, &hairpin_c, FALSE}, - {NULL} }; - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = NM_SETTING_BRIDGE_SETTING_NAME; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - if (!master && ask) - master = master_ask = nmc_readline (PROMPT_BRIDGE_MASTER); - if (!master) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'master' is required.")); - return FALSE; - } - /* Verify master argument */ - checked_master = verify_master_for_slave (all_connections, master, NM_SETTING_BRIDGE_SETTING_NAME); - if (!checked_master) - printf (_("Warning: master='%s' doesn't refer to any existing profile.\n"), master); - - if (type) - printf (_("Warning: 'type' is currently ignored. " - "We only support ethernet slaves for now.\n")); - - /* Add 'bridge-port' setting */ - /* Must be done *before* bridge_prop_string_to_uint() so that the type is known */ - s_bridge_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge_port)); - - /* Also ask for all optional arguments if '--ask' is specified. */ - priority = priority_c ? g_strdup (priority_c) : NULL; - path_cost = path_cost_c ? g_strdup (path_cost_c) : NULL; - hairpin = hairpin_c ? g_strdup (hairpin_c) : NULL; - if (ask) - do_questionnaire_bridge_slave (&priority, &path_cost, &hairpin); - - if (priority) - if (!bridge_prop_string_to_uint (priority, "priority", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PRIORITY, &prio_int, error)) - goto cleanup_bridge_slave; - if (path_cost) - if (!bridge_prop_string_to_uint (path_cost, "path-cost", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PATH_COST, &path_cost_int, error)) - goto cleanup_bridge_slave; - if (hairpin) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (hairpin, &hairpin_bool, &tmp_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'hairpin': %s."), tmp_err->message); - g_clear_error (&tmp_err); - goto cleanup_bridge_slave; - } - } - - /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, checked_master ? checked_master : _strip_master_prefix (master, NULL), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - if (priority) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PRIORITY, prio_int, NULL); - if (path_cost) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PATH_COST, path_cost_int, NULL); - if (hairpin) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, hairpin_bool, NULL); - - success = TRUE; -cleanup_bridge_slave: - g_free (master_ask); - g_free (priority); - g_free (path_cost); - g_free (hairpin); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_VPN_SETTING_NAME)) { - /* Build up the settings required for 'vpn' */ - gboolean success = FALSE; - const char *vpn_type = NULL; - char *vpn_type_ask = NULL; - const char *user_c = NULL; - char *user = NULL; - const char *st; - char *service_type = NULL; - nmc_arg_t exp_args[] = { {"vpn-type", TRUE, &vpn_type, !ask}, - {"user", TRUE, &user_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!vpn_type && ask) - vpn_type = vpn_type_ask = nmc_readline (PROMPT_VPN_TYPE); - if (!vpn_type) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'vpn-type' is required.")); - goto cleanup_vpn; - } - if (vpn_type_ask) - vpn_type = g_strstrip (vpn_type_ask); - - if (!(st = nmc_string_is_valid (vpn_type, nmc_known_vpns, NULL))) { - printf (_("Warning: 'vpn-type': %s not known.\n"), vpn_type); - st = vpn_type; - } - service_type = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, st); - - /* Also ask for all optional arguments if '--ask' is specified. */ - user = user_c ? g_strdup (user_c) : NULL; - if (ask) - do_questionnaire_vpn (&user); - - /* Add 'vpn' setting */ - s_vpn = (NMSettingVPN *) nm_setting_vpn_new (); - nm_connection_add_setting (connection, NM_SETTING (s_vpn)); - - g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL); - g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, user, NULL); - - success = TRUE; -cleanup_vpn: - g_free (vpn_type_ask); - g_free (service_type); - g_free (user); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_OLPC_MESH_SETTING_NAME)) { - /* Build up the settings required for 'olpc' */ - gboolean success = FALSE; - char *ssid_ask = NULL; - const char *ssid = NULL; - GByteArray *ssid_arr; - const char *channel_c = NULL; - char *channel = NULL; - unsigned long chan; - const char *dhcp_anycast_c = NULL; - char *dhcp_anycast = NULL; - GByteArray *array = NULL; - nmc_arg_t exp_args[] = { {"ssid", TRUE, &ssid, !ask}, - {"channel", TRUE, &channel_c, FALSE}, - {"dhcp-anycast", TRUE, &dhcp_anycast_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!ssid && ask) - ssid = ssid_ask = nmc_readline (_("SSID: ")); - if (!ssid) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'ssid' is required.")); - goto cleanup_olpc; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - channel = channel_c ? g_strdup (channel_c) : NULL; - dhcp_anycast = dhcp_anycast_c ? g_strdup (dhcp_anycast_c) : NULL; - if (ask) - do_questionnaire_olpc (&channel, &dhcp_anycast); - - if (channel) { - if (!nmc_string_to_uint (channel, TRUE, 1, 13, &chan)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'channel': '%s' is not valid; use <1-13>."), - channel); - goto cleanup_olpc; - } - } - if (!check_and_convert_mac (dhcp_anycast, &array, ARPHRD_ETHER, "dhcp-anycast", error)) - goto cleanup_olpc; - - /* Add OLPC mesh setting */ - s_olpc_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new (); - nm_connection_add_setting (connection, NM_SETTING (s_olpc_mesh)); - - ssid_arr = g_byte_array_sized_new (strlen (ssid)); - g_byte_array_append (ssid_arr, (const guint8 *) ssid, strlen (ssid)); - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_SSID, ssid_arr, NULL); - if (channel) - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_CHANNEL, chan, NULL); - else - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_CHANNEL, 1, NULL); - if (array) { - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - g_byte_array_free (ssid_arr, TRUE); - - success = TRUE; -cleanup_olpc: - g_free (ssid_ask); - g_free (channel); - g_free (dhcp_anycast); - if (!success) - return FALSE; - - } else { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s' is not a valid connection type."), - con_type); - return FALSE; - } - - /* Read and add IP configuration */ - if ( strcmp (con_type, "bond-slave") != 0 - && strcmp (con_type, "team-slave") != 0 - && strcmp (con_type, "bridge-slave") != 0) { - - NMIP4Address *ip4addr = NULL; - NMIP6Address *ip6addr = NULL; - const char *ip4 = NULL, *gw4 = NULL, *ip6 = NULL, *gw6 = NULL; - nmc_arg_t exp_args[] = { {"ip4", TRUE, &ip4, FALSE}, {"gw4", TRUE, &gw4, FALSE}, - {"ip6", TRUE, &ip6, FALSE}, {"gw6", TRUE, &gw6, FALSE}, - {NULL} }; - - while (argc) { - nmc_arg_t *p; - - /* reset 'found' flag */ - for (p = exp_args; p->name; p++) - p->found = FALSE; - - ip4 = gw4 = ip6 = gw6 = NULL; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - /* coverity[dead_error_begin] */ - if (ip4) { - ip4addr = nmc_parse_and_build_ip4_address (ip4, gw4, error); - if (!ip4addr) { - g_prefix_error (error, _("Error: ")); - return FALSE; - } - add_ip4_address_to_connection (ip4addr, connection); - } - - /* coverity[dead_error_begin] */ - if (ip6) { - ip6addr = nmc_parse_and_build_ip6_address (ip6, gw6, error); - if (!ip6addr) { - g_prefix_error (error, _("Error: ")); - return FALSE; - } - add_ip6_address_to_connection (ip6addr, connection); - } - } - - /* Ask for addresses if '--ask' is specified. */ - if (ask) - do_questionnaire_ip (connection); - } - - return TRUE; -} - -static char * -unique_connection_name (GSList *list, const char *try_name) -{ - NMConnection *connection; - const char *name; - char *new_name; - unsigned int num = 1; - GSList *iterator = list; - - new_name = g_strdup (try_name); - while (iterator) { - connection = NM_CONNECTION (iterator->data); - - name = nm_connection_get_id (connection); - if (g_strcmp0 (new_name, name) == 0) { - g_free (new_name); - new_name = g_strdup_printf ("%s-%d", try_name, num++); - iterator = list; - } - iterator = g_slist_next (iterator); - } - return new_name; -} - -typedef struct { - NmCli *nmc; - char *con_name; -} AddConnectionInfo; - -static void -add_connection_cb (NMRemoteSettings *settings, - NMRemoteConnection *connection, - GError *error, - gpointer user_data) -{ - AddConnectionInfo *info = (AddConnectionInfo *) user_data; - NmCli *nmc = info->nmc; - - if (error) { - g_string_printf (nmc->return_text, - _("Error: Failed to add '%s' connection: (%d) %s"), - info->con_name, error->code, error->message); - nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; - } else { - printf (_("Connection '%s' (%s) successfully added.\n"), - nm_connection_get_id (NM_CONNECTION (connection)), - nm_connection_get_uuid (NM_CONNECTION (connection))); - } - - g_free (info->con_name); - g_free (info); - quit (); -} - -static gboolean -add_new_connection (gboolean persistent, - NMRemoteSettings *settings, - NMConnection *connection, - NMRemoteSettingsAddConnectionFunc callback, - gpointer user_data) -{ - if (persistent) - return nm_remote_settings_add_connection (settings, connection, callback, user_data); - else - return nm_remote_settings_add_connection_unsaved (settings, connection, callback, user_data); -} - -static void -update_connection (gboolean persistent, - NMRemoteConnection *connection, - NMRemoteConnectionResultFunc callback, - gpointer user_data) -{ - if (persistent) - nm_remote_connection_commit_changes (connection, callback, user_data); - else - nm_remote_connection_commit_changes_unsaved (connection, callback, user_data); -} - -static char * -gen_func_vpn_types (const char *text, int state) -{ - return nmc_rl_gen_func_basic (text, state, nmc_known_vpns); -} - -static char * -gen_func_bool_values_l10n (const char *text, int state) -{ - const char *words[] = { WORD_LOC_YES, WORD_LOC_NO, NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_ib_type (const char *text, int state) -{ - const char *words[] = { "datagram", "connected", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_bt_type (const char *text, int state) -{ - const char *words[] = { "panu", "dun-gsm", "dun-cdma", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_bond_mode (const char *text, int state) -{ - const char *words[] = { "balance-rr", "active-backup", "balance-xor", "broadcast", - "802.3ad", "balance-tlb", "balance-alb", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} -static char * -gen_func_bond_mon_mode (const char *text, int state) -{ - const char *words[] = { "miimon", "arp", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_master_ifnames (const char *text, int state) -{ - GSList *iter; - GPtrArray *ifnames; - char *ret; - NMConnection *con; - NMSettingConnection *s_con; - const char *con_type, *ifname; - - if (!nm_cli.system_connections) - return NULL; - - /* Disable appending space after completion */ - rl_completion_append_character = '\0'; - - ifnames = g_ptr_array_sized_new (20); - for (iter = nm_cli.system_connections; iter; iter = g_slist_next (iter)) { - con = NM_CONNECTION (iter->data); - s_con = nm_connection_get_setting_connection (con); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - if (g_strcmp0 (con_type, nmc_tab_completion.con_type) != 0) - continue; - ifname = nm_connection_get_virtual_iface_name (con); - g_ptr_array_add (ifnames, (gpointer) ifname); - } - g_ptr_array_add (ifnames, (gpointer) NULL); - - ret = nmc_rl_gen_func_basic (text, state, (const char **) ifnames->pdata); - - g_ptr_array_free (ifnames, TRUE); - return ret; -} - -static gboolean -is_single_word (const char* line) -{ - size_t n1, n2, n3; - - n1 = strspn (line, " \t"); - n2 = strcspn (line+n1, " \t\0") + n1; - n3 = strspn (line+n2, " \t"); - - if (n3 == 0) - return TRUE; - else - return FALSE; -} - -static char ** -nmcli_con_add_tab_completion (const char *text, int start, int end) -{ - char **match_array = NULL; - rl_compentry_func_t *generator_func = NULL; - - /* Disable readline's default filename completion */ - rl_attempted_completion_over = 1; - - /* Restore standard append character to space */ - rl_completion_append_character = ' '; - - if (!is_single_word (rl_line_buffer)) - return NULL; - - if (g_strcmp0 (rl_prompt, PROMPT_CON_TYPE) == 0) - generator_func = gen_connection_types; - else if (g_strcmp0 (rl_prompt, PROMPT_VPN_TYPE) == 0) - generator_func = gen_func_vpn_types; - else if ( g_strcmp0 (rl_prompt, PROMPT_BOND_MASTER) == 0 - || g_strcmp0 (rl_prompt, PROMPT_TEAM_MASTER) == 0 - || g_strcmp0 (rl_prompt, PROMPT_BRIDGE_MASTER) == 0) - generator_func = gen_func_master_ifnames; - else if ( g_str_has_suffix (rl_prompt, prompt_yes_no (TRUE, NULL)) - || g_str_has_suffix (rl_prompt, prompt_yes_no (TRUE, ":")) - || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, NULL)) - || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, ":"))) - generator_func = gen_func_bool_values_l10n; - else if (g_str_has_suffix (rl_prompt, PROMPT_IB_MODE)) - generator_func = gen_func_ib_type; - else if (g_str_has_suffix (rl_prompt, PROMPT_BT_TYPE)) - generator_func = gen_func_bt_type; - else if (g_str_has_prefix (rl_prompt, PROMPT_BOND_MODE)) - generator_func = gen_func_bond_mode; - else if (g_str_has_suffix (rl_prompt, PROMPT_BOND_MON_MODE)) - generator_func = gen_func_bond_mon_mode; - - if (generator_func) - match_array = rl_completion_matches (text, generator_func); - - return match_array; -} - -static NMCResultCode -do_connection_add (NmCli *nmc, int argc, char **argv) -{ - NMConnection *connection = NULL; - NMSettingConnection *s_con; - char *uuid; - char *default_name = NULL; - const char *type = NULL; - char *type_ask = NULL; - const char *con_name = NULL; - const char *autoconnect = NULL; - gboolean auto_bool = TRUE; - const char *ifname = NULL; - char *ifname_ask = NULL; - gboolean ifname_mandatory = TRUE; - const char *save = NULL; - gboolean save_bool = TRUE; - AddConnectionInfo *info = NULL; - const char *setting_name; - GError *error = NULL; - nmc_arg_t exp_args[] = { {"type", TRUE, &type, !nmc->ask}, - {"con-name", TRUE, &con_name, FALSE}, - {"autoconnect", TRUE, &autoconnect, FALSE}, - {"ifname", TRUE, &ifname, FALSE}, - {"save", TRUE, &save, FALSE}, - {NULL} }; - - rl_attempted_completion_function = (rl_completion_func_t *) nmcli_con_add_tab_completion; - - nmc->return_value = NMC_RESULT_SUCCESS; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, &error)) { - g_string_assign (nmc->return_text, error->message); - nmc->return_value = error->code; - g_clear_error (&error); - goto error; - } - - if (!type && nmc->ask) { - char *types_tmp = get_valid_options_string (nmc_valid_connection_types); - printf ("Valid types: [%s]\n", types_tmp); - type = type_ask = nmc_readline (PROMPT_CON_TYPE); - g_free (types_tmp); - } - if (!type) { - g_string_printf (nmc->return_text, _("Error: 'type' argument is required.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - if (type_ask) - type = g_strstrip (type_ask); - - if (!(setting_name = check_valid_name (type, nmc_valid_connection_types, &error))) { - g_string_printf (nmc->return_text, _("Error: invalid connection type; %s."), - error->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&error); - goto error; - } - if (autoconnect) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (autoconnect, &auto_bool, &tmp_err)) { - g_string_printf (nmc->return_text, _("Error: 'autoconnect': %s."), - tmp_err->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&tmp_err); - goto error; - } - } - if (save) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (save, &save_bool, &tmp_err)) { - g_string_printf (nmc->return_text, _("Error: 'save': %s."), - tmp_err->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&tmp_err); - goto error; - } - } - - /* ifname is mandatory for all connection types except virtual ones (bond, team, bridge, vlan) */ - if ( strcmp (type, NM_SETTING_BOND_SETTING_NAME) == 0 - || strcmp (type, NM_SETTING_TEAM_SETTING_NAME) == 0 - || strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME) == 0 - || strcmp (type, NM_SETTING_VLAN_SETTING_NAME) == 0) - ifname_mandatory = FALSE; - - if (!ifname && ifname_mandatory && nmc->ask) { - ifname = ifname_ask = nmc_readline (_("Interface name [*]: ")); - if (!ifname) - ifname = ifname_ask = g_strdup ("*"); - } - if (!ifname && ifname_mandatory) { - g_string_printf (nmc->return_text, _("Error: 'ifname' argument is required.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - if (ifname) { - if (!nm_utils_iface_valid_name (ifname) && strcmp (ifname, "*") != 0) { - g_string_printf (nmc->return_text, - _("Error: 'ifname': '%s' is not a valid interface nor '*'."), - ifname); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - /* Special value of '*' means no specific interface name */ - if (strcmp (ifname, "*") == 0) - ifname = NULL; - } - - /* Create a new connection object */ - connection = nm_connection_new (); - - /* Build up the 'connection' setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - uuid = nm_utils_uuid_generate (); - if (con_name) - default_name = g_strdup (con_name); - else { - char *try_name = ifname ? - g_strdup_printf ("%s-%s", get_name_alias (setting_name, nmc_valid_connection_types), ifname) - : g_strdup (get_name_alias (setting_name, nmc_valid_connection_types)); - default_name = unique_connection_name (nmc->system_connections, try_name); - g_free (try_name); - } - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, default_name, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, setting_name, - NM_SETTING_CONNECTION_AUTOCONNECT, auto_bool, - NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, - NULL); - g_free (uuid); - g_free (default_name); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - if (!complete_connection_by_type (connection, - setting_name, - nmc->system_connections, - nmc->ask, - argc, - argv, - &error)) { - g_string_assign (nmc->return_text, error->message); - nmc->return_value = error->code; - g_clear_error (&error); - goto error; - } - - nmc->should_wait = TRUE; - - info = g_malloc0 (sizeof (AddConnectionInfo)); - info->nmc = nmc; - info->con_name = g_strdup (nm_connection_get_id (connection)); - - /* Tell the settings service to add the new connection */ - add_new_connection (save_bool, - nmc->system_settings, - connection, - add_connection_cb, - info); - - if (connection) - g_object_unref (connection); - - return nmc->return_value; - -error: - if (connection) - g_object_unref (connection); - g_free (type_ask); - g_free (ifname_ask); - - nmc->should_wait = FALSE; - return nmc->return_value; -} - - -/*----------------------------------------------------------------------------*/ -/* Functions for readline TAB completion in editor */ - -static void -uuid_display_hook (char **array, int len, int max_len) -{ - NMConnection *con; - int i, max = 0; - char *tmp; - const char *id; - - for (i = 1; i <= len; i++) { - con = nmc_find_connection (nmc_tab_completion.nmc->system_connections, "uuid", array[i], NULL); - id = con ? nm_connection_get_id (con) : NULL; - if (id) { - tmp = g_strdup_printf ("%s (%s)", array[i], id); - g_free (array[i]); - array[i] = tmp; - if (max < strlen (id)) - max = strlen (id); - } - } - rl_display_match_list (array, len, max_len + max + 3); - rl_forced_update_display (); -} - -static char *pre_input_deftext; -static int -set_deftext (void) -{ - if (pre_input_deftext && rl_startup_hook) { - rl_insert_text (pre_input_deftext); - g_free (pre_input_deftext); - pre_input_deftext = NULL; - rl_startup_hook = NULL; - } - return 0; -} - -static char * -gen_nmcli_cmds_menu (const char *text, int state) -{ - const char *words[] = { "goto", "set", "remove", "describe", "print", "verify", - "save", "activate", "back", "help", "quit", "nmcli", - NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_nmcli_cmds_submenu (const char *text, int state) -{ - const char *words[] = { "set", "add", "change", "remove", "describe", - "print", "back", "help", "quit", - NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_nmcli (const char *text, int state) -{ - const char *words[] = { "status-line", "save-confirmation", "prompt-color", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_nmcli_prompt_color (const char *text, int state) -{ - const char *words[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_bool_values (const char *text, int state) -{ - const char *words[] = { "yes", "no", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_verify0 (const char *text, int state) -{ - const char *words[] = { "all", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_print0 (const char *text, int state) -{ - static char **words = NULL; - char *ret = NULL; - - if (!state) { - GHashTable *settings; - GHashTableIter iter; - const char *setting_name; - int i = 0; - - settings = nm_connection_to_hash (nmc_tab_completion.connection, NM_SETTING_HASH_FLAG_NO_SECRETS); - words = g_new (char *, g_hash_table_size (settings) + 2); - g_hash_table_iter_init (&iter, settings); - while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, NULL)) - words [i++] = g_strdup (setting_name); - words[i++] = g_strdup ("all"); - words[i] = NULL; - g_hash_table_unref (settings); - } - - if (words) { - ret = nmc_rl_gen_func_basic (text, state, (const char **) words); - if (ret == NULL) { - g_strfreev (words); - words = NULL; - } - } - return ret; -} - -static char * -gen_cmd_print2 (const char *text, int state) -{ - const char *words[] = { "setting", "connection", "all", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_save (const char *text, int state) -{ - const char *words[] = { "persistent", "temporary", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_connection_types (const char *text, int state) -{ - static int list_idx, len; - const char *c_type, *a_type; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - while (nmc_valid_connection_types[list_idx].name) { - a_type = nmc_valid_connection_types[list_idx].alias; - c_type = nmc_valid_connection_types[list_idx].name; - list_idx++; - if (a_type && !strncmp (text, a_type, len)) - return g_strdup (a_type); - if (c_type && !strncmp (text, c_type, len)) - return g_strdup (c_type); - } - - return NULL; -} - -static char * -gen_setting_names (const char *text, int state) -{ - static int list_idx, len; - const char *s_name, *a_name; - const NameItem *valid_settings_arr; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - if (!valid_settings_arr) - return NULL; - while (valid_settings_arr[list_idx].name) { - a_name = valid_settings_arr[list_idx].alias; - s_name = valid_settings_arr[list_idx].name; - list_idx++; - if (len == 0 && a_name) - return g_strdup_printf ("%s (%s)", s_name, a_name); - if (a_name && !strncmp (text, a_name, len)) - return g_strdup (a_name); - if (s_name && !strncmp (text, s_name, len)) - return g_strdup (s_name); - } - return NULL; -} - -static char * -gen_property_names (const char *text, int state) -{ - NMSetting *setting = NULL; - char **valid_props = NULL; - char *ret = NULL; - const char *line = rl_line_buffer; - const char *setting_name; - char **strv = NULL; - const NameItem *valid_settings_arr; - const char *p1; - - /* Try to get the setting from 'line' - setting_name.property */ - p1 = strchr (line, '.'); - if (p1) { - while (p1 > line && !g_ascii_isspace (*p1)) - p1--; - - strv = g_strsplit (p1+1, ".", 2); - - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - setting_name = check_valid_name (strv[0], valid_settings_arr, NULL); - setting = nmc_setting_new_for_name (setting_name); - } else { - /* Else take the current setting, if any */ - setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; - } - - if (setting) { - valid_props = nmc_setting_get_valid_properties (setting); - ret = nmc_rl_gen_func_basic (text, state, (const char **) valid_props); - } - - g_strfreev (strv); - g_strfreev (valid_props); - if (setting) - g_object_unref (setting); - return ret; -} - -static char * -gen_compat_devices (const char *text, int state) -{ - int i, j = 0; - const GPtrArray *devices; - const char **compatible_devices; - char *ret; - - devices = nm_client_get_devices (nmc_tab_completion.nmc->client); - if (!devices || devices->len < 1) - return NULL; - - compatible_devices = g_new (const char *, devices->len + 1); - for (i = 0; i < devices->len; i++) { - NMDevice *dev = g_ptr_array_index (devices, i); - const char *ifname = nm_device_get_iface (dev); - NMDevice *device = NULL; - const char *spec_object = NULL; - - if (find_device_for_connection (nmc_tab_completion.nmc, nmc_tab_completion.connection, - ifname, NULL, NULL, &device, &spec_object, NULL)) { - compatible_devices[j++] = ifname; - } - } - compatible_devices[j] = NULL; - - ret = nmc_rl_gen_func_basic (text, state, compatible_devices); - - g_free (compatible_devices); - return ret; -} - -static char * -gen_vpn_uuids (const char *text, int state) -{ - GSList *iter; - guint len; - int i = 0; - const char **uuids; - char *ret; - - len = g_slist_length (nmc_tab_completion.nmc->system_connections); - if (len < 1) - return NULL; - - uuids = g_new (const char *, len + 1); - for (iter = nmc_tab_completion.nmc->system_connections; iter; iter = g_slist_next (iter)) { - const char *type = nm_connection_get_connection_type (NM_CONNECTION (iter->data)); - - if (g_strcmp0 (type, NM_SETTING_VPN_SETTING_NAME) == 0) - uuids[i++] = nm_connection_get_uuid (NM_CONNECTION (iter->data)); - } - uuids[i] = NULL; - - ret = nmc_rl_gen_func_basic (text, state, uuids); - - g_free (uuids); - return ret; -} - -static rl_compentry_func_t * -get_gen_func_cmd_nmcli (const char *str) -{ - if (!str) - return NULL; - if (matches (str, "status-line") == 0) - return gen_func_bool_values; - if (matches (str, "save-confirmation") == 0) - return gen_func_bool_values; - if (matches (str, "prompt-color") == 0) - return gen_cmd_nmcli_prompt_color; - return NULL; -} - -/* - * Helper function parsing line for completion. - * IN: - * line : the whole line to be parsed - * end : the position of cursor in the line - * cmd : command to match - * OUT: - * cw_num : is set to the word number being completed (1, 2, 3, 4). - * prev_word : returns the previous word (so that we have some context). - * - * Returns TRUE when the first word of the 'line' matches 'cmd'. - * - * Examples: - * line="rem" cmd="remove" -> TRUE cw_num=1 - * line="set con" cmd="set" -> TRUE cw_num=2 - * line="go ipv4.method" cmd="goto" -> TRUE cw_num=2 - * line=" des eth.mtu " cmd="describe" -> TRUE cw_num=3 - * line=" bla ipv4.method" cmd="goto" -> FALSE - */ -static gboolean -should_complete_cmd (const char *line, int end, const char *cmd, - int *cw_num, char **prev_word) -{ - char *tmp; - const char *word1, *word2, *word3; - size_t n1, n2, n3, n4, n5, n6; - gboolean word1_done, word2_done, word3_done; - gboolean ret = FALSE; - - if (!line) - return FALSE; - - tmp = g_strdup (line); - - n1 = strspn (tmp, " \t"); - n2 = strcspn (tmp+n1, " \t\0") + n1; - n3 = strspn (tmp+n2, " \t") + n2; - n4 = strcspn (tmp+n3, " \t\0") + n3; - n5 = strspn (tmp+n4, " \t") + n4; - n6 = strcspn (tmp+n5, " \t\0") + n5; - - word1_done = end > n2; - word2_done = end > n4; - word3_done = end > n6; - tmp[n2] = tmp[n4] = tmp[n6] = '\0'; - - word1 = tmp[n1] ? tmp + n1 : NULL; - word2 = tmp[n3] ? tmp + n3 : NULL; - word3 = tmp[n5] ? tmp + n5 : NULL; - - if (!word1_done) { - if (cw_num) - *cw_num = 1; - if (prev_word) - *prev_word = NULL; - } else if (!word2_done) { - if (cw_num) - *cw_num = 2; - if (prev_word) - *prev_word = g_strdup (word1); - } else if (!word3_done) { - if (cw_num) - *cw_num = 3; - if (prev_word) - *prev_word = g_strdup (word2); - } else { - if (cw_num) - *cw_num = 4; - if (prev_word) - *prev_word = g_strdup (word3); - } - - if (word1 && matches (word1, cmd) == 0) - ret = TRUE; - - g_free (tmp); - return ret; -} - -static char * -extract_property_name (const char *prompt, const char *line) -{ - char *prop = NULL; - - /* If prompt is set take the property name from it, else extract it from line */ - if (!prompt) { - const char *p1; - size_t num; - p1 = strchr (line, '.'); - if (p1) { - p1++; - } else { - size_t n1, n2, n3; - n1 = strspn (line, " \t"); - n2 = strcspn (line+n1, " \t\0") + n1; - n3 = strspn (line+n2, " \t") + n2; - p1 = line + n3; - } - num = strcspn (p1, " \t\0"); - prop = g_strndup (p1, num); - } else { - const char *p1, *dot; - size_t num; - p1 = strchr (prompt, ' '); - /* prompt looks like this: "nmcli 802-1x>" or "nmcli 802-1x.pac-file>" */ - if (p1) { - dot = strchr (p1 + 1, '.'); - p1 = dot ? dot + 1 : p1; - num = strcspn (p1, ">"); - prop = g_strndup (p1, num); - } - } - - return prop; -} - -static gboolean -should_complete_files (const char *prompt, const char *line) -{ - char *prop; - gboolean found = FALSE; - const char *file_properties[] = { - /* '802-1x' properties */ - "ca-cert", - "ca-path", - "client-cert", - "pac-file", - "phase2-ca-cert", - "phase2-ca-path", - "phase2-client-cert", - "private-key", - "phase2-private-key", - /* 'team' and 'team-port' properties */ - "config", - NULL - }; - - prop = extract_property_name (prompt, line); - if (prop) { - found = !!nmc_string_is_valid (prop, file_properties, NULL); - g_free (prop); - } - return found; -} - -static gboolean -should_complete_vpn_uuids (const char *prompt, const char *line) -{ - char *prop; - gboolean found = FALSE; - const char *uuid_properties[] = { - /* 'connection' properties */ - "secondaries", - NULL - }; - - prop = extract_property_name (prompt, line); - if (prop) { - found = !!nmc_string_is_valid (prop, uuid_properties, NULL); - g_free (prop); - } - return found; -} - -/* from readline */ -extern int rl_complete_with_tilde_expansion; - -/* - * Attempt to complete on the contents of TEXT. START and END show the - * region of TEXT that contains the word to complete. We can use the - * entire line in case we want to do some simple parsing. Return the - * array of matches, or NULL if there aren't any. - */ -static char ** -nmcli_editor_tab_completion (const char *text, int start, int end) -{ - char **match_array = NULL; - const char *line = rl_line_buffer; - const char *prompt = rl_prompt; - rl_compentry_func_t *generator_func = NULL; - gboolean copy_char; - const char *p1; - char *p2, *prompt_tmp; - char *word = NULL; - size_t n1; - int num; - - /* Restore standard append character to space */ - rl_completion_append_character = ' '; - - /* Restore standard function for displaying matches */ - rl_completion_display_matches_hook = NULL; - - /* Disable default filename completion */ - rl_attempted_completion_over = 1; - - /* Enable tilde expansion when filenames are completed */ - rl_complete_with_tilde_expansion = 1; - - /* Filter out possible ANSI color escape sequences */ - p1 = prompt; - p2 = prompt_tmp = g_strdup (prompt); - copy_char = TRUE; - while (*p1) { - if (*p1 == '\33') - copy_char = FALSE; - if (copy_char) - *p2++ = *p1; - if (!copy_char && *p1 == 'm') - copy_char = TRUE; - p1++; - } - *p2 = '\0'; - - /* Find the first non-space character */ - n1 = strspn (line, " \t"); - - /* Choose the right generator function */ - if (strcmp (prompt_tmp, EDITOR_PROMPT_CON_TYPE) == 0) - generator_func = gen_connection_types; - else if (strcmp (prompt_tmp, EDITOR_PROMPT_SETTING) == 0) - generator_func = gen_setting_names; - else if (strcmp (prompt_tmp, EDITOR_PROMPT_PROPERTY) == 0) - generator_func = gen_property_names; - else if ( g_str_has_suffix (rl_prompt, prompt_yes_no (TRUE, NULL)) - || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, NULL))) - generator_func = gen_func_bool_values_l10n; - else if (g_str_has_prefix (prompt_tmp, "nmcli")) { - if (!strchr (prompt_tmp, '.')) { - int level = g_str_has_prefix (prompt_tmp, "nmcli>") ? 0 : 1; - const char *dot = strchr (line, '.'); - - /* Main menu - level 0,1 */ - if (start == n1) - generator_func = gen_nmcli_cmds_menu; - else { - if (should_complete_cmd (line, end, "goto", &num, NULL) && num <= 2) { - if (level == 0 && (!dot || dot >= line + end)) - generator_func = gen_setting_names; - else - generator_func = gen_property_names; - } else if (should_complete_cmd (line, end, "set", &num, NULL)) { - if (num < 3) { - if (level == 0 && (!dot || dot >= line + end)) { - generator_func = gen_setting_names; - rl_completion_append_character = '.'; - } else - generator_func = gen_property_names; - } else if (num >= 3) { - if (num == 3 && should_complete_files (NULL, line)) - rl_attempted_completion_over = 0; - if (should_complete_vpn_uuids (NULL, line)) { - rl_completion_display_matches_hook = uuid_display_hook; - generator_func = gen_vpn_uuids; - } - } - } else if ( ( should_complete_cmd (line, end, "remove", &num, NULL) - || should_complete_cmd (line, end, "describe", &num, NULL)) - && num <= 2) { - if (level == 0 && (!dot || dot >= line + end)) { - generator_func = gen_setting_names; - rl_completion_append_character = '.'; - } else - generator_func = gen_property_names; - } else if (should_complete_cmd (line, end, "nmcli", &num, &word)) { - if (num < 3) - generator_func = gen_cmd_nmcli; - else if (num == 3) - generator_func = get_gen_func_cmd_nmcli (word); - } else if (should_complete_cmd (line, end, "print", &num, NULL) && num <= 2) { - if (level == 0 && (!dot || dot >= line + end)) - generator_func = gen_cmd_print0; - else - generator_func = gen_property_names; - } else if (should_complete_cmd (line, end, "verify", &num, NULL) && num <= 2) { - generator_func = gen_cmd_verify0; - } else if (should_complete_cmd (line, end, "activate", &num, NULL) && num <= 2) { - generator_func = gen_compat_devices; - } else if (should_complete_cmd (line, end, "save", &num, NULL) && num <= 2) { - generator_func = gen_cmd_save; - } else if (should_complete_cmd (line, end, "help", &num, NULL) && num <= 2) - generator_func = gen_nmcli_cmds_menu; - } - } else { - /* Submenu - level 2 */ - if (start == n1) - generator_func = gen_nmcli_cmds_submenu; - else { - if ( should_complete_cmd (line, end, "add", &num, NULL) - || should_complete_cmd (line, end, "set", &num, NULL)) { - if (num <= 2 && should_complete_files (prompt_tmp, line)) - rl_attempted_completion_over = 0; - else if (should_complete_vpn_uuids (prompt_tmp, line)) { - rl_completion_display_matches_hook = uuid_display_hook; - generator_func = gen_vpn_uuids; - } - } - if (should_complete_cmd (line, end, "print", &num, NULL) && num <= 2) - generator_func = gen_cmd_print2; - else if (should_complete_cmd (line, end, "help", &num, NULL) && num <= 2) - generator_func = gen_nmcli_cmds_submenu; - } - } - } - - if (generator_func) - match_array = rl_completion_matches (text, generator_func); - - g_free (prompt_tmp); - g_free (word); - return match_array; -} - -#define NMCLI_EDITOR_HISTORY ".nmcli-history" - -static void -load_history_cmds (const char *uuid) -{ - GKeyFile *kf; - char *filename; - char **keys; - char *line; - size_t i; - GError *err = NULL; - - filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); - kf = g_key_file_new (); - if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { - if (err->code == G_KEY_FILE_ERROR_PARSE) - printf ("Warning: %s parse error: %s\n", filename, err->message); - g_key_file_free (kf); - g_free (filename); - return; - } - keys = g_key_file_get_keys (kf, uuid, NULL, NULL); - for (i = 0; keys && keys[i]; i++) { - line = g_key_file_get_string (kf, uuid, keys[i], NULL); - if (line && *line) - add_history (line); - g_free (line); - } - g_strfreev (keys); - g_key_file_free (kf); - g_free (filename); -} - -static void -save_history_cmds (const char *uuid) -{ - HIST_ENTRY **hist = NULL; - GKeyFile *kf; - char *filename; - size_t i; - char *key; - char *data; - gsize len = 0; - GError *err = NULL; - - hist = history_list (); - if (hist) { - filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); - kf = g_key_file_new (); - if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { - if ( err->code != G_FILE_ERROR_NOENT - && err->code != G_KEY_FILE_ERROR_NOT_FOUND) { - printf ("Warning: %s parse error: %s\n", filename, err->message); - g_key_file_free (kf); - g_free (filename); - g_clear_error (&err); - return; - } - g_clear_error (&err); - } - - /* Remove previous history group and save new history entries */ - g_key_file_remove_group (kf, uuid, NULL); - for (i = 0; hist[i]; i++) - { - key = g_strdup_printf ("%zd", i); - g_key_file_set_string (kf, uuid, key, hist[i]->line); - g_free (key); - } - - /* Write history to file */ - data = g_key_file_to_data (kf, &len, NULL); - if (data) { - g_file_set_contents (filename, data, len, NULL); - g_free (data); - } - g_key_file_free (kf); - g_free (filename); - } -} - -/*----------------------------------------------------------------------------*/ - -static void -editor_show_connection (NMConnection *connection, NmCli *nmc) -{ - nmc->print_output = NMC_PRINT_PRETTY; - nmc->multiline_output = TRUE; - nmc->escape_values = 0; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - nmc_connection_profile_details (connection, nmc); -} - -static void -editor_show_setting (NMSetting *setting, NmCli *nmc) -{ - printf (_("['%s' setting values]\n"), - nm_setting_get_name (setting)); - - nmc->print_output = NMC_PRINT_NORMAL; - nmc->multiline_output = TRUE; - nmc->escape_values = 0; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - setting_details (setting, nmc, NULL); -} - -typedef enum { - NMC_EDITOR_MAIN_CMD_UNKNOWN = 0, - NMC_EDITOR_MAIN_CMD_GOTO, - NMC_EDITOR_MAIN_CMD_REMOVE, - NMC_EDITOR_MAIN_CMD_SET, - NMC_EDITOR_MAIN_CMD_DESCRIBE, - NMC_EDITOR_MAIN_CMD_PRINT, - NMC_EDITOR_MAIN_CMD_VERIFY, - NMC_EDITOR_MAIN_CMD_SAVE, - NMC_EDITOR_MAIN_CMD_ACTIVATE, - NMC_EDITOR_MAIN_CMD_BACK, - NMC_EDITOR_MAIN_CMD_HELP, - NMC_EDITOR_MAIN_CMD_NMCLI, - NMC_EDITOR_MAIN_CMD_QUIT, -} NmcEditorMainCmd; - -static NmcEditorMainCmd -parse_editor_main_cmd (const char *cmd, char **cmd_arg) -{ - NmcEditorMainCmd editor_cmd = NMC_EDITOR_MAIN_CMD_UNKNOWN; - char **vec; - - vec = nmc_strsplit_set (cmd, " \t", 2); - if (g_strv_length (vec) < 1) { - if (cmd_arg) - *cmd_arg = NULL; - return NMC_EDITOR_MAIN_CMD_UNKNOWN; - } - - if (matches (vec[0], "goto") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_GOTO; - else if (matches (vec[0], "remove") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_REMOVE; - else if (matches (vec[0], "set") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_SET; - else if (matches (vec[0], "describe") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_DESCRIBE; - else if (matches (vec[0], "print") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_PRINT; - else if (matches (vec[0], "verify") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_VERIFY; - else if (matches (vec[0], "save") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_SAVE; - else if (matches (vec[0], "activate") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_ACTIVATE; - else if (matches (vec[0], "back") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_BACK; - else if (matches (vec[0], "help") == 0 || strcmp (vec[0], "?") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_HELP; - else if (matches (vec[0], "quit") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_QUIT; - else if (matches (vec[0], "nmcli") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_NMCLI; - - /* set pointer to command argument */ - if (cmd_arg) - *cmd_arg = vec[1] ? g_strstrip (g_strdup (vec[1])) : NULL; - - g_strfreev (vec); - return editor_cmd; -} - -static void -editor_main_usage (void) -{ - printf ("------------------------------------------------------------------------------\n"); - /* TRANSLATORS: do not translate command names and keywords before :: - * However, you should translate terms enclosed in <>. - */ - printf (_("---[ Main menu ]---\n" - "goto [ | ] :: go to a setting or property\n" - "remove [.] | :: remove setting or reset property value\n" - "set [. ] :: set property value\n" - "describe [.] :: describe property\n" - "print [all | [.]] :: print the connection\n" - "verify [all] :: verify the connection\n" - "save [persistent|temporary] :: save the connection\n" - "activate [] [/|] :: activate the connection\n" - "back :: go one level up (back)\n" - "help/? [] :: print this help\n" - "nmcli :: nmcli configuration\n" - "quit :: exit nmcli\n")); - printf ("------------------------------------------------------------------------------\n"); -} - -static void -editor_main_help (const char *command) -{ - if (!command) - editor_main_usage (); - else { - /* detailed command descriptions */ - NmcEditorMainCmd cmd = parse_editor_main_cmd (command, NULL); - - switch (cmd) { - case NMC_EDITOR_MAIN_CMD_GOTO: - printf (_("goto [.] | :: enter setting/property for editing\n\n" - "This command enters into a setting or property for editing it.\n\n" - "Examples: nmcli> goto connection\n" - " nmcli connection> goto secondaries\n" - " nmcli> goto ipv4.addresses\n")); - break; - case NMC_EDITOR_MAIN_CMD_REMOVE: - printf (_("remove [.] :: remove setting or reset property value\n\n" - "This command removes an entire setting from the connection, or if a property\n" - "is given, resets that property to the default value.\n\n" - "Examples: nmcli> remove wifi-sec\n" - " nmcli> remove eth.mtu\n")); - break; - case NMC_EDITOR_MAIN_CMD_SET: - printf (_("set [. ] :: set property value\n\n" - "This command sets property value.\n\n" - "Example: nmcli> set con.id My connection\n")); - break; - case NMC_EDITOR_MAIN_CMD_DESCRIBE: - printf (_("describe [.] :: describe property\n\n" - "Shows property description. You can consult nm-settings(5) " - "manual page to see all NM settings and properties.\n")); - break; - case NMC_EDITOR_MAIN_CMD_PRINT: - printf (_("print [all] :: print setting or connection values\n\n" - "Shows current property or the whole connection.\n\n" - "Example: nmcli ipv4> print all\n")); - break; - case NMC_EDITOR_MAIN_CMD_VERIFY: - printf (_("verify [all] :: verify setting or connection validity\n\n" - "Verifies whether the setting or connection is valid and can " - "be saved later. It indicates invalid values on error.\n\n" - "Examples: nmcli> verify\n" - " nmcli bond> verify\n")); - break; - case NMC_EDITOR_MAIN_CMD_SAVE: - printf (_("save [persistent|temporary] :: save the connection\n\n" - "Sends the connection profile to NetworkManager that either will save it\n" - "persistently, or will only keep it in memory. 'save' without an argument\n" - "means 'save persistent'.\n" - "Note that once you save the profile persistently those settings are saved\n" - "across reboot or restart. Subsequent changes can also be temporary or\n" - "persistent, but any temporary changes will not persist across reboot or\n" - "restart. If you want to fully remove the persistent connection, the connection\n" - "profile must be deleted.\n")); - break; - case NMC_EDITOR_MAIN_CMD_ACTIVATE: - printf (_("activate [] [/|] :: activate the connection\n\n" - "Activates the connection.\n\n" - "Available options:\n" - " - device the connection will be activated on\n" - "/| - AP (Wi-Fi) or NSP (WiMAX) (prepend with / when is not specified)\n")); - break; - case NMC_EDITOR_MAIN_CMD_BACK: - printf (_("back :: go to upper menu level\n\n")); - break; - case NMC_EDITOR_MAIN_CMD_HELP: - printf (_("help/? [] :: help for the nmcli commands\n\n")); - break; - case NMC_EDITOR_MAIN_CMD_NMCLI: - printf (_("nmcli [ ] :: nmcli configuration\n\n" - "Configures nmcli. The following options are available:\n" - "status-line yes | no [default: no]\n" - "save-confirmation yes | no [default: yes]\n" - "prompt-color <0-8> [default: 0]\n" - " 0 = normal\n" - " 1 = \33[30mblack\33[0m\n" - " 2 = \33[31mred\33[0m\n" - " 3 = \33[32mgreen\33[0m\n" - " 4 = \33[33myellow\33[0m\n" - " 5 = \33[34mblue\33[0m\n" - " 6 = \33[35mmagenta\33[0m\n" - " 7 = \33[36mcyan\33[0m\n" - " 8 = \33[37mwhite\33[0m\n" - "\n" - "Examples: nmcli> nmcli status-line yes\n" - " nmcli> nmcli save-confirmation no\n" - " nmcli> nmcli prompt-color 3\n")); - break; - case NMC_EDITOR_MAIN_CMD_QUIT: - printf (_("quit :: exit nmcli\n\n" - "This command exits nmcli. When the connection being edited " - "is not saved, the user is asked to confirm the action.\n")); - break; - default: - printf (_("Unknown command: '%s'\n"), command); - break; - } - } -} - -typedef enum { - NMC_EDITOR_SUB_CMD_UNKNOWN = 0, - NMC_EDITOR_SUB_CMD_SET, - NMC_EDITOR_SUB_CMD_ADD, - NMC_EDITOR_SUB_CMD_CHANGE, - NMC_EDITOR_SUB_CMD_REMOVE, - NMC_EDITOR_SUB_CMD_DESCRIBE, - NMC_EDITOR_SUB_CMD_PRINT, - NMC_EDITOR_SUB_CMD_BACK, - NMC_EDITOR_SUB_CMD_HELP, - NMC_EDITOR_SUB_CMD_QUIT -} NmcEditorSubCmd; - -static NmcEditorSubCmd -parse_editor_sub_cmd (const char *cmd, char **cmd_arg) -{ - NmcEditorSubCmd editor_cmd = NMC_EDITOR_SUB_CMD_UNKNOWN; - char **vec; - - vec = nmc_strsplit_set (cmd, " \t", 2); - if (g_strv_length (vec) < 1) { - if (cmd_arg) - *cmd_arg = NULL; - return NMC_EDITOR_SUB_CMD_UNKNOWN; - } - - if (matches (vec[0], "set") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_SET; - else if (matches (vec[0], "add") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_ADD; - else if (matches (vec[0], "change") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_CHANGE; - else if (matches (vec[0], "remove") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_REMOVE; - else if (matches (vec[0], "describe") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_DESCRIBE; - else if (matches (vec[0], "print") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_PRINT; - else if (matches (vec[0], "back") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_BACK; - else if (matches (vec[0], "help") == 0 || strcmp (vec[0], "?") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_HELP; - else if (matches (vec[0], "quit") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_QUIT; - - /* set pointer to command argument */ - if (cmd_arg) - *cmd_arg = g_strdup (vec[1]); - - g_strfreev (vec); - return editor_cmd; -} - -static void -editor_sub_help (void) -{ - printf ("------------------------------------------------------------------------------\n"); - /* TRANSLATORS: do not translate command names and keywords before :: - * However, you should translate terms enclosed in <>. - */ - printf (_("---[ Property menu ]---\n" - "set [] :: set new value\n" - "add [] :: add new option to the property\n" - "change :: change current value\n" - "remove [ |