You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by as...@apache.org on 2012/11/24 21:29:48 UTC
svn commit: r1413258 [16/33] - in /subversion/branches/compressed-pristines:
./ build/ build/ac-macros/ build/generator/ build/generator/templates/
contrib/client-side/emacs/ contrib/server-side/fsfsfixer/ notes/
notes/directory-index/ subversion/ subv...
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.c Sat Nov 24 20:29:11 2012
@@ -1,655 +1,1131 @@
-/*
- * sysinfo.c : information about the running system
- *
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- */
-
-
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#define PSAPI_VERSION 1
-#include <windows.h>
-#include <psapi.h>
-#endif
-
-#define APR_WANT_STRFUNC
-#include <apr_want.h>
-
-#include <apr_lib.h>
-#include <apr_pools.h>
-#include <apr_file_info.h>
-#include <apr_strings.h>
-
-#include "svn_ctype.h"
-#include "svn_error.h"
-#include "svn_utf.h"
-
-#include "sysinfo.h"
-#include "svn_private_config.h"
-
-#if HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-#ifdef SVN_HAVE_MACOS_PLIST
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-#if HAVE_UNAME
-static const char* canonical_host_from_uname(apr_pool_t *pool);
-#endif
-
-#ifdef WIN32
-static const char * win32_canonical_host(apr_pool_t *pool);
-static const char * win32_release_name(apr_pool_t *pool);
-static const char * win32_shared_libs(apr_pool_t *pool);
-#endif /* WIN32 */
-
-#ifdef SVN_HAVE_MACOS_PLIST
-static const char *macos_release_name(apr_pool_t *pool);
-#endif /* SVN_HAVE_MACOS_PLIST */
-
-
-const char *
-svn_sysinfo__canonical_host(apr_pool_t *pool)
-{
-#if HAVE_UNAME
- return canonical_host_from_uname(pool);
-#elif defined(WIN32)
- return win32_canonical_host(pool);
-#else
- return "unknown-unknown-unknown";
-#endif
-}
-
-
-const char *
-svn_sysinfo__release_name(apr_pool_t *pool)
-{
-#ifdef WIN32
- return win32_release_name(pool);
-#elif defined(SVN_HAVE_MACOS_PLIST)
- return macos_release_name(pool);
-#else
- return NULL;
-#endif
-}
-
-
-const char *
-svn_sysinfo__loaded_libs(apr_pool_t *pool)
-{
-#ifdef WIN32
- return win32_shared_libs(pool);
-#else
- return NULL;
-#endif
-}
-
-
-#if HAVE_UNAME
-static const char*
-canonical_host_from_uname(apr_pool_t *pool)
-{
- const char *machine = "unknown";
- const char *vendor = "unknown";
- const char *sysname = "unknown";
- const char *sysver = "";
- struct utsname info;
-
- if (0 <= uname(&info))
- {
- svn_error_t *err;
- const char *tmp;
-
- err = svn_utf_cstring_to_utf8(&tmp, info.machine, pool);
- if (err)
- svn_error_clear(err);
- else
- machine = tmp;
-
- err = svn_utf_cstring_to_utf8(&tmp, info.sysname, pool);
- if (err)
- svn_error_clear(err);
- else
- {
- char *lwr = apr_pstrdup(pool, tmp);
- char *it = lwr;
- while (*it)
- {
- if (svn_ctype_isupper(*it))
- *it = apr_tolower(*it);
- ++it;
- }
- sysname = lwr;
- }
-
- if (0 == strcmp(sysname, "darwin"))
- vendor = "apple";
-
- err = svn_utf_cstring_to_utf8(&tmp, info.release, pool);
- if (err)
- svn_error_clear(err);
- else
- sysver = tmp;
- }
-
- return apr_psprintf(pool, "%s-%s-%s%s", machine, vendor, sysname, sysver);
-}
-#endif /* HAVE_UNAME */
-
-
-#ifdef WIN32
-typedef DWORD (WINAPI *FNGETNATIVESYSTEMINFO)(LPSYSTEM_INFO);
-typedef BOOL (WINAPI *FNENUMPROCESSMODULES) (HANDLE, HMODULE, DWORD, LPDWORD);
-
-/* Get system and version info, and try to tell the difference
- between the native system type and the runtime environment of the
- current process. Populate results in SYSINFO, LOCAL_SYSINFO
- (optional) and OSINFO. */
-static BOOL
-system_info(SYSTEM_INFO *sysinfo,
- SYSTEM_INFO *local_sysinfo,
- OSVERSIONINFOEXW *osinfo)
-{
- FNGETNATIVESYSTEMINFO GetNativeSystemInfo_ = (FNGETNATIVESYSTEMINFO)
- GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
-
- ZeroMemory(sysinfo, sizeof *sysinfo);
- if (local_sysinfo)
- {
- ZeroMemory(local_sysinfo, sizeof *local_sysinfo);
- GetSystemInfo(local_sysinfo);
- if (GetNativeSystemInfo_)
- GetNativeSystemInfo_(sysinfo);
- else
- memcpy(sysinfo, local_sysinfo, sizeof *sysinfo);
- }
- else
- GetSystemInfo(sysinfo);
-
- ZeroMemory(osinfo, sizeof *osinfo);
- osinfo->dwOSVersionInfoSize = sizeof *osinfo;
- if (!GetVersionExW((LPVOID)osinfo))
- return FALSE;
-
- return TRUE;
-}
-
-/* Map the proccessor type from SYSINFO to a string. */
-static const char *
-processor_name(SYSTEM_INFO *sysinfo)
-{
- switch (sysinfo->wProcessorArchitecture)
- {
- case PROCESSOR_ARCHITECTURE_AMD64: return "x86_64";
- case PROCESSOR_ARCHITECTURE_IA64: return "ia64";
- case PROCESSOR_ARCHITECTURE_INTEL: return "x86";
- case PROCESSOR_ARCHITECTURE_MIPS: return "mips";
- case PROCESSOR_ARCHITECTURE_ALPHA: return "alpha32";
- case PROCESSOR_ARCHITECTURE_PPC: return "powerpc";
- case PROCESSOR_ARCHITECTURE_SHX: return "shx";
- case PROCESSOR_ARCHITECTURE_ARM: return "arm";
- case PROCESSOR_ARCHITECTURE_ALPHA64: return "alpha";
- case PROCESSOR_ARCHITECTURE_MSIL: return "msil";
- case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: return "x86_wow64";
- default: return "unknown";
- }
-}
-
-/* Return the Windows-specific canonical host name. */
-static const char *
-win32_canonical_host(apr_pool_t *pool)
-{
- SYSTEM_INFO sysinfo;
- SYSTEM_INFO local_sysinfo;
- OSVERSIONINFOEXW osinfo;
-
- if (system_info(&sysinfo, &local_sysinfo, &osinfo))
- {
- const char *arch = processor_name(&local_sysinfo);
- const char *machine = processor_name(&sysinfo);
- const char *vendor = "microsoft";
- const char *sysname = "windows";
- const char *sysver = apr_psprintf(pool, "%u.%u.%u",
- (unsigned int)osinfo.dwMajorVersion,
- (unsigned int)osinfo.dwMinorVersion,
- (unsigned int)osinfo.dwBuildNumber);
-
- if (sysinfo.wProcessorArchitecture
- == local_sysinfo.wProcessorArchitecture)
- return apr_psprintf(pool, "%s-%s-%s%s",
- machine, vendor, sysname, sysver);
- return apr_psprintf(pool, "%s/%s-%s-%s%s",
- arch, machine, vendor, sysname, sysver);
- }
-
- return "unknown-microsoft-windows";
-}
-
-/* Convert a Unicode string to UTF-8. */
-static char *
-wcs_to_utf8(const wchar_t *wcs, apr_pool_t *pool)
-{
- const int bufsize = WideCharToMultiByte(CP_UTF8, 0, wcs, -1,
- NULL, 0, NULL, NULL);
- if (bufsize > 0)
- {
- char *const utf8 = apr_palloc(pool, bufsize + 1);
- WideCharToMultiByte(CP_UTF8, 0, wcs, -1, utf8, bufsize, NULL, NULL);
- return utf8;
- }
- return NULL;
-}
-
-/* Query the value called NAME of the registry key HKEY. */
-static char *
-registry_value(HKEY hkey, wchar_t *name, apr_pool_t *pool)
-{
- DWORD size;
- wchar_t *value;
-
- if (RegQueryValueExW(hkey, name, NULL, NULL, NULL, &size))
- return NULL;
-
- value = apr_palloc(pool, size + sizeof *value);
- if (RegQueryValueExW(hkey, name, NULL, NULL, (void*)value, &size))
- return NULL;
- value[size / sizeof *value] = 0;
- return wcs_to_utf8(value, pool);
-}
-
-/* Try to glean the Windows release name and associated info from the
- registry. Failing that, construct a release name from the version
- info. */
-static const char *
-win32_release_name(apr_pool_t *pool)
-{
- SYSTEM_INFO sysinfo;
- OSVERSIONINFOEXW osinfo;
- HKEY hkcv;
-
- if (!system_info(&sysinfo, NULL, &osinfo))
- return NULL;
-
- if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
- 0, KEY_QUERY_VALUE, &hkcv))
- {
- const char *release = registry_value(hkcv, L"ProductName", pool);
- const char *spack = registry_value(hkcv, L"CSDVersion", pool);
- const char *curver = registry_value(hkcv, L"CurrentVersion", pool);
- const char *curtype = registry_value(hkcv, L"CurrentType", pool);
- const char *install = registry_value(hkcv, L"InstallationType", pool);
- const char *curbuild = registry_value(hkcv, L"CurrentBuildNumber", pool);
-
- if (!spack && *osinfo.szCSDVersion)
- spack = wcs_to_utf8(osinfo.szCSDVersion, pool);
-
- if (!curbuild)
- curbuild = registry_value(hkcv, L"CurrentBuild", pool);
-
- if (release || spack || curver || curtype || curbuild)
- {
- const char *bootinfo = "";
- if (curver || install || curtype)
- {
- bootinfo = apr_psprintf(pool, "[%s%s%s%s%s]",
- (curver ? curver : ""),
- (install ? (curver ? " " : "") : ""),
- (install ? install : ""),
- (curtype
- ? (curver||install ? " " : "")
- : ""),
- (curtype ? curtype : ""));
- }
-
- return apr_psprintf(pool, "%s%s%s%s%s%s%s",
- (release ? release : ""),
- (spack ? (release ? ", " : "") : ""),
- (spack ? spack : ""),
- (curbuild
- ? (release||spack ? ", build " : "build ")
- : ""),
- (curbuild ? curbuild : ""),
- (bootinfo
- ? (release||spack||curbuild ? " " : "")
- : ""),
- (bootinfo ? bootinfo : ""));
- }
- }
-
- if (*osinfo.szCSDVersion)
- {
- const char *servicepack = wcs_to_utf8(osinfo.szCSDVersion, pool);
-
- if (servicepack)
- return apr_psprintf(pool, "Windows NT %u.%u, %s, build %u",
- (unsigned int)osinfo.dwMajorVersion,
- (unsigned int)osinfo.dwMinorVersion,
- servicepack,
- (unsigned int)osinfo.dwBuildNumber);
-
- /* Assume wServicePackMajor > 0 if szCSDVersion is not empty */
- if (osinfo.wServicePackMinor)
- return apr_psprintf(pool, "Windows NT %u.%u SP%u.%u, build %u",
- (unsigned int)osinfo.dwMajorVersion,
- (unsigned int)osinfo.dwMinorVersion,
- (unsigned int)osinfo.wServicePackMajor,
- (unsigned int)osinfo.wServicePackMinor,
- (unsigned int)osinfo.dwBuildNumber);
-
- return apr_psprintf(pool, "Windows NT %u.%u SP%u, build %u",
- (unsigned int)osinfo.dwMajorVersion,
- (unsigned int)osinfo.dwMinorVersion,
- (unsigned int)osinfo.wServicePackMajor,
- (unsigned int)osinfo.dwBuildNumber);
- }
-
- return apr_psprintf(pool, "Windows NT %u.%u, build %u",
- (unsigned int)osinfo.dwMajorVersion,
- (unsigned int)osinfo.dwMinorVersion,
- (unsigned int)osinfo.dwBuildNumber);
-}
-
-
-/* Get a list of handles of shared libs loaded by the current
- process. Returns a NULL-terminated array alocated from POOL. */
-static HMODULE *
-enum_loaded_modules(apr_pool_t *pool)
-{
- HANDLE current = GetCurrentProcess();
- HMODULE dummy[1];
- HMODULE *handles;
- DWORD size;
-
- if (!EnumProcessModules(current, dummy, sizeof(dummy), &size))
- return NULL;
-
- handles = apr_palloc(pool, size + sizeof *handles);
- if (!EnumProcessModules(current, handles, size, &size))
- return NULL;
- handles[size / sizeof *handles] = NULL;
- return handles;
-}
-
-/* Find the version number, if any, embedded in FILENAME. */
-static const char *
-file_version_number(const wchar_t *filename, apr_pool_t *pool)
-{
- VS_FIXEDFILEINFO info;
- unsigned int major, minor, micro, nano;
- void *data;
- DWORD data_size = GetFileVersionInfoSizeW(filename, NULL);
- void *vinfo;
- UINT vinfo_size;
-
- if (!data_size)
- return NULL;
-
- data = apr_palloc(pool, data_size);
- if (!GetFileVersionInfoW(filename, 0, data_size, data))
- return NULL;
-
- if (!VerQueryValueW(data, L"\\", &vinfo, &vinfo_size))
- return NULL;
-
- if (vinfo_size != sizeof info)
- return NULL;
-
- memcpy(&info, vinfo, sizeof info);
- major = (info.dwFileVersionMS >> 16) & 0xFFFF;
- minor = info.dwFileVersionMS & 0xFFFF;
- micro = (info.dwFileVersionLS >> 16) & 0xFFFF;
- nano = info.dwFileVersionLS & 0xFFFF;
-
- if (!nano)
- {
- if (!micro)
- return apr_psprintf(pool, "%u.%u", major, minor);
- else
- return apr_psprintf(pool, "%u.%u.%u", major, minor, micro);
- }
- return apr_psprintf(pool, "%u.%u.%u.%u", major, minor, micro, nano);
-}
-
-/* List the shared libraries loaded by the current process. */
-static const char *
-win32_shared_libs(apr_pool_t *pool)
-{
- wchar_t buffer[MAX_PATH + 1];
- HMODULE *handles = enum_loaded_modules(pool);
- char *libinfo = "";
- HMODULE *module;
-
- for (module = handles; module && *module; ++module)
- {
- const char *filename;
- const char *version;
- if (GetModuleFileNameW(*module, buffer, MAX_PATH))
- {
- buffer[MAX_PATH] = 0;
- version = file_version_number(buffer, pool);
- filename = wcs_to_utf8(buffer, pool);
- if (filename)
- {
- char *truename;
- if (0 == apr_filepath_merge(&truename, "", filename,
- APR_FILEPATH_NATIVE
- | APR_FILEPATH_TRUENAME,
- pool))
- filename = truename;
- if (version)
- libinfo = apr_pstrcat(pool, libinfo, " - ", filename,
- " (", version, ")\n", NULL);
- else
- libinfo = apr_pstrcat(pool, libinfo, " - ", filename,
- "\n", NULL);
- }
- }
- }
-
- if (*libinfo)
- return libinfo;
- return NULL;
-}
-#endif /* WIN32 */
-
-#ifdef SVN_HAVE_MACOS_PLIST
-/* Load the SystemVersion.plist or ServerVersion.plist file into a
- property list. Set SERVER to TRUE if the file read was
- ServerVersion.plist. */
-static CFDictionaryRef
-system_version_plist(svn_boolean_t *server, apr_pool_t *pool)
-{
- static const UInt8 server_version[] =
- "/System/Library/CoreServices/ServerVersion.plist";
- static const UInt8 system_version[] =
- "/System/Library/CoreServices/SystemVersion.plist";
-
- CFPropertyListRef plist = NULL;
- CFDataRef resource = NULL;
- CFStringRef errstr = NULL;
- CFURLRef url = NULL;
- SInt32 errcode;
-
- url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- server_version,
- sizeof(server_version) - 1,
- FALSE);
- if (!url)
- return NULL;
-
- if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
- url, &resource,
- NULL, NULL, &errcode))
- {
- CFRelease(url);
- url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- system_version,
- sizeof(system_version) - 1,
- FALSE);
- if (!url)
- return NULL;
-
- if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
- url, &resource,
- NULL, NULL, &errcode))
- {
- CFRelease(url);
- return NULL;
- }
- else
- {
- CFRelease(url);
- *server = FALSE;
- }
- }
- else
- {
- CFRelease(url);
- *server = TRUE;
- }
-
- /* ### CFPropertyListCreateFromXMLData is obsolete, but its
- replacement CFPropertyListCreateWithData is only available
- from Mac OS 1.6 onward. */
- plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resource,
- kCFPropertyListImmutable,
- &errstr);
- if (resource)
- CFRelease(resource);
- if (errstr)
- CFRelease(errstr);
-
- if (CFDictionaryGetTypeID() != CFGetTypeID(plist))
- {
- /* Oops ... this really should be a dict. */
- CFRelease(plist);
- return NULL;
- }
-
- return plist;
-}
-
-/* Return the value for KEY from PLIST, or NULL if not available. */
-static const char *
-value_from_dict(CFDictionaryRef plist, CFStringRef key, apr_pool_t *pool)
-{
- CFStringRef valref;
- CFIndex bufsize;
- const void *valptr;
- const char *value;
-
- if (!CFDictionaryGetValueIfPresent(plist, key, &valptr))
- return NULL;
-
- valref = valptr;
- if (CFStringGetTypeID() != CFGetTypeID(valref))
- return NULL;
-
- value = CFStringGetCStringPtr(valref, kCFStringEncodingUTF8);
- if (value)
- return apr_pstrdup(pool, value);
-
- bufsize = 5 * CFStringGetLength(valref) + 1;
- value = apr_palloc(pool, bufsize);
- if (!CFStringGetCString(valref, (char*)value, bufsize,
- kCFStringEncodingUTF8))
- value = NULL;
-
- return value;
-}
-
-/* Return the commercial name of the OS, given the version number in
- a format that matches the regular expression /^10\.\d+(\..*)?$/ */
-static const char *
-release_name_from_version(const char *osver)
-{
- char *end = NULL;
- unsigned long num = strtoul(osver, &end, 10);
-
- if (!end || *end != '.' || num != 10)
- return NULL;
-
- osver = end + 1;
- end = NULL;
- num = strtoul(osver, &end, 10);
- if (!end || (*end && *end != '.'))
- return NULL;
-
- /* See http://en.wikipedia.org/wiki/History_of_OS_X#Release_timeline */
- switch(num)
- {
- case 0: return "Cheetah";
- case 1: return "Puma";
- case 2: return "Jaguar";
- case 3: return "Panther";
- case 4: return "Tiger";
- case 5: return "Leopard";
- case 6: return "Snow Leopard";
- case 7: return "Lion";
- case 8: return "Mountain Lion";
- }
-
- return NULL;
-}
-
-static const char *
-macos_release_name(apr_pool_t *pool)
-{
- svn_boolean_t server;
- CFDictionaryRef plist = system_version_plist(&server, pool);
-
- if (plist)
- {
- const char *osname = value_from_dict(plist, CFSTR("ProductName"), pool);
- const char *osver = value_from_dict(plist,
- CFSTR("ProductUserVisibleVersion"),
- pool);
- const char *build = value_from_dict(plist,
- CFSTR("ProductBuildVersion"),
- pool);
- const char *release;
-
- if (!osver)
- osver = value_from_dict(plist, CFSTR("ProductVersion"), pool);
- release = release_name_from_version(osver);
-
- CFRelease(plist);
- return apr_psprintf(pool, "%s%s%s%s%s%s%s%s",
- (osname ? osname : ""),
- (osver ? (osname ? " " : "") : ""),
- (osver ? osver : ""),
- (release ? (osname||osver ? " " : "") : ""),
- (release ? release : ""),
- (build
- ? (osname||osver||release ? ", " : "")
- : ""),
- (build
- ? (server ? "server build " : "build ")
- : ""),
- (build ? build : ""));
- }
-
- return NULL;
-}
-#endif /* SVN_HAVE_MACOS_PLIST */
+/*
+ * sysinfo.c : information about the running system
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#define PSAPI_VERSION 1
+#include <windows.h>
+#include <psapi.h>
+#endif
+
+#define APR_WANT_STRFUNC
+#include <apr_want.h>
+
+#include <apr_lib.h>
+#include <apr_pools.h>
+#include <apr_file_info.h>
+#include <apr_signal.h>
+#include <apr_strings.h>
+#include <apr_thread_proc.h>
+#include <apr_version.h>
+#include <apu_version.h>
+
+#include "svn_ctype.h"
+#include "svn_error.h"
+#include "svn_io.h"
+#include "svn_string.h"
+#include "svn_utf.h"
+#include "svn_version.h"
+
+#include "private/svn_sqlite.h"
+
+#include "sysinfo.h"
+#include "svn_private_config.h"
+
+#if HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#ifdef SVN_HAVE_MACOS_PLIST
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#ifdef SVN_HAVE_MACHO_ITERATE
+#include <mach-o/dyld.h>
+#include <mach-o/loader.h>
+#endif
+
+#if HAVE_UNAME
+static const char *canonical_host_from_uname(apr_pool_t *pool);
+# ifndef SVN_HAVE_MACOS_PLIST
+static const char *release_name_from_uname(apr_pool_t *pool);
+# endif
+#endif
+
+#ifdef WIN32
+static const char *win32_canonical_host(apr_pool_t *pool);
+static const char *win32_release_name(apr_pool_t *pool);
+static const apr_array_header_t *win32_shared_libs(apr_pool_t *pool);
+#endif /* WIN32 */
+
+#ifdef SVN_HAVE_MACOS_PLIST
+static const char *macos_release_name(apr_pool_t *pool);
+#endif
+
+#ifdef SVN_HAVE_MACHO_ITERATE
+static const apr_array_header_t *macos_shared_libs(apr_pool_t *pool);
+#endif
+
+
+#if __linux__
+static const char *linux_release_name(apr_pool_t *pool);
+#endif
+
+const char *
+svn_sysinfo__canonical_host(apr_pool_t *pool)
+{
+#ifdef WIN32
+ return win32_canonical_host(pool);
+#elif HAVE_UNAME
+ return canonical_host_from_uname(pool);
+#else
+ return "unknown-unknown-unknown";
+#endif
+}
+
+
+const char *
+svn_sysinfo__release_name(apr_pool_t *pool)
+{
+#ifdef WIN32
+ return win32_release_name(pool);
+#elif defined(SVN_HAVE_MACOS_PLIST)
+ return macos_release_name(pool);
+#elif __linux__
+ return linux_release_name(pool);
+#elif HAVE_UNAME
+ return release_name_from_uname(pool);
+#else
+ return NULL;
+#endif
+}
+
+const apr_array_header_t *
+svn_sysinfo__linked_libs(apr_pool_t *pool)
+{
+ svn_version_ext_linked_lib_t *lib;
+ apr_array_header_t *array = apr_array_make(pool, 3, sizeof(*lib));
+
+ lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
+ lib->name = "APR";
+ lib->compiled_version = APR_VERSION_STRING;
+ lib->runtime_version = apr_pstrdup(pool, apr_version_string());
+
+ lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
+ lib->name = "APR-Util";
+ lib->compiled_version = APU_VERSION_STRING;
+ lib->runtime_version = apr_pstrdup(pool, apu_version_string());
+
+ lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
+ lib->name = "SQLite";
+ lib->compiled_version = apr_pstrdup(pool, svn_sqlite__compiled_version());
+#ifdef SVN_SQLITE_INLINE
+ lib->runtime_version = NULL;
+#else
+ lib->runtime_version = apr_pstrdup(pool, svn_sqlite__runtime_version());
+#endif
+
+ return array;
+}
+
+const apr_array_header_t *
+svn_sysinfo__loaded_libs(apr_pool_t *pool)
+{
+#ifdef WIN32
+ return win32_shared_libs(pool);
+#elif defined(SVN_HAVE_MACHO_ITERATE)
+ return macos_shared_libs(pool);
+#else
+ return NULL;
+#endif
+}
+
+
+#if HAVE_UNAME
+static const char*
+canonical_host_from_uname(apr_pool_t *pool)
+{
+ const char *machine = "unknown";
+ const char *vendor = "unknown";
+ const char *sysname = "unknown";
+ const char *sysver = "";
+ struct utsname info;
+
+ if (0 <= uname(&info))
+ {
+ svn_error_t *err;
+ const char *tmp;
+
+ err = svn_utf_cstring_to_utf8(&tmp, info.machine, pool);
+ if (err)
+ svn_error_clear(err);
+ else
+ machine = tmp;
+
+ err = svn_utf_cstring_to_utf8(&tmp, info.sysname, pool);
+ if (err)
+ svn_error_clear(err);
+ else
+ {
+ char *lwr = apr_pstrdup(pool, tmp);
+ char *it = lwr;
+ while (*it)
+ {
+ if (svn_ctype_isupper(*it))
+ *it = apr_tolower(*it);
+ ++it;
+ }
+ sysname = lwr;
+ }
+
+ if (0 == strcmp(sysname, "darwin"))
+ vendor = "apple";
+ if (0 == strcmp(sysname, "linux"))
+ sysver = "-gnu";
+ else
+ {
+ err = svn_utf_cstring_to_utf8(&tmp, info.release, pool);
+ if (err)
+ svn_error_clear(err);
+ else
+ {
+ apr_size_t n = strspn(tmp, ".0123456789");
+ if (n > 0)
+ {
+ char *ver = apr_pstrdup(pool, tmp);
+ ver[n] = 0;
+ sysver = ver;
+ }
+ else
+ sysver = tmp;
+ }
+ }
+ }
+
+ return apr_psprintf(pool, "%s-%s-%s%s", machine, vendor, sysname, sysver);
+}
+
+# ifndef SVN_HAVE_MACOS_PLIST
+/* Generate a release name from the uname(3) info, effectively
+ returning "`uname -s` `uname -r`". */
+static const char *
+release_name_from_uname(apr_pool_t *pool)
+{
+ struct utsname info;
+ if (0 <= uname(&info))
+ {
+ svn_error_t *err;
+ const char *sysname;
+ const char *sysver;
+
+ err = svn_utf_cstring_to_utf8(&sysname, info.sysname, pool);
+ if (err)
+ {
+ sysname = NULL;
+ svn_error_clear(err);
+ }
+
+
+ err = svn_utf_cstring_to_utf8(&sysver, info.release, pool);
+ if (err)
+ {
+ sysver = NULL;
+ svn_error_clear(err);
+ }
+
+ if (sysname || sysver)
+ {
+ return apr_psprintf(pool, "%s%s%s",
+ (sysname ? sysname : ""),
+ (sysver ? (sysname ? " " : "") : ""),
+ (sysver ? sysver : ""));
+ }
+ }
+ return NULL;
+}
+# endif /* !SVN_HAVE_MACOS_PLIST */
+#endif /* HAVE_UNAME */
+
+
+#if __linux__
+/* Split a stringbuf into a key/value pair.
+ Return the key, leaving the striped value in the stringbuf. */
+static const char *
+stringbuf_split_key(svn_stringbuf_t *buffer, char delim)
+{
+ char *key;
+ char *end;
+
+ end = strchr(buffer->data, delim);
+ if (!end)
+ return NULL;
+
+ svn_stringbuf_strip_whitespace(buffer);
+ key = buffer->data;
+ end = strchr(key, delim);
+ *end = '\0';
+ buffer->len = 1 + end - key;
+ buffer->data = end + 1;
+ svn_stringbuf_strip_whitespace(buffer);
+
+ return key;
+}
+
+/* Parse `/usr/bin/lsb_rlease --all` */
+static const char *
+lsb_release(apr_pool_t *pool)
+{
+ static const char *const args[3] =
+ {
+ "/usr/bin/lsb_release",
+ "--all",
+ NULL
+ };
+
+ const char *distributor = NULL;
+ const char *description = NULL;
+ const char *release = NULL;
+ const char *codename = NULL;
+
+ apr_proc_t lsbproc;
+ svn_stream_t *lsbinfo;
+ svn_error_t *err;
+
+ /* Run /usr/bin/lsb_release --all < /dev/null 2>/dev/null */
+ {
+ apr_file_t *stdin_handle;
+ apr_file_t *stdout_handle;
+
+ err = svn_io_file_open(&stdin_handle, SVN_NULL_DEVICE_NAME,
+ APR_READ, APR_OS_DEFAULT, pool);
+ if (!err)
+ err = svn_io_file_open(&stdout_handle, SVN_NULL_DEVICE_NAME,
+ APR_WRITE, APR_OS_DEFAULT, pool);
+ if (!err)
+ err = svn_io_start_cmd3(&lsbproc, NULL, args[0], args, NULL, FALSE,
+ FALSE, stdin_handle,
+ TRUE, NULL,
+ FALSE, stdout_handle,
+ pool);
+ if (err)
+ {
+ svn_error_clear(err);
+ return NULL;
+ }
+ }
+
+ /* Parse the output and try to populate the */
+ lsbinfo = svn_stream_from_aprfile2(lsbproc.out, TRUE, pool);
+ if (lsbinfo)
+ {
+ for (;;)
+ {
+ svn_boolean_t eof = FALSE;
+ svn_stringbuf_t *line;
+ const char *key;
+
+ err = svn_stream_readline(lsbinfo, &line, "\n", &eof, pool);
+ if (err || eof)
+ break;
+
+ key = stringbuf_split_key(line, ':');
+ if (!key)
+ continue;
+
+ if (0 == svn_cstring_casecmp(key, "Distributor ID"))
+ distributor = line->data;
+ else if (0 == svn_cstring_casecmp(key, "Description"))
+ description = line->data;
+ else if (0 == svn_cstring_casecmp(key, "Release"))
+ release = line->data;
+ else if (0 == svn_cstring_casecmp(key, "Codename"))
+ codename = line->data;
+ }
+ err = svn_error_compose_create(err,
+ svn_stream_close(lsbinfo));
+ if (err)
+ {
+ svn_error_clear(err);
+ apr_proc_kill(&lsbproc, SIGKILL);
+ return NULL;
+ }
+ }
+
+ /* Reap the child process */
+ err = svn_io_wait_for_cmd(&lsbproc, "", NULL, NULL, pool);
+ if (err)
+ {
+ svn_error_clear(err);
+ return NULL;
+ }
+
+ if (description)
+ return apr_psprintf(pool, "%s%s%s%s", description,
+ (codename ? " (" : ""),
+ (codename ? codename : ""),
+ (codename ? ")" : ""));
+ if (distributor)
+ return apr_psprintf(pool, "%s%s%s%s%s%s", distributor,
+ (release ? " " : ""),
+ (release ? release : ""),
+ (codename ? " (" : ""),
+ (codename ? codename : ""),
+ (codename ? ")" : ""));
+
+ return NULL;
+}
+
+/* Read the whole contents of a file. */
+static svn_stringbuf_t *
+read_file_contents(const char *filename, apr_pool_t *pool)
+{
+ svn_error_t *err;
+ svn_stringbuf_t *buffer;
+
+ err = svn_stringbuf_from_file2(&buffer, filename, pool);
+ if (err)
+ {
+ svn_error_clear(err);
+ return NULL;
+ }
+
+ return buffer;
+}
+
+/* Strip everything but the first line from a stringbuf. */
+static void
+stringbuf_first_line_only(svn_stringbuf_t *buffer)
+{
+ char *eol = strchr(buffer->data, '\n');
+ if (eol)
+ {
+ *eol = '\0';
+ buffer->len = 1 + eol - buffer->data;
+ }
+ svn_stringbuf_strip_whitespace(buffer);
+}
+
+/* Look at /etc/redhat_release to detect RHEL/Fedora/CentOS. */
+static const char *
+redhat_release(apr_pool_t *pool)
+{
+ svn_stringbuf_t *buffer = read_file_contents("/etc/redhat-release", pool);
+ if (buffer)
+ {
+ stringbuf_first_line_only(buffer);
+ return buffer->data;
+ }
+ return NULL;
+}
+
+/* Look at /etc/SuSE-release to detect non-LSB SuSE. */
+static const char *
+suse_release(apr_pool_t *pool)
+{
+ const char *release = NULL;
+ const char *codename = NULL;
+
+ svn_stringbuf_t *buffer = read_file_contents("/etc/SuSE-release", pool);
+ svn_stringbuf_t *line;
+ svn_stream_t *stream;
+ svn_boolean_t eof;
+ svn_error_t *err;
+ if (!buffer)
+ return NULL;
+
+ stream = svn_stream_from_stringbuf(buffer, pool);
+ err = svn_stream_readline(stream, &line, "\n", &eof, pool);
+ if (err || eof)
+ {
+ svn_error_clear(err);
+ return NULL;
+ }
+
+ svn_stringbuf_strip_whitespace(line);
+ release = line->data;
+
+ for (;;)
+ {
+ const char *key;
+
+ err = svn_stream_readline(stream, &line, "\n", &eof, pool);
+ if (err || eof)
+ {
+ svn_error_clear(err);
+ break;
+ }
+
+ key = stringbuf_split_key(line, '=');
+ if (!key)
+ continue;
+
+ if (0 == strncmp(key, "CODENAME", 8))
+ codename = line->data;
+ }
+
+ return apr_psprintf(pool, "%s%s%s%s",
+ release,
+ (codename ? " (" : ""),
+ (codename ? codename : ""),
+ (codename ? ")" : ""));
+}
+
+/* Look at /etc/debian_version to detect non-LSB Debian. */
+static const char *
+debian_release(apr_pool_t *pool)
+{
+ svn_stringbuf_t *buffer = read_file_contents("/etc/debian_version", pool);
+ if (!buffer)
+ return NULL;
+
+ stringbuf_first_line_only(buffer);
+ return apr_pstrcat(pool, "Debian ", buffer->data, NULL);
+}
+
+/* Try to find the Linux distribution name, or return info from uname. */
+static const char *
+linux_release_name(apr_pool_t *pool)
+{
+ const char *uname_release = release_name_from_uname(pool);
+
+ /* Try anything that has /usr/bin/lsb_release.
+ Covers, for example, Debian, Ubuntu and SuSE. */
+ const char *release_name = lsb_release(pool);
+
+ /* Try RHEL/Fedora/CentOS */
+ if (!release_name)
+ release_name = redhat_release(pool);
+
+ /* Try Non-LSB SuSE */
+ if (!release_name)
+ release_name = suse_release(pool);
+
+ /* Try non-LSB Debian */
+ if (!release_name)
+ release_name = debian_release(pool);
+
+ if (!release_name)
+ return uname_release;
+
+ if (!uname_release)
+ return release_name;
+
+ return apr_psprintf(pool, "%s [%s]", release_name, uname_release);
+}
+#endif /* __linux__ */
+
+
+#ifdef WIN32
+typedef DWORD (WINAPI *FNGETNATIVESYSTEMINFO)(LPSYSTEM_INFO);
+typedef BOOL (WINAPI *FNENUMPROCESSMODULES) (HANDLE, HMODULE, DWORD, LPDWORD);
+
+/* Get system and version info, and try to tell the difference
+ between the native system type and the runtime environment of the
+ current process. Populate results in SYSINFO, LOCAL_SYSINFO
+ (optional) and OSINFO. */
+static BOOL
+system_info(SYSTEM_INFO *sysinfo,
+ SYSTEM_INFO *local_sysinfo,
+ OSVERSIONINFOEXW *osinfo)
+{
+ FNGETNATIVESYSTEMINFO GetNativeSystemInfo_ = (FNGETNATIVESYSTEMINFO)
+ GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
+
+ ZeroMemory(sysinfo, sizeof *sysinfo);
+ if (local_sysinfo)
+ {
+ ZeroMemory(local_sysinfo, sizeof *local_sysinfo);
+ GetSystemInfo(local_sysinfo);
+ if (GetNativeSystemInfo_)
+ GetNativeSystemInfo_(sysinfo);
+ else
+ memcpy(sysinfo, local_sysinfo, sizeof *sysinfo);
+ }
+ else
+ GetSystemInfo(sysinfo);
+
+ ZeroMemory(osinfo, sizeof *osinfo);
+ osinfo->dwOSVersionInfoSize = sizeof *osinfo;
+ if (!GetVersionExW((LPVOID)osinfo))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Map the proccessor type from SYSINFO to a string. */
+static const char *
+processor_name(SYSTEM_INFO *sysinfo)
+{
+ switch (sysinfo->wProcessorArchitecture)
+ {
+ case PROCESSOR_ARCHITECTURE_AMD64: return "x86_64";
+ case PROCESSOR_ARCHITECTURE_IA64: return "ia64";
+ case PROCESSOR_ARCHITECTURE_INTEL: return "x86";
+ case PROCESSOR_ARCHITECTURE_MIPS: return "mips";
+ case PROCESSOR_ARCHITECTURE_ALPHA: return "alpha32";
+ case PROCESSOR_ARCHITECTURE_PPC: return "powerpc";
+ case PROCESSOR_ARCHITECTURE_SHX: return "shx";
+ case PROCESSOR_ARCHITECTURE_ARM: return "arm";
+ case PROCESSOR_ARCHITECTURE_ALPHA64: return "alpha";
+ case PROCESSOR_ARCHITECTURE_MSIL: return "msil";
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: return "x86_wow64";
+ default: return "unknown";
+ }
+}
+
+/* Return the Windows-specific canonical host name. */
+static const char *
+win32_canonical_host(apr_pool_t *pool)
+{
+ SYSTEM_INFO sysinfo;
+ SYSTEM_INFO local_sysinfo;
+ OSVERSIONINFOEXW osinfo;
+
+ if (system_info(&sysinfo, &local_sysinfo, &osinfo))
+ {
+ const char *arch = processor_name(&local_sysinfo);
+ const char *machine = processor_name(&sysinfo);
+ const char *vendor = "microsoft";
+ const char *sysname = "windows";
+ const char *sysver = apr_psprintf(pool, "%u.%u.%u",
+ (unsigned int)osinfo.dwMajorVersion,
+ (unsigned int)osinfo.dwMinorVersion,
+ (unsigned int)osinfo.dwBuildNumber);
+
+ if (sysinfo.wProcessorArchitecture
+ == local_sysinfo.wProcessorArchitecture)
+ return apr_psprintf(pool, "%s-%s-%s%s",
+ machine, vendor, sysname, sysver);
+ return apr_psprintf(pool, "%s/%s-%s-%s%s",
+ arch, machine, vendor, sysname, sysver);
+ }
+
+ return "unknown-microsoft-windows";
+}
+
+/* Convert a Unicode string to UTF-8. */
+static char *
+wcs_to_utf8(const wchar_t *wcs, apr_pool_t *pool)
+{
+ const int bufsize = WideCharToMultiByte(CP_UTF8, 0, wcs, -1,
+ NULL, 0, NULL, NULL);
+ if (bufsize > 0)
+ {
+ char *const utf8 = apr_palloc(pool, bufsize + 1);
+ WideCharToMultiByte(CP_UTF8, 0, wcs, -1, utf8, bufsize, NULL, NULL);
+ return utf8;
+ }
+ return NULL;
+}
+
+/* Query the value called NAME of the registry key HKEY. */
+static char *
+registry_value(HKEY hkey, wchar_t *name, apr_pool_t *pool)
+{
+ DWORD size;
+ wchar_t *value;
+
+ if (RegQueryValueExW(hkey, name, NULL, NULL, NULL, &size))
+ return NULL;
+
+ value = apr_palloc(pool, size + sizeof *value);
+ if (RegQueryValueExW(hkey, name, NULL, NULL, (void*)value, &size))
+ return NULL;
+ value[size / sizeof *value] = 0;
+ return wcs_to_utf8(value, pool);
+}
+
+/* Try to glean the Windows release name and associated info from the
+ registry. Failing that, construct a release name from the version
+ info. */
+static const char *
+win32_release_name(apr_pool_t *pool)
+{
+ SYSTEM_INFO sysinfo;
+ OSVERSIONINFOEXW osinfo;
+ HKEY hkcv;
+
+ if (!system_info(&sysinfo, NULL, &osinfo))
+ return NULL;
+
+ if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
+ 0, KEY_QUERY_VALUE, &hkcv))
+ {
+ const char *release = registry_value(hkcv, L"ProductName", pool);
+ const char *spack = registry_value(hkcv, L"CSDVersion", pool);
+ const char *curver = registry_value(hkcv, L"CurrentVersion", pool);
+ const char *curtype = registry_value(hkcv, L"CurrentType", pool);
+ const char *install = registry_value(hkcv, L"InstallationType", pool);
+ const char *curbuild = registry_value(hkcv, L"CurrentBuildNumber", pool);
+
+ if (!spack && *osinfo.szCSDVersion)
+ spack = wcs_to_utf8(osinfo.szCSDVersion, pool);
+
+ if (!curbuild)
+ curbuild = registry_value(hkcv, L"CurrentBuild", pool);
+
+ if (release || spack || curver || curtype || curbuild)
+ {
+ const char *bootinfo = "";
+ if (curver || install || curtype)
+ {
+ bootinfo = apr_psprintf(pool, "[%s%s%s%s%s]",
+ (curver ? curver : ""),
+ (install ? (curver ? " " : "") : ""),
+ (install ? install : ""),
+ (curtype
+ ? (curver||install ? " " : "")
+ : ""),
+ (curtype ? curtype : ""));
+ }
+
+ return apr_psprintf(pool, "%s%s%s%s%s%s%s",
+ (release ? release : ""),
+ (spack ? (release ? ", " : "") : ""),
+ (spack ? spack : ""),
+ (curbuild
+ ? (release||spack ? ", build " : "build ")
+ : ""),
+ (curbuild ? curbuild : ""),
+ (bootinfo
+ ? (release||spack||curbuild ? " " : "")
+ : ""),
+ (bootinfo ? bootinfo : ""));
+ }
+ }
+
+ if (*osinfo.szCSDVersion)
+ {
+ const char *servicepack = wcs_to_utf8(osinfo.szCSDVersion, pool);
+
+ if (servicepack)
+ return apr_psprintf(pool, "Windows NT %u.%u, %s, build %u",
+ (unsigned int)osinfo.dwMajorVersion,
+ (unsigned int)osinfo.dwMinorVersion,
+ servicepack,
+ (unsigned int)osinfo.dwBuildNumber);
+
+ /* Assume wServicePackMajor > 0 if szCSDVersion is not empty */
+ if (osinfo.wServicePackMinor)
+ return apr_psprintf(pool, "Windows NT %u.%u SP%u.%u, build %u",
+ (unsigned int)osinfo.dwMajorVersion,
+ (unsigned int)osinfo.dwMinorVersion,
+ (unsigned int)osinfo.wServicePackMajor,
+ (unsigned int)osinfo.wServicePackMinor,
+ (unsigned int)osinfo.dwBuildNumber);
+
+ return apr_psprintf(pool, "Windows NT %u.%u SP%u, build %u",
+ (unsigned int)osinfo.dwMajorVersion,
+ (unsigned int)osinfo.dwMinorVersion,
+ (unsigned int)osinfo.wServicePackMajor,
+ (unsigned int)osinfo.dwBuildNumber);
+ }
+
+ return apr_psprintf(pool, "Windows NT %u.%u, build %u",
+ (unsigned int)osinfo.dwMajorVersion,
+ (unsigned int)osinfo.dwMinorVersion,
+ (unsigned int)osinfo.dwBuildNumber);
+}
+
+
+/* Get a list of handles of shared libs loaded by the current
+ process. Returns a NULL-terminated array alocated from POOL. */
+static HMODULE *
+enum_loaded_modules(apr_pool_t *pool)
+{
+ HANDLE current = GetCurrentProcess();
+ HMODULE dummy[1];
+ HMODULE *handles;
+ DWORD size;
+
+ if (!EnumProcessModules(current, dummy, sizeof(dummy), &size))
+ return NULL;
+
+ handles = apr_palloc(pool, size + sizeof *handles);
+ if (!EnumProcessModules(current, handles, size, &size))
+ return NULL;
+ handles[size / sizeof *handles] = NULL;
+ return handles;
+}
+
+/* Find the version number, if any, embedded in FILENAME. */
+static const char *
+file_version_number(const wchar_t *filename, apr_pool_t *pool)
+{
+ VS_FIXEDFILEINFO info;
+ unsigned int major, minor, micro, nano;
+ void *data;
+ DWORD data_size = GetFileVersionInfoSizeW(filename, NULL);
+ void *vinfo;
+ UINT vinfo_size;
+
+ if (!data_size)
+ return NULL;
+
+ data = apr_palloc(pool, data_size);
+ if (!GetFileVersionInfoW(filename, 0, data_size, data))
+ return NULL;
+
+ if (!VerQueryValueW(data, L"\\", &vinfo, &vinfo_size))
+ return NULL;
+
+ if (vinfo_size != sizeof info)
+ return NULL;
+
+ memcpy(&info, vinfo, sizeof info);
+ major = (info.dwFileVersionMS >> 16) & 0xFFFF;
+ minor = info.dwFileVersionMS & 0xFFFF;
+ micro = (info.dwFileVersionLS >> 16) & 0xFFFF;
+ nano = info.dwFileVersionLS & 0xFFFF;
+
+ if (!nano)
+ {
+ if (!micro)
+ return apr_psprintf(pool, "%u.%u", major, minor);
+ else
+ return apr_psprintf(pool, "%u.%u.%u", major, minor, micro);
+ }
+ return apr_psprintf(pool, "%u.%u.%u.%u", major, minor, micro, nano);
+}
+
+/* List the shared libraries loaded by the current process. */
+static const apr_array_header_t *
+win32_shared_libs(apr_pool_t *pool)
+{
+ apr_array_header_t *array = NULL;
+ wchar_t buffer[MAX_PATH + 1];
+ HMODULE *handles = enum_loaded_modules(pool);
+ HMODULE *module;
+
+ for (module = handles; module && *module; ++module)
+ {
+ const char *filename;
+ const char *version;
+ if (GetModuleFileNameW(*module, buffer, MAX_PATH))
+ {
+ buffer[MAX_PATH] = 0;
+ version = file_version_number(buffer, pool);
+ filename = wcs_to_utf8(buffer, pool);
+ if (filename)
+ {
+ svn_version_ext_loaded_lib_t *lib;
+ char *truename;
+
+ if (0 == apr_filepath_merge(&truename, "", filename,
+ APR_FILEPATH_NATIVE
+ | APR_FILEPATH_TRUENAME,
+ pool))
+ filename = truename;
+
+ if (!array)
+ {
+ array = apr_array_make(pool, 32, sizeof(*lib));
+ }
+ lib = &APR_ARRAY_PUSH(array, svn_version_ext_loaded_lib_t);
+ lib->name = filename;
+ lib->version = version;
+ }
+ }
+ }
+
+ return array;
+}
+#endif /* WIN32 */
+
+
+#ifdef SVN_HAVE_MACOS_PLIST
+/* Load the SystemVersion.plist or ServerVersion.plist file into a
+ property list. Set SERVER to TRUE if the file read was
+ ServerVersion.plist. */
+static CFDictionaryRef
+system_version_plist(svn_boolean_t *server, apr_pool_t *pool)
+{
+ static const UInt8 server_version[] =
+ "/System/Library/CoreServices/ServerVersion.plist";
+ static const UInt8 system_version[] =
+ "/System/Library/CoreServices/SystemVersion.plist";
+
+ CFPropertyListRef plist = NULL;
+ CFDataRef resource = NULL;
+ CFStringRef errstr = NULL;
+ CFURLRef url = NULL;
+ SInt32 errcode;
+
+ url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
+ server_version,
+ sizeof(server_version) - 1,
+ FALSE);
+ if (!url)
+ return NULL;
+
+ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
+ url, &resource,
+ NULL, NULL, &errcode))
+ {
+ CFRelease(url);
+ url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
+ system_version,
+ sizeof(system_version) - 1,
+ FALSE);
+ if (!url)
+ return NULL;
+
+ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
+ url, &resource,
+ NULL, NULL, &errcode))
+ {
+ CFRelease(url);
+ return NULL;
+ }
+ else
+ {
+ CFRelease(url);
+ *server = FALSE;
+ }
+ }
+ else
+ {
+ CFRelease(url);
+ *server = TRUE;
+ }
+
+ /* ### CFPropertyListCreateFromXMLData is obsolete, but its
+ replacement CFPropertyListCreateWithData is only available
+ from Mac OS 1.6 onward. */
+ plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resource,
+ kCFPropertyListImmutable,
+ &errstr);
+ if (resource)
+ CFRelease(resource);
+ if (errstr)
+ CFRelease(errstr);
+
+ if (CFDictionaryGetTypeID() != CFGetTypeID(plist))
+ {
+ /* Oops ... this really should be a dict. */
+ CFRelease(plist);
+ return NULL;
+ }
+
+ return plist;
+}
+
+/* Return the value for KEY from PLIST, or NULL if not available. */
+static const char *
+value_from_dict(CFDictionaryRef plist, CFStringRef key, apr_pool_t *pool)
+{
+ CFStringRef valref;
+ CFIndex bufsize;
+ const void *valptr;
+ const char *value;
+
+ if (!CFDictionaryGetValueIfPresent(plist, key, &valptr))
+ return NULL;
+
+ valref = valptr;
+ if (CFStringGetTypeID() != CFGetTypeID(valref))
+ return NULL;
+
+ value = CFStringGetCStringPtr(valref, kCFStringEncodingUTF8);
+ if (value)
+ return apr_pstrdup(pool, value);
+
+ bufsize = 5 * CFStringGetLength(valref) + 1;
+ value = apr_palloc(pool, bufsize);
+ if (!CFStringGetCString(valref, (char*)value, bufsize,
+ kCFStringEncodingUTF8))
+ value = NULL;
+
+ return value;
+}
+
+/* Return the commercial name of the OS, given the version number in
+ a format that matches the regular expression /^10\.\d+(\..*)?$/ */
+static const char *
+release_name_from_version(const char *osver)
+{
+ char *end = NULL;
+ unsigned long num = strtoul(osver, &end, 10);
+
+ if (!end || *end != '.' || num != 10)
+ return NULL;
+
+ osver = end + 1;
+ end = NULL;
+ num = strtoul(osver, &end, 10);
+ if (!end || (*end && *end != '.'))
+ return NULL;
+
+ /* See http://en.wikipedia.org/wiki/History_of_OS_X#Release_timeline */
+ switch(num)
+ {
+ case 0: return "Cheetah";
+ case 1: return "Puma";
+ case 2: return "Jaguar";
+ case 3: return "Panther";
+ case 4: return "Tiger";
+ case 5: return "Leopard";
+ case 6: return "Snow Leopard";
+ case 7: return "Lion";
+ case 8: return "Mountain Lion";
+ }
+
+ return NULL;
+}
+
+/* Construct the release name from information stored in the Mac OS X
+ "SystemVersion.plist" file (or ServerVersion.plist, for Mac Os
+ Server. */
+static const char *
+macos_release_name(apr_pool_t *pool)
+{
+ svn_boolean_t server;
+ CFDictionaryRef plist = system_version_plist(&server, pool);
+
+ if (plist)
+ {
+ const char *osname = value_from_dict(plist, CFSTR("ProductName"), pool);
+ const char *osver = value_from_dict(plist,
+ CFSTR("ProductUserVisibleVersion"),
+ pool);
+ const char *build = value_from_dict(plist,
+ CFSTR("ProductBuildVersion"),
+ pool);
+ const char *release;
+
+ if (!osver)
+ osver = value_from_dict(plist, CFSTR("ProductVersion"), pool);
+ release = release_name_from_version(osver);
+
+ CFRelease(plist);
+ return apr_psprintf(pool, "%s%s%s%s%s%s%s%s",
+ (osname ? osname : ""),
+ (osver ? (osname ? " " : "") : ""),
+ (osver ? osver : ""),
+ (release ? (osname||osver ? " " : "") : ""),
+ (release ? release : ""),
+ (build
+ ? (osname||osver||release ? ", " : "")
+ : ""),
+ (build
+ ? (server ? "server build " : "build ")
+ : ""),
+ (build ? build : ""));
+ }
+
+ return NULL;
+}
+#endif /* SVN_HAVE_MACOS_PLIST */
+
+#ifdef SVN_HAVE_MACHO_ITERATE
+/* List the shared libraries loaded by the current process.
+ Ignore frameworks and system libraries, they're just clutter. */
+static const apr_array_header_t *
+macos_shared_libs(apr_pool_t *pool)
+{
+ static const char slb_prefix[] = "/usr/lib/system/";
+ static const char fwk_prefix[] = "/System/Library/Frameworks/";
+ static const char pfk_prefix[] = "/System/Library/PrivateFrameworks/";
+
+ const size_t slb_prefix_len = strlen(slb_prefix);
+ const size_t fwk_prefix_len = strlen(fwk_prefix);
+ const size_t pfk_prefix_len = strlen(pfk_prefix);
+
+ apr_array_header_t *result = NULL;
+ apr_array_header_t *dylibs = NULL;
+
+ uint32_t i;
+ for (i = 0;; ++i)
+ {
+ const struct mach_header *header = _dyld_get_image_header(i);
+ const char *filename = _dyld_get_image_name(i);
+ const char *version;
+ char *truename;
+ svn_version_ext_loaded_lib_t *lib;
+
+ if (!(header && filename))
+ break;
+
+ switch (header->cputype)
+ {
+ case CPU_TYPE_I386: version = _("Intel"); break;
+ case CPU_TYPE_X86_64: version = _("Intel 64-bit"); break;
+ case CPU_TYPE_POWERPC: version = _("PowerPC"); break;
+ case CPU_TYPE_POWERPC64: version = _("PowerPC 64-bit"); break;
+ default:
+ version = NULL;
+ }
+
+ if (0 == apr_filepath_merge(&truename, "", filename,
+ APR_FILEPATH_NATIVE
+ | APR_FILEPATH_TRUENAME,
+ pool))
+ filename = truename;
+ else
+ filename = apr_pstrdup(pool, filename);
+
+ if (0 == strncmp(filename, slb_prefix, slb_prefix_len)
+ || 0 == strncmp(filename, fwk_prefix, fwk_prefix_len)
+ || 0 == strncmp(filename, pfk_prefix, pfk_prefix_len))
+ {
+ /* Ignore frameworks and system libraries. */
+ continue;
+ }
+
+ if (header->filetype == MH_EXECUTE)
+ {
+ /* Make sure the program filename is first in the list */
+ if (!result)
+ {
+ result = apr_array_make(pool, 32, sizeof(*lib));
+ }
+ lib = &APR_ARRAY_PUSH(result, svn_version_ext_loaded_lib_t);
+ }
+ else
+ {
+ if (!dylibs)
+ {
+ dylibs = apr_array_make(pool, 32, sizeof(*lib));
+ }
+ lib = &APR_ARRAY_PUSH(dylibs, svn_version_ext_loaded_lib_t);
+ }
+
+ lib->name = filename;
+ lib->version = version;
+ }
+
+ /* Gather results into one array. */
+ if (dylibs)
+ {
+ if (result)
+ apr_array_cat(result, dylibs);
+ else
+ result = dylibs;
+ }
+
+ return result;
+}
+#endif /* SVN_HAVE_MACHO_ITERATE */
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.h?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.h (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/sysinfo.h Sat Nov 24 20:29:11 2012
@@ -1,59 +1,69 @@
-/*
- * sysinfo.h: share svn_sysinfo__* functions
- *
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- */
-
-#ifndef SVN_LIBSVN_SUBR_SYSINFO_H
-#define SVN_LIBSVN_SUBR_SYSINFO_H
-
-#include <apr_pools.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Return a canonical name similar to the output of config.guess,
- * identifying the running system.
- *
- * All allocations are done in POOL.
- */
-const char *svn_sysinfo__canonical_host(apr_pool_t *pool);
-
-/* Return the release name (i.e., marketing name) of the running
- * system, or NULL if it's not available.
- *
- * All allocations are done in POOL.
- */
-const char *svn_sysinfo__release_name(apr_pool_t *pool);
-
-/* Return a string containing a list of shared libraries loaded by the
- * running process, including their versions where applicable, or NULL
- * if the information is not available.
- *
- * All allocations are done in POOL.
- */
-const char *svn_sysinfo__loaded_libs(apr_pool_t *pool);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* SVN_LIBSVN_SUBR_SYSINFO_H */
+/*
+ * sysinfo.h: share svn_sysinfo__* functions
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#ifndef SVN_LIBSVN_SUBR_SYSINFO_H
+#define SVN_LIBSVN_SUBR_SYSINFO_H
+
+#include <apr_pools.h>
+#include <apr_tables.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Return a canonical name similar to the output of config.guess,
+ * identifying the running system.
+ *
+ * All allocations are done in POOL.
+ */
+const char *svn_sysinfo__canonical_host(apr_pool_t *pool);
+
+/* Return the release name (i.e., marketing name) of the running
+ * system, or NULL if it's not available.
+ *
+ * All allocations are done in POOL.
+ */
+const char *svn_sysinfo__release_name(apr_pool_t *pool);
+
+/* Return an array of svn_version_linked_lib_t of descriptions of the
+ * link-time and run-time versions of dependent libraries, or NULL of
+ * the info is not available.
+ *
+ * All allocations are done in POOL.
+ */
+const apr_array_header_t *svn_sysinfo__linked_libs(apr_pool_t *pool);
+
+/* Return an array of svn_version_loaded_lib_t of descriptions of
+ * shared libraries loaded by the running process, including their
+ * versions where applicable, or NULL if the information is not
+ * available.
+ *
+ * All allocations are done in POOL.
+ */
+const apr_array_header_t *svn_sysinfo__loaded_libs(apr_pool_t *pool);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_LIBSVN_SUBR_SYSINFO_H */
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/temp_serializer.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/temp_serializer.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/temp_serializer.c Sat Nov 24 20:29:11 2012
@@ -51,7 +51,9 @@ typedef struct source_stack_t
/* offset within the target buffer to where the structure got copied */
apr_size_t target_offset;
- /* parent stack entry. Will be NULL for the root entry. */
+ /* parent stack entry. Will be NULL for the root entry.
+ * Items in the svn_temp_serializer__context_t recycler will use this
+ * to link to the next unused item. */
struct source_stack_t *upper;
} source_stack_t;
@@ -70,6 +72,9 @@ struct svn_temp_serializer__context_t
* process has been finished. However, it is not necessarily NULL when
* the application end serialization. */
source_stack_t *source;
+
+ /* unused stack elements will be put here for later reuse. */
+ source_stack_t *recycler;
};
/* Make sure the serialized data len is a multiple of the default alignment,
@@ -110,6 +115,7 @@ svn_temp_serializer__init(const void *so
svn_temp_serializer__context_t *context = apr_palloc(pool, sizeof(*context));
context->pool = pool;
context->buffer = svn_stringbuf_create_ensure(init_size, pool);
+ context->recycler = NULL;
/* If a source struct has been given, make it the root struct. */
if (source_struct)
@@ -168,6 +174,9 @@ svn_temp_serializer__init_append(void *b
context->source->target_offset = (char *)source_struct - (char *)buffer;
context->source->upper = NULL;
+ /* initialize the RECYCLER */
+ context->recycler = NULL;
+
/* done */
return context;
}
@@ -219,9 +228,16 @@ svn_temp_serializer__push(svn_temp_seria
apr_size_t struct_size)
{
const void *source = *source_struct;
+ source_stack_t *new;
- /* create a new entry for the structure stack */
- source_stack_t *new = apr_palloc(context->pool, sizeof(*new));
+ /* recycle an old entry or create a new one for the structure stack */
+ if (context->recycler)
+ {
+ new = context->recycler;
+ context->recycler = new->upper;
+ }
+ else
+ new = apr_palloc(context->pool, sizeof(*new));
/* the serialized structure must be properly aligned */
if (source)
@@ -250,11 +266,17 @@ svn_temp_serializer__push(svn_temp_seria
void
svn_temp_serializer__pop(svn_temp_serializer__context_t *context)
{
+ source_stack_t *old = context->source;
+
/* we may pop the original struct but not further */
assert(context->source);
/* one level up the structure stack */
context->source = context->source->upper;
+
+ /* put the old stack element into the recycler for later reuse */
+ old->upper = context->recycler;
+ context->recycler = old;
}
/* Serialize a string referenced from the current structure within the
@@ -311,7 +333,7 @@ svn_temp_serializer__get_length(svn_temp
return context->buffer->len;
}
-/* Return the data buffer that receives the serialialized data from
+/* Return the data buffer that receives the serialized data from
* the given serialization CONTEXT.
*/
svn_stringbuf_t *
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/utf.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/utf.c Sat Nov 24 20:29:11 2012
@@ -892,7 +892,9 @@ svn_utf_stringbuf_from_utf8(svn_stringbu
*dest = svn_stringbuf_dup(src, pool);
}
- put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool);
+ err = svn_error_compose_create(
+ err,
+ put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool));
return err;
}
@@ -925,7 +927,9 @@ svn_utf_string_from_utf8(const svn_strin
*dest = svn_string_dup(src, pool);
}
- put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool);
+ err = svn_error_compose_create(
+ err,
+ put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool));
return err;
}
@@ -939,11 +943,13 @@ svn_utf_cstring_from_utf8(const char **d
xlate_handle_node_t *node;
svn_error_t *err;
- SVN_ERR(check_utf8(src, strlen(src), pool));
+ SVN_ERR(check_cstring_utf8(src, pool));
SVN_ERR(get_uton_xlate_handle_node(&node, pool));
err = convert_cstring(dest, src, node, pool);
- put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool);
+ err = svn_error_compose_create(
+ err,
+ put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool));
return err;
}
@@ -960,12 +966,14 @@ svn_utf_cstring_from_utf8_ex2(const char
const char *convset_key = get_xlate_key(topage, SVN_APR_UTF8_CHARSET,
pool);
- SVN_ERR(check_utf8(src, strlen(src), pool));
+ SVN_ERR(check_cstring_utf8(src, pool));
SVN_ERR(get_xlate_handle_node(&node, topage, SVN_APR_UTF8_CHARSET,
convset_key, pool));
err = convert_cstring(dest, src, node, pool);
- put_xlate_handle_node(node, convset_key, pool);
+ err = svn_error_compose_create(
+ err,
+ put_xlate_handle_node(node, convset_key, pool));
return err;
}
@@ -1062,7 +1070,9 @@ svn_utf_cstring_from_utf8_string(const c
*dest = apr_pstrmemdup(pool, src->data, src->len);
}
- put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool);
+ err = svn_error_compose_create(
+ err,
+ put_xlate_handle_node(node, SVN_UTF_UTON_XLATE_HANDLE, pool));
return err;
}
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/utf_validate.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/utf_validate.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/utf_validate.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/utf_validate.c Sat Nov 24 20:29:11 2012
@@ -57,6 +57,8 @@
*/
#include "private/svn_utf_private.h"
+#include "private/svn_eol_private.h"
+#include "private/svn_dep_compat.h"
/* Lookup table to categorise each octet in the string. */
static const char octet_category[256] = {
@@ -249,12 +251,92 @@ static const char machine [9][14] = {
FSM_ERROR}, /* 0xf5-0xff */
};
+/* Scan MAX_LEN bytes in *DATA for chars that are not in the octet
+ * category 0 (FSM_START). Return the position of the first such char
+ * or DATA + MAX_LEN if all were cat 0.
+ */
+static const char *
+first_non_fsm_start_char(const char *data, apr_size_t max_len)
+{
+#if !SVN_UNALIGNED_ACCESS_IS_OK
+
+ /* On some systems, we need to make sure that buf is properly aligned
+ * for chunky data access.
+ */
+ if ((apr_uintptr_t)data & (sizeof(apr_uintptr_t)-1))
+ {
+ apr_size_t len = (~(apr_uintptr_t)data) & (sizeof(apr_uintptr_t)-1);
+ if (len > max_len)
+ len = max_len;
+ max_len -= len;
+
+ for (; len > 0; ++data, --len)
+ if (*data < 0 || *data >= 0x80)
+ return data;
+ }
+
+#endif
+
+ /* Scan the input one machine word at a time. */
+ for (; max_len > sizeof(apr_uintptr_t)
+ ; data += sizeof(apr_uintptr_t), max_len -= sizeof(apr_uintptr_t))
+ if (*(const apr_uintptr_t *)data & SVN__BIT_7_SET)
+ break;
+
+ /* The remaining odd bytes will be examined the naive way: */
+ for (; max_len > 0; ++data, --max_len)
+ if (*data < 0 || *data >= 0x80)
+ break;
+
+ return data;
+}
+
+/* Scan the C string in *DATA for chars that are not in the octet
+ * category 0 (FSM_START). Return the position of either the such
+ * char or of the terminating NUL.
+ */
+static const char *
+first_non_fsm_start_char_cstring(const char *data)
+{
+ /* We need to make sure that BUF is properly aligned for chunky data
+ * access because we don't know the string's length. Unaligned chunk
+ * read access beyond the NUL terminator could therefore result in a
+ * segfault.
+ */
+ for (; (apr_uintptr_t)data & (sizeof(apr_uintptr_t)-1); ++data)
+ if (*data <= 0 || *data >= 0x80)
+ return data;
+
+ /* Scan the input one machine word at a time. */
+ for (; ; data += sizeof(apr_uintptr_t))
+ {
+ /* Check for non-ASCII chars: */
+ apr_uintptr_t chunk = *(const apr_uintptr_t *)data;
+ if (chunk & SVN__BIT_7_SET)
+ break;
+
+ /* This is the well-known strlen test: */
+ chunk |= (chunk & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
+ if ((chunk & SVN__BIT_7_SET) != SVN__BIT_7_SET)
+ break;
+ }
+
+ /* The remaining odd bytes will be examined the naive way: */
+ for (; ; ++data)
+ if (*data <= 0 || *data >= 0x80)
+ break;
+
+ return data;
+}
const char *
svn_utf__last_valid(const char *data, apr_size_t len)
{
- const char *start = data, *end = data + len;
+ const char *start = first_non_fsm_start_char(data, len);
+ const char *end = data + len;
int state = FSM_START;
+
+ data = start;
while (data < end)
{
unsigned char octet = *data++;
@@ -270,6 +352,8 @@ svn_boolean_t
svn_utf__cstring_is_valid(const char *data)
{
int state = FSM_START;
+ data = first_non_fsm_start_char_cstring(data);
+
while (*data)
{
unsigned char octet = *data++;
@@ -284,6 +368,8 @@ svn_utf__is_valid(const char *data, apr_
{
const char *end = data + len;
int state = FSM_START;
+ data = first_non_fsm_start_char(data, len);
+
while (data < end)
{
unsigned char octet = *data++;
@@ -296,8 +382,11 @@ svn_utf__is_valid(const char *data, apr_
const char *
svn_utf__last_valid2(const char *data, apr_size_t len)
{
- const char *start = data, *end = data + len;
+ const char *start = first_non_fsm_start_char(data, len);
+ const char *end = data + len;
int state = FSM_START;
+
+ data = start;
while (data < end)
{
unsigned char octet = *data++;
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/version.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/version.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/version.c Sat Nov 24 20:29:11 2012
@@ -26,7 +26,9 @@
#include "svn_error.h"
#include "svn_version.h"
+#include "sysinfo.h"
#include "svn_private_config.h"
+#include "private/svn_subr_private.h"
const svn_version_t *
svn_subr_version(void)
@@ -96,3 +98,181 @@ svn_ver_check_list(const svn_version_t *
return err;
}
+
+
+struct svn_version_extended_t
+{
+ const char *build_date; /* Compilation date */
+ const char *build_time; /* Compilation time */
+ const char *build_host; /* Build canonical host name */
+ const char *copyright; /* Copyright notice (localized) */
+ const char *runtime_host; /* Runtime canonical host name */
+ const char *runtime_osname; /* Running OS release name */
+
+ /* Array of svn_version_ext_linked_lib_t describing dependent
+ libraries. */
+ const apr_array_header_t *linked_libs;
+
+ /* Array of svn_version_ext_loaded_lib_t describing loaded shared
+ libraries. */
+ const apr_array_header_t *loaded_libs;
+};
+
+
+const svn_version_extended_t *
+svn_version_extended(svn_boolean_t verbose,
+ apr_pool_t *pool)
+{
+ svn_version_extended_t *info = apr_pcalloc(pool, sizeof(*info));
+
+ info->build_date = __DATE__;
+ info->build_time = __TIME__;
+ info->build_host = SVN_BUILD_HOST;
+ info->copyright = apr_pstrdup
+ (pool, _("Copyright (C) 2012 The Apache Software Foundation.\n"
+ "This software consists of contributions made by many people;\n"
+ "see the NOTICE file for more information.\n"
+ "Subversion is open source software, see "
+ "http://subversion.apache.org/\n"));
+
+ if (verbose)
+ {
+ info->runtime_host = svn_sysinfo__canonical_host(pool);
+ info->runtime_osname = svn_sysinfo__release_name(pool);
+ info->linked_libs = svn_sysinfo__linked_libs(pool);
+ info->loaded_libs = svn_sysinfo__loaded_libs(pool);
+ }
+
+ return info;
+}
+
+
+const char *
+svn_version_ext_build_date(const svn_version_extended_t *ext_info)
+{
+ return ext_info->build_date;
+}
+
+const char *
+svn_version_ext_build_time(const svn_version_extended_t *ext_info)
+{
+ return ext_info->build_time;
+}
+
+const char *
+svn_version_ext_build_host(const svn_version_extended_t *ext_info)
+{
+ return ext_info->build_host;
+}
+
+const char *
+svn_version_ext_copyright(const svn_version_extended_t *ext_info)
+{
+ return ext_info->copyright;
+}
+
+const char *
+svn_version_ext_runtime_host(const svn_version_extended_t *ext_info)
+{
+ return ext_info->runtime_host;
+}
+
+const char *
+svn_version_ext_runtime_osname(const svn_version_extended_t *ext_info)
+{
+ return ext_info->runtime_osname;
+}
+
+const apr_array_header_t *
+svn_version_ext_linked_libs(const svn_version_extended_t *ext_info)
+{
+ return ext_info->linked_libs;
+}
+
+const apr_array_header_t *
+svn_version_ext_loaded_libs(const svn_version_extended_t *ext_info)
+{
+ return ext_info->loaded_libs;
+}
+
+svn_error_t *
+svn_version__parse_version_string(svn_version_t **version_p,
+ const char *version_string,
+ apr_pool_t *result_pool)
+{
+ svn_error_t *err;
+ svn_version_t *version;
+ apr_array_header_t *pieces =
+ svn_cstring_split(version_string, ".", FALSE, result_pool);
+
+ if ((pieces->nelts < 2) || (pieces->nelts > 3))
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING, NULL, NULL);
+
+ version = apr_pcalloc(result_pool, sizeof(*version));
+ version->tag = "";
+
+ /* Parse the major and minor integers strictly. */
+ err = svn_cstring_atoi(&(version->major),
+ APR_ARRAY_IDX(pieces, 0, const char *));
+ if (err)
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING, err, NULL);
+ err = svn_cstring_atoi(&(version->minor),
+ APR_ARRAY_IDX(pieces, 1, const char *));
+ if (err)
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING, err, NULL);
+
+ /* If there's a third component, we'll parse it, too. But we don't
+ require that it be present. */
+ if (pieces->nelts == 3)
+ {
+ const char *piece = APR_ARRAY_IDX(pieces, 2, const char *);
+ char *hyphen = strchr(piece, '-');
+ if (hyphen)
+ {
+ version->tag = apr_pstrdup(result_pool, hyphen + 1);
+ *hyphen = '\0';
+ }
+ err = svn_cstring_atoi(&(version->patch), piece);
+ if (err)
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING,
+ err, NULL);
+ }
+
+ *version_p = version;
+ return SVN_NO_ERROR;
+}
+
+
+svn_boolean_t
+svn_version__at_least(svn_version_t *version,
+ int major,
+ int minor,
+ int patch)
+{
+ /* Compare major versions. */
+ if (version->major < major)
+ return FALSE;
+ if (version->major > major)
+ return TRUE;
+
+ /* Major versions are the same. Compare minor versions. */
+ if (version->minor < minor)
+ return FALSE;
+ if (version->minor > minor)
+ return TRUE;
+
+ /* Major and minor versions are the same. Compare patch
+ versions. */
+ if (version->patch < patch)
+ return FALSE;
+ if (version->patch > patch)
+ return TRUE;
+
+ /* Major, minor, and patch versions are identical matches. But tags
+ in our schema are always used for versions not yet quite at the
+ given patch level. */
+ if (version->tag && version->tag[0])
+ return FALSE;
+
+ return TRUE;
+}
Modified: subversion/branches/compressed-pristines/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_subr/win32_crypto.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_subr/win32_crypto.c Sat Nov 24 20:29:11 2012
@@ -145,7 +145,7 @@ windows_password_decrypter(svn_boolean_t
SVN_ERR(svn_auth__simple_password_get(done, &in, creds, realmstring, username,
parameters, non_interactive, pool));
- if (!done)
+ if (!*done)
return SVN_NO_ERROR;
orig = svn_base64_decode_string(svn_string_create(in, pool), pool);
@@ -270,7 +270,7 @@ windows_ssl_client_cert_pw_decrypter(svn
SVN_ERR(svn_auth__ssl_client_cert_pw_get(done, &in, creds, realmstring,
username, parameters,
non_interactive, pool));
- if (!done)
+ if (!*done)
return SVN_NO_ERROR;
orig = svn_base64_decode_string(svn_string_create(in, pool), pool);
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_files.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_files.c Sat Nov 24 20:29:11 2012
@@ -592,7 +592,7 @@ svn_wc_create_tmp_file2(apr_file_t **fp,
SVN_ERR(svn_wc__db_open(&db,
NULL /* config */,
- TRUE /* auto_upgrade */,
+ FALSE /* auto_upgrade */,
TRUE /* enforce_empty_wq */,
pool, pool));
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_ops.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/adm_ops.c Sat Nov 24 20:29:11 2012
@@ -1019,6 +1019,7 @@ check_can_add_node(svn_node_kind_t *kind
const char *base_name = svn_dirent_basename(local_abspath, scratch_pool);
svn_boolean_t is_wc_root;
svn_node_kind_t kind;
+ svn_boolean_t is_special;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(!copyfrom_url || (svn_uri_is_canonical(copyfrom_url,
@@ -1035,7 +1036,8 @@ check_can_add_node(svn_node_kind_t *kind
SVN_ERR(svn_path_check_valid(local_abspath, scratch_pool));
/* Make sure something's there; set KIND and *KIND_P. */
- SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
+ SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &is_special,
+ scratch_pool));
if (kind == svn_node_none)
return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
_("'%s' not found"),
@@ -1097,14 +1099,20 @@ check_can_add_node(svn_node_kind_t *kind
SVN_ERR_ASSERT(!is_wc_root);
break;
case svn_wc__db_status_normal:
- if (copyfrom_url)
- {
- SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
- db, local_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, local_abspath,
+ scratch_pool));
- if (is_wc_root)
- break;
+ if (is_wc_root && copyfrom_url)
+ {
+ /* Integrate a sub working copy in a parent working copy
+ (legacy behavior) */
+ break;
+ }
+ else if (is_wc_root && is_special)
+ {
+ /* Adding a symlink to a working copy root.
+ (special_tests.py 23: externals as symlink targets) */
+ break;
}
/* else: Fall through in default error */
@@ -2203,7 +2211,7 @@ svn_wc_get_pristine_copy_path(const char
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__db_open(&db, NULL, TRUE, TRUE, pool, pool));
+ SVN_ERR(svn_wc__db_open(&db, NULL, FALSE, TRUE, pool, pool));
/* DB is now open. This is seemingly a "light" function that a caller
may use repeatedly despite error return values. The rest of this
function should aggressively close DB, even in the error case. */
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/cleanup.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/cleanup.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/cleanup.c Sat Nov 24 20:29:11 2012
@@ -206,7 +206,7 @@ svn_wc_cleanup3(svn_wc_context_t *wc_ctx
/* We need a DB that allows a non-empty work queue (though it *will*
auto-upgrade). We'll handle everything manually. */
SVN_ERR(svn_wc__db_open(&db,
- NULL /* ### config */, TRUE, FALSE,
+ NULL /* ### config */, FALSE, FALSE,
scratch_pool, scratch_pool));
SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton,