meson: add gst-ptp-helper
authorTim-Philipp Müller <tim@centricular.com>
Fri, 5 May 2017 10:49:08 +0000 (11:49 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Fri, 5 May 2017 10:49:08 +0000 (11:49 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=774418

config.h.meson
gst/meson.build
libs/gst/helpers/meson.build
libs/gst/helpers/ptp_helper_post_install.sh [new file with mode: 0755]
meson.build
meson_options.txt

index 22949b3..03146df 100644 (file)
 #mesondefine STRUCT_ITIMERSPEC_DEFINITION_MISSING
 #mesondefine clockid_t
 #mesondefine timer_t
+
+#mesondefine HAVE_SIOCGIFCONF_SIOCGIFFLAGS_SIOCGIFHWADDR
+#mesondefine HAVE_GETIFADDRS_AF_LINK
+#mesondefine HAVE_PTP
+#mesondefine HAVE_PTP_HELPER_SETUID_USER
+#mesondefine HAVE_PTP_HELPER_SETUID_GROUP
index 51af4ea..effb6cb 100644 (file)
@@ -154,14 +154,18 @@ else
   gst_registry = []
 endif
 
+# Make copy so configure_file consumes the copy and we can
+# still add to the original cdata later.
+gst_cdata = cdata
+
 configure_file(input : 'gstconfig.h.in',
   output : 'gstconfig.h',
   install_dir : 'include/gstreamer-1.0/gst',
-  configuration : cdata)
+  configuration : gst_cdata)
 gst_version_h = configure_file(input : 'gstversion.h.in',
   output : 'gstversion.h',
   install_dir : 'include/gstreamer-1.0/gst',
-  configuration : cdata)
+  configuration : gst_cdata)
 
 gst_enums = gnome.mkenums('gstenumtypes',
   sources : gst_headers,
index fcba589..124d754 100644 (file)
@@ -1,4 +1,4 @@
-gst_plugin_scanner = executable('gst-plugin-scanner',
+executable('gst-plugin-scanner',
   'gst-plugin-scanner.c',
   c_args : gst_c_args,
   include_directories : [configinc],
@@ -8,10 +8,11 @@ gst_plugin_scanner = executable('gst-plugin-scanner',
   install: true,
 )
 
+# Used in test env setup to make tests find plugin scanner in build tree
 gst_scanner_dir = meson.current_build_dir()
 
 if bashcomp_found
-  gst_completion_helper = executable('gst-completion-helper',
+  executable('gst-completion-helper',
     'gst-completion-helper.c',
     c_args : gst_c_args,
     include_directories : [configinc],
@@ -21,4 +22,113 @@ if bashcomp_found
   )
 endif
 
-# FIXME: gst-ptp-helper
+# Check PTP support
+have_ptp = false
+if host_machine.system() == 'android'
+  message('PTP not supported on Android because of permissions.')
+elif host_machine.system() == 'windows'
+  message('PTP not supported on Windows, not ported yet.')
+elif host_machine.system() == 'ios' # FIXME: is it also darwing on iOS ?
+  message('PTP not supported on iOS because of permissions.')
+elif host_machine.system() == 'darwin'
+  if cc.has_header('MobileCoreServices/MobileCoreServices.h')
+    message('PTP not supported on iOS because of permissions.')
+  else
+    have_ptp = true
+  endif
+elif ['linux', 'netbsd', 'freebsd', 'openbsd', 'kfreebsd', 'dragonfly', 'solaris'].contains(host_machine.system())
+  message('PTP supported on ' + host_machine.system() + '.')
+  have_ptp = true
+endif
+
+if have_ptp
+  cdata.set('HAVE_PTP', 1, description : 'PTP support available')
+
+  if cc.compiles('''#include <sys/ioctl.h>
+                    #include <net/if.h>
+                    int some_func (void) {
+                      struct ifreq ifr;
+                      struct ifconf ifc;
+                      ioctl(0, SIOCGIFCONF, &ifc);
+                      ioctl(0, SIOCGIFFLAGS, &ifr);
+                      ioctl(0, SIOCGIFHWADDR, &ifr);
+                      return ifr.ifr_hwaddr.sa_data[0];
+                    }''',
+                 name : 'SIOCGIFCONF, SIOCGIFFLAGS and SIOCGIFHWADDR available')
+    cdata.set('HAVE_SIOCGIFCONF_SIOCGIFFLAGS_SIOCGIFHWADDR', 1,
+      description : 'SIOCGIFCONF, SIOCGIFFLAGS and SIOCGIFHWADDR is available')
+  endif
+
+  if cc.compiles('''#include <ifaddrs.h>
+                    #include <net/if.h>
+                    #include <net/if_dl.h>
+                    int some_func (void) {
+                      struct ifaddrs *ifaddr;
+                      getifaddrs(&ifaddr);
+                      return (ifaddr->ifa_flags & IFF_LOOPBACK) && ifaddr->ifa_addr->sa_family != AF_LINK;
+                    }''', name : 'getifaddrs() and AF_LINK available')
+    cdata.set('HAVE_GETIFADDRS_AF_LINK', 1,
+      description : 'getifaddrs() and AF_LINK is available')
+  endif
+
+  gst_ptp_have_cap = false
+  cap_dep = []
+  if cc.has_header('sys/capability.h')
+    cap_dep = find_library('cap', required : false)
+    if cap_dep.found() and cc.has_function('cap_init', dependencies : cap_dep)
+      gst_ptp_have_cap = true
+    endif
+  endif
+
+  setcap = find_program('setcap', '/usr/bin/setcap', '/sbin/setcap', required : false)
+
+  # user/group to change to in gst-ptp-helper
+  ptp_helper_setuid_user = get_option('with-ptp-helper-setuid-user')
+  if ptp_helper_setuid_user != ''
+    cdata.set_quoted('HAVE_PTP_HELPER_SETUID_USER', ptp_helper_setuid_user,
+      description : 'PTP helper setuid user')
+  endif
+  ptp_helper_setuid_group = get_option('with-ptp-helper-setuid-group')
+  if ptp_helper_setuid_group != ''
+    cdata.set_quoted('HAVE_PTP_HELPER_SETUID_GROUP', ptp_helper_setuid_group,
+      description : 'PTP helper setuid group')
+  endif
+
+  # how to install gst-ptp-helper
+  with_ptp_helper_permissions = get_option('with-ptp-helper-permissions')
+  if with_ptp_helper_permissions == 'auto'
+    if gst_ptp_have_cap and setcap.found()
+      with_ptp_helper_permissions = 'capabilities'
+    else
+      with_ptp_helper_permissions = 'setuid-root'
+    endif
+  endif
+  message('How to install gst-ptp-helper: ' + with_ptp_helper_permissions)
+
+  if with_ptp_helper_permissions == 'none'
+    # nothing to do
+  elif with_ptp_helper_permissions == 'setuid-root'
+    cdata.set('HAVE_PTP_HELPER_SETUID', 1,
+        description : 'Use setuid-root for permissions in PTP helper')
+  elif with_ptp_helper_permissions == 'capabilities'
+    if not setcap.found()
+      error('capabilities-based ptp-helper-permissions requested, but could not find setcap tool.')
+    endif
+    cdata.set('HAVE_PTP_HELPER_CAPABILITIES', 1,
+        description : 'Use capabilities for permissions in PTP helper')
+  else
+    error('Unexpected ptp helper permissions value: ' + with_ptp_helper_permissions)
+  endif
+
+  executable('gst-ptp-helper', 'gst-ptp-helper.c',
+    c_args : gst_c_args,
+    include_directories : [configinc, libsinc],
+    dependencies : [gio_dep, gobject_dep, glib_dep, mathlib, gst_dep, cap_dep],
+    link_with : [printf_lib],
+    install_dir : helpers_install_dir,
+    install : true)
+
+  meson.add_install_script('ptp_helper_post_install.sh',
+      helpers_install_dir, with_ptp_helper_permissions,
+      setcap.found() ? setcap.path() : '')
+endif
diff --git a/libs/gst/helpers/ptp_helper_post_install.sh b/libs/gst/helpers/ptp_helper_post_install.sh
new file mode 100755 (executable)
index 0000000..5e86773
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh
+# Meson install script for gst-ptp-helper
+# Fails silently at the moment if setting permissions/capabilities doesn't work
+helpers_install_dir="$1"
+with_ptp_helper_permissions="$2"
+setcap="$3"
+
+ptp_helper="$MESON_INSTALL_DESTDIR_PREFIX/$helpers_install_dir/gst-ptp-helper"
+
+case "$with_ptp_helper_permissions" in
+  setuid-root)
+    echo "$0: permissions before: "
+    ls -l "$ptp_helper"
+    chown root "$ptp_helper"
+    chmod u+s "$ptp_helper"
+    echo "$0: permissions after: "
+    ls -l "$ptp_helper"
+    ;;
+  capabilities)
+    echo "Calling $setcap cap_net_bind_service,cap_net_admin+ep $ptp_helper"
+    $setcap cap_net_bind_service,cap_net_admin+ep "$ptp_helper"
+    ;;
+  *)
+    echo "$0 ERROR: unexpected permissions value '$with_ptp_helper_permissions'";
+    exit 2;
+esac
index bd2112f..3772997 100644 (file)
@@ -326,10 +326,6 @@ test_deps = [gmp_dep, gsl_dep, gslcblas_dep]
 dl_dep = cc.find_library('dl', required : false)
 cdata.set('HAVE_DLADDR', cc.has_function('dladdr', dependencies : dl_dep))
 
-configure_file(input : 'config.h.meson',
-  output : 'config.h',
-  configuration : cdata)
-
 
 configinc = include_directories('.')
 libsinc = include_directories('libs')
@@ -423,6 +419,10 @@ subdir('tests')
 subdir('po')
 subdir('data')
 
+configure_file(input : 'config.h.meson',
+  output : 'config.h',
+  configuration : cdata)
+
 if build_machine.system() == 'windows'
   message('Disabling gtk-doc while building on Windows')
 elif get_option('disable_gtkdoc')
index 9bc0e29..2f89562 100644 (file)
@@ -11,3 +11,9 @@ option('disable_introspection',
 option('disable_libunwind',
         type : 'boolean', value : false,
         description : 'Whether to disable the usage of libunwind (to generate backtraces)')
+option('with-ptp-helper-setuid-user', type : 'string',
+        description : 'User to switch to when installing gst-ptp-helper setuid root')
+option('with-ptp-helper-setuid-group', type : 'string',
+        description : 'Group to switch to when installing gst-ptp-helper setuid root')
+option('with-ptp-helper-permissions', type : 'combo',
+       choices : ['none', 'setuid-root', 'capabilities', 'auto'], value : 'auto')