Honor system web proxy settings if available and if 'http-system-proxy'
is set to 'yes' in the 'global' section of the 'servers' configuration
file.

This is implemented for MacOSX only where the system web proxy settings
mean the current 'network location' proxy settings.

* ﻿configure.in
  add system configuration framework to link libraries on MacOSX.

* ﻿subversion/include/svn_config.h
  (﻿SVN_CONFIG_OPTION_HTTP_SYSTEM_PROXY): new configration key.

* ﻿subversion/libsvn_subr/config_file.c
  (﻿svn_config_ensure): added 'http-system-proxy' description.

* ﻿subversion/libsvn_ra_dav/session.c
  (﻿get_system_global_proxy): new function, get the system specific web
  proxy settings.
  (﻿get_global_proxy): new function, extracted from get_server_settings.
  Get the 'global' proxy settings from the 'servers' configuration file.
  (﻿get_group_proxy): new function, extracted from get_server_settings.
  Get 'group' proxy settings from the 'servers' configuration file.
  (﻿get_server_settings): check for new configuration key, use extracted
  functions to get proxy settings.
  

Index: configure.in
===================================================================
--- configure.in	(revision 20914)
+++ configure.in	(working copy)
@@ -294,6 +294,16 @@
 fi
 
 
+dnl MacOSX -------------------
+
+case "$host" in
+powerpc-apple-darwin*)
+  # required framework for reading the current "location" proxy.
+  LIBS="$LIBS -framework SystemConfiguration"
+  ;;
+esac
+
+
 dnl I18n -------------------
 
 AC_ARG_ENABLE(nls,
Index: subversion/include/svn_config.h
===================================================================
--- subversion/include/svn_config.h	(revision 20914)
+++ subversion/include/svn_config.h	(working copy)
@@ -1,7 +1,7 @@
 /** 
  * @copyright
  * ====================================================================
- * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
+ * Copyright (c) 2000-2006 CollabNet.  All rights reserved.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
@@ -66,6 +66,7 @@
 #define SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS     "http-proxy-exceptions"
 #define SVN_CONFIG_OPTION_HTTP_TIMEOUT              "http-timeout"
 #define SVN_CONFIG_OPTION_HTTP_COMPRESSION          "http-compression"
+#define SVN_CONFIG_OPTION_HTTP_SYSTEM_PROXY         "http-system-proxy"
 #define SVN_CONFIG_OPTION_NEON_DEBUG_MASK           "neon-debug-mask"
 #define SVN_CONFIG_OPTION_SSL_AUTHORITY_FILES       "ssl-authority-files"
 #define SVN_CONFIG_OPTION_SSL_TRUST_DEFAULT_CA      "ssl-trust-default-ca"
Index: subversion/libsvn_subr/config_file.c
===================================================================
--- subversion/libsvn_subr/config_file.c	(revision 20914)
+++ subversion/libsvn_subr/config_file.c	(working copy)
@@ -2,7 +2,7 @@
  * config_file.c :  parsing configuration files
  *
  * ====================================================================
- * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
+ * Copyright (c) 2000-2006 CollabNet.  All rights reserved.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
@@ -928,7 +928,7 @@
         APR_EOL_STR
         "# [group1]"
         APR_EOL_STR
-"# http-proxy-host = proxy1.some-domain-name.com"
+        "# http-proxy-host = proxy1.some-domain-name.com"
         APR_EOL_STR
         "# http-proxy-port = 80"
         APR_EOL_STR
@@ -986,6 +986,18 @@
         APR_EOL_STR
         "### due to SSL."
         APR_EOL_STR
+        "###"
+        APR_EOL_STR
+        "### 'http-system-proxy' if set to 'yes' use the system web proxy "
+        APR_EOL_STR
+        "### settings if available (currently MacOSX only):"
+        APR_EOL_STR
+        "### - MacOSX: use the current 'network location' proxy settings"
+        APR_EOL_STR
+        "###"
+        APR_EOL_STR
+        ""
+        APR_EOL_STR
         "[global]"
         APR_EOL_STR
         "# http-proxy-exceptions = *.exception.com, www.internal-site.org"
Index: subversion/libsvn_ra_dav/session.c
===================================================================
--- subversion/libsvn_ra_dav/session.c	(revision 20914)
+++ subversion/libsvn_ra_dav/session.c	(working copy)
@@ -2,7 +2,7 @@
  * session.c :  routines for maintaining sessions state (to the DAV server)
  *
  * ====================================================================
- * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
+ * Copyright (c) 2000-2006 CollabNet.  All rights reserved.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
@@ -25,6 +25,7 @@
 #include <apr_want.h>
 #include <apr_general.h>
 #include <apr_xml.h>
+#include <apr_network_io.h>
 
 #include <ne_socket.h>
 #include <ne_request.h>
@@ -46,6 +47,10 @@
 #include "svn_xml.h"
 #include "svn_private_config.h"
 
+#ifdef __APPLE_CC__
+#include <SystemConfiguration/SystemConfiguration.h>
+#endif /*__APPLE_CC__*/
+
 #include "ra_dav.h"
 
 #define DEFAULT_HTTP_TIMEOUT 3600
@@ -350,6 +355,213 @@
   apr_pool_destroy(pool);
 }
 
+/* Get system specific global proxy settings.
+ * On MacOSX this returns the current "location" proxy settings. It doesn't
+ * return anything on other platforms.
+ *
+ * This is a helper function for get_server_settings. See get_server_settings
+ * for the parameter description.
+ */
+static svn_error_t *get_system_global_proxy(const char **proxy_host,
+                                            const char **proxy_port,
+                                            const char **proxy_username,
+                                            const char **proxy_password,
+                                            const char **timeout,
+                                            const char **debug,
+                                            svn_boolean_t *compression,
+                                            svn_config_t *cfg,
+                                            const char *requested_host,
+                                            apr_pool_t *pool)
+{
+#ifdef __APPLE_CC__
+  /* extract location proxy settings from MacOSX system configuration.
+   * @todo extract proxy username and password. How?? I didn't find any
+   * docu
+   */
+  CFDictionaryRef pdict_ref = SCDynamicStoreCopyProxies(NULL);
+
+  if (pdict_ref != NULL)
+    {
+      /* check if a proxy configuration exists. */
+      CFNumberRef penabled_ref = (CFNumberRef)CFDictionaryGetValue(pdict_ref,
+                                                kSCPropNetProxiesHTTPEnable);
+      if (penabled_ref != NULL)
+        {
+           int penabled;
+           Boolean get = CFNumberGetValue(penabled_ref, kCFNumberIntType,
+                                          &penabled);
+           
+           /* if we have a proxy configuration check if requested_host is in
+              the proxy exception list. */
+           if ( get && penabled == 1 /*on*/ )
+             {
+               Boolean except = FALSE;
+               CFArrayRef pexcept_ref;
+               char ehost[APRMAXHOSTLEN] = {};
+
+               /* check if requested_host is in the proxy exception list. */
+               pexcept_ref = (CFArrayRef)CFDictionaryGetValue(pdict_ref,
+                                           kSCPropNetProxiesExceptionsList);
+               if (pexcept_ref)
+                 {
+                   CFIndex size = CFArrayGetCount(pexcept_ref);
+                   CFIndex i;
+                   
+                   for ( i = 0; i < size; i++ )
+                     {
+                       CFStringRef ehost_ref =
+                         (CFStringRef)CFArrayGetValueAtIndex(pexcept_ref, i);
+                       
+                       if (!ehost_ref)
+                         continue;
+                       
+                       Boolean host = CFStringGetCString
+                                        (ehost_ref, ehost, sizeof(ehost),
+                                         kCFStringEncodingUTF8);
+                       if (host)
+                         {
+                            if (apr_strnatcasecmp(requested_host, ehost) == 0)
+                              {
+                                except = TRUE;
+                                break;
+                              }
+                         }
+                     }
+                 }
+
+               /* if requested_host is not in the proxy exception list get the
+                  proxy host and port. */
+               if (!except)
+                 {
+                   CFStringRef phost_ref;
+                   CFNumberRef pport_ref;
+                   Boolean host = FALSE;
+                   Boolean port = FALSE;
+                   char phost[APRMAXHOSTLEN] = {};
+                   int  pport;
+
+                   /* get proxy host */
+                   phost_ref = (CFStringRef)CFDictionaryGetValue(pdict_ref,
+                                              kSCPropNetProxiesHTTPProxy);
+                   if (phost_ref)
+                     host = CFStringGetCString(phost_ref, phost, sizeof(phost),
+                                               kCFStringEncodingUTF8);
+                   if (host)
+                     *proxy_host = apr_pstrdup(pool, phost);
+
+                   /* get proxy port */
+                   pport_ref = (CFNumberRef)CFDictionaryGetValue(pdict_ref,
+                                          kSCPropNetProxiesHTTPPort);
+                   if (pport_ref)
+                     port = CFNumberGetValue(pport_ref, kCFNumberIntType,
+                                             &pport);
+                   if (port)
+                     *proxy_port = apr_itoa(pool, pport);
+                 }
+             }
+        }  
+      CFRelease(pdict_ref);
+    }
+
+    /* MacOSX system doesn't know about these parameters, so simply use the
+       global values. */
+    svn_config_get(cfg, timeout, SVN_CONFIG_SECTION_GLOBAL, 
+                   SVN_CONFIG_OPTION_HTTP_TIMEOUT, NULL);
+    SVN_ERR(svn_config_get_bool(cfg, compression, SVN_CONFIG_SECTION_GLOBAL,
+                                SVN_CONFIG_OPTION_HTTP_COMPRESSION, TRUE));
+    svn_config_get(cfg, debug, SVN_CONFIG_SECTION_GLOBAL, 
+                   SVN_CONFIG_OPTION_NEON_DEBUG_MASK, NULL);
+
+#endif /* __APPLE_CC__ */
+
+  return SVN_NO_ERROR;
+}
+
+/* Get global proxy settings.
+ *
+ * This is a helper function for get_server_settings. See get_server_settings
+ * for the parameter description.
+ */
+static svn_error_t *get_global_proxy(const char **proxy_host,
+                                     const char **proxy_port,
+                                     const char **proxy_username,
+                                     const char **proxy_password,
+                                     const char **timeout,
+                                     const char **debug,
+                                     svn_boolean_t *compression,
+                                     svn_config_t *cfg,
+                                     const char *requested_host,
+                                     apr_pool_t *pool)
+{
+  const char *exceptions;
+  svn_boolean_t is_exception = FALSE;
+  
+  /* If there are defaults, use them, but only if the requested host
+     is not one of the exceptions to the defaults. */
+  svn_config_get(cfg, &exceptions, SVN_CONFIG_SECTION_GLOBAL, 
+                 SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS, NULL);
+  if (exceptions)
+    {
+      apr_array_header_t *l = svn_cstring_split(exceptions, ",", TRUE, pool);
+      is_exception = svn_cstring_match_glob_list(requested_host, l);
+    }
+  if (! is_exception)
+    {
+      svn_config_get(cfg, proxy_host, SVN_CONFIG_SECTION_GLOBAL, 
+                     SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
+      svn_config_get(cfg, proxy_port, SVN_CONFIG_SECTION_GLOBAL, 
+                     SVN_CONFIG_OPTION_HTTP_PROXY_PORT, NULL);
+      svn_config_get(cfg, proxy_username, SVN_CONFIG_SECTION_GLOBAL, 
+                     SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, NULL);
+      svn_config_get(cfg, proxy_password, SVN_CONFIG_SECTION_GLOBAL, 
+                     SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, NULL);
+
+      svn_config_get(cfg, timeout, SVN_CONFIG_SECTION_GLOBAL, 
+                     SVN_CONFIG_OPTION_HTTP_TIMEOUT, NULL);
+      SVN_ERR(svn_config_get_bool(cfg, compression, SVN_CONFIG_SECTION_GLOBAL,
+                                  SVN_CONFIG_OPTION_HTTP_COMPRESSION, TRUE));
+      svn_config_get(cfg, debug, SVN_CONFIG_SECTION_GLOBAL, 
+                     SVN_CONFIG_OPTION_NEON_DEBUG_MASK, NULL);
+    }
+    
+  return SVN_NO_ERROR;
+}
+
+/* Get group proxy settings.
+ *
+ * This is a helper function for get_server_settings. See get_server_settings
+ * for the parameter description.
+ */
+static svn_error_t *get_group_proxy(const char **proxy_host,
+                                    const char **proxy_port,
+                                    const char **proxy_username,
+                                    const char **proxy_password,
+                                    const char **timeout,
+                                    const char **debug,
+                                    svn_boolean_t *compression,
+                                    svn_config_t *cfg,
+                                    const char* server_group)
+{
+  svn_config_get(cfg, proxy_host, server_group, 
+                 SVN_CONFIG_OPTION_HTTP_PROXY_HOST, *proxy_host);
+  svn_config_get(cfg, proxy_port, server_group, 
+                 SVN_CONFIG_OPTION_HTTP_PROXY_PORT, *proxy_port);
+  svn_config_get(cfg, proxy_username, server_group, 
+                 SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, *proxy_username);
+  svn_config_get(cfg, proxy_password, server_group, 
+                 SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, *proxy_password);
+
+  svn_config_get(cfg, timeout, server_group, 
+                 SVN_CONFIG_OPTION_HTTP_TIMEOUT, *timeout);
+  SVN_ERR(svn_config_get_bool(cfg, compression, server_group,
+                              SVN_CONFIG_OPTION_HTTP_COMPRESSION,
+                              *compression));
+  svn_config_get(cfg, debug, server_group, 
+                 SVN_CONFIG_OPTION_NEON_DEBUG_MASK, *debug);
+                 
+  return SVN_NO_ERROR;
+}
+
 /* Set *PROXY_HOST, *PROXY_PORT, *PROXY_USERNAME, *PROXY_PASSWORD,
  * *TIMEOUT_SECONDS and *NEON_DEBUG to the information for REQUESTED_HOST,
  * allocated in POOL, if there is any applicable information.  If there is
@@ -369,9 +581,8 @@
                                         const char *requested_host,
                                         apr_pool_t *pool)
 {
-  const char *exceptions, *port_str, *timeout_str, *server_group;
-  const char *debug_str;
-  svn_boolean_t is_exception = FALSE;
+  const char *port_str, *timeout_str, *debug_str, *server_group;
+  svn_boolean_t system_proxy = FALSE;
   /* If we find nothing, default to nulls. */
   *proxy_host     = NULL;
   *proxy_port     = (unsigned int) -1;
@@ -381,56 +592,31 @@
   timeout_str     = NULL;
   debug_str       = NULL;
 
-  /* If there are defaults, use them, but only if the requested host
-     is not one of the exceptions to the defaults. */
-  svn_config_get(cfg, &exceptions, SVN_CONFIG_SECTION_GLOBAL, 
-                 SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS, NULL);
-  if (exceptions)
+  /* use global proxy settings or system specific global proxy settings? */
+  SVN_ERR(svn_config_get_bool(cfg, &system_proxy, SVN_CONFIG_SECTION_GLOBAL,
+                              SVN_CONFIG_OPTION_HTTP_SYSTEM_PROXY,
+                              system_proxy));
+  if (system_proxy)
     {
-      apr_array_header_t *l = svn_cstring_split(exceptions, ",", TRUE, pool);
-      is_exception = svn_cstring_match_glob_list(requested_host, l);
+      SVN_ERR(get_system_global_proxy(proxy_host, &port_str, proxy_username,
+                                      proxy_password, &timeout_str, &debug_str,
+                                      compression, cfg, requested_host, pool));
     }
-  if (! is_exception)
+  else
     {
-      svn_config_get(cfg, proxy_host, SVN_CONFIG_SECTION_GLOBAL, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
-      svn_config_get(cfg, &port_str, SVN_CONFIG_SECTION_GLOBAL, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PORT, NULL);
-      svn_config_get(cfg, proxy_username, SVN_CONFIG_SECTION_GLOBAL, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, NULL);
-      svn_config_get(cfg, proxy_password, SVN_CONFIG_SECTION_GLOBAL, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, NULL);
-      svn_config_get(cfg, &timeout_str, SVN_CONFIG_SECTION_GLOBAL, 
-                     SVN_CONFIG_OPTION_HTTP_TIMEOUT, NULL);
-      SVN_ERR(svn_config_get_bool(cfg, compression, SVN_CONFIG_SECTION_GLOBAL,
-                                  SVN_CONFIG_OPTION_HTTP_COMPRESSION, TRUE));
-      svn_config_get(cfg, &debug_str, SVN_CONFIG_SECTION_GLOBAL, 
-                     SVN_CONFIG_OPTION_NEON_DEBUG_MASK, NULL);
+      SVN_ERR(get_global_proxy(proxy_host, &port_str, proxy_username,
+                               proxy_password, &timeout_str, &debug_str,
+                               compression, cfg, requested_host, pool));
     }
+  
+  server_group = svn_config_find_group(cfg, requested_host, 
+                                       SVN_CONFIG_SECTION_GROUPS, pool);
 
-  if (cfg)
-    server_group = svn_config_find_group(cfg, requested_host, 
-                                         SVN_CONFIG_SECTION_GROUPS, pool);
-  else
-    server_group = NULL;
-
   if (server_group)
     {
-      svn_config_get(cfg, proxy_host, server_group, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_HOST, *proxy_host);
-      svn_config_get(cfg, &port_str, server_group, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PORT, port_str);
-      svn_config_get(cfg, proxy_username, server_group, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, *proxy_username);
-      svn_config_get(cfg, proxy_password, server_group, 
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, *proxy_password);
-      svn_config_get(cfg, &timeout_str, server_group, 
-                     SVN_CONFIG_OPTION_HTTP_TIMEOUT, timeout_str);
-      SVN_ERR(svn_config_get_bool(cfg, compression, server_group,
-                                  SVN_CONFIG_OPTION_HTTP_COMPRESSION,
-                                  *compression));
-      svn_config_get(cfg, &debug_str, server_group, 
-                     SVN_CONFIG_OPTION_NEON_DEBUG_MASK, debug_str);
+      SVN_ERR(get_group_proxy(proxy_host, &port_str, proxy_username,
+                              proxy_password, &timeout_str, &debug_str,
+                              compression, cfg, server_group));
     }
 
   /* Special case: convert the port value, if any. */
